Ubuntu 12.04: SToggle – HDMI sound toggle/switch

I’m a newb when it comes to scripting and pretty much anything Linux related. But even so, I’m a bit proud of this script because now I can toggle hdmi audio on my laptop from either my main user account or guest account (that, and the fact that I spent 5 hours trying to find a way to get the script to work)! 😀

So, apparently my udev rules were working. The problem was the script. I learned that running scripts in a terminal, in the background, or by udev isn’t the same; environment variables are different and when you use ‘who’ or ‘w’ in a script that isn’t running in the terminal, it’ll display nothing. I guess in older versions of Ubuntu, when you used
USER="$(who | grep :0 | cut -f 1 -d ' ' | head -n 1)"
a line would show for the gnome-session (tty7)? But as far as I can tell, it wasn’t showing in Ubuntu 12.04 (and apparently 11.10 because in my Ubuntu 11.10 VM, it didn’t show up either). Technically, the script (MToggle) works if you had a terminal opened on TTY opened (probably why I thought it worked). But since I had a terminal opened at most times, I just assumed the script worked.

In 11.10 and 12.04, you could get around this by just putting your actual username for USER, but then it wouldn’t work if you had other users that used the same computer. But then again, the script was made for laptops in mind and I doubt it would work for desktops because it depends on the change of hdmi status… I’m not sure.

But what about guest accounts? What about changing usernames? I didn’t like the fact that I was just using my username in the script to get it to work. So I started searching the filesystem for anything that could tell me about the active user logged on. Eventually I found a file called “database” in “/var/run/ConsoleKit” which had info about “x11_display”, which one was active, and the UID of that corresponded to the displays. So the script:

# Sound Toggle
# By Charles Cruz
# The following script toggles the between laptop speakers and hdmi audio (if detected).
# Version 1.0

USERID="$(cat /var/run/ConsoleKit/database | grep -B 6 is_active=true | grep uid= | cut -f 2 -d '=')"
USER="$(grep $USERID /etc/passwd | cut -f 1 -d ':')"
HDMI_STATUS="$(cat /sys/class/drm/card0-HDMI-A-1/status)"

if [ "${HDMI_STATUS}" = connected ]; then
sudo -u $USER pactl set-card-profile 0 output:hdmi-surround
sudo -u $USER pactl set-card-profile 0 output:analog-stereo+input:analog-stereo

exit 0


  1. In a terminal:
    sudo gedit /etc/udev/rules.d/hdmi.rules
  2. Copy, paste, then save:
    SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/SToggle"
  3. In the terminal:
    sudo udevadm control --reload-rules
  4. In the terminal:
    sudo gedit /usr/local/bin/SToggle
  5. Copy and paste the script above and then save it.
  6. In the terminal:
    sudo chmod 755 /usr/local/bin/SToggle

And that should do it! Hope it works!


9 thoughts on “Ubuntu 12.04: SToggle – HDMI sound toggle/switch

    • @Matt: Sorry, I’m still new at this. So I’m not entirely sure. I updated my script so I suggest that first. If it still isn’t working, try viewing what profiles you have with “pactl list | grep -A 8 Profiles:” in a terminal (I used 8, but you may have more or less available profiles); maybe they’re different? I know that when I used “output:hdmi-surround,” I lost some audio (like the part where the voices are in videos) so I changed it to “output:hdmi-stereo”. You can try reloading the rules with “sudo udevadm control –reload-rules” and check that everything is actually still there in /etc/udev/rules.d and /usr/local/bin. Also, check if you’re using the 11.10 version. Apparently, that only works if you have a tty or terminal open. Hope this helps and you get it working!

  1. i am not sure if this will work on my machine, but do you have any options on how about adding pulseaudio -k to the script? and after adding that rule (pulseaudio needs about 10 to 15 seconds to restart ) making the script halt for 15 to 20 seconds for hdmi to show up in sound settings.

      • Had to think this over again, but this is what i would want to accomplish :

        After a wake up from my laptop, HDMI sound is not available yet (even when i plug in the HDMI cable it is not there). SO, if i plug in the HDMI cable, i first need the command pulseaudio -k for restarting the sound options. that takes so much as 10 seconds or so. to be on the safe side, i optioned for 15 seconds. then the HDMI sound output is available in the sound options. and then i want it to switch automatically to the HDMI sound output…

        i can image that this is a bit to much to add to a script 🙂 i thought you might have a quick idea. thanks for giving it a thought!!

  2. so you still havnt explained how to get the sound to auto switch after a reboot……… the only way it works for me is to do alt f2 and type in killall pulse audio, which is ridiculous, i added that to your script and that doesnt work either. so its not an auto switch togle now is it?

  3. by the way, all my sound dies if i plug in the hdmi cable, and the only way to get it back is the killall command. your script seems to work fine until i reboot, i just want it to be persistant and you said you made it work that way for you but you gave no explanation as to how other than updating something but you didnt explain further what exactly is supposed to be updated……

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s