Tuesday, February 19, 2008

Linux (Ubuntu Gutsy) Firefox, Flash, Alsa, and a bullet to the head.

I am determined to get my Ubuntu install to behave as well as windows. The one thing that has annoyed me the most is the seeming inability to have multiple applications play audio at once. If you have played any flash with audio in the last hour it seems firefox is incapable of releasing the audio card. You have to quit firefox to free it back up, or you have to quite another application to free up the sound for the page you are trying to view.

I played with PulseAudio, and it is OK. Honestly I found it to be more trouble than it was worth. All I want is to play audio from multiple apps at once, and many apps have no support for pulseaudio, and I could never get it to behave very well anyway. So I needed something else.

I finally decided to check out alsa, and I discovered it could do everything I wanted. It's an amazingly versatile tool once you dive into it a little bit. So first order of business was to fix this whole flash nonsense.

In case you don't have it:
$sudo apt-get install alsa-oss

This will get the compatability layer for oss. Everything does oss, even if it does not do alsa. So this is a no-brainer. We will let firefox think it is using OSS and we will just pipe that to alsa.

Now the trick to ALSA it turns out is setting up your ~/.asoundrc file. I'm still outrageously noob at this, and the documentation is, as expected, abysmal. But I have managed to put this much together.

First I want to have all my apps be able to make sounds simultaneously. We can do that with alsa using "dmix" which is the alsa software mixer. I have some intel 5.1 sound in my machine (from the motherboard) so I decided to stick with that.

A good way to figure out what is going on with your sound is the "aplay" command.
$aplay -l
$aplay -L

Will list out the details of your sound card as alsa understands it. My intel card is card 0, so now I:
$vi ~/.asoundrc

I want a mixer so I set up the following sections:

pcm.dmix51 {
type dmix
ipc_key 1024
slave {
pcm "hw:0,0"
channels 6
period_time 0
period_size 1024
buffer_size 8192
rate 48000
}
}

ctl.dmix51 {
type hw
card 0
}

Ok, so what we just did was create a software ALSA mixer and associated it with the sound card at "hw:0,0". We can test it in mplayer using:
$mplayer somefile -ao alsa:device=plug=dmix51
or
$speaker-test -Dplug:dmix51 -c6 -twav

From this I get sound. The speaker-test program actually will send sound to each speaker in your 5.1 setup with a girl saying which channel she expects to be in, making sure you have it right.

Since this is a software mixer you should now be able to use sound from lots of programs through the alsa/dmix51 plug-in. Now we just need to get stuff to use it.

So we have 2 problems now. We want to make the default ALSA device our software mixer, and we want to make firefox use it through the oss layer. Luckily both are now very easy. Open up the ~/.asoundrc file if you closed it. We need to add 2 more sections.

To make the default for every program using alsa to be using your mixer, add the following:

pcm.!default {
type plug
slave.pcm "dmix51"
}

Software looks to this !default tag if no specific device is given ("mplayer -ao alsa" will use this; "mplayer -ao alsa:device=plug=default" will also). So all we do is make a dummy !default plug pointing to our mixer.

The alsa-oss plug defaults to "dsp0", so we need to set up a dummy for that too:

pcm.dsp0 {
type plug
slave.pcm "dmix51"
}

Now we save the file and exit. I then went to the desktop. System->Preferences->Sound. In the "Devices" tab I changed everything to "ALSA". In the "Sounds" tab I disabled "ESD". I continued to have problems so I rebooted at this point.

Upon reboot I changed the firefox launcher command from "firefox" to "aoss firefox" and wuala! Sound from flash. I then went to all my programs (amarok, mplayer, xine, ...) and changed them all to use ALSA for sound output. Now I can have more programs making sound than I could want.

In the future we all will be able to browse the web and listen to music at the same time!

No comments: