You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
5.5 KiB
200 lines
5.5 KiB
#!/bin/bash -eu |
|
|
|
# --------------------------------------------------------- |
|
# Lazy Variables |
|
__save() { |
|
local name=$1 |
|
shift |
|
declare -g $name="$*" |
|
} |
|
|
|
require() { |
|
for name in $@; do |
|
if [ -z "${!name+x}" ]; then |
|
get_$name "__save $name" "require_for $name" |
|
fi |
|
done |
|
} |
|
|
|
shopt -s expand_aliases |
|
alias greq='$2 ' |
|
alias gsave='$1 ' |
|
|
|
typeset -gA require_depends=() |
|
|
|
invalidate() { |
|
for name in $@; do |
|
unset -v $name |
|
if [ -n "${require_depends[$name]:-""}" ]; then |
|
local tmp="${require_depends[$name]}" |
|
unset -v require_depends[$name] |
|
invalidate $tmp |
|
fi |
|
done |
|
} |
|
|
|
require_for() { |
|
local self_name=$1 |
|
shift |
|
require $@ |
|
for name in $@; do |
|
require_depends[$name]="${require_depends[$name]-""} $self_name" |
|
done |
|
} |
|
|
|
# --------------------------------------------------------- |
|
# Lazy variables |
|
get_ponymix_prog() { |
|
gsave $(which ponymix 2>/dev/null) |
|
} |
|
|
|
get_pacmd_prog() { |
|
# May be unavailable if only pulse clients installed |
|
gsave $(which pacmd 2>/dev/null) |
|
} |
|
|
|
get_default_sink() { |
|
gsave $(pactl info | grep 'Default Sink' | cut -d: -f2) |
|
} |
|
|
|
# There doesn't seem to be a better way to get a sink volume right now |
|
get_pacmd_dump() { |
|
greq pacmd_prog |
|
[ -n "$pacmd_prog" ] || { echo "ERROR: \$pacmd_dump requires available pacmd which is part of the pulseaudio server package"; exit 44; } |
|
gsave "$(pacmd dump)" |
|
} |
|
|
|
get_pacmd_default_sink_config() { |
|
greq pacmd_dump default_sink |
|
gsave "$(echo "$pacmd_dump" | grep "$default_sink")" |
|
} |
|
|
|
get_pacmd_default_volume() { |
|
greq pacmd_default_sink_config |
|
gsave $[$(echo "$pacmd_default_sink_config" | grep "set-sink-volume" | cut -d' ' -f3)] |
|
} |
|
|
|
get_default_volume_percent() { |
|
greq ponymix_prog |
|
if [ -n "$ponymix_prog" ]; then |
|
gsave $($ponymix_prog get-volume) |
|
else |
|
greq pacmd_default_volume |
|
gsave $[(100*$pacmd_default_volume+32768)/65535] |
|
fi |
|
} |
|
|
|
get_default_mute() { |
|
greq ponymix_prog |
|
if [ -n "$ponymix_prog" ]; then |
|
$ponymix_prog is-muted && gsave yes || gsave no |
|
else |
|
greq pacmd_default_sink_config |
|
gsave $(echo "$pacmd_default_sink_config" | grep "set-sink-mute" | cut -d' ' -f3) |
|
fi |
|
} |
|
|
|
# --------------------------------------------------------- |
|
# Operations |
|
do_vol() { |
|
# Set default sink volume |
|
require default_sink |
|
local offset |
|
case "$1" in |
|
m|mute) |
|
pactl set-sink-mute $default_sink true |
|
;; |
|
u|unmute) |
|
pactl set-sink-mute $default_sink false |
|
;; |
|
t|toggle|toggle-mute) |
|
pactl set-sink-mute $default_sink toggle |
|
;; |
|
\+) : ${offset:=+5%};& |
|
\-) : ${offset:=-5%};& |
|
*) : ${offset:=$1} |
|
pactl set-sink-mute $default_sink false |
|
pactl set-sink-volume $default_sink $offset |
|
;; |
|
esac |
|
invalidate pacmd_dump default_volume_percent default_mute |
|
} |
|
|
|
do_notify() { |
|
# Notification |
|
if which dunstify >/dev/null 2>&1 && [ -n "`pgrep --ns $$ -u $(id -u) dunst`" ]; then |
|
require default_sink default_volume_percent default_mute |
|
dunst_id=6533319 |
|
if [ $default_mute = yes ]; then |
|
icon=audio-volume-muted |
|
text="Volume muted" |
|
else |
|
text="Volume $default_volume_percent%" |
|
if [ $default_volume_percent -lt 35 ]; then |
|
icon=audio-volume-low |
|
elif [ $default_volume_percent -lt 75 ]; then |
|
icon=audio-volume-medium |
|
else |
|
icon=audio-volume-high |
|
fi |
|
fi |
|
if echo $default_sink | grep -q bluez; then |
|
text="Bluetooth $text" |
|
fi |
|
bar_size=20 |
|
filled=$[(($bar_size * $default_volume_percent) + (100 / (2 * $bar_size)))/100] |
|
bar= |
|
if [ $filled -gt 0 ]; then |
|
bar="`printf %.s● $(seq $filled)`" |
|
fi |
|
if [ $filled -lt $bar_size ]; then |
|
bar="$bar`printf %.s○ $(seq $[$bar_size-$filled])`" |
|
fi |
|
dunstify -a "PA Volume" -u low -i $icon -r $dunst_id "$text" "$bar" |
|
fi |
|
} |
|
|
|
do_print() { |
|
require default_sink default_volume_percent default_mute |
|
[ $default_mute = yes ] && muted=muted || muted=unmuted |
|
echo "$default_sink $default_volume_percent% $muted" |
|
} |
|
|
|
# --------------------------------------------------------- |
|
# Main |
|
|
|
while [ $# -gt 0 ]; do |
|
verb=$1; shift |
|
|
|
case $verb in |
|
v|vol|volume) |
|
do_vol "$1"; shift |
|
do_notify |
|
do_print |
|
;; |
|
set-volume) |
|
do_vol "$1"; shift |
|
;; |
|
n|notify) |
|
do_notify |
|
;; |
|
p|print) |
|
do_print |
|
;; |
|
get-default-sink) |
|
require default_sink |
|
echo $default_sink |
|
;; |
|
*) |
|
echo "Available verbs:" |
|
echo " set-volume <[+-]n%|mute|unmute|toggle> Change default sink volume" |
|
echo " notify Display a notification with current default sink volume" |
|
echo " print Print the default sink and it's volume" |
|
echo " volume <see set-volume> Short for \"set-volume <...> notify print\"" |
|
echo " get-default-sink Print default sink name" |
|
echo |
|
echo " verbs can be chained by separating them with space. Note that some have additional arguments" |
|
exit 1 |
|
;; |
|
esac |
|
done
|
|
|