mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 07:04:36 +00:00
update openal
This commit is contained in:
parent
62f3b93ff9
commit
6721a6b021
287 changed files with 33851 additions and 27325 deletions
|
|
@ -4,21 +4,28 @@
|
|||
#include "context.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <stddef.h>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "al/auxeffectslot.h"
|
||||
#include "al/debug.h"
|
||||
#include "al/source.h"
|
||||
#include "al/effect.h"
|
||||
#include "al/event.h"
|
||||
#include "al/listener.h"
|
||||
#include "albit.h"
|
||||
#include "alc/alu.h"
|
||||
#include "alc/backends/base.h"
|
||||
#include "alspan.h"
|
||||
#include "core/async_event.h"
|
||||
#include "core/device.h"
|
||||
#include "core/effectslot.h"
|
||||
|
|
@ -26,63 +33,68 @@
|
|||
#include "core/voice.h"
|
||||
#include "core/voice_change.h"
|
||||
#include "device.h"
|
||||
#include "flexarray.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "vecmat.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include <cstring>
|
||||
#include "alstring.h"
|
||||
#include "al/eax/globals.h"
|
||||
#endif // ALSOFT_EAX
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
using voidp = void*;
|
||||
|
||||
/* Default context extensions */
|
||||
constexpr ALchar alExtList[] =
|
||||
"AL_EXT_ALAW "
|
||||
"AL_EXT_BFORMAT "
|
||||
"AL_EXT_DOUBLE "
|
||||
"AL_EXT_EXPONENT_DISTANCE "
|
||||
"AL_EXT_FLOAT32 "
|
||||
"AL_EXT_IMA4 "
|
||||
"AL_EXT_LINEAR_DISTANCE "
|
||||
"AL_EXT_MCFORMATS "
|
||||
"AL_EXT_MULAW "
|
||||
"AL_EXT_MULAW_BFORMAT "
|
||||
"AL_EXT_MULAW_MCFORMATS "
|
||||
"AL_EXT_OFFSET "
|
||||
"AL_EXT_source_distance_model "
|
||||
"AL_EXT_SOURCE_RADIUS "
|
||||
"AL_EXT_STATIC_BUFFER "
|
||||
"AL_EXT_STEREO_ANGLES "
|
||||
"AL_LOKI_quadriphonic "
|
||||
"AL_SOFT_bformat_ex "
|
||||
"AL_SOFTX_bformat_hoa "
|
||||
"AL_SOFT_block_alignment "
|
||||
"AL_SOFT_buffer_length_query "
|
||||
"AL_SOFT_callback_buffer "
|
||||
"AL_SOFTX_convolution_reverb "
|
||||
"AL_SOFT_deferred_updates "
|
||||
"AL_SOFT_direct_channels "
|
||||
"AL_SOFT_direct_channels_remix "
|
||||
"AL_SOFT_effect_target "
|
||||
"AL_SOFT_events "
|
||||
"AL_SOFT_gain_clamp_ex "
|
||||
"AL_SOFTX_hold_on_disconnect "
|
||||
"AL_SOFT_loop_points "
|
||||
"AL_SOFTX_map_buffer "
|
||||
"AL_SOFT_MSADPCM "
|
||||
"AL_SOFT_source_latency "
|
||||
"AL_SOFT_source_length "
|
||||
"AL_SOFT_source_resampler "
|
||||
"AL_SOFT_source_spatialize "
|
||||
"AL_SOFT_source_start_delay "
|
||||
"AL_SOFT_UHJ "
|
||||
"AL_SOFT_UHJ_ex";
|
||||
std::vector<std::string_view> getContextExtensions() noexcept
|
||||
{
|
||||
return std::vector<std::string_view>{
|
||||
"AL_EXT_ALAW"sv,
|
||||
"AL_EXT_BFORMAT"sv,
|
||||
"AL_EXT_debug"sv,
|
||||
"AL_EXT_direct_context"sv,
|
||||
"AL_EXT_DOUBLE"sv,
|
||||
"AL_EXT_EXPONENT_DISTANCE"sv,
|
||||
"AL_EXT_FLOAT32"sv,
|
||||
"AL_EXT_IMA4"sv,
|
||||
"AL_EXT_LINEAR_DISTANCE"sv,
|
||||
"AL_EXT_MCFORMATS"sv,
|
||||
"AL_EXT_MULAW"sv,
|
||||
"AL_EXT_MULAW_BFORMAT"sv,
|
||||
"AL_EXT_MULAW_MCFORMATS"sv,
|
||||
"AL_EXT_OFFSET"sv,
|
||||
"AL_EXT_source_distance_model"sv,
|
||||
"AL_EXT_SOURCE_RADIUS"sv,
|
||||
"AL_EXT_STATIC_BUFFER"sv,
|
||||
"AL_EXT_STEREO_ANGLES"sv,
|
||||
"AL_LOKI_quadriphonic"sv,
|
||||
"AL_SOFT_bformat_ex"sv,
|
||||
"AL_SOFTX_bformat_hoa"sv,
|
||||
"AL_SOFT_block_alignment"sv,
|
||||
"AL_SOFT_buffer_length_query"sv,
|
||||
"AL_SOFT_callback_buffer"sv,
|
||||
"AL_SOFTX_convolution_effect"sv,
|
||||
"AL_SOFT_deferred_updates"sv,
|
||||
"AL_SOFT_direct_channels"sv,
|
||||
"AL_SOFT_direct_channels_remix"sv,
|
||||
"AL_SOFT_effect_target"sv,
|
||||
"AL_SOFT_events"sv,
|
||||
"AL_SOFT_gain_clamp_ex"sv,
|
||||
"AL_SOFTX_hold_on_disconnect"sv,
|
||||
"AL_SOFT_loop_points"sv,
|
||||
"AL_SOFTX_map_buffer"sv,
|
||||
"AL_SOFT_MSADPCM"sv,
|
||||
"AL_SOFT_source_latency"sv,
|
||||
"AL_SOFT_source_length"sv,
|
||||
"AL_SOFTX_source_panning"sv,
|
||||
"AL_SOFT_source_resampler"sv,
|
||||
"AL_SOFT_source_spatialize"sv,
|
||||
"AL_SOFT_source_start_delay"sv,
|
||||
"AL_SOFT_UHJ"sv,
|
||||
"AL_SOFT_UHJ_ex"sv,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
@ -90,10 +102,9 @@ constexpr ALchar alExtList[] =
|
|||
std::atomic<bool> ALCcontext::sGlobalContextLock{false};
|
||||
std::atomic<ALCcontext*> ALCcontext::sGlobalContext{nullptr};
|
||||
|
||||
thread_local ALCcontext *ALCcontext::sLocalContext{nullptr};
|
||||
ALCcontext::ThreadCtx::~ThreadCtx()
|
||||
{
|
||||
if(ALCcontext *ctx{ALCcontext::sLocalContext})
|
||||
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},
|
||||
|
|
@ -105,23 +116,18 @@ thread_local ALCcontext::ThreadCtx ALCcontext::sThreadContext;
|
|||
ALeffect ALCcontext::sDefaultEffect;
|
||||
|
||||
|
||||
#ifdef __MINGW32__
|
||||
ALCcontext *ALCcontext::getThreadContext() noexcept
|
||||
{ return sLocalContext; }
|
||||
void ALCcontext::setThreadContext(ALCcontext *context) noexcept
|
||||
{ sThreadContext.set(context); }
|
||||
#endif
|
||||
|
||||
ALCcontext::ALCcontext(al::intrusive_ptr<ALCdevice> device)
|
||||
: ContextBase{device.get()}, mALDevice{std::move(device)}
|
||||
ALCcontext::ALCcontext(al::intrusive_ptr<ALCdevice> 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);
|
||||
}
|
||||
|
||||
ALCcontext::~ALCcontext()
|
||||
{
|
||||
TRACE("Freeing context %p\n", voidp{this});
|
||||
|
||||
size_t count{std::accumulate(mSourceList.cbegin(), mSourceList.cend(), size_t{0u},
|
||||
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)
|
||||
|
|
@ -134,7 +140,7 @@ ALCcontext::~ALCcontext()
|
|||
#endif // ALSOFT_EAX
|
||||
|
||||
mDefaultSlot = nullptr;
|
||||
count = std::accumulate(mEffectSlotList.cbegin(), mEffectSlotList.cend(), size_t{0u},
|
||||
count = std::accumulate(mEffectSlotList.cbegin(), mEffectSlotList.cend(), 0_uz,
|
||||
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
|
||||
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
|
||||
if(count > 0)
|
||||
|
|
@ -151,16 +157,17 @@ void ALCcontext::init()
|
|||
aluInitEffectPanning(mDefaultSlot->mSlot, this);
|
||||
}
|
||||
|
||||
EffectSlotArray *auxslots;
|
||||
std::unique_ptr<EffectSlotArray> auxslots;
|
||||
if(!mDefaultSlot)
|
||||
auxslots = EffectSlot::CreatePtrArray(0);
|
||||
else
|
||||
{
|
||||
auxslots = EffectSlot::CreatePtrArray(1);
|
||||
auxslots = EffectSlot::CreatePtrArray(2);
|
||||
(*auxslots)[0] = mDefaultSlot->mSlot;
|
||||
(*auxslots)[1] = mDefaultSlot->mSlot;
|
||||
mDefaultSlot->mState = SlotState::Playing;
|
||||
}
|
||||
mActiveAuxSlots.store(auxslots, std::memory_order_relaxed);
|
||||
mActiveAuxSlots.store(std::move(auxslots), std::memory_order_relaxed);
|
||||
|
||||
allocVoiceChanges();
|
||||
{
|
||||
|
|
@ -170,26 +177,41 @@ void ALCcontext::init()
|
|||
mCurrentVoiceChange.store(cur, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
mExtensionList = alExtList;
|
||||
mExtensions = getContextExtensions();
|
||||
|
||||
if(sBufferSubDataCompat)
|
||||
{
|
||||
std::string extlist{mExtensionList};
|
||||
|
||||
const auto pos = extlist.find("AL_EXT_SOURCE_RADIUS ");
|
||||
if(pos != std::string::npos)
|
||||
extlist.replace(pos, 20, "AL_SOFT_buffer_sub_data");
|
||||
else
|
||||
extlist += " AL_SOFT_buffer_sub_data";
|
||||
|
||||
mExtensionListOverride = std::move(extlist);
|
||||
mExtensionList = mExtensionListOverride.c_str();
|
||||
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.
|
||||
*/
|
||||
mExtensions.emplace_back("AL_SOFT_buffer_sub_data"sv);
|
||||
}
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
eax_initialize_extensions();
|
||||
#endif // ALSOFT_EAX
|
||||
|
||||
if(!mExtensions.empty())
|
||||
{
|
||||
const size_t len{std::accumulate(mExtensions.cbegin()+1, mExtensions.cend(),
|
||||
mExtensions.front().length(),
|
||||
[](size_t current, std::string_view ext) noexcept
|
||||
{ return current + ext.length() + 1; })};
|
||||
|
||||
std::string extensions;
|
||||
extensions.reserve(len);
|
||||
extensions += mExtensions.front();
|
||||
for(std::string_view ext : al::span{mExtensions}.subspan<1>())
|
||||
{
|
||||
extensions += ' ';
|
||||
extensions += ext;
|
||||
}
|
||||
|
||||
mExtensionsString = std::move(extensions);
|
||||
}
|
||||
|
||||
mParams.Position = alu::Vector{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
mParams.Matrix = alu::Matrix::Identity();
|
||||
mParams.Velocity = alu::Vector{};
|
||||
|
|
@ -202,7 +224,7 @@ void ALCcontext::init()
|
|||
mParams.mDistanceModel = mDistanceModel;
|
||||
|
||||
|
||||
mAsyncEvents = RingBuffer::Create(511, sizeof(AsyncEvent), false);
|
||||
mAsyncEvents = RingBuffer::Create(1024, sizeof(AsyncEvent), false);
|
||||
StartEventThrd(this);
|
||||
|
||||
|
||||
|
|
@ -210,7 +232,7 @@ void ALCcontext::init()
|
|||
mActiveVoiceCount.store(64, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
bool ALCcontext::deinit()
|
||||
void ALCcontext::deinit()
|
||||
{
|
||||
if(sLocalContext == this)
|
||||
{
|
||||
|
|
@ -230,18 +252,14 @@ bool ALCcontext::deinit()
|
|||
dec_ref();
|
||||
}
|
||||
|
||||
bool ret{};
|
||||
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)))
|
||||
{
|
||||
using ContextArray = al::FlexArray<ContextBase*>;
|
||||
auto alloc_ctx_array = [](const size_t count) -> ContextArray*
|
||||
{
|
||||
if(count == 0) return &DeviceBase::sEmptyContextArray;
|
||||
return ContextArray::Create(count).release();
|
||||
};
|
||||
auto *newarray = alloc_ctx_array(oldarray->size() - toremove);
|
||||
const size_t newsize{oldarray->size() - toremove};
|
||||
auto newarray = ContextArray::Create(newsize);
|
||||
|
||||
/* Copy the current/old context handles to the new array, excluding the
|
||||
* given context.
|
||||
|
|
@ -252,21 +270,21 @@ bool ALCcontext::deinit()
|
|||
/* Store the new context array in the device. Wait for any current mix
|
||||
* to finish before deleting the old array.
|
||||
*/
|
||||
mDevice->mContexts.store(newarray);
|
||||
if(oldarray != &DeviceBase::sEmptyContextArray)
|
||||
{
|
||||
mDevice->waitForMix();
|
||||
delete oldarray;
|
||||
}
|
||||
auto prevarray = mDevice->mContexts.exchange(std::move(newarray));
|
||||
std::ignore = mDevice->waitForMix();
|
||||
|
||||
ret = !newarray->empty();
|
||||
stopPlayback = (newsize == 0);
|
||||
}
|
||||
else
|
||||
ret = !oldarray->empty();
|
||||
stopPlayback = oldarray->empty();
|
||||
|
||||
StopEventThrd(this);
|
||||
|
||||
return ret;
|
||||
if(stopPlayback && mALDevice->mDeviceState == DeviceState::Playing)
|
||||
{
|
||||
mALDevice->Backend->stop();
|
||||
mALDevice->mDeviceState = DeviceState::Configured;
|
||||
}
|
||||
}
|
||||
|
||||
void ALCcontext::applyAllUpdates()
|
||||
|
|
@ -295,6 +313,7 @@ void ALCcontext::applyAllUpdates()
|
|||
mHoldUpdates.store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
|
|
@ -306,10 +325,10 @@ void ForEachSource(ALCcontext *context, F func)
|
|||
uint64_t usemask{~sublist.FreeMask};
|
||||
while(usemask)
|
||||
{
|
||||
const int idx{al::countr_zero(usemask)};
|
||||
const auto idx = static_cast<uint>(al::countr_zero(usemask));
|
||||
usemask &= ~(1_u64 << idx);
|
||||
|
||||
func(sublist.Sources[idx]);
|
||||
func((*sublist.Sources)[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -447,43 +466,15 @@ void ALCcontext::eax_initialize_extensions()
|
|||
if(!eax_g_is_enabled)
|
||||
return;
|
||||
|
||||
const auto string_max_capacity =
|
||||
std::strlen(mExtensionList) + 1 +
|
||||
std::strlen(eax1_ext_name) + 1 +
|
||||
std::strlen(eax2_ext_name) + 1 +
|
||||
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;
|
||||
|
||||
std::string extlist;
|
||||
extlist.reserve(string_max_capacity);
|
||||
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX-RAM"sv);
|
||||
if(eaxIsCapable())
|
||||
{
|
||||
extlist += eax1_ext_name;
|
||||
extlist += ' ';
|
||||
|
||||
extlist += eax2_ext_name;
|
||||
extlist += ' ';
|
||||
|
||||
extlist += eax3_ext_name;
|
||||
extlist += ' ';
|
||||
|
||||
extlist += eax4_ext_name;
|
||||
extlist += ' ';
|
||||
|
||||
extlist += eax5_ext_name;
|
||||
extlist += ' ';
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX5.0"sv);
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX4.0"sv);
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX3.0"sv);
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX2.0"sv);
|
||||
mExtensions.emplace(mExtensions.begin(), "EAX"sv);
|
||||
}
|
||||
|
||||
extlist += eax_x_ram_ext_name;
|
||||
extlist += ' ';
|
||||
|
||||
extlist += mExtensionList;
|
||||
|
||||
mExtensionListOverride = std::move(extlist);
|
||||
mExtensionList = mExtensionListOverride.c_str();
|
||||
}
|
||||
|
||||
void ALCcontext::eax_initialize()
|
||||
|
|
@ -555,10 +546,11 @@ unsigned long ALCcontext::eax_detect_speaker_configuration() const
|
|||
case DevFmtX51: return SPEAKERS_5;
|
||||
case DevFmtX61: return SPEAKERS_6;
|
||||
case DevFmtX71: return SPEAKERS_7;
|
||||
/* 7.1.4 is compatible with 7.1. This could instead be HEADPHONES to
|
||||
/* 7.1.4(.4) is compatible with 7.1. This could instead be HEADPHONES to
|
||||
* suggest with-height surround sound (like HRTF).
|
||||
*/
|
||||
case DevFmtX714: return SPEAKERS_7;
|
||||
case DevFmtX7144: return SPEAKERS_7;
|
||||
/* 3D7.1 is only compatible with 5.1. This could instead be HEADPHONES to
|
||||
* suggest full-sphere surround sound (like HRTF).
|
||||
*/
|
||||
|
|
@ -582,7 +574,7 @@ void ALCcontext::eax_update_speaker_configuration()
|
|||
|
||||
void ALCcontext::eax_set_last_error_defaults() noexcept
|
||||
{
|
||||
mEaxLastError = EAX_OK;
|
||||
mEaxLastError = EAXCONTEXT_DEFAULTLASTERROR;
|
||||
}
|
||||
|
||||
void ALCcontext::eax_session_set_defaults() noexcept
|
||||
|
|
@ -671,6 +663,7 @@ void ALCcontext::eax_get_misc(const EaxCall& call)
|
|||
break;
|
||||
case EAXCONTEXT_LASTERROR:
|
||||
call.set_value<ContextException>(mEaxLastError);
|
||||
mEaxLastError = EAX_OK;
|
||||
break;
|
||||
case EAXCONTEXT_SPEAKERCONFIG:
|
||||
call.set_value<ContextException>(mEaxSpeakerConfig);
|
||||
|
|
@ -1018,88 +1011,49 @@ void ALCcontext::eaxCommit()
|
|||
eax_update_sources();
|
||||
}
|
||||
|
||||
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 {
|
||||
public:
|
||||
explicit EaxGetException(const char* message)
|
||||
: EaxException{"EAX_GET", message}
|
||||
{}
|
||||
};
|
||||
|
||||
[[noreturn]] void eax_fail_get(const char* message)
|
||||
{
|
||||
throw EaxGetException{message};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
FORCE_ALIGN ALenum AL_APIENTRY EAXSet(
|
||||
const GUID* property_set_id,
|
||||
ALuint property_id,
|
||||
ALuint property_source_id,
|
||||
ALvoid* property_value,
|
||||
ALuint property_value_size) noexcept
|
||||
try
|
||||
FORCE_ALIGN auto AL_APIENTRY EAXSet(const GUID *property_set_id, ALuint property_id,
|
||||
ALuint source_id, ALvoid *value, ALuint value_size) noexcept -> ALenum
|
||||
{
|
||||
auto context = GetContextRef();
|
||||
|
||||
if(!context)
|
||||
eax_fail_set("No current context.");
|
||||
|
||||
std::lock_guard<std::mutex> prop_lock{context->mPropLock};
|
||||
|
||||
return context->eax_eax_set(
|
||||
property_set_id,
|
||||
property_id,
|
||||
property_source_id,
|
||||
property_value,
|
||||
property_value_size);
|
||||
if(!context) UNLIKELY return AL_INVALID_OPERATION;
|
||||
return EAXSetDirect(context.get(), property_set_id, property_id, source_id, value, value_size);
|
||||
}
|
||||
catch (...)
|
||||
|
||||
FORCE_ALIGN auto AL_APIENTRY EAXSetDirect(ALCcontext *context, const GUID *property_set_id,
|
||||
ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) noexcept -> ALenum
|
||||
try
|
||||
{
|
||||
eax_log_exception(__func__);
|
||||
std::lock_guard<std::mutex> prop_lock{context->mPropLock};
|
||||
return context->eax_eax_set(property_set_id, property_id, source_id, value, value_size);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
context->eaxSetLastError();
|
||||
eax_log_exception(std::data(__func__));
|
||||
return AL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
FORCE_ALIGN ALenum AL_APIENTRY EAXGet(
|
||||
const GUID* property_set_id,
|
||||
ALuint property_id,
|
||||
ALuint property_source_id,
|
||||
ALvoid* property_value,
|
||||
ALuint property_value_size) noexcept
|
||||
try
|
||||
|
||||
FORCE_ALIGN auto AL_APIENTRY EAXGet(const GUID *property_set_id, ALuint property_id,
|
||||
ALuint source_id, ALvoid *value, ALuint value_size) noexcept -> ALenum
|
||||
{
|
||||
auto context = GetContextRef();
|
||||
|
||||
if(!context)
|
||||
eax_fail_get("No current context.");
|
||||
|
||||
std::lock_guard<std::mutex> prop_lock{context->mPropLock};
|
||||
|
||||
return context->eax_eax_get(
|
||||
property_set_id,
|
||||
property_id,
|
||||
property_source_id,
|
||||
property_value,
|
||||
property_value_size);
|
||||
if(!context) UNLIKELY return AL_INVALID_OPERATION;
|
||||
return EAXGetDirect(context.get(), property_set_id, property_id, source_id, value, value_size);
|
||||
}
|
||||
catch (...)
|
||||
|
||||
FORCE_ALIGN auto AL_APIENTRY EAXGetDirect(ALCcontext *context, const GUID *property_set_id,
|
||||
ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) noexcept -> ALenum
|
||||
try
|
||||
{
|
||||
eax_log_exception(__func__);
|
||||
std::lock_guard<std::mutex> prop_lock{context->mPropLock};
|
||||
return context->eax_eax_get(property_set_id, property_id, source_id, value, value_size);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
context->eaxSetLastError();
|
||||
eax_log_exception(std::data(__func__));
|
||||
return AL_INVALID_OPERATION;
|
||||
}
|
||||
#endif // ALSOFT_EAX
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue