audio: Try to keep callbacks firing at normal pace when device is lost.
authorRyan C. Gordon <icculus@icculus.org>
Sun, 26 Feb 2017 00:39:22 -0500
changeset 109154d6e2e2c4912
parent 10914 ebc7ff92677d
child 10916 bade97ed25ac
audio: Try to keep callbacks firing at normal pace when device is lost.
src/audio/SDL_audio.c
     1.1 --- a/src/audio/SDL_audio.c	Sun Feb 26 00:40:04 2017 -0500
     1.2 +++ b/src/audio/SDL_audio.c	Sun Feb 26 00:39:22 2017 -0500
     1.3 @@ -688,13 +688,12 @@
     1.4  
     1.5              while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) {
     1.6                  data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL;
     1.7 -                if (data == NULL) {
     1.8 -                    SDL_AudioStreamClear(device->stream);
     1.9 -                    SDL_Delay(delay);
    1.10 -                    break;
    1.11 +                const int got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size);
    1.12 +                SDL_assert((got < 0) || (got == device->spec.size));
    1.13 +
    1.14 +                if (data == NULL) {  /* device is having issues... */
    1.15 +                    SDL_Delay(delay);  /* wait for as long as this buffer would have played. Maybe device recovers later? */
    1.16                  } else {
    1.17 -                    const int got = SDL_AudioStreamGet(device->stream, data, device->spec.size);
    1.18 -                    SDL_assert((got < 0) || (got == device->spec.size));
    1.19                      if (got != device->spec.size) {
    1.20                          SDL_memset(data, device->spec.silence, device->spec.size);
    1.21                      }
    1.22 @@ -770,15 +769,19 @@
    1.23             and block when there isn't data so this thread isn't eating CPU.
    1.24             But we don't process it further or call the app's callback. */
    1.25  
    1.26 -        while (SDL_AtomicGet(&device->enabled) && (still_need > 0)) {
    1.27 -            const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
    1.28 -            SDL_assert(rc <= still_need);  /* device should not overflow buffer. :) */
    1.29 -            if (rc > 0) {
    1.30 -                still_need -= rc;
    1.31 -                ptr += rc;
    1.32 -            } else {  /* uhoh, device failed for some reason! */
    1.33 -                SDL_OpenedAudioDeviceDisconnected(device);
    1.34 -                break;
    1.35 +        if (!SDL_AtomicGet(&device->enabled)) {
    1.36 +            SDL_Delay(delay);  /* try to keep callback firing at normal pace. */
    1.37 +        } else {
    1.38 +            while (still_need > 0) {
    1.39 +                const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
    1.40 +                SDL_assert(rc <= still_need);  /* device should not overflow buffer. :) */
    1.41 +                if (rc > 0) {
    1.42 +                    still_need -= rc;
    1.43 +                    ptr += rc;
    1.44 +                } else {  /* uhoh, device failed for some reason! */
    1.45 +                    SDL_OpenedAudioDeviceDisconnected(device);
    1.46 +                    break;
    1.47 +                }
    1.48              }
    1.49          }
    1.50