aboutsummaryrefslogtreecommitdiffstats
path: root/al/effects/distortion.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-03-11 00:16:32 -0800
committerChris Robinson <[email protected]>2023-03-11 00:16:32 -0800
commit1d112eee0fb5bfe358dc9a7627a64679292a3df5 (patch)
tree01ff5a270077d366e46c40778bb74a987107e096 /al/effects/distortion.cpp
parentf85bf6fd98a0a2e6b59912dfe0f27e99d2d98d67 (diff)
Convert the EAX Autowah and Compressor effects
Diffstat (limited to 'al/effects/distortion.cpp')
-rw-r--r--al/effects/distortion.cpp329
1 files changed, 139 insertions, 190 deletions
diff --git a/al/effects/distortion.cpp b/al/effects/distortion.cpp
index 5f1206ab..f91314de 100644
--- a/al/effects/distortion.cpp
+++ b/al/effects/distortion.cpp
@@ -122,235 +122,184 @@ const EffectProps DistortionEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-class EaxDistortionEffectException : public EaxException
-{
-public:
- explicit EaxDistortionEffectException(const char* message)
- : EaxException{"EAX_DISTORTION_EFFECT", message}
- {}
-}; // EaxDistortionEffectException
-
-class EaxDistortionEffect final : public EaxEffect4<EaxDistortionEffectException>
-{
-public:
- EaxDistortionEffect(int eax_version);
-
-private:
- struct EdgeValidator {
- void operator()(float flEdge) const
- {
- eax_validate_range<Exception>(
- "Edge",
- flEdge,
- EAXDISTORTION_MINEDGE,
- EAXDISTORTION_MAXEDGE);
- }
- }; // EdgeValidator
-
- struct GainValidator {
- void operator()(long lGain) const
- {
- eax_validate_range<Exception>(
- "Gain",
- lGain,
- EAXDISTORTION_MINGAIN,
- EAXDISTORTION_MAXGAIN);
- }
- }; // GainValidator
-
- struct LowPassCutOffValidator {
- void operator()(float flLowPassCutOff) const
- {
- eax_validate_range<Exception>(
- "Low-pass Cut-off",
- flLowPassCutOff,
- EAXDISTORTION_MINLOWPASSCUTOFF,
- EAXDISTORTION_MAXLOWPASSCUTOFF);
- }
- }; // LowPassCutOffValidator
-
- struct EqCenterValidator {
- void operator()(float flEQCenter) const
- {
- eax_validate_range<Exception>(
- "EQ Center",
- flEQCenter,
- EAXDISTORTION_MINEQCENTER,
- EAXDISTORTION_MAXEQCENTER);
- }
- }; // EqCenterValidator
-
- struct EqBandwidthValidator {
- void operator()(float flEQBandwidth) const
- {
- eax_validate_range<Exception>(
- "EQ Bandwidth",
- flEQBandwidth,
- EAXDISTORTION_MINEQBANDWIDTH,
- EAXDISTORTION_MAXEQBANDWIDTH);
- }
- }; // EqBandwidthValidator
-
- struct AllValidator {
- void operator()(const EAXDISTORTIONPROPERTIES& all) const
- {
- EdgeValidator{}(all.flEdge);
- GainValidator{}(all.lGain);
- LowPassCutOffValidator{}(all.flLowPassCutOff);
- EqCenterValidator{}(all.flEQCenter);
- EqBandwidthValidator{}(all.flEQBandwidth);
- }
- }; // AllValidator
-
- void set_defaults(Props4& props) override;
-
- void set_efx_edge() noexcept;
- void set_efx_gain() noexcept;
- void set_efx_lowpass_cutoff() noexcept;
- void set_efx_eq_center() noexcept;
- void set_efx_eq_bandwidth() 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;
-}; // EaxDistortionEffect
-
-EaxDistortionEffect::EaxDistortionEffect(int eax_version)
- : EaxEffect4{AL_EFFECT_DISTORTION, eax_version}
-{}
-
-void EaxDistortionEffect::set_defaults(Props4& props)
-{
- props.mType = EaxEffectType::Distortion;
- props.mDistortion.flEdge = EAXDISTORTION_DEFAULTEDGE;
- props.mDistortion.lGain = EAXDISTORTION_DEFAULTGAIN;
- props.mDistortion.flLowPassCutOff = EAXDISTORTION_DEFAULTLOWPASSCUTOFF;
- props.mDistortion.flEQCenter = EAXDISTORTION_DEFAULTEQCENTER;
- props.mDistortion.flEQBandwidth = EAXDISTORTION_DEFAULTEQBANDWIDTH;
-}
-
-void EaxDistortionEffect::set_efx_edge() noexcept
-{
- al_effect_props_.Distortion.Edge = clamp(
- props_.mDistortion.flEdge,
- AL_DISTORTION_MIN_EDGE,
- AL_DISTORTION_MAX_EDGE);
-}
+using DistortionCommitter = EaxCommitter<EaxDistortionCommitter>;
-void EaxDistortionEffect::set_efx_gain() noexcept
-{
- al_effect_props_.Distortion.Gain = clamp(
- level_mb_to_gain(static_cast<float>(props_.mDistortion.lGain)),
- AL_DISTORTION_MIN_GAIN,
- AL_DISTORTION_MAX_GAIN);
-}
-
-void EaxDistortionEffect::set_efx_lowpass_cutoff() noexcept
-{
- al_effect_props_.Distortion.LowpassCutoff = clamp(
- props_.mDistortion.flLowPassCutOff,
- AL_DISTORTION_MIN_LOWPASS_CUTOFF,
- AL_DISTORTION_MAX_LOWPASS_CUTOFF);
-}
+struct EdgeValidator {
+ void operator()(float flEdge) const
+ {
+ eax_validate_range<DistortionCommitter::Exception>(
+ "Edge",
+ flEdge,
+ EAXDISTORTION_MINEDGE,
+ EAXDISTORTION_MAXEDGE);
+ }
+}; // EdgeValidator
-void EaxDistortionEffect::set_efx_eq_center() noexcept
-{
- al_effect_props_.Distortion.EQCenter = clamp(
- props_.mDistortion.flEQCenter,
- AL_DISTORTION_MIN_EQCENTER,
- AL_DISTORTION_MAX_EQCENTER);
-}
+struct GainValidator {
+ void operator()(long lGain) const
+ {
+ eax_validate_range<DistortionCommitter::Exception>(
+ "Gain",
+ lGain,
+ EAXDISTORTION_MINGAIN,
+ EAXDISTORTION_MAXGAIN);
+ }
+}; // GainValidator
-void EaxDistortionEffect::set_efx_eq_bandwidth() noexcept
-{
- al_effect_props_.Distortion.EQBandwidth = clamp(
- props_.mDistortion.flEdge,
- AL_DISTORTION_MIN_EQBANDWIDTH,
- AL_DISTORTION_MAX_EQBANDWIDTH);
-}
+struct LowPassCutOffValidator {
+ void operator()(float flLowPassCutOff) const
+ {
+ eax_validate_range<DistortionCommitter::Exception>(
+ "Low-pass Cut-off",
+ flLowPassCutOff,
+ EAXDISTORTION_MINLOWPASSCUTOFF,
+ EAXDISTORTION_MAXLOWPASSCUTOFF);
+ }
+}; // LowPassCutOffValidator
-void EaxDistortionEffect::set_efx_defaults()
-{
- set_efx_edge();
- set_efx_gain();
- set_efx_lowpass_cutoff();
- set_efx_eq_center();
- set_efx_eq_bandwidth();
-}
+struct EqCenterValidator {
+ void operator()(float flEQCenter) const
+ {
+ eax_validate_range<DistortionCommitter::Exception>(
+ "EQ Center",
+ flEQCenter,
+ EAXDISTORTION_MINEQCENTER,
+ EAXDISTORTION_MAXEQCENTER);
+ }
+}; // EqCenterValidator
-void EaxDistortionEffect::get(const EaxCall& call, const Props4& props)
-{
- switch(call.get_property_id())
+struct EqBandwidthValidator {
+ void operator()(float flEQBandwidth) const
{
- case EAXDISTORTION_NONE: break;
- case EAXDISTORTION_ALLPARAMETERS: call.set_value<Exception>(props.mDistortion); break;
- case EAXDISTORTION_EDGE: call.set_value<Exception>(props.mDistortion.flEdge); break;
- case EAXDISTORTION_GAIN: call.set_value<Exception>(props.mDistortion.lGain); break;
- case EAXDISTORTION_LOWPASSCUTOFF: call.set_value<Exception>(props.mDistortion.flLowPassCutOff); break;
- case EAXDISTORTION_EQCENTER: call.set_value<Exception>(props.mDistortion.flEQCenter); break;
- case EAXDISTORTION_EQBANDWIDTH: call.set_value<Exception>(props.mDistortion.flEQBandwidth); break;
- default: fail_unknown_property_id();
+ eax_validate_range<DistortionCommitter::Exception>(
+ "EQ Bandwidth",
+ flEQBandwidth,
+ EAXDISTORTION_MINEQBANDWIDTH,
+ EAXDISTORTION_MAXEQBANDWIDTH);
}
-}
+}; // EqBandwidthValidator
-void EaxDistortionEffect::set(const EaxCall& call, Props4& props)
-{
- switch(call.get_property_id())
+struct AllValidator {
+ void operator()(const EAXDISTORTIONPROPERTIES& all) const
{
- case EAXDISTORTION_NONE: break;
- case EAXDISTORTION_ALLPARAMETERS: defer<AllValidator>(call, props.mDistortion); break;
- case EAXDISTORTION_EDGE: defer<EdgeValidator>(call, props.mDistortion.flEdge); break;
- case EAXDISTORTION_GAIN: defer<GainValidator>(call, props.mDistortion.lGain); break;
- case EAXDISTORTION_LOWPASSCUTOFF: defer<LowPassCutOffValidator>(call, props.mDistortion.flLowPassCutOff); break;
- case EAXDISTORTION_EQCENTER: defer<EqCenterValidator>(call, props.mDistortion.flEQCenter); break;
- case EAXDISTORTION_EQBANDWIDTH: defer<EqBandwidthValidator>(call, props.mDistortion.flEQBandwidth); break;
- default: fail_unknown_property_id();
+ EdgeValidator{}(all.flEdge);
+ GainValidator{}(all.lGain);
+ LowPassCutOffValidator{}(all.flLowPassCutOff);
+ EqCenterValidator{}(all.flEQCenter);
+ EqBandwidthValidator{}(all.flEQBandwidth);
}
+}; // AllValidator
+
+} // namespace
+
+template<>
+struct DistortionCommitter::Exception : public EaxException {
+ explicit Exception(const char *message) : EaxException{"EAX_DISTORTION_EFFECT", message}
+ { }
+};
+
+template<>
+[[noreturn]] void DistortionCommitter::fail(const char *message)
+{
+ throw Exception{message};
}
-bool EaxDistortionEffect::commit_props(const Props4& props)
+template<>
+bool DistortionCommitter::commit(const EaxEffectProps &props)
{
- auto is_dirty = false;
+ const auto orig = props_;
+ props_ = props;
- if (props_.mDistortion.flEdge != props.mDistortion.flEdge)
+ auto is_dirty = bool{orig.mType != props_.mType};
+ if(props_.mDistortion.flEdge != props.mDistortion.flEdge)
{
is_dirty = true;
- set_efx_edge();
+ al_effect_props_.Distortion.Edge = clamp(
+ props_.mDistortion.flEdge,
+ AL_DISTORTION_MIN_EDGE,
+ AL_DISTORTION_MAX_EDGE);
}
- if (props_.mDistortion.lGain != props.mDistortion.lGain)
+ if(props_.mDistortion.lGain != props.mDistortion.lGain)
{
is_dirty = true;
- set_efx_gain();
+ al_effect_props_.Distortion.Gain = clamp(
+ level_mb_to_gain(static_cast<float>(props_.mDistortion.lGain)),
+ AL_DISTORTION_MIN_GAIN,
+ AL_DISTORTION_MAX_GAIN);
}
- if (props_.mDistortion.flLowPassCutOff != props.mDistortion.flLowPassCutOff)
+ if(props_.mDistortion.flLowPassCutOff != props.mDistortion.flLowPassCutOff)
{
is_dirty = true;
- set_efx_lowpass_cutoff();
+ al_effect_props_.Distortion.LowpassCutoff = clamp(
+ props_.mDistortion.flLowPassCutOff,
+ AL_DISTORTION_MIN_LOWPASS_CUTOFF,
+ AL_DISTORTION_MAX_LOWPASS_CUTOFF);
}
- if (props_.mDistortion.flEQCenter != props.mDistortion.flEQCenter)
+ if(props_.mDistortion.flEQCenter != props.mDistortion.flEQCenter)
{
is_dirty = true;
- set_efx_eq_center();
+ al_effect_props_.Distortion.EQCenter = clamp(
+ props_.mDistortion.flEQCenter,
+ AL_DISTORTION_MIN_EQCENTER,
+ AL_DISTORTION_MAX_EQCENTER);
}
- if (props_.mDistortion.flEQBandwidth != props.mDistortion.flEQBandwidth)
+ if(props_.mDistortion.flEQBandwidth != props.mDistortion.flEQBandwidth)
{
is_dirty = true;
- set_efx_eq_bandwidth();
+ al_effect_props_.Distortion.EQBandwidth = clamp(
+ props_.mDistortion.flEdge,
+ AL_DISTORTION_MIN_EQBANDWIDTH,
+ AL_DISTORTION_MAX_EQBANDWIDTH);
}
return is_dirty;
}
-} // namespace
+template<>
+void DistortionCommitter::SetDefaults(EaxEffectProps &props)
+{
+ props.mType = EaxEffectType::Distortion;
+ props.mDistortion.flEdge = EAXDISTORTION_DEFAULTEDGE;
+ props.mDistortion.lGain = EAXDISTORTION_DEFAULTGAIN;
+ props.mDistortion.flLowPassCutOff = EAXDISTORTION_DEFAULTLOWPASSCUTOFF;
+ props.mDistortion.flEQCenter = EAXDISTORTION_DEFAULTEQCENTER;
+ props.mDistortion.flEQBandwidth = EAXDISTORTION_DEFAULTEQBANDWIDTH;
+}
-EaxEffectUPtr eax_create_eax_distortion_effect(int eax_version)
+template<>
+void DistortionCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
{
- return eax_create_eax4_effect<EaxDistortionEffect>(eax_version);
+ switch(call.get_property_id())
+ {
+ case EAXDISTORTION_NONE: break;
+ case EAXDISTORTION_ALLPARAMETERS: call.set_value<Exception>(props.mDistortion); break;
+ case EAXDISTORTION_EDGE: call.set_value<Exception>(props.mDistortion.flEdge); break;
+ case EAXDISTORTION_GAIN: call.set_value<Exception>(props.mDistortion.lGain); break;
+ case EAXDISTORTION_LOWPASSCUTOFF: call.set_value<Exception>(props.mDistortion.flLowPassCutOff); break;
+ case EAXDISTORTION_EQCENTER: call.set_value<Exception>(props.mDistortion.flEQCenter); break;
+ case EAXDISTORTION_EQBANDWIDTH: call.set_value<Exception>(props.mDistortion.flEQBandwidth); break;
+ default: fail_unknown_property_id();
+ }
+}
+
+template<>
+void DistortionCommitter::Set(const EaxCall &call, EaxEffectProps &props)
+{
+ switch(call.get_property_id())
+ {
+ case EAXDISTORTION_NONE: break;
+ case EAXDISTORTION_ALLPARAMETERS: defer<AllValidator>(call, props.mDistortion); break;
+ case EAXDISTORTION_EDGE: defer<EdgeValidator>(call, props.mDistortion.flEdge); break;
+ case EAXDISTORTION_GAIN: defer<GainValidator>(call, props.mDistortion.lGain); break;
+ case EAXDISTORTION_LOWPASSCUTOFF: defer<LowPassCutOffValidator>(call, props.mDistortion.flLowPassCutOff); break;
+ case EAXDISTORTION_EQCENTER: defer<EqCenterValidator>(call, props.mDistortion.flEQCenter); break;
+ case EAXDISTORTION_EQBANDWIDTH: defer<EqBandwidthValidator>(call, props.mDistortion.flEQBandwidth); break;
+ default: fail_unknown_property_id();
+ }
}
#endif // ALSOFT_EAX