static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect) { if(ALEffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL)) { ALeffectState *NewState = NULL; if(!effect || effect->type == AL_EFFECT_NULL) NewState = NoneCreate(); else if(effect->type == AL_EFFECT_EAXREVERB) NewState = EAXVerbCreate(); else if(effect->type == AL_EFFECT_REVERB) NewState = VerbCreate(); else if(effect->type == AL_EFFECT_ECHO) NewState = EchoCreate(); /* No new state? An error occured.. */ if(NewState == NULL || ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE) { if(NewState) ALEffect_Destroy(NewState); return; } if(ALEffectSlot->EffectState) ALEffect_Destroy(ALEffectSlot->EffectState); ALEffectSlot->EffectState = NewState; } if(!effect) { memset(&ALEffectSlot->effect, 0, sizeof(ALEffectSlot->effect)); return; } memcpy(&ALEffectSlot->effect, effect, sizeof(*effect)); ALEffect_Update(ALEffectSlot->EffectState, Context, effect); }
ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *Context; ALsizei i, j; Context = GetContextSuspended(); if(!Context) return; if (n > 0) { ALCdevice *Device = Context->Device; if(Context->AuxiliaryEffectSlotCount+n <= Device->AuxiliaryEffectSlotMax) { // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint))) { ALeffectslot **list = &Context->AuxiliaryEffectSlot; while(*list) list = &(*list)->next; i = 0; while(i < n) { *list = calloc(1, sizeof(ALeffectslot)); if(!(*list) || !((*list)->EffectState=NoneCreate())) { // We must have run out or memory free(*list); *list = NULL; alDeleteAuxiliaryEffectSlots(i, effectslots); alSetError(AL_OUT_OF_MEMORY); break; } (*list)->Gain = 1.0; (*list)->AuxSendAuto = AL_TRUE; for(j = 0;j < BUFFERSIZE;j++) (*list)->WetBuffer[j] = 0.0f; (*list)->refcount = 0; effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list); (*list)->effectslot = effectslots[i]; Context->AuxiliaryEffectSlotCount++; i++; list = &(*list)->next; } } } else alSetError(AL_INVALID_OPERATION); } ProcessContext(Context); }
ALenum InitEffectSlot(ALeffectslot *slot) { ALint i; if(!(slot->EffectState=NoneCreate())) return AL_OUT_OF_MEMORY; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; slot->NeedsUpdate = AL_FALSE; for(i = 0;i < BUFFERSIZE;i++) slot->WetBuffer[i] = 0.0f; for(i = 0;i < 1;i++) { slot->ClickRemoval[i] = 0.0f; slot->PendingClicks[i] = 0.0f; } slot->ref = 0; return AL_NO_ERROR; }
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *Context; ALCdevice *Device; Context = GetContextSuspended(); if(!Context) return; Device = Context->Device; if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint))) alSetError(Context, AL_INVALID_VALUE); else if((ALuint)n > Device->AuxiliaryEffectSlotMax - Context->EffectSlotMap.size) alSetError(Context, AL_INVALID_VALUE); else { ALenum err; ALsizei i, j; i = 0; while(i < n) { ALeffectslot *slot = calloc(1, sizeof(ALeffectslot)); if(!slot || !(slot->EffectState=NoneCreate())) { free(slot); // We must have run out or memory alSetError(Context, AL_OUT_OF_MEMORY); alDeleteAuxiliaryEffectSlots(i, effectslots); break; } slot->effectslot = (ALuint)ALTHUNK_ADDENTRY(slot); err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot); if(err != AL_NO_ERROR) { ALTHUNK_REMOVEENTRY(slot->effectslot); ALEffect_Destroy(slot->EffectState); free(slot); alSetError(Context, err); alDeleteAuxiliaryEffectSlots(i, effectslots); break; } effectslots[i++] = slot->effectslot; slot->Gain = int2ALfp(1); slot->AuxSendAuto = AL_TRUE; for(j = 0;j < BUFFERSIZE;j++) slot->WetBuffer[j] = int2ALfp(0); for(j = 0;j < 1;j++) { slot->ClickRemoval[j] = int2ALfp(0); slot->PendingClicks[j] = int2ALfp(0); } slot->refcount = 0; } } ProcessContext(Context); }
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); ALeffectState *State = NULL; ALenum err = AL_NO_ERROR; LockDevice(Device); if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL) { State = NoneCreate(); if(!State) err = AL_OUT_OF_MEMORY; } else if(newtype == AL_EFFECT_EAXREVERB || newtype == AL_EFFECT_REVERB) { if(EffectSlot->effect.type != AL_EFFECT_EAXREVERB && EffectSlot->effect.type != AL_EFFECT_REVERB) { State = ReverbCreate(); if(!State) err = AL_OUT_OF_MEMORY; } } else if(newtype == AL_EFFECT_ECHO && EffectSlot->effect.type != AL_EFFECT_ECHO) { State = EchoCreate(); if(!State) err = AL_OUT_OF_MEMORY; } else if(newtype == AL_EFFECT_RING_MODULATOR && EffectSlot->effect.type != AL_EFFECT_RING_MODULATOR) { State = ModulatorCreate(); if(!State) err = AL_OUT_OF_MEMORY; } else if(newtype == AL_EFFECT_DEDICATED_DIALOGUE || newtype == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) { if(EffectSlot->effect.type != AL_EFFECT_DEDICATED_DIALOGUE && EffectSlot->effect.type != AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) { State = DedicatedCreate(); if(!State) err = AL_OUT_OF_MEMORY; } } if(err != AL_NO_ERROR) { UnlockDevice(Device); return err; } if(State) { int oldMode; oldMode = SetMixerFPUMode(); if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE) { RestoreFPUMode(oldMode); UnlockDevice(Device); ALeffectState_Destroy(State); return AL_OUT_OF_MEMORY; } State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State); if(!effect) memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); else memcpy(&EffectSlot->effect, effect, sizeof(*effect)); /* FIXME: This should be done asynchronously, but since the EffectState * object was changed, it needs an update before its Process method can * be called. */ EffectSlot->NeedsUpdate = AL_FALSE; ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot); UnlockDevice(Device); RestoreFPUMode(oldMode); ALeffectState_Destroy(State); State = NULL; } else { if(!effect) memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); else memcpy(&EffectSlot->effect, effect, sizeof(*effect)); UnlockDevice(Device); EffectSlot->NeedsUpdate = AL_TRUE; } return AL_NO_ERROR; }