The quick trick is having
defaults.pcm.!card Headsetin your
defaults.ctl.!card Headset
defaults.pcm.!device 0
defaults.ctl.!device 0
~/.asoundrc
. (Replace Headset
with the name of the card on which you want to hear sound. Get the list of available sound cards with aplay -l | awk '/^card/{print$3}'|sort|uniq
. To apply this setting for all users, add the lines above to /etc/asound.conf
instead.) If this doesn't work for you, please continue reading.Let's suppose you have a Linux system and many sound cards with an ALSA (>= 0.9) driver, and you don't use any sound server (e.g. pulse, ESD == esound or artsd). The dmix feature of ALSA does software sound mixing, so it makes it possible to run multiple playbacks simultaneously on the same card. ALSA, by default, enables dmix for all cards which don't support concurrent playback of more than one sound stream.
So you just run
mplayer -ao alsa file1.mp3
, and simultaneously (possibly in another terminal window) mplayer -ao alsa file2.mp3
. You should hear both playbacks at the same time. (Please note that you can omit =-ao alsa= from the mplayer command line if you add ao=alsa
to your ~/.mplayer/config
file.) If the second mplayer doesn't start playback, but exists with an error message containing Device or resource busy
, this means there is something wrong with your settings – this tutorial will help to fix that.If even the first mplayer produces the Device or resource busy error, then close or kill all applications that might play sound. This includes the web browser (with flash), pulse, esd, artsd, mplayer, Skype, MPD and system sounds (disable everything in Gnome / System / Preferences / Sound / Sound). After that,
mplayer -ao alsa file1.mp3
should start the first playback, and simultaneously, mplayer -ao alsa file2.mp3
should start the second playback.If you have multiple sound cards (possibly the sound card in your computer, and an external USB headset), you can set the environment variable
ALSA_CARD
to direct playback to a specific card. Example 1: ALSA_CARD=Headset mplayer -ao alsa file1.mp3
. Example 2: start Firefox as ALSA_CARD=Headset firefox
to have the sound Flash movies played on the card named Headset
.You can get a list of sound cards (with some extra information) with
aplay -l
. For example, on my system, I get$ aplay -lHere is how I can select each card and device:
card 0: Intel [HDA Intel], device 0: CONEXANT Analog [CONEXANT Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: Conexant Digital [Conexant Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: TuxDroid [TuxDroid], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: TuxDroid [TuxDroid], device 1: USB Audio [USB Audio #1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: Headset [Plantronics Headset], device 0: USB Audio [USB Audio]
Subdevices: 0/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 0: CONEXANT Analog [CONEXANT Analog]Once you have the proper
ALSA_CARD=0
ALSA_CARD=Intel
card 0: Intel [HDA Intel], device 1: Conexant Digital [Conexant Digital]
ALSA_CARD=0 ALSA_PCM_CARD=1
ALSA_CARD=Intel ALSA_PCM_CARD=1
card 1: TuxDroid [TuxDroid], device 0: USB Audio [USB Audio]
ALSA_CARD=1
ALSA_CARD=TuxDroid
card 1: TuxDroid [TuxDroid], device 1: USB Audio [USB Audio #1]
ALSA_CARD=1 ALSA_PCM_CARD=1
ALSA_CARD=TuxDroid ALSA_PCM_CARD=1
card 2: Headset [Plantronics Headset], device 0: USB Audio [USB Audio]
ALSA_CARD=2
ALSA_CARD=Headset
ALSA_CARD
and ALSA_PCM_CARD
setting, you can add them to your ~/.bashrc
and ~/.gnomerc
and ~/.xprofile
(and possibly to /etc/environment
and /etc/X11/Xsession.d/*
and /etc/gdm/Xsession
). If you log out and log in to your graphic session, you'll have these environment variables by default.It is possible to select the default sound card without changing setting the
ALSA_CARD
or ALSA_PCM_CARD
environment variables. To do so, add these lines to your ~/.asoundrc
:defaults.pcm.!card HeadsetEach
defaults.ctl.!card Headset
defaults.pcm.!device 0
defaults.ctl.!device 0
!card
line corresponds to the ALSA_CARD
value, and each !device
line corresponds to the ALSA_PCM_CARD
value.If you set the default in
~/.asoundrc
and set the environment variables as well, then the environment variables take effect.Please note that if you specify any specific ALSA device to any program (other than
default
), and the program starts playback, then automatic dmix would not work until that program finishes playback and closes the device. This implies that no other program will be able to start playback (but will yield Device or resource busy) until that happens. For example, Skype keeps the sound card open while it is running. So if you want to play sound not coming from Skype while Skype is running, you have to select Default device (default) in Options / Sound Devices for both Sound Out and Ringing. A similar restriction applies to music players and other software: if you specify the playback device for them in their command line or preferences, then the software will lock the sound card, and you lose dmix and concurrent playback. The only dmix-safe ways to select a sound card are the ALSA_CARD
etc. environment variables and ~/asoundrc
.To get information about the ALSA cards, run
aplay -l
and aplay -v -v -L
.ALSA provides OSS emulation (i.e.
/dev/dsp
, /dev/dsp1
), but dmix doesn't work with OSS emulation. To get it work, please run the software which needs OSS using the aoss wrapper, e.g. aoss mplayer -ao oss file1.oss
, and concurrently, aoss mplayer -ao oss file2.oss
or mplayer -ao alsa file2.oss
. If you get the error message /dev/dsp: Device or resource busy
from a program, then you'll either have to change it to use ALSA, or run it within aoss.Here are some sine wave sound generators if you don't have an MP3 ready to test playback with:
perl -e 'print pack("v",32000*sin($_/34))."\0\0"; ++$_ while 1' | aplay -f dat # Left earIf you have the asoundconf utility, you can use it to set up the default sound card in your
perl -e 'print "\0\0".pack("v",32000*sin($_/34)); ++$_ while 1' | aplay -f dat # Right ear
~/.asoundrc
. For example, after removing ~/.asoundrc
and runningasoundconf set-default-card Headset
, you'll get a line <:/home/USERNAME/.asoundrc.asoundconf>
in file ~/.asoundrc
, and the file ~/.asoundrc.asoundconf
would contain more than 50 config lines, the essential ones being!defaults.pcm.card HeadsetThis seems to be too much compared to the 4 lines the beginning of this tutorial suggests.
defaults.ctl.card Headset
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format S16_LE
defaults.pcm.dmix.card defaults.pcm.card
defaults.pcm.dmix.device defaults.pcm.device
defaults.pcm.dsnoop.card defaults.pcm.card
defaults.pcm.dsnoop.device defaults.pcm.device
defaults.namehint.extended off
Random notes
With ALSA 1.0.15, onlyplughw:
works for tuxdroid (so it cannot be used with ALSA_CARD
, which implies hw:
). Here is how to play: mplayer -ao alsa:device=plughw=TuxDroid file1.mp3
or aplay -D plughw:TuxDroid </dev/urandom
. Please note that this restriction applies to both mplayer and aplay. (Maybe that's because dmix was busy when the tuxdroid was connected -- and if we reload ALSA, maybe it will work if I connect the tuxdroid first, and then load the ALSA modules?) The reason why it doesn't work seems to be that the U8 sample format needed by the tuxdroid was introduced only in ALSA 1.0.16. I've verified with libasound 1.0.16 installed (with the same old ALSA kernel) in a chroot, and dmix works with the tuxdroid.The setting
ALSA_CARD=Foo ALSA_PCM_CARD=2
corresponds to aplay -D hw:Foo,2
and mplayer -ao alsa:device=hw=Foo.2
. Please note that there is no corresponding environment variable setting for plughw
instead of hw
. Please also note that mplayer won't use dmix (thus it won't be able to run multiple playbacks concurrently) if you specify any other ALSA setting than mplayer -ao alsa
or mplayer -ao alsa:device=default
. A similar restriction applies to aplay -D
: if you specify any device other than default
there, it won't use dmix.An example full mplayer error message when dmix didn't work:
[AO_ALSA] alsa-lib: pcm_hw.c:1099:(snd_pcm_hw_open) open /dev/snd/pcmC2D0p failed: Device or resource busy
[AO_ALSA] Playback open error: Device or resource busy
Could not open/initialize audio device -> no sound.
Audio: no sound
Thanks!
ReplyDeleteThose 4 lines are still actual in 2011. That is the only working solution I could find in 4 hours! Thanks again!
And it still works in 2013!
ReplyDeleteThanks a lot for this post.
Still good! Many thanks.
ReplyDelete2015 Still the best way to fix for ALSA only. This little snippet has helped me so much in letting other applications share output to the headset.
ReplyDelete4 little lines.
It's a good little titdbit when you leave the safe embrace of a full desktop provided by big distro ubuntu/suse etc..