MID Format
Format type | Music |
---|---|
Notation type | MIDI |
Instruments | MIDI |
Max channel count | 16 |
Max track count | 65535 |
Max pattern count | 1 |
Max order count | 0 |
Tags? | Text events |
Games |
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.
File format
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.)
MThd Header
The file begins with a header:
Data type | Name | Description |
---|---|---|
BYTE[4] | 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.
MTrk block
The MTrk block is repeated once for each track in the song (the iNumTracks field in the MThd header.)
Data type | Name | Description |
---|---|---|
BYTE[4] | cSignature | "MTrk" (not NULL-terminated) |
UINT32BE | iLength | Length of block |
BYTE[iLength] | cData | MIDI data |
MIDI data
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
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) << 7) | (0x50 & 0x7F)
Here is some C code to read these values:
const char *midi_data = "\x81\x50";
unsigned long val = 0;
for (int i = 0; i < 4; i++) {
// Include the lower 7-bits of this byte into the value
val |= midi_data[i] & 0x7F;
// If the high bit is set, shift the value up
// seven bits to make room for the next value
if (midi_data[i] & 0x80) val <<= 7;
else break; // High bit unset means end of value
}
printf("Value is %lu\n", val);
Generally variable-length integers are defined to be unsigned numbers. However, some MIDI files in the wild assume that delays are measured as signed 32-bit integers, which is used to shift some MIDI events at the start of the file into the negative range. For this reason, if the first delay value on a channel is 2,147,483,648 or greater, it should be treated as a signed number instead.
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.
MIDI events
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 |
---|---|---|---|
0x80 | 0 | 2 | Note off |
0x90 | 1 | 2 | Note on |
0xA0 | 2 | 2 | Polyphonic key pressure |
0xB0 | 3 | 2 | Controller |
0xC0 | 4 | 1 | Instrument change |
0xD0 | 5 | 1 | Channel pressure |
0xE0 | 6 | 2 | Pitch bend |
0xF0 | 7 | Any | Sysex |
0xFF | N/A | Any | Meta-event |
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.
Running-status
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)
This means:
- 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.
Data bytes | Purpose |
---|---|
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.)
Data bytes | Purpose |
---|---|
UINT8 iNote | MIDI note number to key-on (0-127) |
UINT8 iVelocity | How hard to press the note (0-127) |
0xA0: Polyphonic key pressure
Data bytes | Purpose |
---|---|
UINT8 iPressure | Pressure value (0-127) |
UINT8 iNote | MIDI note number to affect (0-127) |
Like channel pressure, but applies to individual notes on the channel.
0xB0: Controller
Set a MIDI controller to the specified value. TODO: List of standard controllers
Data bytes | Purpose |
---|---|
UINT8 iController | Controller index (0-127) |
UINT8 iValue | Value to set (0-127) |
0xC0: Instrument change
Set the channel to the specified instrument.
Data bytes | Purpose |
---|---|
UINT8 iInstrument | Instrument number (0-127) |
0xD0: Channel pressure
Data bytes | Purpose |
---|---|
UINT8 iPressure | Pressure value (0-127) |
Also known as "channel aftertouch", it is designed for instruments that can have their volume/intensity changed after the initial velocity set in the note-on event, such as woodwind instruments where a note can start softly and then become louder. The exact meaning is implementation-defined. For example, this event may set the volume of the notes currently playing on the channel in a similar way as velocity in a note-on event, but other possibilites include applying a filter change or vibrato to the notes.
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.
Data bytes | Purpose |
---|---|
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:
Data bytes | Purpose |
---|---|
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:
Event type | Purpose |
---|---|
0xF0 | Start system exclusive event |
0xF1 | MIDI time code |
0xF2 | Song position pointer |
0xF3 | Song select |
0xF4 | (Unused) |
0xF5 | (Unused) |
0xF6 | Tune request |
0xF7 | End system exclusive event (EOX) |
0xF8 | Timing clock |
0xF9 | (Unused) |
0xFA | Start playback |
0xFB | Continue playback |
0xFC | Stop playback |
0xFD | (Unused) |
0xFE | Active sensing |
0xFF | System reset (used for meta-event in a MIDI file) |
Meta events
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.
Data bytes | Purpose |
---|---|
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. |
0x02 | Copyright notice |
0x03 | Track name. Often the first event (format-0) or the first track (format-1) is the song title. |
0x04 | Instrument name |
0x05 | Lyric |
0x06 | Marker |
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.
0x7F: Manufacturer-specific
The first data byte of this event is a manufacturer ID. If it is 0x00, then the following UINT16BE is the actual manufacturer ID. This means either one or three bytes total will be read to obtain the manufacturer ID.
If the manufacturer ID is 0x3F then it is an Ad Lib, Inc. event, and the file format is technically .mdi (an Ad Lib MIDI file with embedded OPL instruments), see MDI Format for details.
Additional meta-events
Other meta-events (not so important for playing back game music) are listed on various web sites:
Extensions
Some extensions to the format are in use, which work by defining custom controllers, meta events, and so on - but otherwise leave the format unchanged and the files are still readable/playable by normal programs.
- Apogee Expanded MIDI defines MIDI controllers for muting tracks depending on the sound card in use as well as for looping parts of tracks, co-designed by Lee Jackson.
- MDI files provide a method for storing OPL register settings for instruments. In this respect the format is functionally equivalent to CMF, but where CMF uses a custom wrapper around the MIDI data, MDI is entirely standard MIDI.
Tools
- DRO2MIDI - converts .dro files into .mid files
Similar formats
- 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.
External links
- https://web.archive.org/web/20070104033706/http://www.cybermuff.cz/music/MIDIspec.htm - great reference for the MIDI spec