MultipleCards

From the ALSA wiki

Jump to: navigation, search

Naming multiple audio devices has always been a hot issue, until recently. This article tries to clarify the recommended ways to use and name multiple devices.

Contents

[edit] Understanding Alsa naming

[edit] Single device

Originaly, Alsa was only able to name an audio device using the hw:x,y syntax, where x and y are numbers.

For example, if there is only one device installed, in most cases, the device should be named hw:0,0. When there is only one device, the device should always have the same name and numbers.

[edit] Multiple devices

A problem arises when there are multiple devices.

On modern GNU/Linux systems, udev takes care of discovering hardware and loading/unloading Alsa. There is one drawback to udev. Udev will load Alsa modules in an undefined order. After each reboot or plugging/unplugging a device, there is no guarantee that a device is renamed using the same hw:x,y numbers. For example, if you have two USB devices on your systems, for example an Audeon USB and an Edirol UA-25, after each reboot, a card can be "hw:0,0" and the other "hw:1,0", each time randomly.

[edit] Recommended solution

The recommended solution, at user software level, is to stop naming Alsa devices using numbers, and use the real name of devices. Doing a aplay -l dislays a list of PLAYBACK Hardware Devices. For example, on my system:

$aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: UA25 [EDIROL UA-25], device 0: USB Audio [USB Audio]
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 1: Audio [USB Audio], device 0: USB Audio [USB Audio]
 Subdevices: 1/1
 Subdevice #0: subdevice #0

In this example the audio devices are named "UA25" and "Audio".

[edit] Example commands and options for selecting sound cards:

Note options: -d device | device_alias -- Please see man aplay and man alsaplayer for an explanation of the options.

  • These two commands play the ogg on card 0 -- the ens1371 card:

alsaplayer -o alsa -d UA25  some_k00!.ogg
alsaplayer -o alsa -d hw:0,0  some_k00!.ogg

[edit] Feature lacking in Alsa

Even when naming devices using their names, there is still a feature lacking in Alsa: the naming of multiple identical devices. For example, in the previous example, if you have two Aureon cards, you cannot be sure to name the correct device on each reboot or plugin-unplingin. Let us be sure that the Alsa developers are going to fix this issue quickly, because it is a very simple need, and it should have been fixed for years.

[edit] The old way to handle these problems

This text should remain on the wiki until the group of wiki writers uptades the text to clarify Alsa recommended solutions. In my opinion, these solutions do not reflect the Udev modern way to handle modules and them in an udefined order.

[edit] How to choose a particular order for multiple installed cards

Which card is card number 0, 1 and so is by default determined by module load order. This is particularly useful to choose which card becomes the default one.

In theory therefore it is possible to choose which of several installed cards becomes card 0, the default one, by ensure its driver module is loaded first.

However this is in practice difficult to achieve. The only reliable method is to set the card number explicitly by setting the index= parameter of the driver module. To ensure reliable results it must be set for all drivers that get loaded. E.g. if the card supported by snd_hda_intel module is supposed to become card3:

 $modprobe snd_hda_intel index=3

If you set index=0 on one driver module, another driver module might get loaded first and become card number 0 regardless. But if you load two driver modules and one has index=0 and the other has index=1, they will take the respective positions no matter in which order they are loaded.

The 'snd' module also has an option that leads to predictable naming. You can give the names of the modules that are supposed to use each index, thereby reserving respective slots (card numbers). E.g. if the card supported by snd_hda_intel module is supposed to become card0:

 $modprobe snd slots=snd_hda_intel

If any other module is loaded first, it will use 'unreserved' slots starting from card1.

Usually this configuration should be written into some file under /etc/modprobe.d, e.g. /etc/modprobe.d/sound:

 options snd slots=snd_hda_intel
 alias snd-card-0 snd_hda_intel

[edit] Loading the kernel modules for multiple cards

Frank Barknecht offered this dual card configuration example to the alsa-devel mailing-list.

See TwoCardsAsOne for an idea for setting up an .asoundrc to use two cards together. Read chapter below (a code fix).

# START
alias char-major-116 snd
alias char-major-14 soundcore
options snd snd_major=116 snd_cards_limit=3 snd_device_mode=0660 snd_device_gid=29 snd_device_uid=0

# Midiman
alias sound-slot-0 snd-card-0
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-osshree 

# SBLive
alias sound-slot-1 snd-card-1
alias sound-service-1-0 snd-mixer-oss
#alias sound-service-1-1 snd-seq-oss
alias sound-service-1-3 snd-pcm-oss
#alias sound-service-1-8 snd-seq-oss
alias sound-service-1-12 snd-pcm-oss

# VirMIDI
alias sound-slot-2 snd-card-2
#alias sound-service-2-1 snd-seq-oss
#alias sound-service-2-8 snd-seq-oss

#alias snd-card-0 snd-card-ice1712
alias snd-card-0 snd-ice1712
options snd-card-ice1712 snd_index=0 snd_enable

#alias snd-card-1 snd-card-emu10k1
alias snd-card-1 snd-emu10k1
options snd-card-emu10k1 snd_enable

#alias snd-card-2 snd-card-virmidi
alias snd-card-2 snd-virmidi

post-install snd-synth-emu10k1 /usr/bin/sfxload /dos/audio/sblive/SFBank/8mbgmsfx.sf2
# END

[edit] Why doesn't this code work when using newer ALSA versions?

The syntax for the module options has changed. Now you have to write all options without the leading snd_. Example: only index=0 instead of snd_index=0.

Stephan Wurm

[edit] Multiple Sound Cards -- Example on Debian GNU/Linux

RE: How do I use this?

Lines such as found in the multiple sound card configuration example from Frank Barknecht above must finally be entered in a configuration file for modprobe (/lib/modules/modprobe.conf, see man modprobe.conf) so the boot/init process can use it. The process of building the configuration in modprobe.conf differs somewhat from distribution to distribution and, perhaps, also from the 2.4.* to 2.6.* kernels. With Debian GNU/Linux sid/unstable and kernel 2.6.4-rc2 the component configurations to be included in modprobe.conf are found in several files in /etc/modprobe.d:

jkern@boat:~$ ls -l /etc/modprobe.d
total 20
-rw-r--r--    1 root     root         5610 2004-01-30 18:04 aliases
lrwxr-xr-x    1 root     root           22 2004-02-02 00:07 alsa -> /etc/alsa/modutils/1.0
drwxr-xr-x    2 root     root         4096 2004-02-23 09:51 arch
-rw-r--r--    1 root     root          363 2003-02-25 06:57 crypto
-rw-r--r--    1 root     root           29 2003-12-20 17:15 nvidia-kernel-nkc

On this Debian system the /etc/modprobe.d/alsa is a symbolic link to /etc/alsa/modutils/1.0 wherein I have entered commands for two cards, as adapted from Frank Barknecht's configuration above:

jkern@boat:~$ cat /etc/alsa/modutils/1.0

alias char-major-116 snd
alias char-major-14 soundcore

options snd major=116 cards_limit=4

# Sound card 0 -- PCI adapter: ens1371 
# /lib/modules/2.6.4-rc2/kernel/sound/pci/snd-ens1371.ko

alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
alias /dev/dsp0 snd-pcm-oss

alias snd-card-0 snd-ens1371

alias snd-slot-0 snd-card-0
alias sound-slot-0 snd-slot-0

# Sound card 1 -- VIA motherboard sound chip: via82xx
# /lib/modules/2.6.4-rc2/kernel/sound/pci/snd-via82xx.ko

alias sound-service-1-0 snd-mixer-oss
alias sound-service-1-1 snd-seq-oss
alias sound-service-1-3 snd-pcm-oss
alias sound-service-1-8 snd-seq-oss
alias sound-service-1-12 snd-pcm-oss
alias /dev/dsp1 snd-pcm-oss

alias snd-card-1 snd-via82xx

alias snd-slot-1 snd-card-1
alias sound-slot-1 snd-slot-1

# End /etc/alsa/modutils/1.0

After editing /etc/alsa/modutils/1.0, I then run, on this Debian system, /sbin/update-modules, which updates /lib/modules/modprobe.conf to make it ready for the boot/init process. Other GNU/Linux distributions probably have a similiar utility. The aliases are merged with with all the others as specified in the files in the /etc/modprobe.d/ directory. (Please take a look at /lib/modules/modprobe.conf.)

The kernel must be configured to build ALSA modules and also the modules for your specific sound cards. In this example system the specified modules for the two sound cards are thus:

jkern@boat:~$ grep -i "via82xx\|ens1371" /boot/config-2.6.4-rc2
CONFIG_SND_ENS1371=m
CONFIG_SND_VIA82XX=m

After the kernel is installed, these modules are found in /lib/modules/2.6.4-rc2/kernel/sound/pci/:

jkern@boat:~$ ls /lib/modules/2.6.4-rc2/kernel/sound/pci/snd* 
/lib/modules/2.6.4-rc2/kernel/sound/pci/snd-ens1371.ko
/lib/modules/2.6.4-rc2/kernel/sound/pci/snd-via82xx.ko

One can see how these modules correspond to the aliases above in /etc/alsa/modutils/1.0.

On a Debian GNU/Linux system the ALSA modules are all loaded from a script, /etc/init.d/alsa, as part of the system initialization. Doing a lsmod will show all the modules loaded on your system.

[edit] RE: How do I select one card or the other?

Doing a aplay -l dislays a list of PLAYBACK Hardware Devices. An ~/.asoundrc is useful for (among other things) making handy aliases for each sound card. A simple one could look like the following for this system:

# Start ~/.asoundrc
pcm.ens1371 { type  hw  card 0 }
ctl.ens1371 { type  hw  card 0 }
pcm.via82xx { type  hw  card 1 }
ctl.via82xx { type  hw  card 1 }
# End ~/.asoundrc

[edit] Example commands and options for selecting sound cards:

Note options: -d device | device_alias -- Please see man aplay and man alsaplayer for an explanation of the options.

  • These two commands play the ogg on card 0 -- the ens1371 card:

alsaplayer -o alsa -d ens1371  some_k00!.ogg
alsaplayer -o alsa -d hw:0,0  some_k00!.ogg

  • These commands play the sound files on card 1 -- the via82xx card:

alsaplayer -o alsa -d via82xx  some_k00!.ogg
alsaplayer -o alsa -d hw:1,0  some_k00!.ogg
aplay -o alsa -Dplug:via82xx  very_r00d.wav

  • Mixer control commands:

/usr/bin/alsamixer -c 1     # will control card 1 -- the via82xx card.  
/usr/bin/gamix              # or
/usr/bin/gnome-alsamixer    # will provide separate mixer controls for each sound card.

  • Choosing card for SDL apps:

AUDIODEV="via82xx" mySDLapp

These capabilities are the results of the configurations found in /lib/modules/modprobe.conf and ~/.asoundrc.

As an alternative modprobe.conf configuration method, the shell script, /usr/sbin/alsaconf (man alsaconf), may or may not work on your system. If it does, it probably saves a bit of work; otherwise, you now know what to do instead. alsaconf strives to be able to set up sound cards for ALSA on all the varieties of GNU/Linux distributions.

N.B. Please remember that several of the specific examples are for a Debian GNU/Linux sid/unstable system with a 2.6.* kernel. Counterparts to these scripts and configuration files should be found on any GNU/Linux distribution.

[edit] Multiple USB Audio Devices

See also: MultipleUSBAudioDevices and Udev

I am using Debian SID and found a very simple solution: I edited the etc/modules document in which the admin can load Modules on boot. First entry is the card you want to be the card 0 and second the Modules for the second card, so you can set the module load order. That's it.

  • I am not sure if that is true, because dependencies are calculated and system COULD still load modules in wrong order. However, in etc/modules it is also possible to add parameters, so you could append "index=n" to a module name.

[edit] I have all my stuff statically compiled into the kernel

I have all my stuff statically compiled into the kernel, so is there a way to change the order of my cards without using modules?

I found this in mailing list. This was put in linux boot row (in boot loader config file). I do not test this. This should setup via8233 as firs and midi port as second soundcard.

snd-via82xx.index=0 snd-mpu401.index=1 snd-mpu401.port=0x330 snd-mpu401.irq=10

Answer:

OK, thanks, this was easy. For the sake of completeness, here's the relevant part of my menu.lst (grub config file)

title           Debian kernel 2.6.14.3
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.14.3 root=/dev/hda1 ro snd-emu10k1.index=0 snd-intel8x0.index=1
savedefault
boot

I have two cards, a Creative SBLive 5.1 (snd-emu10k1) and a onboard Intel AC97 (snd-intel8x0). With this, the SBLive becomes card0 and the AC97 card1.

[edit] Easy way to do this on Ubuntu Dapper

  1. run sudo nano -w /etc/modprobe.d/alsa-base to edit your alsa config, from a terminal.
  2. change the the appropriate sound-slot-[x] modprobe snd-card-[y] to match your desired order. i.e. if card 0 and card 1 are in reverse order from what you would like, make the following edit:

install sound-slot-0 modprobe snd-card-1
install sound-slot-1 modprobe snd-card-0

[edit] Easy way to do this on Ubuntu Edgy

Since the above advice for Ubuntu Dapper didn't work for me this is what I did:

  1. run sudo nano -w /etc/modprobe.d/alsa-base to edit your alsa config, from a terminal.
  2. then I added the following at the end of the file and left the rest intact:

options snd-intel8x0 index=-2
options snd-cs46xx index=-1

Which made the Hercules Fortissimo II (snd-cs46xx) the default sound adapter and also made the onboard NFORCE2 (snd-intel8x0) the secondary sound adapter.

[edit] I have a m-audio keystation connected via usb, and it hogs

Question:

I have a m-audio keystation connected via usb, and it hogs, if connected while drivers are loaded via modprobe.conf, card0 regardless of how the index is configured... which isn't bad by itself as aconnect -i only displays

client 16: 'USB Keystation 61es' [type=kernel]
    0 'USB Keystation 61es MIDI 1'

if it's card0. This seems to be a "known" problem... at least I read it somewhere.

The problem I'm facing is that if the keyboard isn't plugged while drivers are loaded, my soundcard switches from card1 to card0, rendering all configuration obsolete.

gentoo modules.conf:

alias snd-card-0 snd-usb-audio
alias snd-card-1 snd-via82xx
alias sound-slot-0 snd-card-0
alias sound-slot-1 snd-card-1

 options snd-via82xx snd_index=1

snd_index=1 or index=1 doesn't make a difference.

linux 2.6.17-gentoo-r4 (alsa 1.0.11rc4)

Suggestion: Try using index=-2, this should solve the problem.

[edit] See also

Personal tools