aboutsummaryrefslogtreecommitdiffstats
path: root/al/effects/modulator.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-03-11 16:19:48 -0800
committerChris Robinson <[email protected]>2023-03-11 16:24:01 -0800
commit028e7eff52a4d0b7b7c023832d2792bb56fef0d1 (patch)
tree6a3f5fab8506148f6fe7b8f4bc9c3077295f355c /al/effects/modulator.cpp
parent96b3d98ac330a29e34f4161f9c0e9d1daa05994e (diff)
Convert the remaining EAX effects
Diffstat (limited to 'al/effects/modulator.cpp')
-rw-r--r--al/effects/modulator.cpp248
1 files changed, 100 insertions, 148 deletions
diff --git a/al/effects/modulator.cpp b/al/effects/modulator.cpp
index f1d01ddc..f3e43c52 100644
--- a/al/effects/modulator.cpp
+++ b/al/effects/modulator.cpp
@@ -145,176 +145,128 @@ const EffectProps ModulatorEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-class EaxRingModulatorEffectException : public EaxException
-{
-public:
- explicit EaxRingModulatorEffectException(const char* message)
- : EaxException{"EAX_RING_MODULATOR_EFFECT", message}
- {}
-}; // EaxRingModulatorEffectException
+using ModulatorCommitter = EaxCommitter<EaxModulatorCommitter>;
-class EaxRingModulatorEffect final : public EaxEffect4<EaxRingModulatorEffectException>
-{
-public:
- EaxRingModulatorEffect(int eax_version);
-
-private:
- struct FrequencyValidator {
- void operator()(float flFrequency) const
- {
- eax_validate_range<EaxRingModulatorEffectException>(
- "Frequency",
- flFrequency,
- EAXRINGMODULATOR_MINFREQUENCY,
- EAXRINGMODULATOR_MAXFREQUENCY);
- }
- }; // FrequencyValidator
-
- struct HighPassCutOffValidator {
- void operator()(float flHighPassCutOff) const
- {
- eax_validate_range<EaxRingModulatorEffectException>(
- "High-Pass Cutoff",
- flHighPassCutOff,
- EAXRINGMODULATOR_MINHIGHPASSCUTOFF,
- EAXRINGMODULATOR_MAXHIGHPASSCUTOFF);
- }
- }; // HighPassCutOffValidator
-
- struct WaveformValidator {
- void operator()(unsigned long ulWaveform) const
- {
- eax_validate_range<EaxRingModulatorEffectException>(
- "Waveform",
- ulWaveform,
- EAXRINGMODULATOR_MINWAVEFORM,
- EAXRINGMODULATOR_MAXWAVEFORM);
- }
- }; // WaveformValidator
-
- struct AllValidator {
- void operator()(const EAXRINGMODULATORPROPERTIES& all) const
- {
- FrequencyValidator{}(all.flFrequency);
- HighPassCutOffValidator{}(all.flHighPassCutOff);
- WaveformValidator{}(all.ulWaveform);
- }
- }; // AllValidator
-
- void set_defaults(Props4& props) override;
-
- void set_efx_frequency() noexcept;
- void set_efx_high_pass_cutoff() noexcept;
- void set_efx_waveform();
- 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;
-}; // EaxRingModulatorEffect
-
-EaxRingModulatorEffect::EaxRingModulatorEffect(int eax_version)
- : EaxEffect4{AL_EFFECT_RING_MODULATOR, eax_version}
-{}
-
-void EaxRingModulatorEffect::set_defaults(Props4& props)
-{
- props.mType = EaxEffectType::Modulator;
- props.mModulator.flFrequency = EAXRINGMODULATOR_DEFAULTFREQUENCY;
- props.mModulator.flHighPassCutOff = EAXRINGMODULATOR_DEFAULTHIGHPASSCUTOFF;
- props.mModulator.ulWaveform = EAXRINGMODULATOR_DEFAULTWAVEFORM;
-}
+struct FrequencyValidator {
+ void operator()(float flFrequency) const
+ {
+ eax_validate_range<ModulatorCommitter::Exception>(
+ "Frequency",
+ flFrequency,
+ EAXRINGMODULATOR_MINFREQUENCY,
+ EAXRINGMODULATOR_MAXFREQUENCY);
+ }
+}; // FrequencyValidator
-void EaxRingModulatorEffect::set_efx_frequency() noexcept
-{
- al_effect_props_.Modulator.Frequency = clamp(
- props_.mModulator.flFrequency,
- AL_RING_MODULATOR_MIN_FREQUENCY,
- AL_RING_MODULATOR_MAX_FREQUENCY);
-}
+struct HighPassCutOffValidator {
+ void operator()(float flHighPassCutOff) const
+ {
+ eax_validate_range<ModulatorCommitter::Exception>(
+ "High-Pass Cutoff",
+ flHighPassCutOff,
+ EAXRINGMODULATOR_MINHIGHPASSCUTOFF,
+ EAXRINGMODULATOR_MAXHIGHPASSCUTOFF);
+ }
+}; // HighPassCutOffValidator
+
+struct WaveformValidator {
+ void operator()(unsigned long ulWaveform) const
+ {
+ eax_validate_range<ModulatorCommitter::Exception>(
+ "Waveform",
+ ulWaveform,
+ EAXRINGMODULATOR_MINWAVEFORM,
+ EAXRINGMODULATOR_MAXWAVEFORM);
+ }
+}; // WaveformValidator
+
+struct AllValidator {
+ void operator()(const EAXRINGMODULATORPROPERTIES& all) const
+ {
+ FrequencyValidator{}(all.flFrequency);
+ HighPassCutOffValidator{}(all.flHighPassCutOff);
+ WaveformValidator{}(all.ulWaveform);
+ }
+}; // AllValidator
+
+} // namespace
+
+template<>
+struct ModulatorCommitter::Exception : public EaxException {
+ explicit Exception(const char *message) : EaxException{"EAX_RING_MODULATOR_EFFECT", message}
+ { }
+};
-void EaxRingModulatorEffect::set_efx_high_pass_cutoff() noexcept
+template<>
+[[noreturn]] void ModulatorCommitter::fail(const char *message)
{
- al_effect_props_.Modulator.HighPassCutoff = clamp(
- props_.mModulator.flHighPassCutOff,
- AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF,
- AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF);
+ throw Exception{message};
}
-void EaxRingModulatorEffect::set_efx_waveform()
+template<>
+bool ModulatorCommitter::commit(const EaxEffectProps &props)
{
- const auto waveform = clamp(
- static_cast<ALint>(props_.mModulator.ulWaveform),
- AL_RING_MODULATOR_MIN_WAVEFORM,
- AL_RING_MODULATOR_MAX_WAVEFORM);
- const auto efx_waveform = WaveformFromEmum(waveform);
- assert(efx_waveform.has_value());
- al_effect_props_.Modulator.Waveform = *efx_waveform;
+ const auto orig = props_;
+ props_ = props;
+
+ if(orig.mType == props_.mType && props_.mModulator.flFrequency == props.mModulator.flFrequency
+ && props_.mModulator.flHighPassCutOff == props.mModulator.flHighPassCutOff
+ && props_.mModulator.ulWaveform == props.mModulator.ulWaveform)
+ return false;
+
+ auto get_waveform = [](unsigned long form)
+ {
+ if(form == EAX_RINGMODULATOR_SINUSOID)
+ return ModulatorWaveform::Sinusoid;
+ if(form == EAX_RINGMODULATOR_SAWTOOTH)
+ return ModulatorWaveform::Sawtooth;
+ if(form == EAX_RINGMODULATOR_SQUARE)
+ return ModulatorWaveform::Square;
+ return ModulatorWaveform::Sinusoid;
+ };
+
+ al_effect_props_.Modulator.Frequency = props_.mModulator.flFrequency;
+ al_effect_props_.Modulator.HighPassCutoff = props_.mModulator.flHighPassCutOff;
+ al_effect_props_.Modulator.Waveform = get_waveform(props_.mModulator.ulWaveform);
+
+ return true;
}
-void EaxRingModulatorEffect::set_efx_defaults()
+template<>
+void ModulatorCommitter::SetDefaults(EaxEffectProps &props)
{
- set_efx_frequency();
- set_efx_high_pass_cutoff();
- set_efx_waveform();
+ props.mType = EaxEffectType::Modulator;
+ props.mModulator.flFrequency = EAXRINGMODULATOR_DEFAULTFREQUENCY;
+ props.mModulator.flHighPassCutOff = EAXRINGMODULATOR_DEFAULTHIGHPASSCUTOFF;
+ props.mModulator.ulWaveform = EAXRINGMODULATOR_DEFAULTWAVEFORM;
}
-void EaxRingModulatorEffect::get(const EaxCall& call, const Props4& props)
+template<>
+void ModulatorCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
{
switch(call.get_property_id())
{
- case EAXRINGMODULATOR_NONE: break;
- case EAXRINGMODULATOR_ALLPARAMETERS: call.set_value<Exception>(props.mModulator); break;
- case EAXRINGMODULATOR_FREQUENCY: call.set_value<Exception>(props.mModulator.flFrequency); break;
- case EAXRINGMODULATOR_HIGHPASSCUTOFF: call.set_value<Exception>(props.mModulator.flHighPassCutOff); break;
- case EAXRINGMODULATOR_WAVEFORM: call.set_value<Exception>(props.mModulator.ulWaveform); break;
- default: fail_unknown_property_id();
+ case EAXRINGMODULATOR_NONE: break;
+ case EAXRINGMODULATOR_ALLPARAMETERS: call.set_value<Exception>(props.mModulator); break;
+ case EAXRINGMODULATOR_FREQUENCY: call.set_value<Exception>(props.mModulator.flFrequency); break;
+ case EAXRINGMODULATOR_HIGHPASSCUTOFF: call.set_value<Exception>(props.mModulator.flHighPassCutOff); break;
+ case EAXRINGMODULATOR_WAVEFORM: call.set_value<Exception>(props.mModulator.ulWaveform); break;
+ default: fail_unknown_property_id();
}
}
-void EaxRingModulatorEffect::set(const EaxCall& call, Props4& props)
+template<>
+void ModulatorCommitter::Set(const EaxCall &call, EaxEffectProps &props)
{
switch (call.get_property_id())
{
- case EAXRINGMODULATOR_NONE: break;
- case EAXRINGMODULATOR_ALLPARAMETERS: defer<AllValidator>(call, props.mModulator); break;
- case EAXRINGMODULATOR_FREQUENCY: defer<FrequencyValidator>(call, props.mModulator.flFrequency); break;
- case EAXRINGMODULATOR_HIGHPASSCUTOFF: defer<HighPassCutOffValidator>(call, props.mModulator.flHighPassCutOff); break;
- case EAXRINGMODULATOR_WAVEFORM: defer<WaveformValidator>(call, props.mModulator.ulWaveform); break;
- default: fail_unknown_property_id();
- }
-}
-
-bool EaxRingModulatorEffect::commit_props(const Props4& props)
-{
- auto is_dirty = false;
-
- if (props_.mModulator.flFrequency != props.mModulator.flFrequency)
- {
- is_dirty = true;
- set_efx_frequency();
+ case EAXRINGMODULATOR_NONE: break;
+ case EAXRINGMODULATOR_ALLPARAMETERS: defer<AllValidator>(call, props.mModulator); break;
+ case EAXRINGMODULATOR_FREQUENCY: defer<FrequencyValidator>(call, props.mModulator.flFrequency); break;
+ case EAXRINGMODULATOR_HIGHPASSCUTOFF: defer<HighPassCutOffValidator>(call, props.mModulator.flHighPassCutOff); break;
+ case EAXRINGMODULATOR_WAVEFORM: defer<WaveformValidator>(call, props.mModulator.ulWaveform); break;
+ default: fail_unknown_property_id();
}
-
- if (props_.mModulator.flHighPassCutOff != props.mModulator.flHighPassCutOff)
- {
- is_dirty = true;
- set_efx_high_pass_cutoff();
- }
-
- if (props_.mModulator.ulWaveform != props.mModulator.ulWaveform)
- {
- is_dirty = true;
- set_efx_waveform();
- }
-
- return is_dirty;
-}
-
-} // namespace
-
-EaxEffectUPtr eax_create_eax_ring_modulator_effect(int eax_version)
-{
- return eax_create_eax4_effect<EaxRingModulatorEffect>(eax_version);
}
#endif // ALSOFT_EAX