|
|
-
- #include "config.h"
-
- #include <cmath>
- #include <cstdlib>
-
- #include <algorithm>
-
- #include "AL/efx.h"
-
- #include "alc/effects/base.h"
- #include "effects.h"
-
- #ifdef ALSOFT_EAX
- #include "alnumeric.h"
- #include "al/eax/exception.h"
- #include "al/eax/utils.h"
- #endif // ALSOFT_EAX
-
-
- namespace {
-
- void Autowah_setParamf(EffectProps *props, ALenum param, float val)
- {
- switch(param)
- {
- case AL_AUTOWAH_ATTACK_TIME:
- if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME))
- throw effect_exception{AL_INVALID_VALUE, "Autowah attack time out of range"};
- props->Autowah.AttackTime = val;
- break;
-
- case AL_AUTOWAH_RELEASE_TIME:
- if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME))
- throw effect_exception{AL_INVALID_VALUE, "Autowah release time out of range"};
- props->Autowah.ReleaseTime = val;
- break;
-
- case AL_AUTOWAH_RESONANCE:
- if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE))
- throw effect_exception{AL_INVALID_VALUE, "Autowah resonance out of range"};
- props->Autowah.Resonance = val;
- break;
-
- case AL_AUTOWAH_PEAK_GAIN:
- if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN))
- throw effect_exception{AL_INVALID_VALUE, "Autowah peak gain out of range"};
- props->Autowah.PeakGain = val;
- break;
-
- default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
- }
- }
- void Autowah_setParamfv(EffectProps *props, ALenum param, const float *vals)
- { Autowah_setParamf(props, param, vals[0]); }
-
- void Autowah_setParami(EffectProps*, ALenum param, int)
- { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
- void Autowah_setParamiv(EffectProps*, ALenum param, const int*)
- {
- throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
- param};
- }
-
- void Autowah_getParamf(const EffectProps *props, ALenum param, float *val)
- {
- switch(param)
- {
- case AL_AUTOWAH_ATTACK_TIME:
- *val = props->Autowah.AttackTime;
- break;
-
- case AL_AUTOWAH_RELEASE_TIME:
- *val = props->Autowah.ReleaseTime;
- break;
-
- case AL_AUTOWAH_RESONANCE:
- *val = props->Autowah.Resonance;
- break;
-
- case AL_AUTOWAH_PEAK_GAIN:
- *val = props->Autowah.PeakGain;
- break;
-
- default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
- }
-
- }
- void Autowah_getParamfv(const EffectProps *props, ALenum param, float *vals)
- { Autowah_getParamf(props, param, vals); }
-
- void Autowah_getParami(const EffectProps*, ALenum param, int*)
- { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
- void Autowah_getParamiv(const EffectProps*, ALenum param, int*)
- {
- throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
- param};
- }
-
- EffectProps genDefaultProps() noexcept
- {
- EffectProps props{};
- props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
- props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
- props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
- props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
- return props;
- }
-
- } // namespace
-
- DEFINE_ALEFFECT_VTABLE(Autowah);
-
- const EffectProps AutowahEffectProps{genDefaultProps()};
-
- #ifdef ALSOFT_EAX
- namespace {
-
- class EaxAutoWahEffectException : public EaxException {
- public:
- explicit EaxAutoWahEffectException(const char* message)
- : EaxException{"EAX_AUTO_WAH_EFFECT", message}
- {}
- }; // EaxAutoWahEffectException
-
- class EaxAutoWahEffect final : public EaxEffect4<EaxAutoWahEffectException, EAXAUTOWAHPROPERTIES> {
- public:
- EaxAutoWahEffect(const EaxCall& call);
-
- private:
- struct AttackTimeValidator {
- void operator()(float flAttackTime) const
- {
- eax_validate_range<Exception>(
- "Attack Time",
- flAttackTime,
- EAXAUTOWAH_MINATTACKTIME,
- EAXAUTOWAH_MAXATTACKTIME);
- }
- }; // AttackTimeValidator
-
- struct ReleaseTimeValidator {
- void operator()(float flReleaseTime) const
- {
- eax_validate_range<Exception>(
- "Release Time",
- flReleaseTime,
- EAXAUTOWAH_MINRELEASETIME,
- EAXAUTOWAH_MAXRELEASETIME);
- }
- }; // ReleaseTimeValidator
-
- struct ResonanceValidator {
- void operator()(long lResonance) const
- {
- eax_validate_range<Exception>(
- "Resonance",
- lResonance,
- EAXAUTOWAH_MINRESONANCE,
- EAXAUTOWAH_MAXRESONANCE);
- }
- }; // ResonanceValidator
-
- struct PeakLevelValidator {
- void operator()(long lPeakLevel) const
- {
- eax_validate_range<Exception>(
- "Peak Level",
- lPeakLevel,
- EAXAUTOWAH_MINPEAKLEVEL,
- EAXAUTOWAH_MAXPEAKLEVEL);
- }
- }; // PeakLevelValidator
-
- struct AllValidator {
- void operator()(const Props& all) const
- {
- AttackTimeValidator{}(all.flAttackTime);
- ReleaseTimeValidator{}(all.flReleaseTime);
- ResonanceValidator{}(all.lResonance);
- PeakLevelValidator{}(all.lPeakLevel);
- }
- }; // AllValidator
-
- void set_defaults(Props& props) override;
-
- void set_efx_attack_time() noexcept;
- void set_efx_release_time() noexcept;
- void set_efx_resonance() noexcept;
- void set_efx_peak_gain() noexcept;
- void set_efx_defaults() override;
-
- void get(const EaxCall& call, const Props& props) override;
- void set(const EaxCall& call, Props& props) override;
- bool commit_props(const Props& props) override;
- }; // EaxAutoWahEffect
-
- EaxAutoWahEffect::EaxAutoWahEffect(const EaxCall& call)
- : EaxEffect4{AL_EFFECT_AUTOWAH, call}
- {}
-
- void EaxAutoWahEffect::set_defaults(Props& props)
- {
- props.flAttackTime = EAXAUTOWAH_DEFAULTATTACKTIME;
- props.flReleaseTime = EAXAUTOWAH_DEFAULTRELEASETIME;
- props.lResonance = EAXAUTOWAH_DEFAULTRESONANCE;
- props.lPeakLevel = EAXAUTOWAH_DEFAULTPEAKLEVEL;
- }
-
- void EaxAutoWahEffect::set_efx_attack_time() noexcept
- {
- al_effect_props_.Autowah.AttackTime = clamp(
- props_.flAttackTime,
- AL_AUTOWAH_MIN_ATTACK_TIME,
- AL_AUTOWAH_MAX_ATTACK_TIME);
- }
-
- void EaxAutoWahEffect::set_efx_release_time() noexcept
- {
- al_effect_props_.Autowah.ReleaseTime = clamp(
- props_.flReleaseTime,
- AL_AUTOWAH_MIN_RELEASE_TIME,
- AL_AUTOWAH_MAX_RELEASE_TIME);
- }
-
- void EaxAutoWahEffect::set_efx_resonance() noexcept
- {
- al_effect_props_.Autowah.Resonance = clamp(
- level_mb_to_gain(static_cast<float>(props_.lResonance)),
- AL_AUTOWAH_MIN_RESONANCE,
- AL_AUTOWAH_MAX_RESONANCE);
- }
-
- void EaxAutoWahEffect::set_efx_peak_gain() noexcept
- {
- al_effect_props_.Autowah.PeakGain = clamp(
- level_mb_to_gain(static_cast<float>(props_.lPeakLevel)),
- AL_AUTOWAH_MIN_PEAK_GAIN,
- AL_AUTOWAH_MAX_PEAK_GAIN);
- }
-
- void EaxAutoWahEffect::set_efx_defaults()
- {
- set_efx_attack_time();
- set_efx_release_time();
- set_efx_resonance();
- set_efx_peak_gain();
- }
-
- void EaxAutoWahEffect::get(const EaxCall& call, const Props& props)
- {
- switch (call.get_property_id())
- {
- case EAXAUTOWAH_NONE: break;
- case EAXAUTOWAH_ALLPARAMETERS: call.set_value<Exception>(props); break;
- case EAXAUTOWAH_ATTACKTIME: call.set_value<Exception>(props.flAttackTime); break;
- case EAXAUTOWAH_RELEASETIME: call.set_value<Exception>(props.flReleaseTime); break;
- case EAXAUTOWAH_RESONANCE: call.set_value<Exception>(props.lResonance); break;
- case EAXAUTOWAH_PEAKLEVEL: call.set_value<Exception>(props.lPeakLevel); break;
- default: fail_unknown_property_id();
- }
- }
-
- void EaxAutoWahEffect::set(const EaxCall& call, Props& props)
- {
- switch (call.get_property_id())
- {
- case EAXAUTOWAH_NONE: break;
- case EAXAUTOWAH_ALLPARAMETERS: defer<AllValidator>(call, props); break;
- case EAXAUTOWAH_ATTACKTIME: defer<AttackTimeValidator>(call, props.flAttackTime); break;
- case EAXAUTOWAH_RELEASETIME: defer<ReleaseTimeValidator>(call, props.flReleaseTime); break;
- case EAXAUTOWAH_RESONANCE: defer<ResonanceValidator>(call, props.lResonance); break;
- case EAXAUTOWAH_PEAKLEVEL: defer<PeakLevelValidator>(call, props.lPeakLevel); break;
- default: fail_unknown_property_id();
- }
- }
-
- bool EaxAutoWahEffect::commit_props(const Props& props)
- {
- auto is_dirty = false;
-
- if (props_.flAttackTime != props.flAttackTime)
- {
- is_dirty = true;
- set_efx_attack_time();
- }
-
- if (props_.flReleaseTime != props.flReleaseTime)
- {
- is_dirty = true;
- set_efx_release_time();
- }
-
- if (props_.lResonance != props.lResonance)
- {
- is_dirty = true;
- set_efx_resonance();
- }
-
- if (props_.lPeakLevel != props.lPeakLevel)
- {
- is_dirty = true;
- set_efx_peak_gain();
- }
-
- return is_dirty;
- }
-
- } // namespace
-
- EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call)
- {
- return eax_create_eax4_effect<EaxAutoWahEffect>(call);
- }
-
- #endif // ALSOFT_EAX
|