Jul 5, 2012

kmix: Automatically switch "Master Channel" between devices

Keywords:  bash, KDE 4, kmix, select Master Channel, automatic
Depends on:  kmix
Download:  kmix_set_master

Like nearly all laptops, I have a built-in MIC and speakers.  When I skype, I prefer to use my wireless USB headset.

KDE provides global shortcuts which allow you to bind your keyboard's volume up/down/mute keys.  In turn, the requests are handed to kmix.  kmix dutifully obeys the commands but only for the currently selected Master Channel (in kmix, see Settings > Select Master Channel ...).

What I wanted is kmix to automagically set the master channel to my headset when plugged in and when it's not, revert back to the integrated device.

I asked on IRC, checked Google but came up empty.  I wrote a simple shell script which starts at KDE login to monitor when I plug in my headset.  When it detects it's been plugged in, it uses qdbus to instruct kmix to switch its master channel.

The script has set up instructions.

The script cites the following excellent URL which enabled me to write the qdbus call:  http://usrlocalbin.blogspot.ca/2008/04/qdbus-tutorial-part-one.html

Slight Bug
With my wireless headset, the above script switches the master channel when the USB clip is connected.  The headset does not have to be turned on.  This might be a slight annoyance to people.  :)

If this becomes a problem, I'll see if there's an additional Linux status provided when the USB clip makes contact to the headset.

13 comments:

  1. Thank you for sharing the script!
    This is the only workaround I've found so far.
    But I was thinking if it wouldn't be possible to put the setCurrentMaster command in udev rule to run it when the preferred is being attached.
    Here is my udev rule:
    KERNEL=="pcmC[D0-9cp]*", ACTION=="add", PROGRAM="/bin/sh -c 'K=%k; K=$${K#pcmC}; K=$${K%%D*}; echo defaults.ctl.card $$K > /etc/asound.conf; echo defaults.pcm.card $$K >>/etc/asound.conf", RUN+="/home/blabla/setmix.sh"
    KERNEL=="pcmC[D0-9cp]*", ACTION=="remove", PROGRAM="/bin/sh -c 'echo defaults.ctl.card 0 > /etc/asound.conf; echo defaults.pcm.card 0 >>/etc/asound.conf'"

    Unfortunately this doesn't work. The reason is this error:
    Could not connect to D-Bus server: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11'

    Do you know how to fix this (as I'm not familiar with dbus)?
    Udev rule would be a better solution than monitoring script, imho.

    ReplyDelete
  2. Oh, and this is what's inside setmix.sh:
    #!/bin/sh
    qdbus org.kde.kmix /Mixers org.kde.KMix.MixSet.setCurrentMaster "ALSA::C-Media_USB_Headphone_Set:1" "Speaker:0"

    ReplyDelete
  3. Howdy,

    I'm sorry for the late response ... I was on vacation. :) Try setting DISPLAY to :0.0

    For example, in bash/sh, it'd be "export DISPLAY :0.0"

    btw, clever to use a udev rule. :)

    Cheers,
    -pablo

    ReplyDelete
  4. Yes, I also had to run "xhost +" and add "su - username -c before the qdbus method so that it would be run by user rather than by udev.
    Now it works. I just have to find out why is the udev rule being run multiple times.
    Thanks for your support!

    ReplyDelete
  5. Very nice and useful, and also a good example of how to use this kind of stuff.
    I tried to convert it to a dbus-send command, hoping it was a problem with qdbus... but it seems the problem is worse:

    dbus-send --dest=org.kde.kmix /Mixers org.kde.KMix.MixSet.setCurrentMaster string:"ALSA::C-Media_USB_Headphone_Set:1" string:"Speaker:0"

    testing it from console gives the same problem so I'm wondering if without X11 we can only talk to system dbus services? From a security point of view I really don't like an xhost + (or even an xhost +127.0.0.1).

    ReplyDelete
    Replies
    1. Erhm, lol... -__-;
      https://bugs.launchpad.net/ubuntu/+source/dbus/+bug/812940

      Delete
  6. Thanks for the script. I just switched to Arch and KDE, fed up with Unity/Gnome3 and sick of re-installing Ubuntu every 6 months and having outdated software in the meantime.

    I remember dealing with this issue in gnome years ago before it got fixed.
    KDE is ahead of gnome in some areas and behind in others but its way better than the the what they have going now.

    ReplyDelete
    Replies
    1. Hi,

      Thank you for writing. When I came back to Unix/Linux, I looked at Gnome and KDE along with a few other Window Managers. For my tastes, KDE has worked best. It's not perfect but you can code around issues. Like this one. :)

      I even wrote a KDE User Base document for KWin Rules - http://userbase.kde.org/KWin_Rules

      You might want to have a read and see how you can tailor your windows based on rules. For example, I have thunderbird on Virtual Desktop 1, sized the way I like it, my RSS reader on 2, etc.

      Cheers,
      -pablo

      Delete
  7. Thanks for your script! Unfortunately it was not working with my Logitech Audio Bluetooth-Adapter because it can't be listed with $ fgrep '[' /proc/asound/cards

    My workaround so far:

    pacmd list-cards | grep -B 1 blue 2>&1 >/dev/null #check if any blue(tooth) device is connected
    # pacmd list-cards | grep -B 1 bluez_card.C8_84_47_0D_03_9C 2>&1 >/dev/null #or check for your specific device
    CARD_INSTALLED=$?

    ReplyDelete
  8. Thanks a lot for the script, Pablo!

    ReplyDelete
    Replies
    1. Hi,

      You're very welcome. I appreciate you taking the time to thank me.

      Delete
  9. when i hit mute key on laptop it mutes MASTER, PCM, HEADPHONES. when i unmute with key it only unmutes MASTER i than have to go into mixer and manually unmute PCM and HEADPHONES. this is driving me insane, any idaeas?

    ReplyDelete