From c48172e48a2c12cc17025ed8907039bd15790f96 Mon Sep 17 00:00:00 2001 From: mynameisdeleted Date: Sat, 29 Aug 2026 09:17:07 -0400 Subject: [PATCH] Enhance installation process: add scripts for dependency installation and preflight checks; update documentation for clarity --- .gitignore | 2 + INSTALL.md | 22 +++++++-- README.md | 12 ++--- apply.sh | 68 ++++++++++++++++++++++++--- install-deps.sh | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+), 18 deletions(-) create mode 100644 .gitignore create mode 100755 install-deps.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2cc41a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Bankstown source checkout + build output from install-deps.sh +/build/ diff --git a/INSTALL.md b/INSTALL.md index 61edc0c..9a0b2c6 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -31,6 +31,7 @@ package for your distro first — see mbp15-1-audio-dsp cd mbp15-1-audio-dsp +chmod +x apply.sh install-deps.sh # if git didn't preserve the bit ``` --- @@ -40,6 +41,11 @@ cd mbp15-1-audio-dsp The graph loads four LV2 plugins from three bundles. (`copy` and `convolver` are PipeWire builtins — nothing to install.) +> **Shortcut:** `./install-deps.sh` does everything in this section — detects +> `dnf`/`pacman`/`apt`/`zypper`, installs LSP + SWH, builds Bankstown from source +> if it's missing, then verifies all five URIs. The manual steps below are what +> it runs, for reference or when it can't. + | Plugin URI in `graph.json` | Bundle | Package (varies by distro) | |---|---|---| | `http://lsp-plug.in/plugins/lv2/para_equalizer_x16_stereo` | LSP Plugins | `lsp-plugins` / `lsp-plugins-lv2` | @@ -141,15 +147,21 @@ If you have your own recalibrated FIRs, drop them at that path (or edit the six ./apply.sh ``` -This does: +`apply.sh` preflights before touching anything: -1. `sudo cp graph.json /usr/share/t2-linux-audio/15_1/graph.json` -2. `systemctl --user restart wireplumber` +1. validates `graph.json` is well-formed JSON (`python3` or `jq`) +2. checks the `/usr/share/t2-linux-audio/15_1/` dir exists (§1) +3. checks every FIR `.wav` **referenced by the graph** is present (§4) +4. checks every LV2 plugin URI **the graph loads** resolves in `lv2ls` (§3) -Optional sanity check first (the tool is `python3-json` / stdlib): +then `sudo cp`s the graph into place, restarts WirePlumber, and confirms the +sink came up. Steps 3–4 read the paths/URIs straight out of `graph.json`, so +they stay correct if you edit it. + +Pass `-f` to skip the preflight (JSON validation still runs): ```sh -python3 -m json.tool graph.json > /dev/null && echo "graph.json OK" +./apply.sh -f ``` --- diff --git a/README.md b/README.md index fce07a9..221b5b1 100644 --- a/README.md +++ b/README.md @@ -258,16 +258,16 @@ Full instructions — prerequisites, the LV2 plugin dependencies (LSP, SWH, and source build of Bankstown), the FIR files, verification and troubleshooting — are in **[INSTALL.md](INSTALL.md)**. -Short version, once the prerequisites are met: +Short version, with the `t2-linux-audio` / `t2-apple-audio-dsp` package already +installed (it provides the FIR `.wav` files, `51-t2-dsp.conf` and `mic.json`): ```sh -./apply.sh +./install-deps.sh # LSP + SWH plugins, builds Bankstown from source +./apply.sh # preflights, then copies the graph in and reloads WirePlumber ``` -copies `graph.json` to `/usr/share/t2-linux-audio/15_1/graph.json` (needs `sudo`) -and restarts WirePlumber. Requires the `t2-linux-audio` / `t2-apple-audio-dsp` -package (FIR `.wav` files, `51-t2-dsp.conf`, `mic.json`) and the LV2 plugins the -graph loads. +`apply.sh` refuses to install if a referenced FIR file or plugin URI is missing +(`-f` skips those checks). ## Revert diff --git a/apply.sh b/apply.sh index d81ca5b..90c5e4d 100755 --- a/apply.sh +++ b/apply.sh @@ -1,19 +1,73 @@ #!/bin/bash -# Apply script for MacBook Pro 15,1 audio DSP graph edits +# Apply the MacBook Pro 15,1 audio DSP graph: +# validate JSON, preflight the prerequisites, install, reload WirePlumber. +# +# ./apply.sh full checks +# ./apply.sh -f skip the preflight checks (still validates JSON) + +set -u SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" GRAPH_SRC="$SCRIPT_DIR/graph.json" GRAPH_DST="/usr/share/t2-linux-audio/15_1/graph.json" -if [ ! -f "$GRAPH_SRC" ]; then - echo "Error: $GRAPH_SRC not found!" - exit 1 +FORCE=0 +case "${1:-}" in -f|--force|--no-check) FORCE=1 ;; esac + +have() { command -v "$1" >/dev/null 2>&1; } +die() { echo "Error: $*" >&2; exit 1; } + +[ -f "$GRAPH_SRC" ] || die "$GRAPH_SRC not found" + +# 1. valid JSON ----------------------------------------------------------- +if have python3; then + python3 -m json.tool "$GRAPH_SRC" >/dev/null || die "graph.json is not valid JSON" + echo "ok: graph.json is valid JSON" +elif have jq; then + jq -e . "$GRAPH_SRC" >/dev/null || die "graph.json is not valid JSON" + echo "ok: graph.json is valid JSON" +else + echo "warn: no python3/jq - skipping JSON validation" fi -echo "Copying graph.json to system path..." +if [ "$FORCE" -eq 0 ]; then + # 2. t2 speaker-DSP package present -------------------------------- + [ -d "$(dirname "$GRAPH_DST")" ] || die \ +"$(dirname "$GRAPH_DST") is missing - install the t2 speaker-DSP package first (INSTALL.md section 1)" + + # 3. FIR files referenced by the graph exist ---------------------- + miss=0 + while IFS= read -r w; do + [ -f "$w" ] || { echo " missing FIR: $w"; miss=1; } + done < <(grep -oE '/[^" ]+\.wav' "$GRAPH_SRC" | sort -u) + [ "$miss" -eq 0 ] && echo "ok: FIR .wav files present" \ + || die "FIR files missing - INSTALL.md section 4" + + # 4. every LV2 plugin URI the graph loads resolves --------------- + if have lv2ls; then + miss=0 + while IFS= read -r u; do + lv2ls | grep -qxF "$u" || { echo " missing plugin: $u"; miss=1; } + done < <(grep '"plugin"' "$GRAPH_SRC" | grep -oE 'https?://[^"]+' | sort -u) + [ "$miss" -eq 0 ] && echo "ok: all LV2 plugins resolve" \ + || die "LV2 plugins missing - run ./install-deps.sh (INSTALL.md section 3)" + else + echo "warn: lv2ls not found - cannot verify plugins (install lilv-utils / lilv)" + fi +fi + +# 5. install ------------------------------------------------------------ +echo "Copying graph.json -> $GRAPH_DST" sudo cp "$GRAPH_SRC" "$GRAPH_DST" -echo "Restarting WirePlumber..." +echo "Restarting WirePlumber" systemctl --user restart wireplumber -echo "Done! The new DSP configuration is loaded." +# 6. confirm ---------------------------------------------------------- +sleep 1 +if have wpctl && wpctl status 2>/dev/null | grep -qi "DSP Speakers"; then + echo "Done - 'MacBook Pro 15,1 DSP Speakers' sink is up." +else + echo "Done - graph copied, WirePlumber restarted." + echo "If no 'DSP Speakers' sink shows: journalctl --user -u wireplumber -b -e" +fi diff --git a/install-deps.sh b/install-deps.sh new file mode 100755 index 0000000..58c834a --- /dev/null +++ b/install-deps.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# Install the LV2 plugins this DSP graph loads: +# LSP Plugins - para_equalizer_x16_stereo, mb_compressor_stereo, loud_comp_mono +# SWH Plugins - fastLookaheadLimiter +# Bankstown - https://chadmed.au/bankstown (built from source) +# +# Does NOT install the t2 speaker-DSP package (FIR .wav files + the WirePlumber +# splice that creates the sink). See INSTALL.md sections 1 and 4 for that. + +set -u + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" +BUILD_DIR="$SCRIPT_DIR/build" + +URIS=( + http://lsp-plug.in/plugins/lv2/para_equalizer_x16_stereo + http://lsp-plug.in/plugins/lv2/mb_compressor_stereo + http://lsp-plug.in/plugins/lv2/loud_comp_mono + http://plugin.org.uk/swh-plugins/fastLookaheadLimiter + https://chadmed.au/bankstown +) + +have() { command -v "$1" >/dev/null 2>&1; } +lv2_have() { have lv2ls && lv2ls 2>/dev/null | grep -qxF "$1"; } + +SUDO="" +if [ "$(id -u)" -ne 0 ]; then + if have sudo; then SUDO="sudo"; else + echo "Error: run as root or install sudo." >&2; exit 1 + fi +fi + +if have dnf; then PM=dnf +elif have pacman; then PM=pacman +elif have apt; then PM=apt +elif have zypper; then PM=zypper +else PM=""; fi + +have lv2ls || echo "note: lv2ls not found - install 'lilv-utils' (deb) / 'lilv' (arch/fedora) to verify URIs" + +# ---------------------------------------------------------------- LSP + SWH +need_lsp=1; need_swh=1 +lv2_have http://lsp-plug.in/plugins/lv2/para_equalizer_x16_stereo && need_lsp=0 +lv2_have http://plugin.org.uk/swh-plugins/fastLookaheadLimiter && need_swh=0 + +pkgs=() +[ "$need_lsp" -eq 1 ] && pkgs+=(lsp-plugins) +[ "$need_swh" -eq 1 ] && pkgs+=(swh-plugins) + +if [ "${#pkgs[@]}" -gt 0 ]; then + if [ -z "$PM" ]; then + echo "!! No supported package manager (dnf/pacman/apt/zypper). Install manually: ${pkgs[*]}" + exit 1 + fi + echo "==> Installing ${pkgs[*]} via $PM" + case "$PM" in + dnf) $SUDO dnf install -y "${pkgs[@]}" ;; + pacman) $SUDO pacman -S --needed --noconfirm "${pkgs[@]}" ;; + apt) $SUDO apt-get update && $SUDO apt-get install -y "${pkgs[@]}" ;; + zypper) $SUDO zypper install -y "${pkgs[@]}" ;; + esac +else + echo "==> LSP + SWH already present" +fi + +# ---------------------------------------------------------------- Bankstown +if lv2_have https://chadmed.au/bankstown; then + echo "==> Bankstown already present" +else + echo "==> Building Bankstown from source" + missing=() + have git || missing+=(git) + have cargo || missing+=(rust/cargo) + { have cc || have clang; } || missing+=(clang) + if [ "${#missing[@]}" -gt 0 ]; then + echo "!! Missing build tools: ${missing[*]}" + echo " Fedora: $SUDO dnf install git rust cargo clang" + echo " Arch: $SUDO pacman -S git rust clang" + echo " Debian: $SUDO apt install git cargo clang" + exit 1 + fi + + LIBDIR=/usr/lib64 + [ -d /usr/lib64/lv2 ] || [ -d /usr/lib64 ] || LIBDIR=/usr/lib + + mkdir -p "$BUILD_DIR" + if [ -d "$BUILD_DIR/bankstown/.git" ]; then + git -C "$BUILD_DIR/bankstown" pull --ff-only + else + git clone https://github.com/chadmed/bankstown "$BUILD_DIR/bankstown" + fi + make -C "$BUILD_DIR/bankstown" # -> cargo build --release + $SUDO make -C "$BUILD_DIR/bankstown" install LIBDIR="$LIBDIR" + echo " installed to $LIBDIR/lv2/bankstown.lv2/" +fi + +# ---------------------------------------------------------------- verify +echo +echo "==> Verifying plugin URIs" +fail=0 +if have lv2ls; then + for u in "${URIS[@]}"; do + if lv2ls | grep -qxF "$u"; then + echo " ok $u" + else + echo " MISSING $u"; fail=1 + fi + done +else + echo " lv2ls unavailable - skipping" + fail=1 +fi + +echo +if [ "$fail" -eq 0 ]; then + echo "All plugins resolve. Next: ./apply.sh" +else + echo "Not all plugins resolve - see INSTALL.md section 3." + exit 1 +fi -- 2.43.0