Introduction
Most modern Linux distributions use a hot-pluggable architecture for USB devices. This is very useful for everyday use, but it becomes difficult for pro-audio use, as ALSA device numbers (hw:X) are not stable across reboots, or even when removed and reinserted. This means that Jack has to be reconfigured after every restart or change.
This document describes a method of maintaining ALSA device numbers for USB devices, including MIDI devices. It is not intended for beginning users, as the configuration is relatively arcane.
Preparation
Ensure that all of your USB audio devices are connected and detected by ALSA. Do this in a terminal by executing the command:
foo@bar:~$ cat /proc/asound/cards
My configuration is copied below.
0 [Intel ]: HDA-Intel - HDA Intel HDA Intel at 0xefffc000 irq 20 1 [BCR2000 ]: USB-Audio - BCR2000 BEHRINGER BCR2000 at usb-0000:00:1d.3-1, full speed 2 [default ]: USB-Audio - USB Audio CODEC Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.3-2, full s 3 [U0x46d0x8c6 ]: USB-Audio - USB Device 0x46d:0x8c6 USB Device 0x46d:0x8c6 at usb-0000:00:1d.7-5, high speed 4 [U49 ]: USB-Audio - USB Axiom 49 M-Audio USB Axiom 49 at usb-0000:00:1d.0-2, full speed
The first column is the ALSA device (major) number. In this case, on my laptop i have the following:
- device 0 (hw:0) is the inbuilt Intel High Definition Audio chipset.
- device 1 (hw:1) is a Behringer BCR2000 MIDI controller
- device 2 (hw:2) is a Behringer UCA202 soundcard
- device 3 (hw:3) is the laptop's inbuilt microphone
- device 4 (hw:4) is an M-Audio Axiom 49 MIDI keyboard
Take note of your configuration.
Now, in the same terminal, execute the following:
foo@bar:~$ lsusb
My configuration is copied below:
Bus 004 Device 001: ID 0000:0000 Bus 005 Device 003: ID 1397:00bc Bus 005 Device 002: ID 08bb:2902 Texas Instruments Japan Bus 005 Device 001: ID 0000:0000 Bus 002 Device 003: ID 0763:0199 Midiman Bus 002 Device 002: ID 0430:0005 Sun Microsystems, Inc. Type 6 Keyboard Bus 002 Device 001: ID 0000:0000 Bus 003 Device 005: ID 0a5c:4503 Broadcom Corp. Bus 003 Device 004: ID 0a5c:4502 Broadcom Corp. Bus 003 Device 003: ID 413c:8126 Dell Computer Corp. Bus 003 Device 002: ID 0a5c:4500 Broadcom Corp. Bus 003 Device 001: ID 0000:0000 Bus 001 Device 005: ID 046d:08c6 Logitech, Inc. Bus 001 Device 001: ID 0000:0000
Note that active USB devices have two pairs of hexadecimal numbers for an ID, such as 08bb:2902, and generally have a manufacturer's name, such as Texas Instruments Japan. This is where you may have to do some investigation. By removing a USB device and executing
foo@bar:~$ lsusb
you can see which device corresponds to which ID and manufacturer.
In this case, I have detached the UCA202:
Bus 004 Device 001: ID 0000:0000 Bus 005 Device 003: ID 1397:00bc Bus 005 Device 002: ID 0000:0000 <----------- HERE! Bus 005 Device 001: ID 0000:0000 Bus 002 Device 003: ID 0763:0199 Midiman Bus 002 Device 002: ID 0430:0005 Sun Microsystems, Inc. Type 6 Keyboard Bus 002 Device 001: ID 0000:0000 Bus 003 Device 005: ID 0a5c:4503 Broadcom Corp. Bus 003 Device 004: ID 0a5c:4502 Broadcom Corp. Bus 003 Device 003: ID 413c:8126 Dell Computer Corp. Bus 003 Device 002: ID 0a5c:4500 Broadcom Corp. Bus 003 Device 001: ID 0000:0000 Bus 001 Device 005: ID 046d:08c6 Logitech, Inc. Bus 001 Device 001: ID 0000:0000
Make a note of the ID number pair - ie, 08bb:2902. These numbers represent the Vendor ID (vid) and Product ID (pid) of the device, and will come in handy for configuring the ALSA device numbers.
Through a process of elimination, I discover that my USB devices have the following ID numbers:
- the Behringer BCR2000 MIDI controller is ID 1397:00bc (and has no manufacturer's name)
- the Behringer UCA202 soundcard is ID 08bb:2902
- the M-Audio Axiom 49 MIDI keyboard is ID 0763:0199 and has the manufacturer's name 'Midiman'
There's another way to discover this information, but it requires scrolling through pages and pages of output. It's how I discovered the inbuilt microphone. I had to closely examine the output of:
foo@bar:~$ sudo lsusb -v | less
We use 'sudo' here so that we can see all the information about the device. Here's the (very long) information for the BCR2000:
Bus 005 Device 003: ID 1397:00bc Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1397 idProduct 0x00bc bcdDevice 1.00 iManufacturer 1 BEHRINGER iProduct 2 BCR2000 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 117 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x40 (Missing must-be-set bit!) Self Powered MaxPower 0mA 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 9 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 9 bInCollection 1 baInterfaceNr( 0) 1 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 1 Audio bInterfaceSubClass 3 MIDI Streaming bInterfaceProtocol 0 iInterface 0 MIDIStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 81 MIDIStreaming Interface Descriptor: bLength 6 bDescriptorType 36 bDescriptorSubtype 2 (MIDI_IN_JACK) bJackType 1 Embedded bJackID 1 iJack 0 MIDIStreaming Interface Descriptor: bLength 6 bDescriptorType 36 bDescriptorSubtype 2 (MIDI_IN_JACK) bJackType 2 External bJackID 2 iJack 0 MIDIStreaming Interface Descriptor: bLength 6 bDescriptorType 36 bDescriptorSubtype 2 (MIDI_IN_JACK) bJackType 1 Embedded bJackID 3 iJack 0 MIDIStreaming Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (MIDI_OUT_JACK) bJackType 1 Embedded bJackID 4 bNrInputPins 1 baSourceID( 0) 2 BaSourcePin( 0) 1 iJack 0 MIDIStreaming Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (MIDI_OUT_JACK) bJackType 2 External bJackID 5 bNrInputPins 1 baSourceID( 0) 1 BaSourcePin( 0) 1 iJack 0 MIDIStreaming Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (MIDI_OUT_JACK) bJackType 2 External bJackID 6 bNrInputPins 1 baSourceID( 0) 3 BaSourcePin( 0) 1 iJack 0 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 bRefresh 0 bSynchAddress 0 MIDIStreaming Endpoint Descriptor: bLength 5 bDescriptorType 37 bDescriptorSubtype 1 (GENERAL) bNumEmbMIDIJack 1 baAssocJackID( 0) 4 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0004 1x 4 bytes bInterval 0 bRefresh 0 bSynchAddress 0 MIDIStreaming Endpoint Descriptor: bLength 6 bDescriptorType 37 bDescriptorSubtype 1 (GENERAL) bNumEmbMIDIJack 2 baAssocJackID( 0) 1 baAssocJackID( 1) 3 Device Status: 0x0001 Self Powered
By looking for the 'iProduct' and iManager' strings that correspond to the information from
foo@bar:~$ cat /proc/asound/cards
You can identify some devices. However, the process of identifying some internal devices (such as my microphone) came down to a lot of investigation - look for devices that have the following identifiers:
bInterfaceClass 1 Audio
My internal microphone has the ID 046d:08c6 and is manufactured by Logitech, Inc.
OK. Let's move to the actual configuration!
Configuration
In the text editor of your choice, open (using sudo) /etc/modprobe.d/alsa-base. ie:
foo@bar:~$ gksu gedit /etc/modprobe.d/alsa-base
Look for the following line:
options snd-usb-audio index=-2
and comment it out! (NEVER delete a line in a configuration file - you should always be able to roll back if it goes wrong!) In this configuration file, a '#' is used as a comment marker, so make the line look like:
#options snd-usb-audio index=-2
This line usually prevents a USB device grabbing the hw:0 slot. However, it also prevents it from grabbing any specific spot in the ALSA cards list, so we need to comment it out.
At the end of the file, we need to configure the order that the cards should be listed in. In my case, I want the following setup:
- the first card (hw:0) should always be HDA-Intel
- the second card (hw:1) should always be the inbuilt microphone
- the third card (hw:2) should always be the BCR2000
- the fourth card (hw:3) should always be the Axiom 49
- the fifth card (hw:4) should always be the UCA202
This is so I can use my laptop for general work and still be able to use the inbuilt audio to listen to music, or use the microphone with the inbuilt webcam. I have a FireWire soundcard, so I don't need to use the UCA202 so much. My Windows software (under WINE) expects MIDI controllers to be in the same place - I'm not sure why!
So, I have four USB devices and one Intel HDA device to configure. ALSA uses module names for audio driver configuration - in this case, Intel HDA is represented by the snd-hda-intel driver, and USB devices by the snd-usb-audio driver. Investigating the ALSA Support Matrix will help you identify the drivers for your particular cards.
My configuration means I have to add the following lines to /etc/modprobe.d/alsa-base
# USB Magic, part 1 alias snd-card-0 snd-hda-intel alias snd-card-1 snd-usb-audio alias snd-card-2 snd-usb-audio alias snd-card-3 snd-usb-audio alias snd-card-4 snd-usb-audio
This tells ALSA to prepare five devices. To make the HDA Intel device appear as hw:0, add the following line:
options snd-hda-intel index=0
Remember the ID numbers we noted down before? Here's where they come in. ALSA expects USB device IDs in the form
vid=0x<first number> pid=0x<second number>
so the internal microphone is
vid=0x046d pid=0x08c6
To give the internal microphone the device number hw:1, we enter the line
options snd-usb-audio index=1 vid=0x046d pid=0x08c6
Still with me?
OK!
To configure multiple cards, I had to enter them on the same line, like this:
options snd-usb-audio index=1,2,3,...''n'' vid=0x<vid1>,0x<vid2>,0x<vid3>,...0x<vid''n''>\ pid=0x<pid1>,0x<pid2>,0x<pid3>,...0x<pid''n''>
where <vid1> is the vid number of the card corresponding to the card you want to appear first, and <pid1> is the pid number of that card, and so on. It can get confusing!
My configuration looks like:
options snd-usb-audio index=1,2,3,4 vid=0x046d,0x1397,0x0763,0x08bb \ pid=0x08c6,0x00bc,0x0199,0x2902
Information as of 2014, March 20
The restart of the alsa system can be done with the command "sudo alsa force-reload". If that does not help getting the sound working in the USB headset, a full reboot will do it.
In one case, on a Logitech USB Headset, on an IBM/Lenovo Thinkpad laptop the above configuration with HDA Intel having the priority as first sound card did not allow for the sound to be output to the headset, so it had to be reverted.
Here is the information about this USB headset:
$ cat /proc/asound/cards 0 [Headset ]: USB-Audio - Logitech USB Headset Logitech Logitech USB Headset at usb-0000:00:1d.2-1, full speed 1 [Intel ]: HDA-Intel - HDA Intel HDA Intel at 0xee240000 irq 45 29 [ThinkPadEC ]: ThinkPad EC - ThinkPad Console Audio Control ThinkPad Console Audio Control at EC reg 0x30, fw 79HT50WW-1.07
$ usb-devices (some blocks of texts) T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=046d ProdID=0a14 Rev=01.30 S: Manufacturer=Logitech S: Product=Logitech USB Headset C: #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=00 Driver=snd-usb-audio I: If#= 1 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=snd-usb-audio I: If#= 2 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=00 Driver=snd-usb-audio
$ lsusb (...) Bus 004 Device 002: ID 046d:0a14 Logitech, Inc.
Here is what the end of the alsa-base.conf looks like now.
## USB Magic, part 1 # from https://help.ubuntu.com/community/UbuntuStudio/UsbAudioDevices alias snd-card-0 snd-usb-audio alias snd-card-1 snd-hda-intel # Make the Headset Logitech device appear as hw:0 options snd-usb-audio index=0 # To give the Logitech headset the device number hw:0, we enter the line options snd-usb-audio index=0 vid=0x046d pid=0x0a14
By doing so, the sound vanishes once the headset is unplugged, and the configuration needs to be reverted and the system rebooted in order to have the sound coming out of the integrated speakers. (But if the headset is plugged in again, the audio program can be resumed).
I also tried to configure the thinkpad_acpi audio control (some buttons to raise/lower or pause the sound above the keyboard of the laptop), but this didn't work so far.