diff options
author | Chris Robinson <[email protected]> | 2023-03-11 16:19:48 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-03-11 16:24:01 -0800 |
commit | 028e7eff52a4d0b7b7c023832d2792bb56fef0d1 (patch) | |
tree | 6a3f5fab8506148f6fe7b8f4bc9c3077295f355c /al/effects/modulator.cpp | |
parent | 96b3d98ac330a29e34f4161f9c0e9d1daa05994e (diff) |
Convert the remaining EAX effects
Diffstat (limited to 'al/effects/modulator.cpp')
-rw-r--r-- | al/effects/modulator.cpp | 248 |
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 |