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