Use a separate array for the auxiliary slots in the mixer

This commit is contained in:
Chris Robinson 2011-08-30 20:13:42 -07:00
parent 755062fb76
commit 189add1d5a
4 changed files with 96 additions and 34 deletions

View File

@ -1358,10 +1358,15 @@ static ALCvoid FreeContext(ALCcontext *context)
}
ResetUIntMap(&context->EffectSlotMap);
context->ActiveSourceCount = 0;
free(context->ActiveSources);
context->ActiveSources = NULL;
context->MaxActiveSources = 0;
context->ActiveSourceCount = 0;
context->ActiveEffectSlotCount = 0;
free(context->ActiveEffectSlots);
context->ActiveEffectSlots = NULL;
context->MaxActiveEffectSlots = 0;
//Invalidate context
memset(context, 0, sizeof(ALCcontext));

View File

@ -949,12 +949,11 @@ DECL_TEMPLATE(ALbyte)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{
ALuint SamplesToDo;
ALeffectslot *ALEffectSlot;
ALeffectslot **slot, **slot_end;
ALsource **src, **src_end;
ALCcontext *ctx;
int fpuState;
ALuint i, c;
ALsizei e;
#if defined(HAVE_FESETROUND)
fpuState = fegetround();
@ -1004,30 +1003,31 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
}
/* effect slot processing */
for(e = 0;e < ctx->EffectSlotMap.size;e++)
slot = ctx->ActiveEffectSlots;
slot_end = slot + ctx->ActiveEffectSlotCount;
while(slot != slot_end)
{
ALEffectSlot = ctx->EffectSlotMap.array[e].value;
for(i = 0;i < SamplesToDo;i++)
{
ALEffectSlot->WetBuffer[i] += ALEffectSlot->ClickRemoval[0];
ALEffectSlot->ClickRemoval[0] -= ALEffectSlot->ClickRemoval[0] / 256.0f;
(*slot)->WetBuffer[i] += (*slot)->ClickRemoval[0];
(*slot)->ClickRemoval[0] -= (*slot)->ClickRemoval[0] / 256.0f;
}
for(i = 0;i < 1;i++)
{
ALEffectSlot->ClickRemoval[i] += ALEffectSlot->PendingClicks[i];
ALEffectSlot->PendingClicks[i] = 0.0f;
(*slot)->ClickRemoval[i] += (*slot)->PendingClicks[i];
(*slot)->PendingClicks[i] = 0.0f;
}
if(!DeferUpdates && ExchangeInt(&ALEffectSlot->NeedsUpdate, AL_FALSE))
ALEffect_Update(ALEffectSlot->EffectState, ctx, ALEffectSlot);
if(!DeferUpdates && ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
ALEffect_Update((*slot)->EffectState, ctx, *slot);
ALEffect_Process(ALEffectSlot->EffectState, ALEffectSlot,
SamplesToDo, ALEffectSlot->WetBuffer,
device->DryBuffer);
ALEffect_Process((*slot)->EffectState, *slot, SamplesToDo,
(*slot)->WetBuffer, device->DryBuffer);
for(i = 0;i < SamplesToDo;i++)
ALEffectSlot->WetBuffer[i] = 0.0f;
(*slot)->WetBuffer[i] = 0.0f;
slot++;
}
ctx = ctx->next;

View File

@ -610,6 +610,10 @@ struct ALCcontext_struct
ALsizei ActiveSourceCount;
ALsizei MaxActiveSources;
struct ALeffectslot **ActiveEffectSlots;
ALsizei ActiveEffectSlotCount;
ALsizei MaxActiveEffectSlots;
ALCdevice *Device;
const ALCchar *ExtensionList;

View File

@ -33,6 +33,8 @@
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect);
static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count);
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *val);
#define LookupEffectSlot(m, k) ((ALeffectslot*)LookupUIntMapKey(&(m), (k)))
#define LookupEffect(m, k) ((ALeffect*)LookupUIntMapKey(&(m), (k)))
@ -55,8 +57,14 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
ALenum err;
ALsizei i, j;
i = 0;
while(i < n)
err = ResizeEffectSlotArray(Context, n);
if(err != AL_NO_ERROR)
{
alSetError(Context, err);
n = 0;
}
for(i = 0;i < n;i++)
{
ALeffectslot *slot = calloc(1, sizeof(ALeffectslot));
if(!slot || !(slot->EffectState=NoneCreate()))
@ -68,22 +76,6 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
break;
}
err = NewThunkEntry(&slot->effectslot);
if(err == AL_NO_ERROR)
err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot);
if(err != AL_NO_ERROR)
{
FreeThunkEntry(slot->effectslot);
ALEffect_Destroy(slot->EffectState);
free(slot);
alSetError(Context, err);
alDeleteAuxiliaryEffectSlots(i, effectslots);
break;
}
effectslots[i++] = slot->effectslot;
slot->Gain = 1.0;
slot->AuxSendAuto = AL_TRUE;
slot->NeedsUpdate = AL_FALSE;
@ -95,6 +87,28 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
slot->PendingClicks[j] = 0.0f;
}
slot->ref = 0;
err = ResizeEffectSlotArray(Context, 1);
if(err == AL_NO_ERROR)
{
Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot;
err = NewThunkEntry(&slot->effectslot);
}
if(err == AL_NO_ERROR)
err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot);
if(err != AL_NO_ERROR)
{
RemoveEffectSlotArray(Context, slot);
FreeThunkEntry(slot->effectslot);
ALEffect_Destroy(slot->EffectState);
free(slot);
alSetError(Context, err);
alDeleteAuxiliaryEffectSlots(i, effectslots);
break;
}
effectslots[i] = slot->effectslot;
}
}
@ -143,6 +157,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effect
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
continue;
RemoveEffectSlotArray(Context, EffectSlot);
ALEffect_Destroy(EffectSlot->EffectState);
RemoveUIntMapKey(&Context->EffectSlotMap, EffectSlot->effectslot);
@ -468,6 +483,44 @@ ALeffectState *NoneCreate(void)
return state;
}
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot)
{
ALeffectslot **slotlist, **slotlistend;
slotlist = Context->ActiveEffectSlots;
slotlistend = slotlist + Context->ActiveEffectSlotCount;
while(slotlist != slotlistend)
{
if(*slotlist == slot)
{
*slotlist = *(--slotlistend);
Context->ActiveEffectSlotCount--;
break;
}
}
}
static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count)
{
ALsizei newcount;
void *temp;
if(count <= Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount)
return AL_NO_ERROR;
newcount = Context->MaxActiveEffectSlots ?
(Context->MaxActiveEffectSlots<<1) : 1;
if(newcount <= Context->MaxActiveEffectSlots ||
!(temp=realloc(Context->ActiveEffectSlots, newcount *
sizeof(*Context->ActiveEffectSlots))))
return AL_OUT_OF_MEMORY;
Context->ActiveEffectSlots = temp;
Context->MaxActiveEffectSlots = newcount;
return AL_NO_ERROR;
}
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
{
if(EffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))