- --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
This commit is contained in:
+41
-2
@@ -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
|
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
|
## 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 --skip-kernel` | Quick build, stock kernel | 10-15 min |
|
||||||
| `./build/build.sh --kernel-only` | Only build RT 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 --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
|
## Flashing to SD Card
|
||||||
|
|
||||||
@@ -48,6 +51,42 @@ sync
|
|||||||
sudo eject /dev/sdX
|
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
|
### From macOS
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+53
-7
@@ -1,16 +1,19 @@
|
|||||||
#!/bin/bash
|
#!/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
|
# - RPiOS Lite (64-bit, Bookworm) base
|
||||||
# - Optional PREEMPT_RT kernel (cross-compiled on x86)
|
# - Optional PREEMPT_RT kernel (cross-compiled on x86)
|
||||||
# - JACK2, Carla, ALSA tools, Python deps
|
# - JACK2, Carla, ALSA tools, Python deps
|
||||||
# - Full mixer engine + web UI + Kivy touch UI
|
# - Full mixer engine + web UI + Kivy touch UI
|
||||||
# - First-boot setup wizard
|
# - First-boot setup wizard
|
||||||
# - systemd services for auto-start
|
# - systemd services for auto-start
|
||||||
|
# - Target-specific boot config (SD / USB SSD / NVMe HAT)
|
||||||
#
|
#
|
||||||
# Usage:
|
# 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 --skip-kernel # Skip RT kernel build (use stock kernel)
|
||||||
# ./build.sh --kernel-only # Only build RT kernel, skip image
|
# ./build.sh --kernel-only # Only build RT kernel, skip image
|
||||||
# ./build.sh --output ./my-image.img # Custom output path
|
# ./build.sh --output ./my-image.img # Custom output path
|
||||||
@@ -31,7 +34,7 @@
|
|||||||
# - Cross-compile (optional): gcc-aarch64-linux-gnu, libssl-dev:arm64
|
# - Cross-compile (optional): gcc-aarch64-linux-gnu, libssl-dev:arm64
|
||||||
#
|
#
|
||||||
# Output:
|
# Output:
|
||||||
# build/out/rpi-audio-mixer-<version>.img SD card image
|
# build/out/rpi-audio-mixer-<version>.img Disk image (SD/USB/NVMe)
|
||||||
# build/out/rpi-audio-mixer-<version>.img.xz Compressed image
|
# build/out/rpi-audio-mixer-<version>.img.xz Compressed image
|
||||||
|
|
||||||
set -euo pipefail
|
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_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_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}"
|
MIXER_HOSTNAME="${MIXER_HOSTNAME:-pi-mixer}"
|
||||||
|
|
||||||
|
# Boot target
|
||||||
|
TARGET="${TARGET:-sd}" # sd, usb, or nvme
|
||||||
MIXER_WIFI_SSID="${MIXER_WIFI_SSID:-}"
|
MIXER_WIFI_SSID="${MIXER_WIFI_SSID:-}"
|
||||||
MIXER_WIFI_PASS="${MIXER_WIFI_PASS:-}"
|
MIXER_WIFI_PASS="${MIXER_WIFI_PASS:-}"
|
||||||
|
|
||||||
@@ -255,6 +261,14 @@ build_rt_kernel() {
|
|||||||
# USB audio (build as module)
|
# USB audio (build as module)
|
||||||
scripts/config -m CONFIG_SND_USB_AUDIO
|
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
|
make ARCH=arm64 CROSS_COMPILE="$CROSS_COMPILE" olddefconfig
|
||||||
else
|
else
|
||||||
log "Kernel .config already has PREEMPT_RT enabled"
|
log "Kernel .config already has PREEMPT_RT enabled"
|
||||||
@@ -532,9 +546,41 @@ finalize_image() {
|
|||||||
echo " Kernel: Stock RPiOS (PREEMPT_RT not included)"
|
echo " Kernel: Stock RPiOS (PREEMPT_RT not included)"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BOLD}To flash to SD card:${NC}"
|
echo -e "${BOLD}Boot target:${NC} ${TARGET^^}"
|
||||||
echo " sudo dd if=$img_file of=/dev/sdX bs=4M status=progress conv=fsync"
|
if [[ "$TARGET" == "sd" ]]; then
|
||||||
echo ""
|
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 -e "${BOLD}First boot:${NC}"
|
||||||
echo " - The setup wizard will guide you through configuration"
|
echo " - The setup wizard will guide you through configuration"
|
||||||
echo " - Default hostname: $MIXER_HOSTNAME"
|
echo " - Default hostname: $MIXER_HOSTNAME"
|
||||||
|
|||||||
@@ -307,6 +307,36 @@ fi
|
|||||||
|
|
||||||
press_enter
|
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 ─────────────────────────────────────────────────────────────
|
# ─── 8. Finalize ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
header "Setup Complete"
|
header "Setup Complete"
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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://<ip-address>: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/<n>/<parameter>`
|
||||||
|
- **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 |
|
||||||
Reference in New Issue
Block a user