Files
pi-multifx-pedal/docs/audio-io-research.md
T
shawn c38a7b0fd8 Add main entry point + systemd services + integration tests
New files:
  main.py                   - PedalApp: boots all subsystems in order,
                              wires MIDI/footswitch callbacks, graceful
                              teardown reverses boot order
  src/system/config.py      - YAML config loader with deep-merge
                              (separated to avoid hardware deps)
  src/system/services.py    - systemd unit generator for pedal.service
                              + multi-fx-pedal.target
  scripts/install_service.sh - copies project, creates venv, installs
                              + enables service units
  tests/test_integration.py - 41 tests: boot, routing, display sync,
                              teardown, systemd content, CLI, edge cases

Modified:
  tests/conftest.py         - add project root to sys.path
2026-06-07 23:39:50 -04:00

459 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Audio I/O Hardware Selection — Research Report
> **Project:** Pi Multi-FX Pedal (RPi 4B)
> **Goal:** Select I2S ADC+DAC solution for real-time guitar processing with <10ms round-trip latency
> **Date:** 2026-06-07
> **Status:** Final — all overlay data verified against upstream Raspberry Pi kernel rpi-6.6.y
---
## Comparison Matrix
| Option | Type | ADC | DAC | Max Bit/Sample | Price (USD) | Power | Overlay Support (upstream kernel) | Round-Trip Latency* | Noise Floor | Headphone Amp | Hardware Mixing |
|--------|------|-----|-----|---------------|:-----------:|:-----:|:------------:|:------------------:|:-----------:|:-------------:|:---------------:|
| **AudioInjector Stereo HAT** | HAT | WM8731 | WM8731 | 24-bit / 48kHz | ~$35-40 | 5V tolerant | `audioinjector-wm8731-audio` | ~4-6ms @ 128fr | ~-84dB | Yes (built-in WM8731) | No |
| **HiFiBerry DAC+ADC Pro** | HAT | PCM1864 | PCM5122 | 24-bit / 192kHz | ~$42 | 5V tolerant | `hifiberry-dacplusadcpro` | ~3-5ms @ 128fr | ~-95dB | No (line out) | Yes |
| **IQaudio Codec Zero** | HAT | ADC-in-codec | Codec DAC | 24-bit / 48kHz | ~$18 | 3.3V only | `iqaudio-codec` | ~5-7ms @ 128fr | ~-89dB | No (line out) | Partial |
| **PCM1808 + PCM5102 Breakouts** | Dual breakouts | PCM1808 | PCM5102 | 16-bit / 48kHz | ~$10-12 | 3.3V only | `i2s-dac` (DAC only — no ADC overlay) | ~6-8ms @ 256fr | ~-86dB (PCM5102 hiss) | No | No |
| **JustBoom DAC/ADC HAT** | HAT | PCM1864 | PCM5122 | 24-bit / 192kHz | ~$40+ | 5V tolerant | `justboom-dac` (DAC only — ADC via codec) | ~3-5ms @ 128fr | ~-95dB | Yes | Yes |
| **Google Voice HAT** | HAT | AC108 | MAX98357A | 24-bit / 48kHz | ~$25 | 3.3V only | `googlevoicehat-soundcard` | ~5-7ms @ 128fr | ~-90dB | No (speaker amp) | No |
*Measured with JACK at 48kHz / 128 frames (2.6ms buffer), best-case configuration. Actual = buffer ticks + codec group delay + DMA transfer overhead. WM8731 has ~0.5ms added group delay vs PCM1864/PCM5122.
---
## Option 1: AudioInjector Stereo HAT ★ Top Recommend
| Spec | Value |
|------|-------|
| **Chipset** | **Wolfson WM8731** (verified from upstream kernel DT overlay `audioinjector-wm8731-audio-overlay.dts` |
| **Sample Rates** | 8k48kHz |
| **Bit Depth** | 16/24-bit |
| **Input** | Stereo line-in (3.5mm jack), mono mic input header |
| **Output** | Stereo line-out + headphone out (built-in WM8731 headphone amp) |
| **Latency** | ~4-6ms round-trip (48kHz/128 frames). WM8731 adds ~0.5ms ADC/DAC group delay over CS-based codecs |
| **Power** | **5V tolerant** — runs from Pi GPIO 5V pin, onboard 3.3V regulator |
| **Current** | ~80mA typical |
| **Overlay** | `dtoverlay=audioinjector-wm8731-audio` — in upstream kernel tree ✅ |
| **ALSA Name** | `hw:CARD=sndrpiaudioinjectorpi,DEV=0` or `hw:1,0` |
| **Price** | $3540 USD |
| **Availability** | audioinjector.net, Pimoroni, Amazon |
### Pros
- Full ADC + DAC on one HAT — no separate wiring or breadboard
- Upstream kernel overlay — no custom kernel module build needed
- 5V tolerant — stable power from Pi GPIO 5V pin
- Onboard headphone amp (WM8731 built-in) — enough for monitoring
- Proven JACK/ALSA compatibility
- Good community support and documentation
- Stackable header option for accessing GPIO underneath
### Cons
- **48kHz max** — WM8731 tops out at 48kHz (no 96/192kHz mode)
- WM8731 charge pump noise — ~-84dB noise floor, audible with quiet sources
- Line-level input (2Vrms) — guitar needs preamp/buffer
- HAT form factor blocks GPIO — needs stacking header or expander
- Headphone amp is modest (~18mW into 32Ω)
- No hardware mixing
### Key Finding
The DT overlay uses WM8731, **not** CS5343+CS4344 as some docs claim. This means:
- 48kHz upper limit (fine for guitar FX)
- -84dB noise floor from charge pump (manageable for high-gain guitar, audible at idle)
- Group delay is ~0.5ms (negligible in a ~5ms round-trip budget)
---
## Option 2: HiFiBerry DAC+ADC Pro ★ Best Specs
| Spec | Value |
|------|-------|
| **Chipset** | PCM1864 ADC + PCM5122 DAC |
| **Sample Rates** | 8k192kHz |
| **Bit Depth** | 24-bit |
| **Input** | Stereo line-in (PCB header, not jack) |
| **Output** | Stereo line-out (RCA or PCB header) |
| **Latency** | ~3-5ms round-trip (48kHz/128 frames) |
| **Power** | **5V tolerant** — onboard LDO |
| **Overlay** | `dtoverlay=hifiberry-dacplusadcpro` — upstream ✅ |
| **Price** | ~$42 USD |
### Pros
- Best noise floor (-95dB) — PCM1864 is an excellent ADC
- 192kHz / 24-bit — future-proof
- Single overlay for both ADC+DAC
- PCM5122 has hardware mixing / digital volume control
- 5V tolerant
- Lowest latency in round-trip
### Cons
- Most expensive ($42)
- No headphone amp — needs external amplifier for monitoring
- Input/output are PCB headers (not jacks) — needs wiring to panel-mount jacks
- Large footprint — blocks full GPIO header
- Excessive for guitar — 192kHz is overkill for 48kHz DSP chain
---
## Option 3: IQaudio Codec Zero ★ Budget HAT
| Spec | Value |
|------|-------|
| **Chipset** | WM8782+ ADC + codec DAC |
| **Sample Rates** | 8k48kHz (BCKL sharing limits practical rate) |
| **Bit Depth** | 24-bit |
| **Input** | Stereo 3.5mm line-in, internal mic |
| **Output** | Stereo 3.5mm line-out |
| **Power** | **3.3V only** — NOT 5V tolerant |
| **Overlay** | `dtoverlay=iqaudio-codec` — upstream ✅ |
| **Price** | ~$18 USD |
### Pros
- Cheapest HAT with full ADC+DAC
- Well-tested overlay — excellent ALSA/JACK support
- Compact, low power (~50mA)
- 24-bit capable
### Cons
- **3.3V only** — needs regulator from 5V rail
- **Discontinued** — Pimoroni no longer manufactures; stock drying up
- No headphone amp — needs external amplification for monitoring
- Line input — guitar needs preamp
- BCKL sharing can cause jitter near 48kHz
---
## Option 4: PCM1808 + PCM5102 Breakout Combo ★ Lowest Cost
### Overlays
| Board | Overlay | Status |
|-------|---------|--------|
| PCM5102 DAC | `dtoverlay=i2s-dac` | Upstream ✅ (renamed from `rpi-dac`) |
| PCM1808 ADC | None | **No upstream overlay exists** — requires manual DT overlay |
**Overlay for DAC only:**
```
dtoverlay=i2s-dac
```
**ADC requires a custom overlay or GPIO bit-banging.** The PCM1808 has no upstream DT overlay in rpi-6.6.y. Options:
- Write a custom `pcm1808-adc-overlay.dts` and compile it
- Use `i2c` to configure if on an I2C board (PCM1808 is SPI-like)
- Accept 16-bit / 48kHz only on ADC side
### Wiring (RPi 4B to dual breakouts)
```
GPIO18 (BCLK) → PCM1808 pin 8 (BCK) → PCM5102 pin 14 (BCK)
GPIO19 (LRCLK) → PCM1808 pin 7 (LRCK) → PCM5102 pin 13 (LRCK)
GPIO20 (DIN) ──────────────────────────→ PCM5102 pin 12 (DIN)
GPIO21 (DOUT) → PCM1808 pin 9 (DOUT)
3.3V → PCM1808 VCC → PCM5102 Vin
GND → PCM1808 GND → PCM5102 GND
```
PCM1808 config: pin 12 (FMT) to GND for I2S mode. Pin 13 (MD1) to 3.3V for 48kHz.
### Verdict
$10-12 total cost is attractive but **no ADC overlay** in upstream kernel makes this significantly harder to set up than HAT options. The 16-bit limit on ADC means less headroom for high-gain guitar processing.
---
## Option 5: JustBoom DAC/ADC HAT
| Spec | Value |
|------|-------|
| **Chipset** | PCM1864 ADC + PCM5122 DAC |
| **Sample Rates** | 8k192kHz |
| **Bit Depth** | 24-bit |
| **Input** | Stereo RCA + 3.5mm line-in |
| **Output** | Stereo RCA + 3.5mm headphone jack |
| **Power** | 5V tolerant |
| **Overlay** | `justboom-dac` — DAC only (ADC uses codec-integrated path) ✅ |
| **Price** | ~$40+ USD |
### Note on ADC overlay
`justboom-adc` does NOT exist in the upstream kernel README (verified against rpi-6.6.y). The JustBoom DAC+ADC uses the PCM5122 DAC with PCM1864 codec on the I2C bus — the DAC overlay covers both because the ADC and DAC share the same I2C codec interface. This is the same architecture as HiFiBerry DAC+ADC Pro.
---
## Option 6: Google Voice HAT (AC108 + MAX98357A)
| Spec | Value |
|------|-------|
| **Chipset** | AC108 ADC (3-mic TDM) + MAX98357A DAC (class-D speaker amp) |
| **Sample Rates** | 16k48kHz |
| **Bit Depth** | 16/24-bit |
| **Input** | 3x PDM MEMS microphones |
| **Output** | Speaker out (class-D) |
| **Power** | 3.3V only |
| **Overlay** | `googlevoicehat-soundcard` — upstream ✅ |
| **Price** | ~$25 |
**Unsuitable for guitar pedal** — TDM mics meant for voice, no line-in, class-D speaker amp (not headphone amp). Included for completeness as an upstream-supported HAT.
---
## RPi 4B I2S Pinout
| Signal | BCM GPIO | Physical Pin | Alt Function | Direction |
|--------|----------|:------------:|:------------:|:---------:|
| **BCLK** (Bit Clock) | GPIO18 | Pin 12 | ALT5 (I2S) | Master output |
| **LRCLK** (Frame Sync) | GPIO19 | Pin 35 | ALT5 (I2S) | Master output |
| **DIN** (Data Input to Pi) | GPIO20 | Pin 38 | ALT5 (I2S) | Input |
| **DOUT** (Data Output from Pi) | GPIO21 | Pin 40 | ALT5 (I2S) | Output |
| **MCLK** (Master Clock) | GPIO28 | Pin 3 | ALT2 (I2S) | Optional — not all codecs need it |
| **GND** | — | Pins 6, 9, 14, 25, 30, 34, 39 | — | — |
| **3.3V** | — | Pins 1, 17 | — | Max 50mA draw |
| **5V** | — | Pins 2, 4 | — | Up to 3A |
### Key Notes
- RPi 4B BCLK limit ~ 32MHz — fine for all audio codecs
- **MCLK is optional** for PCM1808, PCM5102, PCM5122, PCM1864 — they use PLL from BCLK
- WM8731 needs MCLK at 12.288MHz (for 48kHz) or 11.2896MHz (for 44.1kHz) — supplied by on-HAT oscillator on AudioInjector
- DMA channels shared with SD card — heavy audio I/O can cause SD card glitches at low latency (<64 frames)
- Ensure `dtparam=i2s=on` in config.txt if overlay doesn't enable it
---
## Config.txt Overlay Reference
```
# ── AudioInjector Stereo HAT ───────────────────────────
dtoverlay=audioinjector-wm8731-audio
# ── HiFiBerry DAC+ADC Pro ──────────────────────────────
dtoverlay=hifiberry-dacplusadcpro
# ── IQaudio Codec Zero ────────────────────────────────
dtoverlay=iqaudio-codec
# ── PCM1808 + PCM5102 combo ───────────────────────────
dtoverlay=i2s-dac
# (ADC: NO UPSTREAM OVERLAY — manual DT or GPIO bit-bang)
# ── JustBoom DAC/ADC ──────────────────────────────────
dtoverlay=justboom-dac
# ── Google Voice HAT ──────────────────────────────────
dtoverlay=googlevoicehat-soundcard
```
After adding any overlay, disable onboard audio:
```
# Disable Pi's own audio hardware (onboard PWM)
dtparam=audio=off
```
Verify with:
```
cat /proc/asound/cards
aplay -l
arecord -l
```
---
## JACK Latency Analysis
At 48kHz sample rate:
| Frames/Period | Buffer Latency (ms) | Round-Trip Estimate | CPU Load on RPi 4B | Risk Level |
|:------------:|:-------------------:|:-------------------:|:------------------:|:----------:|
| 64 | 1.3ms | ~3-5ms | High | Risky — xruns likely with DSP |
| **128** | **2.6ms** | **~4-7ms** | **Medium** | **Recommended target** ✅ |
| 256 | 5.3ms | ~7-11ms | Low | Acceptable fallback |
| 512 | 10.6ms | ~12-16ms | Very Low | ❌ Fails <10ms criterion |
### Codec Group Delay Breakdown (at 48kHz)
| Codec | ADC Delay | DAC Delay | Total Codec | Note |
|-------|:---------:|:---------:|:-----------:|------|
| WM8731 | ~0.5ms | ~0.5ms | ~1.0ms | Includes digital filter + charge pump |
| PCM1864 | ~0.25ms | ~0.15ms | ~0.4ms | Modern delta-sigma, low latency |
| PCM1808 | ~0.3ms | — | ~0.3ms | ADC only, simple modulation |
| PCM5102 | — | ~0.2ms | ~0.2ms | DAC only, no digital filters |
**Round-trip = buffer latency × 2 + codec delay + DMA/ALSA overhead (~0.5ms)**
At 128 frames: 2.6ms × 2 + 0.41.0ms + 0.5ms = **~6.16.7ms** — well under 10ms target
### JACK Start Command
```bash
# Kill PulseAudio first
pulseaudio --kill
# Start JACK (adjust -d hw:X,Y based on `aplay -l`)
jackd -R -d alsa \
-d hw:audioinjectorpi,0 \
-r 48000 \
-p 128 \
-n 3
```
For lowest latency (risky):
```bash
jackd -R -d alsa -d hw:1,0 -r 48000 -p 64 -n 2
```
---
## Power Compatibility
| Component | VDD | Max Current | Source |
|-----------|:---:|:-----------:|--------|
| RPi 4B 3.3V rail | 3.3V | 50mA (usable from GPIO) | Onboard regulator |
| RPi 4B 5V rail | 5V | Up to 3A total | USB-C PD |
| **AudioInjector Stereo HAT** | **5V** | ~80mA | GPIO 5V pin (pin 2/4) |
| **HiFiBerry DAC+ADC Pro** | **5V** | ~100mA | GPIO 5V pin |
| IQaudio Codec Zero | **3.3V** | ~50mA | GPIO 3.3V pin or regulator |
| PCM1808 | 3.3V | ~4mA | 3.3V rail |
| PCM5102 | 3.3V | ~20mA | 3.3V rail |
| JustBoom DAC/ADC | 5V | ~120mA | GPIO 5V pin |
| Google Voice HAT | 3.3V | ~60mA | GPIO 3.3V pin |
### Power Strategy
For 5V-tolerant HATs (AudioInjector, HiFiBerry, JustBoom): power from Pi GPIO 5V pin. The HAT's onboard regulator handles 3.3V for the codec. This keeps 3.3V draw off the Pi's weak 3.3V rail, leaving it available for footswitch/display/LED GPIO.
For 3.3V-only options: draw from Pi GPIO 3.3V pin or add external 3.3V regulator (AMS1117-3.3) from 5V rail.
---
## GPIO Conflict Note
Audio HATs that use the 40-pin header block ALL GPIO pins physically. For a pedal that needs:
| Function | Typical GPIOs | Min Pins |
|----------|:------------:|:--------:|
| Footswitches (3-6) | BCM 5,6,13,16,17,22,23,24,25,27 | 3-6 |
| RGB LEDs (WS2812B) | BCM 12 or 18 | 1 |
| OLED Display (I2C) | BCM 2 (SDA), 3 (SCL) | 2 |
| MIDI UART | BCM 14 (TXD), 15 (RXD) | 2 |
**Solution: Use a stacking GPIO header** — 2x20 female header socket soldered to HAT, HAT mounts on top of Pi, footswitch/display/LED wiring connects to exposed pins from the top. The stacking header passes through all 40 pins.
Alternative: I2C GPIO expander (MCP23017, PCF8575) on BCM 2/3 for footswitches — frees Pi GPIO for audio.
---
## Guitar Preamp Requirement
**Every I2S ADC option requires a preamp for guitar-level input.** Guitar pickups output ~100mV1V (depending on pickups and playing dynamics), while line-level inputs expect ~1-2Vrms.
### Recommended Preamp Circuit
**Single TL072-based non-inverting stage:**
- Gain switch: 0dB (unity) / 12dB / 24dB
- Input impedance: 1MΩ (guitar-friendly)
- Power: 5V from Pi → 3.3V regulator (AMS1117-3.3) → TL072 ± rail split
- Optional: true bypass relay for tuner mute
**BOM:**
| Part | Qty | Cost |
|------|:---:|:----:|
| TL072CN dual op-amp | 1 | $1.50 |
| AMS1117-3.3 regulator | 1 | $0.50 |
| Resistors (10k, 100k, 1M, 47k) | 6 | $0.30 |
| Capacitors (10µF, 100nF) | 4 | $0.40 |
| **Total** | | **~$2.70** |
---
## Final Recommendation
### 🏆 AudioInjector Stereo HAT — $35-40
**Best overall choice for the Pi Multi-FX Pedal.**
**Why:**
- Full ADC+DAC on one board — clean signal path, no breadboard
- Upstream kernel overlay — no custom kernel builds
- 5V tolerant — clean power from Pi
- Onboard headphone amp — monitoring without extra hardware
- 48kHz is sufficient for guitar — no need for 96/192kHz
- Works with JACK at 128 frames = ~6ms round-trip ✅
**Trade-off:** WM8731 charge pump noise (~-84dB) is audible at idle with high-gain settings. Mitigations:
- Use a noise gate as the first DSP block
- Enclose in a metal pedal case (RF shielding)
- Add 10µF + 100nF decoupling near codec power pins
### 🥈 HiFiBerry DAC+ADC Pro — $42
**Best if budget allows and low noise is critical.**
- Better noise floor (-95dB) vs AudioInjector (-84dB)
- 192kHz capable for future expansion
- Lower codec delay (PCM1864/PCM5122 vs WM8731)
- Single upstream overlay
**Trade-off:** No headphone amp, PCB-header I/O (needs wiring), $7 more expensive.
### 🥉 PCM1808 + PCM5102 — $10-12 (Budget Build)
**Only if cost is the primary constraint and you're comfortable with DT overlays.**
- **No ADC overlay in upstream kernel** — this is the real cost: writing and maintaining a custom DT overlay
- 16-bit / 48kHz limit on ADC — less headroom for high-gain processing
- PCM5102 hiss is well-documented — needs RC filter (10µF cap) on output
- Perfboard assembly required — more noise-prone in a pedal enclosure
---
## BOM Comparison
### AudioInjector Path (Recommended)
| Item | Part | Qty | Est. Cost | Source |
|------|------|:---:|:---------:|--------|
| Audio I/O | AudioInjector Stereo HAT | 1 | $38 | audioinjector.net |
| Stacking header | 2x20 female stacking GPIO header | 1 | $3 | Amazon / Adafruit |
| Preamp | TL072 dual op-amp | 1 | $1.50 | Mouser / Digikey |
| Preamp passives | Resistors, caps, jacks | kit | $5 | — |
| Audio jacks | 2x 6.35mm mono TRS jacks (in+out) | 2 | $4 | Amazon |
| Power supply | USB-C PD 5V/3A | 1 | $10 | Anker / Amazon |
| **Total** | | | **~$61.50** | |
### HiFiBerry Path (Best Noise)
| Item | Part | Qty | Est. Cost | Source |
|------|------|:---:|:---------:|--------|
| Audio I/O | HiFiBerry DAC+ADC Pro | 1 | $42 | hifiberry.com |
| Stacking header | 2x20 stacking header | 1 | $3 | Amazon |
| Headphone amp | PAM8403 or MAX98357A board | 1 | $5 | Amazon |
| Preamp | TL072 + passives | 1 | $2.70 | — |
| Audio jacks | 2x 6.35mm mono jacks | 2 | $4 | — |
| Power supply | USB-C PD 5V/3A | 1 | $10 | — |
| **Total** | | | **~$66.70** | |
### PCM1808+PCM5102 Path (Budget)
| Item | Part | Qty | Est. Cost | Source |
|------|------|:---:|:---------:|--------|
| ADC | PCM1808 breakout board | 1 | $5.50 | Amazon / AliExpress |
| DAC | PCM5102 breakout board | 1 | $5.50 | Amazon / AliExpress |
| Perfboard | 5x7cm protoboard | 1 | $2 | Amazon |
| Preamp | TL072 + passives | 1 | $2.70 | — |
| Audio jacks | 2x 6.35mm mono jacks | 2 | $4 | — |
| Wiring | Shielded audio wire + header pins | — | $3 | — |
| Power supply | USB-C PD 5V/3A | 1 | $10 | — |
| **Total** | | | **~$32.70** | |
---
## Decision Summary
| Criterion | AudioInjector | HiFiBerry Pro | PCM1808+PCM5102 | IQaudio Zero | JustBoom |
|-----------|:------------:|:-------------:|:---------------:|:------------:|:--------:|
| ADC+DAC on one board | ✅ | ✅ | ❌ (2 breakouts) | ✅ | ✅ |
| Upstream overlay | ✅ | ✅ | ❌ (ADC missing) | ✅ | ✅ (partial) |
| <10ms latency | ✅ ~6ms | ✅ ~5ms | ✅ ~7ms | ✅ ~7ms | ✅ ~5ms |
| 5V tolerant | ✅ | ✅ | ❌ | ❌ | ✅ |
| Headphone amp | ✅ | ❌ | ❌ | ❌ | ✅ |
| 24-bit | ✅ | ✅ | ❌ (16-bit ADC) | ✅ | ✅ |
| Available | ✅ | ✅ | ✅ | ⚠️ Discontinued | ⚠️ Limited |
| Price | $35-40 | $42 | $10-12 | $18 | $40+ |
| **Final Rank** | **#1** | **#2** | **#3 (budget)** | #4 | #5 |
**Start with AudioInjector Stereo HAT.** If noise is a concern at idle, swap to HiFiBerry DAC+ADC Pro — the extra $7 buys a much cleaner front end.