diff options
Diffstat (limited to 'alc/effects/pshifter.cpp')
-rw-r--r-- | alc/effects/pshifter.cpp | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index 257742ed..5087860f 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -71,6 +71,7 @@ struct FrequencyBin { struct PshifterState final : public EffectState { /* Effect parameters */ size_t mCount; + size_t mPos; uint mPitchShiftI; double mPitchShift; @@ -104,7 +105,8 @@ struct PshifterState final : public EffectState { void PshifterState::deviceUpdate(const ALCdevice*, const Buffer&) { /* (Re-)initializing parameters and clear the buffers. */ - mCount = FIFO_LATENCY; + mCount = 0; + mPos = FIFO_LATENCY; mPitchShiftI = MixerFracOne; mPitchShift = 1.0; @@ -147,12 +149,12 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float for(size_t base{0u};base < samplesToDo;) { - const size_t todo{minz(STFT_SIZE-mCount, samplesToDo-base)}; + const size_t todo{minz(STFT_STEP-mCount, samplesToDo-base)}; /* Retrieve the output samples from the FIFO and fill in the new input * samples. */ - auto fifo_iter = mFIFO.begin() + mCount; + auto fifo_iter = mFIFO.begin()+mPos + mCount; std::transform(fifo_iter, fifo_iter+todo, mBufferOut.begin()+base, [](double d) noexcept -> float { return static_cast<float>(d); }); @@ -161,14 +163,17 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float base += todo; /* Check whether FIFO buffer is filled with new samples. */ - if(mCount < STFT_SIZE) break; - mCount = FIFO_LATENCY; + if(mCount < STFT_STEP) break; + mCount = 0; + mPos = (mPos+STFT_STEP) & (mFIFO.size()-1); /* Time-domain signal windowing, store in FftBuffer, and apply a * forward FFT to get the frequency-domain signal. */ - for(size_t k{0u};k < STFT_SIZE;k++) - mFftBuffer[k] = mFIFO[k] * HannWindow[k]; + for(size_t src{mPos}, k{0u};src < STFT_SIZE;++src,++k) + mFftBuffer[k] = mFIFO[src] * HannWindow[k]; + for(size_t src{0u}, k{STFT_SIZE-mPos};src < mPos;++src,++k) + mFftBuffer[k] = mFIFO[src] * HannWindow[k]; forward_fft(mFftBuffer); /* Analyze the obtained data. Since the real FFT is symmetric, only @@ -229,15 +234,14 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float * for the output with windowing. */ inverse_fft(mFftBuffer); - for(size_t k{0u};k < STFT_SIZE;k++) - mOutputAccum[k] += HannWindow[k]*mFftBuffer[k].real() * (4.0/OVERSAMP/STFT_SIZE); - - /* Shift FIFO and accumulator. */ - fifo_iter = std::copy(mFIFO.begin()+STFT_STEP, mFIFO.end(), mFIFO.begin()); - std::copy_n(mOutputAccum.begin(), STFT_STEP, fifo_iter); - auto accum_iter = std::copy(mOutputAccum.begin()+STFT_STEP, mOutputAccum.end(), - mOutputAccum.begin()); - std::fill(accum_iter, mOutputAccum.end(), 0.0); + for(size_t dst{mPos}, k{0u};dst < STFT_SIZE;++dst,++k) + mOutputAccum[dst] += HannWindow[k]*mFftBuffer[k].real() * (4.0/OVERSAMP/STFT_SIZE); + for(size_t dst{0u}, k{STFT_SIZE-mPos};dst < mPos;++dst,++k) + mOutputAccum[dst] += HannWindow[k]*mFftBuffer[k].real() * (4.0/OVERSAMP/STFT_SIZE); + + /* Copy out the accumulated result, then clear for the next iteration. */ + std::copy_n(mOutputAccum.begin() + mPos, STFT_STEP, mFIFO.begin() + mPos); + std::fill_n(mOutputAccum.begin() + mPos, STFT_STEP, 0.0); } /* Now, mix the processed sound data to the output. */ |