aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-19 22:34:26 -0800
committerChris Robinson <[email protected]>2018-11-19 22:34:26 -0800
commit8472a9d916eae13771455c2b527c1148aa71d8fb (patch)
treed86470a5e2882ce73a86a892eac7082bd2b97566 /Alc
parent6ac84c7a5f6d267522bdc872802c8940dcd2adec (diff)
Use proper inheritence for the effect state objects
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alc.cpp18
-rw-r--r--Alc/alu.cpp18
-rw-r--r--Alc/effects/autowah.cpp116
-rw-r--r--Alc/effects/chorus.cpp135
-rw-r--r--Alc/effects/compressor.cpp75
-rw-r--r--Alc/effects/dedicated.cpp69
-rw-r--r--Alc/effects/distortion.cpp67
-rw-r--r--Alc/effects/echo.cpp99
-rw-r--r--Alc/effects/equalizer.cpp93
-rw-r--r--Alc/effects/fshifter.cpp118
-rw-r--r--Alc/effects/modulator.cpp85
-rw-r--r--Alc/effects/null.cpp69
-rw-r--r--Alc/effects/pshifter.cpp147
-rw-r--r--Alc/effects/reverb.cpp316
14 files changed, 586 insertions, 839 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 6e68d130..56a581fd 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2256,11 +2256,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
if(context->DefaultSlot)
{
ALeffectslot *slot = context->DefaultSlot;
- ALeffectState *state = slot->Effect.State;
+ EffectState *state = slot->Effect.State;
- state->OutBuffer = device->Dry.Buffer;
- state->OutChannels = device->Dry.NumChannels;
- if(V(state,deviceUpdate)(device) == AL_FALSE)
+ state->mOutBuffer = device->Dry.Buffer;
+ state->mOutChannels = device->Dry.NumChannels;
+ if(state->deviceUpdate(device) == AL_FALSE)
update_failed = AL_TRUE;
else
UpdateEffectSlotProps(slot, context);
@@ -2270,11 +2270,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
almtx_lock(&context->EffectSlotLock);
for(auto &slot : context->EffectSlotList)
{
- ALeffectState *state = slot->Effect.State;
+ EffectState *state = slot->Effect.State;
- state->OutBuffer = device->Dry.Buffer;
- state->OutChannels = device->Dry.NumChannels;
- if(V(state,deviceUpdate)(device) == AL_FALSE)
+ state->mOutBuffer = device->Dry.Buffer;
+ state->mOutChannels = device->Dry.NumChannels;
+ if(state->deviceUpdate(device) == AL_FALSE)
update_failed = AL_TRUE;
else
UpdateEffectSlotProps(slot, context);
@@ -2603,7 +2603,7 @@ ALCcontext_struct::~ALCcontext_struct()
while(eprops)
{
struct ALeffectslotProps *next{eprops->next.load(std::memory_order_relaxed)};
- if(eprops->State) ALeffectState_DecRef(eprops->State);
+ if(eprops->State) eprops->State->DecRef();
al_free(eprops);
eprops = next;
++count;
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index e30f6a2e..6a2f0c01 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -381,7 +381,7 @@ static bool CalcListenerParams(ALCcontext *Context)
static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force)
{
struct ALeffectslotProps *props;
- ALeffectState *state;
+ EffectState *state;
props = slot->Update.exchange(nullptr, std::memory_order_acq_rel);
if(!props && !force) return false;
@@ -419,8 +419,8 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f
* count safely to remove it from the update object (it can't reach
* 0 refs since the current params also hold a reference).
*/
- DecrementRef(&state->Ref);
- props->State = NULL;
+ DecrementRef(&state->mRef);
+ props->State = nullptr;
}
else
{
@@ -428,7 +428,7 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f
* event.
*/
AsyncEvent evt = ASYNC_EVENT(EventType_ReleaseEffectState);
- evt.u.EffectState = slot->Params.EffectState;
+ evt.u.mEffectState = slot->Params.EffectState;
slot->Params.EffectState = state;
props->State = NULL;
@@ -442,7 +442,7 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f
* eventually be cleaned up sometime later (not ideal, but
* better than blocking or leaking).
*/
- props->State = evt.u.EffectState;
+ props->State = evt.u.mEffectState;
}
}
@@ -451,7 +451,7 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f
else
state = slot->Params.EffectState;
- V(state,update)(context, slot, &slot->Params.EffectProps);
+ state->update(context, slot, &slot->Params.EffectProps);
return true;
}
@@ -1749,9 +1749,9 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
for(i = 0;i < auxslots->count;i++)
{
const ALeffectslot *slot = auxslots->slot[i];
- ALeffectState *state = slot->Params.EffectState;
- V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer,
- state->OutChannels);
+ EffectState *state = slot->Params.EffectState;
+ state->process(SamplesToDo, slot->WetBuffer, state->mOutBuffer,
+ state->mOutChannels);
}
ctx = ATOMIC_LOAD(&ctx->next, almemory_order_relaxed);
diff --git a/Alc/effects/autowah.cpp b/Alc/effects/autowah.cpp
index 4cf79998..8e789652 100644
--- a/Alc/effects/autowah.cpp
+++ b/Alc/effects/autowah.cpp
@@ -37,7 +37,7 @@
#define MAX_FREQ 2500.0f
#define Q_FACTOR 5.0f
-struct ALautowahState final : public ALeffectState {
+struct ALautowahState final : public EffectState {
/* Effect parameters */
ALfloat mAttackRate;
ALfloat mReleaseRate;
@@ -66,48 +66,34 @@ struct ALautowahState final : public ALeffectState {
/* Effects buffers */
alignas(16) ALfloat mBufferOut[BUFFERSIZE];
-};
-static ALvoid ALautowahState_Destruct(ALautowahState *state);
-static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device);
-static ALvoid ALautowahState_update(ALautowahState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALautowahState)
-DEFINE_ALEFFECTSTATE_VTABLE(ALautowahState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static void ALautowahState_Construct(ALautowahState *state)
-{
- new (state) ALautowahState{};
- ALeffectState_Construct(state);
- SET_VTABLE2(ALautowahState, ALeffectState, state);
-}
-
-static ALvoid ALautowahState_Destruct(ALautowahState *state)
-{
- ALeffectState_Destruct(state);
- state->~ALautowahState();
-}
+ DEF_NEWDEL(ALautowahState)
+};
-static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *UNUSED(device))
+ALboolean ALautowahState::deviceUpdate(ALCdevice *UNUSED(device))
{
/* (Re-)initializing parameters and clear the buffers. */
- state->mAttackRate = 1.0f;
- state->mReleaseRate = 1.0f;
- state->mResonanceGain = 10.0f;
- state->mPeakGain = 4.5f;
- state->mFreqMinNorm = 4.5e-4f;
- state->mBandwidthNorm = 0.05f;
- state->mEnvDelay = 0.0f;
+ mAttackRate = 1.0f;
+ mReleaseRate = 1.0f;
+ mResonanceGain = 10.0f;
+ mPeakGain = 4.5f;
+ mFreqMinNorm = 4.5e-4f;
+ mBandwidthNorm = 0.05f;
+ mEnvDelay = 0.0f;
- for(auto &e : state->mEnv)
+ for(auto &e : mEnv)
{
e.cos_w0 = 0.0f;
e.alpha = 0.0f;
}
- for(auto &chan : state->mChans)
+ for(auto &chan : mChans)
{
std::fill(std::begin(chan.CurrentGains), std::end(chan.CurrentGains), 0.0f);
chan.Filter.z1 = 0.0f;
@@ -117,7 +103,7 @@ static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *U
return AL_TRUE;
}
-static ALvoid ALautowahState_update(ALautowahState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALautowahState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat ReleaseTime;
@@ -125,33 +111,33 @@ static ALvoid ALautowahState_update(ALautowahState *state, const ALCcontext *con
ReleaseTime = clampf(props->Autowah.ReleaseTime, 0.001f, 1.0f);
- state->mAttackRate = expf(-1.0f / (props->Autowah.AttackTime*device->Frequency));
- state->mReleaseRate = expf(-1.0f / (ReleaseTime*device->Frequency));
+ mAttackRate = expf(-1.0f / (props->Autowah.AttackTime*device->Frequency));
+ mReleaseRate = expf(-1.0f / (ReleaseTime*device->Frequency));
/* 0-20dB Resonance Peak gain */
- state->mResonanceGain = sqrtf(log10f(props->Autowah.Resonance)*10.0f / 3.0f);
- state->mPeakGain = 1.0f - log10f(props->Autowah.PeakGain/AL_AUTOWAH_MAX_PEAK_GAIN);
- state->mFreqMinNorm = MIN_FREQ / device->Frequency;
- state->mBandwidthNorm = (MAX_FREQ-MIN_FREQ) / device->Frequency;
+ mResonanceGain = sqrtf(log10f(props->Autowah.Resonance)*10.0f / 3.0f);
+ mPeakGain = 1.0f - log10f(props->Autowah.PeakGain/AL_AUTOWAH_MAX_PEAK_GAIN);
+ mFreqMinNorm = MIN_FREQ / device->Frequency;
+ mBandwidthNorm = (MAX_FREQ-MIN_FREQ) / device->Frequency;
- state->OutBuffer = device->FOAOut.Buffer;
- state->OutChannels = device->FOAOut.NumChannels;
+ mOutBuffer = device->FOAOut.Buffer;
+ mOutChannels = device->FOAOut.NumChannels;
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
- state->mChans[i].TargetGains);
+ mChans[i].TargetGains);
}
-static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALautowahState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- const ALfloat attack_rate = state->mAttackRate;
- const ALfloat release_rate = state->mReleaseRate;
- const ALfloat res_gain = state->mResonanceGain;
- const ALfloat peak_gain = state->mPeakGain;
- const ALfloat freq_min = state->mFreqMinNorm;
- const ALfloat bandwidth = state->mBandwidthNorm;
+ const ALfloat attack_rate = mAttackRate;
+ const ALfloat release_rate = mReleaseRate;
+ const ALfloat res_gain = mResonanceGain;
+ const ALfloat peak_gain = mPeakGain;
+ const ALfloat freq_min = mFreqMinNorm;
+ const ALfloat bandwidth = mBandwidthNorm;
ALfloat env_delay;
ALsizei c, i;
- env_delay = state->mEnvDelay;
+ env_delay = mEnvDelay;
for(i = 0;i < SamplesToDo;i++)
{
ALfloat w0, sample, a;
@@ -165,10 +151,10 @@ static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo,
/* Calculate the cos and alpha components for this sample's filter. */
w0 = minf((bandwidth*env_delay + freq_min), 0.46f) * F_TAU;
- state->mEnv[i].cos_w0 = cosf(w0);
- state->mEnv[i].alpha = sinf(w0)/(2.0f * Q_FACTOR);
+ mEnv[i].cos_w0 = cosf(w0);
+ mEnv[i].alpha = sinf(w0)/(2.0f * Q_FACTOR);
}
- state->mEnvDelay = env_delay;
+ mEnvDelay = env_delay;
for(c = 0;c < MAX_EFFECT_CHANNELS; c++)
{
@@ -178,13 +164,13 @@ static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo,
* envelope. Because the filter changes for each sample, the
* coefficients are transient and don't need to be held.
*/
- ALfloat z1 = state->mChans[c].Filter.z1;
- ALfloat z2 = state->mChans[c].Filter.z2;
+ ALfloat z1 = mChans[c].Filter.z1;
+ ALfloat z2 = mChans[c].Filter.z2;
for(i = 0;i < SamplesToDo;i++)
{
- const ALfloat alpha = state->mEnv[i].alpha;
- const ALfloat cos_w0 = state->mEnv[i].cos_w0;
+ const ALfloat alpha = mEnv[i].alpha;
+ const ALfloat cos_w0 = mEnv[i].cos_w0;
ALfloat input, output;
ALfloat a[3], b[3];
@@ -199,27 +185,23 @@ static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo,
output = input*(b[0]/a[0]) + z1;
z1 = input*(b[1]/a[0]) - output*(a[1]/a[0]) + z2;
z2 = input*(b[2]/a[0]) - output*(a[2]/a[0]);
- state->mBufferOut[i] = output;
+ mBufferOut[i] = output;
}
- state->mChans[c].Filter.z1 = z1;
- state->mChans[c].Filter.z2 = z2;
+ mChans[c].Filter.z1 = z1;
+ mChans[c].Filter.z2 = z2;
/* Now, mix the processed sound data to the output. */
- MixSamples(state->mBufferOut, NumChannels, SamplesOut, state->mChans[c].CurrentGains,
- state->mChans[c].TargetGains, SamplesToDo, 0, SamplesToDo);
+ MixSamples(mBufferOut, NumChannels, SamplesOut, mChans[c].CurrentGains,
+ mChans[c].TargetGains, SamplesToDo, 0, SamplesToDo);
}
}
struct AutowahStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *AutowahStateFactory::create()
-{
- ALautowahState *state;
- NEW_OBJ0(state, ALautowahState)();
- return state;
-}
+EffectState *AutowahStateFactory::create()
+{ return new ALautowahState{}; }
EffectStateFactory *AutowahStateFactory_getFactory(void)
{
diff --git a/Alc/effects/chorus.cpp b/Alc/effects/chorus.cpp
index d859d630..ee0b64e5 100644
--- a/Alc/effects/chorus.cpp
+++ b/Alc/effects/chorus.cpp
@@ -42,7 +42,7 @@ enum WaveForm {
WF_Triangle
};
-struct ALchorusState final : public ALeffectState {
+struct ALchorusState final : public EffectState {
al::vector<ALfloat,16> mSampleBuffer;
ALsizei mOffset{0};
@@ -62,31 +62,16 @@ struct ALchorusState final : public ALeffectState {
ALint mDelay{0};
ALfloat mDepth{0.0f};
ALfloat mFeedback{0.0f};
-};
-
-static ALvoid ALchorusState_Destruct(ALchorusState *state);
-static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device);
-static ALvoid ALchorusState_update(ALchorusState *state, const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props);
-static ALvoid ALchorusState_process(ALchorusState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALchorusState)
-DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static void ALchorusState_Construct(ALchorusState *state)
-{
- new (state) ALchorusState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALchorusState, ALeffectState, state);
-}
-
-static ALvoid ALchorusState_Destruct(ALchorusState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALchorusState();
-}
+ DEF_NEWDEL(ALchorusState)
+};
-static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device)
+ALboolean ALchorusState::deviceUpdate(ALCdevice *Device)
{
const ALfloat max_delay = maxf(AL_CHORUS_MAX_DELAY, AL_FLANGER_MAX_DELAY);
size_t maxlen;
@@ -94,14 +79,14 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev
maxlen = NextPowerOf2(float2int(max_delay*2.0f*Device->Frequency) + 1u);
if(maxlen <= 0) return AL_FALSE;
- if(maxlen != state->mSampleBuffer.size())
+ if(maxlen != mSampleBuffer.size())
{
- state->mSampleBuffer.resize(maxlen);
- state->mSampleBuffer.shrink_to_fit();
+ mSampleBuffer.resize(maxlen);
+ mSampleBuffer.shrink_to_fit();
}
- std::fill(state->mSampleBuffer.begin(), state->mSampleBuffer.end(), 0.0f);
- for(auto &e : state->mGains)
+ std::fill(mSampleBuffer.begin(), mSampleBuffer.end(), 0.0f);
+ for(auto &e : 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);
@@ -110,7 +95,7 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev
return AL_TRUE;
}
-static ALvoid ALchorusState_update(ALchorusState *state, const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props)
+void ALchorusState::update(const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props)
{
const ALsizei mindelay = MAX_RESAMPLE_PADDING << FRACTIONBITS;
const ALCdevice *device = Context->Device;
@@ -122,37 +107,35 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCcontext *Conte
switch(props->Chorus.Waveform)
{
case AL_CHORUS_WAVEFORM_TRIANGLE:
- state->mWaveform = WF_Triangle;
+ mWaveform = WF_Triangle;
break;
case AL_CHORUS_WAVEFORM_SINUSOID:
- state->mWaveform = WF_Sinusoid;
+ mWaveform = WF_Sinusoid;
break;
}
/* The LFO depth is scaled to be relative to the sample delay. Clamp the
* delay and depth to allow enough padding for resampling.
*/
- state->mDelay = maxi(float2int(props->Chorus.Delay*frequency*FRACTIONONE + 0.5f),
- mindelay);
- state->mDepth = minf(props->Chorus.Depth * state->mDelay,
- (ALfloat)(state->mDelay - mindelay));
+ mDelay = maxi(float2int(props->Chorus.Delay*frequency*FRACTIONONE + 0.5f), mindelay);
+ mDepth = minf(props->Chorus.Depth * mDelay, (ALfloat)(mDelay - mindelay));
- state->mFeedback = props->Chorus.Feedback;
+ mFeedback = props->Chorus.Feedback;
/* Gains for left and right sides */
CalcAngleCoeffs(-F_PI_2, 0.0f, 0.0f, coeffs);
- ComputePanGains(&device->Dry, coeffs, Slot->Params.Gain, state->mGains[0].Target);
+ ComputePanGains(&device->Dry, coeffs, Slot->Params.Gain, mGains[0].Target);
CalcAngleCoeffs( F_PI_2, 0.0f, 0.0f, coeffs);
- ComputePanGains(&device->Dry, coeffs, Slot->Params.Gain, state->mGains[1].Target);
+ ComputePanGains(&device->Dry, coeffs, Slot->Params.Gain, mGains[1].Target);
phase = props->Chorus.Phase;
rate = props->Chorus.Rate;
if(!(rate > 0.0f))
{
- state->mLfoOffset = 0;
- state->mLfoRange = 1;
- state->mLfoScale = 0.0f;
- state->mLfoDisp = 0;
+ mLfoOffset = 0;
+ mLfoRange = 1;
+ mLfoScale = 0.0f;
+ mLfoDisp = 0;
}
else
{
@@ -161,22 +144,21 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCcontext *Conte
*/
ALsizei lfo_range = float2int(minf(frequency/rate + 0.5f, (ALfloat)(INT_MAX/360 - 180)));
- state->mLfoOffset = float2int((ALfloat)state->mLfoOffset/state->mLfoRange*
- lfo_range + 0.5f) % lfo_range;
- state->mLfoRange = lfo_range;
- switch(state->mWaveform)
+ mLfoOffset = float2int((ALfloat)mLfoOffset/mLfoRange*lfo_range + 0.5f) % lfo_range;
+ mLfoRange = lfo_range;
+ switch(mWaveform)
{
case WF_Triangle:
- state->mLfoScale = 4.0f / state->mLfoRange;
+ mLfoScale = 4.0f / mLfoRange;
break;
case WF_Sinusoid:
- state->mLfoScale = F_TAU / state->mLfoRange;
+ mLfoScale = F_TAU / mLfoRange;
break;
}
/* Calculate lfo phase displacement */
if(phase < 0) phase = 360 + phase;
- state->mLfoDisp = (state->mLfoRange*phase + 180) / 360;
+ mLfoDisp = (mLfoRange*phase + 180) / 360;
}
}
@@ -204,14 +186,13 @@ static void GetSinusoidDelays(ALint *RESTRICT delays, ALsizei offset, const ALsi
}
}
-
-static ALvoid ALchorusState_process(ALchorusState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALchorusState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- const ALsizei bufmask = state->mSampleBuffer.size()-1;
- const ALfloat feedback = state->mFeedback;
- const ALsizei avgdelay = (state->mDelay + (FRACTIONONE>>1)) >> FRACTIONBITS;
- ALfloat *RESTRICT delaybuf = state->mSampleBuffer.data();
- ALsizei offset = state->mOffset;
+ const ALsizei bufmask = mSampleBuffer.size()-1;
+ const ALfloat feedback = mFeedback;
+ const ALsizei avgdelay = (mDelay + (FRACTIONONE>>1)) >> FRACTIONBITS;
+ ALfloat *RESTRICT delaybuf = mSampleBuffer.data();
+ ALsizei offset = mOffset;
ALsizei i, c;
ALsizei base;
@@ -221,23 +202,21 @@ static ALvoid ALchorusState_process(ALchorusState *state, ALsizei SamplesToDo, c
ALint moddelays[2][256];
alignas(16) ALfloat temps[2][256];
- if(state->mWaveform == WF_Sinusoid)
+ if(mWaveform == WF_Sinusoid)
{
- GetSinusoidDelays(moddelays[0], state->mLfoOffset, state->mLfoRange, state->mLfoScale,
- state->mDepth, state->mDelay, todo);
- GetSinusoidDelays(moddelays[1], (state->mLfoOffset+state->mLfoDisp)%state->mLfoRange,
- state->mLfoRange, state->mLfoScale, state->mDepth, state->mDelay,
+ GetSinusoidDelays(moddelays[0], mLfoOffset, mLfoRange, mLfoScale, mDepth, mDelay,
todo);
+ GetSinusoidDelays(moddelays[1], (mLfoOffset+mLfoDisp)%mLfoRange, mLfoRange, mLfoScale,
+ mDepth, mDelay, todo);
}
else /*if(state->waveform == WF_Triangle)*/
{
- GetTriangleDelays(moddelays[0], state->mLfoOffset, state->mLfoRange, state->mLfoScale,
- state->mDepth, state->mDelay, todo);
- GetTriangleDelays(moddelays[1], (state->mLfoOffset+state->mLfoDisp)%state->mLfoRange,
- state->mLfoRange, state->mLfoScale, state->mDepth, state->mDelay,
+ GetTriangleDelays(moddelays[0], mLfoOffset, mLfoRange, mLfoScale, mDepth, mDelay,
todo);
+ GetTriangleDelays(moddelays[1], (mLfoOffset+mLfoDisp)%mLfoRange, mLfoRange, mLfoScale,
+ mDepth, mDelay, todo);
}
- state->mLfoOffset = (state->mLfoOffset+todo) % state->mLfoRange;
+ mLfoOffset = (mLfoOffset+todo) % mLfoRange;
for(i = 0;i < todo;i++)
{
@@ -267,26 +246,22 @@ static ALvoid ALchorusState_process(ALchorusState *state, ALsizei SamplesToDo, c
}
for(c = 0;c < 2;c++)
- MixSamples(temps[c], NumChannels, SamplesOut, state->mGains[c].Current,
- state->mGains[c].Target, SamplesToDo-base, base, todo);
+ MixSamples(temps[c], NumChannels, SamplesOut, mGains[c].Current,
+ mGains[c].Target, SamplesToDo-base, base, todo);
base += todo;
}
- state->mOffset = offset;
+ mOffset = offset;
}
struct ChorusStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *ChorusStateFactory::create()
-{
- ALchorusState *state;
- NEW_OBJ0(state, ALchorusState)();
- return state;
-}
+EffectState *ChorusStateFactory::create()
+{ return new ALchorusState{}; }
EffectStateFactory *ChorusStateFactory_getFactory(void)
{
@@ -408,15 +383,11 @@ DEFINE_ALEFFECT_VTABLE(ALchorus);
* the same processing functions, so piggyback flanger on the chorus functions.
*/
struct FlangerStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *FlangerStateFactory::create()
-{
- ALchorusState *state;
- NEW_OBJ0(state, ALchorusState)();
- return state;
-}
+EffectState *FlangerStateFactory::create()
+{ return new ALchorusState{}; }
EffectStateFactory *FlangerStateFactory_getFactory(void)
{
diff --git a/Alc/effects/compressor.cpp b/Alc/effects/compressor.cpp
index be91dd6c..c8bdef15 100644
--- a/Alc/effects/compressor.cpp
+++ b/Alc/effects/compressor.cpp
@@ -37,7 +37,7 @@
#define RELEASE_TIME 0.2f /* 200ms to drop from max to min */
-struct ALcompressorState final : public ALeffectState {
+struct ALcompressorState final : public EffectState {
/* Effect gains for each channel */
ALfloat mGain[MAX_EFFECT_CHANNELS][MAX_OUTPUT_CHANNELS]{};
@@ -46,31 +46,16 @@ struct ALcompressorState final : public ALeffectState {
ALfloat mAttackMult{1.0f};
ALfloat mReleaseMult{1.0f};
ALfloat mEnvFollower{1.0f};
-};
-
-static ALvoid ALcompressorState_Destruct(ALcompressorState *state);
-static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdevice *device);
-static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALcompressorState)
-
-DEFINE_ALEFFECTSTATE_VTABLE(ALcompressorState);
-static void ALcompressorState_Construct(ALcompressorState *state)
-{
- new (state) ALcompressorState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALcompressorState, ALeffectState, state);
-}
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static ALvoid ALcompressorState_Destruct(ALcompressorState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALcompressorState();
-}
+ DEF_NEWDEL(ALcompressorState)
+};
-static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdevice *device)
+ALboolean ALcompressorState::deviceUpdate(ALCdevice *device)
{
/* Number of samples to do a full attack and release (non-integer sample
* counts are okay).
@@ -81,27 +66,25 @@ static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdev
/* Calculate per-sample multipliers to attack and release at the desired
* rates.
*/
- state->mAttackMult = powf(AMP_ENVELOPE_MAX/AMP_ENVELOPE_MIN, 1.0f/attackCount);
- state->mReleaseMult = powf(AMP_ENVELOPE_MIN/AMP_ENVELOPE_MAX, 1.0f/releaseCount);
+ mAttackMult = powf(AMP_ENVELOPE_MAX/AMP_ENVELOPE_MIN, 1.0f/attackCount);
+ mReleaseMult = powf(AMP_ENVELOPE_MIN/AMP_ENVELOPE_MAX, 1.0f/releaseCount);
return AL_TRUE;
}
-static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALcompressorState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
- ALuint i;
- state->mEnabled = props->Compressor.OnOff;
+ mEnabled = props->Compressor.OnOff;
- 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->mGain[i]);
+ mOutBuffer = device->FOAOut.Buffer;
+ mOutChannels = device->FOAOut.NumChannels;
+ for(ALsizei i{0};i < 4;i++)
+ ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain, mGain[i]);
}
-static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALcompressorState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
ALsizei i, j, k;
ALsizei base;
@@ -110,10 +93,10 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
{
ALfloat gains[256];
ALsizei td = mini(256, SamplesToDo-base);
- ALfloat env = state->mEnvFollower;
+ ALfloat env = mEnvFollower;
/* Generate the per-sample gains from the signal envelope. */
- if(state->mEnabled)
+ if(mEnabled)
{
for(i = 0;i < td;++i)
{
@@ -123,9 +106,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->mAttackMult, amplitude);
+ env = minf(env*mAttackMult, amplitude);
else if(amplitude < env)
- env = maxf(env*state->mReleaseMult, amplitude);
+ env = maxf(env*mReleaseMult, amplitude);
/* Apply the reciprocal of the envelope to normalize the volume
* (compress the dynamic range).
@@ -143,21 +126,21 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
{
ALfloat amplitude = 1.0f;
if(amplitude > env)
- env = minf(env*state->mAttackMult, amplitude);
+ env = minf(env*mAttackMult, amplitude);
else if(amplitude < env)
- env = maxf(env*state->mReleaseMult, amplitude);
+ env = maxf(env*mReleaseMult, amplitude);
gains[i] = 1.0f / env;
}
}
- state->mEnvFollower = env;
+ 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->mGain[j][k];
+ ALfloat gain = mGain[j][k];
if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
continue;
@@ -172,15 +155,11 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample
struct CompressorStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *CompressorStateFactory::create()
-{
- ALcompressorState *state;
- NEW_OBJ0(state, ALcompressorState)();
- return state;
-}
+EffectState *CompressorStateFactory::create()
+{ return new ALcompressorState{}; }
EffectStateFactory *CompressorStateFactory_getFactory(void)
{
diff --git a/Alc/effects/dedicated.cpp b/Alc/effects/dedicated.cpp
index 8a59fd4b..491b57ec 100644
--- a/Alc/effects/dedicated.cpp
+++ b/Alc/effects/dedicated.cpp
@@ -31,45 +31,30 @@
#include "alu.h"
-struct ALdedicatedState final : public ALeffectState {
+struct ALdedicatedState final : public EffectState {
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS];
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS];
-};
-
-static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state);
-static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *device);
-static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALdedicatedState)
-
-DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState);
-static void ALdedicatedState_Construct(ALdedicatedState *state)
-{
- new (state) ALdedicatedState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALdedicatedState, ALeffectState, state);
-}
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALdedicatedState();
-}
+ DEF_NEWDEL(ALdedicatedState)
+};
-static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *UNUSED(device))
+ALboolean ALdedicatedState::deviceUpdate(ALCdevice *UNUSED(device))
{
- std::fill(std::begin(state->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
+ std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f);
return AL_TRUE;
}
-static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALdedicatedState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat Gain;
- std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
+ std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f);
Gain = slot->Params.Gain * props->Dedicated.Gain;
if(slot->Params.EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
@@ -77,9 +62,9 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext
int idx;
if((idx=GetChannelIdxByName(&device->RealOut, LFE)) != -1)
{
- state->OutBuffer = device->RealOut.Buffer;
- state->OutChannels = device->RealOut.NumChannels;
- state->mTargetGains[idx] = Gain;
+ mOutBuffer = device->RealOut.Buffer;
+ mOutChannels = device->RealOut.NumChannels;
+ mTargetGains[idx] = Gain;
}
}
else if(slot->Params.EffectType == AL_EFFECT_DEDICATED_DIALOGUE)
@@ -89,39 +74,35 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext
int idx{GetChannelIdxByName(&device->RealOut, FrontCenter)};
if(idx != -1)
{
- state->OutBuffer = device->RealOut.Buffer;
- state->OutChannels = device->RealOut.NumChannels;
- state->mTargetGains[idx] = Gain;
+ mOutBuffer = device->RealOut.Buffer;
+ mOutChannels = device->RealOut.NumChannels;
+ mTargetGains[idx] = Gain;
}
else
{
ALfloat coeffs[MAX_AMBI_COEFFS];
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
- state->OutBuffer = device->Dry.Buffer;
- state->OutChannels = device->Dry.NumChannels;
- ComputePanGains(&device->Dry, coeffs, Gain, state->mTargetGains);
+ mOutBuffer = device->Dry.Buffer;
+ mOutChannels = device->Dry.NumChannels;
+ ComputePanGains(&device->Dry, coeffs, Gain, mTargetGains);
}
}
}
-static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALdedicatedState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- MixSamples(SamplesIn[0], NumChannels, SamplesOut, state->mCurrentGains,
- state->mTargetGains, SamplesToDo, 0, SamplesToDo);
+ MixSamples(SamplesIn[0], NumChannels, SamplesOut, mCurrentGains,
+ mTargetGains, SamplesToDo, 0, SamplesToDo);
}
struct DedicatedStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *DedicatedStateFactory::create()
-{
- ALdedicatedState *state;
- NEW_OBJ0(state, ALdedicatedState)();
- return state;
-}
+EffectState *DedicatedStateFactory::create()
+{ return new ALdedicatedState{}; }
EffectStateFactory *DedicatedStateFactory_getFactory(void)
{
diff --git a/Alc/effects/distortion.cpp b/Alc/effects/distortion.cpp
index 48acfa56..a2681e3d 100644
--- a/Alc/effects/distortion.cpp
+++ b/Alc/effects/distortion.cpp
@@ -31,7 +31,7 @@
#include "filters/defs.h"
-struct ALdistortionState final : public ALeffectState {
+struct ALdistortionState final : public EffectState {
/* Effect gains for each channel */
ALfloat mGain[MAX_OUTPUT_CHANNELS]{};
@@ -41,39 +41,24 @@ struct ALdistortionState final : public ALeffectState {
ALfloat mAttenuation{};
ALfloat mEdgeCoeff{};
- ALfloat Buffer[2][BUFFERSIZE]{};
-};
-
-static ALvoid ALdistortionState_Destruct(ALdistortionState *state);
-static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *state, ALCdevice *device);
-static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALdistortionState)
-
-DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState);
+ ALfloat mBuffer[2][BUFFERSIZE]{};
-static void ALdistortionState_Construct(ALdistortionState *state)
-{
- new (state) ALdistortionState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALdistortionState, ALeffectState, state);
-}
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static ALvoid ALdistortionState_Destruct(ALdistortionState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALdistortionState();
-}
+ DEF_NEWDEL(ALdistortionState)
+};
-static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *state, ALCdevice *UNUSED(device))
+ALboolean ALdistortionState::deviceUpdate(ALCdevice *UNUSED(device))
{
- BiquadFilter_clear(&state->mLowpass);
- BiquadFilter_clear(&state->mBandpass);
+ BiquadFilter_clear(&mLowpass);
+ BiquadFilter_clear(&mBandpass);
return AL_TRUE;
}
-static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALdistortionState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat frequency = (ALfloat)device->Frequency;
@@ -85,7 +70,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->mEdgeCoeff = 2.0f * edge / (1.0f-edge);
+ mEdgeCoeff = 2.0f * edge / (1.0f-edge);
cutoff = props->Distortion.LowpassCutoff;
/* Bandwidth value is constant in octaves. */
@@ -93,25 +78,25 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontex
/* Multiply sampling frequency by the amount of oversampling done during
* processing.
*/
- BiquadFilter_setParams(&state->mLowpass, BiquadType::LowPass, 1.0f,
+ BiquadFilter_setParams(&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->mBandpass, BiquadType::BandPass, 1.0f,
+ BiquadFilter_setParams(&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->mGain);
+ ComputePanGains(&device->Dry, coeffs, slot->Params.Gain*props->Distortion.Gain, mGain);
}
-static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALdistortionState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- ALfloat (*RESTRICT buffer)[BUFFERSIZE] = state->Buffer;
- const ALfloat fc = state->mEdgeCoeff;
+ ALfloat (*RESTRICT buffer)[BUFFERSIZE] = mBuffer;
+ const ALfloat fc = mEdgeCoeff;
ALsizei base;
ALsizei i, k;
@@ -135,7 +120,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->mLowpass, buffer[1], buffer[0], todo);
+ BiquadFilter_process(&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 +139,7 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample
}
/* Third step, do bandpass filtering of distorted signal. */
- BiquadFilter_process(&state->mBandpass, buffer[1], buffer[0], todo);
+ BiquadFilter_process(&mBandpass, buffer[1], buffer[0], todo);
todo >>= 2;
for(k = 0;k < NumChannels;k++)
@@ -162,7 +147,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->mGain[k];
+ ALfloat gain = mGain[k];
if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
continue;
@@ -176,15 +161,11 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample
struct DistortionStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *DistortionStateFactory::create()
-{
- ALdistortionState *state;
- NEW_OBJ0(state, ALdistortionState)();
- return state;
-}
+EffectState *DistortionStateFactory::create()
+{ return new ALdistortionState{}; }
EffectStateFactory *DistortionStateFactory_getFactory(void)
{
diff --git a/Alc/effects/echo.cpp b/Alc/effects/echo.cpp
index a72b242c..58728b50 100644
--- a/Alc/effects/echo.cpp
+++ b/Alc/effects/echo.cpp
@@ -35,7 +35,7 @@
#include "vector.h"
-struct ALechoState final : public ALeffectState {
+struct ALechoState final : public EffectState {
al::vector<ALfloat,16> mSampleBuffer;
// The echo is two tap. The delay is the number of samples from before the
@@ -54,31 +54,16 @@ struct ALechoState final : public ALeffectState {
ALfloat mFeedGain{0.0f};
BiquadFilter mFilter;
-};
-
-static ALvoid ALechoState_Destruct(ALechoState *state);
-static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device);
-static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALechoState)
-
-DEFINE_ALEFFECTSTATE_VTABLE(ALechoState);
-static void ALechoState_Construct(ALechoState *state)
-{
- new (state) ALechoState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALechoState, ALeffectState, state);
-}
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static ALvoid ALechoState_Destruct(ALechoState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALechoState();
-}
+ DEF_NEWDEL(ALechoState)
+};
-static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device)
+ALboolean ALechoState::deviceUpdate(ALCdevice *Device)
{
ALuint maxlen;
@@ -89,14 +74,14 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device)
maxlen = NextPowerOf2(maxlen);
if(maxlen <= 0) return AL_FALSE;
- if(maxlen != state->mSampleBuffer.size())
+ if(maxlen != mSampleBuffer.size())
{
- state->mSampleBuffer.resize(maxlen);
- state->mSampleBuffer.shrink_to_fit();
+ mSampleBuffer.resize(maxlen);
+ mSampleBuffer.shrink_to_fit();
}
- std::fill(state->mSampleBuffer.begin(), state->mSampleBuffer.end(), 0.0f);
- for(auto &e : state->mGains)
+ std::fill(mSampleBuffer.begin(), mSampleBuffer.end(), 0.0f);
+ for(auto &e : 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);
@@ -105,16 +90,16 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device)
return AL_TRUE;
}
-static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALechoState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALuint frequency = device->Frequency;
ALfloat coeffs[MAX_AMBI_COEFFS];
ALfloat gainhf, lrpan, spread;
- 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;
+ mTap[0].delay = maxi(float2int(props->Echo.Delay*frequency + 0.5f), 1);
+ mTap[1].delay = float2int(props->Echo.LRDelay*frequency + 0.5f);
+ mTap[1].delay += mTap[0].delay;
spread = props->Echo.Spread;
if(spread < 0.0f) lrpan = -1.0f;
@@ -124,35 +109,35 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context,
*/
spread = asinf(1.0f - fabsf(spread))*4.0f;
- state->mFeedGain = props->Echo.Feedback;
+ mFeedGain = props->Echo.Feedback;
gainhf = maxf(1.0f - props->Echo.Damping, 0.0625f); /* Limit -24dB */
- BiquadFilter_setParams(&state->mFilter, BiquadType::HighShelf,
+ BiquadFilter_setParams(&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->mGains[0].Target);
+ ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, mGains[0].Target);
/* Second tap panning */
CalcAngleCoeffs( F_PI_2*lrpan, 0.0f, spread, coeffs);
- ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mGains[1].Target);
+ ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, mGains[1].Target);
}
-static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALechoState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- const ALsizei mask = state->mSampleBuffer.size()-1;
- const ALsizei tap1 = state->mTap[0].delay;
- const ALsizei tap2 = state->mTap[1].delay;
- ALfloat *RESTRICT delaybuf = state->mSampleBuffer.data();
- ALsizei offset = state->mOffset;
+ const ALsizei mask = mSampleBuffer.size()-1;
+ const ALsizei tap1 = mTap[0].delay;
+ const ALsizei tap2 = mTap[1].delay;
+ ALfloat *RESTRICT delaybuf = mSampleBuffer.data();
+ ALsizei offset = mOffset;
ALfloat z1, z2, in, out;
ALsizei base;
ALsizei c, i;
- z1 = state->mFilter.z1;
- z2 = state->mFilter.z2;
+ z1 = mFilter.z1;
+ z2 = mFilter.z2;
for(base = 0;base < SamplesToDo;)
{
alignas(16) ALfloat temps[2][128];
@@ -172,37 +157,33 @@ static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const
* feedback attenuation.
*/
in = temps[1][i];
- 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;
+ out = in*mFilter.b0 + z1;
+ z1 = in*mFilter.b1 - out*mFilter.a1 + z2;
+ z2 = in*mFilter.b2 - out*mFilter.a2;
- delaybuf[offset&mask] += out * state->mFeedGain;
+ delaybuf[offset&mask] += out * mFeedGain;
offset++;
}
for(c = 0;c < 2;c++)
- MixSamples(temps[c], NumChannels, SamplesOut, state->mGains[c].Current,
- state->mGains[c].Target, SamplesToDo-base, base, td);
+ MixSamples(temps[c], NumChannels, SamplesOut, mGains[c].Current,
+ mGains[c].Target, SamplesToDo-base, base, td);
base += td;
}
- state->mFilter.z1 = z1;
- state->mFilter.z2 = z2;
+ mFilter.z1 = z1;
+ mFilter.z2 = z2;
- state->mOffset = offset;
+ mOffset = offset;
}
struct EchoStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *EchoStateFactory::create()
-{
- ALechoState *state;
- NEW_OBJ0(state, ALechoState)();
- return state;
-}
+EffectState *EchoStateFactory::create()
+{ return new ALechoState{}; }
EffectStateFactory *EchoStateFactory_getFactory(void)
{
diff --git a/Alc/effects/equalizer.cpp b/Alc/effects/equalizer.cpp
index 814b43a4..6329ede2 100644
--- a/Alc/effects/equalizer.cpp
+++ b/Alc/effects/equalizer.cpp
@@ -76,7 +76,7 @@
* http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */
-struct ALequalizerState final : public ALeffectState {
+struct ALequalizerState final : public EffectState {
struct {
/* Effect parameters */
BiquadFilter filter[4];
@@ -87,33 +87,18 @@ struct ALequalizerState final : public ALeffectState {
} mChans[MAX_EFFECT_CHANNELS];
ALfloat mSampleBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]{};
-};
-
-static ALvoid ALequalizerState_Destruct(ALequalizerState *state);
-static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *state, ALCdevice *device);
-static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALequalizerState_process(ALequalizerState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALequalizerState)
-
-DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState);
-static void ALequalizerState_Construct(ALequalizerState *state)
-{
- new (state) ALequalizerState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALequalizerState, ALeffectState, state);
-}
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-static ALvoid ALequalizerState_Destruct(ALequalizerState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALequalizerState();
-}
+ DEF_NEWDEL(ALequalizerState)
+};
-static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *state, ALCdevice *UNUSED(device))
+ALboolean ALequalizerState::deviceUpdate(ALCdevice *UNUSED(device))
{
- for(auto &e : state->mChans)
+ for(auto &e : mChans)
{
std::for_each(std::begin(e.filter), std::end(e.filter),
[](BiquadFilter &f) -> void
@@ -124,7 +109,7 @@ static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *state, ALCdevic
return AL_TRUE;
}
-static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALequalizerState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat frequency = (ALfloat)device->Frequency;
@@ -137,78 +122,68 @@ 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->mChans[0].filter[0], BiquadType::LowShelf,
+ BiquadFilter_setParams(&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->mChans[0].filter[1], BiquadType::Peaking,
- gain, f0norm, calc_rcpQ_from_bandwidth(
- f0norm, props->Equalizer.Mid1Width
- )
+ BiquadFilter_setParams(&mChans[0].filter[1], BiquadType::Peaking,
+ gain, f0norm, calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid1Width)
);
gain = maxf(props->Equalizer.Mid2Gain, 0.0625f);
f0norm = props->Equalizer.Mid2Center/frequency;
- BiquadFilter_setParams(&state->mChans[0].filter[2], BiquadType::Peaking,
- gain, f0norm, calc_rcpQ_from_bandwidth(
- f0norm, props->Equalizer.Mid2Width
- )
+ BiquadFilter_setParams(&mChans[0].filter[2], BiquadType::Peaking,
+ gain, f0norm, calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid2Width)
);
gain = maxf(sqrtf(props->Equalizer.HighGain), 0.0625f);
f0norm = props->Equalizer.HighCutoff/frequency;
- BiquadFilter_setParams(&state->mChans[0].filter[3], BiquadType::HighShelf,
+ BiquadFilter_setParams(&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->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]);
+ BiquadFilter_copyParams(&mChans[i].filter[0], &mChans[0].filter[0]);
+ BiquadFilter_copyParams(&mChans[i].filter[1], &mChans[0].filter[1]);
+ BiquadFilter_copyParams(&mChans[i].filter[2], &mChans[0].filter[2]);
+ BiquadFilter_copyParams(&mChans[i].filter[3], &mChans[0].filter[3]);
}
- state->OutBuffer = device->FOAOut.Buffer;
- state->OutChannels = device->FOAOut.NumChannels;
+ mOutBuffer = device->FOAOut.Buffer;
+ mOutChannels = device->FOAOut.NumChannels;
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
- state->mChans[i].TargetGains);
+ mChans[i].TargetGains);
}
-static ALvoid ALequalizerState_process(ALequalizerState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALequalizerState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- ALfloat (*RESTRICT temps)[BUFFERSIZE] = state->mSampleBuffer;
+ ALfloat (*RESTRICT temps)[BUFFERSIZE] = mSampleBuffer;
ALsizei c;
for(c = 0;c < MAX_EFFECT_CHANNELS;c++)
{
- 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->mChans[c].CurrentGains, state->mChans[c].TargetGains,
- SamplesToDo, 0, SamplesToDo
- );
+ BiquadFilter_process(&mChans[c].filter[0], temps[0], SamplesIn[c], SamplesToDo);
+ BiquadFilter_process(&mChans[c].filter[1], temps[1], temps[0], SamplesToDo);
+ BiquadFilter_process(&mChans[c].filter[2], temps[2], temps[1], SamplesToDo);
+ BiquadFilter_process(&mChans[c].filter[3], temps[3], temps[2], SamplesToDo);
+
+ MixSamples(temps[3], NumChannels, SamplesOut, mChans[c].CurrentGains,
+ mChans[c].TargetGains, SamplesToDo, 0, SamplesToDo);
}
}
struct EqualizerStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *EqualizerStateFactory::create()
-{
- ALequalizerState *state;
- NEW_OBJ0(state, ALequalizerState)();
- return state;
-}
+EffectState *EqualizerStateFactory::create()
+{ return new ALequalizerState{}; }
EffectStateFactory *EqualizerStateFactory_getFactory(void)
{
diff --git a/Alc/effects/fshifter.cpp b/Alc/effects/fshifter.cpp
index b4d073da..38fb5492 100644
--- a/Alc/effects/fshifter.cpp
+++ b/Alc/effects/fshifter.cpp
@@ -60,7 +60,7 @@ std::array<ALdouble,HIL_SIZE> InitHannWindow(void)
alignas(16) const std::array<ALdouble,HIL_SIZE> HannWindow = InitHannWindow();
-struct ALfshifterState final : public ALeffectState {
+struct ALfshifterState final : public EffectState {
/* Effect parameters */
ALsizei mCount{};
ALsizei mPhaseStep{};
@@ -79,152 +79,134 @@ struct ALfshifterState final : public ALeffectState {
/* Effect gains for each output channel */
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS]{};
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS]{};
-};
-ALvoid ALfshifterState_Destruct(ALfshifterState *state);
-ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *device);
-ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALfshifterState)
-DEFINE_ALEFFECTSTATE_VTABLE(ALfshifterState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-void ALfshifterState_Construct(ALfshifterState *state)
-{
- new (state) ALfshifterState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALfshifterState, ALeffectState, state);
-}
-
-ALvoid ALfshifterState_Destruct(ALfshifterState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALfshifterState();
-}
+ DEF_NEWDEL(ALfshifterState)
+};
-ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *UNUSED(device))
+ALboolean ALfshifterState::deviceUpdate(ALCdevice *UNUSED(device))
{
/* (Re-)initializing parameters and clear the buffers. */
- state->mCount = FIFO_LATENCY;
- state->mPhaseStep = 0;
- state->mPhase = 0;
- state->mLdSign = 1.0;
+ mCount = FIFO_LATENCY;
+ mPhaseStep = 0;
+ mPhase = 0;
+ mLdSign = 1.0;
- 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(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(state->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
- std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
+ std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f);
+ std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f);
return AL_TRUE;
}
-ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALfshifterState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device{context->Device};
ALfloat step{props->Fshifter.Frequency / (ALfloat)device->Frequency};
- state->mPhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE);
+ mPhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE);
switch(props->Fshifter.LeftDirection)
{
case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN:
- state->mLdSign = -1.0;
+ mLdSign = -1.0;
break;
case AL_FREQUENCY_SHIFTER_DIRECTION_UP:
- state->mLdSign = 1.0;
+ mLdSign = 1.0;
break;
case AL_FREQUENCY_SHIFTER_DIRECTION_OFF:
- state->mPhase = 0;
- state->mPhaseStep = 0;
+ mPhase = 0;
+ mPhaseStep = 0;
break;
}
ALfloat coeffs[MAX_AMBI_COEFFS];
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
- ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mTargetGains);
+ ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, mTargetGains);
}
-ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALfshifterState::process(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->mBufferOut;
+ ALfloat *RESTRICT BufferOut = mBufferOut;
ALsizei j, k, base;
for(base = 0;base < SamplesToDo;)
{
- ALsizei todo = mini(HIL_SIZE-state->mCount, SamplesToDo-base);
+ ALsizei todo = mini(HIL_SIZE-mCount, SamplesToDo-base);
ASSUME(todo > 0);
/* Fill FIFO buffer with samples data */
- k = state->mCount;
+ k = mCount;
for(j = 0;j < todo;j++,k++)
{
- state->mInFIFO[k] = SamplesIn[0][base+j];
- state->mOutdata[base+j] = state->mOutFIFO[k-FIFO_LATENCY];
+ mInFIFO[k] = SamplesIn[0][base+j];
+ mOutdata[base+j] = mOutFIFO[k-FIFO_LATENCY];
}
- state->mCount += todo;
+ mCount += todo;
base += todo;
/* Check whether FIFO buffer is filled */
- if(state->mCount < HIL_SIZE) continue;
- state->mCount = FIFO_LATENCY;
+ if(mCount < HIL_SIZE) continue;
+ mCount = FIFO_LATENCY;
/* Real signal windowing and store in Analytic buffer */
for(k = 0;k < HIL_SIZE;k++)
{
- state->mAnalytic[k].real(state->mInFIFO[k] * HannWindow[k]);
- state->mAnalytic[k].imag(0.0);
+ mAnalytic[k].real(mInFIFO[k] * HannWindow[k]);
+ mAnalytic[k].imag(0.0);
}
/* Processing signal by Discrete Hilbert Transform (analytical signal). */
- complex_hilbert(state->mAnalytic, HIL_SIZE);
+ complex_hilbert(mAnalytic, HIL_SIZE);
/* Windowing and add to output accumulator */
for(k = 0;k < HIL_SIZE;k++)
- state->mOutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*state->mAnalytic[k];
+ mOutputAccum[k] += 2.0/OVERSAMP*HannWindow[k]*mAnalytic[k];
/* Shift accumulator, input & output FIFO */
- 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 < HIL_STEP;k++) mOutFIFO[k] = mOutputAccum[k];
+ for(j = 0;k < HIL_SIZE;k++,j++) mOutputAccum[j] = mOutputAccum[k];
+ for(;j < HIL_SIZE;j++) mOutputAccum[j] = complex_zero;
for(k = 0;k < FIFO_LATENCY;k++)
- state->mInFIFO[k] = state->mInFIFO[k+HIL_STEP];
+ mInFIFO[k] = mInFIFO[k+HIL_STEP];
}
/* Process frequency shifter using the analytic signal obtained. */
for(k = 0;k < SamplesToDo;k++)
{
- 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);
+ double phase = mPhase * ((1.0/FRACTIONONE) * 2.0*M_PI);
+ BufferOut[k] = (float)(mOutdata[k].real()*std::cos(phase) +
+ mOutdata[k].imag()*std::sin(phase)*mLdSign);
- state->mPhase += state->mPhaseStep;
- state->mPhase &= FRACTIONMASK;
+ mPhase += mPhaseStep;
+ mPhase &= FRACTIONMASK;
}
/* Now, mix the processed sound data to the output. */
- MixSamples(BufferOut, NumChannels, SamplesOut, state->mCurrentGains, state->mTargetGains,
+ MixSamples(BufferOut, NumChannels, SamplesOut, mCurrentGains, mTargetGains,
maxi(SamplesToDo, 512), 0, SamplesToDo);
}
} // namespace
struct FshifterStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *FshifterStateFactory::create()
-{
- ALfshifterState *state;
- NEW_OBJ0(state, ALfshifterState)();
- return state;
-}
+EffectState *FshifterStateFactory::create()
+{ return new ALfshifterState{}; }
EffectStateFactory *FshifterStateFactory_getFactory(void)
{
diff --git a/Alc/effects/modulator.cpp b/Alc/effects/modulator.cpp
index 0062a779..f714f94f 100644
--- a/Alc/effects/modulator.cpp
+++ b/Alc/effects/modulator.cpp
@@ -37,7 +37,7 @@
#define MAX_UPDATE_SAMPLES 128
-struct ALmodulatorState final : public ALeffectState {
+struct ALmodulatorState final : public EffectState {
void (*mGetSamples)(ALfloat*RESTRICT, ALsizei, const ALsizei, ALsizei){};
ALsizei mIndex{0};
@@ -49,15 +49,14 @@ struct ALmodulatorState final : public ALeffectState {
ALfloat CurrentGains[MAX_OUTPUT_CHANNELS]{};
ALfloat TargetGains[MAX_OUTPUT_CHANNELS]{};
} mChans[MAX_EFFECT_CHANNELS];
-};
-static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state);
-static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *state, ALCdevice *device);
-static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALmodulatorState)
-DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
+
+ DEF_NEWDEL(ALmodulatorState)
+};
#define WAVEFORM_FRACBITS 24
@@ -105,22 +104,9 @@ DECL_TEMPLATE(One)
#undef DECL_TEMPLATE
-static void ALmodulatorState_Construct(ALmodulatorState *state)
-{
- new (state) ALmodulatorState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALmodulatorState, ALeffectState, state);
-}
-
-static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state)
+ALboolean ALmodulatorState::deviceUpdate(ALCdevice *UNUSED(device))
{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALmodulatorState();
-}
-
-static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *state, ALCdevice *UNUSED(device))
-{
- for(auto &e : state->mChans)
+ for(auto &e : mChans)
{
BiquadFilter_clear(&e.Filter);
std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f);
@@ -128,43 +114,42 @@ static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *state, ALCdevic
return AL_TRUE;
}
-static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALmodulatorState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat f0norm;
ALsizei i;
- state->mStep = fastf2i(props->Modulator.Frequency / (ALfloat)device->Frequency *
- WAVEFORM_FRACONE);
- state->mStep = clampi(state->mStep, 0, WAVEFORM_FRACONE-1);
+ mStep = fastf2i(props->Modulator.Frequency / (ALfloat)device->Frequency * WAVEFORM_FRACONE);
+ mStep = clampi(mStep, 0, WAVEFORM_FRACONE-1);
- if(state->mStep == 0)
- state->mGetSamples = ModulateOne;
+ if(mStep == 0)
+ mGetSamples = ModulateOne;
else if(props->Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
- state->mGetSamples = ModulateSin;
+ mGetSamples = ModulateSin;
else if(props->Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
- state->mGetSamples = ModulateSaw;
+ mGetSamples = ModulateSaw;
else /*if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/
- state->mGetSamples = ModulateSquare;
+ 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->mChans[0].Filter, BiquadType::HighPass, 1.0f,
+ BiquadFilter_setParams(&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->mChans[i].Filter, &state->mChans[0].Filter);
+ BiquadFilter_copyParams(&mChans[i].Filter, &mChans[0].Filter);
- state->OutBuffer = device->FOAOut.Buffer;
- state->OutChannels = device->FOAOut.NumChannels;
+ mOutBuffer = device->FOAOut.Buffer;
+ mOutChannels = device->FOAOut.NumChannels;
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
- state->mChans[i].TargetGains);
+ mChans[i].TargetGains);
}
-static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALmodulatorState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- const ALsizei step = state->mStep;
+ const ALsizei step = mStep;
ALsizei base;
for(base = 0;base < SamplesToDo;)
@@ -173,20 +158,20 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesT
ALsizei td = mini(MAX_UPDATE_SAMPLES, SamplesToDo-base);
ALsizei c, i;
- state->mGetSamples(modsamples, state->mIndex, step, td);
- state->mIndex += (step*td) & WAVEFORM_FRACMASK;
- state->mIndex &= WAVEFORM_FRACMASK;
+ mGetSamples(modsamples, mIndex, step, td);
+ mIndex += (step*td) & WAVEFORM_FRACMASK;
+ mIndex &= WAVEFORM_FRACMASK;
for(c = 0;c < MAX_EFFECT_CHANNELS;c++)
{
alignas(16) ALfloat temps[MAX_UPDATE_SAMPLES];
- BiquadFilter_process(&state->mChans[c].Filter, temps, &SamplesIn[c][base], td);
+ BiquadFilter_process(&mChans[c].Filter, temps, &SamplesIn[c][base], td);
for(i = 0;i < td;i++)
temps[i] *= modsamples[i];
- MixSamples(temps, NumChannels, SamplesOut, state->mChans[c].CurrentGains,
- state->mChans[c].TargetGains, SamplesToDo-base, base, td);
+ MixSamples(temps, NumChannels, SamplesOut, mChans[c].CurrentGains,
+ mChans[c].TargetGains, SamplesToDo-base, base, td);
}
base += td;
@@ -195,15 +180,11 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesT
struct ModulatorStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *ModulatorStateFactory::create()
-{
- ALmodulatorState *state;
- NEW_OBJ0(state, ALmodulatorState)();
- return state;
-}
+EffectState *ModulatorStateFactory::create()
+{ return new ALmodulatorState{}; }
EffectStateFactory *ModulatorStateFactory_getFactory(void)
{
diff --git a/Alc/effects/null.cpp b/Alc/effects/null.cpp
index f5641e20..d28a6889 100644
--- a/Alc/effects/null.cpp
+++ b/Alc/effects/null.cpp
@@ -11,47 +11,36 @@
#include "alError.h"
-struct ALnullState final : public ALeffectState {
-};
-
-/* Forward-declare "virtual" functions to define the vtable with. */
-static ALvoid ALnullState_Destruct(ALnullState *state);
-static ALboolean ALnullState_deviceUpdate(ALnullState *state, ALCdevice *device);
-static ALvoid ALnullState_update(ALnullState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALnullState_process(ALnullState *state, ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei mumChannels);
-static void *ALnullState_New(size_t size);
-static void ALnullState_Delete(void *ptr);
+struct ALnullState final : public EffectState {
+ ALnullState();
+ ~ALnullState() override;
-/* Define the ALeffectState vtable for this type. */
-DEFINE_ALEFFECTSTATE_VTABLE(ALnullState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
+ DEF_NEWDEL(ALnullState)
+};
/* This constructs the effect state. It's called when the object is first
- * created. Make sure to call the parent Construct function first, and set the
- * vtable!
+ * created.
*/
-static void ALnullState_Construct(ALnullState *state)
+ALnullState::ALnullState()
{
- new (state) ALnullState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALnullState, ALeffectState, state);
}
-/* This destructs (not free!) the effect state. It's called only when the
- * effect slot is no longer used. Make sure to call the parent Destruct
- * function before returning!
+/* This destructs the effect state. It's called only when the effect slot is no
+ * longer used prior to being freed.
*/
-static ALvoid ALnullState_Destruct(ALnullState *state)
+ALnullState::~ALnullState()
{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALnullState();
}
/* This updates the device-dependant effect state. This is called on
* initialization and any time the device parameters (eg. playback frequency,
* format) have been changed.
*/
-static ALboolean ALnullState_deviceUpdate(ALnullState* UNUSED(state), ALCdevice* UNUSED(device))
+ALboolean ALnullState::deviceUpdate(ALCdevice* UNUSED(device))
{
return AL_TRUE;
}
@@ -59,7 +48,7 @@ static ALboolean ALnullState_deviceUpdate(ALnullState* UNUSED(state), ALCdevice*
/* This updates the effect state. This is called any time the effect is
* (re)loaded into a slot.
*/
-static ALvoid ALnullState_update(ALnullState* UNUSED(state), const ALCcontext* UNUSED(context), const ALeffectslot* UNUSED(slot), const ALeffectProps* UNUSED(props))
+void ALnullState::update(const ALCcontext* UNUSED(context), const ALeffectslot* UNUSED(slot), const ALeffectProps* UNUSED(props))
{
}
@@ -67,38 +56,18 @@ static ALvoid ALnullState_update(ALnullState* UNUSED(state), const ALCcontext* U
* input to the output buffer. The result should be added to the output buffer,
* not replace it.
*/
-static ALvoid ALnullState_process(ALnullState* UNUSED(state), ALsizei UNUSED(samplesToDo), const ALfloatBUFFERSIZE*RESTRICT UNUSED(samplesIn), ALfloatBUFFERSIZE*RESTRICT UNUSED(samplesOut), ALsizei UNUSED(numChannels))
+void ALnullState::process(ALsizei UNUSED(samplesToDo), const ALfloat (*RESTRICT UNUSED(samplesIn))[BUFFERSIZE], ALfloat (*RESTRICT UNUSED(samplesOut))[BUFFERSIZE], ALsizei UNUSED(numChannels))
{
}
-/* This allocates memory to store the object, before it gets constructed.
- * DECLARE_DEFAULT_ALLOCATORS can be used to declare a default method.
- */
-static void *ALnullState_New(size_t size)
-{
- return al_calloc(16, size);
-}
-
-/* This frees the memory used by the object, after it has been destructed.
- * DECLARE_DEFAULT_ALLOCATORS can be used to declare a default method.
- */
-static void ALnullState_Delete(void *ptr)
-{
- al_free(ptr);
-}
-
struct NullStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
/* Creates ALeffectState objects of the appropriate type. */
-ALeffectState *NullStateFactory::create()
-{
- ALnullState *state;
- NEW_OBJ0(state, ALnullState)();
- return state;
-}
+EffectState *NullStateFactory::create()
+{ return new ALnullState{}; }
EffectStateFactory *NullStateFactory_getFactory(void)
{
diff --git a/Alc/effects/pshifter.cpp b/Alc/effects/pshifter.cpp
index ec473678..3c375499 100644
--- a/Alc/effects/pshifter.cpp
+++ b/Alc/effects/pshifter.cpp
@@ -117,7 +117,7 @@ inline complex_d polar2rect(const ALphasor &number)
{ return std::polar<double>(number.Amplitude, number.Phase); }
-struct ALpshifterState final : public ALeffectState {
+struct ALpshifterState final : public EffectState {
/* Effect parameters */
ALsizei mCount;
ALsizei mPitchShiftI;
@@ -141,53 +141,39 @@ struct ALpshifterState final : public ALeffectState {
/* Effect gains for each output channel */
ALfloat mCurrentGains[MAX_OUTPUT_CHANNELS];
ALfloat mTargetGains[MAX_OUTPUT_CHANNELS];
-};
-static ALvoid ALpshifterState_Destruct(ALpshifterState *state);
-static ALboolean ALpshifterState_deviceUpdate(ALpshifterState *state, ALCdevice *device);
-static ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
-static ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ALpshifterState)
-DEFINE_ALEFFECTSTATE_VTABLE(ALpshifterState);
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
-void ALpshifterState_Construct(ALpshifterState *state)
-{
- new (state) ALpshifterState{};
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ALpshifterState, ALeffectState, state);
-}
-
-ALvoid ALpshifterState_Destruct(ALpshifterState *state)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
- state->~ALpshifterState();
-}
+ DEF_NEWDEL(ALpshifterState)
+};
-ALboolean ALpshifterState_deviceUpdate(ALpshifterState *state, ALCdevice *device)
+ALboolean ALpshifterState::deviceUpdate(ALCdevice *device)
{
/* (Re-)initializing parameters and clear the buffers. */
- state->mCount = FIFO_LATENCY;
- state->mPitchShiftI = FRACTIONONE;
- state->mPitchShift = 1.0f;
- state->mFreqPerBin = device->Frequency / (ALfloat)STFT_SIZE;
-
- 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->mCurrentGains), std::end(state->mCurrentGains), 0.0f);
- std::fill(std::begin(state->mTargetGains), std::end(state->mTargetGains), 0.0f);
+ mCount = FIFO_LATENCY;
+ mPitchShiftI = FRACTIONONE;
+ mPitchShift = 1.0f;
+ mFreqPerBin = device->Frequency / (ALfloat)STFT_SIZE;
+
+ std::fill(std::begin(mInFIFO), std::end(mInFIFO), 0.0f);
+ std::fill(std::begin(mOutFIFO), std::end(mOutFIFO), 0.0f);
+ std::fill(std::begin(mLastPhase), std::end(mLastPhase), 0.0);
+ std::fill(std::begin(mSumPhase), std::end(mSumPhase), 0.0);
+ std::fill(std::begin(mOutputAccum), std::end(mOutputAccum), 0.0);
+ std::fill(std::begin(mFFTbuffer), std::end(mFFTbuffer), complex_d{});
+ std::fill(std::begin(mAnalysis_buffer), std::end(mAnalysis_buffer), ALfrequencyDomain{});
+ std::fill(std::begin(mSyntesis_buffer), std::end(mSyntesis_buffer), ALfrequencyDomain{});
+
+ std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f);
+ std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f);
return AL_TRUE;
}
-ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+void ALpshifterState::update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
{
const ALCdevice *device = context->Device;
ALfloat coeffs[MAX_AMBI_COEFFS];
@@ -196,30 +182,30 @@ ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context,
pitch = std::pow(2.0f,
(ALfloat)(props->Pshifter.CoarseTune*100 + props->Pshifter.FineTune) / 1200.0f
);
- state->mPitchShiftI = fastf2i(pitch*FRACTIONONE);
- state->mPitchShift = state->mPitchShiftI * (1.0f/FRACTIONONE);
+ mPitchShiftI = fastf2i(pitch*FRACTIONONE);
+ mPitchShift = mPitchShiftI * (1.0f/FRACTIONONE);
CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
- ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, state->mTargetGains);
+ ComputePanGains(&device->Dry, coeffs, slot->Params.Gain, mTargetGains);
}
-ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ALpshifterState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
/* Pitch shifter engine based on the work of Stephan Bernsee.
* http://blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft/
*/
static constexpr ALdouble expected{M_PI*2.0 / OVERSAMP};
- const ALdouble freq_per_bin{state->mFreqPerBin};
- ALfloat *RESTRICT bufferOut{state->mBufferOut};
- ALsizei count{state->mCount};
+ const ALdouble freq_per_bin{mFreqPerBin};
+ ALfloat *RESTRICT bufferOut{mBufferOut};
+ ALsizei count{mCount};
for(ALsizei i{0};i < SamplesToDo;)
{
do {
/* Fill FIFO buffer with samples data */
- state->mInFIFO[count] = SamplesIn[0][i];
- bufferOut[i] = state->mOutFIFO[count - FIFO_LATENCY];
+ mInFIFO[count] = SamplesIn[0][i];
+ bufferOut[i] = mOutFIFO[count - FIFO_LATENCY];
count++;
} while(++i < SamplesToDo && count < STFT_SIZE);
@@ -231,13 +217,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->mFFTbuffer[k].real(state->mInFIFO[k] * HannWindow[k]);
- state->mFFTbuffer[k].imag(0.0);
+ mFFTbuffer[k].real(mInFIFO[k] * HannWindow[k]);
+ mFFTbuffer[k].imag(0.0);
}
/* ANALYSIS */
/* Apply FFT to FFTbuffer data */
- complex_fft(state->mFFTbuffer, STFT_SIZE, -1.0);
+ complex_fft(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 +231,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->mFFTbuffer[k])};
+ ALphasor component{rect2polar(mFFTbuffer[k])};
/* Compute phase difference and subtract expected phase difference */
- double tmp{(component.Phase - state->mLastPhase[k]) - k*expected};
+ double tmp{(component.Phase - mLastPhase[k]) - k*expected};
/* Map delta phase into +/- Pi interval */
int qpd{double2int(tmp / M_PI)};
@@ -261,29 +247,28 @@ 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->mAnalysis_buffer[k].Amplitude = 2.0 * component.Amplitude;
- state->mAnalysis_buffer[k].Frequency = (k + tmp) * freq_per_bin;
+ mAnalysis_buffer[k].Amplitude = 2.0 * component.Amplitude;
+ mAnalysis_buffer[k].Frequency = (k + tmp) * freq_per_bin;
/* Store actual phase[k] for the calculations in the next frame*/
- state->mLastPhase[k] = component.Phase;
+ mLastPhase[k] = component.Phase;
}
/* PROCESSING */
/* pitch shifting */
for(ALsizei k{0};k < STFT_HALF_SIZE+1;k++)
{
- state->mSyntesis_buffer[k].Amplitude = 0.0;
- state->mSyntesis_buffer[k].Frequency = 0.0;
+ mSyntesis_buffer[k].Amplitude = 0.0;
+ mSyntesis_buffer[k].Frequency = 0.0;
}
for(ALsizei k{0};k < STFT_HALF_SIZE+1;k++)
{
- ALsizei j{(k*state->mPitchShiftI) >> FRACTIONBITS};
+ ALsizei j{(k*mPitchShiftI) >> FRACTIONBITS};
if(j >= STFT_HALF_SIZE+1) break;
- state->mSyntesis_buffer[j].Amplitude += state->mAnalysis_buffer[k].Amplitude;
- state->mSyntesis_buffer[j].Frequency = state->mAnalysis_buffer[k].Frequency *
- state->mPitchShift;
+ mSyntesis_buffer[j].Amplitude += mAnalysis_buffer[k].Amplitude;
+ mSyntesis_buffer[j].Frequency = mAnalysis_buffer[k].Frequency * mPitchShift;
}
/* SYNTHESIS */
@@ -294,56 +279,52 @@ ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, cons
ALdouble tmp;
/* Compute bin deviation from scaled freq */
- tmp = state->mSyntesis_buffer[k].Frequency/freq_per_bin - k;
+ tmp = mSyntesis_buffer[k].Frequency/freq_per_bin - k;
/* Calculate actual delta phase and accumulate it to get bin phase */
- state->mSumPhase[k] += (k + tmp) * expected;
+ mSumPhase[k] += (k + tmp) * expected;
- component.Amplitude = state->mSyntesis_buffer[k].Amplitude;
- component.Phase = state->mSumPhase[k];
+ component.Amplitude = mSyntesis_buffer[k].Amplitude;
+ component.Phase = mSumPhase[k];
/* Compute phasor component to cartesian complex number and storage it into FFTbuffer*/
- state->mFFTbuffer[k] = polar2rect(component);
+ mFFTbuffer[k] = polar2rect(component);
}
/* zero negative frequencies for recontruct a real signal */
for(ALsizei k{STFT_HALF_SIZE+1};k < STFT_SIZE;k++)
- state->mFFTbuffer[k] = complex_d{};
+ mFFTbuffer[k] = complex_d{};
/* Apply iFFT to buffer data */
- complex_fft(state->mFFTbuffer, STFT_SIZE, 1.0);
+ complex_fft(mFFTbuffer, STFT_SIZE, 1.0);
/* Windowing and add to output */
for(ALsizei k{0};k < STFT_SIZE;k++)
- state->mOutputAccum[k] += HannWindow[k] * state->mFFTbuffer[k].real() /
- (0.5 * STFT_HALF_SIZE * OVERSAMP);
+ mOutputAccum[k] += HannWindow[k] * 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->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 < STFT_STEP;k++) mOutFIFO[k] = (ALfloat)mOutputAccum[k];
+ for(j = 0;k < STFT_SIZE;k++,j++) mOutputAccum[j] = mOutputAccum[k];
+ for(;j < STFT_SIZE;j++) mOutputAccum[j] = 0.0;
for(k = 0;k < FIFO_LATENCY;k++)
- state->mInFIFO[k] = state->mInFIFO[k+STFT_STEP];
+ mInFIFO[k] = mInFIFO[k+STFT_STEP];
}
- state->mCount = count;
+ mCount = count;
/* Now, mix the processed sound data to the output. */
- MixSamples(bufferOut, NumChannels, SamplesOut, state->mCurrentGains, state->mTargetGains,
+ MixSamples(bufferOut, NumChannels, SamplesOut, mCurrentGains, mTargetGains,
maxi(SamplesToDo, 512), 0, SamplesToDo);
}
} // namespace
struct PshifterStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *PshifterStateFactory::create()
-{
- ALpshifterState *state;
- NEW_OBJ0(state, ALpshifterState)();
- return state;
-}
+EffectState *PshifterStateFactory::create()
+{ return new ALpshifterState{}; }
EffectStateFactory *PshifterStateFactory_getFactory(void)
{
diff --git a/Alc/effects/reverb.cpp b/Alc/effects/reverb.cpp
index 229cd316..91d2d0d6 100644
--- a/Alc/effects/reverb.cpp
+++ b/Alc/effects/reverb.cpp
@@ -280,7 +280,7 @@ typedef struct LateReverb {
ALfloat PanGain[NUM_LINES][MAX_OUTPUT_CHANNELS];
} LateReverb;
-struct ReverbState final : public ALeffectState {
+struct ReverbState final : public EffectState {
/* All delay lines are allocated as a single buffer to reduce memory
* fragmentation and management code.
*/
@@ -332,116 +332,106 @@ struct ReverbState final : public ALeffectState {
/* Temporary storage used when processing. */
alignas(16) ALfloat mTempSamples[NUM_LINES][MAX_UPDATE_SAMPLES];
alignas(16) ALfloat mMixBuffer[NUM_LINES][MAX_UPDATE_SAMPLES];
-};
-static ALvoid ReverbState_Destruct(ReverbState *State);
-static ALboolean ReverbState_deviceUpdate(ReverbState *State, ALCdevice *Device);
-static ALvoid ReverbState_update(ReverbState *State, const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props);
-static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
-DECLARE_DEFAULT_ALLOCATORS(ReverbState)
-DEFINE_ALEFFECTSTATE_VTABLE(ReverbState);
+ ReverbState();
-static void ReverbState_Construct(ReverbState *state)
-{
- new (state) ReverbState{};
+ ALboolean deviceUpdate(ALCdevice *device) override;
+ void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) override;
+ void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) override;
- ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
- SET_VTABLE2(ReverbState, ALeffectState, state);
+ DEF_NEWDEL(ReverbState)
+};
- state->mParams.Density = AL_EAXREVERB_DEFAULT_DENSITY;
- state->mParams.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
- state->mParams.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
- state->mParams.HFDecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME*AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
- state->mParams.LFDecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME*AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
- state->mParams.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
- state->mParams.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
+ReverbState::ReverbState()
+{
+ mParams.Density = AL_EAXREVERB_DEFAULT_DENSITY;
+ mParams.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
+ mParams.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
+ mParams.HFDecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME*AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
+ mParams.LFDecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME*AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
+ mParams.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
+ mParams.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
for(ALsizei i{0};i < NUM_LINES;i++)
{
- BiquadFilter_clear(&state->mFilter[i].Lp);
- BiquadFilter_clear(&state->mFilter[i].Hp);
+ BiquadFilter_clear(&mFilter[i].Lp);
+ BiquadFilter_clear(&mFilter[i].Hp);
}
- state->mDelay.Mask = 0;
- state->mDelay.Line = NULL;
+ mDelay.Mask = 0;
+ mDelay.Line = NULL;
for(ALsizei i{0};i < NUM_LINES;i++)
{
- state->mEarlyDelayTap[i][0] = 0;
- state->mEarlyDelayTap[i][1] = 0;
- state->mEarlyDelayCoeff[i][0] = 0.0f;
- state->mEarlyDelayCoeff[i][1] = 0.0f;
+ mEarlyDelayTap[i][0] = 0;
+ mEarlyDelayTap[i][1] = 0;
+ mEarlyDelayCoeff[i][0] = 0.0f;
+ mEarlyDelayCoeff[i][1] = 0.0f;
}
- state->mLateFeedTap = 0;
+ mLateFeedTap = 0;
for(ALsizei i{0};i < NUM_LINES;i++)
{
- state->mLateDelayTap[i][0] = 0;
- state->mLateDelayTap[i][1] = 0;
+ mLateDelayTap[i][0] = 0;
+ mLateDelayTap[i][1] = 0;
}
- state->mMixX = 0.0f;
- state->mMixY = 0.0f;
+ mMixX = 0.0f;
+ mMixY = 0.0f;
- state->mEarly.VecAp.Delay.Mask = 0;
- state->mEarly.VecAp.Delay.Line = NULL;
- state->mEarly.VecAp.Coeff = 0.0f;
- state->mEarly.Delay.Mask = 0;
- state->mEarly.Delay.Line = NULL;
+ mEarly.VecAp.Delay.Mask = 0;
+ mEarly.VecAp.Delay.Line = NULL;
+ mEarly.VecAp.Coeff = 0.0f;
+ mEarly.Delay.Mask = 0;
+ mEarly.Delay.Line = NULL;
for(ALsizei i{0};i < NUM_LINES;i++)
{
- state->mEarly.VecAp.Offset[i][0] = 0;
- state->mEarly.VecAp.Offset[i][1] = 0;
- state->mEarly.Offset[i][0] = 0;
- state->mEarly.Offset[i][1] = 0;
- state->mEarly.Coeff[i][0] = 0.0f;
- state->mEarly.Coeff[i][1] = 0.0f;
+ mEarly.VecAp.Offset[i][0] = 0;
+ mEarly.VecAp.Offset[i][1] = 0;
+ mEarly.Offset[i][0] = 0;
+ mEarly.Offset[i][1] = 0;
+ mEarly.Coeff[i][0] = 0.0f;
+ mEarly.Coeff[i][1] = 0.0f;
}
- state->mLate.DensityGain[0] = 0.0f;
- state->mLate.DensityGain[1] = 0.0f;
- state->mLate.Delay.Mask = 0;
- state->mLate.Delay.Line = NULL;
- state->mLate.VecAp.Delay.Mask = 0;
- state->mLate.VecAp.Delay.Line = NULL;
- state->mLate.VecAp.Coeff = 0.0f;
+ mLate.DensityGain[0] = 0.0f;
+ mLate.DensityGain[1] = 0.0f;
+ mLate.Delay.Mask = 0;
+ mLate.Delay.Line = NULL;
+ mLate.VecAp.Delay.Mask = 0;
+ mLate.VecAp.Delay.Line = NULL;
+ mLate.VecAp.Coeff = 0.0f;
for(ALsizei i{0};i < NUM_LINES;i++)
{
- state->mLate.Offset[i][0] = 0;
- state->mLate.Offset[i][1] = 0;
+ mLate.Offset[i][0] = 0;
+ mLate.Offset[i][1] = 0;
- state->mLate.VecAp.Offset[i][0] = 0;
- state->mLate.VecAp.Offset[i][1] = 0;
+ mLate.VecAp.Offset[i][0] = 0;
+ mLate.VecAp.Offset[i][1] = 0;
- state->mLate.T60[i].MidGain[0] = 0.0f;
- state->mLate.T60[i].MidGain[1] = 0.0f;
- BiquadFilter_clear(&state->mLate.T60[i].HFFilter);
- BiquadFilter_clear(&state->mLate.T60[i].LFFilter);
+ mLate.T60[i].MidGain[0] = 0.0f;
+ mLate.T60[i].MidGain[1] = 0.0f;
+ BiquadFilter_clear(&mLate.T60[i].HFFilter);
+ BiquadFilter_clear(&mLate.T60[i].LFFilter);
}
for(ALsizei i{0};i < NUM_LINES;i++)
{
for(ALsizei j{0};j < MAX_OUTPUT_CHANNELS;j++)
{
- state->mEarly.CurrentGain[i][j] = 0.0f;
- state->mEarly.PanGain[i][j] = 0.0f;
- state->mLate.CurrentGain[i][j] = 0.0f;
- state->mLate.PanGain[i][j] = 0.0f;
+ mEarly.CurrentGain[i][j] = 0.0f;
+ mEarly.PanGain[i][j] = 0.0f;
+ mLate.CurrentGain[i][j] = 0.0f;
+ mLate.PanGain[i][j] = 0.0f;
}
}
- state->mFadeCount = 0;
- state->mMaxUpdate[0] = MAX_UPDATE_SAMPLES;
- state->mMaxUpdate[1] = MAX_UPDATE_SAMPLES;
- state->mOffset = 0;
-}
-
-static ALvoid ReverbState_Destruct(ReverbState *State)
-{
- ALeffectState_Destruct(STATIC_CAST(ALeffectState,State));
- State->~ReverbState();
+ mFadeCount = 0;
+ mMaxUpdate[0] = MAX_UPDATE_SAMPLES;
+ mMaxUpdate[1] = MAX_UPDATE_SAMPLES;
+ mOffset = 0;
}
/**************************************
@@ -555,70 +545,70 @@ static ALboolean AllocLines(const ALuint frequency, ReverbState *State)
return AL_TRUE;
}
-static ALboolean ReverbState_deviceUpdate(ReverbState *State, ALCdevice *Device)
+ALboolean ReverbState::deviceUpdate(ALCdevice *Device)
{
ALuint frequency = Device->Frequency;
ALfloat multiplier;
ALsizei i, j;
/* Allocate the delay lines. */
- if(!AllocLines(frequency, State))
+ if(!AllocLines(frequency, this))
return AL_FALSE;
multiplier = CalcDelayLengthMult(AL_EAXREVERB_MAX_DENSITY);
/* The late feed taps are set a fixed position past the latest delay tap. */
- State->mLateFeedTap = float2int((AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
- EARLY_TAP_LENGTHS[NUM_LINES-1]*multiplier) *
- frequency);
+ mLateFeedTap = float2int((AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
+ EARLY_TAP_LENGTHS[NUM_LINES-1]*multiplier) *
+ frequency);
/* Clear filters and gain coefficients since the delay lines were all just
* cleared (if not reallocated).
*/
for(i = 0;i < NUM_LINES;i++)
{
- BiquadFilter_clear(&State->mFilter[i].Lp);
- BiquadFilter_clear(&State->mFilter[i].Hp);
+ BiquadFilter_clear(&mFilter[i].Lp);
+ BiquadFilter_clear(&mFilter[i].Hp);
}
for(i = 0;i < NUM_LINES;i++)
{
- State->mEarlyDelayCoeff[i][0] = 0.0f;
- State->mEarlyDelayCoeff[i][1] = 0.0f;
+ mEarlyDelayCoeff[i][0] = 0.0f;
+ mEarlyDelayCoeff[i][1] = 0.0f;
}
for(i = 0;i < NUM_LINES;i++)
{
- State->mEarly.Coeff[i][0] = 0.0f;
- State->mEarly.Coeff[i][1] = 0.0f;
+ mEarly.Coeff[i][0] = 0.0f;
+ mEarly.Coeff[i][1] = 0.0f;
}
- State->mLate.DensityGain[0] = 0.0f;
- State->mLate.DensityGain[1] = 0.0f;
+ mLate.DensityGain[0] = 0.0f;
+ mLate.DensityGain[1] = 0.0f;
for(i = 0;i < NUM_LINES;i++)
{
- State->mLate.T60[i].MidGain[0] = 0.0f;
- State->mLate.T60[i].MidGain[1] = 0.0f;
- BiquadFilter_clear(&State->mLate.T60[i].HFFilter);
- BiquadFilter_clear(&State->mLate.T60[i].LFFilter);
+ mLate.T60[i].MidGain[0] = 0.0f;
+ mLate.T60[i].MidGain[1] = 0.0f;
+ BiquadFilter_clear(&mLate.T60[i].HFFilter);
+ BiquadFilter_clear(&mLate.T60[i].LFFilter);
}
for(i = 0;i < NUM_LINES;i++)
{
for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
{
- State->mEarly.CurrentGain[i][j] = 0.0f;
- State->mEarly.PanGain[i][j] = 0.0f;
- State->mLate.CurrentGain[i][j] = 0.0f;
- State->mLate.PanGain[i][j] = 0.0f;
+ mEarly.CurrentGain[i][j] = 0.0f;
+ mEarly.PanGain[i][j] = 0.0f;
+ mLate.CurrentGain[i][j] = 0.0f;
+ mLate.PanGain[i][j] = 0.0f;
}
}
/* Reset counters and offset base. */
- State->mFadeCount = 0;
- State->mMaxUpdate[0] = MAX_UPDATE_SAMPLES;
- State->mMaxUpdate[1] = MAX_UPDATE_SAMPLES;
- State->mOffset = 0;
+ mFadeCount = 0;
+ mMaxUpdate[0] = MAX_UPDATE_SAMPLES;
+ mMaxUpdate[1] = MAX_UPDATE_SAMPLES;
+ mOffset = 0;
return AL_TRUE;
}
@@ -902,8 +892,8 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
aluMatrixf transform, rot;
ALsizei i;
- STATIC_CAST(ALeffectState,State)->OutBuffer = Device->FOAOut.Buffer;
- STATIC_CAST(ALeffectState,State)->OutChannels = Device->FOAOut.NumChannels;
+ State->mOutBuffer = Device->FOAOut.Buffer;
+ State->mOutChannels = Device->FOAOut.NumChannels;
/* Note: _res is transposed. */
#define MATRIX_MULT(_res, _m1, _m2) do { \
@@ -934,7 +924,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
#undef MATRIX_MULT
}
-static void ReverbState_update(ReverbState *State, const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props)
+void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props)
{
const ALCdevice *Device = Context->Device;
const ALlistener &Listener = Context->Listener;
@@ -950,29 +940,29 @@ static void ReverbState_update(ReverbState *State, const ALCcontext *Context, co
* killing most of the signal.
*/
gainhf = maxf(props->Reverb.GainHF, 0.001f);
- BiquadFilter_setParams(&State->mFilter[0].Lp, BiquadType::HighShelf, gainhf, hf0norm,
+ BiquadFilter_setParams(&mFilter[0].Lp, BiquadType::HighShelf, gainhf, hf0norm,
calc_rcpQ_from_slope(gainhf, 1.0f));
lf0norm = minf(props->Reverb.LFReference / frequency, 0.49f);
gainlf = maxf(props->Reverb.GainLF, 0.001f);
- BiquadFilter_setParams(&State->mFilter[0].Hp, BiquadType::LowShelf, gainlf, lf0norm,
+ BiquadFilter_setParams(&mFilter[0].Hp, BiquadType::LowShelf, gainlf, lf0norm,
calc_rcpQ_from_slope(gainlf, 1.0f));
for(i = 1;i < NUM_LINES;i++)
{
- BiquadFilter_copyParams(&State->mFilter[i].Lp, &State->mFilter[0].Lp);
- BiquadFilter_copyParams(&State->mFilter[i].Hp, &State->mFilter[0].Hp);
+ BiquadFilter_copyParams(&mFilter[i].Lp, &mFilter[0].Lp);
+ BiquadFilter_copyParams(&mFilter[i].Hp, &mFilter[0].Hp);
}
/* Update the main effect delay and associated taps. */
UpdateDelayLine(props->Reverb.ReflectionsDelay, props->Reverb.LateReverbDelay,
props->Reverb.Density, props->Reverb.DecayTime, frequency,
- State);
+ this);
/* Update the early lines. */
UpdateEarlyLines(props->Reverb.Density, props->Reverb.Diffusion,
- props->Reverb.DecayTime, frequency, &State->mEarly);
+ props->Reverb.DecayTime, frequency, &mEarly);
/* Get the mixing matrix coefficients. */
- CalcMatrixCoeffs(props->Reverb.Diffusion, &State->mMixX, &State->mMixY);
+ CalcMatrixCoeffs(props->Reverb.Diffusion, &mMixX, &mMixY);
/* If the HF limit parameter is flagged, calculate an appropriate limit
* based on the air absorption parameter.
@@ -992,45 +982,43 @@ static void ReverbState_update(ReverbState *State, const ALCcontext *Context, co
/* Update the late lines. */
UpdateLateLines(props->Reverb.Density, props->Reverb.Diffusion,
lfDecayTime, props->Reverb.DecayTime, hfDecayTime, lf0norm, hf0norm,
- frequency, &State->mLate
+ frequency, &mLate
);
/* Update early and late 3D panning. */
gain = props->Reverb.Gain * Slot->Params.Gain * ReverbBoost;
Update3DPanning(Device, props->Reverb.ReflectionsPan, props->Reverb.LateReverbPan,
props->Reverb.ReflectionsGain*gain, props->Reverb.LateReverbGain*gain,
- State);
+ this);
/* Calculate the max update size from the smallest relevant delay. */
- State->mMaxUpdate[1] = mini(MAX_UPDATE_SAMPLES,
- mini(State->mEarly.Offset[0][1], State->mLate.Offset[0][1])
- );
+ mMaxUpdate[1] = mini(MAX_UPDATE_SAMPLES, mini(mEarly.Offset[0][1], mLate.Offset[0][1]));
/* Determine if delay-line cross-fading is required. Density is essentially
* a master control for the feedback delays, so changes the offsets of many
* delay lines.
*/
- if(State->mParams.Density != props->Reverb.Density ||
+ if(mParams.Density != props->Reverb.Density ||
/* Diffusion and decay times influences the decay rate (gain) of the
* late reverb T60 filter.
*/
- State->mParams.Diffusion != props->Reverb.Diffusion ||
- State->mParams.DecayTime != props->Reverb.DecayTime ||
- State->mParams.HFDecayTime != hfDecayTime ||
- State->mParams.LFDecayTime != lfDecayTime ||
+ mParams.Diffusion != props->Reverb.Diffusion ||
+ mParams.DecayTime != props->Reverb.DecayTime ||
+ mParams.HFDecayTime != hfDecayTime ||
+ mParams.LFDecayTime != lfDecayTime ||
/* HF/LF References control the weighting used to calculate the density
* gain.
*/
- State->mParams.HFReference != props->Reverb.HFReference ||
- State->mParams.LFReference != props->Reverb.LFReference)
- State->mFadeCount = 0;
- State->mParams.Density = props->Reverb.Density;
- State->mParams.Diffusion = props->Reverb.Diffusion;
- State->mParams.DecayTime = props->Reverb.DecayTime;
- State->mParams.HFDecayTime = hfDecayTime;
- State->mParams.LFDecayTime = lfDecayTime;
- State->mParams.HFReference = props->Reverb.HFReference;
- State->mParams.LFReference = props->Reverb.LFReference;
+ mParams.HFReference != props->Reverb.HFReference ||
+ mParams.LFReference != props->Reverb.LFReference)
+ mFadeCount = 0;
+ mParams.Density = props->Reverb.Density;
+ mParams.Diffusion = props->Reverb.Diffusion;
+ mParams.DecayTime = props->Reverb.DecayTime;
+ mParams.HFDecayTime = hfDecayTime;
+ mParams.LFDecayTime = lfDecayTime;
+ mParams.HFReference = props->Reverb.HFReference;
+ mParams.LFReference = props->Reverb.LFReference;
}
@@ -1454,12 +1442,12 @@ static void LateReverb_Faded(ReverbState *State, ALsizei offset, const ALsizei t
VectorScatterRevDelayIn(&late_delay, offset, mixX, mixY, temps, todo);
}
-static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+void ReverbState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- ALfloat (*RESTRICT afmt)[MAX_UPDATE_SAMPLES] = State->mTempSamples;
- ALfloat (*RESTRICT samples)[MAX_UPDATE_SAMPLES] = State->mMixBuffer;
- ALsizei fadeCount = State->mFadeCount;
- ALsizei offset = State->mOffset;
+ ALfloat (*RESTRICT afmt)[MAX_UPDATE_SAMPLES] = mTempSamples;
+ ALfloat (*RESTRICT samples)[MAX_UPDATE_SAMPLES] = mMixBuffer;
+ ALsizei fadeCount = mFadeCount;
+ ALsizei offset = mOffset;
ALsizei base, c;
/* Process reverb for these samples. */
@@ -1470,9 +1458,9 @@ static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const
if(FADE_SAMPLES-fadeCount > 0)
{
todo = mini(todo, FADE_SAMPLES-fadeCount);
- todo = mini(todo, State->mMaxUpdate[0]);
+ todo = mini(todo, mMaxUpdate[0]);
}
- todo = mini(todo, State->mMaxUpdate[1]);
+ todo = mini(todo, mMaxUpdate[1]);
/* If this is not the final update, ensure the update size is a
* multiple of 4 for the SIMD mixers.
*/
@@ -1490,11 +1478,11 @@ static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const
for(c = 0;c < NUM_LINES;c++)
{
/* Band-pass the incoming samples. */
- BiquadFilter_process(&State->mFilter[c].Lp, samples[0], afmt[c], todo);
- BiquadFilter_process(&State->mFilter[c].Hp, samples[1], samples[0], todo);
+ BiquadFilter_process(&mFilter[c].Lp, samples[0], afmt[c], todo);
+ BiquadFilter_process(&mFilter[c].Hp, samples[1], samples[0], todo);
/* Feed the initial delay line. */
- DelayLineIn(&State->mDelay, offset, c, samples[1], todo);
+ DelayLineIn(&mDelay, offset, c, samples[1], todo);
}
if(UNLIKELY(fadeCount < FADE_SAMPLES))
@@ -1502,21 +1490,21 @@ static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const
ALfloat fade = (ALfloat)fadeCount;
/* Generate early reflections. */
- EarlyReflection_Faded(State, offset, todo, fade, samples);
+ EarlyReflection_Faded(this, offset, todo, fade, samples);
/* Mix the A-Format results to output, implicitly converting back
* to B-Format.
*/
for(c = 0;c < NUM_LINES;c++)
MixSamples(samples[c], NumChannels, SamplesOut,
- State->mEarly.CurrentGain[c], State->mEarly.PanGain[c],
+ mEarly.CurrentGain[c], mEarly.PanGain[c],
SamplesToDo-base, base, todo
);
/* Generate and mix late reverb. */
- LateReverb_Faded(State, offset, todo, fade, samples);
+ LateReverb_Faded(this, offset, todo, fade, samples);
for(c = 0;c < NUM_LINES;c++)
MixSamples(samples[c], NumChannels, SamplesOut,
- State->mLate.CurrentGain[c], State->mLate.PanGain[c],
+ mLate.CurrentGain[c], mLate.PanGain[c],
SamplesToDo-base, base, todo
);
@@ -1528,35 +1516,35 @@ static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const
fadeCount = FADE_SAMPLES;
for(c = 0;c < NUM_LINES;c++)
{
- State->mEarlyDelayTap[c][0] = State->mEarlyDelayTap[c][1];
- State->mEarlyDelayCoeff[c][0] = State->mEarlyDelayCoeff[c][1];
- State->mEarly.VecAp.Offset[c][0] = State->mEarly.VecAp.Offset[c][1];
- State->mEarly.Offset[c][0] = State->mEarly.Offset[c][1];
- State->mEarly.Coeff[c][0] = State->mEarly.Coeff[c][1];
- State->mLateDelayTap[c][0] = State->mLateDelayTap[c][1];
- State->mLate.VecAp.Offset[c][0] = State->mLate.VecAp.Offset[c][1];
- State->mLate.Offset[c][0] = State->mLate.Offset[c][1];
- State->mLate.T60[c].MidGain[0] = State->mLate.T60[c].MidGain[1];
+ mEarlyDelayTap[c][0] = mEarlyDelayTap[c][1];
+ mEarlyDelayCoeff[c][0] = mEarlyDelayCoeff[c][1];
+ mEarly.VecAp.Offset[c][0] = mEarly.VecAp.Offset[c][1];
+ mEarly.Offset[c][0] = mEarly.Offset[c][1];
+ mEarly.Coeff[c][0] = mEarly.Coeff[c][1];
+ mLateDelayTap[c][0] = mLateDelayTap[c][1];
+ mLate.VecAp.Offset[c][0] = mLate.VecAp.Offset[c][1];
+ mLate.Offset[c][0] = mLate.Offset[c][1];
+ mLate.T60[c].MidGain[0] = mLate.T60[c].MidGain[1];
}
- State->mLate.DensityGain[0] = State->mLate.DensityGain[1];
- State->mMaxUpdate[0] = State->mMaxUpdate[1];
+ mLate.DensityGain[0] = mLate.DensityGain[1];
+ mMaxUpdate[0] = mMaxUpdate[1];
}
}
else
{
/* Generate and mix early reflections. */
- EarlyReflection_Unfaded(State, offset, todo, samples);
+ EarlyReflection_Unfaded(this, offset, todo, samples);
for(c = 0;c < NUM_LINES;c++)
MixSamples(samples[c], NumChannels, SamplesOut,
- State->mEarly.CurrentGain[c], State->mEarly.PanGain[c],
+ mEarly.CurrentGain[c], mEarly.PanGain[c],
SamplesToDo-base, base, todo
);
/* Generate and mix late reverb. */
- LateReverb_Unfaded(State, offset, todo, samples);
+ LateReverb_Unfaded(this, offset, todo, samples);
for(c = 0;c < NUM_LINES;c++)
MixSamples(samples[c], NumChannels, SamplesOut,
- State->mLate.CurrentGain[c], State->mLate.PanGain[c],
+ mLate.CurrentGain[c], mLate.PanGain[c],
SamplesToDo-base, base, todo
);
}
@@ -1566,21 +1554,17 @@ static ALvoid ReverbState_process(ReverbState *State, ALsizei SamplesToDo, const
base += todo;
}
- State->mOffset = offset;
- State->mFadeCount = fadeCount;
+ mOffset = offset;
+ mFadeCount = fadeCount;
}
struct ReverbStateFactory final : public EffectStateFactory {
- ALeffectState *create() override;
+ EffectState *create() override;
};
-ALeffectState *ReverbStateFactory::create()
-{
- ReverbState *state;
- NEW_OBJ0(state, ReverbState)();
- return state;
-}
+EffectState *ReverbStateFactory::create()
+{ return new ReverbState{}; }
EffectStateFactory *ReverbStateFactory_getFactory(void)
{