AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *Context; Context = GetContextRef(); if(!Context) return; if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint))) alSetError(Context, AL_INVALID_VALUE); else { ALenum err; ALsizei i; 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 || InitEffectSlot(slot) != AL_NO_ERROR) { free(slot); // We must have run out or memory alSetError(Context, AL_OUT_OF_MEMORY); alDeleteAuxiliaryEffectSlots(i, effectslots); break; } LockContext(Context); err = ResizeEffectSlotArray(Context, 1); if(err == AL_NO_ERROR) Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot; UnlockContext(Context); if(err == AL_NO_ERROR) 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); ALeffectState_Destroy(slot->EffectState); free(slot); alSetError(Context, err); alDeleteAuxiliaryEffectSlots(i, effectslots); break; } effectslots[i] = slot->effectslot; } } ALCcontext_DecRef(Context); }
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *Context; ALsizei cur = 0; Context = GetContextRef(); if(!Context) return; al_try { ALenum err; CHECK_VALUE(Context, n >= 0); for(cur = 0;cur < n;cur++) { ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); err = AL_OUT_OF_MEMORY; if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) { al_free(slot); al_throwerr(Context, err); break; } err = NewThunkEntry(&slot->id); if(err == AL_NO_ERROR) err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->id, slot); if(err != AL_NO_ERROR) { FreeThunkEntry(slot->id); ALeffectState_Destroy(slot->EffectState); al_free(slot); al_throwerr(Context, err); } effectslots[cur] = slot->id; } err = AddEffectSlotArray(Context, n, effectslots); if(err != AL_NO_ERROR) al_throwerr(Context, err); } al_catchany() { if(cur > 0) alDeleteAuxiliaryEffectSlots(cur, effectslots); } al_endtry; ALCcontext_DecRef(Context); }
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) { ALCcontext *Context; ALeffectslot *EffectSlot; ALsizei i; Context = GetContextRef(); if(!Context) return; if(n < 0) alSetError(Context, AL_INVALID_VALUE); else { // Check that all effectslots are valid for(i = 0;i < n;i++) { if((EffectSlot=LookupEffectSlot(Context, effectslots[i])) == NULL) { alSetError(Context, AL_INVALID_NAME); n = 0; break; } else if(EffectSlot->ref != 0) { alSetError(Context, AL_INVALID_OPERATION); n = 0; break; } } // All effectslots are valid for(i = 0;i < n;i++) { // Recheck that the effectslot is valid, because there could be duplicated names if((EffectSlot=RemoveEffectSlot(Context, effectslots[i])) == NULL) continue; FreeThunkEntry(EffectSlot->effectslot); RemoveEffectSlotArray(Context, EffectSlot); ALeffectState_Destroy(EffectSlot->EffectState); memset(EffectSlot, 0, sizeof(ALeffectslot)); free(EffectSlot); } } ALCcontext_DecRef(Context); }
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; for(pos = 0;pos < Context->EffectSlotMap.size;pos++) { ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; // Release effectslot structure ALeffectState_Destroy(temp->EffectState); FreeThunkEntry(temp->effectslot); memset(temp, 0, sizeof(ALeffectslot)); free(temp); } }
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) { ALCcontext *Context; ALeffectslot *slot; ALsizei i; Context = GetContextRef(); if(!Context) return; al_try { CHECK_VALUE(Context, n >= 0); for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(Context, effectslots[i])) == NULL) al_throwerr(Context, AL_INVALID_NAME); if(slot->ref != 0) al_throwerr(Context, AL_INVALID_OPERATION); } // All effectslots are valid for(i = 0;i < n;i++) { if((slot=RemoveEffectSlot(Context, effectslots[i])) == NULL) continue; FreeThunkEntry(slot->id); RemoveEffectSlotArray(Context, slot); ALeffectState_Destroy(slot->EffectState); memset(slot, 0, sizeof(*slot)); al_free(slot); } } al_endtry; ALCcontext_DecRef(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; }