Resolve effect_input/effect_output audio filter pairs (#14241)

* Resolve effect_input/effect_output audio filter pairs

User filter chains can name their input and output nodes differently, so the existing input-name prefix check cannot find their downstream sink. Match effect_output.<suffix> exactly for effect_input.<suffix>, avoiding similarly named filters while retaining prefix-compatible custom tunings and the existing EasyEffects fallbacks.

Generated by GPT-6 in Codex. Reviewed by Claude Opus 5.5 Medium.

Co-Authored-By: Claude Opus 5.5 Medium <noreply@anthropic.com>

* Prefer an exact filter output over legacy prefix matches

An earlier stream for a similarly named filter can satisfy the legacy prefix check and select the wrong device before the exact paired output is read. Keep the first prefix candidate as a fallback for effect_input sinks and finish searching for the exact effect_output pair. Preserve first-match behavior for all other sink names.

Generated by GPT-6 in Codex. Reviewed by Claude Opus 5.5 Medium.

Co-Authored-By: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: Omarchy Bot <317366263+omarchybot@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 Medium <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-10-04 10:07:28 -04:00
1 parent e73c4d863b
commit 245630786c
2 files changed
+67 -2

No files matched your search

+11 -2
View File
@@ -29,16 +29,25 @@ fi
# stream down to the sink underneath.
downstream="$(pactl list sink-inputs 2>/dev/null |
awk -v virt="$sink" '
BEGIN {
output = virt
sub(/^effect_input\./, "effect_output.", output)
}
/^Sink Input #/ {target = ""}
/^[[:space:]]*Sink:/ {target = $2}
/node\.name = / {
name = $0
sub(/.*node\.name = "/, "", name)
sub(/"$/, "", name)
if (index(name, virt) == 1 && target != "") {print target; exit}
if (target != "" && (name == output || (output == virt && index(name, virt) == 1))) {selected = target; exit}
if (target != "" && fallback == "" && index(name, virt) == 1) fallback = target
}
/application\.name = "EasyEffects"/ {
if (virt == "easyeffects_sink" && target != "") {print target; exit}
if (virt == "easyeffects_sink" && target != "") {selected = target; exit}
}
END {
if (selected != "") print selected
else if (fallback != "") print fallback
}')"
if [[ -n $downstream ]]; then