-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathaudio-device
executable file
·190 lines (154 loc) · 4.42 KB
/
audio-device
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env bash
set -euo pipefail
assert_command() {
if ! type "${1}" >/dev/null 2>&1; then
echo "${2:-"command not found: ${1}"}"
exit 1
fi
}
assert_val() {
if [[ -z "${1}" ]]; then
echo "${2}"
exit 1
fi
}
assert_func() {
if ! declare -F "${1}" >/dev/null; then
echo "${2}"
exit 1
fi
}
__linux_device_type() {
local device_type="${1}"
case "${1}" in
i*|so*) echo "source";;
o*|si*) echo "sink";;
*)
echo "invalid device type: ${1}"
exit 1
esac
}
__linux_describe_device() {
local -r device_type="$(__linux_device_type "${1}")"
local -r index=$(( ${2} ))
local -r key="${3}"
local delim=":"
if [[ "${key}" = *"."* ]]; then
delim='"'
fi
pacmd list-"${device_type}s" \
| sed -n "/index: ${index}/,/index: /{/index: /!p;}" \
| grep -e "${key}" | cut -d "${delim}" -f2 | head -1 \
| sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' \
|| echo ""
}
__linux_device_name() {
local -r device_type="$(__linux_device_type "${1}")"
local -r index="${2}"
local device_name
for key in "device.product.name" "bluez.alias" "device.description"; do
device_name="$(__linux_describe_device "${device_type}" "${index}" "${key}")"
if test -n "${device_name}"; then
echo "${device_name}"
return
fi
done
}
__linux_current_device_index() {
local -r device_type="$(__linux_device_type "${1}")"
pacmd list-"${device_type}s" | grep "\* index: " | sed -e 's/ *\* *index: *//'
}
__linux_list_devices() {
local -r device_type="$(__linux_device_type "${1}")"
local -a devices
mapfile -t devices < <(pactl list short "${device_type}s")
local index
for device in "${devices[@]}"; do
index="$(echo "${device}" | awk '{print $1}')"
if [[ "$(__linux_describe_device "${device_type}" "${index}" "flags")" = *HARDWARE* ]]; then
echo "${index} $(__linux_device_name "${device_type}" "${index}")"
fi
done
}
_linux_current() {
local -r input_device="$(__linux_device_name input "$(__linux_current_device_index input)")"
local -r output_device="$(__linux_device_name output "$(__linux_current_device_index output)")"
local -n variable="${1:-}_device"
if test -z "${variable:-}"; then
echo " Input: ${input_device}"
echo "Output: ${output_device}"
else
echo "${variable}"
fi
}
_linux_input() {
local -r device_type="$(__linux_device_type input)"
local selected_index
selected_index="$(__linux_list_devices "${device_type}" | fzf | cut -d' ' -f1)"
pactl set-default-source "${selected_index}"
}
_linux_output() {
local -r device_type="$(__linux_device_type output)"
local selected_index
selected_index="$(__linux_list_devices "${device_type}" | fzf | cut -d' ' -f1)"
pactl set-default-sink "${selected_index}"
if [[ "$(__linux_describe_device "${device_type}" "${selected_index}" "device.bus")" = "bluetooth" ]]; then
local -A profile_map=(["Headset Head Unit (w/ Microphone)"]=headset_head_unit ["High Fidelity Playback (w/o Micrphone)"]=a2dp_sink)
local -r profile="${profile_map[$(printf "%s\n" "${!profile_map[@]}" | fzf --header='Bluetooth Sound Profile')]}"
pacmd set-card-profile "$(__linux_describe_device "${device_type}" "${selected_index}" "card" | awk '{ print $1 }')" "${profile}"
fi
}
_darwin_current() {
local -r input_device="$(SwitchAudioSource -t input -c)"
local -r output_device="$(SwitchAudioSource -t output -c)"
local -n variable="${1:-}_device"
if test -z "${variable:-}"; then
echo " Input: ${input_device}"
echo "Output: ${output_device}"
else
echo "${variable}"
fi
}
_darwin_input() {
local -r device="$(SwitchAudioSource -t input -a | fzf --header='Input Device')"
SwitchAudioSource -t input -s "${device}"
}
_darwin_output() {
local -r device="$(SwitchAudioSource -t output -a | fzf --header='Output Device')"
SwitchAudioSource -t output -s "${device}"
}
assert_command fzf
declare OS=""
case "${OSTYPE}" in
darwin*)
assert_command SwitchAudioSource
OS="darwin"
;;
linux*)
assert_command pacmd
assert_command pactl
OS="linux"
;;
*)
echo "Unsupported OS!"
exit 1;;
esac
declare -r cmd="${1:-"help"}"
shift || true
case "${cmd}" in
source)
cmd="input";;
sink)
cmd="output";;
help)
cat << HELP
USAGE:
audio-device current [input|output]
audio-device input
audio-device output
HELP
exit 0
esac
declare -r func="_${OS}_${cmd}"
assert_func "${func}" "invalid command: ${cmd}"
$func $@