audio: Made some SDL_AudioDevice fields atomic.
This makes sure they're properly communicated to the audio threads.
parent
b35b9f950e
commit
6d5c9c1e67
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue