aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/auxeffectslot.h4
-rw-r--r--al/eax/effect.h137
-rw-r--r--al/effects/modulator.cpp248
-rw-r--r--al/effects/pshifter.cpp190
-rw-r--r--al/effects/vmorpher.cpp480
5 files changed, 410 insertions, 649 deletions
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 999ea102..3e9a2a4e 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -139,11 +139,11 @@ private:
guidLoadEffect != EAX_DISTORTION_EFFECT &&
guidLoadEffect != EAX_ECHO_EFFECT &&
guidLoadEffect != EAX_EQUALIZER_EFFECT &&
- guidLoadEffect != EAX_FLANGER_EFFECT /*&&
+ guidLoadEffect != EAX_FLANGER_EFFECT &&
guidLoadEffect != EAX_FREQUENCYSHIFTER_EFFECT &&
guidLoadEffect != EAX_VOCALMORPHER_EFFECT &&
guidLoadEffect != EAX_PITCHSHIFTER_EFFECT &&
- guidLoadEffect != EAX_RINGMODULATOR_EFFECT*/)
+ guidLoadEffect != EAX_RINGMODULATOR_EFFECT)
{
eax_fail_unknown_effect_id();
}
diff --git a/al/eax/effect.h b/al/eax/effect.h
index 6e5a0553..2de768b7 100644
--- a/al/eax/effect.h
+++ b/al/eax/effect.h
@@ -189,6 +189,15 @@ struct EaxFlangerCommitter : public EaxCommitter<EaxFlangerCommitter> {
struct EaxFrequencyShifterCommitter : public EaxCommitter<EaxFrequencyShifterCommitter> {
using EaxCommitter<EaxFrequencyShifterCommitter>::EaxCommitter;
};
+struct EaxModulatorCommitter : public EaxCommitter<EaxModulatorCommitter> {
+ using EaxCommitter<EaxModulatorCommitter>::EaxCommitter;
+};
+struct EaxPitchShifterCommitter : public EaxCommitter<EaxPitchShifterCommitter> {
+ using EaxCommitter<EaxPitchShifterCommitter>::EaxCommitter;
+};
+struct EaxVocalMorpherCommitter : public EaxCommitter<EaxVocalMorpherCommitter> {
+ using EaxCommitter<EaxVocalMorpherCommitter>::EaxCommitter;
+};
struct EaxNullCommitter : public EaxCommitter<EaxNullCommitter> {
using EaxCommitter<EaxNullCommitter>::EaxCommitter;
};
@@ -197,7 +206,7 @@ struct EaxNullCommitter : public EaxCommitter<EaxNullCommitter> {
class EaxEffect {
public:
EaxEffect() noexcept = default;
- virtual ~EaxEffect() = default;
+ ~EaxEffect() = default;
ALenum al_effect_type_{AL_EFFECT_NULL};
EffectProps al_effect_props_{};
@@ -236,10 +245,6 @@ public:
State4 state4_{};
State4 state5_{};
- [[deprecated]] virtual void dispatch(const EaxCall& /*call*/) { }
-
- // Returns "true" if any immediated property was changed.
- /*[[nodiscard]]*/ [[deprecated]] virtual bool commit() { return false; }
template<typename T, typename ...Args>
void call_set_defaults(Args&& ...args)
@@ -265,6 +270,12 @@ public:
return call_set_defaults<EaxFlangerCommitter>(props);
if(altype == AL_EFFECT_FREQUENCY_SHIFTER)
return call_set_defaults<EaxFrequencyShifterCommitter>(props);
+ if(altype == AL_EFFECT_RING_MODULATOR)
+ return call_set_defaults<EaxModulatorCommitter>(props);
+ if(altype == AL_EFFECT_PITCH_SHIFTER)
+ return call_set_defaults<EaxPitchShifterCommitter>(props);
+ if(altype == AL_EFFECT_VOCAL_MORPHER)
+ return call_set_defaults<EaxVocalMorpherCommitter>(props);
return call_set_defaults<EaxNullCommitter>(props);
}
@@ -316,6 +327,12 @@ public:
return Callable<EaxFlangerCommitter>(__VA_ARGS__); \
if(T == EaxEffectType::FrequencyShifter) \
return Callable<EaxFrequencyShifterCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::Modulator) \
+ return Callable<EaxModulatorCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::PitchShifter) \
+ return Callable<EaxPitchShifterCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::VocalMorpher) \
+ return Callable<EaxVocalMorpherCommitter>(__VA_ARGS__); \
return Callable<EaxNullCommitter>(__VA_ARGS__)
template<typename T, typename ...Args>
@@ -404,116 +421,6 @@ public:
#undef EAXCALL
}; // EaxEffect
-// Base class for EAX4+ effects.
-template<typename TException>
-class EaxEffect4 : public EaxEffect
-{
-public:
- EaxEffect4(ALenum, int) { }
-
- void initialize()
- {
- set_defaults();
- set_efx_defaults();
- }
-
- void dispatch(const EaxCall& call) override
- { call.is_get() ? get(call) : set(call); }
-
- bool commit() final
- {
- switch (version_)
- {
- case 4: return commit_state(state4_);
- case 5: return commit_state(state5_);
- default: fail_unknown_version();
- }
- }
-
-protected:
- using Exception = TException;
-
- template<typename TValidator, typename TProperty>
- static void defer(const EaxCall& call, TProperty& property)
- {
- const auto& value = call.get_value<Exception, const TProperty>();
- TValidator{}(value);
- property = value;
- }
-
- virtual void set_defaults(Props4& props) = 0;
- virtual void set_efx_defaults() = 0;
-
- virtual void get(const EaxCall& call, const Props4& props) = 0;
- virtual void set(const EaxCall& call, Props4& props) = 0;
-
- virtual bool commit_props(const Props4& props) = 0;
-
- [[noreturn]] static void fail(const char* message)
- {
- throw Exception{message};
- }
-
- [[noreturn]] static void fail_unknown_property_id()
- {
- fail(EaxEffectErrorMessages::unknown_property_id());
- }
-
- [[noreturn]] static void fail_unknown_version()
- {
- fail(EaxEffectErrorMessages::unknown_version());
- }
-
-private:
- void set_defaults()
- {
- set_defaults(props_);
- state4_.i = props_;
- state4_.d = props_;
- state5_.i = props_;
- state5_.d = props_;
- }
-
- void get(const EaxCall& call)
- {
- switch (call.get_version())
- {
- case 4: get(call, state4_.i); break;
- case 5: get(call, state5_.i); break;
- default: fail_unknown_version();
- }
- }
-
- void set(const EaxCall& call)
- {
- const auto version = call.get_version();
- switch (version)
- {
- case 4: set(call, state4_.d); break;
- case 5: set(call, state5_.d); break;
- default: fail_unknown_version();
- }
- version_ = version;
- }
-
- bool commit_state(State4& state)
- {
- const auto props = props_;
- state.i = state.d;
- props_ = state.d;
- return commit_props(props);
- }
-}; // EaxEffect4
-
using EaxEffectUPtr = std::unique_ptr<EaxEffect>;
-// Creates EAX4+ effect.
-template<typename TEffect>
-EaxEffectUPtr eax_create_eax4_effect(int eax_version)
-{
- auto effect = std::make_unique<TEffect>(eax_version);
- effect->initialize();
- return effect;
-}
-
#endif // !EAX_EFFECT_INCLUDED
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
diff --git a/al/effects/pshifter.cpp b/al/effects/pshifter.cpp
index 524585a2..53115edb 100644
--- a/al/effects/pshifter.cpp
+++ b/al/effects/pshifter.cpp
@@ -92,141 +92,101 @@ const EffectProps PshifterEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-class EaxPitchShifterEffectException : public EaxException
-{
-public:
- explicit EaxPitchShifterEffectException(const char* message)
- : EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
- {}
-}; // EaxPitchShifterEffectException
-
-class EaxPitchShifterEffect final : public EaxEffect4<EaxPitchShifterEffectException> {
-public:
- EaxPitchShifterEffect(int eax_version);
-
-private:
- struct CoarseTuneValidator {
- void operator()(long lCoarseTune) const
- {
- eax_validate_range<Exception>(
- "Coarse Tune",
- lCoarseTune,
- EAXPITCHSHIFTER_MINCOARSETUNE,
- EAXPITCHSHIFTER_MAXCOARSETUNE);
- }
- }; // CoarseTuneValidator
-
- struct FineTuneValidator {
- void operator()(long lFineTune) const
- {
- eax_validate_range<Exception>(
- "Fine Tune",
- lFineTune,
- EAXPITCHSHIFTER_MINFINETUNE,
- EAXPITCHSHIFTER_MAXFINETUNE);
- }
- }; // FineTuneValidator
-
- struct AllValidator {
- void operator()(const EAXPITCHSHIFTERPROPERTIES& all) const
- {
- CoarseTuneValidator{}(all.lCoarseTune);
- FineTuneValidator{}(all.lFineTune);
- }
- }; // AllValidator
-
- void set_defaults(Props4& props) override;
-
- void set_efx_coarse_tune() noexcept;
- void set_efx_fine_tune() 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& old_i) override;
-}; // EaxPitchShifterEffect
-
-EaxPitchShifterEffect::EaxPitchShifterEffect(int eax_version)
- : EaxEffect4{AL_EFFECT_PITCH_SHIFTER, eax_version}
-{}
-
-void EaxPitchShifterEffect::set_defaults(Props4& props)
-{
- props.mType = EaxEffectType::PitchShifter;
- props.mPitchShifter.lCoarseTune = EAXPITCHSHIFTER_DEFAULTCOARSETUNE;
- props.mPitchShifter.lFineTune = EAXPITCHSHIFTER_DEFAULTFINETUNE;
-}
+using PitchShifterCommitter = EaxCommitter<EaxPitchShifterCommitter>;
-void EaxPitchShifterEffect::set_efx_coarse_tune() noexcept
-{
- al_effect_props_.Pshifter.CoarseTune = clamp(
- static_cast<ALint>(props_.mPitchShifter.lCoarseTune),
- AL_PITCH_SHIFTER_MIN_COARSE_TUNE,
- AL_PITCH_SHIFTER_MAX_COARSE_TUNE);
-}
+struct CoarseTuneValidator {
+ void operator()(long lCoarseTune) const
+ {
+ eax_validate_range<PitchShifterCommitter::Exception>(
+ "Coarse Tune",
+ lCoarseTune,
+ EAXPITCHSHIFTER_MINCOARSETUNE,
+ EAXPITCHSHIFTER_MAXCOARSETUNE);
+ }
+}; // CoarseTuneValidator
-void EaxPitchShifterEffect::set_efx_fine_tune() noexcept
+struct FineTuneValidator {
+ void operator()(long lFineTune) const
+ {
+ eax_validate_range<PitchShifterCommitter::Exception>(
+ "Fine Tune",
+ lFineTune,
+ EAXPITCHSHIFTER_MINFINETUNE,
+ EAXPITCHSHIFTER_MAXFINETUNE);
+ }
+}; // FineTuneValidator
+
+struct AllValidator {
+ void operator()(const EAXPITCHSHIFTERPROPERTIES& all) const
+ {
+ CoarseTuneValidator{}(all.lCoarseTune);
+ FineTuneValidator{}(all.lFineTune);
+ }
+}; // AllValidator
+
+} // namespace
+
+template<>
+struct PitchShifterCommitter::Exception : public EaxException {
+ explicit Exception(const char *message) : EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
+ { }
+};
+
+template<>
+[[noreturn]] void PitchShifterCommitter::fail(const char *message)
{
- al_effect_props_.Pshifter.FineTune = clamp(
- static_cast<ALint>(props_.mPitchShifter.lFineTune),
- AL_PITCH_SHIFTER_MIN_FINE_TUNE,
- AL_PITCH_SHIFTER_MAX_FINE_TUNE);
+ throw Exception{message};
}
-void EaxPitchShifterEffect::set_efx_defaults()
+template<>
+bool PitchShifterCommitter::commit(const EaxEffectProps &props)
{
- set_efx_coarse_tune();
- set_efx_fine_tune();
+ const auto orig = props_;
+ props_ = props;
+
+ if(orig.mType == props_.mType
+ && props_.mPitchShifter.lCoarseTune == props.mPitchShifter.lCoarseTune
+ && props_.mPitchShifter.lFineTune == props.mPitchShifter.lFineTune)
+ return false;
+
+ al_effect_props_.Pshifter.CoarseTune = static_cast<ALint>(props_.mPitchShifter.lCoarseTune);
+ al_effect_props_.Pshifter.FineTune = static_cast<ALint>(props_.mPitchShifter.lFineTune);
+
+ return true;
}
-void EaxPitchShifterEffect::get(const EaxCall& call, const Props4& props)
+template<>
+void PitchShifterCommitter::SetDefaults(EaxEffectProps &props)
{
- switch(call.get_property_id())
- {
- case EAXPITCHSHIFTER_NONE: break;
- case EAXPITCHSHIFTER_ALLPARAMETERS: call.set_value<Exception>(props.mPitchShifter); break;
- case EAXPITCHSHIFTER_COARSETUNE: call.set_value<Exception>(props.mPitchShifter.lCoarseTune); break;
- case EAXPITCHSHIFTER_FINETUNE: call.set_value<Exception>(props.mPitchShifter.lFineTune); break;
- default: fail_unknown_property_id();
- }
+ props.mType = EaxEffectType::PitchShifter;
+ props.mPitchShifter.lCoarseTune = EAXPITCHSHIFTER_DEFAULTCOARSETUNE;
+ props.mPitchShifter.lFineTune = EAXPITCHSHIFTER_DEFAULTFINETUNE;
}
-void EaxPitchShifterEffect::set(const EaxCall& call, Props4& props)
+template<>
+void PitchShifterCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
{
switch(call.get_property_id())
{
- case EAXPITCHSHIFTER_NONE: break;
- case EAXPITCHSHIFTER_ALLPARAMETERS: defer<AllValidator>(call, props.mPitchShifter); break;
- case EAXPITCHSHIFTER_COARSETUNE: defer<CoarseTuneValidator>(call, props.mPitchShifter.lCoarseTune); break;
- case EAXPITCHSHIFTER_FINETUNE: defer<FineTuneValidator>(call, props.mPitchShifter.lFineTune); break;
- default: fail_unknown_property_id();
+ case EAXPITCHSHIFTER_NONE: break;
+ case EAXPITCHSHIFTER_ALLPARAMETERS: call.set_value<Exception>(props.mPitchShifter); break;
+ case EAXPITCHSHIFTER_COARSETUNE: call.set_value<Exception>(props.mPitchShifter.lCoarseTune); break;
+ case EAXPITCHSHIFTER_FINETUNE: call.set_value<Exception>(props.mPitchShifter.lFineTune); break;
+ default: fail_unknown_property_id();
}
}
-bool EaxPitchShifterEffect::commit_props(const Props4& props)
+template<>
+void PitchShifterCommitter::Set(const EaxCall &call, EaxEffectProps &props)
{
- auto is_dirty = false;
-
- if (props_.mPitchShifter.lCoarseTune != props.mPitchShifter.lCoarseTune)
- {
- is_dirty = true;
- set_efx_coarse_tune();
- }
-
- if (props_.mPitchShifter.lFineTune != props.mPitchShifter.lFineTune)
+ switch(call.get_property_id())
{
- is_dirty = true;
- set_efx_fine_tune();
+ case EAXPITCHSHIFTER_NONE: break;
+ case EAXPITCHSHIFTER_ALLPARAMETERS: defer<AllValidator>(call, props.mPitchShifter); break;
+ case EAXPITCHSHIFTER_COARSETUNE: defer<CoarseTuneValidator>(call, props.mPitchShifter.lCoarseTune); break;
+ case EAXPITCHSHIFTER_FINETUNE: defer<FineTuneValidator>(call, props.mPitchShifter.lFineTune); break;
+ default: fail_unknown_property_id();
}
-
- return is_dirty;
-}
-
-} // namespace
-
-EaxEffectUPtr eax_create_eax_pitch_shifter_effect(int eax_version)
-{
- return eax_create_eax4_effect<EaxPitchShifterEffect>(eax_version);
}
#endif // ALSOFT_EAX
diff --git a/al/effects/vmorpher.cpp b/al/effects/vmorpher.cpp
index d8d74b94..f8be5856 100644
--- a/al/effects/vmorpher.cpp
+++ b/al/effects/vmorpher.cpp
@@ -258,116 +258,174 @@ const EffectProps VmorpherEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-class EaxVocalMorpherEffectException : public EaxException {
-public:
- explicit EaxVocalMorpherEffectException(const char* message)
- : EaxException{"EAX_VOCAL_MORPHER_EFFECT", message}
- {}
-}; // EaxVocalMorpherEffectException
-
-class EaxVocalMorpherEffect final : public EaxEffect4<EaxVocalMorpherEffectException> {
-public:
- EaxVocalMorpherEffect(int eax_version);
-
-private:
- struct PhonemeAValidator {
- void operator()(unsigned long ulPhonemeA) const
- {
- eax_validate_range<Exception>(
- "Phoneme A",
- ulPhonemeA,
- EAXVOCALMORPHER_MINPHONEMEA,
- EAXVOCALMORPHER_MAXPHONEMEA);
- }
- }; // PhonemeAValidator
+using VocalMorpherCommitter = EaxCommitter<EaxVocalMorpherCommitter>;
- struct PhonemeACoarseTuningValidator {
- void operator()(long lPhonemeACoarseTuning) const
- {
- eax_validate_range<Exception>(
- "Phoneme A Coarse Tuning",
- lPhonemeACoarseTuning,
- EAXVOCALMORPHER_MINPHONEMEACOARSETUNING,
- EAXVOCALMORPHER_MAXPHONEMEACOARSETUNING);
- }
- }; // PhonemeACoarseTuningValidator
+struct PhonemeAValidator {
+ void operator()(unsigned long ulPhonemeA) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Phoneme A",
+ ulPhonemeA,
+ EAXVOCALMORPHER_MINPHONEMEA,
+ EAXVOCALMORPHER_MAXPHONEMEA);
+ }
+}; // PhonemeAValidator
- struct PhonemeBValidator {
- void operator()(unsigned long ulPhonemeB) const
- {
- eax_validate_range<Exception>(
- "Phoneme B",
- ulPhonemeB,
- EAXVOCALMORPHER_MINPHONEMEB,
- EAXVOCALMORPHER_MAXPHONEMEB);
- }
- }; // PhonemeBValidator
+struct PhonemeACoarseTuningValidator {
+ void operator()(long lPhonemeACoarseTuning) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Phoneme A Coarse Tuning",
+ lPhonemeACoarseTuning,
+ EAXVOCALMORPHER_MINPHONEMEACOARSETUNING,
+ EAXVOCALMORPHER_MAXPHONEMEACOARSETUNING);
+ }
+}; // PhonemeACoarseTuningValidator
- struct PhonemeBCoarseTuningValidator {
- void operator()(long lPhonemeBCoarseTuning) const
- {
- eax_validate_range<Exception>(
- "Phoneme B Coarse Tuning",
- lPhonemeBCoarseTuning,
- EAXVOCALMORPHER_MINPHONEMEBCOARSETUNING,
- EAXVOCALMORPHER_MAXPHONEMEBCOARSETUNING);
- }
- }; // PhonemeBCoarseTuningValidator
+struct PhonemeBValidator {
+ void operator()(unsigned long ulPhonemeB) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Phoneme B",
+ ulPhonemeB,
+ EAXVOCALMORPHER_MINPHONEMEB,
+ EAXVOCALMORPHER_MAXPHONEMEB);
+ }
+}; // PhonemeBValidator
- struct WaveformValidator {
- void operator()(unsigned long ulWaveform) const
- {
- eax_validate_range<Exception>(
- "Waveform",
- ulWaveform,
- EAXVOCALMORPHER_MINWAVEFORM,
- EAXVOCALMORPHER_MAXWAVEFORM);
- }
- }; // WaveformValidator
+struct PhonemeBCoarseTuningValidator {
+ void operator()(long lPhonemeBCoarseTuning) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Phoneme B Coarse Tuning",
+ lPhonemeBCoarseTuning,
+ EAXVOCALMORPHER_MINPHONEMEBCOARSETUNING,
+ EAXVOCALMORPHER_MAXPHONEMEBCOARSETUNING);
+ }
+}; // PhonemeBCoarseTuningValidator
- struct RateValidator {
- void operator()(float flRate) const
- {
- eax_validate_range<Exception>(
- "Rate",
- flRate,
- EAXVOCALMORPHER_MINRATE,
- EAXVOCALMORPHER_MAXRATE);
- }
- }; // RateValidator
+struct WaveformValidator {
+ void operator()(unsigned long ulWaveform) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Waveform",
+ ulWaveform,
+ EAXVOCALMORPHER_MINWAVEFORM,
+ EAXVOCALMORPHER_MAXWAVEFORM);
+ }
+}; // WaveformValidator
- struct AllValidator {
- void operator()(const EAXVOCALMORPHERPROPERTIES& all) const
- {
- PhonemeAValidator{}(all.ulPhonemeA);
- PhonemeACoarseTuningValidator{}(all.lPhonemeACoarseTuning);
- PhonemeBValidator{}(all.ulPhonemeB);
- PhonemeBCoarseTuningValidator{}(all.lPhonemeBCoarseTuning);
- WaveformValidator{}(all.ulWaveform);
- RateValidator{}(all.flRate);
- }
- }; // AllValidator
+struct RateValidator {
+ void operator()(float flRate) const
+ {
+ eax_validate_range<VocalMorpherCommitter::Exception>(
+ "Rate",
+ flRate,
+ EAXVOCALMORPHER_MINRATE,
+ EAXVOCALMORPHER_MAXRATE);
+ }
+}; // RateValidator
- void set_defaults(Props4& props) override;
+struct AllValidator {
+ void operator()(const EAXVOCALMORPHERPROPERTIES& all) const
+ {
+ PhonemeAValidator{}(all.ulPhonemeA);
+ PhonemeACoarseTuningValidator{}(all.lPhonemeACoarseTuning);
+ PhonemeBValidator{}(all.ulPhonemeB);
+ PhonemeBCoarseTuningValidator{}(all.lPhonemeBCoarseTuning);
+ WaveformValidator{}(all.ulWaveform);
+ RateValidator{}(all.flRate);
+ }
+}; // AllValidator
- void set_efx_phoneme_a();
- void set_efx_phoneme_a_coarse_tuning() noexcept;
- void set_efx_phoneme_b();
- void set_efx_phoneme_b_coarse_tuning() noexcept;
- void set_efx_waveform();
- void set_efx_rate() noexcept;
- void set_efx_defaults() override;
+} // namespace
- void get(const EaxCall& call, const Props4& props) override;
- void set(const EaxCall& call, Props4& props) override;
- bool commit_props(const Props4& props) override;
-}; // EaxVocalMorpherEffect
+template<>
+struct VocalMorpherCommitter::Exception : public EaxException {
+ explicit Exception(const char *message) : EaxException{"EAX_VOCAL_MORPHER_EFFECT", message}
+ { }
+};
-EaxVocalMorpherEffect::EaxVocalMorpherEffect(int eax_version)
- : EaxEffect4{AL_EFFECT_VOCAL_MORPHER, eax_version}
-{}
+template<>
+[[noreturn]] void VocalMorpherCommitter::fail(const char *message)
+{
+ throw Exception{message};
+}
-void EaxVocalMorpherEffect::set_defaults(Props4& props)
+template<>
+bool VocalMorpherCommitter::commit(const EaxEffectProps &props)
+{
+ const auto orig = props_;
+ props_ = props;
+
+ if(orig.mType == props_.mType
+ && props_.mVocalMorpher.ulPhonemeA == props.mVocalMorpher.ulPhonemeA
+ && props_.mVocalMorpher.lPhonemeACoarseTuning == props.mVocalMorpher.lPhonemeACoarseTuning
+ && props_.mVocalMorpher.ulPhonemeB == props.mVocalMorpher.ulPhonemeB
+ && props_.mVocalMorpher.lPhonemeBCoarseTuning == props.mVocalMorpher.lPhonemeBCoarseTuning
+ && props_.mVocalMorpher.ulWaveform == props.mVocalMorpher.ulWaveform
+ && props_.mVocalMorpher.flRate == props.mVocalMorpher.flRate)
+ return false;
+
+ auto get_phoneme = [](unsigned long phoneme) noexcept
+ {
+#define HANDLE_PHENOME(x) case x: return VMorpherPhenome::x
+ switch(phoneme)
+ {
+ HANDLE_PHENOME(A);
+ HANDLE_PHENOME(E);
+ HANDLE_PHENOME(I);
+ HANDLE_PHENOME(O);
+ HANDLE_PHENOME(U);
+ HANDLE_PHENOME(AA);
+ HANDLE_PHENOME(AE);
+ HANDLE_PHENOME(AH);
+ HANDLE_PHENOME(AO);
+ HANDLE_PHENOME(EH);
+ HANDLE_PHENOME(ER);
+ HANDLE_PHENOME(IH);
+ HANDLE_PHENOME(IY);
+ HANDLE_PHENOME(UH);
+ HANDLE_PHENOME(UW);
+ HANDLE_PHENOME(B);
+ HANDLE_PHENOME(D);
+ HANDLE_PHENOME(F);
+ HANDLE_PHENOME(G);
+ HANDLE_PHENOME(J);
+ HANDLE_PHENOME(K);
+ HANDLE_PHENOME(L);
+ HANDLE_PHENOME(M);
+ HANDLE_PHENOME(N);
+ HANDLE_PHENOME(P);
+ HANDLE_PHENOME(R);
+ HANDLE_PHENOME(S);
+ HANDLE_PHENOME(T);
+ HANDLE_PHENOME(V);
+ HANDLE_PHENOME(Z);
+ }
+ return VMorpherPhenome::A;
+#undef HANDLE_PHENOME
+ };
+ auto get_waveform = [](unsigned long form) noexcept
+ {
+ if(form == EAX_VOCALMORPHER_SINUSOID) return VMorpherWaveform::Sinusoid;
+ if(form == EAX_VOCALMORPHER_TRIANGLE) return VMorpherWaveform::Triangle;
+ if(form == EAX_VOCALMORPHER_SAWTOOTH) return VMorpherWaveform::Sawtooth;
+ return VMorpherWaveform::Sinusoid;
+ };
+
+ al_effect_props_.Vmorpher.PhonemeA = get_phoneme(props_.mVocalMorpher.ulPhonemeA);
+ al_effect_props_.Vmorpher.PhonemeACoarseTuning = static_cast<ALint>(props_.mVocalMorpher.lPhonemeACoarseTuning);
+ al_effect_props_.Vmorpher.PhonemeB = get_phoneme(props_.mVocalMorpher.ulPhonemeB);
+ al_effect_props_.Vmorpher.PhonemeBCoarseTuning = static_cast<ALint>(props_.mVocalMorpher.lPhonemeBCoarseTuning);
+ al_effect_props_.Vmorpher.Waveform = get_waveform(props_.mVocalMorpher.ulWaveform);
+ al_effect_props_.Vmorpher.Rate = props_.mVocalMorpher.flRate;
+
+ return true;
+}
+
+template<>
+void VocalMorpherCommitter::SetDefaults(EaxEffectProps &props)
{
props.mType = EaxEffectType::VocalMorpher;
props.mVocalMorpher.ulPhonemeA = EAXVOCALMORPHER_DEFAULTPHONEMEA;
@@ -378,202 +436,86 @@ void EaxVocalMorpherEffect::set_defaults(Props4& props)
props.mVocalMorpher.flRate = EAXVOCALMORPHER_DEFAULTRATE;
}
-void EaxVocalMorpherEffect::set_efx_phoneme_a()
-{
- const auto phoneme_a = clamp(
- static_cast<ALint>(props_.mVocalMorpher.ulPhonemeA),
- AL_VOCAL_MORPHER_MIN_PHONEMEA,
- AL_VOCAL_MORPHER_MAX_PHONEMEA);
- const auto efx_phoneme_a = PhenomeFromEnum(phoneme_a);
- assert(efx_phoneme_a.has_value());
- al_effect_props_.Vmorpher.PhonemeA = *efx_phoneme_a;
-}
-
-void EaxVocalMorpherEffect::set_efx_phoneme_a_coarse_tuning() noexcept
-{
- const auto phoneme_a_coarse_tuning = clamp(
- static_cast<ALint>(props_.mVocalMorpher.lPhonemeACoarseTuning),
- AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING,
- AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING);
- al_effect_props_.Vmorpher.PhonemeACoarseTuning = phoneme_a_coarse_tuning;
-}
-
-void EaxVocalMorpherEffect::set_efx_phoneme_b()
-{
- const auto phoneme_b = clamp(
- static_cast<ALint>(props_.mVocalMorpher.ulPhonemeB),
- AL_VOCAL_MORPHER_MIN_PHONEMEB,
- AL_VOCAL_MORPHER_MAX_PHONEMEB);
- const auto efx_phoneme_b = PhenomeFromEnum(phoneme_b);
- assert(efx_phoneme_b.has_value());
- al_effect_props_.Vmorpher.PhonemeB = *efx_phoneme_b;
-}
-
-void EaxVocalMorpherEffect::set_efx_phoneme_b_coarse_tuning() noexcept
-{
- al_effect_props_.Vmorpher.PhonemeBCoarseTuning = clamp(
- static_cast<ALint>(props_.mVocalMorpher.lPhonemeBCoarseTuning),
- AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING,
- AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING);
-}
-
-void EaxVocalMorpherEffect::set_efx_waveform()
-{
- const auto waveform = clamp(
- static_cast<ALint>(props_.mVocalMorpher.ulWaveform),
- AL_VOCAL_MORPHER_MIN_WAVEFORM,
- AL_VOCAL_MORPHER_MAX_WAVEFORM);
- const auto wfx_waveform = WaveformFromEmum(waveform);
- assert(wfx_waveform.has_value());
- al_effect_props_.Vmorpher.Waveform = *wfx_waveform;
-}
-
-void EaxVocalMorpherEffect::set_efx_rate() noexcept
-{
- al_effect_props_.Vmorpher.Rate = clamp(
- props_.mVocalMorpher.flRate,
- AL_VOCAL_MORPHER_MIN_RATE,
- AL_VOCAL_MORPHER_MAX_RATE);
-}
-
-void EaxVocalMorpherEffect::set_efx_defaults()
-{
- set_efx_phoneme_a();
- set_efx_phoneme_a_coarse_tuning();
- set_efx_phoneme_b();
- set_efx_phoneme_b_coarse_tuning();
- set_efx_waveform();
- set_efx_rate();
-}
-
-void EaxVocalMorpherEffect::get(const EaxCall& call, const Props4& props)
+template<>
+void VocalMorpherCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
{
switch(call.get_property_id())
{
- case EAXVOCALMORPHER_NONE:
- break;
+ case EAXVOCALMORPHER_NONE:
+ break;
- case EAXVOCALMORPHER_ALLPARAMETERS:
- call.set_value<Exception>(props.mVocalMorpher);
- break;
+ case EAXVOCALMORPHER_ALLPARAMETERS:
+ call.set_value<Exception>(props.mVocalMorpher);
+ break;
- case EAXVOCALMORPHER_PHONEMEA:
- call.set_value<Exception>(props.mVocalMorpher.ulPhonemeA);
- break;
+ case EAXVOCALMORPHER_PHONEMEA:
+ call.set_value<Exception>(props.mVocalMorpher.ulPhonemeA);
+ break;
- case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
- call.set_value<Exception>(props.mVocalMorpher.lPhonemeACoarseTuning);
- break;
+ case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
+ call.set_value<Exception>(props.mVocalMorpher.lPhonemeACoarseTuning);
+ break;
- case EAXVOCALMORPHER_PHONEMEB:
- call.set_value<Exception>(props.mVocalMorpher.ulPhonemeB);
- break;
+ case EAXVOCALMORPHER_PHONEMEB:
+ call.set_value<Exception>(props.mVocalMorpher.ulPhonemeB);
+ break;
- case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
- call.set_value<Exception>(props.mVocalMorpher.lPhonemeBCoarseTuning);
- break;
+ case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
+ call.set_value<Exception>(props.mVocalMorpher.lPhonemeBCoarseTuning);
+ break;
- case EAXVOCALMORPHER_WAVEFORM:
- call.set_value<Exception>(props.mVocalMorpher.ulWaveform);
- break;
+ case EAXVOCALMORPHER_WAVEFORM:
+ call.set_value<Exception>(props.mVocalMorpher.ulWaveform);
+ break;
- case EAXVOCALMORPHER_RATE:
- call.set_value<Exception>(props.mVocalMorpher.flRate);
- break;
+ case EAXVOCALMORPHER_RATE:
+ call.set_value<Exception>(props.mVocalMorpher.flRate);
+ break;
- default:
- fail_unknown_property_id();
+ default:
+ fail_unknown_property_id();
}
}
-void EaxVocalMorpherEffect::set(const EaxCall& call, Props4& props)
+template<>
+void VocalMorpherCommitter::Set(const EaxCall &call, EaxEffectProps &props)
{
switch(call.get_property_id())
{
- case EAXVOCALMORPHER_NONE:
- break;
-
- case EAXVOCALMORPHER_ALLPARAMETERS:
- defer<AllValidator>(call, props.mVocalMorpher);
- break;
-
- case EAXVOCALMORPHER_PHONEMEA:
- defer<PhonemeAValidator>(call, props.mVocalMorpher.ulPhonemeA);
- break;
-
- case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
- defer<PhonemeACoarseTuningValidator>(call, props.mVocalMorpher.lPhonemeACoarseTuning);
- break;
-
- case EAXVOCALMORPHER_PHONEMEB:
- defer<PhonemeBValidator>(call, props.mVocalMorpher.ulPhonemeB);
- break;
-
- case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
- defer<PhonemeBCoarseTuningValidator>(call, props.mVocalMorpher.lPhonemeBCoarseTuning);
- break;
-
- case EAXVOCALMORPHER_WAVEFORM:
- defer<WaveformValidator>(call, props.mVocalMorpher.ulWaveform);
- break;
-
- case EAXVOCALMORPHER_RATE:
- defer<RateValidator>(call, props.mVocalMorpher.flRate);
- break;
+ case EAXVOCALMORPHER_NONE:
+ break;
- default:
- fail_unknown_property_id();
- }
-}
+ case EAXVOCALMORPHER_ALLPARAMETERS:
+ defer<AllValidator>(call, props.mVocalMorpher);
+ break;
-bool EaxVocalMorpherEffect::commit_props(const Props4& props)
-{
- auto is_dirty = false;
+ case EAXVOCALMORPHER_PHONEMEA:
+ defer<PhonemeAValidator>(call, props.mVocalMorpher.ulPhonemeA);
+ break;
- if (props_.mVocalMorpher.ulPhonemeA != props.mVocalMorpher.ulPhonemeA)
- {
- is_dirty = true;
- set_efx_phoneme_a();
- }
+ case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
+ defer<PhonemeACoarseTuningValidator>(call, props.mVocalMorpher.lPhonemeACoarseTuning);
+ break;
- if (props_.mVocalMorpher.lPhonemeACoarseTuning != props.mVocalMorpher.lPhonemeACoarseTuning)
- {
- is_dirty = true;
- set_efx_phoneme_a_coarse_tuning();
- }
+ case EAXVOCALMORPHER_PHONEMEB:
+ defer<PhonemeBValidator>(call, props.mVocalMorpher.ulPhonemeB);
+ break;
- if (props_.mVocalMorpher.ulPhonemeB != props.mVocalMorpher.ulPhonemeB)
- {
- is_dirty = true;
- set_efx_phoneme_b();
- }
+ case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
+ defer<PhonemeBCoarseTuningValidator>(call, props.mVocalMorpher.lPhonemeBCoarseTuning);
+ break;
- if (props_.mVocalMorpher.lPhonemeBCoarseTuning != props.mVocalMorpher.lPhonemeBCoarseTuning)
- {
- is_dirty = true;
- set_efx_phoneme_b_coarse_tuning();
- }
+ case EAXVOCALMORPHER_WAVEFORM:
+ defer<WaveformValidator>(call, props.mVocalMorpher.ulWaveform);
+ break;
- if (props_.mVocalMorpher.ulWaveform != props.mVocalMorpher.ulWaveform)
- {
- is_dirty = true;
- set_efx_waveform();
- }
+ case EAXVOCALMORPHER_RATE:
+ defer<RateValidator>(call, props.mVocalMorpher.flRate);
+ break;
- if (props_.mVocalMorpher.flRate != props.mVocalMorpher.flRate)
- {
- is_dirty = true;
- set_efx_rate();
+ default:
+ fail_unknown_property_id();
}
-
- return is_dirty;
-}
-
-} // namespace
-
-EaxEffectUPtr eax_create_eax_vocal_morpher_effect(int eax_version)
-{
- return eax_create_eax4_effect<EaxVocalMorpherEffect>(eax_version);
}
#endif // ALSOFT_EAX