[EAX] Use separate FX slot state for each version (#730)

* [EAX] Use separate FX slot state for each version
[EAX] Don't defer FX slot properties

* [EAX_FXSLOT] Use mPropsDirty to defer update
[EAX_CONTEXT] Commit all updates on first initialization
master
Boris I. Bendovsky 2022-07-12 12:46:51 +03:00 committed by GitHub
parent fa51c89549
commit 6fb5cb553f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 749 additions and 823 deletions

File diff suppressed because it is too large Load Diff

View File

@ -20,13 +20,23 @@
#include <memory>
#include "eax/call.h"
#include "eax/effect.h"
#include "eax/exception.h"
#include "eax/fx_slot_index.h"
#include "eax/utils.h"
#endif // ALSOFT_EAX
struct ALbuffer;
struct ALeffect;
struct WetBuffer;
#ifdef ALSOFT_EAX
class EaxFxSlotException : public EaxException {
public:
explicit EaxFxSlotException(const char* message)
: EaxException{"EAX_FX_SLOT", message}
{}
};
#endif // ALSOFT_EAX
enum class SlotState : ALenum {
Initial = AL_INITIAL,
@ -79,162 +89,282 @@ public:
const EAX50FXSLOTPROPERTIES& eax_get_eax_fx_slot() const noexcept;
// [[nodiscard]]
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax_dispatch(const EaxCall& call)
{ return call.is_get() ? eax_get(call) : eax_set(call); }
void eax_unlock_legacy() noexcept;
void eax_commit() { eax_apply_deferred(); }
void eax_commit();
private:
static constexpr auto eax_load_effect_dirty_bit = EaxDirtyFlags{1} << 0;
static constexpr auto eax_volume_dirty_bit = EaxDirtyFlags{1} << 1;
static constexpr auto eax_lock_dirty_bit = EaxDirtyFlags{1} << 2;
static constexpr auto eax_flags_dirty_bit = EaxDirtyFlags{1} << 3;
static constexpr auto eax_occlusion_dirty_bit = EaxDirtyFlags{1} << 4;
static constexpr auto eax_occlusion_lf_ratio_dirty_bit = EaxDirtyFlags{1} << 5;
using Exception = EaxFxSlotException;
using Eax4Props = EAX40FXSLOTPROPERTIES;
struct Eax4State {
Eax4Props i; // Immediate.
EaxDirtyFlags df; // Dirty flags.
};
using Eax5Props = EAX50FXSLOTPROPERTIES;
struct Eax5State {
Eax5Props i; // Immediate.
EaxDirtyFlags df; // Dirty flags.
};
struct EaxRangeValidator {
template<typename TValue>
void operator()(
const char* name,
const TValue& value,
const TValue& min_value,
const TValue& max_value) const
{
eax_validate_range<Exception>(name, value, min_value, max_value);
}
};
struct Eax4GuidLoadEffectValidator {
void operator()(const GUID& guidLoadEffect) const
{
if (guidLoadEffect != EAX_NULL_GUID &&
guidLoadEffect != EAX_REVERB_EFFECT &&
guidLoadEffect != EAX_AGCCOMPRESSOR_EFFECT &&
guidLoadEffect != EAX_AUTOWAH_EFFECT &&
guidLoadEffect != EAX_CHORUS_EFFECT &&
guidLoadEffect != EAX_DISTORTION_EFFECT &&
guidLoadEffect != EAX_ECHO_EFFECT &&
guidLoadEffect != EAX_EQUALIZER_EFFECT &&
guidLoadEffect != EAX_FLANGER_EFFECT &&
guidLoadEffect != EAX_FREQUENCYSHIFTER_EFFECT &&
guidLoadEffect != EAX_VOCALMORPHER_EFFECT &&
guidLoadEffect != EAX_PITCHSHIFTER_EFFECT &&
guidLoadEffect != EAX_RINGMODULATOR_EFFECT)
{
eax_fail_unknown_effect_id();
}
}
};
struct Eax4VolumeValidator {
void operator()(long lVolume) const
{
EaxRangeValidator{}(
"Volume",
lVolume,
EAXFXSLOT_MINVOLUME,
EAXFXSLOT_MAXVOLUME);
}
};
struct Eax4LockValidator {
void operator()(long lLock) const
{
EaxRangeValidator{}(
"Lock",
lLock,
EAXFXSLOT_MINLOCK,
EAXFXSLOT_MAXLOCK);
}
};
struct Eax4FlagsValidator {
void operator()(unsigned long ulFlags) const
{
EaxRangeValidator{}(
"Flags",
ulFlags,
0UL,
~EAX40FXSLOTFLAGS_RESERVED);
}
};
struct Eax4AllValidator {
void operator()(const EAX40FXSLOTPROPERTIES& all) const
{
Eax4GuidLoadEffectValidator{}(all.guidLoadEffect);
Eax4VolumeValidator{}(all.lVolume);
Eax4LockValidator{}(all.lLock);
Eax4FlagsValidator{}(all.ulFlags);
}
};
struct Eax5OcclusionValidator {
void operator()(long lOcclusion) const
{
EaxRangeValidator{}(
"Occlusion",
lOcclusion,
EAXFXSLOT_MINOCCLUSION,
EAXFXSLOT_MAXOCCLUSION);
}
};
struct Eax5OcclusionLfRatioValidator {
void operator()(float flOcclusionLFRatio) const
{
EaxRangeValidator{}(
"Occlusion LF Ratio",
flOcclusionLFRatio,
EAXFXSLOT_MINOCCLUSIONLFRATIO,
EAXFXSLOT_MAXOCCLUSIONLFRATIO);
}
};
struct Eax5FlagsValidator {
void operator()(unsigned long ulFlags) const
{
EaxRangeValidator{}(
"Flags",
ulFlags,
0UL,
~EAX50FXSLOTFLAGS_RESERVED);
}
};
struct Eax5AllValidator {
void operator()(const EAX50FXSLOTPROPERTIES& all) const
{
Eax4AllValidator{}(static_cast<const EAX40FXSLOTPROPERTIES&>(all));
Eax5OcclusionValidator{}(all.lOcclusion);
Eax5OcclusionLfRatioValidator{}(all.flOcclusionLFRatio);
}
};
ALCcontext* eax_al_context_{};
EaxFxSlotIndexValue eax_fx_slot_index_{};
EAX50FXSLOTPROPERTIES eax_eax_fx_slot_{};
int eax_version_{}; // Current EAX version.
EaxEffectUPtr eax_effect_{};
bool eax_is_locked_{};
Eax5State eax123_{}; // EAX1/EAX2/EAX3 state.
Eax4State eax4_{}; // EAX4 state.
Eax5State eax5_{}; // EAX5 state.
Eax5Props eax_{}; // Current EAX state.
[[noreturn]] static void eax_fail(const char* message);
[[noreturn]] static void eax_fail_unknown_effect_id();
[[noreturn]] static void eax_fail_unknown_property_id();
[[noreturn]] static void eax_fail_unknown_version();
[[noreturn]]
static void eax_fail(
const char* message);
// Gets a new value from EAX call,
// validates it,
// sets a dirty flag only if the new value differs form the old one,
// and assigns the new value.
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
void eax_fx_slot_set(const EaxCall& call, TProperties& dst, EaxDirtyFlags& dirty_flags)
{
const auto& src = call.get_value<Exception, const TProperties>();
TValidator{}(src);
dirty_flags |= (dst != src ? TDirtyBit : EaxDirtyFlags{});
dst = src;
}
// Gets a new value from EAX call,
// validates it,
// sets a dirty flag without comparing the values,
// and assigns the new value.
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
void eax_fx_slot_set_dirty(const EaxCall& call, TProperties& dst, EaxDirtyFlags& dirty_flags)
{
const auto& src = call.get_value<Exception, const TProperties>();
TValidator{}(src);
dirty_flags |= TDirtyBit;
dst = src;
}
GUID eax_get_eax_default_effect_guid() const noexcept;
constexpr bool eax4_fx_slot_is_legacy() const noexcept
{ return eax_fx_slot_index_ < 2; }
void eax4_fx_slot_ensure_unlocked() const;
static ALenum eax_get_efx_effect_type(const GUID& guid);
const GUID& eax_get_eax_default_effect_guid() const noexcept;
long eax_get_eax_default_lock() const noexcept;
void eax_set_eax_fx_slot_defaults();
void eax4_fx_slot_set_defaults(Eax4Props& props);
void eax4_fx_slot_set_defaults();
void eax5_fx_slot_set_defaults(Eax5Props& props);
void eax5_fx_slot_set_defaults();
void eax_fx_slot_set_defaults();
void eax_initialize_eax();
void eax_initialize_lock();
void eax_initialize_effects(const EaxCall& call);
void eax_get_fx_slot_all(const EaxCall& call) const;
void eax_get_fx_slot(const EaxCall& call) const;
// [[nodiscard]]
void eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props) const;
void eax5_fx_slot_get(const EaxCall& call, const Eax5Props& props) const;
void eax_fx_slot_get(const EaxCall& call) const;
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax_get(const EaxCall& call);
void eax_fx_slot_load_effect();
void eax_fx_slot_set_volume();
void eax_fx_slot_set_environment_flag();
void eax_fx_slot_set_flags();
void eax_set_fx_slot_effect(const EaxCall& call, ALenum effect_type);
void eax4_fx_slot_set_all(const EaxCall& call);
void eax5_fx_slot_set_all(const EaxCall& call);
void eax_set_fx_slot_effect(const EaxCall& call);
void eax_set_efx_effect_slot_gain();
void eax_set_fx_slot_volume();
void eax_set_effect_slot_send_auto();
void eax_set_fx_slot_flags();
void eax_ensure_is_unlocked() const;
void eax_validate_fx_slot_effect(const GUID& eax_effect_id);
void eax_validate_fx_slot_volume(long eax_volume);
void eax_validate_fx_slot_lock(long eax_lock);
void eax_validate_fx_slot_flags(const EaxCall& call, unsigned long eax_flags);
void eax_validate_fx_slot_occlusion(long eax_occlusion);
void eax_validate_fx_slot_occlusion_lf_ratio(float eax_occlusion_lf_ratio);
void eax_validate_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& fx_slot);
void eax_validate_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& fx_slot);
void eax_set_fx_slot_effect(const EaxCall& call, const GUID& eax_effect_id);
void eax_set_fx_slot_volume(
long eax_volume);
void eax_set_fx_slot_lock(
long eax_lock);
void eax_set_fx_slot_flags(
unsigned long eax_flags);
// [[nodiscard]]
bool eax_set_fx_slot_occlusion(
long eax_occlusion);
// [[nodiscard]]
bool eax_set_fx_slot_occlusion_lf_ratio(
float eax_occlusion_lf_ratio);
void eax_set_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& eax_fx_slot);
// [[nodiscard]]
bool eax_set_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& eax_fx_slot);
void eax_defer_fx_slot_effect(const EaxCall& call);
void eax_defer_fx_slot_volume(const EaxCall& call);
void eax_defer_fx_slot_lock(const EaxCall& call);
void eax_defer_fx_slot_flags(const EaxCall& call);
// [[nodiscard]]
bool eax_defer_fx_slot_occlusion(const EaxCall& call);
// [[nodiscard]]
bool eax_defer_fx_slot_occlusion_lf_ratio(const EaxCall& call);
// [[nodiscard]]
bool eax_defer_fx_slot_all(const EaxCall& call);
bool eax_set_fx_slot(const EaxCall& call);
void eax_apply_deferred();
// [[nodiscard]]
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax4_fx_slot_set(const EaxCall& call);
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax5_fx_slot_set(const EaxCall& call);
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax_fx_slot_set(const EaxCall& call);
// Returns `true` if all sources should be updated, or `false` otherwise.
bool eax_set(const EaxCall& call);
template<
EaxDirtyFlags TDirtyBit,
typename TMemberResult,
typename TProps,
typename TState>
void eax_fx_slot_commit_property(
TState& state,
EaxDirtyFlags& dst_df,
TMemberResult TProps::*member) noexcept
{
auto& src_i = state.i;
auto& src_df = state.df;
auto& dst_i = eax_;
if ((src_df & TDirtyBit) != EaxDirtyFlags{}) {
dst_df |= TDirtyBit;
dst_i.*member = src_i.*member;
}
}
void eax4_fx_slot_commit(EaxDirtyFlags& dst_df);
void eax5_fx_slot_commit(Eax5State& state, EaxDirtyFlags& dst_df);
void eax_dispatch_effect(const EaxCall& call);
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_EFFECT, effect)`
void eax_set_effect_slot_effect(EaxEffect &effect);
void eax_set_efx_slot_effect(EaxEffect &effect);
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, value)`
void eax_set_effect_slot_send_auto(bool is_send_auto);
void eax_set_efx_slot_send_auto(bool is_send_auto);
// `alAuxiliaryEffectSlotf(effect_slot, AL_EFFECTSLOT_GAIN, gain)`
void eax_set_effect_slot_gain(ALfloat gain);
void eax_set_efx_slot_gain(ALfloat gain);
public:
class EaxDeleter {
public:
void operator()(ALeffectslot *effect_slot);
}; // EaxAlEffectSlotDeleter
};
#endif // ALSOFT_EAX
};
void UpdateAllEffectSlotProps(ALCcontext *context);
#ifdef ALSOFT_EAX
using EaxAlEffectSlotUPtr = std::unique_ptr<ALeffectslot, ALeffectslot::EaxDeleter>;
EaxAlEffectSlotUPtr eax_create_al_effect_slot(
ALCcontext& context);
void eax_delete_al_effect_slot(
ALCcontext& context,
ALeffectslot& effect_slot);
EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context);
void eax_delete_al_effect_slot(ALCcontext& context, ALeffectslot& effect_slot);
#endif // ALSOFT_EAX
#endif

View File

@ -23,6 +23,7 @@ EaxCall::EaxCall(
ALvoid* property_buffer,
ALuint property_size)
: type_{type}, version_{0}, property_set_id_{EaxCallPropertySetId::none}
, is_deferred_{(property_id & deferred_flag) != 0}
, property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
, property_buffer_{property_buffer}, property_size_{property_size}
{

View File

@ -32,6 +32,7 @@ public:
ALuint property_size);
bool is_get() const noexcept { return type_ == EaxCallType::get; }
bool is_deferred() const noexcept { return is_deferred_; }
int get_version() const noexcept { return version_; }
EaxCallPropertySetId get_property_set_id() const noexcept { return property_set_id_; }
ALuint get_property_id() const noexcept { return property_id_; }
@ -76,6 +77,7 @@ private:
int version_;
EaxFxSlotIndex fx_slot_index_;
EaxCallPropertySetId property_set_id_;
bool is_deferred_;
ALuint property_id_;
ALuint property_source_id_;

View File

@ -35,8 +35,8 @@ 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)}
EaxEffect4(ALenum type, int eax_version)
: EaxEffect{type}, version_{clamp(eax_version, 4, 5)}
{}
void initialize()
@ -70,10 +70,10 @@ protected:
Props d; // Deferred.
}; // State
int version_;
Props props_;
State state4_;
State state5_;
int version_{};
Props props_{};
State state4_{};
State state5_{};
template<typename TValidator, typename TProperty>
static void defer(const EaxCall& call, TProperty& property)
@ -149,25 +149,25 @@ using EaxEffectUPtr = std::unique_ptr<EaxEffect>;
// Creates EAX4+ effect.
template<typename TEffect>
EaxEffectUPtr eax_create_eax4_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax4_effect(int eax_version)
{
auto effect = std::make_unique<TEffect>(call);
auto effect = std::make_unique<TEffect>(eax_version);
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);
EaxEffectUPtr eax_create_eax_chorus_effect(int eax_version);
EaxEffectUPtr eax_create_eax_distortion_effect(int eax_version);
EaxEffectUPtr eax_create_eax_echo_effect(int eax_version);
EaxEffectUPtr eax_create_eax_flanger_effect(int eax_version);
EaxEffectUPtr eax_create_eax_frequency_shifter_effect(int eax_version);
EaxEffectUPtr eax_create_eax_vocal_morpher_effect(int eax_version);
EaxEffectUPtr eax_create_eax_pitch_shifter_effect(int eax_version);
EaxEffectUPtr eax_create_eax_ring_modulator_effect(int eax_version);
EaxEffectUPtr eax_create_eax_auto_wah_effect(int eax_version);
EaxEffectUPtr eax_create_eax_compressor_effect(int eax_version);
EaxEffectUPtr eax_create_eax_equalizer_effect(int eax_version);
EaxEffectUPtr eax_create_eax_reverb_effect(int eax_version);
#endif // !EAX_EFFECT_INCLUDED

View File

@ -57,12 +57,6 @@ ALeffectslot& EaxFxSlots::get(EaxFxSlotIndex index)
return *fx_slots_[index.value()];
}
void EaxFxSlots::unlock_legacy() noexcept
{
fx_slots_[0]->eax_unlock_legacy();
fx_slots_[1]->eax_unlock_legacy();
}
[[noreturn]]
void EaxFxSlots::fail(
const char* message)

View File

@ -33,9 +33,6 @@ public:
ALeffectslot& get(
EaxFxSlotIndex index);
void unlock_legacy() noexcept;
private:
using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;

View File

@ -6,6 +6,8 @@
#include <string>
#include <type_traits>
using EaxDirtyFlags = unsigned int;
struct EaxAlLowPassParam {
float gain;
float gain_hf;

View File

@ -127,7 +127,7 @@ public:
class EaxAutoWahEffect final : public EaxEffect4<EaxAutoWahEffectException, EAXAUTOWAHPROPERTIES> {
public:
EaxAutoWahEffect(const EaxCall& call);
EaxAutoWahEffect(int eax_version);
private:
struct AttackTimeValidator {
@ -197,8 +197,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxAutoWahEffect
EaxAutoWahEffect::EaxAutoWahEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_AUTOWAH, call}
EaxAutoWahEffect::EaxAutoWahEffect(int eax_version)
: EaxEffect4{AL_EFFECT_AUTOWAH, eax_version}
{}
void EaxAutoWahEffect::set_defaults(Props& props)
@ -310,9 +310,9 @@ bool EaxAutoWahEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_auto_wah_effect(int eax_version)
{
return eax_create_eax4_effect<EaxAutoWahEffect>(call);
return eax_create_eax4_effect<EaxAutoWahEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -433,8 +433,8 @@ public:
using typename Base::State;
using Base::defer;
EaxChorusFlangerEffect(const EaxCall& call)
: Base{Traits::efx_effect(), call}
EaxChorusFlangerEffect(int eax_version)
: Base{Traits::efx_effect(), eax_version}
{}
private:
@ -712,23 +712,23 @@ private:
}; // EaxChorusFlangerEffect
template<typename TTraits>
EaxEffectUPtr eax_create_eax_chorus_flanger_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_chorus_flanger_effect(int eax_version)
{
return eax_create_eax4_effect<EaxChorusFlangerEffect<TTraits>>(call);
return eax_create_eax4_effect<EaxChorusFlangerEffect<TTraits>>(eax_version);
}
} // namespace
// ==========================================================================
EaxEffectUPtr eax_create_eax_chorus_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_chorus_effect(int eax_version)
{
return eax_create_eax_chorus_flanger_effect<EaxChorusTraits>(call);
return eax_create_eax_chorus_flanger_effect<EaxChorusTraits>(eax_version);
}
EaxEffectUPtr eax_create_eax_flanger_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_flanger_effect(int eax_version)
{
return eax_create_eax_chorus_flanger_effect<EaxFlangerTraits>(call);
return eax_create_eax_chorus_flanger_effect<EaxFlangerTraits>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -91,7 +91,7 @@ public:
class EaxCompressorEffect final : public EaxEffect4<EaxCompressorEffectException, EAXAGCCOMPRESSORPROPERTIES>
{
public:
EaxCompressorEffect(const EaxCall& call);
EaxCompressorEffect(int eax_version);
private:
struct OnOffValidator {
@ -122,8 +122,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxCompressorEffect
EaxCompressorEffect::EaxCompressorEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_COMPRESSOR, call}
EaxCompressorEffect::EaxCompressorEffect(int eax_version)
: EaxEffect4{AL_EFFECT_COMPRESSOR, eax_version}
{}
void EaxCompressorEffect::set_defaults(Props& props)
@ -182,9 +182,9 @@ bool EaxCompressorEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_compressor_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_compressor_effect(int eax_version)
{
return eax_create_eax4_effect<EaxCompressorEffect>(call);
return eax_create_eax4_effect<EaxCompressorEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -133,7 +133,7 @@ public:
class EaxDistortionEffect final : public EaxEffect4<EaxDistortionEffectException, EAXDISTORTIONPROPERTIES>
{
public:
EaxDistortionEffect(const EaxCall& call);
EaxDistortionEffect(int eax_version);
private:
struct EdgeValidator {
@ -216,8 +216,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxDistortionEffect
EaxDistortionEffect::EaxDistortionEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_DISTORTION, call}
EaxDistortionEffect::EaxDistortionEffect(int eax_version)
: EaxEffect4{AL_EFFECT_DISTORTION, eax_version}
{}
void EaxDistortionEffect::set_defaults(Props& props)
@ -347,9 +347,9 @@ bool EaxDistortionEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_distortion_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_distortion_effect(int eax_version)
{
return eax_create_eax4_effect<EaxDistortionEffect>(call);
return eax_create_eax4_effect<EaxDistortionEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -130,7 +130,7 @@ public:
class EaxEchoEffect final : public EaxEffect4<EaxEchoEffectException, EAXECHOPROPERTIES>
{
public:
EaxEchoEffect(const EaxCall& call);
EaxEchoEffect(int eax_version);
private:
struct DelayValidator {
@ -213,8 +213,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxEchoEffect
EaxEchoEffect::EaxEchoEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_ECHO, call}
EaxEchoEffect::EaxEchoEffect(int eax_version)
: EaxEffect4{AL_EFFECT_ECHO, eax_version}
{}
void EaxEchoEffect::set_defaults(Props& props)
@ -344,9 +344,9 @@ bool EaxEchoEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_echo_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_echo_effect(int eax_version)
{
return eax_create_eax4_effect<EaxEchoEffect>(call);
return eax_create_eax4_effect<EaxEchoEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -1,16 +1,12 @@
#include "config.h"
#ifdef ALSOFT_EAX
#include <cassert>
#include "AL/efx.h"
#include "effects.h"
#include <cassert>
#include "AL/efx.h"
EaxEffectUPtr eax_create_eax_effect(ALenum al_effect_type, const EaxCall& call)
EaxEffectUPtr eax_create_eax_effect(ALenum al_effect_type, int eax_version)
{
#define EAX_PREFIX "[EAX_MAKE_EAX_EFFECT] "
@ -20,40 +16,40 @@ EaxEffectUPtr eax_create_eax_effect(ALenum al_effect_type, const EaxCall& call)
return eax_create_eax_null_effect();
case AL_EFFECT_CHORUS:
return eax_create_eax_chorus_effect(call);
return eax_create_eax_chorus_effect(eax_version);
case AL_EFFECT_DISTORTION:
return eax_create_eax_distortion_effect(call);
return eax_create_eax_distortion_effect(eax_version);
case AL_EFFECT_ECHO:
return eax_create_eax_echo_effect(call);
return eax_create_eax_echo_effect(eax_version);
case AL_EFFECT_FLANGER:
return eax_create_eax_flanger_effect(call);
return eax_create_eax_flanger_effect(eax_version);
case AL_EFFECT_FREQUENCY_SHIFTER:
return eax_create_eax_frequency_shifter_effect(call);
return eax_create_eax_frequency_shifter_effect(eax_version);
case AL_EFFECT_VOCAL_MORPHER:
return eax_create_eax_vocal_morpher_effect(call);
return eax_create_eax_vocal_morpher_effect(eax_version);
case AL_EFFECT_PITCH_SHIFTER:
return eax_create_eax_pitch_shifter_effect(call);
return eax_create_eax_pitch_shifter_effect(eax_version);
case AL_EFFECT_RING_MODULATOR:
return eax_create_eax_ring_modulator_effect(call);
return eax_create_eax_ring_modulator_effect(eax_version);
case AL_EFFECT_AUTOWAH:
return eax_create_eax_auto_wah_effect(call);
return eax_create_eax_auto_wah_effect(eax_version);
case AL_EFFECT_COMPRESSOR:
return eax_create_eax_compressor_effect(call);
return eax_create_eax_compressor_effect(eax_version);
case AL_EFFECT_EQUALIZER:
return eax_create_eax_equalizer_effect(call);
return eax_create_eax_equalizer_effect(eax_version);
case AL_EFFECT_EAXREVERB:
return eax_create_eax_reverb_effect(call);
return eax_create_eax_reverb_effect(eax_version);
default:
assert(false && "Unsupported AL effect type.");

View File

@ -6,7 +6,6 @@
#include "core/except.h"
#ifdef ALSOFT_EAX
#include "al/eax/call.h"
#include "al/eax/effect.h"
#endif // ALSOFT_EAX
@ -87,7 +86,7 @@ extern const EffectVtable ConvolutionEffectVtable;
#ifdef ALSOFT_EAX
EaxEffectUPtr eax_create_eax_effect(ALenum al_effect_type, const EaxCall& call);
EaxEffectUPtr eax_create_eax_effect(ALenum al_effect_type, int eax_version);
#endif // ALSOFT_EAX
#endif /* AL_EFFECTS_EFFECTS_H */

View File

@ -188,7 +188,7 @@ public:
class EaxEqualizerEffect final : public EaxEffect4<EaxEqualizerEffectException, EAXEQUALIZERPROPERTIES>
{
public:
EaxEqualizerEffect(const EaxCall& call);
EaxEqualizerEffect(int eax_version);
private:
struct LowGainValidator {
@ -336,8 +336,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxEqualizerEffect
EaxEqualizerEffect::EaxEqualizerEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_EQUALIZER, call}
EaxEqualizerEffect::EaxEqualizerEffect(int eax_version)
: EaxEffect4{AL_EFFECT_EQUALIZER, eax_version}
{}
void EaxEqualizerEffect::set_defaults(Props& props)
@ -557,9 +557,9 @@ bool EaxEqualizerEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_equalizer_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_equalizer_effect(int eax_version)
{
return eax_create_eax4_effect<EaxEqualizerEffect>(call);
return eax_create_eax4_effect<EaxEqualizerEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -149,7 +149,7 @@ public:
class EaxFrequencyShifterEffect final : public EaxEffect4<EaxFrequencyShifterEffectException, EAXFREQUENCYSHIFTERPROPERTIES> {
public:
EaxFrequencyShifterEffect(const EaxCall& call);
EaxFrequencyShifterEffect(int eax_version);
private:
struct FrequencyValidator {
@ -207,8 +207,8 @@ private:
}; // EaxFrequencyShifterEffect
EaxFrequencyShifterEffect::EaxFrequencyShifterEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_FREQUENCY_SHIFTER, call}
EaxFrequencyShifterEffect::EaxFrequencyShifterEffect(int eax_version)
: EaxEffect4{AL_EFFECT_FREQUENCY_SHIFTER, eax_version}
{}
void EaxFrequencyShifterEffect::set_defaults(Props& props)
@ -308,9 +308,9 @@ bool EaxFrequencyShifterEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_frequency_shifter_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_frequency_shifter_effect(int eax_version)
{
return eax_create_eax4_effect<EaxFrequencyShifterEffect>(call);
return eax_create_eax4_effect<EaxFrequencyShifterEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -156,7 +156,7 @@ public:
class EaxRingModulatorEffect final : public EaxEffect4<EaxRingModulatorEffectException, EAXRINGMODULATORPROPERTIES>
{
public:
EaxRingModulatorEffect(const EaxCall& call);
EaxRingModulatorEffect(int eax_version);
private:
struct FrequencyValidator {
@ -213,8 +213,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxRingModulatorEffect
EaxRingModulatorEffect::EaxRingModulatorEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_RING_MODULATOR, call}
EaxRingModulatorEffect::EaxRingModulatorEffect(int eax_version)
: EaxEffect4{AL_EFFECT_RING_MODULATOR, eax_version}
{}
void EaxRingModulatorEffect::set_defaults(Props& props)
@ -311,9 +311,9 @@ bool EaxRingModulatorEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_ring_modulator_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_ring_modulator_effect(int eax_version)
{
return eax_create_eax4_effect<EaxRingModulatorEffect>(call);
return eax_create_eax4_effect<EaxRingModulatorEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -102,7 +102,7 @@ public:
class EaxPitchShifterEffect final : public EaxEffect4<EaxPitchShifterEffectException, EAXPITCHSHIFTERPROPERTIES> {
public:
EaxPitchShifterEffect(const EaxCall& call);
EaxPitchShifterEffect(int eax_version);
private:
struct CoarseTuneValidator {
@ -146,8 +146,8 @@ private:
bool commit_props(const Props& old_i) override;
}; // EaxPitchShifterEffect
EaxPitchShifterEffect::EaxPitchShifterEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_PITCH_SHIFTER, call}
EaxPitchShifterEffect::EaxPitchShifterEffect(int eax_version)
: EaxEffect4{AL_EFFECT_PITCH_SHIFTER, eax_version}
{}
void EaxPitchShifterEffect::set_defaults(Props& props)
@ -223,9 +223,9 @@ bool EaxPitchShifterEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_pitch_shifter_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_pitch_shifter_effect(int eax_version)
{
return eax_create_eax4_effect<EaxPitchShifterEffect>(call);
return eax_create_eax4_effect<EaxPitchShifterEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -577,7 +577,7 @@ public:
class EaxReverbEffect final : public EaxEffect
{
public:
EaxReverbEffect(const EaxCall& call) noexcept;
EaxReverbEffect(int eax_version) noexcept;
void dispatch(const EaxCall& call) override;
/*[[nodiscard]]*/ bool commit() override;
@ -1194,8 +1194,8 @@ private:
static void translate(const Props2& src, Props3& dst) noexcept;
}; // EaxReverbEffect
EaxReverbEffect::EaxReverbEffect(const EaxCall& call) noexcept
: EaxEffect{AL_EFFECT_EAXREVERB}, version_{call.get_version()}
EaxReverbEffect::EaxReverbEffect(int eax_version) noexcept
: EaxEffect{AL_EFFECT_EAXREVERB}, version_{eax_version}
{
set_defaults();
set_current_defaults();
@ -1986,9 +1986,9 @@ void EaxReverbEffect::translate(const Props2& src, Props3& dst) noexcept
} // namespace
EaxEffectUPtr eax_create_eax_reverb_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_reverb_effect(int eax_version)
{
return std::make_unique<EaxReverbEffect>(call);
return std::make_unique<EaxReverbEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -267,7 +267,7 @@ public:
class EaxVocalMorpherEffect final : public EaxEffect4<EaxVocalMorpherEffectException, EAXVOCALMORPHERPROPERTIES> {
public:
EaxVocalMorpherEffect(const EaxCall& call);
EaxVocalMorpherEffect(int eax_version);
private:
struct PhonemeAValidator {
@ -363,8 +363,8 @@ private:
bool commit_props(const Props& props) override;
}; // EaxVocalMorpherEffect
EaxVocalMorpherEffect::EaxVocalMorpherEffect(const EaxCall& call)
: EaxEffect4{AL_EFFECT_VOCAL_MORPHER, call}
EaxVocalMorpherEffect::EaxVocalMorpherEffect(int eax_version)
: EaxEffect4{AL_EFFECT_VOCAL_MORPHER, eax_version}
{}
void EaxVocalMorpherEffect::set_defaults(Props& props)
@ -570,9 +570,9 @@ bool EaxVocalMorpherEffect::commit_props(const Props& props)
} // namespace
EaxEffectUPtr eax_create_eax_vocal_morpher_effect(const EaxCall& call)
EaxEffectUPtr eax_create_eax_vocal_morpher_effect(int eax_version)
{
return eax_create_eax4_effect<EaxVocalMorpherEffect>(call);
return eax_create_eax4_effect<EaxVocalMorpherEffect>(eax_version);
}
#endif // ALSOFT_EAX

View File

@ -339,7 +339,6 @@ ALenum ALCcontext::eax_eax_set(
property_value_size);
eax_version_ = call.get_version();
eax_initialize(call);
eax_unlock_legacy_fx_slots(call);
switch (call.get_property_set_id())
{
@ -360,8 +359,7 @@ ALenum ALCcontext::eax_eax_set(
eax_fail("Unsupported property set id.");
}
static constexpr auto deferred_flag = 0x80000000u;
if(!(property_id&deferred_flag) && !mDeferUpdates)
if(!call.is_deferred() && !mDeferUpdates)
applyAllUpdates();
return AL_NO_ERROR;
@ -383,7 +381,6 @@ ALenum ALCcontext::eax_eax_get(
property_value_size);
eax_version_ = call.get_version();
eax_initialize(call);
eax_unlock_legacy_fx_slots(call);
switch (call.get_property_set_id())
{
@ -501,6 +498,9 @@ void ALCcontext::eax_initialize(const EaxCall& call)
eax_initialize_sources();
eax_is_initialized_ = true;
if(!mDeferUpdates)
applyAllUpdates();
}
bool ALCcontext::eax_has_no_default_effect_slot() const noexcept
@ -603,15 +603,6 @@ void ALCcontext::eax_set_defaults() noexcept
eax_d_ = eax_;
}
void ALCcontext::eax_unlock_legacy_fx_slots(const EaxCall& call) noexcept
{
if (call.get_version() != 5 || eax_are_legacy_fx_slots_unlocked_)
return;
eax_are_legacy_fx_slots_unlocked_ = true;
eax_fx_slots_.unlock_legacy();
}
void ALCcontext::eax_dispatch_fx_slot(const EaxCall& call)
{
const auto fx_slot_index = call.get_fx_slot_index();

View File

@ -251,7 +251,6 @@ private:
bool eax_is_initialized_{};
bool eax_is_tried_{};
bool eax_are_legacy_fx_slots_unlocked_{};
long eax_last_error_{};
unsigned long eax_speaker_config_{};
@ -305,9 +304,6 @@ private:
void eax_initialize_sources();
void eax_unlock_legacy_fx_slots(const EaxCall& call) noexcept;
void eax_dispatch_fx_slot(const EaxCall& call);
void eax_dispatch_source(const EaxCall& call);