From 35a2b0e5f8fb3b981cc72c5f19c414d8978c3534 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 9 Apr 2020 20:57:12 -0700 Subject: Simplify generating chorus delays a bit --- alc/effects/chorus.cpp | 122 +++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 55 deletions(-) (limited to 'alc/effects/chorus.cpp') diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index c425ccc9..9a81ffe9 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -54,37 +54,7 @@ enum class WaveForm { Triangle }; -void GetTriangleDelays(ALuint *delays, const ALuint start_offset, const ALuint lfo_range, - const float lfo_scale, const float depth, const ALsizei delay, const size_t todo) -{ - ASSUME(lfo_range > 0); - ASSUME(todo > 0); - - ALuint offset{start_offset}; - auto gen_lfo = [&offset,lfo_range,lfo_scale,depth,delay]() -> ALuint - { - offset = (offset+1)%lfo_range; - const float offset_norm{static_cast(offset) * lfo_scale}; - return static_cast(fastf2i((1.0f-std::abs(2.0f-offset_norm)) * depth) + delay); - }; - std::generate_n(delays, todo, gen_lfo); -} - -void GetSinusoidDelays(ALuint *delays, const ALuint start_offset, const ALuint lfo_range, - const float lfo_scale, const float depth, const ALsizei delay, const size_t todo) -{ - ASSUME(lfo_range > 0); - ASSUME(todo > 0); - - ALuint offset{start_offset}; - auto gen_lfo = [&offset,lfo_range,lfo_scale,depth,delay]() -> ALuint - { - offset = (offset+1)%lfo_range; - const float offset_norm{static_cast(offset) * lfo_scale}; - return static_cast(fastf2i(std::sin(offset_norm)*depth) + delay); - }; - std::generate_n(delays, todo, gen_lfo); -} +#define MAX_UPDATE_SAMPLES 256 struct ChorusState final : public EffectState { al::vector mSampleBuffer; @@ -107,6 +77,8 @@ struct ChorusState final : public EffectState { float mDepth{0.0f}; float mFeedback{0.0f}; + void getTriangleDelays(ALuint (*delays)[MAX_UPDATE_SAMPLES], const size_t todo); + void getSinusoidDelays(ALuint (*delays)[MAX_UPDATE_SAMPLES], const size_t todo); bool deviceUpdate(const ALCdevice *device) override; void update(const ALCcontext *context, const ALeffectslot *slot, const EffectProps *props, const EffectTarget target) override; @@ -191,12 +163,12 @@ void ChorusState::update(const ALCcontext *Context, const ALeffectslot *Slot, co mLfoRange = lfo_range; switch(mWaveform) { - case WaveForm::Triangle: - mLfoScale = 4.0f / static_cast(mLfoRange); - break; - case WaveForm::Sinusoid: - mLfoScale = al::MathDefs::Tau() / static_cast(mLfoRange); - break; + case WaveForm::Triangle: + mLfoScale = 4.0f / static_cast(mLfoRange); + break; + case WaveForm::Sinusoid: + mLfoScale = al::MathDefs::Tau() / static_cast(mLfoRange); + break; } /* Calculate lfo phase displacement */ @@ -206,6 +178,57 @@ void ChorusState::update(const ALCcontext *Context, const ALeffectslot *Slot, co } } + +void ChorusState::getTriangleDelays(ALuint (*delays)[MAX_UPDATE_SAMPLES], const size_t todo) +{ + const ALuint lfo_range{mLfoRange}; + const float lfo_scale{mLfoScale}; + const float depth{mDepth}; + const int delay{mDelay}; + + ASSUME(lfo_range > 0); + ASSUME(todo > 0); + + ALuint offset{mLfoOffset}; + auto gen_lfo = [&offset,lfo_range,lfo_scale,depth,delay]() -> ALuint + { + offset = (offset+1)%lfo_range; + const float offset_norm{static_cast(offset) * lfo_scale}; + return static_cast(fastf2i((1.0f-std::abs(2.0f-offset_norm)) * depth) + delay); + }; + std::generate_n(delays[0], todo, gen_lfo); + + offset = (mLfoOffset+mLfoDisp) % lfo_range; + std::generate_n(delays[1], todo, gen_lfo); + + mLfoOffset = static_cast(mLfoOffset+todo) % lfo_range; +} + +void ChorusState::getSinusoidDelays(ALuint (*delays)[MAX_UPDATE_SAMPLES], const size_t todo) +{ + const ALuint lfo_range{mLfoRange}; + const float lfo_scale{mLfoScale}; + const float depth{mDepth}; + const int delay{mDelay}; + + ASSUME(lfo_range > 0); + ASSUME(todo > 0); + + ALuint offset{mLfoOffset}; + auto gen_lfo = [&offset,lfo_range,lfo_scale,depth,delay]() -> ALuint + { + offset = (offset+1)%lfo_range; + const float offset_norm{static_cast(offset) * lfo_scale}; + return static_cast(fastf2i(std::sin(offset_norm)*depth) + delay); + }; + std::generate_n(delays[0], todo, gen_lfo); + + offset = (mLfoOffset+mLfoDisp) % lfo_range; + std::generate_n(delays[1], todo, gen_lfo); + + mLfoOffset = static_cast(mLfoOffset+todo) % lfo_range; +} + void ChorusState::process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) { const size_t bufmask{mSampleBuffer.size()-1}; @@ -216,27 +239,16 @@ void ChorusState::process(const size_t samplesToDo, const al::span(todo)) % mLfoRange; + getTriangleDelays(moddelays, todo); - alignas(16) float temps[2][256]; - for(size_t i{0u};i < todo;i++) + alignas(16) float temps[2][MAX_UPDATE_SAMPLES]; + for(size_t i{0u};i < todo;++i) { // Feed the buffer's input first (necessary for delays < 1). delaybuf[offset&bufmask] = samplesIn[0][base+i]; @@ -258,7 +270,7 @@ void ChorusState::process(const size_t samplesToDo, const al::span