aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/filter.cpp81
-rw-r--r--al/filter.h39
-rw-r--r--al/source.cpp193
-rw-r--r--al/source.h49
-rw-r--r--alc/context.cpp29
-rw-r--r--alc/context.h8
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();