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 3819b225d9820ee3
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
     1.1 --- a/src/audio/alsa/SDL_alsa_audio.c	Fri Oct 06 19:45:11 2006 +0000
     1.2 +++ b/src/audio/alsa/SDL_alsa_audio.c	Fri Oct 06 20:36:23 2006 +0000
     1.3 @@ -42,13 +42,6 @@
     1.4  /* The default ALSA audio driver */
     1.5  #define DEFAULT_DEVICE	"default"
     1.6  
     1.7 -/* Audio driver functions */
     1.8 -static int ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec);
     1.9 -static void ALSA_WaitAudio(_THIS);
    1.10 -static void ALSA_PlayAudio(_THIS);
    1.11 -static Uint8 *ALSA_GetAudioBuf(_THIS);
    1.12 -static void ALSA_CloseAudio(_THIS);
    1.13 -
    1.14  static int (*ALSA_snd_pcm_open)
    1.15                  (snd_pcm_t **, const char *, snd_pcm_stream_t, int);
    1.16  static int (*ALSA_snd_pcm_close)(snd_pcm_t * pcm);
    1.17 @@ -148,10 +141,14 @@
    1.18      return 0;
    1.19  }
    1.20  
    1.21 +#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
    1.22 +
    1.23 +static int library_load_count = 0;
    1.24 +
    1.25  static void
    1.26  UnloadALSALibrary(void)
    1.27  {
    1.28 -    if (alsa_handle != NULL) {
    1.29 +    if ((alsa_handle != NULL) && (--library_load_count == 0)) {
    1.30          dlclose(alsa_handle);
    1.31          alsa_handle = NULL;
    1.32      }
    1.33 @@ -160,16 +157,19 @@
    1.34  static int
    1.35  LoadALSALibrary(void)
    1.36  {
    1.37 -    int i, retval = -1;
    1.38 -
    1.39 -    alsa_handle = dlopen(alsa_library, RTLD_NOW);
    1.40 -    if (alsa_handle == NULL) {
    1.41 -        SDL_SetError("ALSA: dlopen('%s') failed: %s\n",
    1.42 -                      alsa_library, strerror(errno));
    1.43 -    } else {
    1.44 -        retval = load_alsa_syms();
    1.45 -        if (retval < 0) {
    1.46 -            UnloadALSALibrary();
    1.47 +    int retval = 0;
    1.48 +    if (library_load_count++ == 0) {
    1.49 +        alsa_handle = dlopen(alsa_library, RTLD_NOW);
    1.50 +        if (alsa_handle == NULL) {
    1.51 +            library_load_count--;
    1.52 +            retval = -1;
    1.53 +            SDL_SetError("ALSA: dlopen('%s') failed: %s\n",
    1.54 +                          alsa_library, strerror(errno));
    1.55 +        } else {
    1.56 +            retval = load_alsa_syms();
    1.57 +            if (retval < 0) {
    1.58 +                UnloadALSALibrary();
    1.59 +            }
    1.60          }
    1.61      }
    1.62      return retval;
    1.63 @@ -180,7 +180,6 @@
    1.64  static void
    1.65  UnloadALSALibrary(void)
    1.66  {
    1.67 -    return;
    1.68  }
    1.69  
    1.70  static int
    1.71 @@ -209,79 +208,32 @@
    1.72      return device;
    1.73  }
    1.74  
    1.75 -/* Audio driver bootstrap functions */
    1.76  
    1.77  static int
    1.78 -Audio_Available(void)
    1.79 +ALSA_Available(void)
    1.80  {
    1.81 -    int available;
    1.82 +    int available = 0;
    1.83      int status;
    1.84      snd_pcm_t *handle;
    1.85  
    1.86 -    available = 0;
    1.87 -    if (LoadALSALibrary() < 0) {
    1.88 -        return available;
    1.89 +    if (LoadALSALibrary() >= 0) {
    1.90 +        int status = ALSA_snd_pcm_open(&handle, get_audio_device(2),
    1.91 +                                       SND_PCM_STREAM_PLAYBACK,
    1.92 +                                       SND_PCM_NONBLOCK);
    1.93 +        if (status >= 0) {
    1.94 +            available = 1;
    1.95 +            ALSA_snd_pcm_close(handle);
    1.96 +        }
    1.97 +        UnloadALSALibrary();
    1.98      }
    1.99 -    status = ALSA_snd_pcm_open(&handle, get_audio_device(2),
   1.100 -                               SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
   1.101 -    if (status >= 0) {
   1.102 -        available = 1;
   1.103 -        ALSA_snd_pcm_close(handle);
   1.104 -    }
   1.105 -    UnloadALSALibrary();
   1.106      return (available);
   1.107  }
   1.108  
   1.109 -static void
   1.110 -Audio_DeleteDevice(SDL_AudioDevice * device)
   1.111 -{
   1.112 -    SDL_free(device->hidden);
   1.113 -    SDL_free(device);
   1.114 -    UnloadALSALibrary();
   1.115 -}
   1.116  
   1.117 -static SDL_AudioDevice *
   1.118 -Audio_CreateDevice(int devindex)
   1.119 -{
   1.120 -    SDL_AudioDevice *this;
   1.121 -
   1.122 -    /* Initialize all variables that we clean on shutdown */
   1.123 -    LoadALSALibrary();
   1.124 -    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
   1.125 -    if (this) {
   1.126 -        SDL_memset(this, 0, (sizeof *this));
   1.127 -        this->hidden = (struct SDL_PrivateAudioData *)
   1.128 -            SDL_malloc((sizeof *this->hidden));
   1.129 -    }
   1.130 -    if ((this == NULL) || (this->hidden == NULL)) {
   1.131 -        SDL_OutOfMemory();
   1.132 -        if (this) {
   1.133 -            SDL_free(this);
   1.134 -        }
   1.135 -        return (0);
   1.136 -    }
   1.137 -    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   1.138 -
   1.139 -    /* Set the function pointers */
   1.140 -    this->OpenAudio = ALSA_OpenAudio;
   1.141 -    this->WaitAudio = ALSA_WaitAudio;
   1.142 -    this->PlayAudio = ALSA_PlayAudio;
   1.143 -    this->GetAudioBuf = ALSA_GetAudioBuf;
   1.144 -    this->CloseAudio = ALSA_CloseAudio;
   1.145 -
   1.146 -    this->free = Audio_DeleteDevice;
   1.147 -
   1.148 -    return this;
   1.149 -}
   1.150 -
   1.151 -AudioBootStrap ALSA_bootstrap = {
   1.152 -    DRIVER_NAME, "ALSA 0.9 PCM audio",
   1.153 -    Audio_Available, Audio_CreateDevice, 0
   1.154 -};
   1.155  
   1.156  /* This function waits until it is possible to write a full sound buffer */
   1.157  static void
   1.158 -ALSA_WaitAudio(_THIS)
   1.159 +ALSA_WaitDevice(_THIS)
   1.160  {
   1.161      /* Check to see if the thread-parent process is still alive */
   1.162      {
   1.163 @@ -289,8 +241,9 @@
   1.164          /* Note that this only works with thread implementations 
   1.165             that use a different process id for each thread.
   1.166           */
   1.167 -        if (parent && (((++cnt) % 10) == 0)) {  /* Check every 10 loops */
   1.168 -            if (kill(parent, 0) < 0) {
   1.169 +        /* Check every 10 loops */
   1.170 +        if (this->hidden->parent && (((++cnt) % 10) == 0)) {
   1.171 +            if (kill(this->hidden->parent, 0) < 0) {
   1.172                  this->enabled = 0;
   1.173              }
   1.174          }
   1.175 @@ -298,13 +251,14 @@
   1.176  }
   1.177  
   1.178  
   1.179 +/* !!! FIXME: is there a channel swizzler in alsalib instead? */
   1.180  /*
   1.181   * http://bugzilla.libsdl.org/show_bug.cgi?id=110
   1.182   * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
   1.183   *  and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
   1.184   */
   1.185  #define SWIZ6(T) \
   1.186 -    T *ptr = (T *) mixbuf; \
   1.187 +    T *ptr = (T *) this->hidden->mixbuf; \
   1.188      const Uint32 count = (this->spec.samples / 6); \
   1.189      Uint32 i; \
   1.190      for (i = 0; i < count; i++, ptr += 6) { \
   1.191 @@ -338,8 +292,8 @@
   1.192  
   1.193  
   1.194  /*
   1.195 - * Called right before feeding this->mixbuf to the hardware. Swizzle channels
   1.196 - *  from Windows/Mac order to the format alsalib will want.
   1.197 + * Called right before feeding this->hidden->mixbuf to the hardware. Swizzle
   1.198 + *  channels from Windows/Mac order to the format alsalib will want.
   1.199   */
   1.200  static __inline__ void
   1.201  swizzle_alsa_channels(_THIS)
   1.202 @@ -361,7 +315,7 @@
   1.203  
   1.204  
   1.205  static void
   1.206 -ALSA_PlayAudio(_THIS)
   1.207 +ALSA_PlayDevice(_THIS)
   1.208  {
   1.209      int status;
   1.210      int sample_len;
   1.211 @@ -370,10 +324,12 @@
   1.212      swizzle_alsa_channels(this);
   1.213  
   1.214      sample_len = this->spec.samples;
   1.215 -    sample_buf = (signed short *) mixbuf;
   1.216 +    sample_buf = (signed short *) this->hidden->mixbuf;
   1.217  
   1.218      while (sample_len > 0) {
   1.219 -        status = ALSA_snd_pcm_writei(pcm_handle, sample_buf, sample_len);
   1.220 +        status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
   1.221 +                                     sample_buf, sample_len);
   1.222 +
   1.223          if (status < 0) {
   1.224              if (status == -EAGAIN) {
   1.225                  SDL_Delay(1);
   1.226 @@ -382,11 +338,11 @@
   1.227              if (status == -ESTRPIPE) {
   1.228                  do {
   1.229                      SDL_Delay(1);
   1.230 -                    status = ALSA_snd_pcm_resume(pcm_handle);
   1.231 +                    status = ALSA_snd_pcm_resume(this->hidden->pcm_handle);
   1.232                  } while (status == -EAGAIN);
   1.233              }
   1.234              if (status < 0) {
   1.235 -                status = ALSA_snd_pcm_prepare(pcm_handle);
   1.236 +                status = ALSA_snd_pcm_prepare(this->hidden->pcm_handle);
   1.237              }
   1.238              if (status < 0) {
   1.239                  /* Hmm, not much we can do - abort */
   1.240 @@ -401,72 +357,89 @@
   1.241  }
   1.242  
   1.243  static Uint8 *
   1.244 -ALSA_GetAudioBuf(_THIS)
   1.245 +ALSA_GetDeviceBuf(_THIS)
   1.246  {
   1.247 -    return (mixbuf);
   1.248 +    return (this->hidden->mixbuf);
   1.249  }
   1.250  
   1.251  static void
   1.252 -ALSA_CloseAudio(_THIS)
   1.253 +ALSA_CloseDevice(_THIS)
   1.254  {
   1.255 -    if (mixbuf != NULL) {
   1.256 -        SDL_FreeAudioMem(mixbuf);
   1.257 -        mixbuf = NULL;
   1.258 -    }
   1.259 -    if (pcm_handle) {
   1.260 -        ALSA_snd_pcm_drain(pcm_handle);
   1.261 -        ALSA_snd_pcm_close(pcm_handle);
   1.262 -        pcm_handle = NULL;
   1.263 +    if (this->hidden != NULL) {
   1.264 +        if (this->hidden->mixbuf != NULL) {
   1.265 +            SDL_FreeAudioMem(this->hidden->mixbuf);
   1.266 +            this->hidden->mixbuf = NULL;
   1.267 +        }
   1.268 +        if (this->hidden->pcm_handle) {
   1.269 +            ALSA_snd_pcm_drain(this->hidden->pcm_handle);
   1.270 +            ALSA_snd_pcm_close(this->hidden->pcm_handle);
   1.271 +            this->hidden->pcm_handle = NULL;
   1.272 +        }
   1.273 +        SDL_free(this->hidden);
   1.274 +        this->hidden = NULL;
   1.275      }
   1.276  }
   1.277  
   1.278  static int
   1.279 -ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec)
   1.280 +ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
   1.281  {
   1.282 -    int status;
   1.283 -    snd_pcm_hw_params_t *hwparams;
   1.284 -    snd_pcm_sw_params_t *swparams;
   1.285 -    snd_pcm_format_t format;
   1.286 -    snd_pcm_uframes_t frames;
   1.287 -    SDL_AudioFormat test_format;
   1.288 +    int status = 0;
   1.289 +    snd_pcm_t *pcm_handle = NULL;
   1.290 +    snd_pcm_hw_params_t *hwparams = NULL;
   1.291 +    snd_pcm_sw_params_t *swparams = NULL;
   1.292 +    snd_pcm_format_t format = 0;
   1.293 +    snd_pcm_uframes_t frames = 0;
   1.294 +    SDL_AudioFormat test_format = 0;
   1.295 +
   1.296 +    /* Initialize all variables that we clean on shutdown */
   1.297 +    this->hidden = (struct SDL_PrivateAudioData *)
   1.298 +                        SDL_malloc((sizeof *this->hidden));
   1.299 +    if (this->hidden == NULL) {
   1.300 +        SDL_OutOfMemory();
   1.301 +        return 0;
   1.302 +    }
   1.303 +    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   1.304  
   1.305      /* Open the audio device */
   1.306      /* Name of device should depend on # channels in spec */
   1.307      status = ALSA_snd_pcm_open(&pcm_handle,
   1.308 -                               get_audio_device(spec->channels),
   1.309 +                               get_audio_device(this->spec.channels),
   1.310                                 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
   1.311  
   1.312      if (status < 0) {
   1.313 -        SDL_SetError("Couldn't open audio device: %s",
   1.314 +        ALSA_CloseDevice(this);
   1.315 +        SDL_SetError("ALSA: Couldn't open audio device: %s",
   1.316                       ALSA_snd_strerror(status));
   1.317 -        return (-1);
   1.318 +        return 0;
   1.319      }
   1.320  
   1.321 +    this->hidden->pcm_handle = pcm_handle;
   1.322 +
   1.323      /* Figure out what the hardware is capable of */
   1.324      snd_pcm_hw_params_alloca(&hwparams);
   1.325      status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
   1.326      if (status < 0) {
   1.327 -        SDL_SetError("Couldn't get hardware config: %s",
   1.328 +        ALSA_CloseDevice(this);
   1.329 +        SDL_SetError("ALSA: Couldn't get hardware config: %s",
   1.330                       ALSA_snd_strerror(status));
   1.331 -        ALSA_CloseAudio(this);
   1.332 -        return (-1);
   1.333 +        return 0;
   1.334      }
   1.335  
   1.336      /* SDL only uses interleaved sample output */
   1.337      status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
   1.338                                                 SND_PCM_ACCESS_RW_INTERLEAVED);
   1.339      if (status < 0) {
   1.340 -        SDL_SetError("Couldn't set interleaved access: %s",
   1.341 +        ALSA_CloseDevice(this);
   1.342 +        SDL_SetError("ALSA: Couldn't set interleaved access: %s",
   1.343                       ALSA_snd_strerror(status));
   1.344 -        ALSA_CloseAudio(this);
   1.345 -        return (-1);
   1.346 +        return 0;
   1.347      }
   1.348  
   1.349      /* Try for a closest match on audio format */
   1.350      status = -1;
   1.351 -    for (test_format = SDL_FirstAudioFormat(spec->format);
   1.352 +    for (test_format = SDL_FirstAudioFormat(this->spec.format);
   1.353           test_format && (status < 0);) {
   1.354 -        status = 0;             /* if we can't support a format, it'll become -1. */
   1.355 +        status = 0;      /* if we can't support a format, it'll become -1. */
   1.356          switch (test_format) {
   1.357          case AUDIO_U8:
   1.358              format = SND_PCM_FORMAT_U8;
   1.359 @@ -511,112 +484,133 @@
   1.360          }
   1.361      }
   1.362      if (status < 0) {
   1.363 -        SDL_SetError("Couldn't find any hardware audio formats");
   1.364 -        ALSA_CloseAudio(this);
   1.365 -        return (-1);
   1.366 +        ALSA_CloseDevice(this);
   1.367 +        SDL_SetError("ALSA: Couldn't find any hardware audio formats");
   1.368 +        return 0;
   1.369      }
   1.370 -    spec->format = test_format;
   1.371 +    this->spec.format = test_format;
   1.372  
   1.373      /* Set the number of channels */
   1.374      status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
   1.375 -                                                 spec->channels);
   1.376 +                                                 this->spec.channels);
   1.377      if (status < 0) {
   1.378          status = ALSA_snd_pcm_hw_params_get_channels(hwparams);
   1.379          if ((status <= 0) || (status > 2)) {
   1.380 -            SDL_SetError("Couldn't set audio channels");
   1.381 -            ALSA_CloseAudio(this);
   1.382 -            return (-1);
   1.383 +            ALSA_CloseDevice(this);
   1.384 +            SDL_SetError("ALSA: Couldn't set audio channels");
   1.385 +            return 0;
   1.386          }
   1.387 -        spec->channels = status;
   1.388 +        this->spec.channels = status;
   1.389      }
   1.390  
   1.391      /* Set the audio rate */
   1.392      status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
   1.393 -                                                  spec->freq, NULL);
   1.394 +                                                  this->spec.freq, NULL);
   1.395      if (status < 0) {
   1.396 -        ALSA_CloseAudio(this);
   1.397 -        SDL_SetError("Couldn't set audio frequency: %s",
   1.398 +        ALSA_CloseDevice(this);
   1.399 +        SDL_SetError("ALSA: Couldn't set audio frequency: %s",
   1.400                       ALSA_snd_strerror(status));
   1.401 -        return (-1);
   1.402 +        return 0;
   1.403      }
   1.404 -    spec->freq = status;
   1.405 +    this->spec.freq = status;
   1.406  
   1.407      /* Set the buffer size, in samples */
   1.408 -    frames = spec->samples;
   1.409 +    frames = this->spec.samples;
   1.410      frames = ALSA_snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams,
   1.411                                                           frames, NULL);
   1.412 -    spec->samples = frames;
   1.413 +    this->spec.samples = frames;
   1.414      ALSA_snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, 2, NULL);
   1.415  
   1.416      /* "set" the hardware with the desired parameters */
   1.417      status = ALSA_snd_pcm_hw_params(pcm_handle, hwparams);
   1.418      if (status < 0) {
   1.419 -        ALSA_CloseAudio(this);
   1.420 -        SDL_SetError("Couldn't set hardware audio parameters: %s",
   1.421 +        ALSA_CloseDevice(this);
   1.422 +        SDL_SetError("ALSA: Couldn't set hardware audio parameters: %s",
   1.423                       ALSA_snd_strerror(status));
   1.424 -        return (-1);
   1.425 +        return 0;
   1.426      }
   1.427  
   1.428 -/* This is useful for debugging... */
   1.429 -/*
   1.430 -{ snd_pcm_sframes_t bufsize; int fragments;
   1.431 -   bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
   1.432 -   fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
   1.433 -
   1.434 -   fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments);
   1.435 +#if AUDIO_DEBUG
   1.436 +{
   1.437 +    snd_pcm_sframes_t bufsize;
   1.438 +    int fragments;
   1.439 +    bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
   1.440 +    fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
   1.441 +    fprintf(stderr,"ALSA: bufsize = %ld, fragments = %d\n",bufsize,fragments);
   1.442  }
   1.443 -*/
   1.444 +#endif
   1.445  
   1.446      /* Set the software parameters */
   1.447      snd_pcm_sw_params_alloca(&swparams);
   1.448      status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
   1.449      if (status < 0) {
   1.450 -        SDL_SetError("Couldn't get software config: %s",
   1.451 +        ALSA_CloseDevice(this);
   1.452 +        SDL_SetError("ALSA: Couldn't get software config: %s",
   1.453                       ALSA_snd_strerror(status));
   1.454 -        ALSA_CloseAudio(this);
   1.455 -        return (-1);
   1.456 +        return 0;
   1.457      }
   1.458      status = ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle,swparams,0);
   1.459      if (status < 0) {
   1.460 -        SDL_SetError("Couldn't set start threshold: %s",
   1.461 +        ALSA_CloseDevice(this);
   1.462 +        SDL_SetError("ALSA: Couldn't set start threshold: %s",
   1.463                       ALSA_snd_strerror(status));
   1.464 -        ALSA_CloseAudio(this);
   1.465 -        return (-1);
   1.466 +        return 0;
   1.467      }
   1.468      status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, frames);
   1.469      if (status < 0) {
   1.470 +        ALSA_CloseDevice(this);
   1.471          SDL_SetError("Couldn't set avail min: %s", ALSA_snd_strerror(status));
   1.472 -        ALSA_CloseAudio(this);
   1.473 -        return (-1);
   1.474 +        return 0;
   1.475      }
   1.476      status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
   1.477      if (status < 0) {
   1.478 +        ALSA_CloseDevice(this);
   1.479          SDL_SetError("Couldn't set software audio parameters: %s",
   1.480                       ALSA_snd_strerror(status));
   1.481 -        ALSA_CloseAudio(this);
   1.482 -        return (-1);
   1.483 +        return 0;
   1.484      }
   1.485  
   1.486      /* Calculate the final parameters for this audio specification */
   1.487 -    SDL_CalculateAudioSpec(spec);
   1.488 +    SDL_CalculateAudioSpec(&this->spec);
   1.489  
   1.490      /* Allocate mixing buffer */
   1.491 -    mixlen = spec->size;
   1.492 -    mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
   1.493 -    if (mixbuf == NULL) {
   1.494 -        ALSA_CloseAudio(this);
   1.495 -        return (-1);
   1.496 +    this->hidden->mixlen = this->spec.size;
   1.497 +    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   1.498 +    if (this->hidden->mixbuf == NULL) {
   1.499 +        ALSA_CloseDevice(this);
   1.500 +        SDL_OutOfMemory();
   1.501 +        return 0;
   1.502      }
   1.503 -    SDL_memset(mixbuf, spec->silence, spec->size);
   1.504 +    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
   1.505  
   1.506      /* Get the parent process id (we're the parent of the audio thread) */
   1.507 -    parent = getpid();
   1.508 +    this->hidden->parent = getpid();
   1.509  
   1.510      /* Switch to blocking mode for playback */
   1.511      ALSA_snd_pcm_nonblock(pcm_handle, 0);
   1.512  
   1.513      /* We're ready to rock and roll. :-) */
   1.514 -    return (0);
   1.515 +    return 1;
   1.516  }
   1.517  
   1.518 +static int
   1.519 +ALSA_Init(SDL_AudioDriverImpl *impl)
   1.520 +{
   1.521 +    /* Set the function pointers */
   1.522 +    impl->OpenDevice = ALSA_OpenDevice;
   1.523 +    impl->WaitDevice = ALSA_WaitDevice;
   1.524 +    impl->GetDeviceBuf = ALSA_GetDeviceBuf;
   1.525 +    impl->PlayDevice = ALSA_PlayDevice;
   1.526 +    impl->CloseDevice = ALSA_CloseDevice;
   1.527 +    impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: Add device enum! */
   1.528 +
   1.529 +    return 1;
   1.530 +}
   1.531 +
   1.532 +
   1.533 +AudioBootStrap ALSA_bootstrap = {
   1.534 +    DRIVER_NAME, "ALSA 0.9 PCM audio",
   1.535 +    ALSA_Available, ALSA_Init, 0
   1.536 +};
   1.537 +
   1.538  /* vi: set ts=4 sw=4 expandtab: */
     2.1 --- a/src/audio/alsa/SDL_alsa_audio.h	Fri Oct 06 19:45:11 2006 +0000
     2.2 +++ b/src/audio/alsa/SDL_alsa_audio.h	Fri Oct 06 20:36:23 2006 +0000
     2.3 @@ -46,11 +46,5 @@
     2.4      int mixlen;
     2.5  };
     2.6  
     2.7 -/* Old variable names */
     2.8 -#define pcm_handle		(this->hidden->pcm_handle)
     2.9 -#define parent			(this->hidden->parent)
    2.10 -#define mixbuf			(this->hidden->mixbuf)
    2.11 -#define mixlen			(this->hidden->mixlen)
    2.12 -
    2.13  #endif /* _ALSA_PCM_audio_h */
    2.14  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/audio/baudio/SDL_beaudio.cc	Fri Oct 06 19:45:11 2006 +0000
     3.2 +++ b/src/audio/baudio/SDL_beaudio.cc	Fri Oct 06 20:36:23 2006 +0000
     3.3 @@ -36,138 +36,95 @@
     3.4  #include "../../thread/beos/SDL_systhread_c.h"
     3.5  #include "SDL_beaudio.h"
     3.6  
     3.7 +}
     3.8  
     3.9 -/* Audio driver functions */
    3.10 -    static int BE_OpenAudio(_THIS, SDL_AudioSpec * spec);
    3.11 -    static void BE_WaitAudio(_THIS);
    3.12 -    static void BE_PlayAudio(_THIS);
    3.13 -    static Uint8 *BE_GetAudioBuf(_THIS);
    3.14 -    static void BE_CloseAudio(_THIS);
    3.15 -
    3.16 -/* Audio driver bootstrap functions */
    3.17  
    3.18 -    static int Audio_Available(void)
    3.19 -    {
    3.20 -        return (1);
    3.21 -    }
    3.22 +static int BEAUDIO_Available(void)
    3.23 +{
    3.24 +    return 1;  /* Always available on BeOS. */
    3.25 +}
    3.26  
    3.27 -    static void Audio_DeleteDevice(SDL_AudioDevice * device)
    3.28 -    {
    3.29 -        SDL_free(device->hidden);
    3.30 -        SDL_free(device);
    3.31 -    }
    3.32 -
    3.33 -    static SDL_AudioDevice *Audio_CreateDevice(int devindex)
    3.34 -    {
    3.35 -        SDL_AudioDevice *device;
    3.36  
    3.37 -        /* Initialize all variables that we clean on shutdown */
    3.38 -        device = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
    3.39 -        if (device) {
    3.40 -            SDL_memset(device, 0, (sizeof *device));
    3.41 -            device->hidden = (struct SDL_PrivateAudioData *)
    3.42 -                SDL_malloc((sizeof *device->hidden));
    3.43 -        }
    3.44 -        if ((device == NULL) || (device->hidden == NULL)) {
    3.45 -            SDL_OutOfMemory();
    3.46 -            if (device) {
    3.47 -                SDL_free(device);
    3.48 -            }
    3.49 -            return (0);
    3.50 -        }
    3.51 -        SDL_memset(device->hidden, 0, (sizeof *device->hidden));
    3.52 -
    3.53 -        /* Set the function pointers */
    3.54 -        device->OpenAudio = BE_OpenAudio;
    3.55 -        device->WaitAudio = BE_WaitAudio;
    3.56 -        device->PlayAudio = BE_PlayAudio;
    3.57 -        device->GetAudioBuf = BE_GetAudioBuf;
    3.58 -        device->CloseAudio = BE_CloseAudio;
    3.59 -
    3.60 -        device->free = Audio_DeleteDevice;
    3.61 +/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
    3.62 +/* The BeOS callback for handling the audio buffer */
    3.63 +static void
    3.64 +FillSound(void *device, void *stream, size_t len,
    3.65 +          const media_raw_audio_format & format)
    3.66 +{
    3.67 +    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
    3.68  
    3.69 -        return device;
    3.70 -    }
    3.71 -
    3.72 -    AudioBootStrap BAUDIO_bootstrap = {
    3.73 -        "baudio", "BeOS BSoundPlayer",
    3.74 -        Audio_Available, Audio_CreateDevice
    3.75 -    };
    3.76 +    /* Silence the buffer, since it's ours */
    3.77 +    SDL_memset(stream, audio->spec.silence, len);
    3.78  
    3.79 -/* The BeOS callback for handling the audio buffer */
    3.80 -    static void FillSound(void *device, void *stream, size_t len,
    3.81 -                          const media_raw_audio_format & format)
    3.82 -    {
    3.83 -        SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
    3.84 -
    3.85 -        /* Silence the buffer, since it's ours */
    3.86 -        SDL_memset(stream, audio->spec.silence, len);
    3.87 +    /* Only do soemthing if audio is enabled */
    3.88 +    if (!audio->enabled)
    3.89 +        return;
    3.90  
    3.91 -        /* Only do soemthing if audio is enabled */
    3.92 -        if (!audio->enabled)
    3.93 -            return;
    3.94 -
    3.95 -        if (!audio->paused) {
    3.96 -            if (audio->convert.needed) {
    3.97 -                SDL_mutexP(audio->mixer_lock);
    3.98 -                (*audio->spec.callback) (audio->spec.userdata,
    3.99 +    if (!audio->paused) {
   3.100 +        if (audio->convert.needed) {
   3.101 +            SDL_mutexP(audio->mixer_lock);
   3.102 +            (*audio->spec.callback) (audio->spec.userdata,
   3.103                                           (Uint8 *) audio->convert.buf,
   3.104                                           audio->convert.len);
   3.105 -                SDL_mutexV(audio->mixer_lock);
   3.106 -                SDL_ConvertAudio(&audio->convert);
   3.107 -                SDL_memcpy(stream, audio->convert.buf,
   3.108 -                           audio->convert.len_cvt);
   3.109 -            } else {
   3.110 -                SDL_mutexP(audio->mixer_lock);
   3.111 -                (*audio->spec.callback) (audio->spec.userdata,
   3.112 -                                         (Uint8 *) stream, len);
   3.113 -                SDL_mutexV(audio->mixer_lock);
   3.114 -            }
   3.115 +            SDL_mutexV(audio->mixer_lock);
   3.116 +            SDL_ConvertAudio(&audio->convert);
   3.117 +            SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
   3.118 +        } else {
   3.119 +            SDL_mutexP(audio->mixer_lock);
   3.120 +            (*audio->spec.callback) (audio->spec.userdata,
   3.121 +                                        (Uint8 *) stream, len);
   3.122 +            SDL_mutexV(audio->mixer_lock);
   3.123          }
   3.124 -        return;
   3.125      }
   3.126 +}
   3.127  
   3.128 -/* Dummy functions -- we don't use thread-based audio */
   3.129 -    void BE_WaitAudio(_THIS)
   3.130 -    {
   3.131 -        return;
   3.132 -    }
   3.133 -    void BE_PlayAudio(_THIS)
   3.134 -    {
   3.135 -        return;
   3.136 -    }
   3.137 -    Uint8 *BE_GetAudioBuf(_THIS)
   3.138 -    {
   3.139 -        return (NULL);
   3.140 -    }
   3.141 +static void
   3.142 +BEAUDIO_CloseDevice(_THIS)
   3.143 +{
   3.144 +    if (_this->hidden != NULL) {
   3.145 +        if (_this->hidden->audio_obj) {
   3.146 +            _this->hidden->audio_obj->Stop();
   3.147 +            delete _this->hidden->audio_obj;
   3.148 +            _this->hidden->audio_obj = NULL;
   3.149 +        }
   3.150  
   3.151 -    void BE_CloseAudio(_THIS)
   3.152 -    {
   3.153 -        if (audio_obj) {
   3.154 -            audio_obj->Stop();
   3.155 -            delete audio_obj;
   3.156 -            audio_obj = NULL;
   3.157 -        }
   3.158 +        delete _this->hidden;
   3.159 +        _this->hidden = NULL;
   3.160  
   3.161          /* Quit the Be Application, if there's nothing left to do */
   3.162          SDL_QuitBeApp();
   3.163      }
   3.164 +}
   3.165  
   3.166 -    int BE_OpenAudio(_THIS, SDL_AudioSpec * spec)
   3.167 -    {
   3.168 -        int valid_datatype = 0;
   3.169 -        media_raw_audio_format format;
   3.170 -        SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
   3.171 +static int
   3.172 +BEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
   3.173 +{
   3.174 +    int valid_datatype = 0;
   3.175 +    media_raw_audio_format format;
   3.176 +    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
   3.177  
   3.178 -        /* Parse the audio format and fill the Be raw audio format */
   3.179 -        memset(&format, '\0', sizeof(media_raw_audio_format));
   3.180 -        format.byte_order = B_MEDIA_LITTLE_ENDIAN;
   3.181 -        format.frame_rate = (float) spec->freq;
   3.182 -        format.channel_count = spec->channels;  /* !!! FIXME: support > 2? */
   3.183 -        while ((!valid_datatype) && (test_format)) {
   3.184 -            valid_datatype = 1;
   3.185 -            spec->format = test_format;
   3.186 -            switch (test_format) {
   3.187 +    /* Initialize all variables that we clean on shutdown */
   3.188 +    _this->hidden = new SDL_PrivateAudioData;
   3.189 +    if (_this->hidden == NULL) {
   3.190 +        SDL_OutOfMemory();
   3.191 +        return 0;
   3.192 +    }
   3.193 +    SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
   3.194 +
   3.195 +    /* Initialize the Be Application, if it's not already started */
   3.196 +    if (SDL_InitBeApp() < 0) {
   3.197 +        return 0;
   3.198 +    }
   3.199 +
   3.200 +    /* Parse the audio format and fill the Be raw audio format */
   3.201 +    memset(&format, '\0', sizeof(media_raw_audio_format));
   3.202 +    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
   3.203 +    format.frame_rate = (float) this->spec.freq;
   3.204 +    format.channel_count = this->spec.channels;  /* !!! FIXME: support > 2? */
   3.205 +    while ((!valid_datatype) && (test_format)) {
   3.206 +        valid_datatype = 1;
   3.207 +        this->spec.format = test_format;
   3.208 +        switch (test_format) {
   3.209              case AUDIO_S8:
   3.210                  format.format = media_raw_audio_format::B_AUDIO_CHAR;
   3.211                  break;
   3.212 @@ -207,43 +164,53 @@
   3.213                  valid_datatype = 0;
   3.214                  test_format = SDL_NextAudioFormat();
   3.215                  break;
   3.216 -            }
   3.217          }
   3.218 -
   3.219 -        format.buffer_size = spec->samples;
   3.220 -
   3.221 -        if (!valid_datatype) {  /* shouldn't happen, but just in case... */
   3.222 -            SDL_SetError("Unsupported audio format");
   3.223 -            return (-1);
   3.224 -        }
   3.225 -
   3.226 -        /* Initialize the Be Application, if it's not already started */
   3.227 -        if (SDL_InitBeApp() < 0) {
   3.228 -            return (-1);
   3.229 -        }
   3.230 -
   3.231 -        /* Calculate the final parameters for this audio specification */
   3.232 -        SDL_CalculateAudioSpec(spec);
   3.233 +    }
   3.234  
   3.235 -        /* Subscribe to the audio stream (creates a new thread) */
   3.236 -        {
   3.237 -            sigset_t omask;
   3.238 -            SDL_MaskSignals(&omask);
   3.239 -            audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound,
   3.240 -                                         NULL, _this);
   3.241 -            SDL_UnmaskSignals(&omask);
   3.242 -        }
   3.243 -        if (audio_obj->Start() == B_NO_ERROR) {
   3.244 -            audio_obj->SetHasData(true);
   3.245 -        } else {
   3.246 -            SDL_SetError("Unable to start Be audio");
   3.247 -            return (-1);
   3.248 -        }
   3.249 +    format.buffer_size = this->spec.samples;
   3.250  
   3.251 -        /* We're running! */
   3.252 -        return (1);
   3.253 +    if (!valid_datatype) {  /* shouldn't happen, but just in case... */
   3.254 +        SDL_SetError("Unsupported audio format");
   3.255 +        return 0;
   3.256      }
   3.257  
   3.258 -};                              /* Extern C */
   3.259 +    /* Calculate the final parameters for this audio specification */
   3.260 +    SDL_CalculateAudioSpec(&this->spec);
   3.261 +
   3.262 +    /* Subscribe to the audio stream (creates a new thread) */
   3.263 +    sigset_t omask;
   3.264 +    SDL_MaskSignals(&omask);
   3.265 +    _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
   3.266 +                                                FillSound, NULL, _this);
   3.267 +    SDL_UnmaskSignals(&omask);
   3.268 +
   3.269 +    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
   3.270 +        _this->hidden->audio_obj->SetHasData(true);
   3.271 +    } else {
   3.272 +        SDL_SetError("Unable to start Be audio");
   3.273 +        return 0;
   3.274 +    }
   3.275 +
   3.276 +    /* We're running! */
   3.277 +    return 1;
   3.278 +}
   3.279 +
   3.280 +static int
   3.281 +BEAUDIO_Init(SDL_AudioDriverImpl *impl)
   3.282 +{
   3.283 +    /* Set the function pointers */
   3.284 +    impl->OpenDevice = DSP_OpenDevice;
   3.285 +    impl->CloseDevice = DSP_CloseDevice;
   3.286 +    impl->ProvidesOwnCallbackThread = 1;
   3.287 +    impl->OnlyHasDefaultOutputDevice = 1;
   3.288 +
   3.289 +    return 1;
   3.290 +}
   3.291 +
   3.292 +
   3.293 +AudioBootStrap BEAUDIO_bootstrap = {
   3.294 +    "baudio", "BeOS BSoundPlayer",
   3.295 +    BEAUDIO_Available, BEAUDIO_Init, 0
   3.296 +};
   3.297  
   3.298  /* vi: set ts=4 sw=4 expandtab: */
     4.1 --- a/src/audio/baudio/SDL_beaudio.h	Fri Oct 06 19:45:11 2006 +0000
     4.2 +++ b/src/audio/baudio/SDL_beaudio.h	Fri Oct 06 20:36:23 2006 +0000
     4.3 @@ -34,8 +34,5 @@
     4.4      BSoundPlayer *audio_obj;
     4.5  };
     4.6  
     4.7 -/* Old variable names */
     4.8 -#define audio_obj	(_this->hidden->audio_obj)
     4.9 -
    4.10  #endif /* _SDL_lowaudio_h */
    4.11  /* vi: set ts=4 sw=4 expandtab: */
     5.1 --- a/src/audio/dart/SDL_dart.c	Fri Oct 06 19:45:11 2006 +0000
     5.2 +++ b/src/audio/dart/SDL_dart.c	Fri Oct 06 20:36:23 2006 +0000
     5.3 @@ -42,10 +42,10 @@
     5.4  //---------------------------------------------------------------------
     5.5  // DARTEventFunc
     5.6  //
     5.7 -// This function is called by DART, when an event occures, like end of 
     5.8 +// This function is called by DART, when an event occurs, like end of
     5.9  // playback of a buffer, etc...
    5.10  //---------------------------------------------------------------------
    5.11 -LONG APIENTRY
    5.12 +static LONG APIENTRY
    5.13  DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
    5.14  {
    5.15      if (ulFlags && MIX_WRITE_COMPLETE) {        // Playback of buffer completed!
    5.16 @@ -71,10 +71,10 @@
    5.17  }
    5.18  
    5.19  
    5.20 -int
    5.21 -DART_OpenAudio(_THIS, SDL_AudioSpec * spec)
    5.22 +static int
    5.23 +DART_OpenDevice(_THIS, const char *devname, int iscapture)
    5.24  {
    5.25 -    SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
    5.26 +    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    5.27      int valid_datatype = 0;
    5.28      MCI_AMP_OPEN_PARMS AmpOpenParms;
    5.29      MCI_GENERIC_PARMS GenericParms;
    5.30 @@ -89,6 +89,15 @@
    5.31      int iSilence;
    5.32      int rc;
    5.33  
    5.34 +    /* Initialize all variables that we clean on shutdown */
    5.35 +    this->hidden = (struct SDL_PrivateAudioData *)
    5.36 +                        SDL_malloc((sizeof *this->hidden));
    5.37 +    if (this->hidden == NULL) {
    5.38 +        SDL_OutOfMemory();
    5.39 +        return 0;
    5.40 +    }
    5.41 +    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    5.42 +
    5.43      // First thing is to try to open a given DART device!
    5.44      SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
    5.45      // pszDeviceType should contain the device type in low word, and device ordinal in high word!
    5.46 @@ -100,30 +109,33 @@
    5.47          iOpenMode |= MCI_OPEN_SHAREABLE;
    5.48  
    5.49      rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
    5.50 -    if (rc != MCIERR_SUCCESS)   // No audio available??
    5.51 -        return (-1);
    5.52 +    if (rc != MCIERR_SUCCESS) {  // No audio available??
    5.53 +        DART_CloseDevice(this);
    5.54 +        return 0;
    5.55 +    }
    5.56 +
    5.57      // Save the device ID we got from DART!
    5.58      // We will use this in the next calls!
    5.59 -    iDeviceOrd = AmpOpenParms.usDeviceID;
    5.60 +    _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID;
    5.61  
    5.62      // Determine the audio parameters from the AudioSpec
    5.63 -    if (spec->channels > 4)
    5.64 -        spec->channels = 4;
    5.65 +    if (this->spec.channels > 4)
    5.66 +        this->spec.channels = 4;
    5.67  
    5.68      while ((!valid_datatype) && (test_format)) {
    5.69 -        spec->format = test_format;
    5.70 +        this->spec.format = test_format;
    5.71          valid_datatype = 1;
    5.72          switch (test_format) {
    5.73          case AUDIO_U8:
    5.74              // Unsigned 8 bit audio data
    5.75              iSilence = 0x80;
    5.76 -            iBits = 8;
    5.77 +            _this->hidden->iCurrBits = iBits = 8;
    5.78              break;
    5.79  
    5.80          case AUDIO_S16LSB:
    5.81              // Signed 16 bit audio data
    5.82              iSilence = 0x00;
    5.83 -            iBits = 16;
    5.84 +            _this->hidden->iCurrBits = iBits = 16;
    5.85              break;
    5.86  
    5.87              // !!! FIXME: int32?
    5.88 @@ -137,16 +149,16 @@
    5.89  
    5.90      if (!valid_datatype) {      // shouldn't happen, but just in case...
    5.91          // Close DART, and exit with error code!
    5.92 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
    5.93 +        DART_CloseDevice(this);
    5.94          SDL_SetError("Unsupported audio format");
    5.95 -        return (-1);
    5.96 +        return 0;
    5.97      }
    5.98  
    5.99 -    iFreq = spec->freq;
   5.100 -    iChannels = spec->channels;
   5.101 +    _this->hidden->iCurrFreq = iFreq = this->spec.freq;
   5.102 +    _this->hidden->iCurrChannels = iChannels = this->spec.channels;
   5.103      /* Update the fragment size as size in bytes */
   5.104 -    SDL_CalculateAudioSpec(spec);
   5.105 -    iBufSize = spec->size;
   5.106 +    SDL_CalculateAudioSpec(&this->spec);
   5.107 +    _this->hidden->iCurrBufSize = iBufSize = this->spec.size;
   5.108  
   5.109      // Now query this device if it supports the given freq/bits/channels!
   5.110      SDL_memset(&(_this->hidden->MixSetupParms), 0,
   5.111 @@ -163,9 +175,9 @@
   5.112                          &(_this->hidden->MixSetupParms), 0);
   5.113      if (rc != MCIERR_SUCCESS) { // The device cannot handle this format!
   5.114          // Close DART, and exit with error code!
   5.115 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
   5.116 +        DART_CloseDevice(this);
   5.117          SDL_SetError("Audio device doesn't support requested audio format");
   5.118 -        return (-1);
   5.119 +        return 0;
   5.120      }
   5.121      // The device can handle this format, so initialize!
   5.122      rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
   5.123 @@ -173,9 +185,9 @@
   5.124                          &(_this->hidden->MixSetupParms), 0);
   5.125      if (rc != MCIERR_SUCCESS) { // The device could not be opened!
   5.126          // Close DART, and exit with error code!
   5.127 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
   5.128 +        DART_CloseDevice(this);
   5.129          SDL_SetError("Audio device could not be set up");
   5.130 -        return (-1);
   5.131 +        return 0;
   5.132      }
   5.133      // Ok, the device is initialized.
   5.134      // Now we should allocate buffers. For this, we need a place where
   5.135 @@ -184,9 +196,9 @@
   5.136          (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs);
   5.137      if (!(_this->hidden->pMixBuffers)) {        // Not enough memory!
   5.138          // Close DART, and exit with error code!
   5.139 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
   5.140 -        SDL_SetError("Not enough memory for audio buffer descriptors");
   5.141 -        return (-1);
   5.142 +        DART_CloseDevice(this);
   5.143 +        SDL_OutOfMemory();
   5.144 +        return 0;
   5.145      }
   5.146      // Now that we have the place for buffer list, we can ask DART for the
   5.147      // buffers!
   5.148 @@ -201,12 +213,12 @@
   5.149          || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers)
   5.150          || (_this->hidden->BufferParms.ulBufferSize == 0)) {    // Could not allocate memory!
   5.151          // Close DART, and exit with error code!
   5.152 -        SDL_free(_this->hidden->pMixBuffers);
   5.153 -        _this->hidden->pMixBuffers = NULL;
   5.154 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
   5.155 +        DART_CloseDevice(this);
   5.156          SDL_SetError("DART could not allocate buffers");
   5.157 -        return (-1);
   5.158 +        return 0;
   5.159      }
   5.160 +    _this->hidden->iCurrNumBufs = iNumBufs;
   5.161 +
   5.162      // Ok, we have all the buffers allocated, let's mark them!
   5.163      {
   5.164          int i;
   5.165 @@ -216,24 +228,9 @@
   5.166              // Check if this buffer was really allocated by DART
   5.167              if ((!(_this->hidden->pMixBuffers[i].pBuffer))
   5.168                  || (!pBufferDesc)) {    // Wrong buffer!
   5.169 -                // Close DART, and exit with error code!
   5.170 -                // Free buffer descriptions
   5.171 -                {
   5.172 -                    int j;
   5.173 -                    for (j = 0; j < i; j++)
   5.174 -                        SDL_free((void *) (_this->hidden->pMixBuffers[j].
   5.175 -                                           ulUserParm));
   5.176 -                }
   5.177 -                // and cleanup
   5.178 -                mciSendCommand(iDeviceOrd, MCI_BUFFER,
   5.179 -                               MCI_WAIT | MCI_DEALLOCATE_MEMORY,
   5.180 -                               &(_this->hidden->BufferParms), 0);
   5.181 -                SDL_free(_this->hidden->pMixBuffers);
   5.182 -                _this->hidden->pMixBuffers = NULL;
   5.183 -                mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT,
   5.184 -                               &GenericParms, 0);
   5.185 +                DART_CloseDevice(this);
   5.186                  SDL_SetError("Error at internal buffer check");
   5.187 -                return (-1);
   5.188 +                return 0;
   5.189              }
   5.190              pBufferDesc->iBufferUsage = BUFFER_EMPTY;
   5.191              pBufferDesc->pSDLAudioDevice = _this;
   5.192 @@ -254,35 +251,15 @@
   5.193      if (DosCreateEventSem
   5.194          (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR)
   5.195      {
   5.196 -        // Could not create event semaphore!
   5.197 -        {
   5.198 -            int i;
   5.199 -            for (i = 0; i < iNumBufs; i++)
   5.200 -                SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
   5.201 -        }
   5.202 -        mciSendCommand(iDeviceOrd, MCI_BUFFER,
   5.203 -                       MCI_WAIT | MCI_DEALLOCATE_MEMORY,
   5.204 -                       &(_this->hidden->BufferParms), 0);
   5.205 -        SDL_free(_this->hidden->pMixBuffers);
   5.206 -        _this->hidden->pMixBuffers = NULL;
   5.207 -        mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
   5.208 +        DART_CloseDevice(this);
   5.209          SDL_SetError("Could not create event semaphore");
   5.210 -        return (-1);
   5.211 +        return 0;
   5.212      }
   5.213 -    // Store the new settings in global variables
   5.214 -    _this->hidden->iCurrDeviceOrd = iDeviceOrd;
   5.215 -    _this->hidden->iCurrFreq = iFreq;
   5.216 -    _this->hidden->iCurrBits = iBits;
   5.217 -    _this->hidden->iCurrChannels = iChannels;
   5.218 -    _this->hidden->iCurrNumBufs = iNumBufs;
   5.219 -    _this->hidden->iCurrBufSize = iBufSize;
   5.220  
   5.221 -    return (0);
   5.222 +    return 1;
   5.223  }
   5.224  
   5.225 -
   5.226 -
   5.227 -void
   5.228 +static void
   5.229  DART_ThreadInit(_THIS)
   5.230  {
   5.231      /* Increase the priority of this thread to make sure that
   5.232 @@ -291,14 +268,14 @@
   5.233      if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
   5.234  #ifdef DEBUG_BUILD
   5.235          printf
   5.236 -            ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n",
   5.237 +            ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
   5.238               SDL_ThreadID());
   5.239  #endif
   5.240          DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
   5.241      } else {
   5.242  #ifdef DEBUG_BUILD
   5.243          printf
   5.244 -            ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n",
   5.245 +            ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
   5.246               SDL_ThreadID());
   5.247  #endif
   5.248          DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
   5.249 @@ -307,8 +284,8 @@
   5.250  }
   5.251  
   5.252  /* This function waits until it is possible to write a full sound buffer */
   5.253 -void
   5.254 -DART_WaitAudio(_THIS)
   5.255 +static void
   5.256 +DART_WaitDevice(_THIS)
   5.257  {
   5.258      int i;
   5.259      pMixBufferDesc pBufDesc;
   5.260 @@ -326,8 +303,8 @@
   5.261      return;
   5.262  }
   5.263  
   5.264 -void
   5.265 -DART_PlayAudio(_THIS)
   5.266 +static void
   5.267 +DART_PlayDevice(_THIS)
   5.268  {
   5.269      int iFreeBuf = _this->hidden->iNextFreeBuffer;
   5.270      pMixBufferDesc pBufDesc;
   5.271 @@ -346,8 +323,8 @@
   5.272      _this->hidden->iNextFreeBuffer = iFreeBuf;
   5.273  }
   5.274  
   5.275 -Uint8 *
   5.276 -DART_GetAudioBuf(_THIS)
   5.277 +static Uint8 *
   5.278 +DART_GetDeviceBuf(_THIS)
   5.279  {
   5.280      int iFreeBuf;
   5.281      Uint8 *pResult;
   5.282 @@ -366,125 +343,116 @@
   5.283                      return pResult;
   5.284                  }
   5.285              } else
   5.286 -                printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n",
   5.287 +                printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
   5.288                         pBufDesc);
   5.289          } else
   5.290 -            printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n",
   5.291 +            printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
   5.292                     _this->hidden);
   5.293      } else
   5.294 -        printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this);
   5.295 +        printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
   5.296      return NULL;
   5.297  }
   5.298  
   5.299 -void
   5.300 +static void
   5.301  DART_WaitDone(_THIS)
   5.302  {
   5.303      pMixBufferDesc pBufDesc;
   5.304 -    ULONG ulPostCount;
   5.305 -    APIRET rc;
   5.306 +    ULONG ulPostCount = 0;
   5.307 +    APIRET rc = NO_ERROR;
   5.308  
   5.309 -    pBufDesc =
   5.310 -        (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden->
   5.311 -                                                    iLastPlayedBuf].
   5.312 -        ulUserParm;
   5.313 -    rc = NO_ERROR;
   5.314 +    pBufDesc = (pMixBufferDesc)
   5.315 +          _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
   5.316 +
   5.317      while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
   5.318          DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
   5.319          rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000);        // 1 sec timeout! Important!
   5.320      }
   5.321  }
   5.322  
   5.323 -void
   5.324 -DART_CloseAudio(_THIS)
   5.325 +static void
   5.326 +DART_CloseDevice(_THIS)
   5.327  {
   5.328      MCI_GENERIC_PARMS GenericParms;
   5.329      int rc;
   5.330 +    int i;
   5.331  
   5.332 -    // Stop DART playback
   5.333 -    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT,
   5.334 -                        &GenericParms, 0);
   5.335 -    if (rc != MCIERR_SUCCESS) {
   5.336 +    if (_this->hidden != NULL) {
   5.337 +        // Stop DART playback
   5.338 +        if (_this->hidden->iCurrDeviceOrd) {
   5.339 +            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
   5.340 +                                MCI_WAIT, &GenericParms, 0);
   5.341  #ifdef SFX_DEBUG_BUILD
   5.342 -        printf("Could not stop DART playback!\n");
   5.343 -        fflush(stdout);
   5.344 +            if (rc != MCIERR_SUCCESS) {
   5.345 +                printf("Could not stop DART playback!\n");
   5.346 +                fflush(stdout);
   5.347 +            }
   5.348  #endif
   5.349 -    }
   5.350 -    // Close event semaphore
   5.351 -    DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
   5.352 +        }
   5.353 +
   5.354 +        // Close event semaphore
   5.355 +        if (_this->hidden->hevAudioBufferPlayed) {
   5.356 +            DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
   5.357 +            _this->hidden->hevAudioBufferPlayed = 0;
   5.358 +        }
   5.359  
   5.360 -    // Free memory of buffer descriptions
   5.361 -    {
   5.362 -        int i;
   5.363 -        for (i = 0; i < _this->hidden->iCurrNumBufs; i++)
   5.364 +        // Free memory of buffer descriptions
   5.365 +        for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
   5.366              SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
   5.367 -    }
   5.368 +            _this->hidden->pMixBuffers[i].ulUserParm = 0;
   5.369 +        }
   5.370 +        _this->hidden->iCurrNumBufs = 0;
   5.371 +
   5.372 +        // Deallocate buffers
   5.373 +        if (_this->hidden->iCurrDeviceOrd) {
   5.374 +            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
   5.375 +                                MCI_WAIT | MCI_DEALLOCATE_MEMORY,
   5.376 +                                &(_this->hidden->BufferParms), 0);
   5.377 +        }
   5.378  
   5.379 -    // Deallocate buffers
   5.380 -    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
   5.381 -                        MCI_WAIT | MCI_DEALLOCATE_MEMORY,
   5.382 -                        &(_this->hidden->BufferParms), 0);
   5.383 +        // Free bufferlist
   5.384 +        if (_this->hidden->pMixBuffers != NULL) {
   5.385 +            SDL_free(_this->hidden->pMixBuffers);
   5.386 +            _this->hidden->pMixBuffers = NULL;
   5.387 +        }
   5.388  
   5.389 -    // Free bufferlist
   5.390 -    SDL_free(_this->hidden->pMixBuffers);
   5.391 -    _this->hidden->pMixBuffers = NULL;
   5.392 +        // Close dart
   5.393 +        if (_this->hidden->iCurrDeviceOrd) {
   5.394 +            rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
   5.395 +                                MCI_WAIT, &(GenericParms), 0);
   5.396 +        }
   5.397 +        _this->hidden->iCurrDeviceOrd = 0;
   5.398  
   5.399 -    // Close dart
   5.400 -    rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT,
   5.401 -                        &(GenericParms), 0);
   5.402 +        SDL_free(_this->hidden);
   5.403 +        _this->hidden = NULL;
   5.404 +    }
   5.405  }
   5.406  
   5.407 -/* Audio driver bootstrap functions */
   5.408 -
   5.409 -int
   5.410 -Audio_Available(void)
   5.411 +static int
   5.412 +DART_Available(void)
   5.413  {
   5.414 -    return (1);
   5.415 -}
   5.416 -
   5.417 -void
   5.418 -Audio_DeleteDevice(SDL_AudioDevice * device)
   5.419 -{
   5.420 -    SDL_free(device->hidden);
   5.421 -    SDL_free(device);
   5.422 +    return 1;  /* Always available on OS/2 Warp */
   5.423  }
   5.424  
   5.425 -SDL_AudioDevice *
   5.426 -Audio_CreateDevice(int devindex)
   5.427 +static int
   5.428 +DART_Init(SDL_AudioDriverImpl *impl)
   5.429  {
   5.430 -    SDL_AudioDevice *this;
   5.431 +    /* Set the function pointers */
   5.432 +    impl->OpenDevice = DART_OpenDevice;
   5.433 +    impl->ThreadInit = DART_ThreadInit;
   5.434 +    impl->WaitDevice = DART_WaitDevice;
   5.435 +    impl->GetDeviceBuf = DART_GetDeviceBuf;
   5.436 +    impl->PlayDevice = DART_PlayDevice;
   5.437 +    impl->WaitDone = DART_WaitDone;
   5.438 +    impl->CloseDevice = DART_CloseDevice;
   5.439 +    impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: is this right? */
   5.440  
   5.441 -    /* Initialize all variables that we clean on shutdown */
   5.442 -    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
   5.443 -    if (this) {
   5.444 -        SDL_memset(this, 0, (sizeof *this));
   5.445 -        this->hidden = (struct SDL_PrivateAudioData *)
   5.446 -            SDL_malloc((sizeof *this->hidden));
   5.447 -    }
   5.448 -    if ((this == NULL) || (this->hidden == NULL)) {
   5.449 -        SDL_OutOfMemory();
   5.450 -        if (this)
   5.451 -            SDL_free(this);
   5.452 -        return (0);
   5.453 -    }
   5.454 -    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   5.455 +    return 1;
   5.456 +}
   5.457  
   5.458 -    /* Set the function pointers */
   5.459 -    this->OpenAudio = DART_OpenAudio;
   5.460 -    this->ThreadInit = DART_ThreadInit;
   5.461 -    this->WaitAudio = DART_WaitAudio;
   5.462 -    this->PlayAudio = DART_PlayAudio;
   5.463 -    this->GetAudioBuf = DART_GetAudioBuf;
   5.464 -    this->WaitDone = DART_WaitDone;
   5.465 -    this->CloseAudio = DART_CloseAudio;
   5.466 -
   5.467 -    this->free = Audio_DeleteDevice;
   5.468 -
   5.469 -    return this;
   5.470 -}
   5.471  
   5.472  AudioBootStrap DART_bootstrap = {
   5.473      "dart", "OS/2 Direct Audio RouTines (DART)",
   5.474 -    Audio_Available, Audio_CreateDevice, 0
   5.475 +    DART_Available, DART_Init, 0
   5.476  };
   5.477  
   5.478  /* vi: set ts=4 sw=4 expandtab: */
     6.1 --- a/src/audio/dart/SDL_dart.h	Fri Oct 06 19:45:11 2006 +0000
     6.2 +++ b/src/audio/dart/SDL_dart.h	Fri Oct 06 20:36:23 2006 +0000
     6.3 @@ -21,8 +21,8 @@
     6.4  */
     6.5  #include "SDL_config.h"
     6.6  
     6.7 -#ifndef _SDL_lowaudio_h
     6.8 -#define _SDL_lowaudio_h
     6.9 +#ifndef _SDL_dart_h
    6.10 +#define _SDL_dart_h
    6.11  
    6.12  #define INCL_TYPES
    6.13  #define INCL_DOSSEMAPHORES
    6.14 @@ -61,5 +61,6 @@
    6.15      HEV hevAudioBufferPlayed;   // Event semaphore to indicate that an audio buffer has been played by DART
    6.16  };
    6.17  
    6.18 -#endif /* _SDL_lowaudio_h */
    6.19 +#endif /* _SDL_dart_h */
    6.20 +
    6.21  /* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/audio/dc/SDL_dcaudio.c	Fri Oct 06 19:45:11 2006 +0000
     7.2 +++ b/src/audio/dc/SDL_dcaudio.c	Fri Oct 06 20:36:23 2006 +0000
     7.3 @@ -33,79 +33,6 @@
     7.4  #include "aica.h"
     7.5  #include <dc/spu.h>
     7.6  
     7.7 -/* Audio driver functions */
     7.8 -static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
     7.9 -static void DCAUD_WaitAudio(_THIS);
    7.10 -static void DCAUD_PlayAudio(_THIS);
    7.11 -static Uint8 *DCAUD_GetAudioBuf(_THIS);
    7.12 -static void DCAUD_CloseAudio(_THIS);
    7.13 -
    7.14 -/* Audio driver bootstrap functions */
    7.15 -static int
    7.16 -DCAUD_Available(void)
    7.17 -{
    7.18 -    return 1;
    7.19 -}
    7.20 -
    7.21 -static void
    7.22 -DCAUD_DeleteDevice(SDL_AudioDevice * device)
    7.23 -{
    7.24 -    SDL_free(device->hidden);
    7.25 -    SDL_free(device);
    7.26 -}
    7.27 -
    7.28 -static SDL_AudioDevice *
    7.29 -DCAUD_CreateDevice(int devindex)
    7.30 -{
    7.31 -    SDL_AudioDevice *this;
    7.32 -
    7.33 -    /* Initialize all variables that we clean on shutdown */
    7.34 -    this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
    7.35 -    if (this) {
    7.36 -        SDL_memset(this, 0, (sizeof *this));
    7.37 -        this->hidden = (struct SDL_PrivateAudioData *)
    7.38 -            SDL_malloc((sizeof *this->hidden));
    7.39 -    }
    7.40 -    if ((this == NULL) || (this->hidden == NULL)) {
    7.41 -        SDL_OutOfMemory();
    7.42 -        if (this) {
    7.43 -            SDL_free(this);
    7.44 -        }
    7.45 -        return (0);
    7.46 -    }
    7.47 -    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    7.48 -
    7.49 -    /* Set the function pointers */
    7.50 -    this->OpenAudio = DCAUD_OpenAudio;
    7.51 -    this->WaitAudio = DCAUD_WaitAudio;
    7.52 -    this->PlayAudio = DCAUD_PlayAudio;
    7.53 -    this->GetAudioBuf = DCAUD_GetAudioBuf;
    7.54 -    this->CloseAudio = DCAUD_CloseAudio;
    7.55 -
    7.56 -    this->free = DCAUD_DeleteDevice;
    7.57 -
    7.58 -    spu_init();
    7.59 -
    7.60 -    return this;
    7.61 -}
    7.62 -
    7.63 -AudioBootStrap DCAUD_bootstrap = {
    7.64 -    "dcaudio", "Dreamcast AICA audio",
    7.65 -    DCAUD_Available, DCAUD_CreateDevice, 0
    7.66 -};
    7.67 -
    7.68 -/* This function waits until it is possible to write a full sound buffer */
    7.69 -static void
    7.70 -DCAUD_WaitAudio(_THIS)
    7.71 -{
    7.72 -    if (this->hidden->playing) {
    7.73 -        /* wait */
    7.74 -        while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
    7.75 -            thd_pass();
    7.76 -        }
    7.77 -    }
    7.78 -}
    7.79 -
    7.80  #define	SPU_RAM_BASE	0xa0800000
    7.81  
    7.82  static void
    7.83 @@ -151,7 +78,7 @@
    7.84  }
    7.85  
    7.86  static void
    7.87 -DCAUD_PlayAudio(_THIS)
    7.88 +DCAUD_PlayDevice(_THIS)
    7.89  {
    7.90      SDL_AudioSpec *spec = &this->spec;
    7.91      unsigned int offset;
    7.92 @@ -199,28 +126,59 @@
    7.93  }
    7.94  
    7.95  static Uint8 *
    7.96 -DCAUD_GetAudioBuf(_THIS)
    7.97 +DCAUD_GetDeviceBuf(_THIS)
    7.98  {
    7.99      return (this->hidden->mixbuf);
   7.100  }
   7.101  
   7.102 +/* This function waits until it is possible to write a full sound buffer */
   7.103  static void
   7.104 -DCAUD_CloseAudio(_THIS)
   7.105 +DCAUD_WaitDevice(_THIS)
   7.106  {
   7.107 -    aica_stop(0);
   7.108 -    if (this->spec.channels == 2)
   7.109 -        aica_stop(1);
   7.110 -    if (this->hidden->mixbuf != NULL) {
   7.111 -        SDL_FreeAudioMem(this->hidden->mixbuf);
   7.112 -        this->hidden->mixbuf = NULL;
   7.113 +    if (this->hidden->playing) {
   7.114 +        /* wait */
   7.115 +        while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
   7.116 +            thd_pass();
   7.117 +        }
   7.118 +    }
   7.119 +}
   7.120 +
   7.121 +static void
   7.122 +DCAUD_CloseDevice(_THIS)
   7.123 +{
   7.124 +    if (this->hidden != NULL) {
   7.125 +        aica_stop(0);
   7.126 +        if (this->spec.channels == 2) {
   7.127 +            aica_stop(1);
   7.128 +        }
   7.129 +        if (this->hidden->mixbuf != NULL) {
   7.130 +            SDL_FreeAudioMem(this->hidden->mixbuf);
   7.131 +            this->hidden->mixbuf = NULL;
   7.132 +        }
   7.133 +        SDL_free(this->hidden);
   7.134 +        this->hidden = NULL;
   7.135 +
   7.136 +        /* !!! FIXME: is there a reverse of spu_init()? */
   7.137      }
   7.138  }
   7.139  
   7.140  static int
   7.141 -DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec)
   7.142 +DCAUD_OpenDevice(_THIS, SDL_AudioSpec * spec)
   7.143  {
   7.144      SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
   7.145      int valid_datatype = 0;
   7.146 +
   7.147 +    /* Initialize all variables that we clean on shutdown */
   7.148 +    this->hidden = (struct SDL_PrivateAudioData *)
   7.149 +                        SDL_malloc((sizeof *this->hidden));
   7.150 +    if (this->hidden == NULL) {
   7.151 +        SDL_OutOfMemory();
   7.152 +        return 0;
   7.153 +    }
   7.154 +    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   7.155 +
   7.156 +    spu_init();
   7.157 +
   7.158      while ((!valid_datatype) && (test_format)) {
   7.159          spec->format = test_format;
   7.160          switch (test_format) {
   7.161 @@ -237,8 +195,9 @@
   7.162      }
   7.163  
   7.164      if (!valid_datatype) {      /* shouldn't happen, but just in case... */
   7.165 +        DCAUD_CloseDevice(this);
   7.166          SDL_SetError("Unsupported audio format");
   7.167 -        return (-1);
   7.168 +        return 0;
   7.169      }
   7.170  
   7.171      if (spec->channels > 2)
   7.172 @@ -251,7 +210,9 @@
   7.173      this->hidden->mixlen = spec->size;
   7.174      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   7.175      if (this->hidden->mixbuf == NULL) {
   7.176 -        return (-1);
   7.177 +        DCAUD_CloseDevice(this);
   7.178 +        SDL_OutOfMemory();
   7.179 +        return 0;
   7.180      }
   7.181      SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
   7.182      this->hidden->leftpos = 0x11000;
   7.183 @@ -260,7 +221,32 @@
   7.184      this->hidden->nextbuf = 0;
   7.185  
   7.186      /* We're ready to rock and roll. :-) */
   7.187 -    return (0);
   7.188 +    return 1;
   7.189 +}
   7.190 +
   7.191 +static int
   7.192 +DCAUD_Available(void)
   7.193 +{
   7.194 +    return 1;  /* Dreamcast hardware is always available.  :) */
   7.195  }
   7.196  
   7.197 +static int
   7.198 +DCAUD_Init(SDL_AudioDriverImpl *impl)
   7.199 +{
   7.200 +    /* Set the function pointers */
   7.201 +    impl->OpenDevice = DCAUD_OpenDevice;
   7.202 +    impl->PlayDevice = DCAUD_PlayDevice;
   7.203 +    impl->WaitDevice = DCAUD_WaitDevice;
   7.204 +    impl->GetDeviceBuf = DCAUD_GetDeviceBuf;
   7.205 +    impl->CloseDevice = DCAUD_CloseDevice;
   7.206 +    impl->OnlyHasDefaultOutputDevice = 1;
   7.207 +
   7.208 +    return 1;
   7.209 +}
   7.210 +
   7.211 +AudioBootStrap DCAUD_bootstrap = {
   7.212 +    "dcaudio", "Dreamcast AICA audio",
   7.213 +    DCAUD_Available, DCAUD_Init, 0
   7.214 +};
   7.215 +
   7.216  /* vi: set ts=4 sw=4 expandtab: */