diff options
-rw-r--r-- | Alc/alc.cpp | 18 | ||||
-rw-r--r-- | Alc/alu.cpp | 18 | ||||
-rw-r--r-- | Alc/effects/autowah.cpp | 116 | ||||
-rw-r--r-- | Alc/effects/chorus.cpp | 135 | ||||
-rw-r--r-- | Alc/effects/compressor.cpp | 75 | ||||
-rw-r--r-- | Alc/effects/dedicated.cpp | 69 | ||||
-rw-r--r-- | Alc/effects/distortion.cpp | 67 | ||||
-rw-r--r-- | Alc/effects/echo.cpp | 99 | ||||
-rw-r--r-- | Alc/effects/equalizer.cpp | 93 | ||||
-rw-r--r-- | Alc/effects/fshifter.cpp | 118 | ||||
-rw-r--r-- | Alc/effects/modulator.cpp | 85 | ||||
-rw-r--r-- | Alc/effects/null.cpp | 69 | ||||
-rw-r--r-- | Alc/effects/pshifter.cpp | 147 | ||||
-rw-r--r-- | Alc/effects/reverb.cpp | 316 | ||||
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 59 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 3 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.cpp | 59 | ||||
-rw-r--r-- | OpenAL32/event.cpp | 2 |
18 files changed, 626 insertions, 922 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) { diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index d3d4e704..ca2cb663 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -8,58 +8,31 @@ #include "atomic.h" -struct ALeffectStateVtable; struct ALeffectslot; -typedef struct ALeffectState { - RefCount Ref; - const struct ALeffectStateVtable *vtbl; - ALfloat (*OutBuffer)[BUFFERSIZE]; - ALsizei OutChannels; -} ALeffectState; +struct EffectState { + RefCount mRef{1u}; -void ALeffectState_Construct(ALeffectState *state); -void ALeffectState_Destruct(ALeffectState *state); + ALfloat (*mOutBuffer)[BUFFERSIZE]{nullptr}; + ALsizei mOutChannels{0}; -struct ALeffectStateVtable { - void (*const Destruct)(ALeffectState *state); - ALboolean (*const deviceUpdate)(ALeffectState *state, ALCdevice *device); - void (*const update)(ALeffectState *state, const ALCcontext *context, const struct ALeffectslot *slot, const union ALeffectProps *props); - void (*const process)(ALeffectState *state, ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels); + virtual ~EffectState() = default; - void (*const Delete)(void *ptr); -}; + virtual ALboolean deviceUpdate(ALCdevice *device) = 0; + virtual void update(const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) = 0; + virtual void process(ALsizei samplesToDo, const ALfloat (*RESTRICT samplesIn)[BUFFERSIZE], ALfloat (*RESTRICT samplesOut)[BUFFERSIZE], ALsizei numChannels) = 0; -/* Small hack to use a pointer-to-array types as a normal argument type. - * Shouldn't be used directly. - */ -typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE]; - -#define DEFINE_ALEFFECTSTATE_VTABLE(T) \ -DECLARE_THUNK(T, ALeffectState, void, Destruct) \ -DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \ -DECLARE_THUNK3(T, ALeffectState, void, update, const ALCcontext*, const ALeffectslot*, const ALeffectProps*) \ -DECLARE_THUNK4(T, ALeffectState, void, process, ALsizei, const ALfloatBUFFERSIZE*RESTRICT, ALfloatBUFFERSIZE*RESTRICT, ALsizei) \ -static void T##_ALeffectState_Delete(void *ptr) \ -{ return T##_Delete(STATIC_UPCAST(T, ALeffectState, (ALeffectState*)ptr)); } \ - \ -static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ - T##_ALeffectState_Destruct, \ - \ - T##_ALeffectState_deviceUpdate, \ - T##_ALeffectState_update, \ - T##_ALeffectState_process, \ - \ - T##_ALeffectState_Delete, \ -} + void IncRef() noexcept; + void DecRef() noexcept; +}; struct EffectStateFactory { virtual ~EffectStateFactory() { } - virtual ALeffectState *create() = 0; + virtual EffectState *create() = 0; }; @@ -79,7 +52,7 @@ struct ALeffectslotProps { ALenum Type; ALeffectProps Props; - ALeffectState *State; + EffectState *State; ATOMIC(struct ALeffectslotProps*) next; }; @@ -93,7 +66,7 @@ struct ALeffectslot { ALenum Type{AL_EFFECT_NULL}; ALeffectProps Props{}; - ALeffectState *State{nullptr}; + EffectState *State{nullptr}; } Effect; ATOMIC(ALenum) PropsClean{AL_TRUE}; @@ -108,7 +81,7 @@ struct ALeffectslot { ALenum EffectType{AL_EFFECT_NULL}; ALeffectProps EffectProps{}; - ALeffectState *EffectState{nullptr}; + EffectState *EffectState{nullptr}; ALfloat RoomRolloff{0.0f}; /* Added to the source's room rolloff, not multiplied. */ ALfloat DecayTime{0.0f}; @@ -167,6 +140,4 @@ EffectStateFactory *DedicatedStateFactory_getFactory(void); ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); -void ALeffectState_DecRef(ALeffectState *state); - #endif diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 64297592..8f08d94a 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -206,6 +206,7 @@ struct ALCbackend; struct ALbuffer; struct ALeffect; struct ALfilter; +struct EffectState; #define DEFAULT_OUTPUT_RATE (44100) @@ -755,7 +756,7 @@ typedef struct AsyncEvent { ALuint param; ALchar msg[1008]; } user; - struct ALeffectState *EffectState; + EffectState *mEffectState; } u; } AsyncEvent; #define ASYNC_EVENT(t) { t, { 0 } } diff --git a/OpenAL32/alAuxEffectSlot.cpp b/OpenAL32/alAuxEffectSlot.cpp index 4e25d3ee..cab9e43d 100644 --- a/OpenAL32/alAuxEffectSlot.cpp +++ b/OpenAL32/alAuxEffectSlot.cpp @@ -74,8 +74,6 @@ static inline EffectStateFactory *getFactoryByType(ALenum type) return nullptr; } -static void ALeffectState_IncRef(ALeffectState *state); - static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) { @@ -483,7 +481,7 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect ALCdevice *Device = Context->Device; ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); struct ALeffectslotProps *props; - ALeffectState *State; + EffectState *State; if(newtype != EffectSlot->Effect.Type) { @@ -498,13 +496,13 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect START_MIXER_MODE(); almtx_lock(&Device->BackendLock); - 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) { almtx_unlock(&Device->BackendLock); LEAVE_MIXER_MODE(); - ALeffectState_DecRef(State); + State->DecRef(); return AL_OUT_OF_MEMORY; } almtx_unlock(&Device->BackendLock); @@ -521,7 +519,7 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect EffectSlot->Effect.Props = effect->Props; } - ALeffectState_DecRef(EffectSlot->Effect.State); + EffectSlot->Effect.State->DecRef(); EffectSlot->Effect.State = State; } else if(effect) @@ -532,7 +530,7 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect while(props) { if(props->State) - ALeffectState_DecRef(props->State); + props->State->DecRef(); props->State = nullptr; props = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } @@ -541,30 +539,17 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect } -static void ALeffectState_IncRef(ALeffectState *state) +void EffectState::IncRef() noexcept { - auto ref = IncrementRef(&state->Ref); - TRACEREF("%p increasing refcount to %u\n", state, ref); -} - -void ALeffectState_DecRef(ALeffectState *state) -{ - auto ref = DecrementRef(&state->Ref); - TRACEREF("%p decreasing refcount to %u\n", state, ref); - if(ref == 0) DELETE_OBJ(state); -} - - -void ALeffectState_Construct(ALeffectState *state) -{ - InitRef(&state->Ref, 1); - - state->OutBuffer = nullptr; - state->OutChannels = 0; + auto ref = IncrementRef(&mRef); + TRACEREF("%p increasing refcount to %u\n", this, ref); } -void ALeffectState_Destruct(ALeffectState *UNUSED(state)) +void EffectState::DecRef() noexcept { + auto ref = DecrementRef(&mRef); + TRACEREF("%p decreasing refcount to %u\n", this, ref); + if(ref == 0) delete this; } @@ -664,7 +649,7 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Effect.State = factory->create(); if(!slot->Effect.State) return AL_OUT_OF_MEMORY; - ALeffectState_IncRef(slot->Effect.State); + slot->Effect.State->IncRef(); slot->Params.EffectState = slot->Effect.State; return AL_NO_ERROR; } @@ -674,21 +659,21 @@ ALeffectslot::~ALeffectslot() struct ALeffectslotProps *props{Update.load()}; if(props) { - if(props->State) ALeffectState_DecRef(props->State); + if(props->State) props->State->DecRef(); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } if(Effect.State) - ALeffectState_DecRef(Effect.State); + Effect.State->DecRef(); if(Params.EffectState) - ALeffectState_DecRef(Params.EffectState); + Params.EffectState->DecRef(); } void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context) { struct ALeffectslotProps *props; - ALeffectState *oldstate; + EffectState *oldstate; /* Get an unused property container, or allocate a new one as needed. */ props = context->FreeEffectslotProps.load(std::memory_order_relaxed); @@ -712,7 +697,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - ALeffectState_IncRef(slot->Effect.State); + slot->Effect.State->IncRef(); oldstate = props->State; props->State = slot->Effect.State; @@ -724,13 +709,13 @@ void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context) * freelist. */ if(props->State) - ALeffectState_DecRef(props->State); + props->State->DecRef(); props->State = nullptr; AtomicReplaceHead(context->FreeEffectslotProps, props); } if(oldstate) - ALeffectState_DecRef(oldstate); + oldstate->DecRef(); } void UpdateAllEffectSlotProps(ALCcontext *context) diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp index 1dc2745f..d6fa01fb 100644 --- a/OpenAL32/event.cpp +++ b/OpenAL32/event.cpp @@ -34,7 +34,7 @@ static int EventThread(ALCcontext *context) if(evt.EnumType == EventType_ReleaseEffectState) { - ALeffectState_DecRef(evt.u.EffectState); + evt.u.mEffectState->DecRef(); continue; } |