diff options
author | Sven Gothel <[email protected]> | 2023-11-28 12:51:46 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-11-28 12:51:46 +0100 |
commit | 1aaf4f070011490bcece50394b9b32dfa593fd9e (patch) | |
tree | 17d68284e401a35eea3d3a574d986d446a60763a /al/state.cpp | |
parent | 6e7cee4fa9a8af03f28ca26cd89f8357390dfc90 (diff) | |
parent | 571b546f35eead77ce109f8d4dd6c3de3199d573 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'al/state.cpp')
-rw-r--r-- | al/state.cpp | 866 |
1 files changed, 293 insertions, 573 deletions
diff --git a/al/state.cpp b/al/state.cpp index 86d81b13..5131edd9 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -24,7 +24,9 @@ #include <atomic> #include <cmath> +#include <cstring> #include <mutex> +#include <optional> #include <stdexcept> #include <string> @@ -32,16 +34,18 @@ #include "AL/alc.h" #include "AL/alext.h" +#include "al/debug.h" +#include "albit.h" #include "alc/alu.h" #include "alc/context.h" #include "alc/inprogext.h" #include "alnumeric.h" -#include "aloptional.h" #include "atomic.h" #include "core/context.h" #include "core/except.h" #include "core/mixer/defs.h" #include "core/voice.h" +#include "direct_defs.h" #include "intrusive_ptr.h" #include "opthelpers.h" #include "strutils.h" @@ -67,6 +71,8 @@ constexpr ALchar alErrInvalidEnum[] = "Invalid Enum"; constexpr ALchar alErrInvalidValue[] = "Invalid Value"; constexpr ALchar alErrInvalidOp[] = "Invalid Operation"; constexpr ALchar alErrOutOfMemory[] = "Out of Memory"; +constexpr ALchar alStackOverflow[] = "Stack Overflow"; +constexpr ALchar alStackUnderflow[] = "Stack Underflow"; /* Resampler strings */ template<Resampler rtype> struct ResamplerName { }; @@ -103,7 +109,7 @@ const ALchar *GetResamplerName(const Resampler rtype) throw std::runtime_error{"Unexpected resampler index"}; } -al::optional<DistanceModel> DistanceModelFromALenum(ALenum model) +std::optional<DistanceModel> DistanceModelFromALenum(ALenum model) { switch(model) { @@ -115,7 +121,7 @@ al::optional<DistanceModel> DistanceModelFromALenum(ALenum model) case AL_EXPONENT_DISTANCE: return DistanceModel::Exponent; case AL_EXPONENT_DISTANCE_CLAMPED: return DistanceModel::ExponentClamped; } - return al::nullopt; + return std::nullopt; } ALenum ALenumFromDistanceModel(DistanceModel model) { @@ -132,626 +138,352 @@ ALenum ALenumFromDistanceModel(DistanceModel model) throw std::runtime_error{"Unexpected distance model "+std::to_string(static_cast<int>(model))}; } -} // namespace - -/* WARNING: Non-standard export! Not part of any extension, or exposed in the - * alcFunctions list. - */ -AL_API const ALchar* AL_APIENTRY alsoft_get_version(void) -START_API_FUNC -{ - static const auto spoof = al::getenv("ALSOFT_SPOOF_VERSION"); - if(spoof) return spoof->c_str(); - return ALSOFT_VERSION; -} -END_API_FUNC - -#define DO_UPDATEPROPS() do { \ - if(!context->mDeferUpdates) \ - UpdateContextProps(context.get()); \ - else \ - context->mPropsDirty = true; \ -} while(0) - - -AL_API void AL_APIENTRY alEnable(ALenum capability) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - { - std::lock_guard<std::mutex> _{context->mPropLock}; - context->mSourceDistanceModel = true; - DO_UPDATEPROPS(); - } - break; - - case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: - context->setError(AL_INVALID_OPERATION, "Re-enabling AL_STOP_SOURCES_ON_DISCONNECT_SOFT not yet supported"); - break; - - default: - context->setError(AL_INVALID_VALUE, "Invalid enable property 0x%04x", capability); - } -} -END_API_FUNC - -AL_API void AL_APIENTRY alDisable(ALenum capability) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - { - std::lock_guard<std::mutex> _{context->mPropLock}; - context->mSourceDistanceModel = false; - DO_UPDATEPROPS(); - } - break; - - case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: - context->mStopVoicesOnDisconnect = false; - break; - - default: - context->setError(AL_INVALID_VALUE, "Invalid disable property 0x%04x", capability); - } -} -END_API_FUNC - -AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return AL_FALSE; - - std::lock_guard<std::mutex> _{context->mPropLock}; - ALboolean value{AL_FALSE}; - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - value = context->mSourceDistanceModel ? AL_TRUE : AL_FALSE; - break; - - case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: - value = context->mStopVoicesOnDisconnect ? AL_TRUE : AL_FALSE; - break; - - default: - context->setError(AL_INVALID_VALUE, "Invalid is enabled property 0x%04x", capability); - } - - return value; -} -END_API_FUNC - -AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) -START_API_FUNC +enum PropertyValue : ALenum { + DopplerFactor = AL_DOPPLER_FACTOR, + DopplerVelocity = AL_DOPPLER_VELOCITY, + DistanceModel = AL_DISTANCE_MODEL, + SpeedOfSound = AL_SPEED_OF_SOUND, + DeferredUpdates = AL_DEFERRED_UPDATES_SOFT, + GainLimit = AL_GAIN_LIMIT_SOFT, + NumResamplers = AL_NUM_RESAMPLERS_SOFT, + DefaultResampler = AL_DEFAULT_RESAMPLER_SOFT, + DebugLoggedMessages = AL_DEBUG_LOGGED_MESSAGES_EXT, + DebugNextLoggedMessageLength = AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_EXT, + MaxDebugMessageLength = AL_MAX_DEBUG_MESSAGE_LENGTH_EXT, + MaxDebugLoggedMessages = AL_MAX_DEBUG_LOGGED_MESSAGES_EXT, + MaxDebugGroupDepth = AL_MAX_DEBUG_GROUP_STACK_DEPTH_EXT, + MaxLabelLength = AL_MAX_LABEL_LENGTH_EXT, + ContextFlags = AL_CONTEXT_FLAGS_EXT, +#ifdef ALSOFT_EAX + EaxRamSize = AL_EAX_RAM_SIZE, + EaxRamFree = AL_EAX_RAM_FREE, +#endif +}; + +template<typename T> +struct PropertyCastType { + template<typename U> + constexpr auto operator()(U&& value) const noexcept + { return static_cast<T>(std::forward<U>(value)); } +}; +/* Special-case ALboolean to be an actual bool instead of a char type. */ +template<> +struct PropertyCastType<ALboolean> { + template<typename U> + constexpr ALboolean operator()(U&& value) const noexcept + { return static_cast<bool>(std::forward<U>(value)) ? AL_TRUE : AL_FALSE; } +}; + + +template<typename T> +void GetValue(ALCcontext *context, ALenum pname, T *values) { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return AL_FALSE; + auto cast_value = PropertyCastType<T>{}; - std::lock_guard<std::mutex> _{context->mPropLock}; - ALboolean value{AL_FALSE}; - switch(pname) + switch(static_cast<PropertyValue>(pname)) { case AL_DOPPLER_FACTOR: - if(context->mDopplerFactor != 0.0f) - value = AL_TRUE; - break; + *values = cast_value(context->mDopplerFactor); + return; case AL_DOPPLER_VELOCITY: - if(context->mDopplerVelocity != 0.0f) - value = AL_TRUE; - break; - - case AL_DISTANCE_MODEL: - if(context->mDistanceModel == DistanceModel::Default) - value = AL_TRUE; - break; + if(context->mContextFlags.test(ContextFlags::DebugBit)) UNLIKELY + context->debugMessage(DebugSource::API, DebugType::DeprecatedBehavior, 0, + DebugSeverity::Medium, + "AL_DOPPLER_VELOCITY is deprecated in AL 1.1, use AL_SPEED_OF_SOUND; " + "AL_DOPPLER_VELOCITY -> AL_SPEED_OF_SOUND / 343.3f"); + *values = cast_value(context->mDopplerVelocity); + return; case AL_SPEED_OF_SOUND: - if(context->mSpeedOfSound != 0.0f) - value = AL_TRUE; - break; - - case AL_DEFERRED_UPDATES_SOFT: - if(context->mDeferUpdates) - value = AL_TRUE; - break; + *values = cast_value(context->mSpeedOfSound); + return; case AL_GAIN_LIMIT_SOFT: - if(GainMixMax/context->mGainBoost != 0.0f) - value = AL_TRUE; - break; - - case AL_NUM_RESAMPLERS_SOFT: - /* Always non-0. */ - value = AL_TRUE; - break; - - case AL_DEFAULT_RESAMPLER_SOFT: - value = static_cast<int>(ResamplerDefault) ? AL_TRUE : AL_FALSE; - break; - - default: - context->setError(AL_INVALID_VALUE, "Invalid boolean property 0x%04x", pname); - } - - return value; -} -END_API_FUNC - -AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return 0.0; - - std::lock_guard<std::mutex> _{context->mPropLock}; - ALdouble value{0.0}; - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = context->mDopplerFactor; - break; - - case AL_DOPPLER_VELOCITY: - value = context->mDopplerVelocity; - break; - - case AL_DISTANCE_MODEL: - value = static_cast<ALdouble>(ALenumFromDistanceModel(context->mDistanceModel)); - break; - - case AL_SPEED_OF_SOUND: - value = context->mSpeedOfSound; - break; + *values = cast_value(GainMixMax / context->mGainBoost); + return; case AL_DEFERRED_UPDATES_SOFT: - if(context->mDeferUpdates) - value = static_cast<ALdouble>(AL_TRUE); - break; - - case AL_GAIN_LIMIT_SOFT: - value = ALdouble{GainMixMax}/context->mGainBoost; - break; - - case AL_NUM_RESAMPLERS_SOFT: - value = static_cast<ALdouble>(Resampler::Max) + 1.0; - break; - - case AL_DEFAULT_RESAMPLER_SOFT: - value = static_cast<ALdouble>(ResamplerDefault); - break; - - default: - context->setError(AL_INVALID_VALUE, "Invalid double property 0x%04x", pname); - } - - return value; -} -END_API_FUNC - -AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return 0.0f; - - std::lock_guard<std::mutex> _{context->mPropLock}; - ALfloat value{0.0f}; - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = context->mDopplerFactor; - break; - - case AL_DOPPLER_VELOCITY: - value = context->mDopplerVelocity; - break; + *values = cast_value(context->mDeferUpdates ? AL_TRUE : AL_FALSE); + return; case AL_DISTANCE_MODEL: - value = static_cast<ALfloat>(ALenumFromDistanceModel(context->mDistanceModel)); - break; - - case AL_SPEED_OF_SOUND: - value = context->mSpeedOfSound; - break; - - case AL_DEFERRED_UPDATES_SOFT: - if(context->mDeferUpdates) - value = static_cast<ALfloat>(AL_TRUE); - break; - - case AL_GAIN_LIMIT_SOFT: - value = GainMixMax/context->mGainBoost; - break; + *values = cast_value(ALenumFromDistanceModel(context->mDistanceModel)); + return; case AL_NUM_RESAMPLERS_SOFT: - value = static_cast<ALfloat>(Resampler::Max) + 1.0f; - break; + *values = cast_value(al::to_underlying(Resampler::Max) + 1); + return; case AL_DEFAULT_RESAMPLER_SOFT: - value = static_cast<ALfloat>(ResamplerDefault); - break; + *values = cast_value(al::to_underlying(ResamplerDefault)); + return; - default: - context->setError(AL_INVALID_VALUE, "Invalid float property 0x%04x", pname); + case AL_DEBUG_LOGGED_MESSAGES_EXT: + { + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + *values = cast_value(context->mDebugLog.size()); + return; } - return value; -} -END_API_FUNC - -AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return 0; - - std::lock_guard<std::mutex> _{context->mPropLock}; - ALint value{0}; - switch(pname) + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_EXT: { - case AL_DOPPLER_FACTOR: - value = static_cast<ALint>(context->mDopplerFactor); - break; + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + *values = cast_value(context->mDebugLog.empty() ? 0_uz + : (context->mDebugLog.front().mMessage.size()+1)); + return; + } - case AL_DOPPLER_VELOCITY: - value = static_cast<ALint>(context->mDopplerVelocity); - break; + case AL_MAX_DEBUG_MESSAGE_LENGTH_EXT: + *values = cast_value(MaxDebugMessageLength); + return; - case AL_DISTANCE_MODEL: - value = ALenumFromDistanceModel(context->mDistanceModel); - break; + case AL_MAX_DEBUG_LOGGED_MESSAGES_EXT: + *values = cast_value(MaxDebugLoggedMessages); + return; - case AL_SPEED_OF_SOUND: - value = static_cast<ALint>(context->mSpeedOfSound); - break; + case AL_MAX_DEBUG_GROUP_STACK_DEPTH_EXT: + *values = cast_value(MaxDebugGroupDepth); + return; - case AL_DEFERRED_UPDATES_SOFT: - if(context->mDeferUpdates) - value = AL_TRUE; - break; + case AL_MAX_LABEL_LENGTH_EXT: + *values = cast_value(MaxObjectLabelLength); + return; - case AL_GAIN_LIMIT_SOFT: - value = static_cast<ALint>(GainMixMax/context->mGainBoost); - break; - - case AL_NUM_RESAMPLERS_SOFT: - value = static_cast<int>(Resampler::Max) + 1; - break; - - case AL_DEFAULT_RESAMPLER_SOFT: - value = static_cast<int>(ResamplerDefault); - break; + case AL_CONTEXT_FLAGS_EXT: + *values = cast_value(context->mContextFlags.to_ulong()); + return; #ifdef ALSOFT_EAX #define EAX_ERROR "[alGetInteger] EAX not enabled." case AL_EAX_RAM_SIZE: - if (eax_g_is_enabled) - { - value = eax_x_ram_max_size; - } - else + if(eax_g_is_enabled) { - context->setError(AL_INVALID_VALUE, EAX_ERROR); + *values = cast_value(eax_x_ram_max_size); + return; } - - break; + context->setError(AL_INVALID_ENUM, EAX_ERROR); + return; case AL_EAX_RAM_FREE: - if (eax_g_is_enabled) + if(eax_g_is_enabled) { auto device = context->mALDevice.get(); std::lock_guard<std::mutex> device_lock{device->BufferLock}; - - value = static_cast<ALint>(device->eax_x_ram_free_size); + *values = cast_value(device->eax_x_ram_free_size); + return; } - else - { - context->setError(AL_INVALID_VALUE, EAX_ERROR); - } - - break; + context->setError(AL_INVALID_ENUM, EAX_ERROR); + return; #undef EAX_ERROR #endif // ALSOFT_EAX - - default: - context->setError(AL_INVALID_VALUE, "Invalid integer property 0x%04x", pname); } + context->setError(AL_INVALID_ENUM, "Invalid context property 0x%04x", pname); +} - return value; + +inline void UpdateProps(ALCcontext *context) +{ + if(!context->mDeferUpdates) + UpdateContextProps(context); + else + context->mPropsDirty = true; } -END_API_FUNC -AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) -START_API_FUNC +} // namespace + +/* WARNING: Non-standard export! Not part of any extension, or exposed in the + * alcFunctions list. + */ +AL_API const ALchar* AL_APIENTRY alsoft_get_version(void) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return 0_i64; + static const auto spoof = al::getenv("ALSOFT_SPOOF_VERSION"); + if(spoof) return spoof->c_str(); + return ALSOFT_VERSION; +} - std::lock_guard<std::mutex> _{context->mPropLock}; - ALint64SOFT value{0}; - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = static_cast<ALint64SOFT>(context->mDopplerFactor); - break; - case AL_DOPPLER_VELOCITY: - value = static_cast<ALint64SOFT>(context->mDopplerVelocity); +AL_API DECL_FUNC1(void, alEnable, ALenum) +FORCE_ALIGN void AL_APIENTRY alEnableDirect(ALCcontext *context, ALenum capability) noexcept +{ + switch(capability) + { + case AL_SOURCE_DISTANCE_MODEL: + { + std::lock_guard<std::mutex> _{context->mPropLock}; + context->mSourceDistanceModel = true; + UpdateProps(context); + } break; - case AL_DISTANCE_MODEL: - value = ALenumFromDistanceModel(context->mDistanceModel); + case AL_DEBUG_OUTPUT_EXT: + context->mDebugEnabled = true; break; - case AL_SPEED_OF_SOUND: - value = static_cast<ALint64SOFT>(context->mSpeedOfSound); + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + context->setError(AL_INVALID_OPERATION, "Re-enabling AL_STOP_SOURCES_ON_DISCONNECT_SOFT not yet supported"); break; - case AL_DEFERRED_UPDATES_SOFT: - if(context->mDeferUpdates) - value = AL_TRUE; - break; + default: + context->setError(AL_INVALID_VALUE, "Invalid enable property 0x%04x", capability); + } +} - case AL_GAIN_LIMIT_SOFT: - value = static_cast<ALint64SOFT>(GainMixMax/context->mGainBoost); +AL_API DECL_FUNC1(void, alDisable, ALenum) +FORCE_ALIGN void AL_APIENTRY alDisableDirect(ALCcontext *context, ALenum capability) noexcept +{ + switch(capability) + { + case AL_SOURCE_DISTANCE_MODEL: + { + std::lock_guard<std::mutex> _{context->mPropLock}; + context->mSourceDistanceModel = false; + UpdateProps(context); + } break; - case AL_NUM_RESAMPLERS_SOFT: - value = static_cast<ALint64SOFT>(Resampler::Max) + 1; + case AL_DEBUG_OUTPUT_EXT: + context->mDebugEnabled = false; break; - case AL_DEFAULT_RESAMPLER_SOFT: - value = static_cast<ALint64SOFT>(ResamplerDefault); + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + context->mStopVoicesOnDisconnect = false; break; default: - context->setError(AL_INVALID_VALUE, "Invalid integer64 property 0x%04x", pname); + context->setError(AL_INVALID_VALUE, "Invalid disable property 0x%04x", capability); } - - return value; } -END_API_FUNC -AL_API ALvoid* AL_APIENTRY alGetPointerSOFT(ALenum pname) -START_API_FUNC +AL_API DECL_FUNC1(ALboolean, alIsEnabled, ALenum) +FORCE_ALIGN ALboolean AL_APIENTRY alIsEnabledDirect(ALCcontext *context, ALenum capability) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return nullptr; - std::lock_guard<std::mutex> _{context->mPropLock}; - void *value{nullptr}; - switch(pname) + ALboolean value{AL_FALSE}; + switch(capability) { - case AL_EVENT_CALLBACK_FUNCTION_SOFT: - value = reinterpret_cast<void*>(context->mEventCb); + case AL_SOURCE_DISTANCE_MODEL: + value = context->mSourceDistanceModel ? AL_TRUE : AL_FALSE; break; - case AL_EVENT_CALLBACK_USER_PARAM_SOFT: - value = context->mEventParam; + case AL_DEBUG_OUTPUT_EXT: + value = context->mDebugEnabled ? AL_TRUE : AL_FALSE; + break; + + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + value = context->mStopVoicesOnDisconnect ? AL_TRUE : AL_FALSE; break; default: - context->setError(AL_INVALID_VALUE, "Invalid pointer property 0x%04x", pname); + context->setError(AL_INVALID_VALUE, "Invalid is enabled property 0x%04x", capability); } return value; } -END_API_FUNC -AL_API void AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values) -START_API_FUNC -{ - if(values) - { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - case AL_GAIN_LIMIT_SOFT: - case AL_NUM_RESAMPLERS_SOFT: - case AL_DEFAULT_RESAMPLER_SOFT: - values[0] = alGetBoolean(pname); - return; - } - } +#define DECL_GETFUNC(R, Name, Ext) \ +AL_API R AL_APIENTRY Name##Ext(ALenum pname) noexcept \ +{ \ + R value{}; \ + auto context = GetContextRef(); \ + if(!context) UNLIKELY return value; \ + Name##vDirect##Ext(GetContextRef().get(), pname, &value); \ + return value; \ +} \ +FORCE_ALIGN R AL_APIENTRY Name##Direct##Ext(ALCcontext *context, ALenum pname) noexcept \ +{ \ + R value{}; \ + Name##vDirect##Ext(context, pname, &value); \ + return value; \ +} - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; +DECL_GETFUNC(ALboolean, alGetBoolean,) +DECL_GETFUNC(ALdouble, alGetDouble,) +DECL_GETFUNC(ALfloat, alGetFloat,) +DECL_GETFUNC(ALint, alGetInteger,) - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { - default: - context->setError(AL_INVALID_VALUE, "Invalid boolean-vector property 0x%04x", pname); - } -} -END_API_FUNC +DECL_GETFUNC(ALint64SOFT, alGetInteger64,SOFT) +DECL_GETFUNC(ALvoid*, alGetPointer,SOFT) -AL_API void AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values) -START_API_FUNC -{ - if(values) - { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - case AL_GAIN_LIMIT_SOFT: - case AL_NUM_RESAMPLERS_SOFT: - case AL_DEFAULT_RESAMPLER_SOFT: - values[0] = alGetDouble(pname); - return; - } - } +#undef DECL_GETFUNC - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { - default: - context->setError(AL_INVALID_VALUE, "Invalid double-vector property 0x%04x", pname); - } +AL_API DECL_FUNC2(void, alGetBooleanv, ALenum, ALboolean*) +FORCE_ALIGN void AL_APIENTRY alGetBooleanvDirect(ALCcontext *context, ALenum pname, ALboolean *values) noexcept +{ + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + GetValue(context, pname, values); } -END_API_FUNC -AL_API void AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values) -START_API_FUNC +AL_API DECL_FUNC2(void, alGetDoublev, ALenum, ALdouble*) +FORCE_ALIGN void AL_APIENTRY alGetDoublevDirect(ALCcontext *context, ALenum pname, ALdouble *values) noexcept { - if(values) - { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - case AL_GAIN_LIMIT_SOFT: - case AL_NUM_RESAMPLERS_SOFT: - case AL_DEFAULT_RESAMPLER_SOFT: - values[0] = alGetFloat(pname); - return; - } - } - - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { - default: - context->setError(AL_INVALID_VALUE, "Invalid float-vector property 0x%04x", pname); - } + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + GetValue(context, pname, values); } -END_API_FUNC -AL_API void AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) -START_API_FUNC +AL_API DECL_FUNC2(void, alGetFloatv, ALenum, ALfloat*) +FORCE_ALIGN void AL_APIENTRY alGetFloatvDirect(ALCcontext *context, ALenum pname, ALfloat *values) noexcept { - if(values) - { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - case AL_GAIN_LIMIT_SOFT: - case AL_NUM_RESAMPLERS_SOFT: - case AL_DEFAULT_RESAMPLER_SOFT: - values[0] = alGetInteger(pname); - return; - } - } - - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { - default: - context->setError(AL_INVALID_VALUE, "Invalid integer-vector property 0x%04x", pname); - } + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + GetValue(context, pname, values); } -END_API_FUNC -AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) -START_API_FUNC +AL_API DECL_FUNC2(void, alGetIntegerv, ALenum, ALint*) +FORCE_ALIGN void AL_APIENTRY alGetIntegervDirect(ALCcontext *context, ALenum pname, ALint *values) noexcept { - if(values) - { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - case AL_GAIN_LIMIT_SOFT: - case AL_NUM_RESAMPLERS_SOFT: - case AL_DEFAULT_RESAMPLER_SOFT: - values[0] = alGetInteger64SOFT(pname); - return; - } - } - - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + GetValue(context, pname, values); +} - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { - default: - context->setError(AL_INVALID_VALUE, "Invalid integer64-vector property 0x%04x", pname); - } +AL_API DECL_FUNCEXT2(void, alGetInteger64v,SOFT, ALenum, ALint64SOFT*) +FORCE_ALIGN void AL_APIENTRY alGetInteger64vDirectSOFT(ALCcontext *context, ALenum pname, ALint64SOFT *values) noexcept +{ + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + GetValue(context, pname, values); } -END_API_FUNC -AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, ALvoid **values) -START_API_FUNC +AL_API DECL_FUNCEXT2(void, alGetPointerv,SOFT, ALenum, ALvoid**) +FORCE_ALIGN void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum pname, ALvoid **values) noexcept { - if(values) + if(!values) UNLIKELY + return context->setError(AL_INVALID_VALUE, "NULL pointer"); + + switch(pname) { - switch(pname) - { - case AL_EVENT_CALLBACK_FUNCTION_SOFT: - case AL_EVENT_CALLBACK_USER_PARAM_SOFT: - values[0] = alGetPointerSOFT(pname); - return; - } - } + case AL_EVENT_CALLBACK_FUNCTION_SOFT: + *values = al::bit_cast<void*>(context->mEventCb); + break; - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; + case AL_EVENT_CALLBACK_USER_PARAM_SOFT: + *values = context->mEventParam; + break; + + case AL_DEBUG_CALLBACK_FUNCTION_EXT: + *values = al::bit_cast<void*>(context->mDebugCb); + break; + + case AL_DEBUG_CALLBACK_USER_PARAM_EXT: + *values = context->mDebugParam; + break; - if(!values) - context->setError(AL_INVALID_VALUE, "NULL pointer"); - else switch(pname) - { default: - context->setError(AL_INVALID_VALUE, "Invalid pointer-vector property 0x%04x", pname); + context->setError(AL_INVALID_ENUM, "Invalid context pointer property 0x%04x", pname); } } -END_API_FUNC -AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname) -START_API_FUNC +AL_API DECL_FUNC1(const ALchar*, alGetString, ALenum) +FORCE_ALIGN const ALchar* AL_APIENTRY alGetStringDirect(ALCcontext *context, ALenum pname) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return nullptr; - const ALchar *value{nullptr}; switch(pname) { @@ -768,7 +500,7 @@ START_API_FUNC break; case AL_EXTENSIONS: - value = context->mExtensionList; + value = context->mExtensionsString.c_str(); break; case AL_NO_ERROR: @@ -795,112 +527,79 @@ START_API_FUNC value = alErrOutOfMemory; break; + case AL_STACK_OVERFLOW_EXT: + value = alStackOverflow; + break; + + case AL_STACK_UNDERFLOW_EXT: + value = alStackUnderflow; + break; + default: context->setError(AL_INVALID_VALUE, "Invalid string property 0x%04x", pname); } return value; } -END_API_FUNC -AL_API void AL_APIENTRY alDopplerFactor(ALfloat value) -START_API_FUNC +AL_API DECL_FUNC1(void, alDopplerFactor, ALfloat) +FORCE_ALIGN void AL_APIENTRY alDopplerFactorDirect(ALCcontext *context, ALfloat value) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - if(!(value >= 0.0f && std::isfinite(value))) context->setError(AL_INVALID_VALUE, "Doppler factor %f out of range", value); else { std::lock_guard<std::mutex> _{context->mPropLock}; context->mDopplerFactor = value; - DO_UPDATEPROPS(); + UpdateProps(context); } } -END_API_FUNC -AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value) -START_API_FUNC +AL_API DECL_FUNC1(void, alSpeedOfSound, ALfloat) +FORCE_ALIGN void AL_APIENTRY alSpeedOfSoundDirect(ALCcontext *context, ALfloat value) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - if(!(value >= 0.0f && std::isfinite(value))) - context->setError(AL_INVALID_VALUE, "Doppler velocity %f out of range", value); - else - { - std::lock_guard<std::mutex> _{context->mPropLock}; - context->mDopplerVelocity = value; - DO_UPDATEPROPS(); - } -} -END_API_FUNC - -AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value) -START_API_FUNC -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - if(!(value > 0.0f && std::isfinite(value))) context->setError(AL_INVALID_VALUE, "Speed of sound %f out of range", value); else { std::lock_guard<std::mutex> _{context->mPropLock}; context->mSpeedOfSound = value; - DO_UPDATEPROPS(); + UpdateProps(context); } } -END_API_FUNC -AL_API void AL_APIENTRY alDistanceModel(ALenum value) -START_API_FUNC +AL_API DECL_FUNC1(void, alDistanceModel, ALenum) +FORCE_ALIGN void AL_APIENTRY alDistanceModelDirect(ALCcontext *context, ALenum value) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - if(auto model = DistanceModelFromALenum(value)) { std::lock_guard<std::mutex> _{context->mPropLock}; context->mDistanceModel = *model; if(!context->mSourceDistanceModel) - DO_UPDATEPROPS(); + UpdateProps(context); } else context->setError(AL_INVALID_VALUE, "Distance model 0x%04x out of range", value); } -END_API_FUNC -AL_API void AL_APIENTRY alDeferUpdatesSOFT(void) -START_API_FUNC +AL_API DECL_FUNCEXT(void, alDeferUpdates,SOFT) +FORCE_ALIGN void AL_APIENTRY alDeferUpdatesDirectSOFT(ALCcontext *context) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - std::lock_guard<std::mutex> _{context->mPropLock}; context->deferUpdates(); } -END_API_FUNC -AL_API void AL_APIENTRY alProcessUpdatesSOFT(void) -START_API_FUNC +AL_API DECL_FUNCEXT(void, alProcessUpdates,SOFT) +FORCE_ALIGN void AL_APIENTRY alProcessUpdatesDirectSOFT(ALCcontext *context) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - std::lock_guard<std::mutex> _{context->mPropLock}; context->processUpdates(); } -END_API_FUNC -AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index) -START_API_FUNC +AL_API DECL_FUNCEXT2(const ALchar*, alGetStringi,SOFT, ALenum,ALsizei) +FORCE_ALIGN const ALchar* AL_APIENTRY alGetStringiDirectSOFT(ALCcontext *context, ALenum pname, ALsizei index) noexcept { - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return nullptr; - const ALchar *value{nullptr}; switch(pname) { @@ -916,7 +615,28 @@ START_API_FUNC } return value; } -END_API_FUNC + + +AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + if(context->mContextFlags.test(ContextFlags::DebugBit)) UNLIKELY + context->debugMessage(DebugSource::API, DebugType::DeprecatedBehavior, 0, + DebugSeverity::Medium, + "alDopplerVelocity is deprecated in AL 1.1, use alSpeedOfSound; " + "alDopplerVelocity(x) -> alSpeedOfSound(343.3f * x)"); + + if(!(value >= 0.0f && std::isfinite(value))) + context->setError(AL_INVALID_VALUE, "Doppler velocity %f out of range", value); + else + { + std::lock_guard<std::mutex> _{context->mPropLock}; + context->mDopplerVelocity = value; + UpdateProps(context.get()); + } +} void UpdateContextProps(ALCcontext *context) |