113 lines
3.3 KiB
Bash
Executable File
113 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This script toggles state between a few of my audio cables:
|
|
# combine sink -> default_output | hyperx_output
|
|
# clementine sink -> combine sink | default_output
|
|
# The script also outputs a symbol indicating which configuration is active.
|
|
# Usecase: My USB-C headset is a different sink than the one in the laptop; sometimes I want to have audio over the headset, sometimes through the laptop.
|
|
|
|
# Output symbols
|
|
# SYMBOLS=("neither" "co^!cl" "cl^!co" "both")
|
|
SYMBOLS=(" " " " " " " ")
|
|
|
|
# The sinks to test against
|
|
DEFAULT_SINKS=("bluez_output_internal.0A_E6_E0_F9_F1_BE.1" "alsa_output.pci-0000_06_00.6.analog-stereo" "bluez_output.20_18_5B_F0_FC_4A.1" "bluez_output.0A_E6_E0_F9_F1_BE.1" "bluez_output.0A_E6_E0_F9_F1_BE" "bluez_output.0A:E6:E0:F9:F1:BE")
|
|
USB_C_SINK="alsa_output.usb-HP__Inc_HyperX_Cloud_III_Wireless_0000000000000000-00.analog-stereo"
|
|
COMBINE_SINK="combine"
|
|
|
|
# awkcommand - a little complicated, but basically tests if the DEFAULT_SINK is connected to the clementine sink (adding +2 if so) or the combine sink (adding +1). This gives a numerical mapping for all 4 states im interested in:
|
|
# 0: neither combine,clementine are attached to usb_c_sink
|
|
# 1: only combine is attached to usb_c_sink
|
|
# 2: only clementine is attached to usb_c_sink
|
|
# 3: both combine,clementine are attached to usb_c_sink
|
|
read -r -d "" awkcommand << EOF
|
|
/$USB_C_SINK:playback_FL/,/$USB_C_SINK:playback_FR/ {
|
|
if (\$2 == "combine:monitor_FL") {
|
|
state += 1
|
|
}
|
|
}
|
|
|
|
/$COMBINE_SINK:playback_FL/,/$COMBINE_SINK:playback_FR/ {
|
|
if (\$2 == "clementine:monitor_FL") {
|
|
state += 2
|
|
}
|
|
}
|
|
|
|
END {
|
|
printf "%d\n", state
|
|
}
|
|
EOF
|
|
|
|
# Attaches a single sink to a specific source
|
|
function attach() {
|
|
echo "attaching $1 to $2"
|
|
pw-link "$1":monitor_FL "$2":playback_FL
|
|
pw-link "$1":monitor_FR "$2":playback_FR
|
|
}
|
|
|
|
# Attaches an array of sinks to a specific source.
|
|
# $1 = source (pw monitor)
|
|
# $2 = list of sinks to attach
|
|
function attachArray() {
|
|
name=$2[@]
|
|
a=("${!name}")
|
|
for sink in "${a[@]}"; do
|
|
attach "$1" "$sink"
|
|
done
|
|
}
|
|
|
|
# Detaches a single sink from a specific source
|
|
function detach() {
|
|
echo "detaching $1 from $2"
|
|
pw-link -d "$1":monitor_FL "$2":playback_FL
|
|
pw-link -d "$1":monitor_FR "$2":playback_FR
|
|
}
|
|
|
|
# Detaches an array of sinks to a specific source.
|
|
# $1 = source (pw monitor)
|
|
# $2 = list of sinks to attach
|
|
function detachArray() {
|
|
name=$2[@]
|
|
a=("${!name}")
|
|
for sink in "${a[@]}"; do
|
|
detach "$1" "$sink"
|
|
done
|
|
}
|
|
|
|
|
|
state=$(pw-link -li | awk "$awkcommand")
|
|
IFS=$'\n'
|
|
|
|
# actually toggle iff we have a $1 telling us to
|
|
if [[ "$1" == "toggle" ]];then
|
|
case "$2" in
|
|
"clementine")
|
|
if [[ $state -eq 2 || $state -eq 3 ]]; then
|
|
detach "clementine" "$COMBINE_SINK"
|
|
attachArray "clementine" "DEFAULT_SINKS"
|
|
state=$((state-2))
|
|
else
|
|
detachArray "clementine" "DEFAULT_SINKS"
|
|
attach "clementine" "$COMBINE_SINK"
|
|
state=$((state+2))
|
|
fi
|
|
;;
|
|
"combine")
|
|
if [[ $state -eq 1 || $state -eq 3 ]]; then
|
|
detach "combine" "$USB_C_SINK"
|
|
attachArray "combine" "DEFAULT_SINKS"
|
|
state=$((state-1))
|
|
else
|
|
detachArray "combine" "DEFAULT_SINKS"
|
|
attach "combine" "$USB_C_SINK"
|
|
state=$((state+1))
|
|
fi
|
|
;;
|
|
*)
|
|
echo "Unknown option: '$2'"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
echo "${SYMBOLS[$state]}"
|