diff options
-rw-r--r-- | alc/voice.cpp | 8 | ||||
-rw-r--r-- | core/uhjfilter.cpp | 49 | ||||
-rw-r--r-- | core/uhjfilter.h | 7 |
3 files changed, 31 insertions, 33 deletions
diff --git a/alc/voice.cpp b/alc/voice.cpp index 7e761b29..891bc3dc 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -636,15 +636,9 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) if(mDecoder) { - std::array<float*,4> samples{{mVoiceSamples[0].data() + MaxResamplerEdge, - mVoiceSamples[1].data() + MaxResamplerEdge, - mVoiceSamples[2].data() + MaxResamplerEdge, - nullptr}}; - if(mVoiceSamples.size() > 3) - samples[3] = mVoiceSamples[3].data() + MaxResamplerEdge; const size_t srcOffset{(increment*DstBufferSize + DataPosFrac)>>MixerFracBits}; SrcBufferSize = SrcBufferSize - PostPadding + MaxResamplerEdge; - mDecoder->decode(samples, SrcBufferSize, srcOffset); + mDecoder->decode(mVoiceSamples, MaxResamplerEdge, SrcBufferSize, srcOffset); } } diff --git a/core/uhjfilter.cpp b/core/uhjfilter.cpp index 6f01e608..f1ba8589 100644 --- a/core/uhjfilter.cpp +++ b/core/uhjfilter.cpp @@ -109,55 +109,56 @@ void Uhj2Encoder::encode(const FloatBufferSpan LeftOut, const FloatBufferSpan Ri * UHJ should not be run through a normal B-Format decoder, as it needs * different shelf filters. */ -void UhjDecoder::decode(const al::span<float*,4> Samples, const size_t SamplesToDo, - const size_t ForwardSamples) +void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset, + const size_t samplesToDo, const size_t forwardSamples) { - ASSUME(SamplesToDo > 0); + ASSUME(samplesToDo > 0); /* S = Left + Right */ - for(size_t i{0};i < SamplesToDo+sFilterDelay;++i) - mS[i] = Samples[0][i] + Samples[1][i]; + for(size_t i{0};i < samplesToDo+sFilterDelay;++i) + mS[i] = samples[0][offset+i] + samples[1][offset+i]; /* D = Left - Right */ - for(size_t i{0};i < SamplesToDo+sFilterDelay;++i) - mD[i] = Samples[0][i] - Samples[1][i]; + for(size_t i{0};i < samplesToDo+sFilterDelay;++i) + mD[i] = samples[0][offset+i] - samples[1][offset+i]; /* T */ - for(size_t i{0};i < SamplesToDo+sFilterDelay;++i) - mT[i] = Samples[2][i]; + for(size_t i{0};i < samplesToDo+sFilterDelay;++i) + mT[i] = samples[2][offset+i]; - float *woutput{Samples[0]}; - float *xoutput{Samples[1]}; - float *youtput{Samples[2]}; + float *woutput{samples[0].data() + offset}; + float *xoutput{samples[1].data() + offset}; + float *youtput{samples[2].data() + offset}; /* Precompute j(0.828347*D + 0.767835*T) and store in xoutput. */ auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin()); - std::transform(mD.cbegin(), mD.cbegin()+SamplesToDo+sFilterDelay, mT.cbegin(), tmpiter, + std::transform(mD.cbegin(), mD.cbegin()+samplesToDo+sFilterDelay, mT.cbegin(), tmpiter, [](const float d, const float t) noexcept { return 0.828347f*d + 0.767835f*t; }); - std::copy_n(mTemp.cbegin()+ForwardSamples, mDTHistory.size(), mDTHistory.begin()); - PShift.process({xoutput, SamplesToDo}, mTemp.data()); + std::copy_n(mTemp.cbegin()+forwardSamples, mDTHistory.size(), mDTHistory.begin()); + PShift.process({xoutput, samplesToDo}, mTemp.data()); /* W = 0.981530*S + 0.197484*j(0.828347*D + 0.767835*T) */ - for(size_t i{0};i < SamplesToDo;++i) + for(size_t i{0};i < samplesToDo;++i) woutput[i] = 0.981530f*mS[i] + 0.197484f*xoutput[i]; /* X = 0.418504*S - j(0.828347*D + 0.767835*T) */ - for(size_t i{0};i < SamplesToDo;++i) + for(size_t i{0};i < samplesToDo;++i) xoutput[i] = 0.418504f*mS[i] - xoutput[i]; /* Precompute j*S and store in youtput. */ tmpiter = std::copy(mSHistory.cbegin(), mSHistory.cend(), mTemp.begin()); - std::copy_n(mS.cbegin(), SamplesToDo+sFilterDelay, tmpiter); - std::copy_n(mTemp.cbegin()+ForwardSamples, mSHistory.size(), mSHistory.begin()); - PShift.process({youtput, SamplesToDo}, mTemp.data()); + std::copy_n(mS.cbegin(), samplesToDo+sFilterDelay, tmpiter); + std::copy_n(mTemp.cbegin()+forwardSamples, mSHistory.size(), mSHistory.begin()); + PShift.process({youtput, samplesToDo}, mTemp.data()); /* Y = 0.795954*D - 0.676406*T + j(0.186626*S) */ - for(size_t i{0};i < SamplesToDo;++i) + for(size_t i{0};i < samplesToDo;++i) youtput[i] = 0.795954f*mD[i] - 0.676406f*mT[i] + 0.186626f*youtput[i]; - if(Samples[3]) + if(samples.size() > 3) { + float *zoutput{samples[3].data() + offset}; /* Z = 1.023332*Q */ - for(size_t i{0};i < SamplesToDo;++i) - Samples[3][i] = 1.023332f*Samples[3][i]; + for(size_t i{0};i < samplesToDo;++i) + zoutput[i] = 1.023332f*zoutput[i]; } } diff --git a/core/uhjfilter.h b/core/uhjfilter.h index 22b3d4df..bc9e10b1 100644 --- a/core/uhjfilter.h +++ b/core/uhjfilter.h @@ -37,6 +37,9 @@ struct Uhj2Encoder { struct UhjDecoder { constexpr static size_t sFilterDelay{128}; + constexpr static size_t sLineSize{BufferLineSize+MaxResamplerPadding+sFilterDelay}; + using BufferLine = std::array<float,sLineSize>; + alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mS{}; alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mD{}; alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mT{}; @@ -46,8 +49,8 @@ struct UhjDecoder { alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge + sFilterDelay*2> mTemp{}; - void decode(const al::span<float*,4> Samples, const size_t SamplesToDo, - const size_t ForwardSamples); + void decode(const al::span<BufferLine> samples, const size_t offset, const size_t samplesToDo, + const size_t forwardSamples); DEF_NEWDEL(UhjDecoder) }; |