ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); ALeffectStateFactory *factory; if(newtype != EffectSlot->Effect.Type) { ALeffectState *State; FPUCtl oldMode; factory = getFactoryByType(newtype); if(!factory) { ERR("Failed to find factory for effect type 0x%04x\n", newtype); return AL_INVALID_ENUM; } State = V0(factory,create)(); if(!State) return AL_OUT_OF_MEMORY; SetMixerFPUMode(&oldMode); /* FIXME: This just needs to prevent the device from being reset during * the state's device update, so the list lock in ALc.c should do here. */ ALCdevice_Lock(Device); State->OutBuffer = Device->Dry.Buffer; State->OutChannels = Device->Dry.NumChannels; if(V(State,deviceUpdate)(Device) == AL_FALSE) { ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); DELETE_OBJ(State); return AL_OUT_OF_MEMORY; } ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); if(!effect) { EffectSlot->Effect.Type = AL_EFFECT_NULL; memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); } else { EffectSlot->Effect.Type = effect->type; memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); } EffectSlot->Effect.State = State; UpdateEffectSlotProps(EffectSlot, AL_TRUE); } else if(effect) { memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); UpdateEffectSlotProps(EffectSlot, AL_FALSE); } return AL_NO_ERROR; }
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); ALeffectStateFactory *factory; if(newtype != EffectSlot->Effect.Type) { ALeffectState *State; FPUCtl oldMode; factory = getFactoryByType(newtype); if(!factory) { ERR("Failed to find factory for effect type 0x%04x\n", newtype); return AL_INVALID_ENUM; } State = V0(factory,create)(); if(!State) return AL_OUT_OF_MEMORY; SetMixerFPUMode(&oldMode); almtx_lock(&Device->BackendLock); State->OutBuffer = Device->Dry.Buffer; State->OutChannels = Device->Dry.NumChannels; if(V(State,deviceUpdate)(Device) == AL_FALSE) { almtx_unlock(&Device->BackendLock); RestoreFPUMode(&oldMode); DELETE_OBJ(State); return AL_OUT_OF_MEMORY; } almtx_unlock(&Device->BackendLock); RestoreFPUMode(&oldMode); if(!effect) { EffectSlot->Effect.Type = AL_EFFECT_NULL; memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); } else { EffectSlot->Effect.Type = effect->type; EffectSlot->Effect.Props = effect->Props; } EffectSlot->Effect.State = State; UpdateEffectSlotProps(EffectSlot); } else if(effect) { EffectSlot->Effect.Props = effect->Props; UpdateEffectSlotProps(EffectSlot); } return AL_NO_ERROR; }
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value) { ALCcontext *context; ALeffectslot *slot; context = GetContextRef(); if(!context) return; WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) { case AL_EFFECTSLOT_GAIN: if(!(value >= 0.0f && value <= 1.0f)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->Gain = value; break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } UpdateEffectSlotProps(slot); done: UnlockEffectSlotsRead(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); }
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value) { ALCdevice *device; ALCcontext *context; ALeffectslot *slot; ALeffect *effect = NULL; ALenum err; context = GetContextRef(); if(!context) return; WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) { case AL_EFFECTSLOT_EFFECT: device = context->Device; LockEffectsRead(device); effect = (value ? LookupEffect(device, value) : NULL); if(!(value == 0 || effect != NULL)) { UnlockEffectsRead(device); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } err = InitializeEffect(device, slot, effect); UnlockEffectsRead(device); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; UpdateEffectSlotProps(slot); if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) UpdateAllSourceProps(context); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: UnlockEffectSlotsRead(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); }
void UpdateAllEffectSlotProps(ALCcontext *context) { struct ALeffectslotArray *auxslots; ALsizei i; LockEffectSlotList(context); auxslots = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); for(i = 0;i < auxslots->count;i++) { ALeffectslot *slot = auxslots->slot[i]; if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) UpdateEffectSlotProps(slot, context); } UnlockEffectSlotList(context); }