aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-07-12 12:46:51 +0300
committerGitHub <[email protected]>2022-07-12 02:46:51 -0700
commit6fb5cb553f4c2faf4b991ac377ec457a7bba7e4c (patch)
tree5b62a1111fa1a48f3a2e226b8491bc1615db865d /al
parentfa51c89549590319cb545a8c81419e2e1ddc5db3 (diff)
[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
Diffstat (limited to 'al')
-rw-r--r--al/auxeffectslot.cpp838
-rw-r--r--al/auxeffectslot.h370
-rw-r--r--al/eax/call.cpp1
-rw-r--r--al/eax/call.h2
-rw-r--r--al/eax/effect.h40
-rw-r--r--al/eax/fx_slots.cpp6
-rw-r--r--al/eax/fx_slots.h3
-rw-r--r--al/eax/utils.h2
-rw-r--r--al/effects/autowah.cpp10
-rw-r--r--al/effects/chorus.cpp16
-rw-r--r--al/effects/compressor.cpp10
-rw-r--r--al/effects/distortion.cpp10
-rw-r--r--al/effects/echo.cpp10
-rw-r--r--al/effects/effects.cpp32
-rw-r--r--al/effects/effects.h3
-rw-r--r--al/effects/equalizer.cpp10
-rw-r--r--al/effects/fshifter.cpp10
-rw-r--r--al/effects/modulator.cpp10
-rw-r--r--al/effects/pshifter.cpp10
-rw-r--r--al/effects/reverb.cpp10
-rw-r--r--al/effects/vmorpher.cpp10
21 files changed, 676 insertions, 737 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index d37168e7..8a5915a6 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -50,11 +50,6 @@
#include "effect.h"
#include "opthelpers.h"
-#ifdef ALSOFT_EAX
-#include "eax/exception.h"
-#include "eax/utils.h"
-#endif // ALSOFT_EAX
-
namespace {
struct FactoryItem {
@@ -1057,667 +1052,500 @@ EffectSlotSubList::~EffectSlotSubList()
}
#ifdef ALSOFT_EAX
-namespace {
-
-class EaxFxSlotException :
- public EaxException
-{
-public:
- explicit EaxFxSlotException(
- const char* message)
- :
- EaxException{"EAX_FX_SLOT", message}
- {
- }
-}; // EaxFxSlotException
-
-
-} // namespace
-
-
void ALeffectslot::eax_initialize(
const EaxCall& call,
ALCcontext& al_context,
EaxFxSlotIndexValue index)
{
- eax_al_context_ = &al_context;
-
- if (index >= EAX_MAX_FXSLOTS)
- {
+ if(index >= EAX_MAX_FXSLOTS)
eax_fail("Index out of range.");
- }
+ mPropsDirty = true;
+ eax_al_context_ = &al_context;
eax_fx_slot_index_ = index;
-
- eax_initialize_eax();
- eax_initialize_lock();
- eax_initialize_effects(call);
+ eax_version_ = call.get_version();
+ eax_fx_slot_set_defaults();
}
const EAX50FXSLOTPROPERTIES& ALeffectslot::eax_get_eax_fx_slot() const noexcept
{
- return eax_eax_fx_slot_;
+ return eax_;
}
-void ALeffectslot::eax_ensure_is_unlocked() const
+void ALeffectslot::eax_commit()
{
- if (eax_is_locked_)
- eax_fail("Locked.");
-}
+ auto df = EaxDirtyFlags{};
-void ALeffectslot::eax_validate_fx_slot_effect(const GUID& eax_effect_id)
-{
- eax_ensure_is_unlocked();
-
- if (eax_effect_id != EAX_NULL_GUID &&
- eax_effect_id != EAX_REVERB_EFFECT &&
- eax_effect_id != EAX_AGCCOMPRESSOR_EFFECT &&
- eax_effect_id != EAX_AUTOWAH_EFFECT &&
- eax_effect_id != EAX_CHORUS_EFFECT &&
- eax_effect_id != EAX_DISTORTION_EFFECT &&
- eax_effect_id != EAX_ECHO_EFFECT &&
- eax_effect_id != EAX_EQUALIZER_EFFECT &&
- eax_effect_id != EAX_FLANGER_EFFECT &&
- eax_effect_id != EAX_FREQUENCYSHIFTER_EFFECT &&
- eax_effect_id != EAX_VOCALMORPHER_EFFECT &&
- eax_effect_id != EAX_PITCHSHIFTER_EFFECT &&
- eax_effect_id != EAX_RINGMODULATOR_EFFECT)
+ switch(eax_version_)
{
- eax_fail("Unsupported EAX effect GUID.");
+ case 1:
+ case 2:
+ case 3:
+ eax5_fx_slot_commit(eax123_, df);
+ break;
+ case 4:
+ eax4_fx_slot_commit(df);
+ break;
+ case 5:
+ eax5_fx_slot_commit(eax5_, df);
+ break;
+ default:
+ eax_fail_unknown_version();
}
-}
-void ALeffectslot::eax_validate_fx_slot_volume(long eax_volume)
-{
- eax_validate_range<EaxFxSlotException>(
- "Volume",
- eax_volume,
- EAXFXSLOT_MINVOLUME,
- EAXFXSLOT_MAXVOLUME);
-}
+ if(df == EaxDirtyFlags{}) {
+ if(eax_effect_ != nullptr && eax_effect_->commit())
+ eax_set_efx_slot_effect(*eax_effect_);
-void ALeffectslot::eax_validate_fx_slot_lock(long eax_lock)
-{
- eax_ensure_is_unlocked();
+ return;
+ }
- eax_validate_range<EaxFxSlotException>(
- "Lock",
- eax_lock,
- EAXFXSLOT_MINLOCK,
- EAXFXSLOT_MAXLOCK);
-}
+ if((df & eax_load_effect_dirty_bit) != EaxDirtyFlags{})
+ eax_fx_slot_load_effect();
+ else {
+ if(eax_effect_ != nullptr && eax_effect_->commit())
+ eax_set_efx_slot_effect(*eax_effect_);
+ }
-void ALeffectslot::eax_validate_fx_slot_flags(const EaxCall& call, unsigned long eax_flags)
-{
- eax_validate_range<EaxFxSlotException>(
- "Flags",
- eax_flags,
- 0UL,
- ~(call.get_version() == 4 ? EAX40FXSLOTFLAGS_RESERVED : EAX50FXSLOTFLAGS_RESERVED));
-}
+ if((df & eax_volume_dirty_bit) != EaxDirtyFlags{})
+ eax_fx_slot_set_volume();
-void ALeffectslot::eax_validate_fx_slot_occlusion(long eax_occlusion)
-{
- eax_validate_range<EaxFxSlotException>(
- "Occlusion",
- eax_occlusion,
- EAXFXSLOT_MINOCCLUSION,
- EAXFXSLOT_MAXOCCLUSION);
+ if((df & eax_flags_dirty_bit) != EaxDirtyFlags{})
+ eax_fx_slot_set_flags();
}
-void ALeffectslot::eax_validate_fx_slot_occlusion_lf_ratio(float eax_occlusion_lf_ratio)
+[[noreturn]] void ALeffectslot::eax_fail(const char* message)
{
- eax_validate_range<EaxFxSlotException>(
- "Occlusion LF Ratio",
- eax_occlusion_lf_ratio,
- EAXFXSLOT_MINOCCLUSIONLFRATIO,
- EAXFXSLOT_MAXOCCLUSIONLFRATIO);
+ throw Exception{message};
}
-void ALeffectslot::eax_validate_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& fx_slot)
+[[noreturn]] void ALeffectslot::eax_fail_unknown_effect_id()
{
- eax_validate_fx_slot_effect(fx_slot.guidLoadEffect);
- eax_validate_fx_slot_volume(fx_slot.lVolume);
- eax_validate_fx_slot_lock(fx_slot.lLock);
- eax_validate_fx_slot_flags(call, fx_slot.ulFlags);
+ eax_fail("Unknown effect ID.");
}
-void ALeffectslot::eax_validate_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& fx_slot)
+[[noreturn]] void ALeffectslot::eax_fail_unknown_property_id()
{
- eax_validate_fx_slot_all(call, static_cast<const EAX40FXSLOTPROPERTIES&>(fx_slot));
- eax_validate_fx_slot_occlusion(fx_slot.lOcclusion);
- eax_validate_fx_slot_occlusion_lf_ratio(fx_slot.flOcclusionLFRatio);
+ eax_fail("Unknown property ID.");
}
-void ALeffectslot::eax_set_fx_slot_effect(const EaxCall& call, const GUID& eax_effect_id)
+[[noreturn]] void ALeffectslot::eax_fail_unknown_version()
{
- if (eax_eax_fx_slot_.guidLoadEffect == eax_effect_id)
- {
- return;
- }
-
- eax_eax_fx_slot_.guidLoadEffect = eax_effect_id;
-
- eax_set_fx_slot_effect(call);
+ eax_fail("Unknown version.");
}
-void ALeffectslot::eax_set_fx_slot_volume(
- long eax_volume)
+void ALeffectslot::eax4_fx_slot_ensure_unlocked() const
{
- if (eax_eax_fx_slot_.lVolume == eax_volume)
- {
- return;
- }
-
- eax_eax_fx_slot_.lVolume = eax_volume;
-
- eax_set_fx_slot_volume();
+ if(eax4_fx_slot_is_legacy())
+ eax_fail("Locked legacy slot.");
}
-void ALeffectslot::eax_set_fx_slot_lock(
- long eax_lock)
+ALenum ALeffectslot::eax_get_efx_effect_type(const GUID& guid)
{
- if (eax_eax_fx_slot_.lLock == eax_lock)
- {
- return;
- }
+ if(guid == EAX_NULL_GUID)
+ return AL_EFFECT_NULL;
+ if(guid == EAX_AUTOWAH_EFFECT)
+ return AL_EFFECT_AUTOWAH;
+ if(guid == EAX_CHORUS_EFFECT)
+ return AL_EFFECT_CHORUS;
+ if(guid == EAX_AGCCOMPRESSOR_EFFECT)
+ return AL_EFFECT_COMPRESSOR;
+ if(guid == EAX_DISTORTION_EFFECT)
+ return AL_EFFECT_DISTORTION;
+ if(guid == EAX_REVERB_EFFECT)
+ return AL_EFFECT_EAXREVERB;
+ if(guid == EAX_ECHO_EFFECT)
+ return AL_EFFECT_ECHO;
+ if(guid == EAX_EQUALIZER_EFFECT)
+ return AL_EFFECT_EQUALIZER;
+ if(guid == EAX_FLANGER_EFFECT)
+ return AL_EFFECT_FLANGER;
+ if(guid == EAX_FREQUENCYSHIFTER_EFFECT)
+ return AL_EFFECT_FREQUENCY_SHIFTER;
+ if(guid == EAX_PITCHSHIFTER_EFFECT)
+ return AL_EFFECT_PITCH_SHIFTER;
+ if(guid == EAX_RINGMODULATOR_EFFECT)
+ return AL_EFFECT_RING_MODULATOR;
+ if(guid == EAX_VOCALMORPHER_EFFECT)
+ return AL_EFFECT_VOCAL_MORPHER;
- eax_eax_fx_slot_.lLock = eax_lock;
+ eax_fail_unknown_effect_id();
}
-void ALeffectslot::eax_set_fx_slot_flags(
- unsigned long eax_flags)
+const GUID& ALeffectslot::eax_get_eax_default_effect_guid() const noexcept
{
- if (eax_eax_fx_slot_.ulFlags == eax_flags)
+ switch(eax_fx_slot_index_)
{
- return;
+ case 0: return EAX_REVERB_EFFECT;
+ case 1: return EAX_CHORUS_EFFECT;
+ default: return EAX_NULL_GUID;
}
-
- eax_eax_fx_slot_.ulFlags = eax_flags;
-
- eax_set_fx_slot_flags();
}
-// [[nodiscard]]
-bool ALeffectslot::eax_set_fx_slot_occlusion(
- long eax_occlusion)
+long ALeffectslot::eax_get_eax_default_lock() const noexcept
{
- if (eax_eax_fx_slot_.lOcclusion == eax_occlusion)
- {
- return false;
- }
-
- eax_eax_fx_slot_.lOcclusion = eax_occlusion;
-
- return true;
+ return eax4_fx_slot_is_legacy() ? EAXFXSLOT_LOCKED : EAXFXSLOT_UNLOCKED;
}
-// [[nodiscard]]
-bool ALeffectslot::eax_set_fx_slot_occlusion_lf_ratio(
- float eax_occlusion_lf_ratio)
+void ALeffectslot::eax4_fx_slot_set_defaults(Eax4Props& props)
{
- if (eax_eax_fx_slot_.flOcclusionLFRatio == eax_occlusion_lf_ratio)
- {
- return false;
- }
-
- eax_eax_fx_slot_.flOcclusionLFRatio = eax_occlusion_lf_ratio;
-
- return true;
+ props.guidLoadEffect = eax_get_eax_default_effect_guid();
+ props.lVolume = EAXFXSLOT_DEFAULTVOLUME;
+ props.lLock = eax_get_eax_default_lock();
+ props.ulFlags = EAX40FXSLOT_DEFAULTFLAGS;
}
-void ALeffectslot::eax_set_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& eax_fx_slot)
+void ALeffectslot::eax4_fx_slot_set_defaults()
{
- eax_set_fx_slot_effect(call, eax_fx_slot.guidLoadEffect);
- eax_set_fx_slot_volume(eax_fx_slot.lVolume);
- eax_set_fx_slot_lock(eax_fx_slot.lLock);
- eax_set_fx_slot_flags(eax_fx_slot.ulFlags);
+ eax4_fx_slot_set_defaults(eax4_.i);
+ eax4_.df = ~EaxDirtyFlags{};
}
-// [[nodiscard]]
-bool ALeffectslot::eax_set_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& eax_fx_slot)
+void ALeffectslot::eax5_fx_slot_set_defaults(Eax5Props& props)
{
- eax_set_fx_slot_all(call, static_cast<const EAX40FXSLOTPROPERTIES&>(eax_fx_slot));
-
- const auto is_occlusion_modified = eax_set_fx_slot_occlusion(eax_fx_slot.lOcclusion);
- const auto is_occlusion_lf_ratio_modified = eax_set_fx_slot_occlusion_lf_ratio(eax_fx_slot.flOcclusionLFRatio);
-
- return is_occlusion_modified || is_occlusion_lf_ratio_modified;
+ eax4_fx_slot_set_defaults(static_cast<Eax4Props&>(props));
+ props.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
+ props.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
}
-void ALeffectslot::eax_unlock_legacy() noexcept
+void ALeffectslot::eax5_fx_slot_set_defaults()
{
- assert(eax_fx_slot_index_ < 2);
- eax_is_locked_ = false;
- eax_eax_fx_slot_.lLock = EAXFXSLOT_UNLOCKED;
+ eax5_fx_slot_set_defaults(eax5_.i);
+ eax5_.df = ~EaxDirtyFlags{};
}
-[[noreturn]]
-void ALeffectslot::eax_fail(
- const char* message)
+void ALeffectslot::eax_fx_slot_set_defaults()
{
- throw EaxFxSlotException{message};
+ eax4_fx_slot_set_defaults();
+ eax5_fx_slot_set_defaults();
+ eax123_ = eax5_;
+ eax_ = eax5_.i;
}
-GUID ALeffectslot::eax_get_eax_default_effect_guid() const noexcept
+void ALeffectslot::eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props) const
{
- switch (eax_fx_slot_index_)
+ switch(call.get_property_id())
{
- case 0: return EAX_REVERB_EFFECT;
- case 1: return EAX_CHORUS_EFFECT;
- default: return EAX_NULL_GUID;
+ case EAXFXSLOT_ALLPARAMETERS:
+ call.set_value<Exception>(props);
+ break;
+ case EAXFXSLOT_LOADEFFECT:
+ call.set_value<Exception>(props.guidLoadEffect);
+ break;
+ case EAXFXSLOT_VOLUME:
+ call.set_value<Exception>(props.lVolume);
+ break;
+ case EAXFXSLOT_LOCK:
+ call.set_value<Exception>(props.lLock);
+ break;
+ case EAXFXSLOT_FLAGS:
+ call.set_value<Exception>(props.ulFlags);
+ break;
+ default:
+ eax_fail_unknown_property_id();
}
}
-long ALeffectslot::eax_get_eax_default_lock() const noexcept
+void ALeffectslot::eax5_fx_slot_get(const EaxCall& call, const Eax5Props& props) const
{
- return eax_fx_slot_index_ < 2 ? EAXFXSLOT_LOCKED : EAXFXSLOT_UNLOCKED;
-}
-
-void ALeffectslot::eax_set_eax_fx_slot_defaults()
-{
- eax_eax_fx_slot_.guidLoadEffect = eax_get_eax_default_effect_guid();
- eax_eax_fx_slot_.lVolume = EAXFXSLOT_DEFAULTVOLUME;
- eax_eax_fx_slot_.lLock = eax_get_eax_default_lock();
- eax_eax_fx_slot_.ulFlags = EAX40FXSLOT_DEFAULTFLAGS;
- eax_eax_fx_slot_.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
- eax_eax_fx_slot_.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
-}
-
-void ALeffectslot::eax_initialize_eax()
-{
- eax_set_eax_fx_slot_defaults();
-}
-
-void ALeffectslot::eax_initialize_lock()
-{
- eax_is_locked_ = (eax_fx_slot_index_ < 2);
-}
-
-void ALeffectslot::eax_initialize_effects(const EaxCall& call)
-{
- eax_set_fx_slot_effect(call);
-}
-
-void ALeffectslot::eax_get_fx_slot_all(const EaxCall& call) const
-{
- switch (call.get_version())
+ switch(call.get_property_id())
{
- case 4:
- call.set_value<EaxFxSlotException, EAX40FXSLOTPROPERTIES>(eax_eax_fx_slot_);
- break;
-
- case 5:
- call.set_value<EaxFxSlotException, EAX50FXSLOTPROPERTIES>(eax_eax_fx_slot_);
- break;
-
- default:
- eax_fail("Unsupported EAX version.");
+ case EAXFXSLOT_ALLPARAMETERS:
+ call.set_value<Exception>(props);
+ break;
+ case EAXFXSLOT_LOADEFFECT:
+ call.set_value<Exception>(props.guidLoadEffect);
+ break;
+ case EAXFXSLOT_VOLUME:
+ call.set_value<Exception>(props.lVolume);
+ break;
+ case EAXFXSLOT_LOCK:
+ call.set_value<Exception>(props.lLock);
+ break;
+ case EAXFXSLOT_FLAGS:
+ call.set_value<Exception>(props.ulFlags);
+ break;
+ case EAXFXSLOT_OCCLUSION:
+ call.set_value<Exception>(props.lOcclusion);
+ break;
+ case EAXFXSLOT_OCCLUSIONLFRATIO:
+ call.set_value<Exception>(props.flOcclusionLFRatio);
+ break;
+ default:
+ eax_fail_unknown_property_id();
}
}
-void ALeffectslot::eax_get_fx_slot(const EaxCall& call) const
+void ALeffectslot::eax_fx_slot_get(const EaxCall& call) const
{
- switch (call.get_property_id())
+ switch(call.get_version())
{
- case EAXFXSLOT_ALLPARAMETERS:
- eax_get_fx_slot_all(call);
- break;
-
- case EAXFXSLOT_LOADEFFECT:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.guidLoadEffect);
- break;
-
- case EAXFXSLOT_VOLUME:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.lVolume);
- break;
-
- case EAXFXSLOT_LOCK:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.lLock);
- break;
-
- case EAXFXSLOT_FLAGS:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.ulFlags);
- break;
-
- case EAXFXSLOT_OCCLUSION:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.lOcclusion);
- break;
-
- case EAXFXSLOT_OCCLUSIONLFRATIO:
- call.set_value<EaxFxSlotException>(eax_eax_fx_slot_.flOcclusionLFRatio);
- break;
-
- default:
- eax_fail("Unsupported FX slot property id.");
+ case 4: eax4_fx_slot_get(call, eax4_.i); break;
+ case 5: eax4_fx_slot_get(call, eax5_.i); break;
+ default: eax_fail_unknown_version();
}
}
-// [[nodiscard]]
bool ALeffectslot::eax_get(const EaxCall& call)
{
- switch (call.get_property_set_id())
+ switch(call.get_property_set_id())
{
- case EaxCallPropertySetId::fx_slot:
- eax_get_fx_slot(call);
- break;
-
- case EaxCallPropertySetId::fx_slot_effect:
- eax_dispatch_effect(call);
- break;
-
- default:
- eax_fail("Unsupported property id.");
+ case EaxCallPropertySetId::fx_slot:
+ eax_fx_slot_get(call);
+ break;
+ case EaxCallPropertySetId::fx_slot_effect:
+ eax_dispatch_effect(call);
+ break;
+ default:
+ eax_fail_unknown_property_id();
}
return false;
}
-void ALeffectslot::eax_set_fx_slot_effect(const EaxCall& call, ALenum al_effect_type)
+void ALeffectslot::eax_fx_slot_load_effect()
{
- if(!IsValidEffectType(al_effect_type))
- eax_fail("Unsupported effect.");
-
eax_effect_ = nullptr;
- eax_effect_ = eax_create_eax_effect(al_effect_type, call);
-
- eax_set_effect_slot_effect(*eax_effect_);
-}
-
-void ALeffectslot::eax_set_fx_slot_effect(const EaxCall& call)
-{
- auto al_effect_type = ALenum{};
-
- if (false)
- {
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_NULL_GUID)
- {
- al_effect_type = AL_EFFECT_NULL;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_AUTOWAH_EFFECT)
- {
- al_effect_type = AL_EFFECT_AUTOWAH;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_CHORUS_EFFECT)
- {
- al_effect_type = AL_EFFECT_CHORUS;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_AGCCOMPRESSOR_EFFECT)
- {
- al_effect_type = AL_EFFECT_COMPRESSOR;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_DISTORTION_EFFECT)
- {
- al_effect_type = AL_EFFECT_DISTORTION;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_REVERB_EFFECT)
- {
- al_effect_type = AL_EFFECT_EAXREVERB;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_ECHO_EFFECT)
- {
- al_effect_type = AL_EFFECT_ECHO;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_EQUALIZER_EFFECT)
- {
- al_effect_type = AL_EFFECT_EQUALIZER;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_FLANGER_EFFECT)
- {
- al_effect_type = AL_EFFECT_FLANGER;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_FREQUENCYSHIFTER_EFFECT)
- {
- al_effect_type = AL_EFFECT_FREQUENCY_SHIFTER;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_PITCHSHIFTER_EFFECT)
- {
- al_effect_type = AL_EFFECT_PITCH_SHIFTER;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_RINGMODULATOR_EFFECT)
- {
- al_effect_type = AL_EFFECT_RING_MODULATOR;
- }
- else if (eax_eax_fx_slot_.guidLoadEffect == EAX_VOCALMORPHER_EFFECT)
- {
- al_effect_type = AL_EFFECT_VOCAL_MORPHER;
- }
- else
- {
- eax_fail("Unsupported effect.");
- }
-
- eax_set_fx_slot_effect(call, al_effect_type);
-}
+ const auto efx_effect_type = eax_get_efx_effect_type(eax_.guidLoadEffect);
-void ALeffectslot::eax_set_efx_effect_slot_gain()
-{
- const auto gain = level_mb_to_gain(
- static_cast<float>(clamp(
- eax_eax_fx_slot_.lVolume,
- EAXFXSLOT_MINVOLUME,
- EAXFXSLOT_MAXVOLUME)));
+ if(!IsValidEffectType(efx_effect_type))
+ eax_fail("Invalid effect type.");
- eax_set_effect_slot_gain(gain);
+ eax_effect_ = eax_create_eax_effect(efx_effect_type, eax_version_);
+ eax_set_efx_slot_effect(*eax_effect_);
}
-void ALeffectslot::eax_set_fx_slot_volume()
+void ALeffectslot::eax_fx_slot_set_volume()
{
- eax_set_efx_effect_slot_gain();
+ const auto volume = clamp(eax_.lVolume, EAXFXSLOT_MINVOLUME, EAXFXSLOT_MAXVOLUME);
+ const auto gain = level_mb_to_gain(static_cast<float>(volume));
+ eax_set_efx_slot_gain(gain);
}
-void ALeffectslot::eax_set_effect_slot_send_auto()
+void ALeffectslot::eax_fx_slot_set_environment_flag()
{
- eax_set_effect_slot_send_auto((eax_eax_fx_slot_.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0);
+ eax_set_efx_slot_send_auto((eax_.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0u);
}
-void ALeffectslot::eax_set_fx_slot_flags()
+void ALeffectslot::eax_fx_slot_set_flags()
{
- eax_set_effect_slot_send_auto();
+ eax_fx_slot_set_environment_flag();
}
-void ALeffectslot::eax_defer_fx_slot_effect(const EaxCall& call)
+void ALeffectslot::eax4_fx_slot_set_all(const EaxCall& call)
{
- const auto& eax_effect_id =
- call.get_value<EaxFxSlotException, const decltype(EAX40FXSLOTPROPERTIES::guidLoadEffect)>();
-
- eax_validate_fx_slot_effect(eax_effect_id);
- eax_set_fx_slot_effect(call, eax_effect_id);
+ eax4_fx_slot_ensure_unlocked();
+ const auto& src = call.get_value<Exception, const EAX40FXSLOTPROPERTIES>();
+ Eax4AllValidator{}(src);
+ auto& dst = eax4_.i;
+ auto& df = eax4_.df;
+ df |= eax_load_effect_dirty_bit; // Always reset the effect.
+ df |= (dst.lVolume != src.lVolume ? eax_volume_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.lLock != src.lLock ? eax_lock_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.ulFlags != src.ulFlags ? eax_flags_dirty_bit : EaxDirtyFlags{});
+ dst = src;
}
-void ALeffectslot::eax_defer_fx_slot_volume(const EaxCall& call)
+void ALeffectslot::eax5_fx_slot_set_all(const EaxCall& call)
{
- const auto& eax_volume =
- call.get_value<EaxFxSlotException, const decltype(EAX40FXSLOTPROPERTIES::lVolume)>();
-
- eax_validate_fx_slot_volume(eax_volume);
- eax_set_fx_slot_volume(eax_volume);
-}
-
-void ALeffectslot::eax_defer_fx_slot_lock(const EaxCall& call)
-{
- const auto& eax_lock =
- call.get_value<EaxFxSlotException, const decltype(EAX40FXSLOTPROPERTIES::lLock)>();
-
- eax_validate_fx_slot_lock(eax_lock);
- eax_set_fx_slot_lock(eax_lock);
-}
-
-void ALeffectslot::eax_defer_fx_slot_flags(const EaxCall& call)
-{
- const auto& eax_flags =
- call.get_value<EaxFxSlotException, const decltype(EAX40FXSLOTPROPERTIES::ulFlags)>();
-
- eax_validate_fx_slot_flags(call, eax_flags);
- eax_set_fx_slot_flags(eax_flags);
+ const auto& src = call.get_value<Exception, const EAX50FXSLOTPROPERTIES>();
+ Eax5AllValidator{}(src);
+ auto& dst = eax5_.i;
+ auto& df = eax5_.df;
+ df |= eax_load_effect_dirty_bit; // Always reset the effect.
+ df |= (dst.lVolume != src.lVolume ? eax_volume_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.lLock != src.lLock ? eax_lock_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.ulFlags != src.ulFlags ? eax_flags_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.lOcclusion != src.lOcclusion ? eax_flags_dirty_bit : EaxDirtyFlags{});
+ df |= (dst.flOcclusionLFRatio != src.flOcclusionLFRatio ? eax_flags_dirty_bit : EaxDirtyFlags{});
+ dst = src;
}
-// [[nodiscard]]
-bool ALeffectslot::eax_defer_fx_slot_occlusion(const EaxCall& call)
+// Returns `true` if all sources should be updated, or `false` otherwise.
+bool ALeffectslot::eax4_fx_slot_set(const EaxCall& call)
{
- const auto& eax_occlusion =
- call.get_value<EaxFxSlotException, const decltype(EAX50FXSLOTPROPERTIES::lOcclusion)>();
+ auto& df = eax4_.df;
+ auto& dst = eax4_.i;
- eax_validate_fx_slot_occlusion(eax_occlusion);
+ switch(call.get_property_id())
+ {
+ case EAXFXSLOT_NONE:
+ break;
+ case EAXFXSLOT_ALLPARAMETERS:
+ eax4_fx_slot_set_all(call);
+ break;
+ case EAXFXSLOT_LOADEFFECT:
+ eax4_fx_slot_ensure_unlocked();
+ eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call, dst.guidLoadEffect, df);
+ break;
+ case EAXFXSLOT_VOLUME:
+ eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, df);
+ break;
+ case EAXFXSLOT_LOCK:
+ eax4_fx_slot_ensure_unlocked();
+ eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, df);
+ break;
+ case EAXFXSLOT_FLAGS:
+ eax_fx_slot_set<Eax4FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, df);
+ break;
+ default:
+ eax_fail_unknown_property_id();
+ }
- return eax_set_fx_slot_occlusion(eax_occlusion);
+ return (df & (eax_occlusion_dirty_bit | eax_occlusion_lf_ratio_dirty_bit)) != EaxDirtyFlags{};
}
-// [[nodiscard]]
-bool ALeffectslot::eax_defer_fx_slot_occlusion_lf_ratio(const EaxCall& call)
+// Returns `true` if all sources should be updated, or `false` otherwise.
+bool ALeffectslot::eax5_fx_slot_set(const EaxCall& call)
{
- const auto& eax_occlusion_lf_ratio =
- call.get_value<EaxFxSlotException, const decltype(EAX50FXSLOTPROPERTIES::flOcclusionLFRatio)>();
+ auto& df = eax5_.df;
+ auto& dst = eax5_.i;
- eax_validate_fx_slot_occlusion_lf_ratio(eax_occlusion_lf_ratio);
+ switch(call.get_property_id())
+ {
+ case EAXFXSLOT_NONE:
+ break;
+ case EAXFXSLOT_ALLPARAMETERS:
+ eax5_fx_slot_set_all(call);
+ break;
+ case EAXFXSLOT_LOADEFFECT:
+ eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call, dst.guidLoadEffect, df);
+ break;
+ case EAXFXSLOT_VOLUME:
+ eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, df);
+ break;
+ case EAXFXSLOT_LOCK:
+ eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, df);
+ break;
+ case EAXFXSLOT_FLAGS:
+ eax_fx_slot_set<Eax4FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, df);
+ break;
+ case EAXFXSLOT_OCCLUSION:
+ eax_fx_slot_set<Eax5OcclusionValidator, eax_occlusion_dirty_bit>(call, dst.lOcclusion, df);
+ break;
+ case EAXFXSLOT_OCCLUSIONLFRATIO:
+ eax_fx_slot_set<Eax5OcclusionLfRatioValidator, eax_occlusion_lf_ratio_dirty_bit>(call, dst.flOcclusionLFRatio, df);
+ break;
+ default:
+ eax_fail_unknown_property_id();
+ }
- return eax_set_fx_slot_occlusion_lf_ratio(eax_occlusion_lf_ratio);
+ return (df & (eax_occlusion_dirty_bit | eax_occlusion_lf_ratio_dirty_bit)) != EaxDirtyFlags{};
}
-// [[nodiscard]]
-bool ALeffectslot::eax_defer_fx_slot_all(const EaxCall& call)
+// Returns `true` if all sources should be updated, or `false` otherwise.
+bool ALeffectslot::eax_fx_slot_set(const EaxCall& call)
{
switch (call.get_version())
{
- case 4:
- {
- const auto& eax_all =
- call.get_value<EaxFxSlotException, const EAX40FXSLOTPROPERTIES>();
-
- eax_validate_fx_slot_all(call, eax_all);
- eax_set_fx_slot_all(call, eax_all);
-
- return false;
- }
-
- case 5:
- {
- const auto& eax_all =
- call.get_value<EaxFxSlotException, const EAX50FXSLOTPROPERTIES>();
-
- eax_validate_fx_slot_all(call, eax_all);
- return eax_set_fx_slot_all(call, eax_all);
- }
-
- default:
- eax_fail("Unsupported EAX version.");
+ case 4: return eax4_fx_slot_set(call);
+ case 5: return eax5_fx_slot_set(call);
+ default: eax_fail_unknown_version();
}
}
-bool ALeffectslot::eax_set_fx_slot(const EaxCall& call)
+// Returns `true` if all sources should be updated, or `false` otherwise.
+bool ALeffectslot::eax_set(const EaxCall& call)
{
- switch (call.get_property_id())
- {
- case EAXFXSLOT_NONE:
- return false;
-
- case EAXFXSLOT_ALLPARAMETERS:
- return eax_defer_fx_slot_all(call);
+ const auto version = call.get_version();
- case EAXFXSLOT_LOADEFFECT:
- eax_defer_fx_slot_effect(call);
- return false;
+ if(eax_version_ != version) {
+ constexpr auto all_bits = ~EaxDirtyFlags{};
+ eax123_.df = all_bits;
+ eax4_.df = all_bits;
+ eax5_.df = all_bits;
+ }
- case EAXFXSLOT_VOLUME:
- eax_defer_fx_slot_volume(call);
- return false;
+ eax_version_ = version;
- case EAXFXSLOT_LOCK:
- eax_defer_fx_slot_lock(call);
- return false;
+ switch(call.get_property_set_id())
+ {
+ case EaxCallPropertySetId::fx_slot: return eax_fx_slot_set(call);
+ case EaxCallPropertySetId::fx_slot_effect: eax_dispatch_effect(call); return false;
+ default: eax_fail_unknown_property_id();
+ }
+}
- case EAXFXSLOT_FLAGS:
- eax_defer_fx_slot_flags(call);
- return false;
+void ALeffectslot::eax4_fx_slot_commit(EaxDirtyFlags& dst_df)
+{
+ if(eax4_.df == EaxDirtyFlags{})
+ return;
- case EAXFXSLOT_OCCLUSION:
- return eax_defer_fx_slot_occlusion(call);
+ eax_fx_slot_commit_property<eax_load_effect_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::guidLoadEffect);
+ eax_fx_slot_commit_property<eax_volume_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::lVolume);
+ eax_fx_slot_commit_property<eax_lock_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::lLock);
+ eax_fx_slot_commit_property<eax_flags_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::ulFlags);
- case EAXFXSLOT_OCCLUSIONLFRATIO:
- return eax_defer_fx_slot_occlusion_lf_ratio(call);
+ auto& dst_i = eax_;
+ if(dst_i.lOcclusion != EAXFXSLOT_DEFAULTOCCLUSION) {
+ dst_df |= eax_occlusion_dirty_bit;
+ dst_i.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
+ }
- default:
- eax_fail("Unsupported FX slot property id.");
+ if(dst_i.flOcclusionLFRatio != EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO) {
+ dst_df |= eax_occlusion_lf_ratio_dirty_bit;
+ dst_i.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
}
+
+ eax4_.df = EaxDirtyFlags{};
}
-// [[nodiscard]]
-bool ALeffectslot::eax_set(const EaxCall& call)
+void ALeffectslot::eax5_fx_slot_commit(Eax5State& state, EaxDirtyFlags& dst_df)
{
- switch(call.get_property_set_id())
- {
- case EaxCallPropertySetId::fx_slot:
- return eax_set_fx_slot(call);
-
- case EaxCallPropertySetId::fx_slot_effect:
- eax_dispatch_effect(call);
- break;
-
- default:
- eax_fail("Unsupported property id.");
- }
+ if(state.df == EaxDirtyFlags{})
+ return;
- return false;
+ eax_fx_slot_commit_property<eax_load_effect_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::guidLoadEffect);
+ eax_fx_slot_commit_property<eax_volume_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::lVolume);
+ eax_fx_slot_commit_property<eax_lock_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::lLock);
+ eax_fx_slot_commit_property<eax_flags_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::ulFlags);
+ eax_fx_slot_commit_property<eax_occlusion_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::lOcclusion);
+ eax_fx_slot_commit_property<eax_occlusion_lf_ratio_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::flOcclusionLFRatio);
+ state.df = EaxDirtyFlags{};
}
void ALeffectslot::eax_dispatch_effect(const EaxCall& call)
-{ if(eax_effect_) eax_effect_->dispatch(call); }
-
-void ALeffectslot::eax_apply_deferred()
{
- /* The other FXSlot properties (volume, effect, etc) aren't deferred? */
-
- auto is_changed = false;
- if(eax_effect_)
- is_changed = eax_effect_->commit();
- if(is_changed)
- eax_set_effect_slot_effect(*eax_effect_);
+ if(eax_effect_ != nullptr)
+ eax_effect_->dispatch(call);
}
-
-void ALeffectslot::eax_set_effect_slot_effect(EaxEffect &effect)
+void ALeffectslot::eax_set_efx_slot_effect(EaxEffect &effect)
{
#define EAX_PREFIX "[EAX_SET_EFFECT_SLOT_EFFECT] "
const auto error = initEffect(effect.al_effect_type_, effect.al_effect_props_, eax_al_context_);
- if (error != AL_NO_ERROR)
- {
+
+ if(error != AL_NO_ERROR) {
ERR(EAX_PREFIX "%s\n", "Failed to initialize an effect.");
return;
}
- if (mState == SlotState::Initial)
- {
+ if(mState == SlotState::Initial) {
mPropsDirty = false;
updateProps(eax_al_context_);
-
auto effect_slot_ptr = this;
-
AddActiveEffectSlots({&effect_slot_ptr, 1}, eax_al_context_);
mState = SlotState::Playing;
-
return;
}
- UpdateProps(this, eax_al_context_);
+ mPropsDirty = true;
#undef EAX_PREFIX
}
-void ALeffectslot::eax_set_effect_slot_send_auto(
- bool is_send_auto)
+void ALeffectslot::eax_set_efx_slot_send_auto(bool is_send_auto)
{
if(AuxSendAuto == is_send_auto)
return;
AuxSendAuto = is_send_auto;
- UpdateProps(this, eax_al_context_);
+ mPropsDirty = true;
}
-void ALeffectslot::eax_set_effect_slot_gain(
- ALfloat gain)
+void ALeffectslot::eax_set_efx_slot_gain(ALfloat gain)
{
#define EAX_PREFIX "[EAX_SET_EFFECT_SLOT_GAIN] "
@@ -1727,43 +1555,37 @@ void ALeffectslot::eax_set_effect_slot_gain(
ERR(EAX_PREFIX "Gain out of range (%f)\n", gain);
Gain = clampf(gain, 0.0f, 1.0f);
- UpdateProps(this, eax_al_context_);
+ mPropsDirty = true;
#undef EAX_PREFIX
}
-
void ALeffectslot::EaxDeleter::operator()(ALeffectslot* effect_slot)
{
assert(effect_slot);
eax_delete_al_effect_slot(*effect_slot->eax_al_context_, *effect_slot);
}
-
-EaxAlEffectSlotUPtr eax_create_al_effect_slot(
- ALCcontext& context)
+EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context)
{
#define EAX_PREFIX "[EAX_MAKE_EFFECT_SLOT] "
std::unique_lock<std::mutex> effect_slot_lock{context.mEffectSlotLock};
-
auto& device = *context.mALDevice;
- if (context.mNumEffectSlots == device.AuxiliaryEffectSlotMax)
- {
+ if(context.mNumEffectSlots == device.AuxiliaryEffectSlotMax) {
ERR(EAX_PREFIX "%s\n", "Out of memory.");
return nullptr;
}
- if (!EnsureEffectSlots(&context, 1))
- {
+ if(!EnsureEffectSlots(&context, 1)) {
ERR(EAX_PREFIX "%s\n", "Failed to ensure.");
return nullptr;
}
auto effect_slot = EaxAlEffectSlotUPtr{AllocEffectSlot(&context)};
- if (!effect_slot)
- {
+
+ if(effect_slot == nullptr) {
ERR(EAX_PREFIX "%s\n", "Failed to allocate.");
return nullptr;
}
@@ -1773,22 +1595,18 @@ EaxAlEffectSlotUPtr eax_create_al_effect_slot(
#undef EAX_PREFIX
}
-void eax_delete_al_effect_slot(
- ALCcontext& context,
- ALeffectslot& effect_slot)
+void eax_delete_al_effect_slot(ALCcontext& context, ALeffectslot& effect_slot)
{
#define EAX_PREFIX "[EAX_DELETE_EFFECT_SLOT] "
std::lock_guard<std::mutex> effect_slot_lock{context.mEffectSlotLock};
- if (ReadRef(effect_slot.ref) != 0)
- {
+ if(ReadRef(effect_slot.ref) != 0) {
ERR(EAX_PREFIX "Deleting in-use effect slot %u.\n", effect_slot.id);
return;
}
auto effect_slot_ptr = &effect_slot;
-
RemoveActiveEffectSlots({&effect_slot_ptr, 1}, &context);
FreeEffectSlot(&context, &effect_slot);
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 83711372..fb6a2e1e 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -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:
- ALCcontext* eax_al_context_{};
+ 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_{};
-
-
- [[noreturn]]
- static void eax_fail(
- const char* message);
-
-
- GUID eax_get_eax_default_effect_guid() const noexcept;
+ 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();
+
+ // 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;
+ }
+
+ 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 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 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_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_set_fx_slot_effect(const EaxCall& call, ALenum effect_type);
-
- 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]]
+ 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 eax4_fx_slot_set_all(const EaxCall& call);
+ void eax5_fx_slot_set_all(const EaxCall& call);
+
+ // 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
diff --git a/al/eax/call.cpp b/al/eax/call.cpp
index 1fd05968..f779c2b0 100644
--- a/al/eax/call.cpp
+++ b/al/eax/call.cpp
@@ -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}
{
diff --git a/al/eax/call.h b/al/eax/call.h
index 9c2706c3..4c35551c 100644
--- a/al/eax/call.h
+++ b/al/eax/call.h
@@ -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_;
diff --git a/al/eax/effect.h b/al/eax/effect.h
index b57bf240..f09a2520 100644
--- a/al/eax/effect.h
+++ b/al/eax/effect.h
@@ -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
diff --git a/al/eax/fx_slots.cpp b/al/eax/fx_slots.cpp
index 671d2cfb..83de8f78 100644
--- a/al/eax/fx_slots.cpp
+++ b/al/eax/fx_slots.cpp
@@ -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)
diff --git a/al/eax/fx_slots.h b/al/eax/fx_slots.h
index e7d1452e..cb7e0db4 100644
--- a/al/eax/fx_slots.h
+++ b/al/eax/fx_slots.h
@@ -33,9 +33,6 @@ public:
ALeffectslot& get(
EaxFxSlotIndex index);
- void unlock_legacy() noexcept;
-
-
private:
using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;
diff --git a/al/eax/utils.h b/al/eax/utils.h
index 2960c6d7..8ff75a18 100644
--- a/al/eax/utils.h
+++ b/al/eax/utils.h
@@ -6,6 +6,8 @@
#include <string>
#include <type_traits>
+using EaxDirtyFlags = unsigned int;
+
struct EaxAlLowPassParam {
float gain;
float gain_hf;
diff --git a/al/effects/autowah.cpp b/al/effects/autowah.cpp
index 7e0e34aa..3400f5a4 100644
--- a/al/effects/autowah.cpp
+++ b/al/effects/autowah.cpp
@@ -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
diff --git a/al/effects/chorus.cpp b/al/effects/chorus.cpp
index 0d4283c9..1651ebb9 100644
--- a/al/effects/chorus.cpp
+++ b/al/effects/chorus.cpp
@@ -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
diff --git a/al/effects/compressor.cpp b/al/effects/compressor.cpp
index 9824d11b..df318709 100644
--- a/al/effects/compressor.cpp
+++ b/al/effects/compressor.cpp
@@ -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
diff --git a/al/effects/distortion.cpp b/al/effects/distortion.cpp
index b58412b9..80e5f46d 100644
--- a/al/effects/distortion.cpp
+++ b/al/effects/distortion.cpp
@@ -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
diff --git a/al/effects/echo.cpp b/al/effects/echo.cpp
index f25c94bf..c0968676 100644
--- a/al/effects/echo.cpp
+++ b/al/effects/echo.cpp
@@ -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
diff --git a/al/effects/effects.cpp b/al/effects/effects.cpp
index e4e61231..7c8447e4 100644
--- a/al/effects/effects.cpp
+++ b/al/effects/effects.cpp
@@ -1,16 +1,12 @@
-
#include "config.h"
#ifdef ALSOFT_EAX
-#include "effects.h"
-
#include <cassert>
-
#include "AL/efx.h"
+#include "effects.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.");
diff --git a/al/effects/effects.h b/al/effects/effects.h
index 164c0d19..acfeec6a 100644
--- a/al/effects/effects.h
+++ b/al/effects/effects.h
@@ -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 */
diff --git a/al/effects/equalizer.cpp b/al/effects/equalizer.cpp
index 80dd1c4b..0ee351f3 100644
--- a/al/effects/equalizer.cpp
+++ b/al/effects/equalizer.cpp
@@ -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
diff --git a/al/effects/fshifter.cpp b/al/effects/fshifter.cpp
index 2b1710ad..400c0bf4 100644
--- a/al/effects/fshifter.cpp
+++ b/al/effects/fshifter.cpp
@@ -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
diff --git a/al/effects/modulator.cpp b/al/effects/modulator.cpp
index 774fb767..e917e3a0 100644
--- a/al/effects/modulator.cpp
+++ b/al/effects/modulator.cpp
@@ -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
diff --git a/al/effects/pshifter.cpp b/al/effects/pshifter.cpp
index 51dbdd8f..9711da28 100644
--- a/al/effects/pshifter.cpp
+++ b/al/effects/pshifter.cpp
@@ -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
diff --git a/al/effects/reverb.cpp b/al/effects/reverb.cpp
index 07d6dfcf..19b52d66 100644
--- a/al/effects/reverb.cpp
+++ b/al/effects/reverb.cpp
@@ -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
diff --git a/al/effects/vmorpher.cpp b/al/effects/vmorpher.cpp
index 95f98db5..e1b7a698 100644
--- a/al/effects/vmorpher.cpp
+++ b/al/effects/vmorpher.cpp
@@ -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