reference

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:

MessageHexDecimalData bytes count
Note off8n128+n2
Note on9n144+n2
Polyphonic key pressureAn160+n2
Control/Mode changeBn176+n2
Program changeCn192+n1
Monophonic channel pressureDn208+n1
Pitch bend changeEn224+n2

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.

MessageHexDecimalData bytes count
System exclusive statusF0240variable

System common :

MessageHexDecimalData bytes count
MIDI Time Code (MTC)F12411
Song position pointerF22422
Song selectF32431
(Undefined)F42440
Cable select*F52451
Tune requestF62460
End of exclusive (EOX)F72470

System real-time :

Real-time messages may be interspersed in the MIDI data stream, even within a multibyte message, without affecting the current status

MessageHexDecimalData bytes count
Timing clockF82480
(Undefined)F92490
StartFA2500
ContinueFB2510
StopFC2520
(Undefined)FD2530
Active senseFE2540
System resetFF2550

Resources