shithub: leaf

Download patch

ref: 32bb7b96736d4d845eb53428a9d22b2dade022f5
parent: 9dffd7c97f0263f5207db0a08dd4ab2d6af5b21d
author: mulshine <mulshine@princeton.edu>
date: Wed Jan 2 13:09:19 EST 2019

Rought implementation of DATTORRO reverb ported from Tom Erbe's max patches.

--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -100,7 +100,7 @@
 } tDelayA;
 
 void        tDelayA_init        (tDelayA*  const, float delay, uint32_t maxDelay);
-void        tDelayA_free        (tDelayA* const);
+void        tDelayA_free        (tDelayA* const);
 
 int         tDelayA_setDelay    (tDelayA*  const, float delay);
 float       tDelayA_getDelay    (tDelayA*  const);
@@ -109,7 +109,10 @@
 float       tDelayA_addTo       (tDelayA*  const, float value, uint32_t tapDelay);
 float       tDelayA_tick        (tDelayA*  const, float sample);
 float       tDelayA_getLastOut  (tDelayA*  const);
-float       tDelayA_getLastIn   (tDelayA*  const);
+float       tDelayA_getLastIn   (tDelayA*  const);
+void        tDelayA_setGain     (tDelayA*  const, float gain);
+float       tDelayA_getGain     (tDelayA*  const);
+
 
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
--- a/LEAF/Inc/leaf-filter.h
+++ b/LEAF/Inc/leaf-filter.h
@@ -25,7 +25,8 @@
 {
     float gain;
     float a0,a1;
-    float b0,b1;
+    float b0,b1;
+    float freq;
     
     float lastIn, lastOut;
     
@@ -37,7 +38,8 @@
 float       tOnePole_tick           (tOnePole* const, float input);
 void        tOnePole_setB0          (tOnePole* const, float b0);
 void        tOnePole_setA1          (tOnePole* const, float a1);
-void        tOnePole_setPole        (tOnePole* const, float thePole);
+void        tOnePole_setPole        (tOnePole* const, float thePole);
+void        tOnePole_setFreq        (tOnePole* const, float freq);
 void        tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
 void        tOnePole_setGain        (tOnePole* const, float gain);
 
--- a/LEAF/Src_cpp/leaf-filter.cpp
+++ b/LEAF/Src_cpp/leaf-filter.cpp
@@ -276,6 +276,12 @@
     else                    f->b0 = (1.0f + thePole);
     
     f->a1 = -thePole;
+}
+
+void        tOnePole_setFreq        (tOnePole* const f, float freq)
+{
+    f->a1 = expf(-2.0 * PI * freq);
+    f->b0 = 1.0f - f->a1;
 }
 
 void    tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -679,7 +685,7 @@
     
     float a1,a2,a3,g,k;
     g = tanf(PI * freq * leaf.invSampleRate);
-    k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
+    k = 1.0f/Q;
     a1 = 1.0f/(1.0f+g*(g+k));
     a2 = g*a1;
     a3 = g*a2;
@@ -708,7 +714,7 @@
 
 int     tSVF_setQ(tSVF* const svf, float Q)
 {
-    svf->k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
+    svf->k = 1.0f/Q;
     svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
     svf->a2 = svf->g * svf->a1;
     svf->a3 = svf->g * svf->a2;
--- a/LEAF_JUCEPlugin/LEAF.jucer
+++ b/LEAF_JUCEPlugin/LEAF.jucer
@@ -21,8 +21,6 @@
           <FILE id="O0YJRY" name="d_fft_mayer.c" compile="1" resource="0" file="../LEAF/Externals/d_fft_mayer.c"/>
           <FILE id="L7c1sT" name="d_fft_mayer.cpp" compile="1" resource="0" file="../LEAF/Externals/d_fft_mayer.cpp"/>
           <FILE id="HdG3WV" name="d_fft_mayer.h" compile="0" resource="0" file="../LEAF/Externals/d_fft_mayer.h"/>
-          <FILE id="E7GkIZ" name="mpool.cpp" compile="1" resource="0" file="../LEAF/Externals/mpool.cpp"/>
-          <FILE id="udMePt" name="mpool.h" compile="0" resource="0" file="../LEAF/Externals/mpool.h"/>
           <FILE id="Hu4b98" name="trigtbl.h" compile="0" resource="0" file="../LEAF/Externals/trigtbl.h"/>
         </GROUP>
         <GROUP id="{0E2E673D-2AE5-AECB-4E28-A1EE29180BD2}" name="Inc">
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -20,7 +20,11 @@
 
 std::vector<juce::String> cSliderNames =  std::vector<juce::String>
 {
-    "mix"
+    "mix",
+    "predelay",
+    "input filter",
+    "feedback filter",
+    "feedback gain"
 };
 
 std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -14,45 +14,228 @@
 
 static void leaf_pool_report(void);
 static void leaf_pool_dump(void);
-static void run_pool_test(void);
+static void run_pool_test(void);
+
+
+// INPUT
+tDelayL     in_delay;
+tOnePole    in_filter;
+tDelayA     in_allpass[4];
+float       in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
+float       in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
+
+// FEEDBACK 1
+tDelayA     f1_allpass;
+tDelayL     f1_delay_1;
+tOnePole    f1_filter;
+tDelayL     f1_delay_2;
+tDelayL     f1_delay_3;
+
+tCycle      f1_lfo;
+
+// FEEDBACK 2
+tDelayA     f2_allpass;
+tDelayL     f2_delay_1;
+tOnePole    f2_filter;
+tDelayL     f2_delay_2;
+tDelayL     f2_delay_3;
+
+tCycle      f2_lfo;
+
+float t;
 
-tSquare osc;
 
 void    LEAFTest_init            (float sampleRate, int blockSize)
 {
     LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
     
-    tSquare_init(&osc);
-    tSquare_setFreq(&osc, 110.0f);
+    t = leaf.sampleRate * 0.001f;
     
-    tSquare_setTableSize(&osc, 4000);
-
+    // ==================DATTORRO===================
+    // INPUT
+    tDelayL_init(&in_delay, 0.f, 200.f*t);
+    tOnePole_init(&in_filter, 1.f);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tDelayA_init(&in_allpass[i], in_allpass_delays[i], 20.f*t);
+        tDelayA_setGain(&in_allpass[i], in_allpass_gains[i]);
+    }
+    
+    // FEEDBACK 1
+    tDelayA_init(&f1_allpass, 30.51f*t, 100.f*t);
+    tDelayA_setGain(&f1_allpass, 0.7f);
+    
+    tDelayL_init(&f1_delay_1, 141.69f*t, 200.0f*t);
+    tDelayL_init(&f1_delay_2, 89.24f*t, 100.0f*t);
+    tDelayL_init(&f1_delay_3, 125.f*t, 200.0f*t);
+    
+    tOnePole_init(&f1_filter, 1.f);
+    
+    tCycle_init(&f1_lfo);
+    tCycle_setFreq(&f1_lfo, 0.1f);
+    
+    // FEEDBACK 2
+    tDelayA_init(&f2_allpass, 22.58f*t, 100.f*t);
+    tDelayA_setGain(&f2_allpass, 0.7f);
+    
+    tDelayL_init(&f2_delay_1, 149.62f*t, 200.0f*t);
+    tDelayL_init(&f2_delay_2, 60.48f*t, 100.0f*t);
+    tDelayL_init(&f2_delay_3, 106.28f*t, 200.0f*t);
+    
+    tOnePole_init(&f2_filter, 1.f);
+    
+    tCycle_init(&f2_lfo);
+    tCycle_setFreq(&f2_lfo, 0.07f);
+    
+    // =============================================
+    
     leaf_pool_report();
 }
 
 int timer = 0;
+
+
+float f1_delay_2_last;
+float f2_delay_2_last;
+
+float f1_last;
+float f2_last;
+
+
+float mix;
+float predelay = 0.f;
+float input_filter = 1.;
+float feedback_filter = 1.f;
+float feedback_gain = 0.0f;
+
 
-float prev = 0.0;
 
 float   LEAFTest_tick            (float input)
-{
-    float sample = 0.0f;
-    
-    timer++;
-    if (timer == (1 * leaf.sampleRate))
-    {
-        timer = 0;
+{
+    // ==================DATTORRO===================
+    
+    // INPUT
+    float in_sample = tDelayL_tick(&in_delay, input);
+    
+    in_sample = tOnePole_tick(&in_filter, in_sample);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        in_sample = tDelayA_tick(&in_allpass[i], in_sample);
     }
+
+    // FEEDBACK 1
+    float f1_sample = in_sample + f2_last; // + f2_last_out;
     
-    sample = 0.5 * tSquare_tick(&osc);
+    tDelayA_setDelay(&f1_allpass, 30.51f*t + tCycle_tick(&f1_lfo) * 4.0f);
+    
+    f1_sample = tDelayA_tick(&f1_allpass, f1_sample);
+    
+    f1_sample = tDelayL_tick(&f1_delay_1, f1_sample);
+    
+    f1_sample = tOnePole_tick(&f1_filter, f1_sample);
+    
+    f1_sample = f1_sample + f1_delay_2_last * 0.5f;
+    
+    float f1_delay_2_sample = tDelayL_tick(&f1_delay_2, f1_sample * 0.5f);
+    
+    f1_delay_2_last = f1_delay_2_sample;
+    
+    f1_sample = f1_delay_2_last + f1_sample;
+    
+    f1_sample *= feedback_gain;
+    
+    f1_last = tDelayL_tick(&f1_delay_3, f1_sample);
+
+    // FEEDBACK 2
+    float f2_sample = in_sample + f1_last;
+    
+    tDelayA_setDelay(&f2_allpass, 22.58f*t + tCycle_tick(&f2_lfo) * 4.0f);
+    
+    f2_sample = tDelayA_tick(&f2_allpass, f2_sample);
+    
+    f2_sample = tDelayL_tick(&f2_delay_1, f2_sample);
+    
+    f2_sample = tOnePole_tick(&f2_filter, f2_sample);
+    
+    f2_sample = f2_sample + f2_delay_2_last * 0.5f;
+    
+    float f2_delay_2_sample = tDelayL_tick(&f2_delay_2, f2_sample * 0.5f);
+    
+    f2_delay_2_last = f2_delay_2_sample;
+    
+    f2_sample = f2_delay_2_last + f2_sample;
+    
+    f2_sample *= feedback_gain;
+    
+    f2_last = tDelayL_tick(&f2_delay_3, f2_sample);
+    
+    // TAP OUT 1
+    f1_sample =     tDelayL_tapOut(&f1_delay_1, 8.9f*t) +
+                    tDelayL_tapOut(&f1_delay_1, 99.8f*t);
+    
+    f1_sample -=    tDelayL_tapOut(&f1_delay_2, 64.2f*t);
+    
+    f1_sample +=    tDelayL_tapOut(&f1_delay_3, 67.f*t);
+    
+    f1_sample -=    tDelayL_tapOut(&f2_delay_1, 66.8f*t);
+    
+    f1_sample -=    tDelayL_tapOut(&f2_delay_2, 6.3f*t);
+    
+    f1_sample -=    tDelayL_tapOut(&f2_delay_3, 35.8f*t);
+    
+    f1_sample *=    0.14;
+    
+    // TAP OUT 2
+    f2_sample =     tDelayL_tapOut(&f2_delay_1, 11.8f*t) +
+                    tDelayL_tapOut(&f2_delay_1, 121.7f*t);
+    
+    f2_sample -=    tDelayL_tapOut(&f2_delay_2, 6.3f*t);
+    
+    f2_sample +=    tDelayL_tapOut(&f2_delay_3, 89.7f*t);
+    
+    f2_sample -=    tDelayL_tapOut(&f1_delay_1, 70.8f*t);
+    
+    f2_sample -=    tDelayL_tapOut(&f1_delay_2, 11.2f*t);
+    
+    f2_sample -=    tDelayL_tapOut(&f1_delay_3, 4.1f*t);
+    
+    f2_sample *=    0.14f;
+    
+    float sample = (f1_sample + f2_sample) * 0.5f;
+    
+    // =============================================
     
-    return sample;
+    return (input * (1.0f - mix) + sample * mix);
      
 }
 
 void    LEAFTest_block           (void)
-{
-    float val = getSliderValue("mix");
+{
+    float val = getSliderValue("mix");
+    
+    mix = val;
+    
+    val = getSliderValue("predelay");
+    
+    predelay = (val * 200.f) * leaf.sampleRate * 0.001f;
+    tDelayL_setDelay(&in_delay, predelay);
+    
+    val = getSliderValue("input filter");
+    
+    input_filter =  val * 20000.f;
+    tOnePole_setFreq(&in_filter, input_filter);
+    
+    val = getSliderValue("feedback filter");
+    
+    feedback_filter = val * 20000.f;
+    tOnePole_setFreq(&f1_filter, feedback_filter);
+    tOnePole_setFreq(&f2_filter, feedback_filter);
+    
+    val = getSliderValue("feedback gain");
+    
+    feedback_gain = val;
 }
 
 void    LEAFTest_controllerInput (int cnum, float cval)