aboutsummaryrefslogtreecommitdiffstats
path: root/alc/effects
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-03-22 10:06:23 -0700
committerChris Robinson <[email protected]>2020-03-22 10:06:23 -0700
commitd30d9a2c9f74f1bbede11c1f7f8b7a6aada2bf7b (patch)
tree6940e870ce50593207af2f45d61c22a6743b7518 /alc/effects
parent002d0eb6a05e7ff4cb10f60304033a9915a7ac1d (diff)
Clean up the pitch and frequency shifter some
Diffstat (limited to 'alc/effects')
-rw-r--r--alc/effects/fshifter.cpp62
-rw-r--r--alc/effects/pshifter.cpp59
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);
}