diff options
author | Chris Robinson <[email protected]> | 2020-08-24 19:10:16 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-08-24 19:13:46 -0700 |
commit | 9e5a388dfe2dbd5250f80675426c95a9bdade39c (patch) | |
tree | 87f73a32036dff620eb571b76e5faf52f428431e | |
parent | 9d61484e4bc0b2691b714d758391b3c3ecfd7890 (diff) |
Add a method for effects to create persistent buffer data
-rw-r--r-- | al/auxeffectslot.cpp | 13 | ||||
-rw-r--r-- | al/auxeffectslot.h | 1 | ||||
-rw-r--r-- | alc/alc.cpp | 13 | ||||
-rw-r--r-- | alc/effects/base.h | 13 |
4 files changed, 39 insertions, 1 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index bfacb290..88512bef 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -460,7 +460,14 @@ START_API_FUNC DecrementRef(oldbuffer->ref); slot->Buffer = buffer; - /* TODO: Create a shared effectstate representation of the buffer. */ + slot->Effect.Buffer = nullptr; + if(buffer) + { + FPUCtl mixer_mode{}; + auto *state = slot->Effect.State.get(); + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(), + buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels, buffer->SampleLen)); + } } break; @@ -730,6 +737,10 @@ ALenum ALeffectslot::initEffect(ALeffect *effect, ALCcontext *context) { FPUCtl mixer_mode{}; State->deviceUpdate(Device); + Effect.Buffer = nullptr; + if(Buffer) + Effect.Buffer.reset(State->createBuffer(Device, Buffer->mData.data(), + Buffer->Frequency, Buffer->mFmtType, Buffer->mFmtChannels, Buffer->SampleLen)); } if(!effect) diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h index 71f99a11..de640b58 100644 --- a/al/auxeffectslot.h +++ b/al/auxeffectslot.h @@ -50,6 +50,7 @@ struct ALeffectslot { EffectProps Props{}; al::intrusive_ptr<EffectState> State; + al::intrusive_ptr<EffectBufferBase> Buffer; } Effect; std::atomic_flag PropsClean; diff --git a/alc/alc.cpp b/alc/alc.cpp index 75f809de..40bef38d 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2098,6 +2098,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) EffectState *state{slot->Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; state->deviceUpdate(device); + if(ALbuffer *buffer{slot->Buffer}) + { + slot->Effect.Buffer = nullptr; + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(), + buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels, buffer->SampleLen)); + } slot->updateProps(context); } @@ -2119,6 +2125,13 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) EffectState *state{slot->Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; state->deviceUpdate(device); + if(ALbuffer *buffer{slot->Buffer}) + { + slot->Effect.Buffer = nullptr; + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(), + buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels, + buffer->SampleLen)); + } slot->updateProps(context); } } diff --git a/alc/effects/base.h b/alc/effects/base.h index 8ed3c6f8..f4ca6df2 100644 --- a/alc/effects/base.h +++ b/alc/effects/base.h @@ -8,6 +8,7 @@ #include "almalloc.h" #include "alspan.h" #include "atomic.h" +#include "buffer_formats.h" #include "intrusive_ptr.h" struct ALeffectslot; @@ -154,6 +155,10 @@ const EffectVtable T##_vtable = { \ } +struct EffectBufferBase : public al::intrusive_ref<EffectBufferBase> { + virtual ~EffectBufferBase() = default; +}; + struct EffectTarget { MixParams *Main; RealMixParams *RealOut; @@ -166,6 +171,14 @@ struct EffectState : public al::intrusive_ref<EffectState> { virtual ~EffectState() = default; virtual void deviceUpdate(const ALCdevice *device) = 0; + /* Implementations are currently required to copy the buffer data if they + * wish to hold on to it, as there's no guarantee the buffer won't be + * detached and deleted or altered during a mix. + */ + virtual EffectBufferBase *createBuffer(const ALCdevice */*device*/, + const al::byte */*samplesData*/, ALuint /*sampleRate*/, FmtType /*sampleType*/, + FmtChannels /*channelType*/, ALuint /*numSamples*/) + { return nullptr; } virtual void update(const ALCcontext *context, const ALeffectslot *slot, const EffectProps *props, const EffectTarget target) = 0; virtual void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut) = 0; }; |