Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

04 — Data structures

Offsets are into the unpacked struct (after the 8-in-7 decoding in 03) unless the record is marked plain.

Preset — SysEx 0x0B (by index) and 0x0C (edit buffer)

126 packed MIDI bytes → 110 struct bytes. Layout derived by correlating all 99 presets read at startup with the CC values the pedal sent after program changes (tools/decode/preset_layout.py). Offsets marked ✔ were confirmed by that correlation; ✓ by constant/structural evidence; ? unknown.

OffsetSizeFieldNotes
01preset index0-based (P01 = 0). 0x0C reads return 0 here
1–770reserved / header
810x62 (98)constant in all presets (number of presets − 1? version?) ?
9–1130
121OD/FX head= CC 0x00 (bit 6 = off, bits 0–5 = model) ✔
131AMP head= CC 0x01 ✔
141CAB head= CC 0x02 ✔
151MOD head= CC 0x03 ✔
161DELAY head= CC 0x04 ✔
171REVERB head= CC 0x05 ✔
181GATE head= CC 0x06 ✔
191EQ head= CC 0x07 ✔
201GATE param count (2)✓
21–222GATE THRESHOLD, DECAY= CC 0x08, 0x09 ✔
23–242pad
251OD/FX param count (2–4)✓
26–294OD/FX params 1–4= CC 0x0C–0x0F ✔
30–312pad
321AMP param count (6)✓
33–386AMP GAIN…MASTER= CC 0x12–0x17 ✔
39–402pad
411CAB param count (5)✓
42–465CAB MIC, POSITION, LOW CUT, HIGH CUT, VOLUME= CC 0x1A–0x1E ✔
471pad
481EQ param count (6 or 12)✓
49–6012EQ bands= CC 0x20–0x2B ✔
611MOD param count (1–4)✓
62–654MOD params= CC 0x2C–0x2F ✔
661DELAY param count (3–4)✓
67–704DELAY params= CC 0x30–0x33 ✓ (by pattern)
71–722pad
731REVERB param count (2–4)✓
74–774REVERB params= CC 0x36–0x39 ✔
781VOL= CC 0x3A (80 in every factory preset) ✓
79–8130? (BPM / flags?)
8216constant ? (chain length − 1?)
83–897signal-chain ordermodule indices, e.g. 00 01 02 07 03 04 05 = OD/FX, AMP, CAB, EQ, MOD, DLY, RVB. Varies per preset ✓
90–9340?
94–10916nameASCII, zero padded ✔

Notes:

  • The param-count bytes equal the selected model’s number of parameters; the official app keeps them consistent with the model. Unused param bytes keep stale values.
  • Packing: the whole 126-byte body (from the index byte onwards) is one packed stream.
  • The static analysis found a related layout from a sibling product (NBA150PPresetStruct: 11 heads, [model, p…] arrays, userName[16]…). The Dual Stomp Lite layout above is similar in spirit but not identical; trust the table above.

System settings — SysEx 0x14

20 packed bytes → 17 struct bytes. Factory values: 00 0A 1E 0A 32 32 32 32 32 01 01 3C B4 00 00 00 00.

OffsetFieldValuesStatus
0?0
1Input Trim0–20 → −10…+10 dB (10 = 0 dB)confirmed
2?30
3?10
4Global EQ Bass0–100 (50 centre)confirmed
5Global EQ Mid0–100confirmed
6Global EQ Treble0–100confirmed
7, 8?50, 50
9Wireless0 off, 1 onconfirmed
10LoopBack0 off, 1 onconfirmed
11?60(energy-saving timeout? guess)
12?180
13–16?0

Always read, modify, write back, like the official app. Global EQ changed on the pedal is not reported over USB.

User IR slot info — SysEx 0x09

read:   70 09 00 <slot>                      (slot 0..9)
reply:  70 09 02 <slot> <packed record>      (43 MIDI bytes total payload)
write:  70 09 01 <slot> <packed record>

Unpacked record: [0..3] = 4 bytes (CRC?), [4..] = name (ASCII, zero padded; field is probably 32 bytes, per the static NBA150PIrNameStruct). Empty slot: 00 00 00 00 "--------". After an IR upload the app wrote 01 00 00 00 "Delay And Reverb", so the 4-byte field was 1 there. Whether it is a real CRC is open.

User AMP (NAM) slot info — SysEx 0x58, sub-command “read info”

read:   70 58 00 <packed: 00 <slot> 04 00 ...>
reply:  70 58 02 <packed, 160 MIDI bytes>

Unpacked reply: [0]=0, [1]=slot, [2]=4 (sub-cmd), [8]=0x80, [12..]= name "USER AMP 01"…, zero padded. More fields follow (a 01 at offset ~45). Full upload protocol: 05.

Current state — SysEx 0x15 (plain)

Reply payload: 50 01 00 00 00 00 00 00. 0x50 = 80 (likely VOL, guess), 01 unknown.

Looper — SysEx 0x18 (plain)

Payload: 01 32 32 <state> 00 …. Byte 0 = 1 (?), byte 1 = REC level (50), byte 2 = PLAYBACK level (50), byte 3 = looper state (same encoding as CC 0x44). The app reads it when the loop panel opens and writes the first 5 bytes back unchanged.

Drum — SysEx 0x19 (plain)

Payload (read reply, 8 bytes): 00 00 32 00 00 78 00 00

ByteField
0? (0)
1pattern (flat, style*10+pattern, = CC 0x40)
2level (= CC 0x41)
3? (0)
4–5BPM, 14-bit: (b4 << 7) | b5 (00 78 = 120)

The notification form is 70 7E 02 19 02 <same 6 bytes>.

Tuner — SysEx 0x6F (plain)

Payload: <status> 00 0A 00 00. status 1 = tuner active, 0 = off. 0x0A is probably the A4 reference (maybe 430 + 10 = 440 Hz, guess). Static field names: status, mode, pitch, mute. Live pitch data comes as CCs 0x45/0x46/0x48.