From 217356363253b91359171ea0c91ea35495d495e5 Mon Sep 17 00:00:00 2001 From: 28allday Date: Fri, 1 May 2026 15:25:08 +0100 Subject: [PATCH] Add wireplumber rule excluding aloop from default-sink selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this, wireplumber's auto-default algorithm promotes aloop to default whenever Resolve plays audio (because aloop becomes RUNNING), and the bridge's "send to default sink" output ends up back in aloop — renders complete, but monitor audio loops onto itself with nothing reaching real hardware. Writes 51-resolve-aloop-no-default.conf with priority.session = 0, priority.driver = 0, and node.dont-fallback / node.disable-fallback to cover wireplumber 0.4 and 0.5+. Restart order changed to wireplumber-first so the rule is in place when the aloop nodes republish. --- Omarchy_resolve_v2.sh | 60 ++++++++++++++++++++++++++++++++++++++----- README.md | 52 +++++++++++++++++++++++++------------ 2 files changed, 89 insertions(+), 23 deletions(-) diff --git a/Omarchy_resolve_v2.sh b/Omarchy_resolve_v2.sh index 2c96600..d9ec276 100755 --- a/Omarchy_resolve_v2.sh +++ b/Omarchy_resolve_v2.sh @@ -502,8 +502,10 @@ else # Bridge snd-aloop capture → default sink so monitor audio is audible. # Without this, Resolve writes to the loopback and the audio goes nowhere # (loopback is a black hole until something captures the other side). - # The bridge is a PipeWire loopback module loaded from user config; it - # tracks the default sink so headphone/HDMI switching keeps working. + # The bridge is a PipeWire loopback module loaded from user config; its + # playback side uses media.class = Stream/Output/Audio so it follows the + # current system default sink — headphone/HDMI/analog switching keeps + # working without editing this file. ALOOP_BRIDGE_DIR="${HOME}/.config/pipewire/pipewire.conf.d" ALOOP_BRIDGE_FILE="${ALOOP_BRIDGE_DIR}/50-resolve-aloop-bridge.conf" mkdir -p "${ALOOP_BRIDGE_DIR}" @@ -532,14 +534,58 @@ context.modules = [ ] EOF log " Wrote ${ALOOP_BRIDGE_FILE} (PipeWire loopback bridge)" - # Reload user PipeWire services so the new conf is picked up - if systemctl --user is-active --quiet pipewire 2>/dev/null; then - systemctl --user restart pipewire pipewire-pulse wireplumber 2>/dev/null || true - log " Reloaded user PipeWire services" - fi else log " ${ALOOP_BRIDGE_FILE} already in place" fi + + # Wireplumber rule: keep aloop OUT of the default-sink rotation. + # Wireplumber's auto-default algorithm promotes whichever sink is RUNNING + # — and aloop is RUNNING precisely while Resolve plays audio. Without + # this rule, aloop becomes default mid-session, the bridge's "send to + # default sink" output lands back in aloop, and monitor audio loops onto + # itself (renders still complete, but you hear nothing during playback). + # Lowering priority + dont-fallback / disable-fallback excludes aloop + # from default selection without disabling the device. + WPRULE_DIR="${HOME}/.config/wireplumber/wireplumber.conf.d" + WPRULE_FILE="${WPRULE_DIR}/51-resolve-aloop-no-default.conf" + mkdir -p "${WPRULE_DIR}" + if [[ ! -f "${WPRULE_FILE}" ]]; then + cat > "${WPRULE_FILE}" <<'EOF' +# DaVinci Resolve aloop — keep snd-aloop out of the default-sink rotation. +# Managed by Omarchy_resolve_v2.sh. Without this, wireplumber promotes +# aloop to default whenever Resolve makes it RUNNING, and the bridge loops +# audio back into aloop instead of reaching real hardware. Setting both +# dont-fallback (older) and disable-fallback (newer) covers wireplumber +# 0.4 and 0.5+. +monitor.alsa.rules = [ + { + matches = [ + { node.name = "alsa_output.platform-snd_aloop.0.analog-stereo" } + { node.name = "alsa_input.platform-snd_aloop.0.analog-stereo" } + ] + actions = { + update-props = { + priority.session = 0 + priority.driver = 0 + node.dont-fallback = true + node.disable-fallback = true + } + } + } +] +EOF + log " Wrote ${WPRULE_FILE} (wireplumber default-sink exclusion)" + else + log " ${WPRULE_FILE} already in place" + fi + + # Reload user PipeWire + wireplumber so the new configs are picked up. + # Restart wireplumber FIRST so its monitor reapplies the alsa rule when + # pipewire republishes the aloop nodes. + if systemctl --user is-active --quiet pipewire 2>/dev/null; then + systemctl --user restart wireplumber pipewire pipewire-pulse 2>/dev/null || true + log " Reloaded user wireplumber + PipeWire services" + fi fi echo diff --git a/README.md b/README.md index 04b578f..b1b7127 100644 --- a/README.md +++ b/README.md @@ -123,11 +123,18 @@ proceeds normally. The script: - Writes `/etc/modules-load.d/snd-aloop.conf` so it autoloads at boot - Writes a PipeWire loopback bridge at `~/.config/pipewire/pipewire.conf.d/50-resolve-aloop-bridge.conf` so - monitor audio routes from the loopback's capture side to the system - default sink (without it, Resolve renders fine but you hear nothing - during playback; headphone/HDMI sink switching keeps working through - the bridge) -- Restarts user PipeWire services so the bridge loads immediately + monitor audio routes from the loopback's capture side to the current + system default sink (without it, Resolve renders fine but you hear + nothing during playback; headphone/HDMI sink switching keeps working + through the bridge) +- Writes a Wireplumber rule at + `~/.config/wireplumber/wireplumber.conf.d/51-resolve-aloop-no-default.conf` + that excludes the aloop card from default-sink selection — without this, + Wireplumber would promote aloop to default whenever Resolve plays audio + (because aloop is RUNNING), and the bridge would loop audio back into + aloop instead of your real hardware +- Restarts user Wireplumber + PipeWire services so the configs load + immediately Set `RESOLVE_NO_ALOOP=1` to skip this entirely (useful if you have a dedicated audio interface Resolve already uses cleanly). @@ -255,23 +262,35 @@ clip codec with `ffprobe` — ProRes RAW will hang silently on Linux without Apple's ProRes RAW SDK plugins, which is a separate issue from this audio fix. -### No audio during playback / monitor sink switches don't work +### No audio during playback / sink keeps flipping to "Loopback" -The PipeWire loopback bridge at -`~/.config/pipewire/pipewire.conf.d/50-resolve-aloop-bridge.conf` routes -the snd-aloop capture side to your default sink. If headphone/HDMI -switching stops working for Resolve playback, restart user PipeWire -services: +If your system default sink keeps switching to "Loopback Analog Stereo" +the moment Resolve starts playing, the wireplumber exclusion rule isn't +in effect. Confirm the rule file exists: ```bash -systemctl --user restart pipewire pipewire-pulse wireplumber +cat ~/.config/wireplumber/wireplumber.conf.d/51-resolve-aloop-no-default.conf ``` -To remove the bridge entirely: +If absent, re-run the installer or pin your real sink manually: + +```bash +pactl set-default-sink # e.g. alsa_output.pci-0000_01_00.1.hdmi-stereo +``` + +If headphone/HDMI switching stops working for Resolve playback, restart +the user audio stack (wireplumber first): + +```bash +systemctl --user restart wireplumber pipewire pipewire-pulse +``` + +To remove the bridge + rule entirely: ```bash rm ~/.config/pipewire/pipewire.conf.d/50-resolve-aloop-bridge.conf -systemctl --user restart pipewire pipewire-pulse wireplumber +rm ~/.config/wireplumber/wireplumber.conf.d/51-resolve-aloop-no-default.conf +systemctl --user restart wireplumber pipewire pipewire-pulse ``` ### Missing library errors @@ -327,10 +346,11 @@ sudo rm -f /usr/lib/udev/rules.d/99-BlackmagicDevices.rules sudo rm -f /usr/lib/udev/rules.d/99-ResolveKeyboardHID.rules sudo rm -f /usr/lib/udev/rules.d/99-DavinciPanel.rules -# Remove the snd-aloop autoload entry + PipeWire bridge (optional) +# Remove the snd-aloop autoload entry + PipeWire bridge + wireplumber rule sudo rm -f /etc/modules-load.d/snd-aloop.conf rm -f ~/.config/pipewire/pipewire.conf.d/50-resolve-aloop-bridge.conf -systemctl --user restart pipewire pipewire-pulse wireplumber +rm -f ~/.config/wireplumber/wireplumber.conf.d/51-resolve-aloop-no-default.conf +systemctl --user restart wireplumber pipewire pipewire-pulse # Remove user data (WARNING: deletes all projects and settings) rm -rf ~/.local/share/DaVinciResolve