%global debug_package %{nil} Name: t2bce-audio-dsp Version: 0.0.r409.g059ecce Release: 100.2.1%{?dist} Summary: PipeWire/WirePlumber DSP profiles for Apple T2 Mac audio by Deqrocks License: MIT URL: https://github.com/kaiT2en/KaiT2en-Fedora Source0: https://github.com/kaiT2en/KaiT2en-Fedora/archive/refs/heads/main.tar.gz Source1: t2bce-audio-dsp-configure Source2: 90-t2bce-audio-dsp.rules ExclusiveArch: x86_64 BuildRequires: python3 BuildRequires: systemd-rpm-macros Requires: t2bce-audio-ucm-conf Requires: bash Requires: coreutils Requires: sed Requires: systemd-udev Requires: pipewire >= 1.0 Requires: wireplumber >= 0.5.1 Requires: pipewire-module-filter-chain-lv2 Requires: lv2-bankstown >= 1.1.0 Requires: lv2-triforce >= 0.2.0 Requires: lsp-plugins-lv2 >= 1.2.13 %description Model-specific PipeWire/WirePlumber DSP graphs and FIR filters for supported Apple T2 Macs. All speaker graphs are kept active with node.always-process=true so short one-shot sounds are not lost while the DSP graph wakes up. Microphone graphs retain their upstream idle behavior. A udev hardware rule detects the T2 audio PCI function on the real machine and generates the matching WirePlumber configuration. This is safe for live ISOs, installed systems and non-systemd distributions. %prep %autosetup -n KaiT2en-Fedora-main %build %{python3} - <<'PY' import json from pathlib import Path root = Path("modules/t2bce_audio-dsp/firs") installed_root = Path("/usr/share/t2bce-audio-dsp/profiles") def rewrite_strings(value, old, new): if isinstance(value, str): return value.replace(old, new) if isinstance(value, list): return [rewrite_strings(v, old, new) for v in value] if isinstance(value, dict): return {k: rewrite_strings(v, old, new) for k, v in value.items()} return value for profile_dir in sorted(p for p in root.iterdir() if p.is_dir()): profile = profile_dir.name old_root = f"/usr/share/t2-linux-audio/{profile}" new_root = str(installed_root / profile) graph_path = profile_dir / "graph.json" if graph_path.exists(): data = json.loads(graph_path.read_text()) data = rewrite_strings(data, old_root, new_root) capture = data.setdefault("capture.props", {}) capture["node.always-process"] = "true" playback = data.setdefault("playback.props", {}) playback["target.object"] = "alsa_output.hw_Audio_0" graph_path.write_text(json.dumps(data, indent=4) + "\n") mic_path = profile_dir / "mic.json" if mic_path.exists(): data = json.loads(mic_path.read_text()) data = rewrite_strings(data, old_root, new_root) capture = data.get("capture.props") if isinstance(capture, dict) and "target.object" in capture: capture["target.object"] = "@T2_MIC_SOURCE@" playback = data.setdefault("playback.props", {}) playback["priority.session"] = 1800 mic_path.write_text(json.dumps(data, indent=4) + "\n") PY %install install -d %{buildroot}%{_datadir}/t2bce-audio-dsp/profiles cp -a modules/t2bce_audio-dsp/firs/. \ %{buildroot}%{_datadir}/t2bce-audio-dsp/profiles/ find %{buildroot}%{_datadir}/t2bce-audio-dsp/profiles -type d -exec chmod 0755 {} + find %{buildroot}%{_datadir}/t2bce-audio-dsp/profiles -type f -exec chmod 0644 {} + install -Dm0755 %{SOURCE1} \ %{buildroot}/usr/lib/t2bce-audio-dsp/configure install -Dm0644 %{SOURCE2} \ %{buildroot}%{_udevrulesdir}/90-t2bce-audio-dsp.rules %post /usr/bin/udevadm control --reload-rules >/dev/null 2>&1 || : /usr/lib/t2bce-audio-dsp/configure >/dev/null 2>&1 || : %preun if [ "$1" -eq 0 ]; then /usr/lib/t2bce-audio-dsp/configure --remove >/dev/null 2>&1 || : fi %postun /usr/bin/udevadm control --reload-rules >/dev/null 2>&1 || : %files %{_datadir}/t2bce-audio-dsp/ %dir /usr/lib/t2bce-audio-dsp /usr/lib/t2bce-audio-dsp/configure %{_udevrulesdir}/90-t2bce-audio-dsp.rules %changelog * Thu Aug 13 2026 Sl (Shahaf Levi) - 0.2-1 - Replace boot-time systemd service with an init-neutral udev hardware trigger - Keep all speaker graphs active with node.always-process=true - Preserve upstream microphone idle behavior