mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 08:34:40 +00:00
update openal-soft to 1.24.3
keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
This commit is contained in:
parent
12db0500e8
commit
ba32094b7b
276 changed files with 49304 additions and 8712 deletions
|
|
@ -31,7 +31,6 @@
|
|||
#include <mutex>
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
|
@ -54,27 +53,27 @@
|
|||
#include "buffer.h"
|
||||
#include "core/buffer_storage.h"
|
||||
#include "core/device.h"
|
||||
#include "core/except.h"
|
||||
#include "core/fpu_ctrl.h"
|
||||
#include "core/logging.h"
|
||||
#include "direct_defs.h"
|
||||
#include "effect.h"
|
||||
#include "error.h"
|
||||
#include "flexarray.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include "eax/api.h"
|
||||
#include "eax/call.h"
|
||||
#include "eax/effect.h"
|
||||
#include "eax/fx_slot_index.h"
|
||||
#include "eax/utils.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
using SubListAllocator = al::allocator<std::array<ALeffectslot,64>>;
|
||||
|
||||
EffectStateFactory *getFactoryByType(EffectSlotType type)
|
||||
[[nodiscard]]
|
||||
auto getFactoryByType(EffectSlotType type) -> EffectStateFactory*
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
|
|
@ -98,6 +97,7 @@ EffectStateFactory *getFactoryByType(EffectSlotType type)
|
|||
}
|
||||
|
||||
|
||||
[[nodiscard]]
|
||||
auto LookupEffectSlot(ALCcontext *context, ALuint id) noexcept -> ALeffectslot*
|
||||
{
|
||||
const size_t lidx{(id-1) >> 6};
|
||||
|
|
@ -111,7 +111,8 @@ auto LookupEffectSlot(ALCcontext *context, ALuint id) noexcept -> ALeffectslot*
|
|||
return al::to_address(sublist.EffectSlots->begin() + slidx);
|
||||
}
|
||||
|
||||
inline auto LookupEffect(ALCdevice *device, ALuint id) noexcept -> ALeffect*
|
||||
[[nodiscard]]
|
||||
inline auto LookupEffect(al::Device *device, ALuint id) noexcept -> ALeffect*
|
||||
{
|
||||
const size_t lidx{(id-1) >> 6};
|
||||
const ALuint slidx{(id-1) & 0x3f};
|
||||
|
|
@ -124,7 +125,8 @@ inline auto LookupEffect(ALCdevice *device, ALuint id) noexcept -> ALeffect*
|
|||
return al::to_address(sublist.Effects->begin() + slidx);
|
||||
}
|
||||
|
||||
inline auto LookupBuffer(ALCdevice *device, ALuint id) noexcept -> ALbuffer*
|
||||
[[nodiscard]]
|
||||
inline auto LookupBuffer(al::Device *device, ALuint id) noexcept -> ALbuffer*
|
||||
{
|
||||
const size_t lidx{(id-1) >> 6};
|
||||
const ALuint slidx{(id-1) & 0x3f};
|
||||
|
|
@ -217,6 +219,7 @@ void RemoveActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext
|
|||
}
|
||||
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto EffectSlotTypeFromEnum(ALenum type) noexcept -> EffectSlotType
|
||||
{
|
||||
switch(type)
|
||||
|
|
@ -239,10 +242,11 @@ constexpr auto EffectSlotTypeFromEnum(ALenum type) noexcept -> EffectSlotType
|
|||
case AL_EFFECT_DEDICATED_DIALOGUE: return EffectSlotType::Dedicated;
|
||||
case AL_EFFECT_CONVOLUTION_SOFT: return EffectSlotType::Convolution;
|
||||
}
|
||||
ERR("Unhandled effect enum: 0x%04x\n", type);
|
||||
ERR("Unhandled effect enum: {:#04x}", as_unsigned(type));
|
||||
return EffectSlotType::None;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto EnsureEffectSlots(ALCcontext *context, size_t needed) noexcept -> bool
|
||||
try {
|
||||
size_t count{std::accumulate(context->mEffectSlotList.cbegin(),
|
||||
|
|
@ -267,7 +271,8 @@ catch(...) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ALeffectslot *AllocEffectSlot(ALCcontext *context)
|
||||
[[nodiscard]]
|
||||
auto AllocEffectSlot(ALCcontext *context) -> ALeffectslot*
|
||||
{
|
||||
auto sublist = std::find_if(context->mEffectSlotList.begin(), context->mEffectSlotList.end(),
|
||||
[](const EffectSlotSubList &entry) noexcept -> bool
|
||||
|
|
@ -322,20 +327,21 @@ FORCE_ALIGN void AL_APIENTRY alGenAuxiliaryEffectSlotsDirect(ALCcontext *context
|
|||
ALuint *effectslots) noexcept
|
||||
try {
|
||||
if(n < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Generating %d effect slots", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Generating {} effect slots", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
auto slotlock = std::lock_guard{context->mEffectSlotLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
|
||||
const al::span eids{effectslots, static_cast<ALuint>(n)};
|
||||
if(eids.size() > device->AuxiliaryEffectSlotMax-context->mNumEffectSlots)
|
||||
throw al::context_error{AL_OUT_OF_MEMORY, "Exceeding %u effect slot limit (%u + %d)",
|
||||
device->AuxiliaryEffectSlotMax, context->mNumEffectSlots, n};
|
||||
if(context->mNumEffectSlots > device->AuxiliaryEffectSlotMax
|
||||
|| eids.size() > device->AuxiliaryEffectSlotMax-context->mNumEffectSlots)
|
||||
context->throw_error(AL_OUT_OF_MEMORY, "Exceeding {} effect slot limit ({} + {})",
|
||||
device->AuxiliaryEffectSlotMax, context->mNumEffectSlots, n);
|
||||
|
||||
if(!EnsureEffectSlots(context, eids.size()))
|
||||
throw al::context_error{AL_OUT_OF_MEMORY, "Failed to allocate %d effectslot%s", n,
|
||||
(n == 1) ? "" : "s"};
|
||||
context->throw_error(AL_OUT_OF_MEMORY, "Failed to allocate {} effectslot{}", n,
|
||||
(n==1) ? "" : "s");
|
||||
|
||||
std::vector<ALeffectslot*> slots;
|
||||
try {
|
||||
|
|
@ -355,16 +361,18 @@ try {
|
|||
}
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
ERR("Exception allocating effectslot %zu of %d: %s\n", slots.size()+1, n, e.what());
|
||||
ERR("Exception allocating effectslot {} of {}: {}", slots.size()+1, n, e.what());
|
||||
auto delete_effectslot = [context](ALeffectslot *slot) -> void
|
||||
{ FreeEffectSlot(context, slot); };
|
||||
std::for_each(slots.begin(), slots.end(), delete_effectslot);
|
||||
throw al::context_error{AL_INVALID_OPERATION, "Exception allocating %d effectslots: %s", n,
|
||||
e.what()};
|
||||
context->throw_error(AL_INVALID_OPERATION, "Exception allocating {} effectslots: {}", n,
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alDeleteAuxiliaryEffectSlots, ALsizei,n, const ALuint*,effectslots)
|
||||
|
|
@ -372,7 +380,7 @@ FORCE_ALIGN void AL_APIENTRY alDeleteAuxiliaryEffectSlotsDirect(ALCcontext *cont
|
|||
const ALuint *effectslots) noexcept
|
||||
try {
|
||||
if(n < 0) UNLIKELY
|
||||
throw al::context_error{AL_INVALID_VALUE, "Deleting %d effect slots", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Deleting {} effect slots", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
|
|
@ -380,10 +388,10 @@ try {
|
|||
{
|
||||
ALeffectslot *slot{LookupEffectSlot(context, *effectslots)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", *effectslots};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", *effectslots);
|
||||
if(slot->ref.load(std::memory_order_relaxed) != 0)
|
||||
throw al::context_error{AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
|
||||
*effectslots};
|
||||
context->throw_error(AL_INVALID_OPERATION, "Deleting in-use effect slot {}",
|
||||
*effectslots);
|
||||
|
||||
RemoveActiveEffectSlots({&slot, 1u}, context);
|
||||
FreeEffectSlot(context, slot);
|
||||
|
|
@ -398,10 +406,9 @@ try {
|
|||
{
|
||||
ALeffectslot *slot{LookupEffectSlot(context, eid)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", eid};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", eid);
|
||||
if(slot->ref.load(std::memory_order_relaxed) != 0)
|
||||
throw al::context_error{AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
|
||||
eid};
|
||||
context->throw_error(AL_INVALID_OPERATION, "Deleting in-use effect slot {}", eid);
|
||||
return slot;
|
||||
};
|
||||
std::transform(eids.cbegin(), eids.cend(), std::back_inserter(slots), lookupslot);
|
||||
|
|
@ -417,8 +424,10 @@ try {
|
|||
std::for_each(eids.begin(), eids.end(), delete_effectslot);
|
||||
}
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(ALboolean, alIsAuxiliaryEffectSlot, ALuint,effectslot)
|
||||
|
|
@ -436,7 +445,6 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotPlaySOFT(ALuint) noexcept
|
|||
{
|
||||
ContextRef context{GetContextRef()};
|
||||
if(!context) UNLIKELY return;
|
||||
|
||||
context->setError(AL_INVALID_OPERATION, "alAuxiliaryEffectSlotPlaySOFT not supported");
|
||||
}
|
||||
|
||||
|
|
@ -444,7 +452,6 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotPlayvSOFT(ALsizei, const ALuint*) n
|
|||
{
|
||||
ContextRef context{GetContextRef()};
|
||||
if(!context) UNLIKELY return;
|
||||
|
||||
context->setError(AL_INVALID_OPERATION, "alAuxiliaryEffectSlotPlayvSOFT not supported");
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +459,6 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopSOFT(ALuint) noexcept
|
|||
{
|
||||
ContextRef context{GetContextRef()};
|
||||
if(!context) UNLIKELY return;
|
||||
|
||||
context->setError(AL_INVALID_OPERATION, "alAuxiliaryEffectSlotStopSOFT not supported");
|
||||
}
|
||||
|
||||
|
|
@ -460,7 +466,6 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopvSOFT(ALsizei, const ALuint*) n
|
|||
{
|
||||
ContextRef context{GetContextRef()};
|
||||
if(!context) UNLIKELY return;
|
||||
|
||||
context->setError(AL_INVALID_OPERATION, "alAuxiliaryEffectSlotStopvSOFT not supported");
|
||||
}
|
||||
|
||||
|
|
@ -474,7 +479,7 @@ try {
|
|||
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot) UNLIKELY
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
ALeffectslot *target{};
|
||||
ALenum err{};
|
||||
|
|
@ -482,20 +487,20 @@ try {
|
|||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
ALeffect *effect{value ? LookupEffect(device, static_cast<ALuint>(value)) : nullptr};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
auto *effect = value ? LookupEffect(device, static_cast<ALuint>(value)) : nullptr;
|
||||
if(effect)
|
||||
err = slot->initEffect(effect->id, effect->type, effect->Props, context);
|
||||
else
|
||||
{
|
||||
if(value != 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Invalid effect ID %u", value};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid effect ID {}", value);
|
||||
err = slot->initEffect(0, AL_EFFECT_NULL, EffectProps{}, context);
|
||||
}
|
||||
}
|
||||
if(err != AL_NO_ERROR)
|
||||
throw al::context_error{err, "Effect initialization failed"};
|
||||
context->throw_error(err, "Effect initialization failed");
|
||||
|
||||
if(slot->mState == SlotState::Initial) UNLIKELY
|
||||
{
|
||||
|
|
@ -511,8 +516,7 @@ try {
|
|||
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
if(!(value == AL_TRUE || value == AL_FALSE))
|
||||
throw al::context_error{AL_INVALID_VALUE,
|
||||
"Effect slot auxiliary send auto out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Effect slot auxiliary send auto out of range");
|
||||
if(!(slot->AuxSendAuto == !!value)) LIKELY
|
||||
{
|
||||
slot->AuxSendAuto = !!value;
|
||||
|
|
@ -523,7 +527,7 @@ try {
|
|||
case AL_EFFECTSLOT_TARGET_SOFT:
|
||||
target = LookupEffectSlot(context, static_cast<ALuint>(value));
|
||||
if(value && !target)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Invalid effect slot target ID"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid effect slot target ID {}", value);
|
||||
if(slot->Target == target) UNLIKELY
|
||||
return;
|
||||
if(target)
|
||||
|
|
@ -532,9 +536,9 @@ try {
|
|||
while(checker && checker != slot)
|
||||
checker = checker->Target;
|
||||
if(checker)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Setting target of effect slot ID %u to %u creates circular chain", slot->id,
|
||||
target->id};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Setting target of effect slot ID {} to {} creates circular chain", slot->id,
|
||||
target->id);
|
||||
}
|
||||
|
||||
if(ALeffectslot *oldtarget{slot->Target})
|
||||
|
|
@ -569,17 +573,17 @@ try {
|
|||
assert(factory);
|
||||
al::intrusive_ptr<EffectState> state{factory->create()};
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto bufferlock = std::unique_lock{device->BufferLock};
|
||||
ALbuffer *buffer{};
|
||||
if(value)
|
||||
{
|
||||
buffer = LookupBuffer(device, static_cast<ALuint>(value));
|
||||
if(!buffer)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Invalid buffer ID %u", value};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid buffer ID {}", value);
|
||||
if(buffer->mCallback)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Callback buffer not valid for effects"};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Callback buffer not valid for effects");
|
||||
|
||||
IncrementRef(buffer->ref);
|
||||
}
|
||||
|
|
@ -605,17 +609,17 @@ try {
|
|||
}
|
||||
else
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto bufferlock = std::unique_lock{device->BufferLock};
|
||||
ALbuffer *buffer{};
|
||||
if(value)
|
||||
{
|
||||
buffer = LookupBuffer(device, static_cast<ALuint>(value));
|
||||
if(!buffer)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Invalid buffer ID %u", value};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid buffer ID {}", value);
|
||||
if(buffer->mCallback)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Callback buffer not valid for effects"};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Callback buffer not valid for effects");
|
||||
|
||||
IncrementRef(buffer->ref);
|
||||
}
|
||||
|
|
@ -633,13 +637,16 @@ try {
|
|||
return;
|
||||
|
||||
case AL_EFFECTSLOT_STATE_SOFT:
|
||||
throw al::context_error{AL_INVALID_OPERATION, "AL_EFFECTSLOT_STATE_SOFT is read-only"};
|
||||
context->throw_error(AL_INVALID_OPERATION, "AL_EFFECTSLOT_STATE_SOFT is read-only");
|
||||
}
|
||||
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot integer property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alAuxiliaryEffectSlotiv, ALuint,effectslot, ALenum,param, const ALint*,values)
|
||||
|
|
@ -660,16 +667,15 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot integer-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alAuxiliaryEffectSlotf, ALuint,effectslot, ALenum,param, ALfloat,value)
|
||||
|
|
@ -681,13 +687,13 @@ try {
|
|||
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
if(!(value >= 0.0f && value <= 1.0f))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Effect slot gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Effect slot gain {} out of range", value);
|
||||
if(!(slot->Gain == value)) LIKELY
|
||||
{
|
||||
slot->Gain = value;
|
||||
|
|
@ -696,10 +702,13 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alAuxiliaryEffectSlotfv, ALuint,effectslot, ALenum,param, const ALfloat*,values)
|
||||
|
|
@ -716,16 +725,15 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot float-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot float-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -736,7 +744,7 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -767,10 +775,13 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot integer property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetAuxiliaryEffectSlotiv, ALuint,effectslot, ALenum,param, ALint*,values)
|
||||
|
|
@ -791,16 +802,15 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot = LookupEffectSlot(context, effectslot);
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot integer-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetAuxiliaryEffectSlotf, ALuint,effectslot, ALenum,param, ALfloat*,value)
|
||||
|
|
@ -810,19 +820,20 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
*value = slot->Gain;
|
||||
return;
|
||||
case AL_EFFECTSLOT_GAIN: *value = slot->Gain; return;
|
||||
}
|
||||
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetAuxiliaryEffectSlotfv, ALuint,effectslot, ALenum,param, ALfloat*,values)
|
||||
|
|
@ -839,16 +850,15 @@ try {
|
|||
std::lock_guard<std::mutex> slotlock{context->mEffectSlotLock};
|
||||
ALeffectslot *slot{LookupEffectSlot(context, effectslot)};
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", effectslot};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", effectslot);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid effect slot float-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid effect slot float-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -890,12 +900,13 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect
|
|||
EffectStateFactory *factory{getFactoryByType(newtype)};
|
||||
if(!factory)
|
||||
{
|
||||
ERR("Failed to find factory for effect slot type %d\n", static_cast<int>(newtype));
|
||||
ERR("Failed to find factory for effect slot type {}",
|
||||
int{al::to_underlying(newtype)});
|
||||
return AL_INVALID_ENUM;
|
||||
}
|
||||
al::intrusive_ptr<EffectState> state{factory->create()};
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
auto *device = context->mALDevice.get();
|
||||
state->mOutTarget = device->Dry.Buffer;
|
||||
{
|
||||
FPUCtl mixer_mode{};
|
||||
|
|
@ -964,7 +975,7 @@ void ALeffectslot::SetName(ALCcontext* context, ALuint id, std::string_view name
|
|||
|
||||
auto slot = LookupEffectSlot(context, id);
|
||||
if(!slot)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect slot ID %u", id};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect slot ID {}", id);
|
||||
|
||||
context->mEffectSlotNames.insert_or_assign(id, name);
|
||||
}
|
||||
|
|
@ -1004,51 +1015,51 @@ EffectSlotSubList::~EffectSlotSubList()
|
|||
EffectSlots = nullptr;
|
||||
}
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
void ALeffectslot::eax_initialize(ALCcontext& al_context, EaxFxSlotIndexValue index)
|
||||
{
|
||||
if(index >= EAX_MAX_FXSLOTS)
|
||||
eax_fail("Index out of range.");
|
||||
|
||||
eax_al_context_ = &al_context;
|
||||
eax_fx_slot_index_ = index;
|
||||
mEaxALContext = &al_context;
|
||||
mEaxFXSlotIndex = index;
|
||||
eax_fx_slot_set_defaults();
|
||||
|
||||
eax_effect_ = std::make_unique<EaxEffect>();
|
||||
if(index == 0) eax_effect_->init<EaxReverbCommitter>();
|
||||
else if(index == 1) eax_effect_->init<EaxChorusCommitter>();
|
||||
else eax_effect_->init<EaxNullCommitter>();
|
||||
mEaxEffect = std::make_unique<EaxEffect>();
|
||||
if(index == 0) mEaxEffect->init<EaxReverbCommitter>();
|
||||
else if(index == 1) mEaxEffect->init<EaxChorusCommitter>();
|
||||
else mEaxEffect->init<EaxNullCommitter>();
|
||||
}
|
||||
|
||||
void ALeffectslot::eax_commit()
|
||||
{
|
||||
if(eax_df_ != EaxDirtyFlags{})
|
||||
if(mEaxDf.any())
|
||||
{
|
||||
auto df = EaxDirtyFlags{};
|
||||
switch(eax_version_)
|
||||
auto df = std::bitset<eax_dirty_bit_count>{};
|
||||
switch(mEaxVersion)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
eax5_fx_slot_commit(eax123_, df);
|
||||
eax5_fx_slot_commit(mEax123, df);
|
||||
break;
|
||||
case 4:
|
||||
eax4_fx_slot_commit(df);
|
||||
break;
|
||||
case 5:
|
||||
eax5_fx_slot_commit(eax5_, df);
|
||||
eax5_fx_slot_commit(mEax5, df);
|
||||
break;
|
||||
}
|
||||
eax_df_ = EaxDirtyFlags{};
|
||||
mEaxDf.reset();
|
||||
|
||||
if((df & eax_volume_dirty_bit) != EaxDirtyFlags{})
|
||||
if(df.test(eax_volume_dirty_bit))
|
||||
eax_fx_slot_set_volume();
|
||||
if((df & eax_flags_dirty_bit) != EaxDirtyFlags{})
|
||||
if(df.test(eax_flags_dirty_bit))
|
||||
eax_fx_slot_set_flags();
|
||||
}
|
||||
|
||||
if(eax_effect_->commit(eax_version_))
|
||||
eax_set_efx_slot_effect(*eax_effect_);
|
||||
if(mEaxEffect->commit(mEaxVersion))
|
||||
eax_set_efx_slot_effect(*mEaxEffect);
|
||||
}
|
||||
|
||||
[[noreturn]] void ALeffectslot::eax_fail(const char* message)
|
||||
|
|
@ -1111,7 +1122,7 @@ ALenum ALeffectslot::eax_get_efx_effect_type(const GUID& guid)
|
|||
|
||||
const GUID& ALeffectslot::eax_get_eax_default_effect_guid() const noexcept
|
||||
{
|
||||
switch(eax_fx_slot_index_)
|
||||
switch(mEaxFXSlotIndex)
|
||||
{
|
||||
case 0: return EAX_REVERB_EFFECT;
|
||||
case 1: return EAX_CHORUS_EFFECT;
|
||||
|
|
@ -1124,7 +1135,7 @@ long ALeffectslot::eax_get_eax_default_lock() const noexcept
|
|||
return eax4_fx_slot_is_legacy() ? EAXFXSLOT_LOCKED : EAXFXSLOT_UNLOCKED;
|
||||
}
|
||||
|
||||
void ALeffectslot::eax4_fx_slot_set_defaults(Eax4Props& props) noexcept
|
||||
void ALeffectslot::eax4_fx_slot_set_defaults(EAX40FXSLOTPROPERTIES& props) noexcept
|
||||
{
|
||||
props.guidLoadEffect = eax_get_eax_default_effect_guid();
|
||||
props.lVolume = EAXFXSLOT_DEFAULTVOLUME;
|
||||
|
|
@ -1132,7 +1143,7 @@ void ALeffectslot::eax4_fx_slot_set_defaults(Eax4Props& props) noexcept
|
|||
props.ulFlags = EAX40FXSLOT_DEFAULTFLAGS;
|
||||
}
|
||||
|
||||
void ALeffectslot::eax5_fx_slot_set_defaults(Eax5Props& props) noexcept
|
||||
void ALeffectslot::eax5_fx_slot_set_defaults(EAX50FXSLOTPROPERTIES& props) noexcept
|
||||
{
|
||||
props.guidLoadEffect = eax_get_eax_default_effect_guid();
|
||||
props.lVolume = EAXFXSLOT_DEFAULTVOLUME;
|
||||
|
|
@ -1144,14 +1155,14 @@ void ALeffectslot::eax5_fx_slot_set_defaults(Eax5Props& props) noexcept
|
|||
|
||||
void ALeffectslot::eax_fx_slot_set_defaults()
|
||||
{
|
||||
eax5_fx_slot_set_defaults(eax123_.i);
|
||||
eax4_fx_slot_set_defaults(eax4_.i);
|
||||
eax5_fx_slot_set_defaults(eax5_.i);
|
||||
eax_ = eax5_.i;
|
||||
eax_df_ = EaxDirtyFlags{};
|
||||
eax5_fx_slot_set_defaults(mEax123.i);
|
||||
eax4_fx_slot_set_defaults(mEax4.i);
|
||||
eax5_fx_slot_set_defaults(mEax5.i);
|
||||
mEax = mEax5.i;
|
||||
mEaxDf.reset();
|
||||
}
|
||||
|
||||
void ALeffectslot::eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props)
|
||||
void ALeffectslot::eax4_fx_slot_get(const EaxCall& call, const EAX40FXSLOTPROPERTIES& props)
|
||||
{
|
||||
switch(call.get_property_id())
|
||||
{
|
||||
|
|
@ -1175,7 +1186,7 @@ void ALeffectslot::eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props)
|
|||
}
|
||||
}
|
||||
|
||||
void ALeffectslot::eax5_fx_slot_get(const EaxCall& call, const Eax5Props& props)
|
||||
void ALeffectslot::eax5_fx_slot_get(const EaxCall& call, const EAX50FXSLOTPROPERTIES& props)
|
||||
{
|
||||
switch(call.get_property_id())
|
||||
{
|
||||
|
|
@ -1209,8 +1220,8 @@ void ALeffectslot::eax_fx_slot_get(const EaxCall& call) const
|
|||
{
|
||||
switch(call.get_version())
|
||||
{
|
||||
case 4: eax4_fx_slot_get(call, eax4_.i); break;
|
||||
case 5: eax5_fx_slot_get(call, eax5_.i); break;
|
||||
case 4: eax4_fx_slot_get(call, mEax4.i); break;
|
||||
case 5: eax5_fx_slot_get(call, mEax5.i); break;
|
||||
default: eax_fail_unknown_version();
|
||||
}
|
||||
}
|
||||
|
|
@ -1223,7 +1234,7 @@ bool ALeffectslot::eax_get(const EaxCall& call)
|
|||
eax_fx_slot_get(call);
|
||||
break;
|
||||
case EaxCallPropertySetId::fx_slot_effect:
|
||||
eax_effect_->get(call);
|
||||
mEaxEffect->get(call);
|
||||
break;
|
||||
default:
|
||||
eax_fail_unknown_property_id();
|
||||
|
|
@ -1236,19 +1247,19 @@ void ALeffectslot::eax_fx_slot_load_effect(int version, ALenum altype)
|
|||
{
|
||||
if(!IsValidEffectType(altype))
|
||||
altype = AL_EFFECT_NULL;
|
||||
eax_effect_->set_defaults(version, altype);
|
||||
mEaxEffect->set_defaults(version, altype);
|
||||
}
|
||||
|
||||
void ALeffectslot::eax_fx_slot_set_volume()
|
||||
{
|
||||
const auto volume = std::clamp(eax_.lVolume, EAXFXSLOT_MINVOLUME, EAXFXSLOT_MAXVOLUME);
|
||||
const auto volume = std::clamp(mEax.lVolume, EAXFXSLOT_MINVOLUME, EAXFXSLOT_MAXVOLUME);
|
||||
const auto gain = level_mb_to_gain(static_cast<float>(volume));
|
||||
eax_set_efx_slot_gain(gain);
|
||||
}
|
||||
|
||||
void ALeffectslot::eax_fx_slot_set_environment_flag()
|
||||
{
|
||||
eax_set_efx_slot_send_auto((eax_.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0u);
|
||||
eax_set_efx_slot_send_auto((mEax.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0u);
|
||||
}
|
||||
|
||||
void ALeffectslot::eax_fx_slot_set_flags()
|
||||
|
|
@ -1261,11 +1272,11 @@ void ALeffectslot::eax4_fx_slot_set_all(const EaxCall& call)
|
|||
eax4_fx_slot_ensure_unlocked();
|
||||
const auto& src = call.get_value<Exception, const EAX40FXSLOTPROPERTIES>();
|
||||
Eax4AllValidator{}(src);
|
||||
auto& dst = eax4_.i;
|
||||
eax_df_ |= eax_load_effect_dirty_bit; // Always reset the effect.
|
||||
eax_df_ |= (dst.lVolume != src.lVolume ? eax_volume_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.lLock != src.lLock ? eax_lock_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.ulFlags != src.ulFlags ? eax_flags_dirty_bit : EaxDirtyFlags{});
|
||||
auto& dst = mEax4.i;
|
||||
mEaxDf.set(eax_load_effect_dirty_bit); // Always reset the effect.
|
||||
if(dst.lVolume != src.lVolume) mEaxDf.set(eax_volume_dirty_bit);
|
||||
if(dst.lLock != src.lLock) mEaxDf.set(eax_lock_dirty_bit);
|
||||
if(dst.ulFlags != src.ulFlags) mEaxDf.set(eax_flags_dirty_bit);
|
||||
dst = src;
|
||||
}
|
||||
|
||||
|
|
@ -1273,30 +1284,30 @@ void ALeffectslot::eax5_fx_slot_set_all(const EaxCall& call)
|
|||
{
|
||||
const auto& src = call.get_value<Exception, const EAX50FXSLOTPROPERTIES>();
|
||||
Eax5AllValidator{}(src);
|
||||
auto& dst = eax5_.i;
|
||||
eax_df_ |= eax_load_effect_dirty_bit; // Always reset the effect.
|
||||
eax_df_ |= (dst.lVolume != src.lVolume ? eax_volume_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.lLock != src.lLock ? eax_lock_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.ulFlags != src.ulFlags ? eax_flags_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.lOcclusion != src.lOcclusion ? eax_flags_dirty_bit : EaxDirtyFlags{});
|
||||
eax_df_ |= (dst.flOcclusionLFRatio != src.flOcclusionLFRatio ? eax_flags_dirty_bit : EaxDirtyFlags{});
|
||||
auto& dst = mEax5.i;
|
||||
mEaxDf.set(eax_load_effect_dirty_bit); // Always reset the effect.
|
||||
if(dst.lVolume != src.lVolume) mEaxDf.set(eax_volume_dirty_bit);
|
||||
if(dst.lLock != src.lLock) mEaxDf.set(eax_lock_dirty_bit);
|
||||
if(dst.ulFlags != src.ulFlags) mEaxDf.set(eax_flags_dirty_bit);
|
||||
if(dst.lOcclusion != src.lOcclusion) mEaxDf.set(eax_flags_dirty_bit);
|
||||
if(dst.flOcclusionLFRatio != src.flOcclusionLFRatio) mEaxDf.set(eax_flags_dirty_bit);
|
||||
dst = src;
|
||||
}
|
||||
|
||||
bool ALeffectslot::eax_fx_slot_should_update_sources() const noexcept
|
||||
{
|
||||
static constexpr auto dirty_bits =
|
||||
eax_occlusion_dirty_bit |
|
||||
eax_occlusion_lf_ratio_dirty_bit |
|
||||
eax_flags_dirty_bit;
|
||||
|
||||
return (eax_df_ & dirty_bits) != EaxDirtyFlags{};
|
||||
static constexpr auto dirty_bits = std::bitset<eax_dirty_bit_count>{
|
||||
(1u << eax_occlusion_dirty_bit)
|
||||
| (1u << eax_occlusion_lf_ratio_dirty_bit)
|
||||
| (1u << eax_flags_dirty_bit)
|
||||
};
|
||||
return (mEaxDf & dirty_bits).any();
|
||||
}
|
||||
|
||||
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||
bool ALeffectslot::eax4_fx_slot_set(const EaxCall& call)
|
||||
{
|
||||
auto& dst = eax4_.i;
|
||||
auto& dst = mEax4.i;
|
||||
|
||||
switch(call.get_property_id())
|
||||
{
|
||||
|
|
@ -1304,24 +1315,25 @@ bool ALeffectslot::eax4_fx_slot_set(const EaxCall& call)
|
|||
break;
|
||||
case EAXFXSLOT_ALLPARAMETERS:
|
||||
eax4_fx_slot_set_all(call);
|
||||
if((eax_df_ & eax_load_effect_dirty_bit))
|
||||
if(mEaxDf.test(eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_load_effect(4, eax_get_efx_effect_type(dst.guidLoadEffect));
|
||||
break;
|
||||
case EAXFXSLOT_LOADEFFECT:
|
||||
eax4_fx_slot_ensure_unlocked();
|
||||
eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call, dst.guidLoadEffect, eax_df_);
|
||||
if((eax_df_ & eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call,
|
||||
dst.guidLoadEffect, mEaxDf);
|
||||
if(mEaxDf.test(eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_load_effect(4, eax_get_efx_effect_type(dst.guidLoadEffect));
|
||||
break;
|
||||
case EAXFXSLOT_VOLUME:
|
||||
eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, eax_df_);
|
||||
eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_LOCK:
|
||||
eax4_fx_slot_ensure_unlocked();
|
||||
eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, eax_df_);
|
||||
eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_FLAGS:
|
||||
eax_fx_slot_set<Eax4FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, eax_df_);
|
||||
eax_fx_slot_set<Eax4FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, mEaxDf);
|
||||
break;
|
||||
default:
|
||||
eax_fail_unknown_property_id();
|
||||
|
|
@ -1333,7 +1345,7 @@ bool ALeffectslot::eax4_fx_slot_set(const EaxCall& call)
|
|||
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||
bool ALeffectslot::eax5_fx_slot_set(const EaxCall& call)
|
||||
{
|
||||
auto& dst = eax5_.i;
|
||||
auto& dst = mEax5.i;
|
||||
|
||||
switch(call.get_property_id())
|
||||
{
|
||||
|
|
@ -1341,28 +1353,31 @@ bool ALeffectslot::eax5_fx_slot_set(const EaxCall& call)
|
|||
break;
|
||||
case EAXFXSLOT_ALLPARAMETERS:
|
||||
eax5_fx_slot_set_all(call);
|
||||
if((eax_df_ & eax_load_effect_dirty_bit))
|
||||
if(mEaxDf.test(eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_load_effect(5, eax_get_efx_effect_type(dst.guidLoadEffect));
|
||||
break;
|
||||
case EAXFXSLOT_LOADEFFECT:
|
||||
eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call, dst.guidLoadEffect, eax_df_);
|
||||
if((eax_df_ & eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_set_dirty<Eax4GuidLoadEffectValidator, eax_load_effect_dirty_bit>(call,
|
||||
dst.guidLoadEffect, mEaxDf);
|
||||
if(mEaxDf.test(eax_load_effect_dirty_bit))
|
||||
eax_fx_slot_load_effect(5, eax_get_efx_effect_type(dst.guidLoadEffect));
|
||||
break;
|
||||
case EAXFXSLOT_VOLUME:
|
||||
eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, eax_df_);
|
||||
eax_fx_slot_set<Eax4VolumeValidator, eax_volume_dirty_bit>(call, dst.lVolume, mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_LOCK:
|
||||
eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, eax_df_);
|
||||
eax_fx_slot_set<Eax4LockValidator, eax_lock_dirty_bit>(call, dst.lLock, mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_FLAGS:
|
||||
eax_fx_slot_set<Eax5FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, eax_df_);
|
||||
eax_fx_slot_set<Eax5FlagsValidator, eax_flags_dirty_bit>(call, dst.ulFlags, mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_OCCLUSION:
|
||||
eax_fx_slot_set<Eax5OcclusionValidator, eax_occlusion_dirty_bit>(call, dst.lOcclusion, eax_df_);
|
||||
eax_fx_slot_set<Eax5OcclusionValidator, eax_occlusion_dirty_bit>(call, dst.lOcclusion,
|
||||
mEaxDf);
|
||||
break;
|
||||
case EAXFXSLOT_OCCLUSIONLFRATIO:
|
||||
eax_fx_slot_set<Eax5OcclusionLfRatioValidator, eax_occlusion_lf_ratio_dirty_bit>(call, dst.flOcclusionLFRatio, eax_df_);
|
||||
eax_fx_slot_set<Eax5OcclusionLfRatioValidator, eax_occlusion_lf_ratio_dirty_bit>(call,
|
||||
dst.flOcclusionLFRatio, mEaxDf);
|
||||
break;
|
||||
default:
|
||||
eax_fail_unknown_property_id();
|
||||
|
|
@ -1374,7 +1389,7 @@ bool ALeffectslot::eax5_fx_slot_set(const EaxCall& call)
|
|||
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||
bool ALeffectslot::eax_fx_slot_set(const EaxCall& call)
|
||||
{
|
||||
switch (call.get_version())
|
||||
switch(call.get_version())
|
||||
{
|
||||
case 4: return eax4_fx_slot_set(call);
|
||||
case 5: return eax5_fx_slot_set(call);
|
||||
|
|
@ -1390,39 +1405,41 @@ bool ALeffectslot::eax_set(const EaxCall& call)
|
|||
switch(call.get_property_set_id())
|
||||
{
|
||||
case EaxCallPropertySetId::fx_slot: ret = eax_fx_slot_set(call); break;
|
||||
case EaxCallPropertySetId::fx_slot_effect: eax_effect_->set(call); break;
|
||||
case EaxCallPropertySetId::fx_slot_effect: mEaxEffect->set(call); break;
|
||||
default: eax_fail_unknown_property_id();
|
||||
}
|
||||
|
||||
const auto version = call.get_version();
|
||||
if(eax_version_ != version)
|
||||
eax_df_ = ~EaxDirtyFlags{};
|
||||
eax_version_ = version;
|
||||
if(mEaxVersion != version)
|
||||
mEaxDf.set();
|
||||
mEaxVersion = version;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ALeffectslot::eax4_fx_slot_commit(EaxDirtyFlags& dst_df)
|
||||
void ALeffectslot::eax4_fx_slot_commit(std::bitset<eax_dirty_bit_count>& dst_df)
|
||||
{
|
||||
eax_fx_slot_commit_property<eax_load_effect_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::guidLoadEffect);
|
||||
eax_fx_slot_commit_property<eax_volume_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::lVolume);
|
||||
eax_fx_slot_commit_property<eax_lock_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::lLock);
|
||||
eax_fx_slot_commit_property<eax_flags_dirty_bit>(eax4_, dst_df, &EAX40FXSLOTPROPERTIES::ulFlags);
|
||||
eax_fx_slot_commit_property<eax_load_effect_dirty_bit>(mEax4, dst_df, &EAX40FXSLOTPROPERTIES::guidLoadEffect);
|
||||
eax_fx_slot_commit_property<eax_volume_dirty_bit>(mEax4, dst_df, &EAX40FXSLOTPROPERTIES::lVolume);
|
||||
eax_fx_slot_commit_property<eax_lock_dirty_bit>(mEax4, dst_df, &EAX40FXSLOTPROPERTIES::lLock);
|
||||
eax_fx_slot_commit_property<eax_flags_dirty_bit>(mEax4, dst_df, &EAX40FXSLOTPROPERTIES::ulFlags);
|
||||
|
||||
auto& dst_i = eax_;
|
||||
auto& dst_i = mEax;
|
||||
|
||||
if(dst_i.lOcclusion != EAXFXSLOT_DEFAULTOCCLUSION) {
|
||||
dst_df |= eax_occlusion_dirty_bit;
|
||||
if(dst_i.lOcclusion != EAXFXSLOT_DEFAULTOCCLUSION)
|
||||
{
|
||||
dst_df.set(eax_occlusion_dirty_bit);
|
||||
dst_i.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
|
||||
}
|
||||
|
||||
if(dst_i.flOcclusionLFRatio != EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO) {
|
||||
dst_df |= eax_occlusion_lf_ratio_dirty_bit;
|
||||
if(dst_i.flOcclusionLFRatio != EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO)
|
||||
{
|
||||
dst_df.set(eax_occlusion_lf_ratio_dirty_bit);
|
||||
dst_i.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
|
||||
}
|
||||
}
|
||||
|
||||
void ALeffectslot::eax5_fx_slot_commit(Eax5State& state, EaxDirtyFlags& dst_df)
|
||||
void ALeffectslot::eax5_fx_slot_commit(Eax5State& state, std::bitset<eax_dirty_bit_count>& dst_df)
|
||||
{
|
||||
eax_fx_slot_commit_property<eax_load_effect_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::guidLoadEffect);
|
||||
eax_fx_slot_commit_property<eax_volume_dirty_bit>(state, dst_df, &EAX50FXSLOTPROPERTIES::lVolume);
|
||||
|
|
@ -1437,18 +1454,19 @@ void ALeffectslot::eax_set_efx_slot_effect(EaxEffect &effect)
|
|||
#define EAX_PREFIX "[EAX_SET_EFFECT_SLOT_EFFECT] "
|
||||
|
||||
const auto error = initEffect(0, effect.al_effect_type_, effect.al_effect_props_,
|
||||
eax_al_context_);
|
||||
|
||||
if(error != AL_NO_ERROR) {
|
||||
ERR(EAX_PREFIX "%s\n", "Failed to initialize an effect.");
|
||||
mEaxALContext);
|
||||
if(error != AL_NO_ERROR)
|
||||
{
|
||||
ERR(EAX_PREFIX "Failed to initialize an effect.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(mState == SlotState::Initial) {
|
||||
if(mState == SlotState::Initial)
|
||||
{
|
||||
mPropsDirty = false;
|
||||
updateProps(eax_al_context_);
|
||||
updateProps(mEaxALContext);
|
||||
auto effect_slot_ptr = this;
|
||||
AddActiveEffectSlots({&effect_slot_ptr, 1}, eax_al_context_);
|
||||
AddActiveEffectSlots({&effect_slot_ptr, 1}, mEaxALContext);
|
||||
mState = SlotState::Playing;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1474,7 +1492,7 @@ void ALeffectslot::eax_set_efx_slot_gain(ALfloat gain)
|
|||
if(gain == Gain)
|
||||
return;
|
||||
if(gain < 0.0f || gain > 1.0f)
|
||||
ERR(EAX_PREFIX "Gain out of range (%f)\n", gain);
|
||||
ERR(EAX_PREFIX "Slot gain out of range ({:f})", gain);
|
||||
|
||||
Gain = std::clamp(gain, 0.0f, 1.0f);
|
||||
mPropsDirty = true;
|
||||
|
|
@ -1484,7 +1502,7 @@ void ALeffectslot::eax_set_efx_slot_gain(ALfloat gain)
|
|||
|
||||
void ALeffectslot::EaxDeleter::operator()(ALeffectslot* effect_slot)
|
||||
{
|
||||
eax_delete_al_effect_slot(*effect_slot->eax_al_context_, *effect_slot);
|
||||
eax_delete_al_effect_slot(*effect_slot->mEaxALContext, *effect_slot);
|
||||
}
|
||||
|
||||
EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context)
|
||||
|
|
@ -1494,13 +1512,15 @@ EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context)
|
|||
std::lock_guard<std::mutex> slotlock{context.mEffectSlotLock};
|
||||
auto& device = *context.mALDevice;
|
||||
|
||||
if(context.mNumEffectSlots == device.AuxiliaryEffectSlotMax) {
|
||||
ERR(EAX_PREFIX "%s\n", "Out of memory.");
|
||||
if(context.mNumEffectSlots == device.AuxiliaryEffectSlotMax)
|
||||
{
|
||||
ERR(EAX_PREFIX "Out of memory.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!EnsureEffectSlots(&context, 1)) {
|
||||
ERR(EAX_PREFIX "%s\n", "Failed to ensure.");
|
||||
if(!EnsureEffectSlots(&context, 1))
|
||||
{
|
||||
ERR(EAX_PREFIX "Failed to ensure.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -1517,7 +1537,7 @@ void eax_delete_al_effect_slot(ALCcontext& context, ALeffectslot& effect_slot)
|
|||
|
||||
if(effect_slot.ref.load(std::memory_order_relaxed) != 0)
|
||||
{
|
||||
ERR(EAX_PREFIX "Deleting in-use effect slot %u.\n", effect_slot.id);
|
||||
ERR(EAX_PREFIX "Deleting in-use effect slot {}.", effect_slot.id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
#ifndef AL_AUXEFFECTSLOT_H
|
||||
#define AL_AUXEFFECTSLOT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
|
@ -16,7 +19,7 @@
|
|||
#include "core/effectslot.h"
|
||||
#include "intrusive_ptr.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <memory>
|
||||
#include "eax/api.h"
|
||||
#include "eax/call.h"
|
||||
|
|
@ -28,7 +31,7 @@
|
|||
|
||||
struct ALbuffer;
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
class EaxFxSlotException : public EaxException {
|
||||
public:
|
||||
explicit EaxFxSlotException(const char* message)
|
||||
|
|
@ -50,7 +53,7 @@ struct ALeffectslot {
|
|||
|
||||
struct EffectData {
|
||||
EffectSlotType Type{EffectSlotType::None};
|
||||
EffectProps Props{};
|
||||
EffectProps Props;
|
||||
|
||||
al::intrusive_ptr<EffectState> State;
|
||||
};
|
||||
|
|
@ -67,7 +70,7 @@ struct ALeffectslot {
|
|||
/* Self ID */
|
||||
ALuint id{};
|
||||
|
||||
ALeffectslot(ALCcontext *context);
|
||||
explicit ALeffectslot(ALCcontext *context);
|
||||
ALeffectslot(const ALeffectslot&) = delete;
|
||||
ALeffectslot& operator=(const ALeffectslot&) = delete;
|
||||
~ALeffectslot();
|
||||
|
|
@ -79,13 +82,14 @@ struct ALeffectslot {
|
|||
static void SetName(ALCcontext *context, ALuint id, std::string_view name);
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
public:
|
||||
void eax_initialize(ALCcontext& al_context, EaxFxSlotIndexValue index);
|
||||
|
||||
[[nodiscard]] auto eax_get_index() const noexcept -> EaxFxSlotIndexValue { return eax_fx_slot_index_; }
|
||||
[[nodiscard]] auto eax_get_eax_fx_slot() const noexcept -> const EAX50FXSLOTPROPERTIES&
|
||||
{ return eax_; }
|
||||
[[nodiscard]]
|
||||
auto eax_get_index() const noexcept -> EaxFxSlotIndexValue { return mEaxFXSlotIndex; }
|
||||
[[nodiscard]]
|
||||
auto eax_get_eax_fx_slot() const noexcept -> const EAX50FXSLOTPROPERTIES& { return mEax; }
|
||||
|
||||
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||
[[nodiscard]] auto eax_dispatch(const EaxCall& call) -> bool
|
||||
|
|
@ -94,25 +98,24 @@ public:
|
|||
void eax_commit();
|
||||
|
||||
private:
|
||||
static constexpr auto eax_load_effect_dirty_bit = EaxDirtyFlags{1} << 0;
|
||||
static constexpr auto eax_volume_dirty_bit = EaxDirtyFlags{1} << 1;
|
||||
static constexpr auto eax_lock_dirty_bit = EaxDirtyFlags{1} << 2;
|
||||
static constexpr auto eax_flags_dirty_bit = EaxDirtyFlags{1} << 3;
|
||||
static constexpr auto eax_occlusion_dirty_bit = EaxDirtyFlags{1} << 4;
|
||||
static constexpr auto eax_occlusion_lf_ratio_dirty_bit = EaxDirtyFlags{1} << 5;
|
||||
enum {
|
||||
eax_load_effect_dirty_bit,
|
||||
eax_volume_dirty_bit,
|
||||
eax_lock_dirty_bit,
|
||||
eax_flags_dirty_bit,
|
||||
eax_occlusion_dirty_bit,
|
||||
eax_occlusion_lf_ratio_dirty_bit,
|
||||
eax_dirty_bit_count
|
||||
};
|
||||
|
||||
using Exception = EaxFxSlotException;
|
||||
|
||||
using Eax4Props = EAX40FXSLOTPROPERTIES;
|
||||
|
||||
struct Eax4State {
|
||||
Eax4Props i; // Immediate.
|
||||
EAX40FXSLOTPROPERTIES i; // Immediate.
|
||||
};
|
||||
|
||||
using Eax5Props = EAX50FXSLOTPROPERTIES;
|
||||
|
||||
struct Eax5State {
|
||||
Eax5Props i; // Immediate.
|
||||
EAX50FXSLOTPROPERTIES i; // Immediate.
|
||||
};
|
||||
|
||||
struct EaxRangeValidator {
|
||||
|
|
@ -237,15 +240,15 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
ALCcontext* eax_al_context_{};
|
||||
EaxFxSlotIndexValue eax_fx_slot_index_{};
|
||||
int eax_version_{}; // Current EAX version.
|
||||
EaxDirtyFlags eax_df_{}; // Dirty flags for the current EAX version.
|
||||
EaxEffectUPtr eax_effect_{};
|
||||
Eax5State eax123_{}; // EAX1/EAX2/EAX3 state.
|
||||
Eax4State eax4_{}; // EAX4 state.
|
||||
Eax5State eax5_{}; // EAX5 state.
|
||||
Eax5Props eax_{}; // Current EAX state.
|
||||
ALCcontext* mEaxALContext{};
|
||||
EaxFxSlotIndexValue mEaxFXSlotIndex{};
|
||||
int mEaxVersion{}; // Current EAX version.
|
||||
std::bitset<eax_dirty_bit_count> mEaxDf; // Dirty flags for the current EAX version.
|
||||
EaxEffectUPtr mEaxEffect;
|
||||
Eax5State mEax123{}; // EAX1/EAX2/EAX3 state.
|
||||
Eax4State mEax4{}; // EAX4 state.
|
||||
Eax5State mEax5{}; // EAX5 state.
|
||||
EAX50FXSLOTPROPERTIES mEax{}; // Current EAX state.
|
||||
|
||||
[[noreturn]] static void eax_fail(const char* message);
|
||||
[[noreturn]] static void eax_fail_unknown_effect_id();
|
||||
|
|
@ -256,12 +259,14 @@ private:
|
|||
// validates it,
|
||||
// sets a dirty flag only if the new value differs form the old one,
|
||||
// and assigns the new value.
|
||||
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
|
||||
static void eax_fx_slot_set(const EaxCall& call, TProperties& dst, EaxDirtyFlags& dirty_flags)
|
||||
template<typename TValidator, size_t DirtyBit, typename TProperties>
|
||||
static void eax_fx_slot_set(const EaxCall& call, TProperties& dst,
|
||||
std::bitset<eax_dirty_bit_count>& dirty_flags)
|
||||
{
|
||||
const auto& src = call.get_value<Exception, const TProperties>();
|
||||
TValidator{}(src);
|
||||
dirty_flags |= (dst != src ? TDirtyBit : EaxDirtyFlags{});
|
||||
if(dst != src)
|
||||
dirty_flags.set(DirtyBit);
|
||||
dst = src;
|
||||
}
|
||||
|
||||
|
|
@ -269,18 +274,18 @@ private:
|
|||
// validates it,
|
||||
// sets a dirty flag without comparing the values,
|
||||
// and assigns the new value.
|
||||
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
|
||||
template<typename TValidator, size_t DirtyBit, typename TProperties>
|
||||
static void eax_fx_slot_set_dirty(const EaxCall& call, TProperties& dst,
|
||||
EaxDirtyFlags& dirty_flags)
|
||||
std::bitset<eax_dirty_bit_count>& dirty_flags)
|
||||
{
|
||||
const auto& src = call.get_value<Exception, const TProperties>();
|
||||
TValidator{}(src);
|
||||
dirty_flags |= TDirtyBit;
|
||||
dirty_flags.set(DirtyBit);
|
||||
dst = src;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto eax4_fx_slot_is_legacy() const noexcept -> bool
|
||||
{ return eax_fx_slot_index_ < 2; }
|
||||
{ return mEaxFXSlotIndex < 2; }
|
||||
|
||||
void eax4_fx_slot_ensure_unlocked() const;
|
||||
|
||||
|
|
@ -288,15 +293,15 @@ private:
|
|||
[[nodiscard]] auto eax_get_eax_default_effect_guid() const noexcept -> const GUID&;
|
||||
[[nodiscard]] auto eax_get_eax_default_lock() const noexcept -> long;
|
||||
|
||||
void eax4_fx_slot_set_defaults(Eax4Props& props) noexcept;
|
||||
void eax5_fx_slot_set_defaults(Eax5Props& props) noexcept;
|
||||
void eax4_fx_slot_set_current_defaults(const Eax4Props& props) noexcept;
|
||||
void eax5_fx_slot_set_current_defaults(const Eax5Props& props) noexcept;
|
||||
void eax4_fx_slot_set_defaults(EAX40FXSLOTPROPERTIES& props) noexcept;
|
||||
void eax5_fx_slot_set_defaults(EAX50FXSLOTPROPERTIES& props) noexcept;
|
||||
void eax4_fx_slot_set_current_defaults(const EAX40FXSLOTPROPERTIES& props) noexcept;
|
||||
void eax5_fx_slot_set_current_defaults(const EAX50FXSLOTPROPERTIES& props) noexcept;
|
||||
void eax_fx_slot_set_current_defaults();
|
||||
void eax_fx_slot_set_defaults();
|
||||
|
||||
static void eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props);
|
||||
static void eax5_fx_slot_get(const EaxCall& call, const Eax5Props& props);
|
||||
static void eax4_fx_slot_get(const EaxCall& call, const EAX40FXSLOTPROPERTIES& props);
|
||||
static void eax5_fx_slot_get(const EaxCall& call, const EAX50FXSLOTPROPERTIES& props);
|
||||
void eax_fx_slot_get(const EaxCall& call) const;
|
||||
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||
bool eax_get(const EaxCall& call);
|
||||
|
|
@ -321,25 +326,25 @@ private:
|
|||
bool eax_set(const EaxCall& call);
|
||||
|
||||
template<
|
||||
EaxDirtyFlags TDirtyBit,
|
||||
size_t DirtyBit,
|
||||
typename TMemberResult,
|
||||
typename TProps,
|
||||
typename TState>
|
||||
void eax_fx_slot_commit_property(TState& state, EaxDirtyFlags& dst_df,
|
||||
void eax_fx_slot_commit_property(TState& state, std::bitset<eax_dirty_bit_count>& dst_df,
|
||||
TMemberResult TProps::*member) noexcept
|
||||
{
|
||||
auto& src_i = state.i;
|
||||
auto& dst_i = eax_;
|
||||
auto& dst_i = mEax;
|
||||
|
||||
if((eax_df_ & TDirtyBit) != EaxDirtyFlags{})
|
||||
if(mEaxDf.test(DirtyBit))
|
||||
{
|
||||
dst_df |= TDirtyBit;
|
||||
dst_df.set(DirtyBit);
|
||||
dst_i.*member = src_i.*member;
|
||||
}
|
||||
}
|
||||
|
||||
void eax4_fx_slot_commit(EaxDirtyFlags& dst_df);
|
||||
void eax5_fx_slot_commit(Eax5State& state, EaxDirtyFlags& dst_df);
|
||||
void eax4_fx_slot_commit(std::bitset<eax_dirty_bit_count>& dst_df);
|
||||
void eax5_fx_slot_commit(Eax5State& state, std::bitset<eax_dirty_bit_count>& dst_df);
|
||||
|
||||
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_EFFECT, effect)`
|
||||
void eax_set_efx_slot_effect(EaxEffect &effect);
|
||||
|
|
@ -360,7 +365,7 @@ public:
|
|||
|
||||
void UpdateAllEffectSlotProps(ALCcontext *context);
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
using EaxAlEffectSlotUPtr = std::unique_ptr<ALeffectslot, ALeffectslot::EaxDeleter>;
|
||||
|
||||
EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef AL_BUFFER_H
|
||||
#define AL_BUFFER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
|
@ -17,7 +19,7 @@
|
|||
#include "core/buffer_storage.h"
|
||||
#include "vector.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
enum class EaxStorage : uint8_t {
|
||||
Automatic,
|
||||
Accessible,
|
||||
|
|
@ -54,7 +56,7 @@ struct ALbuffer : public BufferStorage {
|
|||
|
||||
DISABLE_ALLOC
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
EaxStorage eax_x_ram_mode{EaxStorage::Automatic};
|
||||
bool eax_x_ram_is_hardware{};
|
||||
#endif // ALSOFT_EAX
|
||||
|
|
|
|||
|
|
@ -21,18 +21,17 @@
|
|||
|
||||
#include "alc/context.h"
|
||||
#include "alc/device.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "alstring.h"
|
||||
#include "auxeffectslot.h"
|
||||
#include "buffer.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/voice.h"
|
||||
#include "direct_defs.h"
|
||||
#include "effect.h"
|
||||
#include "error.h"
|
||||
#include "filter.h"
|
||||
#include "fmt/core.h"
|
||||
#include "intrusive_ptr.h"
|
||||
#include "opthelpers.h"
|
||||
#include "source.h"
|
||||
|
|
@ -45,6 +44,8 @@ DebugGroup::~DebugGroup() = default;
|
|||
|
||||
namespace {
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static_assert(DebugSeverityBase+DebugSeverityCount <= 32, "Too many debug bits");
|
||||
|
||||
template<typename T, T ...Vals>
|
||||
|
|
@ -109,7 +110,8 @@ constexpr auto GetDebugSourceEnum(DebugSource source) -> ALenum
|
|||
case DebugSource::Application: return AL_DEBUG_SOURCE_APPLICATION_EXT;
|
||||
case DebugSource::Other: return AL_DEBUG_SOURCE_OTHER_EXT;
|
||||
}
|
||||
throw std::runtime_error{"Unexpected debug source value "+std::to_string(al::to_underlying(source))};
|
||||
throw std::runtime_error{fmt::format("Unexpected debug source value: {}",
|
||||
int{al::to_underlying(source)})};
|
||||
}
|
||||
|
||||
constexpr auto GetDebugTypeEnum(DebugType type) -> ALenum
|
||||
|
|
@ -126,7 +128,8 @@ constexpr auto GetDebugTypeEnum(DebugType type) -> ALenum
|
|||
case DebugType::PopGroup: return AL_DEBUG_TYPE_POP_GROUP_EXT;
|
||||
case DebugType::Other: return AL_DEBUG_TYPE_OTHER_EXT;
|
||||
}
|
||||
throw std::runtime_error{"Unexpected debug type value "+std::to_string(al::to_underlying(type))};
|
||||
throw std::runtime_error{fmt::format("Unexpected debug type value: {}",
|
||||
int{al::to_underlying(type)})};
|
||||
}
|
||||
|
||||
constexpr auto GetDebugSeverityEnum(DebugSeverity severity) -> ALenum
|
||||
|
|
@ -138,50 +141,51 @@ constexpr auto GetDebugSeverityEnum(DebugSeverity severity) -> ALenum
|
|||
case DebugSeverity::Low: return AL_DEBUG_SEVERITY_LOW_EXT;
|
||||
case DebugSeverity::Notification: return AL_DEBUG_SEVERITY_NOTIFICATION_EXT;
|
||||
}
|
||||
throw std::runtime_error{"Unexpected debug severity value "+std::to_string(al::to_underlying(severity))};
|
||||
throw std::runtime_error{fmt::format("Unexpected debug severity value: {}",
|
||||
int{al::to_underlying(severity)})};
|
||||
}
|
||||
|
||||
|
||||
constexpr auto GetDebugSourceName(DebugSource source) noexcept -> const char*
|
||||
constexpr auto GetDebugSourceName(DebugSource source) noexcept -> std::string_view
|
||||
{
|
||||
switch(source)
|
||||
{
|
||||
case DebugSource::API: return "API";
|
||||
case DebugSource::System: return "Audio System";
|
||||
case DebugSource::ThirdParty: return "Third Party";
|
||||
case DebugSource::Application: return "Application";
|
||||
case DebugSource::Other: return "Other";
|
||||
case DebugSource::API: return "API"sv;
|
||||
case DebugSource::System: return "Audio System"sv;
|
||||
case DebugSource::ThirdParty: return "Third Party"sv;
|
||||
case DebugSource::Application: return "Application"sv;
|
||||
case DebugSource::Other: return "Other"sv;
|
||||
}
|
||||
return "<invalid source>";
|
||||
return "<invalid source>"sv;
|
||||
}
|
||||
|
||||
constexpr auto GetDebugTypeName(DebugType type) noexcept -> const char*
|
||||
constexpr auto GetDebugTypeName(DebugType type) noexcept -> std::string_view
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DebugType::Error: return "Error";
|
||||
case DebugType::DeprecatedBehavior: return "Deprecated Behavior";
|
||||
case DebugType::UndefinedBehavior: return "Undefined Behavior";
|
||||
case DebugType::Portability: return "Portability";
|
||||
case DebugType::Performance: return "Performance";
|
||||
case DebugType::Marker: return "Marker";
|
||||
case DebugType::PushGroup: return "Push Group";
|
||||
case DebugType::PopGroup: return "Pop Group";
|
||||
case DebugType::Other: return "Other";
|
||||
case DebugType::Error: return "Error"sv;
|
||||
case DebugType::DeprecatedBehavior: return "Deprecated Behavior"sv;
|
||||
case DebugType::UndefinedBehavior: return "Undefined Behavior"sv;
|
||||
case DebugType::Portability: return "Portability"sv;
|
||||
case DebugType::Performance: return "Performance"sv;
|
||||
case DebugType::Marker: return "Marker"sv;
|
||||
case DebugType::PushGroup: return "Push Group"sv;
|
||||
case DebugType::PopGroup: return "Pop Group"sv;
|
||||
case DebugType::Other: return "Other"sv;
|
||||
}
|
||||
return "<invalid type>";
|
||||
return "<invalid type>"sv;
|
||||
}
|
||||
|
||||
constexpr auto GetDebugSeverityName(DebugSeverity severity) noexcept -> const char*
|
||||
constexpr auto GetDebugSeverityName(DebugSeverity severity) noexcept -> std::string_view
|
||||
{
|
||||
switch(severity)
|
||||
{
|
||||
case DebugSeverity::High: return "High";
|
||||
case DebugSeverity::Medium: return "Medium";
|
||||
case DebugSeverity::Low: return "Low";
|
||||
case DebugSeverity::Notification: return "Notification";
|
||||
case DebugSeverity::High: return "High"sv;
|
||||
case DebugSeverity::Medium: return "Medium"sv;
|
||||
case DebugSeverity::Low: return "Low"sv;
|
||||
case DebugSeverity::Notification: return "Notification"sv;
|
||||
}
|
||||
return "<invalid severity>";
|
||||
return "<invalid severity>"sv;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -195,8 +199,8 @@ void ALCcontext::sendDebugMessage(std::unique_lock<std::mutex> &debuglock, Debug
|
|||
|
||||
if(message.length() >= MaxDebugMessageLength) UNLIKELY
|
||||
{
|
||||
ERR("Debug message too long (%zu >= %d):\n-> %.*s\n", message.length(),
|
||||
MaxDebugMessageLength, al::sizei(message), message.data());
|
||||
ERR("Debug message too long ({} >= {}):\n-> {}", message.length(),
|
||||
MaxDebugMessageLength, message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -231,13 +235,13 @@ void ALCcontext::sendDebugMessage(std::unique_lock<std::mutex> &debuglock, Debug
|
|||
mDebugLog.emplace_back(source, type, id, severity, message);
|
||||
else UNLIKELY
|
||||
ERR("Debug message log overflow. Lost message:\n"
|
||||
" Source: %s\n"
|
||||
" Type: %s\n"
|
||||
" ID: %u\n"
|
||||
" Severity: %s\n"
|
||||
" Message: \"%.*s\"\n",
|
||||
" Source: {}\n"
|
||||
" Type: {}\n"
|
||||
" ID: {}\n"
|
||||
" Severity: {}\n"
|
||||
" Message: \"{}\"",
|
||||
GetDebugSourceName(source), GetDebugTypeName(type), id,
|
||||
GetDebugSeverityName(severity), al::sizei(message), message.data());
|
||||
GetDebugSeverityName(severity), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,32 +264,36 @@ try {
|
|||
return;
|
||||
|
||||
if(!message)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Null message pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Null message pointer");
|
||||
|
||||
auto msgview = (length < 0) ? std::string_view{message}
|
||||
: std::string_view{message, static_cast<uint>(length)};
|
||||
if(msgview.size() >= MaxDebugMessageLength)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Debug message too long (%zu >= %d)",
|
||||
msgview.size(), MaxDebugMessageLength};
|
||||
context->throw_error(AL_INVALID_VALUE, "Debug message too long ({} >= {})", msgview.size(),
|
||||
MaxDebugMessageLength);
|
||||
|
||||
auto dsource = GetDebugSource(source);
|
||||
if(!dsource)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug source 0x%04x", source};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug source {:#04x}", as_unsigned(source));
|
||||
if(*dsource != DebugSource::ThirdParty && *dsource != DebugSource::Application)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Debug source 0x%04x not allowed", source};
|
||||
context->throw_error(AL_INVALID_ENUM, "Debug source {:#04x} not allowed",
|
||||
as_unsigned(source));
|
||||
|
||||
auto dtype = GetDebugType(type);
|
||||
if(!dtype)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug type 0x%04x", type};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug type {:#04x}", as_unsigned(type));
|
||||
|
||||
auto dseverity = GetDebugSeverity(severity);
|
||||
if(!dseverity)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug severity 0x%04x", severity};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug severity {:#04x}",
|
||||
as_unsigned(severity));
|
||||
|
||||
context->debugMessage(*dsource, *dtype, id, *dseverity, msgview);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -296,20 +304,20 @@ try {
|
|||
if(count > 0)
|
||||
{
|
||||
if(!ids)
|
||||
throw al::context_error{AL_INVALID_VALUE, "IDs is null with non-0 count"};
|
||||
context->throw_error(AL_INVALID_VALUE, "IDs is null with non-0 count");
|
||||
if(source == AL_DONT_CARE_EXT)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Debug source cannot be AL_DONT_CARE_EXT with IDs"};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Debug source cannot be AL_DONT_CARE_EXT with IDs");
|
||||
if(type == AL_DONT_CARE_EXT)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Debug type cannot be AL_DONT_CARE_EXT with IDs"};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Debug type cannot be AL_DONT_CARE_EXT with IDs");
|
||||
if(severity != AL_DONT_CARE_EXT)
|
||||
throw al::context_error{AL_INVALID_OPERATION,
|
||||
"Debug severity must be AL_DONT_CARE_EXT with IDs"};
|
||||
context->throw_error(AL_INVALID_OPERATION,
|
||||
"Debug severity must be AL_DONT_CARE_EXT with IDs");
|
||||
}
|
||||
|
||||
if(enable != AL_TRUE && enable != AL_FALSE)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug enable %d", enable};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug enable {}", enable);
|
||||
|
||||
static constexpr size_t ElemCount{DebugSourceCount + DebugTypeCount + DebugSeverityCount};
|
||||
static constexpr auto Values = make_array_sequence<uint8_t,ElemCount>();
|
||||
|
|
@ -319,7 +327,8 @@ try {
|
|||
{
|
||||
auto dsource = GetDebugSource(source);
|
||||
if(!dsource)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug source 0x%04x", source};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug source {:#04x}",
|
||||
as_unsigned(source));
|
||||
srcIndices = srcIndices.subspan(al::to_underlying(*dsource), 1);
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +337,7 @@ try {
|
|||
{
|
||||
auto dtype = GetDebugType(type);
|
||||
if(!dtype)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug type 0x%04x", type};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug type {:#04x}", as_unsigned(type));
|
||||
typeIndices = typeIndices.subspan(al::to_underlying(*dtype), 1);
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +346,8 @@ try {
|
|||
{
|
||||
auto dseverity = GetDebugSeverity(severity);
|
||||
if(!dseverity)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug severity 0x%04x", severity};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug severity {:#04x}",
|
||||
as_unsigned(severity));
|
||||
svrIndices = svrIndices.subspan(al::to_underlying(*dseverity), 1);
|
||||
}
|
||||
|
||||
|
|
@ -383,8 +393,10 @@ try {
|
|||
[apply_type](const uint idx){ apply_type(1<<idx); });
|
||||
}
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -396,23 +408,24 @@ try {
|
|||
{
|
||||
size_t newlen{std::strlen(message)};
|
||||
if(newlen >= MaxDebugMessageLength)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Debug message too long (%zu >= %d)", newlen,
|
||||
MaxDebugMessageLength};
|
||||
context->throw_error(AL_INVALID_VALUE, "Debug message too long ({} >= {})", newlen,
|
||||
MaxDebugMessageLength);
|
||||
length = static_cast<ALsizei>(newlen);
|
||||
}
|
||||
else if(length >= MaxDebugMessageLength)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Debug message too long (%d >= %d)", length,
|
||||
MaxDebugMessageLength};
|
||||
context->throw_error(AL_INVALID_VALUE, "Debug message too long ({} >= {})", length,
|
||||
MaxDebugMessageLength);
|
||||
|
||||
auto dsource = GetDebugSource(source);
|
||||
if(!dsource)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid debug source 0x%04x", source};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid debug source {:#04x}", as_unsigned(source));
|
||||
if(*dsource != DebugSource::ThirdParty && *dsource != DebugSource::Application)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Debug source 0x%04x not allowed", source};
|
||||
context->throw_error(AL_INVALID_ENUM, "Debug source {:#04x} not allowed",
|
||||
as_unsigned(source));
|
||||
|
||||
std::unique_lock<std::mutex> debuglock{context->mDebugCbLock};
|
||||
if(context->mDebugGroups.size() >= MaxDebugGroupDepth)
|
||||
throw al::context_error{AL_STACK_OVERFLOW_EXT, "Pushing too many debug groups"};
|
||||
context->throw_error(AL_STACK_OVERFLOW_EXT, "Pushing too many debug groups");
|
||||
|
||||
context->mDebugGroups.emplace_back(*dsource, id,
|
||||
std::string_view{message, static_cast<uint>(length)});
|
||||
|
|
@ -426,8 +439,10 @@ try {
|
|||
context->sendDebugMessage(debuglock, newback.mSource, DebugType::PushGroup, newback.mId,
|
||||
DebugSeverity::Notification, newback.mMessage);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
FORCE_ALIGN DECL_FUNCEXT(void, alPopDebugGroup,EXT)
|
||||
|
|
@ -435,8 +450,7 @@ FORCE_ALIGN void AL_APIENTRY alPopDebugGroupDirectEXT(ALCcontext *context) noexc
|
|||
try {
|
||||
std::unique_lock<std::mutex> debuglock{context->mDebugCbLock};
|
||||
if(context->mDebugGroups.size() <= 1)
|
||||
throw al::context_error{AL_STACK_UNDERFLOW_EXT,
|
||||
"Attempting to pop the default debug group"};
|
||||
context->throw_error(AL_STACK_UNDERFLOW_EXT, "Attempting to pop the default debug group");
|
||||
|
||||
DebugGroup &debug = context->mDebugGroups.back();
|
||||
const auto source = debug.mSource;
|
||||
|
|
@ -448,8 +462,10 @@ try {
|
|||
context->sendDebugMessage(debuglock, source, DebugType::PopGroup, id,
|
||||
DebugSeverity::Notification, message);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -458,66 +474,60 @@ FORCE_ALIGN ALuint AL_APIENTRY alGetDebugMessageLogDirectEXT(ALCcontext *context
|
|||
ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities,
|
||||
ALsizei *lengths, ALchar *logBuf) noexcept
|
||||
try {
|
||||
if(logBufSize < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Negative debug log buffer size"};
|
||||
if(logBuf && logBufSize < 0)
|
||||
context->throw_error(AL_INVALID_VALUE, "Negative debug log buffer size");
|
||||
|
||||
auto sourcesOut = al::span{sources, sources ? count : 0u};
|
||||
auto typesOut = al::span{types, types ? count : 0u};
|
||||
auto idsOut = al::span{ids, ids ? count : 0u};
|
||||
auto severitiesOut = al::span{severities, severities ? count : 0u};
|
||||
auto lengthsOut = al::span{lengths, lengths ? count : 0u};
|
||||
auto logOut = al::span{logBuf, logBuf ? static_cast<ALuint>(logBufSize) : 0u};
|
||||
const auto sourcesSpan = al::span{sources, sources ? count : 0u};
|
||||
const auto typesSpan = al::span{types, types ? count : 0u};
|
||||
const auto idsSpan = al::span{ids, ids ? count : 0u};
|
||||
const auto severitiesSpan = al::span{severities, severities ? count : 0u};
|
||||
const auto lengthsSpan = al::span{lengths, lengths ? count : 0u};
|
||||
const auto logSpan = al::span{logBuf, logBuf ? static_cast<ALuint>(logBufSize) : 0u};
|
||||
|
||||
std::lock_guard<std::mutex> debuglock{context->mDebugCbLock};
|
||||
auto sourceiter = sourcesSpan.begin();
|
||||
auto typeiter = typesSpan.begin();
|
||||
auto iditer = idsSpan.begin();
|
||||
auto severityiter = severitiesSpan.begin();
|
||||
auto lengthiter = lengthsSpan.begin();
|
||||
auto logiter = logSpan.begin();
|
||||
|
||||
auto debuglock = std::lock_guard{context->mDebugCbLock};
|
||||
for(ALuint i{0};i < count;++i)
|
||||
{
|
||||
if(context->mDebugLog.empty())
|
||||
return i;
|
||||
|
||||
auto &entry = context->mDebugLog.front();
|
||||
const size_t tocopy{entry.mMessage.size() + 1};
|
||||
if(logOut.data() != nullptr)
|
||||
const auto tocopy = size_t{entry.mMessage.size() + 1};
|
||||
if(al::to_address(logiter) != nullptr)
|
||||
{
|
||||
if(logOut.size() < tocopy)
|
||||
if(static_cast<size_t>(std::distance(logiter, logSpan.end())) < tocopy)
|
||||
return i;
|
||||
auto oiter = std::copy(entry.mMessage.cbegin(), entry.mMessage.cend(), logOut.begin());
|
||||
*oiter = '\0';
|
||||
logOut = {oiter+1, logOut.end()};
|
||||
logiter = std::copy(entry.mMessage.cbegin(), entry.mMessage.cend(), logiter);
|
||||
*(logiter++) = '\0';
|
||||
}
|
||||
|
||||
if(!sourcesOut.empty())
|
||||
{
|
||||
sourcesOut.front() = GetDebugSourceEnum(entry.mSource);
|
||||
sourcesOut = sourcesOut.subspan<1>();
|
||||
}
|
||||
if(!typesOut.empty())
|
||||
{
|
||||
typesOut.front() = GetDebugTypeEnum(entry.mType);
|
||||
typesOut = typesOut.subspan<1>();
|
||||
}
|
||||
if(!idsOut.empty())
|
||||
{
|
||||
idsOut.front() = entry.mId;
|
||||
idsOut = idsOut.subspan<1>();
|
||||
}
|
||||
if(!severitiesOut.empty())
|
||||
{
|
||||
severitiesOut.front() = GetDebugSeverityEnum(entry.mSeverity);
|
||||
severitiesOut = severitiesOut.subspan<1>();
|
||||
}
|
||||
if(!lengthsOut.empty())
|
||||
{
|
||||
lengthsOut.front() = static_cast<ALsizei>(tocopy);
|
||||
lengthsOut = lengthsOut.subspan<1>();
|
||||
}
|
||||
if(al::to_address(sourceiter) != nullptr)
|
||||
*(sourceiter++) = GetDebugSourceEnum(entry.mSource);
|
||||
if(al::to_address(typeiter) != nullptr)
|
||||
*(typeiter++) = GetDebugTypeEnum(entry.mType);
|
||||
if(al::to_address(iditer) != nullptr)
|
||||
*(iditer++) = entry.mId;
|
||||
if(al::to_address(severityiter) != nullptr)
|
||||
*(severityiter++) = GetDebugSeverityEnum(entry.mSeverity);
|
||||
if(al::to_address(lengthiter) != nullptr)
|
||||
*(lengthiter++) = static_cast<ALsizei>(tocopy);
|
||||
|
||||
context->mDebugLog.pop_front();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
return 0;
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -526,13 +536,13 @@ FORCE_ALIGN void AL_APIENTRY alObjectLabelDirectEXT(ALCcontext *context, ALenum
|
|||
ALuint name, ALsizei length, const ALchar *label) noexcept
|
||||
try {
|
||||
if(!label && length != 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Null label pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Null label pointer");
|
||||
|
||||
auto objname = (length < 0) ? std::string_view{label}
|
||||
: std::string_view{label, static_cast<uint>(length)};
|
||||
if(objname.size() >= MaxObjectLabelLength)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Object label length too long (%zu >= %d)",
|
||||
objname.size(), MaxObjectLabelLength};
|
||||
context->throw_error(AL_INVALID_VALUE, "Object label length too long ({} >= {})",
|
||||
objname.size(), MaxObjectLabelLength);
|
||||
|
||||
switch(identifier)
|
||||
{
|
||||
|
|
@ -543,10 +553,13 @@ try {
|
|||
case AL_AUXILIARY_EFFECT_SLOT_EXT: ALeffectslot::SetName(context, name, objname); return;
|
||||
}
|
||||
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid name identifier 0x%04x", identifier};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid name identifier {:#04x}",
|
||||
as_unsigned(identifier));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
FORCE_ALIGN DECL_FUNCEXT5(void, alGetObjectLabel,EXT, ALenum,identifier, ALuint,name, ALsizei,bufSize, ALsizei*,length, ALchar*,label)
|
||||
|
|
@ -554,12 +567,12 @@ FORCE_ALIGN void AL_APIENTRY alGetObjectLabelDirectEXT(ALCcontext *context, ALen
|
|||
ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) noexcept
|
||||
try {
|
||||
if(bufSize < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Negative label bufSize"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Negative label bufSize");
|
||||
|
||||
if(!label && !length)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Null length and label"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Null length and label");
|
||||
if(label && bufSize == 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Zero label bufSize"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Zero label bufSize");
|
||||
|
||||
const auto labelOut = al::span{label, label ? static_cast<ALuint>(bufSize) : 0u};
|
||||
auto copy_name = [name,length,labelOut](std::unordered_map<ALuint,std::string> &names)
|
||||
|
|
@ -589,20 +602,20 @@ try {
|
|||
}
|
||||
else if(identifier == AL_BUFFER)
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard buflock{device->BufferLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto buflock = std::lock_guard{device->BufferLock};
|
||||
copy_name(device->mBufferNames);
|
||||
}
|
||||
else if(identifier == AL_FILTER_EXT)
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto buflock = std::lock_guard{device->FilterLock};
|
||||
copy_name(device->mFilterNames);
|
||||
}
|
||||
else if(identifier == AL_EFFECT_EXT)
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto buflock = std::lock_guard{device->EffectLock};
|
||||
copy_name(device->mEffectNames);
|
||||
}
|
||||
else if(identifier == AL_AUXILIARY_EFFECT_SLOT_EXT)
|
||||
|
|
@ -611,8 +624,11 @@ try {
|
|||
copy_name(context->mEffectSlotNames);
|
||||
}
|
||||
else
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid name identifier 0x%04x", identifier};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid name identifier {:#04x}",
|
||||
as_unsigned(identifier));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "AL/al.h"
|
||||
|
||||
#include "opthelpers.h"
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
using GUID = struct _GUID { /* NOLINT(*-reserved-identifier) */
|
||||
|
|
@ -37,14 +39,16 @@ inline bool operator!=(const GUID& lhs, const GUID& rhs) noexcept
|
|||
{ return !(lhs == rhs); }
|
||||
#endif // _WIN32
|
||||
|
||||
/* TODO: This seems to create very inefficient comparisons. C++20 should allow
|
||||
* creating default comparison operators, avoiding the need for this.
|
||||
*/
|
||||
#define DECL_EQOP(T, ...) \
|
||||
[[nodiscard]] auto get_members() const noexcept { return std::forward_as_tuple(__VA_ARGS__); } \
|
||||
[[nodiscard]] friend bool operator==(const T &lhs, const T &rhs) noexcept \
|
||||
{ return lhs.get_members() == rhs.get_members(); } \
|
||||
[[nodiscard]] friend bool operator!=(const T &lhs, const T &rhs) noexcept \
|
||||
{ return !(lhs == rhs); }
|
||||
{ return lhs.get_members() == rhs.get_members(); } \
|
||||
[[nodiscard]] friend bool operator!=(const T &lhs, const T &rhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
extern const GUID DSPROPSETID_EAX_ReverbProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAX_ReverbProperties;
|
||||
|
||||
enum DSPROPERTY_EAX_REVERBPROPERTY : unsigned int {
|
||||
DSPROPERTY_EAX_ALL,
|
||||
|
|
@ -62,7 +66,7 @@ struct EAX_REVERBPROPERTIES {
|
|||
}; // EAX_REVERBPROPERTIES
|
||||
|
||||
|
||||
extern const GUID DSPROPSETID_EAXBUFFER_ReverbProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAXBUFFER_ReverbProperties;
|
||||
|
||||
enum DSPROPERTY_EAXBUFFER_REVERBPROPERTY : unsigned int {
|
||||
DSPROPERTY_EAXBUFFER_ALL,
|
||||
|
|
@ -78,7 +82,7 @@ constexpr auto EAX_BUFFER_MAXREVERBMIX = 1.0F;
|
|||
constexpr auto EAX_REVERBMIX_USEDISTANCE = -1.0F;
|
||||
|
||||
|
||||
extern const GUID DSPROPSETID_EAX20_ListenerProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAX20_ListenerProperties;
|
||||
|
||||
enum DSPROPERTY_EAX20_LISTENERPROPERTY : unsigned int {
|
||||
DSPROPERTY_EAX20LISTENER_NONE,
|
||||
|
|
@ -216,7 +220,7 @@ constexpr auto EAX2LISTENER_DEFAULTFLAGS =
|
|||
EAX2LISTENERFLAGS_DECAYHFLIMIT;
|
||||
|
||||
|
||||
extern const GUID DSPROPSETID_EAX20_BufferProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAX20_BufferProperties;
|
||||
|
||||
enum DSPROPERTY_EAX20_BUFFERPROPERTY : unsigned int {
|
||||
DSPROPERTY_EAX20BUFFER_NONE,
|
||||
|
|
@ -252,9 +256,9 @@ struct EAX20BUFFERPROPERTIES {
|
|||
unsigned long dwFlags; // modifies the behavior of properties
|
||||
}; // EAX20BUFFERPROPERTIES
|
||||
|
||||
extern const GUID DSPROPSETID_EAX30_ListenerProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAX30_ListenerProperties;
|
||||
|
||||
extern const GUID DSPROPSETID_EAX30_BufferProperties;
|
||||
DECL_HIDDEN extern const GUID DSPROPSETID_EAX30_BufferProperties;
|
||||
|
||||
|
||||
constexpr auto EAX_MAX_FXSLOTS = 4;
|
||||
|
|
@ -272,31 +276,29 @@ constexpr auto EAXERR_INCOMPATIBLE_SOURCE_TYPE = -5L;
|
|||
constexpr auto EAXERR_INCOMPATIBLE_EAX_VERSION = -6L;
|
||||
|
||||
|
||||
extern const GUID EAX_NULL_GUID;
|
||||
DECL_HIDDEN extern const GUID EAX_NULL_GUID;
|
||||
|
||||
extern const GUID EAX_PrimaryFXSlotID;
|
||||
DECL_HIDDEN extern const GUID EAX_PrimaryFXSlotID;
|
||||
|
||||
|
||||
struct EAXVECTOR {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
[[nodiscard]]
|
||||
auto get_members() const noexcept { return std::forward_as_tuple(x, y, z); }
|
||||
}; // EAXVECTOR
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool operator==(const EAXVECTOR& lhs, const EAXVECTOR& rhs) noexcept
|
||||
{ return lhs.get_members() == rhs.get_members(); }
|
||||
{ return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool operator!=(const EAXVECTOR& lhs, const EAXVECTOR& rhs) noexcept
|
||||
{ return !(lhs == rhs); }
|
||||
|
||||
|
||||
extern const GUID EAXPROPERTYID_EAX40_Context;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_Context;
|
||||
|
||||
extern const GUID EAXPROPERTYID_EAX50_Context;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_Context;
|
||||
|
||||
// EAX50
|
||||
constexpr auto HEADPHONES = 0UL;
|
||||
|
|
@ -372,17 +374,17 @@ constexpr auto EAXCONTEXT_DEFAULTMACROFXFACTOR = 0.0F;
|
|||
|
||||
constexpr auto EAXCONTEXT_DEFAULTLASTERROR = EAX_OK;
|
||||
|
||||
extern const GUID EAXPROPERTYID_EAX40_FXSlot0;
|
||||
extern const GUID EAXPROPERTYID_EAX50_FXSlot0;
|
||||
extern const GUID EAXPROPERTYID_EAX40_FXSlot1;
|
||||
extern const GUID EAXPROPERTYID_EAX50_FXSlot1;
|
||||
extern const GUID EAXPROPERTYID_EAX40_FXSlot2;
|
||||
extern const GUID EAXPROPERTYID_EAX50_FXSlot2;
|
||||
extern const GUID EAXPROPERTYID_EAX40_FXSlot3;
|
||||
extern const GUID EAXPROPERTYID_EAX50_FXSlot3;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_FXSlot0;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_FXSlot0;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_FXSlot1;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_FXSlot1;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_FXSlot2;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_FXSlot2;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_FXSlot3;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_FXSlot3;
|
||||
|
||||
extern const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||
extern const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||
DECL_HIDDEN extern const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||
DECL_HIDDEN extern const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||
|
||||
enum EAXFXSLOT_PROPERTY : unsigned int {
|
||||
EAXFXSLOT_PARAMETER = 0,
|
||||
|
|
@ -445,8 +447,8 @@ struct EAX50FXSLOTPROPERTIES : public EAX40FXSLOTPROPERTIES {
|
|||
float flOcclusionLFRatio;
|
||||
}; // EAX50FXSLOTPROPERTIES
|
||||
|
||||
extern const GUID EAXPROPERTYID_EAX40_Source;
|
||||
extern const GUID EAXPROPERTYID_EAX50_Source;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX40_Source;
|
||||
DECL_HIDDEN extern const GUID EAXPROPERTYID_EAX50_Source;
|
||||
|
||||
// Source object properties
|
||||
enum EAXSOURCE_PROPERTY : unsigned int {
|
||||
|
|
@ -713,16 +715,16 @@ struct EAXSOURCEEXCLUSIONSENDPROPERTIES {
|
|||
float flExclusionLFRatio;
|
||||
}; // EAXSOURCEEXCLUSIONSENDPROPERTIES
|
||||
|
||||
extern const EAX40ACTIVEFXSLOTS EAX40SOURCE_DEFAULTACTIVEFXSLOTID;
|
||||
DECL_HIDDEN extern const EAX40ACTIVEFXSLOTS EAX40SOURCE_DEFAULTACTIVEFXSLOTID;
|
||||
|
||||
extern const EAX50ACTIVEFXSLOTS EAX50SOURCE_3DDEFAULTACTIVEFXSLOTID;
|
||||
DECL_HIDDEN extern const EAX50ACTIVEFXSLOTS EAX50SOURCE_3DDEFAULTACTIVEFXSLOTID;
|
||||
|
||||
extern const EAX50ACTIVEFXSLOTS EAX50SOURCE_2DDEFAULTACTIVEFXSLOTID;
|
||||
DECL_HIDDEN extern const EAX50ACTIVEFXSLOTS EAX50SOURCE_2DDEFAULTACTIVEFXSLOTID;
|
||||
|
||||
|
||||
// EAX Reverb Effect
|
||||
|
||||
extern const GUID EAX_REVERB_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_REVERB_EFFECT;
|
||||
|
||||
// Reverb effect properties
|
||||
enum EAXREVERB_PROPERTY : unsigned int {
|
||||
|
|
@ -959,18 +961,18 @@ constexpr auto EAXREVERB_DEFAULTFLAGS =
|
|||
|
||||
|
||||
using Eax1ReverbPresets = std::array<EAX_REVERBPROPERTIES, EAX1_ENVIRONMENT_COUNT>;
|
||||
extern const Eax1ReverbPresets EAX1REVERB_PRESETS;
|
||||
DECL_HIDDEN extern const Eax1ReverbPresets EAX1REVERB_PRESETS;
|
||||
|
||||
using Eax2ReverbPresets = std::array<EAX20LISTENERPROPERTIES, EAX2_ENVIRONMENT_COUNT>;
|
||||
extern const Eax2ReverbPresets EAX2REVERB_PRESETS;
|
||||
DECL_HIDDEN extern const Eax2ReverbPresets EAX2REVERB_PRESETS;
|
||||
|
||||
using EaxReverbPresets = std::array<EAXREVERBPROPERTIES, EAX1_ENVIRONMENT_COUNT>;
|
||||
extern const EaxReverbPresets EAXREVERB_PRESETS;
|
||||
DECL_HIDDEN extern const EaxReverbPresets EAXREVERB_PRESETS;
|
||||
|
||||
|
||||
// AGC Compressor Effect
|
||||
|
||||
extern const GUID EAX_AGCCOMPRESSOR_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_AGCCOMPRESSOR_EFFECT;
|
||||
|
||||
enum EAXAGCCOMPRESSOR_PROPERTY : unsigned int {
|
||||
EAXAGCCOMPRESSOR_NONE,
|
||||
|
|
@ -991,7 +993,7 @@ constexpr auto EAXAGCCOMPRESSOR_DEFAULTONOFF = EAXAGCCOMPRESSOR_MAXONOFF;
|
|||
|
||||
// Autowah Effect
|
||||
|
||||
extern const GUID EAX_AUTOWAH_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_AUTOWAH_EFFECT;
|
||||
|
||||
enum EAXAUTOWAH_PROPERTY : unsigned int {
|
||||
EAXAUTOWAH_NONE,
|
||||
|
|
@ -1030,7 +1032,7 @@ constexpr auto EAXAUTOWAH_DEFAULTPEAKLEVEL = 2100L;
|
|||
|
||||
// Chorus Effect
|
||||
|
||||
extern const GUID EAX_CHORUS_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_CHORUS_EFFECT;
|
||||
|
||||
enum EAXCHORUS_PROPERTY : unsigned int {
|
||||
EAXCHORUS_NONE,
|
||||
|
|
@ -1086,7 +1088,7 @@ constexpr auto EAXCHORUS_DEFAULTDELAY = 0.016F;
|
|||
|
||||
// Distortion Effect
|
||||
|
||||
extern const GUID EAX_DISTORTION_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_DISTORTION_EFFECT;
|
||||
|
||||
enum EAXDISTORTION_PROPERTY : unsigned int {
|
||||
EAXDISTORTION_NONE,
|
||||
|
|
@ -1131,7 +1133,7 @@ constexpr auto EAXDISTORTION_DEFAULTEQBANDWIDTH = 3600.0F;
|
|||
|
||||
// Echo Effect
|
||||
|
||||
extern const GUID EAX_ECHO_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_ECHO_EFFECT;
|
||||
|
||||
enum EAXECHO_PROPERTY : unsigned int {
|
||||
EAXECHO_NONE,
|
||||
|
|
@ -1176,7 +1178,7 @@ constexpr auto EAXECHO_DEFAULTSPREAD = -1.0F;
|
|||
|
||||
// Equalizer Effect
|
||||
|
||||
extern const GUID EAX_EQUALIZER_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_EQUALIZER_EFFECT;
|
||||
|
||||
enum EAXEQUALIZER_PROPERTY : unsigned int {
|
||||
EAXEQUALIZER_NONE,
|
||||
|
|
@ -1252,7 +1254,7 @@ constexpr auto EAXEQUALIZER_DEFAULTHIGHCUTOFF = 6000.0F;
|
|||
|
||||
// Flanger Effect
|
||||
|
||||
extern const GUID EAX_FLANGER_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_FLANGER_EFFECT;
|
||||
|
||||
enum EAXFLANGER_PROPERTY : unsigned int {
|
||||
EAXFLANGER_NONE,
|
||||
|
|
@ -1308,7 +1310,7 @@ constexpr auto EAXFLANGER_DEFAULTDELAY = 0.002F;
|
|||
|
||||
// Frequency Shifter Effect
|
||||
|
||||
extern const GUID EAX_FREQUENCYSHIFTER_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_FREQUENCYSHIFTER_EFFECT;
|
||||
|
||||
enum EAXFREQUENCYSHIFTER_PROPERTY : unsigned int {
|
||||
EAXFREQUENCYSHIFTER_NONE,
|
||||
|
|
@ -1347,7 +1349,7 @@ constexpr auto EAXFREQUENCYSHIFTER_DEFAULTRIGHTDIRECTION = EAXFREQUENCYSHIFTER_M
|
|||
|
||||
// Vocal Morpher Effect
|
||||
|
||||
extern const GUID EAX_VOCALMORPHER_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_VOCALMORPHER_EFFECT;
|
||||
|
||||
enum EAXVOCALMORPHER_PROPERTY : unsigned int {
|
||||
EAXVOCALMORPHER_NONE,
|
||||
|
|
@ -1439,7 +1441,7 @@ constexpr auto EAXVOCALMORPHER_DEFAULTRATE = 1.41F;
|
|||
|
||||
// Pitch Shifter Effect
|
||||
|
||||
extern const GUID EAX_PITCHSHIFTER_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_PITCHSHIFTER_EFFECT;
|
||||
|
||||
enum EAXPITCHSHIFTER_PROPERTY : unsigned int {
|
||||
EAXPITCHSHIFTER_NONE,
|
||||
|
|
@ -1466,7 +1468,7 @@ constexpr auto EAXPITCHSHIFTER_DEFAULTFINETUNE = 0L;
|
|||
|
||||
// Ring Modulator Effect
|
||||
|
||||
extern const GUID EAX_RINGMODULATOR_EFFECT;
|
||||
DECL_HIDDEN extern const GUID EAX_RINGMODULATOR_EFFECT;
|
||||
|
||||
enum EAXRINGMODULATOR_PROPERTY : unsigned int {
|
||||
EAXRINGMODULATOR_NONE,
|
||||
|
|
|
|||
|
|
@ -15,13 +15,8 @@ public:
|
|||
|
||||
} // namespace
|
||||
|
||||
EaxCall::EaxCall(
|
||||
EaxCallType type,
|
||||
const GUID& property_set_guid,
|
||||
ALuint property_id,
|
||||
ALuint property_source_id,
|
||||
ALvoid* property_buffer,
|
||||
ALuint property_size)
|
||||
EaxCall::EaxCall(EaxCallType type, const GUID &property_set_guid, ALuint property_id,
|
||||
ALuint property_source_id, ALvoid *property_buffer, ALuint property_size)
|
||||
: mCallType{type}, mIsDeferred{(property_id & deferred_flag) != 0}
|
||||
, mPropertyId{property_id & ~deferred_flag}, mPropertySourceId{property_source_id}
|
||||
, mPropertyBuffer{property_buffer}, mPropertyBufferSize{property_size}
|
||||
|
|
@ -145,23 +140,34 @@ EaxCall::EaxCall(
|
|||
fail("Unsupported property set id.");
|
||||
}
|
||||
|
||||
switch(mPropertyId)
|
||||
if(mPropertySetId == EaxCallPropertySetId::context)
|
||||
{
|
||||
case EAXCONTEXT_LASTERROR:
|
||||
case EAXCONTEXT_SPEAKERCONFIG:
|
||||
case EAXCONTEXT_EAXSESSION:
|
||||
case EAXFXSLOT_NONE:
|
||||
case EAXFXSLOT_ALLPARAMETERS:
|
||||
case EAXFXSLOT_LOADEFFECT:
|
||||
case EAXFXSLOT_VOLUME:
|
||||
case EAXFXSLOT_LOCK:
|
||||
case EAXFXSLOT_FLAGS:
|
||||
case EAXFXSLOT_OCCLUSION:
|
||||
case EAXFXSLOT_OCCLUSIONLFRATIO:
|
||||
// EAX allow to set "defer" flag on immediate-only properties.
|
||||
// If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
|
||||
mIsDeferred = false;
|
||||
break;
|
||||
switch(mPropertyId)
|
||||
{
|
||||
case EAXCONTEXT_LASTERROR:
|
||||
case EAXCONTEXT_SPEAKERCONFIG:
|
||||
case EAXCONTEXT_EAXSESSION:
|
||||
// EAX allow to set "defer" flag on immediate-only properties.
|
||||
// If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
|
||||
mIsDeferred = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(mPropertySetId == EaxCallPropertySetId::fx_slot)
|
||||
{
|
||||
switch(mPropertyId)
|
||||
{
|
||||
case EAXFXSLOT_NONE:
|
||||
case EAXFXSLOT_ALLPARAMETERS:
|
||||
case EAXFXSLOT_LOADEFFECT:
|
||||
case EAXFXSLOT_VOLUME:
|
||||
case EAXFXSLOT_LOCK:
|
||||
case EAXFXSLOT_FLAGS:
|
||||
case EAXFXSLOT_OCCLUSION:
|
||||
case EAXFXSLOT_OCCLUSIONLFRATIO:
|
||||
mIsDeferred = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mIsDeferred)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef EAX_EFFECT_INCLUDED
|
||||
#define EAX_EFFECT_INCLUDED
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
#include "alnumeric.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alext.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "call.h"
|
||||
|
||||
inline bool EaxTraceCommits{false};
|
||||
|
||||
struct EaxEffectErrorMessages {
|
||||
static constexpr auto unknown_property_id() noexcept { return "Unknown property id."; }
|
||||
static constexpr auto unknown_version() noexcept { return "Unknown version."; }
|
||||
|
|
@ -123,10 +123,6 @@ template<typename T>
|
|||
struct EaxCommitter {
|
||||
struct Exception;
|
||||
|
||||
EaxCommitter(EaxEffectProps &eaxprops, EffectProps &alprops)
|
||||
: mEaxProps{eaxprops}, mAlProps{alprops}
|
||||
{ }
|
||||
|
||||
EaxEffectProps &mEaxProps;
|
||||
EffectProps &mAlProps;
|
||||
|
||||
|
|
@ -141,10 +137,18 @@ struct EaxCommitter {
|
|||
[[noreturn]] static void fail(const char *message);
|
||||
[[noreturn]] static void fail_unknown_property_id()
|
||||
{ fail(EaxEffectErrorMessages::unknown_property_id()); }
|
||||
|
||||
private:
|
||||
EaxCommitter(EaxEffectProps &eaxprops, EffectProps &alprops)
|
||||
: mEaxProps{eaxprops}, mAlProps{alprops}
|
||||
{ }
|
||||
|
||||
friend T;
|
||||
};
|
||||
|
||||
struct EaxAutowahCommitter : public EaxCommitter<EaxAutowahCommitter> {
|
||||
using EaxCommitter<EaxAutowahCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxAutowahCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXAUTOWAHPROPERTIES &props);
|
||||
|
||||
|
|
@ -153,7 +157,8 @@ struct EaxAutowahCommitter : public EaxCommitter<EaxAutowahCommitter> {
|
|||
static void Set(const EaxCall &call, EAXAUTOWAHPROPERTIES &props);
|
||||
};
|
||||
struct EaxChorusCommitter : public EaxCommitter<EaxChorusCommitter> {
|
||||
using EaxCommitter<EaxChorusCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxChorusCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXCHORUSPROPERTIES &props);
|
||||
|
||||
|
|
@ -162,7 +167,8 @@ struct EaxChorusCommitter : public EaxCommitter<EaxChorusCommitter> {
|
|||
static void Set(const EaxCall &call, EAXCHORUSPROPERTIES &props);
|
||||
};
|
||||
struct EaxCompressorCommitter : public EaxCommitter<EaxCompressorCommitter> {
|
||||
using EaxCommitter<EaxCompressorCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxCompressorCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXAGCCOMPRESSORPROPERTIES &props);
|
||||
|
||||
|
|
@ -171,7 +177,8 @@ struct EaxCompressorCommitter : public EaxCommitter<EaxCompressorCommitter> {
|
|||
static void Set(const EaxCall &call, EAXAGCCOMPRESSORPROPERTIES &props);
|
||||
};
|
||||
struct EaxDistortionCommitter : public EaxCommitter<EaxDistortionCommitter> {
|
||||
using EaxCommitter<EaxDistortionCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxDistortionCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXDISTORTIONPROPERTIES &props);
|
||||
|
||||
|
|
@ -180,7 +187,8 @@ struct EaxDistortionCommitter : public EaxCommitter<EaxDistortionCommitter> {
|
|||
static void Set(const EaxCall &call, EAXDISTORTIONPROPERTIES &props);
|
||||
};
|
||||
struct EaxEchoCommitter : public EaxCommitter<EaxEchoCommitter> {
|
||||
using EaxCommitter<EaxEchoCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxEchoCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXECHOPROPERTIES &props);
|
||||
|
||||
|
|
@ -189,7 +197,8 @@ struct EaxEchoCommitter : public EaxCommitter<EaxEchoCommitter> {
|
|||
static void Set(const EaxCall &call, EAXECHOPROPERTIES &props);
|
||||
};
|
||||
struct EaxEqualizerCommitter : public EaxCommitter<EaxEqualizerCommitter> {
|
||||
using EaxCommitter<EaxEqualizerCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxEqualizerCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXEQUALIZERPROPERTIES &props);
|
||||
|
||||
|
|
@ -198,7 +207,8 @@ struct EaxEqualizerCommitter : public EaxCommitter<EaxEqualizerCommitter> {
|
|||
static void Set(const EaxCall &call, EAXEQUALIZERPROPERTIES &props);
|
||||
};
|
||||
struct EaxFlangerCommitter : public EaxCommitter<EaxFlangerCommitter> {
|
||||
using EaxCommitter<EaxFlangerCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxFlangerCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXFLANGERPROPERTIES &props);
|
||||
|
||||
|
|
@ -207,7 +217,8 @@ struct EaxFlangerCommitter : public EaxCommitter<EaxFlangerCommitter> {
|
|||
static void Set(const EaxCall &call, EAXFLANGERPROPERTIES &props);
|
||||
};
|
||||
struct EaxFrequencyShifterCommitter : public EaxCommitter<EaxFrequencyShifterCommitter> {
|
||||
using EaxCommitter<EaxFrequencyShifterCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxFrequencyShifterCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXFREQUENCYSHIFTERPROPERTIES &props);
|
||||
|
||||
|
|
@ -216,7 +227,8 @@ struct EaxFrequencyShifterCommitter : public EaxCommitter<EaxFrequencyShifterCom
|
|||
static void Set(const EaxCall &call, EAXFREQUENCYSHIFTERPROPERTIES &props);
|
||||
};
|
||||
struct EaxModulatorCommitter : public EaxCommitter<EaxModulatorCommitter> {
|
||||
using EaxCommitter<EaxModulatorCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxModulatorCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXRINGMODULATORPROPERTIES &props);
|
||||
|
||||
|
|
@ -225,7 +237,8 @@ struct EaxModulatorCommitter : public EaxCommitter<EaxModulatorCommitter> {
|
|||
static void Set(const EaxCall &call, EAXRINGMODULATORPROPERTIES &props);
|
||||
};
|
||||
struct EaxPitchShifterCommitter : public EaxCommitter<EaxPitchShifterCommitter> {
|
||||
using EaxCommitter<EaxPitchShifterCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxPitchShifterCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXPITCHSHIFTERPROPERTIES &props);
|
||||
|
||||
|
|
@ -234,7 +247,8 @@ struct EaxPitchShifterCommitter : public EaxCommitter<EaxPitchShifterCommitter>
|
|||
static void Set(const EaxCall &call, EAXPITCHSHIFTERPROPERTIES &props);
|
||||
};
|
||||
struct EaxVocalMorpherCommitter : public EaxCommitter<EaxVocalMorpherCommitter> {
|
||||
using EaxCommitter<EaxVocalMorpherCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxVocalMorpherCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const EAXVOCALMORPHERPROPERTIES &props);
|
||||
|
||||
|
|
@ -243,7 +257,8 @@ struct EaxVocalMorpherCommitter : public EaxCommitter<EaxVocalMorpherCommitter>
|
|||
static void Set(const EaxCall &call, EAXVOCALMORPHERPROPERTIES &props);
|
||||
};
|
||||
struct EaxNullCommitter : public EaxCommitter<EaxNullCommitter> {
|
||||
using EaxCommitter<EaxNullCommitter>::EaxCommitter;
|
||||
template<typename ...Args>
|
||||
explicit EaxNullCommitter(Args&& ...args) : EaxCommitter{std::forward<Args>(args)...} { }
|
||||
|
||||
bool commit(const std::monostate &props);
|
||||
|
||||
|
|
@ -279,7 +294,7 @@ public:
|
|||
~EaxEffect() = default;
|
||||
|
||||
ALenum al_effect_type_{AL_EFFECT_NULL};
|
||||
EffectProps al_effect_props_{};
|
||||
EffectProps al_effect_props_;
|
||||
|
||||
using Props1 = EAX_REVERBPROPERTIES;
|
||||
using Props2 = EAX20LISTENERPROPERTIES;
|
||||
|
|
@ -308,7 +323,7 @@ public:
|
|||
|
||||
int version_{};
|
||||
bool changed_{};
|
||||
Props4 props_{};
|
||||
Props4 props_;
|
||||
State1 state1_{};
|
||||
State2 state2_{};
|
||||
State3 state3_{};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include <cassert>
|
||||
#include <exception>
|
||||
|
||||
#include "alstring.h"
|
||||
#include "core/logging.h"
|
||||
|
||||
|
||||
|
|
@ -18,9 +17,9 @@ void eax_log_exception(std::string_view message) noexcept
|
|||
std::rethrow_exception(exception_ptr);
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
ERR("%.*s %s\n", al::sizei(message), message.data(), ex.what());
|
||||
ERR("{} {}", message, ex.what());
|
||||
}
|
||||
catch(...) {
|
||||
ERR("%.*s %s\n", al::sizei(message), message.data(), "Generic exception.");
|
||||
ERR("{} {}", message, "Generic exception.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
#ifndef EAX_UTILS_INCLUDED
|
||||
#define EAX_UTILS_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
using EaxDirtyFlags = unsigned int;
|
||||
|
||||
struct EaxAlLowPassParam {
|
||||
float gain;
|
||||
|
|
@ -25,71 +21,9 @@ void eax_validate_range(std::string_view value_name, const TValue& value, const
|
|||
if(value >= min_value && value <= max_value) LIKELY
|
||||
return;
|
||||
|
||||
const auto message =
|
||||
std::string{value_name} +
|
||||
" out of range (value: " +
|
||||
std::to_string(value) + "; min: " +
|
||||
std::to_string(min_value) + "; max: " +
|
||||
std::to_string(max_value) + ").";
|
||||
|
||||
const auto message = fmt::format("{} out of range (value: {}; min: {}; max: {}).", value_name,
|
||||
value, min_value, max_value);
|
||||
throw TException{message.c_str()};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct EaxIsBitFieldStruct {
|
||||
private:
|
||||
using yes = std::true_type;
|
||||
using no = std::false_type;
|
||||
|
||||
template<typename U>
|
||||
static auto test(int) -> decltype(std::declval<typename U::EaxIsBitFieldStruct>(), yes{});
|
||||
|
||||
template<typename>
|
||||
static no test(...);
|
||||
|
||||
public:
|
||||
static constexpr auto value = std::is_same<decltype(test<T>(0)), yes>::value;
|
||||
};
|
||||
|
||||
template<typename T, typename TValue>
|
||||
inline bool eax_bit_fields_are_equal(const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(TValue), "Invalid type size.");
|
||||
return reinterpret_cast<const TValue&>(lhs) == reinterpret_cast<const TValue&>(rhs);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<
|
||||
typename T,
|
||||
std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
|
||||
>
|
||||
inline bool operator==(const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
using Value = std::conditional_t<
|
||||
sizeof(T) == 1,
|
||||
std::uint8_t,
|
||||
std::conditional_t<
|
||||
sizeof(T) == 2,
|
||||
std::uint16_t,
|
||||
std::conditional_t<
|
||||
sizeof(T) == 4,
|
||||
std::uint32_t,
|
||||
void>>>;
|
||||
|
||||
static_assert(!std::is_same<Value, void>::value, "Unsupported type.");
|
||||
return detail::eax_bit_fields_are_equal<T, Value>(lhs, rhs);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
|
||||
>
|
||||
inline bool operator!=(const T& lhs, const T& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
#endif // !EAX_UTILS_INCLUDED
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@
|
|||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "alstring.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "direct_defs.h"
|
||||
#include "error.h"
|
||||
#include "intrusive_ptr.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
|
|
@ -139,7 +139,8 @@ void InitEffectParams(ALeffect *effect, ALenum type) noexcept
|
|||
effect->type = type;
|
||||
}
|
||||
|
||||
auto EnsureEffects(ALCdevice *device, size_t needed) noexcept -> bool
|
||||
[[nodiscard]]
|
||||
auto EnsureEffects(al::Device *device, size_t needed) noexcept -> bool
|
||||
try {
|
||||
size_t count{std::accumulate(device->EffectList.cbegin(), device->EffectList.cend(), 0_uz,
|
||||
[](size_t cur, const EffectSubList &sublist) noexcept -> size_t
|
||||
|
|
@ -162,7 +163,8 @@ catch(...) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ALeffect *AllocEffect(ALCdevice *device) noexcept
|
||||
[[nodiscard]]
|
||||
auto AllocEffect(al::Device *device) noexcept -> ALeffect*
|
||||
{
|
||||
auto sublist = std::find_if(device->EffectList.begin(), device->EffectList.end(),
|
||||
[](const EffectSubList &entry) noexcept -> bool
|
||||
|
|
@ -182,7 +184,7 @@ ALeffect *AllocEffect(ALCdevice *device) noexcept
|
|||
return effect;
|
||||
}
|
||||
|
||||
void FreeEffect(ALCdevice *device, ALeffect *effect)
|
||||
void FreeEffect(al::Device *device, ALeffect *effect)
|
||||
{
|
||||
device->mEffectNames.erase(effect->id);
|
||||
|
||||
|
|
@ -195,7 +197,8 @@ void FreeEffect(ALCdevice *device, ALeffect *effect)
|
|||
device->EffectList[lidx].FreeMask |= 1_u64 << slidx;
|
||||
}
|
||||
|
||||
inline auto LookupEffect(ALCdevice *device, ALuint id) noexcept -> ALeffect*
|
||||
[[nodiscard]] inline
|
||||
auto LookupEffect(al::Device *device, ALuint id) noexcept -> ALeffect*
|
||||
{
|
||||
const size_t lidx{(id-1) >> 6};
|
||||
const ALuint slidx{(id-1) & 0x3f};
|
||||
|
|
@ -214,21 +217,23 @@ AL_API DECL_FUNC2(void, alGenEffects, ALsizei,n, ALuint*,effects)
|
|||
FORCE_ALIGN void AL_APIENTRY alGenEffectsDirect(ALCcontext *context, ALsizei n, ALuint *effects) noexcept
|
||||
try {
|
||||
if(n < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Generating %d effects", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Generating {} effects", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
const al::span eids{effects, static_cast<ALuint>(n)};
|
||||
if(!EnsureEffects(device, eids.size()))
|
||||
throw al::context_error{AL_OUT_OF_MEMORY, "Failed to allocate %d effect%s", n,
|
||||
(n == 1) ? "" : "s"};
|
||||
context->throw_error(AL_OUT_OF_MEMORY, "Failed to allocate {} effect{}", n,
|
||||
(n==1) ? "" : "s");
|
||||
|
||||
std::generate(eids.begin(), eids.end(), [device]{ return AllocEffect(device)->id; });
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alDeleteEffects, ALsizei,n, const ALuint*,effects)
|
||||
|
|
@ -236,11 +241,11 @@ FORCE_ALIGN void AL_APIENTRY alDeleteEffectsDirect(ALCcontext *context, ALsizei
|
|||
const ALuint *effects) noexcept
|
||||
try {
|
||||
if(n < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Deleting %d effects", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Deleting {} effects", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
/* First try to find any effects that are invalid. */
|
||||
auto validate_effect = [device](const ALuint eid) -> bool
|
||||
|
|
@ -249,7 +254,7 @@ try {
|
|||
const al::span eids{effects, static_cast<ALuint>(n)};
|
||||
auto inveffect = std::find_if_not(eids.begin(), eids.end(), validate_effect);
|
||||
if(inveffect != eids.end())
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", *inveffect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", *inveffect);
|
||||
|
||||
/* All good. Delete non-0 effect IDs. */
|
||||
auto delete_effect = [device](ALuint eid) -> void
|
||||
|
|
@ -259,15 +264,17 @@ try {
|
|||
};
|
||||
std::for_each(eids.begin(), eids.end(), delete_effect);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(ALboolean, alIsEffect, ALuint,effect)
|
||||
FORCE_ALIGN ALboolean AL_APIENTRY alIsEffectDirect(ALCcontext *context, ALuint effect) noexcept
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
if(!effect || LookupEffect(device, effect))
|
||||
return AL_TRUE;
|
||||
return AL_FALSE;
|
||||
|
|
@ -277,12 +284,12 @@ AL_API DECL_FUNC3(void, alEffecti, ALuint,effect, ALenum,param, ALint,value)
|
|||
FORCE_ALIGN void AL_APIENTRY alEffectiDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
ALint value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -292,8 +299,8 @@ try {
|
|||
auto check_effect = [value](const EffectList &item) -> bool
|
||||
{ return value == item.val && !DisabledEffects.test(item.type); };
|
||||
if(!std::any_of(gEffectList.cbegin(), gEffectList.cend(), check_effect))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Effect type 0x%04x not supported",
|
||||
value};
|
||||
context->throw_error(AL_INVALID_VALUE, "Effect type {:#04x} not supported",
|
||||
as_unsigned(value));
|
||||
}
|
||||
|
||||
InitEffectParams(aleffect, value);
|
||||
|
|
@ -301,15 +308,17 @@ try {
|
|||
}
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,value](auto &arg)
|
||||
std::visit([context,aleffect,param,value](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.SetParami(std::get<PropType>(aleffect->Props), param, value);
|
||||
return arg.SetParami(context, std::get<PropType>(aleffect->Props), param, value);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alEffectiv, ALuint,effect, ALenum,param, const ALint*,values)
|
||||
|
|
@ -323,81 +332,87 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,values](auto &arg)
|
||||
std::visit([context,aleffect,param,values](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.SetParamiv(std::get<PropType>(aleffect->Props), param, values);
|
||||
return arg.SetParamiv(context, std::get<PropType>(aleffect->Props), param, values);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alEffectf, ALuint,effect, ALenum,param, ALfloat,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alEffectfDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
ALfloat value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect) UNLIKELY
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
if(!aleffect)
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,value](auto &arg)
|
||||
std::visit([context,aleffect,param,value](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.SetParamf(std::get<PropType>(aleffect->Props), param, value);
|
||||
return arg.SetParamf(context, std::get<PropType>(aleffect->Props), param, value);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alEffectfv, ALuint,effect, ALenum,param, const ALfloat*,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alEffectfvDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
const ALfloat *values) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,values](auto &arg)
|
||||
std::visit([context,aleffect,param,values](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.SetParamfv(std::get<PropType>(aleffect->Props), param, values);
|
||||
return arg.SetParamfv(context, std::get<PropType>(aleffect->Props), param, values);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetEffecti, ALuint,effect, ALenum,param, ALint*,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetEffectiDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
ALint *value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -407,15 +422,17 @@ try {
|
|||
}
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,value](auto &arg)
|
||||
std::visit([context,aleffect,param,value](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.GetParami(std::get<PropType>(aleffect->Props), param, value);
|
||||
return arg.GetParami(context, std::get<PropType>(aleffect->Props), param, value);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetEffectiv, ALuint,effect, ALenum,param, ALint*,values)
|
||||
|
|
@ -429,69 +446,75 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,values](auto &arg)
|
||||
std::visit([context,aleffect,param,values](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.GetParamiv(std::get<PropType>(aleffect->Props), param, values);
|
||||
return arg.GetParamiv(context, std::get<PropType>(aleffect->Props), param, values);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetEffectf, ALuint,effect, ALenum,param, ALfloat*,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetEffectfDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
ALfloat *value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,value](auto &arg)
|
||||
std::visit([context,aleffect,param,value](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.GetParamf(std::get<PropType>(aleffect->Props), param, value);
|
||||
return arg.GetParamf(context, std::get<PropType>(aleffect->Props), param, value);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetEffectfv, ALuint,effect, ALenum,param, ALfloat*,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetEffectfvDirect(ALCcontext *context, ALuint effect, ALenum param,
|
||||
ALfloat *values) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||
if(!aleffect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", effect};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", effect);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([aleffect,param,values](auto &arg)
|
||||
std::visit([context,aleffect,param,values](auto &arg)
|
||||
{
|
||||
using Type = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
|
||||
using PropType = typename Type::prop_type;
|
||||
return arg.GetParamfv(std::get<PropType>(aleffect->Props), param, values);
|
||||
return arg.GetParamfv(context, std::get<PropType>(aleffect->Props), param, values);
|
||||
}, aleffect->PropsVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -502,12 +525,12 @@ void InitEffect(ALeffect *effect)
|
|||
|
||||
void ALeffect::SetName(ALCcontext* context, ALuint id, std::string_view name)
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> effectlock{device->EffectLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto effectlock = std::lock_guard{device->EffectLock};
|
||||
|
||||
auto effect = LookupEffect(device, id);
|
||||
if(!effect)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid effect ID %u", id};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid effect ID {}", id);
|
||||
|
||||
device->mEffectNames.insert_or_assign(id, name);
|
||||
}
|
||||
|
|
@ -673,7 +696,7 @@ void LoadReverbPreset(const std::string_view name, ALeffect *effect)
|
|||
if(al::case_compare(name, "NONE"sv) == 0)
|
||||
{
|
||||
InitEffectParams(effect, AL_EFFECT_NULL);
|
||||
TRACE("Loading reverb '%s'\n", "NONE");
|
||||
TRACE("Loading reverb '{}'", "NONE");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -688,7 +711,7 @@ void LoadReverbPreset(const std::string_view name, ALeffect *effect)
|
|||
if(al::case_compare(name, std::data(reverbitem.name)) != 0)
|
||||
continue;
|
||||
|
||||
TRACE("Loading reverb '%s'\n", std::data(reverbitem.name));
|
||||
TRACE("Loading reverb '{}'", std::data(reverbitem.name));
|
||||
const auto &props = reverbitem.props;
|
||||
auto &dst = std::get<ReverbProps>(effect->Props);
|
||||
dst.Density = props.flDensity;
|
||||
|
|
@ -721,7 +744,7 @@ void LoadReverbPreset(const std::string_view name, ALeffect *effect)
|
|||
return;
|
||||
}
|
||||
|
||||
WARN("Reverb preset '%.*s' not found\n", al::sizei(name), name.data());
|
||||
WARN("Reverb preset '{}' not found", name);
|
||||
}
|
||||
|
||||
bool IsValidEffectType(ALenum type) noexcept
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
|
@ -43,7 +44,7 @@ struct EffectList {
|
|||
ALuint type;
|
||||
ALenum val;
|
||||
};
|
||||
extern const std::array<EffectList,16> gEffectList;
|
||||
DECL_HIDDEN extern const std::array<EffectList,16> gEffectList;
|
||||
|
||||
using EffectHandlerVariant = std::variant<NullEffectHandler,ReverbEffectHandler,
|
||||
StdReverbEffectHandler,AutowahEffectHandler,ChorusEffectHandler,CompressorEffectHandler,
|
||||
|
|
@ -56,7 +57,7 @@ struct ALeffect {
|
|||
ALenum type{AL_EFFECT_NULL};
|
||||
|
||||
EffectHandlerVariant PropsVariant;
|
||||
EffectProps Props{};
|
||||
EffectProps Props;
|
||||
|
||||
/* Self ID */
|
||||
ALuint id{0u};
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@
|
|||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -35,75 +33,68 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps AutowahEffectProps{genDefaultProps()};
|
||||
|
||||
void AutowahEffectHandler::SetParami(AutowahProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
|
||||
void AutowahEffectHandler::SetParamiv(AutowahProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void AutowahEffectHandler::SetParami(ALCcontext *context, AutowahProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer property {:#04x}", as_unsigned(param)); }
|
||||
void AutowahEffectHandler::SetParamiv(ALCcontext *context, AutowahProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
void AutowahEffectHandler::SetParamf(AutowahProps &props, ALenum param, float val)
|
||||
void AutowahEffectHandler::SetParamf(ALCcontext *context, AutowahProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_AUTOWAH_ATTACK_TIME:
|
||||
if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Autowah attack time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Autowah attack time out of range");
|
||||
props.AttackTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_AUTOWAH_RELEASE_TIME:
|
||||
if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Autowah release time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Autowah release time out of range");
|
||||
props.ReleaseTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_AUTOWAH_RESONANCE:
|
||||
if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Autowah resonance out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Autowah resonance out of range");
|
||||
props.Resonance = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_AUTOWAH_PEAK_GAIN:
|
||||
if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Autowah peak gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Autowah peak gain out of range");
|
||||
props.PeakGain = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void AutowahEffectHandler::SetParamfv(AutowahProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void AutowahEffectHandler::GetParami(const AutowahProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
|
||||
void AutowahEffectHandler::GetParamiv(const AutowahProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid autowah float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void AutowahEffectHandler::SetParamfv(ALCcontext *context, AutowahProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void AutowahEffectHandler::GetParamf(const AutowahProps &props, ALenum param, float *val)
|
||||
void AutowahEffectHandler::GetParami(ALCcontext *context, const AutowahProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer property {:#04x}", as_unsigned(param)); }
|
||||
void AutowahEffectHandler::GetParamiv(ALCcontext *context, const AutowahProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
void AutowahEffectHandler::GetParamf(ALCcontext *context, const AutowahProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_AUTOWAH_ATTACK_TIME: *val = props.AttackTime; break;
|
||||
case AL_AUTOWAH_RELEASE_TIME: *val = props.ReleaseTime; break;
|
||||
case AL_AUTOWAH_RESONANCE: *val = props.Resonance; break;
|
||||
case AL_AUTOWAH_PEAK_GAIN: *val = props.PeakGain; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
|
||||
case AL_AUTOWAH_ATTACK_TIME: *val = props.AttackTime; return;
|
||||
case AL_AUTOWAH_RELEASE_TIME: *val = props.ReleaseTime; return;
|
||||
case AL_AUTOWAH_RESONANCE: *val = props.Resonance; return;
|
||||
case AL_AUTOWAH_PEAK_GAIN: *val = props.PeakGain; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid autowah float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void AutowahEffectHandler::GetParamfv(const AutowahProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void AutowahEffectHandler::GetParamfv(ALCcontext *context, const AutowahProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using AutowahCommitter = EaxCommitter<EaxAutowahCommitter>;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "core/logging.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <cassert>
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
|
|
@ -41,7 +44,8 @@ constexpr ALenum EnumFromWaveform(ChorusWaveform type)
|
|||
case ChorusWaveform::Sinusoid: return AL_CHORUS_WAVEFORM_SINUSOID;
|
||||
case ChorusWaveform::Triangle: return AL_CHORUS_WAVEFORM_TRIANGLE;
|
||||
}
|
||||
throw std::runtime_error{"Invalid chorus waveform: "+std::to_string(static_cast<int>(type))};
|
||||
throw std::runtime_error{fmt::format("Invalid chorus waveform: {}",
|
||||
int{al::to_underlying(type)})};
|
||||
}
|
||||
|
||||
constexpr EffectProps genDefaultChorusProps() noexcept
|
||||
|
|
@ -72,7 +76,7 @@ constexpr EffectProps genDefaultFlangerProps() noexcept
|
|||
|
||||
const EffectProps ChorusEffectProps{genDefaultChorusProps()};
|
||||
|
||||
void ChorusEffectHandler::SetParami(ChorusProps &props, ALenum param, int val)
|
||||
void ChorusEffectHandler::SetParami(ALCcontext *context, ChorusProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -80,89 +84,90 @@ void ChorusEffectHandler::SetParami(ChorusProps &props, ALenum param, int val)
|
|||
if(auto formopt = WaveformFromEnum(val))
|
||||
props.Waveform = *formopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Invalid chorus waveform: 0x%04x", val};
|
||||
break;
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid chorus waveform: {:#04x}",
|
||||
as_unsigned(val));
|
||||
return;
|
||||
|
||||
case AL_CHORUS_PHASE:
|
||||
if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Chorus phase out of range: %d", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Chorus phase out of range: {}", val);
|
||||
props.Phase = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid chorus integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ChorusEffectHandler::SetParamiv(ChorusProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
void ChorusEffectHandler::SetParamf(ChorusProps &props, ALenum param, float val)
|
||||
void ChorusEffectHandler::SetParamiv(ALCcontext *context, ChorusProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void ChorusEffectHandler::SetParamf(ALCcontext *context, ChorusProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_CHORUS_RATE:
|
||||
if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Chorus rate out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Chorus rate out of range: {:f}", val);
|
||||
props.Rate = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_CHORUS_DEPTH:
|
||||
if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Chorus depth out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Chorus depth out of range: {:f}", val);
|
||||
props.Depth = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_CHORUS_FEEDBACK:
|
||||
if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Chorus feedback out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Chorus feedback out of range: {:f}", val);
|
||||
props.Feedback = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_CHORUS_DELAY:
|
||||
if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Chorus delay out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Chorus delay out of range: {:f}", val);
|
||||
props.Delay = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void ChorusEffectHandler::SetParamfv(ChorusProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void ChorusEffectHandler::GetParami(const ChorusProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid chorus float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ChorusEffectHandler::SetParamfv(ALCcontext *context, ChorusProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void ChorusEffectHandler::GetParami(ALCcontext *context, const ChorusProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_CHORUS_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
|
||||
case AL_CHORUS_PHASE: *val = props.Phase; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param};
|
||||
case AL_CHORUS_WAVEFORM: *val = EnumFromWaveform(props.Waveform); return;
|
||||
case AL_CHORUS_PHASE: *val = props.Phase; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid chorus integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ChorusEffectHandler::GetParamiv(const ChorusProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void ChorusEffectHandler::GetParamf(const ChorusProps &props, ALenum param, float *val)
|
||||
void ChorusEffectHandler::GetParamiv(ALCcontext *context, const ChorusProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void ChorusEffectHandler::GetParamf(ALCcontext *context, const ChorusProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_CHORUS_RATE: *val = props.Rate; break;
|
||||
case AL_CHORUS_DEPTH: *val = props.Depth; break;
|
||||
case AL_CHORUS_FEEDBACK: *val = props.Feedback; break;
|
||||
case AL_CHORUS_DELAY: *val = props.Delay; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param};
|
||||
case AL_CHORUS_RATE: *val = props.Rate; return;
|
||||
case AL_CHORUS_DEPTH: *val = props.Depth; return;
|
||||
case AL_CHORUS_FEEDBACK: *val = props.Feedback; return;
|
||||
case AL_CHORUS_DELAY: *val = props.Delay; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid chorus float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ChorusEffectHandler::GetParamfv(const ChorusProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void ChorusEffectHandler::GetParamfv(ALCcontext *context, const ChorusProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
const EffectProps FlangerEffectProps{genDefaultFlangerProps()};
|
||||
|
||||
void FlangerEffectHandler::SetParami(ChorusProps &props, ALenum param, int val)
|
||||
void FlangerEffectHandler::SetParami(ALCcontext *context, ChorusProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -170,87 +175,88 @@ void FlangerEffectHandler::SetParami(ChorusProps &props, ALenum param, int val)
|
|||
if(auto formopt = WaveformFromEnum(val))
|
||||
props.Waveform = *formopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Invalid flanger waveform: 0x%04x", val};
|
||||
break;
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid flanger waveform: {:#04x}",
|
||||
as_unsigned(val));
|
||||
return;
|
||||
|
||||
case AL_FLANGER_PHASE:
|
||||
if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Flanger phase out of range: %d", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Flanger phase out of range: {}", val);
|
||||
props.Phase = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid flanger integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FlangerEffectHandler::SetParamiv(ChorusProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
void FlangerEffectHandler::SetParamf(ChorusProps &props, ALenum param, float val)
|
||||
void FlangerEffectHandler::SetParamiv(ALCcontext *context, ChorusProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void FlangerEffectHandler::SetParamf(ALCcontext *context, ChorusProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FLANGER_RATE:
|
||||
if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Flanger rate out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Flanger rate out of range: {:f}", val);
|
||||
props.Rate = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_FLANGER_DEPTH:
|
||||
if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Flanger depth out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Flanger depth out of range: {:f}", val);
|
||||
props.Depth = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_FLANGER_FEEDBACK:
|
||||
if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Flanger feedback out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Flanger feedback out of range: {:f}", val);
|
||||
props.Feedback = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_FLANGER_DELAY:
|
||||
if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Flanger delay out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Flanger delay out of range: {:f}", val);
|
||||
props.Delay = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void FlangerEffectHandler::SetParamfv(ChorusProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void FlangerEffectHandler::GetParami(const ChorusProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid flanger float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FlangerEffectHandler::SetParamfv(ALCcontext *context, ChorusProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void FlangerEffectHandler::GetParami(ALCcontext *context, const ChorusProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FLANGER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
|
||||
case AL_FLANGER_PHASE: *val = props.Phase; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param};
|
||||
case AL_FLANGER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); return;
|
||||
case AL_FLANGER_PHASE: *val = props.Phase; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid flanger integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FlangerEffectHandler::GetParamiv(const ChorusProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void FlangerEffectHandler::GetParamf(const ChorusProps &props, ALenum param, float *val)
|
||||
void FlangerEffectHandler::GetParamiv(ALCcontext *context, const ChorusProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void FlangerEffectHandler::GetParamf(ALCcontext *context, const ChorusProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FLANGER_RATE: *val = props.Rate; break;
|
||||
case AL_FLANGER_DEPTH: *val = props.Depth; break;
|
||||
case AL_FLANGER_FEEDBACK: *val = props.Feedback; break;
|
||||
case AL_FLANGER_DELAY: *val = props.Delay; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param};
|
||||
case AL_FLANGER_RATE: *val = props.Rate; return;
|
||||
case AL_FLANGER_DEPTH: *val = props.Depth; return;
|
||||
case AL_FLANGER_FEEDBACK: *val = props.Feedback; return;
|
||||
case AL_FLANGER_DELAY: *val = props.Delay; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid flanger float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FlangerEffectHandler::GetParamfv(const ChorusProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void FlangerEffectHandler::GetParamfv(ALCcontext *context, const ChorusProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
struct EaxChorusTraits {
|
||||
|
|
@ -558,6 +564,17 @@ public:
|
|||
al_props_.Depth = props.flDepth;
|
||||
al_props_.Feedback = props.flFeedback;
|
||||
al_props_.Delay = props.flDelay;
|
||||
if(EaxTraceCommits) UNLIKELY
|
||||
{
|
||||
TRACE("Chorus/flanger commit:\n"
|
||||
" Waveform: {}\n"
|
||||
" Phase: {}\n"
|
||||
" Rate: {:f}\n"
|
||||
" Depth: {:f}\n"
|
||||
" Feedback: {:f}\n"
|
||||
" Delay: {:f}", al::to_underlying(al_props_.Waveform), al_props_.Phase,
|
||||
al_props_.Rate, al_props_.Depth, al_props_.Feedback, al_props_.Delay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -28,53 +28,46 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps CompressorEffectProps{genDefaultProps()};
|
||||
|
||||
void CompressorEffectHandler::SetParami(CompressorProps &props, ALenum param, int val)
|
||||
void CompressorEffectHandler::SetParami(ALCcontext *context, CompressorProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_COMPRESSOR_ONOFF:
|
||||
if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Compressor state out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Compressor state out of range");
|
||||
props.OnOff = (val != AL_FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void CompressorEffectHandler::SetParamiv(CompressorProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
void CompressorEffectHandler::SetParamf(CompressorProps&, ALenum param, float)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
|
||||
void CompressorEffectHandler::SetParamfv(CompressorProps&, ALenum param, const float*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
|
||||
void CompressorEffectHandler::GetParami(const CompressorProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid compressor integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void CompressorEffectHandler::SetParamiv(ALCcontext *context, CompressorProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void CompressorEffectHandler::SetParamf(ALCcontext *context, CompressorProps&, ALenum param, float)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid compressor float property {:#04x}", as_unsigned(param)); }
|
||||
void CompressorEffectHandler::SetParamfv(ALCcontext *context, CompressorProps&, ALenum param, const float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid compressor float-vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
void CompressorEffectHandler::GetParami(ALCcontext *context, const CompressorProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_COMPRESSOR_ONOFF: *val = props.OnOff; break;
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x",
|
||||
param};
|
||||
case AL_COMPRESSOR_ONOFF: *val = props.OnOff; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid compressor integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void CompressorEffectHandler::GetParamiv(const CompressorProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void CompressorEffectHandler::GetParamf(const CompressorProps&, ALenum param, float*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
|
||||
void CompressorEffectHandler::GetParamfv(const CompressorProps&, ALenum param, float*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void CompressorEffectHandler::GetParamiv(ALCcontext *context, const CompressorProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void CompressorEffectHandler::GetParamf(ALCcontext *context, const CompressorProps&, ALenum param, float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid compressor float property {:#04x}", as_unsigned(param)); }
|
||||
void CompressorEffectHandler::GetParamfv(ALCcontext *context, const CompressorProps&, ALenum param, float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid compressor float-vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using CompressorCommitter = EaxCommitter<EaxCompressorCommitter>;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
#include "AL/al.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "effects.h"
|
||||
|
||||
|
||||
|
|
@ -28,90 +28,49 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps ConvolutionEffectProps{genDefaultProps()};
|
||||
|
||||
void ConvolutionEffectHandler::SetParami(ConvolutionProps& /*props*/, ALenum param, int /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x",
|
||||
param};
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::SetParamiv(ConvolutionProps &props, ALenum param, const int *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
SetParami(props, param, *vals);
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::SetParamf(ConvolutionProps& /*props*/, ALenum param, float /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x",
|
||||
param};
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::SetParamfv(ConvolutionProps &props, ALenum param, const float *values)
|
||||
void ConvolutionEffectHandler::SetParami(ALCcontext *context, ConvolutionProps& /*props*/, ALenum param, int /*val*/)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect integer property {:#04x}", as_unsigned(param)); }
|
||||
void ConvolutionEffectHandler::SetParamiv(ALCcontext *context, ConvolutionProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
|
||||
void ConvolutionEffectHandler::SetParamf(ALCcontext *context, ConvolutionProps& /*props*/, ALenum param, float /*val*/)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect float property {:#04x}", as_unsigned(param)); }
|
||||
void ConvolutionEffectHandler::SetParamfv(ALCcontext *context, ConvolutionProps &props, ALenum param, const float *values)
|
||||
{
|
||||
static constexpr auto finite_checker = [](float val) -> bool { return std::isfinite(val); };
|
||||
al::span<const float> vals;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_CONVOLUTION_ORIENTATION_SOFT:
|
||||
vals = {values, 6_uz};
|
||||
auto vals = al::span{values, 6_uz};
|
||||
if(!std::all_of(vals.cbegin(), vals.cend(), finite_checker))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Property 0x%04x value out of range", param};
|
||||
context->throw_error(AL_INVALID_VALUE, "Convolution orientation out of range", param);
|
||||
|
||||
std::copy_n(vals.cbegin(), props.OrientAt.size(), props.OrientAt.begin());
|
||||
std::copy_n(vals.cbegin()+3, props.OrientUp.size(), props.OrientUp.begin());
|
||||
break;
|
||||
|
||||
default:
|
||||
SetParamf(props, param, *values);
|
||||
return;
|
||||
}
|
||||
|
||||
SetParamf(context, props, param, *values);
|
||||
}
|
||||
|
||||
void ConvolutionEffectHandler::GetParami(const ConvolutionProps& /*props*/, ALenum param, int* /*val*/)
|
||||
void ConvolutionEffectHandler::GetParami(ALCcontext *context, const ConvolutionProps& /*props*/, ALenum param, int* /*val*/)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect integer property {:#04x}", as_unsigned(param)); }
|
||||
void ConvolutionEffectHandler::GetParamiv(ALCcontext *context, const ConvolutionProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
|
||||
void ConvolutionEffectHandler::GetParamf(ALCcontext *context, const ConvolutionProps& /*props*/, ALenum param, float* /*val*/)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect float property {:#04x}", as_unsigned(param)); }
|
||||
void ConvolutionEffectHandler::GetParamfv(ALCcontext *context, const ConvolutionProps &props, ALenum param, float *values)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x",
|
||||
param};
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::GetParamiv(const ConvolutionProps &props, ALenum param, int *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
GetParami(props, param, vals);
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::GetParamf(const ConvolutionProps& /*props*/, ALenum param, float* /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x",
|
||||
param};
|
||||
}
|
||||
}
|
||||
void ConvolutionEffectHandler::GetParamfv(const ConvolutionProps &props, ALenum param, float *values)
|
||||
{
|
||||
al::span<float> vals;
|
||||
switch(param)
|
||||
{
|
||||
case AL_CONVOLUTION_ORIENTATION_SOFT:
|
||||
vals = {values, 6_uz};
|
||||
auto vals = al::span{values, 6_uz};
|
||||
std::copy(props.OrientAt.cbegin(), props.OrientAt.cend(), vals.begin());
|
||||
std::copy(props.OrientUp.cbegin(), props.OrientUp.cend(), vals.begin()+3);
|
||||
break;
|
||||
|
||||
default:
|
||||
GetParamf(props, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
GetParamf(context, props, param, values);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
|
||||
|
|
@ -32,91 +33,81 @@ constexpr EffectProps genDefaultLfeProps() noexcept
|
|||
|
||||
const EffectProps DedicatedDialogEffectProps{genDefaultDialogProps()};
|
||||
|
||||
void DedicatedDialogEffectHandler::SetParami(DedicatedProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
|
||||
void DedicatedDialogEffectHandler::SetParamiv(DedicatedProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void DedicatedDialogEffectHandler::SetParamf(DedicatedProps &props, ALenum param, float val)
|
||||
void DedicatedDialogEffectHandler::SetParami(ALCcontext *context, DedicatedProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedDialogEffectHandler::SetParamiv(ALCcontext *context, DedicatedProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedDialogEffectHandler::SetParamf(ALCcontext *context, DedicatedProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DEDICATED_GAIN:
|
||||
if(!(val >= 0.0f && std::isfinite(val)))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Dedicated gain out of range");
|
||||
props.Gain = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void DedicatedDialogEffectHandler::SetParamfv(DedicatedProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void DedicatedDialogEffectHandler::GetParami(const DedicatedProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
|
||||
void DedicatedDialogEffectHandler::GetParamiv(const DedicatedProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid dedicated float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DedicatedDialogEffectHandler::GetParamf(const DedicatedProps &props, ALenum param, float *val)
|
||||
void DedicatedDialogEffectHandler::SetParamfv(ALCcontext *context, DedicatedProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void DedicatedDialogEffectHandler::GetParami(ALCcontext *context, const DedicatedProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedDialogEffectHandler::GetParamiv(ALCcontext *context, const DedicatedProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedDialogEffectHandler::GetParamf(ALCcontext *context, const DedicatedProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DEDICATED_GAIN: *val = props.Gain; break;
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
|
||||
case AL_DEDICATED_GAIN: *val = props.Gain; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid dedicated float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DedicatedDialogEffectHandler::GetParamfv(const DedicatedProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void DedicatedDialogEffectHandler::GetParamfv(ALCcontext *context, const DedicatedProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
const EffectProps DedicatedLfeEffectProps{genDefaultLfeProps()};
|
||||
|
||||
void DedicatedLfeEffectHandler::SetParami(DedicatedProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
|
||||
void DedicatedLfeEffectHandler::SetParamiv(DedicatedProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void DedicatedLfeEffectHandler::SetParamf(DedicatedProps &props, ALenum param, float val)
|
||||
void DedicatedLfeEffectHandler::SetParami(ALCcontext *context, DedicatedProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedLfeEffectHandler::SetParamiv(ALCcontext *context, DedicatedProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedLfeEffectHandler::SetParamf(ALCcontext *context, DedicatedProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DEDICATED_GAIN:
|
||||
if(!(val >= 0.0f && std::isfinite(val)))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Dedicated gain out of range");
|
||||
props.Gain = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void DedicatedLfeEffectHandler::SetParamfv(DedicatedProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void DedicatedLfeEffectHandler::GetParami(const DedicatedProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
|
||||
void DedicatedLfeEffectHandler::GetParamiv(const DedicatedProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid dedicated float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DedicatedLfeEffectHandler::GetParamf(const DedicatedProps &props, ALenum param, float *val)
|
||||
void DedicatedLfeEffectHandler::SetParamfv(ALCcontext *context, DedicatedProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void DedicatedLfeEffectHandler::GetParami(ALCcontext *context, const DedicatedProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedLfeEffectHandler::GetParamiv(ALCcontext *context, const DedicatedProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid dedicated integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void DedicatedLfeEffectHandler::GetParamf(ALCcontext *context, const DedicatedProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DEDICATED_GAIN: *val = props.Gain; break;
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
|
||||
case AL_DEDICATED_GAIN: *val = props.Gain; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid dedicated float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DedicatedLfeEffectHandler::GetParamfv(const DedicatedProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void DedicatedLfeEffectHandler::GetParamfv(ALCcontext *context, const DedicatedProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -32,80 +32,76 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps DistortionEffectProps{genDefaultProps()};
|
||||
|
||||
void DistortionEffectHandler::SetParami(DistortionProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
|
||||
void DistortionEffectHandler::SetParamiv(DistortionProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void DistortionEffectHandler::SetParamf(DistortionProps &props, ALenum param, float val)
|
||||
void DistortionEffectHandler::SetParami(ALCcontext *context, DistortionProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid distortion integer property {:#04x}", as_unsigned(param)); }
|
||||
void DistortionEffectHandler::SetParamiv(ALCcontext *context, DistortionProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid distortion integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
void DistortionEffectHandler::SetParamf(ALCcontext *context, DistortionProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DISTORTION_EDGE:
|
||||
if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Distortion edge out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Distortion edge out of range");
|
||||
props.Edge = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_DISTORTION_GAIN:
|
||||
if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Distortion gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Distortion gain out of range");
|
||||
props.Gain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_DISTORTION_LOWPASS_CUTOFF:
|
||||
if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Distortion low-pass cutoff out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Distortion low-pass cutoff out of range");
|
||||
props.LowpassCutoff = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_DISTORTION_EQCENTER:
|
||||
if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Distortion EQ center out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Distortion EQ center out of range");
|
||||
props.EQCenter = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_DISTORTION_EQBANDWIDTH:
|
||||
if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Distortion EQ bandwidth out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Distortion EQ bandwidth out of range");
|
||||
props.EQBandwidth = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void DistortionEffectHandler::SetParamfv(DistortionProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void DistortionEffectHandler::GetParami(const DistortionProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
|
||||
void DistortionEffectHandler::GetParamiv(const DistortionProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid distortion float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DistortionEffectHandler::GetParamf(const DistortionProps &props, ALenum param, float *val)
|
||||
void DistortionEffectHandler::SetParamfv(ALCcontext *context, DistortionProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void DistortionEffectHandler::GetParami(ALCcontext *context, const DistortionProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid distortion integer property {:#04x}", as_unsigned(param)); }
|
||||
void DistortionEffectHandler::GetParamiv(ALCcontext *context, const DistortionProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid distortion integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
void DistortionEffectHandler::GetParamf(ALCcontext *context, const DistortionProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_DISTORTION_EDGE: *val = props.Edge; break;
|
||||
case AL_DISTORTION_GAIN: *val = props.Gain; break;
|
||||
case AL_DISTORTION_LOWPASS_CUTOFF: *val = props.LowpassCutoff; break;
|
||||
case AL_DISTORTION_EQCENTER: *val = props.EQCenter; break;
|
||||
case AL_DISTORTION_EQBANDWIDTH: *val = props.EQBandwidth; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
|
||||
case AL_DISTORTION_EDGE: *val = props.Edge; return;
|
||||
case AL_DISTORTION_GAIN: *val = props.Gain; return;
|
||||
case AL_DISTORTION_LOWPASS_CUTOFF: *val = props.LowpassCutoff; return;
|
||||
case AL_DISTORTION_EQCENTER: *val = props.EQCenter; return;
|
||||
case AL_DISTORTION_EQBANDWIDTH: *val = props.EQBandwidth; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid distortion float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void DistortionEffectHandler::GetParamfv(const DistortionProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void DistortionEffectHandler::GetParamfv(ALCcontext *context, const DistortionProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using DistortionCommitter = EaxCommitter<EaxDistortionCommitter>;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -35,74 +35,74 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps EchoEffectProps{genDefaultProps()};
|
||||
|
||||
void EchoEffectHandler::SetParami(EchoProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
|
||||
void EchoEffectHandler::SetParamiv(EchoProps&, ALenum param, const int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
|
||||
void EchoEffectHandler::SetParamf(EchoProps &props, ALenum param, float val)
|
||||
void EchoEffectHandler::SetParami(ALCcontext *context, EchoProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid echo integer property {:#04x}", as_unsigned(param)); }
|
||||
void EchoEffectHandler::SetParamiv(ALCcontext *context, EchoProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid echo integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void EchoEffectHandler::SetParamf(ALCcontext *context, EchoProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_ECHO_DELAY:
|
||||
if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Echo delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Echo delay out of range");
|
||||
props.Delay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_ECHO_LRDELAY:
|
||||
if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Echo LR delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Echo LR delay out of range");
|
||||
props.LRDelay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_ECHO_DAMPING:
|
||||
if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Echo damping out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Echo damping out of range");
|
||||
props.Damping = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_ECHO_FEEDBACK:
|
||||
if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Echo feedback out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Echo feedback out of range");
|
||||
props.Feedback = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_ECHO_SPREAD:
|
||||
if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Echo spread out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Echo spread out of range");
|
||||
props.Spread = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void EchoEffectHandler::SetParamfv(EchoProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void EchoEffectHandler::GetParami(const EchoProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
|
||||
void EchoEffectHandler::GetParamiv(const EchoProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
|
||||
void EchoEffectHandler::GetParamf(const EchoProps &props, ALenum param, float *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid echo float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void EchoEffectHandler::SetParamfv(ALCcontext *context, EchoProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void EchoEffectHandler::GetParami(ALCcontext *context, const EchoProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid echo integer property {:#04x}", as_unsigned(param)); }
|
||||
void EchoEffectHandler::GetParamiv(ALCcontext *context, const EchoProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid echo integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void EchoEffectHandler::GetParamf(ALCcontext *context, const EchoProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_ECHO_DELAY: *val = props.Delay; break;
|
||||
case AL_ECHO_LRDELAY: *val = props.LRDelay; break;
|
||||
case AL_ECHO_DAMPING: *val = props.Damping; break;
|
||||
case AL_ECHO_FEEDBACK: *val = props.Feedback; break;
|
||||
case AL_ECHO_SPREAD: *val = props.Spread; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
|
||||
case AL_ECHO_DELAY: *val = props.Delay; return;
|
||||
case AL_ECHO_LRDELAY: *val = props.LRDelay; return;
|
||||
case AL_ECHO_DAMPING: *val = props.Damping; return;
|
||||
case AL_ECHO_FEEDBACK: *val = props.Feedback; return;
|
||||
case AL_ECHO_SPREAD: *val = props.Spread; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid echo float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void EchoEffectHandler::GetParamfv(const EchoProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void EchoEffectHandler::GetParamfv(ALCcontext *context, const EchoProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using EchoCommitter = EaxCommitter<EaxEchoCommitter>;
|
||||
|
|
|
|||
|
|
@ -3,23 +3,24 @@
|
|||
|
||||
#include <variant>
|
||||
|
||||
#include "AL/alc.h"
|
||||
#include "AL/al.h"
|
||||
|
||||
#include "al/error.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
#define DECL_HANDLER(N, T) \
|
||||
struct N { \
|
||||
using prop_type = T; \
|
||||
\
|
||||
static void SetParami(prop_type &props, ALenum param, int val); \
|
||||
static void SetParamiv(prop_type &props, ALenum param, const int *vals); \
|
||||
static void SetParamf(prop_type &props, ALenum param, float val); \
|
||||
static void SetParamfv(prop_type &props, ALenum param, const float *vals);\
|
||||
static void GetParami(const prop_type &props, ALenum param, int *val); \
|
||||
static void GetParamiv(const prop_type &props, ALenum param, int *vals); \
|
||||
static void GetParamf(const prop_type &props, ALenum param, float *val); \
|
||||
static void GetParamfv(const prop_type &props, ALenum param, float *vals);\
|
||||
static void SetParami(ALCcontext *context, prop_type &props, ALenum param, int val); \
|
||||
static void SetParamiv(ALCcontext *context, prop_type &props, ALenum param, const int *vals); \
|
||||
static void SetParamf(ALCcontext *context, prop_type &props, ALenum param, float val); \
|
||||
static void SetParamfv(ALCcontext *context, prop_type &props, ALenum param, const float *vals);\
|
||||
static void GetParami(ALCcontext *context, const prop_type &props, ALenum param, int *val); \
|
||||
static void GetParamiv(ALCcontext *context, const prop_type &props, ALenum param, int *vals); \
|
||||
static void GetParamf(ALCcontext *context, const prop_type &props, ALenum param, float *val); \
|
||||
static void GetParamfv(ALCcontext *context, const prop_type &props, ALenum param, float *vals);\
|
||||
};
|
||||
DECL_HANDLER(NullEffectHandler, std::monostate)
|
||||
DECL_HANDLER(ReverbEffectHandler, ReverbProps)
|
||||
|
|
@ -41,26 +42,23 @@ DECL_HANDLER(ConvolutionEffectHandler, ConvolutionProps)
|
|||
#undef DECL_HANDLER
|
||||
|
||||
|
||||
using effect_exception = al::context_error;
|
||||
|
||||
|
||||
/* Default properties for the given effect types. */
|
||||
extern const EffectProps NullEffectProps;
|
||||
extern const EffectProps ReverbEffectProps;
|
||||
extern const EffectProps StdReverbEffectProps;
|
||||
extern const EffectProps AutowahEffectProps;
|
||||
extern const EffectProps ChorusEffectProps;
|
||||
extern const EffectProps CompressorEffectProps;
|
||||
extern const EffectProps DistortionEffectProps;
|
||||
extern const EffectProps EchoEffectProps;
|
||||
extern const EffectProps EqualizerEffectProps;
|
||||
extern const EffectProps FlangerEffectProps;
|
||||
extern const EffectProps FshifterEffectProps;
|
||||
extern const EffectProps ModulatorEffectProps;
|
||||
extern const EffectProps PshifterEffectProps;
|
||||
extern const EffectProps VmorpherEffectProps;
|
||||
extern const EffectProps DedicatedDialogEffectProps;
|
||||
extern const EffectProps DedicatedLfeEffectProps;
|
||||
extern const EffectProps ConvolutionEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps NullEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps ReverbEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps StdReverbEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps AutowahEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps ChorusEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps CompressorEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps DistortionEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps EchoEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps EqualizerEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps FlangerEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps FshifterEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps ModulatorEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps PshifterEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps VmorpherEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps DedicatedDialogEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps DedicatedLfeEffectProps;
|
||||
DECL_HIDDEN extern const EffectProps ConvolutionEffectProps;
|
||||
|
||||
#endif /* AL_EFFECTS_EFFECTS_H */
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -37,115 +37,109 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps EqualizerEffectProps{genDefaultProps()};
|
||||
|
||||
void EqualizerEffectHandler::SetParami(EqualizerProps&, ALenum param, int)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
|
||||
void EqualizerEffectHandler::SetParamiv(EqualizerProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void EqualizerEffectHandler::SetParamf(EqualizerProps &props, ALenum param, float val)
|
||||
void EqualizerEffectHandler::SetParami(ALCcontext *context, EqualizerProps&, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid equalizer integer property {:#04x}", as_unsigned(param)); }
|
||||
void EqualizerEffectHandler::SetParamiv(ALCcontext *context, EqualizerProps&, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid equalizer integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void EqualizerEffectHandler::SetParamf(ALCcontext *context, EqualizerProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EQUALIZER_LOW_GAIN:
|
||||
if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer low-band gain out of range");
|
||||
props.LowGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_LOW_CUTOFF:
|
||||
if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band cutoff out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer low-band cutoff out of range");
|
||||
props.LowCutoff = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID1_GAIN:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid1-band gain out of range");
|
||||
props.Mid1Gain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID1_CENTER:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band center out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid1-band center out of range");
|
||||
props.Mid1Center = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID1_WIDTH:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band width out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid1-band width out of range");
|
||||
props.Mid1Width = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID2_GAIN:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid2-band gain out of range");
|
||||
props.Mid2Gain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID2_CENTER:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band center out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid2-band center out of range");
|
||||
props.Mid2Center = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_MID2_WIDTH:
|
||||
if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band width out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer mid2-band width out of range");
|
||||
props.Mid2Width = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_HIGH_GAIN:
|
||||
if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer high-band gain out of range");
|
||||
props.HighGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EQUALIZER_HIGH_CUTOFF:
|
||||
if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band cutoff out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Equalizer high-band cutoff out of range");
|
||||
props.HighCutoff = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void EqualizerEffectHandler::SetParamfv(EqualizerProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void EqualizerEffectHandler::GetParami(const EqualizerProps&, ALenum param, int*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
|
||||
void EqualizerEffectHandler::GetParamiv(const EqualizerProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid equalizer float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void EqualizerEffectHandler::GetParamf(const EqualizerProps &props, ALenum param, float *val)
|
||||
void EqualizerEffectHandler::SetParamfv(ALCcontext *context, EqualizerProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void EqualizerEffectHandler::GetParami(ALCcontext *context, const EqualizerProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid equalizer integer property {:#04x}", as_unsigned(param)); }
|
||||
void EqualizerEffectHandler::GetParamiv(ALCcontext *context, const EqualizerProps&, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid equalizer integer-vector property {:#04x}", as_unsigned(param)); }
|
||||
void EqualizerEffectHandler::GetParamf(ALCcontext *context, const EqualizerProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EQUALIZER_LOW_GAIN: *val = props.LowGain; break;
|
||||
case AL_EQUALIZER_LOW_CUTOFF: *val = props.LowCutoff; break;
|
||||
case AL_EQUALIZER_MID1_GAIN: *val = props.Mid1Gain; break;
|
||||
case AL_EQUALIZER_MID1_CENTER: *val = props.Mid1Center; break;
|
||||
case AL_EQUALIZER_MID1_WIDTH: *val = props.Mid1Width; break;
|
||||
case AL_EQUALIZER_MID2_GAIN: *val = props.Mid2Gain; break;
|
||||
case AL_EQUALIZER_MID2_CENTER: *val = props.Mid2Center; break;
|
||||
case AL_EQUALIZER_MID2_WIDTH: *val = props.Mid2Width; break;
|
||||
case AL_EQUALIZER_HIGH_GAIN: *val = props.HighGain; break;
|
||||
case AL_EQUALIZER_HIGH_CUTOFF: *val = props.HighCutoff; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
|
||||
case AL_EQUALIZER_LOW_GAIN: *val = props.LowGain; return;
|
||||
case AL_EQUALIZER_LOW_CUTOFF: *val = props.LowCutoff; return;
|
||||
case AL_EQUALIZER_MID1_GAIN: *val = props.Mid1Gain; return;
|
||||
case AL_EQUALIZER_MID1_CENTER: *val = props.Mid1Center; return;
|
||||
case AL_EQUALIZER_MID1_WIDTH: *val = props.Mid1Width; return;
|
||||
case AL_EQUALIZER_MID2_GAIN: *val = props.Mid2Gain; return;
|
||||
case AL_EQUALIZER_MID2_CENTER: *val = props.Mid2Center; return;
|
||||
case AL_EQUALIZER_MID2_WIDTH: *val = props.Mid2Width; return;
|
||||
case AL_EQUALIZER_HIGH_GAIN: *val = props.HighGain; return;
|
||||
case AL_EQUALIZER_HIGH_CUTOFF: *val = props.HighCutoff; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid equalizer float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void EqualizerEffectHandler::GetParamfv(const EqualizerProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void EqualizerEffectHandler::GetParamfv(ALCcontext *context, const EqualizerProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using EqualizerCommitter = EaxCommitter<EaxEqualizerCommitter>;
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <cassert>
|
||||
#include "alnumeric.h"
|
||||
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -39,7 +40,7 @@ constexpr ALenum EnumFromDirection(FShifterDirection dir)
|
|||
case FShifterDirection::Up: return AL_FREQUENCY_SHIFTER_DIRECTION_UP;
|
||||
case FShifterDirection::Off: return AL_FREQUENCY_SHIFTER_DIRECTION_OFF;
|
||||
}
|
||||
throw std::runtime_error{"Invalid direction: "+std::to_string(static_cast<int>(dir))};
|
||||
throw std::runtime_error{fmt::format("Invalid direction: {}", int{al::to_underlying(dir)})};
|
||||
}
|
||||
|
||||
constexpr EffectProps genDefaultProps() noexcept
|
||||
|
|
@ -55,7 +56,7 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps FshifterEffectProps{genDefaultProps()};
|
||||
|
||||
void FshifterEffectHandler::SetParami(FshifterProps &props, ALenum param, int val)
|
||||
void FshifterEffectHandler::SetParami(ALCcontext *context, FshifterProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -63,81 +64,75 @@ void FshifterEffectHandler::SetParami(FshifterProps &props, ALenum param, int va
|
|||
if(auto diropt = DirectionFromEmum(val))
|
||||
props.LeftDirection = *diropt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE,
|
||||
"Unsupported frequency shifter left direction: 0x%04x", val};
|
||||
break;
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Unsupported frequency shifter left direction: {:#04x}", as_unsigned(val));
|
||||
return;
|
||||
|
||||
case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
|
||||
if(auto diropt = DirectionFromEmum(val))
|
||||
props.RightDirection = *diropt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE,
|
||||
"Unsupported frequency shifter right direction: 0x%04x", val};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM,
|
||||
"Invalid frequency shifter integer property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Unsupported frequency shifter right direction: {:#04x}", as_unsigned(val));
|
||||
return;
|
||||
}
|
||||
}
|
||||
void FshifterEffectHandler::SetParamiv(FshifterProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
|
||||
void FshifterEffectHandler::SetParamf(FshifterProps &props, ALenum param, float val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid frequency shifter integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FshifterEffectHandler::SetParamiv(ALCcontext *context, FshifterProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
|
||||
void FshifterEffectHandler::SetParamf(ALCcontext *context, FshifterProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FREQUENCY_SHIFTER_FREQUENCY:
|
||||
if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Frequency shifter frequency out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Frequency shifter frequency out of range");
|
||||
props.Frequency = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void FshifterEffectHandler::SetParamfv(FshifterProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void FshifterEffectHandler::GetParami(const FshifterProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid frequency shifter float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FshifterEffectHandler::SetParamfv(ALCcontext *context, FshifterProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void FshifterEffectHandler::GetParami(ALCcontext *context, const FshifterProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION:
|
||||
*val = EnumFromDirection(props.LeftDirection);
|
||||
break;
|
||||
return;
|
||||
case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
|
||||
*val = EnumFromDirection(props.RightDirection);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM,
|
||||
"Invalid frequency shifter integer property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void FshifterEffectHandler::GetParamiv(const FshifterProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
|
||||
void FshifterEffectHandler::GetParamf(const FshifterProps &props, ALenum param, float *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid frequency shifter integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FshifterEffectHandler::GetParamiv(ALCcontext *context, const FshifterProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
|
||||
void FshifterEffectHandler::GetParamf(ALCcontext *context, const FshifterProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_FREQUENCY_SHIFTER_FREQUENCY:
|
||||
*val = props.Frequency;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x",
|
||||
param};
|
||||
case AL_FREQUENCY_SHIFTER_FREQUENCY: *val = props.Frequency; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid frequency shifter float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void FshifterEffectHandler::GetParamfv(const FshifterProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void FshifterEffectHandler::GetParamfv(ALCcontext *context, const FshifterProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using FrequencyShifterCommitter = EaxCommitter<EaxFrequencyShifterCommitter>;
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <cassert>
|
||||
#include "alnumeric.h"
|
||||
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -39,8 +40,8 @@ constexpr ALenum EnumFromWaveform(ModulatorWaveform type)
|
|||
case ModulatorWaveform::Sawtooth: return AL_RING_MODULATOR_SAWTOOTH;
|
||||
case ModulatorWaveform::Square: return AL_RING_MODULATOR_SQUARE;
|
||||
}
|
||||
throw std::runtime_error{"Invalid modulator waveform: " +
|
||||
std::to_string(static_cast<int>(type))};
|
||||
throw std::runtime_error{fmt::format("Invalid modulator waveform: {}",
|
||||
int{al::to_underlying(type)})};
|
||||
}
|
||||
|
||||
constexpr EffectProps genDefaultProps() noexcept
|
||||
|
|
@ -56,84 +57,84 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps ModulatorEffectProps{genDefaultProps()};
|
||||
|
||||
void ModulatorEffectHandler::SetParami(ModulatorProps &props, ALenum param, int val)
|
||||
void ModulatorEffectHandler::SetParami(ALCcontext *context, ModulatorProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_RING_MODULATOR_FREQUENCY:
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
|
||||
SetParamf(props, param, static_cast<float>(val));
|
||||
break;
|
||||
SetParamf(context, props, param, static_cast<float>(val));
|
||||
return;
|
||||
|
||||
case AL_RING_MODULATOR_WAVEFORM:
|
||||
if(auto formopt = WaveformFromEmum(val))
|
||||
props.Waveform = *formopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Invalid modulator waveform: 0x%04x", val};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid modulator waveform: {:#04x}",
|
||||
as_unsigned(val));
|
||||
return;
|
||||
}
|
||||
}
|
||||
void ModulatorEffectHandler::SetParamiv(ModulatorProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
|
||||
void ModulatorEffectHandler::SetParamf(ModulatorProps &props, ALenum param, float val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid modulator integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ModulatorEffectHandler::SetParamiv(ALCcontext *context, ModulatorProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
|
||||
void ModulatorEffectHandler::SetParamf(ALCcontext *context, ModulatorProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_RING_MODULATOR_FREQUENCY:
|
||||
if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Modulator frequency out of range: {:f}", val);
|
||||
props.Frequency = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
|
||||
if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: {:f}",
|
||||
val);
|
||||
props.HighPassCutoff = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void ModulatorEffectHandler::SetParamfv(ModulatorProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void ModulatorEffectHandler::GetParami(const ModulatorProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid modulator float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ModulatorEffectHandler::SetParamfv(ALCcontext *context, ModulatorProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void ModulatorEffectHandler::GetParami(ALCcontext *context, const ModulatorProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_RING_MODULATOR_FREQUENCY: *val = static_cast<int>(props.Frequency); break;
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = static_cast<int>(props.HighPassCutoff); break;
|
||||
case AL_RING_MODULATOR_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x",
|
||||
param};
|
||||
case AL_RING_MODULATOR_FREQUENCY: *val = static_cast<int>(props.Frequency); return;
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = static_cast<int>(props.HighPassCutoff); return;
|
||||
case AL_RING_MODULATOR_WAVEFORM: *val = EnumFromWaveform(props.Waveform); return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid modulator integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ModulatorEffectHandler::GetParamiv(const ModulatorProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void ModulatorEffectHandler::GetParamf(const ModulatorProps &props, ALenum param, float *val)
|
||||
void ModulatorEffectHandler::GetParamiv(ALCcontext *context, const ModulatorProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void ModulatorEffectHandler::GetParamf(ALCcontext *context, const ModulatorProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_RING_MODULATOR_FREQUENCY: *val = props.Frequency; break;
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = props.HighPassCutoff; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param};
|
||||
case AL_RING_MODULATOR_FREQUENCY: *val = props.Frequency; return;
|
||||
case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = props.HighPassCutoff; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid modulator float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ModulatorEffectHandler::GetParamfv(const ModulatorProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void ModulatorEffectHandler::GetParamfv(ALCcontext *context, const ModulatorProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using ModulatorCommitter = EaxCommitter<EaxModulatorCommitter>;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#endif // ALSOFT_EAX
|
||||
|
|
@ -24,78 +25,46 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps NullEffectProps{genDefaultProps()};
|
||||
|
||||
void NullEffectHandler::SetParami(std::monostate& /*props*/, ALenum param, int /*val*/)
|
||||
void NullEffectHandler::SetParami(ALCcontext *context, std::monostate& /*props*/, ALenum param, int /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x",
|
||||
param};
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid null effect integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void NullEffectHandler::SetParamiv(std::monostate &props, ALenum param, const int *vals)
|
||||
void NullEffectHandler::SetParamiv(ALCcontext *context, std::monostate &props, ALenum param, const int *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
SetParami(props, param, *vals);
|
||||
}
|
||||
SetParami(context, props, param, *vals);
|
||||
}
|
||||
void NullEffectHandler::SetParamf(std::monostate& /*props*/, ALenum param, float /*val*/)
|
||||
void NullEffectHandler::SetParamf(ALCcontext *context, std::monostate& /*props*/, ALenum param, float /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x",
|
||||
param};
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid null effect float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void NullEffectHandler::SetParamfv(std::monostate &props, ALenum param, const float *vals)
|
||||
void NullEffectHandler::SetParamfv(ALCcontext *context, std::monostate &props, ALenum param, const float *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
SetParamf(props, param, *vals);
|
||||
}
|
||||
SetParamf(context, props, param, *vals);
|
||||
}
|
||||
|
||||
void NullEffectHandler::GetParami(const std::monostate& /*props*/, ALenum param, int* /*val*/)
|
||||
void NullEffectHandler::GetParami(ALCcontext *context, const std::monostate& /*props*/, ALenum param, int* /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x",
|
||||
param};
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid null effect integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void NullEffectHandler::GetParamiv(const std::monostate &props, ALenum param, int *vals)
|
||||
void NullEffectHandler::GetParamiv(ALCcontext *context, const std::monostate &props, ALenum param, int *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
GetParami(props, param, vals);
|
||||
}
|
||||
GetParami(context, props, param, vals);
|
||||
}
|
||||
void NullEffectHandler::GetParamf(const std::monostate& /*props*/, ALenum param, float* /*val*/)
|
||||
void NullEffectHandler::GetParamf(ALCcontext *context, const std::monostate& /*props*/, ALenum param, float* /*val*/)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x",
|
||||
param};
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid null effect float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void NullEffectHandler::GetParamfv(const std::monostate &props, ALenum param, float *vals)
|
||||
void NullEffectHandler::GetParamfv(ALCcontext *context, const std::monostate &props, ALenum param, float *vals)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
GetParamf(props, param, vals);
|
||||
}
|
||||
GetParamf(context, props, param, vals);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using NullCommitter = EaxCommitter<EaxNullCommitter>;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alnumeric.h"
|
||||
#if ALSOFT_EAX
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
#include "al/eax/utils.h"
|
||||
|
|
@ -29,63 +29,55 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps PshifterEffectProps{genDefaultProps()};
|
||||
|
||||
void PshifterEffectHandler::SetParami(PshifterProps &props, ALenum param, int val)
|
||||
void PshifterEffectHandler::SetParami(ALCcontext *context, PshifterProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_PITCH_SHIFTER_COARSE_TUNE:
|
||||
if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Pitch shifter coarse tune out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Pitch shifter coarse tune out of range");
|
||||
props.CoarseTune = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_PITCH_SHIFTER_FINE_TUNE:
|
||||
if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Pitch shifter fine tune out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Pitch shifter fine tune out of range");
|
||||
props.FineTune = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void PshifterEffectHandler::SetParamiv(PshifterProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
|
||||
void PshifterEffectHandler::SetParamf(PshifterProps&, ALenum param, float)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
|
||||
void PshifterEffectHandler::SetParamfv(PshifterProps&, ALenum param, const float*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void PshifterEffectHandler::SetParamiv(ALCcontext *context, PshifterProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
|
||||
void PshifterEffectHandler::GetParami(const PshifterProps &props, ALenum param, int *val)
|
||||
void PshifterEffectHandler::SetParamf(ALCcontext *context, PshifterProps&, ALenum param, float)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter float property {:#04x}", as_unsigned(param)); }
|
||||
void PshifterEffectHandler::SetParamfv(ALCcontext *context, PshifterProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void PshifterEffectHandler::GetParami(ALCcontext *context, const PshifterProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; break;
|
||||
case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
|
||||
param};
|
||||
case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; return;
|
||||
case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void PshifterEffectHandler::GetParamiv(const PshifterProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void PshifterEffectHandler::GetParamiv(ALCcontext *context, const PshifterProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
|
||||
void PshifterEffectHandler::GetParamf(const PshifterProps&, ALenum param, float*)
|
||||
{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
|
||||
void PshifterEffectHandler::GetParamfv(const PshifterProps&, ALenum param, float*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void PshifterEffectHandler::GetParamf(ALCcontext *context, const PshifterProps&, ALenum param, float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter float property {:#04x}", as_unsigned(param)); }
|
||||
void PshifterEffectHandler::GetParamfv(ALCcontext *context, const PshifterProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using PitchShifterCommitter = EaxCommitter<EaxPitchShifterCommitter>;
|
||||
|
|
|
|||
|
|
@ -9,13 +9,17 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "core/logging.h"
|
||||
#include "effects.h"
|
||||
#include "fmt/ranges.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <cassert>
|
||||
|
||||
#include "al/eax/api.h"
|
||||
#include "al/eax/call.h"
|
||||
#include "al/eax/effect.h"
|
||||
|
|
@ -92,152 +96,149 @@ constexpr EffectProps genDefaultStdProps() noexcept
|
|||
|
||||
const EffectProps ReverbEffectProps{genDefaultProps()};
|
||||
|
||||
void ReverbEffectHandler::SetParami(ReverbProps &props, ALenum param, int val)
|
||||
void ReverbEffectHandler::SetParami(ALCcontext *context, ReverbProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EAXREVERB_DECAY_HFLIMIT:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range");
|
||||
props.DecayHFLimit = val != AL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ReverbEffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
void ReverbEffectHandler::SetParamf(ReverbProps &props, ALenum param, float val)
|
||||
void ReverbEffectHandler::SetParamiv(ALCcontext *context, ReverbProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void ReverbEffectHandler::SetParamf(ALCcontext *context, ReverbProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EAXREVERB_DENSITY:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb density out of range");
|
||||
props.Density = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_DIFFUSION:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb diffusion out of range");
|
||||
props.Diffusion = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_GAIN:
|
||||
if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb gain out of range");
|
||||
props.Gain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_GAINHF:
|
||||
if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb gainhf out of range");
|
||||
props.GainHF = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_GAINLF:
|
||||
if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainlf out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb gainlf out of range");
|
||||
props.GainLF = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_DECAY_TIME:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay time out of range");
|
||||
props.DecayTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_DECAY_HFRATIO:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range");
|
||||
props.DecayHFRatio = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_DECAY_LFRATIO:
|
||||
if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range");
|
||||
props.DecayLFRatio = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_REFLECTIONS_GAIN:
|
||||
if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb reflections gain out of range");
|
||||
props.ReflectionsGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_REFLECTIONS_DELAY:
|
||||
if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb reflections delay out of range");
|
||||
props.ReflectionsDelay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_LATE_REVERB_GAIN:
|
||||
if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range");
|
||||
props.LateReverbGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_LATE_REVERB_DELAY:
|
||||
if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range");
|
||||
props.LateReverbDelay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_ECHO_TIME:
|
||||
if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb echo time out of range");
|
||||
props.EchoTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_ECHO_DEPTH:
|
||||
if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo depth out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb echo depth out of range");
|
||||
props.EchoDepth = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_MODULATION_TIME:
|
||||
if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb modulation time out of range");
|
||||
props.ModulationTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_MODULATION_DEPTH:
|
||||
if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation depth out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb modulation depth out of range");
|
||||
props.ModulationDepth = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
|
||||
if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range");
|
||||
props.AirAbsorptionGainHF = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_HFREFERENCE:
|
||||
if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb hfreference out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb hfreference out of range");
|
||||
props.HFReference = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_LFREFERENCE:
|
||||
if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb lfreference out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb lfreference out of range");
|
||||
props.LFReference = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
|
||||
if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range");
|
||||
props.RoomRolloffFactor = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ReverbEffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals)
|
||||
void ReverbEffectHandler::SetParamfv(ALCcontext *context, ReverbProps &props, ALenum param, const float *vals)
|
||||
{
|
||||
static constexpr auto finite_checker = [](float f) -> bool { return std::isfinite(f); };
|
||||
al::span<const float> values;
|
||||
|
|
@ -246,64 +247,60 @@ void ReverbEffectHandler::SetParamfv(ReverbProps &props, ALenum param, const flo
|
|||
case AL_EAXREVERB_REFLECTIONS_PAN:
|
||||
values = {vals, 3_uz};
|
||||
if(!std::all_of(values.cbegin(), values.cend(), finite_checker))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections pan out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb reflections pan out of range");
|
||||
std::copy(values.cbegin(), values.cend(), props.ReflectionsPan.begin());
|
||||
break;
|
||||
return;
|
||||
case AL_EAXREVERB_LATE_REVERB_PAN:
|
||||
values = {vals, 3_uz};
|
||||
if(!std::all_of(values.cbegin(), values.cend(), finite_checker))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range");
|
||||
std::copy(values.cbegin(), values.cend(), props.LateReverbPan.begin());
|
||||
break;
|
||||
|
||||
default:
|
||||
SetParamf(props, param, *vals);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
SetParamf(context, props, param, *vals);
|
||||
}
|
||||
|
||||
void ReverbEffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val)
|
||||
void ReverbEffectHandler::GetParami(ALCcontext *context, const ReverbProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EAXREVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; break;
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
|
||||
param};
|
||||
case AL_EAXREVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; return;
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ReverbEffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void ReverbEffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val)
|
||||
void ReverbEffectHandler::GetParamiv(ALCcontext *context, const ReverbProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void ReverbEffectHandler::GetParamf(ALCcontext *context, const ReverbProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_EAXREVERB_DENSITY: *val = props.Density; break;
|
||||
case AL_EAXREVERB_DIFFUSION: *val = props.Diffusion; break;
|
||||
case AL_EAXREVERB_GAIN: *val = props.Gain; break;
|
||||
case AL_EAXREVERB_GAINHF: *val = props.GainHF; break;
|
||||
case AL_EAXREVERB_GAINLF: *val = props.GainLF; break;
|
||||
case AL_EAXREVERB_DECAY_TIME: *val = props.DecayTime; break;
|
||||
case AL_EAXREVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
|
||||
case AL_EAXREVERB_DECAY_LFRATIO: *val = props.DecayLFRatio; break;
|
||||
case AL_EAXREVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
|
||||
case AL_EAXREVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
|
||||
case AL_EAXREVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
|
||||
case AL_EAXREVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
|
||||
case AL_EAXREVERB_ECHO_TIME: *val = props.EchoTime; break;
|
||||
case AL_EAXREVERB_ECHO_DEPTH: *val = props.EchoDepth; break;
|
||||
case AL_EAXREVERB_MODULATION_TIME: *val = props.ModulationTime; break;
|
||||
case AL_EAXREVERB_MODULATION_DEPTH: *val = props.ModulationDepth; break;
|
||||
case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
|
||||
case AL_EAXREVERB_HFREFERENCE: *val = props.HFReference; break;
|
||||
case AL_EAXREVERB_LFREFERENCE: *val = props.LFReference; break;
|
||||
case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
|
||||
case AL_EAXREVERB_DENSITY: *val = props.Density; return;
|
||||
case AL_EAXREVERB_DIFFUSION: *val = props.Diffusion; return;
|
||||
case AL_EAXREVERB_GAIN: *val = props.Gain; return;
|
||||
case AL_EAXREVERB_GAINHF: *val = props.GainHF; return;
|
||||
case AL_EAXREVERB_GAINLF: *val = props.GainLF; return;
|
||||
case AL_EAXREVERB_DECAY_TIME: *val = props.DecayTime; return;
|
||||
case AL_EAXREVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; return;
|
||||
case AL_EAXREVERB_DECAY_LFRATIO: *val = props.DecayLFRatio; return;
|
||||
case AL_EAXREVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; return;
|
||||
case AL_EAXREVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; return;
|
||||
case AL_EAXREVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; return;
|
||||
case AL_EAXREVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; return;
|
||||
case AL_EAXREVERB_ECHO_TIME: *val = props.EchoTime; return;
|
||||
case AL_EAXREVERB_ECHO_DEPTH: *val = props.EchoDepth; return;
|
||||
case AL_EAXREVERB_MODULATION_TIME: *val = props.ModulationTime; return;
|
||||
case AL_EAXREVERB_MODULATION_DEPTH: *val = props.ModulationDepth; return;
|
||||
case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; return;
|
||||
case AL_EAXREVERB_HFREFERENCE: *val = props.HFReference; return;
|
||||
case AL_EAXREVERB_LFREFERENCE: *val = props.LFReference; return;
|
||||
case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void ReverbEffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals)
|
||||
void ReverbEffectHandler::GetParamfv(ALCcontext *context, const ReverbProps &props, ALenum param, float *vals)
|
||||
{
|
||||
al::span<float> values;
|
||||
switch(param)
|
||||
|
|
@ -311,159 +308,155 @@ void ReverbEffectHandler::GetParamfv(const ReverbProps &props, ALenum param, flo
|
|||
case AL_EAXREVERB_REFLECTIONS_PAN:
|
||||
values = {vals, 3_uz};
|
||||
std::copy(props.ReflectionsPan.cbegin(), props.ReflectionsPan.cend(), values.begin());
|
||||
break;
|
||||
return;
|
||||
case AL_EAXREVERB_LATE_REVERB_PAN:
|
||||
values = {vals, 3_uz};
|
||||
std::copy(props.LateReverbPan.cbegin(), props.LateReverbPan.cend(), values.begin());
|
||||
break;
|
||||
|
||||
default:
|
||||
GetParamf(props, param, vals);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
GetParamf(context, props, param, vals);
|
||||
}
|
||||
|
||||
|
||||
const EffectProps StdReverbEffectProps{genDefaultStdProps()};
|
||||
|
||||
void StdReverbEffectHandler::SetParami(ReverbProps &props, ALenum param, int val)
|
||||
void StdReverbEffectHandler::SetParami(ALCcontext *context, ReverbProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_REVERB_DECAY_HFLIMIT:
|
||||
if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range");
|
||||
props.DecayHFLimit = val != AL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void StdReverbEffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(props, param, *vals); }
|
||||
void StdReverbEffectHandler::SetParamf(ReverbProps &props, ALenum param, float val)
|
||||
void StdReverbEffectHandler::SetParamiv(ALCcontext *context, ReverbProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void StdReverbEffectHandler::SetParamf(ALCcontext *context, ReverbProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_REVERB_DENSITY:
|
||||
if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb density out of range");
|
||||
props.Density = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_DIFFUSION:
|
||||
if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb diffusion out of range");
|
||||
props.Diffusion = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_GAIN:
|
||||
if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb gain out of range");
|
||||
props.Gain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_GAINHF:
|
||||
if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb gainhf out of range");
|
||||
props.GainHF = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_DECAY_TIME:
|
||||
if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay time out of range");
|
||||
props.DecayTime = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_DECAY_HFRATIO:
|
||||
if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range");
|
||||
props.DecayHFRatio = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_REFLECTIONS_GAIN:
|
||||
if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb reflections gain out of range");
|
||||
props.ReflectionsGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_REFLECTIONS_DELAY:
|
||||
if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb reflections delay out of range");
|
||||
props.ReflectionsDelay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_LATE_REVERB_GAIN:
|
||||
if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range");
|
||||
props.LateReverbGain = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_LATE_REVERB_DELAY:
|
||||
if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range");
|
||||
props.LateReverbDelay = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_AIR_ABSORPTION_GAINHF:
|
||||
if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range");
|
||||
props.AirAbsorptionGainHF = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_REVERB_ROOM_ROLLOFF_FACTOR:
|
||||
if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR))
|
||||
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range");
|
||||
props.RoomRolloffFactor = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void StdReverbEffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void StdReverbEffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void StdReverbEffectHandler::SetParamfv(ALCcontext *context, ReverbProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void StdReverbEffectHandler::GetParami(ALCcontext *context, const ReverbProps &props, ALenum param, int *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_REVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; break;
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
|
||||
param};
|
||||
case AL_REVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; return;
|
||||
}
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void StdReverbEffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
|
||||
{ GetParami(props, param, vals); }
|
||||
void StdReverbEffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val)
|
||||
void StdReverbEffectHandler::GetParamiv(ALCcontext *context, const ReverbProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void StdReverbEffectHandler::GetParamf(ALCcontext *context, const ReverbProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_REVERB_DENSITY: *val = props.Density; break;
|
||||
case AL_REVERB_DIFFUSION: *val = props.Diffusion; break;
|
||||
case AL_REVERB_GAIN: *val = props.Gain; break;
|
||||
case AL_REVERB_GAINHF: *val = props.GainHF; break;
|
||||
case AL_REVERB_DECAY_TIME: *val = props.DecayTime; break;
|
||||
case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
|
||||
case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
|
||||
case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
|
||||
case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
|
||||
case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
|
||||
case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
|
||||
case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
|
||||
case AL_REVERB_DENSITY: *val = props.Density; return;
|
||||
case AL_REVERB_DIFFUSION: *val = props.Diffusion; return;
|
||||
case AL_REVERB_GAIN: *val = props.Gain; return;
|
||||
case AL_REVERB_GAINHF: *val = props.GainHF; return;
|
||||
case AL_REVERB_DECAY_TIME: *val = props.DecayTime; return;
|
||||
case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; return;
|
||||
case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; return;
|
||||
case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; return;
|
||||
case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; return;
|
||||
case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; return;
|
||||
case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; return;
|
||||
case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid EAX reverb float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void StdReverbEffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void StdReverbEffectHandler::GetParamfv(ALCcontext *context, const ReverbProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
class EaxReverbEffectException : public EaxException
|
||||
|
|
@ -1064,6 +1057,38 @@ bool EaxReverbCommitter::commit(const EAXREVERBPROPERTIES &props)
|
|||
ret.LFReference = props.flLFReference;
|
||||
ret.RoomRolloffFactor = props.flRoomRolloffFactor;
|
||||
ret.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
|
||||
if(EaxTraceCommits) UNLIKELY
|
||||
{
|
||||
TRACE("Reverb commit:\n"
|
||||
" Density: {:f}\n"
|
||||
" Diffusion: {:f}\n"
|
||||
" Gain: {:f}\n"
|
||||
" GainHF: {:f}\n"
|
||||
" GainLF: {:f}\n"
|
||||
" DecayTime: {:f}\n"
|
||||
" DecayHFRatio: {:f}\n"
|
||||
" DecayLFRatio: {:f}\n"
|
||||
" ReflectionsGain: {:f}\n"
|
||||
" ReflectionsDelay: {:f}\n"
|
||||
" ReflectionsPan: {}\n"
|
||||
" LateReverbGain: {:f}\n"
|
||||
" LateReverbDelay: {:f}\n"
|
||||
" LateRevernPan: {}\n"
|
||||
" EchoTime: {:f}\n"
|
||||
" EchoDepth: {:f}\n"
|
||||
" ModulationTime: {:f}\n"
|
||||
" ModulationDepth: {:f}\n"
|
||||
" AirAbsorptionGainHF: {:f}\n"
|
||||
" HFReference: {:f}\n"
|
||||
" LFReference: {:f}\n"
|
||||
" RoomRolloffFactor: {:f}\n"
|
||||
" DecayHFLimit: {}", ret.Density, ret.Diffusion, ret.Gain, ret.GainHF, ret.GainLF,
|
||||
ret.DecayTime, ret.DecayHFRatio, ret.DecayLFRatio, ret.ReflectionsGain,
|
||||
ret.ReflectionsDelay, ret.ReflectionsPan, ret.LateReverbGain, ret.LateReverbDelay,
|
||||
ret.LateReverbPan, ret.EchoTime, ret.EchoDepth, ret.ModulationTime,
|
||||
ret.ModulationDepth, ret.AirAbsorptionGainHF, ret.HFReference, ret.LFReference,
|
||||
ret.RoomRolloffFactor, ret.DecayHFLimit ? "true" : "false");
|
||||
}
|
||||
return ret;
|
||||
}();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@
|
|||
#include "AL/al.h"
|
||||
#include "AL/efx.h"
|
||||
|
||||
#include "core/effects/base.h"
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include <cassert>
|
||||
#include "al/eax/effect.h"
|
||||
#include "al/eax/exception.h"
|
||||
|
|
@ -96,7 +97,7 @@ constexpr ALenum EnumFromPhenome(VMorpherPhenome phenome)
|
|||
HANDLE_PHENOME(V);
|
||||
HANDLE_PHENOME(Z);
|
||||
}
|
||||
throw std::runtime_error{"Invalid phenome: "+std::to_string(static_cast<int>(phenome))};
|
||||
throw std::runtime_error{fmt::format("Invalid phenome: {}", int{al::to_underlying(phenome)})};
|
||||
#undef HANDLE_PHENOME
|
||||
}
|
||||
|
||||
|
|
@ -118,8 +119,8 @@ constexpr ALenum EnumFromWaveform(VMorpherWaveform type)
|
|||
case VMorpherWaveform::Triangle: return AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE;
|
||||
case VMorpherWaveform::Sawtooth: return AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH;
|
||||
}
|
||||
throw std::runtime_error{"Invalid vocal morpher waveform: " +
|
||||
std::to_string(static_cast<int>(type))};
|
||||
throw std::runtime_error{fmt::format("Invalid vocal morpher waveform: {}",
|
||||
int{al::to_underlying(type)})};
|
||||
}
|
||||
|
||||
constexpr EffectProps genDefaultProps() noexcept
|
||||
|
|
@ -138,7 +139,7 @@ constexpr EffectProps genDefaultProps() noexcept
|
|||
|
||||
const EffectProps VmorpherEffectProps{genDefaultProps()};
|
||||
|
||||
void VmorpherEffectHandler::SetParami(VmorpherProps &props, ALenum param, int val)
|
||||
void VmorpherEffectHandler::SetParami(ALCcontext *context, VmorpherProps &props, ALenum param, int val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -146,101 +147,94 @@ void VmorpherEffectHandler::SetParami(VmorpherProps &props, ALenum param, int va
|
|||
if(auto phenomeopt = PhenomeFromEnum(val))
|
||||
props.PhonemeA = *phenomeopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a out of range: 0x%04x", val};
|
||||
break;
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Vocal morpher phoneme-a out of range: {:#04x}", as_unsigned(val));
|
||||
return;
|
||||
|
||||
case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING:
|
||||
if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a coarse tuning out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Vocal morpher phoneme-a coarse tuning out of range");
|
||||
props.PhonemeACoarseTuning = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_VOCAL_MORPHER_PHONEMEB:
|
||||
if(auto phenomeopt = PhenomeFromEnum(val))
|
||||
props.PhonemeB = *phenomeopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b out of range: 0x%04x", val};
|
||||
break;
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Vocal morpher phoneme-b out of range: {:#04x}", as_unsigned(val));
|
||||
return;
|
||||
|
||||
case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING:
|
||||
if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b coarse tuning out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE,
|
||||
"Vocal morpher phoneme-b coarse tuning out of range");
|
||||
props.PhonemeBCoarseTuning = val;
|
||||
break;
|
||||
return;
|
||||
|
||||
case AL_VOCAL_MORPHER_WAVEFORM:
|
||||
if(auto formopt = WaveformFromEmum(val))
|
||||
props.Waveform = *formopt;
|
||||
else
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher waveform out of range: 0x%04x", val};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_VALUE, "Vocal morpher waveform out of range: {:#04x}",
|
||||
as_unsigned(val));
|
||||
return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid vocal morpher integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void VmorpherEffectHandler::SetParamiv(VmorpherProps&, ALenum param, const int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void VmorpherEffectHandler::SetParamf(VmorpherProps &props, ALenum param, float val)
|
||||
void VmorpherEffectHandler::SetParamiv(ALCcontext *context, VmorpherProps &props, ALenum param, const int *vals)
|
||||
{ SetParami(context, props, param, *vals); }
|
||||
void VmorpherEffectHandler::SetParamf(ALCcontext *context, VmorpherProps &props, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_VOCAL_MORPHER_RATE:
|
||||
if(!(val >= AL_VOCAL_MORPHER_MIN_RATE && val <= AL_VOCAL_MORPHER_MAX_RATE))
|
||||
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher rate out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Vocal morpher rate out of range");
|
||||
props.Rate = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher float property 0x%04x",
|
||||
param};
|
||||
return;
|
||||
}
|
||||
}
|
||||
void VmorpherEffectHandler::SetParamfv(VmorpherProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(props, param, *vals); }
|
||||
|
||||
void VmorpherEffectHandler::GetParami(const VmorpherProps &props, ALenum param, int* val)
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid vocal morpher float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void VmorpherEffectHandler::SetParamfv(ALCcontext *context, VmorpherProps &props, ALenum param, const float *vals)
|
||||
{ SetParamf(context, props, param, *vals); }
|
||||
|
||||
void VmorpherEffectHandler::GetParami(ALCcontext *context, const VmorpherProps &props, ALenum param, int* val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_VOCAL_MORPHER_PHONEMEA: *val = EnumFromPhenome(props.PhonemeA); break;
|
||||
case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: *val = props.PhonemeACoarseTuning; break;
|
||||
case AL_VOCAL_MORPHER_PHONEMEB: *val = EnumFromPhenome(props.PhonemeB); break;
|
||||
case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: *val = props.PhonemeBCoarseTuning; break;
|
||||
case AL_VOCAL_MORPHER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x",
|
||||
param};
|
||||
case AL_VOCAL_MORPHER_PHONEMEA: *val = EnumFromPhenome(props.PhonemeA); return;
|
||||
case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: *val = props.PhonemeACoarseTuning; return;
|
||||
case AL_VOCAL_MORPHER_PHONEMEB: *val = EnumFromPhenome(props.PhonemeB); return;
|
||||
case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: *val = props.PhonemeBCoarseTuning; return;
|
||||
case AL_VOCAL_MORPHER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid vocal morpher integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void VmorpherEffectHandler::GetParamiv(const VmorpherProps&, ALenum param, int*)
|
||||
{
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
|
||||
param};
|
||||
}
|
||||
void VmorpherEffectHandler::GetParamf(const VmorpherProps &props, ALenum param, float *val)
|
||||
void VmorpherEffectHandler::GetParamiv(ALCcontext *context, const VmorpherProps &props, ALenum param, int *vals)
|
||||
{ GetParami(context, props, param, vals); }
|
||||
void VmorpherEffectHandler::GetParamf(ALCcontext *context, const VmorpherProps &props, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_VOCAL_MORPHER_RATE:
|
||||
*val = props.Rate;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher float property 0x%04x",
|
||||
param};
|
||||
case AL_VOCAL_MORPHER_RATE: *val = props.Rate; return;
|
||||
}
|
||||
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid vocal morpher float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
void VmorpherEffectHandler::GetParamfv(const VmorpherProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(props, param, vals); }
|
||||
void VmorpherEffectHandler::GetParamfv(ALCcontext *context, const VmorpherProps &props, ALenum param, float *vals)
|
||||
{ GetParamf(context, props, param, vals); }
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
namespace {
|
||||
|
||||
using VocalMorpherCommitter = EaxCommitter<EaxVocalMorpherCommitter>;
|
||||
|
|
|
|||
|
|
@ -20,24 +20,19 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <csignal>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
|
@ -45,53 +40,19 @@
|
|||
#include "al/debug.h"
|
||||
#include "alc/alconfig.h"
|
||||
#include "alc/context.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alnumeric.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "opthelpers.h"
|
||||
#include "strutils.h"
|
||||
|
||||
|
||||
namespace al {
|
||||
context_error::context_error(ALenum code, const char *msg, ...) : mErrorCode{code}
|
||||
void ALCcontext::setErrorImpl(ALenum errorCode, const fmt::string_view fmt, fmt::format_args args)
|
||||
{
|
||||
/* NOLINTBEGIN(*-array-to-pointer-decay) */
|
||||
std::va_list args;
|
||||
va_start(args, msg);
|
||||
setMessage(msg, args);
|
||||
va_end(args);
|
||||
/* NOLINTEND(*-array-to-pointer-decay) */
|
||||
}
|
||||
context_error::~context_error() = default;
|
||||
} /* namespace al */
|
||||
const auto msg = fmt::vformat(fmt, std::move(args));
|
||||
|
||||
void ALCcontext::setError(ALenum errorCode, const char *msg, ...)
|
||||
{
|
||||
auto message = std::vector<char>(256);
|
||||
|
||||
/* NOLINTBEGIN(*-array-to-pointer-decay) */
|
||||
std::va_list args, args2;
|
||||
va_start(args, msg);
|
||||
va_copy(args2, args);
|
||||
int msglen{std::vsnprintf(message.data(), message.size(), msg, args)};
|
||||
if(msglen >= 0 && static_cast<size_t>(msglen) >= message.size())
|
||||
{
|
||||
message.resize(static_cast<size_t>(msglen) + 1u);
|
||||
msglen = std::vsnprintf(message.data(), message.size(), msg, args2);
|
||||
}
|
||||
va_end(args2);
|
||||
va_end(args);
|
||||
/* NOLINTEND(*-array-to-pointer-decay) */
|
||||
|
||||
if(msglen >= 0)
|
||||
msg = message.data();
|
||||
else
|
||||
{
|
||||
msg = "<internal error constructing message>";
|
||||
msglen = static_cast<int>(strlen(msg));
|
||||
}
|
||||
|
||||
WARN("Error generated on context %p, code 0x%04x, \"%s\"\n",
|
||||
decltype(std::declval<void*>()){this}, errorCode, msg);
|
||||
WARN("Error generated on context {}, code {:#04x}, \"{}\"",
|
||||
decltype(std::declval<void*>()){this}, as_unsigned(errorCode), msg);
|
||||
if(TrapALError)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
|
@ -106,10 +67,18 @@ void ALCcontext::setError(ALenum errorCode, const char *msg, ...)
|
|||
if(mLastThreadError.get() == AL_NO_ERROR)
|
||||
mLastThreadError.set(errorCode);
|
||||
|
||||
debugMessage(DebugSource::API, DebugType::Error, 0, DebugSeverity::High,
|
||||
{msg, static_cast<uint>(msglen)});
|
||||
debugMessage(DebugSource::API, DebugType::Error, static_cast<ALuint>(errorCode),
|
||||
DebugSeverity::High, msg);
|
||||
}
|
||||
|
||||
void ALCcontext::throw_error_impl(ALenum errorCode, const fmt::string_view fmt,
|
||||
fmt::format_args args)
|
||||
{
|
||||
setErrorImpl(errorCode, fmt, std::move(args));
|
||||
throw al::base_exception{};
|
||||
}
|
||||
|
||||
|
||||
/* Special-case alGetError since it (potentially) raises a debug signal and
|
||||
* returns a non-default value for a null context.
|
||||
*/
|
||||
|
|
@ -125,17 +94,20 @@ AL_API auto AL_APIENTRY alGetError() noexcept -> ALenum
|
|||
optstr = ConfigValueStr({}, "game_compat", optname);
|
||||
if(optstr)
|
||||
{
|
||||
char *end{};
|
||||
auto value = std::strtoul(optstr->c_str(), &end, 0);
|
||||
if(end && *end == '\0' && value <= std::numeric_limits<ALenum>::max())
|
||||
return static_cast<ALenum>(value);
|
||||
ERR("Invalid default error value: \"%s\"", optstr->c_str());
|
||||
try {
|
||||
auto idx = 0_uz;
|
||||
auto value = std::stoi(*optstr, &idx, 0);
|
||||
if(idx >= optstr->size() || std::isspace(optstr->at(idx)))
|
||||
return static_cast<ALenum>(value);
|
||||
} catch(...) {
|
||||
}
|
||||
ERR("Invalid default error value: \"{}\"", *optstr);
|
||||
}
|
||||
return AL_INVALID_OPERATION;
|
||||
};
|
||||
static const ALenum deferror{get_value("__ALSOFT_DEFAULT_ERROR", "default-error")};
|
||||
|
||||
WARN("Querying error state on null context (implicitly 0x%04x)\n", deferror);
|
||||
WARN("Querying error state on null context (implicitly {:#04x})", as_unsigned(deferror));
|
||||
if(TrapALError)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef AL_ERROR_H
|
||||
#define AL_ERROR_H
|
||||
|
||||
#include "AL/al.h"
|
||||
|
||||
#include "core/except.h"
|
||||
|
||||
namespace al {
|
||||
|
||||
class context_error final : public al::base_exception {
|
||||
ALenum mErrorCode{};
|
||||
|
||||
public:
|
||||
#ifdef __MINGW32__
|
||||
[[gnu::format(__MINGW_PRINTF_FORMAT, 3, 4)]]
|
||||
#else
|
||||
[[gnu::format(printf, 3, 4)]]
|
||||
#endif
|
||||
context_error(ALenum code, const char *msg, ...);
|
||||
~context_error() final;
|
||||
|
||||
[[nodiscard]] auto errorCode() const noexcept -> ALenum { return mErrorCode; }
|
||||
};
|
||||
|
||||
} /* namespace al */
|
||||
|
||||
#endif /* AL_ERROR_H */
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "event.h"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <exception>
|
||||
|
|
@ -12,10 +11,8 @@
|
|||
#include <new>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#include "AL/al.h"
|
||||
|
|
@ -23,15 +20,17 @@
|
|||
#include "AL/alext.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alsem.h"
|
||||
#include "alspan.h"
|
||||
#include "alstring.h"
|
||||
#include "core/async_event.h"
|
||||
#include "core/context.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "debug.h"
|
||||
#include "direct_defs.h"
|
||||
#include "error.h"
|
||||
#include "intrusive_ptr.h"
|
||||
#include "opthelpers.h"
|
||||
#include "ringbuffer.h"
|
||||
|
|
@ -51,14 +50,15 @@ int EventThread(ALCcontext *context)
|
|||
bool quitnow{false};
|
||||
while(!quitnow)
|
||||
{
|
||||
auto evt_data = ring->getReadVector().first;
|
||||
auto evt_data = ring->getReadVector()[0];
|
||||
if(evt_data.len == 0)
|
||||
{
|
||||
context->mEventSem.wait();
|
||||
continue;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> eventlock{context->mEventCbLock};
|
||||
auto eventlock = std::lock_guard{context->mEventCbLock};
|
||||
const auto enabledevts = context->mEnabledEvts.load(std::memory_order_acquire);
|
||||
auto evt_span = al::span{std::launder(reinterpret_cast<AsyncEvent*>(evt_data.buf)),
|
||||
evt_data.len};
|
||||
for(auto &event : evt_span)
|
||||
|
|
@ -66,7 +66,6 @@ int EventThread(ALCcontext *context)
|
|||
quitnow = std::holds_alternative<AsyncKillThread>(event);
|
||||
if(quitnow) UNLIKELY break;
|
||||
|
||||
auto enabledevts = context->mEnabledEvts.load(std::memory_order_acquire);
|
||||
auto proc_killthread = [](AsyncKillThread&) { };
|
||||
auto proc_release = [](AsyncEffectReleaseEvent &evt)
|
||||
{
|
||||
|
|
@ -101,7 +100,7 @@ int EventThread(ALCcontext *context)
|
|||
break;
|
||||
}
|
||||
context->mEventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.mId, state,
|
||||
static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam);
|
||||
al::sizei(msg), msg.c_str(), context->mEventParam);
|
||||
};
|
||||
auto proc_buffercomp = [context,enabledevts](AsyncBufferCompleteEvent &evt)
|
||||
{
|
||||
|
|
@ -113,18 +112,16 @@ int EventThread(ALCcontext *context)
|
|||
if(evt.mCount == 1) msg += " buffer completed";
|
||||
else msg += " buffers completed";
|
||||
context->mEventCb(AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT, evt.mId, evt.mCount,
|
||||
static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam);
|
||||
al::sizei(msg), msg.c_str(), context->mEventParam);
|
||||
};
|
||||
auto proc_disconnect = [context,enabledevts](AsyncDisconnectEvent &evt)
|
||||
{
|
||||
context->debugMessage(DebugSource::System, DebugType::Error, 0,
|
||||
DebugSeverity::High, evt.msg);
|
||||
if(!context->mEventCb
|
||||
|| !enabledevts.test(al::to_underlying(AsyncEnableBits::Disconnected)))
|
||||
return;
|
||||
|
||||
if(context->mEventCb
|
||||
&& enabledevts.test(al::to_underlying(AsyncEnableBits::Disconnected)))
|
||||
context->mEventCb(AL_EVENT_TYPE_DISCONNECTED_SOFT, 0, 0,
|
||||
static_cast<ALsizei>(evt.msg.length()), evt.msg.c_str(),
|
||||
context->mEventParam);
|
||||
context->mEventCb(AL_EVENT_TYPE_DISCONNECTED_SOFT, 0, 0, al::sizei(evt.msg),
|
||||
evt.msg.c_str(), context->mEventParam);
|
||||
};
|
||||
|
||||
std::visit(overloaded{proc_srcstate, proc_buffercomp, proc_release, proc_disconnect,
|
||||
|
|
@ -156,22 +153,22 @@ void StartEventThrd(ALCcontext *ctx)
|
|||
ctx->mEventThread = std::thread{EventThread, ctx};
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
ERR("Failed to start event thread: %s\n", e.what());
|
||||
ERR("Failed to start event thread: {}", e.what());
|
||||
}
|
||||
catch(...) {
|
||||
ERR("Failed to start event thread! Expect problems.\n");
|
||||
ERR("Failed to start event thread! Expect problems.");
|
||||
}
|
||||
}
|
||||
|
||||
void StopEventThrd(ALCcontext *ctx)
|
||||
{
|
||||
RingBuffer *ring{ctx->mAsyncEvents.get()};
|
||||
auto evt_data = ring->getWriteVector().first;
|
||||
auto evt_data = ring->getWriteVector()[0];
|
||||
if(evt_data.len == 0)
|
||||
{
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
evt_data = ring->getWriteVector().first;
|
||||
evt_data = ring->getWriteVector()[0];
|
||||
} while(evt_data.len == 0);
|
||||
}
|
||||
std::ignore = InitAsyncEvent<AsyncKillThread>(evt_data.buf);
|
||||
|
|
@ -187,18 +184,19 @@ FORCE_ALIGN void AL_APIENTRY alEventControlDirectSOFT(ALCcontext *context, ALsiz
|
|||
const ALenum *types, ALboolean enable) noexcept
|
||||
try {
|
||||
if(count < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Controlling %d events", count};
|
||||
context->throw_error(AL_INVALID_VALUE, "Controlling {} events", count);
|
||||
if(count <= 0) UNLIKELY return;
|
||||
|
||||
if(!types)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
ContextBase::AsyncEventBitset flags{};
|
||||
for(ALenum evttype : al::span{types, static_cast<uint>(count)})
|
||||
{
|
||||
auto etype = GetEventType(evttype);
|
||||
if(!etype)
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid event type 0x%04x", evttype};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid event type {:#04x}",
|
||||
as_unsigned(evttype));
|
||||
flags.set(al::to_underlying(*etype));
|
||||
}
|
||||
|
||||
|
|
@ -226,15 +224,22 @@ try {
|
|||
std::lock_guard<std::mutex> eventlock{context->mEventCbLock};
|
||||
}
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNCEXT2(void, alEventCallback,SOFT, ALEVENTPROCSOFT,callback, void*,userParam)
|
||||
FORCE_ALIGN void AL_APIENTRY alEventCallbackDirectSOFT(ALCcontext *context,
|
||||
ALEVENTPROCSOFT callback, void *userParam) noexcept
|
||||
{
|
||||
try {
|
||||
std::lock_guard<std::mutex> eventlock{context->mEventCbLock};
|
||||
context->mEventCb = callback;
|
||||
context->mEventParam = userParam;
|
||||
}
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alstring.h"
|
||||
#include "direct_defs.h"
|
||||
#include "opthelpers.h"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -41,12 +40,12 @@
|
|||
#include "albit.h"
|
||||
#include "alc/context.h"
|
||||
#include "alc/device.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "almalloc.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "direct_defs.h"
|
||||
#include "error.h"
|
||||
#include "intrusive_ptr.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
|
|
@ -97,7 +96,8 @@ void InitFilterParams(ALfilter *filter, ALenum type)
|
|||
filter->type = type;
|
||||
}
|
||||
|
||||
auto EnsureFilters(ALCdevice *device, size_t needed) noexcept -> bool
|
||||
[[nodiscard]]
|
||||
auto EnsureFilters(al::Device *device, size_t needed) noexcept -> bool
|
||||
try {
|
||||
size_t count{std::accumulate(device->FilterList.cbegin(), device->FilterList.cend(), 0_uz,
|
||||
[](size_t cur, const FilterSubList &sublist) noexcept -> size_t
|
||||
|
|
@ -121,7 +121,8 @@ catch(...) {
|
|||
}
|
||||
|
||||
|
||||
ALfilter *AllocFilter(ALCdevice *device) noexcept
|
||||
[[nodiscard]]
|
||||
auto AllocFilter(al::Device *device) noexcept -> ALfilter*
|
||||
{
|
||||
auto sublist = std::find_if(device->FilterList.begin(), device->FilterList.end(),
|
||||
[](const FilterSubList &entry) noexcept -> bool
|
||||
|
|
@ -141,7 +142,7 @@ ALfilter *AllocFilter(ALCdevice *device) noexcept
|
|||
return filter;
|
||||
}
|
||||
|
||||
void FreeFilter(ALCdevice *device, ALfilter *filter)
|
||||
void FreeFilter(al::Device *device, ALfilter *filter)
|
||||
{
|
||||
device->mFilterNames.erase(filter->id);
|
||||
|
||||
|
|
@ -155,7 +156,8 @@ void FreeFilter(ALCdevice *device, ALfilter *filter)
|
|||
}
|
||||
|
||||
|
||||
auto LookupFilter(ALCdevice *device, ALuint id) noexcept -> ALfilter*
|
||||
[[nodiscard]]
|
||||
auto LookupFilter(al::Device *device, ALuint id) noexcept -> ALfilter*
|
||||
{
|
||||
const size_t lidx{(id-1) >> 6};
|
||||
const ALuint slidx{(id-1) & 0x3f};
|
||||
|
|
@ -172,171 +174,176 @@ auto LookupFilter(ALCdevice *device, ALuint id) noexcept -> ALfilter*
|
|||
|
||||
/* Null filter parameter handlers */
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::setParami(ALfilter*, ALenum param, int)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::setParami(ALCcontext *context, ALfilter*, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::setParamiv(ALfilter*, ALenum param, const int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::setParamiv(ALCcontext *context, ALfilter*, ALenum param, const int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::setParamf(ALfilter*, ALenum param, float)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::setParamf(ALCcontext *context, ALfilter*, ALenum param, float)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::setParamfv(ALfilter*, ALenum param, const float*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::setParamfv(ALCcontext *context, ALfilter*, ALenum param, const float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::getParami(const ALfilter*, ALenum param, int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::getParami(ALCcontext *context, const ALfilter*, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::getParamiv(const ALfilter*, ALenum param, int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::getParamiv(ALCcontext *context, const ALfilter*, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::getParamf(const ALfilter*, ALenum param, float*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::getParamf(ALCcontext *context, const ALfilter*, ALenum param, float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<NullFilterTable>::getParamfv(const ALfilter*, ALenum param, float*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
|
||||
void FilterTable<NullFilterTable>::getParamfv(ALCcontext *context, const ALfilter*, ALenum param, float*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid null filter property {:#04x}", as_unsigned(param)); }
|
||||
|
||||
/* Lowpass parameter handlers */
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::setParami(ALfilter*, ALenum param, int)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<LowpassFilterTable>::setParami(ALCcontext *context, ALfilter*, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid low-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::setParamiv(ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(filter, param, *values); }
|
||||
void FilterTable<LowpassFilterTable>::setParamiv(ALCcontext *context, ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(context, filter, param, *values); }
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::setParamf(ALfilter *filter, ALenum param, float val)
|
||||
void FilterTable<LowpassFilterTable>::setParamf(ALCcontext *context, ALfilter *filter, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_LOWPASS_GAIN:
|
||||
if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Low-pass gain %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Low-pass gain {:f} out of range", val);
|
||||
filter->Gain = val;
|
||||
return;
|
||||
|
||||
case AL_LOWPASS_GAINHF:
|
||||
if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Low-pass gainhf %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Low-pass gainhf {:f} out of range", val);
|
||||
filter->GainHF = val;
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid low-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::setParamfv(ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(filter, param, *vals); }
|
||||
void FilterTable<LowpassFilterTable>::setParamfv(ALCcontext *context, ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(context, filter, param, *vals); }
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::getParami(const ALfilter*, ALenum param, int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<LowpassFilterTable>::getParami(ALCcontext *context, const ALfilter*, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid low-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::getParamiv(const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(filter, param, values); }
|
||||
void FilterTable<LowpassFilterTable>::getParamiv(ALCcontext *context, const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(context, filter, param, values); }
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::getParamf(const ALfilter *filter, ALenum param, float *val)
|
||||
void FilterTable<LowpassFilterTable>::getParamf(ALCcontext *context, const ALfilter *filter, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_LOWPASS_GAIN: *val = filter->Gain; return;
|
||||
case AL_LOWPASS_GAINHF: *val = filter->GainHF; return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid low-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<LowpassFilterTable>::getParamfv(const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(filter, param, vals); }
|
||||
void FilterTable<LowpassFilterTable>::getParamfv(ALCcontext *context, const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(context, filter, param, vals); }
|
||||
|
||||
/* Highpass parameter handlers */
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::setParami(ALfilter*, ALenum param, int)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<HighpassFilterTable>::setParami(ALCcontext *context, ALfilter*, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid high-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::setParamiv(ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(filter, param, *values); }
|
||||
void FilterTable<HighpassFilterTable>::setParamiv(ALCcontext *context, ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(context, filter, param, *values); }
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::setParamf(ALfilter *filter, ALenum param, float val)
|
||||
void FilterTable<HighpassFilterTable>::setParamf(ALCcontext *context, ALfilter *filter, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_HIGHPASS_GAIN:
|
||||
if(!(val >= AL_HIGHPASS_MIN_GAIN && val <= AL_HIGHPASS_MAX_GAIN))
|
||||
throw al::context_error{AL_INVALID_VALUE, "High-pass gain %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "High-pass gain {:f} out of range", val);
|
||||
filter->Gain = val;
|
||||
return;
|
||||
|
||||
case AL_HIGHPASS_GAINLF:
|
||||
if(!(val >= AL_HIGHPASS_MIN_GAINLF && val <= AL_HIGHPASS_MAX_GAINLF))
|
||||
throw al::context_error{AL_INVALID_VALUE, "High-pass gainlf %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "High-pass gainlf {:f} out of range", val);
|
||||
filter->GainLF = val;
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid high-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::setParamfv(ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(filter, param, *vals); }
|
||||
void FilterTable<HighpassFilterTable>::setParamfv(ALCcontext *context, ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(context, filter, param, *vals); }
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::getParami(const ALfilter*, ALenum param, int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<HighpassFilterTable>::getParami(ALCcontext *context, const ALfilter*, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid high-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::getParamiv(const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(filter, param, values); }
|
||||
void FilterTable<HighpassFilterTable>::getParamiv(ALCcontext *context, const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(context, filter, param, values); }
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::getParamf(const ALfilter *filter, ALenum param, float *val)
|
||||
void FilterTable<HighpassFilterTable>::getParamf(ALCcontext *context, const ALfilter *filter, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_HIGHPASS_GAIN: *val = filter->Gain; return;
|
||||
case AL_HIGHPASS_GAINLF: *val = filter->GainLF; return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid high-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<HighpassFilterTable>::getParamfv(const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(filter, param, vals); }
|
||||
void FilterTable<HighpassFilterTable>::getParamfv(ALCcontext *context, const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(context, filter, param, vals); }
|
||||
|
||||
/* Bandpass parameter handlers */
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::setParami(ALfilter*, ALenum param, int)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<BandpassFilterTable>::setParami(ALCcontext *context, ALfilter*, ALenum param, int)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid band-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::setParamiv(ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(filter, param, *values); }
|
||||
void FilterTable<BandpassFilterTable>::setParamiv(ALCcontext *context, ALfilter *filter, ALenum param, const int *values)
|
||||
{ setParami(context, filter, param, *values); }
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::setParamf(ALfilter *filter, ALenum param, float val)
|
||||
void FilterTable<BandpassFilterTable>::setParamf(ALCcontext *context, ALfilter *filter, ALenum param, float val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_BANDPASS_GAIN:
|
||||
if(!(val >= AL_BANDPASS_MIN_GAIN && val <= AL_BANDPASS_MAX_GAIN))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Band-pass gain %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Band-pass gain {:f} out of range", val);
|
||||
filter->Gain = val;
|
||||
return;
|
||||
|
||||
case AL_BANDPASS_GAINHF:
|
||||
if(!(val >= AL_BANDPASS_MIN_GAINHF && val <= AL_BANDPASS_MAX_GAINHF))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Band-pass gainhf %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Band-pass gainhf {:f} out of range", val);
|
||||
filter->GainHF = val;
|
||||
return;
|
||||
|
||||
case AL_BANDPASS_GAINLF:
|
||||
if(!(val >= AL_BANDPASS_MIN_GAINLF && val <= AL_BANDPASS_MAX_GAINLF))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Band-pass gainlf %f out of range", val};
|
||||
context->throw_error(AL_INVALID_VALUE, "Band-pass gainlf {:f} out of range", val);
|
||||
filter->GainLF = val;
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid band-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::setParamfv(ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(filter, param, *vals); }
|
||||
void FilterTable<BandpassFilterTable>::setParamfv(ALCcontext *context, ALfilter *filter, ALenum param, const float *vals)
|
||||
{ setParamf(context, filter, param, *vals); }
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::getParami(const ALfilter*, ALenum param, int*)
|
||||
{ throw al::context_error{AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param}; }
|
||||
void FilterTable<BandpassFilterTable>::getParami(ALCcontext *context, const ALfilter*, ALenum param, int*)
|
||||
{ context->throw_error(AL_INVALID_ENUM, "Invalid band-pass integer property {:#04x}", as_unsigned(param)); }
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::getParamiv(const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(filter, param, values); }
|
||||
void FilterTable<BandpassFilterTable>::getParamiv(ALCcontext *context, const ALfilter *filter, ALenum param, int *values)
|
||||
{ getParami(context, filter, param, values); }
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::getParamf(const ALfilter *filter, ALenum param, float *val)
|
||||
void FilterTable<BandpassFilterTable>::getParamf(ALCcontext *context, const ALfilter *filter, ALenum param, float *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -344,32 +351,35 @@ void FilterTable<BandpassFilterTable>::getParamf(const ALfilter *filter, ALenum
|
|||
case AL_BANDPASS_GAINHF: *val = filter->GainHF; return;
|
||||
case AL_BANDPASS_GAINLF: *val = filter->GainLF; return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid band-pass float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
template<>
|
||||
void FilterTable<BandpassFilterTable>::getParamfv(const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(filter, param, vals); }
|
||||
void FilterTable<BandpassFilterTable>::getParamfv(ALCcontext *context, const ALfilter *filter, ALenum param, float *vals)
|
||||
{ getParamf(context, filter, param, vals); }
|
||||
|
||||
|
||||
AL_API DECL_FUNC2(void, alGenFilters, ALsizei,n, ALuint*,filters)
|
||||
FORCE_ALIGN void AL_APIENTRY alGenFiltersDirect(ALCcontext *context, ALsizei n, ALuint *filters) noexcept
|
||||
try {
|
||||
if(n < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Generating %d filters", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Generating {} filters", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
const al::span fids{filters, static_cast<ALuint>(n)};
|
||||
if(!EnsureFilters(device, fids.size()))
|
||||
throw al::context_error{AL_OUT_OF_MEMORY, "Failed to allocate %d filter%s", n,
|
||||
(n == 1) ? "" : "s"};
|
||||
context->throw_error(AL_OUT_OF_MEMORY, "Failed to allocate {} filter{}", n,
|
||||
(n==1) ? "" : "s");
|
||||
|
||||
std::generate(fids.begin(), fids.end(), [device]{ return AllocFilter(device)->id; });
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alDeleteFilters, ALsizei,n, const ALuint*,filters)
|
||||
|
|
@ -377,11 +387,11 @@ FORCE_ALIGN void AL_APIENTRY alDeleteFiltersDirect(ALCcontext *context, ALsizei
|
|||
const ALuint *filters) noexcept
|
||||
try {
|
||||
if(n < 0)
|
||||
throw al::context_error{AL_INVALID_VALUE, "Deleting %d filters", n};
|
||||
context->throw_error(AL_INVALID_VALUE, "Deleting {} filters", n);
|
||||
if(n <= 0) UNLIKELY return;
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
/* First try to find any filters that are invalid. */
|
||||
auto validate_filter = [device](const ALuint fid) -> bool
|
||||
|
|
@ -390,7 +400,7 @@ try {
|
|||
const al::span fids{filters, static_cast<ALuint>(n)};
|
||||
auto invflt = std::find_if_not(fids.begin(), fids.end(), validate_filter);
|
||||
if(invflt != fids.end())
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", *invflt};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", *invflt);
|
||||
|
||||
/* All good. Delete non-0 filter IDs. */
|
||||
auto delete_filter = [device](const ALuint fid) -> void
|
||||
|
|
@ -400,15 +410,17 @@ try {
|
|||
};
|
||||
std::for_each(fids.begin(), fids.end(), delete_filter);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(ALboolean, alIsFilter, ALuint,filter)
|
||||
FORCE_ALIGN ALboolean AL_APIENTRY alIsFilterDirect(ALCcontext *context, ALuint filter) noexcept
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
if(!filter || LookupFilter(device, filter))
|
||||
return AL_TRUE;
|
||||
return AL_FALSE;
|
||||
|
|
@ -419,29 +431,32 @@ AL_API DECL_FUNC3(void, alFilteri, ALuint,filter, ALenum,param, ALint,value)
|
|||
FORCE_ALIGN void AL_APIENTRY alFilteriDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
ALint value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
if(!(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS
|
||||
|| value == AL_FILTER_HIGHPASS || value == AL_FILTER_BANDPASS))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Invalid filter type 0x%04x", value};
|
||||
context->throw_error(AL_INVALID_VALUE, "Invalid filter type {:#04x}",
|
||||
as_unsigned(value));
|
||||
InitFilterParams(alfilt, value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,value](auto&& thunk){thunk.setParami(alfilt, param, value);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,value](auto&& thunk)
|
||||
{ thunk.setParami(context, alfilt, param, value); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alFilteriv, ALuint,filter, ALenum,param, const ALint*,values)
|
||||
|
|
@ -455,83 +470,89 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,values](auto&& thunk){thunk.setParamiv(alfilt, param, values);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,values](auto&& thunk)
|
||||
{ thunk.setParamiv(context, alfilt, param, values); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alFilterf, ALuint,filter, ALenum,param, ALfloat,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alFilterfDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
ALfloat value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,value](auto&& thunk){thunk.setParamf(alfilt, param, value);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,value](auto&& thunk)
|
||||
{ thunk.setParamf(context, alfilt, param, value); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alFilterfv, ALuint,filter, ALenum,param, const ALfloat*,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alFilterfvDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
const ALfloat *values) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,values](auto&& thunk){thunk.setParamfv(alfilt, param, values);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,values](auto&& thunk)
|
||||
{ thunk.setParamfv(context, alfilt, param, values); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetFilteri, ALuint,filter, ALenum,param, ALint*,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetFilteriDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
ALint *value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
const ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
*value = alfilt->type;
|
||||
return;
|
||||
case AL_FILTER_TYPE: *value = alfilt->type; return;
|
||||
}
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,value](auto&& thunk){thunk.getParami(alfilt, param, value);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,value](auto&& thunk)
|
||||
{ thunk.getParami(context, alfilt, param, value); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetFilteriv, ALuint,filter, ALenum,param, ALint*,values)
|
||||
|
|
@ -545,68 +566,74 @@ try {
|
|||
return;
|
||||
}
|
||||
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
const ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,values](auto&& thunk){thunk.getParamiv(alfilt, param, values);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,values](auto&& thunk)
|
||||
{ thunk.getParamiv(context, alfilt, param, values); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetFilterf, ALuint,filter, ALenum,param, ALfloat*,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetFilterfDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
ALfloat *value) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
const ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt) UNLIKELY
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
if(!alfilt)
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,value](auto&& thunk){thunk.getParamf(alfilt, param, value);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,value](auto&& thunk)
|
||||
{ thunk.getParamf(context, alfilt, param, value); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC3(void, alGetFilterfv, ALuint,filter, ALenum,param, ALfloat*,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetFilterfvDirect(ALCcontext *context, ALuint filter, ALenum param,
|
||||
ALfloat *values) noexcept
|
||||
try {
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
const ALfilter *alfilt{LookupFilter(device, filter)};
|
||||
if(!alfilt) UNLIKELY
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", filter};
|
||||
if(!alfilt)
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", filter);
|
||||
|
||||
/* Call the appropriate handler */
|
||||
std::visit([alfilt,param,values](auto&& thunk){thunk.getParamfv(alfilt, param, values);},
|
||||
alfilt->mTypeVariant);
|
||||
std::visit([context,alfilt,param,values](auto&& thunk)
|
||||
{ thunk.getParamfv(context, alfilt, param, values); }, alfilt->mTypeVariant);
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
void ALfilter::SetName(ALCcontext *context, ALuint id, std::string_view name)
|
||||
{
|
||||
ALCdevice *device{context->mALDevice.get()};
|
||||
std::lock_guard<std::mutex> filterlock{device->FilterLock};
|
||||
auto *device = context->mALDevice.get();
|
||||
auto filterlock = std::lock_guard{device->FilterLock};
|
||||
|
||||
auto filter = LookupFilter(device, id);
|
||||
if(!filter)
|
||||
throw al::context_error{AL_INVALID_NAME, "Invalid filter ID %u", id};
|
||||
context->throw_error(AL_INVALID_NAME, "Invalid filter ID {}", id);
|
||||
|
||||
device->mFilterNames.insert_or_assign(id, name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,27 @@
|
|||
#include "almalloc.h"
|
||||
#include "alnumeric.h"
|
||||
|
||||
struct ALfilter;
|
||||
|
||||
|
||||
inline constexpr float LowPassFreqRef{5000.0f};
|
||||
inline constexpr float HighPassFreqRef{250.0f};
|
||||
|
||||
template<typename T>
|
||||
struct FilterTable {
|
||||
static void setParami(struct ALfilter*, ALenum, int);
|
||||
static void setParamiv(struct ALfilter*, ALenum, const int*);
|
||||
static void setParamf(struct ALfilter*, ALenum, float);
|
||||
static void setParamfv(struct ALfilter*, ALenum, const float*);
|
||||
static void setParami(ALCcontext*, ALfilter*, ALenum, int);
|
||||
static void setParamiv(ALCcontext*, ALfilter*, ALenum, const int*);
|
||||
static void setParamf(ALCcontext*, ALfilter*, ALenum, float);
|
||||
static void setParamfv(ALCcontext*, ALfilter*, ALenum, const float*);
|
||||
|
||||
static void getParami(const struct ALfilter*, ALenum, int*);
|
||||
static void getParamiv(const struct ALfilter*, ALenum, int*);
|
||||
static void getParamf(const struct ALfilter*, ALenum, float*);
|
||||
static void getParamfv(const struct ALfilter*, ALenum, float*);
|
||||
static void getParami(ALCcontext*, const ALfilter*, ALenum, int*);
|
||||
static void getParamiv(ALCcontext*, const ALfilter*, ALenum, int*);
|
||||
static void getParamf(ALCcontext*, const ALfilter*, ALenum, float*);
|
||||
static void getParamfv(ALCcontext*, const ALfilter*, ALenum, float*);
|
||||
|
||||
private:
|
||||
FilterTable() = default;
|
||||
friend T;
|
||||
};
|
||||
|
||||
struct NullFilterTable : public FilterTable<NullFilterTable> { };
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@
|
|||
#include "AL/efx.h"
|
||||
|
||||
#include "alc/context.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "core/except.h"
|
||||
#include "core/logging.h"
|
||||
#include "direct_defs.h"
|
||||
#include "error.h"
|
||||
#include "opthelpers.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
|
@ -54,7 +54,7 @@ inline void CommitAndUpdateProps(ALCcontext *context)
|
|||
{
|
||||
if(!context->mDeferUpdates)
|
||||
{
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
if(context->eaxNeedsCommit())
|
||||
{
|
||||
context->mPropsDirty = true;
|
||||
|
|
@ -79,22 +79,26 @@ try {
|
|||
{
|
||||
case AL_GAIN:
|
||||
if(!(value >= 0.0f && std::isfinite(value)))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Listener gain out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Listener gain {:f} out of range", value);
|
||||
listener.Gain = value;
|
||||
UpdateProps(context);
|
||||
return;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Listener meters per unit out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Listener meters per unit {:f} out of range",
|
||||
value);
|
||||
listener.mMetersPerUnit = value;
|
||||
UpdateProps(context);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener float property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC4(void, alListener3f, ALenum,param, ALfloat,value1, ALfloat,value2, ALfloat,value3)
|
||||
|
|
@ -107,7 +111,7 @@ try {
|
|||
{
|
||||
case AL_POSITION:
|
||||
if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Listener position out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Listener position out of range");
|
||||
listener.Position[0] = value1;
|
||||
listener.Position[1] = value2;
|
||||
listener.Position[2] = value3;
|
||||
|
|
@ -116,17 +120,20 @@ try {
|
|||
|
||||
case AL_VELOCITY:
|
||||
if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
|
||||
throw al::context_error{AL_INVALID_VALUE, "Listener velocity out of range"};
|
||||
context->throw_error(AL_INVALID_VALUE, "Listener velocity out of range");
|
||||
listener.Velocity[0] = value1;
|
||||
listener.Velocity[1] = value2;
|
||||
listener.Velocity[2] = value3;
|
||||
CommitAndUpdateProps(context);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener 3-float property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener 3-float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alListenerfv, ALenum,param, const ALfloat*,values)
|
||||
|
|
@ -134,7 +141,7 @@ FORCE_ALIGN void AL_APIENTRY alListenerfvDirect(ALCcontext *context, ALenum para
|
|||
const ALfloat *values) noexcept
|
||||
try {
|
||||
if(!values)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -157,17 +164,20 @@ try {
|
|||
case AL_ORIENTATION:
|
||||
auto vals = al::span<const float,6>{values, 6_uz};
|
||||
if(!std::all_of(vals.cbegin(), vals.cend(), [](float f) { return std::isfinite(f); }))
|
||||
return context->setError(AL_INVALID_VALUE, "Listener orientation out of range");
|
||||
context->throw_error(AL_INVALID_VALUE, "Listener orientation out of range");
|
||||
/* AT then UP */
|
||||
std::copy_n(vals.cbegin(), 3, listener.OrientAt.begin());
|
||||
std::copy_n(vals.cbegin()+3, 3, listener.OrientUp.begin());
|
||||
CommitAndUpdateProps(context);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener float-vector property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener float-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -175,10 +185,13 @@ AL_API DECL_FUNC2(void, alListeneri, ALenum,param, ALint,value)
|
|||
FORCE_ALIGN void AL_APIENTRY alListeneriDirect(ALCcontext *context, ALenum param, ALint /*value*/) noexcept
|
||||
try {
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener integer property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC4(void, alListener3i, ALenum,param, ALint,value1, ALint,value2, ALint,value3)
|
||||
|
|
@ -195,10 +208,13 @@ try {
|
|||
}
|
||||
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener 3-integer property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener 3-integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alListeneriv, ALenum,param, const ALint*,values)
|
||||
|
|
@ -206,7 +222,7 @@ FORCE_ALIGN void AL_APIENTRY alListenerivDirect(ALCcontext *context, ALenum para
|
|||
const ALint *values) noexcept
|
||||
try {
|
||||
if(!values)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
al::span<const ALint> vals;
|
||||
switch(param)
|
||||
|
|
@ -229,11 +245,13 @@ try {
|
|||
}
|
||||
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener integer-vector property 0x%x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener integer-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -242,7 +260,7 @@ FORCE_ALIGN void AL_APIENTRY alGetListenerfDirect(ALCcontext *context, ALenum pa
|
|||
ALfloat *value) noexcept
|
||||
try {
|
||||
if(!value)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
ALlistener &listener = context->mListener;
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -251,10 +269,13 @@ try {
|
|||
case AL_GAIN: *value = listener.Gain; return;
|
||||
case AL_METERS_PER_UNIT: *value = listener.mMetersPerUnit; return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener float property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC4(void, alGetListener3f, ALenum,param, ALfloat*,value1, ALfloat*,value2, ALfloat*,value3)
|
||||
|
|
@ -262,7 +283,7 @@ FORCE_ALIGN void AL_APIENTRY alGetListener3fDirect(ALCcontext *context, ALenum p
|
|||
ALfloat *value1, ALfloat *value2, ALfloat *value3) noexcept
|
||||
try {
|
||||
if(!value1 || !value2 || !value3)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
ALlistener &listener = context->mListener;
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -280,10 +301,13 @@ try {
|
|||
*value3 = listener.Velocity[2];
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener 3-float property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener 3-float property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alGetListenerfv, ALenum,param, ALfloat*,values)
|
||||
|
|
@ -291,7 +315,7 @@ FORCE_ALIGN void AL_APIENTRY alGetListenerfvDirect(ALCcontext *context, ALenum p
|
|||
ALfloat *values) noexcept
|
||||
try {
|
||||
if(!values)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -318,22 +342,28 @@ try {
|
|||
std::copy_n(listener.OrientUp.cbegin(), 3, vals.begin()+3);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener float-vector property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener float-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
|
||||
AL_API DECL_FUNC2(void, alGetListeneri, ALenum,param, ALint*,value)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetListeneriDirect(ALCcontext *context, ALenum param, ALint *value) noexcept
|
||||
try {
|
||||
if(!value) throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
if(!value) context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener integer property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC4(void, alGetListener3i, ALenum,param, ALint*,value1, ALint*,value2, ALint*,value3)
|
||||
|
|
@ -341,7 +371,7 @@ FORCE_ALIGN void AL_APIENTRY alGetListener3iDirect(ALCcontext *context, ALenum p
|
|||
ALint *value1, ALint *value2, ALint *value3) noexcept
|
||||
try {
|
||||
if(!value1 || !value2 || !value3)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
ALlistener &listener = context->mListener;
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -359,10 +389,13 @@ try {
|
|||
*value3 = static_cast<ALint>(listener.Velocity[2]);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener 3-integer property 0x%x", param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener 3-integer property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC2(void, alGetListeneriv, ALenum,param, ALint*,values)
|
||||
|
|
@ -370,7 +403,7 @@ FORCE_ALIGN void AL_APIENTRY alGetListenerivDirect(ALCcontext *context, ALenum p
|
|||
ALint *values) noexcept
|
||||
try {
|
||||
if(!values)
|
||||
throw al::context_error{AL_INVALID_VALUE, "NULL pointer"};
|
||||
context->throw_error(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
||||
switch(param)
|
||||
{
|
||||
|
|
@ -394,9 +427,11 @@ try {
|
|||
std::transform(listener.OrientUp.cbegin(), listener.OrientUp.cend(), vals.begin()+3, f2i);
|
||||
return;
|
||||
}
|
||||
throw al::context_error{AL_INVALID_ENUM, "Invalid listener integer-vector property 0x%x",
|
||||
param};
|
||||
context->throw_error(AL_INVALID_ENUM, "Invalid listener integer-vector property {:#04x}",
|
||||
as_unsigned(param));
|
||||
}
|
||||
catch(al::context_error& e) {
|
||||
context->setError(e.errorCode(), "%s", e.what());
|
||||
catch(al::base_exception&) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
ERR("Caught exception: {}", e.what());
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef AL_SOURCE_H
|
||||
#define AL_SOURCE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
|
@ -20,7 +22,7 @@
|
|||
#include "core/context.h"
|
||||
#include "core/voice.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#include "eax/api.h"
|
||||
#include "eax/call.h"
|
||||
#include "eax/exception.h"
|
||||
|
|
@ -45,12 +47,10 @@ inline bool sBufferSubDataCompat{false};
|
|||
|
||||
struct ALbufferQueueItem : public VoiceBufferItem {
|
||||
ALbuffer *mBuffer{nullptr};
|
||||
|
||||
DISABLE_ALLOC
|
||||
};
|
||||
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
class EaxSourceException : public EaxException {
|
||||
public:
|
||||
explicit EaxSourceException(const char* message)
|
||||
|
|
@ -71,7 +71,7 @@ struct ALsource {
|
|||
float RefDistance{1.0f};
|
||||
float MaxDistance{std::numeric_limits<float>::max()};
|
||||
float RolloffFactor{1.0f};
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
// For EAXSOURCE_ROLLOFFFACTOR, which is distinct from and added to
|
||||
// AL_ROLLOFF_FACTOR
|
||||
float RolloffFactor2{0.0f};
|
||||
|
|
@ -165,10 +165,10 @@ struct ALsource {
|
|||
|
||||
DISABLE_ALLOC
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
public:
|
||||
void eaxInitialize(ALCcontext *context) noexcept;
|
||||
void eaxDispatch(const EaxCall& call);
|
||||
void eaxDispatch(const EaxCall& call) { call.is_get() ? eax_get(call) : eax_set(call); }
|
||||
void eaxCommit();
|
||||
void eaxMarkAsChanged() noexcept { mEaxChanged = true; }
|
||||
|
||||
|
|
@ -199,26 +199,23 @@ private:
|
|||
using EaxSpeakerLevels = std::array<EAXSPEAKERLEVELPROPERTIES, eax_max_speakers>;
|
||||
using EaxSends = std::array<EAXSOURCEALLSENDPROPERTIES, EAX_MAX_FXSLOTS>;
|
||||
|
||||
using Eax1Props = EAXBUFFER_REVERBPROPERTIES;
|
||||
struct Eax1State {
|
||||
Eax1Props i; // Immediate.
|
||||
Eax1Props d; // Deferred.
|
||||
EAXBUFFER_REVERBPROPERTIES i; // Immediate.
|
||||
EAXBUFFER_REVERBPROPERTIES d; // Deferred.
|
||||
};
|
||||
|
||||
using Eax2Props = EAX20BUFFERPROPERTIES;
|
||||
struct Eax2State {
|
||||
Eax2Props i; // Immediate.
|
||||
Eax2Props d; // Deferred.
|
||||
EAX20BUFFERPROPERTIES i; // Immediate.
|
||||
EAX20BUFFERPROPERTIES d; // Deferred.
|
||||
};
|
||||
|
||||
using Eax3Props = EAX30SOURCEPROPERTIES;
|
||||
struct Eax3State {
|
||||
Eax3Props i; // Immediate.
|
||||
Eax3Props d; // Deferred.
|
||||
EAX30SOURCEPROPERTIES i; // Immediate.
|
||||
EAX30SOURCEPROPERTIES d; // Deferred.
|
||||
};
|
||||
|
||||
struct Eax4Props {
|
||||
Eax3Props source;
|
||||
EAX30SOURCEPROPERTIES source;
|
||||
EaxSends sends;
|
||||
EAX40ACTIVEFXSLOTS active_fx_slots;
|
||||
};
|
||||
|
|
@ -490,14 +487,14 @@ private:
|
|||
};
|
||||
|
||||
struct Eax1SourceAllValidator {
|
||||
void operator()(const Eax1Props& props) const
|
||||
void operator()(const EAXBUFFER_REVERBPROPERTIES& props) const
|
||||
{
|
||||
Eax1SourceReverbMixValidator{}(props.fMix);
|
||||
}
|
||||
};
|
||||
|
||||
struct Eax2SourceAllValidator {
|
||||
void operator()(const Eax2Props& props) const
|
||||
void operator()(const EAX20BUFFERPROPERTIES& props) const
|
||||
{
|
||||
Eax2SourceDirectValidator{}(props.lDirect);
|
||||
Eax2SourceDirectHfValidator{}(props.lDirectHF);
|
||||
|
|
@ -516,7 +513,7 @@ private:
|
|||
};
|
||||
|
||||
struct Eax3SourceAllValidator {
|
||||
void operator()(const Eax3Props& props) const
|
||||
void operator()(const EAX30SOURCEPROPERTIES& props) const
|
||||
{
|
||||
Eax2SourceDirectValidator{}(props.lDirect);
|
||||
Eax2SourceDirectHfValidator{}(props.lDirectHF);
|
||||
|
|
@ -823,11 +820,11 @@ private:
|
|||
[[noreturn]] static void eax_fail_unknown_receiving_fx_slot_id();
|
||||
|
||||
static void eax_set_sends_defaults(EaxSends& sends, const EaxFxSlotIds& ids) noexcept;
|
||||
static void eax1_set_defaults(Eax1Props& props) noexcept;
|
||||
static void eax1_set_defaults(EAXBUFFER_REVERBPROPERTIES& props) noexcept;
|
||||
void eax1_set_defaults() noexcept;
|
||||
static void eax2_set_defaults(Eax2Props& props) noexcept;
|
||||
static void eax2_set_defaults(EAX20BUFFERPROPERTIES& props) noexcept;
|
||||
void eax2_set_defaults() noexcept;
|
||||
static void eax3_set_defaults(Eax3Props& props) noexcept;
|
||||
static void eax3_set_defaults(EAX30SOURCEPROPERTIES& props) noexcept;
|
||||
void eax3_set_defaults() noexcept;
|
||||
static void eax4_set_sends_defaults(EaxSends& sends) noexcept;
|
||||
static void eax4_set_active_fx_slots_defaults(EAX40ACTIVEFXSLOTS& slots) noexcept;
|
||||
|
|
@ -840,9 +837,9 @@ private:
|
|||
void eax5_set_defaults() noexcept;
|
||||
void eax_set_defaults() noexcept;
|
||||
|
||||
static void eax1_translate(const Eax1Props& src, Eax5Props& dst) noexcept;
|
||||
static void eax2_translate(const Eax2Props& src, Eax5Props& dst) noexcept;
|
||||
static void eax3_translate(const Eax3Props& src, Eax5Props& dst) noexcept;
|
||||
static void eax1_translate(const EAXBUFFER_REVERBPROPERTIES& src, Eax5Props& dst) noexcept;
|
||||
static void eax2_translate(const EAX20BUFFERPROPERTIES& src, Eax5Props& dst) noexcept;
|
||||
static void eax3_translate(const EAX30SOURCEPROPERTIES& src, Eax5Props& dst) noexcept;
|
||||
static void eax4_translate(const Eax4Props& src, Eax5Props& dst) noexcept;
|
||||
|
||||
static float eax_calculate_dst_occlusion_mb(
|
||||
|
|
@ -907,12 +904,12 @@ private:
|
|||
}
|
||||
|
||||
static void eax_get_active_fx_slot_id(const EaxCall& call, const al::span<const GUID> src_ids);
|
||||
static void eax1_get(const EaxCall& call, const Eax1Props& props);
|
||||
static void eax2_get(const EaxCall& call, const Eax2Props& props);
|
||||
static void eax3_get_obstruction(const EaxCall& call, const Eax3Props& props);
|
||||
static void eax3_get_occlusion(const EaxCall& call, const Eax3Props& props);
|
||||
static void eax3_get_exclusion(const EaxCall& call, const Eax3Props& props);
|
||||
static void eax3_get(const EaxCall& call, const Eax3Props& props);
|
||||
static void eax1_get(const EaxCall& call, const EAXBUFFER_REVERBPROPERTIES& props);
|
||||
static void eax2_get(const EaxCall& call, const EAX20BUFFERPROPERTIES& props);
|
||||
static void eax3_get_obstruction(const EaxCall& call, const EAX30SOURCEPROPERTIES& props);
|
||||
static void eax3_get_occlusion(const EaxCall& call, const EAX30SOURCEPROPERTIES& props);
|
||||
static void eax3_get_exclusion(const EaxCall& call, const EAX30SOURCEPROPERTIES& props);
|
||||
static void eax3_get(const EaxCall& call, const EAX30SOURCEPROPERTIES& props);
|
||||
void eax4_get(const EaxCall& call, const Eax4Props& props);
|
||||
static void eax5_get_all_2d(const EaxCall& call, const EAX50SOURCEPROPERTIES& props);
|
||||
static void eax5_get_speaker_levels(const EaxCall& call, const EaxSpeakerLevels& props);
|
||||
|
|
@ -1034,9 +1031,9 @@ private:
|
|||
void eax_set_efx_wet_gain_auto();
|
||||
void eax_set_efx_wet_gain_hf_auto();
|
||||
|
||||
static void eax1_set(const EaxCall& call, Eax1Props& props);
|
||||
static void eax2_set(const EaxCall& call, Eax2Props& props);
|
||||
void eax3_set(const EaxCall& call, Eax3Props& props);
|
||||
static void eax1_set(const EaxCall& call, EAXBUFFER_REVERBPROPERTIES& props);
|
||||
static void eax2_set(const EaxCall& call, EAX20BUFFERPROPERTIES& props);
|
||||
void eax3_set(const EaxCall& call, EAX30SOURCEPROPERTIES& props);
|
||||
void eax4_set(const EaxCall& call, Eax4Props& props);
|
||||
static void eax5_defer_all_2d(const EaxCall& call, EAX50SOURCEPROPERTIES& props);
|
||||
static void eax5_defer_speaker_levels(const EaxCall& call, EaxSpeakerLevels& props);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "al/listener.h"
|
||||
#include "alc/alu.h"
|
||||
#include "alc/context.h"
|
||||
#include "alc/device.h"
|
||||
#include "alc/inprogext.h"
|
||||
#include "alnumeric.h"
|
||||
#include "atomic.h"
|
||||
|
|
@ -52,9 +53,7 @@
|
|||
#include "opthelpers.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#include "alc/device.h"
|
||||
|
||||
#if ALSOFT_EAX
|
||||
#include "eax/globals.h"
|
||||
#include "eax/x_ram.h"
|
||||
#endif // ALSOFT_EAX
|
||||
|
|
@ -62,6 +61,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
using ALvoidptr = ALvoid*;
|
||||
|
||||
[[nodiscard]] constexpr auto GetVendorString() noexcept { return "OpenAL Community"; }
|
||||
[[nodiscard]] constexpr auto GetVersionString() noexcept { return "1.1 ALSOFT " ALSOFT_VERSION; }
|
||||
[[nodiscard]] constexpr auto GetRendererString() noexcept { return "OpenAL Soft"; }
|
||||
|
|
@ -94,6 +95,10 @@ template<> struct ResamplerName<Resampler::FastBSinc24>
|
|||
{ static constexpr const ALchar *Get() noexcept { return "23rd order Sinc (fast)"; } };
|
||||
template<> struct ResamplerName<Resampler::BSinc24>
|
||||
{ static constexpr const ALchar *Get() noexcept { return "23rd order Sinc"; } };
|
||||
template<> struct ResamplerName<Resampler::FastBSinc48>
|
||||
{ static constexpr const ALchar *Get() noexcept { return "47th order Sinc (fast)"; } };
|
||||
template<> struct ResamplerName<Resampler::BSinc48>
|
||||
{ static constexpr const ALchar *Get() noexcept { return "47th order Sinc"; } };
|
||||
|
||||
const ALchar *GetResamplerName(const Resampler rtype)
|
||||
{
|
||||
|
|
@ -108,6 +113,8 @@ const ALchar *GetResamplerName(const Resampler rtype)
|
|||
HANDLE_RESAMPLER(Resampler::BSinc12);
|
||||
HANDLE_RESAMPLER(Resampler::FastBSinc24);
|
||||
HANDLE_RESAMPLER(Resampler::BSinc24);
|
||||
HANDLE_RESAMPLER(Resampler::FastBSinc48);
|
||||
HANDLE_RESAMPLER(Resampler::BSinc48);
|
||||
}
|
||||
#undef HANDLE_RESAMPLER
|
||||
/* Should never get here. */
|
||||
|
|
@ -144,24 +151,24 @@ constexpr auto ALenumFromDistanceModel(DistanceModel model) -> ALenum
|
|||
}
|
||||
|
||||
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,
|
||||
DopplerFactorProp = AL_DOPPLER_FACTOR,
|
||||
DopplerVelocityProp = AL_DOPPLER_VELOCITY,
|
||||
DistanceModelProp = AL_DISTANCE_MODEL,
|
||||
SpeedOfSoundProp = AL_SPEED_OF_SOUND,
|
||||
DeferredUpdatesProp = AL_DEFERRED_UPDATES_SOFT,
|
||||
GainLimitProp = AL_GAIN_LIMIT_SOFT,
|
||||
NumResamplersProp = AL_NUM_RESAMPLERS_SOFT,
|
||||
DefaultResamplerProp = AL_DEFAULT_RESAMPLER_SOFT,
|
||||
DebugLoggedMessagesProp = AL_DEBUG_LOGGED_MESSAGES_EXT,
|
||||
DebugNextLoggedMessageLengthProp = AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_EXT,
|
||||
MaxDebugMessageLengthProp = AL_MAX_DEBUG_MESSAGE_LENGTH_EXT,
|
||||
MaxDebugLoggedMessagesProp = AL_MAX_DEBUG_LOGGED_MESSAGES_EXT,
|
||||
MaxDebugGroupDepthProp = AL_MAX_DEBUG_GROUP_STACK_DEPTH_EXT,
|
||||
MaxLabelLengthProp = AL_MAX_LABEL_LENGTH_EXT,
|
||||
ContextFlagsProp = AL_CONTEXT_FLAGS_EXT,
|
||||
#if ALSOFT_EAX
|
||||
EaxRamSizeProp = AL_EAX_RAM_SIZE,
|
||||
EaxRamFreeProp = AL_EAX_RAM_FREE,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -259,7 +266,7 @@ void GetValue(ALCcontext *context, ALenum pname, T *values)
|
|||
*values = cast_value(context->mContextFlags.to_ulong());
|
||||
return;
|
||||
|
||||
#ifdef ALSOFT_EAX
|
||||
#if ALSOFT_EAX
|
||||
#define EAX_ERROR "[alGetInteger] EAX not enabled"
|
||||
|
||||
case AL_EAX_RAM_SIZE:
|
||||
|
|
@ -268,7 +275,7 @@ void GetValue(ALCcontext *context, ALenum pname, T *values)
|
|||
*values = cast_value(eax_x_ram_max_size);
|
||||
return;
|
||||
}
|
||||
ERR(EAX_ERROR "\n");
|
||||
ERR(EAX_ERROR);
|
||||
break;
|
||||
|
||||
case AL_EAX_RAM_FREE:
|
||||
|
|
@ -279,13 +286,13 @@ void GetValue(ALCcontext *context, ALenum pname, T *values)
|
|||
*values = cast_value(device->eax_x_ram_free_size);
|
||||
return;
|
||||
}
|
||||
ERR(EAX_ERROR "\n");
|
||||
ERR(EAX_ERROR);
|
||||
break;
|
||||
|
||||
#undef EAX_ERROR
|
||||
#endif // ALSOFT_EAX
|
||||
}
|
||||
context->setError(AL_INVALID_ENUM, "Invalid context property 0x%04x", pname);
|
||||
context->setError(AL_INVALID_ENUM, "Invalid context property {:#04x}", as_unsigned(pname));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -331,7 +338,8 @@ FORCE_ALIGN void AL_APIENTRY alEnableDirect(ALCcontext *context, ALenum capabili
|
|||
context->setError(AL_INVALID_OPERATION, "Re-enabling AL_STOP_SOURCES_ON_DISCONNECT_SOFT not yet supported");
|
||||
return;
|
||||
}
|
||||
context->setError(AL_INVALID_VALUE, "Invalid enable property 0x%04x", capability);
|
||||
context->setError(AL_INVALID_VALUE, "Invalid enable property {:#04x}",
|
||||
as_unsigned(capability));
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(void, alDisable, ALenum,capability)
|
||||
|
|
@ -355,7 +363,8 @@ FORCE_ALIGN void AL_APIENTRY alDisableDirect(ALCcontext *context, ALenum capabil
|
|||
context->mStopVoicesOnDisconnect.store(false);
|
||||
return;
|
||||
}
|
||||
context->setError(AL_INVALID_VALUE, "Invalid disable property 0x%04x", capability);
|
||||
context->setError(AL_INVALID_VALUE, "Invalid disable property {:#04x}",
|
||||
as_unsigned(capability));
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(ALboolean, alIsEnabled, ALenum,capability)
|
||||
|
|
@ -369,14 +378,15 @@ FORCE_ALIGN ALboolean AL_APIENTRY alIsEnabledDirect(ALCcontext *context, ALenum
|
|||
case AL_STOP_SOURCES_ON_DISCONNECT_SOFT:
|
||||
return context->mStopVoicesOnDisconnect.load() ? AL_TRUE : AL_FALSE;
|
||||
}
|
||||
context->setError(AL_INVALID_VALUE, "Invalid is enabled property 0x%04x", capability);
|
||||
context->setError(AL_INVALID_VALUE, "Invalid is enabled property {:#04x}",
|
||||
as_unsigned(capability));
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
#define DECL_GETFUNC(R, Name, Ext) \
|
||||
AL_API auto AL_APIENTRY Name##Ext(ALenum pname) noexcept -> R \
|
||||
auto AL_APIENTRY Name##Ext(ALenum pname) noexcept -> R \
|
||||
{ \
|
||||
R value{}; \
|
||||
auto value = R{}; \
|
||||
auto context = GetContextRef(); \
|
||||
if(!context) UNLIKELY return value; \
|
||||
Name##vDirect##Ext(GetContextRef().get(), pname, &value); \
|
||||
|
|
@ -384,18 +394,19 @@ AL_API auto AL_APIENTRY Name##Ext(ALenum pname) noexcept -> R \
|
|||
} \
|
||||
FORCE_ALIGN auto AL_APIENTRY Name##Direct##Ext(ALCcontext *context, ALenum pname) noexcept -> R \
|
||||
{ \
|
||||
R value{}; \
|
||||
auto value = R{}; \
|
||||
Name##vDirect##Ext(context, pname, &value); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
DECL_GETFUNC(ALboolean, alGetBoolean,)
|
||||
DECL_GETFUNC(ALdouble, alGetDouble,)
|
||||
DECL_GETFUNC(ALfloat, alGetFloat,)
|
||||
DECL_GETFUNC(ALint, alGetInteger,)
|
||||
AL_API DECL_GETFUNC(ALboolean, alGetBoolean,)
|
||||
AL_API DECL_GETFUNC(ALdouble, alGetDouble,)
|
||||
AL_API DECL_GETFUNC(ALfloat, alGetFloat,)
|
||||
AL_API DECL_GETFUNC(ALint, alGetInteger,)
|
||||
|
||||
DECL_GETFUNC(ALint64SOFT, alGetInteger64,SOFT)
|
||||
DECL_GETFUNC(ALvoid*, alGetPointer,SOFT)
|
||||
DECL_GETFUNC(ALvoidptr, alGetPointer,EXT)
|
||||
AL_API DECL_GETFUNC(ALint64SOFT, alGetInteger64,SOFT)
|
||||
AL_API DECL_GETFUNC(ALvoidptr, alGetPointer,SOFT)
|
||||
|
||||
#undef DECL_GETFUNC
|
||||
|
||||
|
|
@ -442,6 +453,10 @@ FORCE_ALIGN void AL_APIENTRY alGetInteger64vDirectSOFT(ALCcontext *context, ALen
|
|||
|
||||
AL_API DECL_FUNCEXT2(void, alGetPointerv,SOFT, ALenum,pname, ALvoid**,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum pname, ALvoid **values) noexcept
|
||||
{ return alGetPointervDirectEXT(context, pname, values); }
|
||||
|
||||
FORCE_ALIGN DECL_FUNCEXT2(void, alGetPointerv,EXT, ALenum,pname, ALvoid**,values)
|
||||
FORCE_ALIGN void AL_APIENTRY alGetPointervDirectEXT(ALCcontext *context, ALenum pname, ALvoid **values) noexcept
|
||||
{
|
||||
if(!values) UNLIKELY
|
||||
return context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||
|
|
@ -464,7 +479,8 @@ FORCE_ALIGN void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum
|
|||
*values = context->mDebugParam;
|
||||
return;
|
||||
}
|
||||
context->setError(AL_INVALID_ENUM, "Invalid context pointer property 0x%04x", pname);
|
||||
context->setError(AL_INVALID_ENUM, "Invalid context pointer property {:#04x}",
|
||||
as_unsigned(pname));
|
||||
}
|
||||
|
||||
AL_API DECL_FUNC1(const ALchar*, alGetString, ALenum,pname)
|
||||
|
|
@ -472,9 +488,18 @@ FORCE_ALIGN const ALchar* AL_APIENTRY alGetStringDirect(ALCcontext *context, ALe
|
|||
{
|
||||
switch(pname)
|
||||
{
|
||||
case AL_VENDOR: return GetVendorString();
|
||||
case AL_VERSION: return GetVersionString();
|
||||
case AL_RENDERER: return GetRendererString();
|
||||
case AL_VENDOR:
|
||||
if(auto device = context->mALDevice.get(); !device->mVendorOverride.empty())
|
||||
return device->mVendorOverride.c_str();
|
||||
return GetVendorString();
|
||||
case AL_VERSION:
|
||||
if(auto device = context->mALDevice.get(); !device->mVersionOverride.empty())
|
||||
return device->mVersionOverride.c_str();
|
||||
return GetVersionString();
|
||||
case AL_RENDERER:
|
||||
if(auto device = context->mALDevice.get(); !device->mRendererOverride.empty())
|
||||
return device->mRendererOverride.c_str();
|
||||
return GetRendererString();
|
||||
case AL_EXTENSIONS: return context->mExtensionsString.c_str();
|
||||
case AL_NO_ERROR: return GetNoErrorString();
|
||||
case AL_INVALID_NAME: return GetInvalidNameString();
|
||||
|
|
@ -485,7 +510,7 @@ FORCE_ALIGN const ALchar* AL_APIENTRY alGetStringDirect(ALCcontext *context, ALe
|
|||
case AL_STACK_OVERFLOW_EXT: return GetStackOverflowString();
|
||||
case AL_STACK_UNDERFLOW_EXT: return GetStackUnderflowString();
|
||||
}
|
||||
context->setError(AL_INVALID_VALUE, "Invalid string property 0x%04x", pname);
|
||||
context->setError(AL_INVALID_VALUE, "Invalid string property {:#04x}", as_unsigned(pname));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -493,7 +518,7 @@ AL_API DECL_FUNC1(void, alDopplerFactor, ALfloat,value)
|
|||
FORCE_ALIGN void AL_APIENTRY alDopplerFactorDirect(ALCcontext *context, ALfloat value) noexcept
|
||||
{
|
||||
if(!(value >= 0.0f && std::isfinite(value)))
|
||||
context->setError(AL_INVALID_VALUE, "Doppler factor %f out of range", value);
|
||||
context->setError(AL_INVALID_VALUE, "Doppler factor {:f} out of range", value);
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -506,7 +531,7 @@ AL_API DECL_FUNC1(void, alSpeedOfSound, ALfloat,value)
|
|||
FORCE_ALIGN void AL_APIENTRY alSpeedOfSoundDirect(ALCcontext *context, ALfloat value) noexcept
|
||||
{
|
||||
if(!(value > 0.0f && std::isfinite(value)))
|
||||
context->setError(AL_INVALID_VALUE, "Speed of sound %f out of range", value);
|
||||
context->setError(AL_INVALID_VALUE, "Speed of sound {:f} out of range", value);
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -526,7 +551,8 @@ FORCE_ALIGN void AL_APIENTRY alDistanceModelDirect(ALCcontext *context, ALenum v
|
|||
UpdateProps(context);
|
||||
}
|
||||
else
|
||||
context->setError(AL_INVALID_VALUE, "Distance model 0x%04x out of range", value);
|
||||
context->setError(AL_INVALID_VALUE, "Distance model {:#04x} out of range",
|
||||
as_unsigned(value));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -551,12 +577,13 @@ FORCE_ALIGN const ALchar* AL_APIENTRY alGetStringiDirectSOFT(ALCcontext *context
|
|||
switch(pname)
|
||||
{
|
||||
case AL_RESAMPLER_NAME_SOFT:
|
||||
if(index >= 0 && index <= static_cast<ALint>(Resampler::Max))
|
||||
if(index >= 0 && index <= al::to_underlying(Resampler::Max))
|
||||
return GetResamplerName(static_cast<Resampler>(index));
|
||||
context->setError(AL_INVALID_VALUE, "Resampler name index %d out of range", index);
|
||||
context->setError(AL_INVALID_VALUE, "Resampler name index {} out of range", index);
|
||||
return nullptr;
|
||||
}
|
||||
context->setError(AL_INVALID_VALUE, "Invalid string indexed property");
|
||||
context->setError(AL_INVALID_VALUE, "Invalid string indexed property {:#04x}",
|
||||
as_unsigned(pname));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -567,13 +594,13 @@ AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value) noexcept
|
|||
if(!context) UNLIKELY return;
|
||||
|
||||
if(context->mContextFlags.test(ContextFlags::DebugBit)) UNLIKELY
|
||||
context->debugMessage(DebugSource::API, DebugType::DeprecatedBehavior, 0,
|
||||
context->debugMessage(DebugSource::API, DebugType::DeprecatedBehavior, 1,
|
||||
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);
|
||||
context->setError(AL_INVALID_VALUE, "Doppler velocity {:f} out of range", value);
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> proplock{context->mPropLock};
|
||||
|
|
@ -611,6 +638,9 @@ void UpdateContextProps(ALCcontext *context)
|
|||
props->DopplerFactor = context->mDopplerFactor;
|
||||
props->DopplerVelocity = context->mDopplerVelocity;
|
||||
props->SpeedOfSound = context->mSpeedOfSound;
|
||||
#if ALSOFT_EAX
|
||||
props->DistanceFactor = context->eaxGetDistanceFactor();
|
||||
#endif
|
||||
|
||||
props->SourceDistanceModel = context->mSourceDistanceModel;
|
||||
props->mDistanceModel = context->mDistanceModel;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue