aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2020-04-01 23:50:42 -0400
committerB. Watson <yalhcru@gmail.com>2020-04-01 23:50:42 -0400
commit926f740f5445dfcde1c43990566c719053ff2238 (patch)
tree36b124df936c8f39b4e4bdc8521949a71e87e95f
parent435021147e6e3c0fb7d1ecd3d6d7fc2051a6afbb (diff)
downloadmisc-scripts-926f740f5445dfcde1c43990566c719053ff2238.tar.gz
New script: vol (adjust audio volume with OSD)
-rwxr-xr-xvol167
1 files changed, 167 insertions, 0 deletions
diff --git a/vol b/vol
new file mode 100755
index 0000000..bf2f7de
--- /dev/null
+++ b/vol
@@ -0,0 +1,167 @@
+#!/bin/sh
+
+# vol - Adjust volume, with on-screen display.
+
+# (c) 2020 B. Watson <yalhcru@gmail.com>
+# Released under the WTFPL, see http://www.wtfpl.net/txt/copying/
+
+# Requires xosd.
+# Intended for use with xbindkeys, like so:
+
+#$ cat ~/.xbindkeysrc
+#"vol up &"
+# Control+Alt + Prior
+#
+#"vol down &"
+# Control+Alt + Next
+#
+#"vol mute &"
+# Control+Alt + Pause
+
+# "Next" and "Prior" are PageDown and PageUp. Replace with "Up" and "Down"
+# to use arrow keys. If you have multimedia keys, you can probably use
+# them. See xbindkeys(1).
+
+# Can also be used from the command line. Run with no args for help.
+
+# --------------------
+# Configurable options
+# --------------------
+
+# Should be "Master" for most (all?) cards. Use "amixer scontrols" to
+# get a list.
+CHANNEL=Master
+
+# Each up/down adjustment is by this much. Use the dB suffix if you
+# prefer decibels, or leave it off for percentage.
+ADJ=3dB
+
+# osd_cat seems a bit picky about what fonts it'll use. If you give a
+# nonexistent font, it won't run at all. If you give a font it "doesn't
+# like", you'll see the percentage bar, but no "Volume" text.
+FONT=12x24
+
+# What color is the OSD bar and text? See /usr/share/X11/rgb.txt.
+# COLOR is for when we're unmuted, MUTECOLOR is for muted.
+COLOR=green
+MUTECOLOR=red
+
+# Text drop shadow, 0 to disable.
+SHADOW=3
+
+# Where does the OSD show up on screen? One of: top middle bottom
+POSITION=bottom
+
+# How long does the OSD persist? In seconds, integer only.
+DELAY=2
+
+# amixer options. Could use -c, -D here. Don't use -q.
+# default is "-M", see amixer(1).
+AMIXER_OPTS="-M"
+
+# ------------------------------------------
+# End of configurable options, rest is code.
+# ------------------------------------------
+
+SELF="$( basename $0 )"
+
+PIDFILE="$HOME/.$SELF.osd.pid"
+
+# osd() will kill any previously-spawned osd_cat process. Ideally this
+# means rapid multiple keypresses won't "step on" each other. In practice
+# it seems to work OK, but if you press the key really fast on a slow
+# system, or hold it down with your key-repeat rate cranked up (on any
+# system), the OSD bar will never get a chance to display.
+
+osd() {
+ local got="$( amixer $AMIXER_OPTS get $CHANNEL )"
+ local muted="$( echo $got | grep '\[off\]$' )"
+ local volpct="$( echo $got | cut -d'[' -f2 | cut -d% -f1 )"
+ local db="$( echo $got | cut -d'[' -f3 | cut -d']' -f1 )"
+ local text="Volume $db ($volpct%)"
+ local color="$COLOR"
+ local oldpid
+
+ if [ -n "$muted" ]; then
+ text="$text [Muted]"
+ color="$MUTECOLOR"
+ fi
+
+ # the silliness with grepping in /proc is meant to avoid stale PID
+ # files whose PIDs have been recycled.
+ if [ -e $PIDFILE ]; then
+ oldpid="$( cat $PIDFILE )"
+ grep -q '^osd_cat' /proc/$oldpid/cmdline 2>/dev/null && \
+ kill "$oldpid" 2>/dev/null
+ fi
+
+ osd_cat -b percentage \
+ -d $DELAY \
+ -P $volpct \
+ -p $POSITION \
+ -c $color \
+ -s $SHADOW -T \
+ "$text" \
+ -f $FONT &
+
+ echo "$!" > $PIDFILE
+}
+
+amixer_set() {
+ amixer -q $AMIXER_OPTS set $CHANNEL $1
+}
+
+vol() {
+ amixer_set ${ADJ}${1}
+}
+
+mute() {
+ amixer_set toggle
+}
+
+usage() {
+ cat <<EOF
+$SELF [up|down|mute|<nnn>]
+
+<nnn> is a numeric volume, possibly followed by "dB" and/or "+" or "-".
+ It will be passed to 'amixer $AMIXER_OPTS set $CHANNEL' as-is.
+EOF
+ exit 1
+}
+
+check_deps() {
+ local missing="no"
+ for dep in osd_cat amixer; do
+ if ! type -p "$dep" > /dev/null; then
+ echo "$SELF: missing required executable '$dep'" 1>&2
+ missing="yes"
+ fi
+ done
+ if [ "$missing" = "yes" ]; then
+ echo "$SELF: please install the missing executable(s)" 1>&2
+ exit 1
+ fi
+}
+
+###main()
+
+check_deps
+
+case "$1" in
+ up) vol + ;;
+ down) vol - ;;
+ mute) mute ;;
+ [0-9]*) amixer_set "$1" ;;
+ *) usage ;;
+esac
+
+osd
+exit 0
+
+# For reference:
+#$ amixer get Master
+#Simple mixer control 'Master',0
+# Capabilities: pvolume pvolume-joined pswitch pswitch-joined
+# Playback channels: Mono
+# Limits: Playback 0 - 87
+# Mono: Playback 31 [36%] [-42.00dB] [on]