diff options
Diffstat (limited to 'alc/effects/fshifter.cpp')
-rw-r--r-- | alc/effects/fshifter.cpp | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index 1f881f9d..4037f46b 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -63,6 +63,7 @@ alignas(16) const std::array<double,HIL_SIZE> HannWindow = InitHannWindow(); struct FshifterState final : public EffectState { /* Effect parameters */ size_t mCount{}; + size_t mPos{}; uint mPhaseStep[2]{}; uint mPhase[2]{}; double mSign[2]{}; @@ -95,7 +96,8 @@ struct FshifterState final : public EffectState { void FshifterState::deviceUpdate(const ALCdevice*, const Buffer&) { /* (Re-)initializing parameters and clear the buffers. */ - mCount = FIFO_LATENCY; + mCount = 0; + mPos = FIFO_LATENCY; std::fill(std::begin(mPhaseStep), std::end(mPhaseStep), 0u); std::fill(std::begin(mPhase), std::end(mPhase), 0u); @@ -160,38 +162,41 @@ void FshifterState::process(const size_t samplesToDo, const al::span<const Float { for(size_t base{0u};base < samplesToDo;) { - size_t todo{minz(HIL_SIZE-mCount, samplesToDo-base)}; + size_t todo{minz(HIL_STEP-mCount, samplesToDo-base)}; /* Fill FIFO buffer with samples data */ + const size_t pos{mPos}; size_t count{mCount}; do { - mInFIFO[count] = samplesIn[0][base]; - mOutdata[base] = mOutFIFO[count-FIFO_LATENCY]; + mInFIFO[pos+count] = samplesIn[0][base]; + mOutdata[base] = mOutFIFO[count]; ++base; ++count; } while(--todo); mCount = count; /* Check whether FIFO buffer is filled */ - if(mCount < HIL_SIZE) break; - mCount = FIFO_LATENCY; + if(mCount < HIL_STEP) break; + mCount = 0; + mPos = (mPos+HIL_STEP) & (HIL_SIZE-1); /* Real signal windowing and store in Analytic buffer */ - for(size_t k{0};k < HIL_SIZE;k++) - mAnalytic[k] = mInFIFO[k]*HannWindow[k]; + for(size_t src{mPos}, k{0u};src < HIL_SIZE;++src,++k) + mAnalytic[k] = mInFIFO[src]*HannWindow[k]; + for(size_t src{0u}, k{HIL_SIZE-mPos};src < mPos;++src,++k) + mAnalytic[k] = mInFIFO[src]*HannWindow[k]; /* Processing signal by Discrete Hilbert Transform (analytical signal). */ complex_hilbert(mAnalytic); /* Windowing and add to output accumulator */ - for(size_t k{0};k < HIL_SIZE;k++) - mOutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*mAnalytic[k]; - - /* Shift accumulator, input & output FIFO */ - std::copy_n(mOutputAccum, HIL_STEP, mOutFIFO); - auto accum_iter = std::copy(std::begin(mOutputAccum)+HIL_STEP, std::end(mOutputAccum), - std::begin(mOutputAccum)); - std::fill(accum_iter, std::end(mOutputAccum), complex_d{}); - std::copy(std::begin(mInFIFO)+HIL_STEP, std::end(mInFIFO), std::begin(mInFIFO)); + for(size_t dst{mPos}, k{0u};dst < HIL_SIZE;++dst,++k) + mOutputAccum[dst] += 2.0/OVERSAMP*HannWindow[k]*mAnalytic[k]; + for(size_t dst{0u}, k{HIL_SIZE-mPos};dst < mPos;++dst,++k) + mOutputAccum[dst] += 2.0/OVERSAMP*HannWindow[k]*mAnalytic[k]; + + /* Copy out the accumulated result, then clear for the next iteration. */ + std::copy_n(mOutputAccum + mPos, HIL_STEP, mOutFIFO); + std::fill_n(mOutputAccum + mPos, HIL_STEP, complex_d{}); } /* Process frequency shifter using the analytic signal obtained. */ |