Use a NULL source for inactive activesources
Also only access the activesource's source field once per update.
This commit is contained in:
@@ -1927,6 +1927,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
ALactivesource *src = context->ActiveSources[pos];
|
||||
ALsource *source = src->Source;
|
||||
ALuint s = device->NumAuxSends;
|
||||
|
||||
while(s < MAX_SENDS)
|
||||
{
|
||||
src->Send[s].Moving = AL_FALSE;
|
||||
@@ -1934,8 +1935,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
s++;
|
||||
}
|
||||
|
||||
src->Update(src, context);
|
||||
ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
|
||||
if(source)
|
||||
{
|
||||
src->Update(src, source, context);
|
||||
ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
context = context->next;
|
||||
|
||||
@@ -166,7 +166,7 @@ static ALvoid CalcListenerParams(ALlistener *Listener)
|
||||
aluMatrixVector(Listener->Params.Velocity, 0.0f, Listener->Params.Matrix);
|
||||
}
|
||||
|
||||
ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALsource *ALSource, const ALCcontext *ALContext)
|
||||
{
|
||||
static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } };
|
||||
static const struct ChanMap StereoMap[2] = {
|
||||
@@ -216,7 +216,6 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
};
|
||||
|
||||
ALCdevice *Device = ALContext->Device;
|
||||
const ALsource *ALSource = src->Source;
|
||||
ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
|
||||
ALbufferlistitem *BufferListItem;
|
||||
enum FmtChannels Channels;
|
||||
@@ -563,10 +562,9 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
}
|
||||
}
|
||||
|
||||
ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
ALvoid CalcSourceParams(ALactivesource *src, const ALsource *ALSource, const ALCcontext *ALContext)
|
||||
{
|
||||
ALCdevice *Device = ALContext->Device;
|
||||
const ALsource *ALSource = src->Source;
|
||||
ALfloat Velocity[3],Direction[3],Position[3],SourceToListener[3];
|
||||
ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist;
|
||||
ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff;
|
||||
@@ -1178,22 +1176,21 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
|
||||
while(src != src_end)
|
||||
{
|
||||
ALsource *source = (*src)->Source;
|
||||
if(!source) goto next;
|
||||
|
||||
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
|
||||
{
|
||||
ALactivesource *temp = *(--src_end);
|
||||
*src_end = *src;
|
||||
*src = temp;
|
||||
--(ctx->ActiveSourceCount);
|
||||
continue;
|
||||
(*src)->Source = NULL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if(!DeferUpdates && (ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) ||
|
||||
UpdateSources))
|
||||
(*src)->Update(*src, ctx);
|
||||
(*src)->Update(*src, source, ctx);
|
||||
|
||||
if(source->state != AL_PAUSED)
|
||||
MixSource(*src, device, SamplesToDo);
|
||||
MixSource(*src, source, device, SamplesToDo);
|
||||
next:
|
||||
src++;
|
||||
}
|
||||
|
||||
@@ -1305,13 +1302,16 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
|
||||
while(src != src_end)
|
||||
{
|
||||
ALsource *source = (*src)->Source;
|
||||
if(source->state == AL_PLAYING)
|
||||
(*src)->Source = NULL;
|
||||
|
||||
if(source && source->state == AL_PLAYING)
|
||||
{
|
||||
source->state = AL_STOPPED;
|
||||
ATOMIC_STORE(&source->current_buffer, NULL);
|
||||
source->position = 0;
|
||||
source->position_fraction = 0;
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
Context->ActiveSourceCount = 0;
|
||||
|
||||
+1
-2
@@ -178,12 +178,11 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter
|
||||
}
|
||||
|
||||
|
||||
ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
ALvoid MixSource(ALactivesource *src, ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
MixerFunc Mix;
|
||||
HrtfMixerFunc HrtfMix;
|
||||
ResamplerFunc Resample;
|
||||
ALsource *Source = src->Source;
|
||||
ALbufferlistitem *BufferListItem;
|
||||
ALuint DataPosInt, DataPosFrac;
|
||||
ALboolean Looping;
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ALbuffer;
|
||||
struct ALsource;
|
||||
|
||||
extern enum Resampler DefaultResampler;
|
||||
|
||||
extern const ALsizei ResamplerPadding[ResamplerMax];
|
||||
@@ -25,10 +28,10 @@ typedef struct ALbufferlistitem {
|
||||
|
||||
|
||||
typedef struct ALactivesource {
|
||||
struct ALsource *Source;
|
||||
struct ALsource *volatile Source;
|
||||
|
||||
/** Method to update mixing parameters. */
|
||||
ALvoid (*Update)(struct ALactivesource *self, const ALCcontext *context);
|
||||
ALvoid (*Update)(struct ALactivesource *self, const struct ALsource *source, const ALCcontext *context);
|
||||
|
||||
/** Current target parameters used for mixing. */
|
||||
ALint Step;
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ALsource;
|
||||
struct ALactivesource;
|
||||
|
||||
|
||||
enum ActiveFilters {
|
||||
AF_None = 0,
|
||||
AF_LowPass = 1,
|
||||
@@ -216,10 +220,10 @@ inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxC
|
||||
}
|
||||
|
||||
|
||||
ALvoid CalcSourceParams(struct ALactivesource *src, const ALCcontext *ALContext);
|
||||
ALvoid CalcNonAttnSourceParams(struct ALactivesource *src, const ALCcontext *ALContext);
|
||||
ALvoid CalcSourceParams(struct ALactivesource *src, const struct ALsource *source, const ALCcontext *ALContext);
|
||||
ALvoid CalcNonAttnSourceParams(struct ALactivesource *src, const struct ALsource *source, const ALCcontext *ALContext);
|
||||
|
||||
ALvoid MixSource(struct ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo);
|
||||
ALvoid MixSource(struct ALactivesource *src, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo);
|
||||
|
||||
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
|
||||
/* Caller must lock the device. */
|
||||
|
||||
+29
-25
@@ -1400,14 +1400,9 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
|
||||
srclistend = srclist + context->ActiveSourceCount;
|
||||
while(srclist != srclistend)
|
||||
{
|
||||
if((*srclist)->Source == Source)
|
||||
{
|
||||
ALactivesource *temp = *(--srclistend);
|
||||
*srclistend = *srclist;
|
||||
*srclist = temp;
|
||||
--(context->ActiveSourceCount);
|
||||
ALsource *old = Source;
|
||||
if(COMPARE_EXCHANGE(&(*srclist)->Source, &old, NULL))
|
||||
break;
|
||||
}
|
||||
srclist++;
|
||||
}
|
||||
UnlockContext(context);
|
||||
@@ -2456,7 +2451,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
|
||||
ALCdevice *device = Context->Device;
|
||||
ALbufferlistitem *BufferList;
|
||||
ALactivesource *src = NULL;
|
||||
ALsizei j, k;
|
||||
ALsizei i;
|
||||
|
||||
/* Check that there is a queue containing at least one valid, non zero
|
||||
* length Buffer. */
|
||||
@@ -2488,44 +2483,53 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
|
||||
if(!BufferList || !device->Connected)
|
||||
goto do_stop;
|
||||
|
||||
for(j = 0;j < Context->ActiveSourceCount;j++)
|
||||
for(i = 0;i < Context->ActiveSourceCount;i++)
|
||||
{
|
||||
if(Context->ActiveSources[j]->Source == Source)
|
||||
if(Context->ActiveSources[i]->Source == Source)
|
||||
{
|
||||
src = Context->ActiveSources[j];
|
||||
src = Context->ActiveSources[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(src == NULL)
|
||||
{
|
||||
src = Context->ActiveSources[Context->ActiveSourceCount];
|
||||
if(src == NULL)
|
||||
for(i = 0;i < Context->ActiveSourceCount;i++)
|
||||
{
|
||||
src = al_malloc(16, sizeof(src[0]));
|
||||
Context->ActiveSources[Context->ActiveSourceCount] = src;
|
||||
ALsource *old = NULL;
|
||||
src = Context->ActiveSources[i];
|
||||
if(COMPARE_EXCHANGE(&src->Source, &old, Source))
|
||||
break;
|
||||
}
|
||||
if(i == Context->ActiveSourceCount)
|
||||
{
|
||||
src = Context->ActiveSources[Context->ActiveSourceCount];
|
||||
if(src == NULL)
|
||||
{
|
||||
src = al_malloc(16, sizeof(src[0]));
|
||||
Context->ActiveSources[Context->ActiveSourceCount] = src;
|
||||
}
|
||||
Context->ActiveSourceCount++;
|
||||
}
|
||||
memset(src, 0, sizeof(*src));
|
||||
Context->ActiveSourceCount++;
|
||||
|
||||
src->Source = Source;
|
||||
}
|
||||
else
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
src->Direct.Moving = AL_FALSE;
|
||||
src->Direct.Counter = 0;
|
||||
for(j = 0;j < MAX_INPUT_CHANNELS;j++)
|
||||
for(i = 0;i < MAX_INPUT_CHANNELS;i++)
|
||||
{
|
||||
for(k = 0;k < SRC_HISTORY_LENGTH;k++)
|
||||
src->Direct.Mix.Hrtf.State[j].History[k] = 0.0f;
|
||||
for(k = 0;k < HRIR_LENGTH;k++)
|
||||
ALsizei j;
|
||||
for(j = 0;j < SRC_HISTORY_LENGTH;j++)
|
||||
src->Direct.Mix.Hrtf.State[i].History[j] = 0.0f;
|
||||
for(j = 0;j < HRIR_LENGTH;j++)
|
||||
{
|
||||
src->Direct.Mix.Hrtf.State[j].Values[k][0] = 0.0f;
|
||||
src->Direct.Mix.Hrtf.State[j].Values[k][1] = 0.0f;
|
||||
src->Direct.Mix.Hrtf.State[i].Values[j][0] = 0.0f;
|
||||
src->Direct.Mix.Hrtf.State[i].Values[j][1] = 0.0f;
|
||||
}
|
||||
}
|
||||
for(i = 0;i < device->NumAuxSends;i++)
|
||||
for(i = 0;i < (ALsizei)device->NumAuxSends;i++)
|
||||
{
|
||||
src->Send[i].Counter = 0;
|
||||
src->Send[i].Moving = AL_FALSE;
|
||||
|
||||
+4
-6
@@ -732,19 +732,17 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
|
||||
while(src != src_end)
|
||||
{
|
||||
ALsource *source = (*src)->Source;
|
||||
if(!source) goto next;
|
||||
|
||||
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
|
||||
{
|
||||
ALactivesource *temp = *(--src_end);
|
||||
*src_end = *src;
|
||||
*src = temp;
|
||||
--(context->ActiveSourceCount);
|
||||
(*src)->Source = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
|
||||
(*src)->Update(*src, context);
|
||||
|
||||
(*src)->Update(*src, source, context);
|
||||
next:
|
||||
src++;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user