Sophie

Sophie

distrib > Mandriva > 9.2 > i586 > media > contrib > by-pkgid > 6a008f60192f948b748b09d760d81244 > files > 19

tse3-0.2.7-3mdk.i586.rpm

<html>

  <head>
    <title>MIDI data and the Playable Interface</title>
  </head>
  
<body bgcolor=#ffffff text=#000000>
<table width=100% cellspacing=0 cellpadding=1 border=0 bgcolor=#000000><tr><td>
<table width=100% cellspacing=0 cellpadding=1 border=0><tr><td valign=center bgcolor=#c8d559>
<table width=100% cellspacing=0 cellpadding=0 border=0><tr>
<td align=left width=30%><b>&nbsp;TSE3 documentation<b></td>
<td align=center width=30%>Version 0.2.7</td>
<td align=right width=30%>
  <a href="index.html"><b>Index</b></a>
  <a href="api/index.html">API</a>&nbsp;
  <a href="Version.html">Version</a>&nbsp;
  <a href="Structure.html">Structure</a>&nbsp;
</td>
</tr></table>
</td></tr></table>
</td></tr></table>

    <h1>MIDI data and the Playable interface</h1>

    <h3>MIDI data handling in TSE3</h3>

    <p>
    The TSE3 library has a single header file providing definitions for the
    elements of the standard MIDI specification. This is the file
    <code>Midi.h</code> (see the reference at the bottom of this page).

    <p>
    It defines the following elements:

    <dl>

      <dt><b>The <code>Clock</code> data value type.</b></dt>
      <dd>Describes a time value in a song, as a number of <i>ticks</i>.
          These ticks are in units of a pulse. There is a fixed number of
          <i>pulses per quarter note</i> (PPQN) defined in
          <code>Clock::PPQN</code>. (A <i>quarter note</i> is another
          name for a crotchet.)</dd>

      <dt><b>The <code>Event</code> template data value type.</b></dt>
      <dd>Provides a standard way to generate object which associate a
          data value (for example, a tempo change) with a time in
          <code>Clock</code>s.</dd>

      <dt><b>The <code>MidiCommands</code> and other similar
          definitions.</b></dt>
      <dd>Definitions of all the MIDI status bytes (e.g.
          <code>MidiCommand_NoteOn</code>, system commands, controller
          values etc. These are: <code>MidiCommands</code>,
          <code>MidiSystemCommands</code>, and <code>MidiControlChanges</code>.
          </dd>

      <dt><b>The <code>MidiCommand</code> data value class.</b></dt>
      <dd>This is the basic value type used to describe a single MIDI
          command, including it's statub byte, channel and port pair (which
          describe where the MIDI command should be sent), and any data bytes.
          </dd>

      <dt><b>The <code>MidiEvent</code> data value class.</b></dt>
      <dd>This is built upon the <code>MidiCommand</code> class, but associates
          it with an event time in <code>Clock<code>s.<br>
          Note that here we <i>do not</i> use the <code>Event</code> template
          class as a definition. This is because the <code>MidiEvent</code>
          contains a second <code>MidiCommand</code>, used if the first is a
          <code>MidiCommand_NoteOn</code>. If so, the second command holds the
          related <code>MidiCommand_NoteOff</code> event. This can be used by
          the TSE3 library to ensure that all MIDI note off events are sent for
          any scheduled note on event.
          </dd>

      <dt><b>The <code>TSE3MetaMidiCommand</code> definitions.</b></dt>
      <dd>These are a number of extension status bytes only understood by
          the TSE3 library which are used internally.</dd>

    </dl>

    <p>
    Used together, these definitions describe standard MIDI data, scheduled
    to some clock source. The TSE3 song components generate musical data
    in this format.

    <p>
    The <a href="KDOC.html">kdoc documentation</a> describes these classes.
    You can find further information about them there.


    <h3>The playable interface</h3>

    <p>
    Each component that comprises a Song can produce some sort of stream of
    MIDI data that needs to be scheduled to a timed output. To simplify this
    process they implement the <b><code>Playable</code></b> interface. This
    makes the Song structure use a form of the <i>composite</i> design pattern
    (GoF book).

    <p>
    The <code>Playable</code? meerly defines one method, creating for the
    client a <b><code>PlayableIterator</code></b> that can iterate over the
    MIDI data in the output stream. This is a form of the <i>iterator</i>
    design pattern.

    <p>
    Each different kind of <code>Playable</code> object provides it's own
    implementation of the <code>PlayableIterator</code> interface that knows
    how to generate the MIDI events.

    <p>
    The user can ignore the individual song components <code>Playable</code>
    interface, and meerly use the <code>Song</code>'s
    <code>PlayableIterator</code> that will in turn use the
    <code>Playable</code> iterators of all sub components to create a MIDI data 
    stream for the whole song.

<pre><b>
+------------\     +------------+      creates +--------------------+
| Interface  |_\   |  Playable  |--------------|  PlayableIterator  |
|              |   +------------+              +--------------------+
+------------- +         ^                               ^
                         |                               |
+------------\           |                               |
|   Example  |_\   +------------+              +--------------------+
| Implemenation |  |    Song    |              |    SongIterator    |
+---------------+  +------------+              +--------------------+
</b></pre>

    <p>
    The data generated by a <code>PlayableIterator</code> object is in the form
    described above, as defined by the <code>Midi.h</code> header file.

    <h3>Streaming system exclusive MIDI data</h3>

    <p>
    System exclusive MIDI data is a particular nuisance. All sequencer
    systems have this problem. If you don't care about, or know about
    system exclusive MIDI data (or <i>sysex</i> data) then you can skip
    this section.

    <p>
    Any other form of MIDI data, for example <code>MidiCommand_NoteOn</code>
    events and the like, can be interspersed in any order. They are sent
    in whole atomic units (the <code>MidiEvent</code> or
    <code>MidiCommand</code> classes). They are easy to handle and stream around
    the system in <code>PlaybaleIterator</code> objects.

    <p>
    However, sysex events break this simple atomic data structure. They
    can be of arbitrary size, with a single start of sysex system byte at the
    start, and an end of sysex status byte at the end.

    <p>
    So how do we stream these around using the <code>PlayableIterator</code>
    class? <i>Carefully</i>, is the answer.

    <p>
    Sysex data has been designed to fit into the <code>Playable</code>
    architecture rather than be handled as a special case. However, there are
    certain restrictions involved in their use. 

    <p>
    The start of a sysex block is naturally defined by a
    <code>MidiCommand</code> with
    <code>MidiComand_System</code> status byte and reason code
    <code>MidiSystem_SysExStart</code>. The <code>data1</code> byte contains
    the first data byte. <code>data2</code> is not used. If the event
    is held in a <code>MidiEvent</code> (rather than a single
    <code>MidiCommand</code> - this will be true if it is streamed from a
    <code>PlayableIterator</code>) then the second (note off) field is not
    used to hold extra values.

    <p>
    The next <code>MidiCommand</code> may need to be another sysex data byte. In
    this case the same status information is put in the <code>MidiComand</code>
    - although the playing
    <code>MidiScheduler</code> object knows not to send this again.
    <code>data1</code> contains this next data byte. More sysex data bytes
    may follow.
   
    <p>
    The stream carries on in this manner until the end of the sysex data block,
    when a <code>MidiComand</code> containing the
    <code>MidiSystem_SysExEnd</code> status information is put in the stream.

    <p>
    As stated above, sysex data cannot be rearranged. Nor can other MIDI
    events occur in the middle of them (you cannot shove a note on in the
    middle of a block of sysex). For this reason any
    <code>PlayableIterator</code> must take care to give each sysex
    <code>MidiCommand</code>
    <i>exactly the same</i> clock time to ensure no other events can get into
    the middle of the sysex stream.

    <p>
    The standard TSE3 <code>PlayableIterator</code> objects are designed in
    such a way that if all events have the same event time, events from
    other sources will not interrupt the stream.

    <h3>See also</h3>

    <ul>
      <li><a href="api/Midi_h.html"><code>Midi.h</code></a> for
           descriptions of the TSE3 representation of MIDI data.
      <li><a href="api/Playable_h.html"><code>Playable.h</code></a> for
           the definition of the <code>Playable</code> class.
    </ul>

<body bgcolor=#ffffff text=#000000>
<table width=100% cellspacing=0 cellpadding=1 border=0 bgcolor=#000000><tr><td>
<table width=100% cellspacing=0 cellpadding=1 border=0><tr><td valign=center bgcolor=#c8d559>
<table width=100% cellspacing=0 cellpadding=0 border=0><tr>
<td align=left width=30%>&nbsp;&copy; Pete Goodliffe, 2001-2003</td>
<td align=center width=30%><a href="Copyright.html">Copyright</a></td>
<td align=right width=30%><a href="Psalm150.html">Psalm 150</a>&nbsp;</td>
</tr></table>
</td></tr></table>
</td></tr></table>
    
  </body>

</html>