src/audio/SDL_audio.c
changeset 9397 d72d2aa46341
parent 9396 69c501ed36f3
child 9398 c41dd34e4996
     1.1 --- a/src/audio/SDL_audio.c	Thu Mar 19 13:15:28 2015 -0400
     1.2 +++ b/src/audio/SDL_audio.c	Thu Mar 19 13:27:10 2015 -0400
     1.3 @@ -727,7 +727,7 @@
     1.4             resampling process can be any number. We will have to see what a good size for the
     1.5             stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
     1.6           */
     1.7 -        while (device->enabled) {
     1.8 +        while (!device->shutdown) {
     1.9  
    1.10              if (device->paused) {
    1.11                  SDL_Delay(delay);
    1.12 @@ -810,31 +810,27 @@
    1.13          const int silence = (int) device->spec.silence;
    1.14  
    1.15          /* Loop, filling the audio buffers */
    1.16 -        while (device->enabled) {
    1.17 -
    1.18 +        while (!device->shutdown) {
    1.19              /* Fill the current buffer with sound */
    1.20              if (device->convert.needed) {
    1.21 -                if (device->convert.buf) {
    1.22 -                    stream = device->convert.buf;
    1.23 -                } else {
    1.24 -                    continue;
    1.25 -                }
    1.26 +                stream = device->convert.buf;
    1.27 +            } else if (device->enabled) {
    1.28 +                stream = current_audio.impl.GetDeviceBuf(device);
    1.29              } else {
    1.30 -                stream = current_audio.impl.GetDeviceBuf(device);
    1.31 -                if (stream == NULL) {
    1.32 -                    stream = device->fake_stream;
    1.33 -                }
    1.34 +                /* if the device isn't enabled, we still write to the
    1.35 +                    fake_stream, so the app's callback will fire with
    1.36 +                    a regular frequency, in case they depend on that
    1.37 +                    for timing or progress. They can use hotplug
    1.38 +                    now to know if the device failed. */
    1.39 +                stream = NULL;
    1.40 +            }
    1.41 +
    1.42 +            if (stream == NULL) {
    1.43 +                stream = device->fake_stream;
    1.44              }
    1.45  
    1.46              /* !!! FIXME: this should be LockDevice. */
    1.47              SDL_LockMutex(device->mixer_lock);
    1.48 -
    1.49 -            /* Check again, in case device was removed while a lock was held. */
    1.50 -            if (!device->enabled) {
    1.51 -                SDL_UnlockMutex(device->mixer_lock);
    1.52 -                break;
    1.53 -            }
    1.54 -
    1.55              if (device->paused) {
    1.56                  SDL_memset(stream, silence, stream_len);
    1.57              } else {
    1.58 @@ -843,14 +839,15 @@
    1.59              SDL_UnlockMutex(device->mixer_lock);
    1.60  
    1.61              /* Convert the audio if necessary */
    1.62 -            if (device->convert.needed) {
    1.63 +            if (device->enabled && device->convert.needed) {
    1.64                  SDL_ConvertAudio(&device->convert);
    1.65                  stream = current_audio.impl.GetDeviceBuf(device);
    1.66                  if (stream == NULL) {
    1.67                      stream = device->fake_stream;
    1.68 +                } else {
    1.69 +                    SDL_memcpy(stream, device->convert.buf,
    1.70 +                               device->convert.len_cvt);
    1.71                  }
    1.72 -                SDL_memcpy(stream, device->convert.buf,
    1.73 -                           device->convert.len_cvt);
    1.74              }
    1.75  
    1.76              /* Ready current buffer for play and change current buffer */
    1.77 @@ -1084,6 +1081,7 @@
    1.78  close_audio_device(SDL_AudioDevice * device)
    1.79  {
    1.80      device->enabled = 0;
    1.81 +    device->shutdown = 1;
    1.82      if (device->thread != NULL) {
    1.83          SDL_WaitThread(device->thread, NULL);
    1.84      }
    1.85 @@ -1178,6 +1176,7 @@
    1.86      SDL_AudioDevice *device;
    1.87      SDL_bool build_cvt;
    1.88      void *handle = NULL;
    1.89 +    int stream_len;
    1.90      int i = 0;
    1.91  
    1.92      if (!SDL_WasInit(SDL_INIT_AUDIO)) {
    1.93 @@ -1304,14 +1303,6 @@
    1.94      }
    1.95      device->opened = 1;
    1.96  
    1.97 -    /* Allocate a fake audio memory buffer */
    1.98 -    device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
    1.99 -    if (device->fake_stream == NULL) {
   1.100 -        close_audio_device(device);
   1.101 -        SDL_OutOfMemory();
   1.102 -        return 0;
   1.103 -    }
   1.104 -
   1.105      /* See if we need to do any conversion */
   1.106      build_cvt = SDL_FALSE;
   1.107      if (obtained->freq != device->spec.freq) {
   1.108 @@ -1370,6 +1361,18 @@
   1.109          }
   1.110      }
   1.111  
   1.112 +    /* Allocate a fake audio memory buffer */
   1.113 +    stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
   1.114 +    if (device->spec.size > stream_len) {
   1.115 +        stream_len = device->spec.size;
   1.116 +    }
   1.117 +    device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len);
   1.118 +    if (device->fake_stream == NULL) {
   1.119 +        close_audio_device(device);
   1.120 +        SDL_OutOfMemory();
   1.121 +        return 0;
   1.122 +    }
   1.123 +
   1.124      if (device->spec.callback == NULL) {  /* use buffer queueing? */
   1.125          /* pool a few packets to start. Enough for two callbacks. */
   1.126          const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;