Phase 1-4: Audio stack, mixer engine, MIDI, and network API
Lint & Validate / lint (push) Has been cancelled

P2-R1: ALSA + JACK2 low-latency config (scripts, quirks, tuning)
P2-R2: Carla integration (build scripts, 8ch rack config, NAM LV2 support)
P2-R3: Plugin manager, categories, blacklist, NAM model support
P3-R1: Mixer DSP engine (channel strip, routing matrix, bus mgr, automation)
P4-R1: MIDI engine (learn mode, clock sync, HID discovery, mapping store)
P4-R2: Network API (OSC server, FastAPI REST, WebSocket, auth, rate limiter)
P5-R1: Touchscreen UI evaluation + main entry point
docs: Audio stack, Carla integration, MIDI support, UI evaluation
tests: Full test suite (292 passing)
This commit is contained in:
2026-05-19 20:39:17 -04:00
parent 7b123762b5
commit 9cd8292acc
97 changed files with 26545 additions and 5 deletions
+67
View File
@@ -0,0 +1,67 @@
# /etc/udev/rules.d/99-midi.rules
# USB MIDI device hotplug rules for Raspberry Pi RT Audio Mixer
#
# These rules:
# 1. Give the 'audio' group read/write access to USB MIDI devices
# 2. Create a persistent symlink for known controllers
# 3. Trigger systemd service reload on hotplug
# 4. Set nice/rtprio for MIDI processing threads
#
# Install: sudo cp config/99-midi.rules /etc/udev/rules.d/
# Reload: sudo udevadm control --reload-rules && sudo udevadm trigger
# ── Generic USB MIDI class devices (class-compliant) ────────────────────────
# USB Audio Class MIDI Streaming (subclass 0x03)
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
GROUP="audio", MODE="0660", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="midi-hotplug@$devpath.service"
# ── Known controllers — persistent symlinks by VID:PID ──────────────────────
# Behringer X-Touch Compact
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="1397", ATTRS{idProduct}=="00b4", \
SYMLINK+="midi/xtouch-compact", \
ENV{MIDI_CONTROLLER}="Behringer X-Touch Compact"
# Behringer X-Touch (MCU mode)
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="1397", ATTRS{idProduct}=="00b5", \
SYMLINK+="midi/xtouch", \
ENV{MIDI_CONTROLLER}="Behringer X-Touch"
# FaderFox UC4
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0d27", \
SYMLINK+="midi/faderfox-uc4", \
ENV{MIDI_CONTROLLER}="FaderFox UC4"
# Akai MIDImix
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="09e8", ATTRS{idProduct}=="0031", \
SYMLINK+="midi/midimix", \
ENV{MIDI_CONTROLLER}="Akai MIDImix"
# Arturia BeatStep
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="1c75", ATTRS{idProduct}=="0208", \
SYMLINK+="midi/beatstep", \
ENV{MIDI_CONTROLLER}="Arturia BeatStep"
# Novation Launch Control XL
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="1235", ATTRS{idProduct}=="0061", \
SYMLINK+="midi/launchcontrol-xl", \
ENV{MIDI_CONTROLLER}="Novation Launch Control XL"
# Korg nanoKONTROL2
SUBSYSTEM=="sound", ACTION=="add", KERNEL=="midi*", \
ATTRS{idVendor}=="0944", ATTRS{idProduct}=="0117", \
SYMLINK+="midi/nanokontrol2", \
ENV{MIDI_CONTROLLER}="Korg nanoKONTROL2"
# ── Cleanup on removal ──────────────────────────────────────────────────────
SUBSYSTEM=="sound", ACTION=="remove", KERNEL=="midi*", \
RUN+="/usr/bin/systemctl stop midi-hotplug@$devpath.service || true"
+57
View File
@@ -0,0 +1,57 @@
<?xml version='1.0' encoding='utf-8'?>
<CARLA-PRESET version="2.6.0">
<Info Name="RPi Mixer Default Rack" Author="hermes-kanban" />
<Engine>
<AudioDriver>JACK</AudioDriver>
<ProcessMode>MultipleClients</ProcessMode>
<TransportMode>Disabled</TransportMode>
<SampleRate>48000</SampleRate>
<BufferSize>128</BufferSize>
<ForceStereo>true</ForceStereo>
</Engine>
<Rack enabled="true">
<Plugin id="0" name="Ch1 Gate" type="LV2" uri="http://calf.sourceforge.net/plugins/Gate" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="threshold" value="-40" />
<Parameter name="ratio" value="4.0" />
<Parameter name="attack" value="10" />
<Parameter name="release" value="100" />
</Plugin>
<Plugin id="1" name="Ch1 EQ" type="LV2" uri="http://calf.sourceforge.net/plugins/Equalizer12Band" enabled="true" bypass="false" drywet="1.0" volume="0.0" />
<Plugin id="2" name="Ch1 Comp" type="LV2" uri="http://calf.sourceforge.net/plugins/Compressor" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="threshold" value="-20" />
<Parameter name="ratio" value="4.0" />
<Parameter name="attack" value="5" />
<Parameter name="release" value="50" />
<Parameter name="makeup" value="3" />
</Plugin>
<Plugin id="3" name="Ch2 Gate" type="LV2" uri="http://calf.sourceforge.net/plugins/Gate" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="threshold" value="-40" />
<Parameter name="ratio" value="4.0" />
</Plugin>
<Plugin id="4" name="Ch2 EQ" type="LV2" uri="http://calf.sourceforge.net/plugins/Equalizer8Band" enabled="true" bypass="false" drywet="1.0" volume="0.0" />
<Plugin id="5" name="Ch2 Comp" type="LV2" uri="http://calf.sourceforge.net/plugins/Compressor" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="threshold" value="-20" />
<Parameter name="ratio" value="4.0" />
</Plugin>
<Plugin id="6" name="Ch3 NAM" type="LV2" uri="http://github.com/mikeoliphant/neural-amp-modeler-lv2" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="model" value="/home/pi/nam-models/default.nam" />
</Plugin>
<Plugin id="7" name="Ch3 IR Loader" type="LV2" uri="http://guitarix.org/plugins/gx_ampmodeller" enabled="true" bypass="false" drywet="1.0" volume="0.0" />
<Plugin id="8" name="AUX1 Hall Reverb" type="LV2" uri="http://calf.sourceforge.net/plugins/Reverb" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="decay_time" value="2.5" />
<Parameter name="dry/wet" value="0.3" />
<Parameter name="room_size" value="0.7" />
</Plugin>
<Plugin id="9" name="AUX2 Delay" type="LV2" uri="http://calf.sourceforge.net/plugins/VintageDelay" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="time_l" value="250" />
<Parameter name="time_r" value="375" />
<Parameter name="feedback" value="0.4" />
<Parameter name="dry/wet" value="0.25" />
</Plugin>
<Plugin id="10" name="Master Limiter" type="LV2" uri="http://calf.sourceforge.net/plugins/Limiter" enabled="true" bypass="false" drywet="1.0" volume="0.0">
<Parameter name="limit" value="-1.0" />
<Parameter name="threshold" value="-3.0" />
<Parameter name="release" value="20" />
</Plugin>
</Rack>
</CARLA-PRESET>
+8
View File
@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<CARLA-PATCHBAY version="2.6.0">
<Connection id="0" source="system:capture_1" dest="Carla:Ch1_Gate_in1" label="Capture 1 → Ch1 Gate" enabled="true" />
<Connection id="1" source="system:capture_2" dest="Carla:Ch2_Gate_in1" label="Capture 2 → Ch2 Gate" enabled="true" />
<Connection id="2" source="system:capture_3" dest="Carla:Ch3_NAM_in1" label="Capture 3 → Guitar NAM" enabled="true" />
<Connection id="3" source="Carla:Master_Limiter_out1" dest="system:playback_1" label="Master L → Playback 1" enabled="true" />
<Connection id="4" source="Carla:Master_Limiter_out2" dest="system:playback_2" label="Master R → Playback 2" enabled="true" />
</CARLA-PATCHBAY>
+36
View File
@@ -0,0 +1,36 @@
# USB audio quirks configuration
# Apply device-specific workarounds for USB audio interfaces
#
# Find your device VID/PID with: lsusb | grep -i audio
# Then uncomment the matching line below.
# ── General optimizations ────────────────────────────
# Reduce USB transfer latency by disabling implicit feedback buffering
options snd-usb-audio nrpacks=1
# ── Focusrite Scarlett 18i20 (3rd Gen) ───────────────
# VID=0x1235 PID=0x8210
# Device setup 1 enables ALSA mixer controls for routing
# options snd-usb-audio vid=0x1235 pid=0x8210 device_setup=1
# ── Behringer UMC1820 ────────────────────────────────
# VID=0x1397 PID=0x0508
# Implicit feedback sync for clock stability
# options snd-usb-audio vid=0x1397 pid=0x0508 implicit_fb=1
# ── Behringer UMC404HD ───────────────────────────────
# VID=0x1397 PID=0x0509
# options snd-usb-audio vid=0x1397 pid=0x0509 implicit_fb=1
# ── Behringer UMC204HD ───────────────────────────────
# VID=0x1397 PID=0x0507
# options snd-usb-audio vid=0x1397 pid=0x0507 implicit_fb=1
# ── Zoom UAC-8 ───────────────────────────────────────
# VID=0x1686 PID=0x0160
# options snd-usb-audio vid=0x1686 pid=0x0160 nrpacks=1
# ── RME Babyface Pro FS ──────────────────────────────
# Class-compliant mode — no quirks needed, works OOTB
# Just ensure the interface is in "CC" (Class Compliant) mode