Files & Sounds
Standard MIDI Files
Spec: Standard MIDI Files 1.0
A .mid file is a sequence of chunks. Its tracks hold MIDI messages, each stamped with a delta time,
plus meta events for tempo, meter, names and markers. The format is compact, big-endian, and simple to parse.
Chunks
Every chunk has the same 8-byte preamble:
type 4 ASCII bytes "MThd" or "MTrk"
length 32-bit big-endian byte count of the data that follows
data length bytes
A file is one MThd header chunk followed by one or more MTrk track chunks. Readers must
skip chunk types they do not recognize by using the length. That rule is how the format stays extensible.
Header chunk: MThd
4D 54 68 64 00 00 00 06 ffff nnnn dddd
"MThd" length 6 format ntrks division
| Field | Size | Meaning |
|---|---|---|
| format | 16 bits | 0: a single multi-channel track. 1: one or more simultaneous tracks; by convention, track 1 holds the tempo map. 2: one or more independent single-track patterns (rare). |
| ntrks | 16 bits | Number of track chunks. Always 1 for format 0. |
| division | 16 bits | See below. |
Header length is 6 today, but a reader should honor a larger length and skip the extra bytes.
Division
| Bit 15 | Bits 14–8 | Bits 7–0 | Meaning |
|---|---|---|---|
0 | ticks per quarter note (15 bits) | Musical time (PPQ). Most files. Tempo comes from Set Tempo events. | |
1 | negative SMPTE format: −24, −25, −29, −30 | ticks per frame | Absolute time. −29 means 29.97 fps drop-frame. E.g. E7 28 = 25 fps × 40 = 1 ms ticks. |
See Timing & Sync for converting ticks to seconds.
Track chunks: MTrk
A track is a stream of events, each prefixed by a delta time:
<MTrk event> = <delta-time> <event>
<event> = <MIDI event> | <sysex event> | <meta event>
The delta time is the number of ticks since the previous event in the same track (or since the start of the track), encoded as a variable-length quantity. Simultaneous events have a delta of 0.
- MIDI events are ordinary channel messages. System Real-Time and System Common messages are not stored as MIDI events. Use SysEx escapes if you really need them.
-
Running status is allowed and common: if an event starts with a data byte (<
80), reuse the previous channel status. Meta and SysEx events cancel running status. - Every track must end with an End of Track meta event,
FF 2F 00.
Variable-length quantities
Delta times and some lengths use a VLQ: the number is split into 7-bit groups, most significant
first. Every byte except the last has bit 7 set. The largest allowed value is 0FFFFFFF, so a VLQ is at
most 4 bytes.
decode: value = 0
repeat: b = next byte; value = (value << 7) | (b & 0x7F)
until (b & 0x80) == 0
| Value (hex) | VLQ bytes |
|---|---|
00000000 |
00 |
00000040 |
40 |
0000007F |
7F |
00000080 |
81 00 |
00002000 |
C0 00 |
00003FFF |
FF 7F |
00004000 |
81 80 00 |
00100000 |
C0 80 00 |
001FFFFF |
FF FF 7F |
00200000 |
81 80 80 00 |
08000000 |
C0 80 80 00 |
0FFFFFFF |
FF FF FF 7F |
SysEx events
Files frame SysEx with a VLQ length instead of relying on the trailing F7:
| Form | Meaning |
|---|---|
F0 len bytes |
A SysEx message. bytes is everything after the F0, including the final
F7 if the message is complete. If the F7 is missing, more packets follow.
|
F7 len bytes |
An "escape": bytes are sent to the output as-is. Used for continuation packets of a split
SysEx (with their own timing), or for arbitrary bytes like System Real-Time or Song Position messages.
|
Example: GM System On stored in a file is 00 F0 05 7E 7F 09 01 F7 (delta 0, F0, length 5, then 5
bytes).
Meta events
Meta events hold non-MIDI information: FF type len
data, where len is a VLQ. They are never sent to a MIDI port. (On the wire,
FF means System Reset.) Readers must skip unknown meta types by length.
| Type | Length | Name | Data |
|---|---|---|---|
| FF 00 | 02 |
Sequence Number | ssss: 16-bit sequence number. At the start of a track, before any nonzero delta. |
| FF 01 | len |
Text | Any text. Annotations, comments. |
| FF 02 | len |
Copyright Notice | Should be the first event in the first track. |
| FF 03 | len |
Sequence / Track Name | In track 1 of format 1 (or the only track of format 0): the sequence name. Elsewhere: the track name. |
| FF 04 | len |
Instrument Name | Describes the instrumentation for the track. |
| FF 05 | len |
Lyric | A syllable or lyric, usually one per note. |
| FF 06 | len |
Marker | Rehearsal letters, section names ("Verse", "Chorus"). |
| FF 07 | len |
Cue Point | Something happening on stage or film at this point. |
| FF 08 | len |
Program Name | Name of the patch used by the following program changes (RP-019). |
| FF 09 | len |
Device Name | Name of the device/port this track is meant for (RP-019). |
| FF 20 | 01 |
MIDI Channel Prefix | cc: following meta/sysex events in this track relate to channel cc (0–15). |
| FF 21 | 01 |
MIDI Port | pp: output port number. Widely used but never formally adopted; prefer Device Name. |
| FF 2F | 00 |
End of Track | Required. Must be the last event in every track. |
| FF 51 | 03 |
Set Tempo | tt tt tt: microseconds per quarter note, 24-bit big-endian. |
| FF 54 | 05 |
SMPTE Offset | hr mn se fr ff: SMPTE time at which the track starts. hr includes the frame-rate bits as in MTC. |
| FF 58 | 04 |
Time Signature | nn dd cc bb: see below. |
| FF 59 | 02 |
Key Signature | sf mi: sf = −7…+7 flats/sharps (signed byte), mi = 0 major, 1 minor. |
| FF 7F | len |
Sequencer-Specific | Manufacturer ID first, then proprietary data. Equivalent of SysEx for files. |
Text events (01–0F) have no defined encoding. Old files are often Latin-1 or Shift-JIS.
Newer files tend to be UTF-8, and RP-026 lets a file declare its encoding.
Time signature: FF 58 04 nn dd cc bb
nn: numerator.dd: denominator as a power of two (2 = quarter, 3 = eighth). 6/8 is06 03.cc: MIDI clocks per metronome click (24 = every quarter note; 36 = every dotted quarter).bb: number of notated 32nd notes per MIDI quarter note (normally 8).
4/4 with a click every quarter: FF 58 04 04 02 18 08.
Set tempo: FF 51 03 tt tt tt
Microseconds per quarter note. 07 A1 20 = 500,000 µs = 120 BPM. In format 1, tempo events belong in
the first track. Default when absent: 120 BPM.
A complete file, byte by byte
The smallest useful file: format 0, 96 PPQ, one quarter-note middle C at 120 BPM. 52 bytes in total: a 14-byte header chunk and a track chunk with 8 bytes of preamble and 30 bytes of events.
| Bytes | Meaning |
|---|---|
4D 54 68 64 |
"MThd" chunk ID |
00 00 00 06 |
Header length: 6 |
00 00 |
Format 0 |
00 01 |
1 track |
00 60 |
Division: 96 ticks per quarter note |
4D 54 72 6B |
"MTrk" chunk ID |
00 00 00 1E |
Track length: 30 bytes |
00 FF 51 03 07 A1 20 |
Δ0 · Set Tempo 500,000 µs/qn (120 BPM) |
00 FF 58 04 04 02 18 08 |
Δ0 · Time Signature 4/4, 24 clocks/click, 8 32nds/qn |
00 C0 00 |
Δ0 · Program Change, channel 1, program 0 (Acoustic Grand Piano) |
00 90 3C 64 |
Δ0 · Note On, channel 1, note 60 (C4), velocity 100 |
60 80 3C 40 |
Δ96 · Note Off, channel 1, note 60, velocity 64 (one quarter note later) |
00 FF 2F 00 |
Δ0 · End of Track |
The Note Off could also be written 60 3C 00 with running status, reusing the
90 status: a Note On with velocity 0 means Note Off. That makes the track 29 bytes and its length
00 00 00 1D.
Parsing pitfalls
- Trust chunk lengths, but guard against files whose last track is truncated or whose length is wrong.
- Handle running status, and remember Note On with velocity 0 is a Note Off.
- Pair overlapping Note On / Note Off events for the same key and channel by first-in, first-out.
- Tempo changes in format 1 apply to all tracks. Build one merged tempo map before converting ticks to seconds.
- RIFF-wrapped files (
.rmi) contain a normal SMF inside aRIFF/RMIDdatachunk.
Spotted an error? Edit this page on GitHub.