shithub: leaf

Download patch

ref: d6d64a92922b89abb17d2e695586ad1fdcb4bf89
parent: 77f442e4ff86a02bd97e5a61e2cbffa6802c7f11
author: Matthew Wang <Matthew@nat-oitwireless-inside-vapornet100-10-9-116-242.princeton.edu>
date: Wed Oct 23 12:27:44 EDT 2019

pass in char* for mempool, updated most objects to use mempool for large/variable size members

--- a/LEAF/Inc/leaf-808.h
+++ b/LEAF/Inc/leaf-808.h
@@ -4,16 +4,16 @@
     Created: 30 Nov 2018 10:24:44am
     Author:  airship
 
-==============================================================================*/
-
-#ifndef LEAF_808_H_INCLUDED
-#define LEAF_808_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//==============================================================================
+==============================================================================*/
+
+#ifndef LEAF_808_H_INCLUDED
+#define LEAF_808_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//==============================================================================
     
 #include "leaf-globals.h"
 #include "leaf-math.h"
@@ -20,9 +20,9 @@
 
 #include "leaf-oscillator.h"
 #include "leaf-utilities.h"
-#include "leaf-filter.h"
-
-//==============================================================================
+#include "leaf-filter.h"
+
+//==============================================================================
     
 // 808 Cowbell
 typedef struct _t808Cowbell {
@@ -50,7 +50,7 @@
 void    t808Cowbell_setFreq          (t808Cowbell* const, float freq);
 void    t808Cowbell_setOscMix        (t808Cowbell* const, float oscMix);
 
-//==============================================================================
+//==============================================================================
     
 // 808 Hihat
 typedef struct _t808Hihat {
@@ -88,8 +88,8 @@
 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
 typedef struct _t808Snare {
@@ -131,7 +131,7 @@
 void        t808Snare_setNoiseFilterFreq    (t808Snare* const, float noiseFilterFreq);
 void        t808Snare_setNoiseFilterQ       (t808Snare* const, float noiseFilterQ);
 
-//==============================================================================
+//==============================================================================
     
 // 808 Kick
 typedef struct _t808Kick {
@@ -169,16 +169,16 @@
 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);
-    
-//==============================================================================
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_808_H_INCLUDED
-
+void        t808Kick_setNoiseFilterQ       (t808Kick* const, float noiseFilterQ);
+    
+//==============================================================================
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_808_H_INCLUDED
+
 //==============================================================================
 
 
--- a/LEAF/Inc/leaf-WDF.h
+++ b/LEAF/Inc/leaf-WDF.h
@@ -64,6 +64,7 @@
 
 //WDF Linear Components
 void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
+void tWDF_free(tWDF* const r);
 float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
 
 void tWDF_setValue(tWDF* const r, float value);
--- a/LEAF/Inc/leaf-formant.h
+++ b/LEAF/Inc/leaf-formant.h
@@ -4,21 +4,21 @@
     Created: 30 Nov 2018 11:03:37am
     Author:  airship
 
-==============================================================================*/
-
-#ifndef LEAF_FORMANT_H_INCLUDED
-#define LEAF_FORMANT_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
+==============================================================================*/
+
+#ifndef LEAF_FORMANT_H_INCLUDED
+#define LEAF_FORMANT_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
 #endif
 
-//==============================================================================
+//==============================================================================
     
 #include "leaf-globals.h"
 #include "leaf-math.h"
 
-//==============================================================================
+//==============================================================================
     
 #define FORD 7
 #define FORMANT_BUFFER_SIZE 2048
@@ -26,20 +26,21 @@
 typedef struct _tFormantShifter
 {
     int ford;
+    int bufsize;
     float falph;
     float flamb;
-    float fk[FORD];
-    float fb[FORD];
-    float fc[FORD];
-    float frb[FORD];
-    float frc[FORD];
-    float fsig[FORD];
-    float fsmooth[FORD];
+    float* fk;
+    float* fb;
+    float* fc;
+    float* frb;
+    float* frc;
+    float* fsig;
+    float* fsmooth;
     float fhp;
     float flp;
     float flpa;
-    float fbuff[FORD][FORMANT_BUFFER_SIZE];
-    float ftvec[FORD];
+    float** fbuff;
+    float* ftvec;
     float fmute;
     float fmutealph;
     unsigned int cbi;
@@ -46,21 +47,21 @@
     
 } tFormantShifter;
 
-void        tFormantShifter_init            (tFormantShifter* const);
+void        tFormantShifter_init            (tFormantShifter* const, int bufsize, int order);
 void        tFormantShifter_free            (tFormantShifter* const);
 
 float       tFormantShifter_tick            (tFormantShifter* const, float input, float fwarp);
 float       tFormantShifter_remove          (tFormantShifter* const, float input);
 float       tFormantShifter_add             (tFormantShifter* const, float input, float fwarp);
-void        tFormantShifter_ioSamples       (tFormantShifter* const, float* in, float* out, int size, float fwarp);
+void        tFormantShifter_ioSamples       (tFormantShifter* const, float* in, float* out, int size, float fwarp);
     
-//==============================================================================
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_FORMANT_H_INCLUDED
-
+//==============================================================================
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_FORMANT_H_INCLUDED
+
 //==============================================================================
 
--- a/LEAF/Inc/leaf-globals.h
+++ b/LEAF/Inc/leaf-globals.h
@@ -41,17 +41,9 @@
     
 //==============================================================================
 
-#define NUM_VOICES 8
-#define NUM_SHIFTERS 4
-#define POLY_NUM_MAX_VOICES 8
-#define NUM_OSC 4
-#define INV_NUM_OSC (1.0f / NUM_OSC)
 #define PS_FRAME_SIZE 1024 // SNAC_FRAME_SIZE in leaf-pitch.h should match (or be smaller than?) this
 #define ENV_WINDOW_SIZE 1024
 #define ENV_HOP_SIZE 256
-
-#define     DELAY_LENGTH        16000   // The maximum delay length of all Delay/DelayL/DelayA components.
-                                            // Feel free to change to suit memory constraints or desired delay max length / functionality.
     
 union unholy_t { /* a union between a float and an integer */
     float f;
--- a/LEAF/Inc/leaf-mempool.h
+++ b/LEAF/Inc/leaf-mempool.h
@@ -75,7 +75,7 @@
     int next;
 } mpool_t;
 
-void mpool_create (size_t size, mpool_t* pool);
+void mpool_create (char* memory, size_t size, mpool_t* pool);
 
 void *mpool_alloc(size_t size, mpool_t* pool);
 void mpool_free(void* ptr, mpool_t* pool);
@@ -84,7 +84,7 @@
 size_t mpool_get_used(mpool_t* pool);
 
 
-void leaf_pool_init(size_t size);
+void leaf_pool_init(char* memory, size_t size);
 
 void* leaf_alloc(size_t size);
 void leaf_free(void* ptr);
--- a/LEAF/Inc/leaf-midi.h
+++ b/LEAF/Inc/leaf-midi.h
@@ -25,18 +25,20 @@
 /* tPoly */
 typedef struct _tPoly
 {
-    tStack* stack;
-    tStack* orderStack;
+    tStack stack;
+    tStack orderStack;
     
-    tRamp* ramp[POLY_NUM_MAX_VOICES];
-    float rampVals[POLY_NUM_MAX_VOICES];
-    oBool firstReceived[POLY_NUM_MAX_VOICES];
+    tRamp* ramp;
+    float* rampVals;
+    oBool* firstReceived;
     float glideTime;
     oBool pitchGlideIsActive;
     
     int numVoices;
+    int maxNumVoices;
     
-    int voices[POLY_NUM_MAX_VOICES][2];
+    //int voices[POLY_NUM_MAX_VOICES][2];
+    int** voices;
     
     int notes[128][2];
     
@@ -47,7 +49,7 @@
     int lastVoiceToChange;
     
     float pitchBend;
-    tRamp* pitchBendRamp;
+    tRamp pitchBendRamp;
     
     int currentNote;
     int currentVoice;
@@ -57,7 +59,7 @@
 } tPoly;
 
 /* MPoly*/
-void    tPoly_init(tPoly* const, int numVoices);
+void    tPoly_init(tPoly* const, int maxNumVoices);
 void    tPoly_free(tPoly* const);
 
 //ADDING A NOTE
--- a/LEAF/Inc/leaf-oversampler.h
+++ b/LEAF/Inc/leaf-oversampler.h
@@ -33,6 +33,7 @@
 } tOversampler;
 
 void        tOversampler_init(tOversampler* const, int order, oBool extraQuality);
+void        tOversampler_free(tOversampler* const);
 void        tOversampler_upsample(tOversampler* const, float input, float* output);
 float       tOversampler_downsample(tOversampler *const os, float* input);
 float       tOversampler_tick(tOversampler* const, float input, float (*effectTick)(float));
--- a/LEAF/Inc/leaf-pitch.h
+++ b/LEAF/Inc/leaf-pitch.h
@@ -6,13 +6,13 @@
     Author:  airship
 
   ==============================================================================
-*/
-
-#ifndef LEAF_PITCH_H_INCLUDED
-#define LEAF_PITCH_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
+*/
+
+#ifndef LEAF_PITCH_H_INCLUDED
+#define LEAF_PITCH_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
 #endif
 
 //==============================================================================
@@ -22,8 +22,8 @@
 
 #include "leaf-filter.h"
 #include "leaf-utilities.h"
-#include "leaf.h"
-//==============================================================================
+#include "../leaf.h"
+//==============================================================================
     
 #define DEFPITCHRATIO 2.0f
 #define DEFTIMECONSTANT 100.0f
@@ -32,93 +32,9 @@
 #define FBA 20
 #define HPFREQ 40.0f
 
-//==============================================================================
-    
-/* tSOLAD : pitch shifting algorithm that underlies tPitchShifter etc */
-#define LOOPSIZE (2048*2)      // (4096*2) // loop size must be power of two
-#define LOOPMASK (LOOPSIZE - 1)
-#define PITCHFACTORDEFAULT 1.0f
-#define INITPERIOD 64.0f
-#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
-#define MINPERIOD 8.0f
 
-typedef struct _tSOLAD
-{
-    uint16_t timeindex;              // current reference time, write index
-    uint16_t blocksize;              // signal input / output block size
-    float pitchfactor;        // pitch factor between 0.25 and 4
-    float readlag;            // read pointer's lag behind write pointer
-    float period;             // period length in input signal
-    float jump;               // read pointer jump length and direction
-    float xfadelength;        // crossfade length expressed at input sample rate
-    float xfadevalue;         // crossfade phase and value
-
-    float* delaybuf;
+//==============================================================================
     
-} tSOLAD;
-
-void    tSOLAD_init             (tSOLAD* const);
-void    tSOLAD_free             (tSOLAD* const);
-
-// send one block of input samples, receive one block of output samples
-void    tSOLAD_ioSamples        (tSOLAD *w, float* in, float* out, int blocksize);
-
-// set periodicity analysis data
-void    tSOLAD_setPeriod        (tSOLAD *w, float period);
-
-// set pitch factor between 0.25 and 4
-void    tSOLAD_setPitchFactor   (tSOLAD *w, float pitchfactor);
-
-// force readpointer lag
-void    tSOLAD_setReadLag       (tSOLAD *w, float readlag);
-
-// reset state variables
-void    tSOLAD_resetState       (tSOLAD *w);
-
-//==============================================================================
-    
-// tSNAC: period detector
-#define SNAC_FRAME_SIZE 1024           // default analysis framesize // should be the same as (or smaller than?) PS_FRAME_SIZE
-#define DEFOVERLAP 1                // default overlap
-#define DEFBIAS 0.2f        // default bias
-#define DEFMINRMS 0.003f   // default minimum RMS
-#define SEEK 0.85f       // seek-length as ratio of framesize
-
-typedef struct _tSNAC
-{
-	float* inputbuf;
-	float* processbuf;
-	float* spectrumbuf;
-	float* biasbuf;
-    uint16_t timeindex;
-    uint16_t framesize;
-    uint16_t overlap;
-    uint16_t periodindex;
-    
-    float periodlength;
-    float fidelity;
-    float biasfactor;
-    float minrms;
-    
-} tSNAC;
-
-
-
-
-void    tSNAC_init          (tSNAC* const, int overlaparg);    // constructor
-void    tSNAC_free          (tSNAC* const);    // destructor
-
-void    tSNAC_ioSamples     (tSNAC *s, float *in, float *out, int size);
-void    tSNAC_setOverlap    (tSNAC *s, int lap);
-void    tSNAC_setBias       (tSNAC *s, float bias);
-void    tSNAC_setMinRMS     (tSNAC *s, float rms);
-
-/*To get freq, perform SAMPLE_RATE/snac_getperiod() */
-float   tSNAC_getPeriod     (tSNAC *s);
-float   tSNAC_getfidelity   (tSNAC *s);
-
-//==============================================================================
-    
 // Pitch shifter 
 typedef struct _tPitchShifter
 {
@@ -164,7 +80,7 @@
 void        tPitchShifter_setWindowSize     (tPitchShifter* const, int ws);
 float       tPitchShifter_getPeriod         (tPitchShifter* const);
 
-//==============================================================================
+//==============================================================================
     
 // Period detection
 typedef struct _tPeriod
@@ -203,7 +119,7 @@
 void        tPeriod_setHopSize              (tPeriod* p, int hs);
 void        tPeriod_setWindowSize           (tPeriod* p, int ws);
 
-//==============================================================================
+//==============================================================================
     
 // Pitch shift
 typedef struct _tPitchShift
@@ -234,12 +150,12 @@
 float       tPitchShift_shiftToFreq         (tPitchShift* const, float freq);
 void        tPitchShift_setPitchFactor      (tPitchShift* const, float pf);
 
-//==============================================================================
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_PITCH_H_INCLUDED
-
+//==============================================================================
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_PITCH_H_INCLUDED
+
 //==============================================================================
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -7,22 +7,22 @@
 ==============================================================================*/
 
 #ifndef LEAF_REVERB_H_INCLUDED
-#define LEAF_REVERB_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
+#define LEAF_REVERB_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
 #endif
 
-//==============================================================================
+//==============================================================================
     
 #include "leaf-globals.h"
 #include "leaf-math.h"
 
-#include "leaf-delay.h"
-#include "leaf-filter.h"
+#include "leaf-delay.h"
+#include "leaf-filter.h"
 #include "leaf-oscillator.h"
 
-//==============================================================================
+//==============================================================================
 
 /* PRCRev: Reverb, reimplemented from STK (Cook and Scavone). */
 typedef struct _tPRCRev
@@ -31,8 +31,8 @@
     
     float inv_441;
     
-    tDelay* allpassDelays[2];
-    tDelay* combDelay;
+    tDelay allpassDelays[2];
+    tDelay combDelay;
     float allpassCoeff;
     float combCoeff;
     
@@ -60,8 +60,8 @@
     
     float inv_sr, inv_441;
     
-    tDelay* allpassDelays[8];
-    tDelay* combDelays[6];
+    tDelay allpassDelays[8];
+    tDelay combDelays[6];
     float allpassCoeff;
     float combCoeffs[6];
     float lowpassState;
@@ -81,68 +81,68 @@
 // 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, size_max, t;
-    
-    float   f1_delay_2_last,
-    f2_delay_2_last;
-    
-    float   f1_last,
-    f2_last;
-    
-    // INPUT
-    tTapeDelay  in_delay;
-    tOnePole    in_filter;
-    tAllpass    in_allpass[4];
-    
-    // FEEDBACK 1
-    tAllpass    f1_allpass;
-    tTapeDelay  f1_delay_1;
-    tOnePole    f1_filter;
-    tTapeDelay  f1_delay_2;
-    tTapeDelay  f1_delay_3;
-    tHighpass   f1_hp;
-    
-    tCycle      f1_lfo;
-    
-    // FEEDBACK 2
-    tAllpass    f2_allpass;
-    tTapeDelay  f2_delay_1;
-    tOnePole    f2_filter;
-    tTapeDelay  f2_delay_2;
-    tTapeDelay  f2_delay_3;
-    tHighpass   f2_hp;
-    
-    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);
-    
-#ifdef __cplusplus
-}
+//==============================================================================
+
+typedef struct _tDattorro
+{
+    float   predelay;
+    float   input_filter;
+    float   feedback_filter;
+    float   feedback_gain;
+    float   mix;
+    
+    
+    float   size, size_max, t;
+    
+    float   f1_delay_2_last,
+    f2_delay_2_last;
+    
+    float   f1_last,
+    f2_last;
+    
+    // INPUT
+    tTapeDelay  in_delay;
+    tOnePole    in_filter;
+    tAllpass    in_allpass[4];
+    
+    // FEEDBACK 1
+    tAllpass    f1_allpass;
+    tTapeDelay  f1_delay_1;
+    tOnePole    f1_filter;
+    tTapeDelay  f1_delay_2;
+    tTapeDelay  f1_delay_3;
+    tHighpass   f1_hp;
+    
+    tCycle      f1_lfo;
+    
+    // FEEDBACK 2
+    tAllpass    f2_allpass;
+    tTapeDelay  f2_delay_1;
+    tOnePole    f2_filter;
+    tTapeDelay  f2_delay_2;
+    tTapeDelay  f2_delay_3;
+    tHighpass   f2_hp;
+    
+    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);
+    
+#ifdef __cplusplus
+}
 #endif
 
-#endif  // LEAF_REVERB_H_INCLUDED
-
+#endif  // LEAF_REVERB_H_INCLUDED
+
 //==============================================================================
--- a/LEAF/Inc/leaf-sample.h
+++ b/LEAF/Inc/leaf-sample.h
@@ -95,7 +95,7 @@
 
     } tSampler;
     
-    void    tSampler_init      (tSampler* const, tBuffer* s);
+    void    tSampler_init      (tSampler* const, tBuffer* const);
     void    tSampler_free      (tSampler* const);
     
     float   tSampler_tick      (tSampler* const);
--- a/LEAF/Inc/leaf-string.h
+++ b/LEAF/Inc/leaf-string.h
@@ -7,13 +7,13 @@
 
   ==============================================================================
 */
-
-#ifndef LEAF_STRING_H_INCLUDED
-#define LEAF_STRING_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+
+#ifndef LEAF_STRING_H_INCLUDED
+#define LEAF_STRING_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
     
 //==============================================================================
 
@@ -29,10 +29,10 @@
 /* Karplus Strong model */
 typedef struct _tPluck
 {
-    tDelayA*     delayLine; // Allpass or Linear??  big difference...
-    tOneZero*    loopFilter;
-    tOnePole*    pickFilter;
-    tNoise*      noise;
+    tDelayA     delayLine; // Allpass or Linear??  big difference...
+    tOneZero    loopFilter;
+    tOnePole    pickFilter;
+    tNoise      noise;
     
     float lastOut;
     float loopGain;
@@ -65,16 +65,16 @@
 // tPluck Utilities.
 float       tPluck_getLastOut    (tPluck*  const);
 
-//==============================================================================
+//==============================================================================
     
 /* Stif Karplus Strong model */
 typedef struct _tStifKarp
 {
-    tDelayA*  delayLine;
-    tDelayL* combDelay;
-    tOneZero* filter;
-    tNoise*   noise;
-    tBiQuad*  biquad[4];
+    tDelayA  delayLine;
+    tDelayL combDelay;
+    tOneZero filter;
+    tNoise   noise;
+    tBiQuad  biquad[4];
     
     
     
@@ -132,12 +132,12 @@
 // tStifKarp utilities.
 float       tStifKarp_getLastOut         (tStifKarp*  const);
 
-//==============================================================================
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_STRING_H_INCLUDED
-
+//==============================================================================
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_STRING_H_INCLUDED
+
 //==============================================================================
--- a/LEAF/Inc/leaf-utilities.h
+++ b/LEAF/Inc/leaf-utilities.h
@@ -390,6 +390,88 @@
 void    tEnv_processBlock   (tEnv* const, float* in);
 
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+/* tSOLAD : pitch shifting algorithm that underlies tPitchShifter etc */
+#define LOOPSIZE (2048*2)      // (4096*2) // loop size must be power of two
+#define LOOPMASK (LOOPSIZE - 1)
+#define PITCHFACTORDEFAULT 1.0f
+#define INITPERIOD 64.0f
+#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
+#define MINPERIOD 8.0f
+    
+typedef struct _tSOLAD
+{
+    uint16_t timeindex;              // current reference time, write index
+    uint16_t blocksize;              // signal input / output block size
+    float pitchfactor;        // pitch factor between 0.25 and 4
+    float readlag;            // read pointer's lag behind write pointer
+    float period;             // period length in input signal
+    float jump;               // read pointer jump length and direction
+    float xfadelength;        // crossfade length expressed at input sample rate
+    float xfadevalue;         // crossfade phase and value
+    
+    float* delaybuf;
+    
+} tSOLAD;
+
+void    tSOLAD_init             (tSOLAD* const);
+void    tSOLAD_free             (tSOLAD* const);
+
+// send one block of input samples, receive one block of output samples
+void    tSOLAD_ioSamples        (tSOLAD *w, float* in, float* out, int blocksize);
+
+// set periodicity analysis data
+void    tSOLAD_setPeriod        (tSOLAD *w, float period);
+
+// set pitch factor between 0.25 and 4
+void    tSOLAD_setPitchFactor   (tSOLAD *w, float pitchfactor);
+
+// force readpointer lag
+void    tSOLAD_setReadLag       (tSOLAD *w, float readlag);
+
+// reset state variables
+void    tSOLAD_resetState       (tSOLAD *w);
+    
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+// tSNAC: period detector
+#define SNAC_FRAME_SIZE 1024           // default analysis framesize // should be the same as (or smaller than?) PS_FRAME_SIZE
+#define DEFOVERLAP 1                // default overlap
+#define DEFBIAS 0.2f        // default bias
+#define DEFMINRMS 0.003f   // default minimum RMS
+#define SEEK 0.85f       // seek-length as ratio of framesize
+
+typedef struct _tSNAC
+{
+    float* inputbuf;
+    float* processbuf;
+    float* spectrumbuf;
+    float* biasbuf;
+    uint16_t timeindex;
+    uint16_t framesize;
+    uint16_t overlap;
+    uint16_t periodindex;
+    
+    float periodlength;
+    float fidelity;
+    float biasfactor;
+    float minrms;
+    
+} tSNAC;
+
+void    tSNAC_init          (tSNAC* const, int overlaparg);    // constructor
+void    tSNAC_free          (tSNAC* const);    // destructor
+
+void    tSNAC_ioSamples     (tSNAC *s, float *in, float *out, int size);
+void    tSNAC_setOverlap    (tSNAC *s, int lap);
+void    tSNAC_setBias       (tSNAC *s, float bias);
+void    tSNAC_setMinRMS     (tSNAC *s, float rms);
+
+/*To get freq, perform SAMPLE_RATE/snac_getperiod() */
+float   tSNAC_getPeriod     (tSNAC *s);
+float   tSNAC_getfidelity   (tSNAC *s);
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
 #ifdef __cplusplus
 }
--- a/LEAF/Inc/leaf-vocoder.h
+++ b/LEAF/Inc/leaf-vocoder.h
@@ -7,10 +7,10 @@
 ==============================================================================*/
 
 #ifndef LEAF_VOCODER_H_INCLUDED
-#define LEAF_VOCODER_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
+#define LEAF_VOCODER_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
 #endif
 
 //==============================================================================
@@ -22,16 +22,17 @@
 
 /* tTalkbox */
 #define NUM_TALKBOX_PARAM 4
-#define TALKBOX_BUFFER_LENGTH   1024    // Every talkbox instance introduces 5 buffers of this size - was originally 1600
 
 typedef struct _tTalkbox
 {
     float param[NUM_TALKBOX_PARAM];
     
-    ///global internal variables
-    float car0[TALKBOX_BUFFER_LENGTH], car1[TALKBOX_BUFFER_LENGTH];
-    float window[TALKBOX_BUFFER_LENGTH];
-    float buf0[TALKBOX_BUFFER_LENGTH], buf1[TALKBOX_BUFFER_LENGTH];
+    int bufsize;
+    float* car0;
+    float* car1;
+    float* window;
+    float* buf0;
+    float* buf1;
     
     float emphasis;
     int32_t K, N, O, pos;
@@ -41,7 +42,7 @@
     
 } tTalkbox;
 
-void        tTalkbox_init        (tTalkbox* const);
+void        tTalkbox_init        (tTalkbox* const, int bufsize);
 void        tTalkbox_free        (tTalkbox* const);
 float       tTalkbox_tick        (tTalkbox* const, float synth, float voice);
 void        tTalkbox_update      (tTalkbox* const);
@@ -78,11 +79,11 @@
 void        tVocoder_suspend     (tVocoder* const);
 
 //==============================================================================
-
-#ifdef __cplusplus
-}
-#endif
+
+#ifdef __cplusplus
+}
+#endif
         
-#endif  // LEAF_VOCODER_H_INCLUDED
-
+#endif  // LEAF_VOCODER_H_INCLUDED
+
 //==============================================================================
--- a/LEAF/Inc/leaf-wavefolder.h
+++ b/LEAF/Inc/leaf-wavefolder.h
@@ -22,16 +22,6 @@
 //==============================================================================
 
 /* tLockhartWavefolder */
-#define THRESH 10e-10
-#define ILL_THRESH 10e-10
-#define LOCKHART_RL 7.5e3
-#define LOCKHART_R 15e3
-#define LOCKHART_VT 26e-3
-#define LOCKHART_Is 10e-16
-#define LOCKHART_A 2.0*LOCKHART_RL/LOCKHART_R
-#define LOCKHART_B (LOCKHART_R+2.0*LOCKHART_RL)/(LOCKHART_VT*LOCKHART_R)
-#define LOCKHART_D (LOCKHART_RL*LOCKHART_Is)/LOCKHART_VT
-#define VT_DIV_B LOCKHART_VT/LOCKHART_B
 
 typedef struct _tLockhartWavefolder
 {
--- a/LEAF/Src/leaf-WDF.c
+++ b/LEAF/Src/leaf-WDF.c
@@ -32,6 +32,7 @@
 
 static float get_reflected_wave_for_ideal(tWDF* const n, float input, float incident_wave);
 static float get_reflected_wave_for_diode(tWDF* const n, float input, float incident_wave);
+static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave);
 
 //WDF
 void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
@@ -143,10 +144,19 @@
     }
     else if (r->type == DiodePair)
     {
-        //n->calculate_reflected_wave = &calculate_reflected_wave_for_ideal;
+        r->port_resistance_up = tWDF_getPortResistance(child);
+        r->port_conductance_up = 1.0f / r->port_resistance_up;
+        
+        r->get_reflected_wave_down = &get_reflected_wave_for_diode_pair;
+        r->get_port_resistance = &get_port_resistance_for_root;
     }
 }
 
+void tWDF_free(tWDF* const r)
+{
+    leaf_free(r);
+}
+
 float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged)
 {
     tWDF* child;
@@ -315,11 +325,13 @@
 
 static void set_incident_wave_for_inverter(tWDF* const r, float incident_wave, float input)
 {
+    r->incident_wave_up = incident_wave;
     tWDF_setIncidentWave(r->child_left, -1.0f * incident_wave, input);
 }
 
 static void set_incident_wave_for_series(tWDF* const r, float incident_wave, float input)
 {
+    r->incident_wave_up = incident_wave;
 	float gamma_left = r->port_resistance_left * r->gamma_zero;
 	float gamma_right = r->port_resistance_right * r->gamma_zero;
 	float left_wave = tWDF_getReflectedWaveUp(r->child_left, input);
@@ -336,6 +348,7 @@
 
 static void set_incident_wave_for_parallel(tWDF* const r, float incident_wave, float input)
 {
+    r->incident_wave_up = incident_wave;
 	float gamma_left = r->port_conductance_left * r->gamma_zero;
 	float gamma_right = r->port_conductance_right * r->gamma_zero;
 	float left_wave = tWDF_getReflectedWaveUp(r->child_left, input);
@@ -376,7 +389,8 @@
 static float get_reflected_wave_for_series(tWDF* const r, float input)
 {
 	//-( downPorts[0]->a + downPorts[1]->a );
-	return (-1.0f * (tWDF_getReflectedWaveUp(r->child_left, input) + tWDF_getReflectedWaveUp(r->child_right, input)));
+    r->reflected_wave_up = (-1.0f * (tWDF_getReflectedWaveUp(r->child_left, input) + tWDF_getReflectedWaveUp(r->child_right, input)));
+	return r->reflected_wave_up;
 }
 
 static float get_reflected_wave_for_parallel(tWDF* const r, float input)
@@ -384,14 +398,10 @@
 	float gamma_left = r->port_conductance_left * r->gamma_zero;
 	float gamma_right = r->port_conductance_right * r->gamma_zero;
 	//return ( dl * downPorts[0]->a + dr * downPorts[1]->a );
-	return (gamma_left * tWDF_getReflectedWaveUp(r->child_left, input) + gamma_right * tWDF_getReflectedWaveUp(r->child_right, input));
+    r->reflected_wave_up = (gamma_left * tWDF_getReflectedWaveUp(r->child_left, input) + gamma_right * tWDF_getReflectedWaveUp(r->child_right, input));
+	return r->reflected_wave_up;
 }
 
-float tWDFNonlinear_getReflectedWaveDown(tWDF*  const n, float input, float incident_wave)
-{
-    return n->get_reflected_wave_down(n, input, incident_wave);
-}
-
 static float get_reflected_wave_for_ideal(tWDF* const n, float input, float incident_wave)
 {
     return (2.0f * input) - incident_wave;
@@ -446,4 +456,14 @@
     float a = incident_wave;
     float r = n->port_resistance_up;
     return a + 2.0f*r*Is_DIODE - 2.0f*VT_DIODE*lambertW(a, r, Is_DIODE, 1.0f/VT_DIODE);
+}
+
+static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave)
+{
+    float a = incident_wave;
+    float sgn = 0.0f;
+    if (a > 0.0f) sgn = 1.0f;
+    else if (a < 0.0f) sgn = -1.0f;
+    float r = n->port_resistance_up;
+    return a + 2 * sgn * (r*Is_DIODE - VT_DIODE*lambertW(sgn*a, r, Is_DIODE, 1.0f/VT_DIODE));
 }
--- a/LEAF/Src/leaf-filter.c
+++ b/LEAF/Src/leaf-filter.c
@@ -821,8 +821,8 @@
 }
 
 void	tFIR_init(tFIR* const fir, float* coeffs, int numTaps){
-	fir->coeff = coeffs;
     fir->numTaps = numTaps;
+    fir->coeff = coeffs;
     fir->past = (float*)leaf_alloc(sizeof(float) * fir->numTaps);
     for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
 }
@@ -835,4 +835,8 @@
 	return y;
 }
 
-void	tFIR_free(tFIR* const fir){}
+void	tFIR_free(tFIR* const fir)
+{
+    leaf_free(fir->past);
+    leaf_free(fir);
+}
--- a/LEAF/Src/leaf-formant.c
+++ b/LEAF/Src/leaf-formant.c
@@ -16,9 +16,26 @@
 #endif
 
 
-void tFormantShifter_init(tFormantShifter* const fs)
+void tFormantShifter_init(tFormantShifter* const fs, int bufsize, int order)
 {
-    fs->ford = FORD;
+    fs->ford = order;
+    fs->bufsize = bufsize;
+    fs->fk = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->fb = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->fc = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->frb = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->frc = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->fsig = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->fsmooth = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    fs->ftvec = (float*) leaf_alloc(sizeof(float) * fs->ford);
+    
+    fs->fbuff = (float**) leaf_alloc(sizeof(float*) * fs->ford);
+    for (int i = 0; i < fs->ford; i++)
+    {
+        fs->fbuff[i] = (float*) leaf_alloc(sizeof(float) * fs->bufsize);
+    }
+    
+    
     fs->falph = powf(0.001f, 80.0f / (leaf.sampleRate));
     fs->flamb = -(0.8517f*sqrt(atanf(0.06583f*leaf.sampleRate))-0.1916f);
     fs->fhp = 0.0f;
@@ -31,6 +48,20 @@
 
 void tFormantShifter_free(tFormantShifter* const fs)
 {
+    leaf_free(fs->fk);
+    leaf_free(fs->fb);
+    leaf_free(fs->fc);
+    leaf_free(fs->frb);
+    leaf_free(fs->frc);
+    leaf_free(fs->fsig);
+    leaf_free(fs->fsmooth);
+    leaf_free(fs->ftvec);
+    for (int i = 0; i < fs->ford; i++)
+    {
+        leaf_free(fs->fbuff[i]);
+    }
+    leaf_free(fs->fbuff);
+    
     leaf_free(fs);
 }
 
@@ -42,8 +73,7 @@
 
 float tFormantShifter_remove(tFormantShifter* fs, float in)
 {
-    float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, fk, tf2, f0resp, f1resp, frlamb;
-    int outindex = 0;
+    float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, fk;
     int ti4;
     ford = fs->ford;
     falph = fs->falph;
@@ -73,7 +103,7 @@
         fa = fa - tf*fc;
     }
     fs->cbi++;
-    if(fs->cbi >= FORMANT_BUFFER_SIZE)
+    if(fs->cbi >= fs->bufsize)
     {
         fs->cbi = 0;
     }
@@ -83,8 +113,7 @@
 
 float tFormantShifter_add(tFormantShifter* fs, float in, float fwarp)
 {
-    float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, fk, tf2, f0resp, f1resp, frlamb;
-    int outindex = 0;
+    float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
     int ti4;
     ford = fs->ford;
     falph = fs->falph;
--- a/LEAF/Src/leaf-mempool.c
+++ b/LEAF/Src/leaf-mempool.c
@@ -36,24 +36,21 @@
 
 /* written with C99 style */
 
+#if _WIN32 || _WIN64
 
-#include "../Inc/leaf-mempool.h"
-#include "leaf.h"
-#define NUM_BLOCKS 50
+#include "..\Inc\leaf-mempool.h"
+#include "..\leaf.h"
 
-#ifdef STM32
+#else
 
-char memory[MPOOL_POOL_SIZE] __ATTR_RAM_D2;
+#include "../Inc/leaf-mempool.h"
+#include "../leaf.h"
 
-#else
-char memory[MPOOL_POOL_SIZE];
 #endif
 
+#define NUM_BLOCKS 50
 
 mpool_pool_t blocks[NUM_BLOCKS];
-
-
- //
 mpool_t leaf_pool;
 
 /**
@@ -65,10 +62,8 @@
 /**
  * create memory pool
  */
-void mpool_create (size_t size, mpool_t* pool)
+void mpool_create (char* memory, size_t size, mpool_t* pool)
 {
-    if (size > MPOOL_POOL_SIZE) size = MPOOL_POOL_SIZE;
-    
     pool->mpool = &blocks[0];
     
     pool->mpool->pool = (void*)memory;
@@ -78,12 +73,12 @@
     pool->usize  = 0;
     pool->msize  = size;
     
-    for (int i = 0; i < MPOOL_POOL_SIZE; i++) memory[i]=0;
+    for (int i = 0; i < size; i++) memory[i]=0;
 }
 
-void leaf_pool_init(size_t size)
+void leaf_pool_init(char* memory, size_t size)
 {
-    mpool_create(size, &leaf_pool);
+    mpool_create(memory, size, &leaf_pool);
 }
 
 /**
@@ -195,7 +190,7 @@
 
 void* leaf_pool_get_pool(void)
 {
-    float* buff = (float*)memory;
+    float* buff = (float*)leaf_pool.mpool->pool;
     
     return buff;
 }
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -17,9 +17,10 @@
 #endif
 
 // POLY
-void tPoly_init(tPoly* const poly, int numVoices)
+void tPoly_init(tPoly* const poly, int maxNumVoices)
 {
-    poly->numVoices = numVoices;
+    poly->numVoices = maxNumVoices;
+    poly->maxNumVoices = maxNumVoices;
     poly->lastVoiceToChange = 0;
     
     // Arp mode stuff
@@ -35,29 +36,49 @@
     }
     
     poly->glideTime = 5.0f;
-    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
+    
+    poly->ramp = (tRamp*) leaf_alloc(sizeof(tRamp) * poly->maxNumVoices);
+    poly->rampVals = (float*) leaf_alloc(sizeof(float) * poly->maxNumVoices);
+    poly->firstReceived = (oBool*) leaf_alloc(sizeof(oBool) * poly->maxNumVoices);
+    poly->voices = (int**) leaf_alloc(sizeof(int*) * poly->maxNumVoices);
+    
+    for (int i = 0; i < poly->maxNumVoices; ++i)
     {
+        poly->voices[i] = (int*) leaf_alloc(sizeof(int) * 2);
         poly->voices[i][0] = -1;
         poly->firstReceived[i] = OFALSE;
         
-        poly->ramp[i] = (tRamp*) leaf_alloc(sizeof(tRamp));
-        
-        tRamp_init(poly->ramp[i], poly->glideTime, 1);
+        tRamp_init(&poly->ramp[i], poly->glideTime, 1);
     }
     
     poly->pitchBend = 0.0f;
-    poly->pitchBendRamp = (tRamp*) leaf_alloc(sizeof(tRamp));
-    tRamp_init(poly->pitchBendRamp, 1.0f, 1);
     
-    poly->stack = (tStack*) leaf_alloc(sizeof(tStack));
-    tStack_init(poly->stack);
+    tRamp_init(&poly->pitchBendRamp, 1.0f, 1);
+    tStack_init(&poly->stack);
+    tStack_init(&poly->orderStack);
     
-    poly->orderStack = (tStack*) leaf_alloc(sizeof(tStack));
-    tStack_init(poly->orderStack);
-    
     poly->pitchGlideIsActive = OFALSE;
 }
 
+void tPoly_free(tPoly* const poly)
+{
+    for (int i = 0; i < poly->maxNumVoices; i++)
+    {
+        tRamp_free(&poly->ramp[i]);
+        leaf_free(poly->voices[i]);
+    }
+    tRamp_free(&poly->pitchBendRamp);
+    tStack_free(&poly->stack);
+    tStack_free(&poly->orderStack);
+    
+    leaf_free(poly->voices);
+    leaf_free(poly->ramp);
+    leaf_free(poly->rampVals);
+    leaf_free(poly->firstReceived);
+
+    
+}
+
 void tPoly_tickPitch(tPoly* poly)
 {
     tPoly_tickPitchGlide(poly);
@@ -66,15 +87,15 @@
 
 void tPoly_tickPitchGlide(tPoly* poly)
 {
-    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
+    for (int i = 0; i < poly->maxNumVoices; ++i)
     {
-        tRamp_tick(poly->ramp[i]);
+        tRamp_tick(&poly->ramp[i]);
     }
 }
 
 void tPoly_tickPitchBend(tPoly* poly)
 {
-    tRamp_tick(poly->pitchBendRamp);
+    tRamp_tick(&poly->pitchBendRamp);
 }
 
 //instead of including in dacsend, should have a separate pitch bend ramp, that is added when the ramps are ticked and sent to DAC
@@ -81,17 +102,17 @@
 void tPoly_setPitchBend(tPoly* const poly, float pitchBend)
 {
     poly->pitchBend = pitchBend;
-    tRamp_setDest(poly->pitchBendRamp, poly->pitchBend);
+    tRamp_setDest(&poly->pitchBendRamp, poly->pitchBend);
 }
 
 int tPoly_noteOn(tPoly* const poly, int note, uint8_t vel)
 {
     // if not in keymap or already on stack, dont do anything. else, add that note.
-    if (tStack_contains(poly->stack, note) >= 0) return -1;
+    if (tStack_contains(&poly->stack, note) >= 0) return -1;
     else
     {
         tPoly_orderedAddToStack(poly, note);
-        tStack_add(poly->stack, note);
+        tStack_add(&poly->stack, note);
         
         int alteredVoice = -1;
         oBool found = OFALSE;
@@ -101,7 +122,7 @@
             {
                 if (!poly->firstReceived[i] || !poly->pitchGlideIsActive)
                 {
-                    tRamp_setVal(poly->ramp[i], note);
+                    tRamp_setVal(&poly->ramp[i], note);
                     poly->firstReceived[i] = OTRUE;
                 }
                 
@@ -113,7 +134,7 @@
                 poly->notes[note][0] = vel;
                 poly->notes[note][1] = i;
                 
-                tRamp_setDest(poly->ramp[i], poly->voices[i][0]);
+                tRamp_setDest(&poly->ramp[i], poly->voices[i][0]);
                 
                 alteredVoice = i;
                 break;
@@ -123,9 +144,9 @@
         if (!found) //steal
         {
             int whichVoice, whichNote;
-            for (int j = tStack_getSize(poly->stack) - 1; j >= 0; j--)
+            for (int j = tStack_getSize(&poly->stack) - 1; j >= 0; j--)
             {
-                whichNote = tStack_get(poly->stack, j);
+                whichNote = tStack_get(&poly->stack, j);
                 whichVoice = poly->notes[whichNote][1];
                 if (whichVoice >= 0)
                 {
@@ -137,8 +158,8 @@
                     poly->notes[note][0] = vel;
                     poly->notes[note][1] = whichVoice;
                     
-                    tRamp_setTime(poly->ramp[whichVoice], poly->glideTime);
-                    tRamp_setDest(poly->ramp[whichVoice], poly->voices[whichVoice][0]);
+                    tRamp_setTime(&poly->ramp[whichVoice], poly->glideTime);
+                    tRamp_setDest(&poly->ramp[whichVoice], poly->voices[whichVoice][0]);
                     
                     alteredVoice = whichVoice;
                     
@@ -155,8 +176,8 @@
 
 int tPoly_noteOff(tPoly* const poly, uint8_t note)
 {
-    tStack_remove(poly->stack, note);
-    tStack_remove(poly->orderStack, note);
+    tStack_remove(&poly->stack, note);
+    tStack_remove(&poly->orderStack, note);
     poly->notes[note][0] = 0;
     poly->notes[note][1] = -1;
     
@@ -186,14 +207,14 @@
     //grab old notes off the stack if there are notes waiting to replace the free voice
     if (deactivatedVoice >= 0)
     {
-        for (int j = 0; j < tStack_getSize(poly->stack); ++j)
+        for (int j = 0; j < tStack_getSize(&poly->stack); ++j)
         {
-            noteToTest = tStack_get(poly->stack, j);
+            noteToTest = tStack_get(&poly->stack, j);
             
             if (poly->notes[noteToTest][1] < 0) //if there is a stolen note waiting (marked inactive but on the stack)
             {
                 poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note
-                tRamp_setDest(poly->ramp[deactivatedVoice], poly->voices[deactivatedVoice][0]);
+                tRamp_setDest(&poly->ramp[deactivatedVoice], poly->voices[deactivatedVoice][0]);
                 poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][0]; // set the velocity of the voice to be the velocity of that note
                 poly->notes[noteToTest][1] = deactivatedVoice; //mark that it is no longer stolen and is now active
                 return -1;
@@ -209,15 +230,15 @@
     uint8_t j;
     int myPitch, thisPitch, nextPitch;
     
-    tStack* ns = poly->orderStack;
+    tStack ns = poly->orderStack;
     
     int whereToInsert = 0;
     
-    for (j = 0; j < ns->size; j++)
+    for (j = 0; j < ns.size; j++)
     {
         myPitch = noteVal;
-        thisPitch = ns->data[j];
-        nextPitch = ns->data[j+1];
+        thisPitch = ns.data[j];
+        nextPitch = ns.data[j+1];
         
         if (myPitch > thisPitch)
         {
@@ -230,21 +251,21 @@
     }
     
     //first move notes that are already in the stack one position to the right
-    for (j = ns->size; j > whereToInsert; j--)
+    for (j = ns.size; j > whereToInsert; j--)
     {
-        ns->data[j] = ns->data[(j - 1)];
+        ns.data[j] = ns.data[(j - 1)];
     }
     
     //then, insert the new note into the front of the stack
-    ns->data[whereToInsert] =  noteVal;
+    ns.data[whereToInsert] =  noteVal;
     
-    ns->size++;
+    ns.size++;
     
 }
 
 void tPoly_setNumVoices(tPoly* const poly, uint8_t numVoices)
 {
-    poly->numVoices = (numVoices > POLY_NUM_MAX_VOICES) ? POLY_NUM_MAX_VOICES : numVoices;
+    poly->numVoices = (numVoices > poly->maxNumVoices) ? poly->maxNumVoices : numVoices;
 }
 
 void tPoly_setPitchGlideActive(tPoly* const poly, oBool isActive)
@@ -255,9 +276,9 @@
 void tPoly_setPitchGlideTime(tPoly* const poly, float t)
 {
     poly->glideTime = t;
-    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
+    for (int i = 0; i < poly->maxNumVoices; ++i)
     {
-        tRamp_setTime(poly->ramp[i], poly->glideTime);
+        tRamp_setTime(&poly->ramp[i], poly->glideTime);
     }
 }
 
@@ -268,7 +289,7 @@
 
 float tPoly_getPitch(tPoly* const poly, uint8_t voice)
 {
-    return tRamp_sample(poly->ramp[voice]) + tRamp_sample(poly->pitchBendRamp);
+    return tRamp_sample(&poly->ramp[voice]) + tRamp_sample(&poly->pitchBendRamp);
 }
 
 int tPoly_getKey(tPoly* const poly, uint8_t voice)
--- a/LEAF/Src/leaf-oversampler.c
+++ b/LEAF/Src/leaf-oversampler.c
@@ -31,10 +31,17 @@
         int idx = (int)(log2f(os->ratio))-1+offset;
         os->numTaps = firNumTaps[idx];
         os->phaseLength = os->numTaps / os->ratio;
-        os->pCoeffs = firCoeffs[idx];
+        os->pCoeffs = (float*) firCoeffs[idx];
         os->upState = leaf_alloc(sizeof(float) * os->phaseLength);
         os->downState = leaf_alloc(sizeof(float) * os->phaseLength);
     }
+}
+
+void tOversampler_free(tOversampler* const os)
+{
+    leaf_free(os->upState);
+    leaf_free(os->downState);
+    leaf_free(os);
 }
 
 float tOversampler_tick(tOversampler* const os, float input, float (*effectTick)(float))
--- a/LEAF/Src/leaf-pitch.c
+++ b/LEAF/Src/leaf-pitch.c
@@ -354,7 +354,7 @@
     
     p->hopSize = DEFHOPSIZE;
     p->windowSize = DEFWINDOWSIZE;
-    p->fba = FBA;
+    p->fba = FBA;
     
     tEnv_init(&p->env, p->windowSize, p->hopSize, p->frameSize);
     
@@ -374,7 +374,6 @@
 
 float tPeriod_findPeriod (tPeriod* p, float sample)
 {
-    float period;
     int i, iLast;
     
     i = (p->curBlock*p->frameSize);
@@ -460,7 +459,7 @@
     ps->index = 0;
     ps->pitchFactor = 1.0f;
     
-    tSOLAD_init(&ps->sola);
+    tSOLAD_init(&ps->sola);
     
     tHighpass_init(&ps->hp, HPFREQ);
     
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -43,15 +43,10 @@
         }
     }
     
-    r->allpassDelays[0] = (tDelay*) leaf_alloc(sizeof(tDelay));
-    tDelay_init(r->allpassDelays[0], lengths[0], lengths[0] * 2);
+    tDelay_init(&r->allpassDelays[0], lengths[0], lengths[0] * 2);
+    tDelay_init(&r->allpassDelays[1], lengths[1], lengths[1] * 2);
+    tDelay_init(&r->combDelay, lengths[2], lengths[2] * 2);
     
-    r->allpassDelays[1] = (tDelay*) leaf_alloc(sizeof(tDelay));
-    tDelay_init(r->allpassDelays[1], lengths[1], lengths[1] * 2);
-    
-    r->combDelay = (tDelay*) leaf_alloc(sizeof(tDelay));
-    tDelay_init(r->combDelay, lengths[2], lengths[2] * 2);
-    
     tPRCRev_setT60(r, t60);
     
     r->allpassCoeff = 0.7f;
@@ -60,9 +55,9 @@
 
 void tPRCRev_free(tPRCRev* const r)
 {
-    tDelay_free(r->allpassDelays[0]);
-    tDelay_free(r->allpassDelays[1]);
-    tDelay_free(r->combDelay);
+    tDelay_free(&r->allpassDelays[0]);
+    tDelay_free(&r->allpassDelays[1]);
+    tDelay_free(&r->combDelay);
     leaf_free(r);
 }
 
@@ -72,7 +67,7 @@
     
     r->t60 = t60;
     
-    r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(r->combDelay) * leaf.invSampleRate / t60 ));
+    r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf.invSampleRate / t60 ));
     
 }
 
@@ -88,21 +83,21 @@
     
     r->lastIn = input;
     
-    temp = tDelay_getLastOut(r->allpassDelays[0]);
+    temp = tDelay_getLastOut(&r->allpassDelays[0]);
     temp0 = r->allpassCoeff * temp;
     temp0 += input;
-    tDelay_tick(r->allpassDelays[0], temp0);
+    tDelay_tick(&r->allpassDelays[0], temp0);
     temp0 = -( r->allpassCoeff * temp0) + temp;
     
-    temp = tDelay_getLastOut(r->allpassDelays[1]);
+    temp = tDelay_getLastOut(&r->allpassDelays[1]);
     temp1 = r->allpassCoeff * temp;
     temp1 += temp0;
-    tDelay_tick(r->allpassDelays[1], temp1);
+    tDelay_tick(&r->allpassDelays[1], temp1);
     temp1 = -(r->allpassCoeff * temp1) + temp;
     
-    temp2 = temp1 + ( r->combCoeff * tDelay_getLastOut(r->combDelay));
+    temp2 = temp1 + ( r->combCoeff * tDelay_getLastOut(&r->combDelay));
     
-    out = r->mix * tDelay_tick(r->combDelay, temp2);
+    out = r->mix * tDelay_tick(&r->combDelay, temp2);
     
     temp = (1.0f - r->mix) * input;
     
@@ -115,7 +110,7 @@
 
 void     tPRCRevSampleRateChanged (tPRCRev* const r)
 {
-    r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(r->combDelay) * leaf.invSampleRate / r->t60 ));
+    r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf.invSampleRate / r->t60 ));
 }
 
 /* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NRev ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -142,21 +137,18 @@
     
     for ( i=0; i<6; i++ )
     {
-        r->combDelays[i] = (tDelay*) leaf_alloc(sizeof(tDelay));
-        tDelay_init(r->combDelays[i], lengths[i], lengths[i] * 2.0f);
+        tDelay_init(&r->combDelays[i], lengths[i], lengths[i] * 2.0f);
         r->combCoeffs[i] = pow(10.0, (-3 * lengths[i] * leaf.invSampleRate / t60));
     }
     
     for ( i=0; i<8; i++ )
     {
-        r->allpassDelays[i] = (tDelay*) leaf_alloc(sizeof(tDelay));
-        tDelay_init(r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2.0f);
+        tDelay_init(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2.0f);
     }
     
     for ( i=0; i<2; i++ )
     {
-        tDelay_setDelay(r->allpassDelays[i], lengths[i]);
-        tDelay_setDelay(r->combDelays[i], lengths[i+2]);
+        tDelay_setDelay(&r->combDelays[i], lengths[i+2]);
     }
     
     tNRev_setT60(r, t60);
@@ -168,12 +160,12 @@
 {
     for (int i = 0; i < 6; i++)
     {
-        tDelay_free(r->combDelays[i]);
+        tDelay_free(&r->combDelays[i]);
     }
     
     for (int i = 0; i < 8; i++)
     {
-        tDelay_free(r->allpassDelays[i]);
+        tDelay_free(&r->allpassDelays[i]);
     }
     
     leaf_free(r);
@@ -185,7 +177,7 @@
     
     r->t60 = t60;
     
-    for (int i=0; i<6; i++)   r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(r->combDelays[i]) * leaf.invSampleRate / t60 ));
+    for (int i=0; i<6; i++)   r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(&r->combDelays[i]) * leaf.invSampleRate / t60 ));
     
 }
 
@@ -204,31 +196,31 @@
     temp0 = 0.0;
     for ( i=0; i<6; i++ )
     {
-        temp = input + (r->combCoeffs[i] * tDelay_getLastOut(r->combDelays[i]));
-        temp0 += tDelay_tick(r->combDelays[i],temp);
+        temp = input + (r->combCoeffs[i] * tDelay_getLastOut(&r->combDelays[i]));
+        temp0 += tDelay_tick(&r->combDelays[i],temp);
     }
     
     for ( i=0; i<3; i++ )
     {
-        temp = tDelay_getLastOut(r->allpassDelays[i]);
+        temp = tDelay_getLastOut(&r->allpassDelays[i]);
         temp1 = r->allpassCoeff * temp;
         temp1 += temp0;
-        tDelay_tick(r->allpassDelays[i], temp1);
+        tDelay_tick(&r->allpassDelays[i], temp1);
         temp0 = -(r->allpassCoeff * temp1) + temp;
     }
     
     // One-pole lowpass filter.
     r->lowpassState = 0.7f * r->lowpassState + 0.3f * temp0;
-    temp = tDelay_getLastOut(r->allpassDelays[3]);
+    temp = tDelay_getLastOut(&r->allpassDelays[3]);
     temp1 = r->allpassCoeff * temp;
     temp1 += r->lowpassState;
-    tDelay_tick(r->allpassDelays[3], temp1 );
+    tDelay_tick(&r->allpassDelays[3], temp1 );
     temp1 = -(r->allpassCoeff * temp1) + temp;
     
-    temp = tDelay_getLastOut(r->allpassDelays[4]);
+    temp = tDelay_getLastOut(&r->allpassDelays[4]);
     temp2 = r->allpassCoeff * temp;
     temp2 += temp1;
-    tDelay_tick(r->allpassDelays[4], temp2 );
+    tDelay_tick(&r->allpassDelays[4], temp2 );
     out = r->mix * ( -( r->allpassCoeff * temp2 ) + temp );
     
     /*
@@ -246,275 +238,275 @@
     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)
-{
-    r->size_max = 2.0f;
-    r->size = 1.f;
-    r->t = r->size * leaf.sampleRate * 0.001f;
-    
-    // INPUT
-    tTapeDelay_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], SAMP(in_allpass_delays[i]), SAMP(20.f)); // * r->size_max
-        tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
-    }
-    
-    // FEEDBACK 1
-    tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f)); // * r->size_max
-    tAllpass_setGain(&r->f1_allpass, 0.7f);
-    
-    tTapeDelay_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f) * r->size_max + 1);
-    tTapeDelay_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f) * r->size_max + 1);
-    tTapeDelay_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f) * r->size_max + 1);
-    
-    tOnePole_init(&r->f1_filter, 1.f);
-    
-    tHighpass_init(&r->f1_hp, 20.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)); // * r->size_max
-    tAllpass_setGain(&r->f2_allpass, 0.7f);
-    
-    tTapeDelay_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.f) * r->size_max + 1);
-    tTapeDelay_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.f) * r->size_max + 1);
-    tTapeDelay_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.f) * r->size_max + 1);
-    
-    tOnePole_init(&r->f2_filter, 1.f);
-    
-    tHighpass_init(&r->f2_hp, 20.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
-    tTapeDelay_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);
-    
-    tTapeDelay_free(&r->f1_delay_1);
-    tTapeDelay_free(&r->f1_delay_2);
-    tTapeDelay_free(&r->f1_delay_3);
-    
-    tOnePole_free(&r->f1_filter);
-    
-    tCycle_free(&r->f1_lfo);
-    
-    // FEEDBACK 2
-    tAllpass_free(&r->f2_allpass);
-    
-    tTapeDelay_free(&r->f2_delay_1);
-    tTapeDelay_free(&r->f2_delay_2);
-    tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tHighpass_tick(&r->f1_hp, f1_sample);
-    
-    f1_sample *= r->feedback_gain;
-    
-    r->f1_last = tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tHighpass_tick(&r->f2_hp, f2_sample);
-    
-    f2_sample *= r->feedback_gain;
-    
-    r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
-    
-    
-    // TAP OUT 1
-    f1_sample =     tTapeDelay_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
-    tTapeDelay_tapOut(&r->f1_delay_1, SAMP(99.8f));
-    
-    f1_sample -=    tTapeDelay_tapOut(&r->f1_delay_2, SAMP(64.2f));
-    
-    f1_sample +=    tTapeDelay_tapOut(&r->f1_delay_3, SAMP(67.f));
-    
-    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_1, SAMP(66.8f));
-    
-    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
-    
-    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_3, SAMP(35.8f));
-    
-    f1_sample *=    0.14f;
-    
-    // TAP OUT 2
-    f2_sample =     tTapeDelay_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
-    tTapeDelay_tapOut(&r->f2_delay_1, SAMP(121.7f));
-    
-    f2_sample -=    tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
-    
-    f2_sample +=    tTapeDelay_tapOut(&r->f2_delay_3, SAMP(89.7f));
-    
-    f2_sample -=    tTapeDelay_tapOut(&r->f1_delay_1, SAMP(70.8f));
-    
-    f2_sample -=    tTapeDelay_tapOut(&r->f1_delay_2, SAMP(11.2f));
-    
-    f2_sample -=    tTapeDelay_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.01f, size*r->size_max, r->size_max);
-    r->t = r->size * leaf.sampleRate * 0.001f;
-    
-    /*
-     for (int i = 0; i < 4; i++)
-     {
-     tAllpass_setDelay(&r->in_allpass[i], SAMP(in_allpass_delays[i]));
-     }
-     */
-    
-    // FEEDBACK 1
-    //tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f));
-    
-    tTapeDelay_setDelay(&r->f1_delay_1, SAMP(141.69f));
-    tTapeDelay_setDelay(&r->f1_delay_2, SAMP(89.24f));
-    tTapeDelay_setDelay(&r->f1_delay_3, SAMP(125.f));
-    
-    // maybe change rate of SINE LFO's when size changes?
-    
-    // FEEDBACK 2
-    //tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f));
-    
-    tTapeDelay_setDelay(&r->f2_delay_1, SAMP(149.62f));
-    tTapeDelay_setDelay(&r->f2_delay_2, SAMP(60.48f));
-    tTapeDelay_setDelay(&r->f2_delay_3, SAMP(106.28f));
-}
-
-void    tDattorro_setInputDelay     (tDattorro* const r, float preDelay)
-{
-    r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
-    
-    tTapeDelay_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;
-}
+    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)
+{
+    r->size_max = 2.0f;
+    r->size = 1.f;
+    r->t = r->size * leaf.sampleRate * 0.001f;
+    
+    // INPUT
+    tTapeDelay_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], SAMP(in_allpass_delays[i]), SAMP(20.f)); // * r->size_max
+        tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f)); // * r->size_max
+    tAllpass_setGain(&r->f1_allpass, 0.7f);
+    
+    tTapeDelay_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f) * r->size_max + 1);
+    tTapeDelay_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f) * r->size_max + 1);
+    tTapeDelay_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f) * r->size_max + 1);
+    
+    tOnePole_init(&r->f1_filter, 1.f);
+    
+    tHighpass_init(&r->f1_hp, 20.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)); // * r->size_max
+    tAllpass_setGain(&r->f2_allpass, 0.7f);
+    
+    tTapeDelay_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.f) * r->size_max + 1);
+    tTapeDelay_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.f) * r->size_max + 1);
+    tTapeDelay_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.f) * r->size_max + 1);
+    
+    tOnePole_init(&r->f2_filter, 1.f);
+    
+    tHighpass_init(&r->f2_hp, 20.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
+    tTapeDelay_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);
+    
+    tTapeDelay_free(&r->f1_delay_1);
+    tTapeDelay_free(&r->f1_delay_2);
+    tTapeDelay_free(&r->f1_delay_3);
+    
+    tOnePole_free(&r->f1_filter);
+    
+    tCycle_free(&r->f1_lfo);
+    
+    // FEEDBACK 2
+    tAllpass_free(&r->f2_allpass);
+    
+    tTapeDelay_free(&r->f2_delay_1);
+    tTapeDelay_free(&r->f2_delay_2);
+    tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tHighpass_tick(&r->f1_hp, f1_sample);
+    
+    f1_sample *= r->feedback_gain;
+    
+    r->f1_last = tTapeDelay_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 = tTapeDelay_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 = tTapeDelay_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 = tHighpass_tick(&r->f2_hp, f2_sample);
+    
+    f2_sample *= r->feedback_gain;
+    
+    r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
+    
+    
+    // TAP OUT 1
+    f1_sample =     tTapeDelay_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+    tTapeDelay_tapOut(&r->f1_delay_1, SAMP(99.8f));
+    
+    f1_sample -=    tTapeDelay_tapOut(&r->f1_delay_2, SAMP(64.2f));
+    
+    f1_sample +=    tTapeDelay_tapOut(&r->f1_delay_3, SAMP(67.f));
+    
+    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_1, SAMP(66.8f));
+    
+    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f1_sample -=    tTapeDelay_tapOut(&r->f2_delay_3, SAMP(35.8f));
+    
+    f1_sample *=    0.14f;
+    
+    // TAP OUT 2
+    f2_sample =     tTapeDelay_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+    tTapeDelay_tapOut(&r->f2_delay_1, SAMP(121.7f));
+    
+    f2_sample -=    tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
+    
+    f2_sample +=    tTapeDelay_tapOut(&r->f2_delay_3, SAMP(89.7f));
+    
+    f2_sample -=    tTapeDelay_tapOut(&r->f1_delay_1, SAMP(70.8f));
+    
+    f2_sample -=    tTapeDelay_tapOut(&r->f1_delay_2, SAMP(11.2f));
+    
+    f2_sample -=    tTapeDelay_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.01f, size*r->size_max, r->size_max);
+    r->t = r->size * leaf.sampleRate * 0.001f;
+    
+    /*
+     for (int i = 0; i < 4; i++)
+     {
+     tAllpass_setDelay(&r->in_allpass[i], SAMP(in_allpass_delays[i]));
+     }
+     */
+    
+    // FEEDBACK 1
+    //tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f));
+    
+    tTapeDelay_setDelay(&r->f1_delay_1, SAMP(141.69f));
+    tTapeDelay_setDelay(&r->f1_delay_2, SAMP(89.24f));
+    tTapeDelay_setDelay(&r->f1_delay_3, SAMP(125.f));
+    
+    // maybe change rate of SINE LFO's when size changes?
+    
+    // FEEDBACK 2
+    //tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f));
+    
+    tTapeDelay_setDelay(&r->f2_delay_1, SAMP(149.62f));
+    tTapeDelay_setDelay(&r->f2_delay_2, SAMP(60.48f));
+    tTapeDelay_setDelay(&r->f2_delay_3, SAMP(106.28f));
+}
+
+void    tDattorro_setInputDelay     (tDattorro* const r, float preDelay)
+{
+    r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
+    
+    tTapeDelay_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-sample.c
+++ b/LEAF/Src/leaf-sample.c
@@ -106,7 +106,7 @@
 
 //================================tSampler=====================================
 
-void tSampler_init         (tSampler* const p, tBuffer* s)
+void tSampler_init(tSampler* const p, tBuffer* const s)
 {
     p->samp = s;
     
@@ -135,7 +135,7 @@
 
 void tSampler_free         (tSampler* const p)
 {
-    leaf_free(p->samp);
+    tRamp_free(&p->gain);
     leaf_free(p);
 }
 
@@ -178,52 +178,52 @@
         end = p->start;
     }
     
-    // Check dir (direction) to interpolate properly
-    if (dir > 0)
-    {
-        // FORWARD NORMAL SAMPLE
-        int i1 = ((idx-1) + p->len) % p->len;
-        int i3 = (idx+1) % p->len;
-        int i4 = (idx+2) % p->len;
-
-        sample =     LEAF_interpolate_hermite (buff[i1],
-                                               buff[idx],
-                                               buff[i3],
-                                               buff[i4],
-                                               alpha);
-        
-        // num samples to end of loop
-        numsamps = (idx - start) / p->inc;
-        //numsamps = (dir > 0) ? (end - idx) : (idx - start);
-        //numsamps *= p->iinc;
-        
-        if (p->mode == PlayLoop)
-        {
-            if (numsamps <= p->cfxlen)
-            {
-                // CROSSFADE SAMPLE
-                float idxx =  p->idx - p->len;
-                int cdx = ((int)(idxx) + p->len) % p->len;
-                
-                i1 = ((cdx-1) + p->len) % p->len;
-                i3 = (cdx+1) % p->len;
-                i4 = (cdx+2) % p->len;
-                
-                cfxsample =     LEAF_interpolate_hermite (buff[i1],
-                                                          buff[cdx],
-                                                          buff[i3],
-                                                          buff[i4],
-                                                          alpha);
-                
-                g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
-            }
-        }
-    }
-    else
+    // Check dir (direction) to interpolate properly
+    if (dir > 0)
     {
-        // REVERSE
-        int i1 = (idx+1) % p->len;
-        int i3 = ((idx-1) + p->len) % p->len;
+        // FORWARD NORMAL SAMPLE
+        int i1 = ((idx-1) + p->len) % p->len;
+        int i3 = (idx+1) % p->len;
+        int i4 = (idx+2) % p->len;
+
+        sample =     LEAF_interpolate_hermite (buff[i1],
+                                               buff[idx],
+                                               buff[i3],
+                                               buff[i4],
+                                               alpha);
+        
+        // num samples to end of loop
+        numsamps = (idx - start) / p->inc;
+        //numsamps = (dir > 0) ? (end - idx) : (idx - start);
+        //numsamps *= p->iinc;
+        
+        if (p->mode == PlayLoop)
+        {
+            if (numsamps <= p->cfxlen)
+            {
+                // CROSSFADE SAMPLE
+                float idxx =  p->idx - p->len;
+                int cdx = ((int)(idxx) + p->len) % p->len;
+                
+                i1 = ((cdx-1) + p->len) % p->len;
+                i3 = (cdx+1) % p->len;
+                i4 = (cdx+2) % p->len;
+                
+                cfxsample =     LEAF_interpolate_hermite (buff[i1],
+                                                          buff[cdx],
+                                                          buff[i3],
+                                                          buff[i4],
+                                                          alpha);
+                
+                g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
+            }
+        }
+    }
+    else
+    {
+        // REVERSE
+        int i1 = (idx+1) % p->len;
+        int i3 = ((idx-1) + p->len) % p->len;
         int i4 = ((idx-2) + p->len) % p->len;
     
         sample =     LEAF_interpolate_hermite (buff[i1],
--- a/LEAF/Src/leaf-string.c
+++ b/LEAF/Src/leaf-string.c
@@ -21,21 +21,27 @@
 {
     if ( lowestFrequency <= 0.0f )  lowestFrequency = 10.0f;
     
-    p->noise = (tNoise*)leaf_alloc(sizeof(tNoise));
-    tNoise_init(p->noise, WhiteNoise);
+    tNoise_init(&p->noise, WhiteNoise);
     
-    p->pickFilter = (tOnePole*) leaf_alloc(sizeof(tOnePole));
-    tOnePole_init(p->pickFilter, 0.0f);
+    tOnePole_init(&p->pickFilter, 0.0f);
     
-    p->loopFilter = (tOneZero*) leaf_alloc(sizeof(tOneZero));
-    tOneZero_init(p->loopFilter, 0.0f);
+    tOneZero_init(&p->loopFilter, 0.0f);
     
-    p->delayLine = (tDelayA*) leaf_alloc(sizeof(tDelayA));
-    tDelayA_init(p->delayLine, 0.0f, leaf.sampleRate * 2);
+    tDelayA_init(&p->delayLine, 0.0f, leaf.sampleRate * 2);
     
     tPluck_setFrequency(p, 220.0f);
 }
 
+void tPluck_free (tPluck* const p)
+{
+    tNoise_free(&p->noise);
+    tOnePole_free(&p->pickFilter);
+    tOneZero_free(&p->loopFilter);
+    tDelayA_free(&p->delayLine);
+
+    leaf_free(p);
+}
+
 float   tPluck_getLastOut    (tPluck *p)
 {
     return p->lastOut;
@@ -43,7 +49,7 @@
 
 float   tPluck_tick          (tPluck *p)
 {
-    return (p->lastOut = 3.0f * tDelayA_tick(p->delayLine, tOneZero_tick(p->loopFilter, tDelayA_getLastOut(p->delayLine) * p->loopGain ) ));
+    return (p->lastOut = 3.0f * tDelayA_tick(&p->delayLine, tOneZero_tick(&p->loopFilter, tDelayA_getLastOut(&p->delayLine) * p->loopGain ) ));
 }
 
 void    tPluck_pluck         (tPluck* const p, float amplitude)
@@ -51,12 +57,12 @@
     if ( amplitude < 0.0f)      amplitude = 0.0f;
     else if (amplitude > 1.0f)  amplitude = 1.0f;
     
-    tOnePole_setPole(p->pickFilter, 0.999f - (amplitude * 0.15f));
-    tOnePole_setGain(p->pickFilter, amplitude * 0.5f );
+    tOnePole_setPole(&p->pickFilter, 0.999f - (amplitude * 0.15f));
+    tOnePole_setGain(&p->pickFilter, amplitude * 0.5f );
     
     // Fill delay with noise additively with current contents.
-    for ( uint32_t i = 0; i < (uint32_t)tDelayA_getDelay(p->delayLine); i++ )
-        tDelayA_tick(p->delayLine, 0.6f * tDelayA_getLastOut(p->delayLine) + tOnePole_tick(p->pickFilter, tNoise_tick(p->noise) ) );
+    for ( uint32_t i = 0; i < (uint32_t)tDelayA_getDelay(&p->delayLine); i++ )
+        tDelayA_tick(&p->delayLine, 0.6f * tDelayA_getLastOut(&p->delayLine) + tOnePole_tick(&p->pickFilter, tNoise_tick(&p->noise) ) );
 }
 
 // Start a note with the given frequency and amplitude.;
@@ -82,9 +88,9 @@
     if ( frequency <= 0.0f )   frequency = 0.001f;
     
     // Delay = length - filter delay.
-    float delay = ( leaf.sampleRate / frequency ) - tOneZero_getPhaseDelay(p->loopFilter, frequency );
+    float delay = ( leaf.sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );
     
-    tDelayA_setDelay(p->delayLine, delay );
+    tDelayA_setDelay(&p->delayLine, delay );
     
     p->loopGain = 0.99f + (frequency * 0.000005f);
     
@@ -108,22 +114,17 @@
 {
     if ( lowestFrequency <= 0.0f )  lowestFrequency = 8.0f;
     
-    p->delayLine = (tDelayA*) leaf_alloc(sizeof(tDelayA));
-    tDelayA_init(p->delayLine, 0.0f, leaf.sampleRate * 2);
+    tDelayA_init(&p->delayLine, 0.0f, leaf.sampleRate * 2);
+
+    tDelayL_init(&p->combDelay, 0.0f, leaf.sampleRate * 2);
     
-    p->combDelay = (tDelayL*) leaf_alloc(sizeof(tDelayL));
-    tDelayL_init(p->combDelay, 0.0f, leaf.sampleRate * 2);
+    tOneZero_init(&p->filter, 0.0f);
     
-    p->filter = (tOneZero*) leaf_alloc(sizeof(tOneZero));
-    tOneZero_init(p->filter, 0.0f);
+    tNoise_init(&p->noise, WhiteNoise);
     
-    p->noise = (tNoise*) leaf_alloc(sizeof(tNoise));
-    tNoise_init(p->noise, WhiteNoise);
-    
     for (int i = 0; i < 4; i++)
     {
-        p->biquad[i] = (tBiQuad*) leaf_alloc(sizeof(tBiQuad));
-        tBiQuad_init(p->biquad[i]);
+        tBiQuad_init(&p->biquad[i]);
     }
     
     p->pluckAmplitude = 0.3f;
@@ -139,14 +140,14 @@
 
 void tStifKarp_free (tStifKarp* const p)
 {
-    tDelayA_free(p->delayLine);
-    tDelayL_free(p->combDelay);
-    tOneZero_free(p->filter);
-    tNoise_free(p->noise);
+    tDelayA_free(&p->delayLine);
+    tDelayL_free(&p->combDelay);
+    tOneZero_free(&p->filter);
+    tNoise_free(&p->noise);
     
     for (int i = 0; i < 4; i++)
     {
-        tBiQuad_free(p->biquad[i]);
+        tBiQuad_free(&p->biquad[i]);
     }
     
     leaf_free(p);
@@ -159,16 +160,16 @@
 
 float   tStifKarp_tick          (tStifKarp* const p)
 {
-    float temp = tDelayA_getLastOut(p->delayLine) * p->loopGain;
+    float temp = tDelayA_getLastOut(&p->delayLine) * p->loopGain;
     
     // Calculate allpass stretching.
-    for (int i=0; i<4; i++)     temp = tBiQuad_tick(p->biquad[i],temp);
+    for (int i=0; i<4; i++)     temp = tBiQuad_tick(&p->biquad[i],temp);
     
     // Moving average filter.
-    temp = tOneZero_tick(p->filter, temp);
+    temp = tOneZero_tick(&p->filter, temp);
     
-    float out = tDelayA_tick(p->delayLine, temp);
-    out = out - tDelayL_tick(p->combDelay, out);
+    float out = tDelayA_tick(&p->delayLine, temp);
+    out = out - tDelayL_tick(&p->combDelay, out);
     p->lastOut = out;
     
     return p->lastOut;
@@ -181,10 +182,10 @@
     
     p->pluckAmplitude = amplitude;
     
-    for ( uint32_t i=0; i < (uint32_t)tDelayA_getDelay(p->delayLine); i++ )
+    for ( uint32_t i=0; i < (uint32_t)tDelayA_getDelay(&p->delayLine); i++ )
     {
         // Fill delay with noise additively with current contents.
-        tDelayA_tick(p->delayLine, (tDelayA_getLastOut(p->delayLine) * 0.6f) + 0.4f * tNoise_tick(p->noise) * p->pluckAmplitude );
+        tDelayA_tick(&p->delayLine, (tDelayA_getLastOut(&p->delayLine) * 0.6f) + 0.4f * tNoise_tick(&p->noise) * p->pluckAmplitude );
         //delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
     }
 }
@@ -213,7 +214,7 @@
     p->lastFrequency = frequency;
     p->lastLength = leaf.sampleRate / p->lastFrequency;
     float delay = p->lastLength - 0.5f;
-    tDelayA_setDelay(p->delayLine, delay );
+    tDelayA_setDelay(&p->delayLine, delay);
     
     // MAYBE MODIFY LOOP GAINS
     p->loopGain = p->baseLoopGain + (frequency * 0.000005f);
@@ -221,7 +222,7 @@
     
     tStifKarp_setStretch(p, p->stretching);
     
-    tDelayL_setDelay(p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
+    tDelayL_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
     
 }
 
@@ -238,13 +239,13 @@
     for ( int i=0; i<4; i++ )
     {
         coefficient = temp * temp;
-        tBiQuad_setA2(p->biquad[i], coefficient);
-        tBiQuad_setB0(p->biquad[i], coefficient);
-        tBiQuad_setB2(p->biquad[i], 1.0f);
+        tBiQuad_setA2(&p->biquad[i], coefficient);
+        tBiQuad_setB0(&p->biquad[i], coefficient);
+        tBiQuad_setB2(&p->biquad[i], 1.0f);
         
         coefficient = -2.0f * temp * cos(TWO_PI * freq / leaf.sampleRate);
-        tBiQuad_setA1(p->biquad[i], coefficient);
-        tBiQuad_setB1(p->biquad[i], coefficient);
+        tBiQuad_setA1(&p->biquad[i], coefficient);
+        tBiQuad_setB1(&p->biquad[i], coefficient);
         
         freq += dFreq;
     }
@@ -257,7 +258,7 @@
     else if (position <= 1.0f)  p->pickupPosition = position;
     else                        p->pickupPosition = 1.0f;
     
-    tDelayL_setDelay(p->combDelay, 0.5f * p->pickupPosition * p->lastLength);
+    tDelayL_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength);
 }
 
 // Set the base loop gain.
--- a/LEAF/Src/leaf-utilities.c
+++ b/LEAF/Src/leaf-utilities.c
@@ -496,7 +496,6 @@
     adsr->decayInc = adsr->inc_buff[decayIndex];
     adsr->releaseInc = adsr->inc_buff[releaseIndex];
     adsr->rampInc = adsr->inc_buff[rampIndex];
-    
 }
 
 int     tADSR_setAttack(tADSR* const adsr, float attack)
--- a/LEAF/Src/leaf-vocoder.c
+++ b/LEAF/Src/leaf-vocoder.c
@@ -26,7 +26,7 @@
  *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-void tTalkbox_init(tTalkbox* const v)
+void tTalkbox_init(tTalkbox* const v, int bufsize)
 {
     v->param[0] = 0.5f;  //wet
     v->param[1] = 0.0f;  //dry
@@ -33,11 +33,25 @@
     v->param[2] = 0; // Swap
     v->param[3] = 1.0f;  //quality
     
+    v->bufsize = bufsize;
+    
+    v->car0 =   (float*) leaf_alloc(sizeof(float) * v->bufsize);
+    v->car1 =   (float*) leaf_alloc(sizeof(float) * v->bufsize);
+    v->window = (float*) leaf_alloc(sizeof(float) * v->bufsize);
+    v->buf0 =   (float*) leaf_alloc(sizeof(float) * v->bufsize);
+    v->buf1 =   (float*) leaf_alloc(sizeof(float) * v->bufsize);
+    
     tTalkbox_update(v);
 }
 
 void tTalkbox_free(tTalkbox* const v)
 {
+    leaf_free(v->car0);
+    leaf_free(v->car1);
+    leaf_free(v->window);
+    leaf_free(v->buf0);
+    leaf_free(v->buf1);
+    
     leaf_free(v);
 }
 
@@ -48,7 +62,7 @@
     if(fs > 96000.0f) fs = 96000.0f;
     
     int32_t n = (int32_t)(0.01633f * fs);
-    if(n > TALKBOX_BUFFER_LENGTH) n = TALKBOX_BUFFER_LENGTH;
+    if(n > v->bufsize) n = v->bufsize;
     
     //O = (VstInt32)(0.0005f * fs);
     v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * fs);
@@ -77,7 +91,7 @@
     v->u0 = v->u1 = v->u2 = v->u3 = v->u4 = 0.0f;
     v->d0 = v->d1 = v->d2 = v->d3 = v->d4 = 0.0f;
     
-    for (int32_t i = 0; i < TALKBOX_BUFFER_LENGTH; i++)
+    for (int32_t i = 0; i < v->bufsize; i++)
     {
         v->buf0[i] = 0;
         v->buf1[i] = 0;
--- a/LEAF/Src/leaf.c
+++ b/LEAF/Src/leaf.c
@@ -20,9 +20,9 @@
 
 LEAF leaf;
 
-void LEAF_init(float sr, int blocksize, float(*random)(void))
+void LEAF_init(float sr, int blocksize, char* memory, size_t memorysize, float(*random)(void))
 {
-    leaf_pool_init(MPOOL_POOL_SIZE);
+    leaf_pool_init(memory, memorysize);
     
     leaf.sampleRate = sr;
     
--- a/LEAF/leaf.h
+++ b/LEAF/leaf.h
@@ -60,18 +60,13 @@
 #include "./Inc/leaf-tables.h"
 #include "./Inc/leaf-WDF.h"
 
-#include "main.h"  // not sure this is a good idea. not all applications will have a main.h.  But doing this for now. It's so that there is a place to put the STM32 define -JS
-
-
 #endif
 
-
-
 #ifdef __cplusplus
 extern "C" {
 #endif
     
-void        LEAF_init            (float sampleRate, int blocksize, float(*randomNumberFunction)(void));
+void        LEAF_init            (float sampleRate, int blocksize, char* memory, size_t memorysize, float(*randomNumberFunction)(void));
 void        LEAF_setSampleRate   (float sampleRate);
 float       LEAF_getSampleRate   (void);
 
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -16,69 +16,36 @@
 static void leaf_pool_dump(void);
 static void run_pool_test(void);
 
-tWDF r1;
-tWDF r2;
-tWDF c1;
-tWDF c2;
-tWDF rs1;
-tWDF p1;
-tWDF s1;
-tWDF s2;
-tWDF i;
-tWDF d;
 tNoise noise;
 tCycle sine;
+tDelay delay;
 
 float gain;
+float freq;
+float dtime;
 bool buttonState;
 int ratio = 2;
 
+#define MSIZE 500000
+char memory[MSIZE];
+
 void    LEAFTest_init            (float sampleRate, int blockSize)
 {
-    LEAF_init(sampleRate, blockSize, &getRandomFloat);
+    LEAF_init(sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
     
     tNoise_init(&noise, WhiteNoise);
     tCycle_init(&sine);
     tCycle_setFreq(&sine, 200);
-    
-    //Bandpass circuit 1
-    //use c1 for output voltage
-//    tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
-//    tWDF_init(&r2, Resistor, 10000.0f, NULL, NULL);
-//    tWDF_init(&c1, Capacitor, 0.000000159154943f, NULL, NULL);
-//    tWDF_init(&c2, Capacitor, 0.000000159154943f, NULL, NULL);
-//    tWDF_init(&p1, ParallelAdaptor, 10000.0f, &r1, &c1);
-//    tWDF_init(&s1, SeriesAdaptor, 0.0f, &c2, &r2);
-//    tWDF_init(&s2, SeriesAdaptor, 0.0f, &s1, &p1);
-    
-    //Bandpass circuit 2
-//    tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
-//    tWDF_init(&c1, Capacitor, 0.000000159154943f, NULL, NULL);
-//    tWDF_init(&s1, SeriesAdaptor, 0.0f, &c1, &r1);
-//    tWDF_init(&r2, Resistor, 10000.0f, NULL, NULL);
-//    tWDF_init(&p1, ParallelAdaptor, 10000.0f, &s1, &r2);
-//    tWDF_init(&c2, Capacitor, 0.000000159154943f, NULL, NULL);
-//    tWDF_init(&s2, SeriesAdaptor, 0.0f, &c2, &p1);
-    
-//    tWDF_setOutputPoint(&s2, &c1);
-    
-//    tWDFNonlinear_init(&i, IdealSource, &s2);
-    
-    tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
-    tWDF_init(&rs1, ResistiveSource, 1.0f, NULL, NULL);
-    tWDF_init(&s1, SeriesAdaptor, 0.0f, &r1, &rs1);
-    tWDF_init(&d, Diode, 0.0f, &s1, NULL);
-    
-    leaf_pool_report();
+    tDelay_init(&delay, 44100, 44100);
 }
 
 float   LEAFTest_tick            (float input)
 {
-    float sample = tCycle_tick(&sine) * gain;
+    tCycle_setFreq(&sine, freq);
+    float sample = tCycle_tick(&sine) * 0.1;
+    tDelay_setDelay(&delay, dtime);
+    sample += tDelay_tick(&delay, sample);
     
-    //tWDF_setValue(&rs1, sample*gain);
-    sample = tWDF_tick(&d, sample, &d, 1);
-    
     return sample;
 }
 
@@ -88,14 +55,10 @@
 void    LEAFTest_block           (void)
 {
     float val = getSliderValue("mod freq");
-    val = 1.0f + 10000.0f * val;
+    freq = val * 2000.f;
     
-    tWDF_setValue(&r1, val);
-    
     val = getSliderValue("mod depth");
-    val = 10.0f * val;
-    gain = val;
-    //tWDF_setValue(&r2, val);
+    dtime = val * 40000.;
 }
 
 void    LEAFTest_controllerInput (int cnum, float cval)