Add a method for effects to create persistent buffer data
This commit is contained in:
+12
-1
@@ -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)
|
||||
|
||||
@@ -50,6 +50,7 @@ struct ALeffectslot {
|
||||
EffectProps Props{};
|
||||
|
||||
al::intrusive_ptr<EffectState> State;
|
||||
al::intrusive_ptr<EffectBufferBase> Buffer;
|
||||
} Effect;
|
||||
|
||||
std::atomic_flag PropsClean;
|
||||
|
||||
+13
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user