Files
raspberry-pi-mixer/scripts/nam-build.sh
T
shawn 9cd8292acc
Lint & Validate / lint (push) Has been cancelled
Phase 1-4: Audio stack, mixer engine, MIDI, and network API
P2-R1: ALSA + JACK2 low-latency config (scripts, quirks, tuning)
P2-R2: Carla integration (build scripts, 8ch rack config, NAM LV2 support)
P2-R3: Plugin manager, categories, blacklist, NAM model support
P3-R1: Mixer DSP engine (channel strip, routing matrix, bus mgr, automation)
P4-R1: MIDI engine (learn mode, clock sync, HID discovery, mapping store)
P4-R2: Network API (OSC server, FastAPI REST, WebSocket, auth, rate limiter)
P5-R1: Touchscreen UI evaluation + main entry point
docs: Audio stack, Carla integration, MIDI support, UI evaluation
tests: Full test suite (292 passing)
2026-05-19 20:39:17 -04:00

180 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
# nam-build.sh — Build Neural Amp Modeler LV2 plugin for RPi4B (ARM Cortex-A72)
# This builds the headless LV2 version that Carla can host.
# Uses RTNeural for real-time neural inference (no libtorch needed).
#
# Usage:
# chmod +x nam-build.sh
# ./nam-build.sh # Build only
# ./nam-build.sh --install # Build + install LV2 to /usr/lib/lv2
# ./nam-build.sh --clean # Clean rebuild
#
# Note: NAM models are CPU-intensive. For RPi4B, use "feather" or "nano"
# sized models from https://www.tone3000.com/. Standard models may xrun.
set -euo pipefail
NAM_REPO="https://github.com/mikeoliphant/neural-amp-modeler-lv2.git"
NAM_DIR="/tmp/nam-lv2-build"
JOBS=$(nproc 2>/dev/null || echo 4)
# Cortex-A72 optimized flags
# Use -march=armv8-a (no crypto needed for NAM) + -O3
# Enable NEON explicitly for vectorized math
A72_FLAGS="-march=armv8-a -mtune=cortex-a72 -O3 -ffast-math -ftree-vectorize"
NEON_FLAGS="-mfpu=neon"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[nam-build]${NC} $*"; }
warn() { echo -e "${YELLOW}[nam-build] WARN:${NC} $*"; }
err() { echo -e "${RED}[nam-build] ERROR:${NC} $*" >&2; exit 1; }
INSTALL=false
CLEAN=false
BUILD_TYPE="Release"
while [[ $# -gt 0 ]]; do
case "$1" in
--install) INSTALL=true; shift ;;
--clean) CLEAN=true; shift ;;
--debug) BUILD_TYPE="Debug"; shift ;;
*) echo "Unknown flag: $1"; exit 1 ;;
esac
done
# ── Check platform ─────────────────────────────────────
ARCH=$(uname -m)
if [[ "$ARCH" != "aarch64" ]] && [[ "$ARCH" != "armv7l" ]]; then
warn "Not running on ARM (detected $ARCH). Cross-compilation not supported."
warn "Run this script directly on the Raspberry Pi 4B."
fi
# ── Install build dependencies ─────────────────────────
log "Installing NAM build dependencies..."
sudo apt update -qq
sudo apt install -y \
build-essential \
cmake \
pkg-config \
g++ \
git \
libeigen3-dev \
lv2-dev \
liblilv-dev \
libserd-dev \
libsord-dev \
libsratom-dev
# Check for Eigen3 (critical)
if ! pkg-config --modversion eigen3 2>/dev/null && ! dpkg -l | grep -q libeigen3-dev; then
err "Eigen3 not found. Install with: sudo apt install libeigen3-dev"
fi
log "Eigen3 found: $(pkg-config --modversion eigen3 2>/dev/null || echo 'version unknown')"
# ── Clone NAM-LV2 ──────────────────────────────────────
if [ "$CLEAN" = true ] || [ ! -d "$NAM_DIR" ]; then
log "Cloning NAM-LV2 repository (with submodules)..."
rm -rf "$NAM_DIR"
git clone --recursive -j4 "$NAM_REPO" "$NAM_DIR"
fi
cd "$NAM_DIR"
# ── Check submodule status ─────────────────────────────
if [ ! -f "NeuralAudio/CMakeLists.txt" ]; then
log "Initializing submodules..."
git submodule update --init --recursive
fi
# ── Create build directory ─────────────────────────────
mkdir -p build
cd build
# ── Configure CMake with ARM Cortex-A72 optimizations ──
log "Configuring CMake (${BUILD_TYPE}, Cortex-A72 optimized)..."
# NeuralAudio performance options for ARM:
# USE_NATIVE_ARCH=ON → auto-detects CPU features
# NEON_OPTIMIZATIONS=ON → enable NEON SIMD in RTNeural
# RTNEURAL_NEON=ON → use NEON backend in RTNeural
#
# For maximum RPi4B performance:
# LTO=ON → link-time optimization
# SMARTCACHING=ON → cache layer activations to avoid recomputation
cmake .. \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DCMAKE_CXX_FLAGS="$A72_FLAGS" \
-DCMAKE_C_FLAGS="$A72_FLAGS" \
-DUSE_NATIVE_ARCH=ON \
-DLTO=ON \
2>&1 | tee /tmp/nam-configure.log
# ── Build ──────────────────────────────────────────────
log "Building NAM LV2 (${JOBS} parallel jobs)..."
make -j"$JOBS" 2>&1 | tee /tmp/nam-build.log
# ── Check build results ────────────────────────────────
if [ -d "neural_amp_modeler.lv2" ]; then
log "✓ NAM LV2 bundle built successfully."
LV2_SIZE=$(du -sh neural_amp_modeler.lv2 | cut -f1)
log " Plugin size: $LV2_SIZE"
if [ -f "neural_amp_modeler.lv2/neural_amp_modeler.so" ]; then
file neural_amp_modeler.lv2/neural_amp_modeler.so
fi
else
err "NAM LV2 bundle not found. Check /tmp/nam-build.log"
fi
# ── Install (optional) ─────────────────────────────────
if [ "$INSTALL" = true ]; then
log "Installing NAM LV2 to system..."
LV2_DIR="/usr/lib/lv2"
# Respect LIB_INSTALL_DIR if set
if [ -n "${LIB_INSTALL_DIR:-}" ]; then
LV2_DIR="$LIB_INSTALL_DIR"
fi
sudo mkdir -p "$LV2_DIR"
sudo cp -r neural_amp_modeler.lv2 "$LV2_DIR/"
log "✓ Installed to $LV2_DIR/neural_amp_modeler.lv2"
# Verify with lv2ls
if command -v lv2ls >/dev/null 2>&1; then
echo ""
log "LV2 plugins containing 'neural':"
lv2ls 2>/dev/null | grep -i neural || warn "NAM not showing in lv2ls yet. Run: lv2ls"
fi
fi
# ── Model download guidance ────────────────────────────
# Check if lv2_validate is available (from lilv-utils)
log ""
log "╔══════════════════════════════════════════════╗"
log "║ NAM LV2 Build Summary ║"
log "╚══════════════════════════════════════════════╝"
log ""
log " Bundle: neural_amp_modeler.lv2"
log " Platform: $ARCH (Cortex-A72 optimized)"
log " Build type: $BUILD_TYPE"
log " Installed: $([ "$INSTALL" = true ] && echo "yes" || echo "no (use --install)")"
log ""
log " Model recommendations for RPi4B:"
log " • Use 'nano' or 'feather' sized models"
log " • Standard models are too CPU-heavy"
log " • Browse: https://www.tone3000.com/search?sizes=feather"
log ""
log " Using NAM in Carla:"
log " 1. Start Carla: carla ./config/carla-default.carxp"
log " 2. Add Plugin → LV2 → Neural Amp Modeler"
log " 3. Set model path via atom:Path parameter"
log " 4. Place an IR loader AFTER NAM for cab sim"
log ""
log " Download example models:"
log " mkdir -p ~/nam-models"
log " # Download feather models from Tone3000 and place here"
log ""