Resolve the audio output sink through EasyEffects 8
omarchy-audio-output-sink follows a DSP sink to the physical sink through the DSP's playback stream. EasyEffects 8 has no such stream: its output node links its ports straight to the sink's playback ports, so the search found nothing and the volume keys, the bar's audio panel and the output switcher all acted on easyeffects_sink itself. That sink's volume is inert -- its monitor, which EasyEffects reads, does not follow it -- so the OSD moved while the speakers did not. Follow the port links to the alsa_output sink instead, and when EasyEffects is idle and has dropped them, use the output device its settings name, if that sink exists. Filter-chain tunings keep resolving through their stream as before. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
c5b4db77d6
commit
91fd24c2b1
2 files changed
+120
No files matched your search
@@ -50,6 +50,38 @@ if [[ -n $downstream ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# EasyEffects 8 does not play into the physical sink through a stream of its
|
||||
# own: its output node links its ports straight to the sink's playback ports,
|
||||
# so the sink-input search above finds nothing and the keys would move the
|
||||
# EasyEffects sink -- whose volume its monitor, the input of the processing,
|
||||
# does not follow. Follow the port links instead: the first alsa_output sink
|
||||
# any EasyEffects output port is linked to.
|
||||
if [[ $sink == "easyeffects_sink" ]]; then
|
||||
linked="$(pw-link -l 2>/dev/null |
|
||||
awk '
|
||||
/^[^ ]/ {src = $0}
|
||||
/^[[:space:]]*\|->/ {
|
||||
if (src ~ /^ee_/ && $2 ~ /^alsa_output\..*:playback_/) {
|
||||
sub(/:playback_.*$/, "", $2); print $2; exit
|
||||
}
|
||||
}')"
|
||||
|
||||
# Idle, EasyEffects drops those links: fall back to the output device it is
|
||||
# configured to feed, when that sink exists.
|
||||
if [[ -z $linked ]]; then
|
||||
configured="$(sed -n 's/^outputDevice=//p' \
|
||||
"${XDG_CONFIG_HOME:-$HOME/.config}/easyeffects/db/easyeffectsrc" 2>/dev/null)"
|
||||
if [[ -n $configured ]] && pactl list sinks short 2>/dev/null | awk '{print $2}' | grep -qx "$configured"; then
|
||||
linked="$configured"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $linked ]]; then
|
||||
printf '%s\n' "$linked"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Nothing resolvable downstream -- the DSP sink may simply be idle and unlinked.
|
||||
# Fall back to the sink itself so callers still have something to act on.
|
||||
printf '%s\n' "$sink"
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "$(dirname "$0")/base-test.sh"
|
||||
|
||||
test_home=$(mktemp -d)
|
||||
test_bin=$(mktemp -d)
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$test_home" "$test_bin"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Stub PipeWire's clients: the default sink, the sink list, the sink inputs and
|
||||
# the port links are all data files the test writes per scenario.
|
||||
cat >"$test_bin/pactl" <<'STUB'
|
||||
#!/bin/bash
|
||||
case "$1 $2" in
|
||||
"get-default-sink ") cat "$TEST_DATA/default-sink" ;;
|
||||
"list sinks") cat "$TEST_DATA/sinks" ;;
|
||||
"list sink-inputs") cat "$TEST_DATA/sink-inputs" 2>/dev/null ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
STUB
|
||||
cat >"$test_bin/pw-link" <<'STUB'
|
||||
#!/bin/bash
|
||||
cat "$TEST_DATA/links" 2>/dev/null
|
||||
STUB
|
||||
chmod +x "$test_bin/pactl" "$test_bin/pw-link"
|
||||
|
||||
physical=alsa_output.pci-0000_00_1f.3.analog-surround-40
|
||||
|
||||
resolve() {
|
||||
HOME="$test_home" XDG_CONFIG_HOME="$test_home/.config" TEST_DATA="$test_home/data" \
|
||||
PATH="$test_bin:$PATH" bash "$ROOT/bin/omarchy-audio-output-sink" "$@"
|
||||
}
|
||||
|
||||
reset_scenario() {
|
||||
rm -rf "$test_home/data" "$test_home/.config"
|
||||
mkdir -p "$test_home/data"
|
||||
printf '%s\n' easyeffects_sink >"$test_home/data/default-sink"
|
||||
printf '267\t%s\tPipeWire\ts32le 4ch 44100Hz\tRUNNING\n870\teasyeffects_sink\tPipeWire\tfloat32le 2ch 48000Hz\tRUNNING\n' \
|
||||
"$physical" >"$test_home/data/sinks"
|
||||
}
|
||||
|
||||
# A physical default is returned as is.
|
||||
reset_scenario
|
||||
printf '%s\n' "$physical" >"$test_home/data/default-sink"
|
||||
[[ $(resolve) == "$physical" ]] || fail "a physical default sink resolves to itself"
|
||||
pass "physical default sink resolves to itself"
|
||||
|
||||
# EasyEffects 8 playing: its output ports are linked straight to the card.
|
||||
reset_scenario
|
||||
cat >"$test_home/data/links" <<LINKS
|
||||
ee_soe_output_level:output_FL
|
||||
|-> $physical:playback_FL
|
||||
ee_soe_output_level:output_FR
|
||||
|-> $physical:playback_FR
|
||||
ee_soe_output_level:input_FL
|
||||
|<- ee_soe_limiter:output_FL
|
||||
LINKS
|
||||
[[ $(resolve) == "$physical" ]] || fail "easyeffects_sink resolves through the port links to the card"
|
||||
pass "easyeffects_sink resolves through its port links"
|
||||
|
||||
# EasyEffects 8 idle: no links, but its settings name the output device.
|
||||
reset_scenario
|
||||
mkdir -p "$test_home/.config/easyeffects/db"
|
||||
printf '[StreamOutputs]\noutputDevice=%s\n' "$physical" >"$test_home/.config/easyeffects/db/easyeffectsrc"
|
||||
[[ $(resolve) == "$physical" ]] || fail "idle easyeffects_sink resolves through the configured output device"
|
||||
pass "idle easyeffects_sink resolves through the configured output device"
|
||||
|
||||
# A configured device that is gone (headphones unplugged) is not returned.
|
||||
reset_scenario
|
||||
mkdir -p "$test_home/.config/easyeffects/db"
|
||||
printf '[StreamOutputs]\noutputDevice=alsa_output.usb-gone.analog-stereo\n' >"$test_home/.config/easyeffects/db/easyeffectsrc"
|
||||
[[ $(resolve) == "easyeffects_sink" ]] || fail "a configured device that no longer exists falls back to the DSP sink"
|
||||
pass "missing configured device falls back to the DSP sink"
|
||||
|
||||
# The stream-based resolution (filter-chain tunings) still comes first.
|
||||
reset_scenario
|
||||
printf '%s\n' omarchy_speaker_tuning >"$test_home/data/default-sink"
|
||||
cat >"$test_home/data/sink-inputs" <<INPUTS
|
||||
Sink Input #42
|
||||
Sink: 267
|
||||
Properties:
|
||||
node.name = "omarchy_speaker_tuning.stream"
|
||||
INPUTS
|
||||
[[ $(resolve) == "$physical" ]] || fail "a filter-chain tuning still resolves through its stream"
|
||||
pass "filter-chain tuning resolves through its stream"
|
||||
Reference in new issue
Block a user