#!/bin/sh
set -e
[ -n "$DEBUG" ] && set -x
DEFAULT_PROFILE="output:analog-stereo+input:analog-stereo"
HDMI_PROFILE="output:hdmi-stereo"
export MENU_PROMPT="soundswitch"
global=
focused=
profile=
hdmi=
reset=
output=
input=
usage() {
printf "usage: %s [-gfhr]\n" "$(basename "$0")"
printf "\n"
printf " -O \t(manipulate pulseaudio sinks)\n"
printf " -I \t(manipulate pulseaudio sources)\n"
printf " -g \t(set default sink and switch global output)\n"
printf " -f \t(switch focused container output)\n"
printf " -p \t(switch card profile)\n"
printf " -H \t(switch card to HDMI profile)\n"
printf " -R \t(switch card to default profile)\n"
printf "\n"
printf "Needs swq(1) to work.\n"
exit 2
}
while getopts OIfgpHRh name; do
case ${name} in
g) global=1 ;;
f) focused=1 ;;
p) profile=1 ;;
H) hdmi=1 ;;
R) reset=1 ;;
O) output=1 ;;
I) input=1 ;;
h|?) usage ;;
esac
done
if [ "$#" -lt 1 ]; then
printf "global\nfocused\ncard profile\nhdmi profile\nreset profile\n" | menu | {
read -r line
case ${line} in
global) exec "$0" -g ;;
focused) exec "$0" -f ;;
"card profile") exec "$0" -p ;;
"hdmi profile") exec "$0" -H ;;
"reset profile") exec "$0" -R ;;
*) usage ;;
esac
}
exit $?
fi
if [ -n "$global" ] || [ -n "$focused" ]; then
if [ -z "$output" ] && [ -z "$input" ]; then
printf "output\ninput\n" | menu | {
read -r line
case ${line} in
output) exec "$0" -O "$*" ;;
input) exec "$0" -I "$*" ;;
*) usage ;;
esac
}
exit $?
fi
fi
[ -n "$output" ] && keyword="sink" && what="sink-input"
[ -n "$input" ] && keyword="source" && what="source-output"
# returns the sink_id
selects()
{
pactl list short "${keyword}s" | awk '{print $2}' | menu
}
if [ -n "${global}" ]
then
target=$(selects)
notify-send -a soundswitch "soundswitch: global" "switch to ${target}"
# set new default
pactl "set-default-${keyword}" "${target}"
# move all attached to the new target
pactl list "${what}s" short | cut -f1 \
| xargs -i pactl "move-${what}" "{}" "${target}"
elif [ -n "${focused}" ]
then
# parse pid of currently focused container
# then get the sink-inputs for it and parse the sink-input-id
focused_binary=$(swq current con | jq -r '.pid' | xargs ps -o comm=)
what_id=$(printf "%s\n" "${focused_binary}" \
| xargs pacmd "list-${what}s" \
| tr '\n' '\r' \
| perl -pe 's/[^\r]*index: ([0-9]+).+?application\.process\.binary = "([^\r]+)"\r.+?(?=index:|$)/\2=\1\r/g' \
| tr '\r' '\n' \
| grep "^{}" \
| cut -d'=' -f2)
[ -z "${what_id}" ] && exit 1
# select where to switch to
target=$(selects)
[ -z "${what_id}" ] && exit 1
notify-send -a soundswitch "soundswitch: ${focused_binary}" "switch to ${target}"
pacmd move-sink-input "${what_id}" "${target}"
elif [ -n "${profile}" ]
then
target_card=$(pactl list short cards | awk '{print $2}' | menu)
target_profile=$(pacmd list-cards \
| tr '\n' '\r' \
| perl -pe 's/[^\r]index: ([0-9]+).+?name: \r.+profiles:\r(.+)sinks:.*?(?=index:|$)/\2\r/g' \
| tr -d '\t' \
| tr '\r' '\n' \
| tail -n+2 \
| menu \
| perl -pe 's/^\s*([^\s]+):\s.*$/\1/')
notify-send -a soundswitch "soundswitch: profile" "switch ${target_card} to ${target_profile} profile"
pactl set-card-profile "${target_card}" ${target_profile}
elif [ -n "${hdmi}" ]
then
target_card=$(pactl list short cards | awk '{print $2}' | menu)
notify-send -a soundswitch "soundswitch: hdmi" "switch ${target_card} to HDMI profile"
pactl set-card-profile "${target_card}" ${HDMI_PROFILE}
exit $?
elif [ -n "${reset}" ]
then
target_card=$(pactl list short cards | awk '{print $2}' | menu)
notify-send -a soundswitch "soundswitch: reset" "switch ${target_card} to default profile"
pactl set-card-profile "${target_card}" ${DEFAULT_PROFILE}
fi