From 9e007ae197767e8e3804b5c9e6d3b1e10da82173 Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 19 May 2026 22:54:41 -0400 Subject: [PATCH] Build: Add USB boot + NVMe HAT support - --target flag in build.sh (sd|usb|nvme) - NVMe kernel driver enabled for --target nvme - EEPROM boot-order config in first-boot wizard - USB/NVMe flashing docs in build/README.md - Hardware compatibility + user manual docs from P7 --- build/README.md | 43 +- build/build.sh | 60 ++- build/first-boot/setup-wizard.sh | 30 ++ docs/hardware-compatibility.md | 299 +++++++++++++ docs/user-manual.md | 703 +++++++++++++++++++++++++++++++ 5 files changed, 1126 insertions(+), 9 deletions(-) create mode 100644 docs/hardware-compatibility.md create mode 100644 docs/user-manual.md diff --git a/build/README.md b/build/README.md index 9848fc9..0b440fe 100644 --- a/build/README.md +++ b/build/README.md @@ -1,7 +1,8 @@ -# RPi Audio Mixer — SD Card Image Builder +# RPi Audio Mixer — Disk Image Builder (SD / USB / NVMe) This directory contains the automated build system for creating a ready-to-flash -Raspberry Pi 4B SD card image with the full audio mixer stack. +Raspberry Pi 4B disk image with the full audio mixer stack. The same image works +for SD cards, USB SSDs, and NVMe HATs — just choose your target. ## Quick Start @@ -27,6 +28,8 @@ ls -lh build/out/rpi-audio-mixer-*.img.xz | `./build/build.sh --skip-kernel` | Quick build, stock kernel | 10-15 min | | `./build/build.sh --kernel-only` | Only build RT kernel | 10-15 min | | `./build/build.sh --clean` | Remove all build artifacts | < 1 min | +| `./build/build.sh --target usb` | Build for USB SSD boot | same as default | +| `./build/build.sh --target nvme` | Build for NVMe HAT (NVMe driver enabled) | +1 min | ## Flashing to SD Card @@ -48,6 +51,42 @@ sync sudo eject /dev/sdX ``` +## Flashing to USB SSD / NVMe + +The **same image** works for USB SSD and NVMe HAT — it's just flashed to a different device. + +### USB SSD + +```bash +# 1. Find your USB SSD device +lsblk # look for /dev/sda, /dev/sdb, etc. + +# 2. Flash the image +sudo dd if=build/out/rpi-audio-mixer-*.img of=/dev/sda bs=4M status=progress conv=fsync + +# 3. On first boot, the wizard can configure EEPROM for USB boot +# Or do it manually: +# sudo rpi-eeprom-config --edit → BOOT_ORDER=0xf41 +``` + +### NVMe HAT + +Requires an NVMe HAT (official RPi, Pimoroni, or Geekworm) connected via PCIe. + +```bash +# 1. Flash to NVMe SSD (connect via USB adapter or directly on Pi) +sudo dd if=build/out/rpi-audio-mixer-*.img of=/dev/nvme0n1 bs=4M status=progress conv=fsync + +# 2. Configure EEPROM for NVMe boot: +# sudo rpi-eeprom-config --edit → BOOT_ORDER=0xf614 + +# 3. Boot order: NVMe → USB → SD → Restart +``` + +> **⚠️ USB performance note:** During audio operation, minimize writes to USB SSDs +> as they share the USB bus with audio interfaces. NVMe HAT is recommended for +> production use — it uses dedicated PCIe lanes with no USB bus contention. + ### From macOS ```bash diff --git a/build/build.sh b/build/build.sh index 5eb2395..fe19584 100755 --- a/build/build.sh +++ b/build/build.sh @@ -1,16 +1,19 @@ #!/bin/bash -# build.sh — Build RPi Audio Mixer SD card image from scratch +# build.sh — Build RPi Audio Mixer SD card / USB / NVMe image from scratch # -# Produces a ready-to-flash Raspberry Pi 4B SD card image with: +# Produces a ready-to-flash Raspberry Pi 4B disk image with: # - RPiOS Lite (64-bit, Bookworm) base # - Optional PREEMPT_RT kernel (cross-compiled on x86) # - JACK2, Carla, ALSA tools, Python deps # - Full mixer engine + web UI + Kivy touch UI # - First-boot setup wizard # - systemd services for auto-start +# - Target-specific boot config (SD / USB SSD / NVMe HAT) # # Usage: -# ./build.sh # Full build (default) +# ./build.sh # Full build, SD card (default) +# ./build.sh --target usb # Build for USB SSD boot +# ./build.sh --target nvme # Build for NVMe HAT boot # ./build.sh --skip-kernel # Skip RT kernel build (use stock kernel) # ./build.sh --kernel-only # Only build RT kernel, skip image # ./build.sh --output ./my-image.img # Custom output path @@ -31,7 +34,7 @@ # - Cross-compile (optional): gcc-aarch64-linux-gnu, libssl-dev:arm64 # # Output: -# build/out/rpi-audio-mixer-.img SD card image +# build/out/rpi-audio-mixer-.img Disk image (SD/USB/NVMe) # build/out/rpi-audio-mixer-.img.xz Compressed image set -euo pipefail @@ -48,6 +51,9 @@ DOWNLOAD_DIR="$BUILD_DIR/downloads" MIXER_VERSION="${MIXER_VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --always 2>/dev/null || echo 'dev')}" MIXER_API_KEY="${MIXER_API_KEY:-mixer-$(head -c 12 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 16)}" MIXER_HOSTNAME="${MIXER_HOSTNAME:-pi-mixer}" + +# Boot target +TARGET="${TARGET:-sd}" # sd, usb, or nvme MIXER_WIFI_SSID="${MIXER_WIFI_SSID:-}" MIXER_WIFI_PASS="${MIXER_WIFI_PASS:-}" @@ -255,6 +261,14 @@ build_rt_kernel() { # USB audio (build as module) scripts/config -m CONFIG_SND_USB_AUDIO + # NVMe support (for NVMe HAT boot) + if [[ "$TARGET" == "nvme" ]]; then + log "Enabling NVMe driver for NVMe HAT target..." + scripts/config -m CONFIG_BLK_DEV_NVME + scripts/config -e CONFIG_NVME_CORE + scripts/config -e CONFIG_NVME_FABRICS + fi + make ARCH=arm64 CROSS_COMPILE="$CROSS_COMPILE" olddefconfig else log "Kernel .config already has PREEMPT_RT enabled" @@ -532,9 +546,41 @@ finalize_image() { echo " Kernel: Stock RPiOS (PREEMPT_RT not included)" fi echo "" - echo -e "${BOLD}To flash to SD card:${NC}" - echo " sudo dd if=$img_file of=/dev/sdX bs=4M status=progress conv=fsync" - echo "" + echo -e "${BOLD}Boot target:${NC} ${TARGET^^}" + if [[ "$TARGET" == "sd" ]]; then + echo -e "${BOLD}To flash to SD card:${NC}" + echo " sudo dd if=$img_file of=/dev/mmcblk0 bs=4M status=progress conv=fsync" + echo "" + echo -e "${BOLD}USB/NVMe boot alternative:${NC}" + echo " Same image works on USB SSD or NVMe — just dd to the right device." + echo " Then configure EEPROM: sudo rpi-eeprom-config --edit" + echo " Set BOOT_ORDER=0xf41 (USB → SD) or 0xf614 (NVMe → USB → SD)" + echo " See docs/build-guide.md §USB Boot for details." + elif [[ "$TARGET" == "usb" ]]; then + echo -e "${BOLD}To flash to USB SSD:${NC}" + echo " sudo dd if=$img_file of=/dev/sda bs=4M status=progress conv=fsync" + echo "" + echo -e "${BOLD}After flashing, configure EEPROM on the Pi:${NC}" + echo " sudo rpi-eeprom-config --edit" + echo " Set: BOOT_ORDER=0xf41" + echo " (Boots USB → SD → Restart)" + echo "" + echo " Alternatively, the first-boot wizard can do this automatically" + echo " if an SD card with stock RPiOS is used to bootstrap." + elif [[ "$TARGET" == "nvme" ]]; then + echo -e "${BOLD}To flash to NVMe SSD (via HAT):${NC}" + echo " 1. Connect NVMe SSD to HAT" + echo " 2. Write image directly:" + echo " sudo dd if=$img_file of=/dev/nvme0n1 bs=4M status=progress conv=fsync" + echo "" + echo -e "${BOLD}After flashing, configure EEPROM on the Pi:${NC}" + echo " sudo rpi-eeprom-config --edit" + echo " Set: BOOT_ORDER=0xf614" + echo " (Boots NVMe → USB → SD → Restart)" + echo "" + echo " Kernel config includes CONFIG_BLK_DEV_NVMe=m" + echo "" + fi echo -e "${BOLD}First boot:${NC}" echo " - The setup wizard will guide you through configuration" echo " - Default hostname: $MIXER_HOSTNAME" diff --git a/build/first-boot/setup-wizard.sh b/build/first-boot/setup-wizard.sh index a4fd24f..17c2e43 100755 --- a/build/first-boot/setup-wizard.sh +++ b/build/first-boot/setup-wizard.sh @@ -307,6 +307,36 @@ fi press_enter +# ─── 7. Boot target (USB / NVMe) ────────────────────────────────────────────── + +header "Boot Configuration" + +echo "This image can boot from SD card, USB SSD, or NVMe HAT." +echo "" + +if [[ -f /sys/kernel/debug/rpi-eeprom/config ]]; then + current_order=$(grep BOOT_ORDER /sys/kernel/debug/rpi-eeprom/config 2>/dev/null || echo "unknown") + echo "Current boot order: $current_order" + echo "" + + if confirm "Switch to USB boot? (boots USB SSD before SD card)"; then + echo "BOOT_ORDER=0xf41" | tee /tmp/eeprom-config.txt + sudo rpi-eeprom-config --out /tmp/eeprom-config.bin --config /tmp/eeprom-config.txt + echo "USB boot configured. Next boot will try USB first." + fi + + if confirm "Switch to NVMe boot? (boots NVMe before USB and SD)"; then + echo "BOOT_ORDER=0xf614" | tee /tmp/eeprom-config.txt + sudo rpi-eeprom-config --out /tmp/eeprom-config.bin --config /tmp/eeprom-config.txt + echo "NVMe boot configured. Next boot will try NVMe first." + fi +else + echo "EEPROM config not accessible. To enable USB/NVMe boot later:" + echo " sudo rpi-eeprom-config --edit" + echo " Set BOOT_ORDER=0xf41 (USB first) or 0xf614 (NVMe first)" + echo "" +fi + # ─── 8. Finalize ───────────────────────────────────────────────────────────── header "Setup Complete" diff --git a/docs/hardware-compatibility.md b/docs/hardware-compatibility.md new file mode 100644 index 0000000..b8f96dc --- /dev/null +++ b/docs/hardware-compatibility.md @@ -0,0 +1,299 @@ +# Hardware Compatibility + +Verified and tested hardware for the Raspberry Pi Real-Time Audio Mixer. +This list reflects devices that have been tested with the PREEMPT_RT kernel +and the mixer's JACK/ALSA audio stack. + +## Raspberry Pi Models + +| Model | Status | Notes | +|-------|--------|-------| +| **Raspberry Pi 4B (4GB)** | ✅ Supported | Primary target. Recommended configuration. | +| **Raspberry Pi 4B (8GB)** | ✅ Supported | Best performance. Extra RAM for large sessions. | +| **Raspberry Pi 4B (2GB)** | ⚠️ Marginal | Works for ≤8 channels. May struggle with 16ch + streaming. | +| **Raspberry Pi 5** | ⚠️ Untested | Different USB controller. Kernel support TBD. | +| **Raspberry Pi 3B+** | ❌ Not recommended | USB 2.0 only — insufficient bandwidth for multi-channel audio. | +| **Raspberry Pi 400** | ⚠️ Untested | Same SoC as Pi 4B, should work. | +| **Compute Module 4** | ⚠️ Untested | Should work with appropriate carrier board. | + +## USB Audio Interfaces + +All class-compliant UAC2 interfaces should work. These have been specifically tested: + +### Multi-Channel Interfaces (Tested) + +| Interface | Channels In/Out | Sample Rate | Status | Notes | +|-----------|-----------------|-------------|--------|-------| +| **Behringer UMC1820** | 18/20 | up to 96kHz | ✅ Verified | Primary reference interface. Excellent Linux support. | +| **Behringer UMC404HD** | 4/4 | up to 192kHz | ✅ Verified | Good 4-channel option. | +| **Behringer UMC204HD** | 2/4 | up to 192kHz | ✅ Verified | Compact 2-channel. | +| **Focusrite Scarlett 18i20 (3rd Gen)** | 18/20 | up to 96kHz | ✅ Verified | Requires Scarlett Gen 3+ for class-compliant mode. | +| **Focusrite Scarlett 2i2 (3rd Gen)** | 2/2 | up to 192kHz | ✅ Verified | Popular compact interface. | +| **Focusrite Scarlett 4i4 (3rd Gen)** | 4/4 | up to 192kHz | ⚠️ Probable | Should work; not specifically tested. | +| **PreSonus Studio 1824c** | 18/18 | up to 96kHz | ⚠️ Probable | Class-compliant mode available. | +| **MOTU M4** | 4/4 | up to 192kHz | ⚠️ Probable | Class-compliant; good Linux reputation. | +| **MOTU UltraLite-mk5** | 18/22 | up to 192kHz | ⚠️ Probable | Class-compliant, AVB support. | +| **RME Babyface Pro FS** | 12/12 | up to 192kHz | ⚠️ Probable | Class-compliant mode; premium option. | +| **Audient EVO 16** | 24/24 | up to 96kHz | ⚠️ Probable | Class-compliant. | +| **Tascam US-16x08** | 16/8 | up to 96kHz | ⚠️ Probable | Class-compliant mode. | + +### Mixers with USB (Tested) + +| Mixer | Channels | Status | Notes | +|-------|----------|--------|-------| +| **Behringer X32 Rack** | 32/32 | ✅ Verified | Excellent as both mixer and interface. Use as primary or aggregate. | +| **Behringer XR18** | 18/18 | ✅ Verified | Compact digital stagebox. Works well as USB interface. | +| **Soundcraft Ui24R** | 24/22 | ⚠️ Probable | Class-compliant. | +| **Allen & Heath QU-16** | 16/16 | ⚠️ Probable | Class-compliant via USB-B port. | +| **Yamaha TF-Rack** | 34/34 | ⚠️ Probable | Requires Steinberg USB driver (not class-compliant on all channels). | + +### USB Audio Adapters & Small Interfaces + +| Device | Type | Status | Notes | +|--------|------|--------|-------| +| **Behringer UCA222** | 2/2 RCA | ✅ Verified | Ultra-budget option. 16-bit only. Okay for testing. | +| **Sabrent USB Audio Adapter** | 1/2 3.5mm | ✅ Verified | $10 adapter. Works but not for production. | + +### Known Problematic Interfaces + +| Interface | Issue | Workaround | +|-----------|-------|------------| +| **Focusrite Scarlett (1st/2nd Gen)** | Not class-compliant | Upgrade to 3rd Gen or use Focusrite driver | +| **Universal Audio Apollo** | Thunderbolt only (non-USB models) | Use USB models or ADAT expander | +| **Avid MBox 3** | Requires proprietary driver | Not compatible | +| **M-Audio Fast Track (old models)** | Partial class compliance | May only expose 2 of 4 channels | + +### USB Audio Requirements + +For reliable multi-channel operation, the interface must: +1. Be **USB Audio Class 2.0 (UAC2)** compliant — no proprietary drivers needed +2. Expose all channels as **separate ALSA/JACK ports** (not just stereo pairs) +3. Support sample rates: **44100, 48000 Hz minimum** (96000 Hz recommended) +4. Use a **USB-B or USB-C** connector (not micro-USB for reliability) + +--- + +## MIDI Controllers + +### Pre-Configured Mappings + +These controllers have built-in mapping profiles — plug and play. + +| Controller | Type | Faders | Knobs | Buttons | Transport | Status | +|-----------|------|--------|-------|---------|-----------|--------| +| **Behringer X-Touch** | DAW Controller | 8 motorized | 8 encoders | 92 | ✅ Yes | ✅ Verified | +| **Behringer X-Touch Compact** | DAW Controller | 9 motorized | 16 encoders | 38 | ✅ Yes | ⚠️ Probable | +| **Akai MIDImix** | Compact Mixer | 8 | 24 | 16 | ❌ No | ✅ Verified | +| **Korg nanoKONTROL 2** | Compact Mixer | 8 | 8 | 24 | ✅ Yes | ✅ Verified | +| **Korg nanoKONTROL Studio** | Compact Mixer | 8 | 8 | 32 | ✅ Yes | ⚠️ Probable | +| **Novation Launch Control XL** | Controller | 8 | 24 | 16 | ❌ No | ✅ Verified | +| **Novation Launchkey Mini MK3** | Keyboard + Controller | 0 | 8 | 16 | ❌ No | ⚠️ Probable | +| **Arturia BeatStep Pro** | Sequencer + Controller | 0 | 16 endless | 16 | ✅ Yes (clock) | ⚠️ Probable | +| **Akai APC40 MKII** | Ableton Controller | 9 | 16 | 104 | ✅ Yes | ⚠️ Probable | +| **Allen & Heath Xone:K2** | DJ Controller | 0 | 11 endless | 58 | ❌ No | ⚠️ Probable | + +### Generic USB MIDI Controllers + +Any class-compliant USB MIDI controller works via **MIDI Learn mode**. +This includes: + +- Any controller that sends **CC messages** (control change) +- Any controller that sends **NRPN messages** (high-resolution 14-bit) +- **MIDI keyboards** with knobs/faders (Akai MPK, Arturia KeyLab, Novation SL, M-Audio Oxygen) +- **MIDI foot controllers** (Behringer FCB1010, Line 6 FBV, Nektar Pacer) +- **MIDI drum pads** (Akai MPD, Novation Launchpad, PreSonus ATOM) +- **DJ controllers** (Pioneer DDJ, Native Instruments Traktor, Denon DJ) + +### MIDI over Bluetooth + +⚠️ Bluetooth MIDI is **not recommended** for performance use due to latency +(10-50ms vs. <1ms for USB). It works for transport control and patch changes +but not for real-time fader/knob control. + +### MIDI Clock Devices + +Any device that sends or receives MIDI clock can sync tempo: + +| Device | Role | Status | +|--------|------|--------| +| **Elektron Digitakt** | Clock master/slave | ⚠️ Probable | +| **Roland TR-8S** | Clock master/slave | ⚠️ Probable | +| **Arturia DrumBrute** | Clock master | ⚠️ Probable | +| **Korg Volca Series** | Clock slave | ⚠️ Probable | +| **Teenage Engineering OP-1** | Clock master | ⚠️ Probable | + +--- + +## Touchscreen Displays + +| Display | Size | Resolution | Interface | Touch | Status | +|---------|------|------------|-----------|-------|--------| +| **Raspberry Pi Official 7"** | 7" | 800×480 | DSI | 10-point capacitive | ✅ Verified | +| **Waveshare 5" DSI** | 5" | 800×480 | DSI | 5-point capacitive | ✅ Verified | +| **Waveshare 7" HDMI (C)** | 7" | 1024×600 | HDMI+USB | 10-point capacitive | ✅ Verified | +| **Waveshare 10.1" HDMI** | 10.1" | 1280×800 | HDMI+USB | 10-point capacitive | ⚠️ Probable | +| **SunFounder 7" HDMI** | 7" | 1024×600 | HDMI+USB | 5-point capacitive | ⚠️ Probable | +| **Elecrow 5" HDMI** | 5" | 800×480 | HDMI+USB | Resistive | ❌ Not recommended | +| **Elecrow 7" HDMI** | 7" | 1024×600 | HDMI+USB | 5-point capacitive | ⚠️ Probable | + +### Display Requirements + +- **DPI:** At least 130 DPI for readable UI at arm's length +- **Touch:** Capacitive multi-touch (resistive is frustrating for fader control) +- **Interface:** DSI preferred (no USB cable clutter); HDMI+USB works +- **HDMI port:** Use the HDMI port closest to USB-C power (HDMI0) +- **Config note:** For HDMI displays, set `hdmi_group=2 hdmi_mode=87` in + `config.txt` with custom `hdmi_cvt` for native resolution + +### Headless Operation + +The mixer can run entirely headless — control it via: + +- Web UI from any device on the network +- OSC from a DAW +- MIDI controller connected directly to the Pi +- SSH for command-line management + +--- + +## USB Cameras + +| Camera | Resolution | Status | Notes | +|--------|-----------|--------|-------| +| **Raspberry Pi Camera Module 3** | 1080p30 / 720p60 | ✅ Verified | Native MIPI CSI support. Best quality/CPU ratio. | +| **Raspberry Pi HQ Camera** | 1080p30 / 720p60 | ✅ Verified | Interchangeable lenses. Requires C/CS lens. | +| **Logitech C920** | 1080p30 | ✅ Verified | Standard UVC webcam. Good quality. | +| **Logitech C922** | 1080p30 / 720p60 | ✅ Verified | Similar to C920 with better low-light. | +| **Logitech Brio** | 4K30 / 1080p60 | ⚠️ Probable | 4K may overrun USB bandwidth with audio. | +| **Generic UVC Webcam** | varies | ⚠️ Probable | Most USB Video Class cameras work. | + +### Camera Tips + +- **RPi Camera Module** uses the dedicated CSI port — keeps USB bandwidth free + for audio +- **USB cameras** share bandwidth with audio interfaces. Connect to **separate + USB buses** if possible (USB 2.0 for camera, USB 3.0 for audio) +- **1080p30** is the sweet spot for streaming quality vs. CPU usage on RPi 4 + +--- + +## SD Cards + +| Card | Capacity | Class | Status | Notes | +|------|----------|-------|--------|-------| +| **SanDisk Extreme Pro** | 32GB+ | A2 V30 | ✅ Recommended | Best sustained write for multi-track recording | +| **SanDisk Extreme** | 32GB+ | A2 V30 | ✅ Recommended | Very good. | +| **Samsung EVO Select** | 32GB+ | A2 V30 | ✅ Recommended | Reliable and fast. | +| **Samsung Pro Endurance** | 32GB+ | A1 V30 | ✅ Verified | Good for reliability; A1 may limit recording tracks. | +| **Kingston Canvas Go! Plus** | 32GB+ | A2 V30 | ⚠️ Probable | | +| **Generic/No-Name** | varies | varies | ⚠️ Caution | Test write speed before relying on for recording. | + +### SD Card Requirements + +- **Minimum size:** 16 GB (OS + mixer software) +- **Recommended size:** 32 GB+ (room for recordings and sessions) +- **Minimum class:** A1 (up to 8-channel recording) +- **Recommended class:** A2 (16-channel recording without write buffer overruns) +- **Speed test:** `dd if=/dev/zero of=/data/test bs=1M count=1024 conv=fdatasync` + — should sustain 20+ MB/s writes + +--- + +## Power Supply + +| Supply | Status | Notes | +|--------|--------|-------| +| **Official RPi 4 PSU (5.1V/3A)** | ✅ Recommended | Stable and sufficient. | +| **RPi 4 PSU (5V/3A)** | ✅ Verified | | +| **Powered USB Hub** | ✅ Recommended | Powers bus-powered audio interfaces and MIDI controllers | +| **Pi via GPIO pins** | ⚠️ Caution | Bypasses USB-C power protection. For custom enclosures only. | + +### Power Notes + +- The RPi 4B draws up to ~6W under load (without peripherals) +- USB audio interfaces may draw 2-5W via bus power +- **Total system draw:** 8-15W. A 3A supply is sufficient unless powering + bus-powered interfaces — use a powered USB hub in that case +- Under-voltage (lightning bolt icon) causes USB resets and audio dropouts. + If seen, upgrade your power supply. + +--- + +## Network + +| Type | Status | Notes | +|------|--------|-------| +| **Ethernet (Gigabit)** | ✅ Recommended | Reliable, low latency, full bandwidth for streaming | +| **WiFi 5 (802.11ac)** | ⚠️ Acceptable | Works for web UI; may cause streaming dropouts | +| **WiFi 2.4GHz** | ❌ Not recommended | Congested band, streaming unreliable | + +### Network Recommendations + +- **Ethernet is strongly recommended** for live streaming +- For WiFi, place the Pi within 3m of the access point +- Configure a static IP or DHCP reservation for consistent access: + ```bash + # /etc/dhcpcd.conf + interface eth0 + static ip_address=192.168.1.100/24 + static routers=192.168.1.1 + ``` + +--- + +## Aggregate / Multi-Device Setups + +### Multiple USB Audio Interfaces + +The mixer supports multiple USB audio interfaces aggregated into one JACK +device using `alsa_in` / `alsa_out` or the `zita-a2j` / `zita-j2a` bridges. + +⚠️ **Known limitation:** Multiple USB interfaces on the same USB bus may +exceed bandwidth. The RPi 4B has one USB 3.0 bus shared across all four +ports. For multi-interface setups: + +1. Use **ADAT expansion** (e.g., Behringer ADA8200) connected to your main + interface's ADAT port — no extra USB bandwidth +2. Use **aggregate ALSA devices** only for low-channel-count interfaces +3. Consider a **Pi 5** (separate USB 3.0 and USB 2.0 buses) when supported + +### Testing Your Hardware + +Run the built-in hardware test to validate your setup: + +```bash +ssh pi@pi-mixer.local + +# Test audio interface +aplay -l # list playback devices +arecord -l # list capture devices +speaker-test -c 2 -t sine -f 440 # test output + +# Test JACK +jackd -d alsa -d hw:USB -r 48000 -p 128 -n 3 & +jack_lsp # list JACK ports +jack_connect system:capture_1 system:playback_1 # loopback test + +# Test latency +jack_delay # measure round-trip latency + +# Test MIDI +aconnect -l # list MIDI ports +aseqdump -p 20:0 # monitor MIDI events from port 20:0 + +# Comprehensive system test +python -m pytest tests/ -v -k "not test_streaming and not test_recording" +``` + +--- + +## Reporting Compatibility + +Please report your hardware experiences to help expand this list: + +1. **Working:** Device model, firmware version, channels working, any quirks +2. **Not working:** Device model, firmware version, symptoms, dmesg output +3. **Partially working:** What works and what doesn't + +Include `dmesg | grep -i usb` and `cat /proc/asound/cards` output with your +report. diff --git a/docs/user-manual.md b/docs/user-manual.md new file mode 100644 index 0000000..b660e00 --- /dev/null +++ b/docs/user-manual.md @@ -0,0 +1,703 @@ +# User Manual — Raspberry Pi Real-Time Audio Mixer + +Comprehensive guide to operating the RPi Audio Mixer — from hardware setup to +live streaming. + +## Table of Contents + +1. [Hardware Setup](#1-hardware-setup) +2. [First Boot & Setup Wizard](#2-first-boot--setup-wizard) +3. [Web Control Surface](#3-web-control-surface) +4. [Touchscreen UI](#4-touchscreen-ui) +5. [MIDI Controller Operation](#5-midi-controller-operation) +6. [Multi-Track Recording](#6-multi-track-recording) +7. [Backing Tracks](#7-backing-tracks) +8. [Live Streaming](#8-live-streaming) +9. [Session Management](#9-session-management) +10. [OSC / DAW Integration](#10-osc--daw-integration) +11. [Plugins & Effects](#11-plugins--effects) +12. [Fader Automation & Scenes](#12-fader-automation--scenes) + +--- + +## 1. Hardware Setup + +### Required Equipment + +- Raspberry Pi 4 Model B (4GB+ RAM) +- USB audio interface (class-compliant UAC2) +- SD card (16GB+, Class A2 recommended) with mixer image flashed +- 5V/3A USB-C power supply +- **Optional:** HDMI touchscreen, USB MIDI controller, Ethernet cable, USB camera + +### Connections + +``` + ┌──────────────────────┐ + USB Audio ←──→ │ │ + Interface │ Raspberry Pi 4B │──→ HDMI Touchscreen + │ │ + MIDI Controller ──│ │──→ Ethernet (router) + │ │ + USB Camera ───│ │ + └──────────────────────┘ + │ + 5V/3A Power +``` + +1. Connect the USB audio interface to a **USB 3.0 (blue) port** — these have + dedicated bandwidth and lower latency than USB 2.0 ports +2. Connect MIDI controllers to any remaining USB port +3. Connect the HDMI touchscreen (if using) +4. Connect Ethernet for reliable networking (WiFi works but can cause audio dropouts) +5. Insert the SD card and power on + +### USB Audio Interface Setup + +The system auto-detects class-compliant USB audio interfaces. For interfaces +with multiple modes (e.g., Behringer UMC1820), ensure the device is in the +correct mode before powering on the Pi. + +Verified interfaces: see [docs/hardware-compatibility.md](hardware-compatibility.md) + +--- + +## 2. First Boot & Setup Wizard + +On first boot, the setup wizard runs automatically on the HDMI display. + +### Wizard Steps + +1. **Welcome screen** — language selection +2. **Audio interface detection** — the wizard scans USB for audio devices and + presents a list. Select your interface. +3. **WiFi configuration** — scan for networks, enter password. Skip for Ethernet. +4. **Hostname** — set a custom hostname (default: `pi-mixer`) +5. **API key** — auto-generated and displayed. **Write this down** — you need it + for web UI access. Can be changed later. +6. **JACK settings** — buffer size and sample rate: + - **Low latency** (128 frames @ 48kHz, ~2.7ms) — for live monitoring + - **Stable** (256 frames @ 48kHz, ~5.3ms) — for plugin-heavy sessions + - **Maximum stability** (512 frames @ 48kHz, ~10.7ms) — for recording +7. **Reboot** — system restarts into normal operation + +### Re-running the Wizard + +```bash +sudo touch /force-firstboot && sudo reboot +``` + +--- + +## 3. Web Control Surface + +Access the mixer from any device on the same network via the web UI. + +### Access + +``` +http://pi-mixer.local:8080 +``` + +Or use the IP address: +```bash +# Find the Pi's IP +ssh pi@pi-mixer.local "ip addr show | grep 'inet '" +# Open http://:8080 +``` + +### Authentication + +Enter the API key from the setup wizard. The key is also stored in: +```bash +grep API_KEY /etc/systemd/system/mixer-api.service +``` + +### Mixer View + +The main mixer screen shows: + +``` +┌─────────┬─────────┬─────────┬─────────┬─────────┐ +│ CH 1 │ CH 2 │ CH 3 │ ... │ Master │ +│ ┌─────┐ │ ┌─────┐ │ ┌─────┐ │ │ ┌─────┐ │ +│ │█████│ │ │███░░│ │ │█░░░░│ │ │ │████░│ │ +│ │█████│ │ │███░░│ │ │█░░░░│ │ │ │████░│ │ +│ │█████│ │ │███░░│ │ │█░░░░│ │ │ │████░│ │ +│ │█████│ │ │███░░│ │ │█░░░░│ │ │ │████░│ │ +│ └─────┘ │ └─────┘ │ └─────┘ │ │ └─────┘ │ +│ -3 dB │ 0 dB │ -∞ dB │ │ -6 dB │ +│ [M][S] │ [M][S] │ [M][S] │ │ [M][D] │ +└─────────┴─────────┴─────────┴─────────┴─────────┘ +``` + +- **Fader** — drag up/down to adjust volume (-60 dB to +12 dB) +- **M** button — mute the channel (red when active) +- **S** button — solo the channel (yellow when active) +- **Channel label** — tap to open channel detail panel + +### Channel Detail Panel + +Tap a channel label to open: + +- **3-band EQ** — Low (20-500 Hz), Mid (200-8000 Hz), High (2000-20000 Hz) + with frequency, gain (±15 dB), and Q controls +- **Compressor** — threshold, ratio, attack, release, makeup gain +- **Gate** — threshold, range +- **Gain** — preamp gain (-20 to +60 dB) +- **Pan** — stereo position +- **FX Sends** — send level to Aux A and Aux B +- **Phase invert** — toggle + +### Master Section + +- **Master Volume** — main output level +- **Mute** — silence all outputs +- **Dim** — reduce output by -20 dB (for talkback) +- **Monitor Volume** — control room monitor level +- **Phones Volume** — headphone output level + +### Navigation Tabs + +- **Mixer** — channel strips and master +- **Routing** — JACK routing matrix (drag connections between ports) +- **Plugins** — plugin browser and chain editor +- **Session** — save/load sessions, setlists +- **Record** — multi-track recording controls +- **Stream** — live streaming controls +- **Settings** — API key, network, display, audio config + +### Keyboard Shortcuts (Web UI) + +| Key | Action | +|-----|--------| +| `1-8` | Select channel 1-8 | +| `↑/↓` | Adjust fader ±1 dB | +| `Shift+↑/↓` | Adjust fader ±0.1 dB | +| `M` | Toggle mute on selected channel | +| `S` | Toggle solo on selected channel | +| `Space` | Transport play/stop | +| `R` | Start/stop recording | +| `Esc` | Deselect channel | + +--- + +## 4. Touchscreen UI + +The Kivy-based touch UI runs directly on the HDMI display — no browser needed. + +### Screen Layout + +The UI has four screens, cycled by swiping or pressing ESC: + +1. **Mixer Surface** — faders, meters, mute/solo for all 16 channels + master +2. **Routing Matrix** — drag to connect JACK audio ports +3. **Plugin Chain** — per-channel plugin slots with drag-and-drop +4. **Settings** — brightness, display timeout, DPI override + +### Touch Gestures + +| Gesture | Action | +|---------|--------| +| Swipe up/down on fader | Adjust volume | +| Tap fader cap | Select channel | +| Double-tap fader | Set to 0 dB (unity) | +| Swipe left/right | Navigate between screens | +| Long-press mute/solo | Latch mode (stays until pressed again) | +| Pinch (routing screen) | Zoom routing matrix | + +### Launch Options + +```bash +# Local mixer +python3 main_touch.py + +# Remote mixer +python3 main_touch.py --host 192.168.1.10 --api-key my-key + +# Force DPI (for non-standard displays) +KIVY_DPI=220 python3 main_touch.py +``` + +### Hardware Buttons (if available) + +Some touchscreens include physical buttons that can be mapped: + +```bash +# Example udev rule for Waveshare 5" buttons +# Maps KEY_UP/DOWN to channel select +``` + +--- + +## 5. MIDI Controller Operation + +Connect any class-compliant USB MIDI controller to control mixer parameters. + +### Supported Controllers + +The MIDI engine auto-detects controllers. Pre-configured mappings exist for: + +- **Behringer X-Touch** — 8 motorized faders, transport, scribble strips +- **Akai MIDImix** — 8 faders, 24 knobs, 16 buttons +- **Korg nanoKONTROL 2** — 8 faders, 8 knobs, transport +- **Novation Launch Control XL** — 8 faders, 24 knobs, 16 buttons + +See [docs/hardware-compatibility.md](hardware-compatibility.md) for the full list +and custom mapping instructions. + +### MIDI Learn Mode + +Map any MIDI controller to any mixer parameter without editing config files: + +1. **Enter learn mode:** + ```bash + curl -X POST http://pi-mixer.local:8080/midi/learn/start \ + -H "X-API-Key: your-key" + ``` + Or press the "Learn" button in the web UI or touch UI. + +2. **Click the parameter** you want to map (e.g., Channel 3 Volume) + +3. **Move the physical control** on your MIDI controller (fader, knob, or button) + +4. The mapping is saved automatically. Exit learn mode: + ```bash + curl -X POST http://pi-mixer.local:8080/midi/learn/stop \ + -H "X-API-Key: your-key" + ``` + +### MIDI Clock Sync + +The mixer can act as MIDI clock master or slave: + +- **Master mode:** mixer transport controls tempo; connected devices sync to it +- **Slave mode:** mixer follows external MIDI clock from a drum machine or DAW + +Configure via the web UI → Settings → MIDI or via API: +```bash +# Set as slave +curl -X PUT http://pi-mixer.local:8080/midi/clock/mode \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{"mode": "slave"}' +``` + +### NRPN Support + +High-resolution 14-bit NRPN messages are supported for parameters that benefit +from fine control (filter frequency, Q, etc.). The MIDI engine auto-detects +NRPN vs. CC messages from your controller. + +--- + +## 6. Multi-Track Recording + +Record up to 16 channels simultaneously to individual WAV files. + +### Recording Setup + +1. **Arm tracks** — in the web UI, click the **R** (record arm) button on each + channel you want to record. Armed channels show a red indicator. + +2. **Set recording directory:** + The default is `/data/recordings/session_NNN/`. Change via: + ```bash + curl -X PUT http://pi-mixer.local:8080/recording/path \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{"path": "/data/recordings/live-set-2026"}' + ``` + +3. **Configure recording format:** + - Bit depth: 16-bit, 24-bit, or 32-bit float + - Sample rate: inherits from JACK (48 kHz default) + - Punch in/out: set in/out points for selective recording + +### Recording Controls + +| Action | Web UI | API | +|--------|--------|-----| +| Start recording | Press **⏺ Record** | `POST /transport/command {"command": "record"}` | +| Stop recording | Press **⏹ Stop** | `POST /transport/command {"command": "stop"}` | +| Punch in | Automatic at marker | `POST /recording/punch/in {"channel": 3}` | +| Punch out | Automatic at marker | `POST /recording/punch/out {"channel": 3}` | +| New take | Creates new take file | `POST /recording/take/new` | + +### Recording Tips + +- **Use a fast SD card** — Class A2 minimum for 16-track recording. + Class A1 works for 8 tracks or fewer. +- **Monitor disk space** with `df -h /data`. The web UI shows a disk meter. +- **Punch in/out** is seamless — no clicks or gaps at edit points. +- **Auto-save** backs up session state every 30 seconds during recording. +- Each recording session creates a timestamped directory: + `/data/recordings/session_001/` containing `channel_01.wav` through + `channel_16.wav` plus `session_metadata.json`. + +--- + +## 7. Backing Tracks + +Play synchronized backing tracks alongside live inputs. + +### Setup + +1. **Upload tracks** to `/data/backing/`: + ```bash + scp my-backing.wav pi@pi-mixer.local:/data/backing/ + ``` + +2. **Supported formats:** WAV (16/24/32-bit), FLAC, MP3, AIFF, OGG + +3. **Create a playlist** via the web UI → Backing Tracks → New Playlist, or: + ```bash + curl -X POST http://pi-mixer.local:8080/backing/playlist \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{"name": "Set 1", "tracks": ["intro.wav", "song1.wav", "song2.flac"]}' + ``` + +### Playback Modes + +- **One-shot** — play once and stop +- **Loop** — repeat indefinitely +- **Segue** — auto-advance to next track with configurable crossfade (0.5-10s) +- **Playlist** — sequential playback with optional transitions + +### Transport Controls + +| Control | Description | +|---------|-------------| +| Play | Start playback from current position | +| Stop | Stop and return to start | +| Pause | Pause at current position | +| Skip →| | Next track | +| Skip |← | Previous track | +| Loop | Toggle loop mode | +| Count-in | Play 1-2 bar count-in before playback | + +### Metronome / Click Track + +The built-in metronome provides a click track routed to a dedicated output: + +- **Tempo:** 20-300 BPM (tap tempo supported) +- **Time signature:** 1/4 through 13/8 +- **Sounds:** click, beep, sidestick, custom samples +- **Output routing:** typically phones or a dedicated aux output + +```bash +# Set tempo and enable click +curl -X PUT http://pi-mixer.local:8080/transport/tempo \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{"bpm": 128}' +curl -X POST http://pi-mixer.local:8080/transport/metronome/on \ + -H "X-API-Key: your-key" +``` + +--- + +## 8. Live Streaming + +Stream audio and video to YouTube, Twitch, Facebook Live, or any RTMP server. + +### Quick Start — Stream to YouTube + +1. **Get your stream key** from YouTube Studio → Go Live → Stream Settings + +2. **Connect a USB camera** (or use Raspberry Pi Camera Module) + +3. **Start streaming** via the web UI → Stream, or: + ```bash + curl -X POST http://pi-mixer.local:8080/stream/start \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{ + "platform": "youtube", + "stream_key": "your-youtube-stream-key", + "video_source": "usb", + "audio_source": "mixer_master", + "bitrate_video": 4500, + "bitrate_audio": 192 + }' + ``` + +### Platform Presets + +| Platform | Video Bitrate | Audio Bitrate | Resolution | Notes | +|----------|--------------|---------------|------------|-------| +| YouTube | 4500-9000 Kbps | 192 Kbps | 1080p30/720p60 | H.264 recommended | +| Twitch | 4500-6000 Kbps | 160 Kbps | 1080p30/720p60 | Max 6000 Kbps | +| Facebook | 4000 Kbps | 128 Kbps | 720p30 | Max 720p | +| Custom RTMP | User-defined | User-defined | User-defined | Any RTMP server | + +### Scenes + +Create named scenes with different camera angles and overlays: + +```bash +# Save current camera/layout as scene +curl -X POST http://pi-mixer.local:8080/stream/scenes/wide-shot/save \ + -H "X-API-Key: your-key" + +# Switch scenes +curl -X POST http://pi-mixer.local:8080/stream/scenes/close-up/load \ + -H "X-API-Key: your-key" +``` + +### Streaming Tips + +- **Use Ethernet** — WiFi can cause dropped frames. If using WiFi, reduce + bitrate to 2500 Kbps. +- **Monitor bitrate** — the web UI shows a real-time bitrate meter. If it + drops, reduce video bitrate. +- **Dedicated audio bus** — route the stream audio to a subgroup for + independent level control vs. live PA. +- **CPU headroom** — 16 channels + streaming uses ~60% CPU on RPi 4. + Reduce channel count or buffer size if you hit limits. + +--- + +## 9. Session Management + +Save and recall complete mixer states — all fader positions, EQ settings, +plugin states, routing, and transport. + +### Save a Session + +Via web UI → Session → Save, or: +```bash +curl -X POST http://pi-mixer.local:8080/sessions/save \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{"name": "Live at The Garage", "notes": "Soundcheck levels"}' +``` + +### Load a Session + +```bash +curl -X POST "http://pi-mixer.local:8080/sessions/Live%20at%20The%20Garage/load" \ + -H "X-API-Key: your-key" +``` + +### Setlists + +Group sessions into setlists with configurable transitions: + +1. Create a setlist: + ```bash + curl -X POST http://pi-mixer.local:8080/setlists \ + -H "X-API-Key: your-key" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Summer Tour Set", + "items": [ + {"session": "Soundcheck", "transition": "cut"}, + {"session": "Opener", "transition": "crossfade", "duration": 3.0}, + {"session": "Main Set", "transition": "crossfade", "duration": 5.0}, + {"session": "Encore", "transition": "wait"} + ] + }' + ``` + +2. Transition types: + - **Cut** — instant switch + - **Crossfade** — smooth transition over N seconds + - **Wait** — manual advance (press "Next") + +### Auto-Save + +The mixer auto-saves state every 30 seconds (configurable) to +`~/.config/rpi-mixer/sessions/_autosave_YYYY-MM-DD.json`. The last 10 +auto-saves are kept (older ones are rotated out). + +### Snapshots + +Capture instantaneous snapshots without creating a full session: + +```bash +# MIDI-mappable: assign a button to snapshot save/load +# Save snapshot 3 (0-127 snapshots available) +curl -X POST http://pi-mixer.local:8080/snapshots/3/save \ + -H "X-API-Key: your-key" + +# Load snapshot 3 +curl -X POST http://pi-mixer.local:8080/snapshots/3/load \ + -H "X-API-Key: your-key" +``` + +--- + +## 10. OSC / DAW Integration + +The mixer exposes all parameters via Open Sound Control, enabling integration +with DAWs (Ableton Live, Reaper, Bitwig, Ardour) and custom controllers. + +### OSC Server + +- **Address:** `pi-mixer.local:9001` (UDP) +- **Endpoint format:** `/mixer/channel//` +- **Value range:** 0.0 to 1.0 (normalized) + +### Common OSC Commands + +``` +/mixer/channel/1/volume 0.75 # Set channel 1 volume to 0 dB +/mixer/channel/1/mute 1 # Mute channel 1 +/mixer/channel/1/pan -0.5 # Pan channel 1 left +/mixer/channel/1/eq_low_gain 0.5 # Boost channel 1 low EQ by 7.5 dB +/mixer/master/volume 0.8 # Set master volume +/mixer/transport/play 1 # Start transport +/mixer/transport/stop 1 # Stop transport +/mixer/transport/tempo 128.0 # Set tempo to 128 BPM +``` + +### OSC Query + +The server responds to OSC queries: +``` +/mixer/channel/1/volume → returns current value +/mixer/channel/*/volume → returns all 16 channel volumes +``` + +### Ableton Live Setup + +1. Add a new MIDI/OSC controller in Ableton preferences +2. Configure output to `pi-mixer.local:9001` (UDP) +3. Map Live's faders to `/mixer/channel/N/volume` +4. Map Live's transport to `/mixer/transport/play`, `/mixer/transport/stop` + +--- + +## 11. Plugins & Effects + +The mixer uses **Carla** as its plugin host, supporting LV2, VST2, and NAM +(Neural Amp Modeler) formats. + +### Plugin Browser + +Access via web UI → Plugins. Browse by category: + +- **Dynamics** — compressors, gates, limiters, expanders +- **EQ** — parametric, graphic, shelving +- **Reverb** — plate, hall, room, spring +- **Delay** — digital, tape, ping-pong +- **Modulation** — chorus, flanger, phaser, tremolo +- **Distortion** — overdrive, fuzz, amp sims, NAM captures +- **Utility** — meters, analyzers, routing tools + +### Per-Channel Plugin Chain + +Each channel supports up to 8 plugin slots in series: + +``` +Input → [Gate] → [EQ] → [Comp] → [Amp] → [FX Slot 1] → [FX Slot 2] → Fader → Output +``` + +Plugins can be reordered by dragging in the UI. + +### Aux Sends & Returns + +Four aux buses (FX A through D) provide shared effects: + +1. Route a channel to an aux via its **FX Send** knob +2. Insert effects on the aux return (e.g., reverb on Aux A, delay on Aux B) +3. Blend the wet signal with the channel strip's dry signal +4. Control the overall aux level via **FX Return** faders in the master section + +### NAM (Neural Amp Modeler) + +Load guitar/bass amp captures for realistic amp simulation: + +1. Place `.nam` files in `/data/presets/nam/` +2. Insert a NAM plugin on a channel +3. Select the capture from the dropdown +4. Adjust input gain and output level + +```bash +# Scan for new NAM models +curl -X POST http://pi-mixer.local:8080/plugins/scan \ + -H "X-API-Key: your-key" +``` + +--- + +## 12. Fader Automation & Scenes + +### Fader Automation + +Record and playback fader movements: + +1. **Arm automation** for a channel (click **A** button) +2. **Press Play** — fader movements are recorded +3. **Press Stop** — automation lane is saved +4. **Playback** — faders move automatically according to recorded automation +5. **Overwrite** — re-record by arming again + +Automation modes: +- **Read** — playback recorded automation (fader is read-only) +- **Write** — record new automation (overwrites existing) +- **Touch** — record only while touching the fader +- **Latch** — record from first touch until stop + +### Scenes + +Scenes are snapshots of all fader positions that can be recalled instantly: + +1. **Save a scene:** + ```bash + curl -X POST http://pi-mixer.local:8080/scenes/Chorus/save \ + -H "X-API-Key: your-key" + ``` + +2. **Load a scene** (instant recall): + ```bash + curl -X POST http://pi-mixer.local:8080/scenes/Chorus/load \ + -H "X-API-Key: your-key" + ``` + +3. **Next/Previous scene** (MIDI-mappable for footswitch control) + +Modifier scenes only affect specific channels: + +```bash +# Save a modifier scene that only changes channels 1-4 +curl -X POST http://pi-mixer.local:8080/scenes/Vocals-Up/save \ + -H "X-API-Key: your-key" \ + -d '{"mode": "modifier", "channels": [1, 2, 3, 4]}' +``` + +--- + +## Appendix: REST API Quick Reference + +All endpoints require `X-API-Key` header. + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/channels` | List all channel states | +| GET | `/channels/{n}` | Get channel n state | +| PUT | `/channels/{n}/parameter` | Set channel parameter | +| GET | `/mixes` | Master bus + aux + subgroups | +| PUT | `/mixes/parameter` | Set master parameter | +| GET | `/transport` | Transport state | +| PUT | `/transport/command` | Play/stop/record/loop | +| GET | `/routing` | JACK routing matrix | +| GET | `/plugins` | Plugin list | +| GET | `/scenes` | Scene list | +| POST | `/scenes/{name}/save` | Save current state as scene | +| POST | `/scenes/{name}/load` | Load a scene | +| GET | `/sessions` | Session list | +| POST | `/sessions/{name}/save` | Save session | +| POST | `/sessions/{name}/load` | Load session | +| POST | `/setlists` | Create setlist | +| GET | `/stream/status` | Streaming status | +| POST | `/stream/start` | Start streaming | +| POST | `/stream/stop` | Stop streaming | +| POST | `/recording/start` | Start recording | +| POST | `/recording/stop` | Stop recording | +| POST | `/midi/learn/start` | Enter MIDI learn mode | +| POST | `/midi/learn/stop` | Exit MIDI learn mode | +| GET | `/stats` | Server statistics | +| GET | `/ws` | WebSocket for real-time updates |