Wednesday, July 30, 2008

Teaching OSS to Share

Say you're doing some programming, or trying out an older audio program, and you get some form of the following cryptic error:



unable to open `/dev/dsp', Device or resource busy


What does it mean and what can you do about it?



As to what it means - basically, an application somewhere isn't being very nice and sharing, like we have all be taught to do. Or it wants to hog the sound device all to itself and another app won't let it go. /dev/dsp is the device pointer for the default "dsp" or digital sound processor and, as audio remains a bit of an Achilles heel for Linux, there can be problems in the sandbox.



So what you need to do is to figure out which app currently has locked, so maybe you can quit that application to allow our other one to access it. You might think of using lsof or fuser to figure it out. So you check:



$ lsof /dev/dsp
$ fuser /dev/dsp


But unfortunately, it won't show you anything. I think this is because /dev/dsp is just an affectation, which allows Linux to point wherever it really wants to.



In this case, it is the /dev/snd/* files. It is here you want to see who is grabbing things:



$ ls /dev/snd
controlC0 hwC0D2 pcmC0D0p pcmC0D1p pcmC1D0c seq
controlC1 pcmC0D0c pcmC0D1c pcmC0D2c pcmC1D0p timer
$ lsof /dev/snd/*
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
VirtualBo 4083 jdarnold mem CHR 116,10 4395 /dev/snd/pcmC0D0c
VirtualBo 4083 jdarnold mem CHR 116,9 4390 /dev/snd/pcmC0D0p
VirtualBo 4083 jdarnold 40r CHR 116,2 0t0 4102 /dev/snd/timer
VirtualBo 4083 jdarnold 42u CHR 116,10 0t0 4395 /dev/snd/pcmC0D0c
VirtualBo 4083 jdarnold 43u CHR 116,12 0t0 4411 /dev/snd/controlC0
VirtualBo 4083 jdarnold 44r CHR 116,2 0t0 4102 /dev/snd/timer
VirtualBo 4083 jdarnold 45u CHR 116,9 0t0 4390 /dev/snd/pcmC0D0p
VirtualBo 4083 jdarnold 46u CHR 116,12 0t0 4411 /dev/snd/controlC0
kmix 4155 jdarnold 12u CHR 116,12 0t0 4411 /dev/snd/controlC0
kmix 4155 jdarnold 13u CHR 116,5 0t0 4560 /dev/snd/controlC1
$ fuser /dev/snd/*
/dev/snd/controlC0: 4155 4800
/dev/snd/controlC1: 4155
/dev/snd/pcmC0D0c: 4800m
/dev/snd/pcmC0D0p: 4800m
/dev/snd/timer: 4800
$ ps -c 4800
PID CLS PRI TTY STAT TIME COMMAND
4800 TS 19 ? SLl 0:12 /usr/lib/virtualbox/VirtualBox -comment Debia


Pretty conclusive proof that it is VirtualBox using the device. So let's see what it looks like after I quit out of VirtualBox:



$ lsof /dev/snd/*
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
kmix 4155 jdarnold 12u CHR 116,12 0t0 4411 /dev/snd/controlC0
kmix 4155 jdarnold 13u CHR 116,5 0t0 4560 /dev/snd/controlC1
$ fuser /dev/snd/*
/dev/snd/controlC0: 4155
/dev/snd/controlC1: 4155
$ ps -c 4155
PID CLS PRI TTY STAT TIME COMMAND
4155 TS 19 ? S 0:00 kmix [kdeinit] -autostart


kmix, the KDE sound mixer program, is pretty good about things, and thus we no longer have a conflict:



$ ./dspinfo
Information on /dev/dsp:

Defaults:
sampling rate: 8000 Hz
channels: 1
sample size: 8 bits
block size: 1023 bytes

Supported Formats:
mu-law
unsigned 8-bit (default)
signed 16-bit little-endian
signed 16-bit big-endian
signed 8-bit
unsigned 16-bit little-endian
unsigned 16-bit big-endian

Capabilities:
revision: 1
full duplex: yes
real-time: yes
batch: no
coprocessor: no
trigger: yes
mmap: yes

Modes and Limits:
Device Sample Minimum Maximum
Channels Size Rate Rate
-------- -------- -------- --------
1 8 1000 100000
1 16 1000 100000
2 8 1000 100000
2 16 1000 100000


dspinfo is a small program I adapted from the exerpt for the old O'Reilly book Linux Multimedia Guide, which is Chapter 14. Programming Sound Devices. As I said, OSS (Open Sound System) is an old Linux standard, pretty much passed by in these days of 2.6 kernels.