summary refs log tree commit diff
path: root/bin/soundswitch
blob: 59e0b98707db4357fffe88e3798548c91d8211ce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/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=
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 "  -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 OIfgHRh name; do
	case ${name} in
	g) 	global=1 ;;
	f) 	focused=1 ;;
	H) 	hdmi=1 ;;
	R)	reset=1 ;;
	O)	output=1 ;;
	I)	input=1 ;;
	h|?) 	usage ;;
	esac
done

if [ "$#" -lt 1 ]; then
	printf "global\nfocused\nhdmi_profile\nreset_profile\n" | menu | {
		read -r line
		case ${line} in
		global) 	exec "$0" -g ;;
		focused) 	exec "$0" -f ;;
		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 <i>${target}</i>"
	# 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 <i>${target}</i>"
        pacmd move-sink-input "${what_id}" "${target}"

elif [ -n "${hdmi}" ]
then
	target_card=$(pactl list short cards | awk '{print $2}' | menu)
	notify-send -a soundswitch "soundswitch: hdmi" "switch <i>${target_card}</i> 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 <i>${target_card}</i> to default profile"
	pactl set-card-profile "${target_card}" ${DEFAULT_PROFILE}

fi