diff options
Diffstat (limited to 'alc/effects/fshifter.cpp')
-rw-r--r-- | alc/effects/fshifter.cpp | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index a6c2c747..addf512c 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -62,9 +62,10 @@ alignas(16) const std::array<ALdouble,HIL_SIZE> HannWindow = InitHannWindow(); struct FshifterState final : public EffectState { /* Effect parameters */ ALsizei mCount{}; - ALsizei mPhaseStep{}; - ALsizei mPhase{}; - ALdouble mLdSign{}; + ALsizei mPhaseStep[2]{}; + ALsizei mPhase[2]{}; + ALdouble mSign[2]{}; + /*Effects buffers*/ ALfloat mInFIFO[HIL_SIZE]{}; @@ -76,8 +77,10 @@ struct FshifterState final : public EffectState { alignas(16) ALfloat mBufferOut[BUFFERSIZE]{}; /* Effect gains for each output channel */ - ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS]{}; - ALfloat mTargetGains[MAX_OUTPUT_CHANNELS]{}; + struct { + ALfloat Current[MAX_OUTPUT_CHANNELS]{}; + ALfloat Target[MAX_OUTPUT_CHANNELS]{}; + }mGains[2]; ALboolean deviceUpdate(const ALCdevice *device) override; @@ -91,17 +94,20 @@ ALboolean FshifterState::deviceUpdate(const ALCdevice*) { /* (Re-)initializing parameters and clear the buffers. */ mCount = FIFO_LATENCY; - mPhaseStep = 0; - mPhase = 0; - mLdSign = 1.0; + 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(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{}); - std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f); - std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f); + for (auto &gain : mGains) + { + std::fill(std::begin(gain.Current), std::end(gain.Current), 0.0f); + std::fill(std::begin(gain.Target), std::end(gain.Target), 0.0f); + } return AL_TRUE; } @@ -111,29 +117,47 @@ void FshifterState::update(const ALCcontext *context, const ALeffectslot *slot, const ALCdevice *device{context->mDevice.get()}; ALfloat step{props->Fshifter.Frequency / static_cast<ALfloat>(device->Frequency)}; - mPhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE); + mPhaseStep[0] = mPhaseStep[1] = fastf2i(minf(step, 0.5f) * FRACTIONONE); switch(props->Fshifter.LeftDirection) { case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN: - mLdSign = -1.0; + mSign[0] = -1.0; break; case AL_FREQUENCY_SHIFTER_DIRECTION_UP: - mLdSign = 1.0; + mSign[0] = 1.0; break; case AL_FREQUENCY_SHIFTER_DIRECTION_OFF: - mPhase = 0; - mPhaseStep = 0; + mPhase[0] = 0; + mPhaseStep[0] = 0; break; } - ALfloat coeffs[MAX_AMBI_CHANNELS]; - CalcDirectionCoeffs({0.0f, 0.0f, -1.0f}, 0.0f, coeffs); + switch (props->Fshifter.RightDirection) + { + case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN: + mSign[1] = -1.0; + break; + + case AL_FREQUENCY_SHIFTER_DIRECTION_UP: + mSign[1] = 1.0; + break; + + case AL_FREQUENCY_SHIFTER_DIRECTION_OFF: + mPhase[1] = 0; + mPhaseStep[1] = 0; + break; + } + + ALfloat coeffs[2][MAX_AMBI_CHANNELS]; + CalcDirectionCoeffs({-1.0f, 0.0f, -1.0f}, 0.0f, coeffs[0]); + CalcDirectionCoeffs({1.0f, 0.0f, -1.0f }, 0.0f, coeffs[1]); mOutTarget = target.Main->Buffer; - ComputePanGains(target.Main, coeffs, slot->Params.Gain, mTargetGains); + ComputePanGains(target.Main, coeffs[0], slot->Params.Gain, mGains[0].Target); + ComputePanGains(target.Main, coeffs[1], slot->Params.Gain, mGains[1].Target); } void FshifterState::process(const ALsizei samplesToDo, const FloatBufferLine *RESTRICT samplesIn, const ALsizei /*numInput*/, const al::span<FloatBufferLine> samplesOut) @@ -185,19 +209,22 @@ void FshifterState::process(const ALsizei samplesToDo, const FloatBufferLine *RE } /* Process frequency shifter using the analytic signal obtained. */ - for(k = 0;k < samplesToDo;k++) + for (ALsizei c{0}; c < 2; c++) { - double phase = mPhase * ((1.0/FRACTIONONE) * al::MathDefs<double>::Tau()); - BufferOut[k] = static_cast<float>(mOutdata[k].real()*std::cos(phase) + - mOutdata[k].imag()*std::sin(phase)*mLdSign); + for (k = 0; k < samplesToDo; k++) + { + double phase = mPhase[c] * ((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 += mPhaseStep; - mPhase &= FRACTIONMASK; - } + mPhase[c] += mPhaseStep[c]; + mPhase[c] &= FRACTIONMASK; + } - /* Now, mix the processed sound data to the output. */ - MixSamples(BufferOut, samplesOut, mCurrentGains, mTargetGains, maxi(samplesToDo, 512), 0, - samplesToDo); + /* Now, mix the processed sound data to the output. */ + MixSamples(BufferOut, samplesOut, mGains[c].Current, mGains[c].Target, maxi(samplesToDo, 512), 0, + samplesToDo); + } } |