MIDI 1.0

Messages

Spec: MIDI 1.0 Core Specifications All specs

A MIDI 1.0 stream is a sequence of 8-bit bytes. Each message is one status byte followed by zero, one, or two data bytes. System Exclusive is the one exception: it can carry any number of data bytes.

Message decoder

MIDI 1.0 byte stream

Paste or type bytes, e.g. B0 07 64 or 0x90,0x3C,0x64. Running status and interleaved real-time bytes are handled like a real receiver.

Status bytes and data bytes

The most significant bit tells the two kinds of byte apart. Status bytes have the top bit set (0x80–0xFF). Data bytes have it clear (0x00–0x7F), so every data value is 7 bits wide: 0–127.

ByteBitsRangeMeaning
status 1sss nnnn 0x80–0xFF For channel messages, the high nibble sss is the message type and the low nibble nnnn is the channel.
data 0vvv vvvv 0x00–0x7F Parameter values such as note number, velocity, controller number, or controller value.

Because the two ranges never overlap, a receiver can always resynchronize: whenever it sees a byte with the high bit set, a new message starts.

Channels

Channel messages carry the channel in the low nibble of the status byte. People count channels 1–16, but the nibble holds 0–15. 90 is Note On on channel 1 and 9F is Note On on channel 16. In tables on this site, n stands for that channel nibble.

Channel voice messages

StatusMessageData 1Data 2Length
8n Note Off kk note number vv release velocity 3
9n Note On kk note number vv velocity (0 = Note Off) 3
An Polyphonic Key Pressure (poly aftertouch) kk note number vv pressure 3
Bn Control Change cc controller number (0–119) vv value 3
Cn Program Change pp program number none 2
Dn Channel Pressure (channel aftertouch) vv pressure none 2
En Pitch Bend Change ll LSB (bits 0–6) mm MSB (bits 7–13) 3

Note On with velocity 0

A Note On with velocity 0 means exactly the same as a Note Off with velocity 64. Many devices send 9n kk 00 in place of a real Note Off so they can stay in running status (see below). Receivers must treat both forms as note-off.

Pitch bend

Pitch bend is a 14-bit value, sent LSB first: value = (MSB << 7) | LSB. It runs from 0 to 16383, and 8192 (0x2000, sent as 00 40) means no bend. How far the extremes bend is set by the receiver, normally ±2 semitones. The pitch bend sensitivity RPN changes that range. See Notes & Pitch for the math.

Program change numbering

Program Change data runs from 0 to 127 on the wire. Synth front panels and the General MIDI list usually show it as 1–128. To reach more than 128 sounds, send a Bank Select (CC 0 and CC 32) first, then the Program Change.

Channel mode messages

Controller numbers 120–127 do not control sound parameters. They are reserved for channel mode messages, sent as Bn 78–7F: All Sound Off, Reset All Controllers, Local Control, All Notes Off, and the Omni and Mono/Poly mode switches. The full list is on the Control Change page.

System common messages

System messages have no channel. They apply to the whole device or the whole MIDI cable.

StatusMessageDataLength
F0 System Exclusive start Manufacturer ID, then any number of data bytes, ended by F7 var.
F1 MIDI Time Code Quarter Frame 0nnn dddd: piece number nnn, value nibble dddd 2
F2 Song Position Pointer ll mm: 14-bit count of MIDI beats (1 beat = 6 clocks = a 16th note) 3
F3 Song Select ss song number 0–127 2
F4 Undefined (reserved) none n/a
F5 Undefined (reserved) none. Some vendors use it unofficially as a port/cable select. n/a
F6 Tune Request none. Asks analog synths to retune their oscillators. 1
F7 End of Exclusive (EOX) none. Ends a SysEx message. 1

SysEx has its own page: System Exclusive. Time code and song position are covered in Timing & Sync.

System real-time messages

Real-time messages are single status bytes with no data. They carry timing, so they have top priority. They may be sent at any point in the stream, even between the bytes of another message and inside a SysEx dump. A receiver should act on a real-time byte immediately and then carry on parsing the surrounding message as though the real-time byte had not been there.

StatusMessageNotes
F8Timing ClockSent 24 times per quarter note while the clock is running.
F9Undefined (reserved)Once proposed as a 10 ms "Tick". Not part of the standard.
FAStartStart playback from the beginning of the song (position 0).
FBContinueResume from the current song position.
FCStopStop playback and keep the current position.
FDUndefined (reserved)none
FE Active Sensing Optional keep-alive. A sender that uses it transmits at least every 300 ms. When a receiver has seen it once and then hears nothing for more than 300 ms, it should turn off all voices and go back to normal operation.
FF System Reset Reset the receiver to its power-up state. Use it sparingly and never send it automatically at power-up, or two devices can reset each other in a loop.

Running status

If a channel message has the same status byte as the message before it, the sender may leave the status byte out and send only the data bytes. The receiver remembers the last channel status (the running status) and applies it to any data bytes that arrive without one. On a 5-pin DIN cable this cuts note traffic by up to a third.

  • Only channel messages (0x80–0xEF) set the running status.
  • System common messages and SysEx (0xF0–0xF7) clear it. The sender must send the next channel message with its status byte.
  • Real-time messages (0xF8–0xFF) do not affect running status.
  • Data bytes that arrive while no running status is set should be ignored.

Why devices send Note On, velocity 0

With running status, a stream of Note Ons and Note Offs keeps switching between 9n and 8n, and every switch costs a status byte. Sending note-offs as Note On with velocity 0 means a long run of notes needs only one status byte.

Worked example

The bytes below play a C major triad on channel 1 and then release it. A MIDI clock byte lands in the middle of a message:

90 3C 64 40 64 43 64   F8   3C 00 40 F8 00 43 00
BytesDecoded
90 3C 64 Note On, ch 1, C4 (60), velocity 100. Running status is now 0x90.
40 64Running status: Note On, E4 (64), velocity 100.
43 64Running status: Note On, G4 (67), velocity 100.
F8Timing Clock. Running status is unchanged.
3C 00Note On, C4, velocity 0, which means Note Off.
40 F8 00 A Timing Clock arrives inside the message. Handle it, then finish: Note Off for E4.
43 00Note Off for G4.

Timing on the wire

Classic serial MIDI runs at 31,250 bits per second, 8-N-1: one start bit, eight data bits, no parity, one stop bit. That is 10 bits per byte, so each byte takes 320 µs, a 3-byte message takes about 0.96 ms, and a cable carries at most about 3,125 bytes per second. A ten-note chord therefore takes around 6–10 ms to send in full, which is one reason running status matters. USB and network transports send messages in packets at much higher rates; see Transports.

Parser checklist

  1. On a byte >= 0xF8: handle the real-time message right away and change nothing else.
  2. On 0xF0: start collecting SysEx and clear running status.
  3. On 0xF7, or on any other status byte while collecting SysEx: end the SysEx. A non-EOX status byte also ends a SysEx, after which you process it normally.
  4. On 0xF1–0xF6: clear running status and read the message's fixed number of data bytes.
  5. On 0x80–0xEF: set running status and expect 1 or 2 data bytes.
  6. On a data byte: add it to the current message. Once the message is complete, emit it and stay in running status.