307 lines
32 KiB
HTML
307 lines
32 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Be Book - System Overview - The Midi Kit</title><link rel="stylesheet" href="be_book.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
|
||
<link rel="stylesheet" type="text/css" href="be_book_ie.css" />
|
||
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="Access, BeOS, BeBook, API" /><link rel="start" href="index.html" title="The Be Book" /><link rel="up" href="TheMidiKit_Overview.html" title="The Midi Kit" /><link rel="prev" href="TheMidiKit_Introduction.html" title="Introduction" /><link rel="next" href="BMidiPort_Overview.html" title="BMidiPort" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="TheMidiKit_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="TheMidiKit_Overview.html" title="The Midi Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="BMidiPort_Overview.html" title="BMidiPort"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="navigindex"><a accesskey="i" href="ClassIndex.html" title="Index">I</a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">The Be Book - System Overview - The Midi Kit</div></div><div id="headerB">Prev: <a href="TheMidiKit_Introduction.html">Introduction</a> Up: <a href="TheMidiKit_Overview.html">The Midi Kit</a> Next: <a href="BMidiPort_Overview.html">BMidiPort</a></div><hr /></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview"></a>BMidi</h2></div></div></div><a id="id592713" class="indexterm"></a><p><a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
is an abstract class that defines protocols and default
|
||
implementations for functions that most of the other Midi Kit classes
|
||
inherit. The functions that
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
defines fall into four categories:</p><dl class="variablelist"><dt><span class="term">Connection functions.</span></dt><dd><p>The connection functions let you connect the output of one
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object to the input of another
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object.</p></dd><dt><span class="term">Performance functions.</span></dt><dd><p><a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
objects that generate MIDI data (by
|
||
reading from a port or file, as examples) implement the
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
hook function.
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
is the brains of a MIDI performance;
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a> and
|
||
<a class="link" href="BMidi.html#BMidi_Stop" title="Stop()"><code class="methodname">Stop()</code></a>
|
||
control the performance.</p></dd><dt><span class="term">"Spray" functions.</span></dt><dd><p>The "spray" functions send MIDI messages to each
|
||
of the objects that are connected to the output of the sprayer. There's
|
||
a spray function for each type of MIDI message; for example,
|
||
<a class="link" href="BMidi.html#BMidi_SprayNoteOn"><code class="methodname">SprayNoteOn()</code></a>
|
||
corresponds to MIDI's Note On message.</p></dd><dt><span class="term">"MIDI hook" functions.</span></dt><dd>
|
||
The "MIDI hook" functions define the object's
|
||
response to a particular type of MIDI message. There's a hook function
|
||
for each MIDI message
|
||
(<a class="link" href="BMidi.html#BMidi_NoteOn" title="NoteOn(), SprayNoteOn()"><code class="methodname">NoteOn()</code></a>,
|
||
<a class="link" href="BMidi.html#BMidi_NoteOff" title="NoteOff(), SprayNoteOff()"><code class="methodname">NoteOff()</code></a>,
|
||
etc.). The hook functions
|
||
are invoked automatically as "upstream" objects call the corresponding
|
||
spray functions.
|
||
</dd></dl><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_FormingConnections"></a>Forming Connections</h3></div></div></div><p>MIDI data streams through your application, passing from one
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>-derived
|
||
object to another. Each object does whatever it's designed
|
||
to do: Sends the data to a MIDI port, writes it to a file, modifies it
|
||
and passes it on, and so on.</p><p>You form a tree of
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
objects through <a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>'s
|
||
<a class="link" href="BMidi.html#BMidi_Connect" title="Connect()"><code class="methodname">Connect()</code></a>
|
||
function, which takes a single
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
argument. By calling
|
||
<a class="link" href="BMidi.html#BMidi_Connect" title="Connect()"><code class="methodname">Connect()</code></a>,
|
||
you connect the output of the calling object to the input of the argument object.
|
||
(i.e. the caller is the source; the argument is the destination.)</p><p>Let's say you want to connect a MIDI keyboard to your computer, play it,
|
||
and have the performance recorded in a file. You connect a
|
||
<a class="link" href="BMidiPort.html" title="BMidiPort"><code class="classname">BMidiPort</code></a>
|
||
object, which reads data from the MIDI port, to a
|
||
<a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a> object,
|
||
which stores the data that's sent to it and can write it to a file:</p><pre class="programlisting example cpp"><span class="comment">/* Connect the output of a BMidiPort to the input of a BMidiStore. */</span>
|
||
<code class="classname">BMidiPort</code> <code class="varname">m_port</code>;
|
||
<code class="classname">BMidiStore</code> <code class="varname">m_store</code>;
|
||
|
||
<code class="varname">m_port</code>.<code class="methodname">Connect</code>(&<code class="varname">m_store</code>);</pre><p>You also have to tell the
|
||
<a class="link" href="BMidiPort.html" title="BMidiPort"><code class="classname">BMidiPort</code></a>
|
||
to start listening to the MIDI port,
|
||
by calling its
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a>
|
||
function. This is explained in a later section.</p><p>Once you've made the recording, you can play it back by re-connecting the
|
||
objects in the opposite direction:</p><pre class="programlisting example cpp"><span class="comment">/* We'll disconnect first, although this isn't strictly necessary. */</span>
|
||
<code class="varname">m_port</code>.<code class="methodname">Disconnect</code>(&<code class="varname">m_store</code>);
|
||
<code class="varname">m_store</code>.<code class="methodname">Connect</code>(&<code class="varname">m_port</code>);</pre><p>In this configuration, a
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a>
|
||
call to <code class="varname">m_store</code> would cause its MIDI
|
||
data to flow into the
|
||
<a class="link" href="BMidiPort.html" title="BMidiPort"><code class="classname">BMidiPort</code></a>
|
||
(and thence to a synthesizer, for example, for realization).</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_SourcesAndDestinations"></a>Sources and Destinations</h4></div></div></div><p>A <a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object can be the source for any number of other objects:</p><pre class="programlisting example cpp"><code class="varname">a_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">b_object</code>);
|
||
<code class="varname">a_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">c_object</code>);
|
||
<code class="varname">a_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">d_object</code>);</pre><p>A source can get a list of its destinations through the
|
||
<a class="link" href="BMidi.html#BMidi_Connections" title="Connections()"><code class="methodname">Connections()</code></a>
|
||
function.</p><p>A BMidi object can be the destination for any number of sources:</p><pre class="programlisting example cpp"><code class="varname">b_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">e_object</code>);
|
||
<code class="varname">c_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">e_object</code>);
|
||
<code class="varname">d_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">e_object</code>);</pre><p>However, a destination can't get a list of its sources.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_GeneratingMIDIMessages"></a>Generating MIDI Messages</h3></div></div></div><p>If your class wants to generate new MIDI data (as opposed to filtering or
|
||
realizing the data it receives), it must implement the
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function. An implementation of
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
should include a <span class="code">while()</span> loop that broadcasts one
|
||
or more MIDI message on each pass (typically it broadcasts only one), by
|
||
invoking a spray function. To predicate the loop you must test the value
|
||
of the
|
||
<a class="link" href="BMidi.html#BMidi_KeepRunning" title="KeepRunning()"><code class="methodname">KeepRunning()</code></a>
|
||
boolean function.</p><p>The outline of a
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
implementation looks like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyMidi</code>::<code class="methodname">Run</code>()
|
||
{
|
||
while (<code class="methodname">KeepRunning</code>()) {
|
||
<span class="comment">/* Generate a message and spray it. For example... */</span>
|
||
<code class="methodname">SprayNoteOn</code>(...);
|
||
}
|
||
<span class="comment">/* You MUST exit when KeepRunning() returns false. */</span>
|
||
}</pre><div class="admonition warning"><div class="title">Warning</div><div class="graphic"><img class="icon" alt="Warning" width="32" src="./images/admonitions/Stop_32.png" /><div class="text"><p>The <a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function <span class="emphasis"><em>must</em></span> exit when
|
||
<a class="link" href="BMidi.html#BMidi_KeepRunning" title="KeepRunning()"><code class="methodname">KeepRunning()</code></a>
|
||
returns <code class="constant">false</code>. If it doesn't, you'll leak threads.</p></div></div></div><p>To tell an object to perform its
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function, you call the object's
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a>
|
||
function—you never call
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
directly.
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a>
|
||
causes the object to spawn a thread (its "run" thread) and execute
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
within it. When you're tired of the object's performance, you call its
|
||
<a class="link" href="BMidi.html#BMidi_Stop" title="Stop()"><code class="methodname">Stop()</code></a>
|
||
function.</p><p>Keep in mind that the
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function is only needed in classes that
|
||
introduce new MIDI data into a performance. As examples,
|
||
<a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a>'s
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
sprays messages that correspond to the MIDI data that it stores,
|
||
and <a class="link" href="BMidiPort.html" title="BMidiPort"><code class="classname">BMidiPort</code></a>
|
||
reads data from the MIDI port and sprays messages accordingly.</p><p>Another point to keep in mind is that the
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function can run ahead of
|
||
real time. It doesn't have to generate and spray data precisely at the
|
||
moment that the data needs to be realized. This is further explained in
|
||
the section
|
||
"<a class="xref" href="BMidi_Overview.html#BMidi_Overview_Time" title="Time">Time</a>".</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>The
|
||
<a class="link" href="BMidiSynthFile.html" title="BMidiSynthFile"><code class="classname">BMidiSynthFile</code></a>
|
||
class differs from the other classes in the way that
|
||
it implements and uses its
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function; in particular, it doesn't
|
||
spawn a run thread. See the
|
||
<a class="link" href="BMidiSynthFile.html" title="BMidiSynthFile"><code class="classname">BMidiSynthFile</code></a>
|
||
class for more information.</p></div></div></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_SprayFunctions"></a>Spray Functions</h3></div></div></div><p>The spray functions send data to the
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
objects that are connected to
|
||
the running object's output. There's a separate spray function for each
|
||
of the MIDI message types:
|
||
<a class="link" href="BMidi.html#BMidi_SprayNoteOn"><code class="methodname">SprayNoteOn()</code></a>,
|
||
<a class="link" href="BMidi.html#BMidi_SprayNoteOff"><code class="methodname">SprayNoteOff()</code></a>,
|
||
<a class="link" href="BMidi.html#BMidi_SprayPitchBend"><code class="methodname">SprayPitchBend()</code></a>,
|
||
and so on. Spray functions are always found within a
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>'s
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
loop, but they can be found in other places as well. For
|
||
example, if you're creating a MIDI filter, you would use spray functions
|
||
in the implementations of the object's MIDI hook functions (as explained
|
||
next).</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_MIDIHookFunctions"></a>MIDI Hook Functions</h3></div></div></div><p>The MIDI hook functions are hooks that are invoked upon an object's
|
||
connections when the object sprays MIDI data. The functions take the
|
||
names of the MIDI messages to which they respond:
|
||
<a class="link" href="BMidi.html#BMidi_NoteOn" title="NoteOn(), SprayNoteOn()"><code class="methodname">NoteOn()</code></a>
|
||
responds to a Note On message,
|
||
<a class="link" href="BMidi.html#BMidi_NoteOff" title="NoteOff(), SprayNoteOff()"><code class="methodname">NoteOff()</code></a>
|
||
responds to a Note Off, and so on. For example, this…</p><pre class="programlisting example cpp"><code class="varname">a_midi</code>.<code class="methodname">Connect</code>(&<code class="varname">b_midi</code>);
|
||
<code class="varname">a_midi</code>.<code class="methodname">SprayNoteOn</code>(...);</pre><p>…causes <code class="varname">b_midi</code>'s
|
||
<a class="link" href="BMidi.html#BMidi_NoteOn" title="NoteOn(), SprayNoteOn()"><code class="methodname">NoteOn()</code></a>
|
||
function to be invoked. The arguments that are passed to
|
||
<a class="link" href="BMidi.html#BMidi_NoteOn" title="NoteOn(), SprayNoteOn()"><code class="methodname">NoteOn()</code></a>
|
||
are taken directly from the
|
||
<a class="link" href="BMidi.html#BMidi_SprayNoteOn"><code class="methodname">SprayNoteOn()</code></a>
|
||
call.</p><p><a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
doesn't provide default implementations for any of the MIDI hooks;
|
||
it's up to each
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>-derived
|
||
class to decide how to respond to MIDI messages.</p><p>Every <a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object automatically spawns an "inflow" thread when it's
|
||
constructed. It's in this thread that the spray-invoked MIDI hooks are
|
||
executed. The inflow thread is always running—the
|
||
<a class="link" href="BMidi.html#BMidi_Start" title="Start()"><code class="methodname">Start()</code></a> and
|
||
<a class="link" href="BMidi.html#BMidi_Stop" title="Stop()"><code class="methodname">Stop()</code></a>
|
||
functions don't affect it. As soon as you construct an object,
|
||
it's ready to receive data.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_CallingMIDIHooksDirectly"></a>Calling MIDI Hooks Directly</h4></div></div></div><p>You can also feed MIDI data to a
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object by invoking the MIDI hook
|
||
functions directly. For example, let's say you just want to play a note
|
||
on the General MIDI synthesizer. You don't have to create your own
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
class simply to implement a
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function that sprays the note; instead, all you have to do is this:</p><pre class="programlisting example cpp"><code class="classname">BMidiSynth</code> <code class="varname">midiSynth</code>;
|
||
|
||
<span class="comment">/* Initialize the BMidiSynth as described in that class. */</span>
|
||
...
|
||
<span class="comment">/* Play a note. */</span>
|
||
<code class="varname">midiSynth</code>.<code class="methodname">NoteOn</code>(...);</pre><p>Keep in mind that when you invoke a hook function directly, it executes
|
||
synchronously in the calling thread. Furthermore, the object may also be
|
||
receiving MIDI messages in its inflow thread. For the Midi Kit-defined
|
||
classes, this isn't a problem.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_CreatingAMIDIFilter"></a>Creating a MIDI Filter</h4></div></div></div><p>Some BMidi objects "act as filters: They receive data, modify it, and
|
||
then pass it on. To do this, you call the appropriate spray functions
|
||
from within the implementations of the MIDI hooks. Below is the
|
||
implementation of the NoteOn() function for a proposed class called
|
||
Transposer. It takes each Note On, transposes it up a half step, and then
|
||
sprays it:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">Transposer</code>::<code class="methodname">NoteOn</code>(<span class="type">uchar</span> <code class="parameter">channel</code>, <span class="type">uchar</span> <code class="parameter">keyNumber</code>,
|
||
<span class="type">uchar</span> <code class="parameter">velocity</code>, <span class="type">uint32</span> <code class="parameter">time</code>)
|
||
{
|
||
<span class="type">uchar</span> <code class="varname">new_key</code> = <code class="function">max</code>(<code class="parameter">keyNumber</code> + 1, 127);
|
||
<code class="methodname">SprayNoteOn</code>(<code class="parameter">channel</code>, <code class="varname">new_key</code>, <code class="parameter">velocity</code>, <code class="parameter">time</code>);
|
||
}</pre><p>There's a subtle but important distinction between a filter class and a
|
||
"performance" class (where the latter is a class that's designed to
|
||
actually realize the MIDI data it receives). The distinction has to do
|
||
with time, and is explained in the next section. An implication of the
|
||
distinction that affects the current discussion is that it may not be a
|
||
great idea to invest, in a single object, the ability to filter and
|
||
perform MIDI data. Both
|
||
<a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a> and
|
||
<a class="link" href="BMidiPort.html" title="BMidiPort"><code class="classname">BMidiPort</code></a>
|
||
are performance classes—objects of these classes realize the data they receive, the
|
||
former by caching it, the latter by sending it out the MIDI port. In
|
||
neither of these classes do the MIDI hooks spray data.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_Time"></a>Time</h3></div></div></div><p>Every spray and MIDI hook function takes a final time argument. This
|
||
argument declares when the message that the function represents should be
|
||
performed. The argument is given in ticks (milliseconds). Tick 0 occurs
|
||
when you boot your computer; the tick counter automatically starts
|
||
running at that point. To get the current tick measurement, you call the
|
||
global, Kernel Kit-defined
|
||
<a class="link" href="TheKernelKit_Time.html#system_time" title="system_time()"><code class="function">system_time()</code></a>
|
||
function and divide by 1000
|
||
(<a class="link" href="TheKernelKit_Time.html#system_time" title="system_time()"><code class="function">system_time()</code></a>
|
||
returns microseconds).</p><p>By convention, time arguments are applied at an object's input. In other
|
||
words, a MIDI hook should look at the time argument, wait until the
|
||
designated time, and then do whatever it does that it does do. However,
|
||
this only applies to
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>-derived
|
||
classes that are designed to perform
|
||
MIDI data. Objects that simply filter data shouldn't apply the time
|
||
argument.</p><p>To apply the time argument, you call the
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>
|
||
function, passing
|
||
the value of time. For example, a "performance"
|
||
<a class="link" href="BMidi.html#BMidi_NoteOn" title="NoteOn(), SprayNoteOn()"><code class="methodname">NoteOn()</code></a>
|
||
function would look like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyPerformer</code>::<code class="methodname">NoteOn</code>(<span class="type">uchar</span> <code class="parameter">channel</code>, <span class="type">uchar</span> <code class="parameter">keyNumber</code>,
|
||
<span class="type">uchar</span> <code class="parameter">velocity</code>, <span class="type">uint32</span> <code class="parameter">time</code>)
|
||
{
|
||
<code class="methodname">SnoozeUntil</code>(<code class="parameter">time</code>);
|
||
<span class="comment">/* Perform the data here. */</span>
|
||
}</pre><p>If time designates a tick that has already tocked,
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>
|
||
returns immediately; otherwise it tells the inflow thread to snooze until the
|
||
designated tick is at hand.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_SprayingTime"></a>Spraying Time</h3></div></div></div><p>If you're implementing the
|
||
<a class="link" href="BMidi.html#BMidi_Run" title="Run()"><code class="methodname">Run()</code></a>
|
||
function, then you have to generate a
|
||
time value yourself which you pass as the final argument to each spray
|
||
function that you call. The value you generate depends on whether your
|
||
class runs in real time, or ahead of time.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_RunningInRealTime"></a>Running in Real Time</h4></div></div></div><p>If your class conjures MIDI data that needs to be performed immediately,
|
||
you should use the <code class="function">B_NOW</code> macro as the value of the time arguments that
|
||
you pass to your spray functions. <code class="function">B_NOW</code> is simply a cover for
|
||
(<a class="link" href="TheKernelKit_Time.html#system_time" title="system_time()"><code class="function">system_time()</code></a>/1000)
|
||
(converted to <span class="type">uint</span>). By using <code class="function">B_NOW</code> as the time
|
||
argument you're declaring that the data should be performed in the same
|
||
tick in which it was generated. This probably won't happen; by the time
|
||
the MIDI hooks are called and the data realized, a couple of ticks may
|
||
have elapsed. In this case, the MIDI hooks'
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>
|
||
calls will see
|
||
that the time value has passed and will return immediately, allowing the
|
||
data to be realized as quickly as possible.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BMidi_Overview_RunningAheadOfTime"></a>Running Ahead of Time</h4></div></div></div><p>If you're generating data ahead of its performance time, you need to
|
||
compute the time value so that it pinpoints the correct time in the
|
||
future. For example, if you want to create a class that generates a note
|
||
every 100 milliseconds, you need to do something like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyTicker</code>::<code class="methodname">Run</code>()
|
||
{
|
||
<span class="type">uint32</span> <code class="varname">when</code> = <code class="function">B_NOW</code>;
|
||
<span class="type">uchar</span> <code class="varname">key_num</code>;
|
||
|
||
while (<code class="methodname">KeepRunning</code>()) {
|
||
|
||
<span class="comment">/* Make a new note. */</span>
|
||
<code class="methodname">SprayNoteOn</code>(1, 60, 64, <code class="varname">when</code>);
|
||
|
||
<span class="comment">/* Turn the note off 99 ticks later. */</span>
|
||
<code class="varname">when</code> += 99;
|
||
<code class="methodname">SprayNoteOff</code>(1, 60, 0, <code class="varname">when</code>);
|
||
|
||
<span class="comment">/* Bump the when variable so the next Note On
|
||
* will be 100 ticks after this one.
|
||
*/</span>
|
||
<code class="varname">when</code> += 1;
|
||
}
|
||
}</pre><p>When a <code class="classname">MyTicker</code> object is told to start running, it generates a sequence
|
||
of Note On/Note Off pairs, and sprays them to its connected objects.
|
||
Somewhere down the line, a performance object will apply the time value
|
||
by calling
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>.</p><p>But what keeps <code class="classname">MyTicker</code> from running wild and generating thousands or
|
||
millions of notes—which aren't scheduled to be played for
|
||
hours—as fast as possible? It's because the spray functions pass
|
||
data to the MIDI hooks through Kernel Kit ports that are 1 (one) message
|
||
deep. So, as long as one of the MIDI hooks calls
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>,
|
||
the spraying object will never be more than one message ahead.</p><p>A useful feature of this mechanism is that if you connect a series of
|
||
<a class="link" href="BMidi.html" title="BMidi"><code class="classname">BMidi</code></a>
|
||
object that don't invoke
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>,
|
||
you can process MIDI data
|
||
faster than real-time. For example, let's say you want to spray data from
|
||
one
|
||
<a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a>
|
||
object, pass the data through a filter, and then store it in another
|
||
<a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a>.
|
||
The <a class="link" href="BMidiStore.html" title="BMidiStore"><code class="classname">BMidiStore</code></a>
|
||
MIDI hooks don't call
|
||
<a class="link" href="BMidi.html#BMidi_SnoozeUntil" title="SnoozeUntil()"><code class="methodname">SnoozeUntil()</code></a>;
|
||
thus, data will flow out of the first object, through the
|
||
filter, and into its destination as quickly as possible, allowing you to
|
||
process hours of real-time data in just a few seconds. Of course, if you
|
||
add a performance object into this mix (so you can hear the data while
|
||
it's being processed), the data flow will be tethered, as described above.</p></div></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="TheMidiKit_Introduction.html">Introduction</a> Up: <a href="TheMidiKit_Overview.html">The Midi Kit</a> Next: <a href="BMidiPort_Overview.html">BMidiPort</a> </div><div id="footerB"><div id="footerBL"><a href="TheMidiKit_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="TheMidiKit_Overview.html" title="The Midi Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="BMidiPort_Overview.html" title="BMidiPort"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
|
||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
|
||
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>
|