diff options
author | Chris Robinson <[email protected]> | 2020-03-22 10:06:23 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-03-22 10:06:23 -0700 |
commit | d30d9a2c9f74f1bbede11c1f7f8b7a6aada2bf7b (patch) | |
tree | 6940e870ce50593207af2f45d61c22a6743b7518 /alc/effects | |
parent | 002d0eb6a05e7ff4cb10f60304033a9915a7ac1d (diff) |
Clean up the pitch and frequency shifter some
Diffstat (limited to 'alc/effects')
-rw-r--r-- | alc/effects/fshifter.cpp | 62 | ||||
-rw-r--r-- | alc/effects/pshifter.cpp | 59 |
2 files changed, 56 insertions, 65 deletions
diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index f1423468..2c4575a6 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -68,8 +68,8 @@ struct FshifterState final : public EffectState { /*Effects buffers*/ - ALfloat mInFIFO[HIL_SIZE]{}; - complex_d mOutFIFO[HIL_SIZE]{}; + double mInFIFO[HIL_SIZE]{}; + complex_d mOutFIFO[HIL_STEP]{}; complex_d mOutputAccum[HIL_SIZE]{}; complex_d mAnalytic[HIL_SIZE]{}; complex_d mOutdata[BUFFERSIZE]{}; @@ -98,7 +98,7 @@ ALboolean FshifterState::deviceUpdate(const ALCdevice*) std::fill(std::begin(mPhaseStep), std::end(mPhaseStep), 0); std::fill(std::begin(mPhase), std::end(mPhase), 0); std::fill(std::begin(mSign), std::end(mSign), 1.0); - std::fill(std::begin(mInFIFO), std::end(mInFIFO), 0.0f); + std::fill(std::begin(mInFIFO), std::end(mInFIFO), 0.0); std::fill(std::begin(mOutFIFO), std::end(mOutFIFO), complex_d{}); std::fill(std::begin(mOutputAccum), std::end(mOutputAccum), complex_d{}); std::fill(std::begin(mAnalytic), std::end(mAnalytic), complex_d{}); @@ -162,64 +162,58 @@ void FshifterState::update(const ALCcontext *context, const ALeffectslot *slot, void FshifterState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut) { - static constexpr complex_d complex_zero{0.0, 0.0}; - ALfloat *RESTRICT BufferOut = mBufferOut; - size_t j, k; - for(size_t base{0u};base < samplesToDo;) { - const size_t todo{minz(HIL_SIZE-mCount, samplesToDo-base)}; - - ASSUME(todo > 0); + size_t todo{minz(HIL_SIZE-mCount, samplesToDo-base)}; /* Fill FIFO buffer with samples data */ - k = mCount; - for(j = 0;j < todo;j++,k++) - { - mInFIFO[k] = samplesIn[0][base+j]; - mOutdata[base+j] = mOutFIFO[k-FIFO_LATENCY]; - } - mCount += todo; - base += todo; + size_t count{mCount}; + do { + mInFIFO[count] = samplesIn[0][base]; + mOutdata[base] = mOutFIFO[count-FIFO_LATENCY]; + ++base; ++count; + } while(--todo); + mCount = count; /* Check whether FIFO buffer is filled */ - if(mCount < HIL_SIZE) continue; + if(mCount < HIL_SIZE) break; mCount = FIFO_LATENCY; /* Real signal windowing and store in Analytic buffer */ - for(k = 0;k < HIL_SIZE;k++) - { - mAnalytic[k].real(mInFIFO[k] * HannWindow[k]); - mAnalytic[k].imag(0.0); - } + for(size_t k{0};k < HIL_SIZE;k++) + mAnalytic[k] = mInFIFO[k]*HannWindow[k]; /* Processing signal by Discrete Hilbert Transform (analytical signal). */ complex_hilbert(mAnalytic); /* Windowing and add to output accumulator */ - for(k = 0;k < HIL_SIZE;k++) + for(size_t k{0};k < HIL_SIZE;k++) mOutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*mAnalytic[k]; /* Shift accumulator, input & output FIFO */ - for(k = 0;k < HIL_STEP;k++) mOutFIFO[k] = mOutputAccum[k]; - for(j = 0;k < HIL_SIZE;k++,j++) mOutputAccum[j] = mOutputAccum[k]; - for(;j < HIL_SIZE;j++) mOutputAccum[j] = complex_zero; - for(k = 0;k < FIFO_LATENCY;k++) - mInFIFO[k] = mInFIFO[k+HIL_STEP]; + 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)); } /* Process frequency shifter using the analytic signal obtained. */ + ALfloat *RESTRICT BufferOut{mBufferOut}; for(ALsizei c{0};c < 2;++c) { - for(k = 0;k < samplesToDo;++k) + const int phase_step{mPhaseStep[c]}; + int phase_idx{mPhase[c]}; + for(size_t k{0};k < samplesToDo;++k) { - double phase = mPhase[c] * ((1.0 / FRACTIONONE) * al::MathDefs<double>::Tau()); + const double phase{phase_idx * ((1.0 / FRACTIONONE) * al::MathDefs<double>::Tau())}; BufferOut[k] = static_cast<float>(mOutdata[k].real()*std::cos(phase) + mOutdata[k].imag()*std::sin(phase)*mSign[c]); - mPhase[c] += mPhaseStep[c]; - mPhase[c] &= FRACTIONMASK; + phase_idx += phase_step; + phase_idx &= FRACTIONMASK; } + mPhase[c] = phase_idx; /* Now, mix the processed sound data to the output. */ MixSamples({BufferOut, samplesToDo}, samplesOut, mGains[c].Current, mGains[c].Target, diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index 7b00a87e..53b5318b 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -98,8 +98,8 @@ struct PshifterState final : public EffectState { ALfloat mFreqPerBin; /* Effects buffers */ - ALfloat mInFIFO[STFT_SIZE]; - ALfloat mOutFIFO[STFT_STEP]; + double mInFIFO[STFT_SIZE]; + double mOutFIFO[STFT_STEP]; ALdouble mLastPhase[STFT_HALF_SIZE+1]; ALdouble mSumPhase[STFT_HALF_SIZE+1]; ALdouble mOutputAccum[STFT_SIZE]; @@ -169,25 +169,26 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float static constexpr ALdouble expected{al::MathDefs<double>::Tau() / OVERSAMP}; const ALdouble freq_per_bin{mFreqPerBin}; - ALfloat *RESTRICT bufferOut{mBufferOut}; - size_t count{mCount}; - for(size_t i{0u};i < samplesToDo;) + for(size_t base{0u};base < samplesToDo;) { - do { - /* Fill FIFO buffer with samples data */ - mInFIFO[count] = samplesIn[0][i]; - bufferOut[i] = mOutFIFO[count - FIFO_LATENCY]; + size_t todo{minz(STFT_SIZE-mCount, samplesToDo-base)}; - count++; - } while(++i < samplesToDo && count < STFT_SIZE); + /* Fill FIFO buffer with samples data */ + size_t count{mCount}; + do { + mInFIFO[count] = samplesIn[0][base]; + mBufferOut[base] = static_cast<float>(mOutFIFO[count-FIFO_LATENCY]); + ++base; ++count; + } while(--todo); + mCount = count; /* Check whether FIFO buffer is filled */ - if(count < STFT_SIZE) break; - count = FIFO_LATENCY; + if(mCount < STFT_SIZE) break; + mCount = FIFO_LATENCY; /* Real signal windowing and store in FFTbuffer */ - for(ALuint k{0u};k < STFT_SIZE;k++) + for(size_t k{0u};k < STFT_SIZE;k++) { mFFTbuffer[k].real(mInFIFO[k] * HannWindow[k]); mFFTbuffer[k].imag(0.0); @@ -200,7 +201,7 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float /* Analyze the obtained data. Since the real FFT is symmetric, only * STFT_HALF_SIZE+1 samples are needed. */ - for(ALuint k{0u};k < STFT_HALF_SIZE+1;k++) + for(size_t k{0u};k < STFT_HALF_SIZE+1;k++) { /* Compute amplitude and phase */ ALphasor component{rect2polar(mFFTbuffer[k])}; @@ -228,7 +229,7 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float /* PROCESSING */ /* pitch shifting */ - for(ALuint k{0u};k < STFT_HALF_SIZE+1;k++) + for(size_t k{0u};k < STFT_HALF_SIZE+1;k++) { mSyntesis_buffer[k].Amplitude = 0.0; mSyntesis_buffer[k].Frequency = 0.0; @@ -245,17 +246,15 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float /* SYNTHESIS */ /* Synthesis the processing data */ - for(ALuint k{0u};k < STFT_HALF_SIZE+1;k++) + for(size_t k{0u};k < STFT_HALF_SIZE+1;k++) { - ALphasor component; - ALdouble tmp; - /* Compute bin deviation from scaled freq */ - tmp = mSyntesis_buffer[k].Frequency/freq_per_bin - k; + const double tmp{mSyntesis_buffer[k].Frequency/freq_per_bin - k}; /* Calculate actual delta phase and accumulate it to get bin phase */ mSumPhase[k] += (k + tmp) * expected; + ALphasor component; component.Amplitude = mSyntesis_buffer[k].Amplitude; component.Phase = mSumPhase[k]; @@ -263,29 +262,27 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float mFFTbuffer[k] = polar2rect(component); } /* zero negative frequencies for recontruct a real signal */ - for(ALuint k{STFT_HALF_SIZE+1};k < STFT_SIZE;k++) + for(size_t k{STFT_HALF_SIZE+1};k < STFT_SIZE;k++) mFFTbuffer[k] = complex_d{}; /* Apply iFFT to buffer data */ complex_fft(mFFTbuffer, 1.0); /* Windowing and add to output */ - for(ALuint k{0u};k < STFT_SIZE;k++) + for(size_t k{0u};k < STFT_SIZE;k++) mOutputAccum[k] += HannWindow[k] * mFFTbuffer[k].real() / (0.5 * STFT_HALF_SIZE * OVERSAMP); /* Shift accumulator, input & output FIFO */ - size_t j, k; - for(k = 0;k < STFT_STEP;k++) mOutFIFO[k] = static_cast<ALfloat>(mOutputAccum[k]); - for(j = 0;k < STFT_SIZE;k++,j++) mOutputAccum[j] = mOutputAccum[k]; - for(;j < STFT_SIZE;j++) mOutputAccum[j] = 0.0; - for(k = 0;k < FIFO_LATENCY;k++) - mInFIFO[k] = mInFIFO[k+STFT_STEP]; + std::copy_n(mOutputAccum, STFT_STEP, mOutFIFO); + auto accum_iter = std::copy(std::begin(mOutputAccum)+STFT_STEP, std::end(mOutputAccum), + std::begin(mOutputAccum)); + std::fill(accum_iter, std::end(mOutputAccum), 0.0); + std::copy(std::begin(mInFIFO)+STFT_STEP, std::end(mInFIFO), std::begin(mInFIFO)); } - mCount = count; /* Now, mix the processed sound data to the output. */ - MixSamples({bufferOut, samplesToDo}, samplesOut, mCurrentGains, mTargetGains, + MixSamples({mBufferOut, samplesToDo}, samplesOut, mCurrentGains, mTargetGains, maxz(samplesToDo, 512), 0); } |