aboutsummaryrefslogtreecommitdiffstats
path: root/alc/effects/pshifter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alc/effects/pshifter.cpp')
-rw-r--r--alc/effects/pshifter.cpp36
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. */