A program attempting to open a sound device for exclusive access may fail, if that audio device is already in use by another program. Also, depending on the capabilities of the audio device, such as whether it is full-duplex or not, errors may occur if capture is requested during playback. The actual error messages produced are program and operating system dependent. However, some typical error messages are listed below.
Audio device unavailable. Cannot open audio device. Could not gain access to /dev/dsp for writing. Audio capabilities are not available on this machine. Can't open output file '/dev/dsp': Device or resource busy. # ©2007 dsplabs.com.au Error Initializing Audio: There was an error initializing the audio i/o layer.
The reminder of this article briefly discusses the Linux sound architecture, followed by an explanation on how to locate and close applications that are using an audio device.
There are two main audio APIs used under Linux, namely the Open Sound System (OSS) and the Advanced Linux Sound Architecture (ALSA). There are also some alternatives, however OSS and ALSA are by far most popular audio interfaces. If you would like to read a bit more on how OSS and ALSA APIs compare then have a look at the ALSA vs. OSS article. In our article, we will mostly limit our discussion to the ALSA API. Note however that ALSA does provide a compatibility mode for OSS. Some very useful information about ALSA can be found in Alsa-sound-mini-HOWTO. Well, let me squeeze in another useful reference before proceeding. The beautiful thing about Linux is how simple things are under it. Under Linux, the audio devices are simply character devices. This makes it easy to access and use them. If you are planning on writing some code that requires audio device manipulation, then A Tutorial on Using the ALSA Audio API is well worth a read.
To start, lets have a look at audio cards installed on your system, by running the following command.
If, for instance, your sound card is based on NVidia NFORCE chip-set the output might look something like this:
0 [CK804 ]: NFORCE - NVidia CK804 NVidia CK804 with ALC850 at 0xd0103000, irq 233
On my system, the sound card is part of the Intel chip-set and is listed below as card 0. There is also another card with audio capabilities (card 1) which is an analog modem (in this case also a part of the Intel chip-set).
0 [I82801DBICH4 ]: ICH4 - Intel 82801DB-ICH4 Intel 82801DB-ICH4 with unknown codec at 0xe0100c00, irq 10 1 [Modem ]: ICH-MODEM - Intel 82801DB-ICH4 Modem Intel 82801DB-ICH4 Modem at 0x2400, irq 10
Strictly speaking, an audio card could have a number of on-board devices. These devices are available under the
/dev tree. The OSS device nodes are located in
/dev/dsp* while ALSA uses
/dev/snd/*. Lets have a closer look at ALSA's device nodes.
ls -la /dev/snd
The above command should produce an output similar to the one shown below, provided that you do have a sound card and that ALSA is present and loaded on your system.
total 0 drwxr-xr-x 2 root root 280 Oct 31 13:48 . drwxr-xr-x 12 root root 3840 Oct 31 13:49 .. crw------- 1 kamil root 116, 10 Oct 31 13:48 controlC0 crw------- 1 kamil root 116, 13 Oct 31 13:48 controlC1 crw------- 1 kamil root 116, 9 Oct 31 13:48 pcmC0D0c crw------- 1 kamil root 116, 8 Oct 31 13:48 pcmC0D0p crw------- 1 kamil root 116, 7 Oct 31 13:48 pcmC0D1c crw------- 1 kamil root 116, 6 Oct 31 13:48 pcmC0D2c crw------- 1 kamil root 116, 5 Oct 31 13:48 pcmC0D3c crw------- 1 kamil root 116, 4 Oct 31 13:48 pcmC0D4p crw------- 1 kamil root 116, 12 Oct 31 13:48 pcmC1D0c crw------- 1 kamil root 116, 11 Oct 31 13:48 pcmC1D0p crw------- 1 kamil root 116, 3 Oct 31 13:48 seq crw------- 1 kamil root 116, 2 Oct 31 13:48 timer
The above output shows a number of devices. Amongst others, there is the
/dev/snd/controlC0 which is the control device for card 0, as well as
/dev/snd/pcmC0D0p which is the raw audio playback device 0 on card 0. Note that the current naming convention is such that the card number follows the letter
C and device number follows the letter
D. The last letter on the
p, indicates if the device is used for capture or playback, respectively.
Reproducing the error
Let us try to reproduce a conflict described in the introduction. First, we'll run
mplayer to play an mp3 file
song.mp3, as follows.
Then we'll try to play an audio file from Matlab.
>> [x, fs, nbits] = wavread('audio.wav'); >> sound(x, fs); >> Unable to open the audio device for playback: javax.sound.sampled.LineUnavailableException: Audio Device Unavailable
The Java sound interface requires an exclusive access to the audio device, and hence the above error is produced. This is just one, somewhat artificial, example.
Freeing the audio device
So, the question is: how to free a Linux sound device? Well, the simplest way is to close, or end, the program that has opened it in the first place. A program will open an audio device with some read/write permissions and will hold a handle to that device. A well behaved application should release any open file handles (in-fact any resources) on exit back to the operating system. If an application fails to do that the operating system may collect these resources after the application terminates.
One may ask how to find out which program, or programs, have gained access to the audio device? That is where a little knowledge of Linux tools, and especially the
lsof utility, comes in handy. Since we know where in the
/dev tree the devices are mapped under ALSA we can use
lsof, which stands for `list open files', to locate open sound device files.
lsof will also tell us which programs have opened them.
So, lets run
lsof and grep snd from its output to find out which sound devices are open.
lsof |grep snd
The output below shows that the KDE sound mixer,
kmix, has opened the control devices for both cards (the sound card and the modem). More importantly, the
mplayer is using the pcm device (i.e. the raw audio device) for playback. It is for this reason that the playback failed in Matlab.
kmix 5444 kamil 10u CHR 116,10 4807 /dev/snd/controlC0 kmix 5444 kamil 11u CHR 116,13 4944 /dev/snd/controlC1 mplayer 14004 kamil mem CHR 116,8 4684 /dev/snd/pcmC0D0p mplayer 14004 kamil 4r CHR 116,2 3914 /dev/snd/timer mplayer 14004 kamil 5u CHR 116,8 4684 /dev/snd/pcmC0D0p
Once the program that holds the audio device hostage has been identified, one can terminate it to free the device. If it is a shell program then ending it can be achieved with
Ctrl+c. If it is a GUI based program then
Alt+F4 may accomplish it, or f.e. File->Quit menu will also do it. Note however, that there are times when programs become unresponsive, or even crash, without properly freeing the open file handles. In such a case, the use of
lsof becomes even more useful. Once the program is identified, a
kill commands can be used to terminate such a program. You could ask the application to close gracefully, i.e. give it time to perform any exit tasks (including properly freeing resources) by using
killall -TERM mplayer
or you could could force its termination by using
killall -SIGKILL mplayer
If you want to be more specific (and not kill every running instance of
mplayer) then you could terminate a specific program using its process id (
PID). Note that
PID information is part of the
lsof output. In our example the
PID is 14004. The command below was used to terminate it.
kill -TERM 14004
After terminating the program we can have another look at open audio devices.
lsof |grep snd
Notice, in the output below, that the raw audio device is no longer in use by
kmix 5444 kamil 10u CHR 116,10 4807 /dev/snd/controlC0 kmix 5444 kamil 11u CHR 116,13 4944 /dev/snd/controlC1
lsof is an extremely usesful utility. It finds many applications beyond the simple example described here. Another very useful utility is
lslk — list local locks (i.e. list lock files). I will describe the use of
lslk in a future article.
Did you find the above information useful and interesting? If so, please support this site by using the blog directory links at the bottom of this page. Thanks for your support!
If you have any Linux related problems or questions then please feel free to post them on our Linux Forums: http://linux.dsplabs.com.au/forums.