aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
Diffstat (limited to 'alc')
-rw-r--r--alc/effects/fshifter.cpp39
-rw-r--r--alc/effects/pshifter.cpp36
2 files changed, 42 insertions, 33 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. */
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. */