LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   Ordered sound devices (http://www.linuxquestions.org/questions/slackware-14/ordered-sound-devices-701361/)

funkynesh 01-31-2009 10:43 PM

Ordered sound devices
 
Hello,

I am having trouble ordering my sound devices. Usually, I modify the /etc/modprobe.d/sound and put the correct indexes for each of my sound devices but this time it doesn't work.

This time I have two devices that use the same module and I don't know how I can differentiate between them.

I always get the USB as the first card no matter how I tweak my sound file.

Any ideas, how I can fix that?

I think the only way to do that id to write a udev rule, but I am unsure how to do that. In which file do I have to put that new rule if that is the case.

Thank you for your help.

Output of /proc/asound/cards
Code:

0 [U0x46d0x8c5    ]: USB-Audio - USB Device 0x46d:0x8c5
                      USB Device 0x46d:0x8c5 at usb-0000:00:0b.1-7, high speed
 1 [NVidia        ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xefff4000 irq 21
 2 [HDMI          ]: HDA-Intel - HDA ATI HDMI
                      HDA ATI HDMI at 0xefdfc000 irq 16

Output of /proc/asound/modules:
Code:

0 snd_usb_audio
 1 snd_hda_intel
 2 snd_hda_intel

Output of /etc/modprobe.d/sound
Code:

alias snd-card-0 snd-hda-intel
alias snd-card-1 snd-hda-intel
alias snd-card-2 snd-usb-audio
options snd-card-0 index=0
options snd-card-1 index=1
options snd-card-2 index=2


DavidHindman 02-01-2009 11:33 AM

I don't have the answer, but this is an excellent question. I guess it's time for us audio users to figure out how to write udev rules. So until a udev expert shows up and tells us the answer, let's dig in and look for a solution.

The problem is basically that when a system is started, the audio devices come up in a random order. The first one that's recognized is assigned to be the default audio device, even if it's the wrong one. This problem has been called "sound card roulette". People have been using stopgap methods to control the order in which multiple audio devices start up. This is a case where the usual stopgap methods fail.

This writeup seems like a logical starting point for understanding udev rules:

http://reactivated.net/writing_udev_rules.html

The udev rules are in /etc/udev.

I don't understand it yet, but here is an article from the ALSA wiki on writing udev rules:

http://alsa.opensrc.org/index.php/Udev

@funkynesh - what kind of audio devices are you working with?

DavidHindman 02-01-2009 03:33 PM

Okay, googling and consulting the man page for udev reveals that there are two sets of udev rules to work with.

The default rule set is in /lib/udev/rules.d/

The custom rule set is in /etc/udev/rules.d/

I think the idea is that first all the default rule files are merged, then all the custom rules are merged (with the custom rules overriding the default rules of the same name).

There is a default ALSA rule file named 40-alsa.rules in /lib/udev/rules.d/:

Code:

# do not edit this file, it will be overwritten on update

KERNEL=="controlC[0-9]*",      NAME="snd/%k"
KERNEL=="hwC[D0-9]*",          NAME="snd/%k"
KERNEL=="pcmC[D0-9cp]*",        NAME="snd/%k"
KERNEL=="midiC[D0-9]*",        NAME="snd/%k"
KERNEL=="timer",                NAME="snd/%k"
KERNEL=="seq",                  NAME="snd/%k"
KERNEL=="mixer0",              SYMLINK+="mixer"
KERNEL=="dsp0",                SYMLINK+="dsp"
KERNEL=="audio0",              SYMLINK+="audio"

So I'm guessing that we'll need to override this with a custom ALSA rule file named 40-alsa.rules, placing it in the directory /etc/udev/rules.d

I also guess that the nature of the custom ALSA rules will be to recognize each audio device and assign it the desired device name, i.e., /dev/dsp for the first device, /dev/dsp1 for the second, etc.

DavidHindman 02-02-2009 02:29 AM

Here's something that seems to work on my system. I put the following into /etc/udev/rules.d/40-alsa.rules:
Code:

# The USB sound device will create:
#  /dev/snd/controlCx
#  /dev/snd/hwCxD0
#  /dev/snd/pcmCxD0c
#  /dev/snd/pcmCxD0p

# The non-USB sound device will create:
#  /dev/snd/controlCx
#  /dev/snd/pcmCxD0c
#  /dev/snd/pcmCxD0p
#  /dev/snd/pcmCxD1c

# This block of rules recognizes the devices that are being
# created for the USB sound card and renames them to be
# for ALSA card 1
SUBSYSTEMS=="usb", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3040", KERNEL=="controlC?", NAME="snd/controlC1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3040", KERNEL=="hwC?D0", NAME="snd/hwC1D0"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3040", KERNEL=="pcmC?D0c", NAME="snd/pcmC1D0c"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3040", KERNEL=="pcmC?D0p", NAME="snd/pcmC1D0p"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3040", KERNEL=="pcmC?D1c", NAME="snd/pcmC1D1c"

# This block of rules recognizes the devices that are being
# created for the PCI sound card and renames them to be
# for ALSA card 0
KERNELS=="0000:00:1f.5", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x2485", KERNEL=="controlC?", NAME="snd/controlC0"
KERNELS=="0000:00:1f.5", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x2485", KERNEL=="hwC?D0", NAME="snd/hwC0D0"
KERNELS=="0000:00:1f.5", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x2485", KERNEL=="pcmC?D0c", NAME="snd/pcmC0D0c"
KERNELS=="0000:00:1f.5", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x2485", KERNEL=="pcmC?D0p", NAME="snd/pcmC0D0p"
KERNELS=="0000:00:1f.5", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x2485", KERNEL=="pcmC?D1c", NAME="snd/pcmC0D1c"


# I'm not sure exactly what this block of rules does,
# I just brought it over from the default udev rules
# for ALSA devices
KERNEL=="timer", NAME="snd/%k"
KERNEL=="seq", NAME="snd/%k"
KERNEL=="mixer0", SYMLINK+="mixer"
KERNEL=="dsp0", SYMLINK+="dsp"
KERNEL=="audio0", SYMLINK+="audio"

What normally happens with the default rules is that ALSA creates audio devices in /dev/snd. They have names like pcmC0D0p, where the C0 means it's for ALSA card 0. The new custom udev rules intercept those device names and force them to be what we want. In this case, the USB audio device is forced by the renaming to be ALSA channel 1 and the PCI audio device is similarly forced to be channel 0.

This is probably enough to get you going. It's a very similar approach to what was given in the "Simple Udev Rules" section of the ALSA wiki referenced above, except that the rules don't key off the driver name.

Edit to add: This is for Slackware 12.2. I think udev may have been significantly reorganized for 12.2, so this solution may require changes to work with previous versions.

tpreitzel 02-03-2009 01:49 AM

ALSA Configuration is a Mess
 
I even wrote an e-mail to the ALSA users mailing list on this topic and Jaroslav responded that the task of configuring ALSA lies with the various distributions. ALSA can be ordered, but it takes far too much time for most users to solve. Here's my file, sound, in /etc/modprobe.d . HTH you arrive at a workable solution... Pay close attention to how the snd-usb-audio devices are ordered.


Code:


# ALSA portion
alias char-major-116 snd
alias snd-card-0 snd-via82xx
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
alias snd-card-5 snd-usb-audio
alias snd-card-6 snd-virmidi
options snd major=116 cards_limit=7
options snd-via82xx index=0
options snd-usb-audio index=1,2,3,4,5 vid=0x041e,0x045e,0x046d pid=0x4063,0x00f8,0x09c1
options snd-virmidi index=6 midi_devs=4
# OSS/Free portion
alias char-major-14 soundcore
alias sound-slot-0 snd-card-0
alias sound-slot-1 snd-card-1
alias sound-slot-2 snd-card-2
alias sound-slot-3 snd-card-3
alias sound-slot-4 snd-card-4
alias sound-slot-5 snd-card-5
alias sound-slot-6 snd-card-6
# Card #0 (snd-via82xx)
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
# 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-12 snd-pcm-oss
# Card #2
alias sound-service-2-0 snd-mixer-oss
alias sound-service-2-1 snd-seq-oss
alias sound-service-2-3 snd-pcm-oss
alias sound-service-2-12 snd-pcm-oss
# Card #3
alias sound-service-3-0 snd-mixer-oss
alias sound-service-3-1 snd-seq-oss
alias sound-service-3-3 snd-pcm-oss
alias sound-service-3-12 snd-pcm-oss
# Card #4
alias sound-service-4-0 snd-mixer-oss
alias sound-service-4-1 snd-seq-oss
alias sound-service-4-3 snd-pcm-oss
alias sound-service-4-12 snd-pcm-oss
# Card #5
alias sound-service-5-0 snd-mixer-oss
alias sound-service-5-1 snd-seq-oss
alias sound-service-5-3 snd-pcm-oss
alias sound-service-5-12 snd-pcm-oss
# Card #6 (snd-virmidi)


DavidHindman 02-03-2009 09:05 AM

I think there's an even simpler way for the original poster to select his desired default audio device.

Even though the OP has two audio devices using the same driver, all his audio devices have different ID strings (U0x46d0x8c5, NVidia, or HDMI). So they can be differentiated by ID string and the default can be selected in an ~/.asoundrc file.

In the user's home directory create the file ~/.asoundrc as follows:

Code:

pcm.!default {
 type hw
 card HDMI
}

ctl.!default {
 type hw
 card HDMI
}

The OP could replace HDMI with U0x46d0x8c5 or NVidia depending on which device he wants to be the ALSA default.

For Slackware, it could be put into /etc/asound.conf to make it effective for all users.

This isn't a universal solution, but it sure is simpler than messing with udev or modprobe. It works when the desired default device has a unique ID string.

funkynesh 02-03-2009 10:31 PM

Wow!

I quickly browsed the replies and there is a lot of precious information in here. :)

I managed to fix my problem by discovering that I could assign several indexes to the same driver in /etc/modprobe.d/sound. It isn't perfect, but so far it works.

Code:

options snd-hda-intel index=0,1
options snd-usb-audio index=2

I think I am going to carefully read this thread and next time I'll fix it properly. ;)

I am definitely going to bookmark that thread. Thank you all!

DavidHindman 02-04-2009 04:55 PM

Agreed, it's been a challenge to learn about ALSA configuration. I think the fundamental problem is very simple: sound devices don't have unique serial numbers.

Anyway, it seems we all have pieces of the answer. Here's my attempt to consolidate them into a systematic approach to ALSA sound device ordering in Slackware 12.2.

1 - Start up the system and do cat /proc/asound/cards

2 - If all the sound devices have been autodetected AND the desired default sound device has a unique ID string, then you can use ~/.asoundrc or /etc/asound.conf to select the right default sound device. If all you need to do is select the right default device, you're finished.

3 - If there are any sound devices which have not been autodetected OR if the .asoundrc approach didn't suffice, you need to configure an appropriate /etc/modprobe.d/sound

Everything you need to know about configuring /etc/modprobe.d/sound is in the following documentation file which probably came with your Slackware distro (at least this is its location in 12.2):

/usr/src/linux/Documentation/sound/alsa/ALSA-Configuration.txt

4 - Within /etc/modprobe.d/sound you can influence the sound device ordering by controlling the order in which the sound card drivers are loaded. If all the sound devices use different drivers, you're finished.

5 - If there are multiple sound devices which use the same driver, you can sometimes use the module options to order all the devices which share a driver. As shown in tpreitzel's example, the snd-usb-audio lets you order USB audio devices by vid (USB vendor ID) and pid (USB product ID). If you can distinguish all your sound devices by their drivers and module options in /etc/modprobe.d/sound, you're finished.

6 - This leaves the trickiest case, where there are multiple identical sound devices that need to be ordered. By identical, I mean devices that for example report the same USB vendor & product IDs. For this case, I think the udev approach is needed, because it can distinguish between sound devices based on their physical addresses on the USB or PCI buses.


All times are GMT -5. The time now is 02:41 AM.