MIDI Technical Reference
A comprehensive technical reference based on MIDI 1.0 specification, covering message types, Control Change, SysEx protocol, and hardware connectivity. Written for LdA device users.
1. MIDI Overview
MIDI (Musical Instrument Digital Interface) is the international standard protocol for communication between electronic musical instruments, first released by the MMA and AMEI in 1983. MIDI transmits performance data — not audio — such as which note was played, how hard, and how far a knob was turned.
MIDI uses asynchronous serial communication at 31.25 Kbaud (±1%), with 1 start bit, 8 data bits, and 1 stop bit per byte (10 bits total, 320 µs). Data travels as a 5mA current loop, with opto-isolation providing electrical isolation between devices.
2. Message Types
| Message | Status Byte | Data Bytes | Description |
|---|---|---|---|
| Note Off | 0x80-0x8F | Note, Velocity | Note released |
| Note On | 0x90-0x9F | Note, Velocity | Note pressed (Velocity=0 = Note Off) |
| Poly Aftertouch | 0xA0-0xAF | Note, Pressure | Per-key pressure |
| Control Change | 0xB0-0xBF | CC#, Value | Controller change, CC#120-127 are Channel Mode |
| Program Change | 0xC0-0xCF | Program # | Patch/preset change |
| Channel Aftertouch | 0xD0-0xDF | Pressure | Channel-wide pressure |
| Pitch Bend | 0xE0-0xEF | LSB, MSB | 14-bit pitch bend (center=0x2000) |
| System Exclusive | 0xF0 | Manufacturer ID + Data | Vendor-defined, ends with 0xF7 |
| Timing Clock | 0xF8 | None | 24 pulses per quarter note |
| Start / Stop / Continue | 0xFA / 0xFC / 0xFB | None | Real-time transport control |
| Active Sensing | 0xFE | None | Connection keep-alive (every 300ms) |
Note: The low 4 bits (nnnn) of status bytes indicate MIDI channel 0-15 → channel 1-16.
3. CC Reference
Control Change messages use status bytes 0xB0-0xBF (channels 1-16), followed by a CC number (0-127) and value (0-127). CC#120-127 are reserved for Channel Mode messages. Below are the key CC numbers defined in the MIDI 1.0 specification.
| CC# | Name | Range | Type |
|---|---|---|---|
| 0 | Bank Select | 0-127 | MSB |
| 1 | Modulation Wheel | 0-127 | MSB |
| 2 | Breath Controller | 0-127 | MSB |
| 4 | Foot Controller | 0-127 | MSB |
| 5 | Portamento Time | 0-127 | MSB |
| 6 | Data Entry | 0-127 | MSB |
| 7 | Channel Volume | 0-127 | MSB |
| 8 | Balance | 0-127 | MSB |
| 10 | Pan | 0-127 | MSB |
| 11 | Expression | 0-127 | MSB |
| 12 | Effect Control 1 | 0-127 | MSB |
| 13 | Effect Control 2 | 0-127 | MSB |
| 16 | General Purpose 1 | 0-127 | MSB |
| 17 | General Purpose 2 | 0-127 | MSB |
| 18 | General Purpose 3 | 0-127 | MSB |
| 19 | General Purpose 4 | 0-127 | MSB |
| 32 | Bank Select LSB | 0-127 | LSB |
| 38 | Data Entry LSB | 0-127 | LSB |
| 64 | Damper Pedal (Sustain) | 0-63=Off, 64-127=On | Switch |
| 65 | Portamento On/Off | 0-63=Off, 64-127=On | Switch |
| 66 | Sostenuto | 0-63=Off, 64-127=On | Switch |
| 67 | Soft Pedal | 0-63=Off, 64-127=On | Switch |
| 70 | Sound Controller 1 | 0-127 | LSB |
| 71 | Sound Controller 2 | 0-127 | LSB |
| 72 | Sound Controller 3 (Release) | 0-127 | LSB |
| 73 | Sound Controller 4 (Attack) | 0-127 | LSB |
| 74 | Sound Controller 5 (Brightness) | 0-127 | LSB |
| 80 | General Purpose 5 | 0-127 | LSB |
| 81 | General Purpose 6 | 0-127 | LSB |
| 82 | General Purpose 7 | 0-127 | LSB |
| 83 | General Purpose 8 | 0-127 | LSB |
| 91 | Reverb Send Level | 0-127 | MSB |
| 93 | Chorus Send Level | 0-127 | MSB |
| 98 | NRPN LSB | 0-127 | LSB |
| 99 | NRPN MSB | 0-127 | MSB |
| 100 | RPN LSB | 0-127 | LSB |
| 101 | RPN MSB | 0-127 | MSB |
| 120 | All Sound Off | 0 | Mode |
| 121 | Reset All Controllers | 0 | Mode |
| 122 | Local Control | 0=Off, 127=On | Mode |
| 123 | All Notes Off | 0 | Mode |
| 124 | Omni Mode Off | 0 | Mode |
| 125 | Omni Mode On | 0 | Mode |
| 126 | Mono Mode On | 0-16 | Mode |
| 127 | Poly Mode On | 0 | Mode |
4. SysEx Guide
4.1 SysEx Message Format
System Exclusive (SysEx) is the MIDI protocol mechanism for manufacturer-custom communication. Each SysEx message starts with 0xF0 and ends with 0xF7, carrying a manufacturer ID and custom data in between. LdA uses the temporary manufacturer ID 0x7D.
Field Descriptions
| Field | Bytes | Description |
|---|---|---|
| Start | 1 | 0xF0 — SysEx start |
| Maker ID | 1 | 0x7D — LdA temporary ID |
| Dev ID | 1 | 0x01=MS-3, 0x02=LS-4p3, 0xFF=broadcast |
| Command | 1 | Command number |
| Data | 0-N | Command data |
| Checksum | 1 | XOR: Maker ID ⊕ Dev ID ⊕ Command ⊕ Data[0..N-1] |
| End | 1 | 0xF7 — SysEx end |
4.2 Checksum Algorithm
uint8_t checksum = maker_id ^ dev_id ^ cmd;
for (int i = 0; i < data_len; i++) {
checksum ^= data[i];
}4.3 Response Format
Devices respond to commands with a response message. ResponseCode = Command | 0x80 (setting the MSB indicates a response).
F0 7D [DevID] [ResponseCode] [ResponseData] [Checksum] F7
4.4 Error Responses
| ErrorCode | Meaning |
|---|---|
| 0x01 | Command not supported |
| 0x02 | Invalid data format |
| 0x03 | Checksum mismatch |
| 0x04 | Device busy |
| 0x05 | Storage error |
4.5 Command Set Overview
| Range | Category | Example Commands |
|---|---|---|
| 0x00-0x0F | System | 0x00=Firmware, 0x01=Device Info, 0x04=Ping |
| 0x10-0x1F | Preset Management | 0x10=Read, 0x11=Write, 0x13=Switch, 0x14=Backup |
| 0x20-0x2F | MIDI Control | 0x20=Send MIDI, 0x21=Configure Preset MIDI |
| 0x30-0x3F | Loop Control | 0x30=Read Loops, 0x31=Toggle Loop, 0x32=Set All |
| 0x40-0x4F | System Config | 0x40=Read Config, 0x42=Read MIDI Channel |
| 0xF0-0xFF | Firmware Update | 0xF0=Enter Bootloader, 0xF3=Data Block |
4.6 Example: Query Firmware (0x00)
Send:
F0 7D 01 00 [Checksum] F7
Response (firmware v1.2.3):
F0 7D 01 80 01 02 03 00 [Checksum] F7
ResponseCode = 0x80 (0x00 | 0x80), Data = Major.Minor.Patch.Build
4.7 Example: Toggle Loop 2 On (0x31)
F0 7D 01 31 02 7F [Checksum] F7; LoopNum=2, State=0x7F (on)
5. MS-3 MIDI Implementation
The MS-3 supports standard MIDI messages and SysEx protocol. Connect via USB-C or 5-pin DIN to switch presets with Program Change, control loops with Control Change, and manage preset data and system configuration via SysEx.
MS-3 Custom CC Mapping
| CC# | Function | Description |
|---|---|---|
| 0 | Bank Select MSB | Preset bank switch |
| 32 | Bank Select LSB | Preset bank select LSB |
| 80 | Loop 1 | 0-63=Off, 64-127=On |
| 81 | Loop 2 | 0-63=Off, 64-127=On |
| 82 | Loop 3 | 0-63=Off, 64-127=On |
| 90 | Tap Tempo | Tap 3 times to set BPM |
| 91 | Global Tap | Global tap tempo |
| 102 | Preset Up | Next preset |
| 103 | Preset Down | Previous preset |
| 120 | All Sound Off | Mute all |
| 123 | All Notes Off | All notes off |
Program Change Preset Mapping
6. Hardware Connectivity
6.1 MIDI Physical Interface
| Interface | Spec | Notes |
|---|---|---|
| 5-pin DIN | 31.25 Kbaud, 5mA current loop | MIDI 1.0 standard, opto-isolated, max 15m |
| USB-C | USB MIDI Class Compliant | Driverless, plug-and-play on macOS/Windows 10+ |
| TRS (3.5mm) | TRS MIDI (MMA RP-054) | Type A adapter (MMA standard), some devices may need Type B |
6.2 Web MIDI API Integration
Modern browsers support MIDI communication via the Web MIDI API. Here's a JavaScript integration example for LdA devices:
// Request MIDI access with SysEx support
const midi = await navigator.requestMIDIAccess({ sysex: true });
// Send SysEx to LdA device (e.g., query firmware)
function sendSysex(output, makerId, devId, cmd, data = []) {
const checksum = [makerId, devId, cmd, ...data]
.reduce((a, b) => a ^ b, 0);
const msg = new Uint8Array([
0xF0, makerId, devId, cmd, ...data, checksum, 0xF7
]);
output.send(msg);
}
// Listen for MIDI input
input.onmidimessage = (event) => {
const [status, ...rest] = event.data;
if (status === 0xF0) {
// SysEx received
const [makerId, devId, responseCode, ...data] = rest;
const cmd = responseCode & 0x7F;
console.log('Response to cmd', cmd.toString(16), data);
}
};Note: Chrome/Edge support Web MIDI API. Safari/Firefox require manual enabling or third-party extensions.