# Arduino Uno Q — USB Audio Synth A 2-oscillator subtractive synthesizer running Pure Data on the Arduino Uno Q. **Auto-detects** its USB role at boot and works in three modes — no config switching needed. ## Modes | Mode | Connection | Audio Out | MIDI In | Use Case | |------|-----------|-----------|---------|----------| | **Gadget** | USB-C → Host computer | UAC1 gadget (virtual sound card) | gmidi gadget (over same cable) | Plug-and-play with DAWs | | **Host** | USB hub → MIDI controller + USB audio interface | USB audio interface (your interface) | MIDI controller via hub | Standalone jamming | | **I2S DAC** | I2S DAC on GPIO pins (e.g. PCM5102) | Analog line out via DAC | USB MIDI controller (gadget) | Embedded installs | ## Auto-Detection At boot, `detect-usb-role.sh` probes the USB controller to determine the role: ``` USB cable plugged into Host? ─→ gadget mode (UAC1 + gmidi) USB device plugged into Uno? ─→ host mode (drives USB audio interface + MIDI) Neither? ─→ defaults to gadget (safe fallback) ``` A udev rule (`99-usb-role.rules`) re-runs detection on hotplug events and restarts Pd with the new config — unplug from computer and plug into a hub, it just works. ## Architecture ``` ┌─────────────────────────────────────────────────────────┐ │ GADGET MODE │ │ [Host DAW] ←USB-C→ ┌──────────┐ │ │ │ gmidi │←─ ALSA seq ──→ Pd │ │ │ UAC1 │── ALSA pcm ──→ Pd │ │ └──────────┘ │ ├─────────────────────────────────────────────────────────┤ │ HOST MODE │ │ [MIDI Ctrl] ─┐ │ │ [USB Audio] ─┼─USB hub─→ ┌──────────┐ │ │ │ │ USB host │ │ │ └──────────→ │ driver │──→ Pd │ │ └──────────┘ │ ├─────────────────────────────────────────────────────────┤ │ I2S DAC MODE │ │ [PCM5102] ←GPIO(I2S)→ ALSA I2S driver ──→ Pd │ └─────────────────────────────────────────────────────────┘ ``` ## Project Structure ``` uno-q-audio-synth/ ├── pd/ │ └── synth.pd # Pure Data synthesizer patch ├── system/ │ ├── configure-usb-audio.sh # UAC1 + gmidi gadget setup │ ├── configure-usb-host.sh # Host-mode USB audio discovery │ ├── detect-usb-role.sh # Boot-time USB role detection │ ├── detect-i2s-device.sh # I2S device auto-detection │ ├── on-usb-role-change.sh # udev hotplug handler │ ├── asound.conf # ALSA config (gadget mode) │ ├── asound-i2s.conf # ALSA config (I2S DAC mode) │ ├── 99-usb-role.rules # udev rules for hotplug │ ├── usb-role-detect.service # Early-boot role detection │ ├── usb-gadget-audio.service # Gadget-only service │ ├── pd-synth-auto.service # Unified auto-detect service │ ├── pd-synth.service # Gadget-only Pd service │ ├── pd-synth-i2s.service # I2S-only Pd service │ └── detect-i2s-device.service # I2S probe service ├── scripts/ │ └── start-synth.sh # Manual dev startup (all modes) ├── install.sh # Board-side dependency install ├── justfile # Task runner └── mise.toml # Tool version management ``` ## Quick Start ### Deploy to board ```bash export BOARD_HOST=uno-q.local # or IP if mDNS not working just deploy # copy all files just enable-auto # enable auto-detect mode just reboot # apply ``` Once booted, plug into a computer — it appears as "Uno Q Audio Synth" with audio sink + MIDI port. Or plug a USB hub with MIDI controller + audio interface for standalone play. ### Development cycle ```bash just cycle # deploy patch + restart Pd just log # tail Pd logs just status # role, ALSA cards, MIDI ports ``` ### Manual testing ```bash just test-audio # test gadget audio out just test-audio-host # test host-mode USB audio interface just run-remote # run Pd in foreground with auto-detect ``` ## I2S DAC Wiring Add a DAC later without reconfiguring. Common I2S DAC modules: | DAC | Pins | Voltage | |-----|------|---------| | PCM5102 | BCK, DIN, LCK, 5V, GND | 3.3V–5V | | MAX98357 (speaker amp) | BCLK, DIN, LRCLK, Vin, GND | 2.7V–5.5V | | PCM5242 (balanced out) | I2S + I2C config | 3.3V | Typical PCM5102 wiring to Uno Q GPIO: ``` PCM5102 → Uno Q GPIO VIN → 5V GND → GND BCK → I2S_BCK (GPIO pin — check board docs) DIN → I2S_DIN LCK → I2S_LCK ``` Activate I2S mode: `just enable-i2s && just reboot` ## Controls (MIDI) | Control | Mapping | |---------|---------| | MIDI Note On/Off | Play notes | | Velocity | Volume | | CC 74 | Filter cutoff | | GUI sliders (Pd) | Detune, volume, ADSR | ## Requirements (on the Uno Q) - Pure Data (`apt install puredata`) - ALSA utilities (`apt install alsa-utils`) - Linux kernel with UAC + gmidi gadget support (Qualcomm DragonWing) ## Pd Patch: synth.pd - **OSC 1**: Saw wave, direct pitch - **OSC 2**: Saw wave, detunable (±50 cents) - **Mix**: Balanced stereo mix - **Filter**: Low-pass (lop~) with adjustable cutoff - **Envelope**: env~ (attack, decay, sustain, release) - **Output**: Stereo 48kHz 16-bit via dac~ Open in Pd GUI to adjust slider positions and save.