Persistent USB Mapping of Audio devices %28Linux%29 - dh1tw/remoteAudio GitHub Wiki

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

Tools

Here are some tools which will help you when debugging USB related issues:

lsusb

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
[...]

udevadm

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.

udev Rules

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

udev rule based on VID and PID

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"

udev rule based on Serial Number

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"

udev rule based on USB port

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"

asoundrc

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

⚠️ **GitHub.com Fallback** ⚠️