audio: Clean up some CloseDevice() interface details.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 05 Aug 2016 01:44:41 -0400
changeset 102559530fc07da6c
parent 10254 c2730130a448
child 10256 620329de23d4
audio: Clean up some CloseDevice() interface details.

- It's now always called if device->hidden isn't NULL, even if OpenDevice()
failed halfway through. This lets implementation code not have to clean up
itself on every possible failure point; just return an error and SDL will
handle it for you.

- Implementations can assume this->hidden != NULL and not check for it.

- implementations don't have to set this->hidden = NULL when done, because
the caller is always about to free(this).

- Don't reset other fields that are in a block of memory about to be free()'d.

- Implementations all now free things like internal mix buffers last, after
closing devices and such, to guarantee they definitely aren't in use anymore
at the point of deallocation.
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/alsa/SDL_alsa_audio.c
src/audio/android/SDL_androidaudio.c
src/audio/arts/SDL_artsaudio.c
src/audio/bsd/SDL_bsdaudio.c
src/audio/coreaudio/SDL_coreaudio.c
src/audio/directsound/SDL_directsound.c
src/audio/disk/SDL_diskaudio.c
src/audio/dsp/SDL_dspaudio.c
src/audio/emscripten/SDL_emscriptenaudio.c
src/audio/esd/SDL_esdaudio.c
src/audio/fusionsound/SDL_fsaudio.c
src/audio/haiku/SDL_haikuaudio.cc
src/audio/nacl/SDL_naclaudio.c
src/audio/nas/SDL_nasaudio.c
src/audio/paudio/SDL_paudio.c
src/audio/psp/SDL_pspaudio.c
src/audio/pulseaudio/SDL_pulseaudio.c
src/audio/qsa/SDL_qsa_audio.c
src/audio/sndio/SDL_sndioaudio.c
src/audio/sun/SDL_sunaudio.c
src/audio/winmm/SDL_winmm.c
src/audio/xaudio2/SDL_xaudio2.c
     1.1 --- a/src/audio/SDL_audio.c	Thu Aug 04 11:51:17 2016 -0400
     1.2 +++ b/src/audio/SDL_audio.c	Fri Aug 05 01:44:41 2016 -0400
     1.3 @@ -982,9 +982,8 @@
     1.4      if (device->convert.needed) {
     1.5          SDL_FreeAudioMem(device->convert.buf);
     1.6      }
     1.7 -    if (device->opened) {
     1.8 +    if (device->hidden != NULL) {
     1.9          current_audio.impl.CloseDevice(device);
    1.10 -        device->opened = SDL_FALSE;
    1.11      }
    1.12  
    1.13      free_audio_queue(device->buffer_queue_head);
    1.14 @@ -1193,7 +1192,10 @@
    1.15          close_audio_device(device);
    1.16          return 0;
    1.17      }
    1.18 -    device->opened = SDL_TRUE;
    1.19 +
    1.20 +    /* if your target really doesn't need it, set it to 0x1 or something. */
    1.21 +    /* otherwise, close_audio_device() won't call impl.CloseDevice(). */
    1.22 +    SDL_assert(device->hidden != NULL);
    1.23  
    1.24      /* See if we need to do any conversion */
    1.25      build_cvt = SDL_FALSE;
     2.1 --- a/src/audio/SDL_sysaudio.h	Thu Aug 04 11:51:17 2016 -0400
     2.2 +++ b/src/audio/SDL_sysaudio.h	Fri Aug 05 01:44:41 2016 -0400
     2.3 @@ -162,7 +162,6 @@
     2.4      SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */
     2.5      SDL_atomic_t enabled;  /* true if device is functioning and connected. */
     2.6      SDL_atomic_t paused;
     2.7 -    SDL_bool opened;
     2.8      SDL_bool iscapture;
     2.9  
    2.10      /* Fake audio buffer for when the audio hardware is busy */
     3.1 --- a/src/audio/alsa/SDL_alsa_audio.c	Thu Aug 04 11:51:17 2016 -0400
     3.2 +++ b/src/audio/alsa/SDL_alsa_audio.c	Fri Aug 05 01:44:41 2016 -0400
     3.3 @@ -402,17 +402,12 @@
     3.4  static void
     3.5  ALSA_CloseDevice(_THIS)
     3.6  {
     3.7 -    if (this->hidden != NULL) {
     3.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
     3.9 -        this->hidden->mixbuf = NULL;
    3.10 -        if (this->hidden->pcm_handle) {
    3.11 -            ALSA_snd_pcm_drain(this->hidden->pcm_handle);
    3.12 -            ALSA_snd_pcm_close(this->hidden->pcm_handle);
    3.13 -            this->hidden->pcm_handle = NULL;
    3.14 -        }
    3.15 -        SDL_free(this->hidden);
    3.16 -        this->hidden = NULL;
    3.17 +    if (this->hidden->pcm_handle) {
    3.18 +        ALSA_snd_pcm_drain(this->hidden->pcm_handle);
    3.19 +        ALSA_snd_pcm_close(this->hidden->pcm_handle);
    3.20      }
    3.21 +    SDL_FreeAudioMem(this->hidden->mixbuf);
    3.22 +    SDL_free(this->hidden);
    3.23  }
    3.24  
    3.25  static int
    3.26 @@ -555,7 +550,6 @@
    3.27                  SND_PCM_NONBLOCK);
    3.28  
    3.29      if (status < 0) {
    3.30 -        ALSA_CloseDevice(this);
    3.31          return SDL_SetError("ALSA: Couldn't open audio device: %s",
    3.32                              ALSA_snd_strerror(status));
    3.33      }
    3.34 @@ -566,7 +560,6 @@
    3.35      snd_pcm_hw_params_alloca(&hwparams);
    3.36      status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
    3.37      if (status < 0) {
    3.38 -        ALSA_CloseDevice(this);
    3.39          return SDL_SetError("ALSA: Couldn't get hardware config: %s",
    3.40                              ALSA_snd_strerror(status));
    3.41      }
    3.42 @@ -575,7 +568,6 @@
    3.43      status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
    3.44                                                 SND_PCM_ACCESS_RW_INTERLEAVED);
    3.45      if (status < 0) {
    3.46 -        ALSA_CloseDevice(this);
    3.47          return SDL_SetError("ALSA: Couldn't set interleaved access: %s",
    3.48                       ALSA_snd_strerror(status));
    3.49      }
    3.50 @@ -629,7 +621,6 @@
    3.51          }
    3.52      }
    3.53      if (status < 0) {
    3.54 -        ALSA_CloseDevice(this);
    3.55          return SDL_SetError("ALSA: Couldn't find any hardware audio formats");
    3.56      }
    3.57      this->spec.format = test_format;
    3.58 @@ -641,7 +632,6 @@
    3.59      if (status < 0) {
    3.60          status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
    3.61          if (status < 0) {
    3.62 -            ALSA_CloseDevice(this);
    3.63              return SDL_SetError("ALSA: Couldn't set audio channels");
    3.64          }
    3.65          this->spec.channels = channels;
    3.66 @@ -652,7 +642,6 @@
    3.67      status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
    3.68                                                    &rate, NULL);
    3.69      if (status < 0) {
    3.70 -        ALSA_CloseDevice(this);
    3.71          return SDL_SetError("ALSA: Couldn't set audio frequency: %s",
    3.72                              ALSA_snd_strerror(status));
    3.73      }
    3.74 @@ -664,7 +653,6 @@
    3.75          /* Failed to set desired buffer size, do the best you can... */
    3.76          status = ALSA_set_period_size(this, hwparams, 1);
    3.77          if (status < 0) {
    3.78 -            ALSA_CloseDevice(this);
    3.79              return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status));
    3.80          }
    3.81      }
    3.82 @@ -672,26 +660,22 @@
    3.83      snd_pcm_sw_params_alloca(&swparams);
    3.84      status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
    3.85      if (status < 0) {
    3.86 -        ALSA_CloseDevice(this);
    3.87          return SDL_SetError("ALSA: Couldn't get software config: %s",
    3.88                              ALSA_snd_strerror(status));
    3.89      }
    3.90      status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples);
    3.91      if (status < 0) {
    3.92 -        ALSA_CloseDevice(this);
    3.93          return SDL_SetError("Couldn't set minimum available samples: %s",
    3.94                              ALSA_snd_strerror(status));
    3.95      }
    3.96      status =
    3.97          ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1);
    3.98      if (status < 0) {
    3.99 -        ALSA_CloseDevice(this);
   3.100          return SDL_SetError("ALSA: Couldn't set start threshold: %s",
   3.101                              ALSA_snd_strerror(status));
   3.102      }
   3.103      status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
   3.104      if (status < 0) {
   3.105 -        ALSA_CloseDevice(this);
   3.106          return SDL_SetError("Couldn't set software audio parameters: %s",
   3.107                              ALSA_snd_strerror(status));
   3.108      }
   3.109 @@ -704,7 +688,6 @@
   3.110          this->hidden->mixlen = this->spec.size;
   3.111          this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   3.112          if (this->hidden->mixbuf == NULL) {
   3.113 -            ALSA_CloseDevice(this);
   3.114              return SDL_OutOfMemory();
   3.115          }
   3.116          SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
     4.1 --- a/src/audio/android/SDL_androidaudio.c	Thu Aug 04 11:51:17 2016 -0400
     4.2 +++ b/src/audio/android/SDL_androidaudio.c	Fri Aug 05 01:44:41 2016 -0400
     4.3 @@ -44,6 +44,7 @@
     4.4          return SDL_SetError("Capture not supported on Android");
     4.5      }
     4.6  
     4.7 +    /* !!! FIXME: higher level will prevent this now. Lose this check (and global?). */
     4.8      if (audioDevice != NULL) {
     4.9          return SDL_SetError("Only one audio device at a time please!");
    4.10      }
    4.11 @@ -115,10 +116,7 @@
    4.12      Android_JNI_CloseAudioDevice();
    4.13  
    4.14      if (audioDevice == this) {
    4.15 -        if (audioDevice->hidden != NULL) {
    4.16 -            SDL_free(this->hidden);
    4.17 -            this->hidden = NULL;
    4.18 -        }
    4.19 +        SDL_free(this->hidden);
    4.20          audioDevice = NULL;
    4.21      }
    4.22  }
     5.1 --- a/src/audio/arts/SDL_artsaudio.c	Thu Aug 04 11:51:17 2016 -0400
     5.2 +++ b/src/audio/arts/SDL_artsaudio.c	Fri Aug 05 01:44:41 2016 -0400
     5.3 @@ -203,17 +203,12 @@
     5.4  static void
     5.5  ARTS_CloseDevice(_THIS)
     5.6  {
     5.7 -    if (this->hidden != NULL) {
     5.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
     5.9 -        this->hidden->mixbuf = NULL;
    5.10 -        if (this->hidden->stream) {
    5.11 -            SDL_NAME(arts_close_stream) (this->hidden->stream);
    5.12 -            this->hidden->stream = 0;
    5.13 -        }
    5.14 -        SDL_NAME(arts_free) ();
    5.15 -        SDL_free(this->hidden);
    5.16 -        this->hidden = NULL;
    5.17 +    if (this->hidden->stream) {
    5.18 +        SDL_NAME(arts_close_stream) (this->hidden->stream);
    5.19      }
    5.20 +    SDL_NAME(arts_free) ();
    5.21 +    SDL_FreeAudioMem(this->hidden->mixbuf);
    5.22 +    SDL_free(this->hidden);
    5.23  }
    5.24  
    5.25  static int
    5.26 @@ -267,19 +262,16 @@
    5.27          }
    5.28      }
    5.29      if (format == 0) {
    5.30 -        ARTS_CloseDevice(this);
    5.31          return SDL_SetError("Couldn't find any hardware audio formats");
    5.32      }
    5.33      this->spec.format = test_format;
    5.34  
    5.35      if ((rc = SDL_NAME(arts_init) ()) != 0) {
    5.36 -        ARTS_CloseDevice(this);
    5.37          return SDL_SetError("Unable to initialize ARTS: %s",
    5.38                              SDL_NAME(arts_error_text) (rc));
    5.39      }
    5.40  
    5.41      if (!ARTS_Suspend()) {
    5.42 -        ARTS_CloseDevice(this);
    5.43          return SDL_SetError("ARTS can not open audio device");
    5.44      }
    5.45  
    5.46 @@ -297,7 +289,6 @@
    5.47      /* Determine the power of two of the fragment size */
    5.48      for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec);
    5.49      if ((0x01 << frag_spec) != this->spec.size) {
    5.50 -        ARTS_CloseDevice(this);
    5.51          return SDL_SetError("Fragment size must be a power of two");
    5.52      }
    5.53      frag_spec |= 0x00020000;    /* two fragments, for low latency */
    5.54 @@ -318,7 +309,6 @@
    5.55      this->hidden->mixlen = this->spec.size;
    5.56      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    5.57      if (this->hidden->mixbuf == NULL) {
    5.58 -        ARTS_CloseDevice(this);
    5.59          return SDL_OutOfMemory();
    5.60      }
    5.61      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
     6.1 --- a/src/audio/bsd/SDL_bsdaudio.c	Thu Aug 04 11:51:17 2016 -0400
     6.2 +++ b/src/audio/bsd/SDL_bsdaudio.c	Fri Aug 05 01:44:41 2016 -0400
     6.3 @@ -268,16 +268,11 @@
     6.4  static void
     6.5  BSDAUDIO_CloseDevice(_THIS)
     6.6  {
     6.7 -    if (this->hidden != NULL) {
     6.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
     6.9 -        this->hidden->mixbuf = NULL;
    6.10 -        if (this->hidden->audio_fd >= 0) {
    6.11 -            close(this->hidden->audio_fd);
    6.12 -            this->hidden->audio_fd = -1;
    6.13 -        }
    6.14 -        SDL_free(this->hidden);
    6.15 -        this->hidden = NULL;
    6.16 +    if (this->hidden->audio_fd >= 0) {
    6.17 +        close(this->hidden->audio_fd);
    6.18      }
    6.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
    6.20 +    SDL_free(this->hidden);
    6.21  }
    6.22  
    6.23  static int
    6.24 @@ -319,7 +314,6 @@
    6.25      /* Set to play mode */
    6.26      info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY;
    6.27      if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
    6.28 -        BSDAUDIO_CloseDevice(this);
    6.29          return SDL_SetError("Couldn't put device into play mode");
    6.30      }
    6.31  
    6.32 @@ -361,7 +355,6 @@
    6.33      }
    6.34  
    6.35      if (!format) {
    6.36 -        BSDAUDIO_CloseDevice(this);
    6.37          return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
    6.38      }
    6.39  
    6.40 @@ -386,7 +379,6 @@
    6.41          this->hidden->mixlen = this->spec.size;
    6.42          this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    6.43          if (this->hidden->mixbuf == NULL) {
    6.44 -            BSDAUDIO_CloseDevice(this);
    6.45              return SDL_OutOfMemory();
    6.46          }
    6.47          SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
     7.1 --- a/src/audio/coreaudio/SDL_coreaudio.c	Thu Aug 04 11:51:17 2016 -0400
     7.2 +++ b/src/audio/coreaudio/SDL_coreaudio.c	Fri Aug 05 01:44:41 2016 -0400
     7.3 @@ -22,6 +22,8 @@
     7.4  
     7.5  #if SDL_AUDIO_DRIVER_COREAUDIO
     7.6  
     7.7 +/* !!! FIXME: clean out some of the macro salsa in here. */
     7.8 +
     7.9  #include "SDL_audio.h"
    7.10  #include "../SDL_audio_c.h"
    7.11  #include "../SDL_sysaudio.h"
    7.12 @@ -30,11 +32,8 @@
    7.13  
    7.14  #define DEBUG_COREAUDIO 0
    7.15  
    7.16 -static void COREAUDIO_CloseDevice(_THIS);
    7.17 -
    7.18  #define CHECK_RESULT(msg) \
    7.19      if (result != noErr) { \
    7.20 -        COREAUDIO_CloseDevice(this); \
    7.21          SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
    7.22          return 0; \
    7.23      }
    7.24 @@ -436,45 +435,39 @@
    7.25  static void
    7.26  COREAUDIO_CloseDevice(_THIS)
    7.27  {
    7.28 -    if (this->hidden != NULL) {
    7.29 -        const int iscapture = this->iscapture;
    7.30 -        if (this->hidden->audioUnitOpened) {
    7.31 -            #if MACOSX_COREAUDIO
    7.32 -            /* Unregister our disconnect callback. */
    7.33 -            AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
    7.34 -            #endif
    7.35 +    const int iscapture = this->iscapture;
    7.36 +    if (this->hidden->audioUnitOpened) {
    7.37 +        #if MACOSX_COREAUDIO
    7.38 +        /* Unregister our disconnect callback. */
    7.39 +        AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
    7.40 +        #endif
    7.41  
    7.42 -            AURenderCallbackStruct callback;
    7.43 -            const AudioUnitElement output_bus = 0;
    7.44 -            const AudioUnitElement input_bus = 1;
    7.45 -            const AudioUnitElement bus =
    7.46 -                ((iscapture) ? input_bus : output_bus);
    7.47 +        AURenderCallbackStruct callback;
    7.48 +        const AudioUnitElement output_bus = 0;
    7.49 +        const AudioUnitElement input_bus = 1;
    7.50 +        const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
    7.51  
    7.52 -            /* stop processing the audio unit */
    7.53 -            AudioOutputUnitStop(this->hidden->audioUnit);
    7.54 +        /* stop processing the audio unit */
    7.55 +        AudioOutputUnitStop(this->hidden->audioUnit);
    7.56  
    7.57 -            /* Remove the input callback */
    7.58 -            SDL_zero(callback);
    7.59 -            AudioUnitSetProperty(this->hidden->audioUnit,
    7.60 -                                 iscapture ? kAudioOutputUnitProperty_SetInputCallback : kAudioUnitProperty_SetRenderCallback,
    7.61 -                                 kAudioUnitScope_Global, bus, &callback, sizeof(callback));
    7.62 -            AudioComponentInstanceDispose(this->hidden->audioUnit);
    7.63 -            this->hidden->audioUnitOpened = 0;
    7.64 +        /* Remove the input callback */
    7.65 +        SDL_zero(callback);
    7.66 +        AudioUnitSetProperty(this->hidden->audioUnit,
    7.67 +                             iscapture ? kAudioOutputUnitProperty_SetInputCallback : kAudioUnitProperty_SetRenderCallback,
    7.68 +                             kAudioUnitScope_Global, bus, &callback, sizeof(callback));
    7.69 +        AudioComponentInstanceDispose(this->hidden->audioUnit);
    7.70 +    }
    7.71  
    7.72 -            SDL_free(this->hidden->captureBufferList.mBuffers[0].mData);
    7.73 +    SDL_free(this->hidden->captureBufferList.mBuffers[0].mData);
    7.74 +    SDL_free(this->hidden->buffer);
    7.75 +    SDL_free(this->hidden);
    7.76  
    7.77 -        }
    7.78 -        SDL_free(this->hidden->buffer);
    7.79 -        SDL_free(this->hidden);
    7.80 -        this->hidden = NULL;
    7.81 -
    7.82 -        if (iscapture) {
    7.83 -            open_capture_devices--;
    7.84 -        } else {
    7.85 -            open_playback_devices--;
    7.86 -        }
    7.87 -        update_audio_session();
    7.88 +    if (iscapture) {
    7.89 +        open_capture_devices--;
    7.90 +    } else {
    7.91 +        open_playback_devices--;
    7.92      }
    7.93 +    update_audio_session();
    7.94  }
    7.95  
    7.96  #if MACOSX_COREAUDIO
    7.97 @@ -623,7 +616,6 @@
    7.98          framesize *= SDL_AUDIO_BITSIZE(this->spec.format) / 8;
    7.99          ptr = SDL_calloc(1, framesize);
   7.100          if (ptr == NULL) {
   7.101 -            COREAUDIO_CloseDevice(this);
   7.102              SDL_OutOfMemory();
   7.103              return 0;
   7.104          }
   7.105 @@ -655,7 +647,6 @@
   7.106  
   7.107      this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
   7.108      if (this->hidden->buffer == NULL) {
   7.109 -        COREAUDIO_CloseDevice(this);
   7.110          SDL_OutOfMemory();
   7.111          return 0;
   7.112      }
   7.113 @@ -737,7 +728,6 @@
   7.114      }
   7.115  
   7.116      if (!valid_datatype) {      /* shouldn't happen, but just in case... */
   7.117 -        COREAUDIO_CloseDevice(this);
   7.118          return SDL_SetError("Unsupported audio format");
   7.119      }
   7.120  
   7.121 @@ -747,7 +737,6 @@
   7.122          strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
   7.123  
   7.124      if (!prepare_audiounit(this, handle, iscapture, &strdesc)) {
   7.125 -        COREAUDIO_CloseDevice(this);
   7.126          return -1;      /* prepare_audiounit() will call SDL_SetError()... */
   7.127      }
   7.128  
     8.1 --- a/src/audio/directsound/SDL_directsound.c	Thu Aug 04 11:51:17 2016 -0400
     8.2 +++ b/src/audio/directsound/SDL_directsound.c	Fri Aug 05 01:44:41 2016 -0400
     8.3 @@ -322,20 +322,13 @@
     8.4  static void
     8.5  DSOUND_CloseDevice(_THIS)
     8.6  {
     8.7 -    if (this->hidden != NULL) {
     8.8 -        if (this->hidden->sound != NULL) {
     8.9 -            if (this->hidden->mixbuf != NULL) {
    8.10 -                /* Clean up the audio buffer */
    8.11 -                IDirectSoundBuffer_Release(this->hidden->mixbuf);
    8.12 -                this->hidden->mixbuf = NULL;
    8.13 -            }
    8.14 -            IDirectSound_Release(this->hidden->sound);
    8.15 -            this->hidden->sound = NULL;
    8.16 -        }
    8.17 -
    8.18 -        SDL_free(this->hidden);
    8.19 -        this->hidden = NULL;
    8.20 +    if (this->hidden->mixbuf != NULL) {
    8.21 +        IDirectSoundBuffer_Release(this->hidden->mixbuf);
    8.22      }
    8.23 +    if (this->hidden->sound != NULL) {
    8.24 +        IDirectSound_Release(this->hidden->sound);
    8.25 +    }
    8.26 +    SDL_free(this->hidden);
    8.27  }
    8.28  
    8.29  /* This function tries to create a secondary audio buffer, and returns the
    8.30 @@ -443,7 +436,6 @@
    8.31      /* Open the audio device */
    8.32      result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
    8.33      if (result != DS_OK) {
    8.34 -        DSOUND_CloseDevice(this);
    8.35          return SetDSerror("DirectSoundCreate", result);
    8.36      }
    8.37  
    8.38 @@ -465,7 +457,6 @@
    8.39      }
    8.40  
    8.41      if (!valid_format) {
    8.42 -        DSOUND_CloseDevice(this);
    8.43          if (tried_format) {
    8.44              return -1;  /* CreateSecondary() should have called SDL_SetError(). */
    8.45          }
     9.1 --- a/src/audio/disk/SDL_diskaudio.c	Thu Aug 04 11:51:17 2016 -0400
     9.2 +++ b/src/audio/disk/SDL_diskaudio.c	Fri Aug 05 01:44:41 2016 -0400
     9.3 @@ -87,16 +87,11 @@
     9.4  static void
     9.5  DISKAUD_CloseDevice(_THIS)
     9.6  {
     9.7 -    if (this->hidden != NULL) {
     9.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
     9.9 -        this->hidden->mixbuf = NULL;
    9.10 -        if (this->hidden->output != NULL) {
    9.11 -            SDL_RWclose(this->hidden->output);
    9.12 -            this->hidden->output = NULL;
    9.13 -        }
    9.14 -        SDL_free(this->hidden);
    9.15 -        this->hidden = NULL;
    9.16 +    if (this->hidden->output != NULL) {
    9.17 +        SDL_RWclose(this->hidden->output);
    9.18      }
    9.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
    9.20 +    SDL_free(this->hidden);
    9.21  }
    9.22  
    9.23  static int
    9.24 @@ -120,14 +115,12 @@
    9.25      /* Open the audio device */
    9.26      this->hidden->output = SDL_RWFromFile(fname, "wb");
    9.27      if (this->hidden->output == NULL) {
    9.28 -        DISKAUD_CloseDevice(this);
    9.29          return -1;
    9.30      }
    9.31  
    9.32      /* Allocate mixing buffer */
    9.33      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    9.34      if (this->hidden->mixbuf == NULL) {
    9.35 -        DISKAUD_CloseDevice(this);
    9.36          return -1;
    9.37      }
    9.38      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    10.1 --- a/src/audio/dsp/SDL_dspaudio.c	Thu Aug 04 11:51:17 2016 -0400
    10.2 +++ b/src/audio/dsp/SDL_dspaudio.c	Fri Aug 05 01:44:41 2016 -0400
    10.3 @@ -60,16 +60,11 @@
    10.4  static void
    10.5  DSP_CloseDevice(_THIS)
    10.6  {
    10.7 -    if (this->hidden != NULL) {
    10.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    10.9 -        this->hidden->mixbuf = NULL;
   10.10 -        if (this->hidden->audio_fd >= 0) {
   10.11 -            close(this->hidden->audio_fd);
   10.12 -            this->hidden->audio_fd = -1;
   10.13 -        }
   10.14 -        SDL_free(this->hidden);
   10.15 -        this->hidden = NULL;
   10.16 +    if (this->hidden->audio_fd >= 0) {
   10.17 +        close(this->hidden->audio_fd);
   10.18      }
   10.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   10.20 +    SDL_free(this->hidden);
   10.21  }
   10.22  
   10.23  
   10.24 @@ -111,7 +106,6 @@
   10.25      /* Open the audio device */
   10.26      this->hidden->audio_fd = open(devname, flags, 0);
   10.27      if (this->hidden->audio_fd < 0) {
   10.28 -        DSP_CloseDevice(this);
   10.29          return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
   10.30      }
   10.31      this->hidden->mixbuf = NULL;
   10.32 @@ -122,7 +116,6 @@
   10.33          ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
   10.34          ctlflags &= ~O_NONBLOCK;
   10.35          if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
   10.36 -            DSP_CloseDevice(this);
   10.37              return SDL_SetError("Couldn't set audio blocking mode");
   10.38          }
   10.39      }
   10.40 @@ -130,7 +123,6 @@
   10.41      /* Get a list of supported hardware formats */
   10.42      if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
   10.43          perror("SNDCTL_DSP_GETFMTS");
   10.44 -        DSP_CloseDevice(this);
   10.45          return SDL_SetError("Couldn't get audio format list");
   10.46      }
   10.47  
   10.48 @@ -187,7 +179,6 @@
   10.49          }
   10.50      }
   10.51      if (format == 0) {
   10.52 -        DSP_CloseDevice(this);
   10.53          return SDL_SetError("Couldn't find any hardware audio formats");
   10.54      }
   10.55      this->spec.format = test_format;
   10.56 @@ -197,7 +188,6 @@
   10.57      if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
   10.58          (value != format)) {
   10.59          perror("SNDCTL_DSP_SETFMT");
   10.60 -        DSP_CloseDevice(this);
   10.61          return SDL_SetError("Couldn't set audio format");
   10.62      }
   10.63  
   10.64 @@ -205,7 +195,6 @@
   10.65      value = this->spec.channels;
   10.66      if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
   10.67          perror("SNDCTL_DSP_CHANNELS");
   10.68 -        DSP_CloseDevice(this);
   10.69          return SDL_SetError("Cannot set the number of channels");
   10.70      }
   10.71      this->spec.channels = value;
   10.72 @@ -214,7 +203,6 @@
   10.73      value = this->spec.freq;
   10.74      if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
   10.75          perror("SNDCTL_DSP_SPEED");
   10.76 -        DSP_CloseDevice(this);
   10.77          return SDL_SetError("Couldn't set audio frequency");
   10.78      }
   10.79      this->spec.freq = value;
   10.80 @@ -225,7 +213,6 @@
   10.81      /* Determine the power of two of the fragment size */
   10.82      for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
   10.83      if ((0x01U << frag_spec) != this->spec.size) {
   10.84 -        DSP_CloseDevice(this);
   10.85          return SDL_SetError("Fragment size must be a power of two");
   10.86      }
   10.87      frag_spec |= 0x00020000;    /* two fragments, for low latency */
   10.88 @@ -253,7 +240,6 @@
   10.89      this->hidden->mixlen = this->spec.size;
   10.90      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   10.91      if (this->hidden->mixbuf == NULL) {
   10.92 -        DSP_CloseDevice(this);
   10.93          return SDL_OutOfMemory();
   10.94      }
   10.95      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    11.1 --- a/src/audio/emscripten/SDL_emscriptenaudio.c	Thu Aug 04 11:51:17 2016 -0400
    11.2 +++ b/src/audio/emscripten/SDL_emscriptenaudio.c	Fri Aug 05 01:44:41 2016 -0400
    11.3 @@ -136,16 +136,8 @@
    11.4  static void
    11.5  Emscripten_CloseDevice(_THIS)
    11.6  {
    11.7 -    if (this->hidden != NULL) {
    11.8 -        if (this->hidden->mixbuf != NULL) {
    11.9 -            /* Clean up the audio buffer */
   11.10 -            SDL_free(this->hidden->mixbuf);
   11.11 -            this->hidden->mixbuf = NULL;
   11.12 -        }
   11.13 -
   11.14 -        SDL_free(this->hidden);
   11.15 -        this->hidden = NULL;
   11.16 -    }
   11.17 +    SDL_free(this->hidden->mixbuf);
   11.18 +    SDL_free(this->hidden);
   11.19  }
   11.20  
   11.21  static int
    12.1 --- a/src/audio/esd/SDL_esdaudio.c	Thu Aug 04 11:51:17 2016 -0400
    12.2 +++ b/src/audio/esd/SDL_esdaudio.c	Fri Aug 05 01:44:41 2016 -0400
    12.3 @@ -174,17 +174,11 @@
    12.4  static void
    12.5  ESD_CloseDevice(_THIS)
    12.6  {
    12.7 -    if (this->hidden != NULL) {
    12.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    12.9 -        this->hidden->mixbuf = NULL;
   12.10 -        if (this->hidden->audio_fd >= 0) {
   12.11 -            SDL_NAME(esd_close) (this->hidden->audio_fd);
   12.12 -            this->hidden->audio_fd = -1;
   12.13 -        }
   12.14 -
   12.15 -        SDL_free(this->hidden);
   12.16 -        this->hidden = NULL;
   12.17 +    if (this->hidden->audio_fd >= 0) {
   12.18 +        SDL_NAME(esd_close) (this->hidden->audio_fd);
   12.19      }
   12.20 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   12.21 +    SDL_free(this->hidden);
   12.22  }
   12.23  
   12.24  /* Try to get the name of the program */
   12.25 @@ -252,7 +246,6 @@
   12.26      }
   12.27  
   12.28      if (!found) {
   12.29 -        ESD_CloseDevice(this);
   12.30          return SDL_SetError("Couldn't find any hardware audio formats");
   12.31      }
   12.32  
   12.33 @@ -271,7 +264,6 @@
   12.34                                     get_progname());
   12.35  
   12.36      if (this->hidden->audio_fd < 0) {
   12.37 -        ESD_CloseDevice(this);
   12.38          return SDL_SetError("Couldn't open ESD connection");
   12.39      }
   12.40  
   12.41 @@ -285,7 +277,6 @@
   12.42      this->hidden->mixlen = this->spec.size;
   12.43      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   12.44      if (this->hidden->mixbuf == NULL) {
   12.45 -        ESD_CloseDevice(this);
   12.46          return SDL_OutOfMemory();
   12.47      }
   12.48      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    13.1 --- a/src/audio/fusionsound/SDL_fsaudio.c	Thu Aug 04 11:51:17 2016 -0400
    13.2 +++ b/src/audio/fusionsound/SDL_fsaudio.c	Fri Aug 05 01:44:41 2016 -0400
    13.3 @@ -22,6 +22,8 @@
    13.4  
    13.5  #if SDL_AUDIO_DRIVER_FUSIONSOUND
    13.6  
    13.7 +/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */
    13.8 +
    13.9  /* Allow access to a raw mixing buffer */
   13.10  
   13.11  #ifdef HAVE_SIGNAL_H
   13.12 @@ -168,20 +170,14 @@
   13.13  static void
   13.14  SDL_FS_CloseDevice(_THIS)
   13.15  {
   13.16 -    if (this->hidden != NULL) {
   13.17 -        SDL_FreeAudioMem(this->hidden->mixbuf);
   13.18 -        this->hidden->mixbuf = NULL;
   13.19 -        if (this->hidden->stream) {
   13.20 -            this->hidden->stream->Release(this->hidden->stream);
   13.21 -            this->hidden->stream = NULL;
   13.22 -        }
   13.23 -        if (this->hidden->fs) {
   13.24 -            this->hidden->fs->Release(this->hidden->fs);
   13.25 -            this->hidden->fs = NULL;
   13.26 -        }
   13.27 -        SDL_free(this->hidden);
   13.28 -        this->hidden = NULL;
   13.29 +    if (this->hidden->stream) {
   13.30 +        this->hidden->stream->Release(this->hidden->stream);
   13.31      }
   13.32 +    if (this->hidden->fs) {
   13.33 +        this->hidden->fs->Release(this->hidden->fs);
   13.34 +    }
   13.35 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   13.36 +    SDL_free(this->hidden);
   13.37  }
   13.38  
   13.39  
   13.40 @@ -239,7 +235,6 @@
   13.41      }
   13.42  
   13.43      if (format == 0) {
   13.44 -        SDL_FS_CloseDevice(this);
   13.45          return SDL_SetError("Couldn't find any hardware audio formats");
   13.46      }
   13.47      this->spec.format = test_format;
   13.48 @@ -247,7 +242,6 @@
   13.49      /* Retrieve the main sound interface. */
   13.50      ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
   13.51      if (ret) {
   13.52 -        SDL_FS_CloseDevice(this);
   13.53          return SDL_SetError("Unable to initialize FusionSound: %d", ret);
   13.54      }
   13.55  
   13.56 @@ -266,7 +260,6 @@
   13.57          this->hidden->fs->CreateStream(this->hidden->fs, &desc,
   13.58                                         &this->hidden->stream);
   13.59      if (ret) {
   13.60 -        SDL_FS_CloseDevice(this);
   13.61          return SDL_SetError("Unable to create FusionSoundStream: %d", ret);
   13.62      }
   13.63  
   13.64 @@ -287,7 +280,6 @@
   13.65      this->hidden->mixlen = this->spec.size;
   13.66      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   13.67      if (this->hidden->mixbuf == NULL) {
   13.68 -        SDL_FS_CloseDevice(this);
   13.69          return SDL_OutOfMemory();
   13.70      }
   13.71      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    14.1 --- a/src/audio/haiku/SDL_haikuaudio.cc	Thu Aug 04 11:51:17 2016 -0400
    14.2 +++ b/src/audio/haiku/SDL_haikuaudio.cc	Fri Aug 05 01:44:41 2016 -0400
    14.3 @@ -74,16 +74,11 @@
    14.4  static void
    14.5  HAIKUAUDIO_CloseDevice(_THIS)
    14.6  {
    14.7 -    if (_this->hidden != NULL) {
    14.8 -        if (_this->hidden->audio_obj) {
    14.9 -            _this->hidden->audio_obj->Stop();
   14.10 -            delete _this->hidden->audio_obj;
   14.11 -            _this->hidden->audio_obj = NULL;
   14.12 -        }
   14.13 -
   14.14 -        delete _this->hidden;
   14.15 -        _this->hidden = NULL;
   14.16 +    if (_this->hidden->audio_obj) {
   14.17 +        _this->hidden->audio_obj->Stop();
   14.18 +        delete _this->hidden->audio_obj;
   14.19      }
   14.20 +    delete _this->hidden;
   14.21  }
   14.22  
   14.23  
   14.24 @@ -177,7 +172,6 @@
   14.25      }
   14.26  
   14.27      if (!valid_datatype) {      /* shouldn't happen, but just in case... */
   14.28 -        HAIKUAUDIO_CloseDevice(_this);
   14.29          return SDL_SetError("Unsupported audio format");
   14.30      }
   14.31  
   14.32 @@ -196,7 +190,6 @@
   14.33      if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
   14.34          _this->hidden->audio_obj->SetHasData(true);
   14.35      } else {
   14.36 -        HAIKUAUDIO_CloseDevice(_this);
   14.37          return SDL_SetError("Unable to start Be audio");
   14.38      }
   14.39  
    15.1 --- a/src/audio/nacl/SDL_naclaudio.c	Thu Aug 04 11:51:17 2016 -0400
    15.2 +++ b/src/audio/nacl/SDL_naclaudio.c	Fri Aug 05 01:44:41 2016 -0400
    15.3 @@ -43,8 +43,6 @@
    15.4  #define SAMPLE_FRAME_COUNT 4096
    15.5  
    15.6  /* Audio driver functions */
    15.7 -static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture);
    15.8 -static void NACLAUD_CloseDevice(_THIS);
    15.9  static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
   15.10  
   15.11  /* FIXME: Make use of latency if needed */
    16.1 --- a/src/audio/nas/SDL_nasaudio.c	Thu Aug 04 11:51:17 2016 -0400
    16.2 +++ b/src/audio/nas/SDL_nasaudio.c	Fri Aug 05 01:44:41 2016 -0400
    16.3 @@ -190,16 +190,11 @@
    16.4  static void
    16.5  NAS_CloseDevice(_THIS)
    16.6  {
    16.7 -    if (this->hidden != NULL) {
    16.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    16.9 -        this->hidden->mixbuf = NULL;
   16.10 -        if (this->hidden->aud) {
   16.11 -            NAS_AuCloseServer(this->hidden->aud);
   16.12 -            this->hidden->aud = 0;
   16.13 -        }
   16.14 -        SDL_free(this->hidden);
   16.15 -        this2 = this->hidden = NULL;
   16.16 +    if (this->hidden->aud) {
   16.17 +        NAS_AuCloseServer(this->hidden->aud);
   16.18      }
   16.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   16.20 +    SDL_free(this->hidden);
   16.21  }
   16.22  
   16.23  static unsigned char
   16.24 @@ -300,21 +295,18 @@
   16.25          }
   16.26      }
   16.27      if (format == 0) {
   16.28 -        NAS_CloseDevice(this);
   16.29          return SDL_SetError("NAS: Couldn't find any hardware audio formats");
   16.30      }
   16.31      this->spec.format = test_format;
   16.32  
   16.33      this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
   16.34      if (this->hidden->aud == 0) {
   16.35 -        NAS_CloseDevice(this);
   16.36          return SDL_SetError("NAS: Couldn't open connection to NAS server");
   16.37      }
   16.38  
   16.39      this->hidden->dev = find_device(this, this->spec.channels);
   16.40      if ((this->hidden->dev == AuNone)
   16.41          || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
   16.42 -        NAS_CloseDevice(this);
   16.43          return SDL_SetError("NAS: Couldn't find a fitting device on NAS server");
   16.44      }
   16.45  
   16.46 @@ -347,7 +339,6 @@
   16.47      this->hidden->mixlen = this->spec.size;
   16.48      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   16.49      if (this->hidden->mixbuf == NULL) {
   16.50 -        NAS_CloseDevice(this);
   16.51          return SDL_OutOfMemory();
   16.52      }
   16.53      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    17.1 --- a/src/audio/paudio/SDL_paudio.c	Thu Aug 04 11:51:17 2016 -0400
    17.2 +++ b/src/audio/paudio/SDL_paudio.c	Fri Aug 05 01:44:41 2016 -0400
    17.3 @@ -228,16 +228,11 @@
    17.4  static void
    17.5  PAUDIO_CloseDevice(_THIS)
    17.6  {
    17.7 -    if (this->hidden != NULL) {
    17.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    17.9 -        this->hidden->mixbuf = NULL;
   17.10 -        if (this->hidden->audio_fd >= 0) {
   17.11 -            close(this->hidden->audio_fd);
   17.12 -            this->hidden->audio_fd = -1;
   17.13 -        }
   17.14 -        SDL_free(this->hidden);
   17.15 -        this->hidden = NULL;
   17.16 +    if (this->hidden->audio_fd >= 0) {
   17.17 +        close(this->hidden->audio_fd);
   17.18      }
   17.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   17.20 +    SDL_free(this->hidden);
   17.21  }
   17.22  
   17.23  static int
   17.24 @@ -268,7 +263,6 @@
   17.25      fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
   17.26      this->hidden->audio_fd = fd;
   17.27      if (fd < 0) {
   17.28 -        PAUDIO_CloseDevice(this);
   17.29          return SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
   17.30      }
   17.31  
   17.32 @@ -277,7 +271,6 @@
   17.33       * that we can have.
   17.34       */
   17.35      if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
   17.36 -        PAUDIO_CloseDevice(this);
   17.37          return SDL_SetError("Couldn't get audio buffer information");
   17.38      }
   17.39  
   17.40 @@ -391,7 +384,6 @@
   17.41  #ifdef DEBUG_AUDIO
   17.42          fprintf(stderr, "Couldn't find any hardware audio formats\n");
   17.43  #endif
   17.44 -        PAUDIO_CloseDevice(this);
   17.45          return SDL_SetError("Couldn't find any hardware audio formats");
   17.46      }
   17.47      this->spec.format = test_format;
   17.48 @@ -449,7 +441,6 @@
   17.49      }
   17.50  
   17.51      if (err != NULL) {
   17.52 -        PAUDIO_CloseDevice(this);
   17.53          return SDL_SetError("Paudio: %s", err);
   17.54      }
   17.55  
   17.56 @@ -457,7 +448,6 @@
   17.57      this->hidden->mixlen = this->spec.size;
   17.58      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   17.59      if (this->hidden->mixbuf == NULL) {
   17.60 -        PAUDIO_CloseDevice(this);
   17.61          return SDL_OutOfMemory();
   17.62      }
   17.63      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
   17.64 @@ -492,7 +482,6 @@
   17.65      paud_control.ioctl_request = AUDIO_START;
   17.66      paud_control.position = 0;
   17.67      if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
   17.68 -        PAUDIO_CloseDevice(this);
   17.69  #ifdef DEBUG_AUDIO
   17.70          fprintf(stderr, "Can't start audio play\n");
   17.71  #endif
    18.1 --- a/src/audio/psp/SDL_pspaudio.c	Thu Aug 04 11:51:17 2016 -0400
    18.2 +++ b/src/audio/psp/SDL_pspaudio.c	Fri Aug 05 01:44:41 2016 -0400
    18.3 @@ -126,14 +126,11 @@
    18.4  {
    18.5      if (this->hidden->channel >= 0) {
    18.6          sceAudioChRelease(this->hidden->channel);
    18.7 -        this->hidden->channel = -1;
    18.8      }
    18.9 +    free(this->hidden->rawbuf);  /* this uses memalign(), not SDL_malloc(). */
   18.10 +    SDL_free(this->hidden);
   18.11 +}
   18.12  
   18.13 -    if (this->hidden->rawbuf != NULL) {
   18.14 -        free(this->hidden->rawbuf);
   18.15 -        this->hidden->rawbuf = NULL;
   18.16 -    }
   18.17 -}
   18.18  static void PSPAUD_ThreadInit(_THIS)
   18.19  {
   18.20      /* Increase the priority of this audio thread by 1 to put it
   18.21 @@ -151,7 +148,6 @@
   18.22  static int
   18.23  PSPAUD_Init(SDL_AudioDriverImpl * impl)
   18.24  {
   18.25 -
   18.26      /* Set the function pointers */
   18.27      impl->OpenDevice = PSPAUD_OpenDevice;
   18.28      impl->PlayDevice = PSPAUD_PlayDevice;
    19.1 --- a/src/audio/pulseaudio/SDL_pulseaudio.c	Thu Aug 04 11:51:17 2016 -0400
    19.2 +++ b/src/audio/pulseaudio/SDL_pulseaudio.c	Fri Aug 05 01:44:41 2016 -0400
    19.3 @@ -463,20 +463,18 @@
    19.4  static void
    19.5  PULSEAUDIO_CloseDevice(_THIS)
    19.6  {
    19.7 -    if (this->hidden != NULL) {
    19.8 +    if (this->hidden->stream) {
    19.9          if (this->hidden->capturebuf != NULL) {
   19.10              PULSEAUDIO_pa_stream_drop(this->hidden->stream);
   19.11          }
   19.12 -        SDL_FreeAudioMem(this->hidden->mixbuf);
   19.13 -        SDL_free(this->hidden->device_name);
   19.14 -        if (this->hidden->stream) {
   19.15 -            PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
   19.16 -            PULSEAUDIO_pa_stream_unref(this->hidden->stream);
   19.17 -        }
   19.18 -        DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
   19.19 -        SDL_free(this->hidden);
   19.20 -        this->hidden = NULL;
   19.21 +        PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
   19.22 +        PULSEAUDIO_pa_stream_unref(this->hidden->stream);
   19.23      }
   19.24 +
   19.25 +    DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
   19.26 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   19.27 +    SDL_free(this->hidden->device_name);
   19.28 +    SDL_free(this->hidden);
   19.29  }
   19.30  
   19.31  static void
   19.32 @@ -579,7 +577,6 @@
   19.33          }
   19.34      }
   19.35      if (paspec.format == PA_SAMPLE_INVALID) {
   19.36 -        PULSEAUDIO_CloseDevice(this);
   19.37          return SDL_SetError("Couldn't find any hardware audio formats");
   19.38      }
   19.39      this->spec.format = test_format;
   19.40 @@ -595,7 +592,6 @@
   19.41          h->mixlen = this->spec.size;
   19.42          h->mixbuf = (Uint8 *) SDL_AllocAudioMem(h->mixlen);
   19.43          if (h->mixbuf == NULL) {
   19.44 -            PULSEAUDIO_CloseDevice(this);
   19.45              return SDL_OutOfMemory();
   19.46          }
   19.47          SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
   19.48 @@ -621,12 +617,10 @@
   19.49  #endif
   19.50  
   19.51      if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
   19.52 -        PULSEAUDIO_CloseDevice(this);
   19.53          return SDL_SetError("Could not connect to PulseAudio server");
   19.54      }
   19.55  
   19.56      if (!FindDeviceName(h, iscapture, handle)) {
   19.57 -        PULSEAUDIO_CloseDevice(this);
   19.58          return SDL_SetError("Requested PulseAudio sink/source missing?");
   19.59      }
   19.60  
   19.61 @@ -643,7 +637,6 @@
   19.62          );
   19.63  
   19.64      if (h->stream == NULL) {
   19.65 -        PULSEAUDIO_CloseDevice(this);
   19.66          return SDL_SetError("Could not set up PulseAudio stream");
   19.67      }
   19.68  
   19.69 @@ -660,18 +653,15 @@
   19.70      }
   19.71  
   19.72      if (rc < 0) {
   19.73 -        PULSEAUDIO_CloseDevice(this);
   19.74          return SDL_SetError("Could not connect PulseAudio stream");
   19.75      }
   19.76  
   19.77      do {
   19.78          if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
   19.79 -            PULSEAUDIO_CloseDevice(this);
   19.80              return SDL_SetError("pa_mainloop_iterate() failed");
   19.81          }
   19.82          state = PULSEAUDIO_pa_stream_get_state(h->stream);
   19.83          if (!PA_STREAM_IS_GOOD(state)) {
   19.84 -            PULSEAUDIO_CloseDevice(this);
   19.85              return SDL_SetError("Could not connect PulseAudio stream");
   19.86          }
   19.87      } while (state != PA_STREAM_READY);
    20.1 --- a/src/audio/qsa/SDL_qsa_audio.c	Thu Aug 04 11:51:17 2016 -0400
    20.2 +++ b/src/audio/qsa/SDL_qsa_audio.c	Fri Aug 05 01:44:41 2016 -0400
    20.3 @@ -322,27 +322,21 @@
    20.4  static void
    20.5  QSA_CloseDevice(_THIS)
    20.6  {
    20.7 -    if (this->hidden != NULL) {
    20.8 -        if (this->hidden->audio_handle != NULL) {
    20.9 -            if (!this->hidden->iscapture) {
   20.10 -                /* Finish playing available samples */
   20.11 -                snd_pcm_plugin_flush(this->hidden->audio_handle,
   20.12 -                                     SND_PCM_CHANNEL_PLAYBACK);
   20.13 -            } else {
   20.14 -                /* Cancel unread samples during capture */
   20.15 -                snd_pcm_plugin_flush(this->hidden->audio_handle,
   20.16 -                                     SND_PCM_CHANNEL_CAPTURE);
   20.17 -            }
   20.18 -            snd_pcm_close(this->hidden->audio_handle);
   20.19 -            this->hidden->audio_handle = NULL;
   20.20 +    if (this->hidden->audio_handle != NULL) {
   20.21 +        if (!this->hidden->iscapture) {
   20.22 +            /* Finish playing available samples */
   20.23 +            snd_pcm_plugin_flush(this->hidden->audio_handle,
   20.24 +                                 SND_PCM_CHANNEL_PLAYBACK);
   20.25 +        } else {
   20.26 +            /* Cancel unread samples during capture */
   20.27 +            snd_pcm_plugin_flush(this->hidden->audio_handle,
   20.28 +                                 SND_PCM_CHANNEL_CAPTURE);
   20.29          }
   20.30 +        snd_pcm_close(this->hidden->audio_handle);
   20.31 +    }
   20.32  
   20.33 -        SDL_FreeAudioMem(this->hidden->pcm_buf);
   20.34 -        this->hidden->pcm_buf = NULL;
   20.35 -
   20.36 -        SDL_free(this->hidden);
   20.37 -        this->hidden = NULL;
   20.38 -    }
   20.39 +    SDL_FreeAudioMem(this->hidden->pcm_buf);
   20.40 +    SDL_free(this->hidden);
   20.41  }
   20.42  
   20.43  static int
   20.44 @@ -391,7 +385,6 @@
   20.45      /* Check if requested device is opened */
   20.46      if (status < 0) {
   20.47          this->hidden->audio_handle = NULL;
   20.48 -        QSA_CloseDevice(this);
   20.49          return QSA_SetError("snd_pcm_open", status);
   20.50      }
   20.51  
   20.52 @@ -401,7 +394,6 @@
   20.53              snd_pcm_plugin_set_disable(this->hidden->audio_handle,
   20.54                                         PLUGIN_DISABLE_MMAP);
   20.55          if (status < 0) {
   20.56 -            QSA_CloseDevice(this);
   20.57              return QSA_SetError("snd_pcm_plugin_set_disable", status);
   20.58          }
   20.59      }
   20.60 @@ -487,7 +479,6 @@
   20.61  
   20.62      /* assumes test_format not 0 on success */
   20.63      if (test_format == 0) {
   20.64 -        QSA_CloseDevice(this);
   20.65          return SDL_SetError("QSA: Couldn't find any hardware audio formats");
   20.66      }
   20.67  
   20.68 @@ -505,7 +496,6 @@
   20.69      /* Setup the transfer parameters according to cparams */
   20.70      status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams);
   20.71      if (status < 0) {
   20.72 -        QSA_CloseDevice(this);
   20.73          return QSA_SetError("snd_pcm_channel_params", status);
   20.74      }
   20.75  
   20.76 @@ -519,7 +509,6 @@
   20.77  
   20.78      /* Setup an audio channel */
   20.79      if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) {
   20.80 -        QSA_CloseDevice(this);
   20.81          return SDL_SetError("QSA: Unable to setup channel");
   20.82      }
   20.83  
   20.84 @@ -542,7 +531,6 @@
   20.85      this->hidden->pcm_buf =
   20.86          (Uint8 *) SDL_AllocAudioMem(this->hidden->pcm_len);
   20.87      if (this->hidden->pcm_buf == NULL) {
   20.88 -        QSA_CloseDevice(this);
   20.89          return SDL_OutOfMemory();
   20.90      }
   20.91      SDL_memset(this->hidden->pcm_buf, this->spec.silence,
   20.92 @@ -560,7 +548,6 @@
   20.93      }
   20.94  
   20.95      if (this->hidden->audio_fd < 0) {
   20.96 -        QSA_CloseDevice(this);
   20.97          return QSA_SetError("snd_pcm_file_descriptor", status);
   20.98      }
   20.99  
  20.100 @@ -578,7 +565,6 @@
  20.101      }
  20.102  
  20.103      if (status < 0) {
  20.104 -        QSA_CloseDevice(this);
  20.105          return QSA_SetError("snd_pcm_plugin_prepare", status);
  20.106      }
  20.107  
    21.1 --- a/src/audio/sndio/SDL_sndioaudio.c	Thu Aug 04 11:51:17 2016 -0400
    21.2 +++ b/src/audio/sndio/SDL_sndioaudio.c	Fri Aug 05 01:44:41 2016 -0400
    21.3 @@ -180,16 +180,11 @@
    21.4  static void
    21.5  SNDIO_CloseDevice(_THIS)
    21.6  {
    21.7 -    if (this->hidden != NULL) {
    21.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    21.9 -        this->hidden->mixbuf = NULL;
   21.10 -        if ( this->hidden->dev != NULL ) {
   21.11 -            SNDIO_sio_close(this->hidden->dev);
   21.12 -            this->hidden->dev = NULL;
   21.13 -        }
   21.14 -        SDL_free(this->hidden);
   21.15 -        this->hidden = NULL;
   21.16 +    if ( this->hidden->dev != NULL ) {
   21.17 +        SNDIO_sio_close(this->hidden->dev);
   21.18      }
   21.19 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   21.20 +    SDL_free(this->hidden);
   21.21  }
   21.22  
   21.23  static int
   21.24 @@ -210,7 +205,6 @@
   21.25  
   21.26      /* !!! FIXME: SIO_DEVANY can be a specific device... */
   21.27      if ((this->hidden->dev = SNDIO_sio_open(SIO_DEVANY, SIO_PLAY, 0)) == NULL) {
   21.28 -        SNDIO_CloseDevice(this);
   21.29          return SDL_SetError("sio_open() failed");
   21.30      }
   21.31  
   21.32 @@ -233,7 +227,6 @@
   21.33                  continue;
   21.34              }
   21.35              if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) {
   21.36 -                SNDIO_CloseDevice(this);
   21.37                  return SDL_SetError("sio_getpar() failed");
   21.38              }
   21.39              if (par.bps != SIO_BPS(par.bits)) {
   21.40 @@ -248,7 +241,6 @@
   21.41      }
   21.42  
   21.43      if (status < 0) {
   21.44 -        SNDIO_CloseDevice(this);
   21.45          return SDL_SetError("sndio: Couldn't find any hardware audio formats");
   21.46      }
   21.47  
   21.48 @@ -269,7 +261,6 @@
   21.49      else if ((par.bps == 1) && (!par.sig))
   21.50          this->spec.format = AUDIO_U8;
   21.51      else {
   21.52 -        SNDIO_CloseDevice(this);
   21.53          return SDL_SetError("sndio: Got unsupported hardware audio format.");
   21.54      }
   21.55  
   21.56 @@ -284,7 +275,6 @@
   21.57      this->hidden->mixlen = this->spec.size;
   21.58      this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   21.59      if (this->hidden->mixbuf == NULL) {
   21.60 -        SNDIO_CloseDevice(this);
   21.61          return SDL_OutOfMemory();
   21.62      }
   21.63      SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
    22.1 --- a/src/audio/sun/SDL_sunaudio.c	Thu Aug 04 11:51:17 2016 -0400
    22.2 +++ b/src/audio/sun/SDL_sunaudio.c	Fri Aug 05 01:44:41 2016 -0400
    22.3 @@ -183,18 +183,12 @@
    22.4  static void
    22.5  SUNAUDIO_CloseDevice(_THIS)
    22.6  {
    22.7 -    if (this->hidden != NULL) {
    22.8 -        SDL_FreeAudioMem(this->hidden->mixbuf);
    22.9 -        this->hidden->mixbuf = NULL;
   22.10 -        SDL_free(this->hidden->ulaw_buf);
   22.11 -        this->hidden->ulaw_buf = NULL;
   22.12 -        if (this->hidden->audio_fd >= 0) {
   22.13 -            close(this->hidden->audio_fd);
   22.14 -            this->hidden->audio_fd = -1;
   22.15 -        }
   22.16 -        SDL_free(this->hidden);
   22.17 -        this->hidden = NULL;
   22.18 +    SDL_free(this->hidden->ulaw_buf);
   22.19 +    if (this->hidden->audio_fd >= 0) {
   22.20 +        close(this->hidden->audio_fd);
   22.21      }
   22.22 +    SDL_FreeAudioMem(this->hidden->mixbuf);
   22.23 +    SDL_free(this->hidden);
   22.24  }
   22.25  
   22.26  static int
    23.1 --- a/src/audio/winmm/SDL_winmm.c	Thu Aug 04 11:51:17 2016 -0400
    23.2 +++ b/src/audio/winmm/SDL_winmm.c	Fri Aug 05 01:44:41 2016 -0400
    23.3 @@ -155,42 +155,31 @@
    23.4  static void
    23.5  WINMM_CloseDevice(_THIS)
    23.6  {
    23.7 -    /* Close up audio */
    23.8 -    if (this->hidden != NULL) {
    23.9 -        int i;
   23.10 +    int i;
   23.11  
   23.12 -        if (this->hidden->audio_sem) {
   23.13 -            CloseHandle(this->hidden->audio_sem);
   23.14 -            this->hidden->audio_sem = 0;
   23.15 +    if (this->hidden->audio_sem) {
   23.16 +        CloseHandle(this->hidden->audio_sem);
   23.17 +    }
   23.18 +
   23.19 +    /* Clean up mixing buffers */
   23.20 +    for (i = 0; i < NUM_BUFFERS; ++i) {
   23.21 +        if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
   23.22 +            waveOutUnprepareHeader(this->hidden->hout,
   23.23 +                                   &this->hidden->wavebuf[i],
   23.24 +                                   sizeof (this->hidden->wavebuf[i]));
   23.25          }
   23.26 +    }
   23.27  
   23.28 -        /* Clean up mixing buffers */
   23.29 -        for (i = 0; i < NUM_BUFFERS; ++i) {
   23.30 -            if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
   23.31 -                waveOutUnprepareHeader(this->hidden->hout,
   23.32 -                                       &this->hidden->wavebuf[i],
   23.33 -                                       sizeof(this->hidden->wavebuf[i]));
   23.34 -                this->hidden->wavebuf[i].dwUser = 0xFFFF;
   23.35 -            }
   23.36 -        }
   23.37 +    if (this->hidden->hin) {
   23.38 +        waveInClose(this->hidden->hin);
   23.39 +    }
   23.40  
   23.41 -        /* Free raw mixing buffer */
   23.42 -        SDL_free(this->hidden->mixbuf);
   23.43 -        this->hidden->mixbuf = NULL;
   23.44 +    if (this->hidden->hout) {
   23.45 +        waveOutClose(this->hidden->hout);
   23.46 +    }
   23.47  
   23.48 -        if (this->hidden->hin) {
   23.49 -            waveInClose(this->hidden->hin);
   23.50 -            this->hidden->hin = 0;
   23.51 -        }
   23.52 -
   23.53 -        if (this->hidden->hout) {
   23.54 -            waveOutClose(this->hidden->hout);
   23.55 -            this->hidden->hout = 0;
   23.56 -        }
   23.57 -
   23.58 -        SDL_free(this->hidden);
   23.59 -        this->hidden = NULL;
   23.60 -    }
   23.61 +    SDL_free(this->hidden->mixbuf);
   23.62 +    SDL_free(this->hidden);
   23.63  }
   23.64  
   23.65  static SDL_bool
   23.66 @@ -269,7 +258,6 @@
   23.67      }
   23.68  
   23.69      if (!valid_datatype) {
   23.70 -        WINMM_CloseDevice(this);
   23.71          return SDL_SetError("Unsupported audio format");
   23.72      }
   23.73  
   23.74 @@ -288,7 +276,6 @@
   23.75      }
   23.76  
   23.77      if (result != MMSYSERR_NOERROR) {
   23.78 -        WINMM_CloseDevice(this);
   23.79          return SetMMerror("waveOutOpen()", result);
   23.80      }
   23.81  #ifdef SOUND_DEBUG
   23.82 @@ -299,7 +286,6 @@
   23.83          result = waveOutGetDevCaps((UINT) this->hidden->hout,
   23.84                                     &caps, sizeof(caps));
   23.85          if (result != MMSYSERR_NOERROR) {
   23.86 -            WINMM_CloseDevice(this);
   23.87              return SetMMerror("waveOutGetDevCaps()", result);
   23.88          }
   23.89          printf("Audio device: %s\n", caps.szPname);
   23.90 @@ -310,7 +296,6 @@
   23.91      this->hidden->audio_sem =
   23.92          CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
   23.93      if (this->hidden->audio_sem == NULL) {
   23.94 -        WINMM_CloseDevice(this);
   23.95          return SDL_SetError("Couldn't create semaphore");
   23.96      }
   23.97  
   23.98 @@ -318,7 +303,6 @@
   23.99      this->hidden->mixbuf =
  23.100          (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
  23.101      if (this->hidden->mixbuf == NULL) {
  23.102 -        WINMM_CloseDevice(this);
  23.103          return SDL_OutOfMemory();
  23.104      }
  23.105      for (i = 0; i < NUM_BUFFERS; ++i) {
  23.106 @@ -332,7 +316,6 @@
  23.107                                        &this->hidden->wavebuf[i],
  23.108                                        sizeof(this->hidden->wavebuf[i]));
  23.109          if (result != MMSYSERR_NOERROR) {
  23.110 -            WINMM_CloseDevice(this);
  23.111              return SetMMerror("waveOutPrepareHeader()", result);
  23.112          }
  23.113      }
    24.1 --- a/src/audio/xaudio2/SDL_xaudio2.c	Thu Aug 04 11:51:17 2016 -0400
    24.2 +++ b/src/audio/xaudio2/SDL_xaudio2.c	Fri Aug 05 01:44:41 2016 -0400
    24.3 @@ -257,33 +257,30 @@
    24.4  static void
    24.5  XAUDIO2_CloseDevice(_THIS)
    24.6  {
    24.7 -    if (this->hidden != NULL) {
    24.8 -        IXAudio2 *ixa2 = this->hidden->ixa2;
    24.9 -        IXAudio2SourceVoice *source = this->hidden->source;
   24.10 -        IXAudio2MasteringVoice *mastering = this->hidden->mastering;
   24.11 +    IXAudio2 *ixa2 = this->hidden->ixa2;
   24.12 +    IXAudio2SourceVoice *source = this->hidden->source;
   24.13 +    IXAudio2MasteringVoice *mastering = this->hidden->mastering;
   24.14  
   24.15 -        if (source != NULL) {
   24.16 -            IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
   24.17 -            IXAudio2SourceVoice_FlushSourceBuffers(source);
   24.18 -            IXAudio2SourceVoice_DestroyVoice(source);
   24.19 -        }
   24.20 -        if (ixa2 != NULL) {
   24.21 -            IXAudio2_StopEngine(ixa2);
   24.22 -        }
   24.23 -        if (mastering != NULL) {
   24.24 -            IXAudio2MasteringVoice_DestroyVoice(mastering);
   24.25 -        }
   24.26 -        if (ixa2 != NULL) {
   24.27 -            IXAudio2_Release(ixa2);
   24.28 -        }
   24.29 -        SDL_free(this->hidden->mixbuf);
   24.30 -        if (this->hidden->semaphore != NULL) {
   24.31 -            SDL_DestroySemaphore(this->hidden->semaphore);
   24.32 -        }
   24.33 +    if (source != NULL) {
   24.34 +        IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
   24.35 +        IXAudio2SourceVoice_FlushSourceBuffers(source);
   24.36 +        IXAudio2SourceVoice_DestroyVoice(source);
   24.37 +    }
   24.38 +    if (ixa2 != NULL) {
   24.39 +        IXAudio2_StopEngine(ixa2);
   24.40 +    }
   24.41 +    if (mastering != NULL) {
   24.42 +        IXAudio2MasteringVoice_DestroyVoice(mastering);
   24.43 +    }
   24.44 +    if (ixa2 != NULL) {
   24.45 +        IXAudio2_Release(ixa2);
   24.46 +    }
   24.47 +    if (this->hidden->semaphore != NULL) {
   24.48 +        SDL_DestroySemaphore(this->hidden->semaphore);
   24.49 +    }
   24.50  
   24.51 -        SDL_free(this->hidden);
   24.52 -        this->hidden = NULL;
   24.53 -    }
   24.54 +    SDL_free(this->hidden->mixbuf);
   24.55 +    SDL_free(this->hidden);
   24.56  }
   24.57  
   24.58  static int
   24.59 @@ -350,7 +347,6 @@
   24.60      this->hidden->ixa2 = ixa2;
   24.61      this->hidden->semaphore = SDL_CreateSemaphore(1);
   24.62      if (this->hidden->semaphore == NULL) {
   24.63 -        XAUDIO2_CloseDevice(this);
   24.64          return SDL_SetError("XAudio2: CreateSemaphore() failed!");
   24.65      }
   24.66  
   24.67 @@ -368,7 +364,6 @@
   24.68      }
   24.69  
   24.70      if (!valid_format) {
   24.71 -        XAUDIO2_CloseDevice(this);
   24.72          return SDL_SetError("XAudio2: Unsupported audio format");
   24.73      }
   24.74  
   24.75 @@ -379,7 +374,6 @@
   24.76      this->hidden->mixlen = this->spec.size;
   24.77      this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
   24.78      if (this->hidden->mixbuf == NULL) {
   24.79 -        XAUDIO2_CloseDevice(this);
   24.80          return SDL_OutOfMemory();
   24.81      }
   24.82      this->hidden->nextbuf = this->hidden->mixbuf;
   24.83 @@ -401,7 +395,6 @@
   24.84                                             this->spec.freq, 0, devId, NULL);
   24.85  #endif
   24.86      if (result != S_OK) {
   24.87 -        XAUDIO2_CloseDevice(this);
   24.88          return SDL_SetError("XAudio2: Couldn't create mastering voice");
   24.89      }
   24.90  
   24.91 @@ -436,7 +429,6 @@
   24.92  
   24.93  #endif
   24.94      if (result != S_OK) {
   24.95 -        XAUDIO2_CloseDevice(this);
   24.96          return SDL_SetError("XAudio2: Couldn't create source voice");
   24.97      }
   24.98      this->hidden->source = source;
   24.99 @@ -444,13 +436,11 @@
  24.100      /* Start everything playing! */
  24.101      result = IXAudio2_StartEngine(ixa2);
  24.102      if (result != S_OK) {
  24.103 -        XAUDIO2_CloseDevice(this);
  24.104          return SDL_SetError("XAudio2: Couldn't start engine");
  24.105      }
  24.106  
  24.107      result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
  24.108      if (result != S_OK) {
  24.109 -        XAUDIO2_CloseDevice(this);
  24.110          return SDL_SetError("XAudio2: Couldn't start source voice");
  24.111      }
  24.112