ESD detection logic

Okay, this got a little complicated but here it is:

If the user explicitly requested the ESD driver, use it if possible.-
If we can open the audio device twice, and the ESPEAKER environment
variable is not set, then we don’t need ESD and we can write to the
audio device anyway, and this is preferred. Don’t use ESD driver.

If we can open the audio device once, then try to use ESD, but if
ESD is not available, don’t try to start it up.

If we can’t open the audio device at all, try to start up ESD.

Comments?

Code follows:

static int ESD_Available(void)
{
int connection;
int available;

    available = 0;
    connection = esd_open_sound(NULL);
    if ( connection >= 0 ) {
            available = 1;
            esd_close(connection);
    }
    return(available);

}

static int Audio_Available(void)
{
int available
const char *driver;
int audio_fd;
int opened_audio;

    available = 0;

    /* See if the ESD driver was explicitly requested */
    driver_name = getenv("SDL_AUDIODRIVER");
    if ( driver_name && (strcmp(driver_name, ESD_DRIVER_NAME) == 0) ) {
            return ESD_Available();
    }

    /* See if we can open the audio device */
    opened_audio = 0;
    audio_fd = open(SDL_AudioPath(), OPEN_FLAGS, 0);
    if ( audio_fd >= 0 ) {
            opened_audio = 1;
            /* Check to see if we can open audio even if ESD is running */
            if ( getenv("ESPEAKER") == NULL ) {
                    int fd;

                    fd = open(SDL_AudioPath(), OPEN_FLAGS, 0);
                    if ( fd >= 0 ) {
                            /* Opened audio twice, we don't use ESD */
                            close(fd);
                            close(audio_fd);
                            return(0);
                    }
            }
            close(audio_fd);
    }

    /* See if ESD is available, but don't try to start it */
    if ( opened_audio && (getenv("ESD_NO_SPAWN") == NULL) ) {
            /* Only use high latency ESD if it is already running */
            putenv("ESD_NO_SPAWN=true");
            available = ESD_Available();
            unsetenv("ESD_NO_SPAWN");
    } else {
            available = ESD_Available();
    }
    return(available);

}

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software

“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

If the user explicitly requested the ESD driver, use it if possible.

If we can open the audio device twice, and the ESPEAKER environment
variable is not set, then we don’t need ESD and we can write to the
audio device anyway, and this is preferred. Don’t use ESD driver.

If we can open the audio device once, then try to use ESD, but if
ESD is not available, don’t try to start it up.

If we can’t open the audio device at all, try to start up ESD.

Comments?

Good idea, but I’d comment on the existence of a few buggy Sound Blaster
Live drivers that will not fail a second open, but rather block the
calling program until the device is closed (which will never happen in
your case).–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

Sam Lantinga wrote:

If the user explicitly requested the ESD driver, use it if possible.

If we can open the audio device twice, and the ESPEAKER environment
variable is not set, then we don’t need ESD and we can write to the
audio device anyway, and this is preferred. Don’t use ESD driver.

If we can open the audio device once, then try to use ESD, but if
ESD is not available, don’t try to start it up.

If we can’t open the audio device at all, try to start up ESD.

Comments?

Good idea, but I’d comment on the existence of a few buggy Sound Blaster
Live drivers that will not fail a second open, but rather block the
calling program until the device is closed (which will never happen in
your case).

Even if O_NONBLOCK is specified in the open flags?

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

Good idea, but I’d comment on the existence of a few buggy Sound Blaster
Live drivers that will not fail a second open, but rather block the
calling program until the device is closed (which will never happen in
your case).

Even if O_NONBLOCK is specified in the open flags?

Yes. Sucks, eh? Note that they upgraded their drivers I think, so you
might want to do it this way in any case, but I thought you might like
to know… (the emu10k module or something similar)

BTW, for the OSS /dev/dsp, O_NONBLOCK does nothing that I can perceive
(it’s always non-blocking);–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

there is a simple work-around for this:

fire up an separate process/task for doing the detection:
sleep a few secs in the main thread and wait for a results from the
"soundcard probing thread", it it stalls, just
kill the thead with signal 9 ( SIGKILL).
With this trick you will detect multiple open even on buggy soundcard drivers.
:slight_smile:

Benno.On Thu, 03 Feb 2000, Pierre Phaneuf wrote:

Sam Lantinga wrote:

Good idea, but I’d comment on the existence of a few buggy Sound Blaster
Live drivers that will not fail a second open, but rather block the
calling program until the device is closed (which will never happen in
your case).

Even if O_NONBLOCK is specified in the open flags?

Yes. Sucks, eh? Note that they upgraded their drivers I think, so you
might want to do it this way in any case, but I thought you might like
to know… (the emu10k module or something similar)

BTW, for the OSS /dev/dsp, O_NONBLOCK does nothing that I can perceive
(it’s always non-blocking);

Benno Senoner wrote:

fire up an separate process/task for doing the detection:
sleep a few secs in the main thread and wait for a results from the
"soundcard probing thread", it it stalls, just
kill the thead with signal 9 ( SIGKILL).
With this trick you will detect multiple open even on buggy soundcard
drivers. :slight_smile:

Hmm, nifty idea, yes! I’m ashamed I didn’t think of it myself! :slight_smile:

But then, I didn’t face that problem myself (Quadra freezes if the
device is already open, then you can simply close whatever has it open
and it resume right where it was)…–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/