Skip to content

MIDI Protocol

This page documents the MIDI specifications that Timbre implements: MIDI 1.0 (1983), MPE (2018), and USB-MIDI (1999). Use it as a development reference when writing firmware. For Timbre-specific mappings and design decisions, see the concept pages: MIDI & MPE and On the Wire. For Timbre’s consolidated spec sheet, see MIDI Implementation.

The MIDI 1.0 electrical specification defines a current-loop serial interface at 31,250 baud, 8-N-1 (8 data bits, no parity, 1 stop bit). Each byte on the wire takes 320 microseconds.

Every MIDI byte is either a status byte (bit 7 = 1, range 0x800xFF) or a data byte (bit 7 = 0, range 0x000x7F). This single-bit distinction is the foundation of the entire protocol — a receiver can always determine whether it is looking at a command or a parameter.

Running status allows a sender to omit the status byte when consecutive messages share the same status. The rules:

RuleDetail
Applies toChannel messages only (0x800xEF)
Canceled bySystem Common (0xF00xF7) and System Exclusive
Not affected bySystem Real-Time (0xF80xFF) — these may be interleaved freely
Receiver behaviorStore the last received channel status byte; apply it to subsequent data bytes until a new status arrives

Running status is a bandwidth optimization from the era of 31,250-baud serial links. Over USB it saves nothing meaningful, but receivers must handle it correctly because controllers still use it.

Channel Voice messages carry performance data. The low nibble of the status byte encodes the channel (0–15).

Status ByteBinaryData BytesDescription
0x8n1000nnnn2: note, velocityNote Off — velocity often ignored but part of the spec
0x9n1001nnnn2: note, velocityNote On — velocity 0 = Note Off (running status optimization)
0xAn1010nnnn2: note, pressurePolyphonic Aftertouch — per-key pressure
0xBn1011nnnn2: CC#, valueControl Change — see CC table below
0xCn1100nnnn1: programProgram Change — patch selection
0xDn1101nnnn1: pressureChannel Pressure — single pressure value for the whole channel
0xEn1110nnnn2: LSB, MSBPitch Bend — 14-bit value, center = 8192 (0x2000)
ConstantValueNote
Middle CNote 60MIDI standard (some DAWs display as C3, others C4)
A440Note 69Concert pitch reference
Pitch Bend center8192 (0x00, 0x40)LSB first, then MSB
Velocity range1–1270 = Note Off when sent as Note On

CC messages (0xBn) use the second byte as a controller number (0–127) and the third byte as the value (0–127). The MIDI specification assigns specific functions to most of these numbers.

These 32 controllers support 14-bit resolution when paired with their LSB counterparts (CC 32–63).

CCNameTypical Use
0Bank Select MSBBank switching (paired with Program Change)
1Modulation WheelLFO depth, vibrato
2Breath ControllerWind controller input
4Foot ControllerExpression pedal
5Portamento TimeGlide speed
6Data Entry MSBSets value for selected RPN/NRPN
7Channel VolumeMain volume for the channel
8BalanceStereo balance
10PanStereo position (64 = center)
11ExpressionSub-volume (scales within Volume)
12–15Effect Control 1–4General purpose
16–19General Purpose 1–4Undefined by default
20–31UndefinedAvailable for custom use

Fine adjustment for 14-bit resolution. CC 32 is the LSB of CC 0, CC 33 is the LSB of CC 1, and so on.

CCName
32Bank Select LSB
33Modulation Wheel LSB
38Data Entry LSB
34–63LSBs for CC 2–31

Values 0–63 = off, 64–127 = on.

CCNameNotes
64Sustain PedalThe most common CC after Mod Wheel
65Portamento On/OffEnables glide between notes
66SostenutoSustains only notes held at pedal-down
67Soft PedalReduces volume/brightness
68Legato FootswitchEnables legato mode
69Hold 2Extended sustain variation
CCNameCommon Assignment
70Sound VariationTimbre variation
71Resonance / TimbreFilter Q / resonance
72Release TimeAmplitude envelope release
73Attack TimeAmplitude envelope attack
74Brightness / CutoffFilter cutoff frequency
75Decay TimeAmplitude envelope decay (GM2)
76Vibrato RateLFO rate
77Vibrato DepthLFO depth
78Vibrato DelayLFO onset delay
79Sound Controller 10Undefined

MPE note: In MPE mode, CC 74 is the per-note Slide dimension — the third axis of expression alongside Pitch Bend and Channel Pressure. On Timbre, Slide controls oscillation mode morphing rather than simple filter cutoff. See MIDI & MPE.

CCNameNotes
80–83General Purpose 5–8Undefined by default
84Portamento ControlSource note for portamento
85–90Undefined
91Reverb SendEffects depth 1
92Tremolo DepthEffects depth 2
93Chorus SendEffects depth 3
94Celeste DepthEffects depth 4 (detune)
95Phaser DepthEffects depth 5
CCNameFunction
96Data IncrementBump RPN/NRPN value up by 1
97Data DecrementBump RPN/NRPN value down by 1
98NRPN LSBNon-Registered Parameter Number (LSB)
99NRPN MSBNon-Registered Parameter Number (MSB)
100RPN LSBRegistered Parameter Number (LSB)
101RPN MSBRegistered Parameter Number (MSB)

All 18 controllers in this range are unassigned by the MIDI specification and available for custom use.

These are sent as Control Change messages but function as mode commands.

CCNameFunction
120All Sound OffImmediately silence all voices on this channel
121Reset All ControllersReturn all CCs to default values
122Local Control On/OffConnect/disconnect keyboard from internal sound engine
123All Notes OffRelease all held notes (respects sustain pedal)
124Omni Mode OffRespond only to assigned channel
125Omni Mode OnRespond to all channels
126Mono Mode OnOne voice per channel (+ optional voice count)
127Poly Mode OnNormal polyphonic operation

RPNs provide a standardized way to control parameters that do not fit into the 128-controller CC space. The protocol uses four CC messages in sequence:

  1. CC 101 (RPN MSB) — selects the parameter (MSB)
  2. CC 100 (RPN LSB) — selects the parameter (LSB)
  3. CC 6 (Data Entry MSB) — sets the value (MSB)
  4. CC 38 (Data Entry LSB) — sets the value (LSB, optional for 7-bit parameters)

After setting a parameter, transmit RPN NULL (CC 101 = 127, CC 100 = 127) to deselect and prevent accidental data entry changes from affecting the wrong parameter.

RPN (MSB, LSB)NameData Entry ValueRange
0, 0Pitch Bend SensitivityMSB = semitones, LSB = centsTypically 2 (standard) or 48 (MPE)
0, 1Fine Tuning14-bit, center = 8192±100 cents
0, 2Coarse TuningMSB only, center = 64±64 semitones
0, 3Tuning Program ChangeMSB = program0–127
0, 4Tuning Bank SelectMSB = bank0–127
0, 5Modulation Depth RangeMSB = semitones, LSB = centsMPE-defined
0, 6MPE ConfigurationMSB = member channel countSee MPE section
127, 127RPN NULLDeselects active RPN

System messages are not channel-specific — they apply globally to the MIDI bus.

Byte PositionValueDescription
10xF0Start of Exclusive
2Manufacturer ID1 byte (0x010x7C) or 3 bytes (0x00 + 2 bytes)
3…NDataPayload — all bytes must be 0x000x7F (7-bit)
N+10xF7End of Exclusive

7-bit encoding constraint: Every data byte inside a SysEx message must have bit 7 = 0. To transmit 8-bit binary data (firmware images, patch dumps), it must be packed into 7-bit form — typically by splitting each group of 7 bytes into 8 bytes, with the high bits collected in a prefix byte.

IDPurpose
0x7DDevelopment / non-commercial — free use, no registration required
0x7EUniversal Non-Real Time (MIDI-CI, sample dumps, tuning)
0x7FUniversal Real Time (MTC, notation, device control)

Any MIDI device should respond to a Universal SysEx Identity Request:

Request: F0 7E 7F 06 01 F7 (Universal Non-Real Time, broadcast, General Information, Identity Request)

Reply: F0 7E DD 06 02 MM FF FF DD DD SS SS SS SS F7 (DD = device ID, MM = manufacturer, FF FF = family, DD DD = model, SS SS SS SS = version)

StatusBytesNameDescription
0xF11 dataMTC Quarter FrameSMPTE timecode fragment
0xF22 dataSong Position Pointer14-bit beat count (MIDI beat = 6 clocks)
0xF31 dataSong SelectSelect song/sequence number
0xF4Undefined
0xF5Undefined
0xF60Tune RequestTrigger analog oscillator tuning
0xF70End of ExclusiveTerminates SysEx message

Single-byte messages with no data. May be interleaved anywhere in the byte stream — even between the status byte and data bytes of another message, or within a SysEx transfer. Receivers must handle this.

StatusNameDescription
0xF8Timing Clock24 pulses per quarter note (ppqn)
0xF9Undefined
0xFAStartBegin playback from song position 0
0xFBContinueResume from current song position
0xFCStopHalt playback
0xFDUndefined
0xFEActive SensingHeartbeat — once started, must arrive within 300 ms or receiver assumes disconnect
0xFFSystem ResetReturn device to power-on state

MPE (adopted by the MMA in January 2018) assigns each sounding note to its own MIDI channel, enabling per-note continuous control of multiple expression dimensions simultaneously.

MPE defines up to two zones, each with a Manager Channel and one or more Member Channels:

ZoneManager ChannelMember ChannelsDirection
Lower ZoneChannel 1Channels 2 upwardAscending
Upper ZoneChannel 16Channels 15 downwardDescending

The Manager Channel carries zone-wide controls (sustain pedal, volume, program change). Member Channels carry per-note data (note on/off, pitch bend, pressure, CC 74).

Zone setup is performed via RPN 6 on the Manager Channel. The Data Entry MSB specifies how many Member Channels to allocate. Setting it to 0 deactivates the zone.

Lower Zone — 15 member channels:

B0 65 00 CC#101 = 0 (RPN MSB) on channel 1
B0 64 06 CC#100 = 6 (RPN LSB) on channel 1
B0 06 0F CC#6 = 15 (Data Entry) on channel 1

Upper Zone — 7 member channels:

BF 65 00 CC#101 = 0 (RPN MSB) on channel 16
BF 64 06 CC#100 = 6 (RPN LSB) on channel 16
BF 06 07 CC#6 = 7 (Data Entry) on channel 16

Deactivate Lower Zone:

B0 65 00 CC#101 = 0 (RPN MSB) on channel 1
B0 64 06 CC#100 = 6 (RPN LSB) on channel 1
B0 06 00 CC#6 = 0 (Data Entry) on channel 1

After MCM, the MPE specification sets default pitch bend ranges:

Channel TypeDefault RangeRPN 0 Value
Manager Channel±2 semitones2
Member Channels±48 semitones48

The wide ±48 range on member channels gives expressive controllers (Linnstrument, Seaboard, Continuum) full pitch-slide capability across the playing surface.

DimensionMIDI MessageTypical Controller Gesture
Strike velocityNote On velocityInitial key/pad impact
PitchPitch Bend (per-channel)Horizontal slide on playing surface
PressureChannel Pressure (per-channel)Vertical force after initial strike
SlideCC 74 (per-channel)Vertical position on playing surface
Lift velocityNote Off velocityRelease speed

When the number of sounding notes exceeds available member channels, the MPE specification permits note sharing — multiple notes on the same channel. Per-note expression is degraded for shared notes (they receive the same pitch bend and pressure). Instruments should avoid this by voice-stealing the oldest or quietest note before resorting to channel sharing.

The USB Device Class Definition for MIDI Devices (1999) defines how MIDI travels over USB, built on top of the USB Audio Class.

Every USB-MIDI transaction is composed of 32-bit packets:

BitsFieldDescription
31–28Cable NumberVirtual cable / port index (0–15)
27–24Code Index Number (CIN)Identifies the message type and packet size
23–16MIDI_0First MIDI byte (usually status)
15–8MIDI_1Second MIDI byte (or 0x00 if unused)
7–0MIDI_2Third MIDI byte (or 0x00 if unused)
CINMIDI Bytes UsedMessage Type
0x01, 2, or 3Miscellaneous (reserved)
0x22Two-byte System Common
0x33Three-byte System Common
0x43SysEx starts or continues (3 bytes)
0x51Single-byte System Common or SysEx end
0x62SysEx ends with 2 bytes
0x73SysEx ends with 3 bytes
0x83Note Off
0x93Note On
0xA3Polyphonic Aftertouch
0xB3Control Change
0xC2Program Change
0xD2Channel Pressure
0xE3Pitch Bend
0xF1Single Byte (Real-Time)

The Cable Number field allows a single USB connection to carry up to 16 independent virtual MIDI cables (ports), each with its own 16-channel MIDI stream. Timbre uses a single cable in Phase 1–2, with dual cable (performance + configuration) planned for Phase 3.

Quick-lookup table for firmware development:

ConstantValueHexNotes
A440Note 690x45Concert pitch reference
Middle CNote 600x3C
Pitch Bend center81920x200014-bit, LSB first on wire
Max channel150x0F0-indexed (channels 0–15 = display 1–16)
Baud rate31,250Serial MIDI
Byte time320 usAt 31,250 baud, 10 bits per byte
SysEx Start0xF0
SysEx End0xF7
Velocity range1–1270 = Note Off (in Note On context)
14-bit max16,3830x3FFFPitch bend, 14-bit CCs
7-bit max1270x7FStandard CC/velocity/note range
MIDI Clock ppqn24Pulses per quarter note
Active Sensing timeout300 msAfter first 0xFE received
ResourceURL
MIDI 1.0 — Summary of Messagesmidi.org/summary-of-midi-1-0-messages
MIDI Message Quick Referencemichd.me/jsmidgen/midi-message-reference
MPE Specificationmidi.org/midi-polyphonic-expression-mpe
USB-MIDI Class Definitionusb.org/document-library/usb-midi-devices-10
MIDI 2.0 Specificationmidi.org/midi-2-0