shithub: leaf

Download patch

ref: b0f54b934de962a04c77ec53da5d6916ea150843
parent: 98bd108b19d300d9bda1c4cf19b2ea33a740493f
parent: 6e8f4634b7cfc75451ab87275c4ce2b90059b193
author: Jeff Snyder <jeff@snyderphonics.com>
date: Mon Jan 14 12:18:28 EST 2019

merging

binary files a/.DS_Store b/.DS_Store differ
--- /dev/null
+++ b/.gitignore
@@ -1,0 +1,11 @@
+*.DS_Store
+*.app
+*.a
+*.appex
+*.vst
+*.vst3
+*.component
+*.xcuserstate
+*.zip
+*.swp
+*/Builds
--- /dev/null
+++ b/LEAF/.gitignore
@@ -1,0 +1,11 @@
+*.DS_Store
+*.app
+*.a
+*.appex
+*.vst
+*.vst3
+*.component
+*.xcuserstate
+*.zip
+*.swp
+*/Builds
--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -71,7 +71,7 @@
 int         tDelayL_setDelay    (tDelayL*  const, float delay);
 float       tDelayL_getDelay    (tDelayL*  const);
 void        tDelayL_tapIn       (tDelayL*  const, float in, uint32_t tapDelay);
-float       tDelayL_tapOut      (tDelayL*  const, uint32_t tapDelay);
+float       tDelayL_tapOut      (tDelayL*  const, float tapDelay);
 float       tDelayL_addTo       (tDelayL*  const, float value, uint32_t tapDelay);
 float       tDelayL_tick        (tDelayL*  const, float sample);
 float       tDelayL_getLastOut  (tDelayL*  const);
@@ -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);
--- a/LEAF/Inc/leaf-filter.h
+++ b/LEAF/Inc/leaf-filter.h
@@ -14,18 +14,45 @@
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 #include "leaf-globals.h"
-#include "leaf-math.h"
+#include "leaf-math.h"
+
+#include "leaf-delay.h"
 
-#include "leaf-wavetables.h"
+#include "leaf-wavetables.h"
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+/* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
+typedef struct _tAllpass
+{
+    float gain;
+    
+    tDelayL delay;
+    
+    float lastOut;
+    
+} tAllpass;
+
+void        tAllpass_init           (tAllpass* const, float initDelay, uint32_t maxDelay);
+void        tAllpass_free           (tAllpass* const);
+
+float       tAllpass_tick           (tAllpass* const, float input);
+void        tAllpass_setGain        (tAllpass* const, float gain);
+void        tAllpass_setDelay       (tAllpass* const f, float delay);
 
+
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
 typedef struct _tOnePole
 {
-    float gain;
-    float a0,a1;
-    float b0,b1;
+    float gain;
+    float a0,a1;
+    float b0,b1;
+    
+    float coef;
+    
+    float freq;
     
     float lastIn, lastOut;
     
@@ -37,7 +64,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/Inc/leaf-math.h
+++ b/LEAF/Inc/leaf-math.h
@@ -76,13 +76,19 @@
 
 float       LEAF_clip               (float min, float val, float max);
 float   	LEAF_softClip						(float val, float thresh);
-oBool       LEAF_isPrime            (uint64_t number );
-float       LEAF_midiToFrequency    (float f);
+oBool       LEAF_isPrime            (uint64_t number );
 
+float       LEAF_midiToFrequency    (float f);
+float       LEAF_frequencyToMidi(float f);
+
+void        LEAF_generate_sine     (float* buffer, int size);
+void        LEAF_generate_sawtooth (float* buffer, float basefreq, int size);
+void        LEAF_generate_triangle (float* buffer, float basefreq, int size);
+void        LEAF_generate_square   (float* buffer, float basefreq, int size);
+
 // dope af
-float LEAF_chebyshevT(float in, int n);
-float LEAF_CompoundChebyshevT(float in, int n, float* amps);
-float LEAF_frequencyToMidi(float f);
+float       LEAF_chebyshevT(float in, int n);
+float       LEAF_CompoundChebyshevT(float in, int n, float* amps);
 
 static inline float interpolate3max(float *buf, const int peakindex)
 {
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -11,14 +11,16 @@
 #ifndef LEAFREVERB_H_INCLUDED
 #define LEAFREVERB_H_INCLUDED
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 #include "leaf-globals.h"
 #include "leaf-math.h"
 
-#include "leaf-delay.h"
+#include "leaf-delay.h"
+#include "leaf-filter.h"
+#include "leaf-oscillator.h"
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* PRCRev: Reverb, reimplemented from STK (Cook and Scavone). */
 typedef struct _tPRCRev
@@ -47,7 +49,7 @@
 // Set mix between dry input and wet output signal.
 void    tPRCRev_setMix  (tPRCRev* const, float mix);
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* NRev: Reverb, reimplemented from STK (Cook and Scavone). */
 typedef struct _tNRev
@@ -77,6 +79,61 @@
 // Set mix between dry input and wet output signal.
 void    tNRev_setMix    (tNRev*  const, float mix);
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+
+typedef struct _tDattorro
+{
+    float   predelay;
+    float   input_filter;
+    float   feedback_filter;
+    float   feedback_gain;
+    float   mix;
+    
+    float   size, t;
+    
+    float   f1_delay_2_last,
+            f2_delay_2_last;
+    
+    float   f1_last,
+            f2_last;
+    
+    // INPUT
+    tDelayL     in_delay;
+    tOnePole    in_filter;
+    tAllpass    in_allpass[4];
+    
+    // FEEDBACK 1
+    tAllpass    f1_allpass;
+    tDelayL     f1_delay_1;
+    tOnePole    f1_filter;
+    tDelayL     f1_delay_2;
+    tDelayL     f1_delay_3;
+    
+    tCycle      f1_lfo;
+    
+    // FEEDBACK 2
+    tAllpass    f2_allpass;
+    tDelayL     f2_delay_1;
+    tOnePole    f2_filter;
+    tDelayL     f2_delay_2;
+    tDelayL     f2_delay_3;
+    
+    tCycle      f2_lfo;
+
+} tDattorro;
+
+void    tDattorro_init              (tDattorro* const);
+void    tDattorro_free              (tDattorro* const);
+
+float   tDattorro_tick              (tDattorro* const, float input);
+
+void    tDattorro_setMix            (tDattorro* const, float mix);
+void    tDattorro_setSize           (tDattorro* const, float size);
+void    tDattorro_setInputDelay     (tDattorro* const, float preDelay);
+void    tDattorro_setInputFilter    (tDattorro* const, float freq);
+void    tDattorro_setFeedbackFilter (tDattorro* const, float freq);
+void    tDattorro_setFeedbackGain   (tDattorro* const, float gain);
+
 
 #endif  // LEAFREVERB_H_INCLUDED
--- a/LEAF/Inc_cpp/leaf-808.hpp
+++ b/LEAF/Inc_cpp/leaf-808.hpp
@@ -58,9 +58,13 @@
     tSVF bandpassStick;
     tEnvelope envGain;
     tEnvelope envStick;
+    tEnvelope noiseFMGain;
     tHighpass highpass;
     tNoise stick;
-    
+
+    float freq;
+    float stretch;
+    float FM_amount;
     float oscNoiseMix;
     
 } t808Hihat;
@@ -73,10 +77,13 @@
 void        t808Hihat_setOscNoiseMix     (t808Hihat* const, float oscNoiseMix);
 void        t808Hihat_setDecay           (t808Hihat* const, float decay);
 void        t808Hihat_setHighpassFreq    (t808Hihat* const, float freq);
-void        t808Hihat_etOscBandpassFreq  (t808Hihat* const, float freq);
+void        t808Hihat_setOscBandpassFreq  (t808Hihat* const, float freq);
+void 		t808Hihat_setOscBandpassQ		(t808Hihat* const hihat, float Q);
+void        t808Hihat_setStickBandPassFreq  (t808Hihat* const, float freq);
 void        t808Hihat_setOscFreq         (t808Hihat* const, float freq);
+void 		t808Hihat_setStretch				(t808Hihat* const hihat, float stretch);
+void 		t808Hihat_setFM					(t808Hihat* const hihat, float FM_amount);
 
-
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 // 808 Snare
@@ -118,6 +125,46 @@
 void        t808Snare_setToneNoiseMix       (t808Snare* const, float toneNoiseMix);
 void        t808Snare_setNoiseFilterFreq    (t808Snare* const, float noiseFilterFreq);
 void        t808Snare_setNoiseFilterQ       (t808Snare* const, float noiseFilterQ);
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+// 808 Kick
+typedef struct _t808Kick {
+
+
+    tCycle tone; // Tri
+    tNoise noiseOsc;
+    tSVF toneLowpass;
+    tEnvelope toneEnvOscChirp;
+    tEnvelope toneEnvOscSigh;
+    tEnvelope toneEnvGain;
+    tEnvelope noiseEnvGain;
+    tEnvelope toneEnvFilter;
+
+    float toneGain;
+    float noiseGain;
+
+    float toneInitialFreq;
+    float sighAmountInHz;
+    float chirpRatioMinusOne;
+    float noiseFilterFreq;
+
+
+} t808Kick;
+
+void        t808Kick_init                  (t808Kick* const);
+void        t808Kick_free                  (t808Kick* const);
+
+float       t808Kick_tick                  (t808Kick* const);
+void        t808Kick_on                    (t808Kick* const, float vel);
+void        t808Kick_setToneFreq          (t808Kick* const, float freq);
+void        t808Kick_setToneDecay         (t808Kick* const, float decay);
+void        t808Kick_setNoiseDecay         (t808Kick* const, float decay);
+void        t808Kick_setSighAmount         (t808Kick* const, float sigh);
+void        t808Kick_setChirpAmount         (t808Kick* const, float chirp);
+void        t808Kick_setToneNoiseMix       (t808Kick* const, float toneNoiseMix);
+void        t808Kick_setNoiseFilterFreq    (t808Kick* const, float noiseFilterFreq);
+void        t808Kick_setNoiseFilterQ       (t808Kick* const, float noiseFilterQ);
 
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
--- a/LEAF/Inc_cpp/leaf-delay.hpp
+++ b/LEAF/Inc_cpp/leaf-delay.hpp
@@ -71,7 +71,7 @@
 int         tDelayL_setDelay    (tDelayL*  const, float delay);
 float       tDelayL_getDelay    (tDelayL*  const);
 void        tDelayL_tapIn       (tDelayL*  const, float in, uint32_t tapDelay);
-float       tDelayL_tapOut      (tDelayL*  const, uint32_t tapDelay);
+float       tDelayL_tapOut      (tDelayL*  const, float tapDelay);
 float       tDelayL_addTo       (tDelayL*  const, float value, uint32_t tapDelay);
 float       tDelayL_tick        (tDelayL*  const, float sample);
 float       tDelayL_getLastOut  (tDelayL*  const);
@@ -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);
--- a/LEAF/Inc_cpp/leaf-filter.hpp
+++ b/LEAF/Inc_cpp/leaf-filter.hpp
@@ -14,18 +14,45 @@
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 #include "leaf-globals.h"
-#include "leaf-math.h"
+#include "leaf-math.h"
+
+#include "leaf-delay.h"
 
-#include "leaf-wavetables.h"
+#include "leaf-wavetables.h"
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+/* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
+typedef struct _tAllpass
+{
+    float gain;
+    
+    tDelayL delay;
+    
+    float lastOut;
+    
+} tAllpass;
+
+void        tAllpass_init           (tAllpass* const, float initDelay, uint32_t maxDelay);
+void        tAllpass_free           (tAllpass* const);
+
+float       tAllpass_tick           (tAllpass* const, float input);
+void        tAllpass_setGain        (tAllpass* const, float gain);
+void        tAllpass_setDelay       (tAllpass* const f, float delay);
 
+
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
 typedef struct _tOnePole
 {
-    float gain;
-    float a0,a1;
-    float b0,b1;
+    float gain;
+    float a0,a1;
+    float b0,b1;
+    
+    float coef;
+    
+    float freq;
     
     float lastIn, lastOut;
     
@@ -37,7 +64,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/Inc_cpp/leaf-math.hpp
+++ b/LEAF/Inc_cpp/leaf-math.hpp
@@ -70,19 +70,25 @@
 #define TWO_TO_31		2147483648.0f
 #define INV_TWO_TO_31	0.000000000465661f
 
-// Erbe shaper
+// Jones shaper
 float LEAF_shaper     (float input, float m_drive);
 float LEAF_reedTable  (float input, float offset, float slope);
 
 float       LEAF_clip               (float min, float val, float max);
 float   	LEAF_softClip						(float val, float thresh);
-oBool       LEAF_isPrime            (uint64_t number );
-float       LEAF_midiToFrequency    (float f);
+oBool       LEAF_isPrime            (uint64_t number );
 
+float       LEAF_midiToFrequency    (float f);
+float       LEAF_frequencyToMidi(float f);
+
+void        LEAF_generate_sine     (float* buffer, int size);
+void        LEAF_generate_sawtooth (float* buffer, float basefreq, int size);
+void        LEAF_generate_triangle (float* buffer, float basefreq, int size);
+void        LEAF_generate_square   (float* buffer, float basefreq, int size);
+
 // dope af
-float LEAF_chebyshevT(float in, int n);
-float LEAF_CompoundChebyshevT(float in, int n, float* amps);
-float LEAF_frequencyToMidi(float f);
+float       LEAF_chebyshevT(float in, int n);
+float       LEAF_CompoundChebyshevT(float in, int n, float* amps);
 
 static inline float interpolate3max(float *buf, const int peakindex)
 {
--- a/LEAF/Inc_cpp/leaf-reverb.hpp
+++ b/LEAF/Inc_cpp/leaf-reverb.hpp
@@ -11,14 +11,16 @@
 #ifndef LEAFREVERB_H_INCLUDED
 #define LEAFREVERB_H_INCLUDED
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 #include "leaf-globals.h"
 #include "leaf-math.h"
 
-#include "leaf-delay.h"
+#include "leaf-delay.h"
+#include "leaf-filter.h"
+#include "leaf-oscillator.h"
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* PRCRev: Reverb, reimplemented from STK (Cook and Scavone). */
 typedef struct _tPRCRev
@@ -47,7 +49,7 @@
 // Set mix between dry input and wet output signal.
 void    tPRCRev_setMix  (tPRCRev* const, float mix);
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 /* NRev: Reverb, reimplemented from STK (Cook and Scavone). */
 typedef struct _tNRev
@@ -77,6 +79,61 @@
 // Set mix between dry input and wet output signal.
 void    tNRev_setMix    (tNRev*  const, float mix);
 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+
+typedef struct _tDattorro
+{
+    float   predelay;
+    float   input_filter;
+    float   feedback_filter;
+    float   feedback_gain;
+    float   mix;
+    
+    float   size, t;
+    
+    float   f1_delay_2_last,
+            f2_delay_2_last;
+    
+    float   f1_last,
+            f2_last;
+    
+    // INPUT
+    tDelayL     in_delay;
+    tOnePole    in_filter;
+    tAllpass    in_allpass[4];
+    
+    // FEEDBACK 1
+    tAllpass    f1_allpass;
+    tDelayL     f1_delay_1;
+    tOnePole    f1_filter;
+    tDelayL     f1_delay_2;
+    tDelayL     f1_delay_3;
+    
+    tCycle      f1_lfo;
+    
+    // FEEDBACK 2
+    tAllpass    f2_allpass;
+    tDelayL     f2_delay_1;
+    tOnePole    f2_filter;
+    tDelayL     f2_delay_2;
+    tDelayL     f2_delay_3;
+    
+    tCycle      f2_lfo;
+
+} tDattorro;
+
+void    tDattorro_init              (tDattorro* const);
+void    tDattorro_free              (tDattorro* const);
+
+float   tDattorro_tick              (tDattorro* const, float input);
+
+void    tDattorro_setMix            (tDattorro* const, float mix);
+void    tDattorro_setSize           (tDattorro* const, float size);
+void    tDattorro_setInputDelay     (tDattorro* const, float preDelay);
+void    tDattorro_setInputFilter    (tDattorro* const, float freq);
+void    tDattorro_setFeedbackFilter (tDattorro* const, float freq);
+void    tDattorro_setFeedbackGain   (tDattorro* const, float gain);
+
 
 #endif  // LEAFREVERB_H_INCLUDED
--- a/LEAF/Inc_cpp/leaf-wavetables.hpp
+++ b/LEAF/Inc_cpp/leaf-wavetables.hpp
@@ -46,7 +46,7 @@
     TableNameNil
 } TableName;
 
-// mtof lookup table based on input range [0.0,1.0) in 4096 increments - midi frequency values scaled between m25 and m134 (as done in previous code)
+// mtof lookup table based on input range [0.0,1.0) in 4096 increments - midi frequency values scaled between m25 and m134 (from the Snyderphonics DrumBox code)
 
 extern const float exp_decay[EXP_DECAY_TABLE_SIZE];
 extern const float attack_decay_inc[ATTACK_DECAY_INC_TABLE_SIZE];
--- a/LEAF/Src/leaf-808.c
+++ b/LEAF/Src/leaf-808.c
@@ -121,7 +121,7 @@
 float t808Hihat_tick(t808Hihat* const hihat) {
     
     float sample = 0.0f;
-    float gainScale = 0.3f;
+    float gainScale = 0.1666f;
     
 
     float myNoise = tNoise_tick(&hihat->n);
@@ -149,6 +149,7 @@
     sample = tHighpass_tick(&hihat->highpass, sample);
     sample += ((0.5f * tEnvelope_tick(&hihat->envStick)) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick)));
     sample = tanhf(sample * 2.0f);
+
     return sample;
 }
 
@@ -216,6 +217,7 @@
     tEnvelope_init(&hihat->envGain, 0.0f, 50.0f, OFALSE);
     tEnvelope_init(&hihat->envStick, 0.0f, 7.0f, OFALSE);
     
+
     tHighpass_init(&hihat->highpass, 7000.0f);
     
     hihat->freq = 40.0f;
--- a/LEAF/Src/leaf-delay.c
+++ b/LEAF/Src/leaf-delay.c
@@ -29,8 +29,6 @@
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
     
-    d->delay = 0.0f;
-    
     d->inPoint = 0;
     d->outPoint = 0;
     
@@ -143,8 +141,6 @@
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
     
-    d->delay = 0.0f;
-    
     d->gain = 1.0f;
     
     d->lastIn = 0.0f;
@@ -206,14 +202,28 @@
     return 0;
 }
 
-float tDelayL_tapOut (tDelayL* const d, uint32_t tapDelay)
+float tDelayL_tapOut (tDelayL* const d, float tapDelay)
 {
-    int32_t tap = d->inPoint - tapDelay - 1;
+    float tap = (float) d->inPoint - tapDelay - 1.f;
     
     // Check for wraparound.
-    while ( tap < 0 )   tap += d->maxDelay;
+    while ( tap < 0.f )   tap += (float)d->maxDelay;
+
+    float alpha = tap - (int)tap;
+    float omAlpha = 1.f - alpha;
+
+    int ptx = (int) tap;
+    
+    // First 1/2 of interpolation
+    float samp = d->buff[ptx] * omAlpha;
+    
+    // Second 1/2 of interpolation
+    if ((ptx + 1) < d->maxDelay)
+        samp += d->buff[ptx+1] * d->alpha;
+    else
+        samp += d->buff[0] * d->alpha;
     
-    return d->buff[tap];
+    return samp;
     
 }
 
@@ -273,8 +283,6 @@
     else                    d->delay = delay;
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
-    
-    d->delay = 0.0f;
     
     d->gain = 1.0f;
     
--- a/LEAF/Src/leaf-filter.c
+++ b/LEAF/Src/leaf-filter.c
@@ -20,7 +20,44 @@
 #include "../Inc/leaf-wavetables.h"
 #include "../leaf.h"
 
-#endif
+#endif
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void    tAllpass_init(tAllpass* const f, float initDelay, uint32_t maxDelay)
+{
+    f->gain = 0.7f;
+    
+    f->lastOut = 0.0f;
+    
+    tDelayL_init(&f->delay, initDelay, maxDelay);
+}
+
+void    tAllpass_setDelay(tAllpass* const f, float delay)
+{
+    tDelayL_setDelay(&f->delay, delay);
+}
+
+void    tAllpass_free(tAllpass* const f)
+{
+    leaf_free(&f->delay);
+    leaf_free(f);
+}
+
+void    tAllpass_setGain(tAllpass* const f, float gain)
+{
+    f->gain = gain;
+}
+
+float   tAllpass_tick(tAllpass* const f, float input)
+{
+    float s1 = (-f->gain) * f->lastOut + input;
+    
+    float s2 = tDelayL_tick(&f->delay, s1) + (f->gain) * input;
+    
+    f->lastOut = s2;
+    
+    return f->lastOut;
+}
 
 void tButterworth_init(tButterworth* const f, int N, float f1, float f2)
 {
@@ -239,12 +276,12 @@
 }
 
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void    tOnePole_init(tOnePole* const f, float thePole)
+void    tOnePole_init(tOnePole* const f, float freq)
 {
     f->gain = 1.0f;
     f->a0 = 1.0;
     
-    tOnePole_setPole(f, thePole);
+    tOnePole_setFreq(f, freq);
     
     f->lastIn = 0.0f;
     f->lastOut = 0.0f;
@@ -276,6 +313,15 @@
     else                    f->b0 = (1.0f + thePole);
     
     f->a1 = -thePole;
+}
+
+void        tOnePole_setFreq        (tOnePole* const f, float freq)
+{
+    f->b0 = freq * TWO_PI * leaf.invSampleRate;
+    
+    f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+    
+    f->a1 = 1.0f - f->b0;
 }
 
 void    tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -294,7 +340,7 @@
 float   tOnePole_tick(tOnePole* const f, float input)
 {
     float in = input * f->gain;
-    float out = (f->b0 * in) - (f->a1 * f->lastOut);
+    float out = (f->b0 * in) + (f->a1 * f->lastOut);
     
     f->lastIn = in;
     f->lastOut = out;
@@ -679,7 +725,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 +754,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/Src/leaf-math.c
+++ b/LEAF/Src/leaf-math.c
@@ -136,6 +136,91 @@
     else
         return x * ( 27 + x * x ) / ( 27 + 9 * x * x );
 }
+
+
+void LEAF_generate_sine(float* buffer, int size)
+{
+    float phase;
+    for (int i = 0; i < size; i++)
+    {
+        phase = (float) i / (float) size;
+        buffer[i] = sinf(phase * TWO_PI);
+    }
+}
+
+void LEAF_generate_sawtooth(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / harmonic;
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        harmonic++;
+        freq = harmonic * basefreq;
+    }
+}
+
+
+void LEAF_generate_triangle(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp = 1.0f;
+    
+    int count = 0;
+    float mult = 1.0f;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / (float)(harmonic * harmonic);
+        
+        if (count % 2)  mult = -1.0f;
+        else            mult =  1.0f;
+        
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (mult * amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        count++;
+        harmonic += 2;
+        freq = harmonic * basefreq;
+    }
+}
+
+void LEAF_generate_square(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp = 1.0f;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / (float)(harmonic);
+        
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        harmonic += 2;
+        freq = harmonic * basefreq;
+    }
+}
+
 
 //-----------------------------------------------------------------------------
 // name: mtof()
--- a/LEAF/Src/leaf-oscillator.c
+++ b/LEAF/Src/leaf-oscillator.c
@@ -328,7 +328,7 @@
     float out = 0.0f;
     float w;
     
-    int idx = (int)(c->phase * SAW_TABLE_SIZE);
+    int idx = (int)(c->phase * TRI_TABLE_SIZE);
     
     // Wavetable synthesis
     
@@ -386,7 +386,7 @@
         w = ((20480.0f - c->freq) * INV_10240);
         out = (sawtooth[T10240][idx] * w) + (sawtooth[T20480][idx] * (1.0f - w));
     }
-    else if (c->freq <= 24000.0f)
+    else
     {
         out = sawtooth[T20480][idx];
     }
@@ -493,7 +493,7 @@
         w = ((20480.0f - c->freq) * INV_10240);
         out = (triangle[T10240][idx] * w) + (triangle[T20480][idx] * (1.0f - w));
     }
-    else if (c->freq <= 24000.0f)
+    else
     {
         out = triangle[T20480][idx];
     }
@@ -536,7 +536,7 @@
     
     float out = 0.0f;
     float w = 0.0f;
-    int idx = (int)(c->phase * SQR_TABLE_SIZE);
+    int idx = (int)(c->phase * TRI_TABLE_SIZE);
     
     // Wavetable synthesis
     
@@ -594,7 +594,7 @@
         w = ((20480.0f - c->freq) * INV_10240);
         out = (squarewave[T10240][idx] * w) + (squarewave[T20480][idx] * (1.0f - w));
     }
-    else if (c->freq <= 24000.0f)
+    else
     {
         out = squarewave[T20480][idx];
     }
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -248,12 +248,240 @@
     r->lastOut = out;
     
     return out;
-}
+}
 
-
-
 void     tNRevSampleRateChanged (tNRev* const r)
 {
     for (int i=0; i<6; i++)   r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(r->combDelays[i]) * leaf.invSampleRate / r->t60 ));
+}
+
+// ======================================DATTORRO=========================================
+
+#define SAMP(in) (in*r->t)
+
+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 };
+
+void    tDattorro_init              (tDattorro* const r)
+{
+    tDattorro_setSize(r, 1.0f);
+    
+    // INPUT
+    tDelayL_init(&r->in_delay, 0.f, SAMP(200.f));
+    tOnePole_init(&r->in_filter, 1.f);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tAllpass_init(&r->in_allpass[i], in_allpass_delays[i], SAMP(20.f));
+        tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f));
+    tAllpass_setGain(&r->f1_allpass, 0.7f);
+    
+    tDelayL_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f));
+    tDelayL_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f));
+    tDelayL_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f));
+    
+    tOnePole_init(&r->f1_filter, 1.f);
+    
+    tCycle_init(&r->f1_lfo);
+    tCycle_setFreq(&r->f1_lfo, 0.1f);
+    
+    // FEEDBACK 2
+    tAllpass_init(&r->f2_allpass, SAMP(22.58f), SAMP(100.f));
+    tAllpass_setGain(&r->f2_allpass, 0.7f);
+    
+    tDelayL_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.0f));
+    tDelayL_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.0f));
+    tDelayL_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.0f));
+    
+    tOnePole_init(&r->f2_filter, 1.f);
+    
+    tCycle_init(&r->f2_lfo);
+    tCycle_setFreq(&r->f2_lfo, 0.07f);
+    
+    
+    // PARAMETERS
+    tDattorro_setMix(r, 0.5f);
+    
+    tDattorro_setInputDelay(r,  0.f);
+    
+    tDattorro_setInputFilter(r, 10000.f);
+    
+    tDattorro_setFeedbackFilter(r, 5000.f);
+    
+    tDattorro_setFeedbackGain(r, 0.4f);
+}
+
+void    tDattorro_free              (tDattorro* const r)
+{
+    // INPUT
+    tDelayL_free(&r->in_delay);
+    tOnePole_free(&r->in_filter);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tAllpass_free(&r->in_allpass[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_free(&r->f1_allpass);
+    
+    tDelayL_free(&r->f1_delay_1);
+    tDelayL_free(&r->f1_delay_2);
+    tDelayL_free(&r->f1_delay_3);
+    
+    tOnePole_free(&r->f1_filter);
+    
+    tCycle_free(&r->f1_lfo);
+    
+    // FEEDBACK 2
+    tAllpass_free(&r->f2_allpass);
+    
+    tDelayL_free(&r->f2_delay_1);
+    tDelayL_free(&r->f2_delay_2);
+    tDelayL_free(&r->f2_delay_3);
+    
+    tOnePole_free(&r->f2_filter);
+    
+    tCycle_free(&r->f2_lfo);
+    
+    leaf_free(r);
+}
+
+float   tDattorro_tick              (tDattorro* const r, float input)
+{
+    // INPUT
+    float in_sample = tDelayL_tick(&r->in_delay, input);
+    
+    in_sample = tOnePole_tick(&r->in_filter, in_sample);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
+    }
+    
+    // FEEDBACK 1
+    float f1_sample = in_sample + r->f2_last; // + f2_last_out;
+    
+    tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
+    
+    f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
+    
+    f1_sample = tDelayL_tick(&r->f1_delay_1, f1_sample);
+    
+    f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
+    
+    f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
+    
+    float f1_delay_2_sample = tDelayL_tick(&r->f1_delay_2, f1_sample * 0.5f);
+    
+    r->f1_delay_2_last = f1_delay_2_sample;
+    
+    f1_sample = r->f1_delay_2_last + f1_sample;
+    
+    f1_sample *= r->feedback_gain;
+    
+    r->f1_last = tDelayL_tick(&r->f1_delay_3, f1_sample);
+    
+    // FEEDBACK 2
+    float f2_sample = in_sample + r->f1_last;
+    
+    tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
+    
+    f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
+    
+    f2_sample = tDelayL_tick(&r->f2_delay_1, f2_sample);
+    
+    f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
+    
+    f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
+    
+    float f2_delay_2_sample = tDelayL_tick(&r->f2_delay_2, f2_sample * 0.5f);
+    
+    r->f2_delay_2_last = f2_delay_2_sample;
+    
+    f2_sample = r->f2_delay_2_last + f2_sample;
+    
+    f2_sample *= r->feedback_gain;
+    
+    r->f2_last = tDelayL_tick(&r->f2_delay_3, f2_sample);
+    
+    
+    // TAP OUT 1
+    f1_sample =     tDelayL_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+                    tDelayL_tapOut(&r->f1_delay_1, SAMP(99.8f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f1_delay_2, SAMP(64.2f));
+    
+    f1_sample +=    tDelayL_tapOut(&r->f1_delay_3, SAMP(67.f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_1, SAMP(66.8f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_3, SAMP(35.8f));
+    
+    f1_sample *=    0.14f;
+    
+    // TAP OUT 2
+    f2_sample =     tDelayL_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+                    tDelayL_tapOut(&r->f2_delay_1, SAMP(121.7f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f2_sample +=    tDelayL_tapOut(&r->f2_delay_3, SAMP(89.7f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_1, SAMP(70.8f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_2, SAMP(11.2f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_3, SAMP(4.1f));
+    
+    f2_sample *=    0.14f;
+    
+    float sample = (f1_sample + f2_sample) * 0.5f;
+    
+    return (input * (1.0f - r->mix) + sample * r->mix);
+}
+
+void    tDattorro_setMix            (tDattorro* const r, float mix)
+{
+    r->mix = LEAF_clip(0.0f, mix, 1.0f);
+}
+
+void    tDattorro_setSize           (tDattorro* const r, float size)
+{
+    r->size = LEAF_clip(0.001f, size, 100.0f);
+    r->t = r->size * leaf.sampleRate * 0.001f;
+}
+
+void    tDattorro_setInputDelay     (tDattorro* const r, float preDelay)
+{
+    r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
+    
+    tDelayL_setDelay(&r->in_delay, SAMP(r->predelay));
+}
+
+void    tDattorro_setInputFilter    (tDattorro* const r, float freq)
+{
+    r->input_filter = LEAF_clip(0.0f, freq, 20000.0f);
+    
+    tOnePole_setFreq(&r->in_filter, r->input_filter);
+}
+
+void    tDattorro_setFeedbackFilter (tDattorro* const r, float freq)
+{
+    r->feedback_filter = LEAF_clip(0.0f, freq, 20000.0f);
+    
+    tOnePole_setFreq(&r->f1_filter, r->feedback_filter);
+    tOnePole_setFreq(&r->f2_filter, r->feedback_filter);
+}
+
+void    tDattorro_setFeedbackGain   (tDattorro* const r, float gain)
+{
+    r->feedback_gain = gain;
 }
 
--- a/LEAF/Src/leaf-utilities.c
+++ b/LEAF/Src/leaf-utilities.c
@@ -330,8 +330,8 @@
 {
     int32_t decayIndex;
     
-    if (decay <= 1.0f) {
-        decayIndex = 1;
+    if (decay < 0.0f) {
+        decayIndex = 0.0f;
     } else if (decay < 8192.0f) {
         decayIndex = ((int32_t)(decay * 8.0f)) - 1;
     } else {
--- a/LEAF/Src_cpp/leaf-808.cpp
+++ b/LEAF/Src_cpp/leaf-808.cpp
@@ -123,6 +123,16 @@
     float sample = 0.0f;
     float gainScale = 0.1666f;
     
+
+    float myNoise = tNoise_tick(&hihat->n);
+
+	tSquare_setFreq(&hihat->p[0], ((2.0f + hihat->stretch) * hihat->freq));
+	tSquare_setFreq(&hihat->p[1], ((3.00f + hihat->stretch) * hihat->freq));
+	tSquare_setFreq(&hihat->p[2], ((4.16f + hihat->stretch) * hihat->freq));
+	tSquare_setFreq(&hihat->p[3], ((5.43f + hihat->stretch) * hihat->freq));
+	tSquare_setFreq(&hihat->p[4], ((6.79f + hihat->stretch) * hihat->freq));
+	tSquare_setFreq(&hihat->p[5], ((8.21f + hihat->stretch) * hihat->freq));
+
     for (int i = 0; i < 6; i++)
     {
         sample += tSquare_tick(&hihat->p[i]);
@@ -130,16 +140,16 @@
     
     sample *= gainScale;
     
-    sample = (hihat->oscNoiseMix * sample) + ((1.0f-hihat->oscNoiseMix) * (0.8f * tNoise_tick(&hihat->n)));
+    sample = (hihat->oscNoiseMix * sample) + ((1.0f-hihat->oscNoiseMix) * myNoise);
     
     sample = tSVF_tick(&hihat->bandpassOsc, sample);
     
-    sample *= tEnvelope_tick(&hihat->envGain);
-    
-    sample = 0.85f * LEAF_clip(0.0f, tHighpass_tick(&hihat->highpass, sample), 1.0f);
-    
-    sample += 0.15f * tEnvelope_tick(&hihat->envStick) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick));
-    
+    float myGain = tEnvelope_tick(&hihat->envGain);
+    sample *= (myGain*myGain);//square the output gain envelope
+    sample = tHighpass_tick(&hihat->highpass, sample);
+    sample += ((0.5f * tEnvelope_tick(&hihat->envStick)) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick)));
+    sample = tanhf(sample * 2.0f);
+
     return sample;
 }
 
@@ -146,6 +156,7 @@
 void t808Hihat_setDecay(t808Hihat* const hihat, float decay)
 {
     tEnvelope_setDecay(&hihat->envGain,decay);
+    tEnvelope_setDecay(&hihat->noiseFMGain,decay);
 }
 
 void t808Hihat_setHighpassFreq(t808Hihat* const hihat, float freq)
@@ -153,21 +164,35 @@
     tHighpass_setFreq(&hihat->highpass,freq);
 }
 
+void t808Hihat_setStretch(t808Hihat* const hihat, float stretch)
+{
+    hihat->stretch = stretch;
+}
+
+void t808Hihat_setFM(t808Hihat* const hihat, float FM_amount)
+{
+    hihat->FM_amount = FM_amount;
+}
+
 void t808Hihat_setOscBandpassFreq(t808Hihat* const hihat, float freq)
 {
     tSVF_setFreq(&hihat->bandpassOsc,freq);
 }
 
+void t808Hihat_setOscBandpassQ(t808Hihat* const hihat, float Q)
+{
+    tSVF_setQ(&hihat->bandpassOsc,Q);
+}
 
+void t808Hihat_setStickBandPassFreq(t808Hihat* const hihat, float freq)
+{
+    tSVF_setFreq(&hihat->bandpassStick,freq);
+}
+
+
 void t808Hihat_setOscFreq(t808Hihat* const hihat, float freq)
 {
-    tSquare_setFreq(&hihat->p[0], 2.0f * freq);
-    tSquare_setFreq(&hihat->p[1], 3.00f * freq);
-    tSquare_setFreq(&hihat->p[2], 4.16f * freq);
-    tSquare_setFreq(&hihat->p[3], 5.43f * freq);
-    tSquare_setFreq(&hihat->p[4], 6.79f * freq);
-    tSquare_setFreq(&hihat->p[5], 8.21f * freq);
-    
+		hihat->freq = freq;
 }
 
 void t808Hihat_init(t808Hihat* const hihat)
@@ -184,19 +209,22 @@
     tSVF_init(&hihat->bandpassStick, SVFTypeBandpass,2500.0,1.5f);
     tSVF_init(&hihat->bandpassOsc, SVFTypeBandpass,3500,0.5f);
     
-    tEnvelope_init(&hihat->envGain, 5.0f, 50.0f, OFALSE);
-    tEnvelope_init(&hihat->envStick, 5.0f, 15.0f, OFALSE);
-    
+    tEnvelope_init(&hihat->envGain, 0.0f, 50.0f, OFALSE);
+    tEnvelope_init(&hihat->noiseFMGain, 0.0f, 500.0f, OFALSE);
+    tEnvelope_init(&hihat->envStick, 0.0f, 4.0f, OFALSE);
+
     tHighpass_init(&hihat->highpass, 7000.0f);
     
-    float freq = 40.0f;
+    hihat->freq = 40.0f;
+    hihat->stretch = 0.0f;
+    hihat->FM_amount = 1000.0f;
     
-    tSquare_setFreq(&hihat->p[0], 2.0f * freq);
-    tSquare_setFreq(&hihat->p[1], 3.00f * freq);
-    tSquare_setFreq(&hihat->p[2], 4.16f * freq);
-    tSquare_setFreq(&hihat->p[3], 5.43f * freq);
-    tSquare_setFreq(&hihat->p[4], 6.79f * freq);
-    tSquare_setFreq(&hihat->p[5], 8.21f * freq);
+    tSquare_setFreq(&hihat->p[0], 2.0f * hihat->freq);
+    tSquare_setFreq(&hihat->p[1], 3.00f * hihat->freq);
+    tSquare_setFreq(&hihat->p[2], 4.16f * hihat->freq);
+    tSquare_setFreq(&hihat->p[3], 5.43f * hihat->freq);
+    tSquare_setFreq(&hihat->p[4], 6.79f * hihat->freq);
+    tSquare_setFreq(&hihat->p[5], 8.21f * hihat->freq);
 }
 
 void t808Snare_on(t808Snare* const snare, float vel)
@@ -262,19 +290,19 @@
 {
     for (int i = 0; i < 2; i++)
     {
-        tTriangle_setFreq(&snare->tone[i], snare->tone1Freq + (50.0f * tEnvelope_tick(&snare->toneEnvOsc[i])));
+        tTriangle_setFreq(&snare->tone[i], snare->tone1Freq + (20.0f * tEnvelope_tick(&snare->toneEnvOsc[i])));
         tone[i] = tTriangle_tick(&snare->tone[i]);
         
-        tSVF_setFreq(&snare->toneLowpass[i], 2000 + (500 * tEnvelope_tick(&snare->toneEnvFilter[i])));
+        tSVF_setFreq(&snare->toneLowpass[i], 2000.0f + (500.0f * tEnvelope_tick(&snare->toneEnvFilter[i])));
         tone[i] = tSVF_tick(&snare->toneLowpass[i], tone[i]) * tEnvelope_tick(&snare->toneEnvGain[i]);
     }
     
     float noise = tNoise_tick(&snare->noiseOsc);
-    tSVF_setFreq(&snare->noiseLowpass, snare->noiseFilterFreq +(500 * tEnvelope_tick(&snare->noiseEnvFilter)));
+    tSVF_setFreq(&snare->noiseLowpass, snare->noiseFilterFreq + (1000.0f * tEnvelope_tick(&snare->noiseEnvFilter)));
     noise = tSVF_tick(&snare->noiseLowpass, noise) * tEnvelope_tick(&snare->noiseEnvGain);
     
     float sample = (snare->toneNoiseMix)*(tone[0] * snare->toneGain[0] + tone[1] * snare->toneGain[1]) + (1.0f-snare->toneNoiseMix) * (noise * snare->noiseGain);
-    
+    sample = tanhf(sample * 2.0f);
     return sample;
 }
 
@@ -284,21 +312,24 @@
     for (int i = 0; i < 2; i++)
     {
         tTriangle_init(&snare->tone[i]);
+
         tTriangle_setFreq(&snare->tone[i], ratio[i] * 400.0f);
-        tSVF_init(&snare->toneLowpass[i], SVFTypeLowpass, 2000, 1.0f);
-        tEnvelope_init(&snare->toneEnvOsc[i], 3.0f, 20.0f, OFALSE);
-        tEnvelope_init(&snare->toneEnvGain[i], 10.0f, 200.0f, OFALSE);
-        tEnvelope_init(&snare->toneEnvFilter[i], 3.0f, 200.0f, OFALSE);
+        tSVF_init(&snare->toneLowpass[i], SVFTypeLowpass, 4000, 1.0f);
+        tEnvelope_init(&snare->toneEnvOsc[i], 0.0f, 50.0f, OFALSE);
+        tEnvelope_init(&snare->toneEnvGain[i], 1.0f, 150.0f, OFALSE);
+        tEnvelope_init(&snare->toneEnvFilter[i], 1.0f, 2000.0f, OFALSE);
         
         snare->toneGain[i] = 0.5f;
     }
     
-    
+    snare->tone1Freq = ratio[0] * 100.0f;
+    snare->tone2Freq = ratio[1] * 100.0f;
+    snare->noiseFilterFreq = 3000.0f;
     tNoise_init(&snare->noiseOsc, WhiteNoise);
-    tSVF_init(&snare->noiseLowpass, SVFTypeLowpass, 2000, 3.0f);
-    tEnvelope_init(&snare->noiseEnvGain, 10.0f, 125.0f, OFALSE);
-    tEnvelope_init(&snare->noiseEnvFilter, 3.0f, 100.0f, OFALSE);
-    snare->noiseGain = 0.3f;
+    tSVF_init(&snare->noiseLowpass, SVFTypeLowpass, 12000.0f, 0.8f);
+    tEnvelope_init(&snare->noiseEnvGain, 0.0f, 100.0f, OFALSE);
+    tEnvelope_init(&snare->noiseEnvFilter, 0.0f, 1000.0f, OFALSE);
+    snare->noiseGain = 1.0f;
 }
 
 void        t808Snare_free                  (t808Snare* const snare)
@@ -318,5 +349,70 @@
     tEnvelope_free(&snare->noiseEnvGain);
     tEnvelope_free(&snare->noiseEnvFilter);
 }
+
+
+void        t808Kick_init        			(t808Kick* const kick)
+{
+	tCycle_init(&kick->tone);
+	kick->toneInitialFreq = 40.0f;
+	kick->sighAmountInHz = 7.0f;
+	kick->chirpRatioMinusOne = 3.3f;
+	tCycle_setFreq(&kick->tone, 50.0f);
+	tSVF_init(&kick->toneLowpass, SVFTypeLowpass, 2000.0f, 0.5f);
+	tEnvelope_init(&kick->toneEnvOscChirp, 0.0f, 20.0f, OFALSE);
+	tEnvelope_init(&kick->toneEnvOscSigh, 0.0f, 2500.0f, OFALSE);
+	tEnvelope_init(&kick->toneEnvGain, 0.0f, 800.0f, OFALSE);
+	tNoise_init(&kick->noiseOsc, PinkNoise);
+	tEnvelope_init(&kick->noiseEnvGain, 0.0f, 1.0f, OFALSE);
+	kick->noiseGain = 0.3f;
+}
+
+
+void        t808Kick_free                  (t808Kick* const kick)
+{
+	tCycle_free(&kick->tone);
+	tSVF_free(&kick->toneLowpass);
+	tEnvelope_free(&kick->toneEnvOscChirp);
+	tEnvelope_free(&kick->toneEnvOscSigh);
+	tEnvelope_free(&kick->toneEnvGain);
+	tNoise_free(&kick->noiseOsc);
+	tEnvelope_free(&kick->noiseEnvGain);
+}
+
+float       t808Kick_tick                  (t808Kick* const kick)
+{
+	tCycle_setFreq(&kick->tone, (kick->toneInitialFreq * (1.0f + (kick->chirpRatioMinusOne * tEnvelope_tick(&kick->toneEnvOscChirp)))) + (kick->sighAmountInHz * tEnvelope_tick(&kick->toneEnvOscSigh)));
+	float sample = tCycle_tick(&kick->tone) * tEnvelope_tick(&kick->toneEnvGain);
+	sample+= tNoise_tick(&kick->noiseOsc) * tEnvelope_tick(&kick->noiseEnvGain);
+	//add distortion here
+	sample = tSVF_tick(&kick->toneLowpass, sample);
+	return sample;
+}
+
+void        t808Kick_on                    (t808Kick* const kick, float vel)
+{
+	tEnvelope_on(&kick->toneEnvOscChirp, vel);
+	tEnvelope_on(&kick->toneEnvOscSigh, vel);
+	tEnvelope_on(&kick->toneEnvGain, vel);
+	tEnvelope_on(&kick->noiseEnvGain, vel);
+
+}
+void        t808Kick_setToneFreq          (t808Kick* const kick, float freq)
+{
+	kick->toneInitialFreq = freq;
+
+}
+
+void        t808Kick_setToneDecay         (t808Kick* const kick, float decay)
+{
+	tEnvelope_setDecay(&kick->toneEnvGain,decay);
+	tEnvelope_setDecay(&kick->toneEnvGain,decay * 3.0f);
+}
+void        t808Kick_setNoiseDecay         (t808Kick* const kick, float decay);
+void        t808Kick_setSighAmount         (t808Kick* const kick, float sigh);
+void        t808Kick_setChirpAmount         (t808Kick* const kick, float chirp);
+void        t808Kick_setToneNoiseMix       (t808Kick* const kick, float toneNoiseMix);
+void        t808Kick_setNoiseFilterFreq    (t808Kick* const kick, float noiseFilterFreq);
+void        t808Kick_setNoiseFilterQ       (t808Kick* const kick, float noiseFilterQ);
 
 
--- a/LEAF/Src_cpp/leaf-delay.cpp
+++ b/LEAF/Src_cpp/leaf-delay.cpp
@@ -29,8 +29,6 @@
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
     
-    d->delay = 0.0f;
-    
     d->inPoint = 0;
     d->outPoint = 0;
     
@@ -143,8 +141,6 @@
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
     
-    d->delay = 0.0f;
-    
     d->gain = 1.0f;
     
     d->lastIn = 0.0f;
@@ -206,14 +202,28 @@
     return 0;
 }
 
-float tDelayL_tapOut (tDelayL* const d, uint32_t tapDelay)
+float tDelayL_tapOut (tDelayL* const d, float tapDelay)
 {
-    int32_t tap = d->inPoint - tapDelay - 1;
+    float tap = (float) d->inPoint - tapDelay - 1.f;
     
     // Check for wraparound.
-    while ( tap < 0 )   tap += d->maxDelay;
+    while ( tap < 0.f )   tap += (float)d->maxDelay;
+
+    float alpha = tap - (int)tap;
+    float omAlpha = 1.f - alpha;
+
+    int ptx = (int) tap;
+    
+    // First 1/2 of interpolation
+    float samp = d->buff[ptx] * omAlpha;
+    
+    // Second 1/2 of interpolation
+    if ((ptx + 1) < d->maxDelay)
+        samp += d->buff[ptx+1] * d->alpha;
+    else
+        samp += d->buff[0] * d->alpha;
     
-    return d->buff[tap];
+    return samp;
     
 }
 
@@ -273,8 +283,6 @@
     else                    d->delay = delay;
     
     d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
-    
-    d->delay = 0.0f;
     
     d->gain = 1.0f;
     
--- a/LEAF/Src_cpp/leaf-filter.cpp
+++ b/LEAF/Src_cpp/leaf-filter.cpp
@@ -20,7 +20,44 @@
 #include "../Inc/leaf-wavetables.h"
 #include "../leaf.h"
 
-#endif
+#endif
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void    tAllpass_init(tAllpass* const f, float initDelay, uint32_t maxDelay)
+{
+    f->gain = 0.7f;
+    
+    f->lastOut = 0.0f;
+    
+    tDelayL_init(&f->delay, initDelay, maxDelay);
+}
+
+void    tAllpass_setDelay(tAllpass* const f, float delay)
+{
+    tDelayL_setDelay(&f->delay, delay);
+}
+
+void    tAllpass_free(tAllpass* const f)
+{
+    leaf_free(&f->delay);
+    leaf_free(f);
+}
+
+void    tAllpass_setGain(tAllpass* const f, float gain)
+{
+    f->gain = gain;
+}
+
+float   tAllpass_tick(tAllpass* const f, float input)
+{
+    float s1 = (-f->gain) * f->lastOut + input;
+    
+    float s2 = tDelayL_tick(&f->delay, s1) + (f->gain) * input;
+    
+    f->lastOut = s2;
+    
+    return f->lastOut;
+}
 
 void tButterworth_init(tButterworth* const f, int N, float f1, float f2)
 {
@@ -239,12 +276,12 @@
 }
 
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void    tOnePole_init(tOnePole* const f, float thePole)
+void    tOnePole_init(tOnePole* const f, float freq)
 {
     f->gain = 1.0f;
     f->a0 = 1.0;
     
-    tOnePole_setPole(f, thePole);
+    tOnePole_setFreq(f, freq);
     
     f->lastIn = 0.0f;
     f->lastOut = 0.0f;
@@ -276,6 +313,15 @@
     else                    f->b0 = (1.0f + thePole);
     
     f->a1 = -thePole;
+}
+
+void        tOnePole_setFreq        (tOnePole* const f, float freq)
+{
+    f->b0 = freq * TWO_PI * leaf.invSampleRate;
+    
+    f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+    
+    f->a1 = 1.0f - f->b0;
 }
 
 void    tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -294,7 +340,7 @@
 float   tOnePole_tick(tOnePole* const f, float input)
 {
     float in = input * f->gain;
-    float out = (f->b0 * in) - (f->a1 * f->lastOut);
+    float out = (f->b0 * in) + (f->a1 * f->lastOut);
     
     f->lastIn = in;
     f->lastOut = out;
@@ -679,7 +725,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 +754,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/Src_cpp/leaf-math.cpp
+++ b/LEAF/Src_cpp/leaf-math.cpp
@@ -136,6 +136,91 @@
     else
         return x * ( 27 + x * x ) / ( 27 + 9 * x * x );
 }
+
+
+void LEAF_generate_sine(float* buffer, int size)
+{
+    float phase;
+    for (int i = 0; i < size; i++)
+    {
+        phase = (float) i / (float) size;
+        buffer[i] = sinf(phase * TWO_PI);
+    }
+}
+
+void LEAF_generate_sawtooth(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / harmonic;
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        harmonic++;
+        freq = harmonic * basefreq;
+    }
+}
+
+
+void LEAF_generate_triangle(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp = 1.0f;
+    
+    int count = 0;
+    float mult = 1.0f;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / (float)(harmonic * harmonic);
+        
+        if (count % 2)  mult = -1.0f;
+        else            mult =  1.0f;
+        
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (mult * amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        count++;
+        harmonic += 2;
+        freq = harmonic * basefreq;
+    }
+}
+
+void LEAF_generate_square(float* buffer, float basefreq, int size)
+{
+    int harmonic = 1;
+    float phase = 0.0f;
+    float freq = harmonic * basefreq;
+    float amp = 1.0f;
+    
+    while (freq < (leaf.sampleRate * 0.5))
+    {
+        amp = 1.0f / (float)(harmonic);
+        
+        for (int i = 0; i < size; i++)
+        {
+            phase = (float) i / (float) size;
+            buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
+        }
+        
+        harmonic += 2;
+        freq = harmonic * basefreq;
+    }
+}
+
 
 //-----------------------------------------------------------------------------
 // name: mtof()
--- a/LEAF/Src_cpp/leaf-reverb.cpp
+++ b/LEAF/Src_cpp/leaf-reverb.cpp
@@ -248,12 +248,240 @@
     r->lastOut = out;
     
     return out;
-}
+}
 
-
-
 void     tNRevSampleRateChanged (tNRev* const r)
 {
     for (int i=0; i<6; i++)   r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(r->combDelays[i]) * leaf.invSampleRate / r->t60 ));
+}
+
+// ======================================DATTORRO=========================================
+
+#define SAMP(in) (in*r->t)
+
+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 };
+
+void    tDattorro_init              (tDattorro* const r)
+{
+    tDattorro_setSize(r, 1.0f);
+    
+    // INPUT
+    tDelayL_init(&r->in_delay, 0.f, SAMP(200.f));
+    tOnePole_init(&r->in_filter, 1.f);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tAllpass_init(&r->in_allpass[i], in_allpass_delays[i], SAMP(20.f));
+        tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f));
+    tAllpass_setGain(&r->f1_allpass, 0.7f);
+    
+    tDelayL_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f));
+    tDelayL_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f));
+    tDelayL_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f));
+    
+    tOnePole_init(&r->f1_filter, 1.f);
+    
+    tCycle_init(&r->f1_lfo);
+    tCycle_setFreq(&r->f1_lfo, 0.1f);
+    
+    // FEEDBACK 2
+    tAllpass_init(&r->f2_allpass, SAMP(22.58f), SAMP(100.f));
+    tAllpass_setGain(&r->f2_allpass, 0.7f);
+    
+    tDelayL_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.0f));
+    tDelayL_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.0f));
+    tDelayL_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.0f));
+    
+    tOnePole_init(&r->f2_filter, 1.f);
+    
+    tCycle_init(&r->f2_lfo);
+    tCycle_setFreq(&r->f2_lfo, 0.07f);
+    
+    
+    // PARAMETERS
+    tDattorro_setMix(r, 0.5f);
+    
+    tDattorro_setInputDelay(r,  0.f);
+    
+    tDattorro_setInputFilter(r, 10000.f);
+    
+    tDattorro_setFeedbackFilter(r, 5000.f);
+    
+    tDattorro_setFeedbackGain(r, 0.4f);
+}
+
+void    tDattorro_free              (tDattorro* const r)
+{
+    // INPUT
+    tDelayL_free(&r->in_delay);
+    tOnePole_free(&r->in_filter);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tAllpass_free(&r->in_allpass[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_free(&r->f1_allpass);
+    
+    tDelayL_free(&r->f1_delay_1);
+    tDelayL_free(&r->f1_delay_2);
+    tDelayL_free(&r->f1_delay_3);
+    
+    tOnePole_free(&r->f1_filter);
+    
+    tCycle_free(&r->f1_lfo);
+    
+    // FEEDBACK 2
+    tAllpass_free(&r->f2_allpass);
+    
+    tDelayL_free(&r->f2_delay_1);
+    tDelayL_free(&r->f2_delay_2);
+    tDelayL_free(&r->f2_delay_3);
+    
+    tOnePole_free(&r->f2_filter);
+    
+    tCycle_free(&r->f2_lfo);
+    
+    leaf_free(r);
+}
+
+float   tDattorro_tick              (tDattorro* const r, float input)
+{
+    // INPUT
+    float in_sample = tDelayL_tick(&r->in_delay, input);
+    
+    in_sample = tOnePole_tick(&r->in_filter, in_sample);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
+    }
+    
+    // FEEDBACK 1
+    float f1_sample = in_sample + r->f2_last; // + f2_last_out;
+    
+    tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
+    
+    f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
+    
+    f1_sample = tDelayL_tick(&r->f1_delay_1, f1_sample);
+    
+    f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
+    
+    f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
+    
+    float f1_delay_2_sample = tDelayL_tick(&r->f1_delay_2, f1_sample * 0.5f);
+    
+    r->f1_delay_2_last = f1_delay_2_sample;
+    
+    f1_sample = r->f1_delay_2_last + f1_sample;
+    
+    f1_sample *= r->feedback_gain;
+    
+    r->f1_last = tDelayL_tick(&r->f1_delay_3, f1_sample);
+    
+    // FEEDBACK 2
+    float f2_sample = in_sample + r->f1_last;
+    
+    tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
+    
+    f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
+    
+    f2_sample = tDelayL_tick(&r->f2_delay_1, f2_sample);
+    
+    f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
+    
+    f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
+    
+    float f2_delay_2_sample = tDelayL_tick(&r->f2_delay_2, f2_sample * 0.5f);
+    
+    r->f2_delay_2_last = f2_delay_2_sample;
+    
+    f2_sample = r->f2_delay_2_last + f2_sample;
+    
+    f2_sample *= r->feedback_gain;
+    
+    r->f2_last = tDelayL_tick(&r->f2_delay_3, f2_sample);
+    
+    
+    // TAP OUT 1
+    f1_sample =     tDelayL_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+                    tDelayL_tapOut(&r->f1_delay_1, SAMP(99.8f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f1_delay_2, SAMP(64.2f));
+    
+    f1_sample +=    tDelayL_tapOut(&r->f1_delay_3, SAMP(67.f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_1, SAMP(66.8f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f1_sample -=    tDelayL_tapOut(&r->f2_delay_3, SAMP(35.8f));
+    
+    f1_sample *=    0.14f;
+    
+    // TAP OUT 2
+    f2_sample =     tDelayL_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+                    tDelayL_tapOut(&r->f2_delay_1, SAMP(121.7f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f2_sample +=    tDelayL_tapOut(&r->f2_delay_3, SAMP(89.7f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_1, SAMP(70.8f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_2, SAMP(11.2f));
+    
+    f2_sample -=    tDelayL_tapOut(&r->f1_delay_3, SAMP(4.1f));
+    
+    f2_sample *=    0.14f;
+    
+    float sample = (f1_sample + f2_sample) * 0.5f;
+    
+    return (input * (1.0f - r->mix) + sample * r->mix);
+}
+
+void    tDattorro_setMix            (tDattorro* const r, float mix)
+{
+    r->mix = LEAF_clip(0.0f, mix, 1.0f);
+}
+
+void    tDattorro_setSize           (tDattorro* const r, float size)
+{
+    r->size = LEAF_clip(0.001f, size, 100.0f);
+    r->t = r->size * leaf.sampleRate * 0.001f;
+}
+
+void    tDattorro_setInputDelay     (tDattorro* const r, float preDelay)
+{
+    r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
+    
+    tDelayL_setDelay(&r->in_delay, SAMP(r->predelay));
+}
+
+void    tDattorro_setInputFilter    (tDattorro* const r, float freq)
+{
+    r->input_filter = LEAF_clip(0.0f, freq, 20000.0f);
+    
+    tOnePole_setFreq(&r->in_filter, r->input_filter);
+}
+
+void    tDattorro_setFeedbackFilter (tDattorro* const r, float freq)
+{
+    r->feedback_filter = LEAF_clip(0.0f, freq, 20000.0f);
+    
+    tOnePole_setFreq(&r->f1_filter, r->feedback_filter);
+    tOnePole_setFreq(&r->f2_filter, r->feedback_filter);
+}
+
+void    tDattorro_setFeedbackGain   (tDattorro* const r, float gain)
+{
+    r->feedback_gain = gain;
 }
 
--- 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,12 @@
 
 std::vector<juce::String> cSliderNames =  std::vector<juce::String>
 {
-    "mix"
+    "mix",
+    "predelay",
+    "input filter",
+    "feedback filter",
+    "feedback gain",
+    "size"
 };
 
 std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -14,43 +14,68 @@
 
 static void leaf_pool_report(void);
 static void leaf_pool_dump(void);
-static void run_pool_test(void);
+static void run_pool_test(void);
+
+tDattorro reverb;
+
 
-t808Snare snare;
-
 void    LEAFTest_init            (float sampleRate, int blockSize)
 {
-    LEAFInit(sampleRate, blockSize, &randomNumberGenerator);
-    
-    t808Snare_init(&snare);
-    
+    LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
+
+    tDattorro_init(&reverb);
+    
+    setSliderValue("mix", reverb.mix);
+    setSliderValue("predelay", reverb.predelay / 200.0f);
+    setSliderValue("input filter", reverb.input_filter / 20000.0f);
+    setSliderValue("feedback filter", reverb.feedback_filter / 20000.0f);
+    setSliderValue("feedback gain", reverb.feedback_gain);
+    //setSliderValue("size", reverb.size / 4.0f);
+    
     leaf_pool_report();
 }
 
 int timer = 0;
+
+
+#define CLICK 0
 
-float prev = 0.0;
-
 float   LEAFTest_tick            (float input)
-{
-    float sample = 0.0f;
-    
-    timer++;
-    if (timer == (1 * leaf.sampleRate))
-    {
-        timer = 0;
-        t808Snare_on(&snare, 1.0);
-    }
-
-    sample = t808Snare_tick(&snare);
-    
-    return sample;
-     
+{
+#if CLICK
+    input = 0.0f;
+    
+    timer++;
+    if (timer == (1 * leaf.sampleRate))
+    {
+        timer = 0;
+        
+        input = 1.0f;
+    }
+#endif
+    
+    return tDattorro_tick(&reverb, input);
 }
 
 void    LEAFTest_block           (void)
-{
-    float val = getSliderValue("mix");
+{
+    float val = getSliderValue("mix");
+    tDattorro_setMix(&reverb, val);
+    
+    val = getSliderValue("predelay");
+    tDattorro_setInputDelay(&reverb, val * 200.0f);
+    
+    val = getSliderValue("input filter");
+    tDattorro_setInputFilter(&reverb, val * 20000.0f);
+    
+    val = getSliderValue("feedback filter");
+    tDattorro_setFeedbackFilter(&reverb, val * 20000.0f);
+    
+    val = getSliderValue("feedback gain");
+    tDattorro_setFeedbackGain(&reverb, val);
+    
+    //val = getSliderValue("size");
+    //tDattorro_setSize(&reverb, val * 4.0f);
 }
 
 void    LEAFTest_controllerInput (int cnum, float cval)