diff options
author | Chris Robinson <[email protected]> | 2022-02-07 13:52:51 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-02-07 13:53:57 -0800 |
commit | f23c7fe8ba77d4d406d37c60501f961313db7d1a (patch) | |
tree | 569b57749d759f98bf114beac1893c1341dcf702 | |
parent | 1807e083c8a4579979748d062e7b54a19c3b76b9 (diff) |
Avoid a proxy ALfilter object for EAX source properties
-rw-r--r-- | al/filter.cpp | 81 | ||||
-rw-r--r-- | al/filter.h | 39 | ||||
-rw-r--r-- | al/source.cpp | 193 | ||||
-rw-r--r-- | al/source.h | 49 | ||||
-rw-r--r-- | alc/context.cpp | 29 | ||||
-rw-r--r-- | alc/context.h | 8 |
6 files changed, 79 insertions, 320 deletions
diff --git a/al/filter.cpp b/al/filter.cpp index 9989063b..73067fd9 100644 --- a/al/filter.cpp +++ b/al/filter.cpp @@ -45,10 +45,6 @@ #include "opthelpers.h" #include "vector.h" -#ifdef ALSOFT_EAX -#include "core/logging.h" -#endif // ALSOFT_EAX - namespace { @@ -721,80 +717,3 @@ FilterSubList::~FilterSubList() al_free(Filters); Filters = nullptr; } - - -#ifdef ALSOFT_EAX -EaxAlFilterDeleter::EaxAlFilterDeleter( - ALCcontext& context) - : - context_{&context} -{ -} - -void EaxAlFilterDeleter::operator()( - ALfilter* filter) -{ - eax_delete_low_pass_filter(*context_, *filter); -} - -EaxAlFilterUPtr eax_create_al_low_pass_filter( - ALCcontext& context) -{ -#define EAX_PREFIX "[EAX_MAKE_LOW_PASS_FILTER] " - - auto& device = *context.mALDevice; - std::lock_guard<std::mutex> filter_lock{device.FilterLock}; - - if (!EnsureFilters(&device, 1)) - { - ERR(EAX_PREFIX "%s\n", "Failed to ensure."); - return nullptr; - } - - auto filter = EaxAlFilterUPtr{AllocFilter(&device), EaxAlFilterDeleter{context}}; - - if (!filter) - { - ERR(EAX_PREFIX "%s\n", "Failed to allocate."); - return nullptr; - } - - InitFilterParams(filter.get(), AL_FILTER_LOWPASS); - - return filter; - -#undef EAX_PREFIX -} - -void eax_delete_low_pass_filter( - ALCcontext& context, - ALfilter& filter) -{ - auto& device = *context.mALDevice; - std::lock_guard<std::mutex> filter_lock{device.FilterLock}; - - FreeFilter(&device, &filter); -} - -void ALfilter::eax_set_low_pass_params( - ALCcontext& context, - const EaxAlLowPassParam& param) -{ -#define EAX_PREFIX "[EAX_SET_LOW_PASS_FILTER_PARAMS] " - - auto& device = *context.mALDevice; - std::lock_guard<std::mutex> filter_lock{device.FilterLock}; - - try - { - setParamf(AL_LOWPASS_GAIN, param.gain); - setParamf(AL_LOWPASS_GAINHF, param.gain_hf); - } - catch (const filter_exception &e) - { - ERR(EAX_PREFIX "%s\n", e.what()); - } - -#undef EAX_PREFIX -} -#endif // ALSOFT_EAX diff --git a/al/filter.h b/al/filter.h index 98c32325..65a9e30f 100644 --- a/al/filter.h +++ b/al/filter.h @@ -8,12 +8,6 @@ #include "almalloc.h" -#ifdef ALSOFT_EAX -#include <memory> - -#include "eax_utils.h" -#endif // ALSOFT_EAX - #define LOWPASSFREQREF 5000.0f #define HIGHPASSFREQREF 250.0f @@ -53,39 +47,6 @@ struct ALfilter { void getParamfv(ALenum param, float *values) const { vtab->getParamfv(this, param, values); } DISABLE_ALLOC() - -#ifdef ALSOFT_EAX -public: - void eax_set_low_pass_params( - ALCcontext& context, - const EaxAlLowPassParam& param); -#endif // ALSOFT_EAX }; -#ifdef ALSOFT_EAX -class EaxAlFilterDeleter { -public: - EaxAlFilterDeleter() noexcept = default; - - EaxAlFilterDeleter( - ALCcontext& context); - - - void operator()( - ALfilter* filter); - -private: - ALCcontext* context_{}; -}; // EaxAlFilterDeleter - -using EaxAlFilterUPtr = std::unique_ptr<ALfilter, EaxAlFilterDeleter>; - -EaxAlFilterUPtr eax_create_al_low_pass_filter( - ALCcontext& context); - -void eax_delete_low_pass_filter( - ALCcontext& context, - ALfilter& filter); -#endif // ALSOFT_EAX - #endif diff --git a/al/source.cpp b/al/source.cpp index 02df86e4..87696147 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -2400,6 +2400,12 @@ START_API_FUNC context->setError(AL_INVALID_VALUE, "Generating %d sources", n); if UNLIKELY(n <= 0) return; +#ifdef ALSOFT_EAX + const bool has_eax{context->has_eax()}; + std::unique_lock<std::mutex> proplock{}; + if(has_eax) + proplock = std::unique_lock<std::mutex>{context->mPropLock}; +#endif std::unique_lock<std::mutex> srclock{context->mSourceLock}; ALCdevice *device{context->mALDevice.get()}; if(static_cast<ALuint>(n) > device->SourcesMax-context->mNumSources) @@ -2420,22 +2426,16 @@ START_API_FUNC sources[0] = source->id; #ifdef ALSOFT_EAX - if (context->has_eax()) - { - std::unique_lock<std::mutex> prop_lock{context->mPropLock}; - context->eax_initialize_source(*source); - } + if(has_eax) + source->eax_initialize(context.get()); #endif // ALSOFT_EAX } else { #ifdef ALSOFT_EAX auto eax_sources = al::vector<ALsource*>{}; - - if (context->has_eax()) - { + if(has_eax) eax_sources.reserve(static_cast<ALuint>(n)); - } #endif // ALSOFT_EAX al::vector<ALuint> ids; @@ -2445,24 +2445,15 @@ START_API_FUNC ids.emplace_back(source->id); #ifdef ALSOFT_EAX - if (context->has_eax()) - { + if(has_eax) eax_sources.emplace_back(source); - } #endif // ALSOFT_EAX } while(--n); std::copy(ids.cbegin(), ids.cend(), sources); #ifdef ALSOFT_EAX - if (context->has_eax()) - { - std::unique_lock<std::mutex> prop_lock{context->mPropLock}; - - for (auto& eax_source : eax_sources) - { - context->eax_initialize_source(*eax_source); - } - } + for(auto& eax_source : eax_sources) + eax_source->eax_initialize(context.get()); #endif // ALSOFT_EAX } } @@ -3595,10 +3586,6 @@ ALsource::ALsource() ALsource::~ALsource() { -#ifdef ALSOFT_EAX - eax_uninitialize(); -#endif // ALSOFT_EAX - for(auto &item : mQueue) { if(ALbuffer *buffer{item.mBuffer}) @@ -3683,40 +3670,16 @@ public: }; // EaxSourceSendException -void ALsource::eax_initialize( - const EaxSourceInitParam& param) noexcept +void ALsource::eax_initialize(ALCcontext *context) noexcept { - eax_validate_init_param(param); - eax_copy_init_param(param); + assert(context); + eax_al_context_ = context; eax_set_defaults(); eax_initialize_fx_slots(); eax_d_ = eax_; } -void ALsource::eax_uninitialize() -{ - if (!eax_al_context_) - { - return; - } - - if (eax_al_context_->has_eax()) - { - for (auto i = 0; i < EAX_MAX_FXSLOTS; ++i) - { - eax_al_source_3i( - AL_AUXILIARY_SEND_FILTER, - AL_EFFECTSLOT_NULL, - static_cast<ALint>(i), - AL_FILTER_NULL - ); - } - } - - eax_al_context_ = nullptr; -} - void ALsource::eax_dispatch( const EaxEaxCall& eax_call) { @@ -3766,28 +3729,7 @@ void ALsource::eax_fail( throw EaxSourceException{message}; } -void ALsource::eax_validate_init_param( - const EaxSourceInitParam& param) -{ - if (!param.al_context) - { - eax_fail("Null context."); - } - - if (!param.al_filter) - { - eax_fail("Null filter."); - } -} - -void ALsource::eax_copy_init_param( - const EaxSourceInitParam& param) -{ - eax_al_context_ = param.al_context; - eax_al_filter_ = param.al_filter; -} - -void ALsource::eax_set_source_defaults() +void ALsource::eax_set_source_defaults() noexcept { eax_.source.lDirect = EAXSOURCE_DEFAULTDIRECT; eax_.source.lDirectHF = EAXSOURCE_DEFAULTDIRECTHF; @@ -3809,13 +3751,12 @@ void ALsource::eax_set_source_defaults() eax_.source.ulFlags = EAXSOURCE_DEFAULTFLAGS; } -void ALsource::eax_set_active_fx_slots_defaults() +void ALsource::eax_set_active_fx_slots_defaults() noexcept { eax_.active_fx_slots = EAX50SOURCE_3DDEFAULTACTIVEFXSLOTID; } -void ALsource::eax_set_send_defaults( - EAXSOURCEALLSENDPROPERTIES& eax_send) +void ALsource::eax_set_send_defaults(EAXSOURCEALLSENDPROPERTIES& eax_send) noexcept { eax_send.guidReceivingFXSlotID = EAX_NULL_GUID; eax_send.lSend = EAXSOURCE_DEFAULTSEND; @@ -3828,7 +3769,7 @@ void ALsource::eax_set_send_defaults( eax_send.flExclusionLFRatio = EAXSOURCE_DEFAULTEXCLUSIONLFRATIO; } -void ALsource::eax_set_sends_defaults() +void ALsource::eax_set_sends_defaults() noexcept { for (auto& eax_send : eax_.sends) { @@ -3836,12 +3777,12 @@ void ALsource::eax_set_sends_defaults() } } -void ALsource::eax_set_speaker_levels_defaults() +void ALsource::eax_set_speaker_levels_defaults() noexcept { std::fill(eax_.speaker_levels.begin(), eax_.speaker_levels.end(), EAXSOURCE_DEFAULTSPEAKERLEVEL); } -void ALsource::eax_set_defaults() +void ALsource::eax_set_defaults() noexcept { eax_set_source_defaults(); eax_set_active_fx_slots_defaults(); @@ -3960,12 +3901,6 @@ EaxAlLowPassParam ALsource::eax_create_room_filter_param( return al_low_pass_param; } -void ALsource::eax_set_al_filter_parameters( - const EaxAlLowPassParam& al_low_pass_param) const noexcept -{ - eax_al_filter_->eax_set_low_pass_params(*eax_al_context_, al_low_pass_param); -} - void ALsource::eax_set_fx_slots() { eax_uses_primary_id_ = false; @@ -3994,15 +3929,11 @@ void ALsource::eax_set_fx_slots() } } - for (auto i = 0; i < EAX_MAX_FXSLOTS; ++i) + for (auto i = 0u; i < EAX_MAX_FXSLOTS; ++i) { - if (!eax_active_fx_slots_[static_cast<std::size_t>(i)]) + if (!eax_active_fx_slots_[i]) { - eax_al_source_3i( - AL_AUXILIARY_SEND_FILTER, - AL_EFFECTSLOT_NULL, - i, - AL_FILTER_NULL); + eax_set_al_source_send(nullptr, i, EaxAlLowPassParam{1.0f, 1.0f}); } } } @@ -4032,22 +3963,15 @@ void ALsource::eax_update_room_filters_internal() return; } - for (auto i = 0; i < EAX_MAX_FXSLOTS; ++i) + for (auto i = 0u; i < EAX_MAX_FXSLOTS; ++i) { - if (eax_active_fx_slots_[static_cast<std::size_t>(i)]) + if (eax_active_fx_slots_[i]) { - const auto& fx_slot = eax_al_context_->eax_get_fx_slot(static_cast<std::size_t>(i)); - const auto& send = eax_.sends[static_cast<std::size_t>(i)]; + auto& fx_slot = eax_al_context_->eax_get_fx_slot(static_cast<std::size_t>(i)); + const auto& send = eax_.sends[i]; const auto& room_param = eax_create_room_filter_param(fx_slot, send); - eax_set_al_filter_parameters(room_param); - - eax_al_source_3i( - AL_AUXILIARY_SEND_FILTER, - static_cast<ALint>(fx_slot.id), - i, - static_cast<ALint>(eax_al_filter_->id) - ); + eax_set_al_source_send(&fx_slot, i, room_param); } } } @@ -4073,11 +3997,7 @@ void ALsource::eax_update_primary_fx_slot_id() const auto fx_slot_index = previous_primary_fx_slot_index.get(); eax_active_fx_slots_[fx_slot_index] = false; - eax_al_source_3i( - AL_AUXILIARY_SEND_FILTER, - AL_EFFECTSLOT_NULL, - static_cast<ALint>(fx_slot_index), - static_cast<ALint>(AL_FILTER_NULL)); + eax_set_al_source_send(nullptr, fx_slot_index, EaxAlLowPassParam{1.0f, 1.0f}); } if (primary_fx_slot_index.has_value()) @@ -4085,17 +4005,11 @@ void ALsource::eax_update_primary_fx_slot_id() const auto fx_slot_index = primary_fx_slot_index.get(); eax_active_fx_slots_[fx_slot_index] = true; - const auto& fx_slot = eax_al_context_->eax_get_fx_slot(fx_slot_index); + auto& fx_slot = eax_al_context_->eax_get_fx_slot(fx_slot_index); const auto& send = eax_.sends[fx_slot_index]; const auto& room_param = eax_create_room_filter_param(fx_slot, send); - eax_set_al_filter_parameters(room_param); - - eax_al_source_3i( - AL_AUXILIARY_SEND_FILTER, - static_cast<ALint>(fx_slot.id), - static_cast<ALint>(fx_slot_index), - static_cast<ALint>(eax_al_filter_->id)); + eax_set_al_source_send(&fx_slot, fx_slot_index, room_param); } eax_has_active_fx_slots_ = std::any_of( @@ -6042,14 +5956,43 @@ void ALsource::eax_get( } } -void ALsource::eax_al_source_3i( - ALenum param, - ALint value1, - ALint value2, - ALint value3) +void ALsource::eax_set_al_source_send( + ALeffectslot *slot, + size_t sendidx, + const EaxAlLowPassParam &filter) { - const ALint values[3] = {value1, value2, value3}; - SetSourceiv(this, eax_al_context_, static_cast<SourceProp>(param), values); + if(sendidx >= EAX_MAX_FXSLOTS) + return; + + auto &send = Send[sendidx]; + send.Gain = filter.gain; + send.GainHF = filter.gain_hf; + send.HFReference = LOWPASSFREQREF; + send.GainLF = 1.0f; + send.LFReference = HIGHPASSFREQREF; + + if(send.Slot && slot != send.Slot && IsPlayingOrPaused(this)) + { + /* Add refcount on the new slot, and release the previous slot */ + if(slot) IncrementRef(slot->ref); + DecrementRef(send.Slot->ref); + send.Slot = slot; + + /* We must force an update if the auxiliary slot changed on an active + * source, in case the slot is about to be deleted. + */ + Voice *voice{GetSourceVoice(this, eax_al_context_)}; + if(voice) UpdateSourceProps(this, voice, eax_al_context_); + else mPropsDirty.set(std::memory_order_release); + } + else + { + if(slot) IncrementRef(slot->ref); + if(auto *oldslot = send.Slot) + DecrementRef(oldslot->ref); + send.Slot = slot; + UpdateSourceProps(this, eax_al_context_); + } } #endif // ALSOFT_EAX diff --git a/al/source.h b/al/source.h index 691de3a9..b2fea08b 100644 --- a/al/source.h +++ b/al/source.h @@ -48,12 +48,6 @@ struct ALbufferQueueItem : public VoiceBufferItem { #ifdef ALSOFT_EAX -struct EaxSourceInitParam { - ALCcontext* al_context{}; - ALfilter* al_filter{}; -}; // EaxSourceInitParam - - using EaxSourceSourceFilterDirtyFlagsValue = std::uint_least16_t; struct EaxSourceSourceFilterDirtyFlags @@ -214,10 +208,7 @@ struct ALsource { #ifdef ALSOFT_EAX public: - void eax_initialize( - const EaxSourceInitParam& param) noexcept; - - void eax_uninitialize(); + void eax_initialize(ALCcontext *context) noexcept; void eax_dispatch( @@ -259,7 +250,6 @@ private: bool eax_are_active_fx_slots_dirty_{}; ALCcontext* eax_al_context_{}; - ALfilter* eax_al_filter_{}; Eax eax_{}; Eax eax_d_{}; @@ -275,25 +265,12 @@ private: 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(); + void eax_set_source_defaults() noexcept; + void eax_set_active_fx_slots_defaults() noexcept; + void eax_set_send_defaults(EAXSOURCEALLSENDPROPERTIES& eax_send) noexcept; + void eax_set_sends_defaults() noexcept; + void eax_set_speaker_levels_defaults() noexcept; + void eax_set_defaults() noexcept; static float eax_calculate_dst_occlusion_mb( @@ -307,9 +284,6 @@ private: 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(); @@ -806,12 +780,9 @@ private: const EaxEaxCall& eax_call); - // `alSource3i` - void eax_al_source_3i( - ALenum param, - ALint value1, - ALint value2, - ALint value3); + // `alSource3i(source, AL_AUXILIARY_SEND_FILTER, ...)` + void eax_set_al_source_send(ALeffectslot *slot, size_t sendidx, + const EaxAlLowPassParam &filter); #endif // ALSOFT_EAX }; diff --git a/alc/context.cpp b/alc/context.cpp index 902e86be..1e363a41 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -467,22 +467,6 @@ void ALCcontext::eax_uninitialize() noexcept eax_is_tried_ = false; eax_fx_slots_.uninitialize(); - eax_al_filter_ = nullptr; -} - -void ALCcontext::eax_initialize_source( - ALsource& al_source) noexcept -try -{ - auto param = EaxSourceInitParam{}; - param.al_context = this; - param.al_filter = eax_al_filter_.get(); - - al_source.eax_initialize(param); -} -catch (...) -{ - eax_log_exception("Failed to initialize a source."); } ALenum ALCcontext::eax_eax_set( @@ -682,7 +666,6 @@ void ALCcontext::eax_initialize() eax_ensure_compatibility(); eax_initialize_filter_gain(); - eax_initialize_filter(); eax_set_defaults(); eax_set_air_absorbtion_hf(); eax_initialize_fx_slots(); @@ -775,16 +758,6 @@ void ALCcontext::eax_set_defaults() noexcept eax_d_ = eax_; } -void ALCcontext::eax_initialize_filter() -{ - eax_al_filter_ = eax_create_al_low_pass_filter(*this); - - if (!eax_al_filter_) - { - eax_fail("Failed to make a low-pass filter."); - } -} - void ALCcontext::eax_dispatch_fx_slot( const EaxEaxCall& eax_call) { @@ -979,7 +952,7 @@ void ALCcontext::eax_initialize_sources() for (auto& source : SourceListEnumerator{mSourceList}) { - eax_initialize_source(source); + source.eax_initialize(this); } } diff --git a/alc/context.h b/alc/context.h index b964d813..331b21b0 100644 --- a/alc/context.h +++ b/alc/context.h @@ -20,8 +20,6 @@ #include "vector.h" #ifdef ALSOFT_EAX -#include "al/filter.h" - #include "al/eax_eax_call.h" #include "al/eax_fx_slot_index.h" #include "al/eax_fx_slots.h" @@ -213,9 +211,6 @@ public: void eax_uninitialize() noexcept; - void eax_initialize_source( - ALsource& al_source) noexcept; - ALenum eax_eax_set( const GUID* property_set_id, @@ -336,7 +331,6 @@ private: EaxContextSharedDirtyFlags eax_context_shared_dirty_flags_{}; - EaxAlFilterUPtr eax_al_filter_{}; Eax eax_{}; Eax eax_d_{}; EAXSESSIONPROPERTIES eax_session_{}; @@ -383,8 +377,6 @@ private: void eax_set_defaults() noexcept; - void eax_initialize_filter(); - void eax_initialize_sources(); |