MacBook Pro 15,1 — Warm, Natural Audio DSP for t2linux

based on https://github.com/lemmyg/t2-apple-audio-dsp/tree/master

GitHub Repository Fairfax Media Git t2linux Asahi Audio Ecosystem PipeWire Target Hardware

A custom PipeWire filter-chain DSP graph engineered to deliver warm, natural audio to t2linux on the MacBook Pro 15,1 (2018/2019 Intel T2)—aimed at matching or beating macOS (OS X) audio quality both subjectively and objectively.

Note

Architecture: This is not a kernel driver. The Linux T2 kernel/ALSA stack exposes raw speaker PCM. WirePlumber hides the raw device and splices this graph in front of it (alsa_output.platform-sound.RawSpeakers), executing warm voicing EQ, psychoacoustic sub-bass, 8-band dynamic control, driver crossover, FIR correction, and hard driver protection limiters.


⚡ Key Improvements Over Upstream

Upstream graphs (asahi-audio / t2-apple-audio-dsp) target a measurement-flat response that can sound thin, treble-heavy, and distort at high volumes due to missing driver limiters.

Upstream Limitation Solution in This Graph Real-World Result
❄️ Thin / Cold Sound Equal-energy warm voicing curve (+3 dB/octave tilt) Rich, full, balanced audio across all genres
💥 Distortion at High Volume Post-FIR driver limiters (wlim @ -2dB, tlim @ -1dB) Crystal clean output at 100% volume with zero amp clipping
🔊 Woofer Over-Excursion 60 Hz high-pass + 8-band multiband compressor Woofers don't bottom out or rattle on heavy bass beats
🔇 No Deep Sub-Bass Psychoacoustic sub-bass (virtualbass via Bankstown) Extended perceived low-end without physical cone strain
🛡️ Voice-Coil Overheating Dual Woofer & Tweeter Virtual Thermal Guards Continuous white noise automatically attenuated to 500mW / 75mW
🎚️ Fixed / Rigid EQ Isolated 8-band user_eq preference node Custom tone presets that survive git updates

🎛️ Signal Processing Chain

Audio flows through tone controls, dynamic management, ISO-226 equal loudness tracking, FIR driver correction, and physical driver protection limiters:

flowchart TD
    subgraph Stage1 ["1. Input & Voicing"]
        In["🔊 Audio Input"]:::input --> UserEQ["🎚️ User EQ (8-Band Tone Control)"]:::eq
        UserEQ --> EQ["🎼 Voicing EQ (+3dB/oct Warmth & 60Hz HPF)"]:::eq
    end

    subgraph Stage2 ["2. Dynamics & Headroom Management"]
        EQ --> VB["🔊 Virtual Bass (Bankstown Sub-Harmonics)"]:::dynamics
        VB --> MBComp["📊 Multiband Compressor (8-Band LSP)"]:::dynamics
        MBComp --> LoudComp["👂 Loudness Comp (ISO-226 2k FFT)"]:::dynamics
    end

    subgraph Stage3 ["3. Crossover & Driver FIR Correction"]
        LoudComp --> Copy["🔀 4-Channel Crossover Splitter"]:::input
        
        subgraph Tweeters ["Tweeter Channels"]
            Copy --> ConvLT["🔊 Tweeter L FIR (convLT)"]:::fir
            Copy --> ConvRT["🔊 Tweeter R FIR (convRT)"]:::fir
            ConvLT --> TGuard["🛡️ Tweeter Thermal Guard (75mW / 1.0s Tau)"]:::limiter
            ConvRT --> TGuard
            TGuard --> TLim["🛡️ Tweeter Limiter (-1 dB Ceiling)"]:::limiter
        end
        
        subgraph Woofers ["Woofer Channels"]
            Copy --> ConvLW["🔊 Woofer L FIR (convLW)"]:::fir
            Copy --> ConvRW["🔊 Woofer R FIR (convRW)"]:::fir
            ConvLW --> WLim["🛡️ Woofer Limiter (-2 dB Ceiling)"]:::limiter
            ConvRW --> WLim
            WLim --> WGuard["🛡️ Woofer Thermal Guard (500mW / 2.5s Tau)"]:::limiter
        end
    end

    subgraph Stage4 ["4. Driver Output"]
        TLim --> Out["🔈 RawSpeakers Sink"]:::input
        WGuard --> Out
    end

    classDef input fill:#2d3748,stroke:#4a5568,color:#fff;
    classDef eq fill:#2b6cb0,stroke:#3182ce,color:#fff;
    classDef dynamics fill:#d69e2e,stroke:#d69e2e,color:#000;
    classDef fir fill:#805ad5,stroke:#9f7aea,color:#fff;
    classDef limiter fill:#c53030,stroke:#e53e3e,color:#fff;

🛡️ Dual-Driver Virtual Thermal Guards & Power Caps

Because Linux cannot access the T2 hardware current-sensing ADCs, we implement a Virtual Voice-Coil Thermal Model that models continuous electrical power dissipation (P = V_{\text{rms}}^2 / R_{\text{vc}}) and exponential cooling into the air gap:

C_{\text{th}} \frac{d\Delta T(t)}{dt} = \frac{V_{\text{rms}}^2(t)}{R_{\text{vc}}} - \frac{\Delta T(t)}{R_{\text{th}}}

Thermal Guard Configurations

  • Woofer Thermal Guard (thermal_guard @ Post-wlim):
    • Continuous Power Cap: 500\text{ mW} (0.50\text{ W}) per channel (8\% of max 6.25\text{ W} peak power).
    • Linear RMS Threshold (al): 0.282843 (-10.97\text{ dBFS} RMS).
    • Heating Tau (\tau_{\text{heat}}): 2,500\text{ ms} (2.5 seconds).
    • Cooling Tau (\tau_{\text{cool}}): 5,000\text{ ms} (5.0 seconds).
  • Tweeter Thermal Guard (tweeter_thermal_guard @ Pre-tlim):
    • Continuous Power Cap: 75\text{ mW} (0.075\text{ W}) per channel (1.2\% of max 6.25\text{ W} peak power).
    • Linear RMS Threshold (al): 0.109545 (-19.21\text{ dBFS} RMS).
    • Heating Tau (\tau_{\text{heat}}): 1,000\text{ ms} (1.0 second, faster heating for smaller coil mass).
    • Cooling Tau (\tau_{\text{cool}}): 2,500\text{ ms} (2.5 seconds).

Acoustic Result: Dynamic music (Blues, Classical, Rock) has high crest factor (12\text{ dB} - 18\text{ dB}) and operates at 0\text{ dB} gain reduction with full peak dynamics. Continuous high-power signals (full-volume white noise or sine sweeps) are automatically attenuated to harmless power levels after ~2 seconds.


🚀 Quick Start

1. Install Dependencies

Installs required LSP & SWH plugins via your package manager (dnf, pacman, apt, zypper) and builds Bankstown from source:

./install-deps.sh

2. Apply Graph

Preflights FIR paths and plugin URIs, merges user EQ overrides, copies the configuration to WirePlumber, and reloads:

./apply.sh

Tip

Ensure "MacBook Pro 15,1 DSP Speakers" is selected as the default output in your desktop sound settings.


🎚️ Sound Profiles & User EQ

Customize tone settings without touching calibrated internal DSP nodes. user_eq sits at the front of the chain, so even aggressive boosts are safely governed by downstream multiband limiters.

Quick Preset Setup

  1. Create your override file:
    cp user_eq.example.json user_eq.json
    
  2. Edit user_eq.json with your preferred gain multipliers (g_0 to g_7) and apply:
    ./apply.sh
    
Profile 70 Hz (g_0) 110 Hz (g_1) 220 Hz (g_2) 450 Hz (g_3) 1 kHz (g_4) 2.5 kHz (g_5) 6 kHz (g_6) 10 kHz (g_7)
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 Focus) 0.84 0.94 1.00 1.06 1.19 1.19 1.06 1.00
Movie (Action / Bass) 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.19 1.00 0.94

(Note: Gain values are linear multipliers: 1.0 = 0 dB, 1.41 ≈ +3 dB boost, 0.71 ≈ -3 dB cut)


🛠️ Fine-Tuning Guide

If your specific physical unit requires custom acoustic tuning:

  • Woofer Ceiling: Edit wlim.control.limit in graph.json (Default: 0 dBFS into thermal_guard).
  • Thermal Recalibration: Edit al in thermal_guard (al = sqrt(P_watts / 6.25W)).
  • Sub-Bass Synthesis: Adjust virtualbass.control.amt (Default: 1.0).

⚠️ AT-YOUR-OWN-RISK DISCLAIMER & Replacement Resources

Caution

USE AT YOUR OWN RISK: This DSP engine processes micro-speakers with active equal-energy voicing curves and sub-bass synthesis. While dual virtual thermal guards (500\text{ mW} woofers / 75\text{ mW} tweeters), excursion protection, and peak limiters are enabled by default to safeguard hardware, modifying threshold limits, disabling protection nodes, or playing continuous full-volume synthetic square waves is done entirely at your own risk. The authors and maintainers assume no responsibility or liability for damaged speaker cones, blown voice coils, or hardware failures.

🔧 Speaker Replacement & Repair Resources

If you choose to push hardware limits or need to replace aged factory speakers:


🔗 Repositories & Mirrors

📖 Guides & Deep Dives

  • 📖 INSTALL.md — Full prerequisites, manual plugin build steps, package manager lookup, and troubleshooting.
  • 🎓 README.advanced.md — Comprehensive electroacoustic design rationale, magnitude-vs-power physics, gain staging equations, issue tracebacks, and complete parameter reference.
  • 📊 mb-compressor-params.md — Detailed parameter guide for the 8-band LSP multiband compressor.

🔄 Reverting to Stock

To return to the stock PipeWire graph provided by t2-apple-audio-dsp:

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
Description
No description provided
Readme 882 KiB
Languages
Python 77.4%
Shell 22.6%