aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
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));