<html> <head> <title>MIDI data and the Playable Interface</title> </head> <!--TSE3-BODY--> <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> <!--TSE3-FOOTER--> </body> </html>