# Pi Multi-FX Pedal 🎸 A real-time guitar multi-FX pedal running on **Raspberry Pi 4B** with **32 DSP effects**, **NAM A2 neural amp modeling**, **IR cab simulation**, **4-Cable Method** routing, and a **web UI** on `pedal.local`. ## Quick Install (Focusrite 2i2 Test) Get the pedal running on a fresh RPi with a Focusrite 2i2 in under 10 minutes. ### 1. OS Setup Start with **Raspberry Pi OS Lite (64-bit)** or **DietPi**. Configure hostname, enable SSH, and connect to WiFi: ```bash sudo hostnamectl set-hostname pedal # Or on DietPi: use dietpi-config ``` ### 2. System Packages ```bash sudo apt update && sudo apt upgrade -y sudo apt install -y \ git python3 python3-pip python3-venv python3-dev \ jackd2 libjack-jackd2-dev \ libsndfile1-dev \ cmake build-essential \ avahi-daemon # for pedal.local mDNS ``` ### 3. Clone the Repo ```bash git clone https://gitea.ourpad.casa/shawn/pi-multifx-pedal.git ~/projects/pi-multifx-pedal cd ~/projects/pi-multifx-pedal ``` ### 4. Python Environment ```bash python3 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install -r requirements.txt ``` > **Note:** `neural-amp-modeler` needs PyTorch. On RPi 4B aarch64: > ```bash > pip install torch --index-url https://download.pytorch.org/whl/nightly/cpu > ``` ### 5. Focusrite-Specific Config Kill PulseAudio (it grabs USB audio): ```bash pulseaudio --kill ``` Verify Focusrite is detected: ```bash aplay -l # Look for: card 1: USB Audio [Scarlett 2i2 USB], device 0 arecord -l # Look for same ``` Copy the mono test config: ```bash mkdir -p ~/.pedal cp etc/config-focusrite-mono.yaml ~/.pedal/config.yaml ``` ### 6. Run the Pedal ```bash cd ~/projects/pi-multifx-pedal source .venv/bin/activate python3 main.py ``` ### 7. Open the Web UI From any device on the same network: - **Browser:** http://pedal.local - Or use the IP: http://192.168.x.x ### WiFi Hotspot (No Network? No Problem) If there's no WiFi network to join — stage, rehearsal space, park bench — the Pi can create its own: ```bash # Run once to set up sudo bash scripts/setup-wifi-ap.sh # Or with custom SSID/password: sudo bash scripts/setup-wifi-ap.sh --ssid "Pi-Pedal" --psk "yourpassword" # Phone connects to "Pi-Pedal" → open http://pedal.local # To turn it off and go back to client mode: sudo bash scripts/setup-wifi-ap.sh --disable ``` **Pro tip:** Add a USB WiFi dongle for dual-network — Pi creates hotspot on built-in WiFi, dongle handles internet access for git pulls and updates. ### 8. Wire It Up **Mono mode (standard pedal):** ``` Guitar jack → Focusrite Input 1 (front) Focusrite Output 1 (rear) → Amp ``` **4CM mode (four cable method):** ``` Guitar → Focusrite Input 1 Amp FX Send → Focusrite Input 2 Focusrite Output 1 → Amp Input (Send) Focusrite Output 2 → Amp FX Return (Output) ``` Then switch config: ```bash cp etc/config-focusrite-4cm.yaml ~/.pedal/config.yaml ``` Toggle 4CM on/off from the Settings page in the web UI. ## Port & Privileges The web UI runs on **port 80** (standard HTTP), so URLs are clean — just `http://pedal.local` with no port number. Binding to port 80 requires elevated privileges. Either: 1. **Run as root** (simplest): ```bash sudo python3 main.py ``` 2. **Grant the `cap_net_bind_service` capability** (safer — no root shell): ```bash sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which python3)) python3 main.py # no sudo needed ``` 3. **Override the port** via code change (development only): Change `DEFAULT_PORT` in `src/web/server.py` and `port=80` in `main.py`. For development, option 2 is recommended. ## WiFi / Bluetooth Permissions The WiFi hotspot and Bluetooth management features call `sudo` internally for system operations (hostapd, dnsmasq, iwlist, systemctl). If your user does not have passwordless `sudo`, these features will fail silently. Add a sudoers entry to grant passwordless access for the pedal user (`pi` or your username): ```bash sudo visudo -f /etc/sudoers.d/pi-pedal ``` Add one of the following, replacing `pi` with your actual username: **Minimal** (only the WiFi setup script): ``` pi ALL=(ALL) NOPASSWD: /home/pi/projects/pi-multifx-pedal/scripts/setup-wifi-ap.sh * pi ALL=(ALL) NOPASSWD: /usr/sbin/iwlist * pi ALL=(ALL) NOPASSWD: /usr/sbin/iwconfig * pi ALL=(ALL) NOPASSWD: /usr/bin/wpa_cli * pi ALL=(ALL) NOPASSWD: /usr/bin/systemctl * hostapd pi ALL=(ALL) NOPASSWD: /usr/bin/systemctl * dnsmasq pi ALL=(ALL) NOPASSWD: /usr/bin/systemctl * pi-bt-midi ``` **Permissive** (full passwordless sudo — convenient on a dedicated device): ``` pi ALL=(ALL) NOPASSWD: ALL ``` The web UI surfaces permission errors with an `"insufficient_permissions"` key when `sudo` calls fail due to missing sudoers configuration. ## Hardware | Component | Spec | |-----------|------| | **SBC** | Raspberry Pi 4B (2GB+ RAM) | | **Audio I/O** | I2S DAC + ADC (PCM1808 + PCM5102 custom HAT, or USB via Focusrite 2i2) | | **Footswitches** | 3-6 momentary soft-touch (e.g. MXR-style) | | **LEDs** | RGB WS2812B or APA102 per footswitch + status LEDs | | **Display** | 128x64 OLED SSD1306 (I2C) or 5" DSI touch | | **MIDI** | 5-pin DIN in/out via UART + optoisolator | | **Power** | 5V/3A USB-C (with buck for 3.3V rail) | | **Enclosure** | 1590BB or 3D-printed custom | ## 32 Effects | Category | Effects | |----------|---------| | **Dynamics** | Noise Gate, Compressor, Expander, De-esser, Transient Shaper, Sidechain Compressor | | **Drive** | Boost, Overdrive, Distortion, Fuzz, Bitcrusher, Wavefolder, Rectifier | | **Amp + Cab** | NAM Amp Model (any .nam file), IR Cab Sim (any .wav) | | **Modulation** | Chorus, Flanger, Phaser, Tremolo, Vibrato, Ring Mod, Auto-Wah, Envelope Filter, Rotary Speaker, Uni-Vibe, Auto-Pan, Stereo Widener | | **Time** | Delay, Ping-pong Delay, Multi-tap Delay, Reverse Delay, Tape Echo, Reverb, Shimmer Reverb, Early Reflections, Looper | | **Pitch** | Octaver, Detune, Harmonizer, Whammy, Pitch Shifter | | **Filter** | EQ, Parametric EQ, High-Pass, Low-Pass, Band-Pass, Notch, Formant, Wah | | **Utility** | Volume, Tuner | ## Project Structure ``` ├── src/ │ ├── dsp/ Audio processing pipeline │ │ ├── pipeline.py FX chain orchestration (mono + 4CM split) │ │ ├── ir_loader.py IR convolution engine │ │ ├── nam_host.py NAM model loading & inference │ ├── midi/ MIDI subsystem │ │ ├── handler.py MIDI event parse & dispatch │ ├── presets/ Preset system │ │ ├── manager.py Save/load/bank/preset CRUD + 4CM routing │ │ └── types.py Preset & chain data model + FXType enum │ ├── ui/ Hardware UI layer │ │ ├── footswitch.py Debounced GPIO input │ │ ├── leds.py RGB LED controller │ │ └── display.py OLED display manager │ ├── web/ Web UI (FastAPI + WebSocket) │ │ ├── server.py REST + WebSocket endpoints │ │ ├── templates/ Jinja2 HTML pages │ │ └── static/ CSS + JS │ └── system/ System integration │ ├── audio.py ALSA/JACK/I2S configuration │ └── config.py YAML config loader ├── etc/ Config file templates ├── scripts/ Build & utility scripts ├── tests/ Tests ├── docs/ Documentation + test plans └── hardware/ KiCad/PCB schematics ``` ## Development ```bash # Tests source .venv/bin/activate python -m pytest tests/ -v # All 574 tests should pass ``` Early development — initial scaffold.