diff options
author | Chris Robinson <[email protected]> | 2020-08-24 16:08:09 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-08-24 16:08:09 -0700 |
commit | f9d6aa2f480a0d647e8ad901a5680c335ba4fa0c (patch) | |
tree | a5c583d374282367993e56787d331c378365d952 /al | |
parent | 54a0972bfe3c4f248d495ed71ff734ed99cf9ab7 (diff) |
Allow setting a buffer on an effect slot
Diffstat (limited to 'al')
-rw-r--r-- | al/auxeffectslot.cpp | 50 | ||||
-rw-r--r-- | al/auxeffectslot.h | 2 |
2 files changed, 51 insertions, 1 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index 00da51f6..c5f9a295 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -41,6 +41,7 @@ #include "alnumeric.h" #include "alspan.h" #include "alu.h" +#include "buffer.h" #include "effect.h" #include "fpu_ctrl.h" #include "inprogext.h" @@ -76,6 +77,19 @@ inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) noexcept return sublist.Effects + slidx; } +inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) noexcept +{ + const size_t lidx{(id-1) >> 6}; + const ALuint slidx{(id-1) & 0x3f}; + + if UNLIKELY(lidx >= device->BufferList.size()) + return nullptr; + BufferSubList &sublist = device->BufferList[lidx]; + if UNLIKELY(sublist.FreeMask & (1_u64 << slidx)) + return nullptr; + return sublist.Buffers + slidx; +} + void AddActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *context) { @@ -370,6 +384,7 @@ START_API_FUNC SETERR_RETURN(context, AL_INVALID_NAME,, "Invalid effect slot ID %u", effectslot); ALeffectslot *target{}; + ALbuffer *buffer{}; ALCdevice *device{}; ALenum err{}; switch(param) @@ -377,7 +392,8 @@ START_API_FUNC case AL_EFFECTSLOT_EFFECT: device = context->mDevice.get(); - { std::lock_guard<std::mutex> ___{device->EffectLock}; + { + std::lock_guard<std::mutex> ___{device->EffectLock}; ALeffect *effect{value ? LookupEffect(device, static_cast<ALuint>(value)) : nullptr}; if(!(value == 0 || effect != nullptr)) SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid effect ID %u", value); @@ -428,6 +444,26 @@ START_API_FUNC slot->Target = target; break; + case AL_BUFFER: + device = context->mDevice.get(); + + { + std::lock_guard<std::mutex> ___{device->BufferLock}; + if(value) + { + buffer = LookupBuffer(device, static_cast<ALuint>(value)); + if(!buffer) SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid buffer ID"); + } + + if(buffer) IncrementRef(buffer->ref); + if(ALbuffer *oldbuffer{slot->Buffer}) + DecrementRef(oldbuffer->ref); + slot->Buffer = buffer; + + /* TODO: Create a shared effectstate representation of the buffer. */ + } + break; + default: SETERR_RETURN(context, AL_INVALID_ENUM,, "Invalid effect slot integer property 0x%04x", param); @@ -444,6 +480,7 @@ START_API_FUNC case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: case AL_EFFECTSLOT_TARGET_SOFT: + case AL_BUFFER: alAuxiliaryEffectSloti(effectslot, param, values[0]); return; } @@ -545,6 +582,13 @@ START_API_FUNC *value = 0; break; + case AL_BUFFER: + if(auto *buffer = slot->Buffer) + *value = static_cast<ALint>(buffer->id); + else + *value = 0; + break; + default: context->setError(AL_INVALID_ENUM, "Invalid effect slot integer property 0x%04x", param); } @@ -559,6 +603,7 @@ START_API_FUNC case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: case AL_EFFECTSLOT_TARGET_SOFT: + case AL_BUFFER: alGetAuxiliaryEffectSloti(effectslot, param, values); return; } @@ -636,6 +681,9 @@ ALeffectslot::~ALeffectslot() if(Target) DecrementRef(Target->ref); Target = nullptr; + if(Buffer) + DecrementRef(Buffer->ref); + Buffer = nullptr; ALeffectslotProps *props{Params.Update.load()}; if(props) diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h index 12411ede..c9e54f60 100644 --- a/al/auxeffectslot.h +++ b/al/auxeffectslot.h @@ -15,6 +15,7 @@ #include "intrusive_ptr.h" #include "vector.h" +struct ALbuffer; struct ALeffect; struct ALeffectslot; @@ -42,6 +43,7 @@ struct ALeffectslot { float Gain{1.0f}; bool AuxSendAuto{true}; ALeffectslot *Target{nullptr}; + ALbuffer *Buffer{nullptr}; struct { ALenum Type{AL_EFFECT_NULL}; |