- Remove serial.SerialException from except clause since 'serial'
is not defined when import serial fails, causing UnboundLocalError
- Catch only ImportError and OSError
- GET /api/audio/profiles — list available profiles with params
- GET /api/audio/profile — current profile + jack_running + xrun_count
- POST /api/audio/profile {profile: 'standard'|'low'} — switch profile,
restart JACK server + JACK audio client atomically
- Adds audio_system + jack_audio refs to WebServerDeps
- Rollback on JACK restart failure
- Changed delay time from 0.35ms to 350ms for audible delay
- Increased reverb mix 0.25→0.35 and decay 0.35→0.4
- Increased delay mix 0.25→0.35 and feedback 0.2→0.3
- Both reverb and delay now enabled+active by default (bypass=false)
Complete rewrite of _build_nam_model and _build_wavenet to handle:
- SlimmableContainer (A2): pick submodel by quality, recurse into WaveNet
- WaveNet: proper dilated convs with causal padding, 1x1 layer1x1 post-conv
- Linear: simple pass-through with gain/bias
Weight import matches NAM export order:
rechannel -> per-layer(conv w+b, input_mixer w, layer1x1 w+b) -> head_rechannel w+b -> optional head -> head_scale
Also fixes MOCK_PRESETS in frontend to match actual factory preset names.
The PyPI 'nam' package (v0.0.3) is Neural Additive Models for tabular
data — completely different from Neural Audio Model (guitar amp modeling).
Implemented a local _init_from_nam() that builds a WaveNet NAM model
from the Core ML .nam JSON format. Uninstalling the wrong package.
restore_state() loads the last state from disk but doesn't call
activate() on the pipeline, so the NAM model was never loaded
on boot and no audio passed through. Added select() call with
the restored bank/program values so the pipeline loads the
preset chain including the NAM model.
Reordered UI_DIST_DIR candidates so pi-multifx-pedal-ui/dist (the
correct Helix-style pedal UI) is checked first. The old priority
put src/web/ui-dist first, which allowed wrong-build deploys to
mask the real UI.
Also add UI_DIST_DIR env var to systemd service for explicit path.
Two issues found and fixed in the deployed UI bundle:
1. String.fromCharCode(64+y) where y is 0-based bank index
→ 64+y gives 64+0=64 = '@' for bank 0
→ Fixed: 65+y gives 65+0=65 = 'A' for bank 0
2. e.bank||1 where falsy 0 falls through to 1
→ Shows 'Bank 1' for bank 0, 'Bank 2' for bank 1
→ Fixed: e.bank||0 so 0 renders as 'Bank 0'
Source code (frontend-react/src/App.jsx) was already clean —
the bug was in a transport/song mode feature that was built
from uncommitted changes then reverted.
Bank 12 (Blues) with 4 factory presets covering 9 legendary blues artists:
- Preset 0: Texas Flood (SRV) — TS808 + Fender Super Reverb
- Preset 1: Mannish Boy (Muddy Waters) — Fender Bassman cranked w/ slapback
- Preset 2: The Thrill (B.B. King) — Twin Reverb clean w/ comp
- Preset 3: Still Got the Blues (Gary Moore) — Marshall crunch w/ delay
Includes docs/blues-genre-research.md with full gear deep-dives, NAM
model sourcing guide (Tone3000 URLs), chain architectures, and
parameter value rationale for all 9 artists (SRV, B.B. King, Albert King,
Freddie King, Muddy Waters, Buddy Guy, Gary Moore, Joe Bonamassa,
John Mayer).
Implements multi-mode footswitch system for the Helix Stadium-inspired pedal UI:
- Footswitch mode context provider with 4 modes: stomp, preset, snapshot, combo
- ModeSelector in status bar (collapsed cycling mode for mobile)
- Stomp mode: footswitches toggle individual blocks on/off, scribble strips show block name + status
- Preset mode: footswitches show Bank Up/Down + preset selection, scribble strips show preset name + number
- Snapshot mode: footswitches recall 8 snapshots, scribble strips show snapshot name
- Combo mode: first 4 stomp + bank nav + preset select + global bypass
- ScribbleStrip LCD component with LED indicator and double-tap support
- Double-tap gesture hook for secondary actions (tuner, snapshot save, etc.)
- FootswitchBar container with 8 capacitive-touch footswitch buttons and LED rings
- usePedalState hook (WebSocket + API polling, ported from frontend-react/App.jsx)
- Dark pedal theme CSS (Helix-inspired) with responsive mobile layout
- Full App.tsx rewrite with status bar, footswitch bar, tab bar, and all screens
Adds snapshot system to Helix Stadium:
Backend:
- Snapshot data model (8 slots per preset, captures block bypass
+ params + master volume)
- Snapshot API endpoints: list, save, recall, rename, delete
- Integrated into preset serialization/deserialization
- Tracks current_snapshot in state / WebSocket broadcasts
Frontend:
- Camera icon in header bar with current snapshot number
- SnapshotPanel as slide-up overlay
- 8 snapshot slots in a horizontal row
- Tap to recall filled snapshot, tap empty slot to save
- Press-and-hold (600ms) to save current state
- Inline name editing on tap
- Discard Edits toggle
- Green flash indicator on save
- Delete button for active snapshot
- New Preset button: finds first empty slot, saves with default name
- Looper/Recorder tab: Record/Stop via arecord backend, list captures, play back
- Rig: shows loaded IR name more clearly + quick-link buttons to browse IRs/Models
- Backend: capture/start, capture/stop, captures API endpoints with file serve
- Status bar: CPU load + sample rate from /api/state, TUNER badge shown immediately
- Rig: optimistic toggle updates (bypass/tuner respond instantly), prominent tuner card
- FX Chain: loads real block params from /api/block-params/{fx_type}, Add Block picker with all FX types
- Record: replaced fake multitrack with real Signal Monitor (live I/O VU, clip detect, level history)
- Backend: added _gather_system_stats() returning cpu_percent and sample_rate
- Added input_level and output_level to /api/state (scaled 0-100)
- React RigScreen now reads real levels from state instead of random walk
- When no audio flows, VU meters show flat (0) instead of fake animation
- New dark UI with 7 tabs: Rig, FX Chain, Models, IRs, Presets, Settings, Record
- All screens wired to live API endpoints
- Real-time state via WebSocket + polling fallback
- Models screen: list/load/unload/upload NAM files + Tone3000 search/install
- IRs screen: list/load/unload/upload IR files + Tone3000 search/install
- Presets screen: browse banks, activate, save, delete
- Settings screen: WiFi scan/connect/hotspot, Bluetooth/MIDI, 4CM routing
- Rig screen: live state, volume, bypass, tuner, signal chain
- FX Chain screen: block params, per-block bypass
- Serves at / instead of /ui
- Built with Vite, ~71KB gzipped
- tests/test_stability.py — 1-hour continuous DSP pipeline stability test
covering all 46 FX types with CPU/memory/NaN monitoring
- tests/test_integration.py — fixed test_midi_cc_maps_expression to use
correct _on_midi_cc(value, cc_number, channel) signature matching
the Phase 6 MIDI fix
Bug: PedalApp._on_midi_cc() received (value, channel) where channel was
the MIDI channel (0-15) but was treated as the CC number (0-127). The
register_cc callback only passes value + MIDI channel, not the CC number.
Fix: Use a lambda closure in _wire_midi_callbacks to capture the CC
number so _on_midi_cc gets (value, cc_number, channel). Moved expression
pedal (CC#11) check before the presets/pipeline guard so it works even
when no preset is active.
Tests: 21 new integration tests covering:
- CC lambda closure capturing correct CC numbers
- Expression pedal → master volume (CC#11)
- Full parse→dispatch→callback chain for PC and CC
- Preset MIDI mapping lookup by CC number
- Edge cases: min/max values, rapid switching, empty slots
Add UI_DIST_DIR auto-detection and /ui static mount in the
FastAPI server so the built React frontend is served alongside
the main dashboard.
- UI_DIST_DIR env var override
- Auto-detect common project layouts (frontend-react/dist,
pi-multifx-pedal-ui/dist)
- Mount with html=True for SPA client-side routing
- 17 net definitions (GND, +3.3V/+5V, BCK/LRCK/DIN/DOUT, audio signals)
- Net assignments to 35+ pads across all components (PCM1808, PCM5102A, TL072, AMS1117)
- 20 trace segments for I2S bus and audio signal routing
- 4 GND copper pour zones (F.Cu + B.Cu)
Uses string-based S-expression manipulation with proper parenthesis tracking.