Updated a bunch of audio backends to 1.3 API (Dreamcast, OS/2, ALSA, and SDL-ryan-multiple-audio-device
authorRyan C. Gordon <icculus@icculus.org>
Fri, 06 Oct 2006 20:36:23 +0000
branchSDL-ryan-multiple-audio-device
changeset 3819 b225d9820ee3
parent 3818 49eadd6e8962
child 3820 1f156fd874fa
Updated a bunch of audio backends to 1.3 API (Dreamcast, OS/2, ALSA, and BeOS). None are tested, so anyu could fail to compile.
src/audio/alsa/SDL_alsa_audio.c
src/audio/alsa/SDL_alsa_audio.h
src/audio/baudio/SDL_beaudio.cc
src/audio/baudio/SDL_beaudio.h
src/audio/dart/SDL_dart.c
src/audio/dart/SDL_dart.h
src/audio/dc/SDL_dcaudio.c
--- a/src/audio/alsa/SDL_alsa_audio.c	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/alsa/SDL_alsa_audio.c	Fri Oct 06 20:36:23 2006 +0000
@@ -42,13 +42,6 @@
 /* The default ALSA audio driver */
 #define DEFAULT_DEVICE	"default"
 
-/* Audio driver functions */
-static int ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void ALSA_WaitAudio(_THIS);
-static void ALSA_PlayAudio(_THIS);
-static Uint8 *ALSA_GetAudioBuf(_THIS);
-static void ALSA_CloseAudio(_THIS);
-
 static int (*ALSA_snd_pcm_open)
                 (snd_pcm_t **, const char *, snd_pcm_stream_t, int);
 static int (*ALSA_snd_pcm_close)(snd_pcm_t * pcm);
@@ -148,10 +141,14 @@
     return 0;
 }
 
+#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
+
+static int library_load_count = 0;
+
 static void
 UnloadALSALibrary(void)
 {
-    if (alsa_handle != NULL) {
+    if ((alsa_handle != NULL) && (--library_load_count == 0)) {
         dlclose(alsa_handle);
         alsa_handle = NULL;
     }
@@ -160,16 +157,19 @@
 static int
 LoadALSALibrary(void)
 {
-    int i, retval = -1;
-
-    alsa_handle = dlopen(alsa_library, RTLD_NOW);
-    if (alsa_handle == NULL) {
-        SDL_SetError("ALSA: dlopen('%s') failed: %s\n",
-                      alsa_library, strerror(errno));
-    } else {
-        retval = load_alsa_syms();
-        if (retval < 0) {
-            UnloadALSALibrary();
+    int retval = 0;
+    if (library_load_count++ == 0) {
+        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));
+        } else {
+            retval = load_alsa_syms();
+            if (retval < 0) {
+                UnloadALSALibrary();
+            }
         }
     }
     return retval;
@@ -180,7 +180,6 @@
 static void
 UnloadALSALibrary(void)
 {
-    return;
 }
 
 static int
@@ -209,79 +208,32 @@
     return device;
 }
 
-/* Audio driver bootstrap functions */
 
 static int
-Audio_Available(void)
+ALSA_Available(void)
 {
-    int available;
+    int available = 0;
     int status;
     snd_pcm_t *handle;
 
-    available = 0;
-    if (LoadALSALibrary() < 0) {
-        return available;
+    if (LoadALSALibrary() >= 0) {
+        int status = ALSA_snd_pcm_open(&handle, get_audio_device(2),
+                                       SND_PCM_STREAM_PLAYBACK,
+                                       SND_PCM_NONBLOCK);
+        if (status >= 0) {
+            available = 1;
+            ALSA_snd_pcm_close(handle);
+        }
+        UnloadALSALibrary();
     }
-    status = ALSA_snd_pcm_open(&handle, get_audio_device(2),
-                               SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-    if (status >= 0) {
-        available = 1;
-        ALSA_snd_pcm_close(handle);
-    }
-    UnloadALSALibrary();
     return (available);
 }
 
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
-    SDL_free(device->hidden);
-    SDL_free(device);
-    UnloadALSALibrary();
-}
 
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
-{
-    SDL_AudioDevice *this;
-
-    /* Initialize all variables that we clean on shutdown */
-    LoadALSALibrary();
-    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
-    if (this) {
-        SDL_memset(this, 0, (sizeof *this));
-        this->hidden = (struct SDL_PrivateAudioData *)
-            SDL_malloc((sizeof *this->hidden));
-    }
-    if ((this == NULL) || (this->hidden == NULL)) {
-        SDL_OutOfMemory();
-        if (this) {
-            SDL_free(this);
-        }
-        return (0);
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
-    /* Set the function pointers */
-    this->OpenAudio = ALSA_OpenAudio;
-    this->WaitAudio = ALSA_WaitAudio;
-    this->PlayAudio = ALSA_PlayAudio;
-    this->GetAudioBuf = ALSA_GetAudioBuf;
-    this->CloseAudio = ALSA_CloseAudio;
-
-    this->free = Audio_DeleteDevice;
-
-    return this;
-}
-
-AudioBootStrap ALSA_bootstrap = {
-    DRIVER_NAME, "ALSA 0.9 PCM audio",
-    Audio_Available, Audio_CreateDevice, 0
-};
 
 /* This function waits until it is possible to write a full sound buffer */
 static void
-ALSA_WaitAudio(_THIS)
+ALSA_WaitDevice(_THIS)
 {
     /* Check to see if the thread-parent process is still alive */
     {
@@ -289,8 +241,9 @@
         /* Note that this only works with thread implementations 
            that use a different process id for each thread.
          */
-        if (parent && (((++cnt) % 10) == 0)) {  /* Check every 10 loops */
-            if (kill(parent, 0) < 0) {
+        /* Check every 10 loops */
+        if (this->hidden->parent && (((++cnt) % 10) == 0)) {
+            if (kill(this->hidden->parent, 0) < 0) {
                 this->enabled = 0;
             }
         }
@@ -298,13 +251,14 @@
 }
 
 
+/* !!! FIXME: is there a channel swizzler in alsalib instead? */
 /*
  * http://bugzilla.libsdl.org/show_bug.cgi?id=110
  * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
  *  and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
  */
 #define SWIZ6(T) \
-    T *ptr = (T *) mixbuf; \
+    T *ptr = (T *) this->hidden->mixbuf; \
     const Uint32 count = (this->spec.samples / 6); \
     Uint32 i; \
     for (i = 0; i < count; i++, ptr += 6) { \
@@ -338,8 +292,8 @@
 
 
 /*
- * Called right before feeding this->mixbuf to the hardware. Swizzle channels
- *  from Windows/Mac order to the format alsalib will want.
+ * Called right before feeding this->hidden->mixbuf to the hardware. Swizzle
+ *  channels from Windows/Mac order to the format alsalib will want.
  */
 static __inline__ void
 swizzle_alsa_channels(_THIS)
@@ -361,7 +315,7 @@
 
 
 static void
-ALSA_PlayAudio(_THIS)
+ALSA_PlayDevice(_THIS)
 {
     int status;
     int sample_len;
@@ -370,10 +324,12 @@
     swizzle_alsa_channels(this);
 
     sample_len = this->spec.samples;
-    sample_buf = (signed short *) mixbuf;
+    sample_buf = (signed short *) this->hidden->mixbuf;
 
     while (sample_len > 0) {
-        status = ALSA_snd_pcm_writei(pcm_handle, sample_buf, sample_len);
+        status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
+                                     sample_buf, sample_len);
+
         if (status < 0) {
             if (status == -EAGAIN) {
                 SDL_Delay(1);
@@ -382,11 +338,11 @@
             if (status == -ESTRPIPE) {
                 do {
                     SDL_Delay(1);
-                    status = ALSA_snd_pcm_resume(pcm_handle);
+                    status = ALSA_snd_pcm_resume(this->hidden->pcm_handle);
                 } while (status == -EAGAIN);
             }
             if (status < 0) {
-                status = ALSA_snd_pcm_prepare(pcm_handle);
+                status = ALSA_snd_pcm_prepare(this->hidden->pcm_handle);
             }
             if (status < 0) {
                 /* Hmm, not much we can do - abort */
@@ -401,72 +357,89 @@
 }
 
 static Uint8 *
-ALSA_GetAudioBuf(_THIS)
+ALSA_GetDeviceBuf(_THIS)
 {
-    return (mixbuf);
+    return (this->hidden->mixbuf);
 }
 
 static void
-ALSA_CloseAudio(_THIS)
+ALSA_CloseDevice(_THIS)
 {
-    if (mixbuf != NULL) {
-        SDL_FreeAudioMem(mixbuf);
-        mixbuf = NULL;
-    }
-    if (pcm_handle) {
-        ALSA_snd_pcm_drain(pcm_handle);
-        ALSA_snd_pcm_close(pcm_handle);
-        pcm_handle = NULL;
+    if (this->hidden != NULL) {
+        if (this->hidden->mixbuf != NULL) {
+            SDL_FreeAudioMem(this->hidden->mixbuf);
+            this->hidden->mixbuf = NULL;
+        }
+        if (this->hidden->pcm_handle) {
+            ALSA_snd_pcm_drain(this->hidden->pcm_handle);
+            ALSA_snd_pcm_close(this->hidden->pcm_handle);
+            this->hidden->pcm_handle = NULL;
+        }
+        SDL_free(this->hidden);
+        this->hidden = NULL;
     }
 }
 
 static int
-ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec)
+ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
 {
-    int status;
-    snd_pcm_hw_params_t *hwparams;
-    snd_pcm_sw_params_t *swparams;
-    snd_pcm_format_t format;
-    snd_pcm_uframes_t frames;
-    SDL_AudioFormat test_format;
+    int status = 0;
+    snd_pcm_t *pcm_handle = NULL;
+    snd_pcm_hw_params_t *hwparams = NULL;
+    snd_pcm_sw_params_t *swparams = NULL;
+    snd_pcm_format_t format = 0;
+    snd_pcm_uframes_t frames = 0;
+    SDL_AudioFormat test_format = 0;
+
+    /* Initialize all variables that we clean on shutdown */
+    this->hidden = (struct SDL_PrivateAudioData *)
+                        SDL_malloc((sizeof *this->hidden));
+    if (this->hidden == NULL) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
 
     /* Open the audio device */
     /* Name of device should depend on # channels in spec */
     status = ALSA_snd_pcm_open(&pcm_handle,
-                               get_audio_device(spec->channels),
+                               get_audio_device(this->spec.channels),
                                SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
 
     if (status < 0) {
-        SDL_SetError("Couldn't open audio device: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't open audio device: %s",
                      ALSA_snd_strerror(status));
-        return (-1);
+        return 0;
     }
 
+    this->hidden->pcm_handle = pcm_handle;
+
     /* Figure out what the hardware is capable of */
     snd_pcm_hw_params_alloca(&hwparams);
     status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
     if (status < 0) {
-        SDL_SetError("Couldn't get hardware config: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't get hardware config: %s",
                      ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
 
     /* SDL only uses interleaved sample output */
     status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
                                                SND_PCM_ACCESS_RW_INTERLEAVED);
     if (status < 0) {
-        SDL_SetError("Couldn't set interleaved access: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't set interleaved access: %s",
                      ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
 
     /* Try for a closest match on audio format */
     status = -1;
-    for (test_format = SDL_FirstAudioFormat(spec->format);
+    for (test_format = SDL_FirstAudioFormat(this->spec.format);
          test_format && (status < 0);) {
-        status = 0;             /* if we can't support a format, it'll become -1. */
+        status = 0;      /* if we can't support a format, it'll become -1. */
         switch (test_format) {
         case AUDIO_U8:
             format = SND_PCM_FORMAT_U8;
@@ -511,112 +484,133 @@
         }
     }
     if (status < 0) {
-        SDL_SetError("Couldn't find any hardware audio formats");
-        ALSA_CloseAudio(this);
-        return (-1);
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't find any hardware audio formats");
+        return 0;
     }
-    spec->format = test_format;
+    this->spec.format = test_format;
 
     /* Set the number of channels */
     status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
-                                                 spec->channels);
+                                                 this->spec.channels);
     if (status < 0) {
         status = ALSA_snd_pcm_hw_params_get_channels(hwparams);
         if ((status <= 0) || (status > 2)) {
-            SDL_SetError("Couldn't set audio channels");
-            ALSA_CloseAudio(this);
-            return (-1);
+            ALSA_CloseDevice(this);
+            SDL_SetError("ALSA: Couldn't set audio channels");
+            return 0;
         }
-        spec->channels = status;
+        this->spec.channels = status;
     }
 
     /* Set the audio rate */
     status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
-                                                  spec->freq, NULL);
+                                                  this->spec.freq, NULL);
     if (status < 0) {
-        ALSA_CloseAudio(this);
-        SDL_SetError("Couldn't set audio frequency: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't set audio frequency: %s",
                      ALSA_snd_strerror(status));
-        return (-1);
+        return 0;
     }
-    spec->freq = status;
+    this->spec.freq = status;
 
     /* Set the buffer size, in samples */
-    frames = spec->samples;
+    frames = this->spec.samples;
     frames = ALSA_snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams,
                                                          frames, NULL);
-    spec->samples = frames;
+    this->spec.samples = frames;
     ALSA_snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, 2, NULL);
 
     /* "set" the hardware with the desired parameters */
     status = ALSA_snd_pcm_hw_params(pcm_handle, hwparams);
     if (status < 0) {
-        ALSA_CloseAudio(this);
-        SDL_SetError("Couldn't set hardware audio parameters: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't set hardware audio parameters: %s",
                      ALSA_snd_strerror(status));
-        return (-1);
+        return 0;
     }
 
-/* This is useful for debugging... */
-/*
-{ snd_pcm_sframes_t bufsize; int fragments;
-   bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
-   fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
-
-   fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments);
+#if AUDIO_DEBUG
+{
+    snd_pcm_sframes_t bufsize;
+    int fragments;
+    bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
+    fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
+    fprintf(stderr,"ALSA: bufsize = %ld, fragments = %d\n",bufsize,fragments);
 }
-*/
+#endif
 
     /* Set the software parameters */
     snd_pcm_sw_params_alloca(&swparams);
     status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
     if (status < 0) {
-        SDL_SetError("Couldn't get software config: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't get software config: %s",
                      ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
     status = ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle,swparams,0);
     if (status < 0) {
-        SDL_SetError("Couldn't set start threshold: %s",
+        ALSA_CloseDevice(this);
+        SDL_SetError("ALSA: Couldn't set start threshold: %s",
                      ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
     status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, frames);
     if (status < 0) {
+        ALSA_CloseDevice(this);
         SDL_SetError("Couldn't set avail min: %s", ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
     status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
     if (status < 0) {
+        ALSA_CloseDevice(this);
         SDL_SetError("Couldn't set software audio parameters: %s",
                      ALSA_snd_strerror(status));
-        ALSA_CloseAudio(this);
-        return (-1);
+        return 0;
     }
 
     /* Calculate the final parameters for this audio specification */
-    SDL_CalculateAudioSpec(spec);
+    SDL_CalculateAudioSpec(&this->spec);
 
     /* Allocate mixing buffer */
-    mixlen = spec->size;
-    mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
-    if (mixbuf == NULL) {
-        ALSA_CloseAudio(this);
-        return (-1);
+    this->hidden->mixlen = this->spec.size;
+    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+    if (this->hidden->mixbuf == NULL) {
+        ALSA_CloseDevice(this);
+        SDL_OutOfMemory();
+        return 0;
     }
-    SDL_memset(mixbuf, spec->silence, spec->size);
+    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
 
     /* Get the parent process id (we're the parent of the audio thread) */
-    parent = getpid();
+    this->hidden->parent = getpid();
 
     /* Switch to blocking mode for playback */
     ALSA_snd_pcm_nonblock(pcm_handle, 0);
 
     /* We're ready to rock and roll. :-) */
-    return (0);
+    return 1;
 }
 
+static int
+ALSA_Init(SDL_AudioDriverImpl *impl)
+{
+    /* 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->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: Add device enum! */
+
+    return 1;
+}
+
+
+AudioBootStrap ALSA_bootstrap = {
+    DRIVER_NAME, "ALSA 0.9 PCM audio",
+    ALSA_Available, ALSA_Init, 0
+};
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/alsa/SDL_alsa_audio.h	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/alsa/SDL_alsa_audio.h	Fri Oct 06 20:36:23 2006 +0000
@@ -46,11 +46,5 @@
     int mixlen;
 };
 
-/* Old variable names */
-#define pcm_handle		(this->hidden->pcm_handle)
-#define parent			(this->hidden->parent)
-#define mixbuf			(this->hidden->mixbuf)
-#define mixlen			(this->hidden->mixlen)
-
 #endif /* _ALSA_PCM_audio_h */
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/baudio/SDL_beaudio.cc	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.cc	Fri Oct 06 20:36:23 2006 +0000
@@ -36,138 +36,95 @@
 #include "../../thread/beos/SDL_systhread_c.h"
 #include "SDL_beaudio.h"
 
+}
 
-/* Audio driver functions */
-    static int BE_OpenAudio(_THIS, SDL_AudioSpec * spec);
-    static void BE_WaitAudio(_THIS);
-    static void BE_PlayAudio(_THIS);
-    static Uint8 *BE_GetAudioBuf(_THIS);
-    static void BE_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
 
-    static int Audio_Available(void)
-    {
-        return (1);
-    }
+static int BEAUDIO_Available(void)
+{
+    return 1;  /* Always available on BeOS. */
+}
 
-    static void Audio_DeleteDevice(SDL_AudioDevice * device)
-    {
-        SDL_free(device->hidden);
-        SDL_free(device);
-    }
-
-    static SDL_AudioDevice *Audio_CreateDevice(int devindex)
-    {
-        SDL_AudioDevice *device;
 
-        /* Initialize all variables that we clean on shutdown */
-        device = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
-        if (device) {
-            SDL_memset(device, 0, (sizeof *device));
-            device->hidden = (struct SDL_PrivateAudioData *)
-                SDL_malloc((sizeof *device->hidden));
-        }
-        if ((device == NULL) || (device->hidden == NULL)) {
-            SDL_OutOfMemory();
-            if (device) {
-                SDL_free(device);
-            }
-            return (0);
-        }
-        SDL_memset(device->hidden, 0, (sizeof *device->hidden));
-
-        /* Set the function pointers */
-        device->OpenAudio = BE_OpenAudio;
-        device->WaitAudio = BE_WaitAudio;
-        device->PlayAudio = BE_PlayAudio;
-        device->GetAudioBuf = BE_GetAudioBuf;
-        device->CloseAudio = BE_CloseAudio;
-
-        device->free = Audio_DeleteDevice;
+/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
+/* The BeOS callback for handling the audio buffer */
+static void
+FillSound(void *device, void *stream, size_t len,
+          const media_raw_audio_format & format)
+{
+    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
 
-        return device;
-    }
-
-    AudioBootStrap BAUDIO_bootstrap = {
-        "baudio", "BeOS BSoundPlayer",
-        Audio_Available, Audio_CreateDevice
-    };
+    /* Silence the buffer, since it's ours */
+    SDL_memset(stream, audio->spec.silence, len);
 
-/* The BeOS callback for handling the audio buffer */
-    static void FillSound(void *device, void *stream, size_t len,
-                          const media_raw_audio_format & format)
-    {
-        SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
-
-        /* Silence the buffer, since it's ours */
-        SDL_memset(stream, audio->spec.silence, len);
+    /* Only do soemthing if audio is enabled */
+    if (!audio->enabled)
+        return;
 
-        /* Only do soemthing if audio is enabled */
-        if (!audio->enabled)
-            return;
-
-        if (!audio->paused) {
-            if (audio->convert.needed) {
-                SDL_mutexP(audio->mixer_lock);
-                (*audio->spec.callback) (audio->spec.userdata,
+    if (!audio->paused) {
+        if (audio->convert.needed) {
+            SDL_mutexP(audio->mixer_lock);
+            (*audio->spec.callback) (audio->spec.userdata,
                                          (Uint8 *) audio->convert.buf,
                                          audio->convert.len);
-                SDL_mutexV(audio->mixer_lock);
-                SDL_ConvertAudio(&audio->convert);
-                SDL_memcpy(stream, audio->convert.buf,
-                           audio->convert.len_cvt);
-            } else {
-                SDL_mutexP(audio->mixer_lock);
-                (*audio->spec.callback) (audio->spec.userdata,
-                                         (Uint8 *) stream, len);
-                SDL_mutexV(audio->mixer_lock);
-            }
+            SDL_mutexV(audio->mixer_lock);
+            SDL_ConvertAudio(&audio->convert);
+            SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
+        } else {
+            SDL_mutexP(audio->mixer_lock);
+            (*audio->spec.callback) (audio->spec.userdata,
+                                        (Uint8 *) stream, len);
+            SDL_mutexV(audio->mixer_lock);
         }
-        return;
     }
+}
 
-/* Dummy functions -- we don't use thread-based audio */
-    void BE_WaitAudio(_THIS)
-    {
-        return;
-    }
-    void BE_PlayAudio(_THIS)
-    {
-        return;
-    }
-    Uint8 *BE_GetAudioBuf(_THIS)
-    {
-        return (NULL);
-    }
+static void
+BEAUDIO_CloseDevice(_THIS)
+{
+    if (_this->hidden != NULL) {
+        if (_this->hidden->audio_obj) {
+            _this->hidden->audio_obj->Stop();
+            delete _this->hidden->audio_obj;
+            _this->hidden->audio_obj = NULL;
+        }
 
-    void BE_CloseAudio(_THIS)
-    {
-        if (audio_obj) {
-            audio_obj->Stop();
-            delete audio_obj;
-            audio_obj = NULL;
-        }
+        delete _this->hidden;
+        _this->hidden = NULL;
 
         /* Quit the Be Application, if there's nothing left to do */
         SDL_QuitBeApp();
     }
+}
 
-    int BE_OpenAudio(_THIS, SDL_AudioSpec * spec)
-    {
-        int valid_datatype = 0;
-        media_raw_audio_format format;
-        SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+static int
+BEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
+{
+    int valid_datatype = 0;
+    media_raw_audio_format format;
+    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
 
-        /* Parse the audio format and fill the Be raw audio format */
-        memset(&format, '\0', sizeof(media_raw_audio_format));
-        format.byte_order = B_MEDIA_LITTLE_ENDIAN;
-        format.frame_rate = (float) spec->freq;
-        format.channel_count = spec->channels;  /* !!! FIXME: support > 2? */
-        while ((!valid_datatype) && (test_format)) {
-            valid_datatype = 1;
-            spec->format = test_format;
-            switch (test_format) {
+    /* Initialize all variables that we clean on shutdown */
+    _this->hidden = new SDL_PrivateAudioData;
+    if (_this->hidden == NULL) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+    SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
+
+    /* Initialize the Be Application, if it's not already started */
+    if (SDL_InitBeApp() < 0) {
+        return 0;
+    }
+
+    /* Parse the audio format and fill the Be raw audio format */
+    memset(&format, '\0', sizeof(media_raw_audio_format));
+    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
+    format.frame_rate = (float) this->spec.freq;
+    format.channel_count = this->spec.channels;  /* !!! FIXME: support > 2? */
+    while ((!valid_datatype) && (test_format)) {
+        valid_datatype = 1;
+        this->spec.format = test_format;
+        switch (test_format) {
             case AUDIO_S8:
                 format.format = media_raw_audio_format::B_AUDIO_CHAR;
                 break;
@@ -207,43 +164,53 @@
                 valid_datatype = 0;
                 test_format = SDL_NextAudioFormat();
                 break;
-            }
         }
-
-        format.buffer_size = spec->samples;
-
-        if (!valid_datatype) {  /* shouldn't happen, but just in case... */
-            SDL_SetError("Unsupported audio format");
-            return (-1);
-        }
-
-        /* Initialize the Be Application, if it's not already started */
-        if (SDL_InitBeApp() < 0) {
-            return (-1);
-        }
-
-        /* Calculate the final parameters for this audio specification */
-        SDL_CalculateAudioSpec(spec);
+    }
 
-        /* Subscribe to the audio stream (creates a new thread) */
-        {
-            sigset_t omask;
-            SDL_MaskSignals(&omask);
-            audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound,
-                                         NULL, _this);
-            SDL_UnmaskSignals(&omask);
-        }
-        if (audio_obj->Start() == B_NO_ERROR) {
-            audio_obj->SetHasData(true);
-        } else {
-            SDL_SetError("Unable to start Be audio");
-            return (-1);
-        }
+    format.buffer_size = this->spec.samples;
 
-        /* We're running! */
-        return (1);
+    if (!valid_datatype) {  /* shouldn't happen, but just in case... */
+        SDL_SetError("Unsupported audio format");
+        return 0;
     }
 
-};                              /* Extern C */
+    /* Calculate the final parameters for this audio specification */
+    SDL_CalculateAudioSpec(&this->spec);
+
+    /* Subscribe to the audio stream (creates a new thread) */
+    sigset_t omask;
+    SDL_MaskSignals(&omask);
+    _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
+                                                FillSound, NULL, _this);
+    SDL_UnmaskSignals(&omask);
+
+    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
+        _this->hidden->audio_obj->SetHasData(true);
+    } else {
+        SDL_SetError("Unable to start Be audio");
+        return 0;
+    }
+
+    /* We're running! */
+    return 1;
+}
+
+static int
+BEAUDIO_Init(SDL_AudioDriverImpl *impl)
+{
+    /* Set the function pointers */
+    impl->OpenDevice = DSP_OpenDevice;
+    impl->CloseDevice = DSP_CloseDevice;
+    impl->ProvidesOwnCallbackThread = 1;
+    impl->OnlyHasDefaultOutputDevice = 1;
+
+    return 1;
+}
+
+
+AudioBootStrap BEAUDIO_bootstrap = {
+    "baudio", "BeOS BSoundPlayer",
+    BEAUDIO_Available, BEAUDIO_Init, 0
+};
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/baudio/SDL_beaudio.h	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.h	Fri Oct 06 20:36:23 2006 +0000
@@ -34,8 +34,5 @@
     BSoundPlayer *audio_obj;
 };
 
-/* Old variable names */
-#define audio_obj	(_this->hidden->audio_obj)
-
 #endif /* _SDL_lowaudio_h */
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.c	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/dart/SDL_dart.c	Fri Oct 06 20:36:23 2006 +0000
@@ -42,10 +42,10 @@
 //---------------------------------------------------------------------
 // DARTEventFunc
 //
-// This function is called by DART, when an event occures, like end of 
+// This function is called by DART, when an event occurs, like end of
 // playback of a buffer, etc...
 //---------------------------------------------------------------------
-LONG APIENTRY
+static LONG APIENTRY
 DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
 {
     if (ulFlags && MIX_WRITE_COMPLETE) {        // Playback of buffer completed!
@@ -71,10 +71,10 @@
 }
 
 
-int
-DART_OpenAudio(_THIS, SDL_AudioSpec * spec)
+static int
+DART_OpenDevice(_THIS, const char *devname, int iscapture)
 {
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
     int valid_datatype = 0;
     MCI_AMP_OPEN_PARMS AmpOpenParms;
     MCI_GENERIC_PARMS GenericParms;
@@ -89,6 +89,15 @@
     int iSilence;
     int rc;
 
+    /* Initialize all variables that we clean on shutdown */
+    this->hidden = (struct SDL_PrivateAudioData *)
+                        SDL_malloc((sizeof *this->hidden));
+    if (this->hidden == NULL) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
     // First thing is to try to open a given DART device!
     SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
     // pszDeviceType should contain the device type in low word, and device ordinal in high word!
@@ -100,30 +109,33 @@
         iOpenMode |= MCI_OPEN_SHAREABLE;
 
     rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
-    if (rc != MCIERR_SUCCESS)   // No audio available??
-        return (-1);
+    if (rc != MCIERR_SUCCESS) {  // No audio available??
+        DART_CloseDevice(this);
+        return 0;
+    }
+
     // Save the device ID we got from DART!
     // We will use this in the next calls!
-    iDeviceOrd = AmpOpenParms.usDeviceID;
+    _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID;
 
     // Determine the audio parameters from the AudioSpec
-    if (spec->channels > 4)
-        spec->channels = 4;
+    if (this->spec.channels > 4)
+        this->spec.channels = 4;
 
     while ((!valid_datatype) && (test_format)) {
-        spec->format = test_format;
+        this->spec.format = test_format;
         valid_datatype = 1;
         switch (test_format) {
         case AUDIO_U8:
             // Unsigned 8 bit audio data
             iSilence = 0x80;
-            iBits = 8;
+            _this->hidden->iCurrBits = iBits = 8;
             break;
 
         case AUDIO_S16LSB:
             // Signed 16 bit audio data
             iSilence = 0x00;
-            iBits = 16;
+            _this->hidden->iCurrBits = iBits = 16;
             break;
 
             // !!! FIXME: int32?
@@ -137,16 +149,16 @@
 
     if (!valid_datatype) {      // shouldn't happen, but just in case...
         // Close DART, and exit with error code!
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+        DART_CloseDevice(this);
         SDL_SetError("Unsupported audio format");
-        return (-1);
+        return 0;
     }
 
-    iFreq = spec->freq;
-    iChannels = spec->channels;
+    _this->hidden->iCurrFreq = iFreq = this->spec.freq;
+    _this->hidden->iCurrChannels = iChannels = this->spec.channels;
     /* Update the fragment size as size in bytes */
-    SDL_CalculateAudioSpec(spec);
-    iBufSize = spec->size;
+    SDL_CalculateAudioSpec(&this->spec);
+    _this->hidden->iCurrBufSize = iBufSize = this->spec.size;
 
     // Now query this device if it supports the given freq/bits/channels!
     SDL_memset(&(_this->hidden->MixSetupParms), 0,
@@ -163,9 +175,9 @@
                         &(_this->hidden->MixSetupParms), 0);
     if (rc != MCIERR_SUCCESS) { // The device cannot handle this format!
         // Close DART, and exit with error code!
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+        DART_CloseDevice(this);
         SDL_SetError("Audio device doesn't support requested audio format");
-        return (-1);
+        return 0;
     }
     // The device can handle this format, so initialize!
     rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
@@ -173,9 +185,9 @@
                         &(_this->hidden->MixSetupParms), 0);
     if (rc != MCIERR_SUCCESS) { // The device could not be opened!
         // Close DART, and exit with error code!
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+        DART_CloseDevice(this);
         SDL_SetError("Audio device could not be set up");
-        return (-1);
+        return 0;
     }
     // Ok, the device is initialized.
     // Now we should allocate buffers. For this, we need a place where
@@ -184,9 +196,9 @@
         (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs);
     if (!(_this->hidden->pMixBuffers)) {        // Not enough memory!
         // Close DART, and exit with error code!
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
-        SDL_SetError("Not enough memory for audio buffer descriptors");
-        return (-1);
+        DART_CloseDevice(this);
+        SDL_OutOfMemory();
+        return 0;
     }
     // Now that we have the place for buffer list, we can ask DART for the
     // buffers!
@@ -201,12 +213,12 @@
         || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers)
         || (_this->hidden->BufferParms.ulBufferSize == 0)) {    // Could not allocate memory!
         // Close DART, and exit with error code!
-        SDL_free(_this->hidden->pMixBuffers);
-        _this->hidden->pMixBuffers = NULL;
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+        DART_CloseDevice(this);
         SDL_SetError("DART could not allocate buffers");
-        return (-1);
+        return 0;
     }
+    _this->hidden->iCurrNumBufs = iNumBufs;
+
     // Ok, we have all the buffers allocated, let's mark them!
     {
         int i;
@@ -216,24 +228,9 @@
             // Check if this buffer was really allocated by DART
             if ((!(_this->hidden->pMixBuffers[i].pBuffer))
                 || (!pBufferDesc)) {    // Wrong buffer!
-                // Close DART, and exit with error code!
-                // Free buffer descriptions
-                {
-                    int j;
-                    for (j = 0; j < i; j++)
-                        SDL_free((void *) (_this->hidden->pMixBuffers[j].
-                                           ulUserParm));
-                }
-                // and cleanup
-                mciSendCommand(iDeviceOrd, MCI_BUFFER,
-                               MCI_WAIT | MCI_DEALLOCATE_MEMORY,
-                               &(_this->hidden->BufferParms), 0);
-                SDL_free(_this->hidden->pMixBuffers);
-                _this->hidden->pMixBuffers = NULL;
-                mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT,
-                               &GenericParms, 0);
+                DART_CloseDevice(this);
                 SDL_SetError("Error at internal buffer check");
-                return (-1);
+                return 0;
             }
             pBufferDesc->iBufferUsage = BUFFER_EMPTY;
             pBufferDesc->pSDLAudioDevice = _this;
@@ -254,35 +251,15 @@
     if (DosCreateEventSem
         (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR)
     {
-        // Could not create event semaphore!
-        {
-            int i;
-            for (i = 0; i < iNumBufs; i++)
-                SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
-        }
-        mciSendCommand(iDeviceOrd, MCI_BUFFER,
-                       MCI_WAIT | MCI_DEALLOCATE_MEMORY,
-                       &(_this->hidden->BufferParms), 0);
-        SDL_free(_this->hidden->pMixBuffers);
-        _this->hidden->pMixBuffers = NULL;
-        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+        DART_CloseDevice(this);
         SDL_SetError("Could not create event semaphore");
-        return (-1);
+        return 0;
     }
-    // Store the new settings in global variables
-    _this->hidden->iCurrDeviceOrd = iDeviceOrd;
-    _this->hidden->iCurrFreq = iFreq;
-    _this->hidden->iCurrBits = iBits;
-    _this->hidden->iCurrChannels = iChannels;
-    _this->hidden->iCurrNumBufs = iNumBufs;
-    _this->hidden->iCurrBufSize = iBufSize;
 
-    return (0);
+    return 1;
 }
 
-
-
-void
+static void
 DART_ThreadInit(_THIS)
 {
     /* Increase the priority of this thread to make sure that
@@ -291,14 +268,14 @@
     if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
 #ifdef DEBUG_BUILD
         printf
-            ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n",
+            ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
              SDL_ThreadID());
 #endif
         DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
     } else {
 #ifdef DEBUG_BUILD
         printf
-            ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n",
+            ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
              SDL_ThreadID());
 #endif
         DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
@@ -307,8 +284,8 @@
 }
 
 /* This function waits until it is possible to write a full sound buffer */
-void
-DART_WaitAudio(_THIS)
+static void
+DART_WaitDevice(_THIS)
 {
     int i;
     pMixBufferDesc pBufDesc;
@@ -326,8 +303,8 @@
     return;
 }
 
-void
-DART_PlayAudio(_THIS)
+static void
+DART_PlayDevice(_THIS)
 {
     int iFreeBuf = _this->hidden->iNextFreeBuffer;
     pMixBufferDesc pBufDesc;
@@ -346,8 +323,8 @@
     _this->hidden->iNextFreeBuffer = iFreeBuf;
 }
 
-Uint8 *
-DART_GetAudioBuf(_THIS)
+static Uint8 *
+DART_GetDeviceBuf(_THIS)
 {
     int iFreeBuf;
     Uint8 *pResult;
@@ -366,125 +343,116 @@
                     return pResult;
                 }
             } else
-                printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n",
+                printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
                        pBufDesc);
         } else
-            printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n",
+            printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
                    _this->hidden);
     } else
-        printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this);
+        printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
     return NULL;
 }
 
-void
+static void
 DART_WaitDone(_THIS)
 {
     pMixBufferDesc pBufDesc;
-    ULONG ulPostCount;
-    APIRET rc;
+    ULONG ulPostCount = 0;
+    APIRET rc = NO_ERROR;
 
-    pBufDesc =
-        (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden->
-                                                    iLastPlayedBuf].
-        ulUserParm;
-    rc = NO_ERROR;
+    pBufDesc = (pMixBufferDesc)
+          _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
+
     while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
         DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
         rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000);        // 1 sec timeout! Important!
     }
 }
 
-void
-DART_CloseAudio(_THIS)
+static void
+DART_CloseDevice(_THIS)
 {
     MCI_GENERIC_PARMS GenericParms;
     int rc;
+    int i;
 
-    // Stop DART playback
-    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT,
-                        &GenericParms, 0);
-    if (rc != MCIERR_SUCCESS) {
+    if (_this->hidden != NULL) {
+        // Stop DART playback
+        if (_this->hidden->iCurrDeviceOrd) {
+            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
+                                MCI_WAIT, &GenericParms, 0);
 #ifdef SFX_DEBUG_BUILD
-        printf("Could not stop DART playback!\n");
-        fflush(stdout);
+            if (rc != MCIERR_SUCCESS) {
+                printf("Could not stop DART playback!\n");
+                fflush(stdout);
+            }
 #endif
-    }
-    // Close event semaphore
-    DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
+        }
+
+        // Close event semaphore
+        if (_this->hidden->hevAudioBufferPlayed) {
+            DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
+            _this->hidden->hevAudioBufferPlayed = 0;
+        }
 
-    // Free memory of buffer descriptions
-    {
-        int i;
-        for (i = 0; i < _this->hidden->iCurrNumBufs; i++)
+        // Free memory of buffer descriptions
+        for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
             SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
-    }
+            _this->hidden->pMixBuffers[i].ulUserParm = 0;
+        }
+        _this->hidden->iCurrNumBufs = 0;
+
+        // Deallocate buffers
+        if (_this->hidden->iCurrDeviceOrd) {
+            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
+                                MCI_WAIT | MCI_DEALLOCATE_MEMORY,
+                                &(_this->hidden->BufferParms), 0);
+        }
 
-    // Deallocate buffers
-    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
-                        MCI_WAIT | MCI_DEALLOCATE_MEMORY,
-                        &(_this->hidden->BufferParms), 0);
+        // Free bufferlist
+        if (_this->hidden->pMixBuffers != NULL) {
+            SDL_free(_this->hidden->pMixBuffers);
+            _this->hidden->pMixBuffers = NULL;
+        }
 
-    // Free bufferlist
-    SDL_free(_this->hidden->pMixBuffers);
-    _this->hidden->pMixBuffers = NULL;
+        // Close dart
+        if (_this->hidden->iCurrDeviceOrd) {
+            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
+                                MCI_WAIT, &(GenericParms), 0);
+        }
+        _this->hidden->iCurrDeviceOrd = 0;
 
-    // Close dart
-    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT,
-                        &(GenericParms), 0);
+        SDL_free(_this->hidden);
+        _this->hidden = NULL;
+    }
 }
 
-/* Audio driver bootstrap functions */
-
-int
-Audio_Available(void)
+static int
+DART_Available(void)
 {
-    return (1);
-}
-
-void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
-    SDL_free(device->hidden);
-    SDL_free(device);
+    return 1;  /* Always available on OS/2 Warp */
 }
 
-SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
+static int
+DART_Init(SDL_AudioDriverImpl *impl)
 {
-    SDL_AudioDevice *this;
+    /* Set the function pointers */
+    impl->OpenDevice = DART_OpenDevice;
+    impl->ThreadInit = DART_ThreadInit;
+    impl->WaitDevice = DART_WaitDevice;
+    impl->GetDeviceBuf = DART_GetDeviceBuf;
+    impl->PlayDevice = DART_PlayDevice;
+    impl->WaitDone = DART_WaitDone;
+    impl->CloseDevice = DART_CloseDevice;
+    impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: is this right? */
 
-    /* Initialize all variables that we clean on shutdown */
-    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
-    if (this) {
-        SDL_memset(this, 0, (sizeof *this));
-        this->hidden = (struct SDL_PrivateAudioData *)
-            SDL_malloc((sizeof *this->hidden));
-    }
-    if ((this == NULL) || (this->hidden == NULL)) {
-        SDL_OutOfMemory();
-        if (this)
-            SDL_free(this);
-        return (0);
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+    return 1;
+}
 
-    /* Set the function pointers */
-    this->OpenAudio = DART_OpenAudio;
-    this->ThreadInit = DART_ThreadInit;
-    this->WaitAudio = DART_WaitAudio;
-    this->PlayAudio = DART_PlayAudio;
-    this->GetAudioBuf = DART_GetAudioBuf;
-    this->WaitDone = DART_WaitDone;
-    this->CloseAudio = DART_CloseAudio;
-
-    this->free = Audio_DeleteDevice;
-
-    return this;
-}
 
 AudioBootStrap DART_bootstrap = {
     "dart", "OS/2 Direct Audio RouTines (DART)",
-    Audio_Available, Audio_CreateDevice, 0
+    DART_Available, DART_Init, 0
 };
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.h	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/dart/SDL_dart.h	Fri Oct 06 20:36:23 2006 +0000
@@ -21,8 +21,8 @@
 */
 #include "SDL_config.h"
 
-#ifndef _SDL_lowaudio_h
-#define _SDL_lowaudio_h
+#ifndef _SDL_dart_h
+#define _SDL_dart_h
 
 #define INCL_TYPES
 #define INCL_DOSSEMAPHORES
@@ -61,5 +61,6 @@
     HEV hevAudioBufferPlayed;   // Event semaphore to indicate that an audio buffer has been played by DART
 };
 
-#endif /* _SDL_lowaudio_h */
+#endif /* _SDL_dart_h */
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dc/SDL_dcaudio.c	Fri Oct 06 19:45:11 2006 +0000
+++ b/src/audio/dc/SDL_dcaudio.c	Fri Oct 06 20:36:23 2006 +0000
@@ -33,79 +33,6 @@
 #include "aica.h"
 #include <dc/spu.h>
 
-/* Audio driver functions */
-static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DCAUD_WaitAudio(_THIS);
-static void DCAUD_PlayAudio(_THIS);
-static Uint8 *DCAUD_GetAudioBuf(_THIS);
-static void DCAUD_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
-static int
-DCAUD_Available(void)
-{
-    return 1;
-}
-
-static void
-DCAUD_DeleteDevice(SDL_AudioDevice * device)
-{
-    SDL_free(device->hidden);
-    SDL_free(device);
-}
-
-static SDL_AudioDevice *
-DCAUD_CreateDevice(int devindex)
-{
-    SDL_AudioDevice *this;
-
-    /* Initialize all variables that we clean on shutdown */
-    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
-    if (this) {
-        SDL_memset(this, 0, (sizeof *this));
-        this->hidden = (struct SDL_PrivateAudioData *)
-            SDL_malloc((sizeof *this->hidden));
-    }
-    if ((this == NULL) || (this->hidden == NULL)) {
-        SDL_OutOfMemory();
-        if (this) {
-            SDL_free(this);
-        }
-        return (0);
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
-    /* Set the function pointers */
-    this->OpenAudio = DCAUD_OpenAudio;
-    this->WaitAudio = DCAUD_WaitAudio;
-    this->PlayAudio = DCAUD_PlayAudio;
-    this->GetAudioBuf = DCAUD_GetAudioBuf;
-    this->CloseAudio = DCAUD_CloseAudio;
-
-    this->free = DCAUD_DeleteDevice;
-
-    spu_init();
-
-    return this;
-}
-
-AudioBootStrap DCAUD_bootstrap = {
-    "dcaudio", "Dreamcast AICA audio",
-    DCAUD_Available, DCAUD_CreateDevice, 0
-};
-
-/* This function waits until it is possible to write a full sound buffer */
-static void
-DCAUD_WaitAudio(_THIS)
-{
-    if (this->hidden->playing) {
-        /* wait */
-        while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
-            thd_pass();
-        }
-    }
-}
-
 #define	SPU_RAM_BASE	0xa0800000
 
 static void
@@ -151,7 +78,7 @@
 }
 
 static void
-DCAUD_PlayAudio(_THIS)
+DCAUD_PlayDevice(_THIS)
 {
     SDL_AudioSpec *spec = &this->spec;
     unsigned int offset;
@@ -199,28 +126,59 @@
 }
 
 static Uint8 *
-DCAUD_GetAudioBuf(_THIS)
+DCAUD_GetDeviceBuf(_THIS)
 {
     return (this->hidden->mixbuf);
 }
 
+/* This function waits until it is possible to write a full sound buffer */
 static void
-DCAUD_CloseAudio(_THIS)
+DCAUD_WaitDevice(_THIS)
 {
-    aica_stop(0);
-    if (this->spec.channels == 2)
-        aica_stop(1);
-    if (this->hidden->mixbuf != NULL) {
-        SDL_FreeAudioMem(this->hidden->mixbuf);
-        this->hidden->mixbuf = NULL;
+    if (this->hidden->playing) {
+        /* wait */
+        while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
+            thd_pass();
+        }
+    }
+}
+
+static void
+DCAUD_CloseDevice(_THIS)
+{
+    if (this->hidden != NULL) {
+        aica_stop(0);
+        if (this->spec.channels == 2) {
+            aica_stop(1);
+        }
+        if (this->hidden->mixbuf != NULL) {
+            SDL_FreeAudioMem(this->hidden->mixbuf);
+            this->hidden->mixbuf = NULL;
+        }
+        SDL_free(this->hidden);
+        this->hidden = NULL;
+
+        /* !!! FIXME: is there a reverse of spu_init()? */
     }
 }
 
 static int
-DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec)
+DCAUD_OpenDevice(_THIS, SDL_AudioSpec * spec)
 {
     SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
     int valid_datatype = 0;
+
+    /* Initialize all variables that we clean on shutdown */
+    this->hidden = (struct SDL_PrivateAudioData *)
+                        SDL_malloc((sizeof *this->hidden));
+    if (this->hidden == NULL) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+    spu_init();
+
     while ((!valid_datatype) && (test_format)) {
         spec->format = test_format;
         switch (test_format) {
@@ -237,8 +195,9 @@
     }
 
     if (!valid_datatype) {      /* shouldn't happen, but just in case... */
+        DCAUD_CloseDevice(this);
         SDL_SetError("Unsupported audio format");
-        return (-1);
+        return 0;
     }
 
     if (spec->channels > 2)
@@ -251,7 +210,9 @@
     this->hidden->mixlen = spec->size;
     this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
     if (this->hidden->mixbuf == NULL) {
-        return (-1);
+        DCAUD_CloseDevice(this);
+        SDL_OutOfMemory();
+        return 0;
     }
     SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
     this->hidden->leftpos = 0x11000;
@@ -260,7 +221,32 @@
     this->hidden->nextbuf = 0;
 
     /* We're ready to rock and roll. :-) */
-    return (0);
+    return 1;
+}
+
+static int
+DCAUD_Available(void)
+{
+    return 1;  /* Dreamcast hardware is always available.  :) */
 }
 
+static int
+DCAUD_Init(SDL_AudioDriverImpl *impl)
+{
+    /* Set the function pointers */
+    impl->OpenDevice = DCAUD_OpenDevice;
+    impl->PlayDevice = DCAUD_PlayDevice;
+    impl->WaitDevice = DCAUD_WaitDevice;
+    impl->GetDeviceBuf = DCAUD_GetDeviceBuf;
+    impl->CloseDevice = DCAUD_CloseDevice;
+    impl->OnlyHasDefaultOutputDevice = 1;
+
+    return 1;
+}
+
+AudioBootStrap DCAUD_bootstrap = {
+    "dcaudio", "Dreamcast AICA audio",
+    DCAUD_Available, DCAUD_Init, 0
+};
+
 /* vi: set ts=4 sw=4 expandtab: */