FREE worldwide shipping on orders over $200.
Back to Lab

MIDI SysEx Protocol in Practice

Developer2025-03-01

System Exclusive (SysEx) is MIDI's most powerful extension mechanism. Unlike fixed-format channel messages, SysEx allows manufacturers to define custom messages of arbitrary length and format — from simple device queries to complex firmware updates, anything is possible. This article takes a practical approach, using the LdA MS-3 protocol to explain SysEx core concepts and real-world applications.

1. SysEx Message Basics

Every SysEx message starts with 0xF0 and ends with 0xF7. In between is a manufacturer ID (1 or 3 bytes) and custom data. Manufacturer IDs are assigned by MMA or AMEI — well-known brands like Roland (0x41), Yamaha (0x43), Korg (0x42) each have their ID. LdA currently uses temporary ID 0x7D (pending formal MMA application).

┌──────┬──────────┬──────────┬────────────┬────────┬──────┐
│ 0xF0 │ Maker ID │  Data    │    ...     │  0xF7  │
│ Start│ 1-3 bytes│ Variable │            │  End   │
└──────┴──────────┴──────────┴────────────┴────────┘

1-Byte IDs: 0x00-0x7F (e.g. Roland = 0x41)
3-Byte IDs: 0x00 0x00 0x00 format (0x00 0x20 0x00+)
Important

Only System Real-Time messages (e.g., Timing Clock 0xF8) can be interleaved within a SysEx message. Any other message type will terminate the SysEx transfer. Additionally, all data bytes must have MSB = 0 (i.e., value < 0x80).

2. Universal SysEx Messages

The MMA defines Universal SysEx messages using special IDs 0x7E (Non-Real Time) and 0x7F (Real Time) that all devices should respond to. The most commonly used Universal SysEx is the Identity Request/Reply — the standardized way to discover MIDI device identity.

Identity Request

F0 7E [Channel] 06 01 F7

Channel: 0x7F = broadcast (all devices respond), 0x00-0x0F = specific channel

Identity Reply

F0 7E [Channel] 06 02 [MakerID] [Family] [Model] [Version] F7

Maker ID:    1-byte = 0x7D (LdA)
Device Family: 2 bytes (MSB, LSB)
Device Model:  2 bytes
Version:       4 bytes (Major.Minor.Patch.Build)

3. LdA SysEx Protocol In Detail

LdA devices use a unified SysEx protocol format that extends standard SysEx with device ID, command byte, and XOR checksum for communication reliability and data integrity.

LdA Message Format

F0 7D [DevID] [Command] [Data...] [Checksum] F7

Maker ID:  0x7D (LdA temporary)
Dev ID:    0x01=MS-3, 0x02=LS-4p3, 0xFF=broadcast
Command:   See command table below
Data:      0-N bytes, command-specific
Checksum:  XOR of Maker ID ⊕ DevID ⊕ Command ⊕ Data[0..N-1]

Response Format

All command responses use ResponseCode = Command | 0x80 (MSB set to 1). Error responses uniformly use ResponseCode = 0x8F.

Command Set

RangeCategoryKey Commands
0x00-0x0FSystem0x00=Query Firmware, 0x01=Device Info, 0x03=Status, 0x04=Ping
0x10-0x1FPresets0x10=Read Preset, 0x11=Write Preset, 0x13=Switch Preset, 0x14=Backup All, 0x16=Factory Reset
0x20-0x2FMIDI Ctrl0x20=Send MIDI Msg, 0x21=Config Preset MIDI
0x30-0x3FLoop Ctrl0x30=Read Loops, 0x31=Toggle One, 0x32=Set All
0x40-0x4FConfig0x40=Read Config, 0x42=Read MIDI Channel Config
0xF0-0xFFFirmware0xF0=Enter Bootloader, 0xF3=Send Block (128B)

4. Checksum and Error Handling

The LdA protocol uses a simple XOR checksum to detect transmission errors. Calculation: XOR Maker ID (0x7D), Dev ID, Command, and all Data bytes together. The receiver validates the checksum and returns ErrorCode 0x03 on mismatch.

// Checksum calculation in C
uint8_t calc_checksum(uint8_t maker, uint8_t dev,
                       uint8_t cmd, uint8_t *data,
                       size_t len) {
  uint8_t cs = maker ^ dev ^ cmd;
  for (size_t i = 0; i < len; i++) cs ^= data[i];
  return cs;
}

// Example: Query Firmware (cmd=0x00, no data)
// cs = 0x7D ^ 0x01 ^ 0x00 = 0x7C
// Message: F0 7D 01 00 7C F7
Error CodeMeaningAction
0x01Command not supportedCheck command byte
0x02Invalid data formatVerify data byte range (0-0x7F)
0x03Checksum mismatchRecalculate checksum, retry
0x04Device busyWait 100ms and retry
0x05Storage errorCheck memory / factory reset

5. Practical Examples

Example 1: Query MS-3 Firmware

Send:    F0 7D 01 00 7C F7
              (checksum: 0x7D^0x01^0x00 = 0x7C)

Receive: F0 7D 01 80 01 02 03 00 7F F7
              (ResponseCode=0x80, v1.2.3.0, cs verified)

Example 2: Switch to Preset 5

Send:    F0 7D 01 13 05 64 F7
              (cmd=0x13, PresetNum=5, cs=0x7D^1^0x13^5=0x64)

Receive: F0 7D 01 93 05 6F F7
              (ResponseCode=0x93, PresetNum=5)

Example 3: Enable Loop 1, Disable 2 & 3

Send:    F0 7D 01 32 7F 00 00 4D F7
              (cmd=0x32, L1=0x7F(ON), L2=0x00, L3=0x00,
               cs=0x7D^1^0x32^0x7F^0^0=0x4D)

6. Web MIDI API Integration

Below is a complete example of using the Web MIDI API to communicate with LdA devices from the browser. Note: Web MIDI API requires HTTPS or localhost, and the user must explicitly grant permission (especially for SysEx access).

// 1. Request MIDI access with SysEx
const midi = await navigator.requestMIDIAccess({ sysex: true });

// 2. Find LdA device by name
function findLdADevice(midi) {
  const devices = { input: null, output: null };
  for (const [id, input] of midi.inputs) {
    if (input.name?.includes('MS-3') || input.name?.includes('LdA')) {
      devices.input = input;
      break;
    }
  }
  for (const [id, output] of midi.outputs) {
    if (output.name?.includes('MS-3') || output.name?.includes('LdA')) {
      devices.output = output;
      break;
    }
  }
  return devices;
}

// 3. Send LdA SysEx command
function sendLdACmd(output, devId, cmd, data = []) {
  const checksum = [0x7D, devId, cmd, ...data]
    .reduce((a, b) => a ^ b, 0);
  const msg = new Uint8Array([
    0xF0, 0x7D, devId, cmd, ...data, checksum, 0xF7
  ]);
  output.send(msg);
}

// 4. Listen for responses
function setupListener(input) {
  let sysexBuffer = [];
  input.onmidimessage = (event) => {
    const data = Array.from(event.data);
    if (data[0] === 0xF0) {
      sysexBuffer = data;
    } else if (sysexBuffer.length && data[data.length-1] !== 0xF7) {
      sysexBuffer.push(...data);
    }
    if (data[data.length-1] === 0xF7) {
      const full = sysexBuffer.length ? [...sysexBuffer, ...data] : data;
      const makerId = full[1];
      const devId = full[2];
      const responseCode = full[3];
      const cmd = responseCode & 0x7F;
      const payload = full.slice(4, -2);
      const checksum = full[full.length - 2];
      
      // Verify checksum
      const computed = full.slice(1, -2)
        .reduce((a, b) => a ^ b, 0);
      const valid = computed === checksum;
      
      console.log('LdA Response:', {
        cmd: '0x' + cmd.toString(16),
        payload,
        checksumValid: valid,
        isError: cmd === 0x0F
      });
      sysexBuffer = [];
    }
  };
}

// 5. Usage: Query firmware
const { input, output } = findLdADevice(midi);
setupListener(input);
sendLdACmd(output, 0x01, 0x00);  // DevID=MS-3, Cmd=Query Firmware

7. Best Practices & Pitfalls

Always Verify Checksum

MIDI transmission can have errors (especially through USB-MIDI adapters). Always verify checksum on receive, and request retransmission on mismatch.

Handle Device Busy

Devices may need time to process SysEx commands (especially writes). On 0x04 error, wait 100-500ms then retry. Add delays between bulk operations.

Chunk Large Transfers

Large data transfers like preset backups or firmware updates should be chunked (e.g., 128 bytes per block). Wait for device response after each block before sending the next.

Avoid: Data Bytes with MSB ≠ 0

All data bytes in SysEx messages must be &lt; 0x80. To transmit 8-bit data, split into 7-bit format (every 7 bytes encoded as 8 SysEx bytes).

Avoid: Ignoring SysEx Permission

In Web MIDI API, SysEx access requires explicit permission (`{ sysex: true }`). Some browsers may block SysEx or require user interaction. Always check `midi.access` permission state.

8. Summary

The SysEx protocol gives MIDI devices deep control capabilities beyond standard messages. The LdA protocol, with its standardized command format, XOR checksum, and comprehensive error code system, provides a reliable and extensible device communication solution. Mastering SysEx means you can write your own control software, implement automated workflows, and even push the boundaries of device functionality.

📚 Further Reading: MIDI Technical Reference Complete protocol specification and technical details