Woffles Volume Widget

Introduction
Having a usable volume control in my status bar was very important, I needed to be able to adjust the volume if needed, or mute it quickly.

By following this tutorial you'll end up with a widget in your status bar that looks like "Volume: 50%" which responds to mouse actions:


 * Mouse wheel adjusts volume up / down.
 * Left clicking on the volume mutes it.

This tutorial is aimed at systems using alsa, you'll need to confirm that you have the following programs installed:


 * alsamixer -- Ncurses based volume control.
 * amixer -- Tool for adjusting alsa on the fly.
 * pcregrep -- grep using the PCRE syntax.

Preparation
Before we start we need to know which audio channel you want to control, usually "Master" or "PCM". To get a list of available channels:

amixer -c 0 | pcregrep "control"

To test and make sure the value will do what we need run:

amixer -c 0 -- sget Master | pcregrep "[0-9]+%"

The output should look like:

Front Left: Playback 6 [19%] [-37.50dB] [on] Front Right: Playback 6 [19%] [-37.50dB] [on]

''Note: Your card ID (the -c 0 bit) might be different if you have more than one sound card available.''

Create the widget
Put this in whichever status bar you want them:

textbox volume_control { text_align = "right" align = "right" # Volume up: mouse { modkey = {} button = "4" command = "spawn" arg = "~/.awesome/volume-adjust.sh up" } 	# Volume down: mouse { modkey = {} button = "5" command = "spawn" arg = "~/.awesome/volume-adjust.sh down" } 	# Soft mute: mouse { modkey = {} button = "1" command = "spawn" arg = "~/.awesome/volume-adjust.sh mute" } }

Create the scripts
The first shell script we make simply contains the values of our card ID, the name of the channel we want to control, the percent of adjustment we want when using the mouse wheel, the name of the widget to update and finally the speed to update at in seconds:

~/.awesome/volume-values.sh: handle { # Hard mute: if [ "$1" == "0" ] then `amixer -c $cardid sset $channel mute > /dev/null` else `amixer -c $cardid sset $channel unmute > /dev/null` fi # Set widget text: echo " Volume: $1% " } cardid=0 channel="Master" adjust=5 widget="volume_control" speed=10

If you don't have an ~/.awesome folder, feel free to create one (~ is equal to your home directory.)

If you find that updating once every 10 seconds (speed=10) isn't enough feel free to change the value. Just be warned however that the smaller the value the higher your CPU usage will get.

Next we create a script to update the awesome widget:

~/.awesome/volume-update.sh: . ~/.awesome/volume-values.sh volume=`amixer -c $cardid -- sget $channel | pcregrep 'Left:.+[0-9]+%' | pcregrep -o '[0-9]+%' | pcregrep -o '[0-9]+'` echo "0 widget_tell $widget `handle \"$volume\"`" | awesome-client

Now we need a script to handle the volume adjustment:

~/.awesome/volume-adjust.sh: . ~/.awesome/volume-values.sh if [ "$1" == "up" ] then amixer -q -c $cardid sset $channel $adjust%+ fi if [ "$1" == "down" ] then amixer -q -c $cardid sset $channel $adjust%- fi if [ "$1" == "mute" ] then amixer -q -c $cardid sset $channel 0% fi ~/.awesome/volume-update.sh
 * 1) Force awesome to update:

And finally we need a script to monitor the volume, in case another program changes it:

~/.awesome/volume-monitor.sh: while true do 	if [ -S ~/.awesome_ctl.0 ]; then while true do . ~/.awesome/volume-update.sh 			sleep $speed done else sleep 1 fi done

To make sure the scripts can be executed run:

chmod +x ~/.awesome/volume-*

Final steps
The last thing you need to do is find a way to automatically run ~/.awesome/volume-monitor.sh every time you start an X session.

The usual way is to edit your ~/.xinitrc file to include the script, this might look something line:

~/.awesome/volume-monitor.sh & exec awesome

However, you'll probably need to figure something else out if you're using a display manager like xdm, gdm or kdm.

Finally, tell awesome to reload your configuration, the usual way is to press Control-Mod4-R.

That just about covers everything, if you have any question I'm woffle on IRC.