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

01 — Overview: hardware, transport, software

The device

ProductSORAN Dual Stomp Lite (same firmware family as Dual Stomp and Tiny Stomp)
USB IDsVID 0x3962, PID 0x2000
USB stringsManufacturer “SORAN”, Product “JME STOMPBOX”, serial = a date-like string
USB speedHigh-speed (480 Mb/s)
Firmware testedV1.1.1 (pedal reports V1.1.1 / JME-01)
MCUNXP i.MX RT10xx (Cortex-M7), per firmware strings
VendorThe app and firmware are by NUX (Cherub). Bundle id com.jiyou.stompManager, NUX build paths, NUX DFU container

USB interfaces (all class compliant)

IfClassPurposeLinux driver
0Audio Control (UAC2, protocol 0x20)audio interfacesnd-usb-audio
1, 2Audio Streaming (UAC2)playback / capturesnd-usb-audio
3Audio Control (MIDI)snd-usb-audio
4MIDI Streamingall control trafficsnd-usb-audio → ALSA rawmidi/seq

There is no vendor-specific interface. Everything the editor does goes over standard USB-MIDI, so on Linux you need no kernel driver, no libusb and no udev rule beyond ALSA access. The device will show up in amidi -l / aconnect -l as “JME STOMPBOX”.

Firmware updates are different: they use a separate NUX “Device Firmware Updater” over USB HID in DFU mode. That is out of scope here.

Bluetooth: with Wireless on, the pedal also speaks BLE-MIDI as “JME STOMPBOX” (service 03b80e5a-ede8-4b33-a751-6ce34ec4c700, characteristic 7772e5db-3868-4112-a1a9-f2669d106bf3), with exactly the same messages as over USB, only in BLE-MIDI framing. Confirmed on V1.1.1: the full startup sync, every live control, preset switching and acked SysEx writes (examples/ble_check.rs). Two differences: the pedal can’t take unpaced bursts (61 CCs sent back to back froze it until a power cycle; the official app sends CCs ≥ 11 ms apart), and replies take 40–240 ms (median 95 ms) instead of about 1 ms, so the startup sync takes about 19 s. The official app doesn’t import NAM models or IRs over Bluetooth, but the pedal takes them: a NAM import (62 acked writes) took 10.5 s and an IR import 12.4 s, and both slot names read back. The separate classic-Bluetooth “headset” (A2DP/AVRCP) device is the pedal’s Bluetooth audio, not MIDI.

Protocol in one paragraph

Live control is plain MIDI: the pedal reports on channel 1 and the host commands on channel 2, with the same CC numbers. Every module has a “head” CC = (off?0x40:0) | model plus a block of parameter CCs whose values are the 0–100 numbers the app shows. Presets switch with Program Change. Bulk data (whole presets, names, global settings, looper/drum/tuner records, NAM/IR uploads) goes over vendor SysEx F0 00 21 7A 70 <cmd> <dir> … F7 with read (0) / write (1) / reply (2) / ack (3), strictly request → response. Larger records are 8-bit structs packed into a 7-bit little-endian bitstream.

Cheat sheet

USB3962:2000, class-compliant UAC2 + USB-MIDI, no vendor interface
ChannelsPedal → host on channel 1, host → pedal on channel 2, same CC numbers both ways
Head CCs(off ? 0x40 : 0) | model: OD/FX 0x00, AMP 0x01, CAB 0x02, MOD 0x03, DLY 0x04, RVB 0x05, GATE 0x06, EQ 0x07
Parameter CCsOD/FX 0x0C–0F, GATE 0x08–09, AMP 0x12–17, CAB 0x1A–1E, EQ 0x20–2B, MOD 0x2C–2F, DLY 0x30–33, RVB 0x36–39; VOL 0x3A, page 0x3B
PresetsProgram Change 0–98 = P01–P99
SysExF0 00 21 7A 70 <cmd> <dir> … F7; dir 0 read, 1 write, 2 reply, 3 ack; 7E notify
Commands09 IR slot, 0B preset, 0C edit buffer, 10 IR data, 12 name, 14 settings, 15 state, 18 looper, 19 drum, 58 user amp (NAM), 6F tuner
Packed records7-bit LSB-first bitstream (126 MIDI bytes ↔ 110 struct bytes for a preset)
User IRsThe pedal plays only the first 384 taps (ir::PEDAL_IR_TAPS)

The official app (what we reversed)

AppStomp Manager 1.0.2 (build 1), macOS universal
FrameworkFlutter (Dart 3.12.2 AOT, obfuscated)
MIDIflutter_midi_command (CoreMIDI)
BLEuniversal_ble
Native libsnux_plugins (JUCE audio-file → 48 kHz WAV for IRs), imagelib (NeuralAmpModelerCore: NAM → device format), nux_helper (trivial)
LinuxThe dependency list includes flutter_midi_command_linux and bluez, so the vendor builds for Linux internally but doesn’t ship it

App UI layout (for reference when building a clone):

  • Left: preset list P01–P99 with save / import / export icons.
  • Top: VOL slider, connection indicator, tuner, settings (wrench).
  • Signal chain: GATE → OD/FX → AMP → CAB → EQ → MOD → DEL → REV → LOOP → DRUM (coloured = on).
  • Edit panel: module list → model list → parameter sliders and an ON/OFF toggle.
  • Settings: Input Trim, Global EQ (Bass/Mid/Treble), Wireless, LoopBack, Language, version info.

Document map

DocContents
02-midi-cc-reference.mdEvery CC/PC, all modules/models/params, looper/drum/tuner
03-sysex-protocol.mdFraming, command table, handshake, encodings, captured sequences
04-data-structures.mdPreset (110 B), settings, IR/NAM slot info, drum/loop/tuner records
05-uploads-nam-ir.mdNAM/IR upload transport and what’s known about the conversion
06-rust-linux-guide.mdTalking to the pedal from Rust and Linux: crates, architecture, protocol code
07-capture-methodology.mdHow the captures were made; how to make more
08-static-analysis.mdStatic analysis of the app binary, firmware and native libs
09-open-questions.mdWhat is still unknown and how to find out
10-library-guide.mdThe open-stomp crate: API guide, engine, recipes, testing without a pedal
11-python-guide.mdThe Python bindings (import open_stomp)