aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-05-14 23:43:40 -0700
committerChris Robinson <[email protected]>2016-05-14 23:43:40 -0700
commitb3338d25f6d4fd02935ac83d0d3f227b145307d1 (patch)
treecb3b14deec8f1298121d61d1fbd2c57b6610dd41 /OpenAL32/alSource.c
parent0f7e4993237e83ddc53a958a6369924da53c4a99 (diff)
Provide asynchronous property updates for sources
This necessitates a change in how source updates are handled. Rather than just being able to update sources when a dependent object state is changed (e.g. a listener gain change), now all source updates must be proactively provided. Consequently, apps that do not utilize any deferring (AL_SOFT_defer_updates or alcSuspendContext/alcProcessContext) may utilize more CPU since it'll be filling out more update containers for the mixer thread to use. The upside is that there's less blocking between the app's calling thread and the mixer thread, particularly for vectors and other multi-value properties (filters and sends). Deferring behavior when used is also improved, since updates that shouldn't be applied yet are simply not provided. And when they are provided, the mixer doesn't have to ignore them, meaning the actual deferring of a context doesn't have to synchrnously force an update -- the process call will send any pending updates, which the mixer will apply even if another deferral occurs before the mixer runs, because it'll still be there waiting on the next mixer invocation. There is one slight bug introduced by this commit. When a listener change is made, or changes to multiple sources while updates are being deferred, it is possible for the mixer to run while the sources are prepping their updates, causing some of the source updates to be seen before the other. This will be fixed in short order.
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r--OpenAL32/alSource.c452
1 files changed, 320 insertions, 132 deletions
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));