From 189add1d5a5b1f9f55fba63937f3d92cddc0cea2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 30 Aug 2011 20:13:42 -0700 Subject: [PATCH] Use a separate array for the auxiliary slots in the mixer --- Alc/ALc.c | 7 ++- Alc/ALu.c | 30 ++++++------- OpenAL32/Include/alMain.h | 4 ++ OpenAL32/alAuxEffectSlot.c | 89 ++++++++++++++++++++++++++++++-------- 4 files changed, 96 insertions(+), 34 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index bae464cc..ace230d2 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -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)); diff --git a/Alc/ALu.c b/Alc/ALu.c index ae950f32..f2658da7 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -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; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 299b16a0..fe9d3331 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -610,6 +610,10 @@ struct ALCcontext_struct ALsizei ActiveSourceCount; ALsizei MaxActiveSources; + struct ALeffectslot **ActiveEffectSlots; + ALsizei ActiveEffectSlotCount; + ALsizei MaxActiveEffectSlots; + ALCdevice *Device; const ALCchar *ExtensionList; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 4645ed2b..27d92949 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -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))