Анатомія SysEx
Цикл «Анатомія SysEx»: 1. Анатомія SysEx · 2. Yamaha DX7 · 3. Roland/Korg/Sequential/Circuit Tracks · 4. DAW та тулінг · 5. MIDI-CI та MIDI 2.0
Звичайний MIDI Control Change — це три байти: статус, номер контролера (0–127), значення (0–127). 128 контролерів × 128 значень — цього вистачає на гучність і панораму, але не на повний стан синтезатора. System Exclusive (SysEx), в MIDI-специфікації з 1983 року, знімає це обмеження: виробник може передати повідомлення довільної довжини у власному форматі.
NRPN розширює адресний простір до 16 384 параметрів, але лишається протоколом «параметр → значення» і не годиться для bulk-дампу патча. SysEx — єдиний спосіб перенести патч цілком, байт у байт.
Структура повідомлення
F0 XX [XX XX] [dev] [data...] [cs] F7
│ │ │ │ │ │
│ └─ Manuf. └─Dev └─Payload └─CS └─ EOX
└─ Start of SysEx
- F0 — старт SysEx.
- Manufacturer ID — 1 або 3 байти.
- Device ID — 0x00–0x0F, щоб два однакових синти на одній шині не плутались.
- Data bytes — payload. Критично: кожен байт має лежати в діапазоні 0x00–0x7F. Значення ≥ 0x80 зарезервовані під статусні байти — синтезатор зупинить парсинг на першому такому байті без жодного попередження.
- Checksum — опціональний, формула у кожного виробника своя.
- F7 — кінець повідомлення (EOX).
3-байтові Manufacturer ID з'явились у 90-х, коли 1-байтовий простір вичерпався (Focusrite/Novation — 0x00 0x20 0x29). Universal SysEx (0x7E/0x7F) не належить жодному виробнику й покриває Master Volume, MTC, а пізніше — MIDI-CI.
| ID | Виробник |
|---|---|
| 0x41 | Roland |
| 0x42 | Korg |
| 0x43 | Yamaha |
| 0x44 | Casio |
| 0x00 0x20 0x29 | Focusrite / Novation |
| 0x7E | Universal Non-Real-Time |
| 0x7F | Universal Real-Time |
7-bit проблема
8-бітні значення (0–255) не влазять у 7-бітний data-байт без кодування. Два підходи:
Nibblizing (Roland, Novation Circuit Tracks) — байт ділиться на два напівбайти:
0xA3 → [0x0A, 0x03]
High-bit packing (Yamaha) — сім байтів по сім значущих біт пакуються з окремим msb-байтом попереду:
[msb_byte] [b0_low7] [b1_low7] ... [b6_low7]
Дві філософії checksum
Yamaha рахує двійковим доповненням:
checksum = (-sum(data_bytes)) & 0x7F
Roland — за формулою «128 мінус залишок»:
total = sum(address_bytes + data_bytes)
checksum = (128 - (total % 128)) % 128
Формули несумісні. Відправити Roland-checksum синту Yamaha — той мовчки проігнорує повідомлення, без коду помилки, без логу. Дебажиться це годинами, якщо не знати про різницю заздалегідь.
Рамка рішення: CC, NRPN чи SysEx
| CC | NRPN | SysEx | |
|---|---|---|---|
| Параметрів | 128 | 16 384 | необмежено |
| Розмір значення | 7 bit | 14 bit | довільний |
| Bulk dump | немає | немає | є |
| Стандартизований | так | частково | per-vendor |
Bulk-дамп цілого банку патчів — тільки SysEx. Живе крутіння одного параметра в реальному часі — CC або NRPN, вони легші й не ризикують заблокувати пристрій.
Практичне попередження
Некоректний SysEx-дамп здатен завести старий Roland-синт у невизначений стан. Backup поточного стану — перед будь-якою відправкою нових даних, по одному патчу за раз, checksum перевірено заздалегідь. Це той рідкісний випадок у MIDI, де помилка не просто не спрацює — вона зіпсує те, що вже було.
Further reading
7-бітне обмеження SysEx — не технічна слабкість, а рішення 1981 року зарезервувати старший біт під статусні байти, щоб пристрій розумів «це команда чи дані» без окремого поля довжини. Елегантно на папері. У 2026 кожне нове покоління розробників MIDI-бібліотек заново винаходить nibblizing і щиро дивується, чому це досі так.