aboutsummaryrefslogtreecommitdiffstats
path: root/al/source.h
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-01-30 14:47:32 +0200
committerGitHub <[email protected]>2022-01-30 04:47:32 -0800
commit19ed994dc30ed84ea7cbbb5152577669fc25caf6 (patch)
treef68933bf8f778806618bd6c0b1bf9ced1b0ccf08 /al/source.h
parent619249371a40f03cf988d1f5750d643df797c485 (diff)
Add EAX extensions (EAX 2.0-5.0, X-RAM) (#632)
* Add EAX extensions (EAX 2.0-5.0, X-RAM) * Comment out C++17 leftovers * Remove everything related to patching * Update alsoftrc.sample * Rewrite integration * Fix GCC compilation under Linux * Always reset EAX effect properties when loading it into FX slot
Diffstat (limited to 'al/source.h')
-rw-r--r--al/source.h689
1 files changed, 689 insertions, 0 deletions
diff --git a/al/source.h b/al/source.h
index 25ece822..41cd6187 100644
--- a/al/source.h
+++ b/al/source.h
@@ -21,6 +21,12 @@
#include "core/voice.h"
#include "vector.h"
+#if ALSOFT_EAX
+#include "eax_eax_call.h"
+#include "eax_fx_slot_index.h"
+#include "eax_utils.h"
+#endif // ALSOFT_EAX
+
struct ALbuffer;
struct ALeffectslot;
@@ -41,6 +47,77 @@ struct ALbufferQueueItem : public VoiceBufferItem {
};
+#if ALSOFT_EAX
+struct EaxSourceInitParam
+{
+ ALCcontext* al_context{};
+ ALfilter* al_filter{};
+}; // EaxSourceInitParam
+
+
+using EaxSourceSourceFilterDirtyFlagsValue = std::uint_least16_t;
+
+struct EaxSourceSourceFilterDirtyFlags
+{
+ using EaxIsBitFieldStruct = bool;
+
+ EaxSourceSourceFilterDirtyFlagsValue lDirect : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lDirectHF : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lRoom : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lRoomHF : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lObstruction : 1;
+ EaxSourceSourceFilterDirtyFlagsValue flObstructionLFRatio : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lOcclusion : 1;
+ EaxSourceSourceFilterDirtyFlagsValue flOcclusionLFRatio : 1;
+ EaxSourceSourceFilterDirtyFlagsValue flOcclusionRoomRatio : 1;
+ EaxSourceSourceFilterDirtyFlagsValue flOcclusionDirectRatio : 1;
+ EaxSourceSourceFilterDirtyFlagsValue lExclusion : 1;
+ EaxSourceSourceFilterDirtyFlagsValue flExclusionLFRatio : 1;
+}; // EaxSourceSourceFilterDirtyFlags
+
+
+using EaxSourceSourceMiscDirtyFlagsValue = std::uint_least8_t;
+
+struct EaxSourceSourceMiscDirtyFlags
+{
+ using EaxIsBitFieldStruct = bool;
+
+ EaxSourceSourceMiscDirtyFlagsValue lOutsideVolumeHF : 1;
+ EaxSourceSourceMiscDirtyFlagsValue flDopplerFactor : 1;
+ EaxSourceSourceMiscDirtyFlagsValue flRolloffFactor : 1;
+ EaxSourceSourceMiscDirtyFlagsValue flRoomRolloffFactor : 1;
+ EaxSourceSourceMiscDirtyFlagsValue flAirAbsorptionFactor : 1;
+ EaxSourceSourceMiscDirtyFlagsValue ulFlags : 1;
+ EaxSourceSourceMiscDirtyFlagsValue flMacroFXFactor : 1;
+ EaxSourceSourceMiscDirtyFlagsValue speaker_levels : 1;
+}; // EaxSourceSourceMiscDirtyFlags
+
+
+using EaxSourceSendDirtyFlagsValue = std::uint_least8_t;
+
+struct EaxSourceSendDirtyFlags
+{
+ using EaxIsBitFieldStruct = bool;
+
+ EaxSourceSendDirtyFlagsValue lSend : 1;
+ EaxSourceSendDirtyFlagsValue lSendHF : 1;
+ EaxSourceSendDirtyFlagsValue lOcclusion : 1;
+ EaxSourceSendDirtyFlagsValue flOcclusionLFRatio : 1;
+ EaxSourceSendDirtyFlagsValue flOcclusionRoomRatio : 1;
+ EaxSourceSendDirtyFlagsValue flOcclusionDirectRatio : 1;
+ EaxSourceSendDirtyFlagsValue lExclusion : 1;
+ EaxSourceSendDirtyFlagsValue flExclusionLFRatio : 1;
+}; // EaxSourceSendDirtyFlags
+
+
+struct EaxSourceSendsDirtyFlags
+{
+ using EaxIsBitFieldStruct = bool;
+
+ EaxSourceSendDirtyFlags sends[EAX_MAX_FXSLOTS];
+}; // EaxSourceSendsDirtyFlags
+#endif // ALSOFT_EAX
+
struct ALsource {
/** Source properties. */
float Pitch{1.0f};
@@ -135,6 +212,618 @@ struct ALsource {
ALsource& operator=(const ALsource&) = delete;
DISABLE_ALLOC()
+
+#if ALSOFT_EAX
+public:
+ void eax_initialize(
+ const EaxSourceInitParam& param) noexcept;
+
+ void eax_uninitialize();
+
+
+ void eax_dispatch(
+ const EaxEaxCall& eax_call);
+
+
+ void eax_update_filters();
+
+ void eax_update(
+ EaxContextSharedDirtyFlags dirty_flags);
+
+
+ static ALsource* eax_lookup_source(
+ ALCcontext& al_context,
+ ALuint source_id) noexcept;
+
+
+private:
+ static constexpr auto eax_max_speakers = 9;
+
+
+ using EaxActiveFxSlots = std::array<bool, EAX_MAX_FXSLOTS>;
+ using EaxSpeakerLevels = std::array<long, eax_max_speakers>;
+
+
+ struct Eax
+ {
+ using Sends = std::array<EAXSOURCEALLSENDPROPERTIES, EAX_MAX_FXSLOTS>;
+
+ EAX50ACTIVEFXSLOTS active_fx_slots{};
+ EAX50SOURCEPROPERTIES source{};
+ Sends sends{};
+ EaxSpeakerLevels speaker_levels{};
+ }; // Eax
+
+
+ bool eax_uses_primary_id_{};
+ bool eax_has_active_fx_slots_{};
+ bool eax_are_active_fx_slots_dirty_{};
+
+ ALCcontext* eax_al_context_{};
+ ALfilter* eax_al_filter_{};
+
+ Eax eax_{};
+ Eax eax_d_{};
+ EaxActiveFxSlots eax_active_fx_slots_{};
+
+ EaxSourceSendsDirtyFlags eax_sends_dirty_flags_{};
+ EaxSourceSourceFilterDirtyFlags eax_source_dirty_filter_flags_{};
+ EaxSourceSourceMiscDirtyFlags eax_source_dirty_misc_flags_{};
+
+
+ [[noreturn]]
+ static void eax_fail(
+ const char* message);
+
+
+ static void eax_validate_init_param(
+ const EaxSourceInitParam& param);
+
+ void eax_copy_init_param(
+ const EaxSourceInitParam& param);
+
+
+ void eax_set_source_defaults();
+
+ void eax_set_active_fx_slots_defaults();
+
+ void eax_set_send_defaults(
+ EAXSOURCEALLSENDPROPERTIES& eax_send);
+
+ void eax_set_sends_defaults();
+
+ void eax_set_speaker_levels_defaults();
+
+ void eax_set_defaults();
+
+
+ static float eax_calculate_dst_occlusion_mb(
+ long src_occlusion_mb,
+ float path_ratio,
+ float lf_ratio) noexcept;
+
+ EaxAlLowPassParam eax_create_direct_filter_param() const noexcept;
+
+ EaxAlLowPassParam eax_create_room_filter_param(
+ const ALeffectslot& fx_slot,
+ const EAXSOURCEALLSENDPROPERTIES& send) const noexcept;
+
+ void eax_set_al_filter_parameters(
+ const EaxAlLowPassParam& al_low_pass_param) const noexcept;
+
+ void eax_set_fx_slots();
+
+ void eax_initialize_fx_slots();
+
+ void eax_update_direct_filter_internal();
+
+ void eax_update_room_filters_internal();
+
+ void eax_update_filters_internal();
+
+ void eax_update_primary_fx_slot_id();
+
+
+ void eax_defer_active_fx_slots(
+ const EaxEaxCall& eax_call);
+
+
+ static const char* eax_get_exclusion_name() noexcept;
+
+ static const char* eax_get_exclusion_lf_ratio_name() noexcept;
+
+
+ static const char* eax_get_occlusion_name() noexcept;
+
+ static const char* eax_get_occlusion_lf_ratio_name() noexcept;
+
+ static const char* eax_get_occlusion_direct_ratio_name() noexcept;
+
+ static const char* eax_get_occlusion_room_ratio_name() noexcept;
+
+
+ static void eax_validate_send_receiving_fx_slot_guid(
+ const GUID& guidReceivingFXSlotID);
+
+ static void eax_validate_send_send(
+ long lSend);
+
+ static void eax_validate_send_send_hf(
+ long lSendHF);
+
+ static void eax_validate_send_occlusion(
+ long lOcclusion);
+
+ static void eax_validate_send_occlusion_lf_ratio(
+ float flOcclusionLFRatio);
+
+ static void eax_validate_send_occlusion_room_ratio(
+ float flOcclusionRoomRatio);
+
+ static void eax_validate_send_occlusion_direct_ratio(
+ float flOcclusionDirectRatio);
+
+ static void eax_validate_send_exclusion(
+ long lExclusion);
+
+ static void eax_validate_send_exclusion_lf_ratio(
+ float flExclusionLFRatio);
+
+ static void eax_validate_send(
+ const EAXSOURCESENDPROPERTIES& all);
+
+ static void eax_validate_send_exclusion_all(
+ const EAXSOURCEEXCLUSIONSENDPROPERTIES& all);
+
+ static void eax_validate_send_occlusion_all(
+ const EAXSOURCEOCCLUSIONSENDPROPERTIES& all);
+
+ static void eax_validate_send_all(
+ const EAXSOURCEALLSENDPROPERTIES& all);
+
+
+ static EaxFxSlotIndexValue eax_get_send_index(
+ const GUID& send_guid);
+
+
+ void eax_defer_send_send(
+ long lSend,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_send_hf(
+ long lSendHF,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_occlusion(
+ long lOcclusion,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_occlusion_lf_ratio(
+ float flOcclusionLFRatio,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_occlusion_room_ratio(
+ float flOcclusionRoomRatio,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_occlusion_direct_ratio(
+ float flOcclusionDirectRatio,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_exclusion(
+ long lExclusion,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_exclusion_lf_ratio(
+ float flExclusionLFRatio,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send(
+ const EAXSOURCESENDPROPERTIES& all,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_exclusion_all(
+ const EAXSOURCEEXCLUSIONSENDPROPERTIES& all,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_occlusion_all(
+ const EAXSOURCEOCCLUSIONSENDPROPERTIES& all,
+ EaxFxSlotIndexValue index);
+
+ void eax_defer_send_all(
+ const EAXSOURCEALLSENDPROPERTIES& all,
+ EaxFxSlotIndexValue index);
+
+
+ void eax_defer_send(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_send_exclusion_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_send_occlusion_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_send_all(
+ const EaxEaxCall& eax_call);
+
+
+ static void eax_validate_source_direct(
+ long direct);
+
+ static void eax_validate_source_direct_hf(
+ long direct_hf);
+
+ static void eax_validate_source_room(
+ long room);
+
+ static void eax_validate_source_room_hf(
+ long room_hf);
+
+ static void eax_validate_source_obstruction(
+ long obstruction);
+
+ static void eax_validate_source_obstruction_lf_ratio(
+ float obstruction_lf_ratio);
+
+ static void eax_validate_source_occlusion(
+ long occlusion);
+
+ static void eax_validate_source_occlusion_lf_ratio(
+ float occlusion_lf_ratio);
+
+ static void eax_validate_source_occlusion_room_ratio(
+ float occlusion_room_ratio);
+
+ static void eax_validate_source_occlusion_direct_ratio(
+ float occlusion_direct_ratio);
+
+ static void eax_validate_source_exclusion(
+ long exclusion);
+
+ static void eax_validate_source_exclusion_lf_ratio(
+ float exclusion_lf_ratio);
+
+ static void eax_validate_source_outside_volume_hf(
+ long outside_volume_hf);
+
+ static void eax_validate_source_doppler_factor(
+ float doppler_factor);
+
+ static void eax_validate_source_rolloff_factor(
+ float rolloff_factor);
+
+ static void eax_validate_source_room_rolloff_factor(
+ float room_rolloff_factor);
+
+ static void eax_validate_source_air_absorption_factor(
+ float air_absorption_factor);
+
+ static void eax_validate_source_flags(
+ unsigned long flags,
+ int eax_version);
+
+ static void eax_validate_source_macro_fx_factor(
+ float macro_fx_factor);
+
+ static void eax_validate_source_2d_all(
+ const EAXSOURCE2DPROPERTIES& all,
+ int eax_version);
+
+ static void eax_validate_source_obstruction_all(
+ const EAXOBSTRUCTIONPROPERTIES& all);
+
+ static void eax_validate_source_exclusion_all(
+ const EAXEXCLUSIONPROPERTIES& all);
+
+ static void eax_validate_source_occlusion_all(
+ const EAXOCCLUSIONPROPERTIES& all);
+
+ static void eax_validate_source_all(
+ const EAX20BUFFERPROPERTIES& all,
+ int eax_version);
+
+ static void eax_validate_source_all(
+ const EAX30SOURCEPROPERTIES& all,
+ int eax_version);
+
+ static void eax_validate_source_all(
+ const EAX50SOURCEPROPERTIES& all,
+ int eax_version);
+
+ static void eax_validate_source_speaker_id(
+ long speaker_id);
+
+ static void eax_validate_source_speaker_level(
+ long speaker_level);
+
+ static void eax_validate_source_speaker_level_all(
+ const EAXSPEAKERLEVELPROPERTIES& all);
+
+
+ void eax_defer_source_direct(
+ long lDirect);
+
+ void eax_defer_source_direct_hf(
+ long lDirectHF);
+
+ void eax_defer_source_room(
+ long lRoom);
+
+ void eax_defer_source_room_hf(
+ long lRoomHF);
+
+ void eax_defer_source_obstruction(
+ long lObstruction);
+
+ void eax_defer_source_obstruction_lf_ratio(
+ float flObstructionLFRatio);
+
+ void eax_defer_source_occlusion(
+ long lOcclusion);
+
+ void eax_defer_source_occlusion_lf_ratio(
+ float flOcclusionLFRatio);
+
+ void eax_defer_source_occlusion_room_ratio(
+ float flOcclusionRoomRatio);
+
+ void eax_defer_source_occlusion_direct_ratio(
+ float flOcclusionDirectRatio);
+
+ void eax_defer_source_exclusion(
+ long lExclusion);
+
+ void eax_defer_source_exclusion_lf_ratio(
+ float flExclusionLFRatio);
+
+ void eax_defer_source_outside_volume_hf(
+ long lOutsideVolumeHF);
+
+ void eax_defer_source_doppler_factor(
+ float flDopplerFactor);
+
+ void eax_defer_source_rolloff_factor(
+ float flRolloffFactor);
+
+ void eax_defer_source_room_rolloff_factor(
+ float flRoomRolloffFactor);
+
+ void eax_defer_source_air_absorption_factor(
+ float flAirAbsorptionFactor);
+
+ void eax_defer_source_flags(
+ unsigned long ulFlags);
+
+ void eax_defer_source_macro_fx_factor(
+ float flMacroFXFactor);
+
+ void eax_defer_source_2d_all(
+ const EAXSOURCE2DPROPERTIES& all);
+
+ void eax_defer_source_obstruction_all(
+ const EAXOBSTRUCTIONPROPERTIES& all);
+
+ void eax_defer_source_exclusion_all(
+ const EAXEXCLUSIONPROPERTIES& all);
+
+ void eax_defer_source_occlusion_all(
+ const EAXOCCLUSIONPROPERTIES& all);
+
+ void eax_defer_source_all(
+ const EAX20BUFFERPROPERTIES& all);
+
+ void eax_defer_source_all(
+ const EAX30SOURCEPROPERTIES& all);
+
+ void eax_defer_source_all(
+ const EAX50SOURCEPROPERTIES& all);
+
+ void eax_defer_source_speaker_level_all(
+ const EAXSPEAKERLEVELPROPERTIES& all);
+
+
+ void eax_defer_source_direct(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_direct_hf(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_room(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_room_hf(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_obstruction(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_obstruction_lf_ratio(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_occlusion(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_occlusion_lf_ratio(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_occlusion_room_ratio(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_occlusion_direct_ratio(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_exclusion(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_exclusion_lf_ratio(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_outside_volume_hf(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_doppler_factor(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_rolloff_factor(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_room_rolloff_factor(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_air_absorption_factor(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_flags(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_macro_fx_factor(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_2d_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_obstruction_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_exclusion_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_occlusion_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_defer_source_speaker_level_all(
+ const EaxEaxCall& eax_call);
+
+
+ void eax_set_outside_volume_hf();
+
+ void eax_set_doppler_factor();
+
+ void eax_set_rolloff_factor();
+
+ void eax_set_room_rolloff_factor();
+
+ void eax_set_air_absorption_factor();
+
+
+ void eax_set_direct_hf_auto_flag();
+
+ void eax_set_room_auto_flag();
+
+ void eax_set_room_hf_auto_flag();
+
+ void eax_set_flags();
+
+
+ void eax_set_macro_fx_factor();
+
+ void eax_set_speaker_levels();
+
+
+ void eax_apply_deferred();
+
+ void eax_set(
+ const EaxEaxCall& eax_call);
+
+
+ static const GUID& eax_get_send_fx_slot_guid(
+ int eax_version,
+ EaxFxSlotIndexValue fx_slot_index);
+
+ static void eax_copy_send(
+ const EAXSOURCEALLSENDPROPERTIES& src_send,
+ EAXSOURCESENDPROPERTIES& dst_send);
+
+ static void eax_copy_send(
+ const EAXSOURCEALLSENDPROPERTIES& src_send,
+ EAXSOURCEALLSENDPROPERTIES& dst_send);
+
+ static void eax_copy_send(
+ const EAXSOURCEALLSENDPROPERTIES& src_send,
+ EAXSOURCEOCCLUSIONSENDPROPERTIES& dst_send);
+
+ static void eax_copy_send(
+ const EAXSOURCEALLSENDPROPERTIES& src_send,
+ EAXSOURCEEXCLUSIONSENDPROPERTIES& dst_send);
+
+ template<
+ typename TException,
+ typename TSrcSend
+ >
+ void eax_api_get_send_properties(
+ const EaxEaxCall& eax_call) const
+ {
+ const auto eax_version = eax_call.get_version();
+ const auto dst_sends = eax_call.get_values<TException, TSrcSend>();
+ const auto send_count = dst_sends.size();
+
+ for (auto fx_slot_index = EaxFxSlotIndexValue{}; fx_slot_index < send_count; ++fx_slot_index)
+ {
+ auto& dst_send = dst_sends[fx_slot_index];
+ const auto& src_send = eax_.sends[fx_slot_index];
+
+ eax_copy_send(src_send, dst_send);
+
+ dst_send.guidReceivingFXSlotID = eax_get_send_fx_slot_guid(eax_version, fx_slot_index);
+ }
+ }
+
+
+ void eax_api_get_source_all_v2(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_v3(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_v5(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_obstruction(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_occlusion(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_exclusion(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_active_fx_slot_id(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_all_2d(
+ const EaxEaxCall& eax_call);
+
+ void eax_api_get_source_speaker_level_all(
+ const EaxEaxCall& eax_call);
+
+ void eax_get(
+ const EaxEaxCall& eax_call);
+
+
+ // `alSourcei`
+ void eax_al_source_i(
+ ALenum param,
+ ALint value);
+
+ // `alSourcef`
+ void eax_al_source_f(
+ ALenum param,
+ ALfloat value);
+
+ // `alSource3i`
+ void eax_al_source_3i(
+ ALenum param,
+ ALint value1,
+ ALint value2,
+ ALint value3);
+#endif // ALSOFT_EAX
};
void UpdateAllSourceProps(ALCcontext *context);