Saturday, March 31, 2012

Pulseaudio: USB sound device hotplug

When using Pulseaudio and pavucontrol, one can easily change the default sound device by clicking the fallback button on the device. However, this assumes that the default device is always connected.
When a USB sound device, for example a headset, is set as fallback and then disconnected, the fallback device becomes the PCI sound device, or whatever device is still connected. This happens both for source and sink configuration.

It is possible to solve the problem by creating a udev rule.
What needs to be done:
- Use udev to identify the USB sound device plugging in.
- Run pacmd to set default source & sink as the current user.

In this example, I used a Speedlink Medusa 5.1 USB headset, which is configured in pulseaudio as "Analog Surround 5.1 Output & Analog Stereo Input". The system I'm using therefore has these devices:

1. Intel HD Audio
2. USB sound device

Using aplay -l displays the following:
[stavros@stavros-laptop ~]$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC889 Analog [ALC889 Analog]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: ALC889 Digital [ALC889 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Device [USB Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
As you can see, the internal sound card is listed as card 0, and the USB device I want to set as default is listed as card 1.
Since I won't be plugging in any other sound device, I can use "card1" in a udev rule.

udevadm shows events that can be used to create rules for:
[stavros@stavros-laptop ~]$ udevadm monitor --kernel --subsystem=sound
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[2215.105651] add      /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0/sound/card1 (sound)
KERNEL[2215.105732] add      /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0/sound/card1/pcmC1D0p (sound)
KERNEL[2215.105824] add      /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0/sound/card1/pcmC1D0c (sound)
KERNEL[2215.106001] add      /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0/sound/card1/controlC1 (sound)
KERNEL[2215.190918] change   /devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0/sound/card1 (sound)

The device was not completely initialised when the "add" event fired, so I used the "change" event at the end, and created the following rule in /etc/udev/rules.d:

/etc/udev/rules.d/60-snd-usb.rules
SUBSYSTEM=="sound", KERNEL=="card1", ACTION=="change", RUN+="/home/stavros/bin/pulse-ins.sh"

This rule will execute /home/stavros/bin/pulse-ins.sh when card1 is inserted.
One script alone would not work, so I used 2, with pulse-ins.sh merely executing the other script

/home/stavros/bin/pulse-ins.sh:
#!/bin/bash
su -c "/home/stavros/bin/pulse_insert_card.sh & exit" stavros
This script is executed by udev, and it runs another script as the current user, since pacmd has to be run as a regular user.

/home/stavros/bin/pulse_insert_card.sh:
#!/bin/bash
/usr/bin/pacmd set-default-sink alsa_output.usb-0d8c_USB_Sound_Device-00-Device.analog-surround-51
/usr/bin/pacmd set-default-source alsa_input.usb-0d8c_USB_Sound_Device-00-Device.analog-stereo
This runs pacmd and sets the default source & sink devices.

Then, the following command reloads the udev rules without having to reboot. It must be run as root:
[root@stavros-laptop stavros]# udevadm control --reload-rules

Now, the USB sound device will be set as fallback when plugged in, and the internal device will be used as fallback when it is disconnected.

2 comments:

  1. Hey,
    thanks for the nice article. I just have one question. I was looking into usb hotplugging in general and found your article.
    Basically, I'm not using pulseaudio (yet). I'm using kde so I'm just using alsa (and phonon).

    Does pulseaudio offer any advantages in usb audio hotplugging over plain old alsa-only ?

    ReplyDelete
    Replies
    1. I believe there's nothing different between them for simple hotplugging, but pulseaudio is a bit simpler to use, since it uses long name identifiers instead of device numbers. You can run pacmd and specify a card to be set as default, with no need for different setups.

      Delete