A modern web GUI for configuring the Expert Sleepers ES-9 Eurorack audio interface — a nicer-looking replacement for the official config tool.
Use it now: https://frysch.github.io/es9-gui/ — plug in the ES-9, open the page in a Chromium-based browser (Chrome, Edge, Arc, Brave), and allow MIDI access. Everything runs locally in your browser; nothing about your device leaves it. For ES-9 firmware 1.3.x (config version 3).
- Monitor (default view) — just the mixes routed to Main Out and Phones, one continuous strip surface per destination
- Routing — per-channel source/destination selects for USB audio, Mixer 1, and Mixer 2 / S/PDIF, plus a live signal flow summary ("Inputs 1–8 → Mixer 1 → Main Out L/R") that flags buses that carry silence or are never read
- Mixer — macro mixer with custom faders and pan, strips derived from your stereo links, double-click for 0 dB, type exact dB values
- EQ — per-channel 4-band EQ with a draggable frequency-response editor (drag for freq/gain, scroll or shift-drag for Q), live composite curve, and DSP headroom readout
- Settings — DC blocking, S/PDIF vs Mixer 2, MIDI thru/channels, stereo links, mix smoothing, output DC offsets
- Device — flash save/load (hosted & standalone slots), reset to defaults, byte-faithful .syx export/import (compatible with the official tool's files)
- Auto-detects the ES-9's MIDI ports, live sample rate + DSP usage, dark/light theme, MIDI traffic log
npm install
npm run dev # dev server on localhost
npm test # protocol unit tests (vitest)
npm run check # svelte-check + tscOpen the dev server with ?mock=1 to run against a simulated ES-9 without hardware.
UI components → state stores (Svelte 5 runes) → DeviceSession → Es9Transport (WebMIDI | mock)
incoming: transport → decode.ts → typed Es9Event → session → store.applyFromDevice()
User edits update state and send SysEx (fader drags throttled to 25 ms); device messages only ever write state — no feedback loops. The mock transport (src/lib/midi/mockTransport.ts) implements the same interface and simulates firmware behavior including raw-mix echoes.
Everything below was extracted from the official config tool (thanks, Expert Sleepers, for shipping it as readable source) and verified against real hardware. Header: F0 00 21 27 19 <cmd> … F7. Multi-byte values are packed as 3×7-bit words, big-endian.
| Cmd | Meaning |
|---|---|
09 |
Config upload chunk (24 chunks × 32 words; chunk index in byte 6) |
22 |
Request version → reply 32 (ASCII string) |
23 |
Request config → reply 08 (2313-byte dump) |
24/25/26 |
Flash save / restore / defaults (arg: 0 standalone, 1 hosted) |
2A |
Request mix dump → reply 11 |
2B |
Request DSP usage → reply 12 |
2C |
Request sample rate → reply 14 |
31 |
DC blocking bitmask (7 input pairs) |
32 |
Options (bit 0 = Mixer 2 vs S/PDIF, bit 1 = MIDI thru) |
33 |
Stereo link (index, on/off) — indices: 0–6 inputs, 8–15 buses, 16–23 USB, 24–31 mixes |
34 |
Macro mix (slot, value) — see pan quirk below |
35 |
Mixer MIDI channels (USB, DIN; 0 = off) |
36 |
Output DC offset (ch, 21-bit two's complement) |
39 |
EQ filter params (mixer·ch, band, type |
3A |
Mix smoothing (mix, on/off) |
40+dsp |
Capture routing, 8 raw source codes |
50+dsp |
Output routing, 8 destination values |
60+mix |
Raw mix level (ch, 15-bit value) |
- Input capture codes are scrambled: UI value
0x70+i(Input i+1) maps through the lookup78 79 76 75 74 7B 7A 77 73 72 7D 7C 7E 7Ffor sends and dumps. - Pan set/report asymmetry: a stereo pair's pan is set via the odd mix's macro slot (
(mix+1)*8+ch, value64+pan), but reported in the even mix's slot of the mix dump as63+pan. The64+v/p−63pair round-trips exactly. Untouched pans read back as byte 64 (displays as "1R") — a firmware quirk the official tool shows too. - Source values 48/49 are mode-dependent: S/PDIF In L/R in S/PDIF mode, but Mix 9/10 in Mixer 2 mode (they share the
0x30encoding space). - The device pushes unsolicited mix dumps after macro changes and raw-mix echoes (
60+mix) for externally-driven changes — no polling needed. - Macro state lives in the mix dump, not the config dump: config words 194–449 are not authoritative for the macro mixer (the official tool skips them too); they are preserved opaquely for byte-faithful round-trips.
- Config dump layout (768 words): version · DC mask · capture 4×8 · output 4×8 · raw mix 16×8 · vmix (opaque) · options · links (2 words) · MIDI channels · output DC ×8 (sign-extended) · EQ 2×8×4×4 · smoothing.
- dB math: raw
0x2000= 0 dB, 6 dB per doubling,0x7FFF= +12 dB; macro value 103 = 0 dB, 55 = −24 dB (linear below, 0.5 dB/step above).