Files
uno-q-audio-synth/scripts/start-synth.sh
T
david dbd7c2cece auto-detect MIDI device, drop ALSA sequencer dependency, MPK Mini simulator
midi-bridge.py:
  - Auto-detect rawmidi device (gadget f_midi > env override > fallback)
  - Reconnect on ENODEV (device hotplug)
  - No longer needs MIDI_BRIDGE_DEV env var in common cases

start-synth.sh:
  - Remove all -alsamidi/-midiadddev flags (kernel lacks CONFIG_SND_SEQUENCER)
  - MIDI handled entirely by midi-bridge.service → UDP → netreceive
  - Host mode: same approach, no ALSA sequencer needed

mpk-mini-sim.pd:
  - New MPK Mini Mk II simulator (25 keys, 8 pads, 8 CC knobs)
  - Proper Pd #X obj format for all objects (bng, hsl, t, del, netsend, loadbang)
  - UDP output to board:8081, matching midi-bridge format

system: enable usb-gadget-audio.service at boot, load dwc3 module at boot
2026-06-22 23:10:38 -07:00

135 lines
3.9 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
PD_DIR="/home/arduino/pd"
PATCH="$PD_DIR/synth.pd"
MODE="usb"
VERBOSE=false
die() { echo "[ERROR] $*" >&2; exit 1; }
info() { echo "[INFO] $*"; }
while [ $# -gt 0 ]; do
case "$1" in
-a|--auto) MODE="auto"; shift ;;
-i|--i2s) MODE="i2s"; shift ;;
-l|--loopback) MODE="loopback"; shift ;;
-v|--verbose) VERBOSE=true; shift ;;
-k|--kill) pkill -x pd 2>/dev/null && info "Pd stopped" || info "Pd not running"; exit 0 ;;
*) die "Unknown option: $1" ;;
esac
done
if ! command -v pd &>/dev/null; then
die "Pure Data not found. Install: apt install puredata"
fi
if [ ! -f "$PATCH" ]; then
die "Patch not found: $PATCH"
fi
# --- Auto-detect mode ---
if [ "$MODE" = "auto" ]; then
if [ -f /run/usb-role ]; then
ROLE=$(cat /run/usb-role)
else
ROLE=$(/usr/local/bin/detect-usb-role.sh 2>/dev/null && cat /run/usb-role || echo "gadget")
fi
case "$ROLE" in
gadget)
MODE="usb"
if ! aplay -l 2>/dev/null | grep -q "UAC1Gadget"; then
info "Configuring USB gadget..."
/usr/local/bin/configure-usb-audio.sh start 2>/dev/null || true
sleep 1
fi
;;
host)
if [ -f /run/usb-audio-dev ] && [ -s /run/usb-audio-dev ]; then
ALSA_DEV=$(cat /run/usb-audio-dev)
else
info "Detecting USB audio interface..."
/usr/local/bin/configure-usb-host.sh 2>/dev/null || {
die "No USB audio interface found. Plug one in via hub."
}
ALSA_DEV=$(cat /run/usb-audio-dev)
fi
info "Mode: USB host (MIDI controller + USB audio interface)"
# MIDI handled by midi-bridge.service → UDP → Pd netreceive
AUDIO_OPTS=(-audiooutdev 4 -audioindev 4)
PD_ARGS=(
-nogui -alsa
-send "pd dsp 1"
"${AUDIO_OPTS[@]}"
-audiobuf 20 -blocksize 64 -r 48000
-channels 2 -inchannels 0 -outchannels 2
-path "$PD_DIR" "$PATCH"
)
if [ "$VERBOSE" = true ]; then pd "${PD_ARGS[@]}"
else pd "${PD_ARGS[@]}" > /dev/null 2>&1 &
PID=$!; info "Pd started (PID: $PID)"; info " Stop: kill $PID"
fi
exit 0
;;
*)
info "Auto-detect: unknown role '$ROLE', falling back to gadget"
MODE="usb"
;;
esac
fi
# --- Configure per-mode options ---
AUDIO_OPTS=()
if [ "$MODE" = "usb" ]; then
info "Mode: USB gadget (UAC1 audio + gmidi MIDI)"
AUDIO_OPTS=(-audiooutdev 2 -audioindev 2)
if aplay -l 2>/dev/null | grep -q "UAC1Gadget"; then
info " USB gadget: OK"
# MIDI handled by midi-bridge.service → UDP → Pd netreceive
else
info " USB gadget: NOT DETECTED (kernel modules needed)"
fi
fi
if [ "$MODE" = "i2s" ]; then
if [ -f /run/i2s-audio-dev ] && [ -s /run/i2s-audio-dev ]; then
ALSA_DEV=$(cat /run/i2s-audio-dev)
else
for dev in "hw:I2S,0" "hw:MI2S,0" "hw:0,0"; do
if aplay -l 2>/dev/null | grep -qi "${dev%,*}"; then
ALSA_DEV="$dev"
break
fi
done
fi
info "Mode: I2S DAC (standalone analog audio)"
AUDIO_OPTS=(-audioadddev "$ALSA_DEV")
fi
if [ "$MODE" = "loopback" ]; then
info "Mode: ALSA loopback (testing)"
AUDIO_OPTS=(-audiodev 2)
fi
PD_ARGS=(
-nogui -alsa
-send "pd dsp 1"
"${AUDIO_OPTS[@]}"
-audiobuf 20 -blocksize 64 -r 48000
-channels 1 -inchannels 0 -outchannels 1
-path "$PD_DIR" "$PATCH"
)
if [ "$VERBOSE" = true ]; then
pd "${PD_ARGS[@]}" &
else
pd "${PD_ARGS[@]}" > /dev/null 2>&1 &
fi
PID=$!
info "Pd started (PID: $PID)"
info " Stop: kill $PID"
wait $PID
info "Pd exited (code: $?)"