Removed distinction between "available" and "init" in audio backends, since SDL-ryan-multiple-audio-device
authorRyan C. Gordon <icculus@icculus.org>
Tue, 17 Oct 2006 09:09:21 +0000
branchSDL-ryan-multiple-audio-device
changeset 3846 66fb40445587
parent 3845 ee5dfa7f7993
child 4415 2bf2dee62ea7
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.
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
--- 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: */