aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/effects/echo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/effects/echo.cpp')
-rw-r--r--Alc/effects/echo.cpp99
1 files changed, 40 insertions, 59 deletions
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)
{