P7-R2: Wiki documentation — Obsidian + Gitea wiki pages
Lint & Validate / lint (push) Has been cancelled

This commit is contained in:
2026-05-19 22:49:16 -04:00
parent e9c504c0d7
commit 5e208d5123
2 changed files with 542 additions and 41 deletions
+156 -41
View File
@@ -1,58 +1,173 @@
# Raspberry Pi Real-Time Audio Mixer
RPi4B-based multi-channel real-time audio mixer with custom PREEMPT_RT kernel.
[![Python](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/)
[![Platform](https://img.shields.io/badge/platform-Raspberry%20Pi%204B-red.svg)](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-735%20passing-brightgreen.svg)](tests/)
[![Build](https://img.shields.io/badge/build-PREEMPT__RT-orange.svg)](build/)
A professional multi-channel real-time audio mixer running on a Raspberry Pi 4B.
Sub-10ms round-trip latency with 16-channel USB audio, MIDI controller support,
touchscreen UI, multi-track recording, live streaming, and a web control surface.
## Features
- **16-channel mixer** with 3-band EQ, compressor, gate, gain, pan, mute, solo per channel
- **4 aux sends**, 2 subgroups, 2 VCA groups, master bus with dim and monitor
- **MIDI controller support** — CC, NRPN, learn mode, clock sync, JACK MIDI bridge
- **Multi-track recording** — per-channel WAV capture with write-ahead buffering, punch in/out
- **Backing track player** — sync'd playback with metronome, loop/one-shot/segue modes
- **Live streaming** — GStreamer H.264 to YouTube, Twitch, Facebook, or custom RTMP
- **Session manager** — save/load mixer states, setlists with transitions, auto-save
- **Touchscreen UI** — Kivy-based multi-touch interface for 5"/7" displays
- **Web control surface** — FastAPI REST API + WebSocket real-time updates
- **OSC server** — Open Sound Control for DAW integration (Ableton, Reaper, etc.)
- **Plugin host** — LV2, VST2, NAM neural amp models via Carla rack
- **Fader automation** — record, playback, scenes with interpolation
- **SD card image builder** — automated build script produces ready-to-flash images
## Architecture
- **Platform:** Raspberry Pi 4 Model B (8GB RAM)
- **OS:** Raspberry Pi OS Lite (64-bit, Bookworm) + custom PREEMPT_RT kernel
- **Audio:** USB audio interface with multi-channel I/O
- **Goal:** Low-latency (<10ms round-trip) multi-channel audio mixing
```
┌──────────────────────────────────────────────────────────────┐
│ User Interfaces │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Touch UI │ │ Web UI │ │ MIDI Controllers │ │
│ │ (Kivy/HDMI) │ │ (FastAPI) │ │ (USB/ALSA seq) │ │
│ └──────┬──────┘ └──────┬───────┘ └────────┬───────────┘ │
│ │ │ │ │
├─────────┼────────────────┼────────────────────┼──────────────┤
│ │ REST/WS │ OSC │ MIDI/CC/NRPN │
│ ┌──────▼────────────────▼────────────────────▼──────────┐ │
│ │ Mixer Engine (Python) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │DSP Engine│ │Recording │ │ Streaming│ │ Session │ │ │
│ │ │+ Carla │ │(WAV) │ │(GStream) │ │ Manager │ │ │
│ │ └────┬─────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ OSC │ │
│ │ ┌────▼─────────────────────────────────────────────┐ │ │
│ │ │ Carla Rack (LV2/VST/NAM) │ │ │
│ │ └────────────────────┬─────────────────────────────┘ │ │
│ └───────────────────────┼────────────────────────────────┘ │
│ │ JACK │
│ ┌─────▼──────┐ │
│ │ JACK2 RT │ SCHED_FIFO prio 70 │
│ └─────┬──────┘ │
│ │ ALSA hw:USB │
├──────────────────────────┼────────────────────────────────────┤
│ Kernel │ │
│ ┌───────────────────────▼──────────────────────────────┐ │
│ │ PREEMPT_RT 6.12.y │ snd-usb-audio │ xHCI USB │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
```
## Quick Start
### Option 1: Download SD Card Image (Recommended)
1. Download the latest `rpi-audio-mixer-*.img.xz` from [Releases](https://github.com/your-org/rpi-audio-mixer/releases)
2. Flash to a 16GB+ SD card:
```bash
xz -d rpi-audio-mixer-*.img.xz
sudo dd if=rpi-audio-mixer-*.img of=/dev/sdX bs=4M status=progress conv=fsync
```
3. Insert SD card into RPi 4B, connect USB audio interface, power on
4. Follow the first-boot setup wizard on HDMI display
5. Open `http://pi-mixer.local:8080` in your browser
### Option 2: Build from Source
```bash
# Install build dependencies
sudo apt install wget xz-utils dosfstools e2fsprogs qemu-user-static
# Quick build (stock kernel, 10-15 min)
./build/build.sh --skip-kernel
# Full build with PREEMPT_RT kernel (30-45 min)
./build/build.sh
```
See [docs/build-guide.md](docs/build-guide.md) for detailed instructions.
### Option 3: Development Setup
```bash
# Install dependencies
sudo apt install jackd2 carla python3-pip
pip install fastapi uvicorn python-jack-client numpy
# Run tests
python -m pytest tests/ -v
# Start the API server (without full hardware)
python -m src.network.run
```
## Project Structure
```
├── docs/ Research, architecture decisions, manuals
│ ├── research/ Technical research reports
│ ├── decisions/ Architecture Decision Records (ADRs)
── manuals/ Hardware/software manuals and references
├── src/ Source code (audio engine, DSP, UI)
├── build/ Build scripts and cross-compilation tooling
├── recipes/ Buildroot/Yocto recipes (if applicable)
├── scripts/ Utility and deployment scripts
└── wiki/ Local wiki pages
├── src/
│ ├── mixer/ DSP engine, channel strips, routing, OSC, automation
│ ├── midi/ MIDI engine, learn mode, clock sync, device discovery
── session/ Session manager, setlists, snapshots
│ ├── recording/ Multi-track WAV recorder with punch in/out
│ ├── backing/ Backing track player, metronome, transport
│ ├── streaming/ GStreamer pipeline, platform presets, camera
│ ├── network/ REST API, WebSocket, OSC server, auth
│ ├── plugin/ Plugin manager, LV2/VST/NAM support, scanner
│ └── ui/ Kivy touchscreen UI, widgets, screens
├── tests/ 735 tests (pytest)
├── build/ SD card image builder + first-boot scripts
├── scripts/ Utility scripts (Carla presets, LV2 lint, NAM build)
└── docs/ User and developer documentation
```
## Documentation
| Document | Description |
|----------|-------------|
| [docs/build-guide.md](docs/build-guide.md) | Step-by-step SD card image build instructions |
| [docs/user-manual.md](docs/user-manual.md) | Comprehensive mixer operation guide |
| [docs/hardware-compatibility.md](docs/hardware-compatibility.md) | Tested USB interfaces, MIDI controllers, displays |
| [docs/developer-guide.md](docs/developer-guide.md) | Architecture, contributing, source build |
| [docs/troubleshooting.md](docs/troubleshooting.md) | Common issues and solutions |
| [build/README.md](build/README.md) | Image builder reference |
## System Requirements
- **Computer:** Raspberry Pi 4 Model B (4GB+ RAM recommended)
- **SD Card:** 16GB+ Class A2 (32GB+ recommended for recordings)
- **Display:** HDMI touchscreen (official 7" or Waveshare 5") or headless via web UI
- **Audio:** USB audio interface (class-compliant UAC2)
- **Network:** Ethernet recommended; WiFi supported
- **Power:** 5V/3A USB-C power supply
## Performance
| Metric | Value |
|--------|-------|
| Round-trip latency | <10ms (128 frames @ 48kHz) |
| Channels | 16 mono / 8 stereo |
| Sample rate | 48 kHz (44.1k and 96k supported) |
| Bit depth | 32-bit float (internal), 16/24-bit WAV |
| CPU usage (idle) | ~5% (all 16 channels driven) |
| Recording tracks | Up to 16 simultaneous WAV |
| Streaming | 1080p30 H.264 @ 4-8 Mbps |
## Status
**Phase 1-7: Complete audio mixer stack with SD card image builder**
All planned phases complete:
- [x] P1-R1: System Research — USB audio, PREEMPT_RT kernel analysis
- [x] P1-R2: Base OS Selection — RPiOS Lite 64-bit + custom PREEMPT_RT
- [x] P2-R1: ALSA + JACK2 Low-Latency Config
- [x] P3-R1: Core Mixer Engine — DSP pipeline, channel strips, routing
- [x] P3-R2: Backing Track Player — sync'd audio playback
- [x] P3-R3: Multi-Track Recording — WAV capture + session
- [x] P4-R1: MIDI Controller Support — Binding + Learn Mode
- [x] P5-R3: Web App Frontend — touch-optimized mixer UI
- [x] P6-R1: Streaming Pipeline — GStreamer H.264 to YouTube/Twitch
- [x] P6-R2: Session Manager — save/load mixer states + setlists
- [x] P7-R1: Build Script — automated SD card image creation
## SD Card Image Builder
```bash
# Build a ready-to-flash SD card image
./build/build.sh --skip-kernel # Quick build (10-15 min)
./build/build.sh # Full build with RT kernel (30-45 min)
```
See [build/README.md](build/README.md) for flashing instructions and full documentation.
## Getting Started
*Documentation coming in Phase 2+*
- [x] P1: System Research & OS Selection — RPiOS Lite + PREEMPT_RT
- [x] P2: ALSA + JACK2 Low-Latency Configuration
- [x] P3: Core Mixer Engine, Backing Tracks, Multi-Track Recording
- [x] P4: MIDI Controller Support with Learn Mode
- [x] P5: Web App + Touchscreen UI (Kivy)
- [x] P6: Streaming Pipeline + Session Manager
- [x] P7: SD Card Image Builder + Documentation
## License
TBD
MIT
+386
View File
@@ -0,0 +1,386 @@
# Build Guide — SD Card Image Builder
This guide walks through building a ready-to-flash Raspberry Pi SD card image
containing the full audio mixer stack with a PREEMPT_RT kernel.
## Prerequisites
### Host System Requirements
- **OS:** Any modern Linux distribution (x86_64) — Ubuntu 22.04+, Debian 12+, Fedora 38+
- **CPU:** 4+ cores recommended (cross-compilation is parallel)
- **RAM:** 4GB+ (8GB recommended for full PREEMPT_RT kernel build)
- **Disk:** 15GB free space (build artifacts + downloaded OS image)
- **Architecture:** x86_64 host for QEMU user-static chroot emulation
- **macOS** is supported via a Linux VM or Docker container
### Install Build Dependencies
```bash
# Ubuntu / Debian
sudo apt update
sudo apt install -y \
wget xz-utils \
dosfstools e2fsprogs \
qemu-user-static \
parted \
git
# For PREEMPT_RT kernel cross-compilation (optional)
sudo apt install -y \
gcc-aarch64-linux-gnu \
build-essential \
flex bison \
libssl-dev \
bc \
rsync
# Verify QEMU binary is registered
sudo update-binfmts --enable qemu-aarch64
```
```bash
# Fedora
sudo dnf install -y wget xz dosfstools e2fsprogs qemu-user-static parted git
```
## Build Modes
The build script supports three modes, controlled by command-line flags:
| Command | Description | Time | Requires |
|---------|-------------|------|----------|
| `./build/build.sh --skip-kernel` | Quick build, stock RPi kernel | 10-15 min | Basic deps only |
| `./build/build.sh` | Full build with PREEMPT_RT kernel | 30-45 min | + gcc-aarch64 + kernel deps |
| `./build/build.sh --kernel-only` | Build only the RT kernel .deb | 10-15 min | + gcc-aarch64 + kernel deps |
## Step-by-Step: Quick Build (Recommended First Build)
This builds the mixer image using the stock Raspberry Pi OS kernel — fastest
way to get a working image for testing. No cross-compilation toolchain needed.
```bash
# 1. Clone the repository
git clone https://github.com/your-org/rpi-audio-mixer.git
cd rpi-audio-mixer
# 2. Run the quick build
./build/build.sh --skip-kernel
# 3. The compressed image lands here:
ls -lh build/out/rpi-audio-mixer-*.img.xz
```
**What happens during the build:**
1. Downloads Raspberry Pi OS Lite (64-bit, Bookworm) base image (~1.1 GB)
2. Extracts and resizes the image (default 8 GB total)
3. Mounts the image partitions via loopback
4. Chroots into the ARM64 filesystem using QEMU user-static
5. Installs audio packages (JACK2, Carla, ALSA tools, Python deps)
6. Copies the mixer source code and systemd service files
7. Configures real-time audio limits, CPU governor, udev rules
8. Sets up first-boot wizard
9. Unmounts and compresses the final image
## Step-by-Step: Full PREEMPT_RT Build
The full build includes a custom PREEMPT_RT kernel cross-compiled for aarch64
on your x86_64 host. This is what you want for production use.
```bash
# 1. Ensure cross-compilation toolchain is installed
sudo apt install -y gcc-aarch64-linux-gnu build-essential flex bison libssl-dev bc
# 2. Run the full build
./build/build.sh
# This will:
# a. Cross-compile linux-rpi-6.12.y with PREEMPT_RT patch
# b. Package the kernel as a .deb
# c. Build the SD card image with the RT kernel installed
# d. Configure boot/config.txt to use the RT kernel
# 3. Output
ls -lh build/out/rpi-audio-mixer-*.img.xz
```
### Kernel Cross-Compilation Details
The build script:
- Clones `raspberrypi/linux` at branch `rpi-6.12.y`
- Applies the `PREEMPT_RT` patch for 6.12
- Uses `make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig`
- Configures: `CONFIG_PREEMPT_RT=y`, `CONFIG_HZ=1000`
- Builds with `make -j$(nproc)` for parallel compilation
- Packages into a `.deb` using `make deb-pkg`
## Build Customization
### Image Size
The default image is 8 GB. Adjust with `--image-size` (in MB):
```bash
./build/build.sh --skip-kernel --image-size 16384 # 16 GB image
./build/build.sh --skip-kernel --image-size 32768 # 32 GB image
```
### Pre-configure WiFi
Set these environment variables before building:
```bash
MIXER_WIFI_SSID="MyNetwork" \
MIXER_WIFI_PASS="secret123" \
./build/build.sh --skip-kernel
```
### Custom Hostname
```bash
MIXER_HOSTNAME="stage-mixer" ./build/build.sh --skip-kernel
```
### Custom API Key for CI
```bash
MIXER_API_KEY="my-pre-shared-key" ./build/build.sh --skip-kernel
```
### Custom OS Base Image
```bash
RPIOS_URL="https://downloads.raspberrypi.com/raspios_lite_arm64/images/..." \
./build/build.sh
```
### Version Tagging
```bash
export MIXER_VERSION="$(git describe --tags --always)"
./build/build.sh --skip-kernel
```
## Cleaning Up
```bash
# Remove all build artifacts
./build/build.sh --clean
# This deletes:
# build/work/ (mounted image, chroot state, temporary files)
# build/downloads/ (cached OS image downloads)
# build/out/ (built images)
# To preserve downloads (they're cached for faster rebuilds):
rm -rf build/work/ build/out/
```
## Image Contents
```
Partition layout:
├── /boot (FAT32, 256 MB)
│ ├── kernel8.img Stock 64-bit kernel (fallback)
│ ├── kernel8-rt.img PREEMPT_RT kernel (default if built)
│ ├── config.txt GPU, boot, kernel selection
│ ├── cmdline.txt Kernel parameters (isolcpus, threadirqs, etc.)
│ └── *.dtb, overlays/ Device tree blobs
├── / (ext4, ~4 GB used of 6 GB)
│ ├── /opt/rpi-mixer/ Mixer Python source + virtualenv
│ ├── /etc/systemd/system/ Service unit files
│ │ ├── cpu-performance.service
│ │ ├── jackd.service
│ │ ├── mixer-api.service
│ │ ├── mixer-ui.service
│ │ └── mixer-firstboot.service
│ ├── /etc/security/limits.d/99-audio.conf
│ ├── /etc/modprobe.d/alsa-usb.conf
│ └── /home/pi/ Default user home
└── /data (ext4, remaining space)
├── sessions/ Saved mixer session JSON files
├── recordings/ Multi-track WAV recordings
├── presets/ Plugin presets
└── logs/ System and audio logs
```
## Flashing to SD Card
### Linux
```bash
# Decompress the image
xz -d build/out/rpi-audio-mixer-*.img.xz
# Identify your SD card
lsblk
# Look for /dev/sdb or /dev/mmcblk0 (NOT your system drive!)
# Flash the image
sudo dd if=build/out/rpi-audio-mixer-*.img \
of=/dev/sdX \
bs=4M \
status=progress \
conv=fsync
# Sync and eject
sync
sudo eject /dev/sdX
```
### macOS
```bash
# Decompress
xz -d build/out/rpi-audio-mixer-*.img.xz
# Find the SD card
diskutil list
# Look for /dev/diskX (external, physical)
# Unmount
diskutil unmountDisk /dev/diskX
# Flash (use rdisk for faster writes)
sudo dd if=build/out/rpi-audio-mixer-*.img \
of=/dev/rdiskX \
bs=4m \
status=progress
# Eject
diskutil eject /dev/diskX
```
### Windows
Use [Raspberry Pi Imager](https://www.raspberrypi.com/software/) or [balenaEtcher](https://www.balena.io/etcher/):
1. Decompress the `.img.xz` file with 7-Zip or WinRAR
2. Open Raspberry Pi Imager → "Choose OS" → "Use custom"
3. Select the `.img` file
4. Choose your SD card and flash
## First Boot
1. Insert the SD card into a Raspberry Pi 4B
2. Connect your USB audio interface
3. (Optional) Connect HDMI touchscreen + Ethernet
4. Power on
The **first-boot setup wizard** will appear on the HDMI display (or serial
console). It walks through:
1. Audio interface detection and selection
2. WiFi network configuration
3. Hostname setting
4. API key generation (for web UI access)
5. JACK buffer size and latency preferences
After the wizard completes, the system reboots into normal operation.
The wizard auto-disables itself — it only runs once.
### Default Access
| Service | URL / Command | Default Credentials |
|---------|--------------|---------------------|
| Web UI | `http://pi-mixer.local:8080` | API key from wizard |
| SSH | `ssh pi@pi-mixer.local` | Password: `raspberry` |
| Touch UI | HDMI display (auto-starts) | — |
**Important:** Change the default password immediately:
```bash
ssh pi@pi-mixer.local
passwd
```
### Service Management
```bash
# Check all mixer services
systemctl status jackd mixer-api mixer-ui
# View logs
journalctl -u mixer-api -f
journalctl -u jackd -f
# Restart services (must follow order: jackd → mixer-api → mixer-ui)
sudo systemctl stop mixer-ui mixer-api jackd
sudo systemctl start jackd
sleep 2
sudo systemctl start mixer-api mixer-ui
```
## CI / Automated Builds
Build without a Raspberry Pi (CI-friendly) on any x86_64 host:
```bash
export MIXER_VERSION="$(git describe --tags --always)"
export MIXER_HOSTNAME="ci-mixer"
export MIXER_API_KEY="ci-test-key-12345"
./build/build.sh --skip-kernel
```
Example GitHub Actions / Gitea CI workflow:
```yaml
- name: Build SD card image
run: |
sudo apt install -y wget xz-utils dosfstools e2fsprogs qemu-user-static
./build/build.sh --skip-kernel
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sd-card-image
path: build/out/rpi-audio-mixer-*.img.xz
```
## Kernel-Only Build
When you only need a new PREEMPT_RT kernel (e.g., to upgrade an existing
image without rebuilding everything):
```bash
# Build only the kernel .deb package
./build/build.sh --kernel-only
# The .deb lands in build/out/
ls build/out/linux-image-*.deb
# Install on the RPi:
# scp build/out/linux-image-*.deb pi@pi-mixer.local:/tmp/
# ssh pi@pi-mixer.local
# sudo dpkg -i /tmp/linux-image-*.deb
# sudo reboot
```
## Troubleshooting Build Issues
| Problem | Solution |
|---------|----------|
| `qemu-aarch64-static not found` | `sudo apt install qemu-user-static && sudo update-binfmts --enable qemu-aarch64` |
| `apt fails in chroot` | DNS not resolving — check host `/etc/resolv.conf` is accessible |
| `No space left on device` | Increase image size: `--image-size 16384` |
| `kernel build fails` | Install missing deps: `sudo apt install gcc-aarch64-linux-gnu flex bison libssl-dev bc` |
| `loop device busy` | Run `sudo losetup -D` to detach stale loop devices |
| `permission denied` | Build must run with passwordless sudo or as root |
For runtime issues after flashing, see [docs/troubleshooting.md](troubleshooting.md).
## Architecture Decision
This project uses **Raspberry Pi OS Lite (64-bit, Bookworm) + post-install
configuration** rather than Buildroot or Yocto. Rationale:
- Full Debian package ecosystem for rapid audio stack iteration
- `apt install` for JACK, Carla, debugging tools — no image rebuilds needed
- Standard systemd-based system — familiar and well-documented
- PREEMPT_RT kernel built via cross-compilation on x86 host
- Buildroot/Yocto can be revisited for production appliance images
See [docs/research/base-os-decision.md](research/base-os-decision.md) for the
full analysis.