We've all had the problem which prompted this howto. You're listening to some music and you want it louder so you turn up the volume on XMMS until it is at full but things still aren't quite loud enough so you reach over and crank up the volume on the amp. That's better. All of a sudden a friend signs into MSN and GAIM makes the loudest trumpeting noise you've ever heard!
Well I got sick of this the other day and decided to see what could be done about it. After checking the ALSA documentation, epsecially the section regarding plugins, I knocked up the following asound.conf.
I'll try to walk you through it so that people with little understanding of ALSA can follow along. I'll give a complete version of the asound.conf file at the end too if you just want to cut'n'paste.
I'll assume that you currently have ALSA working for your card. By working I mean that you can play more than one sound at a time using either hardware of software mixing. There are more than enough ALSA guides out there to get you to this point.
Output Devices
The first step is to define any output devices. Here just one is created (called output_main) which is a dmix (software mixing) device sending its output to the first device on the first card. If you have additional sound output devices (such as USB headsets or another sound card) then you will need to define additional devices for those cards with the appropriate hw:X,Y (hw:1,0 being the second device, etc) lines.
Code: Select all
pcm.output_main
{
type dmix
ipc_key 1024
ipc_perm 0666
slave
{
pcm "hw:0,0"
period_time 0
period_size 1024
buffer_size 8192
}
}Input Devices
Next we must define any input devices. Here we define two input devices. The first uses hw:0,0 while the second uses hw:1,0 - which in my case is a USB microphone. If you have a headset then you will need to define an additional output device as described above.
Code: Select all
pcm.input_mic
{
type dsnoop
ipc_key 2048
slave.pcm "hw:0,0"
}
pcm.input_usbmic
{
type dsnoop
ipc_key 2049
slave.pcm "hw:1,0"
}Asym Devices
Sometimes it is handy to be able to map different input and output devices to different pcm plugs. In my setup I want the main input (in this case line-in) to be used for some capturing but my USB microphone to be used for others. Below is an example of two asym devices used for exactly that. The first uses the main input and output, the second uses the main output and the USB input.
Code: Select all
pcm.asym_main_mic
{
type asym
playback.pcm "output_main_control"
capture.pcm "input_mic"
}
pcm.asym_main_usbmic
{
type asym
playback.pcm "output_main_control"
capture.pcm "input_usbmic"
}Volume Controls
Firstly we need to define a volume control which we will use to control the overall output volume. Those paying extra close attention will see that we have used it as the output device above and I never mentioned it.
Code: Select all
pcm.output_main_control
{
type softvol
slave.pcm "output_main"
control
{
name "All"
card 0
}
}
pcm.default_control
{
type softvol
slave.pcm "asym_main_mic"
control
{
name "Unassigned"
card 0
}
}Code: Select all
pcm.music_control
{
type softvol
slave.pcm "output_main_control"
control
{
name "Music"
card 0
}
}
pcm.film_control
{
type softvol
slave.pcm "output_main_control"
control
{
name "Film"
card 0
}
}
pcm.gaim_control
{
type softvol
slave.pcm "asym_main_usbmic"
control
{
name "GAIM"
card 0
}
}
pcm.system_control
{
type softvol
slave.pcm "asym_main_mic"
control
{
name "System"
card 0
}
}You would imagine that this would probably be the end of things. I certainly did when I tried it the first time. To my surprise nothing could output to any of the volume controls. This, it turns out, is because the sample rate trickles upwards from the hardware to the top device layer and nothing we have created so far supports sample rate conversion. That is the job of the plug device. So lets create some plug devices already.
Plug Devices
First things first, lets create some defaults. These will be used by any ALSA programs unless something else is specified in their config. If anyone knows the difference between these and why they seem to both be needed I'd love to know.
Code: Select all
pcm.!default
{
type plug
slave.pcm "default_control"
}
pcm.default
{
type plug
slave.pcm "default_control"
}Next we create all the plug devices to connect to for our specific classes of application.
Code: Select all
pcm.music
{
type plug
slave.pcm "music_control"
}
pcm.film
{
type plug
slave.pcm "film_control"
}
pcm.gaim
{
type plug
slave.pcm "gaim_control"
}
pcm.system
{
type plug
slave.pcm "system_control"
}Changes as of alsa-lib-1.0.11
Well, that used to be it. All that was required was a restart of alsa. For some reason since the release of alsa-lib-1.0.11 some more work is required.
To make the mixer devices available you need to run the following commands, modified for the devices you have created of course.
Code: Select all
aplay /path/to/a.wav -Dfilm
aplay /path/to/a.wav -Dgaim
aplay /path/to/a.wav -Dsystem
aplay /path/to/a.wav -Dmusic
aplay /path/to/a.wavAll we have to do now is configure our ALSA applications to use the new plug devices. Thankfully this is fairly easy. I'll give a brief description below for anyone who doesn't know how.
Gnome
This is easy if you use the ESD sound server. If you do then you just need to modify your /etc/esd/esd.conf as below. The key portion is the -d system on the end of spawn_options. You can then check that it works using the test feature of the Multimedia Systems Selector. Don't forget to set it to use esound as the output type too.
Code: Select all
[esd]
auto_spawn=1
spawn_options=-terminate -nobeeps -as 1 -d system
spawn_wait_ms=100
# default options are used in spawned and non-spawned mode
default_options= -as 1XMMS
XMMS is easy. Just run it, open the options screen (Ctrl+P), go to Audio I/O plugins, select ALSA as the output plugin, click configure and enter music in the Audio device box. You can then use the Music mixer device (on Mixer card 0 unless you changed something) instead of a software volume control.
GAIM
GAIM is almost as easy as XMMS. Open the main window and then the options screen (again Ctrl+P), navigate to Sounds (under Interface) and select Command under Sound Method and enter "aplay -D gaim %s" - without the quotes obviously.
XINE
XINE is slightly more complex. You have to run it, obviously. Then click on the small spanner icon to bring up the setup screen. From there navigate to the Audio tab and enter "film" (without the quotes) into the boxes labeled "device used for mono output" and "device used for stereo output". I personally don't set the "sound card can do mmap" option but it works as far as I know.
Enjoy...
When you next fire up a mixer (after a reboot or a restart of alsasound) you should see the new mixer devices. Test them out and enjoy being able to have your system notifications at a reasonable volume even when listening to music. Being able to mute them while watching a film is nice too.
It is worth pointing out at this juncture that some mixer applications require you to select new mixer channels from some kind of menu in their preferences screen.
I hope some of you find this usefull. If you have any questions or comments I'd love to hear them.
Known issues
OSS devices do not play nicely with this configuration. For some reason the volume controls do nothing so all OSS sound is very loud. If anyone knows how to fix this I would be very pleased indeed to hear how. For now Skype is a PITA.
As noted by Jykke if you want to undo this you will have to follow some steps in the correct order.
1) Shutdown ALSA
2) Delete the mixer settings stored in /etc/asound.state
3) Remove the custom /etc/asound.conf
4) Start ALSA
The ALSA init scripts save the mixer settings to /etc/asound.state on shutdown so deleting it first will not work.
EDIT: I just realised that the default device is set to use the asym devices directly so it is VERY loud. Scared me half to death. I've fixed that now so there is a seperate slider for Unassigned output.


