From 6d5c9c1e675718716cc117c6d8a71ce0c0818de2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 2 Aug 2016 13:48:52 -0400 Subject: [PATCH] audio: Made some SDL_AudioDevice fields atomic. This makes sure they're properly communicated to the audio threads. --- src/audio/SDL_audio.c | 25 +++++++++++----------- src/audio/SDL_sysaudio.h | 6 +++--- src/audio/alsa/SDL_alsa_audio.c | 2 +- src/audio/android/SDL_androidaudio.c | 6 +++--- src/audio/coreaudio/SDL_coreaudio.c | 6 +++--- src/audio/emscripten/SDL_emscriptenaudio.c | 8 +++---- src/audio/haiku/SDL_haikuaudio.cc | 5 +++-- src/audio/nacl/SDL_naclaudio.c | 2 +- src/audio/pulseaudio/SDL_pulseaudio.c | 6 +++--- src/audio/qsa/SDL_qsa_audio.c | 4 ++-- src/audio/xaudio2/SDL_xaudio2.c | 6 +++--- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 8fee9dccc18b6..934652a8e5f02 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -366,14 +366,14 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) { SDL_assert(get_audio_device(device->id) == device); - if (!device->enabled) { + if (!SDL_AtomicGet(&device->enabled)) { return; } /* Ends the audio callback and mark the device as STOPPED, but the app still needs to close the device to free resources. */ current_audio.impl.LockDevice(device); - device->enabled = SDL_FALSE; + SDL_AtomicSet(&device->enabled, 0); current_audio.impl.UnlockDevice(device); /* Post the event, if desired */ @@ -615,7 +615,7 @@ SDL_RunAudio(void *devicep) /* Fill the current buffer with sound */ if (device->convert.needed) { stream = device->convert.buf; - } else if (device->enabled) { + } else if (SDL_AtomicGet(&device->enabled)) { stream = current_audio.impl.GetDeviceBuf(device); } else { /* if the device isn't enabled, we still write to the @@ -632,7 +632,7 @@ SDL_RunAudio(void *devicep) /* !!! FIXME: this should be LockDevice. */ SDL_LockMutex(device->mixer_lock); - if (device->paused) { + if (SDL_AtomicGet(&device->paused)) { SDL_memset(stream, silence, stream_len); } else { (*fill) (udata, stream, stream_len); @@ -640,7 +640,7 @@ SDL_RunAudio(void *devicep) SDL_UnlockMutex(device->mixer_lock); /* Convert the audio if necessary */ - if (device->enabled && device->convert.needed) { + if (device->convert.needed && SDL_AtomicGet(&device->enabled)) { SDL_ConvertAudio(&device->convert); stream = current_audio.impl.GetDeviceBuf(device); if (stream == NULL) { @@ -873,8 +873,8 @@ SDL_GetAudioDeviceName(int index, int iscapture) static void close_audio_device(SDL_AudioDevice * device) { - device->enabled = SDL_FALSE; SDL_AtomicSet(&device->shutdown, 1); + SDL_AtomicSet(&device->enabled, 0); if (device->thread != NULL) { SDL_WaitThread(device->thread, NULL); } @@ -1074,13 +1074,14 @@ open_audio_device(const char *devname, int iscapture, return 0; } SDL_zerop(device); - SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ device->id = id + 1; device->spec = *obtained; - device->enabled = SDL_TRUE; - device->paused = SDL_TRUE; device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; + SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ + SDL_AtomicSet(&device->paused, 1); + SDL_AtomicSet(&device->enabled, 1); + /* Create a mutex for locking the sound buffers */ if (!current_audio.impl.SkipMixerLock) { device->mixer_lock = SDL_CreateMutex(); @@ -1256,8 +1257,8 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); SDL_AudioStatus status = SDL_AUDIO_STOPPED; - if (device && device->enabled) { - if (device->paused) { + if (device && SDL_AtomicGet(&device->enabled)) { + if (SDL_AtomicGet(&device->paused)) { status = SDL_AUDIO_PAUSED; } else { status = SDL_AUDIO_PLAYING; @@ -1279,7 +1280,7 @@ SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) SDL_AudioDevice *device = get_audio_device(devid); if (device) { current_audio.impl.LockDevice(device); - device->paused = pause_on ? SDL_TRUE : SDL_FALSE; + SDL_AtomicSet(&device->paused, pause_on ? 1 : 0); current_audio.impl.UnlockDevice(device); } } diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index fcf441d0ef595..0b35b27544ce9 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -158,10 +158,10 @@ struct SDL_AudioDevice /* Current state flags */ SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */ - SDL_bool iscapture; - SDL_bool enabled; /* true if device is functioning and connected. */ - SDL_bool paused; + SDL_atomic_t enabled; /* true if device is functioning and connected. */ + SDL_atomic_t paused; SDL_bool opened; + SDL_bool iscapture; /* Fake audio buffer for when the audio hardware is busy */ Uint8 *fake_stream; diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 1a84380f2fa35..e9f672f8c1fee 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -311,7 +311,7 @@ ALSA_PlayDevice(_THIS) swizzle_alsa_channels(this); - while ( frames_left > 0 && this->enabled ) { + while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) { /* !!! FIXME: This works, but needs more testing before going live */ /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */ status = ALSA_snd_pcm_writei(this->hidden->pcm_handle, diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c index 4a4faadcfbc5f..047793a6078fb 100644 --- a/src/audio/android/SDL_androidaudio.c +++ b/src/audio/android/SDL_androidaudio.c @@ -151,13 +151,13 @@ void AndroidAUD_PauseDevices(void) struct SDL_PrivateAudioData *private; if(audioDevice != NULL && audioDevice->hidden != NULL) { private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (audioDevice->paused) { + if (SDL_AtomicGet(&audioDevice->paused)) { /* The device is already paused, leave it alone */ private->resume = SDL_FALSE; } else { SDL_LockMutex(audioDevice->mixer_lock); - audioDevice->paused = SDL_TRUE; + SDL_AtomicSet(&audioDevice->paused, 1); private->resume = SDL_TRUE; } } @@ -171,7 +171,7 @@ void AndroidAUD_ResumeDevices(void) if(audioDevice != NULL && audioDevice->hidden != NULL) { private = (struct SDL_PrivateAudioData *) audioDevice->hidden; if (private->resume) { - audioDevice->paused = SDL_FALSE; + SDL_AtomicSet(&audioDevice->paused, 0); private->resume = SDL_FALSE; SDL_UnlockMutex(audioDevice->mixer_lock); } diff --git a/src/audio/coreaudio/SDL_coreaudio.c b/src/audio/coreaudio/SDL_coreaudio.c index 3bf66d618e1e7..2385995fd0038 100644 --- a/src/audio/coreaudio/SDL_coreaudio.c +++ b/src/audio/coreaudio/SDL_coreaudio.c @@ -283,7 +283,7 @@ outputCallback(void *inRefCon, UInt32 i; /* Only do anything if audio is enabled and not paused */ - if (!this->enabled || this->paused) { + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { for (i = 0; i < ioData->mNumberBuffers; i++) { abuf = &ioData->mBuffers[i]; SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize); @@ -335,7 +335,7 @@ inputCallback(void *inRefCon, AudioBufferList *ioData) { SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon; - if (!this->enabled || this->paused) { + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { return noErr; /* just drop this if we're not accepting input. */ } @@ -391,7 +391,7 @@ device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectProperty UInt32 size = sizeof (isAlive); OSStatus error; - if (!this->enabled) { + if (!SDL_AtomicGet(&this->enabled)) { return 0; /* already known to be dead. */ } diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c index 8378233ca22ce..ea42723c28973 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/src/audio/emscripten/SDL_emscriptenaudio.c @@ -63,12 +63,10 @@ HandleAudioProcess(_THIS) int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8; int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8; - /* Only do soemthing if audio is enabled */ - if (!this->enabled) - return; - - if (this->paused) + /* Only do something if audio is enabled */ + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { return; + } if (this->convert.needed) { if (this->hidden->conv_in_len != 0) { diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc index 38f3b962188c7..de364b0ef2bb5 100644 --- a/src/audio/haiku/SDL_haikuaudio.cc +++ b/src/audio/haiku/SDL_haikuaudio.cc @@ -49,10 +49,11 @@ FillSound(void *device, void *stream, size_t len, SDL_AudioDevice *audio = (SDL_AudioDevice *) device; /* Only do soemthing if audio is enabled */ - if (!audio->enabled) + if (!SDL_AtomicGet(&audio->enabled)) { return; + } - if (!audio->paused) { + if (!SDL_AtomicGet(&audio->paused)) { if (audio->convert.needed) { SDL_LockMutex(audio->mixer_lock); (*audio->spec.callback) (audio->spec.userdata, diff --git a/src/audio/nacl/SDL_naclaudio.c b/src/audio/nacl/SDL_naclaudio.c index 450a369b4a023..8f1c51ac51622 100644 --- a/src/audio/nacl/SDL_naclaudio.c +++ b/src/audio/nacl/SDL_naclaudio.c @@ -53,7 +53,7 @@ static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelt SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */ - if (_this->enabled && !_this->paused) { + if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) { if (_this->convert.needed) { SDL_LockMutex(_this->mixer_lock); (*_this->spec.callback) (_this->spec.userdata, diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index fdf38c8177a8b..4fed80963ccc4 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -326,7 +326,7 @@ PULSEAUDIO_WaitDevice(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; - while (this->enabled) { + while (SDL_AtomicGet(&this->enabled)) { if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { @@ -344,7 +344,7 @@ PULSEAUDIO_PlayDevice(_THIS) { /* Write the audio data */ struct SDL_PrivateAudioData *h = this->hidden; - if (this->enabled) { + if (SDL_AtomicGet(&this->enabled)) { if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { SDL_OpenedAudioDeviceDisconnected(this); } @@ -360,7 +360,7 @@ stream_drain_complete(pa_stream *s, int success, void *userdata) static void PULSEAUDIO_WaitDone(_THIS) { - if (this->enabled) { + if (SDL_AtomicGet(&this->enabled)) { struct SDL_PrivateAudioData *h = this->hidden; pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL); if (o) { diff --git a/src/audio/qsa/SDL_qsa_audio.c b/src/audio/qsa/SDL_qsa_audio.c index 1742fe3f619ea..88d29f9308626 100644 --- a/src/audio/qsa/SDL_qsa_audio.c +++ b/src/audio/qsa/SDL_qsa_audio.c @@ -229,7 +229,7 @@ QSA_PlayDevice(_THIS) int towrite; void *pcmbuffer; - if ((!this->enabled) || (!this->hidden)) { + if (!SDL_AtomicGet(&this->enabled) || !this->hidden) { return; } @@ -305,7 +305,7 @@ QSA_PlayDevice(_THIS) towrite -= written; pcmbuffer += written * this->spec.channels; } - } while ((towrite > 0) && (this->enabled)); + } while ((towrite > 0) && SDL_AtomicGet(&this->enabled)); /* If we couldn't write, assume fatal error for now */ if (towrite != 0) { diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index dff234b40171c..ba9ad9fbc9e3e 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -195,7 +195,7 @@ XAUDIO2_PlayDevice(_THIS) IXAudio2SourceVoice *source = this->hidden->source; HRESULT result = S_OK; - if (!this->enabled) { /* shutting down? */ + if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */ return; } @@ -226,7 +226,7 @@ XAUDIO2_PlayDevice(_THIS) static void XAUDIO2_WaitDevice(_THIS) { - if (this->enabled) { + if (SDL_AtomicGet(&this->enabled)) { SDL_SemWait(this->hidden->semaphore); } } @@ -236,7 +236,7 @@ XAUDIO2_WaitDone(_THIS) { IXAudio2SourceVoice *source = this->hidden->source; XAUDIO2_VOICE_STATE state; - SDL_assert(!this->enabled); /* flag that stops playing. */ + SDL_assert(!SDL_AtomicGet(&this->enabled)); /* flag that stops playing. */ IXAudio2SourceVoice_Discontinuity(source); #if SDL_XAUDIO2_WIN8 IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);