SDL ignoring AUDIODEV and SDL_DSP_DEV?

I have two sound devices in my system, the onboard sound
device, /dev/sound/dsp, which I let KDE/artsd monopolize; and my real
soundcard, /dev/sound/dsp1, which I use for everything else. No matter what
I do I cannot convince the SDL DSP driver to use the driver specified in the
environment variables.

I know I’m setting the environment variables because SDL_AUDIODRIVER="disk"
works fine… the problem is in fact weirder than using the wrong device, it
tries to open BOTH devices, and actually succeeds in opening the right one:

$ export SDL_DSP_DEV="/dev/sound/dsp1"
$ ls -lh $SDL_DSP_DEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export AUDIODEV="/dev/sound/dsp1"
$ ls -lh $AUDIODEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export SDL_AUDIODRIVER=“dsp”
$ echo $SDL_AUDIODRIVER
dsp
strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It does this not just for blobwars, but for all SDL audio-using applications.

lsof confirms artsd has grabbed /dev/sound/dsp, not /dev/sound/dsp1, and also
confirms nothing else is using /dev/sound/dsp1. I’ve specifically disabled
SDL’s ESD and ARTS backends to ensure they’re not causing it. I’m using
SDL-1.2.8 on gentoo linux amd64, kernel 2.6.5,

Any ideas?

Tyler Montbriand wrote:

I have two sound devices in my system, the onboard sound
device, /dev/sound/dsp, which I let KDE/artsd monopolize; and my real
soundcard, /dev/sound/dsp1, which I use for everything else. No matter what
I do I cannot convince the SDL DSP driver to use the driver specified in the
environment variables.

I know I’m setting the environment variables because SDL_AUDIODRIVER="disk"
works fine… the problem is in fact weirder than using the wrong device, it
tries to open BOTH devices, and actually succeeds in opening the right one:

$ export SDL_DSP_DEV="/dev/sound/dsp1"
$ ls -lh $SDL_DSP_DEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export AUDIODEV="/dev/sound/dsp1"
$ ls -lh $AUDIODEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export SDL_AUDIODRIVER=“dsp”
$ echo $SDL_AUDIODRIVER
dsp
strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It does this not just for blobwars, but for all SDL audio-using applications.

lsof confirms artsd has grabbed /dev/sound/dsp, not /dev/sound/dsp1, and also
confirms nothing else is using /dev/sound/dsp1. I’ve specifically disabled
SDL’s ESD and ARTS backends to ensure they’re not causing it. I’m using
SDL-1.2.8 on gentoo linux amd64, kernel 2.6.5,

Any ideas?

That’s the SDL OSS behaviour, if it fails to open a device, it tries the
next ones.

But I’m not sure what your question is exactly ? You seem to get the
result you want…

Stephane

$ export SDL_DSP_DEV="/dev/sound/dsp1"
$ ls -lh $SDL_DSP_DEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export AUDIODEV="/dev/sound/dsp1"
$ ls -lh $AUDIODEV
crw------- 1 monttyle audio 14, 19 Dec 31 1969 /dev/sound/dsp1
$ export SDL_AUDIODRIVER=“dsp”
$ echo $SDL_AUDIODRIVER
dsp
strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It does this not just for blobwars, but for all SDL audio-using
applications.

lsof confirms artsd has grabbed /dev/sound/dsp, not /dev/sound/dsp1, and
also confirms nothing else is using /dev/sound/dsp1. I’ve specifically
disabled SDL’s ESD and ARTS backends to ensure they’re not causing it.
I’m using SDL-1.2.8 on gentoo linux amd64, kernel 2.6.5,

Any ideas?

That’s the SDL OSS behaviour, if it fails to open a device, it tries the
next ones.
No, that’s not the behavior I expected at all. Observe:

$ strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It shouldn’t be trying for alternatives after /dev/sound/dsp1 – it succeeds
in opening the device I specified, otherwise it that open would return -1.
After that, something goes and tries to open the other one! All SDL programs
that initialize and open audio end up doing this. I have not a clue why.

Another riddle is that the devices are being opened in different
ways. /dev/sound/dsp1 is not being checked with access() and is being opened
with O_RWONLY|O_NONBLOCK, meaning that it won’t hang when /dev/dsp1 is
occupied, just fail. This corresponds directly with what I’ve seen in the
SDL OSS implimentation.

/dev/sound/dsp on the other hand is checked with access beforehand, then
opened in blocking mode – and since ARTSD has already monopolized this
device it hangs hard. It takes a kill -9 to get rid of it unless I kill
artsd instead, after which case the application works and plays through the
correct device even though it insists on opening the wrong one too.

I’m guessing the two have been opened by different SDL backends but I don’t
understand why SDL would try initializing more than one driver when the one I
specified succeeds, and I have been unable to trace this behavior to any
place in the SDL code anyway.

But I’m not sure what your question is exactly ? You seem to get the
result you want…
I most definitely don’t want it hanging! :)On Wednesday 20 April 2005 13:04, Stephane Marchesin wrote:

Tyler Montbriand wrote:

No, that’s not the behavior I expected at all. Observe:

$ strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It shouldn’t be trying for alternatives after /dev/sound/dsp1 – it succeeds
in opening the device I specified, otherwise it that open would return -1.
After that, something goes and tries to open the other one! All SDL programs
that initialize and open audio end up doing this. I have not a clue why.

Another riddle is that the devices are being opened in different
ways. /dev/sound/dsp1 is not being checked with access() and is being opened
with O_RWONLY|O_NONBLOCK, meaning that it won’t hang when /dev/dsp1 is
occupied, just fail. This corresponds directly with what I’ve seen in the
SDL OSS implimentation.

/dev/sound/dsp on the other hand is checked with access beforehand, then
opened in blocking mode – and since ARTSD has already monopolized this
device it hangs hard. It takes a kill -9 to get rid of it unless I kill
artsd instead, after which case the application works and plays through the
correct device even though it insists on opening the wrong one too.

I’m guessing the two have been opened by different SDL backends but I don’t
understand why SDL would try initializing more than one driver when the one I
specified succeeds, and I have been unable to trace this behavior to any
place in the SDL code anyway.

But I’m not sure what your question is exactly ? You seem to get the
result you want…

I most definitely don’t want it hanging! :slight_smile:

Ah, ok. I didn’t catch that it was hanging.

So, could you run it under gdb until it hangs, and then have a backtrace
and see where this happens in SDL (by looking at a backtrace and
"list"ing the code for example) ?

Btw, did it work with previous SDL versions ? The recent oss backend
rewrite looks suspicious to me…

Stephane

Good idea!

#0 0x0000002a9580298f in __open_nocancel () from /lib/tls/libpthread.so.0
#1 0x000000302030b69a in OSS_IsThere () from /usr/lib/libmikmod.so.2
#2 0x0000003020326d1c in _mm_init () from /usr/lib/libmikmod.so.2
#3 0x0000003020325ebd in MikMod_Init () from /usr/lib/libmikmod.so.2
#4 0x0000003022706d87 in Mix_HookMusicFinished ()
from /usr/lib/libSDL_mixer-1.2.so.0
#5 0x0000003022705319 in Mix_OpenAudio () from /usr/lib/libSDL_mixer-1.2.so.0
#6 0x000000000042348c in ?? ()
#7 0x0000000000436a76 in ?? ()
#8 0x0000002a95fcb7b8 in __libc_start_main () from /lib/tls/libc.so.6

No wonder I couldn’t find it in SDL, it’s freaking mikmod! :slight_smile: Must want
something to tell it to use the null backend or something. If I fix this
I’ll post a patch.On Friday 22 April 2005 16:32, Stephane Marchesin wrote:

Tyler Montbriand wrote:

No, that’s not the behavior I expected at all. Observe:

$ strace blobwars

open("/dev/sound/dsp1", O_WRONLY|O_NONBLOCK) = 5

access("/dev/sound/dsp", F_OK) = 0
open("/dev/sound/dsp", O_WRONLY
(hangs)

It shouldn’t be trying for alternatives after /dev/sound/dsp1 – it
succeeds in opening the device I specified, otherwise it that open
would return -1. After that, something goes and tries to open the other
one! All SDL programs that initialize and open audio end up doing this.
I have not a clue why.

Another riddle is that the devices are being opened in different
ways. /dev/sound/dsp1 is not being checked with access() and is being
opened with O_RWONLY|O_NONBLOCK, meaning that it won’t hang when
/dev/dsp1 is occupied, just fail. This corresponds directly with what
I’ve seen in the SDL OSS implimentation.

/dev/sound/dsp on the other hand is checked with access beforehand, then
opened in blocking mode – and since ARTSD has already monopolized this
device it hangs hard. It takes a kill -9 to get rid of it unless I kill
artsd instead, after which case the application works and plays through
the correct device even though it insists on opening the wrong one too.

I’m guessing the two have been opened by different SDL backends but I
don’t understand why SDL would try initializing more than one driver when
the one I specified succeeds, and I have been unable to trace this
behavior to any place in the SDL code anyway.

But I’m not sure what your question is exactly ? You seem to get the
result you want…

I most definitely don’t want it hanging! :slight_smile:

Ah, ok. I didn’t catch that it was hanging.

So, could you run it under gdb until it hangs, and then have a backtrace
and see where this happens in SDL (by looking at a backtrace and
"list"ing the code for example) ?

Speaking of SDL audio drivers, for the Linux target, SDL tries low level
drivers (alsa, oss, etc…) before the higher level ones (alsa, esd,
nas, etc…). Even the disk audio driver is tried in between.

I think that for any target, the higher level ones should be tried to
open first, then the lower level ones, finishing with the dummy null
driver.

For Linux, SDL should try arts and esd before alsa and oss, and these
ones before disk and dummy.

For people interested, look at SDL/src/audio/SDL_audio.c, the bootstrap
structure.–
Patrice Mandin
WWW: http://membres.lycos.fr/pmandin/
Programmeur Linux, Atari
Sp?cialit?: D?veloppement, jeux

Patrice Mandin wrote:

Speaking of SDL audio drivers, for the Linux target, SDL tries low level
drivers (alsa, oss, etc…) before the higher level ones (alsa, esd,
nas, etc…). Even the disk audio driver is tried in between.

Actually, if you use the esd driver, it will start up the esd daemon and
always succeed.
Also, daemons like arts usually lock the oss /dev entry exclusively, so
when they are running using oss fails and SDL fallbacks to arts.

So I think the order is correct.

Stephane

What advantages do higher level audio drivers have?

  • device-sharing
  • format conversion

What disadvanteges do higher-level audio drivers have?

  • Lag – they’re an extra level of buffering
  • More skipping for the same amount of lag
  • Extra CPU workload
  • Instability – I need to do killall -9 artsd at least once a day
  • Insecurity – artsd runs best with root permissions, but this is no longer
    reccomended due to security flaws
  • Unwanted features – I’d rather not have my default soundcard potentially be
    on the other side of the internet
  • More error conditions that cannot be bypassed – you can try an alternative
    OSS device, but good luck finding an alternative artsd!

Lower-level drivers almost almost always offer better performance in all the
ways that matter inside SDL.On Wednesday 04 May 2005 09:22, Patrice Mandin wrote:

Speaking of SDL audio drivers, for the Linux target, SDL tries low level
drivers (alsa, oss, etc…) before the higher level ones (alsa, esd,
nas, etc…). Even the disk audio driver is tried in between.

I think that for any target, the higher level ones should be tried to
open first, then the lower level ones, finishing with the dummy null
driver.