aboutsummaryrefslogtreecommitdiffstats
path: root/al/effects/echo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'al/effects/echo.cpp')
-rw-r--r--al/effects/echo.cpp329
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