P7-R2: Wiki documentation — Obsidian + Gitea wiki pages
Lint & Validate / lint (push) Has been cancelled
Lint & Validate / lint (push) Has been cancelled
This commit is contained in:
@@ -1,58 +1,173 @@
|
|||||||
# Raspberry Pi Real-Time Audio Mixer
|
# Raspberry Pi Real-Time Audio Mixer
|
||||||
|
|
||||||
RPi4B-based multi-channel real-time audio mixer with custom PREEMPT_RT kernel.
|
[](https://www.python.org/)
|
||||||
|
[](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/)
|
||||||
|
[](LICENSE)
|
||||||
|
[](tests/)
|
||||||
|
[](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
|
## 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
|
│ User Interfaces │
|
||||||
- **Goal:** Low-latency (<10ms round-trip) multi-channel audio mixing
|
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
|
||||||
|
│ │ 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
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
├── docs/ Research, architecture decisions, manuals
|
├── src/
|
||||||
│ ├── research/ Technical research reports
|
│ ├── mixer/ DSP engine, channel strips, routing, OSC, automation
|
||||||
│ ├── decisions/ Architecture Decision Records (ADRs)
|
│ ├── midi/ MIDI engine, learn mode, clock sync, device discovery
|
||||||
│ └── manuals/ Hardware/software manuals and references
|
│ ├── session/ Session manager, setlists, snapshots
|
||||||
├── src/ Source code (audio engine, DSP, UI)
|
│ ├── recording/ Multi-track WAV recorder with punch in/out
|
||||||
├── build/ Build scripts and cross-compilation tooling
|
│ ├── backing/ Backing track player, metronome, transport
|
||||||
├── recipes/ Buildroot/Yocto recipes (if applicable)
|
│ ├── streaming/ GStreamer pipeline, platform presets, camera
|
||||||
├── scripts/ Utility and deployment scripts
|
│ ├── network/ REST API, WebSocket, OSC server, auth
|
||||||
└── wiki/ Local wiki pages
|
│ ├── 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
|
## 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: System Research & OS Selection — RPiOS Lite + PREEMPT_RT
|
||||||
- [x] P1-R2: Base OS Selection — RPiOS Lite 64-bit + custom PREEMPT_RT
|
- [x] P2: ALSA + JACK2 Low-Latency Configuration
|
||||||
- [x] P2-R1: ALSA + JACK2 Low-Latency Config
|
- [x] P3: Core Mixer Engine, Backing Tracks, Multi-Track Recording
|
||||||
- [x] P3-R1: Core Mixer Engine — DSP pipeline, channel strips, routing
|
- [x] P4: MIDI Controller Support with Learn Mode
|
||||||
- [x] P3-R2: Backing Track Player — sync'd audio playback
|
- [x] P5: Web App + Touchscreen UI (Kivy)
|
||||||
- [x] P3-R3: Multi-Track Recording — WAV capture + session
|
- [x] P6: Streaming Pipeline + Session Manager
|
||||||
- [x] P4-R1: MIDI Controller Support — Binding + Learn Mode
|
- [x] P7: SD Card Image Builder + Documentation
|
||||||
- [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+*
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
TBD
|
MIT
|
||||||
|
|||||||
@@ -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.
|
||||||
Reference in New Issue
Block a user