aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-07-31 23:42:30 -0700
committerChris Robinson <[email protected]>2016-07-31 23:42:30 -0700
commit0fcd39c4c0205b8229df16f48b05cf0bf6600287 (patch)
treee94485a070eb032097ee010f15984d83dafa2d2f /OpenAL32/alSource.c
parent48ff5d4ce8bd5f2d65c1aa8af77c2923d3be801c (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.
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r--OpenAL32/alSource.c29
1 files changed, 20 insertions, 9 deletions
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
{