aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-08-24 19:10:16 -0700
committerChris Robinson <[email protected]>2020-08-24 19:13:46 -0700
commit9e5a388dfe2dbd5250f80675426c95a9bdade39c (patch)
tree87f73a32036dff620eb571b76e5faf52f428431e
parent9d61484e4bc0b2691b714d758391b3c3ecfd7890 (diff)
Add a method for effects to create persistent buffer data
-rw-r--r--al/auxeffectslot.cpp13
-rw-r--r--al/auxeffectslot.h1
-rw-r--r--alc/alc.cpp13
-rw-r--r--alc/effects/base.h13
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;
};