update openal-soft to 1.24.3

keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
This commit is contained in:
AzaezelX 2025-09-03 11:09:27 -05:00
parent 12db0500e8
commit ba32094b7b
276 changed files with 49304 additions and 8712 deletions

View file

@ -6,12 +6,12 @@
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstring>
#include <functional>
#include <limits>
#include <iterator>
#include <numeric>
#include <stdexcept>
#include <optional>
#include <string_view>
#include <tuple>
#include <utility>
#include "AL/efx.h"
@ -25,19 +25,22 @@
#include "albit.h"
#include "alc/alu.h"
#include "alc/backends/base.h"
#include "alnumeric.h"
#include "alspan.h"
#include "atomic.h"
#include "core/async_event.h"
#include "core/devformat.h"
#include "core/device.h"
#include "core/effectslot.h"
#include "core/logging.h"
#include "core/voice.h"
#include "core/voice_change.h"
#include "device.h"
#include "flexarray.h"
#include "ringbuffer.h"
#include "vecmat.h"
#ifdef ALSOFT_EAX
#if ALSOFT_EAX
#include "al/eax/call.h"
#include "al/eax/globals.h"
#endif // ALSOFT_EAX
@ -70,7 +73,7 @@ std::vector<std::string_view> getContextExtensions() noexcept
"AL_EXT_STEREO_ANGLES"sv,
"AL_LOKI_quadriphonic"sv,
"AL_SOFT_bformat_ex"sv,
"AL_SOFTX_bformat_hoa"sv,
"AL_SOFT_bformat_hoa"sv,
"AL_SOFT_block_alignment"sv,
"AL_SOFT_buffer_length_query"sv,
"AL_SOFT_callback_buffer"sv,
@ -107,7 +110,7 @@ ALCcontext::ThreadCtx::~ThreadCtx()
if(ALCcontext *ctx{std::exchange(ALCcontext::sLocalContext, nullptr)})
{
const bool result{ctx->releaseIfNoDelete()};
ERR("Context %p current for thread being destroyed%s!\n", voidp{ctx},
ERR("Context {} current for thread being destroyed{}!", voidp{ctx},
result ? "" : ", leak detected");
}
}
@ -116,26 +119,30 @@ thread_local ALCcontext::ThreadCtx ALCcontext::sThreadContext;
ALeffect ALCcontext::sDefaultEffect;
ALCcontext::ALCcontext(al::intrusive_ptr<ALCdevice> device, ContextFlagBitset flags)
ALCcontext::ALCcontext(al::intrusive_ptr<al::Device> device, ContextFlagBitset flags)
: ContextBase{device.get()}, mALDevice{std::move(device)}, mContextFlags{flags}
{
mDebugGroups.emplace_back(DebugSource::Other, 0, std::string{});
mDebugEnabled.store(mContextFlags.test(ContextFlags::DebugBit), std::memory_order_relaxed);
/* Low-severity debug messages are disabled by default. */
alDebugMessageControlDirectEXT(this, AL_DONT_CARE_EXT, AL_DONT_CARE_EXT,
AL_DEBUG_SEVERITY_LOW_EXT, 0, nullptr, AL_FALSE);
}
ALCcontext::~ALCcontext()
{
TRACE("Freeing context %p\n", voidp{this});
TRACE("Freeing context {}", voidp{this});
size_t count{std::accumulate(mSourceList.cbegin(), mSourceList.cend(), 0_uz,
[](size_t cur, const SourceSubList &sublist) noexcept -> size_t
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); })};
if(count > 0)
WARN("%zu Source%s not deleted\n", count, (count==1)?"":"s");
WARN("{} Source{} not deleted", count, (count==1)?"":"s");
mSourceList.clear();
mNumSources = 0;
#ifdef ALSOFT_EAX
#if ALSOFT_EAX
eaxUninitialize();
#endif // ALSOFT_EAX
@ -144,7 +151,7 @@ ALCcontext::~ALCcontext()
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
if(count > 0)
WARN("%zu AuxiliaryEffectSlot%s not deleted\n", count, (count==1)?"":"s");
WARN("{} AuxiliaryEffectSlot{} not deleted", count, (count==1)?"":"s");
mEffectSlotList.clear();
mNumEffectSlots = 0;
}
@ -183,13 +190,15 @@ void ALCcontext::init()
{
auto iter = std::find(mExtensions.begin(), mExtensions.end(), "AL_EXT_SOURCE_RADIUS"sv);
if(iter != mExtensions.end()) mExtensions.erase(iter);
/* TODO: Would be nice to sort this alphabetically. Needs case-
* insensitive searching.
/* Insert the AL_SOFT_buffer_sub_data extension string between
* AL_SOFT_buffer_length_query and AL_SOFT_callback_buffer.
*/
mExtensions.emplace_back("AL_SOFT_buffer_sub_data"sv);
iter = std::find(mExtensions.begin(), mExtensions.end(), "AL_SOFT_callback_buffer"sv);
mExtensions.emplace(iter, "AL_SOFT_buffer_sub_data"sv);
}
#ifdef ALSOFT_EAX
#if ALSOFT_EAX
eax_initialize_extensions();
#endif // ALSOFT_EAX
@ -212,14 +221,26 @@ void ALCcontext::init()
mExtensionsString = std::move(extensions);
}
#if ALSOFT_EAX
eax_set_defaults();
#endif
mParams.Position = alu::Vector{0.0f, 0.0f, 0.0f, 1.0f};
mParams.Matrix = alu::Matrix::Identity();
mParams.Velocity = alu::Vector{};
mParams.Gain = mListener.Gain;
mParams.MetersPerUnit = mListener.mMetersPerUnit;
mParams.MetersPerUnit = mListener.mMetersPerUnit
#if ALSOFT_EAX
* eaxGetDistanceFactor()
#endif
;
mParams.AirAbsorptionGainHF = mAirAbsorptionGainHF;
mParams.DopplerFactor = mDopplerFactor;
mParams.SpeedOfSound = mSpeedOfSound * mDopplerVelocity;
mParams.SpeedOfSound = mSpeedOfSound * mDopplerVelocity
#if ALSOFT_EAX
/ eaxGetDistanceFactor()
#endif
;
mParams.SourceDistanceModel = mSourceDistanceModel;
mParams.mDistanceModel = mDistanceModel;
@ -236,35 +257,34 @@ void ALCcontext::deinit()
{
if(sLocalContext == this)
{
WARN("%p released while current on thread\n", voidp{this});
WARN("{} released while current on thread", voidp{this});
auto _ = ContextRef{sLocalContext};
sThreadContext.set(nullptr);
dec_ref();
}
ALCcontext *origctx{this};
if(sGlobalContext.compare_exchange_strong(origctx, nullptr))
if(ALCcontext *origctx{this}; sGlobalContext.compare_exchange_strong(origctx, nullptr))
{
auto _ = ContextRef{origctx};
while(sGlobalContextLock.load()) {
/* Wait to make sure another thread didn't get the context and is
* trying to increment its refcount.
*/
}
dec_ref();
}
bool stopPlayback{};
/* First make sure this context exists in the device's list. */
auto *oldarray = mDevice->mContexts.load(std::memory_order_acquire);
if(auto toremove = static_cast<size_t>(std::count(oldarray->begin(), oldarray->end(), this)))
auto oldarray = al::span{*mDevice->mContexts.load(std::memory_order_acquire)};
if(auto toremove = static_cast<size_t>(std::count(oldarray.begin(), oldarray.end(), this)))
{
using ContextArray = al::FlexArray<ContextBase*>;
const size_t newsize{oldarray->size() - toremove};
const auto newsize = size_t{oldarray.size() - toremove};
auto newarray = ContextArray::Create(newsize);
/* Copy the current/old context handles to the new array, excluding the
* given context.
*/
std::copy_if(oldarray->begin(), oldarray->end(), newarray->begin(),
std::copy_if(oldarray.begin(), oldarray.end(), newarray->begin(),
[this](ContextBase *ctx) { return ctx != this; });
/* Store the new context array in the device. Wait for any current mix
@ -276,7 +296,7 @@ void ALCcontext::deinit()
stopPlayback = (newsize == 0);
}
else
stopPlayback = oldarray->empty();
stopPlayback = oldarray.empty();
StopEventThrd(this);
@ -297,7 +317,7 @@ void ALCcontext::applyAllUpdates()
/* busy-wait */
}
#ifdef ALSOFT_EAX
#if ALSOFT_EAX
if(mEaxNeedsCommit)
eaxCommit();
#endif
@ -314,7 +334,7 @@ void ALCcontext::applyAllUpdates()
}
#ifdef ALSOFT_EAX
#if ALSOFT_EAX
namespace {
template<typename F>
@ -492,7 +512,7 @@ void ALCcontext::eax_initialize()
eax_ensure_compatibility();
eax_set_defaults();
eax_context_commit_air_absorbtion_hf();
eax_context_commit_air_absorption_hf();
eax_update_speaker_configuration();
eax_initialize_fx_slots();
@ -561,7 +581,8 @@ unsigned long ALCcontext::eax_detect_speaker_configuration() const
*/
case DevFmtAmbi3D: return SPEAKERS_7;
}
ERR(EAX_PREFIX "Unexpected device channel format 0x%x.\n", mDevice->FmtChans);
ERR(EAX_PREFIX "Unexpected device channel format {:#x}.",
uint{al::to_underlying(mDevice->FmtChans)});
return HEADPHONES;
#undef EAX_PREFIX
@ -619,7 +640,7 @@ void ALCcontext::eax_context_set_defaults()
eax5_context_set_defaults(mEax5);
mEax = mEax5.i;
mEaxVersion = 5;
mEaxDf = EaxDirtyFlags{};
mEaxDf.reset();
}
void ALCcontext::eax_set_defaults()
@ -746,14 +767,11 @@ void ALCcontext::eax_context_commit_primary_fx_slot_id()
void ALCcontext::eax_context_commit_distance_factor()
{
if(mListener.mMetersPerUnit == mEax.flDistanceFactor)
return;
mListener.mMetersPerUnit = mEax.flDistanceFactor;
/* mEax.flDistanceFactor was changed, so the context props are dirty. */
mPropsDirty = true;
}
void ALCcontext::eax_context_commit_air_absorbtion_hf()
void ALCcontext::eax_context_commit_air_absorption_hf()
{
const auto new_value = level_mb_to_gain(mEax.flAirAbsorptionHF);
@ -814,16 +832,16 @@ void ALCcontext::eax4_defer_all(const EaxCall& call, Eax4State& state)
dst_d = src;
if(dst_i.guidPrimaryFXSlotID != dst_d.guidPrimaryFXSlotID)
mEaxDf |= eax_primary_fx_slot_id_dirty_bit;
mEaxDf.set(eax_primary_fx_slot_id_dirty_bit);
if(dst_i.flDistanceFactor != dst_d.flDistanceFactor)
mEaxDf |= eax_distance_factor_dirty_bit;
mEaxDf.set(eax_distance_factor_dirty_bit);
if(dst_i.flAirAbsorptionHF != dst_d.flAirAbsorptionHF)
mEaxDf |= eax_air_absorption_hf_dirty_bit;
mEaxDf.set(eax_air_absorption_hf_dirty_bit);
if(dst_i.flHFReference != dst_d.flHFReference)
mEaxDf |= eax_hf_reference_dirty_bit;
mEaxDf.set(eax_hf_reference_dirty_bit);
}
void ALCcontext::eax4_defer(const EaxCall& call, Eax4State& state)
@ -834,20 +852,20 @@ void ALCcontext::eax4_defer(const EaxCall& call, Eax4State& state)
eax4_defer_all(call, state);
break;
case EAXCONTEXT_PRIMARYFXSLOTID:
eax_defer<Eax4PrimaryFxSlotIdValidator, eax_primary_fx_slot_id_dirty_bit>(
call, state, &EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_defer<Eax4PrimaryFxSlotIdValidator, eax_primary_fx_slot_id_dirty_bit>(call, state,
&EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID);
break;
case EAXCONTEXT_DISTANCEFACTOR:
eax_defer<Eax4DistanceFactorValidator, eax_distance_factor_dirty_bit>(
call, state, &EAX40CONTEXTPROPERTIES::flDistanceFactor);
eax_defer<Eax4DistanceFactorValidator, eax_distance_factor_dirty_bit>(call, state,
&EAX40CONTEXTPROPERTIES::flDistanceFactor);
break;
case EAXCONTEXT_AIRABSORPTIONHF:
eax_defer<Eax4AirAbsorptionHfValidator, eax_air_absorption_hf_dirty_bit>(
call, state, &EAX40CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_defer<Eax4AirAbsorptionHfValidator, eax_air_absorption_hf_dirty_bit>(call, state,
&EAX40CONTEXTPROPERTIES::flAirAbsorptionHF);
break;
case EAXCONTEXT_HFREFERENCE:
eax_defer<Eax4HfReferenceValidator, eax_hf_reference_dirty_bit>(
call, state, &EAX40CONTEXTPROPERTIES::flHFReference);
eax_defer<Eax4HfReferenceValidator, eax_hf_reference_dirty_bit>(call, state,
&EAX40CONTEXTPROPERTIES::flHFReference);
break;
default:
eax_set_misc(call);
@ -864,19 +882,19 @@ void ALCcontext::eax5_defer_all(const EaxCall& call, Eax5State& state)
dst_d = src;
if(dst_i.guidPrimaryFXSlotID != dst_d.guidPrimaryFXSlotID)
mEaxDf |= eax_primary_fx_slot_id_dirty_bit;
mEaxDf.set(eax_primary_fx_slot_id_dirty_bit);
if(dst_i.flDistanceFactor != dst_d.flDistanceFactor)
mEaxDf |= eax_distance_factor_dirty_bit;
mEaxDf.set(eax_distance_factor_dirty_bit);
if(dst_i.flAirAbsorptionHF != dst_d.flAirAbsorptionHF)
mEaxDf |= eax_air_absorption_hf_dirty_bit;
mEaxDf.set(eax_air_absorption_hf_dirty_bit);
if(dst_i.flHFReference != dst_d.flHFReference)
mEaxDf |= eax_hf_reference_dirty_bit;
mEaxDf.set(eax_hf_reference_dirty_bit);
if(dst_i.flMacroFXFactor != dst_d.flMacroFXFactor)
mEaxDf |= eax_macro_fx_factor_dirty_bit;
mEaxDf.set(eax_macro_fx_factor_dirty_bit);
}
void ALCcontext::eax5_defer(const EaxCall& call, Eax5State& state)
@ -887,24 +905,24 @@ void ALCcontext::eax5_defer(const EaxCall& call, Eax5State& state)
eax5_defer_all(call, state);
break;
case EAXCONTEXT_PRIMARYFXSLOTID:
eax_defer<Eax5PrimaryFxSlotIdValidator, eax_primary_fx_slot_id_dirty_bit>(
call, state, &EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_defer<Eax5PrimaryFxSlotIdValidator, eax_primary_fx_slot_id_dirty_bit>(call, state,
&EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID);
break;
case EAXCONTEXT_DISTANCEFACTOR:
eax_defer<Eax4DistanceFactorValidator, eax_distance_factor_dirty_bit>(
call, state, &EAX50CONTEXTPROPERTIES::flDistanceFactor);
eax_defer<Eax4DistanceFactorValidator, eax_distance_factor_dirty_bit>(call, state,
&EAX50CONTEXTPROPERTIES::flDistanceFactor);
break;
case EAXCONTEXT_AIRABSORPTIONHF:
eax_defer<Eax4AirAbsorptionHfValidator, eax_air_absorption_hf_dirty_bit>(
call, state, &EAX50CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_defer<Eax4AirAbsorptionHfValidator, eax_air_absorption_hf_dirty_bit>(call, state,
&EAX50CONTEXTPROPERTIES::flAirAbsorptionHF);
break;
case EAXCONTEXT_HFREFERENCE:
eax_defer<Eax4HfReferenceValidator, eax_hf_reference_dirty_bit>(
call, state, &EAX50CONTEXTPROPERTIES::flHFReference);
eax_defer<Eax4HfReferenceValidator, eax_hf_reference_dirty_bit>(call, state,
&EAX50CONTEXTPROPERTIES::flHFReference);
break;
case EAXCONTEXT_MACROFXFACTOR:
eax_defer<Eax5MacroFxFactorValidator, eax_macro_fx_factor_dirty_bit>(
call, state, &EAX50CONTEXTPROPERTIES::flMacroFXFactor);
eax_defer<Eax5MacroFxFactorValidator, eax_macro_fx_factor_dirty_bit>(call, state,
&EAX50CONTEXTPROPERTIES::flMacroFXFactor);
break;
default:
eax_set_misc(call);
@ -922,49 +940,49 @@ void ALCcontext::eax_set(const EaxCall& call)
default: eax_fail_unknown_version();
}
if(version != mEaxVersion)
mEaxDf = ~EaxDirtyFlags();
mEaxDf.set();
mEaxVersion = version;
}
void ALCcontext::eax4_context_commit(Eax4State& state, EaxDirtyFlags& dst_df)
void ALCcontext::eax4_context_commit(Eax4State& state, std::bitset<eax_dirty_bit_count>& dst_df)
{
if(mEaxDf == EaxDirtyFlags{})
if(mEaxDf.none())
return;
eax_context_commit_property<eax_primary_fx_slot_id_dirty_bit>(
state, dst_df, &EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_context_commit_property<eax_distance_factor_dirty_bit>(
state, dst_df, &EAX40CONTEXTPROPERTIES::flDistanceFactor);
eax_context_commit_property<eax_air_absorption_hf_dirty_bit>(
state, dst_df, &EAX40CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_context_commit_property<eax_hf_reference_dirty_bit>(
state, dst_df, &EAX40CONTEXTPROPERTIES::flHFReference);
eax_context_commit_property<eax_primary_fx_slot_id_dirty_bit>(state, dst_df,
&EAX40CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_context_commit_property<eax_distance_factor_dirty_bit>(state, dst_df,
&EAX40CONTEXTPROPERTIES::flDistanceFactor);
eax_context_commit_property<eax_air_absorption_hf_dirty_bit>(state, dst_df,
&EAX40CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_context_commit_property<eax_hf_reference_dirty_bit>(state, dst_df,
&EAX40CONTEXTPROPERTIES::flHFReference);
mEaxDf = EaxDirtyFlags{};
mEaxDf.reset();
}
void ALCcontext::eax5_context_commit(Eax5State& state, EaxDirtyFlags& dst_df)
void ALCcontext::eax5_context_commit(Eax5State& state, std::bitset<eax_dirty_bit_count>& dst_df)
{
if(mEaxDf == EaxDirtyFlags{})
if(mEaxDf.none())
return;
eax_context_commit_property<eax_primary_fx_slot_id_dirty_bit>(
state, dst_df, &EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_context_commit_property<eax_distance_factor_dirty_bit>(
state, dst_df, &EAX50CONTEXTPROPERTIES::flDistanceFactor);
eax_context_commit_property<eax_air_absorption_hf_dirty_bit>(
state, dst_df, &EAX50CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_context_commit_property<eax_hf_reference_dirty_bit>(
state, dst_df, &EAX50CONTEXTPROPERTIES::flHFReference);
eax_context_commit_property<eax_macro_fx_factor_dirty_bit>(
state, dst_df, &EAX50CONTEXTPROPERTIES::flMacroFXFactor);
eax_context_commit_property<eax_primary_fx_slot_id_dirty_bit>(state, dst_df,
&EAX50CONTEXTPROPERTIES::guidPrimaryFXSlotID);
eax_context_commit_property<eax_distance_factor_dirty_bit>(state, dst_df,
&EAX50CONTEXTPROPERTIES::flDistanceFactor);
eax_context_commit_property<eax_air_absorption_hf_dirty_bit>(state, dst_df,
&EAX50CONTEXTPROPERTIES::flAirAbsorptionHF);
eax_context_commit_property<eax_hf_reference_dirty_bit>(state, dst_df,
&EAX50CONTEXTPROPERTIES::flHFReference);
eax_context_commit_property<eax_macro_fx_factor_dirty_bit>(state, dst_df,
&EAX50CONTEXTPROPERTIES::flMacroFXFactor);
mEaxDf = EaxDirtyFlags{};
mEaxDf.reset();
}
void ALCcontext::eax_context_commit()
{
auto dst_df = EaxDirtyFlags{};
auto dst_df = std::bitset<eax_dirty_bit_count>{};
switch(mEaxVersion)
{
@ -981,25 +999,25 @@ void ALCcontext::eax_context_commit()
break;
}
if(dst_df == EaxDirtyFlags{})
if(dst_df.none())
return;
if((dst_df & eax_primary_fx_slot_id_dirty_bit) != EaxDirtyFlags{})
if(dst_df.test(eax_primary_fx_slot_id_dirty_bit))
eax_context_commit_primary_fx_slot_id();
if((dst_df & eax_distance_factor_dirty_bit) != EaxDirtyFlags{})
if(dst_df.test(eax_distance_factor_dirty_bit))
eax_context_commit_distance_factor();
if((dst_df & eax_air_absorption_hf_dirty_bit) != EaxDirtyFlags{})
eax_context_commit_air_absorbtion_hf();
if(dst_df.test(eax_air_absorption_hf_dirty_bit))
eax_context_commit_air_absorption_hf();
if((dst_df & eax_hf_reference_dirty_bit) != EaxDirtyFlags{})
if(dst_df.test(eax_hf_reference_dirty_bit))
eax_context_commit_hf_reference();
if((dst_df & eax_macro_fx_factor_dirty_bit) != EaxDirtyFlags{})
if(dst_df.test(eax_macro_fx_factor_dirty_bit))
eax_context_commit_macro_fx_factor();
if((dst_df & eax_primary_fx_slot_id_dirty_bit) != EaxDirtyFlags{})
if(dst_df.test(eax_primary_fx_slot_id_dirty_bit))
eax_update_sources();
}