EFX: Update Frequency shifter
Add f. shifter processing for L and R channels.
This commit is contained in:
+55
-28
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user