From 5c859af24ea44dabbbb31631309bb08a858a523e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 27 Feb 2017 15:35:15 -0800 Subject: Move the current buffer queue entry and play position to the voice This has a couple behavioral changes. First and biggest is that querying AL_BUFFERS_PROCESSED from a source will always return all buffers processed when in an AL_STOPPED state. Previously all buffers would be set as processed when first becoming stopped, but newly queued buffers would *not* be indicated as processed. That old behavior was not compliant with the spec, which unequivocally states "On a source in the AL_STOPPED state, all buffers are processed." Secondly, querying AL_BUFFER on an AL_STREAMING source will now always return 0. Previously it would return the current "active" buffer in the queue, but there's no basis for that in the spec. --- Alc/ALc.c | 26 ++++++++++++++------------ Alc/ALu.c | 9 +++------ Alc/mixer.c | 14 +++++++------- 3 files changed, 24 insertions(+), 25 deletions(-) (limited to 'Alc') diff --git a/Alc/ALc.c b/Alc/ALc.c index c829d8e7..bf683ba3 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1692,22 +1692,24 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); - for(pos = 0;pos < context->SourceMap.size;pos++) + for(pos = 0;pos < context->VoiceCount;pos++) { - ALsource *Source = context->SourceMap.values[pos]; - ALenum new_state; - - if(Source->OffsetType != AL_NONE && IsPlayingOrPaused(Source)) + ALvoice *voice = context->Voices[pos]; + ALsource *source = voice->Source; + if(source && source->OffsetType != AL_NONE) { - WriteLock(&Source->queue_lock); - ApplyOffset(Source); - WriteUnlock(&Source->queue_lock); + WriteLock(&source->queue_lock); + ApplyOffset(source, voice); + WriteUnlock(&source->queue_lock); } - - new_state = Source->new_state; - Source->new_state = AL_NONE; + } + for(pos = 0;pos < context->SourceMap.size;pos++) + { + ALsource *source = context->SourceMap.values[pos]; + ALenum new_state = source->new_state; + source->new_state = AL_NONE; if(new_state) - SetSourceState(Source, context, new_state); + SetSourceState(source, context, new_state); } V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); diff --git a/Alc/ALu.c b/Alc/ALu.c index 3b83711f..b4938152 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1594,16 +1594,13 @@ void aluHandleDisconnect(ALCdevice *device) voice_end = voice + Context->VoiceCount; while(voice != voice_end) { - ALenum playing = AL_PLAYING; ALsource *source = (*voice)->Source; (*voice)->Source = NULL; - if(source && - ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED)) + if(source) { - ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed); - ATOMIC_STORE(&source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release); + ALenum playing = AL_PLAYING; + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED); } voice++; diff --git a/Alc/mixer.c b/Alc/mixer.c index be09ed67..b332030e 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -385,9 +385,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei /* Get source info */ State = AL_PLAYING; /* Only called while playing. */ - BufferListItem = ATOMIC_LOAD(&Source->current_buffer, almemory_order_acquire); - DataPosInt = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); - DataPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_acquire); + DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); + BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); Looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; @@ -681,9 +681,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei voice->Moving = AL_TRUE; /* Update source info */ - ATOMIC_STORE(&Source->state, State, almemory_order_relaxed); - ATOMIC_STORE(&Source->current_buffer, BufferListItem, almemory_order_relaxed); - ATOMIC_STORE(&Source->position, DataPosInt, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, DataPosFrac, almemory_order_release); + ATOMIC_STORE(&Source->state, State, almemory_order_relaxed); + ATOMIC_STORE(&voice->position, DataPosInt, almemory_order_relaxed); + ATOMIC_STORE(&voice->position_fraction, DataPosFrac, almemory_order_relaxed); + ATOMIC_STORE(&voice->current_buffer, BufferListItem, almemory_order_release); return State == AL_PLAYING; } -- cgit v1.2.3