-
Notifications
You must be signed in to change notification settings - Fork 25
Persistent USB Mapping of Audio devices (Linux)
Linux does not guarantee that USB Sound cards are always mapped with the same ID. However with a combination of udev and alsa rules we can make sure that a particular USB Sound card gets a persistant handle. This is particularly helpful if you have several Sound cards on your system.
Here are some ideas in order to distinguish them:
- If your sound cards are from different manufactures, you can create a rule based on the vendor ID (VID)
- If your sound cards are different models, you can create a rule based on the product ID (PID)
- If your sound cards provide a serial number (only few do), you can create a rule based on the serial number
- If nothing else helps, you can write a rule that a sound card of a specific USB port will always receive the same ID
Here are some tools which will help you when debugging USB related issues:
lsusb lists all connected USB devices
$ lsusb
Bus 001 Device 005: ID 0403:eeef Future Technology Devices International, Ltd
Bus 001 Device 006: ID 074d:3556 Micronas GmbH Composite USB-Device
Bus 001 Device 004: ID 0451:2036 Texas Instruments, Inc. TUSB2036 Hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ lsusb --verbose
Bus 001 Device 006: ID 074d:3556 Micronas GmbH Composite USB-Device
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x074d Micronas GmbH
idProduct 0x3556 Composite USB-Device
bcdDevice 0.04
iManufacturer 1 microHAM
iProduct 2 microHAM CODEC
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 407
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 3 G6 2007/08/02 20:40
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 141
bInCollection 2
baInterfaceNr( 0) 1
baInterfaceNr( 1) 2
[...]
The udev management tool (udevadm) can list USB events like plugging-in a USB sound card. In the following example I plugged in a Microham Microkeyer MK2 which has a build-in soundcard.
$ udevadm monitor --kernel --subsystem-match=sound
monitor will print the received events for:
KERNEL - the kernel uevent
KERNEL[167858.249985] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/sound/card1 (sound)
KERNEL[167858.250881] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/sound/card1/controlC1 (sound)
KERNEL[167858.251466] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/sound/card1/pcmC1D0p (sound)
KERNEL[167858.252612] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/sound/card1/pcmC1D0c (sound)
KERNEL[167858.280285] change /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/sound/card1 (sound)
in the example above we can see that the soundcard was plugged in to usb port 1-1/1-1.4/1-1.4.1/1-1.4.1
. Based on this information we could create a fixed mapping of the soundcard to this specific USB port.
In order to create udev rules, open the file /etc/udev/rules.d/70-alsa-permanent.rules
:
$ sudo vim /etc/udev/rules.d/70-alsa-permanent.rules
SUBSYSTEM!="sound", GOTO="my_usb_audio_end"
ACTION!="add", GOTO="my_usb_audio_end"
ATTRS{idVendor}=="0741", ATTRS{idProduct}=="3556", ATTR{id}="SPEAKER"
ATTRS{idVendor}=="2d5a", ATTRS{idProduct}=="34e1", ATTR{id}="HEADSET"
LABEL="my_usb_audio_end"
SUBSYSTEM!="sound", GOTO="my_usb_audio_end"
ACTION!="add", GOTO="my_usb_audio_end"
ATTRS{serial}=="01241", ATTR{id}="SPEAKER"
ATTRS{serial}=="27321", ATTR{id}="HEADSET"
LABEL="my_usb_audio_end"
SUBSYSTEM!="sound", GOTO="my_usb_audio_end"
ACTION!="add", GOTO="my_usb_audio_end"
DEVPATH=="/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/sound/card?", ATTR{id}="SPEAKER"
DEVPATH=="/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/sound/card?", ATTR{id}="HEADSET"
LABEL="my_usb_audio_end"
Now that we have assigned to our two USB sound cards the ID "SPEAKER" and "HEADSET", we can create an alsa asoundrc rule.
$ vim $HOME/.asoundrc
Lets make both devices available and map Headset as our default sound card:
pcm.!default {
type hw
card "HEADSET"
device 0
}
ctl.!default {
type hw
card "HEADSET"
device 0
}
pcm.HEADSET {
type hw
card "HEADSET"
device 0
}
ctl.HEADSET {
type hw
card "HEADSET"
device 0
}
pcm.SPEAKER {
type hw
card "SPEAKER"
device 0
}
ctl.SPEAKER {
type hw
card "SPEAKER"
device 0
}
Now it's time to reboot your Linux machine!
One you have restarted, check that your new devices are mapped correctly, either with aplay -l
or remoteAudio enumerate