changeset 3846:66fb40445587 SDL-ryan-multiple-audio-device

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.
author Ryan C. Gordon <icculus@icculus.org>
date Tue, 17 Oct 2006 09:09:21 +0000
parents ee5dfa7f7993
children 2bf2dee62ea7
files src/audio/SDL_audio.c src/audio/SDL_sysaudio.h src/audio/alsa/SDL_alsa_audio.c src/audio/arts/SDL_artsaudio.c src/audio/baudio/SDL_beaudio.cc src/audio/bsd/SDL_bsdaudio.c src/audio/dart/SDL_dart.c src/audio/dc/SDL_dcaudio.c src/audio/disk/SDL_diskaudio.c src/audio/dma/SDL_dmaaudio.c src/audio/dma/SDL_dmaaudio.h src/audio/dmedia/SDL_irixaudio.c src/audio/dsp/SDL_dspaudio.c src/audio/dummy/SDL_dummyaudio.c src/audio/esd/SDL_esdaudio.c src/audio/macosx/SDL_coreaudio.c src/audio/macrom/SDL_romaudio.c src/audio/mint/SDL_mintaudio_dma8.c src/audio/mint/SDL_mintaudio_gsxb.c src/audio/mint/SDL_mintaudio_mcsn.c src/audio/mint/SDL_mintaudio_stfa.c src/audio/mint/SDL_mintaudio_xbios.c src/audio/mme/SDL_mmeaudio.c src/audio/nas/SDL_nasaudio.c src/audio/nto/SDL_nto_audio.c src/audio/paudio/SDL_paudio.c src/audio/windib/SDL_dibaudio.c src/audio/windx5/SDL_dx5audio.c
diffstat 28 files changed, 334 insertions(+), 553 deletions(-) [+]
line wrap: on
line diff
--- a/src/audio/SDL_audio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/SDL_audio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -360,6 +360,7 @@
 {
     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 @@
         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;
-            }
+    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;
         }
-    } 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);
-            }
-        }
+
+        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. */
     }
--- a/src/audio/SDL_sysaudio.h	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/SDL_sysaudio.h	Tue Oct 17 09:09:21 2006 +0000
@@ -107,10 +107,10 @@
 {
     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: */
--- a/src/audio/alsa/SDL_alsa_audio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/alsa/SDL_alsa_audio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -151,12 +151,10 @@
 
 #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 @@
 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 @@
 }
 
 
-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 @@
         }
         SDL_free(this->hidden);
         this->hidden = NULL;
-        UnloadALSALibrary();
     }
 }
 
@@ -401,11 +383,6 @@
     }
     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,15 +576,26 @@
     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;
@@ -615,8 +603,7 @@
 
 
 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: */
--- a/src/audio/arts/SDL_artsaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/arts/SDL_artsaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -126,32 +126,6 @@
 
 #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 @@
         SDL_free(this->hidden);
         this->hidden = NULL;
     }
-    UnloadARTSLibrary();
 }
 
 
@@ -252,12 +225,6 @@
     }
     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,9 +308,33 @@
 }
 
 
+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;
@@ -351,6 +342,7 @@
     impl->GetDeviceBuf = ARTS_GetDeviceBuf;
     impl->CloseDevice = ARTS_CloseDevice;
     impl->WaitDone = ARTS_WaitDone;
+    impl->Deinitialize = ARTS_Deinitialize;
     impl->OnlyHasDefaultOutputDevice = 1;
 
     return 1;
@@ -358,8 +350,7 @@
 
 
 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: */
--- a/src/audio/baudio/SDL_beaudio.cc	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.cc	Tue Oct 17 09:09:21 2006 +0000
@@ -39,12 +39,6 @@
 }
 
 
-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 @@
 
 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: */
--- a/src/audio/bsd/SDL_bsdaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/bsd/SDL_bsdaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -104,17 +104,6 @@
 }
 
 
-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,14 +432,14 @@
 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;
@@ -458,8 +447,7 @@
 
 
 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: */
--- a/src/audio/dart/SDL_dart.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dart/SDL_dart.c	Tue Oct 17 09:09:21 2006 +0000
@@ -427,11 +427,6 @@
     }
 }
 
-static int
-DART_Available(void)
-{
-    return 1;  /* Always available on OS/2 Warp */
-}
 
 static int
 DART_Init(SDL_AudioDriverImpl *impl)
@@ -451,8 +446,7 @@
 
 
 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: */
--- a/src/audio/dc/SDL_dcaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dc/SDL_dcaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -225,12 +225,6 @@
 }
 
 static int
-DCAUD_Available(void)
-{
-    return 1;  /* Dreamcast hardware is always available.  :) */
-}
-
-static int
 DCAUD_Init(SDL_AudioDriverImpl *impl)
 {
     /* Set the function pointers */
@@ -245,8 +239,7 @@
 }
 
 AudioBootStrap DCAUD_bootstrap = {
-    "dcaudio", "Dreamcast AICA audio",
-    DCAUD_Available, DCAUD_Init, 0
+    "dcaudio", "Dreamcast AICA audio", DCAUD_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/disk/SDL_diskaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/disk/SDL_diskaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -57,13 +57,6 @@
     return devname;
 }
 
-/* Audio driver bootstrap functions */
-static int
-DISKAUD_Available(void)
-{
-    return 1;  /* always available. */
-}
-
 /* This function waits until it is possible to write a full sound buffer */
 static void
 DISKAUD_WaitDevice(_THIS)
@@ -158,9 +151,6 @@
 static int
 DISKAUD_Init(SDL_AudioDriverImpl *impl)
 {
-    /* Initialize all variables that we clean on shutdown */
-    SDL_memset(impl, '\0', sizeof (SDL_AudioDriverImpl));
-
     /* Set the function pointers */
     impl->OpenDevice = DISKAUD_OpenDevice;
     impl->WaitDevice = DISKAUD_WaitDevice;
@@ -172,8 +162,7 @@
 }
 
 AudioBootStrap DISKAUD_bootstrap = {
-    DISKAUD_DRIVER_NAME, "direct-to-disk audio",
-    DISKAUD_Available, DISKAUD_Init, 1
+    DISKAUD_DRIVER_NAME, "direct-to-disk audio", DISKAUD_Init, 1
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dma/SDL_dmaaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dma/SDL_dmaaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -116,15 +116,6 @@
     free_device_list(&inputDevices, &inputDeviceCount);
 }
 
-static int
-DMA_Available(void)
-{
-    int available = 0;
-    build_device_lists();
-    available = ((outputDeviceCount > 0) || (inputDeviceCount > 0));
-    free_device_lists();
-    return available;
-}
 
 static void DMA_Deinitialize(void)
 {
@@ -537,8 +528,7 @@
 }
 
 AudioBootStrap DMA_bootstrap = {
-    DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio",
-    DMA_Available, DMA_Init, 0
+    DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio", DMA_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dma/SDL_dmaaudio.h	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dma/SDL_dmaaudio.h	Tue Oct 17 09:09:21 2006 +0000
@@ -21,8 +21,8 @@
 */
 #include "SDL_config.h"
 
-#ifndef _SDL_dspaudio_h
-#define _SDL_dspaudio_h
+#ifndef _SDL_dmaaudio_h
+#define _SDL_dmaaudio_h
 
 #include "../SDL_sysaudio.h"
 
@@ -49,6 +49,7 @@
 #define FUDGE_TICKS	10      /* The scheduler overhead ticks per frame */
 
 /* Old variable names */
+/* !!! FIXME: remove these. */
 #define audio_fd		(this->hidden->audio_fd)
 #define parent			(this->hidden->parent)
 #define dma_buf			(this->hidden->dma_buf)
@@ -57,5 +58,6 @@
 #define frame_ticks		(this->hidden->frame_ticks)
 #define next_frame		(this->hidden->next_frame)
 
-#endif /* _SDL_dspaudio_h */
+#endif /* _SDL_dmaaudio_h */
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dmedia/SDL_irixaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dmedia/SDL_irixaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -45,12 +45,6 @@
 #define alSetWidth(x,y) ALsetwidth(x,y)
 #endif
 
-static int
-IRIXAUDIO_Available(void)
-{
-    return 1;
-}
-
 void static
 IRIXAUDIO_WaitDevice(_THIS)
 {
@@ -236,8 +230,7 @@
 }
 
 AudioBootStrap IRIXAUDIO_bootstrap = {
-    "AL", "IRIX DMedia audio",
-    IRIXAUDIO_Available, IRIXAUDIO_Init, 0
+    "AL", "IRIX DMedia audio", IRIXAUDIO_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dsp/SDL_dspaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dsp/SDL_dspaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -93,17 +93,6 @@
 }
 
 
-static int
-DSP_Available(void)
-{
-    int available = 0;
-    build_device_lists();
-    available = ((outputDeviceCount > 0) || (inputDeviceCount > 0));
-    free_device_lists();
-    return available;
-}
-
-
 static void
 DSP_Deinitialize(void)
 {
@@ -388,8 +377,7 @@
 
 
 AudioBootStrap DSP_bootstrap = {
-    DSP_DRIVER_NAME, "OSS /dev/dsp standard audio",
-    DSP_Available, DSP_Init, 0
+    DSP_DRIVER_NAME, "OSS /dev/dsp standard audio", DSP_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dummy/SDL_dummyaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/dummy/SDL_dummyaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -25,42 +25,27 @@
 
 /* Output audio to nowhere... */
 
-#include "SDL_rwops.h"
-#include "SDL_timer.h"
 #include "SDL_audio.h"
-#include "../SDL_audiomem.h"
 #include "../SDL_audio_c.h"
 #include "SDL_dummyaudio.h"
 
-/* The tag name used by DUMMY audio */
-#define DUMMYAUD_DRIVER_NAME         "dummy"
-
-static int
-DUMMYAUD_Available(void)
-{
-    return 1;  /* always available. */
-}
-
 static int
 DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture)
 {
     return 1;   /* always succeeds. */
 }
 
-
 static int
 DUMMYAUD_Init(SDL_AudioDriverImpl *impl)
 {
     /* Set the function pointers */
     impl->OpenDevice = DUMMYAUD_OpenDevice;
     impl->OnlyHasDefaultOutputDevice = 1;
-
     return 1;
 }
 
 AudioBootStrap DUMMYAUD_bootstrap = {
-    DUMMYAUD_DRIVER_NAME, "SDL dummy audio driver",
-    DUMMYAUD_Available, DUMMYAUD_Init, 1
+    "dummy", "SDL dummy audio driver", DUMMYAUD_Init, 1
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/esd/SDL_esdaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/esd/SDL_esdaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -115,25 +115,6 @@
 
 #endif /* SDL_AUDIO_DRIVER_ESD_DYNAMIC */
 
-static int
-ESD_Available(void)
-{
-    int available = 0;
-    if (LoadESDLibrary() == 0) {
-        int connection;
-        if (SDL_getenv("ESD_NO_SPAWN") == NULL) {
-            SDL_putenv("ESD_NO_SPAWN=1"); /* Don't start ESD if it's not running */
-        }
-        connection = SDL_NAME(esd_open_sound) (NULL);
-        if (connection >= 0) {
-            available = 1;
-            SDL_NAME(esd_close) (connection);
-        }
-        UnloadESDLibrary();
-    }
-    return available;
-}
-
 
 /* This function waits until it is possible to write a full sound buffer */
 static void
@@ -210,7 +191,6 @@
         SDL_free(this->hidden);
         this->hidden = NULL;
     }
-    UnloadESDLibrary();
 }
 
 /* Try to get the name of the program */
@@ -257,12 +237,6 @@
     SDL_memset(this->hidden, 0, (sizeof *this->hidden));
     this->hidden->audio_fd = -1;
 
-    if (LoadESDLibrary() < 0) {
-        ESD_CloseDevice(this);
-        SDL_SetError("ESD: failed to load library: %s", SDL_GetError());
-        return 0;
-    }
-
     /* Convert audio spec to the ESD audio format */
     /* Try for a closest match on audio format */
     for (test_format = SDL_FirstAudioFormat(this->spec.format);
@@ -331,16 +305,41 @@
     return 1;
 }
 
+static void
+ESD_Deinitialize(void)
+{
+    UnloadESDLibrary();
+}
 
 static int
 ESD_Init(SDL_AudioDriverImpl *impl)
 {
+    if (LoadESDLibrary() < 0) {
+        return 0;
+    } else {
+        int connection = 0;
+
+        /* Don't start ESD if it's not running */
+        if (SDL_getenv("ESD_NO_SPAWN") == NULL) {
+            SDL_putenv("ESD_NO_SPAWN=1");
+        }
+
+        connection = SDL_NAME(esd_open_sound) (NULL);
+        if (connection < 0) {
+            UnloadESDLibrary();
+            SDL_SetError("ESD: esd_open_sound failed (no audio server?)");
+            return 0;
+        }
+        SDL_NAME(esd_close) (connection);
+    }
+
     /* Set the function pointers */
     impl->OpenDevice = ESD_OpenDevice;
     impl->PlayDevice = ESD_PlayDevice;
     impl->WaitDevice = ESD_WaitDevice;
     impl->GetDeviceBuf = ESD_GetDeviceBuf;
     impl->CloseDevice = ESD_CloseDevice;
+    impl->Deinitialize = ESD_Deinitialize;
     impl->OnlyHasDefaultOutputDevice = 1;
 
     return 1;
@@ -348,8 +347,7 @@
 
 
 AudioBootStrap ESD_bootstrap = {
-    ESD_DRIVER_NAME, "Enlightened Sound Daemon",
-    ESD_Available, ESD_Init, 0
+    ESD_DRIVER_NAME, "Enlightened Sound Daemon", ESD_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macosx/SDL_coreaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/macosx/SDL_coreaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -201,11 +201,6 @@
     return 0;
 }
 
-static int
-COREAUDIO_Available(void)
-{
-    return 1;  /* always available on Mac OS X. */
-}
 
 static int
 COREAUDIO_DetectDevices(int iscapture)
@@ -582,8 +577,7 @@
 }
 
 AudioBootStrap COREAUDIO_bootstrap = {
-    "coreaudio", "Mac OS X CoreAudio",
-    COREAUDIO_Available, COREAUDIO_Init, 0
+    "coreaudio", "Mac OS X CoreAudio", COREAUDIO_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macrom/SDL_romaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/macrom/SDL_romaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -50,13 +50,6 @@
 #include "../SDL_sysaudio.h"
 #include "SDL_romaudio.h"
 
-static int
-SNDMGR_Available(void)
-{
-    return (1);
-}
-
-
 #pragma options align=power
 
 static volatile SInt32 audio_is_locked = 0;
@@ -320,8 +313,7 @@
 }
 
 AudioBootStrap SNDMGR_bootstrap = {
-    "sndmgr", SDL_MACOS_NAME " SoundManager",
-    SNDMGR_Available, SNDMGR_Init, 0
+    "sndmgr", SDL_MACOS_NAME " SoundManager", SNDMGR_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_dma8.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_dma8.c	Tue Oct 17 09:09:21 2006 +0000
@@ -61,40 +61,6 @@
 
 static unsigned long cookie_snd, cookie_mch;
 
-
-static int
-MINTDMA8_Available(void)
-{
-    /* Cookie _MCH present ? if not, assume ST machine */
-    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
-        cookie_mch = MCH_ST;
-    }
-
-    /* Cookie _SND present ? if not, assume ST machine */
-    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-        cookie_snd = SND_PSG;
-    }
-
-    /* Check if we have 8 bits audio */
-    if ((cookie_snd & SND_8BIT) == 0) {
-        DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
-        return (0);
-    }
-
-    /* Check if audio is lockable */
-    if (cookie_snd & SND_16BIT) {
-        if (Locksnd() != 1) {
-            DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
-            return (0);
-        }
-
-        Unlocksnd();
-    }
-
-    DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
-    return (1);
-}
-
 static void
 MINTDMA8_LockDevice(_THIS)
 {
@@ -330,6 +296,34 @@
 static int
 MINTDMA8_Init(SDL_AudioDriverImpl *impl)
 {
+    /* Cookie _MCH present ? if not, assume ST machine */
+    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+        cookie_mch = MCH_ST;
+    }
+
+    /* Cookie _SND present ? if not, assume ST machine */
+    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+        cookie_snd = SND_PSG;
+    }
+
+    /* Check if we have 8 bits audio */
+    if ((cookie_snd & SND_8BIT) == 0) {
+        SDL_SetError(DEBUG_NAME "no 8 bits sound");
+        return 0;
+    }
+
+    /* Check if audio is lockable */
+    if (cookie_snd & SND_16BIT) {
+        if (Locksnd() != 1) {
+            SDL_SetError(DEBUG_NAME "audio locked by other application");
+            return 0;
+        }
+
+        Unlocksnd();
+    }
+
+    DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
+
     /* Set the function pointers */
     impl->OpenDevice = MINTDMA8_OpenDevice;
     impl->CloseDevice = MINTDMA8_CloseDevice;
@@ -343,8 +337,7 @@
 }
 
 AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
-    MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver",
-    MINTDMA8_Available, MINTDMA8_Init, 0
+    MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", MINTDMA8_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_gsxb.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c	Tue Oct 17 09:09:21 2006 +0000
@@ -67,43 +67,6 @@
 static void MINTGSXB_GsxbInterrupt(void);
 static void MINTGSXB_GsxbNullInterrupt(void);
 
-
-static int
-MINTGSXB_Available(void)
-{
-    /* Cookie _SND present ? if not, assume ST machine */
-    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-        cookie_snd = SND_PSG;
-    }
-
-    /* Check if we have 16 bits audio */
-    if ((cookie_snd & SND_16BIT) == 0) {
-        DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
-        return (0);
-    }
-
-    /* Cookie GSXB present ? */
-    cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
-
-    /* Is it GSXB ? */
-    if (((cookie_snd & SND_GSXB) == 0) || (cookie_gsxb == 0)) {
-        DEBUG_PRINT((DEBUG_NAME "no GSXB audio\n"));
-        return (0);
-    }
-
-    /* Check if audio is lockable */
-    if (Locksnd() != 1) {
-        DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
-        return (0);
-    }
-
-    Unlocksnd();
-
-    DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
-    return (1);
-}
-
-
 static void
 MINTGSXB_LockDevice(_THIS)
 {
@@ -427,6 +390,36 @@
 static int
 MINTGSXB_Init(SDL_AudioDriverImpl *impl)
 {
+    /* Cookie _SND present ? if not, assume ST machine */
+    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+        cookie_snd = SND_PSG;
+    }
+
+    /* Check if we have 16 bits audio */
+    if ((cookie_snd & SND_16BIT) == 0) {
+        SDL_SetError(DEBUG_NAME "no 16-bit sound");
+        return 0;
+    }
+
+    /* Cookie GSXB present ? */
+    cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
+
+    /* Is it GSXB ? */
+    if (((cookie_snd & SND_GSXB) == 0) || (cookie_gsxb == 0)) {
+        SDL_SetError(DEBUG_NAME "no GSXB audio");
+        return 0;
+    }
+
+    /* Check if audio is lockable */
+    if (Locksnd() != 1) {
+        SDL_SetError(DEBUG_NAME "audio locked by other application");
+        return 0;
+    }
+
+    Unlocksnd();
+
+    DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
+
     /* Set the function pointers */
     impl->OpenDevice = MINTGSXB_OpenDevice;
     impl->CloseDevice = MINTGSXB_CloseDevice;
@@ -440,8 +433,7 @@
 }
 
 AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
-    MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver",
-    MINTGSXB_Available, MINTGSXB_Init, 0
+    MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver", MINTGSXB_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_mcsn.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c	Tue Oct 17 09:09:21 2006 +0000
@@ -65,58 +65,6 @@
 static unsigned long cookie_mch = 0;
 static cookie_mcsn_t *cookie_mcsn = NULL;
 
-static int
-MINTMCSN_Available(void)
-{
-    unsigned long dummy = 0;
-
-    SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
-
-    /* We can't use XBIOS in interrupt with Magic, don't know about thread */
-    if (Getcookie(C_MagX, &dummy) == C_FOUND) {
-        return (0);
-    }
-
-    /* Cookie _MCH present ? if not, assume ST machine */
-    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
-        cookie_mch = MCH_ST;
-    }
-
-    /* Cookie _SND present ? if not, assume ST machine */
-    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-        cookie_snd = SND_PSG;
-    }
-
-    /* Check if we have 16 bits audio */
-    if ((cookie_snd & SND_16BIT) == 0) {
-        DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
-        return (0);
-    }
-
-    /* Cookie MCSN present ? */
-    if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
-        DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n"));
-        return (0);
-    }
-
-    /* Check if interrupt at end of replay */
-    if (cookie_mcsn->pint == 0) {
-        DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n"));
-        return (0);
-    }
-
-    /* Check if audio is lockable */
-    if (Locksnd() != 1) {
-        DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
-        return (0);
-    }
-
-    Unlocksnd();
-
-    DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
-    return (1);
-}
-
 static void
 MINTMCSN_LockDevice(_THIS)
 {
@@ -381,6 +329,53 @@
 static int
 MINTMCSN_Init(SDL_AudioDriverImpl *impl)
 {
+    unsigned long dummy = 0;
+
+    SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
+
+    /* We can't use XBIOS in interrupt with Magic, don't know about thread */
+    if (Getcookie(C_MagX, &dummy) == C_FOUND) {
+        return 0;
+    }
+
+    /* Cookie _MCH present ? if not, assume ST machine */
+    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+        cookie_mch = MCH_ST;
+    }
+
+    /* Cookie _SND present ? if not, assume ST machine */
+    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+        cookie_snd = SND_PSG;
+    }
+
+    /* Check if we have 16 bits audio */
+    if ((cookie_snd & SND_16BIT) == 0) {
+        SDL_SetError(DEBUG_NAME "no 16-bit sound");
+        return 0;
+    }
+
+    /* Cookie MCSN present ? */
+    if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
+        SDL_SetError(DEBUG_NAME "no MCSN audio");
+        return 0;
+    }
+
+    /* Check if interrupt at end of replay */
+    if (cookie_mcsn->pint == 0) {
+        SDL_SetError(DEBUG_NAME "no interrupt at end of replay");
+        return 0;
+    }
+
+    /* Check if audio is lockable */
+    if (Locksnd() != 1) {
+        SDL_SetError(DEBUG_NAME "audio locked by other application");
+        return 0;
+    }
+
+    Unlocksnd();
+
+    DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
+
     /* Set the function pointers */
     impl->OpenDevice = MINTMCSN_OpenDevice;
     impl->CloseDevice = MINTMCSN_CloseDevice;
@@ -394,8 +389,7 @@
 }
 
 AudioBootStrap MINTAUDIO_MCSN_bootstrap = {
-    MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver",
-    MINTMCSN_Available, MINTMCSN_Init, 0
+    MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", MINTMCSN_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_stfa.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_stfa.c	Tue Oct 17 09:09:21 2006 +0000
@@ -70,31 +70,6 @@
     30720, 32336, 43885, 49152
 };
 
-static int
-MINTSTFA_Available(void)
-{
-    /* Cookie _MCH present ? if not, assume ST machine */
-    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
-        cookie_mch = MCH_ST;
-    }
-
-    /* Cookie _SND present ? if not, assume ST machine */
-    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-        cookie_snd = SND_PSG;
-    }
-
-    /* Cookie STFA present ? */
-    if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) {
-        DEBUG_PRINT((DEBUG_NAME "no STFA audio\n"));
-        return (0);
-    }
-
-    SDL_MintAudio_stfa = cookie_stfa;
-
-    DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
-    return (1);
-}
-
 static void
 MINTSTFA_LockDevice(_THIS)
 {
@@ -288,6 +263,26 @@
 static int
 MINTSTFA_Init(SDL_AudioDriverImpl *impl)
 {
+    /* Cookie _MCH present ? if not, assume ST machine */
+    if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+        cookie_mch = MCH_ST;
+    }
+
+    /* Cookie _SND present ? if not, assume ST machine */
+    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+        cookie_snd = SND_PSG;
+    }
+
+    /* Cookie STFA present ? */
+    if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) {
+        SDL_SetError(DEBUG_NAME "no STFA audio");
+        return (0);
+    }
+
+    SDL_MintAudio_stfa = cookie_stfa;
+
+    DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
+
     /* Set the function pointers */
     impl->OpenDevice = MINTSTFA_OpenDevice;
     impl->CloseDevice = MINTSTFA_CloseDevice;
@@ -301,8 +296,7 @@
 }
 
 AudioBootStrap MINTAUDIO_STFA_bootstrap = {
-    MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver",
-    MINTSTFA_Available, MINTSTFA_Init, 0
+    MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", MINTSTFA_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_xbios.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_xbios.c	Tue Oct 17 09:09:21 2006 +0000
@@ -62,41 +62,6 @@
 
 static unsigned long cookie_snd = 0;
 
-static int
-MINTXBIOS_Available(void)
-{
-    unsigned long dummy = 0;
-    /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); */
-    SDL_MintAudio_mint_present = SDL_FALSE;
-
-    /* We can't use XBIOS in interrupt with Magic, don't know about thread */
-    if (Getcookie(C_MagX, &dummy) == C_FOUND) {
-        return (0);
-    }
-
-    /* Cookie _SND present ? if not, assume ST machine */
-    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-        cookie_snd = SND_PSG;
-    }
-
-    /* Check if we have 16 bits audio */
-    if ((cookie_snd & SND_16BIT) == 0) {
-        DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
-        return (0);
-    }
-
-    /* Check if audio is lockable */
-    if (Locksnd() != 1) {
-        DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
-        return (0);
-    }
-
-    Unlocksnd();
-
-    DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n"));
-    return (1);
-}
-
 static void
 MINTXBIOS_LockDevice(_THIS)
 {
@@ -481,6 +446,36 @@
 static int
 MINTXBIOS_Init(SDL_AudioDriverImpl *impl)
 {
+    unsigned long dummy = 0;
+    /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); */
+    SDL_MintAudio_mint_present = SDL_FALSE;
+
+    /* We can't use XBIOS in interrupt with Magic, don't know about thread */
+    if (Getcookie(C_MagX, &dummy) == C_FOUND) {
+        return (0);
+    }
+
+    /* Cookie _SND present ? if not, assume ST machine */
+    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+        cookie_snd = SND_PSG;
+    }
+
+    /* Check if we have 16 bits audio */
+    if ((cookie_snd & SND_16BIT) == 0) {
+        SDL_SetError(DEBUG_NAME "no 16-bit sound");
+        return (0);
+    }
+
+    /* Check if audio is lockable */
+    if (Locksnd() != 1) {
+        SDL_SetError(DEBUG_NAME "audio locked by other application");
+        return (0);
+    }
+
+    Unlocksnd();
+
+    DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n"));
+
     /* Set the function pointers */
     impl->OpenDevice = MINTXBIOS_OpenDevice;
     impl->CloseDevice = MINTXBIOS_CloseDevice;
@@ -494,8 +489,7 @@
 }
 
 AudioBootStrap MINTAUDIO_XBIOS_bootstrap = {
-    MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver",
-    MINTXBIOS_Available, MINTXBIOS_Init, 0
+    MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver", MINTXBIOS_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mme/SDL_mmeaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/mme/SDL_mmeaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -31,12 +31,6 @@
 
 static BOOL inUse[NUM_BUFFERS];
 
-static int
-MME_Available(void)
-{
-    return 1;
-}
-
 static void
 SetMMerror(char *function, MMRESULT code)
 {
@@ -260,8 +254,7 @@
 
 /* !!! FIXME: Windows "windib" driver is called waveout, too */
 AudioBootStrap MMEAUDIO_bootstrap = {
-    "waveout", "Tru64 MME WaveOut",
-    MME_Available, MME_Init, 0
+    "waveout", "Tru64 MME WaveOut", MME_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/nas/SDL_nasaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/nas/SDL_nasaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -97,12 +97,10 @@
 
 #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
 
-static int library_load_count = 0;
-
 static void
 UnloadNASLibrary(void)
 {
-    if ((nas_handle != NULL) && (--library_load_count == 0)) {
+    if (nas_handle != NULL) {
         SDL_UnloadObject(nas_handle);
         nas_handle = NULL;
     }
@@ -112,7 +110,7 @@
 LoadNASLibrary(void)
 {
     int retval = 0;
-    if (library_load_count++ == 0) {
+    if (nas_handle == NULL) {
         nas_handle = SDL_LoadObject(nas_library);
         if (nas_handle == NULL) {
             /* Copy error string so we can use it in a new SDL_SetError(). */
@@ -120,8 +118,6 @@
             size_t len = SDL_strlen(origerr) + 1;
             char *err = (char *) alloca(len);
             SDL_strlcpy(err, origerr, len);
-
-            library_load_count--;
             retval = -1;
             SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s\n",
                           nas_library, err);
@@ -151,21 +147,6 @@
 
 #endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */
 
-static int
-NAS_Available(void)
-{
-    int available = 0;
-    if (LoadNASLibrary() >= 0) {
-        AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
-        if (aud != NULL) {
-            available = 1;
-            NAS_AuCloseServer(aud);
-        }
-        UnloadNASLibrary();
-    }
-    return available;
-}
-
 /* This function waits until it is possible to write a full sound buffer */
 static void
 NAS_WaitDevice(_THIS)
@@ -223,7 +204,6 @@
         }
         SDL_free(this->hidden);
         this2 = this->hidden = NULL;
-        UnloadNASLibrary();
     }
 }
 
@@ -316,11 +296,6 @@
     }
     SDL_memset(this->hidden, 0, (sizeof *this->hidden));
 
-    if (LoadNASLibrary() < 0) {
-        NAS_CloseDevice(this);
-        return 0;
-    }
-
     /* Try for a closest match on audio format */
     format = 0;
     for (test_format = SDL_FirstAudioFormat(this->spec.format);
@@ -390,23 +365,40 @@
     return 1;
 }
 
+static void
+NAS_Deinitialize(void)
+{
+    UnloadNASLibrary();
+}
+
 static int
 NAS_Init(SDL_AudioDriverImpl *impl)
 {
+    if (LoadNASLibrary() < 0) {
+        return 0;
+    } else {
+        AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
+        if (aud == NULL) {
+            SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
+            return 0;
+        }
+        NAS_AuCloseServer(aud);
+    }
+
     /* Set the function pointers */
     impl->OpenDevice = NAS_OpenDevice;
     impl->PlayDevice = NAS_PlayDevice;
     impl->WaitDevice = NAS_WaitDevice;
     impl->GetDeviceBuf = NAS_GetDeviceBuf;
     impl->CloseDevice = NAS_CloseDevice;
+    impl->Deinitialize = NAS_Deinitialize;
     impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: is this true? */
 
     return 1;
 }
 
 AudioBootStrap NAS_bootstrap = {
-    NAS_DRIVER_NAME, "Network Audio System",
-    NAS_Available, NAS_Init, 0
+    NAS_DRIVER_NAME, "Network Audio System", NAS_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/nto/SDL_nto_audio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/nto/SDL_nto_audio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -129,26 +129,6 @@
     cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX;
 }
 
-static int
-NTO_Available(void)
-{
-    /*  See if we can open a nonblocking channel.
-       Return value '1' means we can.
-       Return value '0' means we cannot. */
-
-    int available = 0;
-    snd_pcm_t *handle = NULL;
-    int rval = snd_pcm_open_preferred(&handle, NULL, NULL, OPEN_FLAGS);
-    if (rval >= 0) {
-        available = 1;
-        if ((rval = snd_pcm_close(handle)) < 0) {
-            available = 0;
-        }
-    }
-
-    return (available);
-}
-
 
 /* This function waits until it is possible to write a full sound buffer */
 static void
@@ -452,6 +432,18 @@
 static int
 NTO_Init(SDL_AudioDriverImpl *impl)
 {
+    /*  See if we can open a nonblocking channel. */
+    snd_pcm_t *handle = NULL;
+    int rval = snd_pcm_open_preferred(&handle, NULL, NULL, OPEN_FLAGS);
+    if (rval < 0) {
+        SDL_SetError("NTO: couldn't open preferred audio device");
+        return 0;
+    }
+    if ((rval = snd_pcm_close(handle)) < 0) {
+        SDL_SetError("NTO: couldn't close test audio device");
+        return 0;
+    }
+
     /* Set the function pointers */
     impl->OpenDevice = NTO_OpenDevice;
     impl->ThreadInit = NTO_ThreadInit;
@@ -465,8 +457,7 @@
 }
 
 AudioBootStrap QNXNTOAUDIO_bootstrap = {
-    DRIVER_NAME, "QNX6 QSA-NTO Audio",
-    NTO_AudioAvailable, NTO_Init, 0
+    DRIVER_NAME, "QNX6 QSA-NTO Audio", NTO_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/paudio/SDL_paudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/paudio/SDL_paudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -126,23 +126,6 @@
     return -1;
 }
 
-
-static int
-PAUDIO_Available(void)
-{
-    int fd;
-    int available;
-
-    available = 0;
-    fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
-    if (fd >= 0) {
-        available = 1;
-        close(fd);
-    }
-    return (available);
-}
-
-
 /* This function waits until it is possible to write a full sound buffer */
 static void
 PAUDIO_WaitDevice(_THIS)
@@ -543,6 +526,13 @@
 static int
 PAUDIO_Init(SDL_AudioDriverImpl *impl)
 {
+    int fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
+    if (fd < 0) {
+        SDL_SetError("PAUDIO: Couldn't open audio device");
+        return 0;
+    }
+    close(fd);
+
     /* Set the function pointers */
     impl->OpenDevice = DSP_OpenDevice;
     impl->PlayDevice = DSP_PlayDevice;
@@ -555,8 +545,7 @@
 }
 
 AudioBootStrap PAUDIO_bootstrap = {
-    PAUDIO_DRIVER_NAME, "AIX Paudio",
-    PAUDIO_Available, PAUDIO_Init, 0
+    PAUDIO_DRIVER_NAME, "AIX Paudio", PAUDIO_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/windib/SDL_dibaudio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/windib/SDL_dibaudio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -43,12 +43,6 @@
 #define WINDOWS_OS_NAME "Win32"
 #endif
 
-static int
-WINWAVEOUT_Available(void)
-{
-    return 1;   /* Always available on win32/pocketpc systems... */
-}
-
 /* The Win32 callback for filling the WAVE device */
 static void CALLBACK
 FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
@@ -336,8 +330,7 @@
 }
 
 AudioBootStrap WINWAVEOUT_bootstrap = {
-    "waveout", WINDOWS_OS_NAME " WaveOut",
-    WINWAVEOUT_Available, WINWAVEOUT_Init, 0
+    "waveout", WINDOWS_OS_NAME " WaveOut", WINWAVEOUT_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/windx5/SDL_dx5audio.c	Tue Oct 17 08:04:51 2006 +0000
+++ b/src/audio/windx5/SDL_dx5audio.c	Tue Oct 17 09:09:21 2006 +0000
@@ -88,37 +88,6 @@
 }
 
 
-
-
-static int
-DSOUND_Available(void)
-{
-    int dsound_ok = 1;
-    OSVERSIONINFO ver;
-
-    /*
-     * Unfortunately, the sound drivers on NT have higher latencies than the
-     *  audio buffers used by many SDL applications, so there are gaps in the
-     *  audio - it sounds terrible.  Punt for now.
-     */
-    SDL_memset(&ver, '\0', sizeof (OSVERSIONINFO));
-    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    GetVersionEx(&ver);
-    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
-        if (ver.dwMajorVersion <= 4) {
-            dsound_ok = 0;  /* NT4.0 or earlier. Disable dsound support. */
-        }
-    }
-
-    if (dsound_ok) {
-        dsound_ok = DSOUND_Load();  /* make sure we really have DX5. */
-        DSOUND_Unload();
-    }
-
-    return (dsound_ok);
-}
-
-
 static void
 SetDSerror(const char *function, int code)
 {
@@ -506,8 +475,23 @@
 static int
 DSOUND_Init(SDL_AudioDriverImpl *impl)
 {
-    /* Load DirectX */
-    if (DSOUND_Load() < 0) {
+    OSVERSIONINFO ver;
+
+    /*
+     * Unfortunately, the sound drivers on NT have higher latencies than the
+     *  audio buffers used by many SDL applications, so there are gaps in the
+     *  audio - it sounds terrible.  Punt for now.
+     */
+    SDL_memset(&ver, '\0', sizeof (OSVERSIONINFO));
+    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx(&ver);
+    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
+        if (ver.dwMajorVersion <= 4) {
+            return 0;  /* NT4.0 or earlier. Disable dsound support. */
+        }
+    }
+
+    if (!DSOUND_Load()) {
         return 0;
     }
 
@@ -526,8 +510,7 @@
 }
 
 AudioBootStrap DSOUND_bootstrap = {
-    "dsound", WINDOWS_OS_NAME "DirectSound",
-    DSOUND_Available, DSOUND_Init, 0
+    "dsound", WINDOWS_OS_NAME "DirectSound", DSOUND_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */