I like to have the option of playing music on my headphones or outputting to the stereo – it really improves family life when they don’t always have to hear my dubstep ;) Unfortunately, the sound cards and devices you have available don’t always fit together nicely. For Linux users, ALSA gives you a lot of control and flexibility over audio devices. However, it is usually difficult to figure out exactly what needs to be done to output to multiple audio devices.
In my case, I have an onboard audio device with optical digital out. But onboard audio usually receives a lot of noise from the rest of the components on the motherboard – your headphones buzz when a hard drive seeks or you move your mouse pointer. I have broad musical tastes and orchestras sound pretty awful with static in the background. By adding an old-school Creative Labs SoundBlaster Live card, I can get exceptional quality output for headphones.
What caused difficulty was getting audio output to both the onboard and SoundBlaster audio devices at the same time. By default, Linux applications will send audio directly to one specific device. All you need is a properly structured ~/.asoundrc
file to configure ALSA.
I had to do a bit of hunting on the web and some trial-and-error. No two configurations seem to be the same, and ALSA configuration can be a bit daunting. You have to get into the nitty gritty of each audio device to see exactly which inputs and outputs it provides. Then you determine which are connected to your stereo, headphones, etc. Take the time to completely read and understand the output of aplay -l
and aplay -L
– they make it much easier to get a handle on what devices are in your system. You’ll also want to use alsamixer
to change settings and may need to use iecset
to enable or disable digital outputs.
Once you have your devices figured out and know which output plays where, you instruct ALSA to duplicate the audio output to both of the sound cards. This is the configuration that worked for me (install in ~/.asoundrc
or /etc/asound.conf
) – the 2-channel settings are for the headphones (SoundBlaster Live) and the 4-channel settings are for the stereo (onboard optical out):
# duplicate audio to both devices pcm.!default plug:both ctl.!default { type hw card SB } pcm.both { type route; slave.pcm { type multi; slaves.a.pcm "sblive"; slaves.b.pcm "onboard"; 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; # front left ttable.1.3 1; # front right ttable.0.4 1; # copy front left to rear left ttable.1.5 1; # copy front right to rear right } ctl.both { type hw; card Live; } pcm.onboard { type dmix ipc_key 1024 slave { pcm "hw:0,1" period_time 0 period_size 2048 buffer_size 65536 buffer_time 0 periods 128 rate 48000 channels 4 } bindings { 0 0 1 1 2 2 3 3 } } pcm.sblive { type dmix ipc_key 2048 slave { pcm "hw:1,0" period_time 0 period_size 2048 buffer_size 65536 buffer_time 0 periods 128 rate 48000 channels 2 } bindings { 0 0 1 1 } } ctl.onboard { type hw card "SB" } ctl.sblive { type hw card "Live" }
Thanks for this info. With slight modifications, it helped me set up my multi output to speakers and a wireless headset. I first looked at http://www.alsa-project.org/main/index.php/Asoundrc but I couldn’t get it to work and also I didn’t like their approach with multiple “pcm.” definitions (the “pcm.ttable” in particular). Your solution is nice and clean. Good stuff.
Thanks for this post. It is very useful. With just few modifications I could configure my sound cards.
I should note that recent updates and KDE upgrades have forced me to switch from ALSA to PulseAudio. There was more to dig through to get it working, but now that I understand PulseAudio it doesn’t seem so bad.
The instructions for multiple output devices through PulseAudio.
Your dmix buffer size is too large.
Try
period_size 480
periods 3
rate 48000
The latency of each period is 10ms because the sample rate is 48000. There are 3 periods in each buffer.
Thus, the latency of each buffer is 30ms.
This has proven to be rock solid on my computer.