<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>

<chapter name="Max MIDI Tutorial 3: MIDI Parsing">

<setdocpatch name="03iMIDIParsing" patch="03iMIDIParsing.maxpat"/>
<previous name="midichapter02">Note Management</previous>
<next name="midichapter04">Basic Sequencing</next>
<parent name="00_maxindex">Max Tutorials</parent>

<indexinfo category="MIDI" title="Parsing">Decoding and encoding MIDI streams</indexinfo>

<h1>MIDI Tutorial 3: MIDI Parsing</h1>

<h2>Introduction</h2>

<p>This tutorial dives into a few MIDI-based objects that provide extended functionality for MIDI programming. The <o>midiparse</o> object can be used to examine the components of a raw MIDI stream, while <o>midiformat</o> is used as a one-stop shop for creation of most commonly supported MIDI messages. We also use the <o>xbendin</o> object to see the extended values provided by many MIDI controllers for the pitch bend value.</p>

<p>Because of the nature of these objects, this will be a “show” tutorial rather than a “build” tutorial.  However, please take the time to understand the data flow through these patches, since they are the basis for much of the handling of a complicated MIDI setup.</p>

<p>When creating any significant MIDI-controlled patch, we may need access to all of the notes, controller changes, and other messages generated by a MIDI device.  Rather than using many individual objects (such as <o>notein</o>, <o>ctlin</o>, <o>pgmin</o> and others), we can use a single <o>midiparse</o> object to decode the incoming MIDI stream.  We can also use the <o>midiformat</o> object to generate a MIDI stream that can contain a wide variety of MIDI messages. Both of these objects are very useful for complicated MIDI control patching.</p>

<p>We also take a look at the extended values provided for certain message types – specifically, the extended (14-bit) values provided by most MIDI keyboards for the pitchbend wheel. Since these messages can be produced very rapidly, we will also use the <o>speedlim</o> object to slow down the display of the values, preventing overload of our patch during high-speed message generation.</p>

<p>To open the tutorial patch, click on the <b>Open Tutorial</b> button in the upper right-hand corner of the documentation window.</p>

<h2>Viewing <o>midiparse</o> in action</h2>

<p>In the patcher for this tutorial, we are using a <o>midiin</o> object to grab the raw MIDI input stream from a MIDI input device, and using <o>midiparse</o> to split the data into the various supported message types. The outlets of <o>midiparse</o> issue different types of messages depending on the type of MIDI input: notes, poly key pressure and control changes are lists, while the program change, aftertouch and pitch bend outlets put out single integers. We’ve routed these outputs to <o>slider</o> objects in order to display the various messages as they are received.  If you have a MIDI controller that can generate these messages, select its MIDI port (by double-clicking on the <o>midiin</o> object) and play it – you should see the <o>slider</o> objects respond to incoming messages.  Note that the MIDI <m>channel</m> is not attached to the individual messages; the MIDI channel is sent from a shared outlet that will always display the channel of the most currently received message.</p>

<p>The <o>midiparse</o> object is used whenever you are creating a MIDI-driven patch that has to respond to a large number of message types. Rather than using all of the different message-specific objects (<o>notein</o> etc.), you can use this single object to track the various messages.  MIDI sequences being played into Max from an external hardware or software sequencer, for example, will contain much more than just notes; the <o>midiparse</o> object lets you see the full range of information present in the sequence.</p>

<h2>Viewing <o>midiformat</o> in action</h2>

<p>A complementary object to <o>midiparse</o> is <o>midiformat</o>, which allows us to create many different message types and turn them into a MIDI stream that is acceptable to the <o>midiout</o> object. The lower half of our test patch shows all of the messages that can be created, and provides <o>slider</o> objects that can be used to generate these messages.  To test the result,  double-click on the <o>midiout</o> object, and select an appropriate MIDI output device.  Then move a <o>slider</o> connected to the <o>midiformat</o> object – you should hear the results (when they are audible) from your MIDI device.</p>

<p>Some care needs to be taken when creating messages for <o>midiformat</o>. As with any other note-based device, you should pair MIDI note-on messages with MIDI note-off messages.  You should also limit the rate of controller messages that are sent to any device, since too great a density of controller messages can potentially confound a MIDI synthesizer.  Finally, you should make sure that the MIDI channel you are using is appropriate for the device that you are attempting to control.</p>

<h2>Tracking extended MIDI controllers using <o>xbendin</o></h2>

<p>In most cases, the 7-bit values (<m>0</m>-<m>127</m>) sent and received from MIDI controllers are sufficient for dealing with synthesizer and sampler control.  However, in a few cases, 7-bit values are insufficient for nuanced information.  The most common example of this is the pitchbend control.  When a synthesizer is set to bend +/- one octave, the individual steps of the pitchbend control might correspond to coarse and unmusical pitch steps.  The MIDI specification defines pitchbend to use 14 bits of data, providing values from <m>0</m> (full bend down) to <m>16383</m> (full bend up - the no bend state is <m>8192</m>).  This allows much finer pitch control, and offers a better likelihood of achieving musical results. Few controllers provide all 14 bits of accuracy, but 8 to 10 bits are very common.</p>

<p><o>Midiparse</o> only provides the most significant 7 bits of bend data, but we can track extended pitchbend information using the <o>xbendin</o> object. <o>Xbendin</o> takes raw MIDI input and outputs pitchbend messages that include this extended range.  Even if your MIDI controller does not send true 14-bit messages, they will be parsed as if the full 14-bits were available.  Unfortunately, even the most stable MIDI controller can produce an excessive number of MIDI pitchbend messages when tracking the extended value – the hardware is unable to stabilize on a single value, and may produce a greater-than-acceptable number of very small changes. While this may not affect any connected hardware, it can cause a Max patch to behave sluggishly, or at least make it difficult to properly debug a complex patch.</p>

<p>The solution for this is the <o>speedlim</o> object, which will take the output of any object (in this case, <o>xbendin</o>), and will limit the output to only one message in any given timeframe.  In the example patch, the argument <m>250</m> tells <o>speedlim</o> to output a message <i>at most</i> every <m>250</m> milliseconds (one-quarter second).  The object will discard all but the last message in that timeframe, giving us a less dense set of messages to manage in our patch.  When you send pitchbend information to the example patch, you will see that the <o>button</o> and <o>number</o> box connected to <o>xbendin</o> update much more often than those out of the <o>speedlim</o>; the <o>number</o> box connected to the output of <o>speedlim</o> will always be updated within a quarter-second to show the most recently passed value.</p>

<h2>Summary</h2>

<p>When creating a complicated MIDI-controlled patch, we will often want to use all of the available MIDI messages.  Rather than have a large number of message-specific objects, we can use the <o>midiparse</o> and <o>midiformat</o> messages to stream MIDI data from and to the devices while having access to all the message types. Using <o>midiparse</o> and <o>midiformat</o> is at the heart of any large and complex MIDI-based patching system.</p>

<p>Having access to extended control information can allow us to make more musically sensitive patches. Using <o>xbendin</o> to receive the extended pitch bend information can help us create more stable-sounding synthesizers within Max.  However, since some of this information might be received too quickly, using <o>speedlim</o> to slow down the receipt of these messages can help us keep our patches responsive.</p>

<seealsolist>
<seealso name="midiparse">Separate raw MIDI bytes by message type</seealso>
<seealso name="midiformat">Format data into a MIDI message</seealso>
<seealso name="xbendin">14-bit pitch bend filter/processor</seealso>
<seealso name="speedlim">Limit the speed of messages passing through</seealso>
</seealsolist>

</chapter>
