Expression & MIDI 2.0

MIDI 2.0 & the Universal MIDI Packet

Spec: MIDI 2.0 overview UMP & MIDI 2.0 Protocol (M2-104-UM)

MIDI 2.0 is not a new cable or a new byte stream. It is a new packet format, the Universal MIDI Packet (UMP), plus a higher-resolution set of messages and ways for devices to discover each other. MIDI 1.0 messages still exist inside UMP, so the two protocols live side by side.

What changes, and why

Limit in MIDI 1.0MIDI 2.0 answer
7-bit velocity and controllers (128 steps). 14-bit pairs are awkward to send.16-bit velocity; 32-bit controllers, pressure and pitch bend
Pitch bend and controllers apply to the whole channelPer-note pitch bend, per-note controllers, per-note management
16 channels per cable16 groups × 16 channels = 256 channels per UMP Endpoint
Bank select, program change and RPN/NRPN take several messages eachSingle atomic messages: Program Change carries its bank, and Registered/Assignable Controllers replace RPN/NRPN
Byte stream with no framing; parsing depends on running statusFixed-size 32-bit-word packets whose size can be read from the first 4 bits
One-way: a sender can't tell what a receiver supportsEndpoint and Function Block discovery (UMP Stream) and MIDI-CI
Timing depends on when bytes arriveJitter Reduction (JR) timestamps

UMP basics

A UMP is made of 1 to 4 32-bit words, so packets are 32, 64, 96 or 128 bits long. The top four bits of the first word are the Message Type (MT), which also sets the packet size. A receiver can always tell how long a packet is, even when it doesn't know the message.

For most message types, the next four bits are the group (0–15). Each group works like a separate MIDI 1.0 cable with its own 16 channels. Utility (0x0) and UMP Stream (0xF) messages have no group; they address the whole Endpoint.

Message types

MTBitsTypeContents
0x0 32 Utility NOOP, JR Clock, JR Timestamp, Delta Clockstamp Ticks Per Quarter Note (DCTPQ), Delta Clockstamp. No group.
0x1 32 System Real Time & System Common MIDI 1.0 F1–FF messages (clock, start/stop, MTC quarter frame, SPP, song select, tune request)
0x2 32 MIDI 1.0 Channel Voice The classic 8n–En messages with 7- and 14-bit values, carried in UMP
0x3 64 Data (SysEx7) MIDI 1.0 System Exclusive, split into packets of up to 6 data bytes
0x4 64 MIDI 2.0 Channel Voice High-resolution and per-note messages of the MIDI 2.0 Protocol
0x5 128 Data 128 System Exclusive 8 (8-bit SysEx) and Mixed Data Set
0x6–0x7 32 Reserved
0x8–0xA 64 Reserved
0xB–0xC 96 Reserved
0xD 128 Flex Data Tempo, time and key signature, metronome, chord names, lyrics and other text
0xE 128 Reserved
0xF 128 UMP Stream Endpoint and Function Block discovery, stream configuration, clip start/end. No group.

Worked example: one Note On, two ways

Middle C (note 60) on channel 1, group 1 (written as 0 in the packet), at full velocity.

MIDI 2.0 Protocol Note On (MT 0x4, 64 bits)

0x40903C00 0xFFFF0000

Word 1
4 MT 4b
0 Group 4b
9 Status 4b
0 Channel 4b
3C Note 8b
00 Attr type 8b
Word 2
FFFF Velocity (16-bit) 16b
0000 Attribute data 16b
  • MT = 4: MIDI 2.0 Channel Voice, so the packet is 64 bits.
  • Group = 0, status = 9 (Note On), channel = 0 (channel 1).
  • Note = 0x3C (60). The note number is still 7 bits; the top bit of that byte is 0.
  • Attribute type = 0 (none). Other defined types are 1 = manufacturer specific, 2 = profile specific, and 3 = pitch 7.9, a fixed-point pitch in semitones for microtonal notes.
  • Velocity = 0xFFFF, the maximum of a 16-bit range.

The same note as MIDI 1.0 in UMP (MT 0x2, 32 bits)

0x20903C64, which is the classic 90 3C 64 (velocity 100) with a one-byte MT and group prefix.

Word 1
2 MT 4b
0 Group 4b
9 Status 4b
0 Channel 4b
3C Note 8b
64 Velocity 8b

MIDI 2.0 Channel Voice messages

Every MT 0x4 message has the same first word: MT | group | status | channel | index/note | .... The status nibble picks the message:

StatusMessageNotes
0x0Registered Per-Note ControllerPer-note controller, 256 defined indexes, 32-bit value
0x1Assignable Per-Note ControllerPer-note controller, 256 free indexes, 32-bit value
0x2Registered ControllerRPN: 128 banks × 128 indexes, 32-bit value, one message (no Data Entry sequence)
0x3Assignable ControllerNRPN: 128 banks × 128 indexes, 32-bit value
0x4Relative Registered ControllerSigned 32-bit increment/decrement of an RPN
0x5Relative Assignable ControllerSigned 32-bit increment/decrement of an NRPN
0x6Per-Note Pitch Bend32-bit unsigned, center 0x80000000
0x8Note Off16-bit velocity + attribute
0x9Note On16-bit velocity + attribute. Velocity 0 is a real Note On, not a Note Off.
0xAPoly Pressure32-bit
0xBControl Change7-bit index, 32-bit value
0xCProgram ChangeProgram number plus optional bank MSB/LSB in the same message
0xDChannel Pressure32-bit
0xEPitch Bend32-bit unsigned, center 0x80000000
0xFPer-Note ManagementDetach (D) and/or reset (S) the per-note controllers of a note

Field layouts at a glance

MessageWord 1 (after MT/group/status/channel)Word 2
Note On / Offnote (7) · attribute type (8)velocity (16) · attribute data (16)
Poly Pressurenote (7) · reservedpressure (32)
Control Changeindex (7) · reservedvalue (32)
Registered / Assignable Controllerbank (7) · index (7)value (32)
Per-Note Controller (registered / assignable)note (7) · index (8)value (32)
Program Changereserved (8) · option flags (8); bit 0 = Bank Validprogram (7) · reserved (8) · bank MSB (7) · bank LSB (7)
Channel Pressurereservedpressure (32)
Pitch Bend / Per-Note Pitch Bendreserved / note (7)bend (32), center 0x80000000
Per-Note Managementnote (7) · flags: D (detach), S (reset)reserved

Velocity zero

In MIDI 1.0, a Note On with velocity 0 means Note Off. In the MIDI 2.0 Protocol it doesn't, so senders must use Note Off (0x8). When translating MIDI 2.0 to MIDI 1.0, a velocity that scales down to 0 is sent as 1.

Value scaling: Min-Center-Max

Converting a 7-bit value to 16 or 32 bits is not just a left shift. A plain shift turns 127 into 0xFE00, so the maximum would no longer be the maximum. The spec defines a Min-Center-Max upscaling rule that keeps three points exact:

  • Minimum: 0 always maps to 0.
  • Center: the source midpoint (64 for 7-bit, 8192 for 14-bit) maps to the exact destination midpoint (0x8000, 0x80000000).
  • Maximum: the source maximum maps to all ones.

Values at or below the center are shifted left. For values above the center, the bits below the source's top bit are repeated into the empty low-order bits of the result. Values above the center are spread evenly up to the maximum, and values below it keep the plain shift.

// Reference algorithm from the UMP spec (abridged)
function scaleUp(srcVal, srcBits, dstBits) {
  const scaleBits = dstBits - srcBits;
  let out = srcVal << scaleBits;               // plain shift
  const center = 1 << (srcBits - 1);
  if (srcVal <= center) return out;            // min .. center: done
  const repeatBits = srcBits - 1;
  let repeat = srcVal & ((1 << repeatBits) - 1);  // bits below the top bit
  repeat = scaleBits > repeatBits
    ? repeat << (scaleBits - repeatBits)
    : repeat >> (repeatBits - scaleBits);
  while (repeat) { out |= repeat; repeat >>= repeatBits; }
  return out;
}
7-bit→ 16-bit→ 32-bit
00x00000x00000000
10x02000x02000000
640x80000x80000000
650x82080x82082082
1000xC9240xC9249249
1270xFFFF0xFFFFFFFF

Downscaling is a simple right shift. For example, a 16-bit velocity becomes 7 bits with v >> 9.

Endpoints, Function Blocks and the UMP Stream

A UMP Endpoint is one end of a bidirectional UMP connection, such as a USB MIDI 2.0 device or a virtual port. It may contain up to 32 Function Blocks, each a logical unit (a synth engine, a keyboard, a DIN port) that spans one or more groups. Hosts learn this layout from UMP Stream messages (MT 0xF), which identify themselves with a 2-bit format and a 10-bit status:

StatusMessagePurpose
0x000Endpoint DiscoveryAsk an Endpoint to describe itself
0x001Endpoint Info NotificationUMP version, number of Function Blocks, supported protocols and JR timestamps
0x002Device Identity NotificationManufacturer, family, model and version (same fields as a SysEx Identity Reply)
0x003Endpoint Name NotificationUTF-8 name, possibly across several packets
0x004Product Instance Id NotificationUnique ID, such as a serial number
0x005Stream Configuration RequestAsk to switch protocol (MIDI 1.0 / MIDI 2.0) and JR timestamp use
0x006Stream Configuration NotificationReport the current protocol and JR settings
0x010Function Block DiscoveryAsk for one or all Function Blocks
0x011Function Block Info NotificationActive flag, direction, first group and number of groups spanned, MIDI-CI version
0x012Function Block Name NotificationUTF-8 name of a block
0x020Start of ClipMarks the start of a sequence (e.g. in a MIDI Clip File)
0x021End of ClipMarks the end of a sequence

Choosing a protocol

An Endpoint may support the MIDI 1.0 Protocol, the MIDI 2.0 Protocol, or both. Since UMP 1.1 (2023), the host picks one with Stream Configuration Request/Notification, and the same exchange turns JR timestamps on or off. MIDI-CI 1.1 negotiated the protocol with its own SysEx messages; MIDI-CI 1.2 deprecated that mechanism, so new implementations should use UMP Stream messages.

Jitter Reduction timestamps

A sender can put a JR Timestamp utility message (MT 0x0) in front of other messages. It records when the event happened, as a 16-bit count in units of 1/31,250 second (32 µs). The receiver tracks the sender's clock from periodic JR Clock messages and uses the timestamps to undo transport jitter. This helps most on buffered links such as USB and networks. Musical timing, as opposed to transport timing, uses Delta Clockstamps in ticks (with DCTPQ) in MIDI Clip Files.

SysEx, Flex Data and files

  • SysEx7 (MT 0x3) carries MIDI 1.0 SysEx, up to six bytes per 64-bit packet, with a status of complete, start, continue or end. The F0 and F7 framing bytes are not sent.
  • SysEx8 (MT 0x5) carries full 8-bit data with a stream ID, so binary payloads don't need 7-bit encoding.
  • Flex Data (MT 0xD) holds tempo, time signature, key signature, metronome and chord-name messages, plus text such as lyrics and metadata. It replaces many SMF meta events for live streams.
  • MIDI Clip File and MIDI Container File are the UMP-based successors to the Standard MIDI File.

Platform support

PlatformStatus
macOS / iOSCoreMIDI has UMP APIs (MIDIEventList) since macOS 11 / iOS 14, and supports USB MIDI 2.0 devices.
WindowsWindows MIDI Services, a new UMP-native MIDI stack for Windows 11 with MIDI 2.0, multi-client ports and a compatibility layer for older APIs.
LinuxALSA gained UMP and USB MIDI 2.0 support in kernel 6.5, with matching userspace support in alsa-lib 1.2.10 and later.
AndroidUSB MIDI 2.0 host support since Android 13.
WebThe Web MIDI API is still MIDI 1.0 only.

Libraries with UMP support include AM_MIDI2.0Lib, ni-midi2, ktmidi, cmidi2 and libremidi. For moving UMP over USB, BLE and networks, see Transports.