MIDI Specifications

Back to All Articles
MIDI Specifications and high-level message format.

MIDI data format

A MIDI message consists of one status byte, optionally followed by one or two data bytes, except for system exclusive 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 ($7F).

MIDI Channel messages

Channel messages contain their channel number in the lower four bits of the status byte. The value 0 correspond to the channel 1. Value 15 (0x0f) is channel 16.

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.

Notes:

MessageHexDecimalData bytes count
data00-7F0-127na
System exclusive:
System exclusive statusF0240variable
System common:
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:
Timing clockF82480
(Undefined)F92490
StartFA2500
ContinueFB2510
StopFC2520
(Undefined)FD2530
Active senseFE2540
System resetFF2550

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.

© StudioCode.dev - Made with 11ty and tailwindcss.