blob: 1498dcc2f927470b75bda8e3d953f0eb33f0dc13 (
plain)
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
191
192
193
194
195
196
197
198
|
#!/usr/bin/env bash
set -eu
state_muted="${XDG_RUNTIME_DIR}/state_muted"
state_muted_headphone=""
state_muted_speaker=""
state_bt_headphone=""
name_bt_headphone="bluez_sink.00_1B_66_02_36_41"
cardselector=""
card_icon="/usr/share/icons/gnome/48x48/devices/audio-speakers.png" # gnome-icon-theme
mute_state_on="[on]"
mute_state_off="[off]"
get_mute_state() {
local name="$1"
amixer -M -c "${cardselector}" sget "${name}" |grep -o '\[o[n|f]*\]' |head -n1
}
get_volume_percentage() {
local name="$1"
amixer -M -c "${cardselector}" sget "${name}" |grep -o '\[[0-9]*%*\]' |head -n1 |sed -e 's/\[//;s/\]//'
}
get_volume_db() {
local name="$1"
amixer -M -c "${cardselector}" sget "${name}" |grep -Eo '\[[-]?[0-9]+\.[0-9]+dB\]' |head -n1 |sed -e 's/\[//;s/\]//'
}
is_channel_available() {
local name="$1"
amixer -M -c "${cardselector}" sget "${name}" > /dev/null 2>&1
}
increase_volume() {
amixer -M -c "${cardselector}" sset Master 5%+ &>/dev/null
local state_master=""
state_master=$(get_volume_percentage 'Master')
#update pactl bluetooth audio to same level if present
if [ "$state_bt_headphone" = "[on]" ]; then
pactl set-sink-volume $name_bt_headphone "$state_master%"
fi
print_volumes
}
decrease_volume() {
amixer -M -c "${cardselector}" sset Master 5%- > /dev/null
local state_master=""
state_master=$(get_volume_percentage 'Master')
#update pactl bluetooth audio to same level if present
if [ "$state_bt_headphone" = "[on]" ];then
pactl set-sink-volume $name_bt_headphone "$state_master%"
fi
print_volumes
}
print_volumes() {
local message=()
if is_channel_available 'Master'; then
message+=("🎚 $(get_volume_percentage 'Master') ($(get_volume_db 'Master'))")
fi
if is_channel_available 'Headphone'; then
message+=("🎧 $(get_volume_percentage 'Headphone') ($(get_volume_db 'Headphone'))")
fi
if is_channel_available 'Speaker'; then
message+=("🔈 $(get_volume_percentage 'Speaker') ($(get_volume_db 'Speaker'))")
fi
send_notify "${message[*]}"
}
mute_state_to_icon() {
local state="$1"
local icon=""
if [[ "$state" == "$mute_state_on" ]]; then
icon="🔊"
fi
if [[ "$state" == "$mute_state_off" ]]; then
icon="🔇"
fi
echo "$icon"
}
print_mute_states() {
local message=()
if is_channel_available 'Master'; then
message+=("🎚 [$(mute_state_to_icon "$(get_mute_state 'Master')")] $(get_volume_percentage 'Master') ($(get_volume_db 'Master'))")
fi
if is_channel_available 'Headphone'; then
message+=("🎧 [$(mute_state_to_icon "$(get_mute_state 'Headphone')")] $(get_volume_percentage 'Headphone') ($(get_volume_db 'Headphone'))")
fi
if is_channel_available 'Speaker'; then
message+=("🔈 [$(mute_state_to_icon "$(get_mute_state 'Speaker')")] $(get_volume_percentage 'Speaker') ($(get_volume_db 'Speaker'))")
fi
send_notify "${message[*]}"
}
toggle_volume() {
local state_master=""
local state_headphone=""
local state_speaker=""
if is_channel_available 'Master'; then
state_master=$(get_mute_state 'Master')
fi
if is_channel_available 'Headphone'; then
state_headphone=$(get_mute_state 'Headphone')
fi
if is_channel_available 'Speaker'; then
state_speaker=$(get_mute_state 'Speaker')
fi
case "$state_master" in
"${mute_state_on}")
amixer -M -c "${cardselector}" sset Master mute &>/dev/null
state_master="[off]"
# if headphones are off already, don't mute, instead save state to tmp file
if [ "$state_headphone" = "[off]" ];then
echo "headphone [off]" >> "$state_muted"
else
amixer -M -c "${cardselector}" sset Headphone mute &>/dev/null
state_headphone="[off]"
fi
# if speakers are off already, don't mute, instead save state to tmp file
if [ "$state_speaker" = "[off]" ];then
echo "speaker [off]" >> "$state_muted"
else
amixer -M -c "${cardselector}" sset Speaker mute &>/dev/null
state_speaker="[off]"
fi
# if present, also mute bluetooth headphone
if [ "$state_bt_headphone" = "[on]" ]; then
pactl set-sink-mute $name_bt_headphone 1
fi
;;
"${mute_state_off}")
amixer -M -c "${cardselector}" sset Master unmute &>/dev/null
state_master="[on]"
# if headphones are meant to be off, don't unmute them again
if [ "$state_muted_headphone" != "[off]" ];then
amixer -M -c "${cardselector}" sset Headphone unmute &>/dev/null
state_headphone="[on]"
fi
# if headphones are meant to be off, don't unmute them again
if [ "$state_muted_speaker" != "[off]" ];then
amixer -M -c "${cardselector}" sset Speaker unmute &>/dev/null
state_speaker="[on]"
fi
# if present, also unmute bluetooth headphone
if [ "$state_bt_headphone" = "[on]" ]; then
pactl set-sink-mute $name_bt_headphone 0
fi
;;
esac
print_mute_states
}
send_notify() {
local timeout=1000
notify-send -t $timeout -i "${card_icon}" "Volume" "$1"
}
if [[ "$HOSTNAME" == "dvzrv" ]]; then
cardselector="1"
if [ -n "$(pactl list sinks short | grep $name_bt_headphone)" ]; then
state_bt_headphone="[on]"
fi
#TODO: also check pactl for JACK sink
fi
if [[ "$HOSTNAME" == "hmbx" ]]; then
cardselector="1"
fi
if pgrep jack > /dev/null; then
echo "JACK is running"
fi
case "$1" in
"increase" | "up" | "+" )
increase_volume
;;
"decrease" | "down" | "-" )
decrease_volume
;;
"toggle")
if [ -f "$state_muted" ]; then
set +e
state_muted_speaker="$(cat "$state_muted" | grep speaker | cut -d' ' -f2)"
state_muted_headphone="$(cat "$state_muted" | grep headphone | cut -d' ' -f2)"
set -e
rm "$state_muted"
else
touch "$state_muted"
fi
toggle_volume
;;
*)
;;
esac
exit 0
|