The standard MIDI file format is a very strange beast. When viewed as a
whole, it can be quite overwhelming. Of course, no matter how you look at it, describing a piece of music in enough detail to be able to reproduce it
accurately is no small task. So, while complicated, the structure of the midi file format is fairly intuitive when understood. I must insert a disclaimer here that I am by no means an expert with
midi nor midi files. I recently obtained a Gravis UltraSound board for my PC, and upon hearing a few midi files (.MID) thought, "Gee, I'd like to be able to
make my own .MID files." Well, many aggravating hours later, I discovered that this was no trivial task. But, I couldn't let a stupid file format stop me.
(besides, I once told my wife that computers aren't really that hard to use, and I'd hate to be a hypocrite) So if any errors are found in this
information, please let me know and I will fix it. Also, this document's scope does not extend to EVERY type of midi command and EVERY possible file
configuration. It is a basic guide that should enable the reader (with a moderate investment in time) to generate a quality midi file.
Overview
A midi (.MID) file contains basically 2 things, Header chunks and Track chunks. Section 2 explains the header chunks, and Section 3
explains the track chunks. A midi file contains ONE header chunk describing the file format,
etc., and any number of track chunks. A track may be thought of in the same way as a track on a multi-track tape deck. You may assign one track to each
voice, each staff, each instrument or whatever you want.
Header Chunk
The header chunk appears at the beginning of the file, and describes the file in three ways. The header chunk always looks like: 4D 54 68 64 00 00 00 06 ff ff nn nn dd dd
The ascii equivalent of the first 4 bytes is MThd. After MThd comes the 4-byte size of the header. This will always be
00 00 00 06, because the actual header information will always be 6 bytes.
ff ff is the file format. There are 3 formats:
0
-
single-track
1
-
multiple tracks, synchronous
2
-
multiple tracks, asynchronous
Single track is fairly self-explanatory - one track only. Synchronous multiple tracks means that the tracks will all be vertically
synchronous, or in other words, they all start at the same time, and so can represent different parts
in one song. Asynchronous multiple tracks do not necessarily start at the same time, and can be completely asynchronous.
nn nn
is the number of tracks in the midi file.
dd dd
is the number of delta-time ticks per quarter note. (More about this
later)
Track Chunks
The remainder of the file after the header chunk consists of track chunks.
Each track has one header and may contain as many midi commands as you like.
The header for a track is very similar to the one for the file:
4D 54 72 6B xx xx xx xx
As with the header, the first 4 bytes has an ascii equivalent. This one is MTrk. The 4 bytes after MTrk give the length of the track (not including the
track header) in bytes.
Following the header are midi events. These events are identical to the
actual data sent and received by MIDI ports on a synth with one addition. A
midi event is preceded by a delta-time. A delta time is the number of ticks
after which the midi event is to be executed. The number of ticks per quarter
note was defined previously in the file header chunk. This delta-time is a
variable-length encoded value. This format, while confusing, allows large
numbers to use as many bytes as they need, without requiring small numbers to
waste bytes by filling with zeros. The number is converted into 7-bit bytes,
and the most-significant bit of each byte is 1 except for the last byte of the
number, which has a msb of 0. This allows the number to be read one byte at a
time, and when you see a msb of 0, you know that it was the last (least
significant) byte of the number. According to the MIDI spec, the entire delta-time should be at most 4 bytes long.
Following the delta-time is a midi event. Each midi event (except a
running midi event) has a command byte which will always have a msb of 1 (the
value will be >= 128). A list of most of these commands is in appendix A. Each
command has different parameters and lengths, but the data that follows the
command will have a msb of 0 (less than 128). The exception to this is a meta-
event, which may contain data with a msb of 1. However, meta-events require a
length parameter which alleviates confusion.
One subtlety which can cause confusion is running mode. This is where
the actual midi command is omitted, and the last midi command issued is
assumed. This means that the midi event will consist of a delta-time and the
parameters that would go to the command if it were included.
Conclusion
If this explanation has only served to confuse the issue more, the
appendices contain examples which may help clarify the issue. Also, 2
utilities and a graphic file should have been included with this document:
DEC.EXE - This utility converts a binary file (like .MID) to a tab-delimited
text file containing the decimal equivalents of each byte.
REC.EXE - This utility converts a tab-delimited text file of decimal values
into a binary file in which each byte corresponds to one of the decimal
values.
MIDINOTE.PS - This is the postscript form of a page showing note numbers with
a keyboard and with the standard grand staff. Appendix A
MIDI Event Commands
Each command byte has 2 parts. The left nybble (4 bits) contains the actual
command, and the right nybble contains the midi channel number on which the
command will be executed. There are 16 midi channels, and 8 midi commands (the
command nybble must have a msb of 1).
In the following table, x indicates the midi channel number. Note that all
data bytes will be <128 (msb set to 0).
Hex
Binary
Data
Description
8x
1000xxxx
nn vv
Note off (key is released)
nn
note number
vv
velocity
9x
1001xxxx
nn vv
Note on (key is pressed)
nn
note number
vv
velocity
Ax
1010xxxx
nn vv
Key after-touch
nn
note number
vv
velocity
Bx
1011xxxx
cc vv
Control Change
cc
controller number
vv
new value
Cx
1100xxxx
pp
Program (patch) change
pp
new program number
Dx
1101xxxx
cc
Channel after-touch
cc
channel number
Ex
1110xxxx
bb tt
Pitch wheel change (2000H is normal or no change)
bb
bottom (least sig) 7 bits of value
tt
top (most sig) 7 bits of value
The following table lists meta-events which have no midi channel number. They
are of the format: FF xx nn dd
All meta-events start with FF followed by the command (xx), the length, or number of bytes that will contain data (nn), and the actual data
(dd).
Hex
Binary
Data
Description
00
00000000
nn ssss
Sets the track's sequence number.
nn
02 (length of 2-byte sequence number)
ssss
sequence number
01
00000001
nn tt ..
Text event- any text you want.
nn
length in bytes of text
tt
text characters
02
00000010
nn tt ..
Same as text event, but used for copyright info.
nn tt
same as text event
03
00000011
nn tt ..
Sequence or Track name
nn tt
same as text event
04
00000100
nn tt ..
Track instrument name
nn tt
same as text event
05
00000101
nn tt ..
Lyric
nn tt
same as text event
06
00000110
nn tt ..
Marker
nn tt
same as text event
07
00000111
nn tt ..
Cue point
nn tt
same as text event
2F
00101111
00
This event must come at the end of each track
51
01010001
03 tttttt
Set tempo
tttttt
microseconds/quarter note
58
01011000
04 nn dd ccbb
Time Signature
nn
numerator of time sig.
dd
denominator of time sig.
2
quarter
3
eighth
etc
cc
number of ticks in metronome click
bb
number of 32nd notes to the quarter note
59
01011001
02 sf mi
Key signature
sf
sharps/flats
-7
7 flats
0
key of C
7
7 sharps
mi
major/minor
0
major
1
minor
7F
01111111
xx dd ..
Sequencer specific information
xx
number of bytes to be sent
dd
data
The following table lists system messages which control the entire system.
These have no midi channel number. (these will generally only apply to
controlling a midi keyboard, etc.)
Hex
Binary
Data
Description
F8
11111000
Timing clock used when synchronization is
required.
FA
11111010
Start current sequence
FB
11111011
Continue a stopped sequence where left
off
FC
11111100
Stop a sequence
The following table lists the numbers corresponding to notes for use in note on and note off commands.