Clean up more effects' struct members

This commit is contained in:
Chris Robinson
2018-11-19 19:57:30 -08:00
parent 7f3584ec4c
commit a346380e2b
4 changed files with 100 additions and 111 deletions
+19 -24
View File
@@ -39,13 +39,13 @@
struct ALcompressorState final : public ALeffectState {
/* Effect gains for each channel */
ALfloat Gain[MAX_EFFECT_CHANNELS][MAX_OUTPUT_CHANNELS];
ALfloat mGain[MAX_EFFECT_CHANNELS][MAX_OUTPUT_CHANNELS]{};
/* Effect parameters */
ALboolean Enabled;
ALfloat AttackMult;
ALfloat ReleaseMult;
ALfloat EnvFollower;
ALboolean mEnabled{AL_TRUE};
ALfloat mAttackMult{1.0f};
ALfloat mReleaseMult{1.0f};
ALfloat mEnvFollower{1.0f};
};
static ALvoid ALcompressorState_Destruct(ALcompressorState *state);
@@ -62,11 +62,6 @@ static void ALcompressorState_Construct(ALcompressorState *state)
new (state) ALcompressorState{};
ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
SET_VTABLE2(ALcompressorState, ALeffectState, state);
state->Enabled = AL_TRUE;
state->AttackMult = 1.0f;
state->ReleaseMult = 1.0f;
state->EnvFollower = 1.0f;
}
static ALvoid ALcompressorState_Destruct(ALcompressorState *state)
@@ -86,8 +81,8 @@ static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdev
/* Calculate per-sample multipliers to attack and release at the desired
* rates.
*/
state->AttackMult = powf(AMP_ENVELOPE_MAX/AMP_ENVELOPE_MIN, 1.0f/attackCount);
state->ReleaseMult = powf(AMP_ENVELOPE_MIN/AMP_ENVELOPE_MAX, 1.0f/releaseCount);
state->mAttackMult = powf(AMP_ENVELOPE_MAX/AMP_ENVELOPE_MIN, 1.0f/attackCount);
state->mReleaseMult = powf(AMP_ENVELOPE_MIN/AMP_ENVELOPE_MAX, 1.0f/releaseCount);
return AL_TRUE;
}
@@ -97,13 +92,13 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCcontex
const ALCdevice *device = context->Device;
ALuint i;
state->Enabled = props->Compressor.OnOff;
state->mEnabled = props->Compressor.OnOff;
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 < 4;i++)
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
state->Gain[i]);
state->mGain[i]);
}
static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
@@ -115,10 +110,10 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
{
ALfloat gains[256];
ALsizei td = mini(256, SamplesToDo-base);
ALfloat env = state->EnvFollower;
ALfloat env = state->mEnvFollower;
/* Generate the per-sample gains from the signal envelope. */
if(state->Enabled)
if(state->mEnabled)
{
for(i = 0;i < td;++i)
{
@@ -128,9 +123,9 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
ALfloat amplitude = clampf(fabsf(SamplesIn[0][base+i]),
AMP_ENVELOPE_MIN, AMP_ENVELOPE_MAX);
if(amplitude > env)
env = minf(env*state->AttackMult, amplitude);
env = minf(env*state->mAttackMult, amplitude);
else if(amplitude < env)
env = maxf(env*state->ReleaseMult, amplitude);
env = maxf(env*state->mReleaseMult, amplitude);
/* Apply the reciprocal of the envelope to normalize the volume
* (compress the dynamic range).
@@ -148,21 +143,21 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
{
ALfloat amplitude = 1.0f;
if(amplitude > env)
env = minf(env*state->AttackMult, amplitude);
env = minf(env*state->mAttackMult, amplitude);
else if(amplitude < env)
env = maxf(env*state->ReleaseMult, amplitude);
env = maxf(env*state->mReleaseMult, amplitude);
gains[i] = 1.0f / env;
}
}
state->EnvFollower = env;
state->mEnvFollower = env;
/* Now compress the signal amplitude to output. */
for(j = 0;j < MAX_EFFECT_CHANNELS;j++)
{
for(k = 0;k < NumChannels;k++)
{
ALfloat gain = state->Gain[j][k];
ALfloat gain = state->mGain[j][k];
if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
continue;
+18 -21
View File
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include "alMain.h"
#include "alcontext.h"
@@ -31,8 +32,8 @@
struct ALdedicatedState final : public ALeffectState {
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS];
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS];
};
static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state);
@@ -59,9 +60,7 @@ static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state)
static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *UNUSED(device))
{
ALsizei i;
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
state->CurrentGains[i] = 0.0f;
std::fill(std::begin(state->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
return AL_TRUE;
}
@@ -69,10 +68,8 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext
{
const ALCdevice *device = context->Device;
ALfloat Gain;
ALsizei i;
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
state->TargetGains[i] = 0.0f;
std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
Gain = slot->Params.Gain * props->Dedicated.Gain;
if(slot->Params.EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
@@ -80,38 +77,38 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext
int idx;
if((idx=GetChannelIdxByName(&device->RealOut, LFE)) != -1)
{
STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
state->TargetGains[idx] = Gain;
state->OutBuffer = device->RealOut.Buffer;
state->OutChannels = device->RealOut.NumChannels;
state->mTargetGains[idx] = Gain;
}
}
else if(slot->Params.EffectType == AL_EFFECT_DEDICATED_DIALOGUE)
{
int idx;
/* Dialog goes to the front-center speaker if it exists, otherwise it
* plays from the front-center location. */
if((idx=GetChannelIdxByName(&device->RealOut, FrontCenter)) != -1)
int idx{GetChannelIdxByName(&device->RealOut, FrontCenter)};
if(idx != -1)
{
STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
state->TargetGains[idx] = Gain;
state->OutBuffer = device->RealOut.Buffer;
state->OutChannels = device->RealOut.NumChannels;
state->mTargetGains[idx] = Gain;
}
else
{
ALfloat coeffs[MAX_AMBI_COEFFS];
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer;
STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels;
ComputePanGains(&device->Dry, coeffs, Gain, state->TargetGains);
state->OutBuffer = device->Dry.Buffer;
state->OutChannels = device->Dry.NumChannels;
ComputePanGains(&device->Dry, coeffs, Gain, state->mTargetGains);
}
}
}
static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
MixSamples(SamplesIn[0], NumChannels, SamplesOut, state->CurrentGains,
state->TargetGains, SamplesToDo, 0, SamplesToDo);
MixSamples(SamplesIn[0], NumChannels, SamplesOut, state->mCurrentGains,
state->mTargetGains, SamplesToDo, 0, SamplesToDo);
}
+16 -16
View File
@@ -33,15 +33,15 @@
struct ALdistortionState final : public ALeffectState {
/* Effect gains for each channel */
ALfloat Gain[MAX_OUTPUT_CHANNELS];
ALfloat mGain[MAX_OUTPUT_CHANNELS]{};
/* Effect parameters */
BiquadFilter lowpass;
BiquadFilter bandpass;
ALfloat attenuation;
ALfloat edge_coeff;
BiquadFilter mLowpass;
BiquadFilter mBandpass;
ALfloat mAttenuation{};
ALfloat mEdgeCoeff{};
ALfloat Buffer[2][BUFFERSIZE];
ALfloat Buffer[2][BUFFERSIZE]{};
};
static ALvoid ALdistortionState_Destruct(ALdistortionState *state);
@@ -68,8 +68,8 @@ static ALvoid ALdistortionState_Destruct(ALdistortionState *state)
static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *state, ALCdevice *UNUSED(device))
{
BiquadFilter_clear(&state->lowpass);
BiquadFilter_clear(&state->bandpass);
BiquadFilter_clear(&state->mLowpass);
BiquadFilter_clear(&state->mBandpass);
return AL_TRUE;
}
@@ -85,7 +85,7 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontex
/* Store waveshaper edge settings. */
edge = sinf(props->Distortion.Edge * (F_PI_2));
edge = minf(edge, 0.99f);
state->edge_coeff = 2.0f * edge / (1.0f-edge);
state->mEdgeCoeff = 2.0f * edge / (1.0f-edge);
cutoff = props->Distortion.LowpassCutoff;
/* Bandwidth value is constant in octaves. */
@@ -93,25 +93,25 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontex
/* Multiply sampling frequency by the amount of oversampling done during
* processing.
*/
BiquadFilter_setParams(&state->lowpass, BiquadType::LowPass, 1.0f,
BiquadFilter_setParams(&state->mLowpass, BiquadType::LowPass, 1.0f,
cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth)
);
cutoff = props->Distortion.EQCenter;
/* Convert bandwidth in Hz to octaves. */
bandwidth = props->Distortion.EQBandwidth / (cutoff * 0.67f);
BiquadFilter_setParams(&state->bandpass, BiquadType::BandPass, 1.0f,
BiquadFilter_setParams(&state->mBandpass, BiquadType::BandPass, 1.0f,
cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth)
);
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain*props->Distortion.Gain, state->Gain);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain*props->Distortion.Gain, state->mGain);
}
static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
ALfloat (*RESTRICT buffer)[BUFFERSIZE] = state->Buffer;
const ALfloat fc = state->edge_coeff;
const ALfloat fc = state->mEdgeCoeff;
ALsizei base;
ALsizei i, k;
@@ -135,7 +135,7 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample
* (which is fortunately first step of distortion). So combine three
* operations into the one.
*/
BiquadFilter_process(&state->lowpass, buffer[1], buffer[0], todo);
BiquadFilter_process(&state->mLowpass, buffer[1], buffer[0], todo);
/* Second step, do distortion using waveshaper function to emulate
* signal processing during tube overdriving. Three steps of
@@ -154,7 +154,7 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample
}
/* Third step, do bandpass filtering of distorted signal. */
BiquadFilter_process(&state->bandpass, buffer[1], buffer[0], todo);
BiquadFilter_process(&state->mBandpass, buffer[1], buffer[0], todo);
todo >>= 2;
for(k = 0;k < NumChannels;k++)
@@ -162,7 +162,7 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample
/* Fourth step, final, do attenuation and perform decimation,
* storing only one sample out of four.
*/
ALfloat gain = state->Gain[k];
ALfloat gain = state->mGain[k];
if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
continue;
+47 -50
View File
@@ -23,6 +23,8 @@
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include "alMain.h"
#include "alcontext.h"
#include "alFilter.h"
@@ -33,25 +35,25 @@
struct ALechoState final : public ALeffectState {
ALfloat *SampleBuffer;
ALsizei BufferLength;
ALfloat *mSampleBuffer{nullptr};
ALsizei mBufferLength{0};
// The echo is two tap. The delay is the number of samples from before the
// current offset
struct {
ALsizei delay;
} Tap[2];
ALsizei Offset;
ALsizei delay{0};
} mTap[2];
ALsizei mOffset{0};
/* The panning gains for the two taps */
struct {
ALfloat Current[MAX_OUTPUT_CHANNELS];
ALfloat Target[MAX_OUTPUT_CHANNELS];
} Gains[2];
ALfloat Current[MAX_OUTPUT_CHANNELS]{};
ALfloat Target[MAX_OUTPUT_CHANNELS]{};
} mGains[2];
ALfloat FeedGain;
ALfloat mFeedGain{0.0f};
BiquadFilter Filter;
BiquadFilter mFilter;
};
static ALvoid ALechoState_Destruct(ALechoState *state);
@@ -68,21 +70,12 @@ static void ALechoState_Construct(ALechoState *state)
new (state) ALechoState{};
ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
SET_VTABLE2(ALechoState, ALeffectState, state);
state->BufferLength = 0;
state->SampleBuffer = NULL;
state->Tap[0].delay = 0;
state->Tap[1].delay = 0;
state->Offset = 0;
BiquadFilter_clear(&state->Filter);
}
static ALvoid ALechoState_Destruct(ALechoState *state)
{
al_free(state->SampleBuffer);
state->SampleBuffer = NULL;
al_free(state->mSampleBuffer);
state->mSampleBuffer = NULL;
ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
state->~ALechoState();
}
@@ -98,18 +91,22 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device)
maxlen = NextPowerOf2(maxlen);
if(maxlen <= 0) return AL_FALSE;
if(maxlen != state->BufferLength)
if(maxlen != state->mBufferLength)
{
void *temp = al_calloc(16, maxlen * sizeof(ALfloat));
if(!temp) return AL_FALSE;
al_free(state->SampleBuffer);
state->SampleBuffer = static_cast<float*>(temp);
state->BufferLength = maxlen;
al_free(state->mSampleBuffer);
state->mSampleBuffer = static_cast<float*>(temp);
state->mBufferLength = maxlen;
}
memset(state->SampleBuffer, 0, state->BufferLength*sizeof(ALfloat));
memset(state->Gains, 0, sizeof(state->Gains));
std::fill_n(state->mSampleBuffer, state->mBufferLength, 0.0f);
for(auto &e : state->mGains)
{
std::fill(std::begin(e.Current), std::end(e.Current), 0.0f);
std::fill(std::begin(e.Target), std::end(e.Target), 0.0f);
}
return AL_TRUE;
}
@@ -121,9 +118,9 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context,
ALfloat coeffs[MAX_AMBI_COEFFS];
ALfloat gainhf, lrpan, spread;
state->Tap[0].delay = maxi(float2int(props->Echo.Delay*frequency + 0.5f), 1);
state->Tap[1].delay = float2int(props->Echo.LRDelay*frequency + 0.5f);
state->Tap[1].delay += state->Tap[0].delay;
state->mTap[0].delay = maxi(float2int(props->Echo.Delay*frequency + 0.5f), 1);
state->mTap[1].delay = float2int(props->Echo.LRDelay*frequency + 0.5f);
state->mTap[1].delay += state->mTap[0].delay;
spread = props->Echo.Spread;
if(spread < 0.0f) lrpan = -1.0f;
@@ -133,35 +130,35 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context,
*/
spread = asinf(1.0f - fabsf(spread))*4.0f;
state->FeedGain = props->Echo.Feedback;
state->mFeedGain = props->Echo.Feedback;
gainhf = maxf(1.0f - props->Echo.Damping, 0.0625f); /* Limit -24dB */
BiquadFilter_setParams(&state->Filter, BiquadType::HighShelf,
BiquadFilter_setParams(&state->mFilter, BiquadType::HighShelf,
gainhf, LOWPASSFREQREF/frequency, calc_rcpQ_from_slope(gainhf, 1.0f)
);
/* First tap panning */
CalcAngleCoeffs(-F_PI_2*lrpan, 0.0f, spread, coeffs);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->Gains[0].Target);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mGains[0].Target);
/* Second tap panning */
CalcAngleCoeffs( F_PI_2*lrpan, 0.0f, spread, coeffs);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->Gains[1].Target);
ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mGains[1].Target);
}
static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
const ALsizei mask = state->BufferLength-1;
const ALsizei tap1 = state->Tap[0].delay;
const ALsizei tap2 = state->Tap[1].delay;
ALfloat *RESTRICT delaybuf = state->SampleBuffer;
ALsizei offset = state->Offset;
const ALsizei mask = state->mBufferLength-1;
const ALsizei tap1 = state->mTap[0].delay;
const ALsizei tap2 = state->mTap[1].delay;
ALfloat *RESTRICT delaybuf = state->mSampleBuffer;
ALsizei offset = state->mOffset;
ALfloat z1, z2, in, out;
ALsizei base;
ALsizei c, i;
z1 = state->Filter.z1;
z2 = state->Filter.z2;
z1 = state->mFilter.z1;
z2 = state->mFilter.z2;
for(base = 0;base < SamplesToDo;)
{
alignas(16) ALfloat temps[2][128];
@@ -181,24 +178,24 @@ static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const
* feedback attenuation.
*/
in = temps[1][i];
out = in*state->Filter.b0 + z1;
z1 = in*state->Filter.b1 - out*state->Filter.a1 + z2;
z2 = in*state->Filter.b2 - out*state->Filter.a2;
out = in*state->mFilter.b0 + z1;
z1 = in*state->mFilter.b1 - out*state->mFilter.a1 + z2;
z2 = in*state->mFilter.b2 - out*state->mFilter.a2;
delaybuf[offset&mask] += out * state->FeedGain;
delaybuf[offset&mask] += out * state->mFeedGain;
offset++;
}
for(c = 0;c < 2;c++)
MixSamples(temps[c], NumChannels, SamplesOut, state->Gains[c].Current,
state->Gains[c].Target, SamplesToDo-base, base, td);
MixSamples(temps[c], NumChannels, SamplesOut, state->mGains[c].Current,
state->mGains[c].Target, SamplesToDo-base, base, td);
base += td;
}
state->Filter.z1 = z1;
state->Filter.z2 = z2;
state->mFilter.z1 = z1;
state->mFilter.z2 = z2;
state->Offset = offset;
state->mOffset = offset;
}