mirror of https://github.com/probonopd/MiniDexed
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.9 KiB
156 lines
3.9 KiB
#include "fx_shimmer_reverb.h"
|
|
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
|
|
#define TAIL , -1
|
|
|
|
ShimmerReverb::ShimmerReverb(float32_t sampling_rate) :
|
|
FXElement(sampling_rate),
|
|
engine_(sampling_rate),
|
|
input_gain_(-1.0f),
|
|
diffusion_(-1.0f),
|
|
lp_(-1.0f)
|
|
{
|
|
this->engine_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f);
|
|
this->engine_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f);
|
|
|
|
this->setInputGain(1.0f);
|
|
this->setLP(0.7f);
|
|
this->setDiffusion(0.625f);
|
|
}
|
|
|
|
ShimmerReverb::~ShimmerReverb()
|
|
{
|
|
}
|
|
|
|
void ShimmerReverb::reset()
|
|
{
|
|
this->engine_.reset();
|
|
}
|
|
|
|
void ShimmerReverb::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
|
|
{
|
|
// This is the Griesinger topology described in the Dattorro paper
|
|
// (4 AP diffusers on the input, then a loop of 2x 2AP+1Delay).
|
|
// Modulation is applied in the loop of the first diffuser AP for additional
|
|
// smearing; and to the two long delays for a slow shimmer/chorus effect.
|
|
typedef Engine::Reserve< 113,
|
|
Engine::Reserve< 162,
|
|
Engine::Reserve< 241,
|
|
Engine::Reserve< 399,
|
|
Engine::Reserve<1653,
|
|
Engine::Reserve<2038,
|
|
Engine::Reserve<3411,
|
|
Engine::Reserve<1913,
|
|
Engine::Reserve<1663,
|
|
Engine::Reserve<4782> > > > > > > > > > Memory;
|
|
Engine::DelayLine<Memory, 0> ap1;
|
|
Engine::DelayLine<Memory, 1> ap2;
|
|
Engine::DelayLine<Memory, 2> ap3;
|
|
Engine::DelayLine<Memory, 3> ap4;
|
|
Engine::DelayLine<Memory, 4> dap1a;
|
|
Engine::DelayLine<Memory, 5> dap1b;
|
|
Engine::DelayLine<Memory, 6> del1;
|
|
Engine::DelayLine<Memory, 7> dap2a;
|
|
Engine::DelayLine<Memory, 8> dap2b;
|
|
Engine::DelayLine<Memory, 9> del2;
|
|
Engine::Context c;
|
|
|
|
const float32_t kap = this->diffusion_;
|
|
const float32_t klp = this->lp_;
|
|
const float32_t krt = this->reverb_time_;
|
|
const float32_t gain = this->input_gain_;
|
|
|
|
float32_t lp_1 = this->lp_decay_1_;
|
|
float32_t lp_2 = this->lp_decay_2_;
|
|
|
|
float32_t wet = 0.0f;
|
|
float32_t apout = 0.0f;
|
|
engine_.start(&c);
|
|
|
|
// Smear AP1 inside the loop.
|
|
c.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f);
|
|
c.write(ap1, 100, 0.0f);
|
|
c.read(inL + inR, gain);
|
|
|
|
// Diffuse through 4 allpasses.
|
|
c.read(ap1 TAIL, kap);
|
|
c.writeAllPass(ap1, -kap);
|
|
c.read(ap2 TAIL, kap);
|
|
c.writeAllPass(ap2, -kap);
|
|
c.read(ap3 TAIL, kap);
|
|
c.writeAllPass(ap3, -kap);
|
|
c.read(ap4 TAIL, kap);
|
|
c.writeAllPass(ap4, -kap);
|
|
c.write(apout);
|
|
|
|
// Main reverb loop.
|
|
c.load(apout);
|
|
c.interpolate(del2, 4680.0f, Engine::LFOIndex::LFO_2, 100.0f, krt);
|
|
c.lp(lp_1, klp);
|
|
c.read(dap1a TAIL, -kap);
|
|
c.writeAllPass(dap1a, kap);
|
|
c.read(dap1b TAIL, kap);
|
|
c.writeAllPass(dap1b, -kap);
|
|
c.write(del1, 2.0f);
|
|
c.write(wet, 0.0f);
|
|
|
|
outR = wet;
|
|
|
|
c.load(apout);
|
|
c.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt);
|
|
c.read(del1 TAIL, krt);
|
|
c.lp(lp_2, klp);
|
|
c.read(dap2a TAIL, kap);
|
|
c.writeAllPass(dap2a, -kap);
|
|
c.read(dap2b TAIL, -kap);
|
|
c.writeAllPass(dap2b, kap);
|
|
c.write(del2, 2.0f);
|
|
c.write(wet, 0.0f);
|
|
|
|
outR = wet;
|
|
|
|
this->lp_decay_1_ = lp_1;
|
|
this->lp_decay_2_ = lp_2;
|
|
}
|
|
|
|
void ShimmerReverb::setInputGain(float32_t gain)
|
|
{
|
|
this->input_gain_ = constrain(gain, 0.0f, 1.0f);
|
|
}
|
|
|
|
float32_t ShimmerReverb::getInputGain() const
|
|
{
|
|
return this->input_gain_;
|
|
}
|
|
|
|
void ShimmerReverb::setTime(float32_t time)
|
|
{
|
|
this->reverb_time_ = constrain(time, 0.0f, 1.0f);
|
|
}
|
|
|
|
float32_t ShimmerReverb::getTime() const
|
|
{
|
|
return this->reverb_time_;
|
|
}
|
|
|
|
void ShimmerReverb::setDiffusion(float32_t diffusion)
|
|
{
|
|
this->diffusion_ = constrain(diffusion, 0.0f, 1.0f);
|
|
}
|
|
|
|
float32_t ShimmerReverb::getDiffusion() const
|
|
{
|
|
return this->diffusion_;
|
|
}
|
|
|
|
void ShimmerReverb::setLP(float32_t lp)
|
|
{
|
|
this->lp_ = constrain(lp, 0.0f, 1.0f);
|
|
}
|
|
|
|
float32_t ShimmerReverb::getLP() const
|
|
{
|
|
return this->lp_;
|
|
}
|
|
|