Clean up the remaining effect struct member names
This commit is contained in:
parent
67da3850cb
commit
6ac84c7a5f
@ -23,6 +23,8 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alcontext.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
@ -80,11 +82,11 @@ struct ALequalizerState final : public ALeffectState {
|
||||
BiquadFilter filter[4];
|
||||
|
||||
/* Effect gains for each channel */
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
|
||||
} Chans[MAX_EFFECT_CHANNELS];
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS]{};
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS]{};
|
||||
} mChans[MAX_EFFECT_CHANNELS];
|
||||
|
||||
ALfloat SampleBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE];
|
||||
ALfloat mSampleBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]{};
|
||||
};
|
||||
|
||||
static ALvoid ALequalizerState_Destruct(ALequalizerState *state);
|
||||
@ -111,14 +113,13 @@ static ALvoid ALequalizerState_Destruct(ALequalizerState *state)
|
||||
|
||||
static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *state, ALCdevice *UNUSED(device))
|
||||
{
|
||||
ALsizei i, j;
|
||||
|
||||
for(i = 0; i < MAX_EFFECT_CHANNELS;i++)
|
||||
for(auto &e : state->mChans)
|
||||
{
|
||||
for(j = 0;j < 4;j++)
|
||||
BiquadFilter_clear(&state->Chans[i].filter[j]);
|
||||
for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
|
||||
state->Chans[i].CurrentGains[j] = 0.0f;
|
||||
std::for_each(std::begin(e.filter), std::end(e.filter),
|
||||
[](BiquadFilter &f) -> void
|
||||
{ BiquadFilter_clear(&f); }
|
||||
);
|
||||
std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f);
|
||||
}
|
||||
return AL_TRUE;
|
||||
}
|
||||
@ -136,13 +137,13 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext
|
||||
*/
|
||||
gain = maxf(sqrtf(props->Equalizer.LowGain), 0.0625f); /* Limit -24dB */
|
||||
f0norm = props->Equalizer.LowCutoff/frequency;
|
||||
BiquadFilter_setParams(&state->Chans[0].filter[0], BiquadType::LowShelf,
|
||||
BiquadFilter_setParams(&state->mChans[0].filter[0], BiquadType::LowShelf,
|
||||
gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f)
|
||||
);
|
||||
|
||||
gain = maxf(props->Equalizer.Mid1Gain, 0.0625f);
|
||||
f0norm = props->Equalizer.Mid1Center/frequency;
|
||||
BiquadFilter_setParams(&state->Chans[0].filter[1], BiquadType::Peaking,
|
||||
BiquadFilter_setParams(&state->mChans[0].filter[1], BiquadType::Peaking,
|
||||
gain, f0norm, calc_rcpQ_from_bandwidth(
|
||||
f0norm, props->Equalizer.Mid1Width
|
||||
)
|
||||
@ -150,7 +151,7 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext
|
||||
|
||||
gain = maxf(props->Equalizer.Mid2Gain, 0.0625f);
|
||||
f0norm = props->Equalizer.Mid2Center/frequency;
|
||||
BiquadFilter_setParams(&state->Chans[0].filter[2], BiquadType::Peaking,
|
||||
BiquadFilter_setParams(&state->mChans[0].filter[2], BiquadType::Peaking,
|
||||
gain, f0norm, calc_rcpQ_from_bandwidth(
|
||||
f0norm, props->Equalizer.Mid2Width
|
||||
)
|
||||
@ -158,40 +159,40 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext
|
||||
|
||||
gain = maxf(sqrtf(props->Equalizer.HighGain), 0.0625f);
|
||||
f0norm = props->Equalizer.HighCutoff/frequency;
|
||||
BiquadFilter_setParams(&state->Chans[0].filter[3], BiquadType::HighShelf,
|
||||
BiquadFilter_setParams(&state->mChans[0].filter[3], BiquadType::HighShelf,
|
||||
gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f)
|
||||
);
|
||||
|
||||
/* Copy the filter coefficients for the other input channels. */
|
||||
for(i = 1;i < MAX_EFFECT_CHANNELS;i++)
|
||||
{
|
||||
BiquadFilter_copyParams(&state->Chans[i].filter[0], &state->Chans[0].filter[0]);
|
||||
BiquadFilter_copyParams(&state->Chans[i].filter[1], &state->Chans[0].filter[1]);
|
||||
BiquadFilter_copyParams(&state->Chans[i].filter[2], &state->Chans[0].filter[2]);
|
||||
BiquadFilter_copyParams(&state->Chans[i].filter[3], &state->Chans[0].filter[3]);
|
||||
BiquadFilter_copyParams(&state->mChans[i].filter[0], &state->mChans[0].filter[0]);
|
||||
BiquadFilter_copyParams(&state->mChans[i].filter[1], &state->mChans[0].filter[1]);
|
||||
BiquadFilter_copyParams(&state->mChans[i].filter[2], &state->mChans[0].filter[2]);
|
||||
BiquadFilter_copyParams(&state->mChans[i].filter[3], &state->mChans[0].filter[3]);
|
||||
}
|
||||
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels;
|
||||
state->OutBuffer = device->FOAOut.Buffer;
|
||||
state->OutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
|
||||
state->Chans[i].TargetGains);
|
||||
state->mChans[i].TargetGains);
|
||||
}
|
||||
|
||||
static ALvoid ALequalizerState_process(ALequalizerState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
{
|
||||
ALfloat (*RESTRICT temps)[BUFFERSIZE] = state->SampleBuffer;
|
||||
ALfloat (*RESTRICT temps)[BUFFERSIZE] = state->mSampleBuffer;
|
||||
ALsizei c;
|
||||
|
||||
for(c = 0;c < MAX_EFFECT_CHANNELS;c++)
|
||||
{
|
||||
BiquadFilter_process(&state->Chans[c].filter[0], temps[0], SamplesIn[c], SamplesToDo);
|
||||
BiquadFilter_process(&state->Chans[c].filter[1], temps[1], temps[0], SamplesToDo);
|
||||
BiquadFilter_process(&state->Chans[c].filter[2], temps[2], temps[1], SamplesToDo);
|
||||
BiquadFilter_process(&state->Chans[c].filter[3], temps[3], temps[2], SamplesToDo);
|
||||
BiquadFilter_process(&state->mChans[c].filter[0], temps[0], SamplesIn[c], SamplesToDo);
|
||||
BiquadFilter_process(&state->mChans[c].filter[1], temps[1], temps[0], SamplesToDo);
|
||||
BiquadFilter_process(&state->mChans[c].filter[2], temps[2], temps[1], SamplesToDo);
|
||||
BiquadFilter_process(&state->mChans[c].filter[3], temps[3], temps[2], SamplesToDo);
|
||||
|
||||
MixSamples(temps[3], NumChannels, SamplesOut,
|
||||
state->Chans[c].CurrentGains, state->Chans[c].TargetGains,
|
||||
state->mChans[c].CurrentGains, state->mChans[c].TargetGains,
|
||||
SamplesToDo, 0, SamplesToDo
|
||||
);
|
||||
}
|
||||
|
@ -62,23 +62,23 @@ alignas(16) const std::array<ALdouble,HIL_SIZE> HannWindow = InitHannWindow();
|
||||
|
||||
struct ALfshifterState final : public ALeffectState {
|
||||
/* Effect parameters */
|
||||
ALsizei count;
|
||||
ALsizei PhaseStep;
|
||||
ALsizei Phase;
|
||||
ALdouble ld_sign;
|
||||
ALsizei mCount{};
|
||||
ALsizei mPhaseStep{};
|
||||
ALsizei mPhase{};
|
||||
ALdouble mLdSign{};
|
||||
|
||||
/*Effects buffers*/
|
||||
ALfloat InFIFO[HIL_SIZE];
|
||||
complex_d OutFIFO[HIL_SIZE];
|
||||
complex_d OutputAccum[HIL_SIZE];
|
||||
complex_d Analytic[HIL_SIZE];
|
||||
complex_d Outdata[BUFFERSIZE];
|
||||
ALfloat mInFIFO[HIL_SIZE]{};
|
||||
complex_d mOutFIFO[HIL_SIZE]{};
|
||||
complex_d mOutputAccum[HIL_SIZE]{};
|
||||
complex_d mAnalytic[HIL_SIZE]{};
|
||||
complex_d mOutdata[BUFFERSIZE]{};
|
||||
|
||||
alignas(16) ALfloat BufferOut[BUFFERSIZE];
|
||||
alignas(16) ALfloat mBufferOut[BUFFERSIZE]{};
|
||||
|
||||
/* Effect gains for each output channel */
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS]{};
|
||||
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS]{};
|
||||
};
|
||||
|
||||
ALvoid ALfshifterState_Destruct(ALfshifterState *state);
|
||||
@ -105,113 +105,111 @@ ALvoid ALfshifterState_Destruct(ALfshifterState *state)
|
||||
ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *UNUSED(device))
|
||||
{
|
||||
/* (Re-)initializing parameters and clear the buffers. */
|
||||
state->count = FIFO_LATENCY;
|
||||
state->PhaseStep = 0;
|
||||
state->Phase = 0;
|
||||
state->ld_sign = 1.0;
|
||||
state->mCount = FIFO_LATENCY;
|
||||
state->mPhaseStep = 0;
|
||||
state->mPhase = 0;
|
||||
state->mLdSign = 1.0;
|
||||
|
||||
std::fill(std::begin(state->InFIFO), std::end(state->InFIFO), 0.0f);
|
||||
std::fill(std::begin(state->OutFIFO), std::end(state->OutFIFO), complex_d{});
|
||||
std::fill(std::begin(state->OutputAccum), std::end(state->OutputAccum), complex_d{});
|
||||
std::fill(std::begin(state->Analytic), std::end(state->Analytic), complex_d{});
|
||||
std::fill(std::begin(state->mInFIFO), std::end(state->mInFIFO), 0.0f);
|
||||
std::fill(std::begin(state->mOutFIFO), std::end(state->mOutFIFO), complex_d{});
|
||||
std::fill(std::begin(state->mOutputAccum), std::end(state->mOutputAccum), complex_d{});
|
||||
std::fill(std::begin(state->mAnalytic), std::end(state->mAnalytic), complex_d{});
|
||||
|
||||
std::fill(std::begin(state->CurrentGains), std::end(state->CurrentGains), 0.0f);
|
||||
std::fill(std::begin(state->TargetGains), std::end(state->TargetGains), 0.0f);
|
||||
std::fill(std::begin(state->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
|
||||
std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
|
||||
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
|
||||
{
|
||||
const ALCdevice *device = context->Device;
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat step;
|
||||
const ALCdevice *device{context->Device};
|
||||
|
||||
step = props->Fshifter.Frequency / (ALfloat)device->Frequency;
|
||||
state->PhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE);
|
||||
ALfloat step{props->Fshifter.Frequency / (ALfloat)device->Frequency};
|
||||
state->mPhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE);
|
||||
|
||||
switch(props->Fshifter.LeftDirection)
|
||||
{
|
||||
case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN:
|
||||
state->ld_sign = -1.0;
|
||||
state->mLdSign = -1.0;
|
||||
break;
|
||||
|
||||
case AL_FREQUENCY_SHIFTER_DIRECTION_UP:
|
||||
state->ld_sign = 1.0;
|
||||
state->mLdSign = 1.0;
|
||||
break;
|
||||
|
||||
case AL_FREQUENCY_SHIFTER_DIRECTION_OFF:
|
||||
state->Phase = 0;
|
||||
state->PhaseStep = 0;
|
||||
state->mPhase = 0;
|
||||
state->mPhaseStep = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->TargetGains);
|
||||
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mTargetGains);
|
||||
}
|
||||
|
||||
ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
{
|
||||
static const complex_d complex_zero{0.0, 0.0};
|
||||
ALfloat *RESTRICT BufferOut = state->BufferOut;
|
||||
ALfloat *RESTRICT BufferOut = state->mBufferOut;
|
||||
ALsizei j, k, base;
|
||||
|
||||
for(base = 0;base < SamplesToDo;)
|
||||
{
|
||||
ALsizei todo = mini(HIL_SIZE-state->count, SamplesToDo-base);
|
||||
ALsizei todo = mini(HIL_SIZE-state->mCount, SamplesToDo-base);
|
||||
|
||||
ASSUME(todo > 0);
|
||||
|
||||
/* Fill FIFO buffer with samples data */
|
||||
k = state->count;
|
||||
k = state->mCount;
|
||||
for(j = 0;j < todo;j++,k++)
|
||||
{
|
||||
state->InFIFO[k] = SamplesIn[0][base+j];
|
||||
state->Outdata[base+j] = state->OutFIFO[k-FIFO_LATENCY];
|
||||
state->mInFIFO[k] = SamplesIn[0][base+j];
|
||||
state->mOutdata[base+j] = state->mOutFIFO[k-FIFO_LATENCY];
|
||||
}
|
||||
state->count += todo;
|
||||
state->mCount += todo;
|
||||
base += todo;
|
||||
|
||||
/* Check whether FIFO buffer is filled */
|
||||
if(state->count < HIL_SIZE) continue;
|
||||
|
||||
state->count = FIFO_LATENCY;
|
||||
if(state->mCount < HIL_SIZE) continue;
|
||||
state->mCount = FIFO_LATENCY;
|
||||
|
||||
/* Real signal windowing and store in Analytic buffer */
|
||||
for(k = 0;k < HIL_SIZE;k++)
|
||||
{
|
||||
state->Analytic[k].real(state->InFIFO[k] * HannWindow[k]);
|
||||
state->Analytic[k].imag(0.0);
|
||||
state->mAnalytic[k].real(state->mInFIFO[k] * HannWindow[k]);
|
||||
state->mAnalytic[k].imag(0.0);
|
||||
}
|
||||
|
||||
/* Processing signal by Discrete Hilbert Transform (analytical signal). */
|
||||
complex_hilbert(state->Analytic, HIL_SIZE);
|
||||
complex_hilbert(state->mAnalytic, HIL_SIZE);
|
||||
|
||||
/* Windowing and add to output accumulator */
|
||||
for(k = 0;k < HIL_SIZE;k++)
|
||||
state->OutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*state->Analytic[k];
|
||||
state->mOutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*state->mAnalytic[k];
|
||||
|
||||
/* Shift accumulator, input & output FIFO */
|
||||
for(k = 0;k < HIL_STEP;k++) state->OutFIFO[k] = state->OutputAccum[k];
|
||||
for(j = 0;k < HIL_SIZE;k++,j++) state->OutputAccum[j] = state->OutputAccum[k];
|
||||
for(;j < HIL_SIZE;j++) state->OutputAccum[j] = complex_zero;
|
||||
for(k = 0;k < HIL_STEP;k++) state->mOutFIFO[k] = state->mOutputAccum[k];
|
||||
for(j = 0;k < HIL_SIZE;k++,j++) state->mOutputAccum[j] = state->mOutputAccum[k];
|
||||
for(;j < HIL_SIZE;j++) state->mOutputAccum[j] = complex_zero;
|
||||
for(k = 0;k < FIFO_LATENCY;k++)
|
||||
state->InFIFO[k] = state->InFIFO[k+HIL_STEP];
|
||||
state->mInFIFO[k] = state->mInFIFO[k+HIL_STEP];
|
||||
}
|
||||
|
||||
/* Process frequency shifter using the analytic signal obtained. */
|
||||
for(k = 0;k < SamplesToDo;k++)
|
||||
{
|
||||
double phase = state->Phase * ((1.0/FRACTIONONE) * 2.0*M_PI);
|
||||
BufferOut[k] = (float)(state->Outdata[k].real()*std::cos(phase) +
|
||||
state->Outdata[k].imag()*std::sin(phase)*state->ld_sign);
|
||||
double phase = state->mPhase * ((1.0/FRACTIONONE) * 2.0*M_PI);
|
||||
BufferOut[k] = (float)(state->mOutdata[k].real()*std::cos(phase) +
|
||||
state->mOutdata[k].imag()*std::sin(phase)*state->mLdSign);
|
||||
|
||||
state->Phase += state->PhaseStep;
|
||||
state->Phase &= FRACTIONMASK;
|
||||
state->mPhase += state->mPhaseStep;
|
||||
state->mPhase &= FRACTIONMASK;
|
||||
}
|
||||
|
||||
/* Now, mix the processed sound data to the output. */
|
||||
MixSamples(BufferOut, NumChannels, SamplesOut, state->CurrentGains, state->TargetGains,
|
||||
MixSamples(BufferOut, NumChannels, SamplesOut, state->mCurrentGains, state->mTargetGains,
|
||||
maxi(SamplesToDo, 512), 0, SamplesToDo);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alcontext.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
@ -35,17 +38,17 @@
|
||||
#define MAX_UPDATE_SAMPLES 128
|
||||
|
||||
struct ALmodulatorState final : public ALeffectState {
|
||||
void (*GetSamples)(ALfloat*RESTRICT, ALsizei, const ALsizei, ALsizei);
|
||||
void (*mGetSamples)(ALfloat*RESTRICT, ALsizei, const ALsizei, ALsizei){};
|
||||
|
||||
ALsizei index;
|
||||
ALsizei step;
|
||||
ALsizei mIndex{0};
|
||||
ALsizei mStep{1};
|
||||
|
||||
struct {
|
||||
BiquadFilter Filter;
|
||||
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
|
||||
} Chans[MAX_EFFECT_CHANNELS];
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS]{};
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS]{};
|
||||
} mChans[MAX_EFFECT_CHANNELS];
|
||||
};
|
||||
|
||||
static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state);
|
||||
@ -63,7 +66,7 @@ DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState);
|
||||
|
||||
static inline ALfloat Sin(ALsizei index)
|
||||
{
|
||||
return sinf((ALfloat)index * (F_TAU / WAVEFORM_FRACONE));
|
||||
return std::sin((ALfloat)index * (F_TAU / (ALfloat)WAVEFORM_FRACONE));
|
||||
}
|
||||
|
||||
static inline ALfloat Saw(ALsizei index)
|
||||
@ -107,9 +110,6 @@ static void ALmodulatorState_Construct(ALmodulatorState *state)
|
||||
new (state) ALmodulatorState{};
|
||||
ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
|
||||
SET_VTABLE2(ALmodulatorState, ALeffectState, state);
|
||||
|
||||
state->index = 0;
|
||||
state->step = 1;
|
||||
}
|
||||
|
||||
static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state)
|
||||
@ -120,12 +120,10 @@ static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state)
|
||||
|
||||
static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *state, ALCdevice *UNUSED(device))
|
||||
{
|
||||
ALsizei i, j;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
for(auto &e : state->mChans)
|
||||
{
|
||||
BiquadFilter_clear(&state->Chans[i].Filter);
|
||||
for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
|
||||
state->Chans[i].CurrentGains[j] = 0.0f;
|
||||
BiquadFilter_clear(&e.Filter);
|
||||
std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f);
|
||||
}
|
||||
return AL_TRUE;
|
||||
}
|
||||
@ -136,37 +134,37 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext
|
||||
ALfloat f0norm;
|
||||
ALsizei i;
|
||||
|
||||
state->step = fastf2i(props->Modulator.Frequency / (ALfloat)device->Frequency *
|
||||
WAVEFORM_FRACONE);
|
||||
state->step = clampi(state->step, 0, WAVEFORM_FRACONE-1);
|
||||
state->mStep = fastf2i(props->Modulator.Frequency / (ALfloat)device->Frequency *
|
||||
WAVEFORM_FRACONE);
|
||||
state->mStep = clampi(state->mStep, 0, WAVEFORM_FRACONE-1);
|
||||
|
||||
if(state->step == 0)
|
||||
state->GetSamples = ModulateOne;
|
||||
if(state->mStep == 0)
|
||||
state->mGetSamples = ModulateOne;
|
||||
else if(props->Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
|
||||
state->GetSamples = ModulateSin;
|
||||
state->mGetSamples = ModulateSin;
|
||||
else if(props->Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
|
||||
state->GetSamples = ModulateSaw;
|
||||
state->mGetSamples = ModulateSaw;
|
||||
else /*if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/
|
||||
state->GetSamples = ModulateSquare;
|
||||
state->mGetSamples = ModulateSquare;
|
||||
|
||||
f0norm = props->Modulator.HighPassCutoff / (ALfloat)device->Frequency;
|
||||
f0norm = clampf(f0norm, 1.0f/512.0f, 0.49f);
|
||||
/* Bandwidth value is constant in octaves. */
|
||||
BiquadFilter_setParams(&state->Chans[0].Filter, BiquadType::HighPass, 1.0f,
|
||||
BiquadFilter_setParams(&state->mChans[0].Filter, BiquadType::HighPass, 1.0f,
|
||||
f0norm, calc_rcpQ_from_bandwidth(f0norm, 0.75f));
|
||||
for(i = 1;i < MAX_EFFECT_CHANNELS;i++)
|
||||
BiquadFilter_copyParams(&state->Chans[i].Filter, &state->Chans[0].Filter);
|
||||
BiquadFilter_copyParams(&state->mChans[i].Filter, &state->mChans[0].Filter);
|
||||
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels;
|
||||
state->OutBuffer = device->FOAOut.Buffer;
|
||||
state->OutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
|
||||
state->Chans[i].TargetGains);
|
||||
state->mChans[i].TargetGains);
|
||||
}
|
||||
|
||||
static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
{
|
||||
const ALsizei step = state->step;
|
||||
const ALsizei step = state->mStep;
|
||||
ALsizei base;
|
||||
|
||||
for(base = 0;base < SamplesToDo;)
|
||||
@ -175,20 +173,20 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesT
|
||||
ALsizei td = mini(MAX_UPDATE_SAMPLES, SamplesToDo-base);
|
||||
ALsizei c, i;
|
||||
|
||||
state->GetSamples(modsamples, state->index, step, td);
|
||||
state->index += (step*td) & WAVEFORM_FRACMASK;
|
||||
state->index &= WAVEFORM_FRACMASK;
|
||||
state->mGetSamples(modsamples, state->mIndex, step, td);
|
||||
state->mIndex += (step*td) & WAVEFORM_FRACMASK;
|
||||
state->mIndex &= WAVEFORM_FRACMASK;
|
||||
|
||||
for(c = 0;c < MAX_EFFECT_CHANNELS;c++)
|
||||
{
|
||||
alignas(16) ALfloat temps[MAX_UPDATE_SAMPLES];
|
||||
|
||||
BiquadFilter_process(&state->Chans[c].Filter, temps, &SamplesIn[c][base], td);
|
||||
BiquadFilter_process(&state->mChans[c].Filter, temps, &SamplesIn[c][base], td);
|
||||
for(i = 0;i < td;i++)
|
||||
temps[i] *= modsamples[i];
|
||||
|
||||
MixSamples(temps, NumChannels, SamplesOut, state->Chans[c].CurrentGains,
|
||||
state->Chans[c].TargetGains, SamplesToDo-base, base, td);
|
||||
MixSamples(temps, NumChannels, SamplesOut, state->mChans[c].CurrentGains,
|
||||
state->mChans[c].TargetGains, SamplesToDo-base, base, td);
|
||||
}
|
||||
|
||||
base += td;
|
||||
|
@ -119,28 +119,28 @@ inline complex_d polar2rect(const ALphasor &number)
|
||||
|
||||
struct ALpshifterState final : public ALeffectState {
|
||||
/* Effect parameters */
|
||||
ALsizei count;
|
||||
ALsizei PitchShiftI;
|
||||
ALfloat PitchShift;
|
||||
ALfloat FreqPerBin;
|
||||
ALsizei mCount;
|
||||
ALsizei mPitchShiftI;
|
||||
ALfloat mPitchShift;
|
||||
ALfloat mFreqPerBin;
|
||||
|
||||
/*Effects buffers*/
|
||||
ALfloat InFIFO[STFT_SIZE];
|
||||
ALfloat OutFIFO[STFT_STEP];
|
||||
ALdouble LastPhase[STFT_HALF_SIZE+1];
|
||||
ALdouble SumPhase[STFT_HALF_SIZE+1];
|
||||
ALdouble OutputAccum[STFT_SIZE];
|
||||
/* Effects buffers */
|
||||
ALfloat mInFIFO[STFT_SIZE];
|
||||
ALfloat mOutFIFO[STFT_STEP];
|
||||
ALdouble mLastPhase[STFT_HALF_SIZE+1];
|
||||
ALdouble mSumPhase[STFT_HALF_SIZE+1];
|
||||
ALdouble mOutputAccum[STFT_SIZE];
|
||||
|
||||
complex_d FFTbuffer[STFT_SIZE];
|
||||
complex_d mFFTbuffer[STFT_SIZE];
|
||||
|
||||
ALfrequencyDomain Analysis_buffer[STFT_HALF_SIZE+1];
|
||||
ALfrequencyDomain Syntesis_buffer[STFT_HALF_SIZE+1];
|
||||
ALfrequencyDomain mAnalysis_buffer[STFT_HALF_SIZE+1];
|
||||
ALfrequencyDomain mSyntesis_buffer[STFT_HALF_SIZE+1];
|
||||
|
||||
alignas(16) ALfloat BufferOut[BUFFERSIZE];
|
||||
alignas(16) ALfloat mBufferOut[BUFFERSIZE];
|
||||
|
||||
/* Effect gains for each output channel */
|
||||
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS];
|
||||
};
|
||||
|
||||
static ALvoid ALpshifterState_Destruct(ALpshifterState *state);
|
||||
@ -167,22 +167,22 @@ ALvoid ALpshifterState_Destruct(ALpshifterState *state)
|
||||
ALboolean ALpshifterState_deviceUpdate(ALpshifterState *state, ALCdevice *device)
|
||||
{
|
||||
/* (Re-)initializing parameters and clear the buffers. */
|
||||
state->count = FIFO_LATENCY;
|
||||
state->PitchShiftI = FRACTIONONE;
|
||||
state->PitchShift = 1.0f;
|
||||
state->FreqPerBin = device->Frequency / (ALfloat)STFT_SIZE;
|
||||
state->mCount = FIFO_LATENCY;
|
||||
state->mPitchShiftI = FRACTIONONE;
|
||||
state->mPitchShift = 1.0f;
|
||||
state->mFreqPerBin = device->Frequency / (ALfloat)STFT_SIZE;
|
||||
|
||||
std::fill(std::begin(state->InFIFO), std::end(state->InFIFO), 0.0f);
|
||||
std::fill(std::begin(state->OutFIFO), std::end(state->OutFIFO), 0.0f);
|
||||
std::fill(std::begin(state->LastPhase), std::end(state->LastPhase), 0.0);
|
||||
std::fill(std::begin(state->SumPhase), std::end(state->SumPhase), 0.0);
|
||||
std::fill(std::begin(state->OutputAccum), std::end(state->OutputAccum), 0.0);
|
||||
std::fill(std::begin(state->FFTbuffer), std::end(state->FFTbuffer), complex_d{});
|
||||
std::fill(std::begin(state->Analysis_buffer), std::end(state->Analysis_buffer), ALfrequencyDomain{});
|
||||
std::fill(std::begin(state->Syntesis_buffer), std::end(state->Syntesis_buffer), ALfrequencyDomain{});
|
||||
std::fill(std::begin(state->mInFIFO), std::end(state->mInFIFO), 0.0f);
|
||||
std::fill(std::begin(state->mOutFIFO), std::end(state->mOutFIFO), 0.0f);
|
||||
std::fill(std::begin(state->mLastPhase), std::end(state->mLastPhase), 0.0);
|
||||
std::fill(std::begin(state->mSumPhase), std::end(state->mSumPhase), 0.0);
|
||||
std::fill(std::begin(state->mOutputAccum), std::end(state->mOutputAccum), 0.0);
|
||||
std::fill(std::begin(state->mFFTbuffer), std::end(state->mFFTbuffer), complex_d{});
|
||||
std::fill(std::begin(state->mAnalysis_buffer), std::end(state->mAnalysis_buffer), ALfrequencyDomain{});
|
||||
std::fill(std::begin(state->mSyntesis_buffer), std::end(state->mSyntesis_buffer), ALfrequencyDomain{});
|
||||
|
||||
std::fill(std::begin(state->CurrentGains), std::end(state->CurrentGains), 0.0f);
|
||||
std::fill(std::begin(state->TargetGains), std::end(state->TargetGains), 0.0f);
|
||||
std::fill(std::begin(state->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
|
||||
std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
|
||||
|
||||
return AL_TRUE;
|
||||
}
|
||||
@ -196,11 +196,11 @@ ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context,
|
||||
pitch = std::pow(2.0f,
|
||||
(ALfloat)(props->Pshifter.CoarseTune*100 + props->Pshifter.FineTune) / 1200.0f
|
||||
);
|
||||
state->PitchShiftI = fastf2i(pitch*FRACTIONONE);
|
||||
state->PitchShift = state->PitchShiftI * (1.0f/FRACTIONONE);
|
||||
state->mPitchShiftI = fastf2i(pitch*FRACTIONONE);
|
||||
state->mPitchShift = state->mPitchShiftI * (1.0f/FRACTIONONE);
|
||||
|
||||
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->TargetGains);
|
||||
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mTargetGains);
|
||||
}
|
||||
|
||||
ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
@ -210,16 +210,16 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
|
||||
*/
|
||||
|
||||
static constexpr ALdouble expected{M_PI*2.0 / OVERSAMP};
|
||||
const ALdouble freq_per_bin{state->FreqPerBin};
|
||||
ALfloat *RESTRICT bufferOut{state->BufferOut};
|
||||
ALsizei count{state->count};
|
||||
const ALdouble freq_per_bin{state->mFreqPerBin};
|
||||
ALfloat *RESTRICT bufferOut{state->mBufferOut};
|
||||
ALsizei count{state->mCount};
|
||||
|
||||
for(ALsizei i{0};i < SamplesToDo;)
|
||||
{
|
||||
do {
|
||||
/* Fill FIFO buffer with samples data */
|
||||
state->InFIFO[count] = SamplesIn[0][i];
|
||||
bufferOut[i] = state->OutFIFO[count - FIFO_LATENCY];
|
||||
state->mInFIFO[count] = SamplesIn[0][i];
|
||||
bufferOut[i] = state->mOutFIFO[count - FIFO_LATENCY];
|
||||
|
||||
count++;
|
||||
} while(++i < SamplesToDo && count < STFT_SIZE);
|
||||
@ -231,13 +231,13 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
|
||||
/* Real signal windowing and store in FFTbuffer */
|
||||
for(ALsizei k{0};k < STFT_SIZE;k++)
|
||||
{
|
||||
state->FFTbuffer[k].real(state->InFIFO[k] * HannWindow[k]);
|
||||
state->FFTbuffer[k].imag(0.0);
|
||||
state->mFFTbuffer[k].real(state->mInFIFO[k] * HannWindow[k]);
|
||||
state->mFFTbuffer[k].imag(0.0);
|
||||
}
|
||||
|
||||
/* ANALYSIS */
|
||||
/* Apply FFT to FFTbuffer data */
|
||||
complex_fft(state->FFTbuffer, STFT_SIZE, -1.0);
|
||||
complex_fft(state->mFFTbuffer, STFT_SIZE, -1.0);
|
||||
|
||||
/* Analyze the obtained data. Since the real FFT is symmetric, only
|
||||
* STFT_HALF_SIZE+1 samples are needed.
|
||||
@ -245,10 +245,10 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
|
||||
for(ALsizei k{0};k < STFT_HALF_SIZE+1;k++)
|
||||
{
|
||||
/* Compute amplitude and phase */
|
||||
ALphasor component{rect2polar(state->FFTbuffer[k])};
|
||||
ALphasor component{rect2polar(state->mFFTbuffer[k])};
|
||||
|
||||
/* Compute phase difference and subtract expected phase difference */
|
||||
double tmp{(component.Phase - state->LastPhase[k]) - k*expected};
|
||||
double tmp{(component.Phase - state->mLastPhase[k]) - k*expected};
|
||||
|
||||
/* Map delta phase into +/- Pi interval */
|
||||
int qpd{double2int(tmp / M_PI)};
|
||||
@ -261,29 +261,29 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
|
||||
* for maintain the gain (because half of bins are used) and store
|
||||
* amplitude and true frequency in analysis buffer.
|
||||
*/
|
||||
state->Analysis_buffer[k].Amplitude = 2.0 * component.Amplitude;
|
||||
state->Analysis_buffer[k].Frequency = (k + tmp) * freq_per_bin;
|
||||
state->mAnalysis_buffer[k].Amplitude = 2.0 * component.Amplitude;
|
||||
state->mAnalysis_buffer[k].Frequency = (k + tmp) * freq_per_bin;
|
||||
|
||||
/* Store actual phase[k] for the calculations in the next frame*/
|
||||
state->LastPhase[k] = component.Phase;
|
||||
state->mLastPhase[k] = component.Phase;
|
||||
}
|
||||
|
||||
/* PROCESSING */
|
||||
/* pitch shifting */
|
||||
for(ALsizei k{0};k < STFT_HALF_SIZE+1;k++)
|
||||
{
|
||||
state->Syntesis_buffer[k].Amplitude = 0.0;
|
||||
state->Syntesis_buffer[k].Frequency = 0.0;
|
||||
state->mSyntesis_buffer[k].Amplitude = 0.0;
|
||||
state->mSyntesis_buffer[k].Frequency = 0.0;
|
||||
}
|
||||
|
||||
for(ALsizei k{0};k < STFT_HALF_SIZE+1;k++)
|
||||
{
|
||||
ALsizei j{(k*state->PitchShiftI) >> FRACTIONBITS};
|
||||
ALsizei j{(k*state->mPitchShiftI) >> FRACTIONBITS};
|
||||
if(j >= STFT_HALF_SIZE+1) break;
|
||||
|
||||
state->Syntesis_buffer[j].Amplitude += state->Analysis_buffer[k].Amplitude;
|
||||
state->Syntesis_buffer[j].Frequency = state->Analysis_buffer[k].Frequency *
|
||||
state->PitchShift;
|
||||
state->mSyntesis_buffer[j].Amplitude += state->mAnalysis_buffer[k].Amplitude;
|
||||
state->mSyntesis_buffer[j].Frequency = state->mAnalysis_buffer[k].Frequency *
|
||||
state->mPitchShift;
|
||||
}
|
||||
|
||||
/* SYNTHESIS */
|
||||
@ -294,41 +294,41 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
|
||||
ALdouble tmp;
|
||||
|
||||
/* Compute bin deviation from scaled freq */
|
||||
tmp = state->Syntesis_buffer[k].Frequency/freq_per_bin - k;
|
||||
tmp = state->mSyntesis_buffer[k].Frequency/freq_per_bin - k;
|
||||
|
||||
/* Calculate actual delta phase and accumulate it to get bin phase */
|
||||
state->SumPhase[k] += (k + tmp) * expected;
|
||||
state->mSumPhase[k] += (k + tmp) * expected;
|
||||
|
||||
component.Amplitude = state->Syntesis_buffer[k].Amplitude;
|
||||
component.Phase = state->SumPhase[k];
|
||||
component.Amplitude = state->mSyntesis_buffer[k].Amplitude;
|
||||
component.Phase = state->mSumPhase[k];
|
||||
|
||||
/* Compute phasor component to cartesian complex number and storage it into FFTbuffer*/
|
||||
state->FFTbuffer[k] = polar2rect(component);
|
||||
state->mFFTbuffer[k] = polar2rect(component);
|
||||
}
|
||||
/* zero negative frequencies for recontruct a real signal */
|
||||
for(ALsizei k{STFT_HALF_SIZE+1};k < STFT_SIZE;k++)
|
||||
state->FFTbuffer[k] = complex_d{};
|
||||
state->mFFTbuffer[k] = complex_d{};
|
||||
|
||||
/* Apply iFFT to buffer data */
|
||||
complex_fft(state->FFTbuffer, STFT_SIZE, 1.0);
|
||||
complex_fft(state->mFFTbuffer, STFT_SIZE, 1.0);
|
||||
|
||||
/* Windowing and add to output */
|
||||
for(ALsizei k{0};k < STFT_SIZE;k++)
|
||||
state->OutputAccum[k] += HannWindow[k] * state->FFTbuffer[k].real() /
|
||||
(0.5 * STFT_HALF_SIZE * OVERSAMP);
|
||||
state->mOutputAccum[k] += HannWindow[k] * state->mFFTbuffer[k].real() /
|
||||
(0.5 * STFT_HALF_SIZE * OVERSAMP);
|
||||
|
||||
/* Shift accumulator, input & output FIFO */
|
||||
ALsizei j, k;
|
||||
for(k = 0;k < STFT_STEP;k++) state->OutFIFO[k] = (ALfloat)state->OutputAccum[k];
|
||||
for(j = 0;k < STFT_SIZE;k++,j++) state->OutputAccum[j] = state->OutputAccum[k];
|
||||
for(;j < STFT_SIZE;j++) state->OutputAccum[j] = 0.0;
|
||||
for(k = 0;k < STFT_STEP;k++) state->mOutFIFO[k] = (ALfloat)state->mOutputAccum[k];
|
||||
for(j = 0;k < STFT_SIZE;k++,j++) state->mOutputAccum[j] = state->mOutputAccum[k];
|
||||
for(;j < STFT_SIZE;j++) state->mOutputAccum[j] = 0.0;
|
||||
for(k = 0;k < FIFO_LATENCY;k++)
|
||||
state->InFIFO[k] = state->InFIFO[k+STFT_STEP];
|
||||
state->mInFIFO[k] = state->mInFIFO[k+STFT_STEP];
|
||||
}
|
||||
state->count = count;
|
||||
state->mCount = count;
|
||||
|
||||
/* Now, mix the processed sound data to the output. */
|
||||
MixSamples(bufferOut, NumChannels, SamplesOut, state->CurrentGains, state->TargetGains,
|
||||
MixSamples(bufferOut, NumChannels, SamplesOut, state->mCurrentGains, state->mTargetGains,
|
||||
maxi(SamplesToDo, 512), 0, SamplesToDo);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user