diff options
Diffstat (limited to 'al/effects/echo.cpp')
-rw-r--r-- | al/effects/echo.cpp | 329 |
1 files changed, 139 insertions, 190 deletions
diff --git a/al/effects/echo.cpp b/al/effects/echo.cpp index 1a89dffb..98fa5541 100644 --- a/al/effects/echo.cpp +++ b/al/effects/echo.cpp @@ -119,235 +119,184 @@ const EffectProps EchoEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { -class EaxEchoEffectException : public EaxException -{ -public: - explicit EaxEchoEffectException(const char* message) - : EaxException{"EAX_ECHO_EFFECT", message} - {} -}; // EaxEchoEffectException - -class EaxEchoEffect final : public EaxEffect4<EaxEchoEffectException> -{ -public: - EaxEchoEffect(int eax_version); - -private: - struct DelayValidator { - void operator()(float flDelay) const - { - eax_validate_range<Exception>( - "Delay", - flDelay, - EAXECHO_MINDELAY, - EAXECHO_MAXDELAY); - } - }; // DelayValidator - - struct LrDelayValidator { - void operator()(float flLRDelay) const - { - eax_validate_range<Exception>( - "LR Delay", - flLRDelay, - EAXECHO_MINLRDELAY, - EAXECHO_MAXLRDELAY); - } - }; // LrDelayValidator - - struct DampingValidator { - void operator()(float flDamping) const - { - eax_validate_range<Exception>( - "Damping", - flDamping, - EAXECHO_MINDAMPING, - EAXECHO_MAXDAMPING); - } - }; // DampingValidator - - struct FeedbackValidator { - void operator()(float flFeedback) const - { - eax_validate_range<Exception>( - "Feedback", - flFeedback, - EAXECHO_MINFEEDBACK, - EAXECHO_MAXFEEDBACK); - } - }; // FeedbackValidator - - struct SpreadValidator { - void operator()(float flSpread) const - { - eax_validate_range<Exception>( - "Spread", - flSpread, - EAXECHO_MINSPREAD, - EAXECHO_MAXSPREAD); - } - }; // SpreadValidator - - struct AllValidator { - void operator()(const EAXECHOPROPERTIES& all) const - { - DelayValidator{}(all.flDelay); - LrDelayValidator{}(all.flLRDelay); - DampingValidator{}(all.flDamping); - FeedbackValidator{}(all.flFeedback); - SpreadValidator{}(all.flSpread); - } - }; // AllValidator - - void set_defaults(Props4& props) override; - - void set_efx_delay() noexcept; - void set_efx_lr_delay() noexcept; - void set_efx_damping() noexcept; - void set_efx_feedback() noexcept; - void set_efx_spread() noexcept; - void set_efx_defaults() override; - - void get(const EaxCall& call, const Props4& props) override; - void set(const EaxCall& call, Props4& props) override; - bool commit_props(const Props4& props) override; -}; // EaxEchoEffect - -EaxEchoEffect::EaxEchoEffect(int eax_version) - : EaxEffect4{AL_EFFECT_ECHO, eax_version} -{} - -void EaxEchoEffect::set_defaults(Props4& props) -{ - props.mType = EaxEffectType::Echo; - props.mEcho.flDelay = EAXECHO_DEFAULTDELAY; - props.mEcho.flLRDelay = EAXECHO_DEFAULTLRDELAY; - props.mEcho.flDamping = EAXECHO_DEFAULTDAMPING; - props.mEcho.flFeedback = EAXECHO_DEFAULTFEEDBACK; - props.mEcho.flSpread = EAXECHO_DEFAULTSPREAD; -} - -void EaxEchoEffect::set_efx_delay() noexcept -{ - al_effect_props_.Echo.Delay = clamp( - props_.mEcho.flDelay, - AL_ECHO_MIN_DELAY, - AL_ECHO_MAX_DELAY); -} +using EchoCommitter = EaxCommitter<EaxEchoCommitter>; -void EaxEchoEffect::set_efx_lr_delay() noexcept -{ - al_effect_props_.Echo.LRDelay = clamp( - props_.mEcho.flLRDelay, - AL_ECHO_MIN_LRDELAY, - AL_ECHO_MAX_LRDELAY); -} - -void EaxEchoEffect::set_efx_damping() noexcept -{ - al_effect_props_.Echo.Damping = clamp( - props_.mEcho.flDamping, - AL_ECHO_MIN_DAMPING, - AL_ECHO_MAX_DAMPING); -} +struct DelayValidator { + void operator()(float flDelay) const + { + eax_validate_range<EchoCommitter::Exception>( + "Delay", + flDelay, + EAXECHO_MINDELAY, + EAXECHO_MAXDELAY); + } +}; // DelayValidator -void EaxEchoEffect::set_efx_feedback() noexcept -{ - al_effect_props_.Echo.Feedback = clamp( - props_.mEcho.flFeedback, - AL_ECHO_MIN_FEEDBACK, - AL_ECHO_MAX_FEEDBACK); -} +struct LrDelayValidator { + void operator()(float flLRDelay) const + { + eax_validate_range<EchoCommitter::Exception>( + "LR Delay", + flLRDelay, + EAXECHO_MINLRDELAY, + EAXECHO_MAXLRDELAY); + } +}; // LrDelayValidator -void EaxEchoEffect::set_efx_spread() noexcept -{ - al_effect_props_.Echo.Spread = clamp( - props_.mEcho.flSpread, - AL_ECHO_MIN_SPREAD, - AL_ECHO_MAX_SPREAD); -} +struct DampingValidator { + void operator()(float flDamping) const + { + eax_validate_range<EchoCommitter::Exception>( + "Damping", + flDamping, + EAXECHO_MINDAMPING, + EAXECHO_MAXDAMPING); + } +}; // DampingValidator -void EaxEchoEffect::set_efx_defaults() -{ - set_efx_delay(); - set_efx_lr_delay(); - set_efx_damping(); - set_efx_feedback(); - set_efx_spread(); -} +struct FeedbackValidator { + void operator()(float flFeedback) const + { + eax_validate_range<EchoCommitter::Exception>( + "Feedback", + flFeedback, + EAXECHO_MINFEEDBACK, + EAXECHO_MAXFEEDBACK); + } +}; // FeedbackValidator -void EaxEchoEffect::get(const EaxCall& call, const Props4& props) -{ - switch(call.get_property_id()) +struct SpreadValidator { + void operator()(float flSpread) const { - case EAXECHO_NONE: break; - case EAXECHO_ALLPARAMETERS: call.set_value<Exception>(props.mEcho); break; - case EAXECHO_DELAY: call.set_value<Exception>(props.mEcho.flDelay); break; - case EAXECHO_LRDELAY: call.set_value<Exception>(props.mEcho.flLRDelay); break; - case EAXECHO_DAMPING: call.set_value<Exception>(props.mEcho.flDamping); break; - case EAXECHO_FEEDBACK: call.set_value<Exception>(props.mEcho.flFeedback); break; - case EAXECHO_SPREAD: call.set_value<Exception>(props.mEcho.flSpread); break; - default: fail_unknown_property_id(); + eax_validate_range<EchoCommitter::Exception>( + "Spread", + flSpread, + EAXECHO_MINSPREAD, + EAXECHO_MAXSPREAD); } -} +}; // SpreadValidator -void EaxEchoEffect::set(const EaxCall& call, Props4& props) -{ - switch(call.get_property_id()) +struct AllValidator { + void operator()(const EAXECHOPROPERTIES& all) const { - case EAXECHO_NONE: break; - case EAXECHO_ALLPARAMETERS: defer<AllValidator>(call, props.mEcho); break; - case EAXECHO_DELAY: defer<DelayValidator>(call, props.mEcho.flDelay); break; - case EAXECHO_LRDELAY: defer<LrDelayValidator>(call, props.mEcho.flLRDelay); break; - case EAXECHO_DAMPING: defer<DampingValidator>(call, props.mEcho.flDamping); break; - case EAXECHO_FEEDBACK: defer<FeedbackValidator>(call, props.mEcho.flFeedback); break; - case EAXECHO_SPREAD: defer<SpreadValidator>(call, props.mEcho.flSpread); break; - default: fail_unknown_property_id(); + DelayValidator{}(all.flDelay); + LrDelayValidator{}(all.flLRDelay); + DampingValidator{}(all.flDamping); + FeedbackValidator{}(all.flFeedback); + SpreadValidator{}(all.flSpread); } +}; // AllValidator + +} // namespace + +template<> +struct EchoCommitter::Exception : public EaxException { + explicit Exception(const char* message) : EaxException{"EAX_ECHO_EFFECT", message} + { } +}; + +template<> +[[noreturn]] void EchoCommitter::fail(const char *message) +{ + throw Exception{message}; } -bool EaxEchoEffect::commit_props(const Props4& props) +template<> +bool EchoCommitter::commit(const EaxEffectProps &props) { - auto is_dirty = false; + const auto orig = props_; + props_ = props; - if (props_.mEcho.flDelay != props.mEcho.flDelay) + auto is_dirty = bool{orig.mType != props_.mType}; + if(props_.mEcho.flDelay != props.mEcho.flDelay) { is_dirty = true; - set_efx_delay(); + al_effect_props_.Echo.Delay = clamp( + props_.mEcho.flDelay, + AL_ECHO_MIN_DELAY, + AL_ECHO_MAX_DELAY); } - if (props_.mEcho.flLRDelay != props.mEcho.flLRDelay) + if(props_.mEcho.flLRDelay != props.mEcho.flLRDelay) { is_dirty = true; - set_efx_lr_delay(); + al_effect_props_.Echo.LRDelay = clamp( + props_.mEcho.flLRDelay, + AL_ECHO_MIN_LRDELAY, + AL_ECHO_MAX_LRDELAY); } - if (props_.mEcho.flDamping != props.mEcho.flDamping) + if(props_.mEcho.flDamping != props.mEcho.flDamping) { is_dirty = true; - set_efx_damping(); + al_effect_props_.Echo.Damping = clamp( + props_.mEcho.flDamping, + AL_ECHO_MIN_DAMPING, + AL_ECHO_MAX_DAMPING); } - if (props_.mEcho.flFeedback != props.mEcho.flFeedback) + if(props_.mEcho.flFeedback != props.mEcho.flFeedback) { is_dirty = true; - set_efx_feedback(); + al_effect_props_.Echo.Feedback = clamp( + props_.mEcho.flFeedback, + AL_ECHO_MIN_FEEDBACK, + AL_ECHO_MAX_FEEDBACK); } - if (props_.mEcho.flSpread != props.mEcho.flSpread) + if(props_.mEcho.flSpread != props.mEcho.flSpread) { is_dirty = true; - set_efx_spread(); + al_effect_props_.Echo.Spread = clamp( + props_.mEcho.flSpread, + AL_ECHO_MIN_SPREAD, + AL_ECHO_MAX_SPREAD); } return is_dirty; } -} // namespace +template<> +void EchoCommitter::SetDefaults(EaxEffectProps &props) +{ + props.mType = EaxEffectType::Echo; + props.mEcho.flDelay = EAXECHO_DEFAULTDELAY; + props.mEcho.flLRDelay = EAXECHO_DEFAULTLRDELAY; + props.mEcho.flDamping = EAXECHO_DEFAULTDAMPING; + props.mEcho.flFeedback = EAXECHO_DEFAULTFEEDBACK; + props.mEcho.flSpread = EAXECHO_DEFAULTSPREAD; +} -EaxEffectUPtr eax_create_eax_echo_effect(int eax_version) +template<> +void EchoCommitter::Get(const EaxCall &call, const EaxEffectProps &props) { - return eax_create_eax4_effect<EaxEchoEffect>(eax_version); + switch(call.get_property_id()) + { + case EAXECHO_NONE: break; + case EAXECHO_ALLPARAMETERS: call.set_value<Exception>(props.mEcho); break; + case EAXECHO_DELAY: call.set_value<Exception>(props.mEcho.flDelay); break; + case EAXECHO_LRDELAY: call.set_value<Exception>(props.mEcho.flLRDelay); break; + case EAXECHO_DAMPING: call.set_value<Exception>(props.mEcho.flDamping); break; + case EAXECHO_FEEDBACK: call.set_value<Exception>(props.mEcho.flFeedback); break; + case EAXECHO_SPREAD: call.set_value<Exception>(props.mEcho.flSpread); break; + default: fail_unknown_property_id(); + } +} + +template<> +void EchoCommitter::Set(const EaxCall &call, EaxEffectProps &props) +{ + switch(call.get_property_id()) + { + case EAXECHO_NONE: break; + case EAXECHO_ALLPARAMETERS: defer<AllValidator>(call, props.mEcho); break; + case EAXECHO_DELAY: defer<DelayValidator>(call, props.mEcho.flDelay); break; + case EAXECHO_LRDELAY: defer<LrDelayValidator>(call, props.mEcho.flLRDelay); break; + case EAXECHO_DAMPING: defer<DampingValidator>(call, props.mEcho.flDamping); break; + case EAXECHO_FEEDBACK: defer<FeedbackValidator>(call, props.mEcho.flFeedback); break; + case EAXECHO_SPREAD: defer<SpreadValidator>(call, props.mEcho.flSpread); break; + default: fail_unknown_property_id(); + } } #endif // ALSOFT_EAX |