EFX: Update Frequency shifter

Add f. shifter processing for L and R channels.
This commit is contained in:
Raulshc
2019-08-18 19:28:00 +02:00
parent ff66061091
commit eaaa194163
+55 -28
View File
@@ -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, mGains[c].Current, mGains[c].Target, maxi(samplesToDo, 512), 0,
samplesToDo);
}
/* Now, mix the processed sound data to the output. */
MixSamples(BufferOut, samplesOut, mCurrentGains, mTargetGains, maxi(samplesToDo, 512), 0,
samplesToDo);
}