16. Musical Instrument Digital Interface (MIDI)

This chapter describes the MIDI encoding functionality present in MEI. The purpose of this module is to allow for integrating MIDI data into MEI-encoded notation, to both aid software in translating MEI to MIDI, and to permit the capture of information in files that have been translated from MIDI to MEI. The MIDI model in MEI is similar to that of Mup, and the user is directed to the Mup User Guide for further reading.

The MIDI module defines certain generally-accepted MIDI units that may be used outside of a MIDI context. For example, the @dur.ges attribute accepts MIDI ppq (Pulses Per Quarter) as a valid measurement of duration. Similarly, the @pnum attribute allows MIDI note numbers for specifying a pitch value.

16.1. PPQ in scoreDef and staffDef

To define the MIDI resolution of a score, the @ppq attribute may be used on the scoreDef element. This value can be used to interpret the values found in the @dur.ges attribute on elements in the att.duration.performed class.

<scoreDef key.sig="1f" meter.count="4" meter.sym="common" meter.unit="4" ppq="48">
   <staffGrp>
      <staffDef clef.line="2" clef.shape="G" key.sig="1f" lines="5" n="1" xml:id="midi.P1"></staffDef>
      <staffDef clef.line="4" clef.shape="F" key.sig="1f" lines="5" n="2" xml:id="midi.P2"></staffDef>
      <staffDef clef.line="4" clef.shape="F" key.sig="1f" lines="5" n="3" xml:id="midi.P3"></staffDef>
   </staffGrp>
</scoreDef>
<!-- snip -->
<note dur="8" dur.ges="24p" oct="5" pname="a" stem.dir="up" xml:id="midi.d1e40"></note>
<!-- 8th note -->
<rest dur="32" dur.ges="6p" vo="4" xml:id="midi.d1e58"></rest>
<!-- 32nd note -->
<!-- snip -->

The @ppq attribute is also available on the staffDef element in order to aid in the conversion to MEI from other representations that allow a different time base for each staff. However, these independent values for @ppq are only interpretable in terms of a common time base. Therefore, the @ppq attribute is required on scoreDef when the values of @ppq on the staff definitions differ. In the following example, the values of the @ppq attributes on the staffDef elements are all factors of the value of @ppq attached to scoreDef.

<scoreDef key.sig="1f" meter.count="4" meter.sym="common" meter.unit="4" ppq="48">
   <staffGrp>
      <staffDef clef.line="2" clef.shape="G" key.sig="1f" lines="5" n="1" ppq="2" xml:id="midi.P1"></staffDef>
      <staffDef clef.line="4" clef.shape="F" key.sig="1f" lines="5" n="2" ppq="16" xml:id="midi.P2"></staffDef>
      <staffDef clef.line="4" clef.shape="F" key.sig="1f" lines="5" n="3" ppq="24" xml:id="midi.P3"></staffDef>
   </staffGrp>
</scoreDef>

16.2. Recording General MIDI Instrumentation

The instrDef element can be used to record MIDI instrument names or numbers using the @midi.instrname and @midi.instrnum attributes. The @midi.instrname attribute must contain an instrument name from the list provided by the data.MIDINAMES data type. By default, data.MIDINAMES contains General MIDI Instrument designations.

<scoreDef key.sig="1f" meter.count="4" meter.sym="common" meter.unit="4" ppq="48">
   <staffGrp>
      <staffDef clef.line="2" clef.shape="G" lines="5" n="1" xml:id="midi.P5">
         <instrDef midi.instrname="Violin"></instrDef>
      </staffDef>
      <staffDef clef.line="2" clef.shape="G" lines="5" n="2" xml:id="midi.P6">
         <instrDef midi.instrname="Violin"></instrDef>
      </staffDef>
      <staffDef clef.line="3" clef.shape="C" lines="5" n="3" xml:id="midi.P7">
         <instrDef midi.instrname="Viola"></instrDef>
      </staffDef>
      <staffDef clef.line="4" clef.shape="F" lines="5" n="3" xml:id="midi.P8">
         <instrDef midi.instrname="Cello"></instrDef>
      </staffDef>
   </staffGrp>
</scoreDef>

The @midi.instrnum is provided for those cases when an instrument number is needed. It must contain valid MIDI values; that is, 0-127. In these cases, a General MIDI Instrument name is redundant.

<scoreDef key.sig="1f" meter.count="4" meter.sym="common" meter.unit="4" ppq="48">
   <staffGrp>
      <staffDef clef.line="2" clef.shape="G" lines="5" n="1" xml:id="midi.P5">
         <instrDef midi.instrnum="41"></instrDef>
      </staffDef>
      <staffDef clef.line="2" clef.shape="G" lines="5" n="2" xml:id="midi.P6">
         <instrDef midi.instrnum="41"></instrDef>
      </staffDef>
      <staffDef clef.line="3" clef.shape="C" lines="5" n="3" xml:id="midi.P7">
         <instrDef midi.instrnum="42"></instrDef>
      </staffDef>
      <staffDef clef.line="4" clef.shape="F" lines="5" n="3" xml:id="midi.P8">
         <instrDef midi.instrnum="43"></instrDef>
      </staffDef>
   </staffGrp>
</scoreDef>

16.3. Recording MIDI Event Data

MIDI messages are encapsulated in the midi element, which is typically used in contexts like layer and measure. In earlier versions of MEI, the noteOn and noteOff elements were used to record MIDI note on/off events. The use of these elements is now discouraged in favor of using the note element directly. MIDI duration should be recorded using the @dur.ges attribute, and MIDI pitch information should be recorded using the @pnum attribute.

MIDI control changes ( cc) are encoded using the @num and @val attributes. Control change numbers are specified in the General MIDI documentation. In the example below, the cc elements encode increasing controller event 7 (volume) values, or in musical terms, a crescendo. Other MIDI event messages follow this same pattern, using the @num and @val attributes to record the raw MIDI data.

<measure>
   <staff>
      <layer>
         <note dur.ges="8" pnum="45"></note>
         <note dur.ges="8" pnum="42"></note>
         <note dur.ges="8" pnum="43"></note>
         <note dur.ges="8" pnum="44"></note>
      </layer>
   </staff>
   <midi layer="1" staff="1">
      <cc num="7" tstamp=".5" val="50"></cc>
      <cc num="7" tstamp="1.5" val="55"></cc>
      <cc num="7" tstamp="2" val="60"></cc>
      <cc num="7" tstamp="2.5" val="65"></cc>
   </midi>
</measure>

In the preceding example, each control change is associated with a time stamp. The @tstamp attribute is required in order to indicate when the MIDI event should take place. It is often necessary to indicate a time stamp slightly earlier than the affected notes to compensate for MIDI delay.

For better legibility and error checking, the midi element may be used, as in the following example, to group MIDI parameter changes. Even so, the @tstamp attribute is required on all parameters in order to associate them with their point of actuation:

<midi layer="1" staff="1">
   <cc num="7" tstamp=".5" val="50"></cc>
   <cc num="64" tstamp=".5" val="64"></cc>
</midi>

16.4. MIDI in Mensural and Neume Notation

In mensural, neume, and other historical or non-Western repertoires, there is often no measure-based time stamp with which to associate MIDI controller data. Therefore, in these notations MIDI controller data is assumed to be associated with the event that immediately follows in the same layer. Thus, a crescendo in mensural notation may be encoded like so:

<staff>
   <layer>
      <midi>
         <cc num="7" val="50"></cc>
      </midi>
      <note dur="fusa" dur.ges="8p" pnum="42"></note>
      <midi>
         <cc num="7" val="55"></cc>
      </midi>
      <note dur="fusa" dur.ges="8p" pnum="43"></note>
      <midi>
         <cc num="7" val="60"></cc>
      </midi>
      <note dur="fusa" dur.ges="8p" pnum="44"></note>
      <midi>
         <cc num="7" val="65"></cc>
      </midi>
      <note dur="fusa" dur.ges="8p" pnum="45"></note>
   </layer>
</staff>