Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Removed distinction between "available" and "init" in audio backends,…

… since

 both had to be checked for success as a pair at the higher level and several
 of the Available methods were just always-succeed placeholders anyhow. Now
 the availability check is done in the init code, and the higher level tries
 all possible drivers until one manages to initialize successfully.
  • Loading branch information
icculus committed Oct 17, 2006
1 parent 20d2eae commit cda68e306c1c4672349670bda94670f63b165c0c
@@ -360,6 +360,7 @@ SDL_AudioInit(const char *driver_name)
{
int i = 0;
int initialized = 0;
int tried_to_init = 0;

if (SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_AudioQuit(); /* shutdown driver if already running. */
@@ -373,36 +374,31 @@ SDL_AudioInit(const char *driver_name)
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}

/* !!! FIXME: what's the point of separating available() and init()? */
if (driver_name != NULL) {
for (i = 0; bootstrap[i]; ++i) {
if (SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
if (bootstrap[i]->available()) {
SDL_memset(&current_audio, 0, sizeof (current_audio));
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
initialized = bootstrap[i]->init(&current_audio.impl);
}
break;
}
}
} else {
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
if ((!bootstrap[i]->demand_only) && (bootstrap[i]->available())) {
SDL_memset(&current_audio, 0, sizeof (current_audio));
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
initialized = bootstrap[i]->init(&current_audio.impl);
}
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
/* make sure we should even try this driver before doing so... */
const AudioBootStrap *backend = bootstrap[i];
if ( ((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) ||
((!driver_name) && (backend->demand_only)) ) {
continue;
}

tried_to_init = 1;
SDL_memset(&current_audio, 0, sizeof (current_audio));
current_audio.name = backend->name;
current_audio.desc = backend->desc;
initialized = backend->init(&current_audio.impl);
}

if (!initialized) {
if (driver_name) {
SDL_SetError("%s not available", driver_name);
} else {
SDL_SetError("No available audio device");
/* specific drivers will set the error message if they fail... */
if (!tried_to_init) {
if (driver_name) {
SDL_SetError("%s not available", driver_name);
} else {
SDL_SetError("No available audio device");
}
}

SDL_memset(&current_audio, 0, sizeof (current_audio));
return (-1); /* No driver was available, so fail. */
}
@@ -107,10 +107,10 @@ typedef struct AudioBootStrap
{
const char *name;
const char *desc;
int (*available) (void);
int (*init) (SDL_AudioDriverImpl *impl);
int demand_only:1; /* 1==request explicitly, or it won't be available. */
} AudioBootStrap;

#endif /* _SDL_sysaudio_h */

/* vi: set ts=4 sw=4 expandtab: */
@@ -151,12 +151,10 @@ static int load_alsa_syms(void)

#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC

static int library_load_count = 0;

static void
UnloadALSALibrary(void)
{
if ((alsa_handle != NULL) && (--library_load_count == 0)) {
if (alsa_handle != NULL) {
dlclose(alsa_handle);
alsa_handle = NULL;
}
@@ -166,10 +164,9 @@ static int
LoadALSALibrary(void)
{
int retval = 0;
if (library_load_count++ == 0) {
if (alsa_handle == NULL) {
alsa_handle = dlopen(alsa_library, RTLD_NOW);
if (alsa_handle == NULL) {
library_load_count--;
retval = -1;
SDL_SetError("ALSA: dlopen('%s') failed: %s\n",
alsa_library, strerror(errno));
@@ -217,20 +214,6 @@ get_audio_device(int channels)
}


static int
ALSA_Available(void)
{
int available = 0;

if (LoadALSALibrary() >= 0) {
available = 1;
UnloadALSALibrary();
}
return (available);
}



/* This function waits until it is possible to write a full sound buffer */
static void
ALSA_WaitDevice(_THIS)
@@ -377,7 +360,6 @@ ALSA_CloseDevice(_THIS)
}
SDL_free(this->hidden);
this->hidden = NULL;
UnloadALSALibrary();
}
}

@@ -401,11 +383,6 @@ ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));

if (LoadALSALibrary() < 0) {
ALSA_CloseDevice(this);
return 0;
}

/* Open the audio device */
/* Name of device should depend on # channels in spec */
status = ALSA_snd_pcm_open(&pcm_handle,
@@ -599,24 +576,34 @@ ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
return 1;
}

static void
ALSA_Deinitialize(void)
{
UnloadALSALibrary();
}

static int
ALSA_Init(SDL_AudioDriverImpl *impl)
{
if (LoadALSALibrary() < 0) {
return 0;
}

/* Set the function pointers */
impl->OpenDevice = ALSA_OpenDevice;
impl->WaitDevice = ALSA_WaitDevice;
impl->GetDeviceBuf = ALSA_GetDeviceBuf;
impl->PlayDevice = ALSA_PlayDevice;
impl->CloseDevice = ALSA_CloseDevice;
impl->Deinitialize = ALSA_Deinitialize;
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: Add device enum! */

return 1;
}


AudioBootStrap ALSA_bootstrap = {
DRIVER_NAME, "ALSA 0.9 PCM audio",
ALSA_Available, ALSA_Init, 0
DRIVER_NAME, "ALSA 0.9 PCM audio", ALSA_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */
@@ -126,32 +126,6 @@ LoadARTSLibrary(void)

#endif /* SDL_AUDIO_DRIVER_ARTS_DYNAMIC */

/* Audio driver bootstrap functions */

static int
ARTS_Available(void)
{
int available = 0;

if (LoadARTSLibrary() == 0) {
if (SDL_NAME(arts_init) () == 0) {
#define ARTS_CRASH_HACK /* Play a stream so aRts doesn't crash */
#ifdef ARTS_CRASH_HACK
arts_stream_t stream;
stream = SDL_NAME(arts_play_stream) (44100, 16, 2, "SDL");
SDL_NAME(arts_write) (stream, "", 0);
SDL_NAME(arts_close_stream) (stream);
#endif
available = 1;
SDL_NAME(arts_free) ();
}
UnloadARTSLibrary();
}

return available;
}


/* This function waits until it is possible to write a full sound buffer */
static void
ARTS_WaitDevice(_THIS)
@@ -232,7 +206,6 @@ ARTS_CloseDevice(_THIS)
SDL_free(this->hidden);
this->hidden = NULL;
}
UnloadARTSLibrary();
}


@@ -252,12 +225,6 @@ ARTS_OpenDevice(_THIS, const char *devname, int iscapture)
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));

if (LoadARTSLibrary() < 0) {
ARTS_CloseDevice(this);
SDL_SetError("ARTS: failed to load library: %s", SDL_GetError());
return 0;
}

/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
@@ -341,25 +308,49 @@ ARTS_OpenDevice(_THIS, const char *devname, int iscapture)
}


static void
ARTS_Deinitialize(void)
{
UnloadARTSLibrary();
}


static int
ARTS_Init(SDL_AudioDriverImpl *impl)
{
if (LoadARTSLibrary() < 0) {
return 0;
} else {
if (SDL_NAME(arts_init) () != 0) {
UnloadARTSLibrary();
SDL_SetError("ARTS: arts_init failed (no audio server?)");
return 0;
}

/* Play a stream so aRts doesn't crash */
arts_stream_t stream;
stream = SDL_NAME(arts_play_stream) (44100, 16, 2, "SDL");
SDL_NAME(arts_write) (stream, "", 0);
SDL_NAME(arts_close_stream) (stream);
SDL_NAME(arts_free) ();
}

/* Set the function pointers */
impl->OpenDevice = ARTS_OpenDevice;
impl->PlayDevice = ARTS_PlayDevice;
impl->WaitDevice = ARTS_WaitDevice;
impl->GetDeviceBuf = ARTS_GetDeviceBuf;
impl->CloseDevice = ARTS_CloseDevice;
impl->WaitDone = ARTS_WaitDone;
impl->Deinitialize = ARTS_Deinitialize;
impl->OnlyHasDefaultOutputDevice = 1;

return 1;
}


AudioBootStrap ARTS_bootstrap = {
ARTS_DRIVER_NAME, "Analog RealTime Synthesizer",
ARTS_Available, ARTS_Init, 0
ARTS_DRIVER_NAME, "Analog RealTime Synthesizer", ARTS_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */
@@ -39,12 +39,6 @@ extern "C"
}


static int BEOSAUDIO_Available(void)
{
return 1; /* Always available on BeOS. */
}


/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
/* The BeOS callback for handling the audio buffer */
static void
@@ -215,8 +209,7 @@ BEOSAUDIO_Init(SDL_AudioDriverImpl *impl)

extern "C" { extern AudioBootStrap BEOSAUDIO_bootstrap; }
AudioBootStrap BEOSAUDIO_bootstrap = {
"baudio", "BeOS BSoundPlayer",
BEOSAUDIO_Available, BEOSAUDIO_Init, 0
"baudio", "BeOS BSoundPlayer", BEOSAUDIO_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */
@@ -104,17 +104,6 @@ free_device_lists(void)
}


static int
BSDAUDIO_Available(void)
{
int available = 0;
build_device_lists();
available = ((outputDeviceCount > 0) || (inputDeviceCount > 0));
free_device_lists();
return available;
}


static void
BSDAUDIO_Deinitialize(void)
{
@@ -443,23 +432,22 @@ static int
BSDAUDIO_Init(SDL_AudioDriverImpl *impl)
{
/* Set the function pointers */
impl->DetectDevices = DSP_DetectDevices;
impl->GetDeviceName = DSP_GetDeviceName;
impl->OpenDevice = DSP_OpenDevice;
impl->PlayDevice = DSP_PlayDevice;
impl->WaitDevice = DSP_WaitDevice;
impl->GetDeviceBuf = DSP_GetDeviceBuf;
impl->CloseDevice = DSP_CloseDevice;
impl->Deinitialize = DSP_Deinitialize;
impl->DetectDevices = BSDAUDIO_DetectDevices;
impl->GetDeviceName = BSDAUDIO_GetDeviceName;
impl->OpenDevice = BSDAUDIO_OpenDevice;
impl->PlayDevice = BSDAUDIO_PlayDevice;
impl->WaitDevice = BSDAUDIO_WaitDevice;
impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
impl->CloseDevice = BSDAUDIO_CloseDevice;
impl->Deinitialize = BSDAUDIO_Deinitialize;

build_device_lists();
return 1;
}


AudioBootStrap BSD_AUDIO_bootstrap = {
BSD_AUDIO_DRIVER_NAME, BSD_AUDIO_DRIVER_DESC,
BSDAUDIO_Available, BSDAUDIO_Init, 0
BSD_AUDIO_DRIVER_NAME, BSD_AUDIO_DRIVER_DESC, BSDAUDIO_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */
@@ -427,11 +427,6 @@ DART_CloseDevice(_THIS)
}
}

static int
DART_Available(void)
{
return 1; /* Always available on OS/2 Warp */
}

static int
DART_Init(SDL_AudioDriverImpl *impl)
@@ -451,8 +446,7 @@ DART_Init(SDL_AudioDriverImpl *impl)


AudioBootStrap DART_bootstrap = {
"dart", "OS/2 Direct Audio RouTines (DART)",
DART_Available, DART_Init, 0
"dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */

0 comments on commit cda68e3

Please sign in to comment.