|
- // Copyright 2014 Olivier Gillet.
- //
- // Author: Olivier Gillet (ol.gillet@gmail.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- // See http://creativecommons.org/licenses/MIT/ for more information.
- //
- // -----------------------------------------------------------------------------
- //
- // Reverb.
-
- #ifndef ELEMENTS_DSP_FX_REVERB_H_
- #define ELEMENTS_DSP_FX_REVERB_H_
-
- #include "stmlib/stmlib.h"
-
- #include "elements/dsp/fx/fx_engine.h"
-
- namespace elements {
-
- class Reverb {
- public:
- Reverb() { }
- ~Reverb() { }
-
- void Init(uint16_t* buffer) {
- engine_.Init(buffer);
- engine_.SetLFOFrequency(LFO_1, 0.5f / 32000.0f);
- engine_.SetLFOFrequency(LFO_2, 0.3f / 32000.0f);
- lp_ = 0.7f;
- diffusion_ = 0.625f;
- }
-
- void Process(float* left, float* right, size_t size) {
- // 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 E::Reserve<150,
- E::Reserve<214,
- E::Reserve<319,
- E::Reserve<527,
- E::Reserve<2182,
- E::Reserve<2690,
- E::Reserve<4501,
- E::Reserve<2525,
- E::Reserve<2197,
- E::Reserve<6312> > > > > > > > > > Memory;
- E::DelayLine<Memory, 0> ap1;
- E::DelayLine<Memory, 1> ap2;
- E::DelayLine<Memory, 2> ap3;
- E::DelayLine<Memory, 3> ap4;
- E::DelayLine<Memory, 4> dap1a;
- E::DelayLine<Memory, 5> dap1b;
- E::DelayLine<Memory, 6> del1;
- E::DelayLine<Memory, 7> dap2a;
- E::DelayLine<Memory, 8> dap2b;
- E::DelayLine<Memory, 9> del2;
- E::Context c;
-
- const float kap = diffusion_;
- const float klp = lp_;
- const float krt = reverb_time_;
- const float amount = amount_;
- const float gain = input_gain_;
-
- float lp_1 = lp_decay_1_;
- float lp_2 = lp_decay_2_;
-
- while (size--) {
- float wet;
- float apout = 0.0f;
- engine_.Start(&c);
-
- // Smear AP1 inside the loop.
- c.Interpolate(ap1, 10.0f, LFO_1, 80.0f, 1.0f);
- c.Write(ap1, 100, 0.0f);
-
- c.Read(*left + *right, 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, 6211.0f, 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);
-
- *left += (wet - *left) * amount;
-
- c.Load(apout);
- // c.Interpolate(del1, 4450.0f, 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);
-
- *right += (wet - *right) * amount;
-
- ++left;
- ++right;
- }
-
- lp_decay_1_ = lp_1;
- lp_decay_2_ = lp_2;
- }
-
- inline void set_amount(float amount) {
- amount_ = amount;
- }
-
- inline void set_input_gain(float input_gain) {
- input_gain_ = input_gain;
- }
-
- inline void set_time(float reverb_time) {
- reverb_time_ = reverb_time;
- }
-
- inline void set_diffusion(float diffusion) {
- diffusion_ = diffusion;
- }
-
- inline void set_lp(float lp) {
- lp_ = lp;
- }
-
- private:
- typedef FxEngine<32768, FORMAT_16_BIT> E;
- E engine_;
-
- float amount_;
- float input_gain_;
- float reverb_time_;
- float diffusion_;
- float lp_;
-
- float lp_decay_1_;
- float lp_decay_2_;
-
- DISALLOW_COPY_AND_ASSIGN(Reverb);
- };
-
- } // namespace elements
-
- #endif // ELEMENTS_DSP_FX_REVERB_H_
|