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