Phase 1-4: Audio stack, mixer engine, MIDI, and network API
Lint & Validate / lint (push) Has been cancelled
Lint & Validate / lint (push) Has been cancelled
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)
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
#!/bin/bash
|
||||
# lv2lint-check.sh — Validate LV2 plugins for compatibility with Carla/RPi4B
|
||||
# Uses lv2lint to check plugin spec compliance, plus runtime checks.
|
||||
#
|
||||
# Usage:
|
||||
# chmod +x lv2lint-check.sh
|
||||
# ./lv2lint-check.sh # Check all installed LV2 plugins
|
||||
# ./lv2lint-check.sh /path/to/plugin.lv2 # Check a specific plugin
|
||||
# ./lv2lint-check.sh --nam-only # Only check NAM plugin
|
||||
# ./lv2lint-check.sh --list # List all installed LV2 plugins
|
||||
#
|
||||
# lv2lint checks (from https://git.open-music-kontrollers.ch/lv2/lv2lint):
|
||||
# - URI validity, manifest parsing
|
||||
# - Port definitions (in/out, control/audio/CV)
|
||||
# - TTL consistency
|
||||
# - Required features
|
||||
# - Instantiation test
|
||||
# - Parameter ranges
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[lv2lint]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[lv2lint]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[lv2lint] FAIL:${NC} $*"; }
|
||||
|
||||
# ── Install lv2lint if not present ────────────────────
|
||||
install_lv2lint() {
|
||||
if ! command -v lv2lint >/dev/null 2>&1; then
|
||||
log "lv2lint not found. Building from source..."
|
||||
sudo apt update -qq
|
||||
sudo apt install -y build-essential cmake git \
|
||||
liblilv-dev libserd-dev libsord-dev libsratom-dev \
|
||||
lv2-dev libexempi-dev libsndfile1-dev
|
||||
|
||||
LV2LINT_DIR="/tmp/lv2lint-build"
|
||||
git clone --depth 1 https://git.open-music-kontrollers.ch/lv2/lv2lint "$LV2LINT_DIR" 2>/dev/null || \
|
||||
git clone --depth 1 https://github.com/brummer10/lv2lint.git "$LV2LINT_DIR"
|
||||
|
||||
cd "$LV2LINT_DIR"
|
||||
meson setup build 2>/dev/null || \
|
||||
(mkdir -p build && cd build && cmake .. && make -j"$(nproc)")
|
||||
|
||||
if [ -d "build" ]; then
|
||||
cd build
|
||||
if [ -f "meson.build" ] || [ -f "../meson.build" ]; then
|
||||
meson compile 2>/dev/null && sudo meson install 2>/dev/null || true
|
||||
elif [ -f "Makefile" ]; then
|
||||
make -j"$(nproc)" && sudo make install 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v lv2lint >/dev/null 2>&1; then
|
||||
log "lv2lint installed successfully."
|
||||
else
|
||||
warn "Could not install lv2lint. Skipping spec checks."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ── List installed LV2 plugins ────────────────────────
|
||||
list_plugins() {
|
||||
log "Installed LV2 plugins:"
|
||||
echo ""
|
||||
for dir in /usr/lib/lv2 /usr/local/lib/lv2 /usr/lib/aarch64-linux-gnu/lv2 ~/.lv2; do
|
||||
if [ -d "$dir" ]; then
|
||||
find "$dir" -maxdepth 2 -name "*.ttl" | while read -r ttl; do
|
||||
uri=$(grep -oP 'a\s+lv2:Plugin' "$(dirname "$ttl")"/*.ttl 2>/dev/null | head -1 || true)
|
||||
if [ -n "$uri" ]; then
|
||||
echo " $(basename "$(dirname "$ttl")")"
|
||||
fi
|
||||
done | sort -u
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ── Run lv2lint checks on a plugin ─────────────────────
|
||||
check_plugin() {
|
||||
local plugin_uri="$1"
|
||||
local plugin_path="$2"
|
||||
local issues=0
|
||||
|
||||
log "Checking: $(basename "$plugin_path")"
|
||||
echo " URI: $plugin_uri"
|
||||
|
||||
# Manifest check
|
||||
if [ ! -f "$plugin_path/manifest.ttl" ]; then
|
||||
fail " Missing manifest.ttl"
|
||||
issues=$((issues + 1))
|
||||
fi
|
||||
|
||||
# Binary check
|
||||
local so_file=$(find "$plugin_path" -name "*.so" 2>/dev/null | head -1)
|
||||
if [ -z "$so_file" ]; then
|
||||
warn " No .so file found (might be an extension-only bundle)"
|
||||
else
|
||||
echo " Binary: $so_file"
|
||||
file "$so_file" 2>/dev/null | sed 's/^/ /'
|
||||
|
||||
# ARM-specific: check architecture
|
||||
if file "$so_file" 2>/dev/null | grep -q "x86"; then
|
||||
fail " WRONG ARCH: x86 binary on ARM. Rebuild!"
|
||||
issues=$((issues + 1))
|
||||
fi
|
||||
|
||||
# Check shared library deps
|
||||
echo " Shared libs needed:"
|
||||
ldd "$so_file" 2>/dev/null | grep "not found" | while read -r missing; do
|
||||
fail " MISSING: $missing"
|
||||
issues=$((issues + 1))
|
||||
done || true
|
||||
fi
|
||||
|
||||
# Run lv2lint if available
|
||||
if command -v lv2lint >/dev/null 2>&1; then
|
||||
echo " lv2lint output:"
|
||||
local lint_output
|
||||
lint_output=$(lv2lint -M pack -q -s skip "$plugin_uri" 2>&1) || true
|
||||
if [ -n "$lint_output" ]; then
|
||||
echo "$lint_output" | sed 's/^/ /'
|
||||
# Count warnings/errors
|
||||
local lint_issues=$(echo "$lint_output" | grep -ciE "(FAIL|ERROR|WARN)" || true)
|
||||
issues=$((issues + lint_issues))
|
||||
else
|
||||
echo " ✓ No issues found"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for Carla-specific features
|
||||
if grep -qi "carla" "$plugin_path"/*.ttl 2>/dev/null; then
|
||||
echo " ✓ Contains Carla-specific extensions"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
return $issues
|
||||
}
|
||||
|
||||
# ── Check NAM specifically ─────────────────────────────
|
||||
check_nam() {
|
||||
local nam_dir=""
|
||||
for dir in /usr/lib/lv2/neural_amp_modeler.lv2 \
|
||||
/usr/local/lib/lv2/neural_amp_modeler.lv2 \
|
||||
~/.lv2/neural_amp_modeler.lv2 \
|
||||
/tmp/nam-lv2-build/build/neural_amp_modeler.lv2; do
|
||||
if [ -d "$dir" ]; then
|
||||
nam_dir="$dir"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$nam_dir" ]; then
|
||||
warn "NAM LV2 plugin not found. Build it first: ./scripts/nam-build.sh --install"
|
||||
return 1
|
||||
fi
|
||||
|
||||
check_plugin "http://github.com/mikeoliphant/neural-amp-modeler-lv2" "$nam_dir"
|
||||
|
||||
# NAM-specific: check if atom:Path is supported (critical for model loading)
|
||||
if grep -q "atom:Path" "$nam_dir"/*.ttl 2>/dev/null; then
|
||||
log "✓ NAM supports atom:Path (model selection in Carla works)"
|
||||
else
|
||||
warn "NAM does not declare atom:Path support. Model loading may not work in Carla."
|
||||
fi
|
||||
|
||||
# Performance note for RPi4B
|
||||
echo ""
|
||||
warn "NAM on RPi4B — performance note:"
|
||||
echo " Standard models may cause xruns at 128f buffer."
|
||||
echo " Use 'nano' or 'feather' models from https://www.tone3000.com/"
|
||||
echo " Increase JACK buffer to 256 samples if needed."
|
||||
}
|
||||
|
||||
# ── Check all installed plugins ────────────────────────
|
||||
check_all() {
|
||||
local total_issues=0
|
||||
for dir in /usr/lib/lv2 /usr/local/lib/lv2 /usr/lib/aarch64-linux-gnu/lv2 ~/.lv2; do
|
||||
if [ ! -d "$dir" ]; then continue; fi
|
||||
for bundle in "$dir"/*/; do
|
||||
if [ -f "$bundle/manifest.ttl" ]; then
|
||||
# Extract URI from manifest
|
||||
local uri=""
|
||||
uri=$(grep -oP 'a\s+lv2:Plugin' "$bundle"/*.ttl 2>/dev/null | head -1 | sed 's/:.*//' || true)
|
||||
if [ -z "$uri" ]; then
|
||||
# Just use bundle name
|
||||
uri="urn:lv2:$(basename "$bundle")"
|
||||
fi
|
||||
check_plugin "$uri" "${bundle%/}" || total_issues=$((total_issues + $?))
|
||||
fi
|
||||
done
|
||||
done
|
||||
echo ""
|
||||
log "Total issues: $total_issues"
|
||||
}
|
||||
|
||||
# ── Main ───────────────────────────────────────────────
|
||||
case "${1:-}" in
|
||||
--list|-l)
|
||||
list_plugins
|
||||
exit 0
|
||||
;;
|
||||
--nam-only|-n)
|
||||
install_lv2lint
|
||||
check_nam
|
||||
exit 0
|
||||
;;
|
||||
"")
|
||||
install_lv2lint
|
||||
check_all
|
||||
check_nam
|
||||
;;
|
||||
*)
|
||||
if [ -d "$1" ]; then
|
||||
install_lv2lint
|
||||
check_plugin "urn:lv2:$(basename "$1")" "$1"
|
||||
else
|
||||
echo "Usage: $0 [--list|--nam-only|<plugin-path>]"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user