aboutsummaryrefslogtreecommitdiffstats
path: root/al/effects/autowah.cpp
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-05-24 12:19:14 +0300
committerGitHub <[email protected]>2022-05-24 02:19:14 -0700
commit074dbef2e3129e9f7ee4895c44721c2a0a4b045b (patch)
tree72087ad2df3a5293d6aec82e762797b69de64111 /al/effects/autowah.cpp
parent54d72d17ad64809aeaf7a840447e398b2d38cbc9 (diff)
[EAX] Add separate effect state for each version (#705)
* [EAX] Add separate effect state for each version * [EAX] Don't use EAX call as data member
Diffstat (limited to 'al/effects/autowah.cpp')
-rw-r--r--al/effects/autowah.cpp482
1 files changed, 126 insertions, 356 deletions
diff --git a/al/effects/autowah.cpp b/al/effects/autowah.cpp
index 23f43305..7e0e34aa 100644
--- a/al/effects/autowah.cpp
+++ b/al/effects/autowah.cpp
@@ -13,7 +13,6 @@
#ifdef ALSOFT_EAX
#include "alnumeric.h"
-
#include "al/eax/exception.h"
#include "al/eax/utils.h"
#endif // ALSOFT_EAX
@@ -119,178 +118,127 @@ const EffectProps AutowahEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-using EaxAutoWahEffectDirtyFlagsValue = std::uint_least8_t;
-
-struct EaxAutoWahEffectDirtyFlags
-{
- using EaxIsBitFieldStruct = bool;
-
- EaxAutoWahEffectDirtyFlagsValue flAttackTime : 1;
- EaxAutoWahEffectDirtyFlagsValue flReleaseTime : 1;
- EaxAutoWahEffectDirtyFlagsValue lResonance : 1;
- EaxAutoWahEffectDirtyFlagsValue lPeakLevel : 1;
-}; // EaxAutoWahEffectDirtyFlags
-
-
-class EaxAutoWahEffect final :
- public EaxEffect
-{
+class EaxAutoWahEffectException : public EaxException {
public:
- EaxAutoWahEffect();
-
-
- void dispatch(const EaxEaxCall& eax_call) override;
+ explicit EaxAutoWahEffectException(const char* message)
+ : EaxException{"EAX_AUTO_WAH_EFFECT", message}
+ {}
+}; // EaxAutoWahEffectException
- // [[nodiscard]]
- bool apply_deferred() override;
+class EaxAutoWahEffect final : public EaxEffect4<EaxAutoWahEffectException, EAXAUTOWAHPROPERTIES> {
+public:
+ EaxAutoWahEffect(const EaxCall& call);
private:
- EAXAUTOWAHPROPERTIES eax_{};
- EAXAUTOWAHPROPERTIES eax_d_{};
- EaxAutoWahEffectDirtyFlags eax_dirty_flags_{};
-
-
- void set_eax_defaults();
-
-
- void set_efx_attack_time();
-
- void set_efx_release_time();
-
- void set_efx_resonance();
-
- void set_efx_peak_gain();
-
- void set_efx_defaults();
-
-
- void get(const EaxEaxCall& eax_call);
-
-
- void validate_attack_time(
- float flAttackTime);
-
- void validate_release_time(
- float flReleaseTime);
-
- void validate_resonance(
- long lResonance);
-
- void validate_peak_level(
- long lPeakLevel);
-
- void validate_all(
- const EAXAUTOWAHPROPERTIES& eax_all);
-
-
- void defer_attack_time(
- float flAttackTime);
-
- void defer_release_time(
- float flReleaseTime);
-
- void defer_resonance(
- long lResonance);
-
- void defer_peak_level(
- long lPeakLevel);
-
- void defer_all(
- const EAXAUTOWAHPROPERTIES& eax_all);
-
-
- void defer_attack_time(
- const EaxEaxCall& eax_call);
-
- void defer_release_time(
- const EaxEaxCall& eax_call);
-
- void defer_resonance(
- const EaxEaxCall& eax_call);
-
- void defer_peak_level(
- const EaxEaxCall& eax_call);
-
- void defer_all(
- const EaxEaxCall& eax_call);
-
- void set(const EaxEaxCall& eax_call);
+ struct AttackTimeValidator {
+ void operator()(float flAttackTime) const
+ {
+ eax_validate_range<Exception>(
+ "Attack Time",
+ flAttackTime,
+ EAXAUTOWAH_MINATTACKTIME,
+ EAXAUTOWAH_MAXATTACKTIME);
+ }
+ }; // AttackTimeValidator
+
+ struct ReleaseTimeValidator {
+ void operator()(float flReleaseTime) const
+ {
+ eax_validate_range<Exception>(
+ "Release Time",
+ flReleaseTime,
+ EAXAUTOWAH_MINRELEASETIME,
+ EAXAUTOWAH_MAXRELEASETIME);
+ }
+ }; // ReleaseTimeValidator
+
+ struct ResonanceValidator {
+ void operator()(long lResonance) const
+ {
+ eax_validate_range<Exception>(
+ "Resonance",
+ lResonance,
+ EAXAUTOWAH_MINRESONANCE,
+ EAXAUTOWAH_MAXRESONANCE);
+ }
+ }; // ResonanceValidator
+
+ struct PeakLevelValidator {
+ void operator()(long lPeakLevel) const
+ {
+ eax_validate_range<Exception>(
+ "Peak Level",
+ lPeakLevel,
+ EAXAUTOWAH_MINPEAKLEVEL,
+ EAXAUTOWAH_MAXPEAKLEVEL);
+ }
+ }; // PeakLevelValidator
+
+ struct AllValidator {
+ void operator()(const Props& all) const
+ {
+ AttackTimeValidator{}(all.flAttackTime);
+ ReleaseTimeValidator{}(all.flReleaseTime);
+ ResonanceValidator{}(all.lResonance);
+ PeakLevelValidator{}(all.lPeakLevel);
+ }
+ }; // AllValidator
+
+ void set_defaults(Props& props) override;
+
+ void set_efx_attack_time() noexcept;
+ void set_efx_release_time() noexcept;
+ void set_efx_resonance() noexcept;
+ void set_efx_peak_gain() noexcept;
+ void set_efx_defaults() override;
+
+ void get(const EaxCall& call, const Props& props) override;
+ void set(const EaxCall& call, Props& props) override;
+ bool commit_props(const Props& props) override;
}; // EaxAutoWahEffect
+EaxAutoWahEffect::EaxAutoWahEffect(const EaxCall& call)
+ : EaxEffect4{AL_EFFECT_AUTOWAH, call}
+{}
-class EaxAutoWahEffectException :
- public EaxException
-{
-public:
- explicit EaxAutoWahEffectException(
- const char* message)
- :
- EaxException{"EAX_AUTO_WAH_EFFECT", message}
- {
- }
-}; // EaxAutoWahEffectException
-
-
-EaxAutoWahEffect::EaxAutoWahEffect()
- : EaxEffect{AL_EFFECT_AUTOWAH}
-{
- set_eax_defaults();
- set_efx_defaults();
-}
-
-void EaxAutoWahEffect::dispatch(const EaxEaxCall& eax_call)
-{
- eax_call.is_get() ? get(eax_call) : set(eax_call);
-}
-
-void EaxAutoWahEffect::set_eax_defaults()
+void EaxAutoWahEffect::set_defaults(Props& props)
{
- eax_.flAttackTime = EAXAUTOWAH_DEFAULTATTACKTIME;
- eax_.flReleaseTime = EAXAUTOWAH_DEFAULTRELEASETIME;
- eax_.lResonance = EAXAUTOWAH_DEFAULTRESONANCE;
- eax_.lPeakLevel = EAXAUTOWAH_DEFAULTPEAKLEVEL;
-
- eax_d_ = eax_;
+ props.flAttackTime = EAXAUTOWAH_DEFAULTATTACKTIME;
+ props.flReleaseTime = EAXAUTOWAH_DEFAULTRELEASETIME;
+ props.lResonance = EAXAUTOWAH_DEFAULTRESONANCE;
+ props.lPeakLevel = EAXAUTOWAH_DEFAULTPEAKLEVEL;
}
-void EaxAutoWahEffect::set_efx_attack_time()
+void EaxAutoWahEffect::set_efx_attack_time() noexcept
{
- const auto attack_time = clamp(
- eax_.flAttackTime,
+ al_effect_props_.Autowah.AttackTime = clamp(
+ props_.flAttackTime,
AL_AUTOWAH_MIN_ATTACK_TIME,
AL_AUTOWAH_MAX_ATTACK_TIME);
-
- al_effect_props_.Autowah.AttackTime = attack_time;
}
-void EaxAutoWahEffect::set_efx_release_time()
+void EaxAutoWahEffect::set_efx_release_time() noexcept
{
- const auto release_time = clamp(
- eax_.flReleaseTime,
+ al_effect_props_.Autowah.ReleaseTime = clamp(
+ props_.flReleaseTime,
AL_AUTOWAH_MIN_RELEASE_TIME,
AL_AUTOWAH_MAX_RELEASE_TIME);
-
- al_effect_props_.Autowah.ReleaseTime = release_time;
}
-void EaxAutoWahEffect::set_efx_resonance()
+void EaxAutoWahEffect::set_efx_resonance() noexcept
{
- const auto resonance = clamp(
- level_mb_to_gain(static_cast<float>(eax_.lResonance)),
+ al_effect_props_.Autowah.Resonance = clamp(
+ level_mb_to_gain(static_cast<float>(props_.lResonance)),
AL_AUTOWAH_MIN_RESONANCE,
AL_AUTOWAH_MAX_RESONANCE);
-
- al_effect_props_.Autowah.Resonance = resonance;
}
-void EaxAutoWahEffect::set_efx_peak_gain()
+void EaxAutoWahEffect::set_efx_peak_gain() noexcept
{
- const auto peak_gain = clamp(
- level_mb_to_gain(static_cast<float>(eax_.lPeakLevel)),
+ al_effect_props_.Autowah.PeakGain = clamp(
+ level_mb_to_gain(static_cast<float>(props_.lPeakLevel)),
AL_AUTOWAH_MIN_PEAK_GAIN,
AL_AUTOWAH_MAX_PEAK_GAIN);
-
- al_effect_props_.Autowah.PeakGain = peak_gain;
}
void EaxAutoWahEffect::set_efx_defaults()
@@ -301,248 +249,70 @@ void EaxAutoWahEffect::set_efx_defaults()
set_efx_peak_gain();
}
-void EaxAutoWahEffect::get(const EaxEaxCall& eax_call)
+void EaxAutoWahEffect::get(const EaxCall& call, const Props& props)
{
- switch (eax_call.get_property_id())
+ switch (call.get_property_id())
{
- case EAXAUTOWAH_NONE:
- break;
-
- case EAXAUTOWAH_ALLPARAMETERS:
- eax_call.set_value<EaxAutoWahEffectException>(eax_);
- break;
-
- case EAXAUTOWAH_ATTACKTIME:
- eax_call.set_value<EaxAutoWahEffectException>(eax_.flAttackTime);
- break;
-
- case EAXAUTOWAH_RELEASETIME:
- eax_call.set_value<EaxAutoWahEffectException>(eax_.flReleaseTime);
- break;
-
- case EAXAUTOWAH_RESONANCE:
- eax_call.set_value<EaxAutoWahEffectException>(eax_.lResonance);
- break;
-
- case EAXAUTOWAH_PEAKLEVEL:
- eax_call.set_value<EaxAutoWahEffectException>(eax_.lPeakLevel);
- break;
-
- default:
- throw EaxAutoWahEffectException{"Unsupported property id."};
+ case EAXAUTOWAH_NONE: break;
+ case EAXAUTOWAH_ALLPARAMETERS: call.set_value<Exception>(props); break;
+ case EAXAUTOWAH_ATTACKTIME: call.set_value<Exception>(props.flAttackTime); break;
+ case EAXAUTOWAH_RELEASETIME: call.set_value<Exception>(props.flReleaseTime); break;
+ case EAXAUTOWAH_RESONANCE: call.set_value<Exception>(props.lResonance); break;
+ case EAXAUTOWAH_PEAKLEVEL: call.set_value<Exception>(props.lPeakLevel); break;
+ default: fail_unknown_property_id();
}
}
-void EaxAutoWahEffect::validate_attack_time(
- float flAttackTime)
+void EaxAutoWahEffect::set(const EaxCall& call, Props& props)
{
- eax_validate_range<EaxAutoWahEffectException>(
- "Attack Time",
- flAttackTime,
- EAXAUTOWAH_MINATTACKTIME,
- EAXAUTOWAH_MAXATTACKTIME);
-}
-
-void EaxAutoWahEffect::validate_release_time(
- float flReleaseTime)
-{
- eax_validate_range<EaxAutoWahEffectException>(
- "Release Time",
- flReleaseTime,
- EAXAUTOWAH_MINRELEASETIME,
- EAXAUTOWAH_MAXRELEASETIME);
-}
-
-void EaxAutoWahEffect::validate_resonance(
- long lResonance)
-{
- eax_validate_range<EaxAutoWahEffectException>(
- "Resonance",
- lResonance,
- EAXAUTOWAH_MINRESONANCE,
- EAXAUTOWAH_MAXRESONANCE);
-}
-
-void EaxAutoWahEffect::validate_peak_level(
- long lPeakLevel)
-{
- eax_validate_range<EaxAutoWahEffectException>(
- "Peak Level",
- lPeakLevel,
- EAXAUTOWAH_MINPEAKLEVEL,
- EAXAUTOWAH_MAXPEAKLEVEL);
-}
-
-void EaxAutoWahEffect::validate_all(
- const EAXAUTOWAHPROPERTIES& eax_all)
-{
- validate_attack_time(eax_all.flAttackTime);
- validate_release_time(eax_all.flReleaseTime);
- validate_resonance(eax_all.lResonance);
- validate_peak_level(eax_all.lPeakLevel);
-}
-
-void EaxAutoWahEffect::defer_attack_time(
- float flAttackTime)
-{
- eax_d_.flAttackTime = flAttackTime;
- eax_dirty_flags_.flAttackTime = (eax_.flAttackTime != eax_d_.flAttackTime);
-}
-
-void EaxAutoWahEffect::defer_release_time(
- float flReleaseTime)
-{
- eax_d_.flReleaseTime = flReleaseTime;
- eax_dirty_flags_.flReleaseTime = (eax_.flReleaseTime != eax_d_.flReleaseTime);
-}
-
-void EaxAutoWahEffect::defer_resonance(
- long lResonance)
-{
- eax_d_.lResonance = lResonance;
- eax_dirty_flags_.lResonance = (eax_.lResonance != eax_d_.lResonance);
-}
-
-void EaxAutoWahEffect::defer_peak_level(
- long lPeakLevel)
-{
- eax_d_.lPeakLevel = lPeakLevel;
- eax_dirty_flags_.lPeakLevel = (eax_.lPeakLevel != eax_d_.lPeakLevel);
-}
-
-void EaxAutoWahEffect::defer_all(
- const EAXAUTOWAHPROPERTIES& eax_all)
-{
- validate_all(eax_all);
-
- defer_attack_time(eax_all.flAttackTime);
- defer_release_time(eax_all.flReleaseTime);
- defer_resonance(eax_all.lResonance);
- defer_peak_level(eax_all.lPeakLevel);
-}
-
-void EaxAutoWahEffect::defer_attack_time(
- const EaxEaxCall& eax_call)
-{
- const auto& attack_time =
- eax_call.get_value<EaxAutoWahEffectException, const decltype(EAXAUTOWAHPROPERTIES::flAttackTime)>();
-
- validate_attack_time(attack_time);
- defer_attack_time(attack_time);
-}
-
-void EaxAutoWahEffect::defer_release_time(
- const EaxEaxCall& eax_call)
-{
- const auto& release_time =
- eax_call.get_value<EaxAutoWahEffectException, const decltype(EAXAUTOWAHPROPERTIES::flReleaseTime)>();
-
- validate_release_time(release_time);
- defer_release_time(release_time);
-}
-
-void EaxAutoWahEffect::defer_resonance(
- const EaxEaxCall& eax_call)
-{
- const auto& resonance =
- eax_call.get_value<EaxAutoWahEffectException, const decltype(EAXAUTOWAHPROPERTIES::lResonance)>();
-
- validate_resonance(resonance);
- defer_resonance(resonance);
-}
-
-void EaxAutoWahEffect::defer_peak_level(
- const EaxEaxCall& eax_call)
-{
- const auto& peak_level =
- eax_call.get_value<EaxAutoWahEffectException, const decltype(EAXAUTOWAHPROPERTIES::lPeakLevel)>();
-
- validate_peak_level(peak_level);
- defer_peak_level(peak_level);
-}
-
-void EaxAutoWahEffect::defer_all(
- const EaxEaxCall& eax_call)
-{
- const auto& all =
- eax_call.get_value<EaxAutoWahEffectException, const EAXAUTOWAHPROPERTIES>();
-
- validate_all(all);
- defer_all(all);
-}
-
-// [[nodiscard]]
-bool EaxAutoWahEffect::apply_deferred()
-{
- if (eax_dirty_flags_ == EaxAutoWahEffectDirtyFlags{})
+ switch (call.get_property_id())
{
- return false;
+ case EAXAUTOWAH_NONE: break;
+ case EAXAUTOWAH_ALLPARAMETERS: defer<AllValidator>(call, props); break;
+ case EAXAUTOWAH_ATTACKTIME: defer<AttackTimeValidator>(call, props.flAttackTime); break;
+ case EAXAUTOWAH_RELEASETIME: defer<ReleaseTimeValidator>(call, props.flReleaseTime); break;
+ case EAXAUTOWAH_RESONANCE: defer<ResonanceValidator>(call, props.lResonance); break;
+ case EAXAUTOWAH_PEAKLEVEL: defer<PeakLevelValidator>(call, props.lPeakLevel); break;
+ default: fail_unknown_property_id();
}
+}
- eax_ = eax_d_;
+bool EaxAutoWahEffect::commit_props(const Props& props)
+{
+ auto is_dirty = false;
- if (eax_dirty_flags_.flAttackTime)
+ if (props_.flAttackTime != props.flAttackTime)
{
+ is_dirty = true;
set_efx_attack_time();
}
- if (eax_dirty_flags_.flReleaseTime)
+ if (props_.flReleaseTime != props.flReleaseTime)
{
+ is_dirty = true;
set_efx_release_time();
}
- if (eax_dirty_flags_.lResonance)
+ if (props_.lResonance != props.lResonance)
{
+ is_dirty = true;
set_efx_resonance();
}
- if (eax_dirty_flags_.lPeakLevel)
+ if (props_.lPeakLevel != props.lPeakLevel)
{
+ is_dirty = true;
set_efx_peak_gain();
}
- eax_dirty_flags_ = EaxAutoWahEffectDirtyFlags{};
-
- return true;
-}
-
-void EaxAutoWahEffect::set(const EaxEaxCall& eax_call)
-{
- switch (eax_call.get_property_id())
- {
- case EAXAUTOWAH_NONE:
- break;
-
- case EAXAUTOWAH_ALLPARAMETERS:
- defer_all(eax_call);
- break;
-
- case EAXAUTOWAH_ATTACKTIME:
- defer_attack_time(eax_call);
- break;
-
- case EAXAUTOWAH_RELEASETIME:
- defer_release_time(eax_call);
- break;
-
- case EAXAUTOWAH_RESONANCE:
- defer_resonance(eax_call);
- break;
-
- case EAXAUTOWAH_PEAKLEVEL:
- defer_peak_level(eax_call);
- break;
-
- default:
- throw EaxAutoWahEffectException{"Unsupported property id."};
- }
+ return is_dirty;
}
} // namespace
-EaxEffectUPtr eax_create_eax_auto_wah_effect()
+EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call)
{
- return std::make_unique<::EaxAutoWahEffect>();
+ return eax_create_eax4_effect<EaxAutoWahEffect>(call);
}
#endif // ALSOFT_EAX