The Musical Instrument Digital Interface (MIDI) file format is used for storing the notes required to accurately reproduce a song. Commercial instruments are available that "speak" the MIDI protocol, and a MIDI file (.mid) simply stores the data sent over the wire, with a few headers on the front.
A MIDI file starts with an overall MThd header, followed by one or more MTrk headers for each "track" (a track is normally created for each instrument, for simplicity when the song is being composed.)
The file begins with a header:
|BYTE||cSignature||"MThd" (not NULL-terminated)|
|UINT32BE||iLength||Length of MThd block (usually 6)|
|UINT16BE||iType||0, 1 or 2 (for format-0, 1 or 2)|
|UINT16BE||iNumTracks||Number of tracks (will be 1 for format-0)|
|UINT16BE||iTicksPerQuarterNote||Number of MIDI delay ticks in a quarter-note|
If the high bit in iTicksPerQuarterNote is set (0x8000) then the file uses SMPTE timing instead, which is rare and not covered here.
The MTrk block is repeated once for each track in the song (the iNumTracks field in the MThd header.)
|BYTE||cSignature||"MTrk" (not NULL-terminated)|
|UINT32BE||iLength||Length of block|
The MIDI data consists of a delay value (in MIDI variable-length integer notation), followed by a MIDI event byte (see #MIDI events below.) The event data follows, and will be different depending on the event. It then starts again with the delay value for the next event.
MIDI lengths are stored as variable length integers, between one and four bytes long. Each byte only uses the lower 7-bits, with the MSB set if there is another length byte following. The bytes are in big endian order. Some examples of these length bytes are:
50 // Hex value 0x50 81 50 // Hex value 0xD0 ((0x81 & 0x7F) >> 1) | (0x50 & 0x7F)
Here is some C code to read these values:
Generally speaking, MIDI data that can be sent over the wire uses these values (e.g. delays), whereas data only used to write .mid files on disk (e.g. MTrk lengths in bytes) use normal big-endian fixed-length values.
This table lists the different MIDI events that can occur in a song. The events are listed as channel zero (e.g. 0x80, which would become 0x85 for channel five.) Removing the high bit (
(byte & 0x7F) >> 4) will give the 'event number'.
|Register value||Event number||Data size||Purpose|
|0xA0||2||2||Polyphonic key pressure|
The data bytes for each event are described in the sections below.
Each event is preceded by a delay (as a MIDILEN variable-length integer, see #MIDI lengths above) which specifies the number of MIDI ticks until the event should be actioned.
To convert the number of MIDI ticks into a usable time value, the iTicksPerQuarterNote field from the header will allow the tick count to be converted into a fractional number of quarter notes, then the song's tempo (in microseconds per quarter note) will allow this fractional number of quarter notes to be converted into microseconds.
The default tempo of 500,000 microseconds per quarter note applies until overridden by a set-tempo event.
Any event values without the high-bit set (i.e. less than 0x80) are so-called "running status" values. If one of these bytes is encountered as a MIDI event, it is actually the first data byte of the event instead. The actual event is the same as the previous one. For example, these two lines are equivalent: (delay bytes omitted for clarity)
90 40 7F 91 44 7F 91 47 7F 81 44 7F (full syntax) 90 40 7F 91 44 7F 47 7F 44 00 (with running status)
- 90 40 7F: Turn note 0x40 on channel 0 at maximum velocity
- 91 44 7F: Then turn note 0x44 on channel 1 at maximum velocity
- 47 7F: Turn note 0x47 on the same channel (running status means use event 0x91 from before)
- 44 00: Turn note 0x44 off on the same channel (running status uses event 0x91 again, and takes advantage of note-on at zero velocity being the same as note-off)
Meta-events do not affect running status, so any event from 0xF0 to 0xFF can appear in the middle of data without affecting the running status. For example the following line is equivalent to the two lines above:
90 40 7F 91 44 7F FF 01 02 AA BB 47 7F F0 02 AA F7 44 00
0x80: Note off
Stops the specified note from sounding on this channel. Does not affect any other notes currently being played on the same channel. A note-on event with a velocity of zero is the same as a note-off event.
|UINT8 iNote||MIDI note number to key-off (0-127)|
|UINT8 iVelocity||How hard to release the note (0-127)|
0x90: Note on
Plays the specified note on the given channel. Multiple notes can be sounding at the same time on the same channel. A velocity of zero is the same as a note-off event (this is often used with running status to minimise the amount of data used.)
|UINT8 iNote||MIDI note number to key-on (0-127)|
|UINT8 iVelocity||How hard to press the note (0-127)|
0xA0: Polyphonic key pressure
|UINT8 iPressure||Pressure value (0-127)|
|UINT8 iNote||MIDI note number to affect (0-127)|
Set a MIDI controller to the specified value. TODO: List of standard controllers
|UINT8 iController||Controller index (0-127)|
|UINT8 iValue||Value to set (0-127)|
0xC0: Instrument change
Set the channel to the specified instrument.
|UINT8 iInstrument||Instrument number (0-127)|
0xD0: Channel pressure
|UINT8 iPressure||Pressure value (0-127)|
0xE0: Pitch bend
Bend all notes on the channel up or down by the specified amount. The value is between 0 and 16384. The value 8192 is in the middle and means no bend, thus 8192 can be subtracted from this the value to create a signed integer between -8192 and +8191, with zero meaning "no bend." The actual pitch resulting from the bend depends on the range, which is set (usually at the start of the song) by a MIDI controller message.
|UINT8 iLSB||Least significant byte (0-127)|
|UINT8 iMSB||Most significant byte (0-127)|
The value is calculated by combining the lower seven bits from each of the two bytes into a single 14-bit value:
value = (iMSB << 7) | iLSB
0xF0: System exclusive
These messages are used to send proprietary commands to various MIDI devices. They are essentially a list of raw bytes to send. The channel is not used, so 0xF0 through 0xFF are different "sysex" messages. Since 0xFF is used as a reset it would have no use in a .mid file on disk, so this event is used for meta-events described below.
The event type (0xF0 to 0xFE) is followed by this structure:
|MIDILEN iLength||Length of data|
|UINT8 cData[iLength]||Block of data, iLength bytes long|
Event 0xFF has a different structure and is covered below. The event types are defined as follows:
|0xF0||Start system exclusive event|
|0xF1||MIDI time code|
|0xF2||Song position pointer|
|0xF7||End system exclusive event (EOX)|
|0xFF||System reset (used for meta-event in a MIDI file)|
Meta events are events specific to MIDI files themselves. They are not transmitted to MIDI devices. A meta event is signalled by the 0xFF system exclusive event. The following table lists the format of the bytes following the 0xFF.
|UINT8 iType||Meta-event type|
|MIDILEN iLength||Length of event data|
|UINT8 cData[iLength]||Event data|
The following section lists the meaning of various values of iType.
0x01 - 0x0F: Text
These events set various types of text. The event data is the text to set.
|Event type||Text use|
|0x01||Generic text event. Often the first text event in a song is used as its title.|
|0x03||Track name. Often the first event (format-0) or the first track (format-1) is the song title.|
|0x07||Cue point (e.g. stage instructions)|
0x2F: End of track
Mandatory event at the end of each MTrk track. The length field is always zero, so there are no bytes of event data.
0x51: Set tempo
This event should always have a length of three. The event data is a big-endian integer (not in MIDI variable-length notation) indicating the number of microseconds in a quarter note. Together with the iTicksPerQuarterNote value from the header, this allows MIDI ticks to be converted into microseconds for correct playback speed of the MIDI file.
Unless overridden by this event, the number of microseconds in a quarter note defaults to 500,000.
Other meta-events (not so important for playing back game music) are listed on various web sites:
- DRO2MIDI - converts .dro files into .mid files
- CMF files store their song data in MIDI format.
- MUS files are single-track MIDI files made by id Software.
- XMI files are Extended MIDI files.
- http://www.cybermuff.cz/music/MIDIspec.htm - great reference for the MIDI spec