diff options
author | Chris Robinson <[email protected]> | 2016-07-31 23:42:30 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-07-31 23:42:30 -0700 |
commit | 0fcd39c4c0205b8229df16f48b05cf0bf6600287 (patch) | |
tree | e94485a070eb032097ee010f15984d83dafa2d2f | |
parent | 48ff5d4ce8bd5f2d65c1aa8af77c2923d3be801c (diff) |
Don't store the looping state in the voice
Certain operations on the buffer queue depend on the loop state to behave
properly, so it should not be deferred until the async voice update occurs.
-rw-r--r-- | Alc/ALu.c | 2 | ||||
-rw-r--r-- | Alc/mixer.c | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 6 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 29 |
4 files changed, 23 insertions, 16 deletions
@@ -437,7 +437,6 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } - voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); /* Calculate the stepping value */ Pitch *= (ALfloat)ALBuffer->Frequency / Frequency; @@ -906,7 +905,6 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } - voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); /* Transform source to listener space (convert to head relative) */ if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) diff --git a/Alc/mixer.c b/Alc/mixer.c index b2af812a..9f6ec9d1 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -388,9 +388,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam BufferListItem = ATOMIC_LOAD(&Source->current_buffer); DataPosInt = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); DataPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + Looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; - Looping = voice->Looping; increment = voice->Step; IrSize = (Device->Hrtf ? Device->Hrtf->irSize : 0); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index db138be1..74987b34 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -28,8 +28,6 @@ typedef struct ALvoice { /** Current target parameters used for mixing. */ ALint Step; - ALboolean Looping; - /* If not 'moving', gain/coefficients are set directly without fading. */ ALboolean Moving; @@ -74,7 +72,6 @@ struct ALsourceProps { ATOMIC(ALfloat) Direction[3]; ATOMIC(ALfloat) Orientation[2][3]; ATOMIC(ALboolean) HeadRelative; - ATOMIC(ALboolean) Looping; ATOMIC(enum DistanceModel) DistanceModel; ATOMIC(ALboolean) DirectChannels; @@ -128,7 +125,6 @@ typedef struct ALsource { ALfloat Direction[3]; ALfloat Orientation[2][3]; ALboolean HeadRelative; - ALboolean Looping; enum DistanceModel DistanceModel; ALboolean DirectChannels; @@ -192,6 +188,8 @@ typedef struct ALsource { ATOMIC(ALuint) position; ATOMIC(ALuint) position_fraction; + ATOMIC(ALboolean) looping; + /** Current buffer sample info. */ ALuint NumChannels; ALuint SampleSize; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 4a50d217..0e98f2f5 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -642,8 +642,9 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - Source->Looping = (ALboolean)*values; - DO_UPDATEPROPS(); + WriteLock(&Source->queue_lock); + ATOMIC_STORE(&Source->looping, *values); + WriteUnlock(&Source->queue_lock); return AL_TRUE; case AL_BUFFER: @@ -1198,7 +1199,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_LOOPING: - *values = Source->Looping; + *values = ATOMIC_LOAD(&Source->looping); return AL_TRUE; case AL_BUFFER: @@ -1285,7 +1286,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_PROCESSED: ReadLock(&Source->queue_lock); - if(Source->Looping || Source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD(&Source->looping) || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of * PENDING, so don't report any as PROCESSED */ @@ -2605,6 +2606,13 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); WriteLock(&source->queue_lock); + if(ATOMIC_LOAD(&source->looping) || source->SourceType != AL_STREAMING) + { + WriteUnlock(&source->queue_lock); + /* Trying to unqueue buffers on a looping or non-streaming source. */ + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + /* Find the new buffer queue head */ OldTail = ATOMIC_LOAD(&source->queue); Current = ATOMIC_LOAD(&source->current_buffer); @@ -2617,10 +2625,10 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint OldTail = next; } } - if(source->Looping || source->SourceType != AL_STREAMING || i != nb) + if(i != nb) { WriteUnlock(&source->queue_lock); - /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ + /* Trying to unqueue pending buffers. */ SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } @@ -2693,7 +2701,6 @@ static void InitSourceParams(ALsource *Source) Source->RefDistance = 1.0f; Source->MaxDistance = FLT_MAX; Source->RollOffFactor = 1.0f; - Source->Looping = AL_FALSE; Source->Gain = 1.0f; Source->MinGain = 0.0f; Source->MaxGain = 1.0f; @@ -2741,6 +2748,8 @@ static void InitSourceParams(ALsource *Source) ATOMIC_INIT(&Source->position, 0); ATOMIC_INIT(&Source->position_fraction, 0); + ATOMIC_INIT(&Source->looping, AL_FALSE); + ATOMIC_INIT(&Source->Update, NULL); ATOMIC_INIT(&Source->FreeList, NULL); } @@ -2832,7 +2841,6 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *co almemory_order_relaxed); } ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); - ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); ATOMIC_STORE(&props->DistanceModel, context->SourceDistanceModel ? source->DistanceModel : context->DistanceModel, almemory_order_relaxed @@ -3168,6 +3176,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ALuint readPos, readPosFrac; ALuint totalBufferLen; ALdouble offset = 0.0; + ALboolean looping; ALuint refcount; ReadLock(&Source->queue_lock); @@ -3186,6 +3195,8 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + + looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); } while(refcount != ReadRef(&device->MixCount)); while(BufferList != NULL) @@ -3202,7 +3213,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device } assert(Buffer != NULL); - if(Source->Looping) + if(looping) readPos %= totalBufferLen; else { |