MyTetra Share
Делитесь знаниями!
Alsa
Время создания: 25.04.2013 21:41
Раздел: root - Linux
Запись: Yurons/mytetra/master/base/1366915262jolwb997o2/text.html на raw.github.com

.asoundrc

 


 

cat /etc/asound.conf

pcm.usb

{

type hw

card C170

}

 

pcm.!default

{

type asym

playback.pcm

{

type plug

slave.pcm "dmix"

}

capture.pcm

{

type plug

slave.pcm "usb"

}

}


 

Sometime a need comes to test microphone for use with VOIP applications such us Skype. The simplest and easiest way to test microphone ( MIC ) on your linux system is to use default alsa tools which come with alsa sound system package. First we need to check if alsa had recognized and our sound device.

 

1. List of sound devices

$ cat /proc/asound/cards

0 [NVidia ]: HDA-Intel - HDA NVidia

HDA NVidia at 0xefff0000 irq 20

 

you may get bunch of devices but we are interested in the one which seems to familiar to you or the one which has IRQ. Another command to use to check which sound devices are recognized by your alsa system is arecord -l:

$ arecord -l

**** List of CAPTURE Hardware Devices ****

card 0: NVidia [HDA NVidia], device 0: AD198x Analog

[AD198x Analog]

Subdevices: 3/3

Subdevice #0: subdevice #0

Subdevice #1: subdevice #1

Subdevice #2: subdevice #2

2. Test MIC

 

to test microphone we would used arecord on the command line. This small utility will record sound from your default alsa default sound device. No special arguments as device name are not required since we I have only one sound card.

$ arecord -d 10 /tmp/test-mic.wav

 

this will record 10 seconds.

3. Play test-mic.wav

 

Now it is easy to play your wav file with another simple alsa utility a play:

$ aplay /tmp/test-mic.wav

 

NOTE:

If you have a more sound devices on your system and you need to use the non default sound card you can specify it to arecord with -D option. For example:

$ arecord hw:1,0 -d 10 /tmp/test-mic.wav

 

will use second sound card where 1 refers to card and 0 refers to device as returned by arecord -l command. If you want to change your default alsa sound device globally on the system here is a link to unofficial alsa wiki which you might find helpful:

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

 

 


 

Alsa: multiple output, multiple sound cards, multiple users

I had some difficulties setting up alsa as I wanted, because I encountered some troubles:

when more than one application was playing sound, the first one played nicely but the others wasn't playing at all, complaining about a "busy resource"

solved this one, I had to setup the whole thing to work with two sound cards at the same time

eventually, I wanted to enable concurrent sound for multiple users

Alsa Wiki's guides were useful only for a few things, but none of them gave me the whole solution. So after a deep digging, I ended up with this config:

pcm.USBmic {

type hw

card CNF8215

}

 

ctl.USBmic {

type hw

card CNF8215

}

 

pcm.internal {

type hw

card SB

}

 

ctl.internal {

type hw

card SB

}

 

pcm.wireless {

type hw

card Transceiver

}

 

ctl.wireless {

type hw

card Transceiver

}

 

pcm.internalDmixed {

type dmix

ipc_key 1024

ipc_key_add_uid false

ipc_perm 0666

slave {

pcm "internal"

period_time 0

period_size 2048

channels 4

}

bindings {

0 0

1 1

2 2

3 3

}

}

 

pcm.wirelessDmixed {

type dmix

ipc_key 2048

ipc_key_add_uid false

ipc_perm 0666

slave {

pcm "wireless"

period_time 0

period_size 2048

channels 2

}

bindings {

0 0

1 1

}

}

 

pcm.both {

type route;

slave.pcm {

type multi;

slaves.a.pcm "wirelessDmixed";

slaves.b.pcm "internalDmixed";

slaves.a.channels 2;

slaves.b.channels 4;

bindings.0.slave a;

bindings.0.channel 0;

bindings.1.slave a;

bindings.1.channel 1;

bindings.2.slave b;

bindings.2.channel 0;

bindings.3.slave b;

bindings.3.channel 1;

bindings.4.slave b;

bindings.4.channel 2;

bindings.5.slave b;

bindings.5.channel 3;

}

ttable.0.0 1;

ttable.1.1 1;

ttable.0.2 1;

ttable.1.3 1;

ttable.2.4 1;

ttable.3.5 1;

}

 

pcm.!default {

type plug

slave {

pcm both

}

}

 

ctl.!default {

type hw

card SB

}

 

How does this strange thing work? Let's look at it step by step:

 

 

Understanding which cards you want to use

 

To get your cards names, the easiest way is to use aplay -l command. When I execute it I get this output:

:~$ aplay -l

**** List of PLAYBACK Hardware Devices ****

card 0: Transceiver [2.4G Wireless Transceiver], device 0: USB Audio [USB Audio]

Subdevices: 0/1

Subdevice #0: subdevice #0

card 2: SB [HDA ATI SB], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]

Subdevices: 0/1

Subdevice #0: subdevice #0

card 2: SB [HDA ATI SB], device 1: ALC662 rev1 Digital [ALC662 rev1 Digital]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 3: HDMI [HDA ATI HDMI], device 3: HDMI 0 [HDMI 0]

Subdevices: 1/1

Subdevice #0: subdevice #0

If you use your card's name as reference for alsa is better, because it will always connect to the right card no matter what the cards' order is. Above the card names are the ones I bolded (yours will be different).

 

As you can see, I have a lot of devices here, but the ones I care about are the first two, Transceiver and SB. SB is the internal card, with four speakers plugged, and Transceiver is a USB wireless sound card, transmitting to two speakers in another room.

 

Setup basic pcms

 

Once you know your card's names, you have to setup basic hardware pcms and ctls. A pcm is an input/output device, and a ctl is a control for a device. So I wrote this:

pcm.USBmic {

type hw

card CNF8215

}

 

ctl.USBmic {

type hw

card CNF8215

}

 

pcm.internal {

type hw

card SB

}

 

ctl.internal {

type hw

card SB

}

 

pcm.wireless {

type hw

card Transceiver

}

 

ctl.wireless {

type hw

card Transceiver

}

As you can see there are one pcm and one ctl for each card I want to use, defined by type.devicename. So now if I want to output sound on my internal card I can use aplay -Dinternal sound.wav (thanks to pcm), and alsamixer -Dinternal to manage the volume only for that card (thanks to ctl).

 

Dmix: concurrent sound from more than one application

 

Now we have all this pcms, but we still have that resource busy error hanging around. How do we solve it? We setup a few more pcms:

pcm.internalDmixed {

type dmix

ipc_key 1024

ipc_key_add_uid false

ipc_perm 0666

slave {

pcm "internal"

period_time 0

period_size 2048

channels 4

}

bindings {

0 0

1 1

2 2

3 3

}

}

 

pcm.wirelessDmixed {

type dmix

ipc_key 2048

ipc_key_add_uid false

ipc_perm 0666

slave {

pcm "wireless"

period_time 0

period_size 2048

channels 2

}

bindings {

0 0

1 1

}

}

Here I define two more pcms, using the previously defined ones as slaves. In this way I can use dmix to mix various outputs channels and get rid of that awful resource busy error.

 

More than one user?

 

This one was hard to find but easy to apply. If you look at the two dmixed pcms you will see two lines, "ipc_key_add_uid false" and "ipc_perm 0666". The first one disables user id for the device (or so I suppose) and the second one sets permissions for the device. The two combined makes the device usable for more than one user at the same time.

 

Multiple outputs on multiple cards

 

And here comes the difficult part: getting these two cards to output concurrent sound. How to do it? Luckily I found a good article about it, and after trying and trying again I ended up merging everything together. The trick here is creating another pcm device, named "both", to merge the two dmixed devices:

 

pcm.both {

type route;

slave.pcm {

type multi;

slaves.a.pcm "wirelessDmixed";

slaves.b.pcm "internalDmixed";

slaves.a.channels 2;

slaves.b.channels 4;

bindings.0.slave a;

bindings.0.channel 0;

bindings.1.slave a;

bindings.1.channel 1;

bindings.2.slave b;

bindings.2.channel 0;

bindings.3.slave b;

bindings.3.channel 1;

bindings.4.slave b;

bindings.4.channel 2;

bindings.5.slave b;

bindings.5.channel 3;

}

ttable.0.0 1;

ttable.1.1 1;

ttable.0.2 1;

ttable.1.3 1;

ttable.2.4 1;

ttable.3.5 1;

}

Aaaand... it has surround too! You can try it using the command "speaker-test -c6 -D both -t wav". Here you define a 6-channel device, using the two channels of the first sound card as the first two channels (0-1) and the four channels of the second sound card as the last four channels (2-5). Then using ttable the four channels of the second sound card are copied to the first four channels, so we will have the same otput on the first card and at the same time on the two front speakers of the second card. The last two channels, front center and rear center, will not output sound ad all, but I didn't understand how to change this pcm into a 4-channel one (comments are welcome).

 

If all the 6 speakers were in the same room, I would have done something like this:

pcm.both {

type route;

slave.pcm {

type multi;

slaves.a.pcm "wirelessDmixed";

slaves.b.pcm "internalDmixed";

slaves.a.channels 2;

slaves.b.channels 4;

bindings.0.slave a;

bindings.0.channel 0;

bindings.1.slave a;

bindings.1.channel 1;

bindings.2.slave b;

bindings.2.channel 0;

bindings.3.slave b;

bindings.3.channel 1;

bindings.4.slave b;

bindings.4.channel 2;

bindings.5.slave b;

bindings.5.channel 3;

}

ttable.0.0 1;

ttable.1.1 1;

ttable.2.2 1;

ttable.3.3 1;

ttable.4.4 1;

ttable.5.5 1;

}

 

merging the 2 speakers on one card and 4 speakers on the other into an unique 6-channel setting.

 

Set the default output device

 

Ok, now that this monstrous multichannel stream-mixing device is ready, the last thing to do is set it as the default output device. Here it is:

pcm.!default {

type plug

slave {

pcm both

}

}

 

ctl.!default {

type hw

card SB

}

So simple that doesn't need explanation at all. The ctl here is a bit picky, so it is set to control the main hardware card. Now if you try "speaker-test -c4 -D default -t wav" you will be amazed by the result.

 

Making it work with Skype and Amarok 1.4

 

Skype is easy: just set your mic pcm as the input device (in my case, USBMic), and the default pcm as the output device.

 

Amarok doesn't like the default alsa device, but it's not so hard to fix. Just go in Settings > Configure Amarok > Engine, select xine-engine, select alsa as output plugin, select your speaker arrangment and then set all the fields in "ALSA Devices Configuration" to plug:both.

 

 

 

 

Here, done! :)

 

If you want one application to output sound only to one card, remember to use always the dmixed pcm and not the basic one, otherwise you will be stuck again with the resource busy error.

 

System-wide or single user config

 

To make this setting available for all users, just copy it into /etc/asound.conf (as root), otherwise you can write it into .asoundrc (in the home dir of one or more users), but I fear that the multiuser setting will result useless in this case.

 

To have the system-wide settings work, just restart alsa with /etc/rc.d/rc.alsa restart (as root). If you edited .asoundrc you have to logout and login again.

 


.asoundrc

Asoundrc

 

 

Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования