diff options
author | Chris Robinson <[email protected]> | 2020-11-02 04:24:36 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-11-02 04:24:36 -0800 |
commit | 52d58a40234b8829801f0a587375eca91694c30f (patch) | |
tree | caa8d283de74feeb4f23eab39ea57b3835c3bffc /alc/alc.cpp | |
parent | 6e05adf955bdd81c82a1feabb25f6f27d7bc56e0 (diff) |
Store the wet buffers in the context
This is rather ugly, but we need the wet buffers to remain allocated after its
effect slot is deleted, because a voice can still use it for its final fade-out
mix.
Diffstat (limited to 'alc/alc.cpp')
-rw-r--r-- | alc/alc.cpp | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index c4fdad95..b3da9209 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2100,9 +2100,35 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) FPUCtl mixer_mode{}; for(ALCcontext *context : *device->mContexts.load()) { + std::unique_lock<std::mutex> proplock{context->mPropLock}; + std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock}; + /* HACK: Clear the effect slots' wet buffer references, and clear the wet + * buffer array so they're reallocated (with potentially a new channel + * count) when reinitialized. + */ + if(ALeffectslot *slot{context->mDefaultSlot.get()}) + { + slot->mWetBuffer = nullptr; + slot->Wet.Buffer = {}; + } + for(auto &sublist : context->mEffectSlotList) + { + uint64_t usemask{~sublist.FreeMask}; + while(usemask) + { + const ALsizei idx{CountTrailingZeros(usemask)}; + ALeffectslot *slot{sublist.EffectSlots + idx}; + usemask &= ~(1_u64 << idx); + + slot->mWetBuffer = nullptr; + slot->Wet.Buffer = {}; + } + } + decltype(context->mWetBuffers){}.swap(context->mWetBuffers); + if(ALeffectslot *slot{context->mDefaultSlot.get()}) { - aluInitEffectPanning(slot, device); + aluInitEffectPanning(slot, context); EffectState *state{slot->Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; @@ -2112,8 +2138,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) slot->updateProps(context); } - std::unique_lock<std::mutex> proplock{context->mPropLock}; - std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock}; if(ALeffectslotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)}) std::fill_n(curarray->end(), curarray->size(), nullptr); for(auto &sublist : context->mEffectSlotList) @@ -2125,7 +2149,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) ALeffectslot *slot{sublist.EffectSlots + idx}; usemask &= ~(1_u64 << idx); - aluInitEffectPanning(slot, device); + aluInitEffectPanning(slot, context); EffectState *state{slot->Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; @@ -2439,7 +2463,7 @@ void ALCcontext::init() { mDefaultSlot = std::unique_ptr<ALeffectslot>{new ALeffectslot{}}; if(mDefaultSlot->init() == AL_NO_ERROR) - aluInitEffectPanning(mDefaultSlot.get(), mDevice.get()); + aluInitEffectPanning(mDefaultSlot.get(), this); else { mDefaultSlot = nullptr; |