diff --git a/15_1/tweeters-44k.wav b/15_1/tweeters-44k.wav new file mode 100644 index 0000000..2a7cf8d Binary files /dev/null and b/15_1/tweeters-44k.wav differ diff --git a/15_1/tweeters-48k.wav b/15_1/tweeters-48k.wav new file mode 100644 index 0000000..0216bdc Binary files /dev/null and b/15_1/tweeters-48k.wav differ diff --git a/15_1/tweeters-96k.wav b/15_1/tweeters-96k.wav new file mode 100644 index 0000000..7bf2774 Binary files /dev/null and b/15_1/tweeters-96k.wav differ diff --git a/15_1/woofers-44k.wav b/15_1/woofers-44k.wav new file mode 100644 index 0000000..9105ebc Binary files /dev/null and b/15_1/woofers-44k.wav differ diff --git a/15_1/woofers-48k.wav b/15_1/woofers-48k.wav new file mode 100644 index 0000000..83886bb Binary files /dev/null and b/15_1/woofers-48k.wav differ diff --git a/15_1/woofers-96k.wav b/15_1/woofers-96k.wav new file mode 100644 index 0000000..7aafffa Binary files /dev/null and b/15_1/woofers-96k.wav differ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..61edc0c --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,215 @@ +# Install + +How to get this DSP graph running on a **MacBook Pro 15,1** under Linux (T2 / +`t2linux`, or Asahi on the Intel-T2 stack where applicable). + +For what the graph *does*, see [README.md](README.md). This file is only the +mechanics of getting the pieces in place. + +--- + +## 1. What has to be true first + +This repo is **just a `graph.json`** (plus `apply.sh`). It is not a driver and +not self-contained. Three things must already exist on the machine: + +| Requirement | Provided by | Why | +|---|---|---| +| Raw speaker PCM exposed by the kernel/ALSA | the `t2linux` kernel + ALSA stack | there is nothing to process otherwise | +| A hidden sink `alsa_output.platform-sound.RawSpeakers` with a filter-chain spliced in front of it | the **t2 speaker-DSP package** (`t2-linux-audio` / `t2-apple-audio-dsp`), specifically its WirePlumber drop-in `51-t2-dsp.conf` | this graph *attaches to* that spliced filter-chain; no package → no sink → nothing to apply | +| The FIR correction files at `/usr/share/t2-linux-audio/15_1/` | the same package | `graph.json` references them by absolute path (see §4) | +| The LV2 plugins the graph loads | your distro + a source build for one of them | see §3 | + +If `wpctl status` shows no **"MacBook Pro 15,1 DSP Speakers"** sink and no +`alsa_output.platform-sound.RawSpeakers`, stop here and install the t2 speaker-DSP +package for your distro first — see . + +--- + +## 2. Get the repo + +```sh +git clone mbp15-1-audio-dsp +cd mbp15-1-audio-dsp +``` + +--- + +## 3. LV2 plugin dependencies + +The graph loads four LV2 plugins from three bundles. (`copy` and `convolver` are +PipeWire builtins — nothing to install.) + +| 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` | +| `http://lsp-plug.in/plugins/lv2/mb_compressor_stereo` | LSP Plugins | ″ | +| `http://lsp-plug.in/plugins/lv2/loud_comp_mono` | LSP Plugins | ″ | +| `http://plugin.org.uk/swh-plugins/fastLookaheadLimiter` | SWH Plugins | `swh-plugins` / `lv2-swh-plugins` | +| `https://chadmed.au/bankstown` | Bankstown | **not packaged on most distros — build from source** | + +### 3a. LSP + SWH (from your package manager) + +```sh +# Fedora / Fedora Asahi Remix +sudo dnf install lsp-plugins swh-plugins + +# Arch / t2linux +sudo pacman -S lsp-plugins swh-plugins # or AUR: lsp-plugins-lv2 + +# Debian / Ubuntu +sudo apt install lsp-plugins swh-plugins +``` + +Package names drift — if the above miss, search: `dnf search lsp`, +`pacman -Ss lsp-plugins`, `apt-cache search swh`. The authority is whether the +URIs resolve (§3c), not the package name. + +### 3b. Bankstown (source build) + +Bankstown (`virtualbass` in the graph) is chadmed's psychoacoustic bass plugin. +On Fedora Asahi Remix it ships in the `asahi-audio` stack; everywhere else, +build it: + +```sh +# needs: rust/cargo, clang, lv2 headers, git +git clone https://github.com/chadmed/bankstown +cd bankstown +make # runs: cargo build --release + +# install the bundle. LIBDIR defaults to /usr/lib64 — override on distros +# that use /usr/lib (Arch, Debian/Ubuntu): +sudo make install # Fedora +sudo make install LIBDIR=/usr/lib # Arch, Debian, Ubuntu +# → installs to $LIBDIR/lv2/bankstown.lv2/ + +cd .. +``` + +Per-user install (no sudo) also works — copy the built +`target/release/libbankstown.so` → `~/.lv2/bankstown.lv2/bankstown.so` alongside +`bankstown.ttl` and `manifest.ttl` from the repo. + +### 3c. Verify all four URIs resolve + +```sh +for uri in \ + 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 ; do + lv2ls | grep -qxF "$uri" && echo "ok $uri" || echo "MISSING $uri" +done +``` + +Every line must say `ok`. `lv2ls` is from `lilv` (`lilv-utils` / `lilv`). + +--- + +## 4. FIR correction files + +`graph.json` references them by **absolute path**: + +``` +/usr/share/t2-linux-audio/15_1/tweeters-44k.wav tweeters-48k.wav tweeters-96k.wav +/usr/share/t2-linux-audio/15_1/woofers-44k.wav woofers-48k.wav woofers-96k.wav +``` + +```sh +ls -l /usr/share/t2-linux-audio/15_1/*.wav +``` + +These are **not vendored in this repo** and the paths are **deliberately not +relative**: + +- The t2 speaker-DSP package installs them to this fixed FHS path on every + distro, and you already need that package for the sink to exist at all (§1), + so the absolute path is stable wherever the prerequisite is met. +- PipeWire's convolver resolves a non-absolute `filename` against the process + working directory, which for a WirePlumber-spawned service is unpredictable + (`/` or `$HOME`). Relative paths would be *less* portable, not more. + +If you have your own recalibrated FIRs, drop them at that path (or edit the six +`filename` entries in `graph.json` to point at yours) before §5. + +--- + +## 5. Apply + +```sh +./apply.sh +``` + +This does: + +1. `sudo cp graph.json /usr/share/t2-linux-audio/15_1/graph.json` +2. `systemctl --user restart wireplumber` + +Optional sanity check first (the tool is `python3-json` / stdlib): + +```sh +python3 -m json.tool graph.json > /dev/null && echo "graph.json OK" +``` + +--- + +## 6. Confirm it loaded + +```sh +wpctl status | grep -i "DSP Speakers" +pw-cli ls Node | grep -i t2-151-speakers +``` + +Select **"MacBook Pro 15,1 DSP Speakers"** as the output (`wpctl set-default +`, or your DE's sound settings), then play something. + +To watch the plugins actually run / spot xruns: + +```sh +pw-top # look for the filter-chain node, check for XRUN +``` + +--- + +## 7. Pick a sound profile + +`user_eq` is the first node in the graph and the only block meant for +hand-editing — an 8-band tone control that defaults flat (= the reference +voicing). Paste one of the preset rows from +[README.md § User preference EQ](README.md#user-preference-eq) into its `control` +block and re-run `./apply.sh`. + +--- + +## 8. After a system update + +A `t2-linux-audio` package update **overwrites** +`/usr/share/t2-linux-audio/15_1/graph.json` and silently reverts to the stock +graph. Re-run `./apply.sh` afterward. (Plugin packages updating is fine — the +graph only cares that the URIs still resolve.) + +--- + +## 9. Revert to stock + +```sh +sudo cp /path/to/t2-apple-audio-dsp/configs/15_1/graph.json \ + /usr/share/t2-linux-audio/15_1/graph.json +systemctl --user restart wireplumber +``` + +Or reinstall the t2 speaker-DSP package. + +--- + +## Troubleshooting + +| Symptom | Likely cause | Fix | +|---|---|---| +| No "DSP Speakers" sink after apply | t2 speaker-DSP package / `51-t2-dsp.conf` not installed | §1 | +| Sink present, but silent / falls back to another device | a plugin URI failed to load, so the whole filter-chain fails | §3c — find the `MISSING` line | +| `wireplumber` won't start after apply | malformed `graph.json` | `python3 -m json.tool graph.json`; `journalctl --user -u wireplumber -b` | +| Works, but no bass enhancement | `bankstown` (`virtualbass`) not loaded | §3b, then §3c | +| Distortion when loud | drive too high for your unit — see [README.md § Tuning knobs](README.md#tuning-knobs) | lower `wlim.limit`, or the `user_eq` bass bands | +| Reverted itself after an update | expected — see §8 | re-run `./apply.sh` | diff --git a/README.md b/README.md index a1fc5dc..fce07a9 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,10 @@ This fork's answers, point by point: ## Signal chain ``` -in ─▶ equalizer ─▶ virtualbass ─▶ multiband_compressor ─▶ limiter ─▶ ell/elr ─▶ copyL/R ─┬▶ convLT/convRT ─▶ tlim ─▶ out - (LSP x16) (bankstown) (LSP mb_comp x8) (fastLookahead) (loud_comp) │ (tweeter FIR) (limit) - └▶ convLW/convRW ─▶ wlim ─▶ out - (woofer FIR) (limit) +in ─▶ user_eq ─▶ equalizer ─▶ virtualbass ─▶ multiband_compressor ─▶ limiter ─▶ ell/elr ─▶ copyL/R ─┬▶ convLT/convRT ─▶ tlim ─▶ out + (LSP x16) (LSP x16) (bankstown) (LSP mb_comp x8) (fastLookahead) (loud_comp) │ (tweeter FIR) (limit) + user prefs voicing └▶ convLW/convRW ─▶ wlim ─▶ out + (woofer FIR) (limit) ``` ## Changes vs. upstream `15_1/graph.json` @@ -184,6 +184,43 @@ distortion. 60–150 Hz window, so the ear perceives low end the driver never has to physically produce — the psychoacoustic counterpart to the 60 Hz high-pass. +## User preference EQ + +`user_eq` is the **first node in the graph** and the only block meant for +hand-editing — a plain 8-band tone control for matching the sound to content +type. It defaults **flat** (every `g_*` = `1.0`), which *is* the reference +voicing; editing it never touches the calibrated `equalizer` / dynamics below. +Because it sits ahead of the compressor and limiters, even an aggressive preset +is dynamically governed — it can't clip or over-excurse, it just gets +compressed if pushed hard. + +| Band | `f` | Type | Region | +|---|---|---|---| +| 0 | 70 Hz | low shelf | sub weight / rumble | +| 1 | 110 Hz | bell | bass punch | +| 2 | 220 Hz | bell | warmth / boom | +| 3 | 450 Hz | bell | body / mud | +| 4 | 1 kHz | bell | mids / nasal | +| 5 | 2.5 kHz | bell | presence / attack | +| 6 | 6 kHz | bell | detail / sibilance | +| 7 | 10 kHz | high shelf | air | + +Edit the `g_*` values in the `user_eq` `control` block. **Linear, not dB** +(`+3 dB ≈ 1.41`, `−3 dB ≈ 0.71`). Keep each between `0.5` (−6 dB) and `2.0` +(+6 dB). Run `./apply.sh` after. + +### Presets — the 8 `g_*` values, `g_0`…`g_7` + +| Preset | 70 | 110 | 220 | 450 | 1k | 2.5k | 6k | 10k | +|---|---|---|---|---|---|---|---|---| +| **Reference** (flat) | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | +| Rock / Pop | 1.00 | 1.26 | 1.00 | 0.94 | 1.00 | 1.12 | 1.19 | 1.12 | +| Classical / Acoustic | 1.00 | 1.00 | 1.06 | 1.00 | 1.00 | 1.00 | 1.12 | 1.12 | +| Electronic / Hip-Hop | 1.26 | 1.19 | 1.00 | 0.94 | 1.00 | 1.00 | 1.06 | 1.00 | +| Movie — dialogue | 0.84 | 0.94 | 1.00 | 1.06 | 1.19 | 1.19 | 1.06 | 1.00 | +| Movie — action | 1.41 | 1.12 | 1.00 | 1.00 | 1.00 | 1.06 | 1.12 | 1.12 | +| Late-night (low level) | 0.63 | 0.79 | 1.00 | 1.00 | 1.06 | 1.12 | 1.00 | 0.94 | + ## Tuning knobs If the woofers still bottom out or anything distorts, in order of preference: @@ -217,16 +254,20 @@ holds the tweeter/woofer time alignment. ## Install +Full instructions — prerequisites, the LV2 plugin dependencies (LSP, SWH, and a +source build of Bankstown), the FIR files, verification and troubleshooting — +are in **[INSTALL.md](INSTALL.md)**. + +Short version, once the prerequisites are met: + ```sh ./apply.sh ``` -This copies `graph.json` to `/usr/share/t2-linux-audio/15_1/graph.json` (needs -`sudo`) and restarts WirePlumber (`systemctl --user restart wireplumber`). - -Requires the `t2-linux-audio` / `t2-apple-audio-dsp` package to already be -installed (it provides the FIR `.wav` files, `51-t2-dsp.conf`, and the -`mic.json` graph). +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. ## Revert @@ -237,4 +278,5 @@ systemctl --user restart wireplumber ``` Note: a `t2-linux-audio` package update will overwrite the installed file and -silently revert these changes — re-run `./apply.sh` afterward. +silently revert these changes — re-run `./apply.sh` afterward. See +[INSTALL.md § 8](INSTALL.md#8-after-a-system-update). diff --git a/graph.json b/graph.json index f22112b..ab6aba6 100644 --- a/graph.json +++ b/graph.json @@ -3,6 +3,22 @@ "media.name": "MacBook Pro 15,1 DSP Speakers", "filter.graph": { "nodes": [ + { + "type": "lv2", + "plugin": "http://lsp-plug.in/plugins/lv2/para_equalizer_x16_stereo", + "name": "user_eq", + "control": { + "enabled": 1, "mode": 0, "g_in": 1.0, "g_out": 1.0, + "ft_0": 5, "f_0": 70.0, "g_0": 1.0, "q_0": 0.7, "s_0": 0, + "ft_1": 1, "f_1": 110.0, "g_1": 1.0, "q_1": 1.0, + "ft_2": 1, "f_2": 220.0, "g_2": 1.0, "q_2": 1.0, + "ft_3": 1, "f_3": 450.0, "g_3": 1.0, "q_3": 1.0, + "ft_4": 1, "f_4": 1000.0, "g_4": 1.0, "q_4": 1.0, + "ft_5": 1, "f_5": 2500.0, "g_5": 1.0, "q_5": 1.0, + "ft_6": 1, "f_6": 6000.0, "g_6": 1.0, "q_6": 1.0, + "ft_7": 3, "f_7": 10000.0, "g_7": 1.0, "q_7": 0.7, "s_7": 0 + } + }, { "type": "lv2", "plugin": "http://lsp-plug.in/plugins/lv2/para_equalizer_x16_stereo", @@ -190,6 +206,8 @@ } ], "links": [ + {"output": "user_eq:out_l", "input": "equalizer:in_l"}, + {"output": "user_eq:out_r", "input": "equalizer:in_r"}, {"output": "equalizer:out_l", "input": "virtualbass:in_l"}, {"output": "equalizer:out_r", "input": "virtualbass:in_r"}, {"output": "virtualbass:out_l", "input": "multiband_compressor:in_l"}, @@ -210,8 +228,8 @@ {"output": "convRT:Out", "input": "tlim:in_2"} ], "inputs": [ - "equalizer:in_l", - "equalizer:in_r" + "user_eq:in_l", + "user_eq:in_r" ], "outputs": [ "wlim:out_1",