MIDI Messages
Data format:
A MIDI message consists of one status byte, optionally followed by one or two data bytes, except for system-exclusive (sysex) messages, which have an arbitrary number of data bytes.
Status bytes have their most significant bit (MSB) set to differentiate them from data bytes, so status bytes range in value from 128 (0x80) to 255 (0xFF), while data bytes range from 0 to 127 (0x7F).
┌─────────────────┐ │ 1 × × × × × × × │ Status byte (128–255, 0x80-0xFF) ├─────────────────┤ │ 0 d d d d d d d │ Data byte(s) (0–127, 0x00-0x7F) └─────────────────┘
Undefined and unimplemented status:
Undefined status bytes are reserved and should not be used. Any undefined or unimplemented status bytes received should be ignored. Any subsequent data bytes should be ignored until the next legal status byte is received.
MIDI Channel messages
Channel messages contain their channel number in the lower four bits of the status byte. Value 0 corresponds to channel 1. Value 15 (0x0f) is channel 16.
7 6 5 4 3 2 1 0 ┌─────────────────┐ │ 1 t t t c c c c │ Status byte ├─────────────────┤ │ 0 d d d d d d d │ Data byte(s) └─────────────────┘ Byte Bits Symbol Description ────── ───── ────── ──────────────────────────────────────── Status 7 1 Status byte msb is always 1 Status 6–4 t Message type Status 3–0 c Channel number (0–15 -> channels 1–16) Data 7 0 Data byte msb is always 0 Data 6–0 d Value (0–127)
Example with NOTE ON (0x9n), channel 3, note 60 (middle C), velocity 100:
7 6 5 4 3 2 1 0 ┌─────────────────┐ │ 1 0 0 1 0 0 1 0 │ Status 0x92 = type=001 (Note On), channel=0010 (ch. 3) ├─────────────────┤ │ 0 0 1 1 1 1 0 0 │ Data 0x3C = note number 60 ├─────────────────┤ │ 0 1 1 0 0 1 0 0 │ Data 0x64 = velocity 100 └─────────────────┘
List of channel messages:
| Message | Hex | Decimal | Data bytes count |
|---|---|---|---|
| Note off | 8n | 128+n | 2 |
| Note on | 9n | 144+n | 2 |
| Polyphonic key pressure | An | 160+n | 2 |
| Control/Mode change | Bn | 176+n | 2 |
| Program change | Cn | 192+n | 1 |
| Monophonic channel pressure | Dn | 208+n | 1 |
| Pitch bend change | En | 224+n | 2 |
Running status:
Channel messages can have running status. That is, if the next channel status byte is the same as the last, it may be omitted. The receiver assumes that the accompanying data is of the same status as was last sent. Receipt of any other status byte except real-time terminates running status.
Running status is especially convenient for sending strings of note-on and note-off messages, when using “note on with velocity of 0” for note off, and for output of continuous controllers.
MIDI System messages
System messages are not encoded with channel numbers. There are three types of system messages: common, real-time, and exclusive.
7 6 5 4 3 2 1 0 ┌─────────────────┐ │ 1 1 1 1 0 0 0 0 │ System Exclusive (F0) └─────────────────┘ or: ┌─────────────────┐ │ 1 1 1 1 0 m m m │ System Common (F1–F7) └─────────────────┘ or: ┌─────────────────┐ │ 1 1 1 1 1 m m m │ System Real-Time (F8–FF) └─────────────────┘ Bits Symbol Description ───── ────── ────────────────────────────────────────────── 7–4 1 System message prefix (upper hex digit = 0xF) 3 0 System Exclusive or System Common (F0–F7) 3 1 System Real-Time (F8–FF) 2–0 m Message sub-type
System exclusive (SysEx) :
This is the famous SysEx message. It is used to transfer information that may be specific to a given MIDI device. The message must be terminated with an EOX (End of Exclusive) single-byte message. This means that, in theory, a SysEx message can be arbitrarily long.
System exclusive messages begin with the system exclusive status byte (240, or 0xF0), followed by a manufacturer’s ID code. As not to get stuck reading an endless sysex message if the EOX is missing, the MIDI specification states that any status byte (other than real-time) acts to terminate a system exclusive message.
| Message | Hex | Decimal | Data bytes count |
|---|---|---|---|
| System exclusive status | F0 | 240 | variable |
System common :
| Message | Hex | Decimal | Data bytes count |
|---|---|---|---|
| MIDI Time Code (MTC) | F1 | 241 | 1 |
| Song position pointer | F2 | 242 | 2 |
| Song select | F3 | 243 | 1 |
| (Undefined) | F4 | 244 | 0 |
| Cable select* | F5 | 245 | 1 |
| Tune request | F6 | 246 | 0 |
| End of exclusive (EOX) | F7 | 247 | 0 |
System real-time :
Real-time messages may be interspersed in the MIDI data stream, even within a multibyte message, without affecting the current status
| Message | Hex | Decimal | Data bytes count |
|---|---|---|---|
| Timing clock | F8 | 248 | 0 |
| (Undefined) | F9 | 249 | 0 |
| Start | FA | 250 | 0 |
| Continue | FB | 251 | 0 |
| Stop | FC | 252 | 0 |
| (Undefined) | FD | 253 | 0 |
| Active sense | FE | 254 | 0 |
| System reset | FF | 255 | 0 |
Resources
- Official specifications: https://www.midi.org/specifications
- Excellent resource: http://www.somascape.org/midi/tech/spec.html