diff --git a/al/eax/api.cpp b/al/eax/api.cpp index 1eb5b20d..f0809df1 100644 --- a/al/eax/api.cpp +++ b/al/eax/api.cpp @@ -269,7 +269,8 @@ const GUID EAX_RINGMODULATOR_EFFECT = }; -const GUID EAXCONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX40_FXSlot0; +const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX40_FXSlot0; +const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX50_FXSlot0; const EAX40ACTIVEFXSLOTS EAX40SOURCE_DEFAULTACTIVEFXSLOTID = EAX40ACTIVEFXSLOTS {{ diff --git a/al/eax/api.h b/al/eax/api.h index a436acb2..3d78c90b 100644 --- a/al/eax/api.h +++ b/al/eax/api.h @@ -287,21 +287,19 @@ extern const GUID EAXPROPERTYID_EAX40_Context; extern const GUID EAXPROPERTYID_EAX50_Context; // EAX50 -enum : unsigned long -{ - HEADPHONES = 0, - SPEAKERS_2, - SPEAKERS_4, - SPEAKERS_5, // 5.1 speakers - SPEAKERS_6, // 6.1 speakers - SPEAKERS_7, // 7.1 speakers -}; +constexpr auto HEADPHONES = 0UL; +constexpr auto SPEAKERS_2 = 1UL; +constexpr auto SPEAKERS_4 = 2UL; +constexpr auto SPEAKERS_5 = 3UL; // 5.1 speakers +constexpr auto SPEAKERS_6 = 4UL; // 6.1 speakers +constexpr auto SPEAKERS_7 = 5UL; // 7.1 speakers + +constexpr auto EAXCONTEXT_MINSPEAKERCONFIG = HEADPHONES; +constexpr auto EAXCONTEXT_MAXSPEAKERCONFIG = SPEAKERS_7; // EAX50 -enum : unsigned long { - EAX_40 = 5, // EAX 4.0 - EAX_50 = 6, // EAX 5.0 -}; +constexpr auto EAX_40 = 5UL; // EAX 4.0 +constexpr auto EAX_50 = 6UL; // EAX 5.0 constexpr auto EAXCONTEXT_MINEAXSESSION = EAX_40; constexpr auto EAXCONTEXT_MAXEAXSESSION = EAX_50; @@ -370,7 +368,8 @@ extern const GUID EAXPROPERTYID_EAX50_FXSlot2; extern const GUID EAXPROPERTYID_EAX40_FXSlot3; extern const GUID EAXPROPERTYID_EAX50_FXSlot3; -extern const GUID EAXCONTEXT_DEFAULTPRIMARYFXSLOTID; +extern const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID; +extern const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID; enum EAXFXSLOT_PROPERTY : unsigned int { EAXFXSLOT_PARAMETER = 0, diff --git a/alc/context.cpp b/alc/context.cpp index acd21a1d..f2dcb088 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -30,11 +30,8 @@ #include "vecmat.h" #ifdef ALSOFT_EAX -#include #include - #include "alstring.h" -#include "al/eax/exception.h" #include "al/eax/globals.h" #endif // ALSOFT_EAX @@ -257,7 +254,7 @@ void ALCcontext::applyAllUpdates() } #ifdef ALSOFT_EAX - eax_apply_deferred(); + eax_commit(); #endif if(std::exchange(mPropsDirty, false)) UpdateContextProps(this); @@ -273,19 +270,6 @@ void ALCcontext::applyAllUpdates() #ifdef ALSOFT_EAX namespace { -class ContextException : - public EaxException -{ -public: - explicit ContextException( - const char* message) - : - EaxException{"EAX_CONTEXT", message} - { - } -}; // ContextException - - template void ForEachSource(ALCcontext *context, F func) { @@ -312,14 +296,11 @@ bool ALCcontext::eax_is_capable() const noexcept void ALCcontext::eax_uninitialize() noexcept { - if (!eax_is_initialized_) - { + if(!eax_is_initialized_) return; - } - eax_is_initialized_ = true; + eax_is_initialized_ = false; eax_is_tried_ = false; - eax_fx_slots_.uninitialize(); } @@ -337,26 +318,31 @@ ALenum ALCcontext::eax_eax_set( property_source_id, property_value, property_value_size); - eax_version_ = call.get_version(); + const auto eax_version = call.get_version(); + + if(eax_version != eax_version_) { + eax123_.df = ~EaxDirtyFlags(); + eax4_.df = ~EaxDirtyFlags(); + eax5_.df = ~EaxDirtyFlags(); + } + + eax_version_ = eax_version; eax_initialize(call); - switch (call.get_property_set_id()) + switch(call.get_property_set_id()) { - case EaxCallPropertySetId::context: - eax_set(call); - break; - - case EaxCallPropertySetId::fx_slot: - case EaxCallPropertySetId::fx_slot_effect: - eax_dispatch_fx_slot(call); - break; - - case EaxCallPropertySetId::source: - eax_dispatch_source(call); - break; - - default: - eax_fail("Unsupported property set id."); + case EaxCallPropertySetId::context: + eax_set(call); + break; + case EaxCallPropertySetId::fx_slot: + case EaxCallPropertySetId::fx_slot_effect: + eax_dispatch_fx_slot(call); + break; + case EaxCallPropertySetId::source: + eax_dispatch_source(call); + break; + default: + eax_fail_unknown_property_set_id(); } if(!call.is_deferred() && !mDeferUpdates) @@ -382,23 +368,20 @@ ALenum ALCcontext::eax_eax_get( eax_version_ = call.get_version(); eax_initialize(call); - switch (call.get_property_set_id()) + switch(call.get_property_set_id()) { - case EaxCallPropertySetId::context: - eax_get(call); - break; - - case EaxCallPropertySetId::fx_slot: - case EaxCallPropertySetId::fx_slot_effect: - eax_dispatch_fx_slot(call); - break; - - case EaxCallPropertySetId::source: - eax_dispatch_source(call); - break; - - default: - eax_fail("Unsupported property set id."); + case EaxCallPropertySetId::context: + eax_get(call); + break; + case EaxCallPropertySetId::fx_slot: + case EaxCallPropertySetId::fx_slot_effect: + eax_dispatch_fx_slot(call); + break; + case EaxCallPropertySetId::source: + eax_dispatch_source(call); + break; + default: + eax_fail_unknown_property_set_id(); } return AL_NO_ERROR; @@ -420,19 +403,35 @@ void ALCcontext::eax_set_last_error() noexcept eax_last_error_ = EAXERR_INVALID_OPERATION; } -[[noreturn]] -void ALCcontext::eax_fail( - const char* message) +[[noreturn]] void ALCcontext::eax_fail(const char* message) { throw ContextException{message}; } +[[noreturn]] void ALCcontext::eax_fail_unknown_property_set_id() +{ + eax_fail("Unknown property ID."); +} + +[[noreturn]] void ALCcontext::eax_fail_unknown_primary_fx_slot_id() +{ + eax_fail("Unknown primary FX Slot ID."); +} + +[[noreturn]] void ALCcontext::eax_fail_unknown_property_id() +{ + eax_fail("Unknown property ID."); +} + +[[noreturn]] void ALCcontext::eax_fail_unknown_version() +{ + eax_fail("Unknown version."); +} + void ALCcontext::eax_initialize_extensions() { - if (!eax_g_is_enabled) - { + if(!eax_g_is_enabled) return; - } const auto string_max_capacity = std::strlen(mExtensionList) + 1 + @@ -441,13 +440,11 @@ void ALCcontext::eax_initialize_extensions() std::strlen(eax3_ext_name) + 1 + std::strlen(eax4_ext_name) + 1 + std::strlen(eax5_ext_name) + 1 + - std::strlen(eax_x_ram_ext_name) + 1 + - 0; + std::strlen(eax_x_ram_ext_name) + 1; eax_extension_list_.reserve(string_max_capacity); - if (eax_is_capable()) - { + if(eax_is_capable()) { eax_extension_list_ += eax1_ext_name; eax_extension_list_ += ' '; @@ -473,31 +470,26 @@ void ALCcontext::eax_initialize_extensions() void ALCcontext::eax_initialize(const EaxCall& call) { - if (eax_is_initialized_) - { + if(eax_is_initialized_) return; - } - if (eax_is_tried_) - { + if(eax_is_tried_) eax_fail("No EAX."); - } eax_is_tried_ = true; - if (!eax_g_is_enabled) - { + if(!eax_g_is_enabled) eax_fail("EAX disabled by a configuration."); - } eax_ensure_compatibility(); eax_set_defaults(); - eax_set_air_absorbtion_hf(); + eax_context_commit_air_absorbtion_hf(); eax_update_speaker_configuration(); eax_initialize_fx_slots(call); eax_initialize_sources(); eax_is_initialized_ = true; + mPropsDirty = true; if(!mDeferUpdates) applyAllUpdates(); @@ -510,10 +502,8 @@ bool ALCcontext::eax_has_no_default_effect_slot() const noexcept void ALCcontext::eax_ensure_no_default_effect_slot() const { - if (!eax_has_no_default_effect_slot()) - { + if(!eax_has_no_default_effect_slot()) eax_fail("There is a default effect slot in the context."); - } } bool ALCcontext::eax_has_enough_aux_sends() const noexcept @@ -523,10 +513,8 @@ bool ALCcontext::eax_has_enough_aux_sends() const noexcept void ALCcontext::eax_ensure_enough_aux_sends() const { - if (!eax_has_enough_aux_sends()) - { + if(!eax_has_enough_aux_sends()) eax_fail("Not enough aux sends."); - } } void ALCcontext::eax_ensure_compatibility() @@ -580,27 +568,56 @@ void ALCcontext::eax_set_last_error_defaults() noexcept eax_last_error_ = EAX_OK; } -void ALCcontext::eax_set_session_defaults() noexcept +void ALCcontext::eax_session_set_defaults() noexcept { - eax_session_.ulEAXVersion = EAXCONTEXT_MINEAXSESSION; + eax_session_.ulEAXVersion = EAXCONTEXT_DEFAULTEAXSESSION; eax_session_.ulMaxActiveSends = EAXCONTEXT_DEFAULTMAXACTIVESENDS; } -void ALCcontext::eax_set_context_defaults() noexcept +void ALCcontext::eax4_context_set_defaults(Eax4Props& props) noexcept { - eax_.context.guidPrimaryFXSlotID = EAXCONTEXT_DEFAULTPRIMARYFXSLOTID; - eax_.context.flDistanceFactor = EAXCONTEXT_DEFAULTDISTANCEFACTOR; - eax_.context.flAirAbsorptionHF = EAXCONTEXT_DEFAULTAIRABSORPTIONHF; - eax_.context.flHFReference = EAXCONTEXT_DEFAULTHFREFERENCE; + props.guidPrimaryFXSlotID = EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID; + props.flDistanceFactor = EAXCONTEXT_DEFAULTDISTANCEFACTOR; + props.flAirAbsorptionHF = EAXCONTEXT_DEFAULTAIRABSORPTIONHF; + props.flHFReference = EAXCONTEXT_DEFAULTHFREFERENCE; +} + +void ALCcontext::eax4_context_set_defaults(Eax4State& state) noexcept +{ + eax4_context_set_defaults(state.i); + state.d = state.i; + state.df = ~EaxDirtyFlags{}; +} + +void ALCcontext::eax5_context_set_defaults(Eax5Props& props) noexcept +{ + props.guidPrimaryFXSlotID = EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID; + props.flDistanceFactor = EAXCONTEXT_DEFAULTDISTANCEFACTOR; + props.flAirAbsorptionHF = EAXCONTEXT_DEFAULTAIRABSORPTIONHF; + props.flHFReference = EAXCONTEXT_DEFAULTHFREFERENCE; + props.flMacroFXFactor = EAXCONTEXT_DEFAULTMACROFXFACTOR; +} + +void ALCcontext::eax5_context_set_defaults(Eax5State& state) noexcept +{ + eax5_context_set_defaults(state.i); + state.d = state.i; + state.df = ~EaxDirtyFlags{}; +} + +void ALCcontext::eax_context_set_defaults() noexcept +{ + eax5_context_set_defaults(eax123_); + eax4_context_set_defaults(eax4_); + eax5_context_set_defaults(eax5_); + eax_ = eax5_.i; } void ALCcontext::eax_set_defaults() noexcept { eax_set_last_error_defaults(); - eax_set_session_defaults(); - eax_set_context_defaults(); - - eax_d_ = eax_; + eax_session_set_defaults(); + eax_context_set_defaults(); } void ALCcontext::eax_dispatch_fx_slot(const EaxCall& call) @@ -629,152 +646,128 @@ void ALCcontext::eax_dispatch_source(const EaxCall& call) source->eax_dispatch(call); } -void ALCcontext::eax_get_primary_fx_slot_id(const EaxCall& call) +void ALCcontext::eax_get_misc(const EaxCall& call) { - call.set_value(eax_.context.guidPrimaryFXSlotID); -} - -void ALCcontext::eax_get_distance_factor(const EaxCall& call) -{ - call.set_value(eax_.context.flDistanceFactor); -} - -void ALCcontext::eax_get_air_absorption_hf(const EaxCall& call) -{ - call.set_value(eax_.context.flAirAbsorptionHF); -} - -void ALCcontext::eax_get_hf_reference(const EaxCall& call) -{ - call.set_value(eax_.context.flHFReference); -} - -void ALCcontext::eax_get_last_error(const EaxCall& call) -{ - const auto eax_last_error = eax_last_error_; - eax_last_error_ = EAX_OK; - call.set_value(eax_last_error); -} - -void ALCcontext::eax_get_speaker_config(const EaxCall& call) -{ - call.set_value(eax_speaker_config_); -} - -void ALCcontext::eax_get_session(const EaxCall& call) -{ - call.set_value(eax_session_); -} - -void ALCcontext::eax_get_macro_fx_factor(const EaxCall& call) -{ - call.set_value(eax_.context.flMacroFXFactor); -} - -void ALCcontext::eax_get_context_all(const EaxCall& call) -{ - switch (call.get_version()) + switch(call.get_property_id()) { - case 4: - call.set_value(static_cast(eax_.context)); - break; + case EAXCONTEXT_NONE: + break; + case EAXCONTEXT_LASTERROR: + call.set_value(eax_last_error_); + break; + case EAXCONTEXT_SPEAKERCONFIG: + call.set_value(eax_speaker_config_); + break; + case EAXCONTEXT_EAXSESSION: + call.set_value(eax_session_); + break; + default: + eax_fail_unknown_property_id(); + } +} - case 5: - call.set_value(static_cast(eax_.context)); - break; +void ALCcontext::eax4_get(const EaxCall& call, const Eax4Props& props) +{ + switch(call.get_property_id()) + { + case EAXCONTEXT_ALLPARAMETERS: + call.set_value(props); + break; + case EAXCONTEXT_PRIMARYFXSLOTID: + call.set_value(props.guidPrimaryFXSlotID); + break; + case EAXCONTEXT_DISTANCEFACTOR: + call.set_value(props.flDistanceFactor); + break; + case EAXCONTEXT_AIRABSORPTIONHF: + call.set_value(props.flAirAbsorptionHF); + break; + case EAXCONTEXT_HFREFERENCE: + call.set_value(props.flHFReference); + break; + default: + eax_get_misc(call); + break; + } +} - default: - eax_fail("Unsupported EAX version."); +void ALCcontext::eax5_get(const EaxCall& call, const Eax5Props& props) +{ + switch(call.get_property_id()) + { + case EAXCONTEXT_ALLPARAMETERS: + call.set_value(props); + break; + case EAXCONTEXT_PRIMARYFXSLOTID: + call.set_value(props.guidPrimaryFXSlotID); + break; + case EAXCONTEXT_DISTANCEFACTOR: + call.set_value(props.flDistanceFactor); + break; + case EAXCONTEXT_AIRABSORPTIONHF: + call.set_value(props.flAirAbsorptionHF); + break; + case EAXCONTEXT_HFREFERENCE: + call.set_value(props.flHFReference); + break; + case EAXCONTEXT_MACROFXFACTOR: + call.set_value(props.flMacroFXFactor); + break; + default: + eax_get_misc(call); + break; } } void ALCcontext::eax_get(const EaxCall& call) { - switch (call.get_property_id()) + switch(call.get_version()) { - case EAXCONTEXT_NONE: - break; - - case EAXCONTEXT_ALLPARAMETERS: - eax_get_context_all(call); - break; - - case EAXCONTEXT_PRIMARYFXSLOTID: - eax_get_primary_fx_slot_id(call); - break; - - case EAXCONTEXT_DISTANCEFACTOR: - eax_get_distance_factor(call); - break; - - case EAXCONTEXT_AIRABSORPTIONHF: - eax_get_air_absorption_hf(call); - break; - - case EAXCONTEXT_HFREFERENCE: - eax_get_hf_reference(call); - break; - - case EAXCONTEXT_LASTERROR: - eax_get_last_error(call); - break; - - case EAXCONTEXT_SPEAKERCONFIG: - eax_get_speaker_config(call); - break; - - case EAXCONTEXT_EAXSESSION: - eax_get_session(call); - break; - - case EAXCONTEXT_MACROFXFACTOR: - eax_get_macro_fx_factor(call); - break; - - default: - eax_fail("Unsupported property id."); + case 4: eax4_get(call, eax4_.i); break; + case 5: eax5_get(call, eax5_.i); break; + default: eax_fail_unknown_version(); } } -void ALCcontext::eax_set_primary_fx_slot_id() +void ALCcontext::eax_context_commit_primary_fx_slot_id() { - eax_primary_fx_slot_index_ = eax_.context.guidPrimaryFXSlotID; + eax_primary_fx_slot_index_ = eax_.guidPrimaryFXSlotID; } -void ALCcontext::eax_set_distance_factor() +void ALCcontext::eax_context_commit_distance_factor() { - mListener.mMetersPerUnit = eax_.context.flDistanceFactor; + if(mListener.mMetersPerUnit == eax_.flDistanceFactor) + return; + + mListener.mMetersPerUnit = eax_.flDistanceFactor; mPropsDirty = true; } -void ALCcontext::eax_set_air_absorbtion_hf() +void ALCcontext::eax_context_commit_air_absorbtion_hf() { - mAirAbsorptionGainHF = level_mb_to_gain(eax_.context.flAirAbsorptionHF); + const auto new_value = level_mb_to_gain(eax_.flAirAbsorptionHF); + + if(mAirAbsorptionGainHF == new_value) + return; + + mAirAbsorptionGainHF = new_value; mPropsDirty = true; } -void ALCcontext::eax_set_hf_reference() +void ALCcontext::eax_context_commit_hf_reference() { // TODO } -void ALCcontext::eax_set_macro_fx_factor() +void ALCcontext::eax_context_commit_macro_fx_factor() { // TODO } -void ALCcontext::eax_set_context() -{ - eax_set_primary_fx_slot_id(); - eax_set_distance_factor(); - eax_set_air_absorbtion_hf(); - eax_set_hf_reference(); -} - void ALCcontext::eax_initialize_fx_slots(const EaxCall& call) { eax_fx_slots_.initialize(call, *this); - eax_primary_fx_slot_index_ = eax_.context.guidPrimaryFXSlotID; + eax_primary_fx_slot_index_ = eax_.guidPrimaryFXSlotID; } void ALCcontext::eax_initialize_sources() @@ -793,408 +786,250 @@ void ALCcontext::eax_update_sources() ForEachSource(this, update_source); } -void ALCcontext::eax_validate_primary_fx_slot_id( - const GUID& primary_fx_slot_id) +void ALCcontext::eax_set_misc(const EaxCall& call) { - if (primary_fx_slot_id != EAX_NULL_GUID && - primary_fx_slot_id != EAXPROPERTYID_EAX40_FXSlot0 && - primary_fx_slot_id != EAXPROPERTYID_EAX50_FXSlot0 && - primary_fx_slot_id != EAXPROPERTYID_EAX40_FXSlot1 && - primary_fx_slot_id != EAXPROPERTYID_EAX50_FXSlot1 && - primary_fx_slot_id != EAXPROPERTYID_EAX40_FXSlot2 && - primary_fx_slot_id != EAXPROPERTYID_EAX50_FXSlot2 && - primary_fx_slot_id != EAXPROPERTYID_EAX40_FXSlot3 && - primary_fx_slot_id != EAXPROPERTYID_EAX50_FXSlot3) + switch(call.get_property_id()) { - eax_fail("Unsupported primary FX slot id."); - } -} - -void ALCcontext::eax_validate_distance_factor( - float distance_factor) -{ - eax_validate_range( - "Distance Factor", - distance_factor, - EAXCONTEXT_MINDISTANCEFACTOR, - EAXCONTEXT_MAXDISTANCEFACTOR); -} - -void ALCcontext::eax_validate_air_absorption_hf( - float air_absorption_hf) -{ - eax_validate_range( - "Air Absorption HF", - air_absorption_hf, - EAXCONTEXT_MINAIRABSORPTIONHF, - EAXCONTEXT_MAXAIRABSORPTIONHF); -} - -void ALCcontext::eax_validate_hf_reference( - float hf_reference) -{ - eax_validate_range( - "HF Reference", - hf_reference, - EAXCONTEXT_MINHFREFERENCE, - EAXCONTEXT_MAXHFREFERENCE); -} - -void ALCcontext::eax_validate_speaker_config( - unsigned long speaker_config) -{ - switch (speaker_config) - { - case HEADPHONES: - case SPEAKERS_2: - case SPEAKERS_4: - case SPEAKERS_5: - case SPEAKERS_6: - case SPEAKERS_7: - break; - - default: - eax_fail("Unsupported speaker configuration."); - } -} - -void ALCcontext::eax_validate_session_eax_version( - unsigned long eax_version) -{ - switch (eax_version) - { - case EAX_40: - case EAX_50: - break; - - default: - eax_fail("Unsupported session EAX version."); - } -} - -void ALCcontext::eax_validate_session_max_active_sends( - unsigned long max_active_sends) -{ - eax_validate_range( - "Max Active Sends", - max_active_sends, - EAXCONTEXT_MINMAXACTIVESENDS, - EAXCONTEXT_MAXMAXACTIVESENDS); -} - -void ALCcontext::eax_validate_session( - const EAXSESSIONPROPERTIES& eax_session) -{ - eax_validate_session_eax_version(eax_session.ulEAXVersion); - eax_validate_session_max_active_sends(eax_session.ulMaxActiveSends); -} - -void ALCcontext::eax_validate_macro_fx_factor( - float macro_fx_factor) -{ - eax_validate_range( - "Macro FX Factor", - macro_fx_factor, - EAXCONTEXT_MINMACROFXFACTOR, - EAXCONTEXT_MAXMACROFXFACTOR); -} - -void ALCcontext::eax_validate_context_all( - const EAX40CONTEXTPROPERTIES& context_all) -{ - eax_validate_primary_fx_slot_id(context_all.guidPrimaryFXSlotID); - eax_validate_distance_factor(context_all.flDistanceFactor); - eax_validate_air_absorption_hf(context_all.flAirAbsorptionHF); - eax_validate_hf_reference(context_all.flHFReference); -} - -void ALCcontext::eax_validate_context_all( - const EAX50CONTEXTPROPERTIES& context_all) -{ - eax_validate_context_all(static_cast(context_all)); - eax_validate_macro_fx_factor(context_all.flMacroFXFactor); -} - -void ALCcontext::eax_defer_primary_fx_slot_id( - const GUID& primary_fx_slot_id) -{ - eax_d_.context.guidPrimaryFXSlotID = primary_fx_slot_id; - - eax_context_dirty_flags_.guidPrimaryFXSlotID = - (eax_.context.guidPrimaryFXSlotID != eax_d_.context.guidPrimaryFXSlotID); -} - -void ALCcontext::eax_defer_distance_factor( - float distance_factor) -{ - eax_d_.context.flDistanceFactor = distance_factor; - - eax_context_dirty_flags_.flDistanceFactor = - (eax_.context.flDistanceFactor != eax_d_.context.flDistanceFactor); -} - -void ALCcontext::eax_defer_air_absorption_hf( - float air_absorption_hf) -{ - eax_d_.context.flAirAbsorptionHF = air_absorption_hf; - - eax_context_dirty_flags_.flAirAbsorptionHF = - (eax_.context.flAirAbsorptionHF != eax_d_.context.flAirAbsorptionHF); -} - -void ALCcontext::eax_defer_hf_reference( - float hf_reference) -{ - eax_d_.context.flHFReference = hf_reference; - - eax_context_dirty_flags_.flHFReference = - (eax_.context.flHFReference != eax_d_.context.flHFReference); -} - -void ALCcontext::eax_defer_macro_fx_factor( - float macro_fx_factor) -{ - eax_d_.context.flMacroFXFactor = macro_fx_factor; - - eax_context_dirty_flags_.flMacroFXFactor = - (eax_.context.flMacroFXFactor != eax_d_.context.flMacroFXFactor); -} - -void ALCcontext::eax_defer_context_all( - const EAX40CONTEXTPROPERTIES& context_all) -{ - eax_defer_primary_fx_slot_id(context_all.guidPrimaryFXSlotID); - eax_defer_distance_factor(context_all.flDistanceFactor); - eax_defer_air_absorption_hf(context_all.flAirAbsorptionHF); - eax_defer_hf_reference(context_all.flHFReference); -} - -void ALCcontext::eax_defer_context_all( - const EAX50CONTEXTPROPERTIES& context_all) -{ - eax_defer_context_all(static_cast(context_all)); - eax_defer_macro_fx_factor(context_all.flMacroFXFactor); -} - -void ALCcontext::eax_defer_context_all(const EaxCall& call) -{ - switch(call.get_version()) - { - case 4: - { - const auto& context_all = - call.get_value(); - - eax_validate_context_all(context_all); - eax_defer_context_all(context_all); - } + case EAXCONTEXT_NONE: break; - - case 5: - { - const auto& context_all = - call.get_value(); - - eax_validate_context_all(context_all); - eax_defer_context_all(context_all); - } + case EAXCONTEXT_SPEAKERCONFIG: + eax_set(call, eax_speaker_config_); + break; + case EAXCONTEXT_EAXSESSION: + eax_set(call, eax_session_); break; - default: - eax_fail("Unsupported EAX version."); + eax_fail_unknown_property_id(); } } -void ALCcontext::eax_defer_primary_fx_slot_id(const EaxCall& call) +void ALCcontext::eax4_defer_all(const EaxCall& call, Eax4State& state) { - const auto& primary_fx_slot_id = - call.get_value(); + const auto& src = call.get_value(); + Eax4AllValidator{}(src); + const auto& dst_i = state.i; + auto& dst_d = state.d; + dst_d = src; - eax_validate_primary_fx_slot_id(primary_fx_slot_id); - eax_defer_primary_fx_slot_id(primary_fx_slot_id); + if(dst_i.guidPrimaryFXSlotID != dst_d.guidPrimaryFXSlotID) + state.df |= eax_primary_fx_slot_id_dirty_bit; + + if(dst_i.flDistanceFactor != dst_d.flDistanceFactor) + state.df |= eax_distance_factor_dirty_bit; + + if(dst_i.flAirAbsorptionHF != dst_d.flAirAbsorptionHF) + state.df |= eax_air_absorption_hf_dirty_bit; + + if(dst_i.flHFReference != dst_d.flHFReference) + state.df |= eax_hf_reference_dirty_bit; } -void ALCcontext::eax_defer_distance_factor(const EaxCall& call) +void ALCcontext::eax4_defer(const EaxCall& call, Eax4State& state) { - const auto& distance_factor = - call.get_value(); - - eax_validate_distance_factor(distance_factor); - eax_defer_distance_factor(distance_factor); + switch(call.get_property_id()) + { + case EAXCONTEXT_ALLPARAMETERS: + eax4_defer_all(call, state); + break; + case EAXCONTEXT_PRIMARYFXSLOTID: + eax_defer( + call, state, &EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID); + break; + case EAXCONTEXT_DISTANCEFACTOR: + eax_defer( + call, state, &EAX40CONTEXTPROPERTIES::flDistanceFactor); + break; + case EAXCONTEXT_AIRABSORPTIONHF: + eax_defer( + call, state, &EAX40CONTEXTPROPERTIES::flAirAbsorptionHF); + break; + case EAXCONTEXT_HFREFERENCE: + eax_defer( + call, state, &EAX40CONTEXTPROPERTIES::flHFReference); + break; + default: + eax_set_misc(call); + break; + } } -void ALCcontext::eax_defer_air_absorption_hf(const EaxCall& call) +void ALCcontext::eax5_defer_all(const EaxCall& call, Eax5State& state) { - const auto& air_absorption_hf = - call.get_value(); + const auto& src = call.get_value(); + Eax4AllValidator{}(src); + const auto& dst_i = state.i; + auto& dst_d = state.d; + dst_d = src; - eax_validate_air_absorption_hf(air_absorption_hf); - eax_defer_air_absorption_hf(air_absorption_hf); + if(dst_i.guidPrimaryFXSlotID != dst_d.guidPrimaryFXSlotID) + state.df |= eax_primary_fx_slot_id_dirty_bit; + + if(dst_i.flDistanceFactor != dst_d.flDistanceFactor) + state.df |= eax_distance_factor_dirty_bit; + + if(dst_i.flAirAbsorptionHF != dst_d.flAirAbsorptionHF) + state.df |= eax_air_absorption_hf_dirty_bit; + + if(dst_i.flHFReference != dst_d.flHFReference) + state.df |= eax_hf_reference_dirty_bit; + + if(dst_i.flMacroFXFactor != dst_d.flMacroFXFactor) + state.df |= eax_macro_fx_factor_dirty_bit; } -void ALCcontext::eax_defer_hf_reference(const EaxCall& call) +void ALCcontext::eax5_defer(const EaxCall& call, Eax5State& state) { - const auto& hf_reference = - call.get_value(); - - eax_validate_hf_reference(hf_reference); - eax_defer_hf_reference(hf_reference); -} - -void ALCcontext::eax_set_session(const EaxCall& call) -{ - const auto& eax_session = - call.get_value(); - - eax_validate_session(eax_session); - - eax_session_ = eax_session; -} - -void ALCcontext::eax_defer_macro_fx_factor(const EaxCall& call) -{ - const auto& macro_fx_factor = - call.get_value(); - - eax_validate_macro_fx_factor(macro_fx_factor); - eax_defer_macro_fx_factor(macro_fx_factor); + switch(call.get_property_id()) + { + case EAXCONTEXT_ALLPARAMETERS: + eax5_defer_all(call, state); + break; + case EAXCONTEXT_PRIMARYFXSLOTID: + eax_defer( + call, state, &EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID); + break; + case EAXCONTEXT_DISTANCEFACTOR: + eax_defer( + call, state, &EAX50CONTEXTPROPERTIES::flDistanceFactor); + break; + case EAXCONTEXT_AIRABSORPTIONHF: + eax_defer( + call, state, &EAX50CONTEXTPROPERTIES::flAirAbsorptionHF); + break; + case EAXCONTEXT_HFREFERENCE: + eax_defer( + call, state, &EAX50CONTEXTPROPERTIES::flHFReference); + break; + case EAXCONTEXT_MACROFXFACTOR: + eax_defer( + call, state, &EAX50CONTEXTPROPERTIES::flMacroFXFactor); + break; + default: + eax_set_misc(call); + break; + } } void ALCcontext::eax_set(const EaxCall& call) { - switch (call.get_property_id()) + switch(call.get_version()) { - case EAXCONTEXT_NONE: - break; - - case EAXCONTEXT_ALLPARAMETERS: - eax_defer_context_all(call); - break; - - case EAXCONTEXT_PRIMARYFXSLOTID: - eax_defer_primary_fx_slot_id(call); - break; - - case EAXCONTEXT_DISTANCEFACTOR: - eax_defer_distance_factor(call); - break; - - case EAXCONTEXT_AIRABSORPTIONHF: - eax_defer_air_absorption_hf(call); - break; - - case EAXCONTEXT_HFREFERENCE: - eax_defer_hf_reference(call); - break; - - case EAXCONTEXT_LASTERROR: - eax_fail("Last error is read-only."); - - case EAXCONTEXT_SPEAKERCONFIG: - eax_fail("Speaker configuration is read-only."); - - case EAXCONTEXT_EAXSESSION: - eax_set_session(call); - break; - - case EAXCONTEXT_MACROFXFACTOR: - eax_defer_macro_fx_factor(call); - break; - - default: - eax_fail("Unsupported property id."); + case 4: eax4_defer(call, eax4_); break; + case 5: eax5_defer(call, eax5_); break; + default: eax_fail_unknown_version(); } } -void ALCcontext::eax_apply_deferred() +void ALCcontext::eax4_context_commit(Eax4State& state, EaxDirtyFlags& dst_df) { - if (eax_context_dirty_flags_ == ContextDirtyFlags{}) - { + if(state.df == EaxDirtyFlags{}) return; - } - eax_ = eax_d_; + eax_context_commit_property( + state, dst_df, &EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID); + eax_context_commit_property( + state, dst_df, &EAX40CONTEXTPROPERTIES::flDistanceFactor); + eax_context_commit_property( + state, dst_df, &EAX40CONTEXTPROPERTIES::flAirAbsorptionHF); + eax_context_commit_property( + state, dst_df, &EAX40CONTEXTPROPERTIES::flHFReference); - if (eax_context_dirty_flags_.guidPrimaryFXSlotID) - { - eax_set_primary_fx_slot_id(); - } - - if (eax_context_dirty_flags_.flDistanceFactor) - { - eax_set_distance_factor(); - } - - if (eax_context_dirty_flags_.flAirAbsorptionHF) - { - eax_set_air_absorbtion_hf(); - } - - if (eax_context_dirty_flags_.flHFReference) - { - eax_set_hf_reference(); - } - - if (eax_context_dirty_flags_.flMacroFXFactor) - { - eax_set_macro_fx_factor(); - } - - if (eax_context_dirty_flags_.guidPrimaryFXSlotID) - { - eax_update_sources(); - } - - eax_context_dirty_flags_ = ContextDirtyFlags{}; + state.df = EaxDirtyFlags{}; } - -namespace +void ALCcontext::eax5_context_commit(Eax5State& state, EaxDirtyFlags& dst_df) { + if(state.df == EaxDirtyFlags{}) + return; + eax_context_commit_property( + state, dst_df, &EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID); + eax_context_commit_property( + state, dst_df, &EAX50CONTEXTPROPERTIES::flDistanceFactor); + eax_context_commit_property( + state, dst_df, &EAX50CONTEXTPROPERTIES::flAirAbsorptionHF); + eax_context_commit_property( + state, dst_df, &EAX50CONTEXTPROPERTIES::flHFReference); + eax_context_commit_property( + state, dst_df, &EAX50CONTEXTPROPERTIES::flMacroFXFactor); -class EaxSetException : - public EaxException + state.df = EaxDirtyFlags{}; +} + +void ALCcontext::eax_context_commit() { -public: - explicit EaxSetException( - const char* message) - : - EaxException{"EAX_SET", message} + auto dst_df = EaxDirtyFlags{}; + + switch(eax_version_) { + case 1: + case 2: + case 3: + eax5_context_commit(eax123_, dst_df); + break; + case 4: + eax4_context_commit(eax4_, dst_df); + break; + case 5: + eax5_context_commit(eax5_, dst_df); + break; + default: + eax_fail_unknown_version(); } -}; // EaxSetException + if(dst_df == EaxDirtyFlags{}) + return; -[[noreturn]] -void eax_fail_set( - const char* message) + if((dst_df & eax_primary_fx_slot_id_dirty_bit) != EaxDirtyFlags{}) + eax_context_commit_primary_fx_slot_id(); + + if((dst_df & eax_distance_factor_dirty_bit) != EaxDirtyFlags{}) + eax_context_commit_distance_factor(); + + if((dst_df & eax_air_absorption_hf_dirty_bit) != EaxDirtyFlags{}) + eax_context_commit_air_absorbtion_hf(); + + if((dst_df & eax_hf_reference_dirty_bit) != EaxDirtyFlags{}) + eax_context_commit_hf_reference(); + + if((dst_df & eax_macro_fx_factor_dirty_bit) != EaxDirtyFlags{}) + eax_context_commit_macro_fx_factor(); + + if((dst_df & eax_primary_fx_slot_id_dirty_bit) != EaxDirtyFlags{}) + eax_update_sources(); +} + +void ALCcontext::eax_commit() +{ + eax_context_commit(); +} + +namespace { + +class EaxSetException : public EaxException { +public: + explicit EaxSetException(const char* message) + : EaxException{"EAX_SET", message} + {} +}; + +[[noreturn]] void eax_fail_set(const char* message) { throw EaxSetException{message}; } - -class EaxGetException : - public EaxException -{ +class EaxGetException : public EaxException { public: - explicit EaxGetException( - const char* message) - : - EaxException{"EAX_GET", message} - { - } -}; // EaxGetException + explicit EaxGetException(const char* message) + : EaxException{"EAX_GET", message} + {} +}; - -[[noreturn]] -void eax_fail_get( - const char* message) +[[noreturn]] void eax_fail_get(const char* message) { throw EaxGetException{message}; } - } // namespace @@ -1208,10 +1043,8 @@ try { auto context = GetContextRef(); - if (!context) - { + if(!context) eax_fail_set("No current context."); - } std::lock_guard prop_lock{context->mPropLock}; @@ -1220,8 +1053,7 @@ try property_id, property_source_id, property_value, - property_value_size - ); + property_value_size); } catch (...) { @@ -1239,10 +1071,8 @@ try { auto context = GetContextRef(); - if (!context) - { + if(!context) eax_fail_get("No current context."); - } std::lock_guard prop_lock{context->mPropLock}; @@ -1251,8 +1081,7 @@ try property_id, property_source_id, property_value, - property_value_size - ); + property_value_size); } catch (...) { diff --git a/alc/context.h b/alc/context.h index f107835f..9317455d 100644 --- a/alc/context.h +++ b/alc/context.h @@ -21,22 +21,10 @@ #ifdef ALSOFT_EAX #include "al/eax/call.h" +#include "al/eax/exception.h" #include "al/eax/fx_slot_index.h" #include "al/eax/fx_slots.h" #include "al/eax/utils.h" - - -using ContextDirtyFlagsValue = std::uint_least8_t; - -struct ContextDirtyFlags { - using EaxIsBitFieldStruct = bool; - - ContextDirtyFlagsValue guidPrimaryFXSlotID : 1; - ContextDirtyFlagsValue flDistanceFactor : 1; - ContextDirtyFlagsValue flAirAbsorptionHF : 1; - ContextDirtyFlagsValue flHFReference : 1; - ContextDirtyFlagsValue flMacroFXFactor : 1; -}; // ContextDirtyFlags #endif // ALSOFT_EAX struct ALeffect; @@ -200,14 +188,11 @@ public: #ifdef ALSOFT_EAX public: bool has_eax() const noexcept { return eax_is_initialized_; } - bool eax_is_capable() const noexcept; - + int eax_get_version() const noexcept { return eax_version_; } void eax_uninitialize() noexcept; - int eax_get_version() const noexcept { return eax_version_; } - ALenum eax_eax_set( const GUID* property_set_id, ALuint property_id, @@ -222,15 +207,10 @@ public: ALvoid* property_value, ALuint property_value_size); - void eax_update_filters(); - void eax_commit_and_update_sources(); - - void eax_set_last_error() noexcept; - EaxFxSlotIndex eax_get_primary_fx_slot_index() const noexcept { return eax_primary_fx_slot_index_; } @@ -243,11 +223,169 @@ public: { eax_fx_slots_.commit(); } private: - struct Eax - { - EAX50CONTEXTPROPERTIES context{}; - }; // Eax + static constexpr auto eax_primary_fx_slot_id_dirty_bit = EaxDirtyFlags{1} << 0; + static constexpr auto eax_distance_factor_dirty_bit = EaxDirtyFlags{1} << 1; + static constexpr auto eax_air_absorption_hf_dirty_bit = EaxDirtyFlags{1} << 2; + static constexpr auto eax_hf_reference_dirty_bit = EaxDirtyFlags{1} << 3; + static constexpr auto eax_macro_fx_factor_dirty_bit = EaxDirtyFlags{1} << 4; + using Eax4Props = EAX40CONTEXTPROPERTIES; + + struct Eax4State { + Eax4Props i; // Immediate. + Eax4Props d; // Deferred. + EaxDirtyFlags df; // Dirty flags. + }; + + using Eax5Props = EAX50CONTEXTPROPERTIES; + + struct Eax5State { + Eax5Props i; // Immediate. + Eax5Props d; // Deferred. + EaxDirtyFlags df; // Dirty flags. + }; + + class ContextException : public EaxException + { + public: + explicit ContextException(const char* message) + : EaxException{"EAX_CONTEXT", message} + {} + }; + + struct Eax4PrimaryFxSlotIdValidator { + void operator()(const GUID& guidPrimaryFXSlotID) const + { + if(guidPrimaryFXSlotID != EAX_NULL_GUID && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX40_FXSlot0 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX40_FXSlot1 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX40_FXSlot2 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX40_FXSlot3) + { + eax_fail_unknown_primary_fx_slot_id(); + } + } + }; + + struct Eax4DistanceFactorValidator { + void operator()(float flDistanceFactor) const + { + eax_validate_range( + "Distance Factor", + flDistanceFactor, + EAXCONTEXT_MINDISTANCEFACTOR, + EAXCONTEXT_MAXDISTANCEFACTOR); + } + }; + + struct Eax4AirAbsorptionHfValidator { + void operator()(float flAirAbsorptionHF) const + { + eax_validate_range( + "Air Absorption HF", + flAirAbsorptionHF, + EAXCONTEXT_MINAIRABSORPTIONHF, + EAXCONTEXT_MAXAIRABSORPTIONHF); + } + }; + + struct Eax4HfReferenceValidator { + void operator()(float flHFReference) const + { + eax_validate_range( + "HF Reference", + flHFReference, + EAXCONTEXT_MINHFREFERENCE, + EAXCONTEXT_MAXHFREFERENCE); + } + }; + + struct Eax4AllValidator { + void operator()(const EAX40CONTEXTPROPERTIES& all) const + { + Eax4PrimaryFxSlotIdValidator{}(all.guidPrimaryFXSlotID); + Eax4DistanceFactorValidator{}(all.flDistanceFactor); + Eax4AirAbsorptionHfValidator{}(all.flAirAbsorptionHF); + Eax4HfReferenceValidator{}(all.flHFReference); + } + }; + + struct Eax5PrimaryFxSlotIdValidator { + void operator()(const GUID& guidPrimaryFXSlotID) const + { + if(guidPrimaryFXSlotID != EAX_NULL_GUID && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX50_FXSlot0 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX50_FXSlot1 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX50_FXSlot2 && + guidPrimaryFXSlotID != EAXPROPERTYID_EAX50_FXSlot3) + { + eax_fail_unknown_primary_fx_slot_id(); + } + } + }; + + struct Eax5MacroFxFactorValidator { + void operator()(float flMacroFXFactor) const + { + eax_validate_range( + "Macro FX Factor", + flMacroFXFactor, + EAXCONTEXT_MINMACROFXFACTOR, + EAXCONTEXT_MAXMACROFXFACTOR); + } + }; + + struct Eax5AllValidator { + void operator()(const EAX50CONTEXTPROPERTIES& all) const + { + Eax5PrimaryFxSlotIdValidator{}(all.guidPrimaryFXSlotID); + Eax4DistanceFactorValidator{}(all.flDistanceFactor); + Eax4AirAbsorptionHfValidator{}(all.flAirAbsorptionHF); + Eax4HfReferenceValidator{}(all.flHFReference); + Eax5MacroFxFactorValidator{}(all.flMacroFXFactor); + } + }; + + struct Eax5EaxVersionValidator { + void operator()(unsigned long ulEAXVersion) const + { + eax_validate_range( + "EAX version", + ulEAXVersion, + EAXCONTEXT_MINEAXSESSION, + EAXCONTEXT_MAXEAXSESSION); + } + }; + + struct Eax5MaxActiveSendsValidator { + void operator()(unsigned long ulMaxActiveSends) const + { + eax_validate_range( + "Max Active Sends", + ulMaxActiveSends, + EAXCONTEXT_MINMAXACTIVESENDS, + EAXCONTEXT_MAXMAXACTIVESENDS); + } + }; + + struct Eax5SessionAllValidator { + void operator()(const EAXSESSIONPROPERTIES& all) const + { + Eax5EaxVersionValidator{}(all.ulEAXVersion); + Eax5MaxActiveSendsValidator{}(all.ulMaxActiveSends); + } + }; + + struct Eax5SpeakerConfigValidator { + void operator()(unsigned long ulSpeakerConfig) const + { + eax_validate_range( + "Speaker Config", + ulSpeakerConfig, + EAXCONTEXT_MINSPEAKERCONFIG, + EAXCONTEXT_MAXSPEAKERCONFIG); + } + }; bool eax_is_initialized_{}; bool eax_is_tried_{}; @@ -258,169 +396,129 @@ private: EaxFxSlotIndex eax_primary_fx_slot_index_{}; EaxFxSlots eax_fx_slots_{}; - int eax_version_{}; - Eax eax_{}; - Eax eax_d_{}; + int eax_version_{}; // Current EAX version. + Eax5State eax123_{}; // EAX1/EAX2/EAX3 state. + Eax4State eax4_{}; // EAX4 state. + Eax5State eax5_{}; // EAX5 state. + Eax5Props eax_{}; // Current EAX state. EAXSESSIONPROPERTIES eax_session_{}; - ContextDirtyFlags eax_context_dirty_flags_{}; - std::string eax_extension_list_{}; + [[noreturn]] static void eax_fail(const char* message); + [[noreturn]] static void eax_fail_unknown_property_set_id(); + [[noreturn]] static void eax_fail_unknown_primary_fx_slot_id(); + [[noreturn]] static void eax_fail_unknown_property_id(); + [[noreturn]] static void eax_fail_unknown_version(); - [[noreturn]] - static void eax_fail( - const char* message); + // Gets a value from EAX call, + // validates it, + // and updates the current value. + template + static void eax_set(const EaxCall& call, TProperty& property) + { + const auto& value = call.get_value(); + TValidator{}(value); + property = value; + } + // Gets a new value from EAX call, + // validates it, + // updates the deferred value, + // updates a dirty flag. + template< + typename TValidator, + EaxDirtyFlags TDirtyBit, + typename TMemberResult, + typename TProps, + typename TState> + static void eax_defer( + const EaxCall& call, + TState& state, + TMemberResult TProps::*member) noexcept + { + const auto& src = call.get_value(); + TValidator{}(src); + const auto& dst_i = state.i.*member; + auto& dst_d = state.d.*member; + dst_d = src; + + if(dst_i != dst_d) + state.df |= TDirtyBit; + } + + template< + EaxDirtyFlags TDirtyBit, + typename TMemberResult, + typename TProps, + typename TState> + void eax_context_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 eax_initialize_extensions(); - void eax_initialize(const EaxCall& call); - bool eax_has_no_default_effect_slot() const noexcept; - void eax_ensure_no_default_effect_slot() const; - bool eax_has_enough_aux_sends() const noexcept; - void eax_ensure_enough_aux_sends() const; - void eax_ensure_compatibility(); - unsigned long eax_detect_speaker_configuration() const; void eax_update_speaker_configuration(); - void eax_set_last_error_defaults() noexcept; - - void eax_set_session_defaults() noexcept; - - void eax_set_context_defaults() noexcept; - + void eax_session_set_defaults() noexcept; + static void eax4_context_set_defaults(Eax4Props& props) noexcept; + static void eax4_context_set_defaults(Eax4State& state) noexcept; + static void eax5_context_set_defaults(Eax5Props& props) noexcept; + static void eax5_context_set_defaults(Eax5State& state) noexcept; + void eax_context_set_defaults() noexcept; void eax_set_defaults() noexcept; void eax_initialize_sources(); - void eax_dispatch_fx_slot(const EaxCall& call); - void eax_dispatch_source(const EaxCall& call); - - void eax_get_primary_fx_slot_id(const EaxCall& call); - - void eax_get_distance_factor(const EaxCall& call); - - void eax_get_air_absorption_hf(const EaxCall& call); - - void eax_get_hf_reference(const EaxCall& call); - - void eax_get_last_error(const EaxCall& call); - - void eax_get_speaker_config(const EaxCall& call); - - void eax_get_session(const EaxCall& call); - - void eax_get_macro_fx_factor(const EaxCall& call); - - void eax_get_context_all(const EaxCall& call); - + void eax_get_misc(const EaxCall& call); + void eax4_get(const EaxCall& call, const Eax4Props& props); + void eax5_get(const EaxCall& call, const Eax5Props& props); void eax_get(const EaxCall& call); - - void eax_set_primary_fx_slot_id(); - - void eax_set_distance_factor(); - - void eax_set_air_absorbtion_hf(); - - void eax_set_hf_reference(); - - void eax_set_macro_fx_factor(); - - void eax_set_context(); + void eax_context_commit_primary_fx_slot_id(); + void eax_context_commit_distance_factor(); + void eax_context_commit_air_absorbtion_hf(); + void eax_context_commit_hf_reference(); + void eax_context_commit_macro_fx_factor(); void eax_initialize_fx_slots(const EaxCall& call); - void eax_update_sources(); - - void eax_validate_primary_fx_slot_id( - const GUID& primary_fx_slot_id); - - void eax_validate_distance_factor( - float distance_factor); - - void eax_validate_air_absorption_hf( - float air_absorption_hf); - - void eax_validate_hf_reference( - float hf_reference); - - void eax_validate_speaker_config( - unsigned long speaker_config); - - void eax_validate_session_eax_version( - unsigned long eax_version); - - void eax_validate_session_max_active_sends( - unsigned long max_active_sends); - - void eax_validate_session( - const EAXSESSIONPROPERTIES& eax_session); - - void eax_validate_macro_fx_factor( - float macro_fx_factor); - - void eax_validate_context_all( - const EAX40CONTEXTPROPERTIES& context_all); - - void eax_validate_context_all( - const EAX50CONTEXTPROPERTIES& context_all); - - - void eax_defer_primary_fx_slot_id( - const GUID& primary_fx_slot_id); - - void eax_defer_distance_factor( - float distance_factor); - - void eax_defer_air_absorption_hf( - float air_absorption_hf); - - void eax_defer_hf_reference( - float hf_reference); - - void eax_defer_macro_fx_factor( - float macro_fx_factor); - - void eax_defer_context_all( - const EAX40CONTEXTPROPERTIES& context_all); - - void eax_defer_context_all( - const EAX50CONTEXTPROPERTIES& context_all); - - - void eax_defer_context_all(const EaxCall& call); - - void eax_defer_primary_fx_slot_id(const EaxCall& call); - - void eax_defer_distance_factor(const EaxCall& call); - - void eax_defer_air_absorption_hf(const EaxCall& call); - - void eax_defer_hf_reference(const EaxCall& call); - - void eax_set_session(const EaxCall& call); - - void eax_defer_macro_fx_factor(const EaxCall& call); - + void eax_set_misc(const EaxCall& call); + void eax4_defer_all(const EaxCall& call, Eax4State& state); + void eax4_defer(const EaxCall& call, Eax4State& state); + void eax5_defer_all(const EaxCall& call, Eax5State& state); + void eax5_defer(const EaxCall& call, Eax5State& state); void eax_set(const EaxCall& call); - void eax_apply_deferred(); + void eax4_context_commit(Eax4State& state, EaxDirtyFlags& dst_df); + void eax5_context_commit(Eax5State& state, EaxDirtyFlags& dst_df); + void eax_context_commit(); + void eax_commit(); #endif // ALSOFT_EAX };