ALSA Device Names

December 2010

This is a discussion of ALSA names and card indexes, and how an ALSA user can request a certain sound card.  The information may be well known to ALSA experts, but was not obvious to me.  I present it in the hope that it may be useful to others.

When I became active in Software Defined Radio I purchased an M-Audio Audiophile 24/96 card for my 3 GHz Pentium 4 Debian system.  This is a great card with a flat noise floor and no spurs over its whole bandwidth.  My only complaint is that the maximum sample rate is 96 ksps instead of 192.  Later when I designed a ham radio transmitter I purchased a USB microphone from Radio Shack.  This Mic was "hw:1", the Audiophile was ALSA device "hw:0", and everything worked fine.

Then in 2010 I purchased a Behringer UCA202 USB sound card.  Adding this card caused my Audiophile to stop working.  It was listed in the output from lsusb, but not in "cat /proc/asound/cards".  These messages appeared in dmesg:

cannot find the slot for index 0 (range 0-2), error: -16
ICE1712: probe of 0000:03:03:0 failed with error -12

I knew that the Audiophile could change index, but I could not understand why it stopped working.  Eventually I found a file /etc/modprobe.d/sound that was attempting to install the card at index zero.  But the USB Behringer was already installed there.  Instead of installing the Audiophile at a higher index, ALSA treated this as a fatal error and ignored the card.  So I wrote a new /etc/modprobe.d/sound file that looked like this:
alias snd-card-0 snd-ice1712
alias snd-slot-0 snd-ice1712
alias snd-card-1 snd-usb-audio
alias snd-slot-1 snd-usb-audio
alias snd-card-2 snd-usb-audio
alias snd-slot-2 snd-usb-audio
options snd cards_limit=3
options snd-usb-audio index=-2
options snd-ice1712 index=0
options snd-usb-audio vid=0x08bb index=1
options snd-usb-audio vid=0x0556 index=2
The file attempts to install the Audiophile to index 0, the Behringer to index 1 and the Mic to index 2.  Note the index of -2.  This is a bit map of all ones followed by a single zero (in binary).  It prevents any snd-usb-audio device from taking index 0.  And note the very convenient options for vendor id and product id on the USB devices.  After trying a few combinations and re-booting many times, I finally concluded that this file does not work.  The USB sound cards were still installed starting at index 0.

Both of my USB cards are "USB Audio Class" devices.  That means that they don't need a special USB device driver.  Instead, they use an operating system standard driver.  That makes them work effortlessly on both Linux and Windows, and it makes my life easier because my system dual boots Debian stable and Windows XP.  But in any case, I can't ask my Quisk uses to become root and edit system files in /etc/modprobe.d anyway.

My conclusion is that it is an error to try to dictate card slots and card indexes to a hotplug/udev system like Linux.  Linux must be free to find open slots, and I must figure out a way of finding the card later.

So let us take a closer look at ALSA PCM device names.  The name is a string with three parts: a numeric or string card name, a numeric device, and a numeric subdevice.  Here are examples:

hw:0
hw:1
hw:1,1
hw:1,1,1
hw:M2496
hw:M2496,1,1

The device and subdevice are separated by commas, and default to zero if omitted.  A single card may have multiple devices, for example an analog and SPDIF input.  To see what playback devices you have, enter "aplay -l" in a terminal window.  For capture (recording) devices, use "arecord -l".  Another possibility is "cat /proc/asound/cards" which results in:
 0 [default        ]: USB-Audio - USB Audio CODEC 
Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.1-1, full s
1 [default_1 ]: USB-Audio - AK5370
AKM AK5370 at usb-0000:00:1d.1-2, full speed
2 [M2496 ]: ICE1712 - M Audio Audiophile 24/96
M Audio Audiophile 24/96 at 0xb400, irq 19
The names in brackets are the ALSA card id's, a fact you can verify by looking at /proc/asound/card*/id.  These names can be used in ALSA device names, for example "hw:M2496,0,1".  This could be a way to identify cards by name, but note the "default" and "default_1" names.  These will certainly not be constant as various USB cards are plugged and unplugged, so these will not work as names for specific cards.

It looks like a text search of /proc/asound/cards could be used to find the correct card, but the /proc file system is soon to be split into a /proc and a /sys file system, with ALSA moved to /sys.  I could not find anything resembling /proc/asound/cards in my /sys, so maybe the format is different, or ALSA has not yet been moved.  So this does not seem like a good option either.

But fortunately the text from /proc/asound/cards is available within ALSA.  Here is some C code that loops over all cards, and prints the card index, name and "long name":
	int next;
char * pt;

next = -1;
while (1) {
if (snd_card_next(&next) != 0)
return; // Error
if (next < 0)
return; // No more cards
if (snd_card_get_name(next, &pt) == 0) {
printf ("Name %d: %s\n", next, pt);
}
if (snd_card_get_longname(next, &pt) == 0) {
printf ("Longname %d: %s\n", next, pt);
}
}
This results in the following text:
Name 0: USB Audio CODEC 
Longname 0: Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.1-1, full s
Name 1: AK5370
Longname 1: AKM AK5370 at usb-0000:00:1d.1-2, full speed
Name 2: M Audio Audiophile 24/96
Longname 2: M Audio Audiophile 24/96 at 0xb400, irq 19

This is almost what we want, but we need to loop over all device names too.  To do this, see play.c in the alsa-utils distribution, or see sound-alsa.c in Quisk.  Quisk uses the card name followed by the device name as the descriptive text for the device.  This name is shown on the Quisk config screen, and the special alsa name "alsa:text" will search this description for "text" and match the card.  In this way, Quisk can use names instead of index numbers to identify a card and device.  An alternative is to put the full description in a combo box, and let the user pick the device from there.

In summary, ALSA software authors must provide their users with a way to specify card devices by name, not by index number.  The ALSA text card names are not adequate for this task.  Attempts to force cards into certain index numbers should be discouraged.

Jim Ahlstrom