Skip to content
Permalink
Browse files
audio: Made some SDL_AudioDevice fields atomic.
This makes sure they're properly communicated to the audio threads.
  • Loading branch information
icculus committed Aug 2, 2016
1 parent b35b9f9 commit 6d5c9c1e675718716cc117c6d8a71ce0c0818de2
@@ -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,15 +632,15 @@ 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);
}
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);
}
}
@@ -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;
@@ -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,
@@ -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);
}
@@ -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. */
}

@@ -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) {
@@ -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,
@@ -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,
@@ -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) {
@@ -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) {
@@ -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);

0 comments on commit 6d5c9c1

Please sign in to comment.