audio: run the audio callback even if device was lost.

We will throw away the data anyhow, but some apps depend on the callback
firing to make progress; testmultiaudio.c, if nothing else, is an example
of this.

Capture also will now fire the callback in these conditions, offering nothing
but silence.

Apps can check SDL_GetAudioDeviceStatus() or listen for the
SDL_AUDIODEVICEREMOVED event if they want to gracefully deal with
an opened audio device that has been unexpectedly lost.
This commit is contained in:
Ryan C. Gordon 2017-02-26 00:12:33 -05:00
parent 5728cb2025
commit a366c35f37
1 changed files with 8 additions and 12 deletions

View File

@ -672,7 +672,6 @@ SDL_RunAudio(void *devicep)
data = device->work_buffer; data = device->work_buffer;
} }
if ( SDL_AtomicGet(&device->enabled) ) {
/* !!! FIXME: this should be LockDevice. */ /* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock); SDL_LockMutex(device->mixer_lock);
if (SDL_AtomicGet(&device->paused)) { if (SDL_AtomicGet(&device->paused)) {
@ -681,9 +680,6 @@ SDL_RunAudio(void *devicep)
callback(udata, data, data_len); callback(udata, data, data_len);
} }
SDL_UnlockMutex(device->mixer_lock); SDL_UnlockMutex(device->mixer_lock);
} else {
SDL_memset(data, silence, data_len);
}
if (device->stream) { if (device->stream) {
/* Stream available audio to device, converting/resampling. */ /* Stream available audio to device, converting/resampling. */
@ -752,7 +748,7 @@ SDL_CaptureAudio(void *devicep)
int still_need; int still_need;
Uint8 *ptr; Uint8 *ptr;
if (!SDL_AtomicGet(&device->enabled) || SDL_AtomicGet(&device->paused)) { if (SDL_AtomicGet(&device->paused)) {
SDL_Delay(delay); /* just so we don't cook the CPU. */ SDL_Delay(delay); /* just so we don't cook the CPU. */
if (device->stream) { if (device->stream) {
SDL_AudioStreamClear(device->stream); SDL_AudioStreamClear(device->stream);
@ -774,7 +770,7 @@ SDL_CaptureAudio(void *devicep)
and block when there isn't data so this thread isn't eating CPU. and block when there isn't data so this thread isn't eating CPU.
But we don't process it further or call the app's callback. */ But we don't process it further or call the app's callback. */
while (still_need > 0) { while (SDL_AtomicGet(&device->enabled) && (still_need > 0)) {
const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need); const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */
if (rc > 0) { if (rc > 0) {