aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/Include/alSource.h104
-rw-r--r--OpenAL32/Include/alu.h5
-rw-r--r--OpenAL32/alAuxEffectSlot.c2
-rw-r--r--OpenAL32/alListener.c36
-rw-r--r--OpenAL32/alSource.c452
-rw-r--r--OpenAL32/alState.c48
7 files changed, 474 insertions, 175 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 44ce4fe0..a624e078 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -695,7 +695,7 @@ struct ALCcontext_struct {
volatile ALfloat DopplerFactor;
volatile ALfloat DopplerVelocity;
volatile ALfloat SpeedOfSound;
- volatile ALenum DeferUpdates;
+ ATOMIC(ALenum) DeferUpdates;
RWLock PropLock;
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 187d7e07..6d915153 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -13,6 +13,7 @@ extern "C" {
struct ALbuffer;
struct ALsource;
+struct ALsourceProps;
typedef struct ALbufferlistitem {
@@ -25,11 +26,13 @@ typedef struct ALvoice {
struct ALsource *volatile Source;
/** Method to update mixing parameters. */
- ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const struct ALbuffer *ALBuffer, const ALCcontext *context);
+ ALvoid (*Update)(struct ALvoice *self, const struct ALsourceProps *props, const struct ALbuffer *ALBuffer, const ALCcontext *context);
/** Current target parameters used for mixing. */
ALint Step;
+ ALboolean Looping;
+
/* If not 'moving', gain/coefficients are set directly without fading. */
ALboolean Moving;
@@ -46,6 +49,59 @@ typedef struct ALvoice {
} ALvoice;
+struct ALsourceProps {
+ ATOMIC(ALfloat) Pitch;
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) OuterGain;
+ ATOMIC(ALfloat) MinGain;
+ ATOMIC(ALfloat) MaxGain;
+ ATOMIC(ALfloat) InnerAngle;
+ ATOMIC(ALfloat) OuterAngle;
+ ATOMIC(ALfloat) RefDistance;
+ ATOMIC(ALfloat) MaxDistance;
+ ATOMIC(ALfloat) RollOffFactor;
+ ATOMIC(ALfloat) Position[3];
+ ATOMIC(ALfloat) Velocity[3];
+ ATOMIC(ALfloat) Direction[3];
+ ATOMIC(ALfloat) Orientation[2][3];
+ ATOMIC(ALboolean) HeadRelative;
+ ATOMIC(ALboolean) Looping;
+ ATOMIC(enum DistanceModel) DistanceModel;
+ ATOMIC(ALboolean) DirectChannels;
+
+ ATOMIC(ALboolean) DryGainHFAuto;
+ ATOMIC(ALboolean) WetGainAuto;
+ ATOMIC(ALboolean) WetGainHFAuto;
+ ATOMIC(ALfloat) OuterGainHF;
+
+ ATOMIC(ALfloat) AirAbsorptionFactor;
+ ATOMIC(ALfloat) RoomRolloffFactor;
+ ATOMIC(ALfloat) DopplerFactor;
+
+ ATOMIC(ALfloat) StereoPan[2];
+
+ ATOMIC(ALfloat) Radius;
+
+ /** Direct filter and auxiliary send info. */
+ struct {
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) GainHF;
+ ATOMIC(ALfloat) HFReference;
+ ATOMIC(ALfloat) GainLF;
+ ATOMIC(ALfloat) LFReference;
+ } Direct;
+ struct {
+ ATOMIC(struct ALeffectslot*) Slot;
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) GainHF;
+ ATOMIC(ALfloat) HFReference;
+ ATOMIC(ALfloat) GainLF;
+ ATOMIC(ALfloat) LFReference;
+ } Send[MAX_SENDS];
+
+ ATOMIC(struct ALsourceProps*) next;
+};
+
typedef struct ALsource {
/** Source properties. */
volatile ALfloat Pitch;
@@ -58,9 +114,9 @@ typedef struct ALsource {
volatile ALfloat RefDistance;
volatile ALfloat MaxDistance;
volatile ALfloat RollOffFactor;
- aluVector Position;
- aluVector Velocity;
- aluVector Direction;
+ volatile ALfloat Position[3];
+ volatile ALfloat Velocity[3];
+ volatile ALfloat Direction[3];
volatile ALfloat Orientation[2][3];
volatile ALboolean HeadRelative;
volatile ALboolean Looping;
@@ -83,6 +139,23 @@ typedef struct ALsource {
volatile ALfloat Radius;
+ /** Direct filter and auxiliary send info. */
+ struct {
+ ALfloat Gain;
+ ALfloat GainHF;
+ ALfloat HFReference;
+ ALfloat GainLF;
+ ALfloat LFReference;
+ } Direct;
+ struct {
+ struct ALeffectslot *Slot;
+ ALfloat Gain;
+ ALfloat GainHF;
+ ALfloat HFReference;
+ ALfloat GainLF;
+ ALfloat LFReference;
+ } Send[MAX_SENDS];
+
/**
* Last user-specified offset, and the offset type (bytes, samples, or
* seconds).
@@ -114,25 +187,8 @@ typedef struct ALsource {
ALuint NumChannels;
ALuint SampleSize;
- /** Direct filter and auxiliary send info. */
- struct {
- ALfloat Gain;
- ALfloat GainHF;
- ALfloat HFReference;
- ALfloat GainLF;
- ALfloat LFReference;
- } Direct;
- struct {
- struct ALeffectslot *Slot;
- ALfloat Gain;
- ALfloat GainHF;
- ALfloat HFReference;
- ALfloat GainLF;
- ALfloat LFReference;
- } Send[MAX_SENDS];
-
- /** Source needs to update its mixing parameters. */
- ATOMIC(ALenum) NeedsUpdate;
+ ATOMIC(struct ALsourceProps*) Update;
+ ATOMIC(struct ALsourceProps*) FreeList;
/** Self ID */
ALuint id;
@@ -152,6 +208,8 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id)
inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id)
{ return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); }
+void UpdateSourceProps(ALsource *source, ALuint num_sends);
+void UpdateAllSourceProps(ALCcontext *context);
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state);
ALboolean ApplyOffset(ALsource *Source);
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index c20c6404..8e93dc6e 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -34,6 +34,7 @@ extern "C" {
#endif
struct ALsource;
+struct ALsourceProps;
struct ALvoice;
struct ALeffectslot;
struct ALbuffer;
@@ -375,8 +376,8 @@ void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, c
ALvoid UpdateContextSources(ALCcontext *context);
-ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext);
-ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext);
+ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext);
+ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext);
ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo);
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 98ee9328..6d1423db 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -202,6 +202,8 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
slot->AuxSendAuto = value;
UpdateEffectSlotProps(slot, AL_FALSE);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ UpdateAllSourceProps(context);
break;
default:
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index 1c40c399..c59d644b 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -51,7 +51,11 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -88,7 +92,11 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -140,7 +148,11 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -161,7 +173,11 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value))
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -190,7 +206,11 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -235,7 +255,11 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index a62bf59e..e2d6ca4f 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -48,6 +48,7 @@ extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id);
extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id);
static ALvoid InitSourceParams(ALsource *Source);
+static ALvoid DeinitSource(ALsource *source);
static ALint64 GetSourceSampleOffset(ALsource *Source);
static ALdouble GetSourceSecOffset(ALsource *Source);
static ALdouble GetSourceOffset(ALsource *Source, ALenum name);
@@ -123,6 +124,12 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values);
static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values);
+static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context)
+{
+ return (source->state == AL_PLAYING || source->state == AL_PAUSED) &&
+ !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
+}
+
static ALint FloatValsByProp(ALenum prop)
{
if(prop != (ALenum)((SourceProp)prop))
@@ -376,8 +383,14 @@ static ALint Int64ValsByProp(ALenum prop)
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \
} while(0)
+#define DO_UPDATEPROPS() do { \
+ if(SourceShouldUpdate(Source, Context)) \
+ UpdateSourceProps(Source, device->NumAuxSends); \
+} while(0)
+
static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values)
{
+ ALCdevice *device = Context->Device;
ALint ival;
switch(prop)
@@ -393,98 +406,98 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
CHECKVAL(*values >= 0.0f);
Source->Pitch = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_INNER_ANGLE:
CHECKVAL(*values >= 0.0f && *values <= 360.0f);
Source->InnerAngle = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_ANGLE:
CHECKVAL(*values >= 0.0f && *values <= 360.0f);
Source->OuterAngle = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_GAIN:
CHECKVAL(*values >= 0.0f);
Source->Gain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MAX_DISTANCE:
CHECKVAL(*values >= 0.0f);
Source->MaxDistance = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ROLLOFF_FACTOR:
CHECKVAL(*values >= 0.0f);
Source->RollOffFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_REFERENCE_DISTANCE:
CHECKVAL(*values >= 0.0f);
Source->RefDistance = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MIN_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->MinGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MAX_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->MaxGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->OuterGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_GAINHF:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->OuterGainHF = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AIR_ABSORPTION_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 10.0f);
Source->AirAbsorptionFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ROOM_ROLLOFF_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 10.0f);
Source->RoomRolloffFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DOPPLER_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->DopplerFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_SEC_OFFSET:
@@ -492,13 +505,13 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_BYTE_OFFSET:
CHECKVAL(*values >= 0.0f);
- LockContext(Context);
Source->OffsetType = prop;
Source->Offset = *values;
if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
- !Context->DeferUpdates)
+ !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire))
{
+ LockContext(Context);
WriteLock(&Source->queue_lock);
if(ApplyOffset(Source) == AL_FALSE)
{
@@ -507,68 +520,64 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
WriteUnlock(&Source->queue_lock);
+ UnlockContext(Context);
}
- UnlockContext(Context);
return AL_TRUE;
case AL_SOURCE_RADIUS:
CHECKVAL(*values >= 0.0f && isfinite(*values));
Source->Radius = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_STEREO_ANGLES:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]));
- LockContext(Context);
Source->StereoPan[0] = values[0];
Source->StereoPan[1] = values[1];
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_POSITION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Position, values[0], values[1], values[2], 1.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Position[0] = values[0];
+ Source->Position[1] = values[1];
+ Source->Position[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_VELOCITY:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Velocity, values[0], values[1], values[2], 0.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Velocity[0] = values[0];
+ Source->Velocity[1] = values[1];
+ Source->Velocity[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECTION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Direction, values[0], values[1], values[2], 0.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Direction[0] = values[0];
+ Source->Direction[1] = values[1];
+ Source->Direction[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ORIENTATION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) &&
isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]));
- LockContext(Context);
Source->Orientation[0][0] = values[0];
Source->Orientation[0][1] = values[1];
Source->Orientation[0][2] = values[2];
Source->Orientation[1][0] = values[3];
Source->Orientation[1][1] = values[4];
Source->Orientation[1][2] = values[5];
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
@@ -626,13 +635,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->HeadRelative = (ALboolean)*values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_LOOPING:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->Looping = (ALboolean)*values;
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_BUFFER:
@@ -695,13 +705,13 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_BYTE_OFFSET:
CHECKVAL(*values >= 0);
- LockContext(Context);
Source->OffsetType = prop;
Source->Offset = *values;
if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
- !Context->DeferUpdates)
+ !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire))
{
+ LockContext(Context);
WriteLock(&Source->queue_lock);
if(ApplyOffset(Source) == AL_FALSE)
{
@@ -710,8 +720,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
WriteUnlock(&Source->queue_lock);
+ UnlockContext(Context);
}
- UnlockContext(Context);
return AL_TRUE;
case AL_DIRECT_FILTER:
@@ -722,7 +732,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
- LockContext(Context);
if(!filter)
{
Source->Direct.Gain = 1.0f;
@@ -739,37 +748,36 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->Direct.GainLF = filter->GainLF;
Source->Direct.LFReference = filter->LFReference;
}
- UnlockContext(Context);
UnlockFiltersRead(device);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECT_FILTER_GAINHF_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->DryGainHFAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->WetGainAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->WetGainHFAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECT_CHANNELS_SOFT:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->DirectChannels = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DISTANCE_MODEL:
@@ -783,27 +791,20 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->DistanceModel = *values;
if(Context->SourceDistanceModel)
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER:
LockFiltersRead(device);
- LockContext(Context);
if(!((ALuint)values[1] < device->NumAuxSends &&
(values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) &&
(values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)))
{
- UnlockContext(Context);
UnlockFiltersRead(device);
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
- /* Add refcount on the new slot, and release the previous slot */
- if(slot) IncrementRef(&slot->ref);
- slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
- if(slot) DecrementRef(&slot->ref);
-
if(!filter)
{
/* Disable filter */
@@ -821,9 +822,28 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->Send[values[1]].GainLF = filter->GainLF;
Source->Send[values[1]].LFReference = filter->LFReference;
}
- UnlockContext(Context);
UnlockFiltersRead(device);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+
+ if(slot != Source->Send[values[1]].Slot &&
+ (Source->state == AL_PLAYING || Source->state == AL_PAUSED))
+ {
+ /* Add refcount on the new slot, and release the previous slot */
+ if(slot) IncrementRef(&slot->ref);
+ slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
+ if(slot) DecrementRef(&slot->ref);
+ /* We must force an update if the auxiliary slot changed on a
+ * playing source, in case the slot is about to be deleted.
+ */
+ UpdateSourceProps(Source, device->NumAuxSends);
+ }
+ else
+ {
+ if(slot) IncrementRef(&slot->ref);
+ slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
+ if(slot) DecrementRef(&slot->ref);
+ DO_UPDATEPROPS();
+ }
+
return AL_TRUE;
@@ -1078,10 +1098,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_STEREO_ANGLES:
- LockContext(Context);
values[0] = Source->StereoPan[0];
values[1] = Source->StereoPan[1];
- UnlockContext(Context);
return AL_TRUE;
case AL_SEC_OFFSET_LATENCY_SOFT:
@@ -1093,38 +1111,30 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_POSITION:
- LockContext(Context);
- values[0] = Source->Position.v[0];
- values[1] = Source->Position.v[1];
- values[2] = Source->Position.v[2];
- UnlockContext(Context);
+ values[0] = Source->Position[0];
+ values[1] = Source->Position[1];
+ values[2] = Source->Position[2];
return AL_TRUE;
case AL_VELOCITY:
- LockContext(Context);
- values[0] = Source->Velocity.v[0];
- values[1] = Source->Velocity.v[1];
- values[2] = Source->Velocity.v[2];
- UnlockContext(Context);
+ values[0] = Source->Velocity[0];
+ values[1] = Source->Velocity[1];
+ values[2] = Source->Velocity[2];
return AL_TRUE;
case AL_DIRECTION:
- LockContext(Context);
- values[0] = Source->Direction.v[0];
- values[1] = Source->Direction.v[1];
- values[2] = Source->Direction.v[2];
- UnlockContext(Context);
+ values[0] = Source->Direction[0];
+ values[1] = Source->Direction[1];
+ values[2] = Source->Direction[2];
return AL_TRUE;
case AL_ORIENTATION:
- LockContext(Context);
values[0] = Source->Orientation[0][0];
values[1] = Source->Orientation[0][1];
values[2] = Source->Orientation[0][2];
values[3] = Source->Orientation[1][0];
values[4] = Source->Orientation[1][1];
values[5] = Source->Orientation[1][2];
- UnlockContext(Context);
return AL_TRUE;
/* 1x int */
@@ -1522,9 +1532,8 @@ done:
AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
{
ALCcontext *context;
- ALbufferlistitem *BufferList;
ALsource *Source;
- ALsizei i, j;
+ ALsizei i;
context = GetContextRef();
if(!context) return;
@@ -1559,22 +1568,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
}
UnlockContext(context);
- BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, NULL);
- while(BufferList != NULL)
- {
- ALbufferlistitem *next = BufferList->next;
- if(BufferList->buffer != NULL)
- DecrementRef(&BufferList->buffer->ref);
- free(BufferList);
- BufferList = next;
- }
-
- for(j = 0;j < MAX_SENDS;++j)
- {
- if(Source->Send[j].Slot)
- DecrementRef(&Source->Send[j].Slot->ref);
- Source->Send[j].Slot = NULL;
- }
+ DeinitSource(Source);
memset(Source, 0, sizeof(*Source));
al_free(Source);
@@ -1612,6 +1606,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1620,6 +1615,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
else
SetSourcefv(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1632,6 +1628,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1643,6 +1640,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1655,6 +1653,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1665,6 +1664,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat
else
SetSourcefv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1678,6 +1678,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1689,6 +1690,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va
SetSourcefv(Source, Context, param, &fval);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1701,6 +1703,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1712,6 +1715,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1725,6 +1729,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1742,6 +1747,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1755,6 +1761,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1763,6 +1770,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
else
SetSourceiv(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1775,6 +1783,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1786,6 +1795,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL
SetSourceiv(Source, Context, param, ivals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1798,6 +1808,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1808,6 +1819,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val
else
SetSourceiv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1821,6 +1833,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1829,6 +1842,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO
else
SetSourcei64v(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1841,6 +1855,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1852,6 +1867,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF
SetSourcei64v(Source, Context, param, i64vals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1864,6 +1880,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1874,6 +1891,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin
else
SetSourcei64v(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1887,6 +1905,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1901,6 +1920,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val
*value = (ALfloat)dval;
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1914,6 +1934,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1932,6 +1953,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1946,6 +1968,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1964,6 +1987,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1977,6 +2001,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1987,6 +2012,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *
else
GetSourcedv(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1999,6 +2025,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2017,6 +2044,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2029,6 +2057,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2039,6 +2068,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble
else
GetSourcedv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2052,6 +2082,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2062,6 +2093,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value
else
GetSourceiv(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2075,6 +2107,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2093,6 +2126,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2106,6 +2140,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2116,6 +2151,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values
else
GetSourceiv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2129,6 +2165,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2139,6 +2176,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S
else
GetSourcei64v(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2151,6 +2189,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2169,6 +2208,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2181,6 +2221,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2191,6 +2232,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
else
GetSourcei64v(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2241,8 +2283,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
for(i = 0;i < n;i++)
{
source = LookupSource(context, sources[i]);
- if(context->DeferUpdates) source->new_state = AL_PLAYING;
- else SetSourceState(source, context, AL_PLAYING);
+ if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ source->new_state = AL_PLAYING;
+ else
+ SetSourceState(source, context, AL_PLAYING);
}
UnlockContext(context);
@@ -2277,8 +2321,10 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources)
for(i = 0;i < n;i++)
{
source = LookupSource(context, sources[i]);
- if(context->DeferUpdates) source->new_state = AL_PAUSED;
- else SetSourceState(source, context, AL_PAUSED);
+ if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ source->new_state = AL_PAUSED;
+ else
+ SetSourceState(source, context, AL_PAUSED);
}
UnlockContext(context);
@@ -2594,9 +2640,15 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->InnerAngle = 360.0f;
Source->OuterAngle = 360.0f;
Source->Pitch = 1.0f;
- aluVectorSet(&Source->Position, 0.0f, 0.0f, 0.0f, 1.0f);
- aluVectorSet(&Source->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
- aluVectorSet(&Source->Direction, 0.0f, 0.0f, 0.0f, 0.0f);
+ Source->Position[0] = 0.0f;
+ Source->Position[1] = 0.0f;
+ Source->Position[2] = 0.0f;
+ Source->Velocity[0] = 0.0f;
+ Source->Velocity[1] = 0.0f;
+ Source->Velocity[2] = 0.0f;
+ Source->Direction[0] = 0.0f;
+ Source->Direction[1] = 0.0f;
+ Source->Direction[2] = 0.0f;
Source->Orientation[0][0] = 0.0f;
Source->Orientation[0][1] = 0.0f;
Source->Orientation[0][2] = -1.0f;
@@ -2628,15 +2680,6 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->DistanceModel = DefaultDistanceModel;
- Source->state = AL_INITIAL;
- Source->new_state = AL_NONE;
- Source->SourceType = AL_UNDETERMINED;
- Source->OffsetType = AL_NONE;
- Source->Offset = 0.0;
-
- ATOMIC_INIT(&Source->queue, NULL);
- ATOMIC_INIT(&Source->current_buffer, NULL);
-
Source->Direct.Gain = 1.0f;
Source->Direct.GainHF = 1.0f;
Source->Direct.HFReference = LOWPASSFREQREF;
@@ -2651,7 +2694,170 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->Send[i].LFReference = HIGHPASSFREQREF;
}
- ATOMIC_INIT(&Source->NeedsUpdate, AL_TRUE);
+ Source->state = AL_INITIAL;
+ Source->new_state = AL_NONE;
+ Source->SourceType = AL_UNDETERMINED;
+ Source->OffsetType = AL_NONE;
+ Source->Offset = 0.0;
+
+ ATOMIC_INIT(&Source->queue, NULL);
+ ATOMIC_INIT(&Source->current_buffer, NULL);
+
+ ATOMIC_INIT(&Source->Update, NULL);
+ ATOMIC_INIT(&Source->FreeList, NULL);
+}
+
+static ALvoid DeinitSource(ALsource *source)
+{
+ ALbufferlistitem *BufferList;
+ struct ALsourceProps *props;
+ size_t count = 0;
+ size_t i;
+
+ props = ATOMIC_LOAD(&source->Update);
+ if(props) al_free(props);
+
+ props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed);
+ while(props)
+ {
+ struct ALsourceProps *next;
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ al_free(props);
+ props = next;
+ ++count;
+ }
+ /* This is excessively spammy if it traces every source destruction, so
+ * just warn if it was unexpectedly large.
+ */
+ if(count > 3)
+ WARN("Freed "SZFMT" Source property objects\n", count);
+
+ BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NULL);
+ while(BufferList != NULL)
+ {
+ ALbufferlistitem *next = BufferList->next;
+ if(BufferList->buffer != NULL)
+ DecrementRef(&BufferList->buffer->ref);
+ free(BufferList);
+ BufferList = next;
+ }
+
+ for(i = 0;i < MAX_SENDS;++i)
+ {
+ if(source->Send[i].Slot)
+ DecrementRef(&source->Send[i].Slot->ref);
+ source->Send[i].Slot = NULL;
+ }
+}
+
+void UpdateSourceProps(ALsource *source, ALuint num_sends)
+{
+ struct ALsourceProps *props;
+ size_t i;
+
+ /* Get an unused property container, or allocate a new one as needed. */
+ props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire);
+ if(!props)
+ props = al_calloc(16, sizeof(*props));
+ else
+ {
+ struct ALsourceProps *next;
+ do {
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
+ &source->FreeList, &props, next, almemory_order_seq_cst,
+ almemory_order_consume) == 0);
+ }
+
+ /* Copy in current property values. */
+ ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed);
+ for(i = 0;i < 2;i++)
+ {
+ size_t j;
+ for(j = 0;j < 3;j++)
+ ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j],
+ 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, source->DistanceModel, almemory_order_relaxed);
+ ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed);
+ ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed);
+ ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed);
+
+ for(i = 0;i < num_sends;i++)
+ {
+ ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference,
+ almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference,
+ almemory_order_relaxed);
+ }
+
+ /* Set the new container for updating internal parameters. */
+ props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel);
+ if(props)
+ {
+ /* If there was an unused update container, put it back in the
+ * freelist.
+ */
+ struct ALsourceProps *first = ATOMIC_LOAD(&source->FreeList);
+ do {
+ ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
+ &source->FreeList, &first, props) == 0);
+ }
+}
+
+void UpdateAllSourceProps(ALCcontext *context)
+{
+ ALuint num_sends = context->Device->NumAuxSends;
+ ALsizei pos;
+ for(pos = 0;pos < context->VoiceCount;pos++)
+ {
+ ALvoice *voice = &context->Voices[pos];
+ ALsource *source = voice->Source;
+ if(source != NULL && (source->state == AL_PLAYING ||
+ source->state == AL_PAUSED))
+ UpdateSourceProps(source, num_sends);
+ }
+
}
@@ -2749,11 +2955,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
}
if(BufferList->buffer->FmtChannels == FmtMono)
- voice->Update = CalcSourceParams;
+ voice->Update = CalcAttnSourceParams;
else
voice->Update = CalcNonAttnSourceParams;
-
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ UpdateSourceProps(Source, device->NumAuxSends);
}
else if(state == AL_PAUSED)
{
@@ -3084,30 +3289,13 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac)
*/
ALvoid ReleaseALSources(ALCcontext *Context)
{
- ALbufferlistitem *item;
ALsizei pos;
- ALuint j;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *temp = Context->SourceMap.array[pos].value;
Context->SourceMap.array[pos].value = NULL;
- item = ATOMIC_EXCHANGE(ALbufferlistitem*, &temp->queue, NULL);
- while(item != NULL)
- {
- ALbufferlistitem *next = item->next;
- if(item->buffer != NULL)
- DecrementRef(&item->buffer->ref);
- free(item);
- item = next;
- }
-
- for(j = 0;j < MAX_SENDS;++j)
- {
- if(temp->Send[j].Slot)
- DecrementRef(&temp->Send[j].Slot->ref);
- temp->Send[j].Slot = NULL;
- }
+ DeinitSource(temp);
FreeThunkEntry(temp->id);
memset(temp, 0, sizeof(*temp));
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index c0c2ca82..e8a8d391 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -62,7 +62,11 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -86,7 +90,11 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -148,7 +156,7 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = context->DeferUpdates;
+ value = ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -188,7 +196,7 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALdouble)context->DeferUpdates;
+ value = (ALdouble)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -228,7 +236,7 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALfloat)context->DeferUpdates;
+ value = (ALfloat)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -268,7 +276,7 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALint)context->DeferUpdates;
+ value = (ALint)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -308,7 +316,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALint64SOFT)context->DeferUpdates;
+ value = (ALint64SOFT)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -554,7 +562,11 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerFactor = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -573,7 +585,11 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerVelocity = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -592,7 +608,11 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
WriteLock(&context->PropLock);
context->SpeedOfSound = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -615,7 +635,13 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
WriteLock(&context->PropLock);
context->DistanceModel = value;
if(!context->SourceDistanceModel)
- UpdateListenerProps(context);
+ {
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
+ }
WriteUnlock(&context->PropLock);
done: