MIDI Message Format Reference
I put together this article as a somewhat more comprehensive overview / manual of MIDI 1.0 messaging than the Summary of MIDI messages for my own reference. Hopefully it’s of use to others as well.
Adapted from Summary of MIDI Messages and further reference tables.
See Glossary And Formatting at the bottom of this article to help understand this article.
MIDI comes in the form of messages of one or more bytes. The first byte of a message is called the Status message. Its Most Significant Bit (MSB) is always 1. Any additional data bytes that follow have a MSB of 0, and thus have 7 bits worth of space for 128 possible values.
Different types of message come with a different number of follow-up data bytes.
Common values
Channel
In many messages, the MIDI channel is encoded in the 4 least significant bits of the status byte. This corresponds to MIDI Channel 0
- 15
and is denoted with nnnn
in place of the bits.
Some examples:
- channel
0
=0b0000
- channel
4
=0b0100
- channel
15
=0b1111
.
Key / note
Presented in a data byte, this is a 0
- 127
number indicating which musical note is relevant to the message.
Some keys for reference:
- Key
0
(0b00000000
) is C at Octave -1 - Key
60
(0b00111100
) is middle C (C 3) - Key
69
(0b01000101
) is A 4, typically at 440 Hz concert pitch - Key
127
(0b01111111
) is G 8.
Channel Voice Messages
Status | Data byte(s) | Description |
---|---|---|
0b1000nnnn |
Key:0b0kkkkkkk velocity: 0b0vvvvvvv |
Note off |
0b1001nnnn |
Key:0b0kkkkkkk velocity: 0b0vvvvvvv |
Note on |
0b1010nnnn |
Key:0b0kkkkkkk pressure: 0b0ppppppp |
Polyphonic key pressure (poly aftertouch) |
0b1011nnnn |
Control:0b0ccccccc value 0b0vvvvvvv |
Control change. Controls 120 -127 reserved forChannel Mode Messages. |
0b1100nnnn |
Program:0b0ppppppp |
Program change: load patch by number |
0b1101nnnn |
Pressure:0b0ppppppp |
Channel-wide pressure (mono aftertouch) |
0b1110nnnn |
LSBs:0b0lllllll MSBs: 0b0mmmmmmm |
Pitch bend, 14 bit. (0 - 16384 ). Center: 8192 |
Control change
Control changes set the value of various parameters. A list of controls is available on midi.org: MIDI 1.0 Control Change Messages (Data Bytes)
Fine Adjustment
Normally, in a single MIDI message, you get 7 bit precision for any control change value. However, by sending an additional message with the control number + 32
, and the receiver supports it, you can set the 7 LSBs of the control’s value. This enables 14 bit precision for any control, for a total of 16384
distinct values per control—up from 128
. The drawback is that you have to send more messages, which can lead to delays caused by congestion.
For example, let’s set channel 0
’s “volume” to the value 1337
(0b00 0001010 0111001
):
Byte | Description |
---|---|
0b10110000 |
Control change for channel 0 status byte |
0b00000111 |
Control: Channel volume (coarse) |
0b00001010 |
7 MSBs of value |
- | |
0b10110000 |
Control change for channel 0 status byte |
0b00100111 |
Control: LSB of Channel volume (fine) |
0b00111001 |
7 LSBs of value |
NRPN: Non-Registered Parameter Number
You can control parameters that aren’t in the MIDI specification with control change messages as well. NRPN adjustments take 3 or 4 control change messages:
- NRPN Most significant bits part of identifying the parameter
- NRPN Least significant bits part of identifying the parameter
- Course parameter value (MSBs)
- (optional) Fine parameter value (LSBs)
The 4th message is only required if we want to set the value of this parameter with 14 bit precision, much like in Fine Adjustment.
As an example, let’s set channel 0
’s non-registered parameter numbered 0x0DEA
(0b00 0011011 1101010
), to the value 0x0BEE
(0b00 0010111 1101110
):
Byte | Description |
---|---|
0b10110000 |
Control change for channel 0 status byte |
0b01100011 |
Control: Non-registered param number MSB |
0b00011011 |
7 MSB of NRP number |
- | |
0b10110000 |
Control change for channel 0 status byte |
0b01100010 |
Control: Non-registered param number LSB |
0b01101010 |
7 LSB of NRP number |
- | |
0b10110000 |
Control change for channel 0 status byte |
0b00000110 |
Control: Data Entry MSB |
0b00010111 |
7 MSB of NRP value |
- | |
0b10110000 |
Control change for channel 0 status byte |
0b00100110 |
Control: Data Entry LSB |
0b01101110 |
7 LSB of NRP value |
Channel Mode Messages
Channel mode message are a subset of message that use the “Control change” status byte format, 0b1011nnn
. They comprise control numbers 120
- 127
inclusive.
Control | Value | Description |
---|---|---|
0b01111000 (120) |
0b00000000 |
All sound off. |
0b01111001 (121) |
0b0vvvvvvv |
Reset all controllers. Value should typically be 0 . |
0b01111010 (122) |
0b00000000 |
Local control off. |
0b01111010 (122) |
0b01111111 |
Local control on. |
0b01111011 (123) |
0b00000000 |
All Notes off. Remaining channel mode messages also cause all notes off. |
0b01111100 (124) |
0b00000000 |
Omni Mode Off |
0b01111101 (125) |
0b00000000 |
Omni Mode On (respond to all channels) |
0b01111110 (126) |
0b0MMMMMMM |
Mono Mode On (Poly off), M > 0 : Omni off, M == 0 : Omni On |
0b01111111 (127) |
0b00000000 |
Poly Mode On (Mono off) |
System Common Messages
Status | Data | Description |
---|---|---|
0b11110000 |
Mfr ID0b0iiiiiii [ 0b0iiiiiiii 0b0iiiiiii ]Data 0b0ddddddd […] SysEx end 0b11110111 |
System exclusive |
0b11110001 |
0bnnndddd |
Midi Time Code Quarter frame for synchronising other gear like video decks |
0b11110010 |
LSBs 0b0lllllll MSBs 0b0mmmmmmm |
Song position pointer in # of MIDI beats (16th notes) since start of song. |
0b11110011 |
Song # 0b0sssssss |
Song select |
0b11110100 |
(none) | Undefined (reserved) |
0b11110101 |
(none) | Undefined (reserved) |
0b11110110 |
(none) | Tune request |
0b11110111 |
(none) | End of SysEx data stream marker |
System Exclusive
A system exclusive dump allows sending arbitrary data to devices, so they can implement custom messages for data dumps and any other functionality. It also allows for extending the MIDI spec with further messages.
A System exclusive dump starts with 0b1111000
, and is followed by 1 or 3 bytes to identify the manufacturer this SysEx dump targets.
If the first byte of these identifier bytes is 0b00000000
, the ID will be 3 bytes long, otherwise it is only one byte long.
MIDI.org publishes a list of manufacturer IDs: Manufacturer SysEx ID numbers.
During a SysEx dump, Real-Time messages may appear throughout without affecting it, as they can be clearly differentiated from SysEx data bytes.
Universal SysEx
Despite being under “system exclusive”, there are some messages that are universal, and are denoted by specific 1-byte Manufacturer identifiers.
They come as non-realtime messages with Mfr id 0b01111110
(0x7E
), and realtime messages with Mfr id 0b01111111
(0x7F
).
The Manufacturer (Mfr) ID is followed by 1 or 2 further specified data bytes + any further data + the SysEx end byte.
A list of all of these can be found at midi.org’s MIDI 1.0 Universal Exclusive Messages.
System Real-Time Messages
Each of these messages is one byte long so they stand on their own. They may appear while a System Exclusive message is ongoing.
Byte | Description |
---|---|
0b11111000 |
Timing clock, sent 24 times per quarter note (24PPQ) |
ob11111000 |
Undefined (reserved) |
0b11111010 |
Start. Start sequence from beginning, synchronised by timing clocks. |
0b11111011 |
Continue. Resume sequence at the point where it was stopped. |
0b11111100 |
Stop. Stop the sequence, keep position. |
0b11111101 |
Undefined (reserved) |
0b11111110 |
Active sensing |
0b11111111 |
Reset, set everything to power-up status |
Active sensing
Active sensing can be used to actively check whether a connection between transmitter and receiver is still intact. It is done by sending 0b11111110
at an interval of at most 300 milliseconds. If the interval lapses without such a message, the receiver shuts off all voices and returns to normal operation where it no longer expects active sensing messages.
Use of this message is entirely optional.
Glossary And Formatting
This is a list of terms used in the above article and what they mean.
-
MSB / MSBs Most significant bit(s). In a binary number, the leftmost bits of the number. In an 8-bit number, the most significant bit represents the decimal number 128.
-
LSB / LSBs Least significant bit(s). In a binary number, the rightmost bit(s) of the number. In an 8-bit number, the least significant bit represents the decimal number 1.
-
Message A series of sequential bytes that convey a piece of information or action. Will always contain at least a single byte.
Numbers are formatted as follows:
- Binary
0b
signifies that the digits that follow are in binary. The digits that follow that can be either0
or1
. Spaces may be used to help readability depending on context. Bits may be replaced by a repeating letter to indicate that these digits presents some value that can change, depending on context. Example:0b1000nnnn
represents a byte of which the 4 MSBs are constant, and the 4 LSBs are filled in by some parameter like the channel number. - Hexadecimal
0x
signifies that the digits that follow are in hexadecimal. - Decimal Decimal number have no special prefix; if neither of the preceding prefixes is present, a number is in decimal.