Skip to content

Instantly share code, notes, and snippets.

@novasenco
Created April 29, 2021 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save novasenco/a048f34753cc3eb76eef7da5e8b59ee4 to your computer and use it in GitHub Desktop.
Save novasenco/a048f34753cc3eb76eef7da5e8b59ee4 to your computer and use it in GitHub Desktop.
simple script for volume control with alsa
#!/usr/bin/env bash
# _
# __ _____ | | a simple script to
# \ \ / / _ \| | control volume from
# \ V / (_) | | the command-line or
# \_/ \___/|_| a keybinding
#
# Author: Nova Senco
# Last Change: 29 April 2021
VER='1.2'
printhelp(){
cat <<DONE
Usage: $(basename $0) [OPTIONS]
Easily see and change volume with amixer.
Quick Examples:
vol -i # increase volume by 5 to nearest multiple of 5
vol -ii # increase volume by 10 to nearest multiple of 5
vol -d # decrease volume by 5 to nearest multiple of 5
vol -t # toggle mute
vol -m # mute
vol -i 5 # increase volume by 5
OPTIONS:
-i --increase [<amt>] increment volume by <amt> (default: 5)
-d --decrease [<amt>] decrement volume by <amt> (default: 5)
-s --set <amt> set volume to <amt>
-x --mixer <mixer> select <mixer> (when unspecified: "Master")
-m --mute mute
-u --unmute unmute
-t --toggle toggle mute
-q --quiet don't print or notify; negates -v
-v --verbose print to stdout (-vv to debug) and don't notify
-n --notify notify (even if -v or -q passed); default if noninteractive
-N --no-notify do not notify (even if -n passed or noninteractive)
-h --help display this help and exit
-V --version display the version and exit
DONE
}
argv="$(getopt -n vol \
-l 'help,version,quiet,verbose,notify,no-notify,increase::,decrease::,set:,mixer:,mute,unmute,toggle' \
-o 'hVqvnNi::d::s:x:mut' -- "$@" \
)"
[[ $? -ne 0 ]] && exit 1
eval set -- "$argv"
mixer='Master'
voldelta=0
volstddelta=0
volset=-1
mutectl=0
verbosity=0
toggle='-1'
tty -s && notify=0 || notify=1
nonotify=0
while true
do
case "$1"
in
-h|--help)
printhelp;
exit 0
;;
-V|--version)
echo "vol $VER"
exit 0
;;
-i|--increase)
if [[ $2 =~ ^[0-9]+$ ]]
then
((voldelta+=$2))
else
((volstddelta+=1))
fi
shift
shift
;;
-d|--decrease)
if [[ $2 =~ ^[0-9]+$ ]]
then
((voldelta-=$2))
else
((volstddelta-=1))
fi
shift
shift
;;
-s|--set)
if [[ ! $2 =~ ^[0-9]+$ ]]
then
if [[ $verbosity -ge 0 ]]
then
>&2 echo "vol: invalid option: '$1' requires integer, not '$2'"
fi
exit 2
fi
volset="$2"
shift
shift
;;
-m|--mute)
shift
((mutectl++))
;;
-u|--unmute)
shift
((mutectl--))
;;
-t|--toggle)
shift
((toggle*=-1))
;;
-v|--verbose)
shift
((verbosity++))
;;
-q|--quiet)
shift
((verbosity--))
;;
-n|--notify)
shift
notify=1
;;
-N|--no-notify)
shoft
nonotify=1
;;
-x|--mixer)
shift
mixer="$1"
shift
;;
--)
shift
break
;;
esac
done
read vol on_off < <(amixer get "$mixer" 2>/dev/null \
| perl -n -e '/\[(\d+)%\].*\[(on|off)\]$/ && print("$1 $2\n") && exit')
if [[ -z $vol ]]
then
>&2 echo "Fatal Error: unable to use amixer to get volume information with \"amixer get $mixer\"."
exit 1
fi
if [[ $volstddelta -ne 0 ]]
then
drift=$(( 2-((vol%5+2)%5) ))
((voldelta+=volstddelta*5+drift))
fi
if [[ $volset -ne -1 ]]
then
[[ $verbosity -gt 1 ]] && >&2 echo "> volume = $volset"
amixer set "$mixer" "$volset%" >/dev/null
fi
if [[ $voldelta -ne 0 ]]
then
volsym='+'
if [[ $voldelta -lt 0 ]]
then
volsym='-'
((voldelta*=-1))
fi
[[ $verbosity -gt 1 ]] && >&2 echo "> volume $volsym= $voldelta"
amixer set "$mixer" "$voldelta%$volsym" >/dev/null
fi
if [[ $toggle -eq 1 ]]
then
[[ $verbosity -gt 1 ]] && >&2 echo '> toggling mute'
amixer set "$mixer" toggle >/dev/null
else
if [[ $mutectl -gt 0 ]]
then
[[ $verbosity -gt 1 ]] && >&2 echo '> muting'
amixer set "$mixer" mute >/dev/null
elif [[ $mutectl -lt 0 ]]
then
[[ $verbosity -gt 1 ]] && >&2 echo '> unmuting'
amixer set "$mixer" unmute >/dev/null
fi
fi
read vol on_off < <(amixer get "$mixer" 2>/dev/null \
| perl -n -e '/\[(\d+)%\].*\[(on|off)\]$/ && print("$1 $2\n") && exit')
mutestr=
if [[ $on_off == off ]]
then
mutestr='muted'
fi
if [[ $verbosity -gt 0 ]]
then
echo "$vol%${mutestr:+($mutestr)}"
fi
if [[ -n $mutestr ]] || [[ $vol -eq 0 ]]
then
icon_name="audio-volume-muted"
elif [[ $vol -lt 33 ]]
then
icon_name="audio-volume-low"
elif [[ $vol -lt 67 ]]
then
icon_name="audio-volume-medium"
else
icon_name="audio-volume-high"
fi
if [[ $notify -eq 1 && $nonotify -ne 1 ]]
then
# pgrep -x dunst >/dev/null && \
notify-send "${mutestr:-vol}" \
-i "$icon_name" \
-h "int:value:$vol" \
-h string:synchronous:volume
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment