aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
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
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')
-rw-r--r--OpenAL32/Include/alSource.h6
-rw-r--r--OpenAL32/alSource.c29
2 files changed, 22 insertions, 13 deletions
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
{