From 986a58d5b4936ec6bd4dca7769d291e5a5961f75 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 28 Aug 2020 00:44:55 -0700 Subject: Pass a BufferStorage to EffectState::createBuffer --- al/auxeffectslot.cpp | 8 ++------ alc/alc.cpp | 9 ++------- alc/effects/base.h | 7 +++---- alc/effects/convolution.cpp | 38 ++++++++++++++++++++------------------ 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index fb2d2233..1f35b344 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -469,9 +469,7 @@ START_API_FUNC { FPUCtl mixer_mode{}; auto *state = slot->Effect.State.get(); - slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer.mData.data(), - buffer->mBuffer.mSampleRate, buffer->mBuffer.mType, buffer->mBuffer.mChannels, - buffer->mBuffer.mSampleLen)); + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer)); } } break; @@ -746,9 +744,7 @@ ALenum ALeffectslot::initEffect(ALeffect *effect, ALCcontext *context) State->deviceUpdate(Device); Effect.Buffer = nullptr; if(Buffer) - Effect.Buffer.reset(State->createBuffer(Device, Buffer->mBuffer.mData.data(), - Buffer->mBuffer.mSampleRate, Buffer->mBuffer.mType, Buffer->mBuffer.mChannels, - Buffer->mBuffer.mSampleLen)); + Effect.Buffer.reset(State->createBuffer(Device, Buffer->mBuffer)); } if(!effect) diff --git a/alc/alc.cpp b/alc/alc.cpp index 3ad3569c..7841df28 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2101,9 +2101,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) if(ALbuffer *buffer{slot->Buffer}) { slot->Effect.Buffer = nullptr; - slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer.mData.data(), - buffer->mBuffer.mSampleRate, buffer->mBuffer.mType, buffer->mBuffer.mChannels, - buffer->mBuffer.mSampleLen)); + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer)); } slot->updateProps(context); } @@ -2129,10 +2127,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) if(ALbuffer *buffer{slot->Buffer}) { slot->Effect.Buffer = nullptr; - slot->Effect.Buffer.reset(state->createBuffer(device, - buffer->mBuffer.mData.data(), buffer->mBuffer.mSampleRate, - buffer->mBuffer.mType, buffer->mBuffer.mChannels, - buffer->mBuffer.mSampleLen)); + slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer)); } slot->updateProps(context); } diff --git a/alc/effects/base.h b/alc/effects/base.h index e662d69c..251a066f 100644 --- a/alc/effects/base.h +++ b/alc/effects/base.h @@ -8,10 +8,10 @@ #include "almalloc.h" #include "alspan.h" #include "atomic.h" -#include "buffer_storage.h" #include "intrusive_ptr.h" struct ALeffectslot; +struct BufferStorage; union EffectProps { @@ -173,11 +173,10 @@ struct EffectState : public al::intrusive_ref { 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. + * deleted or altered during a mix. */ virtual EffectBufferBase *createBuffer(const ALCdevice */*device*/, - const al::byte */*sampleData*/, ALuint /*sampleRate*/, FmtType /*sampleType*/, - FmtChannels /*channelType*/, ALuint /*numSamples*/) + const BufferStorage &/*buffer*/) { 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 samplesIn, const al::span samplesOut) = 0; diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp index 2ebb9f51..3ad912cb 100644 --- a/alc/effects/convolution.cpp +++ b/alc/effects/convolution.cpp @@ -10,6 +10,7 @@ #include "alcontext.h" #include "almalloc.h" #include "alspan.h" +#include "buffer_storage.h" #include "effects/base.h" #include "fmt_traits.h" #include "logging.h" @@ -107,8 +108,7 @@ struct ConvolutionState final : public EffectState { ~ConvolutionState() override = default; void deviceUpdate(const ALCdevice *device) override; - EffectBufferBase *createBuffer(const ALCdevice *device, const al::byte *sampleData, - ALuint sampleRate, FmtType sampleType, FmtChannels channelType, ALuint numSamples) override; + EffectBufferBase *createBuffer(const ALCdevice *device, const BufferStorage &buffer) override; void update(const ALCcontext *context, const ALeffectslot *slot, const EffectProps *props, const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; @@ -133,14 +133,13 @@ void ConvolutionState::deviceUpdate(const ALCdevice* /*device*/) } EffectBufferBase *ConvolutionState::createBuffer(const ALCdevice *device, - const al::byte *sampleData, ALuint sampleRate, FmtType sampleType, - FmtChannels channelType, ALuint numSamples) + const BufferStorage &buffer) { /* An empty buffer doesn't need a convolution filter. */ - if(numSamples < 1) return nullptr; + if(buffer.mSampleLen < 1) return nullptr; /* FIXME: Support anything. */ - if(channelType != FmtMono && channelType != FmtStereo) + if(buffer.mChannels != FmtMono && buffer.mChannels != FmtStereo) return nullptr; /* The impulse response needs to have the same sample rate as the input and @@ -149,21 +148,23 @@ EffectBufferBase *ConvolutionState::createBuffer(const ALCdevice *device, * very infrequent called, go ahead and use the polyphase resampler. */ PPhaseResampler resampler; - if(device->Frequency != sampleRate) - resampler.init(sampleRate, device->Frequency); + if(device->Frequency != buffer.mSampleRate) + resampler.init(buffer.mSampleRate, device->Frequency); const auto resampledCount = static_cast( - (uint64_t{numSamples}*device->Frequency + (sampleRate-1)) / sampleRate); + (uint64_t{buffer.mSampleLen}*device->Frequency + (buffer.mSampleRate-1)) / + buffer.mSampleRate); al::intrusive_ptr filter{new ConvolutionFilter{}}; - auto bytesPerSample = BytesFromFmt(sampleType); - auto numChannels = ChannelsFromFmt(channelType, 1); + auto bytesPerSample = BytesFromFmt(buffer.mType); + auto numChannels = ChannelsFromFmt(buffer.mChannels, buffer.mAmbiOrder); constexpr size_t m{ConvolveUpdateSize/2 + 1}; /* Calculate the number of segments needed to hold the impulse response and * the input history (rounded up), and allocate them. */ - filter->mNumConvolveSegs = (numSamples+(ConvolveUpdateSamples-1)) / ConvolveUpdateSamples; + filter->mNumConvolveSegs = (buffer.mSampleLen+(ConvolveUpdateSamples-1)) / + ConvolveUpdateSamples; const size_t complex_length{filter->mNumConvolveSegs * m * (numChannels+1)}; filter->mComplexData = std::make_unique(complex_length); @@ -174,17 +175,18 @@ EffectBufferBase *ConvolutionState::createBuffer(const ALCdevice *device, for(size_t c{1};c < numChannels;++c) filter->mConvolveFilter[c] = filter->mConvolveFilter[c-1] + filter->mNumConvolveSegs*m; - filter->mChannels = channelType; + filter->mChannels = buffer.mChannels; auto fftbuffer = std::make_unique>(); - auto srcsamples = std::make_unique(maxz(numSamples, resampledCount)); + auto srcsamples = std::make_unique(maxz(buffer.mSampleLen, resampledCount)); for(size_t c{0};c < numChannels;++c) { /* Load the samples from the buffer, and resample to match the device. */ - LoadSamples(srcsamples.get(), sampleData + bytesPerSample*c, numChannels, sampleType, - numSamples); - if(device->Frequency != sampleRate) - resampler.process(numSamples, srcsamples.get(), resampledCount, srcsamples.get()); + LoadSamples(srcsamples.get(), buffer.mData.data() + bytesPerSample*c, numChannels, + buffer.mType, buffer.mSampleLen); + if(device->Frequency != buffer.mSampleRate) + resampler.process(buffer.mSampleLen, srcsamples.get(), resampledCount, + srcsamples.get()); size_t done{0}; complex_d *filteriter = filter->mConvolveFilter[c]; -- cgit v1.2.3