|
|
- #ifndef EAX_EFFECT_INCLUDED
- #define EAX_EFFECT_INCLUDED
-
-
- #include <cassert>
- #include <memory>
-
- #include "alnumeric.h"
- #include "AL/al.h"
- #include "core/effects/base.h"
- #include "call.h"
-
- struct EaxEffectErrorMessages
- {
- static constexpr auto unknown_property_id() noexcept { return "Unknown property id."; }
- static constexpr auto unknown_version() noexcept { return "Unknown version."; }
- }; // EaxEffectErrorMessages
-
- class EaxEffect {
- public:
- EaxEffect(ALenum type) noexcept : al_effect_type_{type} { }
- virtual ~EaxEffect() = default;
-
- const ALenum al_effect_type_;
- EffectProps al_effect_props_{};
-
- virtual void dispatch(const EaxCall& call) = 0;
-
- // Returns "true" if any immediated property was changed.
- /*[[nodiscard]]*/ virtual bool commit() = 0;
- }; // EaxEffect
-
- // Base class for EAX4+ effects.
- template<typename TException, typename TProps>
- class EaxEffect4 : public EaxEffect
- {
- public:
- EaxEffect4(ALenum type, const EaxCall& call)
- : EaxEffect{type}, version_{clamp(call.get_version(), 4, 5)}
- {}
-
- void initialize()
- {
- set_defaults();
- set_efx_defaults();
- }
-
- void dispatch(const EaxCall& call) override
- {
- call.is_get() ? get(call) : set(call);
- version_ = call.get_version();
- }
-
- 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;
- using Props = TProps;
-
- struct State {
- Props i; // Immediate.
- Props d; // Deferred.
- }; // State
-
- int version_;
- Props props_;
- State state4_;
- State state5_;
-
- 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(Props& props) = 0;
- virtual void set_efx_defaults() = 0;
-
- virtual void get(const EaxCall& call, const Props& props) = 0;
- virtual void set(const EaxCall& call, Props& props) = 0;
-
- virtual bool commit_props(const Props& 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)
- {
- switch (call.get_version())
- {
- case 4: set(call, state4_.d); break;
- case 5: set(call, state5_.d); break;
- default: fail_unknown_version();
- }
- }
-
- bool commit_state(State& 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(const EaxCall& call)
- {
- auto effect = std::make_unique<TEffect>(call);
- effect->initialize();
- return effect;
- }
-
- EaxEffectUPtr eax_create_eax_null_effect();
- EaxEffectUPtr eax_create_eax_chorus_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_distortion_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_echo_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_flanger_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_frequency_shifter_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_vocal_morpher_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_pitch_shifter_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_ring_modulator_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_compressor_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_equalizer_effect(const EaxCall& call);
- EaxEffectUPtr eax_create_eax_reverb_effect(const EaxCall& call);
-
- #endif // !EAX_EFFECT_INCLUDED
|