diff options
author | Boris I. Bendovsky <[email protected]> | 2022-07-12 12:46:51 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2022-07-12 02:46:51 -0700 |
commit | 6fb5cb553f4c2faf4b991ac377ec457a7bba7e4c (patch) | |
tree | 5b62a1111fa1a48f3a2e226b8491bc1615db865d /al | |
parent | fa51c89549590319cb545a8c81419e2e1ddc5db3 (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.cpp | 838 | ||||
-rw-r--r-- | al/auxeffectslot.h | 370 | ||||
-rw-r--r-- | al/eax/call.cpp | 1 | ||||
-rw-r--r-- | al/eax/call.h | 2 | ||||
-rw-r--r-- | al/eax/effect.h | 40 | ||||
-rw-r--r-- | al/eax/fx_slots.cpp | 6 | ||||
-rw-r--r-- | al/eax/fx_slots.h | 3 | ||||
-rw-r--r-- | al/eax/utils.h | 2 | ||||
-rw-r--r-- | al/effects/autowah.cpp | 10 | ||||
-rw-r--r-- | al/effects/chorus.cpp | 16 | ||||
-rw-r--r-- | al/effects/compressor.cpp | 10 | ||||
-rw-r--r-- | al/effects/distortion.cpp | 10 | ||||
-rw-r--r-- | al/effects/echo.cpp | 10 | ||||
-rw-r--r-- | al/effects/effects.cpp | 32 | ||||
-rw-r--r-- | al/effects/effects.h | 3 | ||||
-rw-r--r-- | al/effects/equalizer.cpp | 10 | ||||
-rw-r--r-- | al/effects/fshifter.cpp | 10 | ||||
-rw-r--r-- | al/effects/modulator.cpp | 10 | ||||
-rw-r--r-- | al/effects/pshifter.cpp | 10 | ||||
-rw-r--r-- | al/effects/reverb.cpp | 10 | ||||
-rw-r--r-- | al/effects/vmorpher.cpp | 10 |
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 |