1948 lines
64 KiB
Markdown
1948 lines
64 KiB
Markdown
# DSP 408 Protocol Documentation
|
||
|
||
# TODO
|
||
|
||
- Existing but not implemented commands: 0x19, 0x25, 0x28, 0x2E, 0x50, 0x51, 0x52, 0x53
|
||
- Commands 0x2E, 0x50, 0x51, 0x52, 0x53 seem to be used for firmware update: DO NOT SEND THEM WITHOUT KNOWLEDGE - RISK OF DEVICE BRICK (I brick my device)
|
||
- Commands: 0x19, 0x24, 0x28 are triggered by upload preset
|
||
- Identify: 0x2C parameters
|
||
- Implement: if 2 DSP with same ip, they need to share same socket since dsp dont accept multiples connections
|
||
- In unlock check if first byte is device id
|
||
- Dsp and python code allow to send commands even if dsp is locked
|
||
- Convert back data as in 0x38 to display real value
|
||
|
||
# Tables of Content
|
||
|
||
## Encoding Index
|
||
|
||
| Encoding | Used by | Description |
|
||
|---|---|---|
|
||
| [Preset Name](#21-preset-name) | Preset save/load | 14-byte fixed string |
|
||
| [Channel Name](#22-channel-name) | Channel labeling | 8-byte fixed string |
|
||
| [Password](#23-password) | Login/lock | 4-byte fixed string |
|
||
| [Preset Index](#31-preset-index) | Preset select | 1-byte index (21 presets) |
|
||
| [Channel Index](#32-channel-index) | Gain, Mute, Delay, PEQ, GEQ | 1-byte index (12 channels) |
|
||
| [PEQ Band Index](#33-peq-band-index) | PEQ | 1-byte index (9 bands) |
|
||
| [Frequency Band Index](#34-frequency-band-index) | GEQ | 1-byte index (31 bands) |
|
||
| [Delay Unit](#35-delay-unit) | Channel Delay | 1-byte unit selector |
|
||
| [Compressor Ratio](#36-compressor-ratio) | Compressor | 1-byte index (16 ratios) |
|
||
| [Input Source Type](#37-input-source-type) | Input select | 1-byte index (4 sources) |
|
||
| [PEQ Filter Type](#38-peq-filter-type) | PEQ | 1-byte index (9 filter types) |
|
||
| [Crossover Slope](#39-crossover-slope) | Crossover | 1-byte index (21 slopes) |
|
||
| [Matrix Input Mask](#41-matrix-input-mask) | Input routing | 1-byte bitmask |
|
||
| [Channel Gain](#51-channel-gain) | Gain | 16-bit dB value (-60 to +12 dB) |
|
||
| [GEQ / PEQ Gain](#52-geq--peq-gain) | GEQ, PEQ | 8-bit ±12 dB value |
|
||
| [PEQ Q Factor](#53-peq-q-factor) | PEQ | 8-bit logarithmic Q value |
|
||
| [Hold](#61-hold-gate) | Gate | 16-bit ms value |
|
||
| [Attack](#62-attack-compressor) | Compressor | 16-bit ms value |
|
||
| [Release](#63-release-compressor) | Compressor | 16-bit ms value |
|
||
| [Knee](#64-knee-compressor) | Compressor | 8-bit dB value |
|
||
| [Sidechain Frequency](#65-sidechain-frequency-compressor) | Compressor | 16-bit logarithmic Hz value |
|
||
| [Gate Threshold](#66-gate-threshold) | Gate | 16-bit dB value |
|
||
| [Compressor Threshold](#67-compressor-threshold) | Compressor | 8-bit dB value |
|
||
| [Channel Delay](#71-channel-delay) | Delay | 8-bit linear value |
|
||
| [Meter Level](#81-meter-level) | Metering | Float16 level + peak byte |
|
||
|
||
---
|
||
|
||
## Commands Index
|
||
|
||
| Command | Category | Description |
|
||
|---|---|---|
|
||
| `0x01` — [Acknowledgement](#0x01--acknowledgement) | Connection & Session | Signals the device finished loading/processing and is ready |
|
||
| `0x02` — [Not Implemented](#0x02--not-implemented) | Connection & Session | Signals that the command just sent is invalid/unimplemented |
|
||
| `0x10` — [Start](#0x10--start) | Connection & Session | Initiates a session with the device |
|
||
| `0x11` — [Disconnect](#0x11--disconnect) | Connection & Session | Terminates the session |
|
||
| `0x12` — [Acknowledgement (Client → Device)](#0x12--acknowledgement-client--device) | Connection & Session | Client-side confirmation after loading parameters |
|
||
| `0x13` — [Device Name](#0x13--device-name) | Device Info | Reads the device's display name |
|
||
| `0x14` — [Current Preset Index](#0x14--current-preset-index) | Preset Management | Reads the currently active preset |
|
||
| `0x15` — [Set Delay Unit](#0x15--set-delay-unit) | Channel Processing | Changes the display unit used for delay values |
|
||
| `0x20` — [Recall Preset](#0x20--recall-preset) | Preset Management | Recalls (loads) a stored preset |
|
||
| `0x21` — [Store Preset](#0x21--store-preset) | Preset Management | Saves the current live settings into a preset slot |
|
||
| `0x22` — [Get Preset Modification Status](#0x22--get-preset-modification-status) | Preset Management | Reports which presets have unsaved/modified state |
|
||
| `0x23` — [Factory Reset](#0x23--factory-reset) | Preset Management | Restores factory defaults |
|
||
| `0x27 / 0x24` — [Config Chunk (Request / Response)](#0x27--0x24--config-chunk-request--response) | Preset Management | Streams the full device configuration in indexed chunks |
|
||
| `0x26` — [Store Preset Name](#0x26--store-preset-name) | Preset Management | Sets the working preset name prior to saving |
|
||
| `0x29` — [Get Preset Name](#0x29--get-preset-name) | Preset Management | Reads the name of a given preset |
|
||
| `0x2A` — [Copy Channel](#0x2a--copy-channel) | Channel Configuration | Copies one channel's settings onto another |
|
||
| `0x2C` — [Device Flags](#0x2c--device-flags) | Device Info | Reads device status flags, including lock state |
|
||
| `0x2D` — [Unlock Device](#0x2d--unlock-device) | Security | Authenticates with a password to unlock the device |
|
||
| `0x2F` — [Lock Device](#0x2f--lock-device) | Security | Locks the device behind a password |
|
||
| `0x30` — [Set Compressor](#0x30--set-compressor) | Dynamics | Sets compressor parameters for a channel |
|
||
| `0x31` — [Set Low-Pass Filter](#0x31--set-low-pass-filter) | Filters & EQ | Sets the low-pass filter for a channel |
|
||
| `0x32` — [Set High-Pass Filter](#0x32--set-high-pass-filter) | Filters & EQ | Sets the high-pass filter for a channel |
|
||
| `0x33` — [Set PEQ Band](#0x33--set-peq-band) | Filters & EQ | Sets one parametric EQ band (input channels only) |
|
||
| `0x34` — [Set Gain](#0x34--set-gain) | Channel Processing | Sets a channel's gain |
|
||
| `0x35` — [Set Mute](#0x35--set-mute) | Channel Processing | Mutes or unmutes a channel |
|
||
| `0x36` — [Invert Gain](#0x36--invert-gain) | Channel Processing | Inverts polarity on a channel |
|
||
| `0x38` — [Set Delay](#0x38--set-delay) | Channel Processing | Sets a channel's delay value |
|
||
| `0x39` — [Set Input Source](#0x39--set-input-source) | Input & Routing | Selects the analog/test signal source |
|
||
| `0x3A` — [Matrix Routing](#0x3a--matrix-routing) | Input & Routing | Sets which inputs feed a given output channel |
|
||
| `0x3B` — [Link Channel](#0x3b--link-channel) | Channel Configuration | Groups channels so they move together |
|
||
| `0x3C` — [Bypass EQ](#0x3c--bypass-eq) | Channel Processing | Enables or bypasses all EQ processing on a channel |
|
||
| `0x3D` — [Set Channel Name](#0x3d--set-channel-name) | Channel Configuration | Sets the display name of an output channel |
|
||
| `0x3E` — [Set Gate Parameters](#0x3e--set-gate-parameters) | Dynamics | Sets noise-gate parameters for a channel |
|
||
| `0x3F` — [Set Output Limiter](#0x3f--set-output-limiter) | Dynamics | Sets output-limiter parameters (output channels only) |
|
||
| `0x40` — [Get Level Meters](#0x40--get-level-meters) | Metering | Reads current level-meter and clip-indicator values for all channels |
|
||
| `0x41` — [Set Matrix Gain](#0x41--set-matrix-gain) | Input & Routing | Sets the send gain from one input to one output |
|
||
| `0x48` — [Set GEQ Band](#0x48--set-geq-band) | Filters & EQ | Sets one band of a 31-band graphic EQ (input channels only) |
|
||
| `0x49` — [Set GEQ Bypass](#0x49--set-geq-bypass) | Filters & EQ | Enables or bypasses the graphic EQ on an input channel (input channels only) |
|
||
|
||
---
|
||
|
||
# Encoding / Decoding Specification
|
||
|
||
## 1. Overview & Conventions
|
||
|
||
- All multi-byte numeric fields are **little-endian**: the low-order byte (`LO`) is transmitted/stored first, the high-order byte (`HI`) second.
|
||
```text
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
```
|
||
- Quantized parameters (e.g. gain, threshold) are rounded to the nearest valid step **before** encoding. The decoding formula always reverses the encoding formula exactly.
|
||
- All lookup-table fields (enums, indices) are 1 byte unless otherwise noted.
|
||
|
||
---
|
||
|
||
## 2. Fixed-Length Strings
|
||
|
||
All string fields share one encoding model: write the text as ASCII bytes, then pad up to the fixed length with a pad byte. Decoding reverses this: read the fixed length, then strip trailing pad bytes.
|
||
|
||
### 2.1 Preset Name
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Human-readable preset name |
|
||
| **Size** | 14 bytes |
|
||
| **Pad byte** | `0x20` (space) |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
bytes = ASCII(name)[0:14]
|
||
bytes = bytes + 0x20 × (14 - len(bytes))
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
name = ASCII(bytes).rstrip(0x20)
|
||
```
|
||
|
||
### 2.2 Channel Name
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Human-readable channel name |
|
||
| **Size** | 8 bytes |
|
||
| **Pad byte** | `0x00` |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
bytes = ASCII(name)[0:8]
|
||
bytes = bytes + 0x00 × (8 - len(bytes))
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
name = ASCII(bytes).rstrip(0x00)
|
||
```
|
||
|
||
### 2.3 Password
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Password value |
|
||
| **Size** | 4 bytes |
|
||
| **Pad byte** | `0x00` |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
bytes = ASCII(password)[0:4]
|
||
bytes = bytes + 0x00 × (4 - len(bytes))
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
password = ASCII(bytes).rstrip(0x00)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Enumerated & Index Values
|
||
|
||
All fields in this section are 1 byte and work as a direct lookup table.
|
||
|
||
**Encoding (value → raw):** find the desired option in the table and use its byte value.
|
||
**Decoding (raw → value):** look up the byte value in the table to get the option.
|
||
|
||
### 3.1 Preset Index
|
||
|
||
**Range:** `0x00`–`0x14` (21 presets)
|
||
|
||
| Index | Preset |
|
||
|---|---|
|
||
| `0x00` | Preset 0 |
|
||
| `0x01` | Preset 1 |
|
||
| … | … |
|
||
| `0x14` | Preset 20 |
|
||
|
||
### 3.2 Channel Index
|
||
|
||
**Range:** `0x00`–`0x0B` (12 channels)
|
||
|
||
| Index | Channel | Index | Channel |
|
||
|---|---|---|---|
|
||
| `0x00` | IN_A | `0x06` | OUT_3 |
|
||
| `0x01` | IN_B | `0x07` | OUT_4 |
|
||
| `0x02` | IN_C | `0x08` | OUT_5 |
|
||
| `0x03` | IN_D | `0x09` | OUT_6 |
|
||
| `0x04` | OUT_1 | `0x0A` | OUT_7 |
|
||
| `0x05` | OUT_2 | `0x0B` | OUT_8 |
|
||
|
||
### 3.3 PEQ Band Index
|
||
|
||
**Range:** `0x00`–`0x08` (9 bands)
|
||
|
||
**Band limit by channel type:**
|
||
|
||
| Channel Type | Maximum Band |
|
||
|---|---|
|
||
| Input | B7 (`0x07`) |
|
||
| Output | B8 (`0x08`) |
|
||
|
||
| Index | Band | Index | Band |
|
||
|---|---|---|---|
|
||
| `0x00` | B0 | `0x05` | B5 |
|
||
| `0x01` | B1 | `0x06` | B6 |
|
||
| `0x02` | B2 | `0x07` | B7 |
|
||
| `0x03` | B3 | `0x08` | B8 |
|
||
| `0x04` | B4 | | |
|
||
|
||
### 3.4 Frequency Band Index
|
||
|
||
**Range:** `0x00`–`0x1E` (31 bands, ISO 1/3-octave centers)
|
||
|
||
| Index | Frequency | Index | Frequency | Index | Frequency | Index | Frequency |
|
||
|---|---|---|---|---|---|---|---|
|
||
| `0x00` | 20 Hz | `0x08` | 125 Hz | `0x10` | 800 Hz | `0x18` | 5 kHz |
|
||
| `0x01` | 25 Hz | `0x09` | 160 Hz | `0x11` | 1 kHz | `0x19` | 6.3 kHz |
|
||
| `0x02` | 31.5 Hz | `0x0A` | 200 Hz | `0x12` | 1.25 kHz | `0x1A` | 8 kHz |
|
||
| `0x03` | 40 Hz | `0x0B` | 250 Hz | `0x13` | 1.6 kHz | `0x1B` | 10 kHz |
|
||
| `0x04` | 50 Hz | `0x0C` | 315 Hz | `0x14` | 2 kHz | `0x1C` | 12.5 kHz |
|
||
| `0x05` | 63 Hz | `0x0D` | 400 Hz | `0x15` | 2.5 kHz | `0x1D` | 16 kHz |
|
||
| `0x06` | 80 Hz | `0x0E` | 500 Hz | `0x16` | 3.15 kHz | `0x1E` | 20 kHz |
|
||
| `0x07` | 100 Hz | `0x0F` | 630 Hz | `0x17` | 4 kHz | | |
|
||
|
||
### 3.6 Compressor Ratio
|
||
|
||
**Range:** `0x0000`–`0x0F00` (16 values)
|
||
|
||
| Value | Ratio | Value | Ratio |
|
||
|---|---|---|---|
|
||
| `0x0000` | 1:1 | `0x0800` | 3.5:1 |
|
||
| `0x0100` | 1.1:1 | `0x0900` | 4:1 |
|
||
| `0x0200` | 1.3:1 | `0x0A00` | 5:1 |
|
||
| `0x0300` | 1.5:1 | `0x0B00` | 6:1 |
|
||
| `0x0400` | 1.7:1 | `0x000C` | 8:1 |
|
||
| `0x0500` | 2:1 | `0x0D00` | 10:1 |
|
||
| `0x0600` | 2.5:1 | `0x0E00` | 20:1 |
|
||
| `0x0700` | 3:1 | `0x0F00` | LIMIT |
|
||
|
||
### 3.7 Input Source Type
|
||
|
||
**Range:** `0x00`–`0x03` (4 types)
|
||
|
||
| Value | Input Source |
|
||
|---|---|
|
||
| `0x00` | Analog |
|
||
| `0x01` | Pink Noise |
|
||
| `0x02` | White Noise |
|
||
| `0x03` | Sine Wave |
|
||
|
||
### 3.8 PEQ Filter Type
|
||
|
||
**Range:** `0x00`–`0x08` (9 types)
|
||
|
||
| Value | Filter | Value | Filter |
|
||
|---|---|---|---|
|
||
| `0x00` | Peak | `0x05` | HP 6dB |
|
||
| `0x01` | Low Shelf | `0x06` | HP 12dB |
|
||
| `0x02` | High Shelf | `0x07` | All Pass 1 |
|
||
| `0x03` | LP 6dB | `0x08` | All Pass 2 |
|
||
| `0x04` | LP 12dB | | |
|
||
|
||
### 3.9 Crossover Slope
|
||
|
||
**Range:** `0x00`–`0x14` (21 values)
|
||
|
||
| Value | Slope | Value | Slope |
|
||
|---|---|---|---|
|
||
| `0x00` | Bypass | `0x0B` | BW 30 |
|
||
| `0x01` | BW 6 | `0x0C` | BL 30 |
|
||
| `0x02` | BL 6 | `0x0D` | BW 36 |
|
||
| `0x03` | BW 12 | `0x0E` | BL 36 |
|
||
| `0x04` | BL 12 | `0x0F` | LR 36 |
|
||
| `0x05` | LR 12 | `0x10` | BW 42 |
|
||
| `0x06` | BW 18 | `0x11` | BL 42 |
|
||
| `0x07` | BL 18 | `0x12` | BW 48 |
|
||
| `0x08` | BW 24 | `0x13` | BL 48 |
|
||
| `0x09` | BL 24 | `0x14` | LR 48 |
|
||
| `0x0A` | LR 24 | | |
|
||
|
||
---
|
||
|
||
## 4. Bit Mask Values
|
||
|
||
### 4.1 Matrix Input Mask
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Which inputs are active/routed |
|
||
| **Size** | 1 byte |
|
||
| **Range** | `0x00`–`0x0F` |
|
||
|
||
| Input | Bit mask |
|
||
|---|---|
|
||
| IN_A | `0x01` |
|
||
| IN_B | `0x02` |
|
||
| IN_C | `0x04` |
|
||
| IN_D | `0x08` |
|
||
|
||
**Encoding (value → raw):** OR together the bit mask of every active input.
|
||
```text
|
||
raw = (IN_A ? 0x01 : 0) | (IN_B ? 0x02 : 0) | (IN_C ? 0x04 : 0) | (IN_D ? 0x08 : 0)
|
||
```
|
||
|
||
**Decoding (raw → value):** AND the raw byte with each bit mask to test whether that input is active.
|
||
```text
|
||
IN_A_active = (raw & 0x01) != 0
|
||
IN_B_active = (raw & 0x02) != 0
|
||
IN_C_active = (raw & 0x04) != 0
|
||
IN_D_active = (raw & 0x08) != 0
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Gain & Equalizer Parameters
|
||
|
||
### 5.1 Channel Gain
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Per-channel input/output gain |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | -60 dB to +12 dB |
|
||
|
||
**Quantization:**
|
||
|
||
| dB Range | Resolution |
|
||
|---|---|
|
||
| `[-60, -20)` | 0.5 dB |
|
||
| `[-20, +12]` | 0.1 dB |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
if -60 <= dB < -20:
|
||
raw = round((dB + 60) / 0.5)
|
||
if -20 <= dB <= 12:
|
||
raw = round(80 + (dB + 20) / 0.1)
|
||
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
|
||
if 0 <= raw <= 79:
|
||
dB = raw × 0.5 - 60
|
||
if 80 <= raw <= 320:
|
||
dB = (raw - 80) × 0.1 - 20
|
||
```
|
||
|
||
### 5.2 GEQ / PEQ Gain
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Graphic/parametric EQ band gain |
|
||
| **Size** | 2 bytes |
|
||
| **Range** | -12 dB to +12 dB |
|
||
| **Resolution** | 0.1 dB |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round(dB × 10 + 120)
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
dB = (raw - 120) / 10
|
||
```
|
||
|
||
| Raw | Gain |
|
||
|---|---|
|
||
| `0x00` | -12 dB |
|
||
| `0x78` | 0 dB |
|
||
| `0xF0` | +12 dB |
|
||
|
||
### 5.3 PEQ Q Factor
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Parametric EQ bandwidth (Q) |
|
||
| **Size** | 1 byte, logarithmic index |
|
||
| **Range** | 0.40 to 128.00 |
|
||
| **Raw range** | `0x00`–`0x64` (0–100) |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round(log(Q / 0.40) / log(128 / 0.40) × 100)
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
Q = 0.40 × (128 / 0.40) ^ (raw / 100)
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Dynamics Processing Parameters
|
||
|
||
### 6.1 Hold (Gate)
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Gate hold time |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | 10 ms to 999 ms |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = hold_ms - 1
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
hold_ms = raw + 1
|
||
```
|
||
|
||
### 6.2 Attack (Compressor)
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Compressor attack time |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | 1 ms to 999 ms |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = attack_ms - 1
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
attack_ms = raw + 1
|
||
```
|
||
|
||
### 6.3 Release
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Release time |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | 10 ms to 3000 ms |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = release_ms - 1
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
release_ms = raw + 1
|
||
```
|
||
|
||
### 6.4 Knee (Compressor)
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Compressor knee width |
|
||
| **Size** | 2 bytes |
|
||
| **Range** | 0 dB to 12 dB |
|
||
| **Resolution** | 1 dB |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round(knee_db)
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
knee_db = LO | (HI << 8)
|
||
```
|
||
|
||
### 6.5 Sidechain Frequency (Compressor)
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Compressor sidechain filter frequency |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | 19.70 Hz to 20160 Hz |
|
||
| **Raw range** | `0x0000`–`0x012C` |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round(log(Hz / 19.70) / log(20160 / 19.70) × 300)
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
Hz = 19.70 × (20160 / 19.70) ^ (raw / 300)
|
||
```
|
||
|
||
### 6.6 Gate Threshold Encoding
|
||
|
||
Gate threshold uses a **16-bit little-endian** value.
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Gate open/close threshold |
|
||
| **Size** | 2 bytes, little-endian |
|
||
| **Range** | `-90.0 dB` to `0.0 dB` |
|
||
| **Raw range** | `0x0000`–`0x00B4` (0–180) |
|
||
| **Resolution** | `0.5 dB` |
|
||
|
||
**Encoding (dB → raw):**
|
||
|
||
```text
|
||
raw = round((dB - (-90.0)) × 2)
|
||
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → dB):**
|
||
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
dB = -90.0 + (raw / 2)
|
||
```
|
||
|
||
### 6.7 Compressor Threshold
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Compressor threshold |
|
||
| **Size** | 2 bytes |
|
||
| **Range** | -110 dB to 0 dB |
|
||
| **Resolution** | 0.5 dB |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round((dB - (-110)) × 2)
|
||
LO = raw & 0xFF
|
||
HI = (raw >> 8) & 0xFF
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
raw = LO | (HI << 8)
|
||
dB = (raw / 2) - 110
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Delay
|
||
|
||
### 7.1 Channel Delay
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Per-channel delay |
|
||
| **Size** | 1 byte |
|
||
| **Raw range** | `0x00`–`0xFF` (0–255) |
|
||
|
||
**Range by selected unit** (see [Delay Unit](#35-delay-unit)):
|
||
|
||
| Unit | `delay_min` | `delay_max` |
|
||
|---|---|---|
|
||
| Millisecond | 0.000 ms | 680.000 ms |
|
||
| Meter | 0.000 m | 233.580 m |
|
||
| Feet | 0.000 ft | 766.329 ft |
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
raw = round((delay - delay_min) / (delay_max - delay_min) × 255)
|
||
```
|
||
|
||
**Decoding (raw → value):**
|
||
```text
|
||
delay = delay_min + (raw / 255) × (delay_max - delay_min)
|
||
```
|
||
|
||
### 7.2 Delay Unit
|
||
|
||
**Range:** `0x00`–`0x02` (3 units)
|
||
|
||
| Value | Unit |
|
||
|---|---|
|
||
| `0x00` | Millisecond |
|
||
| `0x01` | Meter |
|
||
| `0x02` | Feet |
|
||
|
||
---
|
||
|
||
## 8. Metering
|
||
|
||
### 8.1 Meter Level
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| **Purpose** | Per-channel RMS + peak metering, with clip flags |
|
||
| **Payload size** | 38 bytes (exactly; any other length is an error) |
|
||
| **Layout** | 12 channels × 3 bytes = 36 bytes, followed by 2 clip-flag bytes |
|
||
| **Channel order** | Channels 0–3 are inputs, channels 4–11 are outputs, each mapped in enum order |
|
||
|
||
#### Channel record (3 bytes, at offset `i = channel × 3`)
|
||
|
||
| Byte offset | Field | Format |
|
||
|---|---|---|
|
||
| `i + 0` | RMS low byte | Low byte of the RMS float16 |
|
||
| `i + 1` | Shared high byte | High byte of **both** the RMS and Peak float16s |
|
||
| `i + 2` | Peak low byte | Low byte of the Peak float16 |
|
||
|
||
Both values are IEEE 754 half-precision floats (little-endian pairs). The peak is not a separate 1-byte value: it reuses byte `i + 1` as its high byte, so its byte order is reversed relative to the offset order.
|
||
|
||
```text
|
||
rms_raw = float16_decode(lo = payload[i], hi = payload[i + 1])
|
||
peak_raw = float16_decode(lo = payload[i + 2], hi = payload[i + 1])
|
||
```
|
||
|
||
If a float16 fails to decode, the raw value defaults to `0.0`, which converts to `MIN_DB` (-60 dB).
|
||
|
||
#### Clip flags (bytes 36–37)
|
||
|
||
| Channel index | Flag location |
|
||
|---|---|
|
||
| 0–3 | `payload[36]`, bit `index` |
|
||
| 4–11 | `payload[37]`, bit `index - 4` |
|
||
|
||
```text
|
||
clip = (flags_byte & (1 << bit)) != 0
|
||
```
|
||
|
||
#### Raw → dB conversion
|
||
|
||
Raw values are converted with a piecewise-linear curve, then clamped.
|
||
|
||
| Constant | Value | Meaning |
|
||
|---|---|---|
|
||
| `X0` | -25.0 dB | Breakpoint |
|
||
| `Y0` | 1.0 | Raw value at the breakpoint |
|
||
| `K1` | 0.0104 | Raw units per dB below the breakpoint (`raw < Y0`) |
|
||
| `K2` | 0.0208 | Raw units per dB above the breakpoint (`raw >= Y0`) |
|
||
| `MIN_DB` | -60.0 dB | Lower clamp |
|
||
| `MAX_DB` | 12.0 dB | Upper clamp |
|
||
|
||
**Decoding (raw → dB):**
|
||
```text
|
||
if raw < Y0: db = X0 + (raw - Y0) / K1
|
||
else: db = X0 + (raw - Y0) / K2
|
||
db = clamp(db, MIN_DB, MAX_DB)
|
||
```
|
||
|
||
**Encoding (dB → raw):** the inverse of the above. Values outside the clamp range are not recoverable.
|
||
```text
|
||
db = clamp(db, MIN_DB, MAX_DB)
|
||
if db < X0: raw = Y0 + (db - X0) * K1
|
||
else: raw = Y0 + (db - X0) * K2
|
||
```
|
||
|
||
#### Full decode
|
||
|
||
```text
|
||
require len(payload) == 38
|
||
|
||
for index in 0..11:
|
||
i = index * 3
|
||
rms_db = raw_to_db(float16_decode(payload[i], payload[i + 1]))
|
||
peak_db = raw_to_db(float16_decode(payload[i + 2], payload[i + 1]))
|
||
clip = index < 4 ? payload[36] bit index
|
||
: payload[37] bit (index - 4)
|
||
meter[index] = { rms: rms_db, peak: peak_db, clip }
|
||
|
||
inputs = meter[0..3] → InputChannel enum order
|
||
outputs = meter[4..11] → OutputChannel enum order
|
||
```
|
||
|
||
---
|
||
|
||
# Command Specification
|
||
|
||
## 1. Frame Structure
|
||
|
||
Every command — query or response — shares one frame layout. Colors match the highlighted examples throughout this document:
|
||
|
||
| Field | Size | Color | Description |
|
||
|---|---|---|---|
|
||
| `STX` | 2 bytes | <span style="color:#4ea1ff">■</span> | Fixed start marker: `10 02` |
|
||
| `DIR` | 2 bytes | <span style="color:#a56eff">■</span> | Direction (see below) |
|
||
| `LEN` | 1 byte | <span style="color:#ffb347">■</span> | Byte count of `CMD + DATA` |
|
||
| `CMD` | 1 byte | <span style="color:#ff6b6b">■</span> | Command code |
|
||
| `DATA` | `LEN - 1` bytes | <span style="color:#5cd65c">■</span> | Command payload (may be 0 bytes) |
|
||
| `ETX` | 2 bytes | <span style="color:#4ea1ff">■</span> | Fixed end marker: `10 03` |
|
||
| `CS` | 1 byte | <span style="color:#ffd700">■</span> | Checksum (see below) |
|
||
|
||
Example skeleton:
|
||
|
||
<span style="color:#4ea1ff">10 02</span> <span style="color:#a56eff">DIR DIR</span> <span style="color:#ffb347">LEN</span> <span style="color:#ff6b6b">CMD</span> <span style="color:#5cd65c">DATA...</span> <span style="color:#4ea1ff">10 03</span> <span style="color:#ffd700">CS</span>
|
||
|
||
### Direction (`DIR`)
|
||
|
||
| Value | Direction |
|
||
|---|---|
|
||
| `00 XX` | Host → Device (Query) |
|
||
| `XX 00` | Device → Host (Response) |
|
||
|
||
XX represents the device Id
|
||
|
||
### Length (`LEN`)
|
||
|
||
```text
|
||
LEN = size(CMD) + size(DATA) = 1 + size(DATA)
|
||
```
|
||
|
||
### Checksum (`CS`)
|
||
|
||
The checksum is the **XOR of every byte in the frame from `DIR` through `DATA`, inclusive, with an initial seed of `0x01`**.
|
||
|
||
**Encoding (value → raw):**
|
||
```text
|
||
CS = DIR[0] ^ DIR[1] ^ LEN ^ CMD ^ DATA[0] ^ ... ^ DATA[N-1] ^ 0x01
|
||
```
|
||
|
||
**Decoding / verification (raw → check):**
|
||
```text
|
||
computed_CS = DIR[0] ^ DIR[1] ^ LEN ^ CMD ^ DATA[0] ^ ... ^ DATA[N-1] ^ 0x01
|
||
valid = (computed_CS == received_CS)
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Command Template
|
||
|
||
Every command in this document uses the same shape:
|
||
|
||
**`0xXX` — Name**
|
||
**Direction:** Host→Device / Device→Host / Both
|
||
**Category:** ...
|
||
**Purpose:** one-line description
|
||
**Sequencing:** what must precede/follow this command, if anything
|
||
**Payload Fields** — table of `Offset | Field | Size | Encoding Reference | Value/Range`
|
||
**Example** — annotated, color-coded hex frame
|
||
|
||
---
|
||
|
||
## 3. Connection & Session
|
||
|
||
### `0x01` — Acknowledgement
|
||
**Direction:** Device → Host
|
||
**Category:** Connection & Session
|
||
**Purpose:** Signals the device finished loading/processing and is ready.
|
||
**Sequencing:** Sent after any state-changing command.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| — | (none) | 0 bytes | Command has no payload |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">01</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">00</span>
|
||
|
||
---
|
||
|
||
### `0x02` — Not Implemented
|
||
**Direction:** Device → Host
|
||
**Category:** Connection & Session
|
||
**Purpose:** Signals that the command just sent is invalid/unimplemented.
|
||
**Sequencing:** Sent in place of `0x01` when a command fails to parse or is unsupported.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| — | (none) | 0 bytes | Command has no payload |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">02</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">00</span>
|
||
|
||
---
|
||
|
||
### `0x10` — Start
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Connection & Session
|
||
**Purpose:** Initiates a session with the device.
|
||
**Sequencing:** First command sent on connect.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Status | 1 byte | `0x13` = OK |
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">10</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">11</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">10</span>
|
||
<span style="color:#5cd65c">13</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">01</span>
|
||
|
||
---
|
||
|
||
### `0x11` — Disconnect
|
||
**Direction:** Host → Device
|
||
**Category:** Connection & Session
|
||
**Purpose:** Terminates the session.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| — | (none) | 0 bytes | Command has no payload |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">11</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">10</span>
|
||
|
||
---
|
||
|
||
### `0x12` — Acknowledgement (Client → Device)
|
||
**Direction:** Host → Device
|
||
**Category:** Connection & Session
|
||
**Purpose:** Client-side confirmation after loading parameters (mirrors `0x01` but in the opposite direction).
|
||
**Sequencing:** Followed by `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| — | (none) | 0 bytes | Command has no payload |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">12</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">13</span>
|
||
|
||
---
|
||
|
||
## 4. Device Info
|
||
|
||
### `0x13` — Device Name
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Device Info
|
||
**Purpose:** Reads the device's display name.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` – `Byte N-1` | Device name | 13 bytes | [Enc §2.2 Channel Name](#22-channel-name)|
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">13</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">12</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">0E</span>
|
||
<span style="color:#ff6b6b">13</span>
|
||
<span style="color:#5cd65c">44 53 50 34 30 38 20 56 30 31 30 34 50</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">45</span>
|
||
|
||
---
|
||
|
||
### `0x2C` — Device Flags
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Device Info
|
||
**Purpose:** Reads device status flags, including lock state. Not fully reverse-engineered.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Unknown | 1 byte | `00` observed |
|
||
| `Byte 2-3` | Unknown | 2 bytes | `27 0F` observed |
|
||
| `Byte 4-5` | Unknown | 2 bytes | `00 00` observed |
|
||
| `Byte 6` | Lock state | 1 byte | `01` = Locked, `00` = Unlocked |
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">2C</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">2D</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">07</span>
|
||
<span style="color:#ff6b6b">2C</span>
|
||
<span style="color:#5cd65c">00 27 0F 00 00 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">03</span>
|
||
|
||
---
|
||
|
||
## 5. Preset Management
|
||
|
||
### `0x14` — Current Preset Index
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Preset Management
|
||
**Purpose:** Reads the currently active preset.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Preset index | 1 byte | [Enc §3.1 Preset Index](#31-preset-index)|
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">14</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">15</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">14</span>
|
||
<span style="color:#5cd65c">06</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">10</span>
|
||
|
||
---
|
||
|
||
### `0x20` — Recall Preset
|
||
**Direction:** Host → Device
|
||
**Category:** Preset Management
|
||
**Purpose:** Recalls (loads) a stored preset.
|
||
**Sequencing:** Followed by `0x01` (Acknowledgement) once loading finishes.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Preset index | 1 byte | [Enc §3.1 Preset Index](#31-preset-index) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">20</span>
|
||
<span style="color:#5cd65c">10</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">32</span>
|
||
|
||
---
|
||
|
||
### `0x21` — Store Preset
|
||
**Direction:** Host → Device
|
||
**Category:** Preset Management
|
||
**Purpose:** Saves the current live settings into a preset slot.
|
||
**Sequencing:** Call `0x26` (Store Preset Name) first to set the name being saved. Must be followed by `0x12`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Preset slot | 1 byte | [Enc §3.1 Preset Index](#31-preset-index), no 0x00|
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">21</span>
|
||
<span style="color:#5cd65c">01</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x22` — Get Preset Modification Status
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Preset Management
|
||
**Purpose:** Reports which presets have unsaved/modified state.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1`–`Byte 20` | Per-preset modified flag | 1 byte each | `0xFF` = modified, `0x00` = unmodified |
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">22</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">23</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">15</span>
|
||
<span style="color:#ff6b6b">22</span>
|
||
<span style="color:#5cd65c">FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">37</span>
|
||
|
||
---
|
||
|
||
### `0x23` — Factory Reset
|
||
**Direction:** Host → Device
|
||
**Category:** Preset Management
|
||
**Purpose:** Restores factory defaults.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| — | (none) | 0 bytes | Command has no payload |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">23</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x27` / `0x24` — Config Chunk (Request / Response)
|
||
**Direction:** `0x27` Host→Device (Request), `0x24` Device→Host (Response)
|
||
**Category:** Preset Management
|
||
**Purpose:** Streams the full device configuration in indexed chunks.
|
||
**Sequencing:** Request `0x27` is followed by response `0x24`. Must be followed by `0x12`, after full batch request.
|
||
|
||
**Payload Fields — Request (`0x27`)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Chunk index | 1 byte | `0x00`–`0x1C` |
|
||
|
||
**Payload Fields — Response (`0x24`)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Sub-index | 1 bytes | `0x00`–`0x1C` |
|
||
| `Byte 2`–`Byte 51` | Configuration data | 50 bytes | binary/ASCII mixed |
|
||
|
||
**Example — Request**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">27</span>
|
||
<span style="color:#5cd65c">INDEX</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">34</span>
|
||
<span style="color:#ff6b6b">24</span>
|
||
<span style="color:#5cd65c">00 FF 00 44 65 66 61 75 6C 74 20 50 72 65 73 65 74 49 6E 41 00 00 00 00 00 00 00 63 00 63 00 00 00 78 00 78 00 78 00 78 00 78 00 78 00 78 00 78 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">BF</span>
|
||
|
||
---
|
||
|
||
### Config Data — Reassembled Payload Layout
|
||
|
||
The 50-byte pages from chunks `0x00`–`0x1C` are concatenated in index order into a single buffer before parsing. Below is that buffer's field layout, byte-for-byte, in the order fields are consumed.
|
||
|
||
**Legend (protocol constants used below)**
|
||
|
||
| Symbol | Meaning |
|
||
|---|---|
|
||
| `PNL` | `PRESET_NAME_LENGTH` |
|
||
| `CNL` | `CHANNEL_NAME_LENGTH` |
|
||
| `N_IN` | number of input channels (`len(INPUT_ORDER)`) |
|
||
| `N_OUT` | number of output channels (`len(OUTPUT_ORDER)`) |
|
||
| `N_FREQ` | number of GEQ bands (`len(list(FrequencyValue))`) |
|
||
| `N_PEQ_IN` | number of input PEQ bands (`len(PEQ_INPUT_BANDS)`) |
|
||
| `N_PEQ_OUT` | number of output PEQ bands (`len(PEQ_OUTPUT_BANDS)`) |
|
||
|
||
**Header**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `0x00` | Flags (unused) | 2 bytes | reserved |
|
||
| `0x02` | Preset name | `PNL` bytes | ASCII, raw → `raw_to_preset_name` |
|
||
|
||
**Per Input Channel — repeats `N_IN` times**
|
||
|
||
| Offset (within block) | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `+0x00` | Channel name | `CNL` bytes | ASCII, raw → `raw_to_channel_name` |
|
||
| `+CNL` | Gate: attack | 2 bytes | `u16` → `raw_to_attack_ms` |
|
||
| `+CNL+2` | Gate: release | 2 bytes | `u16` → `raw_to_release_ms` |
|
||
| `+CNL+4` | Gate: hold | 2 bytes | `u16` → `raw_to_hold_ms` |
|
||
| `+CNL+6` | Gate: threshold | 2 bytes | `u16` → `raw_to_threshold_db` |
|
||
| `+CNL+8` | GEQ gains | `2 × N_FREQ` bytes | `N_FREQ` × `u16` → `raw_to_eq_gain` |
|
||
| `+CNL+8+2·N_FREQ` | PEQ chain | `6 × N_PEQ_IN` bytes | `N_PEQ_IN` bands, each: `u16` gain, `u16` freq, `u8` Q, `u8` filter type |
|
||
| … | Crossover: HP freq | 2 bytes | `u16` → `raw_to_frequency_hz` |
|
||
| … | Crossover: LP freq | 2 bytes | `u16` → `raw_to_frequency_hz` |
|
||
| … | Crossover: HP slope | 1 byte | `u8` → `raw_to_crossover_filter` |
|
||
| … | Crossover: LP slope | 1 byte | `u8` → `raw_to_crossover_filter` |
|
||
| … | Channel gain | 2 bytes | `u16` → `raw_to_channel_gain` |
|
||
| … | Phase inverted | 1 byte | `u8` bool |
|
||
| … | Reserved | 2 bytes | skipped |
|
||
| … | Delay (raw) | 1 byte | `u8`, resolved via `raw_to_delay(value, delay_unit)` once the header-level delay unit is parsed |
|
||
| … | Linked channels | 2 bytes | `u16` bitmap → `raw_to_link_channels` |
|
||
|
||
Per-channel block size: `CNL + 2·N_FREQ + 6·N_PEQ_IN + 22` bytes.
|
||
|
||
**Per Output Channel — repeats `N_OUT` times** (immediately follows the last input channel block)
|
||
|
||
| Offset (within block) | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `+0x00` | Channel name | `CNL` bytes | ASCII, raw → `raw_to_channel_name` |
|
||
| … | Matrix: connected | 2 bytes | `u16` bitmap → `raw_to_matrix` |
|
||
| … | Matrix: gains | 8 bytes | 4 × `u16` → `raw_to_matrix_gain` |
|
||
| … | Crossover (HP/LP freq + slope) | 6 bytes | same layout as input crossover |
|
||
| … | PEQ chain | `6 × N_PEQ_OUT` bytes | `N_PEQ_OUT` bands, same per-band layout as input |
|
||
| … | Compressor: ratio | 2 bytes | `u16` → `raw_to_ratio` |
|
||
| … | Compressor: attack | 2 bytes | `u16` → `raw_to_attack_ms` |
|
||
| … | Compressor: release | 2 bytes | `u16` → `raw_to_release_ms` |
|
||
| … | Compressor: knee | 2 bytes | `u16` → `raw_to_knee_db` |
|
||
| … | Compressor: threshold | 2 bytes | `u16` → `raw_to_threshold_db` |
|
||
| … | Limiter: attack | 2 bytes | `u16` → `raw_to_attack_ms` |
|
||
| … | Limiter: release | 2 bytes | `u16` → `raw_to_release_ms` |
|
||
| … | Reserved | 2 bytes | skipped |
|
||
| … | Limiter: threshold | 2 bytes | `u16` → `raw_to_threshold_db` |
|
||
| … | Channel gain | 2 bytes | `u16` → `raw_to_channel_gain` |
|
||
| … | Phase inverted | 1 byte | `u8` bool |
|
||
| … | Reserved | 2 bytes | skipped |
|
||
| … | Delay (raw) | 1 byte | `u8`, resolved via `raw_to_delay(value, delay_unit)` |
|
||
| … | Linked channels | 2 bytes | `u16` bitmap → `raw_to_link_channels` |
|
||
|
||
Per-channel block size: `CNL + 6·N_PEQ_OUT + 42` bytes.
|
||
|
||
**Global Flags** (immediately follows the last output channel block)
|
||
|
||
| Offset (within section) | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `+0x00` | Input mute bitmap | 2 bytes | `u16`, bit *i* = `INPUT_ORDER[i]` muted |
|
||
| `+0x02` | Output mute bitmap | 2 bytes | `u16`, bit *i* = `OUTPUT_ORDER[i]` muted |
|
||
| `+0x04` | Input PEQ band mute | `2 × N_IN` bytes | one `u16` per input channel, bit *j* = `PEQ_INPUT_BANDS[j]` bypassed |
|
||
| `+0x04+2·N_IN` | Output PEQ band mute | `2 × N_OUT` bytes | one `u16` per output channel, bit *j* = `PEQ_OUTPUT_BANDS[j]` bypassed |
|
||
|
||
**Input Source & Delay Unit** (immediately follows Global Flags)
|
||
|
||
| Offset (within section) | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `+0x00` | Input source type | 2 bytes | `u16` → `raw_to_input_source` |
|
||
| `+0x02` | Input source frequency | 2 bytes | `u16` → `raw_to_frequency_value` |
|
||
| `+0x04` | Delay unit | 2 bytes | `u16` → `raw_to_delay_unit` (applies to all previously-read raw delay bytes) |
|
||
|
||
**Trailing Bypass Flags** (immediately follows Input Source & Delay Unit)
|
||
|
||
| Offset (within section) | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `+0x00` | Input PEQ chain bypass bitmap | 2 bytes | `u16`, bit *i* = `INPUT_ORDER[i]`'s PEQ chain bypassed |
|
||
| `+0x02` | Output PEQ chain bypass bitmap | 2 bytes | `u16`, bit *i* = `OUTPUT_ORDER[i]`'s PEQ chain bypassed |
|
||
| `+0x04` | Input GEQ bypass bitmap | 2 bytes | `u16`, bit *i* = `INPUT_ORDER[i]`'s GEQ bypassed |
|
||
|
||
**Total reassembled payload size:**
|
||
`2 + PNL + N_IN·(CNL + 2·N_FREQ + 6·N_PEQ_IN + 22) + N_OUT·(CNL + 6·N_PEQ_OUT + 42) + 4 + 2·N_IN + 2·N_OUT + 4 + 2 + 6` bytes.
|
||
|
||
---
|
||
|
||
### `0x26` — Store Preset Name
|
||
**Direction:** Host → Device
|
||
**Category:** Preset Management
|
||
**Purpose:** Sets the working preset name prior to saving.
|
||
**Sequencing:** Call before `0x21` (Store Preset).
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1`–`Byte 14` | Preset name | 14 bytes | [Enc §2.1 Preset Name](#21-preset-name) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0F</span>
|
||
<span style="color:#ff6b6b">26</span>
|
||
<span style="color:#5cd65c">50 72 65 73 65 74 20 4E 61 6D 65 20 20 20</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x29` — Get Preset Name
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Preset Management
|
||
**Purpose:** Reads the name of a given preset.
|
||
|
||
**Payload Fields — Query**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Preset index | 1 byte | [Enc §3.1 Preset Index](#31-preset-index) |
|
||
|
||
**Payload Fields — Response**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1`–`Byte N` | Preset name | 14 bytes | [Enc §2.1 Preset Name](#21-preset-name) |
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">29</span>
|
||
<span style="color:#5cd65c">00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">2B</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">10</span>
|
||
<span style="color:#ff6b6b">29</span>
|
||
<span style="color:#5cd65c">4D 61 69 6E 20 70 72 65 73 65 74 20 20 20</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">17</span>
|
||
|
||
---
|
||
|
||
## 6. Security
|
||
|
||
### `0x2D` — Unlock Device
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Security
|
||
**Purpose:** Authenticates with a password to unlock the device.
|
||
|
||
**Payload Fields — Query**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Unknown | 1 byte | `00` observed |
|
||
| `Byte 2`–`Byte N` | Password | 4 bytes | [Enc §2.3 Password](#23-password) |
|
||
|
||
**Payload Fields — Response**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Status category | 1 byte | `00` observed |
|
||
| `Byte 2` | Authentication result | 1 byte | `00` = Failed, `01` = Success |
|
||
|
||
**Example — Query (password `1234`)**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">06</span>
|
||
<span style="color:#ff6b6b">2D</span>
|
||
<span style="color:#5cd65c">00 31 32 33 34</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">2F</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">2D</span>
|
||
<span style="color:#5cd65c">00 01</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">2F</span>
|
||
|
||
---
|
||
|
||
### `0x2F` — Lock Device
|
||
**Direction:** Host → Device
|
||
**Category:** Security
|
||
**Purpose:** Locks the device behind a password.
|
||
**Sequencing:** Followed by `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1`–`Byte N` | Password | 4 bytes | [Enc §2.3 Password](#23-password) |
|
||
|
||
**Example (password `1234`)**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">05</span>
|
||
<span style="color:#ff6b6b">2F</span>
|
||
<span style="color:#5cd65c">31 32 33 34</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">2E</span>
|
||
|
||
---
|
||
|
||
## 7. Channel Configuration
|
||
|
||
### `0x2A` — Copy Channel
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Configuration
|
||
**Purpose:** Copies one channel's settings onto another.
|
||
**Sequencing:** Followed by `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Source channel | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Destination channel | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">2A</span>
|
||
<span style="color:#5cd65c">00 01</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">28</span>
|
||
|
||
---
|
||
|
||
### `0x3B` — Link Channel
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Configuration
|
||
**Purpose:** Groups channels so they move together.
|
||
**Sequencing:** Followed by `0x01`. Use `0x2A` (Copy Channel) before linking channels with `0x3B`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Link mask | 1 byte | Bitmask — same OR pattern as [Enc §4.1 Matrix Input Mask](#41-matrix-input-mask), generalized to the channel's own bit position |
|
||
|
||
**Link mask rule:** bit `N` set → channel `N` is linked to this channel.
|
||
|
||
| Value | Meaning |
|
||
|---|---|
|
||
| `0x00` | No linked channels |
|
||
| `0x01`–`0x0F` | Valid range for input channels (bits 0–3 only) |
|
||
| `0x01`–`0xFF` | Valid range for output channels (bits 0–7) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">3B</span>
|
||
<span style="color:#5cd65c">03 08</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">33</span>
|
||
|
||
(Channel `0x03`, link mask `0x08` → linked to channel 3)
|
||
|
||
---
|
||
|
||
### `0x3D` — Set Channel Name
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Configuration
|
||
**Purpose:** Sets the display name of an output channel.
|
||
**Sequencing:** Followed by `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Output channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2`–`Byte 9` | Channel name | 8 bytes | [Enc §2.2 Channel Name](#22-channel-name) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0A</span>
|
||
<span style="color:#ff6b6b">3D</span>
|
||
<span style="color:#5cd65c">CH NAME[8]</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
## 8. Channel Processing
|
||
|
||
### `0x15` — Set Delay Unit
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Changes the display unit used for delay values.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Delay unit | 1 byte | [Enc §3.5 Delay Unit](#72-delay-unit) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">15</span>
|
||
<span style="color:#5cd65c">01</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x34` — Set Gain
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Sets a channel's gain.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Gain | 2 bytes, little-endian | [Enc §5.1 Channel Gain](#51-channel-gain) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">04</span>
|
||
<span style="color:#ff6b6b">34</span>
|
||
<span style="color:#5cd65c">CH LO HI</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x35` — Set Mute
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Mutes or unmutes a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Mute state | 1 byte | `0x00` = Unmuted, `0x01` = Muted |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">35</span>
|
||
<span style="color:#5cd65c">CH MUTE</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x36` — Invert Gain
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Inverts polarity on a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Invert state | 1 byte | `0x00` = Normal, `0x01` = Inverted |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">36</span>
|
||
<span style="color:#5cd65c">CH INVERT</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x38` — Set Delay
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Sets a channel's delay value.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Reserved | 1 byte | Always `0x00` |
|
||
| `Byte 3` | Delay | 1 byte | [Enc §7.1 Channel Delay](#71-channel-delay) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">04</span>
|
||
<span style="color:#ff6b6b">38</span>
|
||
<span style="color:#5cd65c">CH 00 DELAY</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x3C` — Bypass EQ
|
||
**Direction:** Host → Device
|
||
**Category:** Channel Processing
|
||
**Purpose:** Enables or bypasses all EQ processing on a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | EQ bypass state | 1 byte | `0x00` = Active, `0x01` = Bypassed |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">3C</span>
|
||
<span style="color:#5cd65c">CH BYPASS</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
## 9. Dynamics
|
||
|
||
### `0x30` — Set Compressor
|
||
**Direction:** Host → Device
|
||
**Category:** Dynamics
|
||
**Purpose:** Sets compressor parameters for a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Ratio | 2 bytes, little-endian | [Enc §3.6 Compressor Ratio](#36-compressor-ratio) |
|
||
| `Byte 4-5` | Attack | 2 bytes, little-endian | [Enc §6.2 Attack](#62-attack-compressor) |
|
||
| `Byte 6-7` | Release | 2 bytes, little-endian | [Enc §6.3 Release](#63-release-compressor) |
|
||
| `Byte 8-9` | Knee | 2 bytes, little-endian | [Enc §6.4 Knee](#64-knee-compressor) |
|
||
| `Byte 10-11` | Threshold | 2 bytes, little-endian | [Enc §6.7 Compressor Threshold](#67-compressor-threshold) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0C</span>
|
||
<span style="color:#ff6b6b">30</span>
|
||
<span style="color:#5cd65c">CH RA 00 AT_LO AT_HI RE_LO RE_HI KN 00 TH 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x3E` — Set Gate Parameters
|
||
**Direction:** Host → Device
|
||
**Category:** Dynamics
|
||
**Purpose:** Sets noise-gate parameters for a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Attack | 2 bytes, little-endian | [Enc §6.2 Attack](#62-attack-compressor) |
|
||
| `Byte 4-5` | Release | 2 bytes, little-endian | [Enc §6.3 Release](#63-release-compressor) |
|
||
| `Byte 6-7` | Hold | 2 bytes, little-endian | [Enc §6.1 Hold](#61-hold-gate) |
|
||
| `Byte 8-9` | Threshold | 2 bytes, little-endian | [Enc §6.6 Gate Threshold](#66-gate-threshold) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0A</span>
|
||
<span style="color:#ff6b6b">3E</span>
|
||
<span style="color:#5cd65c">CH AT 00 RE_LO RE_HI HO_LO HO_HI GA 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">82</span>
|
||
|
||
---
|
||
|
||
### `0x3F` — Set Output Limiter
|
||
**Direction:** Host → Device
|
||
**Category:** Dynamics
|
||
**Purpose:** Sets output-limiter parameters. Output channels only.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Output channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Attack | 2 bytes, little-endian | [Enc §6.2 Attack](#62-attack-compressor) |
|
||
| `Byte 4-5` | Release | 2 bytes, little-endian | [Enc §6.3 Release](#63-release-compressor) |
|
||
| `Byte 6-7` | Reserved | 2 bytes | Always `0000` |
|
||
| `Byte 8-9` | Threshold | 2 bytes, little-endian | [Enc §6.7 Compressor Threshold](#67-compressor-threshold) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0A</span>
|
||
<span style="color:#ff6b6b">3F</span>
|
||
<span style="color:#5cd65c">CH AT_LO AT_HI RE_LO RE_HI 00 00 TH 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
## 10. Filters & EQ
|
||
|
||
### `0x31` — Set Low-Pass Filter
|
||
**Direction:** Host → Device
|
||
**Category:** Filters & EQ
|
||
**Purpose:** Sets the low-pass filter for a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Cutoff frequency | 2 bytes, little-endian | [Enc §6.5 Sidechain Frequency](#65-sidechain-frequency-compressor) |
|
||
| `Byte 4` | Filter type | 1 byte | [Enc §3.9 Crossover Slope](#39-crossover-slope) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">04</span>
|
||
<span style="color:#ff6b6b">31</span>
|
||
<span style="color:#5cd65c">CH FREQ_LO FREQ_HI TYPE</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x32` — Set High-Pass Filter
|
||
**Direction:** Host → Device
|
||
**Category:** Filters & EQ
|
||
**Purpose:** Sets the high-pass filter for a channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2-3` | Cutoff frequency | 2 bytes, little-endian | [Enc §6.5 Sidechain Frequency](#65-sidechain-frequency-compressor) |
|
||
| `Byte 4` | Filter type | 1 byte | [Enc §3.9 Crossover Slope](#39-crossover-slope) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">04</span>
|
||
<span style="color:#ff6b6b">32</span>
|
||
<span style="color:#5cd65c">CH FREQ_LO FREQ_HI TYPE</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x33` — Set PEQ Band
|
||
**Direction:** Host → Device
|
||
**Category:** Filters & EQ
|
||
**Purpose:** Sets one parametric EQ band. Input channels only.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | PEQ band index | 1 byte | [Enc §3.3 PEQ Band Index](#33-peq-band-index) |
|
||
| `Byte 3-4` | Gain | 2 bytes, little-endian | [Enc §5.2 GEQ/PEQ Gain](#52-geq--peq-gain) |
|
||
| `Byte 5-6` | Frequency | 2 bytes, little-endian | [Enc §6.5 Sidechain Frequency](#65-sidechain-frequency-compressor)
|
||
| `Byte 7` | Q factor | 1 byte | [Enc §5.3 PEQ Q Factor](#53-peq-q-factor) | `0x00`–`0x64` |
|
||
| `Byte 8` | Filter type | 1 byte | [Enc §3.8 PEQ Filter Type](#38-peq-filter-type) | `0x00`–`0x08` |
|
||
| `Byte 9` | Bypass | 1 byte | `0x00` = Enabled, `0x01` = Bypassed |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">0A</span>
|
||
<span style="color:#ff6b6b">33</span>
|
||
<span style="color:#5cd65c">CH BAND GAIN 00 FREQ_LO FREQ_HI Q TYPE BYPASS</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x48` — Set GEQ Band
|
||
**Direction:** Host → Device
|
||
**Category:** Filters & EQ
|
||
**Purpose:** Sets one band of a 31-band graphic EQ. Input channels only.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | GEQ band index | 1 byte | [Enc §3.4 Frequency Band Index](#34-frequency-band-index) |
|
||
| `Byte 3-4` | Gain | 2 bytes, little-endian | [Enc §5.2 GEQ/PEQ Gain](#52-geq--peq-gain) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">05</span>
|
||
<span style="color:#ff6b6b">48</span>
|
||
<span style="color:#5cd65c">CH BAND DB 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x49` — Set GEQ Bypass
|
||
**Direction:** Host → Device
|
||
**Category:** Filters & EQ
|
||
**Purpose:** Enables or bypasses the graphic EQ on an input channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Bypass | 1 byte | `0x00` = GEQ enabled, `0x01` = GEQ bypassed |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">02</span>
|
||
<span style="color:#ff6b6b">49</span>
|
||
<span style="color:#5cd65c">CH BP</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
## 11. Input & Routing
|
||
|
||
### `0x39` — Set Input Source
|
||
**Direction:** Host → Device
|
||
**Category:** Input & Routing
|
||
**Purpose:** Selects the analog/test signal source.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Source type | 1 byte | [Enc §3.7 Input Source Type](#37-input-source-type) |
|
||
| `Byte 2` | Sine wave frequency (only meaningful when `Byte 1 = 0x03`) | 1 byte | [Enc §3.4 Frequency Band Index](#34-frequency-band-index) |
|
||
|
||
**Examples**
|
||
|
||
Analog:
|
||
<span style="color:#4ea1ff">10 02</span> <span style="color:#a56eff">00 01</span> <span style="color:#ffb347">03</span> <span style="color:#ff6b6b">39</span> <span style="color:#5cd65c">00 00</span> <span style="color:#4ea1ff">10 03</span> <span style="color:#ffd700">3A</span>
|
||
|
||
Pink Noise:
|
||
<span style="color:#4ea1ff">10 02</span> <span style="color:#a56eff">00 01</span> <span style="color:#ffb347">03</span> <span style="color:#ff6b6b">39</span> <span style="color:#5cd65c">01 00</span> <span style="color:#4ea1ff">10 03</span> <span style="color:#ffd700">3B</span>
|
||
|
||
White Noise:
|
||
<span style="color:#4ea1ff">10 02</span> <span style="color:#a56eff">00 01</span> <span style="color:#ffb347">03</span> <span style="color:#ff6b6b">39</span> <span style="color:#5cd65c">02 00</span> <span style="color:#4ea1ff">10 03</span> <span style="color:#ffd700">38</span>
|
||
|
||
Sine Wave:
|
||
<span style="color:#4ea1ff">10 02</span> <span style="color:#a56eff">00 01</span> <span style="color:#ffb347">03</span> <span style="color:#ff6b6b">39</span> <span style="color:#5cd65c">03 XX</span> <span style="color:#4ea1ff">10 03</span> <span style="color:#ffd700">YY</span>
|
||
|
||
---
|
||
|
||
### `0x3A` — Matrix Routing
|
||
**Direction:** Host → Device
|
||
**Category:** Input & Routing
|
||
**Purpose:** Sets which inputs feed a given output channel.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Output channel | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Input routing mask | 1 byte | [Enc §4.1 Matrix Input Mask](#41-matrix-input-mask) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">03</span>
|
||
<span style="color:#ff6b6b">3A</span>
|
||
<span style="color:#5cd65c">OUT INPUT_MASK</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
### `0x41` — Set Matrix Gain
|
||
**Direction:** Host → Device
|
||
**Category:** Input & Routing
|
||
**Purpose:** Sets the send gain from one input to one output.
|
||
**Sequencing:** Device acknowledges with `0x01`.
|
||
|
||
**Payload Fields**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1` | Output channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 2` | Input channel index | 1 byte | [Enc §3.2 Channel Index](#32-channel-index) |
|
||
| `Byte 3-4` | Gain | 2 bytes, little-endian | [Enc §5.1 Channel Gain](#51-channel-gain) |
|
||
|
||
**Example**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">05</span>
|
||
<span style="color:#ff6b6b">41</span>
|
||
<span style="color:#5cd65c">CH_OUT CH_IN GAIN_LO GAIN_HI</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">CS</span>
|
||
|
||
---
|
||
|
||
## 12. Metering
|
||
|
||
### `0x40` — Get Level Meters
|
||
**Direction:** Host → Device (Query), Device → Host (Response)
|
||
**Category:** Metering
|
||
**Purpose:** Reads current level-meter and clip-indicator values for all channels.
|
||
|
||
**Payload Fields (Response only)**
|
||
|
||
| Offset | Field | Size | Encoding |
|
||
|---|---|---|---|
|
||
| `Byte 1-36` | 12 meter channels | 3 bytes × 12 | [Enc §8.1 Meter Level](#81-meter-level) |
|
||
| `Byte 37` | Input clip indicator | 1 byte bitmask | Same OR bitmask pattern as [Enc §4.1](#41-matrix-input-mask) |
|
||
| `Byte 38` | Output limit indicator | 1 byte bitmask | Same OR bitmask pattern as [Enc §4.1](#41-matrix-input-mask) |
|
||
|
||
**Example — Query**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">00 01</span>
|
||
<span style="color:#ffb347">01</span>
|
||
<span style="color:#ff6b6b">40</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">41</span>
|
||
|
||
**Example — Response**
|
||
|
||
<span style="color:#4ea1ff">10 02</span>
|
||
<span style="color:#a56eff">01 00</span>
|
||
<span style="color:#ffb347">27</span>
|
||
<span style="color:#ff6b6b">40</span>
|
||
<span style="color:#5cd65c">A2 36 A5 A0 36 A0 ... 39 00 00</span>
|
||
<span style="color:#4ea1ff">10 03</span>
|
||
<span style="color:#ffd700">75</span>
|
||
|
||
---
|