shithub: leaf

Download patch

ref: 8b254651676c1c577ecc1bacf05470e61258476a
parent: 62e2951b664a111eb7f82de959e5c1ee8466cd75
author: Matthew Wang <mjw7@princeton.edu>
date: Thu Feb 25 08:48:20 EST 2021

add set sample rate function to all object that depend on sample rate

--- a/leaf/Inc/leaf-analysis.h
+++ b/leaf/Inc/leaf-analysis.h
@@ -364,8 +364,8 @@
         float atk_coeff;
         float rel_coeff;
         
-        int blocksize;
-        int samplerate;
+        int blockSize;
+        int sampleRate;
         
         //RMS amplitude of previous block - used to decide if attack is present
         float prevAmp;
@@ -385,6 +385,7 @@
     void    tAttackDetection_setRelease     (tAttackDetection* const, int inRel);
     void    tAttackDetection_setThreshold   (tAttackDetection* const, float thres);
     int     tAttackDetection_detect         (tAttackDetection* const, float *in);
+    void    tAttackDetection_setSampleRate  (tAttackDetection* const, float sr);
     
     //==============================================================================
     
@@ -593,6 +594,7 @@
         float alpha;
         float tolerance;
         
+        float invSampleRate;
     } _tPeriodDetection;
     
     typedef _tPeriodDetection* tPeriodDetection;
@@ -603,12 +605,13 @@
     
     float   tPeriodDetection_tick               (tPeriodDetection* const, float sample);
     float   tPeriodDetection_getPeriod          (tPeriodDetection* const);
-    float   tPeriodDetection_getFidelity        (tPeriodDetection* pd);
+    float   tPeriodDetection_getFidelity        (tPeriodDetection* const);
     void    tPeriodDetection_setHopSize         (tPeriodDetection* const, int hs);
     void    tPeriodDetection_setWindowSize      (tPeriodDetection* const, int ws);
     void    tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
     void    tPeriodDetection_setAlpha           (tPeriodDetection* const, float alpha);
     void    tPeriodDetection_setTolerance       (tPeriodDetection* const, float tolerance);
+    void    tPeriodDetection_setSampleRate      (tPeriodDetection* const, float sr);
     
     //==============================================================================
     
@@ -644,7 +647,6 @@
     
     typedef struct _tZeroCrossingCollector
     {
-        
         tMempool mempool;
         
         tZeroCrossingInfo* _info;
@@ -689,7 +691,6 @@
     
     typedef struct _tBitset
     {
-        
         tMempool mempool;
         
         unsigned int _value_size;
@@ -718,7 +719,6 @@
     
     typedef struct _tBACF
     {
-        
         tMempool mempool;
         
         tBitset _bitset;
@@ -806,7 +806,6 @@
     
     typedef struct _sub_collector
     {
-        
         tMempool mempool;
         
         float             _first_period;
@@ -845,6 +844,10 @@
         unsigned int            _num_pulses; // = 0;
         int                     _half_empty; // 0;
         
+        float                   sampleRate;
+        float                   lowestFreq;
+        float                   highestFreq;
+        
         tBACF                   _bacf;
         
     } _tPeriodDetector;
@@ -866,6 +869,7 @@
     int     tPeriodDetector_isReset (tPeriodDetector* const detector);
 
     void    tPeriodDetector_setHysteresis   (tPeriodDetector* const detector, float hysteresis);
+    void    tPeriodDetector_setSampleRate   (tPeriodDetector* const detector, float sr);
     
     //==============================================================================
     
@@ -942,6 +946,8 @@
         _pitch_info _current;
         int _frames_after_shift;// = 0;
         
+        float sampleRate;
+        
     } _tPitchDetector;
     
     typedef _tPitchDetector* tPitchDetector;
@@ -958,8 +964,8 @@
     int     tPitchDetector_indeterminate    (tPitchDetector* const detector);
     
     void    tPitchDetector_setHysteresis    (tPitchDetector* const detector, float hysteresis);
+    void    tPitchDetector_setSampleRate    (tPitchDetector* const detector, float sr);
     
-    
     //==============================================================================
     
     /*!
@@ -1041,6 +1047,8 @@
         
         float highest, lowest;
         float thresh;
+        
+        float sampleRate;
 
     } _tDualPitchDetector;
     
@@ -1058,9 +1066,7 @@
     
     void    tDualPitchDetector_setHysteresis    (tDualPitchDetector* const detector, float hysteresis);
     void    tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const detector, float thresh);
-    
-    
-    
+    void    tDualPitchDetector_setSampleRate    (tDualPitchDetector* const detector, float sr);
     
 #ifdef __cplusplus
 }
--- a/leaf/Inc/leaf-distortion.h
+++ b/leaf/Inc/leaf-distortion.h
@@ -61,7 +61,6 @@
     
     typedef struct _tSampleReducer
     {
-        
         tMempool mempool;
         float invRatio;
         float hold;
@@ -124,9 +123,9 @@
     
     typedef struct _tOversampler
     {
-        
         tMempool mempool;
         int maxRatio;
+        int allowHighQuality;
         int ratio;
         int offset;
         float* pCoeffs;
@@ -143,11 +142,12 @@
     void    tOversampler_free           (tOversampler* const);
     
     void    tOversampler_upsample       (tOversampler* const, float input, float* output);
-    float   tOversampler_downsample     (tOversampler* const os, float* input);
+    float   tOversampler_downsample     (tOversampler* const, float* input);
     float   tOversampler_tick           (tOversampler* const, float input, float* oversample,
                                          float (*effectTick)(float));
     void    tOversampler_setRatio       (tOversampler* const, int ratio);
-    int     tOversampler_getLatency     (tOversampler* const os);
+    void    tOversampler_setQuality     (tOversampler* const, int quality);
+    int     tOversampler_getLatency     (tOversampler* const);
     
     //==============================================================================
     
--- a/leaf/Inc/leaf-dynamics.h
+++ b/leaf/Inc/leaf-dynamics.h
@@ -69,6 +69,8 @@
         
         int isActive;
         
+        float sampleRate;
+        
     } _tCompressor;
     
     typedef _tCompressor* tCompressor;
--- a/leaf/Inc/leaf-effects.h
+++ b/leaf/Inc/leaf-effects.h
@@ -1,8 +1,8 @@
 /*==============================================================================
  
  leaf-effects.h
-
  
+ 
  ==============================================================================*/
 
 #ifndef LEAF_EFFECTS_H_INCLUDED
@@ -20,8 +20,8 @@
 #include "leaf-analysis.h"
 #include "leaf-envelopes.h"
     
-
-
+    
+    
     //==============================================================================
     
     /*!
@@ -89,7 +89,7 @@
      @param talkbox A pointer to the relevant tTalkbox.
      
      @} */
-     
+    
 #define NUM_TALKBOX_PARAM 4
     
     typedef struct _tTalkbox
@@ -98,7 +98,7 @@
         tMempool mempool;
         
         float param[NUM_TALKBOX_PARAM];
-
+        
         int bufsize;
         float* car0;
         float* car1;
@@ -117,8 +117,9 @@
         float G;
         double* dl;
         double* Rt;
-
         
+        float sampleRate;
+        
     } _tTalkbox;
     
     typedef _tTalkbox* tTalkbox;
@@ -138,11 +139,12 @@
     void    tTalkbox_setWarpOn      (tTalkbox* const voc, float warpOn);
     void    tTalkbox_setFreeze      (tTalkbox* const voc, float freeze);
     void    tTalkbox_warpedAutocorrelate    (float * x, double* dl, double* Rt, unsigned int L, float * R, unsigned int P, float lambda);
+    void    tTalkbox_setSampleRate  (tTalkbox* const voc, float sr);
     
     
     //==============================================================================
     
-
+    
     /*!
      @defgroup ttalkboxfloat tTalkboxFloat
      @ingroup effects
@@ -208,55 +210,58 @@
      @param talkbox A pointer to the relevant tTalkboxFloat.
      
      @} */
-
+    
     typedef struct _tTalkboxFloat
-      {
-            
-          tMempool mempool;
-          
-          float param[NUM_TALKBOX_PARAM];
-
-          int bufsize;
-          float* car0;
-          float* car1;
-          float* window;
-          float* buf0;
-          float* buf1;
-          float* k;
-          float warpFactor;
-          int32_t warpOn;
-          int freeze;
-          float emphasis;
-          int32_t K, N, O, pos;
-          float wet, dry, FX;
-          float d0, d1, d2, d3, d4;
-          float u0, u1, u2, u3, u4;
-          float G;
-          float* dl;
-          float* Rt;
-
-      } _tTalkboxFloat;
-
-      typedef _tTalkboxFloat* tTalkboxFloat;
-
-      void    tTalkboxFloat_init           (tTalkboxFloat* const, int bufsize, LEAF* const leaf);
-      void    tTalkboxFloat_initToPool     (tTalkboxFloat* const, int bufsize, tMempool* const);
-      void    tTalkboxFloat_free           (tTalkboxFloat* const);
-
-      float   tTalkboxFloat_tick           (tTalkboxFloat* const, float synth, float voice);
-      float     tTalkboxFloat_tickFrozen        (tTalkboxFloat* const voc, float synth, float voice);
-      void    tTalkboxFloat_update         (tTalkboxFloat* const);
-      void    tTalkboxFloat_suspend        (tTalkboxFloat* const);
-      void    tTalkboxFloat_lpcDurbin      (float *r, int p, float *k, float *g);
-      void  tTalkboxFloat_lpc           (float *buf, float *car, float* dl, float* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G);
-      void    tTalkboxFloat_setQuality     (tTalkboxFloat* const, float quality);
-      void  tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);
-      void  tTalkboxFloat_setWarpOn     (tTalkboxFloat* const voc, int warpOn);
-      void  tTalkboxFloat_setFreeze     (tTalkboxFloat* const voc, int freeze);
-      void  tTalkboxFloat_warpedAutocorrelate   (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);
-      //==============================================================================
-
-
+    {
+        
+        tMempool mempool;
+        
+        float param[NUM_TALKBOX_PARAM];
+        
+        int bufsize;
+        float* car0;
+        float* car1;
+        float* window;
+        float* buf0;
+        float* buf1;
+        float* k;
+        float warpFactor;
+        int32_t warpOn;
+        int freeze;
+        float emphasis;
+        int32_t K, N, O, pos;
+        float wet, dry, FX;
+        float d0, d1, d2, d3, d4;
+        float u0, u1, u2, u3, u4;
+        float G;
+        float* dl;
+        float* Rt;
+        
+        float sampleRate;
+        
+    } _tTalkboxFloat;
+    
+    typedef _tTalkboxFloat* tTalkboxFloat;
+    
+    void    tTalkboxFloat_init           (tTalkboxFloat* const, int bufsize, LEAF* const leaf);
+    void    tTalkboxFloat_initToPool     (tTalkboxFloat* const, int bufsize, tMempool* const);
+    void    tTalkboxFloat_free           (tTalkboxFloat* const);
+    
+    float   tTalkboxFloat_tick           (tTalkboxFloat* const, float synth, float voice);
+    float     tTalkboxFloat_tickFrozen        (tTalkboxFloat* const voc, float synth, float voice);
+    void    tTalkboxFloat_update         (tTalkboxFloat* const);
+    void    tTalkboxFloat_suspend        (tTalkboxFloat* const);
+    void    tTalkboxFloat_lpcDurbin      (float *r, int p, float *k, float *g);
+    void    tTalkboxFloat_lpc           (float *buf, float *car, float* dl, float* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G);
+    void    tTalkboxFloat_setQuality     (tTalkboxFloat* const, float quality);
+    void    tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);
+    void    tTalkboxFloat_setWarpOn     (tTalkboxFloat* const voc, int warpOn);
+    void    tTalkboxFloat_setFreeze     (tTalkboxFloat* const voc, int freeze);
+    void    tTalkboxFloat_warpedAutocorrelate   (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);
+    void    tTalkboxFloat_setSampleRate  (tTalkboxFloat* const voc, float sr);
+    //==============================================================================
+    
+    
     /*!
      @defgroup tvocoder tVocoder
      @ingroup effects
@@ -310,6 +315,7 @@
         //filter coeffs and buffers - seems it's faster to leave this global than make local copy
         float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
         
+        float invSampleRate;
     } _tVocoder;
     
     typedef _tVocoder* tVocoder;
@@ -321,6 +327,7 @@
     float   tVocoder_tick           (tVocoder* const, float synth, float voice);
     void    tVocoder_update         (tVocoder* const);
     void    tVocoder_suspend        (tVocoder* const);
+    void    tVocoder_setSampleRate  (tVocoder* const, float sr);
     
     //==============================================================================
     
@@ -369,7 +376,7 @@
      @param pulse A pointer to the relevant tRosenbergGlottalPulse.
      
      @} */
-
+    
     typedef struct _tRosenbergGlottalPulse
     {
         
@@ -380,22 +387,25 @@
         float invPulseLengthMinusOpenLength;
         float freq;
         float inc;
+        float invSampleRate;
     } _tRosenbergGlottalPulse;
-
+    
     typedef _tRosenbergGlottalPulse* tRosenbergGlottalPulse;
-
+    
     void    tRosenbergGlottalPulse_init           (tRosenbergGlottalPulse* const, LEAF* const leaf);
     void    tRosenbergGlottalPulse_initToPool     (tRosenbergGlottalPulse* const, tMempool* const);
     void    tRosenbergGlottalPulse_free           (tRosenbergGlottalPulse* const);
-
+    
     float   tRosenbergGlottalPulse_tick           (tRosenbergGlottalPulse* const);
     float   tRosenbergGlottalPulse_tickHQ           (tRosenbergGlottalPulse* const gp);
     void   tRosenbergGlottalPulse_setFreq           (tRosenbergGlottalPulse* const, float freq);
-
-    void   tRosenbergGlottalPulse_setOpenLength           (tRosenbergGlottalPulse* const, float openLength);
-
-    void   tRosenbergGlottalPulse_setPulseLength           (tRosenbergGlottalPulse* const, float pulseLength);
-    void   tRosenbergGlottalPulse_setOpenLengthAndPulseLength           (tRosenbergGlottalPulse* const gp, float openLength, float pulseLength);
+    
+    void   tRosenbergGlottalPulse_setOpenLength     (tRosenbergGlottalPulse* const, float openLength);
+    
+    void   tRosenbergGlottalPulse_setPulseLength    (tRosenbergGlottalPulse* const, float pulseLength);
+    void   tRosenbergGlottalPulse_setOpenLengthAndPulseLength(tRosenbergGlottalPulse* const, float
+                                                              openLength, float pulseLength);
+    void   tRosenbergGlottalPulse_setSampleRate(tRosenbergGlottalPulse* const, float sr);
     //==============================================================================
     
     /*!
@@ -421,7 +431,7 @@
      @fn void    tSOLAD_ioSamples        (tSOLAD *w, float* in, float* out, int blocksize)
      @brief Send one block of input samples, receive one block of output samples
      @param solad A pointer to the relevant tSOLAD.
-
+     
      @fn void    tSOLAD_setPeriod        (tSOLAD *w, float period)
      @brief Set periodicity analysis data
      @param solad A pointer to the relevant tSOLAD.
@@ -440,11 +450,11 @@
      
      @} */
     
-//#define LOOPSIZE (2048*2)      // (4096*2) // loop size must be power of two
-//#define LOOPMASK (LOOPSIZE - 1)
+    //#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 MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
 #define MINPERIOD 8.0f
     
     typedef struct _tSOLAD
@@ -484,6 +494,7 @@
     void    tSOLAD_setReadLag       (tSOLAD *w, float readlag);
     // reset state variables
     void    tSOLAD_resetState       (tSOLAD *w);
+    void    tSOLAD_setSampleRate    (tSOLAD* const, float sr);
     
     /*!
      @defgroup tpitchshift tPitchShift
@@ -536,6 +547,8 @@
         int index;
         
         float pickiness;
+        
+        float sampleRate;
     } _tPitchShift;
     
     typedef _tPitchShift* tPitchShift;
@@ -548,6 +561,7 @@
     void    tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out);
     
     void    tPitchShift_setPickiness (tPitchShift* const, float p);
+    void    tPitchShift_setSampleRate(tPitchShift* const, float sr);
     
     /*!
      @defgroup tsimpleretune tSimpleRetune
@@ -620,7 +634,8 @@
     void    tSimpleRetune_tuneVoices            (tSimpleRetune* const, float* t);
     void    tSimpleRetune_tuneVoice             (tSimpleRetune* const, int voice, float t);
     float   tSimpleRetune_getInputFrequency     (tSimpleRetune* const);
-    
+    void    tSimpleRetune_setSampleRate         (tSimpleRetune* const, float sr);
+
     /*!
      @defgroup tretune tRetune
      @ingroup effects
@@ -695,6 +710,7 @@
     void    tRetune_tuneVoices          (tRetune* const, float* t);
     void    tRetune_tuneVoice           (tRetune* const, int voice, float t);
     float   tRetune_getInputFrequency   (tRetune* const);
+    void    tRetune_setSampleRate       (tRetune* const, float sr);
     
     //==============================================================================
     
@@ -772,6 +788,8 @@
         tHighpass hp2;
         tFeedbackLeveler fbl1;
         tFeedbackLeveler fbl2;
+        float sampleRate;
+        float invSampleRate;
     } _tFormantShifter;
     
     typedef _tFormantShifter* tFormantShifter;
@@ -786,6 +804,7 @@
     void    tFormantShifter_ioSamples       (tFormantShifter* const, float* in, float* out, int size, float fwarp);
     void    tFormantShifter_setShiftFactor  (tFormantShifter* const, float shiftFactor);
     void    tFormantShifter_setIntensity    (tFormantShifter* const, float intensity);
+    void    tFormantShifter_setSampleRate   (tFormantShifter* const fsr, float sr);
     
     //==============================================================================
     
@@ -796,3 +815,4 @@
 #endif  // LEAF_EFFECTS_H_INCLUDED
 
 //==============================================================================
+
--- a/leaf/Inc/leaf-envelopes.h
+++ b/leaf/Inc/leaf-envelopes.h
@@ -345,9 +345,11 @@
         const float *exp_buff;
         uint32_t buff_size;
         uint32_t buff_sizeMinusOne;
+        float sampleRate;
         float bufferSizeDividedBySampleRateInMs;
         float next;
         
+        float attack, decay, release;
         float attackInc, decayInc, releaseInc, rampInc;
         
         uint32_t whichStage;
@@ -374,6 +376,7 @@
     void    tADSRT_setLeakFactor (tADSRT* const, float leakFactor);
     void    tADSRT_on            (tADSRT* const, float velocity);
     void    tADSRT_off           (tADSRT* const);
+    void    tADSRT_setSampleRate (tADSRT* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
@@ -444,9 +447,13 @@
     {
         
         tMempool mempool;
+        float sampleRate;
         float sampleRateInMs;
         int state;
         float output;
+        float attack;
+        float decay;
+        float release;
         float attackRate;
         float decayRate;
         float releaseRate;
@@ -481,6 +488,7 @@
     void    tADSRS_setLeakFactor (tADSRS* const, float leakFactor);
     void    tADSRS_on            (tADSRS* const, float velocity);
     void    tADSRS_off           (tADSRS* const);
+    void    tADSRS_setSampleRate (tADSRS* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
@@ -528,9 +536,9 @@
     
     typedef struct _tRamp
     {
-        
         tMempool mempool;
         float inc;
+        float sampleRate;
         float inv_sr_ms;
         float minimum_time;
         float curr,dest;
@@ -550,6 +558,7 @@
     void    tRamp_setTime       (tRamp* const, float time);
     void    tRamp_setDest       (tRamp* const, float dest);
     void    tRamp_setVal        (tRamp* const, float val);
+    void    tRamp_setSampleRate (tRamp* const, float sr);
     
     /*!
      @defgroup trampupdown tRampUpDown
@@ -599,10 +608,10 @@
     
     typedef struct _tRampUpDown
     {
-        
         tMempool mempool;
         float upInc;
         float downInc;
+        float sampleRate;
         float inv_sr_ms;
         float minimum_time;
         float curr,dest;
@@ -623,9 +632,8 @@
     void    tRampUpDown_setDownTime       (tRampUpDown* const, float downTime);
     void    tRampUpDown_setDest       (tRampUpDown* const, float dest);
     void    tRampUpDown_setVal        (tRampUpDown* const, float val);
+    void    tRampUpDown_setSampleRate (tRampUpDown* const, float sr);
     
-    
-    
     /*!
      @defgroup tslide tSlide
      @ingroup envelopes
@@ -670,7 +678,6 @@
     
     typedef struct _tSlide
     {
-        
         tMempool mempool;
         float prevOut;
         float currentOut;
--- a/leaf/Inc/leaf-filters.h
+++ b/leaf/Inc/leaf-filters.h
@@ -143,10 +143,12 @@
     {
         
         tMempool mempool;
+        float freq;
         float gain;
         float a0,a1;
         float b0,b1;
         float lastIn, lastOut;
+        float twoPiTimesInvSampleRate;
     } _tOnePole;
     
     typedef _tOnePole* tOnePole;
@@ -162,6 +164,7 @@
     void    tOnePole_setFreq        (tOnePole* const, float freq);
     void    tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
     void    tOnePole_setGain        (tOnePole* const, float gain);
+    void    tOnePole_setSampleRate  (tOnePole* const, float sr);
     
     //==============================================================================
     
@@ -228,6 +231,9 @@
         int normalize;
         
         float lastOut[2];
+        
+        float sampleRate;
+        float twoPiTimesInvSampleRate;
     } _tTwoPole;
     
     typedef _tTwoPole* tTwoPole;
@@ -243,6 +249,7 @@
     void    tTwoPole_setResonance   (tTwoPole* const, float freq, float radius, int normalize);
     void    tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
     void    tTwoPole_setGain        (tTwoPole* const, float gain);
+    void    tTwoPole_setSampleRate  (tTwoPole* const, float sr);
     
     //==============================================================================
     
@@ -298,11 +305,11 @@
     
     typedef struct _tOneZero
     {
-        
         tMempool mempool;
         float gain;
         float b0,b1;
         float lastIn, lastOut, frequency;
+        float invSampleRate;
     } _tOneZero;
     
     typedef _tOneZero* tOneZero;
@@ -317,7 +324,8 @@
     void    tOneZero_setZero        (tOneZero* const, float theZero);
     void    tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
     void    tOneZero_setGain        (tOneZero* const, float gain);
-    float   tOneZero_getPhaseDelay  (tOneZero *f, float frequency);
+    float   tOneZero_getPhaseDelay  (tOneZero* const, float frequency);
+    void    tOneZero_setSampleRate  (tOneZero* const, float sr);
     
     //==============================================================================
     
@@ -374,15 +382,13 @@
 
     typedef struct _tTwoZero
     {
-        
         tMempool mempool;
         
         float gain;
         float b0, b1, b2;
-        
         float frequency, radius;
-        
         float lastIn[2];
+        float twoPiTimesInvSampleRate;
     } _tTwoZero;
     
     typedef _tTwoZero* tTwoZero;
@@ -398,6 +404,7 @@
     void    tTwoZero_setNotch       (tTwoZero* const, float frequency, float radius);
     void    tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
     void    tTwoZero_setGain        (tTwoZero* const, float gain);
+    void    tTwoZero_setSampleRate  (tTwoZero* const, float sr);
     
     //==============================================================================
     
@@ -552,7 +559,6 @@
     
     typedef struct _tBiQuad
     {
-        
         tMempool mempool;
         
         float gain;
@@ -564,6 +570,9 @@
         
         float frequency, radius;
         int normalize;
+        
+        float sampleRate;
+        float twoPiTimesInvSampleRate;
     } _tBiQuad;
     
     typedef _tBiQuad* tBiQuad;
@@ -582,6 +591,7 @@
     void    tBiQuad_setResonance   (tBiQuad* const, float freq, float radius, int normalize);
     void    tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
     void    tBiQuad_setGain        (tBiQuad* const, float gain);
+    void    tBiQuad_setSampleRate  (tBiQuad* const, float sr);
     
     //==============================================================================
     
@@ -636,12 +646,13 @@
     
     typedef struct _tSVF
     {
-        
         tMempool mempool;
         SVFType type;
         float cutoff, Q;
         float ic1eq,ic2eq;
         float g,k,a1,a2,a3,cH,cB,cL,cBK;
+        float sampleRate;
+        float invSampleRate;
     } _tSVF;
     
     typedef _tSVF* tSVF;
@@ -654,6 +665,7 @@
     void    tSVF_setFreq        (tSVF* const, float freq);
     void    tSVF_setQ           (tSVF* const, float Q);
     void    tSVF_setFreqAndQ    (tSVF* const svff, float freq, float Q);
+    void    tSVF_setSampleRate  (tSVF* const svff, float sr);
     
     //==============================================================================
     
@@ -749,10 +761,10 @@
     
     typedef struct _tHighpass
     {
-        
         tMempool mempool;
         float xs, ys, R;
         float frequency;
+        float twoPiTimesInvSampleRate;
     } _tHighpass;
     
     typedef _tHighpass* tHighpass;
@@ -764,6 +776,7 @@
     float   tHighpass_tick          (tHighpass* const, float x);
     void    tHighpass_setFreq       (tHighpass* const, float freq);
     float   tHighpass_getFreq       (tHighpass* const);
+    void    tHighpass_setSampleRate (tHighpass* const, float sr);
     
     //==============================================================================
     
@@ -835,6 +848,7 @@
     void    tButterworth_setF1          (tButterworth* const, float in);
     void    tButterworth_setF2          (tButterworth* const, float in);
     void    tButterworth_setFreqs       (tButterworth* const, float f1, float f2);
+    void    tButterworth_setSampleRate  (tButterworth* const, float sr);
     
     //==============================================================================
     
@@ -952,10 +966,6 @@
      @brief Free a tVZFilter from its mempool.
      @param filter A pointer to the tVZFilter to free.
      
-     @fn void    tVZFilter_setSampleRate  (tVZFilter* const, float sampleRate)
-     @brief
-     @param filter A pointer to the relevant tVZFilter.
-     
      @fn float   tVZFilter_tick               (tVZFilter* const, float input)
      @brief
      @param filter A pointer to the relevant tVZFilter.
@@ -991,6 +1001,10 @@
      @fn float   tVZFilter_BandwidthToR        (tVZFilter* const vf, float B)
      @brief
      @param filter A pointer to the relevant tVZFilter.
+     
+     @fn void    tVZFilter_setSampleRate  (tVZFilter* const, float sampleRate)
+     @brief
+     @param filter A pointer to the relevant tVZFilter.
      
      @} */
     
@@ -1012,7 +1026,6 @@
     
     typedef struct _tVZFilter
     {
-        
         tMempool mempool;
         
         VZFilterType type;
@@ -1032,8 +1045,8 @@
         float B;     // bandwidth (in octaves)
         float m;     // morph parameter (0...1)
         
-        float sr;    //local sampling rate of filter (may be different from leaf sr if oversampled)
-        float inv_sr;
+        float sampleRate;    //local sampling rate of filter (may be different from leaf sr if oversampled)
+        float invSampleRate;
     } _tVZFilter;
     
     typedef _tVZFilter* tVZFilter;
@@ -1094,8 +1107,8 @@
     //diode ladder filter
     typedef struct _tDiodeFilter
     {
-        
         tMempool mempool;
+        float cutoff;
         float f;
         float r;
         float Vt;
@@ -1106,6 +1119,7 @@
         float g1inv;
         float g2inv;
         float s0, s1, s2, s3;
+        float invSampleRate;
     } _tDiodeFilter;
     
     typedef _tDiodeFilter* tDiodeFilter;
@@ -1117,7 +1131,7 @@
     float   tDiodeFilter_tick               (tDiodeFilter* const, float input);
     void    tDiodeFilter_setFreq     (tDiodeFilter* const vf, float cutoff);
     void    tDiodeFilter_setQ     (tDiodeFilter* const vf, float resonance);
-    
+    void    tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr);
     
 #ifdef __cplusplus
 }
--- a/leaf/Inc/leaf-instruments.h
+++ b/leaf/Inc/leaf-instruments.h
@@ -115,6 +115,7 @@
     void    t808Cowbell_setFreq         (t808Cowbell* const, float freq);
     void    t808Cowbell_setOscMix       (t808Cowbell* const, float oscMix);
     void    t808Cowbell_setStick        (t808Cowbell* const, int useStick);
+    void    t808Cowbell_setSampleRate   (t808Cowbell* const, float sr);
     
     //==============================================================================
     
@@ -227,6 +228,7 @@
     void    t808Hihat_setOscFreq            (t808Hihat* const, float freq);
     void    t808Hihat_setStretch            (t808Hihat* const hihat, float stretch);
     void    t808Hihat_setFM                 (t808Hihat* const hihat, float FM_amount);
+    void    t808Hihat_setSampleRate         (t808Hihat* const, float sr);
     
     //==============================================================================
     
@@ -333,6 +335,7 @@
     void    t808Snare_setToneNoiseMix       (t808Snare* const, float toneNoiseMix);
     void    t808Snare_setNoiseFilterFreq    (t808Snare* const, float noiseFilterFreq);
     void    t808Snare_setNoiseFilterQ       (t808Snare* const, float noiseFilterQ);
+    void    t808Snare_setSampleRate         (t808Snare* const, float sr);
     
     //==============================================================================
     
@@ -437,6 +440,7 @@
     void    t808Kick_setToneNoiseMix    (t808Kick* const, float toneNoiseMix);
     void    t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
     void    t808Kick_setNoiseFilterQ    (t808Kick* const, float noiseFilterQ);
+    void    t808kick_setSampleRate      (t808Kick* const, float sr);
     
     //==============================================================================
     
--- a/leaf/Inc/leaf-midi.h
+++ b/leaf/Inc/leaf-midi.h
@@ -309,7 +309,8 @@
     int     tPoly_getKey                (tPoly* const poly, uint8_t voice);
     int     tPoly_getVelocity           (tPoly* const poly, uint8_t voice);
     int     tPoly_isOn                  (tPoly* const poly, uint8_t voice);
-
+    void    tPoly_setSampleRate         (tPoly* const poly, float sr);
+    
     //==============================================================================
 
     /*! @}
--- a/leaf/Inc/leaf-oscillators.h
+++ b/leaf/Inc/leaf-oscillators.h
@@ -63,11 +63,11 @@
     
     typedef struct _tCycle
     {
-        
         tMempool mempool;
         // Underlying phasor
         float phase;
         float inc,freq;
+        float invSampleRate;
     } _tCycle;
     
     typedef _tCycle* tCycle;
@@ -78,6 +78,7 @@
     
     float   tCycle_tick         (tCycle* const osc);
     void    tCycle_setFreq      (tCycle* const osc, float freq);
+    void    tCycle_setSampleRate(tCycle* const osc, float sr);
     
     //==============================================================================
     
@@ -122,6 +123,7 @@
         float inc,freq;
         int oct;
         float w;
+        float invSampleRate;
     } _tTriangle;
     
     typedef _tTriangle* tTriangle;
@@ -132,7 +134,7 @@
     
     float   tTriangle_tick          (tTriangle* const osc);
     void    tTriangle_setFreq       (tTriangle* const osc, float freq);
-
+    void    tTriangle_setSampleRate (tTriangle* const osc, float sr);
     
     //==============================================================================
     
@@ -177,6 +179,7 @@
         float inc,freq;
         int oct;
         float w;
+        float invSampleRate;
     } _tSquare;
     
     typedef _tSquare* tSquare;
@@ -187,6 +190,7 @@
 
     float   tSquare_tick        (tSquare* const osc);
     void    tSquare_setFreq     (tSquare* const osc, float freq);
+    void    tSquare_setSampleRate (tSquare* const osc, float sr);
     
     /*!
      @} */
@@ -234,6 +238,7 @@
         float inc,freq;
         int oct;
         float w;
+        float invSampleRate;
     } _tSawtooth;
     
     typedef _tSawtooth* tSawtooth;
@@ -244,6 +249,7 @@
 
     float   tSawtooth_tick          (tSawtooth* const osc);
     void    tSawtooth_setFreq       (tSawtooth* const osc, float freq);
+    void    tSawtooth_setSampleRate (tSawtooth* const osc, float sr);
     
     //==============================================================================
     
@@ -288,6 +294,7 @@
         float inc,freq;
         float skew;
         float lastOut;
+        float invSampleRate;
     } _tPBTriangle;
     
     typedef _tPBTriangle* tPBTriangle;
@@ -299,6 +306,7 @@
     float   tPBTriangle_tick          (tPBTriangle* const osc);
     void    tPBTriangle_setFreq       (tPBTriangle* const osc, float freq);
     void    tPBTriangle_setSkew       (tPBTriangle* const osc, float skew);
+    void    tPBTriangle_setSampleRate (tPBTriangle* const osc, float sr);
     
     //==============================================================================
     
@@ -342,6 +350,7 @@
         float phase;
         float inc,freq;
         float width;
+        float invSampleRate;
     } _tPBPulse;
     
     typedef _tPBPulse* tPBPulse;
@@ -353,6 +362,7 @@
     float   tPBPulse_tick        (tPBPulse* const osc);
     void    tPBPulse_setFreq     (tPBPulse* const osc, float freq);
     void    tPBPulse_setWidth    (tPBPulse* const osc, float width);
+    void    tPBPulse_setSampleRate (tPBPulse* const osc, float sr);
     
     //==============================================================================
     
@@ -391,6 +401,7 @@
         tMempool mempool;
         float phase;
         float inc,freq;
+        float invSampleRate;
     } _tPBSaw;
     
     typedef _tPBSaw* tPBSaw;
@@ -401,6 +412,7 @@
     
     float   tPBSaw_tick          (tPBSaw* const osc);
     void    tPBSaw_setFreq       (tPBSaw* const osc, float freq);
+    void    tPBSaw_setSampleRate (tPBSaw* const osc, float sr);
     
     //==============================================================================
     
@@ -441,6 +453,7 @@
         float phase;
         float inc,freq;
         uint8_t phaseDidReset;
+        float invSampleRate;
     } _tPhasor;
     
     typedef _tPhasor* tPhasor;
@@ -451,6 +464,7 @@
     
     float   tPhasor_tick        (tPhasor* const osc);
     void    tPhasor_setFreq     (tPhasor* const osc, float freq);
+    void    tPhasor_setSampleRate (tPhasor* const osc, float sr);
     
     //==============================================================================
     
@@ -643,9 +657,7 @@
     void    tNeuron_setV2       (tNeuron* const neuron, float V2);
     void    tNeuron_setV3       (tNeuron* const neuron, float V3);
     void    tNeuron_setTimeStep (tNeuron* const neuron, float timestep);
-    
 
-    
     //==============================================================================
     
     
@@ -708,6 +720,7 @@
         float   _f [FILLEN + STEP_DD_PULSE_LENGTH];
         int     _j, _k;
         bool    _init;
+        float invSampleRate;
     } _tMBPulse;
     
     typedef _tMBPulse* tMBPulse;
@@ -721,6 +734,7 @@
     void tMBPulse_setWidth(tMBPulse* const osc, float w);
     float tMBPulse_sync(tMBPulse* const osc, float sync);
     void tMBPulse_setSyncMode(tMBPulse* const osc, int hardOrSoft);
+    void    tMBPulse_setSampleRate (tMBPulse* const osc, float sr);
     
     /*!
      @defgroup tmbtriangle tMBTriangle
@@ -779,6 +793,7 @@
         float   _f [FILLEN + LONGEST_DD_PULSE_LENGTH];
         int     _j, _k;
         bool    _init;
+        float invSampleRate;
     } _tMBTriangle;
     
     typedef _tMBTriangle* tMBTriangle;
@@ -792,6 +807,7 @@
     void tMBTriangle_setWidth(tMBTriangle* const osc, float w);
     float tMBTriangle_sync(tMBTriangle* const osc, float sync);
     void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft);
+    void   tMBTriangle_setSampleRate (tMBTriangle* const osc, float sr);
     
     
     /*!
@@ -849,6 +865,7 @@
         float   _f [FILLEN + STEP_DD_PULSE_LENGTH];
         int     _j;
         bool    _init;
+        float invSampleRate;
     } _tMBSaw;
     
     typedef _tMBSaw* tMBSaw;
@@ -861,6 +878,7 @@
     void tMBSaw_setFreq(tMBSaw* const osc, float f);
     float tMBSaw_sync(tMBSaw* const osc, float sync);
     void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft);
+    void    tMBSaw_setSampleRate (tMBSaw* const osc, float sr);
     
     //==============================================================================
     
@@ -908,6 +926,7 @@
         int size;
         float inc, freq;
         float phase;
+        float invSampleRate;
     } _tTable;
     
     typedef _tTable* tTable;
@@ -918,6 +937,7 @@
     
     float   tTable_tick(tTable* const osc);
     void    tTable_setFreq(tTable* const osc, float freq);
+    void    tTable_setSampleRate (tTable* const osc, float sr);
     
     //==============================================================================
     
@@ -953,11 +973,14 @@
     {
         tMempool mempool;
         
+        float* baseTable;
         float** tables;
         int size;
         int numTables;
+        float maxFreq;
         float baseFreq, invBaseFreq;
         tButterworth bl;
+        float sampleRate;
     } _tWaveTable;
     
     typedef _tWaveTable* tWaveTable;
@@ -967,6 +990,7 @@
     void    tWaveTable_initToPool(tWaveTable* const osc, float* table, int size,
                                   float maxFreq, tMempool* const mempool);
     void    tWaveTable_free(tWaveTable* const osc);
+    void    tWaveTable_setSampleRate (tWaveTable* const osc, float sr);
    
     //==============================================================================
     
@@ -995,6 +1019,7 @@
         float inc, freq;
         float phase;
         float phaseOffset;
+        float invSampleRate;
         
         int oct;
         float w;
@@ -1011,6 +1036,7 @@
     void    tWaveOsc_setFreq(tWaveOsc* const osc, float freq);
     void    tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);
     void    tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);
+    void    tWaveOsc_setSampleRate (tWaveOsc* const osc, float sr);
     
     //==============================================================================
     
@@ -1087,6 +1113,7 @@
     void    tWaveSynth_setIndexGain(tWaveSynth* const osc, int i, float gain);
     void    tWaveSynth_setIndexPhase(tWaveSynth* const osc, int i, float phase);
 //    void    tWaveSynth_setIndexTable(tWaveSynth* const osc, int i, float* table, int size);
+    void    tWaveSynth_setSampleRate (tWaveSynth* const osc, float sr);
 
     //==============================================================================
     
@@ -1122,13 +1149,16 @@
     {
         tMempool mempool;
         
+        float* baseTable;
         float** tables;
         int numTables;
         int* sizes;
+        float maxFreq;
         float baseFreq, invBaseFreq;
         tButterworth bl;
         float dsBuffer[2];
         tOversampler ds;
+        float sampleRate;
     } _tWaveTableS;
     
     typedef _tWaveTableS* tWaveTableS;
@@ -1136,6 +1166,7 @@
     void    tWaveTableS_init(tWaveTableS* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
     void    tWaveTableS_initToPool(tWaveTableS* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
     void    tWaveTableS_free(tWaveTableS* const osc);
+    void    tWaveTableS_setSampleRate (tWaveTableS* const osc, float sr);
     
     /*!
      @defgroup twaveoscs tWaveOscS
@@ -1182,6 +1213,7 @@
         float inc, freq;
         float phase;
         float phaseOffset;
+        float invSampleRate;
         int oct;
         float w;
         float aa;
@@ -1197,6 +1229,7 @@
     void    tWaveOscS_setFreq(tWaveOscS* const osc, float freq);
     void    tWaveOscS_setAntiAliasing(tWaveOscS* const osc, float aa);
     void    tWaveOscS_setPhaseOffset(tWaveOscS* const osc, float phase);
+    void    tWaveOscS_setSampleRate (tWaveOscS* const osc, float sr);
     
     //==============================================================================
     
@@ -1273,6 +1306,7 @@
     void    tWaveSynthS_setIndexGain(tWaveSynthS* const osc, int i, float gain);
     void    tWaveSynthS_setIndexPhase(tWaveSynthS* const osc, int i, float phase);
 //    void    tWaveSynthS_setIndexTable(tWaveSynthS* const osc, int i, float* table, int size);
+    void    tWaveSynthS_setSampleRate (tWaveSynthS* const osc, float sr);
     
 #ifdef __cplusplus
 }
--- a/leaf/Inc/leaf-physical.h
+++ b/leaf/Inc/leaf-physical.h
@@ -71,7 +71,7 @@
      @fn void    tPluck_noteOff       (tPluck* const, float amplitude )
      @brief Stop a note with the given amplitude (speed of decay)
      @param string A pointer to the relevant tPluck.
-
+     
      @fn void    tPluck_setFrequency  (tPluck* const, float frequency )
      @brief Set instrument parameters for a particular frequency.
      @param string A pointer to the relevant tPluck.
@@ -79,7 +79,7 @@
      @fn void    tPluck_controlChange (tPluck* const, int number, float value)
      @brief Perform the control change specified by \e number and \e value (0.0 - 128.0).
      @param string A pointer to the relevant tPluck.
-    
+     
      @fn float   tPluck_getLastOut    (tPluck* const)
      @brief
      @param string A pointer to the relevant tPluck.
@@ -100,7 +100,7 @@
         float loopGain;
         float lastFreq;
         
-        float sr;
+        float sampleRate;
     } _tPluck;
     
     typedef _tPluck* tPluck;
@@ -116,6 +116,7 @@
     void    tPluck_setFrequency  (tPluck* const, float frequency );
     void    tPluck_controlChange (tPluck* const, int number, float value);
     float   tPluck_getLastOut    (tPluck* const);
+    void    tPluck_setSampleRate (tPluck* const, float sr);
     
     //==============================================================================
     
@@ -146,7 +147,7 @@
      @fn void    tKarplusStrong_pluck              (tKarplusStrong* const, float amplitude)
      @brief Pluck the string.
      @param string A pointer to the relevant tKarplusStrong.
-    
+     
      @fn void    tKarplusStrong_noteOn             (tKarplusStrong* const, float frequency, float amplitude)
      @brief Start a note with the given frequency and amplitude.
      @param string A pointer to the relevant tKarplusStrong.
@@ -210,6 +211,8 @@
         float pickupPosition;
         
         float lastOut;
+        
+        float sampleRate;
     } _tKarplusStrong;
     
     typedef _tKarplusStrong* tKarplusStrong;
@@ -307,6 +310,7 @@
         tHighpass DCblocker;
         tFeedbackLeveler fbLev;
         tExpSmooth wlSmooth;
+        float sampleRate;
     } _tSimpleLivingString;
     
     typedef _tSimpleLivingString* tSimpleLivingString;
@@ -329,6 +333,7 @@
     void    tSimpleLivingString_setLevSmoothFactor  (tSimpleLivingString* const, float levSmoothFactor);
     void    tSimpleLivingString_setLevStrength      (tSimpleLivingString* const, float levStrength);
     void    tSimpleLivingString_setLevMode          (tSimpleLivingString* const, int levMode);
+    void    tSimpleLivingString_setSampleRate       (tSimpleLivingString* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
@@ -404,7 +409,6 @@
     
     typedef struct _tLivingString
     {
-        
         tMempool mempool;
         float freq, waveLengthInSamples;        // the frequency of the whole string, determining delay length
         float pickPos;    // the pick position, dividing the string in two, in ratio
@@ -418,6 +422,7 @@
         tHighpass DCblockerL, DCblockerU;
         tFeedbackLeveler fbLevU, fbLevL;
         tExpSmooth wlSmooth, ppSmooth;
+        float sampleRate;
     } _tLivingString;
     
     typedef _tLivingString* tLivingString;
@@ -442,11 +447,11 @@
     void    tLivingString_setLevSmoothFactor    (tLivingString* const, float levSmoothFactor);
     void    tLivingString_setLevStrength        (tLivingString* const, float levStrength);
     void    tLivingString_setLevMode            (tLivingString* const, int levMode);
+    void    tLivingString_setSampleRate         (tLivingString* const, float sr);
     
-
-  // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-   
+    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
+    
     /*!
      @defgroup tlivingstring2 tLivingString2
      @ingroup physical
@@ -524,55 +529,56 @@
      
      @} */
     typedef struct _tLivingString2
-        {
-
-            tMempool mempool;
-            float freq, waveLengthInSamples;        // the frequency of the whole string, determining delay length
-            float pickPos;    // the pick position, dividing the string in two, in ratio
-            float prepPos;    // the preparation position, dividing the string in two, in ratio
-            float pickupPos;    // the preparation position, dividing the string in two, in ratio
-            float prepIndex;    // the amount of pressure on the preparation position of the string (near 0=soft obj, near 1=hard obj)
-            float decay; // amplitude damping factor for the string (only active in mode 0)
-            int levMode;
-            float brightness;
-            float curr;
-            tHermiteDelay delLF,delUF,delUB,delLB;    // delay for lower/upper/forward/backward part of the waveguide model
-            tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;
-            tHighpass DCblockerL, DCblockerU;
-            tFeedbackLeveler fbLevU, fbLevL;
-            tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;
-        } _tLivingString2;
-
-        typedef _tLivingString2* tLivingString2;
-
-        void    tLivingString2_init                  (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
-                                                     float brightness, float decay, float targetLev, float levSmoothFactor,
-                                                     float levStrength, int levMode, LEAF* const leaf);
-        void    tLivingString2_initToPool            (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
-                                                     float brightness, float decay, float targetLev, float levSmoothFactor,
-                                                     float levStrength, int levMode, tMempool* const);
-        void    tLivingString2_free                  (tLivingString2* const);
-
-        float   tLivingString2_tick                  (tLivingString2* const, float input);
-        float   tLivingString2_sample                (tLivingString2* const);
-        void    tLivingString2_setFreq               (tLivingString2* const, float freq);
-        void    tLivingString2_setWaveLength         (tLivingString2* const, float waveLength); // in samples
-        void    tLivingString2_setPickPos            (tLivingString2* const, float pickPos);
-        void    tLivingString2_setPrepPos            (tLivingString2* const, float prepPos);
-        void    tLivingString2_setPickupPos            (tLivingString2* const, float pickupPos);
-        void    tLivingString2_setPrepIndex          (tLivingString2* const, float prepIndex);
-        void    tLivingString2_setBrightness         (tLivingString2* const, float brightness);
-        void    tLivingString2_setDecay              (tLivingString2* const, float decay); // from 0 to 1, gets converted to real decay factor
-        void    tLivingString2_setTargetLev          (tLivingString2* const, float targetLev);
-        void    tLivingString2_setLevSmoothFactor    (tLivingString2* const, float levSmoothFactor);
-        void    tLivingString2_setLevStrength        (tLivingString2* const, float levStrength);
-        void    tLivingString2_setLevMode            (tLivingString2* const, int levMode);
-
-
-
-            // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-        // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
+    {
+        tMempool mempool;
+        float freq, waveLengthInSamples;        // the frequency of the whole string, determining delay length
+        float pickPos;    // the pick position, dividing the string in two, in ratio
+        float prepPos;    // the preparation position, dividing the string in two, in ratio
+        float pickupPos;    // the preparation position, dividing the string in two, in ratio
+        float prepIndex;    // the amount of pressure on the preparation position of the string (near 0=soft obj, near 1=hard obj)
+        float decay; // amplitude damping factor for the string (only active in mode 0)
+        int levMode;
+        float brightness;
+        float curr;
+        tHermiteDelay delLF,delUF,delUB,delLB;    // delay for lower/upper/forward/backward part of the waveguide model
+        tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;
+        tHighpass DCblockerL, DCblockerU;
+        tFeedbackLeveler fbLevU, fbLevL;
+        tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;
+        float sampleRate;
+    } _tLivingString2;
+    
+    typedef _tLivingString2* tLivingString2;
+    
+    void    tLivingString2_init                  (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
+                                                  float brightness, float decay, float targetLev, float levSmoothFactor,
+                                                  float levStrength, int levMode, LEAF* const leaf);
+    void    tLivingString2_initToPool            (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
+                                                  float brightness, float decay, float targetLev, float levSmoothFactor,
+                                                  float levStrength, int levMode, tMempool* const);
+    void    tLivingString2_free                  (tLivingString2* const);
+    
+    float   tLivingString2_tick                  (tLivingString2* const, float input);
+    float   tLivingString2_sample                (tLivingString2* const);
+    void    tLivingString2_setFreq               (tLivingString2* const, float freq);
+    void    tLivingString2_setWaveLength         (tLivingString2* const, float waveLength); // in samples
+    void    tLivingString2_setPickPos            (tLivingString2* const, float pickPos);
+    void    tLivingString2_setPrepPos            (tLivingString2* const, float prepPos);
+    void    tLivingString2_setPickupPos            (tLivingString2* const, float pickupPos);
+    void    tLivingString2_setPrepIndex          (tLivingString2* const, float prepIndex);
+    void    tLivingString2_setBrightness         (tLivingString2* const, float brightness);
+    void    tLivingString2_setDecay              (tLivingString2* const, float decay); // from 0 to 1, gets converted to real decay factor
+    void    tLivingString2_setTargetLev          (tLivingString2* const, float targetLev);
+    void    tLivingString2_setLevSmoothFactor    (tLivingString2* const, float levSmoothFactor);
+    void    tLivingString2_setLevStrength        (tLivingString2* const, float levStrength);
+    void    tLivingString2_setLevMode            (tLivingString2* const, int levMode);
+    void    tLivingString2_setSampleRate         (tLivingString2* const, float sr);
+    
+    
+    
+    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+    
     /*!
      @defgroup tcomplexlivingstring tComplexLivingString
      @ingroup physical
@@ -649,7 +655,6 @@
     
     typedef struct _tComplexLivingString
     {
-        
         tMempool mempool;
         float freq, waveLengthInSamples;        // the frequency of the whole string, determining delay length
         float pickPos;    // the pick position, dividing the string, in ratio
@@ -665,10 +670,11 @@
         tHighpass DCblockerL, DCblockerU;
         tFeedbackLeveler fbLevU, fbLevL;
         tExpSmooth wlSmooth, pickPosSmooth, prepPosSmooth;
+        float sampleRate;
     } _tComplexLivingString;
-
+    
     typedef _tComplexLivingString* tComplexLivingString;
-
+    
     void    tComplexLivingString_init                  (tComplexLivingString* const, float freq, float pickPos,
                                                         float prepPos, float prepIndex, float dampFreq,
                                                         float decay, float targetLev, float levSmoothFactor,
@@ -678,7 +684,7 @@
                                                         float decay, float targetLev, float levSmoothFactor,
                                                         float levStrength, int levMode, tMempool* const);
     void    tComplexLivingString_free                  (tComplexLivingString* const);
-
+    
     float   tComplexLivingString_tick                  (tComplexLivingString* const, float input);
     float   tComplexLivingString_sample                (tComplexLivingString* const);
     void    tComplexLivingString_setFreq               (tComplexLivingString* const, float freq);
@@ -692,10 +698,11 @@
     void    tComplexLivingString_setLevSmoothFactor    (tComplexLivingString* const, float levSmoothFactor);
     void    tComplexLivingString_setLevStrength        (tComplexLivingString* const, float levStrength);
     void    tComplexLivingString_setLevMode            (tComplexLivingString* const, int levMode);
+    void    tComplexLivingString_setSampleRate         (tComplexLivingString* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
     
+    
     /*!
      @defgroup treedtable tReedTable
      @ingroup physical
@@ -733,7 +740,7 @@
      @param reed A pointer to the relevant tReedTable.
      
      @} */
-
+    
     typedef struct _tReedTable
     {
         
@@ -761,4 +768,5 @@
 #endif // LEAF_PHYSICAL_H_INCLUDED
 
 //==============================================================================
+
 
--- a/leaf/Inc/leaf-reverb.h
+++ b/leaf/Inc/leaf-reverb.h
@@ -78,6 +78,8 @@
         float mix, t60;
         
         float inv_441;
+        float sampleRate;
+        float invSampleRate;
         
         tDelay allpassDelays[2];
         tDelay combDelay;
@@ -97,6 +99,7 @@
     float   tPRCReverb_tick         (tPRCReverb* const, float input);
     void    tPRCReverb_setT60       (tPRCReverb* const, float t60);
     void    tPRCReverb_setMix       (tPRCReverb* const, float mix);
+    void    tPRCReverb_setSampleRate(tPRCReverb* const, float sr);
     
     //==============================================================================
     
@@ -149,7 +152,9 @@
         
         float mix, t60;
         
-        float inv_sr, inv_441;
+        float inv_441;
+        float sampleRate;
+        float invSampleRate;
         
         tLinearDelay allpassDelays[8];
         tLinearDelay combDelays[6];
@@ -171,6 +176,7 @@
     void    tNReverb_tickStereo     (tNReverb* const rev, float input, float* output);
     void    tNReverb_setT60         (tNReverb* const, float t60);
     void    tNReverb_setMix         (tNReverb* const, float mix);
+    void    tNReverb_setSampleRate  (tNReverb* const, float sr);
     
     //==============================================================================
     
@@ -245,12 +251,13 @@
         
         tMempool mempool;
         
+        float   sampleRate;
         float   predelay;
         float   input_filter;
         float   feedback_filter;
         float   feedback_gain;
         float   mix;
-        uint32_t frozen;
+        int frozen;
         
         float   size, size_max, t;
         
@@ -296,7 +303,7 @@
     float   tDattorroReverb_tick              (tDattorroReverb* const, float input);
     void    tDattorroReverb_tickStereo        (tDattorroReverb* const rev, float input, float* output);
     void    tDattorroReverb_setMix            (tDattorroReverb* const, float mix);
-    void    tDattorroReverb_setFreeze         (tDattorroReverb* const rev, uint32_t freeze);
+    void    tDattorroReverb_setFreeze         (tDattorroReverb* const rev, int freeze);
     void    tDattorroReverb_setHP             (tDattorroReverb* const, float freq);
     void    tDattorroReverb_setSize           (tDattorroReverb* const, float size);
     void    tDattorroReverb_setInputDelay     (tDattorroReverb* const, float preDelay);
@@ -303,6 +310,7 @@
     void    tDattorroReverb_setInputFilter    (tDattorroReverb* const, float freq);
     void    tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
     void    tDattorroReverb_setFeedbackGain   (tDattorroReverb* const, float gain);
+    void    tDattorroReverb_setSampleRate     (tDattorroReverb* const, float sr);
     
 #ifdef __cplusplus
 }
--- a/leaf/Inc/leaf-sampling.h
+++ b/leaf/Inc/leaf-sampling.h
@@ -243,13 +243,12 @@
     
     typedef struct _tSampler
     {
-        
         tMempool mempool;
         
         tBuffer samp;
         
-        float leafInvSampleRate;
-        float leafSampleRate;
+        float invSampleRate;
+        float sampleRate;
         float ticksPerSevenMs;
         float rateFactor;
         uint32_t channels;
@@ -284,11 +283,11 @@
     typedef _tSampler* tSampler;
     
     void    tSampler_init               (tSampler* const, tBuffer* const, LEAF* const leaf);
-    void     tSampler_initToPool            (tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf);
+    void    tSampler_initToPool            (tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf);
     void    tSampler_free               (tSampler* const);
     
     float   tSampler_tick               (tSampler* const);
-    float    tSampler_tickStereo            (tSampler* const sp, float* outputArray);
+    float   tSampler_tickStereo            (tSampler* const sp, float* outputArray);
     void    tSampler_setSample          (tSampler* const, tBuffer* const);
     void    tSampler_setMode            (tSampler* const, PlayMode mode);
     void    tSampler_play               (tSampler* const);
@@ -296,8 +295,9 @@
     void    tSampler_setStart           (tSampler* const, int32_t start);
     void    tSampler_setEnd             (tSampler* const, int32_t end);
     void    tSampler_setLength             (tSampler* const, int32_t length);
-    void    tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
+    void    tSampler_setCrossfadeLength (tSampler* const, uint32_t length);
     void    tSampler_setRate            (tSampler* const, float rate);
+    void    tSampler_setSampleRate      (tSampler* const, float sr);
     
     //==============================================================================
     
@@ -388,7 +388,7 @@
     void    tAutoSampler_setWindowSize      (tAutoSampler* const, uint32_t size);
     void    tAutoSampler_setCrossfadeLength (tAutoSampler* const, uint32_t length);
     void    tAutoSampler_setRate            (tAutoSampler* const, float rate);
-    
+    void    tAutoSampler_setSampleRate      (tAutoSampler* const, float sr);
     
     /*!
      @defgroup tmbsampler tMBSampler
--- a/leaf/Src/leaf-analysis.c
+++ b/leaf/Src/leaf-analysis.c
@@ -360,27 +360,13 @@
     mpool_free((char*)a, a->mempool);
 }
 
-/*******Public Functions***********/
-
-
 void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)
 {
     _tAttackDetection* a = *ad;
     
-    a->blocksize = size;
+    a->blockSize = size;
 }
 
-void tAttackDetection_setSamplerate(tAttackDetection* const ad, int inRate)
-{
-    _tAttackDetection* a = *ad;
-    
-    a->samplerate = inRate;
-    
-    //Reset atk and rel to recalculate coeff
-    tAttackDetection_setAttack(ad, a->atk);
-    tAttackDetection_setRelease(ad, a->rel);
-}
-
 void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
 {
     _tAttackDetection* a = *ad;
@@ -391,7 +377,7 @@
 {
     _tAttackDetection* a = *ad;
     a->atk = inAtk;
-    a->atk_coeff = powf(0.01f, 1.0f/(a->atk * a->samplerate * 0.001f));
+    a->atk_coeff = powf(0.01f, 1.0f/(a->atk * a->sampleRate * 0.001f));
 }
 
 void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)
@@ -398,10 +384,9 @@
 {
     _tAttackDetection* a = *ad;
     a->rel = inRel;
-    a->rel_coeff = powf(0.01f, 1.0f/(a->rel * a->samplerate * 0.001f));
+    a->rel_coeff = powf(0.01f, 1.0f/(a->rel * a->sampleRate * 0.001f));
 }
 
-
 int tAttackDetection_detect(tAttackDetection* const ad, float *in)
 {
     _tAttackDetection* a = *ad;
@@ -420,6 +405,16 @@
     return result;
 }
 
+void tAttackDetection_setSampleRate(tAttackDetection* const ad, float sr)
+{
+    _tAttackDetection* a = *ad;
+    
+    a->sampleRate = sr;
+    
+    tAttackDetection_setAttack(ad, a->atk);
+    tAttackDetection_setRelease(ad, a->rel);
+}
+
 /*******Private Functions**********/
 
 static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
@@ -428,9 +423,9 @@
     LEAF* leaf = a->mempool->leaf;
     
     a->env = 0;
-    a->blocksize = blocksize;
+    a->blockSize = blocksize;
     a->threshold = DEFTHRESHOLD;
-    a->samplerate = leaf->sampleRate;
+    a->sampleRate = leaf->sampleRate;
     a->prevAmp = 0;
     
     a->env = 0;
@@ -445,7 +440,7 @@
     
     int i = 0;
     float tmp;
-    for(i = 0; i < a->blocksize; ++i){
+    for(i = 0; i < a->blockSize; ++i){
         tmp = fastabsf(in[i]);
         
         if(tmp > a->env)
@@ -845,6 +840,7 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
     
+    p->invSampleRate = leaf->invSampleRate;
     p->inBuffer = in;
     p->bufSize = bufSize;
     p->frameSize = frameSize;
@@ -865,7 +861,7 @@
     p->alpha = 1.0f;
     p->tolerance = 1.0f;
     p->timeConstant = DEFTIMECONSTANT;
-    p->radius = expf(-1000.0f * p->hopSize * leaf->invSampleRate / p->timeConstant);
+    p->radius = expf(-1000.0f * p->hopSize * p->invSampleRate / p->timeConstant);
     p->fidelityThreshold = 0.95f;
 }
 
@@ -878,7 +874,7 @@
     mpool_free((char*)p, p->mempool);
 }
 
-float tPeriodDetection_tick (tPeriodDetection* pd, float sample)
+float tPeriodDetection_tick (tPeriodDetection* const pd, float sample)
 {
     _tPeriodDetection* p = *pd;
     
@@ -913,43 +909,43 @@
     return p->period;
 }
 
-float tPeriodDetection_getPeriod(tPeriodDetection* pd)
+float tPeriodDetection_getPeriod(tPeriodDetection* const pd)
 {
     _tPeriodDetection* p = *pd;
     return p->period;
 }
 
-float tPeriodDetection_getFidelity(tPeriodDetection* pd)
+float tPeriodDetection_getFidelity(tPeriodDetection* const pd)
 {
     _tPeriodDetection* p = *pd;
     return tSNAC_getFidelity(&p->snac);
 }
 
-void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
+void tPeriodDetection_setHopSize(tPeriodDetection* const pd, int hs)
 {
     _tPeriodDetection* p = *pd;
     p->hopSize = hs;
 }
 
-void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
+void tPeriodDetection_setWindowSize(tPeriodDetection* const pd, int ws)
 {
     _tPeriodDetection* p = *pd;
     p->windowSize = ws;
 }
 
-void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold)
+void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const pd, float threshold)
 {
     _tPeriodDetection* p = *pd;
     p->fidelityThreshold = threshold;
 }
 
-void tPeriodDetection_setAlpha            (tPeriodDetection* pd, float alpha)
+void tPeriodDetection_setAlpha            (tPeriodDetection* const pd, float alpha)
 {
     _tPeriodDetection* p = *pd;
     p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
 }
 
-void tPeriodDetection_setTolerance        (tPeriodDetection* pd, float tolerance)
+void tPeriodDetection_setTolerance        (tPeriodDetection* const pd, float tolerance)
 {
     _tPeriodDetection* p = *pd;
     if (tolerance < 0.0f) p->tolerance = 0.0f;
@@ -956,7 +952,15 @@
     else p->tolerance = tolerance;
 }
 
+void tPeriodDetection_setSampleRate (tPeriodDetection* const pd, float sr)
+{
+    _tPeriodDetection* p = *pd;
+    p->invSampleRate = 1.0f/sr;
+    p->radius = expf(-1000.0f * p->hopSize * p->invSampleRate / p->timeConstant);
+}
 
+//==========================================================================================
+
 void    tZeroCrossingInfo_init  (tZeroCrossingInfo* const zc, LEAF* const leaf)
 {
     tZeroCrossingInfo_initToPool(zc, &leaf->mempool);
@@ -1522,8 +1526,12 @@
     
     LEAF* leaf = p->mempool->leaf;
     
-    tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * leaf->sampleRate * 2.0f, hysteresis, mempool);
-    p->_min_period = (1.0f / highestFreq) * leaf->sampleRate;
+    p->sampleRate = leaf->sampleRate;
+    p->lowestFreq = lowestFreq;
+    p->highestFreq = highestFreq;
+    
+    tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * p->sampleRate * 2.0f, hysteresis, mempool);
+    p->_min_period = (1.0f / highestFreq) * p->sampleRate;
     p->_range = highestFreq / lowestFreq;
     
     int windowSize = tZeroCrossingCollector_getWindowSize(&p->_zc);
@@ -1670,6 +1678,18 @@
     return tZeroCrossingCollector_setHysteresis(&p->_zc, hysteresis);
 }
 
+void    tPeriodDetector_setSampleRate   (tPeriodDetector* const detector, float sr)
+{
+    _tPeriodDetector* p = *detector;
+    _tMempool* m = p->mempool;
+    p->sampleRate = sr;
+    float hysteresis = p->_zc->_hysteresis;
+    
+    tZeroCrossingCollector_free(&p->_zc);
+    tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / p->lowestFreq) * p->sampleRate * 2.0f, hysteresis, &m);
+    p->_min_period = (1.0f / p->highestFreq) * p->sampleRate;
+}
+
 static inline void set_bitstream(tPeriodDetector* const detector)
 {
     _tPeriodDetector* p = *detector;
@@ -1901,11 +1921,13 @@
     _tMempool* m = *mempool;
     _tPitchDetector* p = *detector = (_tPitchDetector*) mpool_alloc(sizeof(_tPitchDetector), m);
     p->mempool = m;
+    LEAF* leaf = p->mempool->leaf;
     
     tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, -120.0f, mempool);
     p->_current.frequency = 0.0f;
     p->_current.periodicity = 0.0f;
     p->_frames_after_shift = 0;
+    p->sampleRate = leaf->sampleRate;
 }
 
 void    tPitchDetector_free (tPitchDetector* const detector)
@@ -1991,11 +2013,10 @@
 float   tPitchDetector_predictFrequency (tPitchDetector* const detector)
 {
     _tPitchDetector* p = *detector;
-    LEAF* leaf = p->mempool->leaf;
     
     float period = tPeriodDetector_predictPeriod(&p->_pd);
     if (period > 0.0f)
-        return leaf->sampleRate / period;
+        return p->sampleRate / period;
     return 0.0f;
 }
 
@@ -2009,18 +2030,23 @@
 void    tPitchDetector_setHysteresis    (tPitchDetector* const detector, float hysteresis)
 {
     _tPitchDetector* p = *detector;
-    
     tPeriodDetector_setHysteresis(&p->_pd, hysteresis);
 }
 
+void    tPitchDetector_setSampleRate    (tPitchDetector* const detector, float sr)
+{
+    _tPitchDetector* p = *detector;
+    p->sampleRate = sr;
+    tPeriodDetector_setSampleRate(&p->_pd, p->sampleRate);
+}
+
 static inline float calculate_frequency(tPitchDetector* const detector)
 {
     _tPitchDetector* p = *detector;
-    LEAF* leaf = p->mempool->leaf;
     
     float period = p->_pd->_fundamental.period;
     if (period > 0.0f)
-        return leaf->sampleRate / period;
+        return p->sampleRate / period;
     return 0.0f;
 }
 
@@ -2131,9 +2157,12 @@
     _tMempool* m = *mempool;
     _tDualPitchDetector* p = *detector = (_tDualPitchDetector*) mpool_alloc(sizeof(_tDualPitchDetector), m);
     p->mempool = m;
+    LEAF* leaf = p->mempool->leaf;
     
     tPeriodDetection_initToPool(&p->_pd1, inBuffer, bufSize, bufSize / 2, mempool);
     tPitchDetector_initToPool(&p->_pd2, lowestFreq, highestFreq, mempool);
+    
+    p->sampleRate = leaf->sampleRate;
 
     p->_current.frequency = 0.0f;
     p->_current.periodicity = 0.0f;
@@ -2159,7 +2188,6 @@
 int     tDualPitchDetector_tick    (tDualPitchDetector* const detector, float sample)
 {
     _tDualPitchDetector* p = *detector;
-    LEAF* leaf = p->mempool->leaf;
     
     tPeriodDetection_tick(&p->_pd1, sample);
     int ready = tPitchDetector_tick(&p->_pd2, sample);
@@ -2172,7 +2200,7 @@
         if (!pd2_indeterminate && period != 0.0f)
         {
             _pitch_info _i1;
-            _i1.frequency = leaf->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);
+            _i1.frequency = p->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);
             _i1.periodicity = tPeriodDetection_getFidelity(&p->_pd1);
             _pitch_info _i2 = p->_pd2->_current;
             
@@ -2274,6 +2302,14 @@
     _tDualPitchDetector* p = *detector;
     
     p->thresh = thresh;
+}
+
+void    tDualPitchDetector_setSampleRate (tDualPitchDetector* const detector, float sr)
+{
+    _tDualPitchDetector* p = *detector;
+    p->sampleRate = sr;
+    tPeriodDetection_setSampleRate(&p->_pd1, p->sampleRate);
+    tPitchDetector_setSampleRate(&p->_pd2, p->sampleRate);
 }
 
 static inline void compute_predicted_frequency(tDualPitchDetector* const detector)
--- a/leaf/Src/leaf-delay.c
+++ b/leaf/Src/leaf-delay.c
@@ -346,9 +346,6 @@
 }
 
 
-
-
-
 /// Hermite Interpolated Delay
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
 void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay, LEAF* const leaf)
--- a/leaf/Src/leaf-distortion.c
+++ b/leaf/Src/leaf-distortion.c
@@ -90,6 +90,7 @@
         
         os->offset = offset;
         os->maxRatio = maxRatio;
+        os->allowHighQuality = extraQuality;
         os->ratio = os->maxRatio;
         int idx = (int)(log2f(os->ratio))-1+os->offset;
         os->numTaps = __leaf_tablesize_firNumTaps[idx];
@@ -318,12 +319,29 @@
     else if (ratio == 2 || ratio == 4  || ratio == 8 ||
         ratio == 16 || ratio == 32 || ratio == 64)
     {
-        os->ratio = os->ratio;
+        os->ratio = ratio;
         int idx = (int)(log2f(os->ratio))-1+os->offset;
         os->numTaps = __leaf_tablesize_firNumTaps[idx];
         os->phaseLength = os->numTaps / os->ratio;
         os->pCoeffs = (float*) __leaf_tableref_firCoeffs[idx];
     }
+}
+
+void    tOversampler_setQuality     (tOversampler* const osr, int quality)
+{
+    _tOversampler* os = *osr;
+    
+    if (!os->allowHighQuality) return;
+    int offset = 0;
+    if (quality > 0) offset = 6;
+    os->offset = offset;
+    
+    if (os->ratio == 1) return;
+    
+    int idx = (int)(log2f(os->ratio))-1+os->offset;
+    os->numTaps = __leaf_tablesize_firNumTaps[idx];
+    os->phaseLength = os->numTaps / os->ratio;
+    os->pCoeffs = (float*) __leaf_tableref_firCoeffs[idx];
 }
 
 int tOversampler_getLatency(tOversampler* const osr)
--- a/leaf/Src/leaf-dynamics.c
+++ b/leaf/Src/leaf-dynamics.c
@@ -51,6 +51,7 @@
     _tMempool* m = *mp;
     _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->tauAttack = 100;
     c->tauRelease = 100;
@@ -61,6 +62,8 @@
     c->R = 0.5f; // compression Ratio
     c->M = 3.0f; // decibel Width of knee transition
     c->W = 1.0f; // decibel Make-up gain
+    
+    c->sampleRate = leaf->sampleRate;
 }
 
 void tCompressor_free (tCompressor* const comp)
@@ -73,7 +76,6 @@
 float tCompressor_tick(tCompressor* const comp, float in)
 {
     _tCompressor* c = *comp;
-    LEAF* leaf = c->mempool->leaf;
     
     float slope, overshoot;
     float alphaAtt, alphaRel;
@@ -107,8 +109,8 @@
     
     c->x_T[0] = out_db - in_db;
     
-    alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * leaf->sampleRate));
-    alphaRel = expf(-1.0f/(0.001f * c->tauRelease * leaf->sampleRate));
+    alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * c->sampleRate));
+    alphaRel = expf(-1.0f/(0.001f * c->tauRelease * c->sampleRate));
     
     if (c->x_T[0] > c->y_T[1])
         c->y_T[0] = alphaAtt * c->y_T[1] + (1-alphaAtt) * c->x_T[0];
--- a/leaf/Src/leaf-effects.c
+++ b/leaf/Src/leaf-effects.c
@@ -42,6 +42,7 @@
     _tMempool* m = *mp;
     _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m);
     v->mempool = m;
+    LEAF* leaf = v->mempool->leaf;
     
     v->param[0] = 0.5f;  //wet
     v->param[1] = 0.0f;  //dry
@@ -62,6 +63,8 @@
     v->Rt = (double*) mpool_alloc(sizeof(double) * v->bufsize, m);
 
     v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
+    
+    v->sampleRate = leaf->sampleRate;
 
     tTalkbox_update(voc);
     tTalkbox_suspend(voc);
@@ -86,9 +89,8 @@
 void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
 {
     _tTalkbox* v = *voc;
-    LEAF* leaf = v->mempool->leaf;
     
-    float fs = leaf->sampleRate;
+    float fs = v->sampleRate;
 //    if(fs <  8000.0f) fs =  8000.0f;
 //    if(fs > 96000.0f) fs = 96000.0f;
     
@@ -320,10 +322,9 @@
 void tTalkbox_setQuality(tTalkbox* const voc, float quality)
 {
     _tTalkbox* v = *voc;
-    LEAF* leaf = v->mempool->leaf;
     
     v->param[3] = quality;
-    v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf->sampleRate);
+    v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * v->sampleRate);
     if (v->O >= ORD_MAX)
     {
         v->O = ORD_MAX-1;
@@ -351,8 +352,13 @@
     v->freeze = freeze;
 }
 
+void tTalkbox_setSampleRate(tTalkbox* const voc, float sr)
+{
+    _tTalkbox* v = *voc;
+    v->sampleRate = sr;
+    tTalkbox_update(voc);
+}
 
-
 ////
 
 // LPC vocoder adapted from MDA's excellent open source talkbox plugin code
@@ -374,6 +380,7 @@
     _tMempool* m = *mp;
     _tTalkboxFloat* v = *voc = (_tTalkboxFloat*) mpool_alloc(sizeof(_tTalkboxFloat), m);
     v->mempool = m;
+    LEAF* leaf = v->mempool->leaf;
 
     v->param[0] = 0.5f;  //wet
     v->param[1] = 0.0f;  //dry
@@ -394,6 +401,8 @@
     v->Rt = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
 
     v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
+    
+    v->sampleRate = leaf->sampleRate;
 
     tTalkboxFloat_update(voc);
     tTalkboxFloat_suspend(voc);
@@ -418,9 +427,8 @@
 void tTalkboxFloat_update(tTalkboxFloat* const voc) ///update internal parameters...
 {
     _tTalkboxFloat* v = *voc;
-    LEAF* leaf = v->mempool->leaf;
     
-    float fs = leaf->sampleRate;
+    float fs = v->sampleRate;
 //    if(fs <  8000.0f) fs =  8000.0f;
 //    if(fs > 96000.0f) fs = 96000.0f;
 
@@ -656,10 +664,9 @@
 void tTalkboxFloat_setQuality(tTalkboxFloat* const voc, float quality)
 {
     _tTalkboxFloat* v = *voc;
-    LEAF* leaf = v->mempool->leaf;
     
     v->param[3] = quality;
-    v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf->sampleRate);
+    v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * v->sampleRate);
     if (v->O >= ORD_MAX)
     {
         v->O = ORD_MAX-1;
@@ -687,6 +694,12 @@
     v->freeze = freeze;
 }
 
+void tTalkboxFloat_setSampleRate(tTalkboxFloat* const voc, float sr)
+{
+    _tTalkboxFloat* v = *voc;
+    v->sampleRate = sr;
+    tTalkboxFloat_update(voc);
+}
 
 //============================================================================================================
 // VOCODER
@@ -702,7 +715,10 @@
     _tMempool* m = *mp;
     _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m);
     v->mempool = m;
+    LEAF* leaf = v->mempool->leaf;
     
+    v->invSampleRate = leaf->invSampleRate;
+    
     v->param[0] = 0.33f;  //input select
     v->param[1] = 0.50f;  //output dB
     v->param[2] = 0.40f;  //hi thru
@@ -725,9 +741,8 @@
 void        tVocoder_update      (tVocoder* const voc)
 {
     _tVocoder* v = *voc;
-    LEAF* leaf = v->mempool->leaf;
     
-    float tpofs = 6.2831853f * leaf->invSampleRate;
+    float tpofs = 6.2831853f * v->invSampleRate;
     
     float rr, th;
     
@@ -871,7 +886,6 @@
     if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability
     
     return o;
-    
 }
 
 void        tVocoder_suspend     (tVocoder* const voc)
@@ -885,7 +899,14 @@
     v->kval = 0;
 }
 
+void    tVocoder_setSampleRate  (tVocoder* const voc, float sr)
+{
+    _tVocoder* v = *voc;
+    v->invSampleRate = 1.0f/sr;
+    tVocoder_update(voc);
+}
 
+
 /// Glottal Pulse (Rosenberg model)
 
 void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const gp, LEAF* const leaf)
@@ -898,6 +919,9 @@
      _tMempool* m = *mp;
     _tRosenbergGlottalPulse* g = *gp = (_tRosenbergGlottalPulse*) mpool_alloc(sizeof(_tRosenbergGlottalPulse), m);
     g->mempool = m;
+    LEAF* leaf = g->mempool->leaf;
+    
+    g->invSampleRate = leaf->invSampleRate;
 
     g->phase  = 0.0f;
     g->openLength = 0.0f;
@@ -972,10 +996,9 @@
 void   tRosenbergGlottalPulse_setFreq           (tRosenbergGlottalPulse* const gp, float freq)
 {
     _tRosenbergGlottalPulse* g = *gp;
-    LEAF* leaf = g->mempool->leaf;
     
     g->freq = freq;
-    g->inc = freq * leaf->invSampleRate;
+    g->inc = freq * g->invSampleRate;
     g->inc -= (int) g->inc;
 }
 
@@ -1001,6 +1024,12 @@
     g->invPulseLengthMinusOpenLength = 1.0f / (g->pulseLength - g->openLength);
 }
 
+void   tRosenbergGlottalPulse_setSampleRate(tRosenbergGlottalPulse* const gp, float sr)
+{
+    _tRosenbergGlottalPulse* g = *gp;
+    g->invSampleRate = 1.0f/sr;
+    tRosenbergGlottalPulse_setFreq(gp, g->freq);
+}
 
 
 //============================================================================================================
@@ -1140,6 +1169,13 @@
     w->blocksize = INITPERIOD;
 }
 
+void tSOLAD_setSampleRate(tSOLAD* const wp, float sr)
+{
+    _tSOLAD* w = *wp;
+    tAttackDetection_setSampleRate(&w->ad, sr);
+    tHighpass_setSampleRate(&w->hp, sr);
+}
+
 /******************************************************************************/
 /******************** private procedures **************************************/
 /******************************************************************************/
@@ -1380,11 +1416,14 @@
     _tMempool* m = *mp;
     _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m);
     ps->mempool = m;
+    LEAF* leaf = ps->mempool->leaf;
     
     ps->pd = *dpd;
     ps->bufSize = bufSize;
     ps->pickiness = 0.0f;
     
+    ps->sampleRate = leaf->sampleRate;
+    
     tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp);
     tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
 }
@@ -1400,13 +1439,12 @@
 void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out)
 {
     _tPitchShift* ps = *psr;
-    LEAF* leaf = ps->mempool->leaf;
     
     float detected = tDualPitchDetector_getFrequency(&ps->pd);
     float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
     if (detected > 0.0f && periodicity > ps->pickiness)
     {
-        float period = leaf->sampleRate / detected;
+        float period = ps->sampleRate / detected;
         tSOLAD_setPeriod(&ps->sola, period);
         tSOLAD_setPitchFactor(&ps->sola, factor);
     }
@@ -1417,7 +1455,6 @@
 void    tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out)
 {
     _tPitchShift* ps = *psr;
-    LEAF* leaf = ps->mempool->leaf;
     
     float detected = tDualPitchDetector_getFrequency(&ps->pd);
     float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
@@ -1425,7 +1462,7 @@
     {
         float period = 1.0f / detected;
         float factor = freq * period;
-        tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);
+        tSOLAD_setPeriod(&ps->sola, ps->sampleRate * period);
         tSOLAD_setPitchFactor(&ps->sola, factor);
     }
     
@@ -1435,11 +1472,16 @@
 void    tPitchShift_setPickiness (tPitchShift* const psr, float p)
 {
     _tPitchShift* ps = *psr;
-    
     ps->pickiness = p;
 }
 
+void    tPitchShift_setSampleRate(tPitchShift* const psr, float sr)
+{
+    _tPitchShift* ps = *psr;
+    tSOLAD_setSampleRate(&ps->sola, sr);
+}
 
+
 //============================================================================================================
 // SIMPLERETUNE
 //============================================================================================================
@@ -1571,6 +1613,16 @@
     return tDualPitchDetector_getFrequency(&r->dp);
 }
 
+void tSimpleRetune_setSampleRate (tSimpleRetune* const rt, float sr)
+{
+    _tSimpleRetune* r = *rt;
+    tDualPitchDetector_setSampleRate(&r->dp, sr);
+    for (int i = 0; i < r->numVoices; ++i)
+    {
+        tPitchShift_setSampleRate(&r->ps[i], sr);
+    }
+}
+
 //============================================================================================================
 // RETUNE
 //============================================================================================================
@@ -1708,6 +1760,16 @@
     return tDualPitchDetector_getFrequency(&r->dp);
 }
 
+void tRetune_setSampleRate(tRetune* const rt, float sr)
+{
+    _tRetune* r = *rt;
+    tDualPitchDetector_setSampleRate(&r->dp, sr);
+    for (int i = 0; i < r->numVoices; ++i)
+    {
+        tPitchShift_setSampleRate(&r->ps[i], sr);
+    }
+}
+
 //============================================================================================================
 // FORMANTSHIFTER
 //============================================================================================================
@@ -1738,14 +1800,16 @@
     
     fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
 
+    fs->sampleRate = leaf->sampleRate;
+    fs->invSampleRate = leaf->invSampleRate;
     
-    fs->falph = powf(0.001f, 10.0f * leaf->invSampleRate);
-    fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * leaf->sampleRate)) - 0.1916f);
+    fs->falph = powf(0.001f, 10.0f * fs->invSampleRate);
+    fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * fs->sampleRate)) - 0.1916f);
     fs->fhp = 0.0f;
     fs->flp = 0.0f;
-    fs->flpa = powf(0.001f, 10.0f * leaf->invSampleRate);
+    fs->flpa = powf(0.001f, 10.0f * fs->invSampleRate);
     fs->fmute = 1.0f;
-    fs->fmutealph = powf(0.001f, 1.0f * leaf->invSampleRate);
+    fs->fmutealph = powf(0.001f, 1.0f * fs->invSampleRate);
     fs->cbi = 0;
     fs->intensity = 1.0f;
     fs->invIntensity = 1.0f;
@@ -1927,8 +1991,6 @@
 {
     _tFormantShifter* fs = *fsr;
 
-
-
     fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
 
    // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
@@ -1942,5 +2004,17 @@
     {
         fs->invIntensity = 1.0f;
     }
+}
 
+void tFormantShifter_setSampleRate(tFormantShifter* const fsr, float sr)
+{
+    _tFormantShifter* fs = *fsr;
+    fs->sampleRate = sr;
+    fs->invSampleRate = 1.0f/fs->sampleRate;
+    fs->falph = powf(0.001f, 10.0f * fs->invSampleRate);
+    fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * fs->sampleRate)) - 0.1916f);
+    fs->flpa = powf(0.001f, 10.0f * fs->invSampleRate);
+    fs->fmutealph = powf(0.001f, 1.0f * fs->invSampleRate);
+    tHighpass_setSampleRate(&fs->hp, fs->sampleRate);
+    tHighpass_setSampleRate(&fs->hp2, fs->sampleRate);
 }
--- a/leaf/Src/leaf-electrical.c
+++ b/leaf/Src/leaf-electrical.c
@@ -222,6 +222,16 @@
 {
     _tWDF* r = *wdf;
     r->sample_rate = sample_rate;
+    if (r->type == Capacitor)
+    {
+        r->port_conductance_up = r->sample_rate * 2.0f * r->value;
+        r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
+    }
+    else if (r->type == Inductor)
+    {
+        r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
+        r->port_conductance_up = 1.0f / r->port_resistance_up;
+    }
 }
 
 uint8_t tWDF_isLeaf(tWDF* const wdf)
--- a/leaf/Src/leaf-envelopes.c
+++ b/leaf/Src/leaf-envelopes.c
@@ -118,7 +118,6 @@
     env->loop = loop;
 }
 
-
 void     tEnvelope_on(tEnvelope* const envlp, float velocity)
 {
     _tEnvelope* env = *envlp;
@@ -495,7 +494,6 @@
     return (rate <= 0.0f) ? 0.0f : expf(-logf((1.0f + targetRatio) / targetRatio) / rate);
 }
 
-
 void    tADSRS_init(tADSRS* const adsrenv, float attack, float decay, float sustain, float release, LEAF* const leaf)
 {
     tADSRS_initToPool(adsrenv, attack, decay, sustain, release, &leaf->mempool);
@@ -509,13 +507,16 @@
     
     LEAF* leaf = adsr->mempool->leaf;
     
-    adsr->sampleRateInMs =  leaf->sampleRate * 0.001f;
+    adsr->sampleRate = leaf->sampleRate;
+    adsr->sampleRateInMs =  adsr->sampleRate * 0.001f;
     adsr->targetRatioA = 0.3f;
     adsr->targetRatioDR = 0.0001f;
+    adsr->attack = attack;
     adsr->attackRate = attack * adsr->sampleRateInMs;
     adsr->attackCoef = calcADSR3Coef(attack * adsr->sampleRateInMs, adsr->targetRatioA);
     adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
 
+    adsr->decay = decay;
     adsr->decayRate = decay * adsr->sampleRateInMs;
     adsr->decayCoef = calcADSR3Coef(decay * adsr->sampleRateInMs,adsr-> targetRatioDR);
     adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
@@ -523,6 +524,7 @@
     adsr->sustainLevel = sustain;
     adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
 
+    adsr->release = release;
     adsr->releaseRate = release * adsr->sampleRateInMs;
     adsr->releaseCoef = calcADSR3Coef(release * adsr->sampleRateInMs, adsr->targetRatioDR);
     adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -546,6 +548,7 @@
 {
     _tADSRS* adsr = *adsrenv;
 
+    adsr->attack = attack;
     adsr->attackRate = attack * adsr->sampleRateInMs;
     adsr->attackCoef = calcADSR3Coef(adsr->attackRate, adsr->targetRatioA);
     adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
@@ -555,6 +558,7 @@
 {
     _tADSRS* adsr = *adsrenv;
 
+    adsr->decay = decay;
     adsr->decayRate = decay * adsr->sampleRateInMs;
     adsr->decayCoef = calcADSR3Coef(adsr->decayRate,adsr-> targetRatioDR);
     adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
@@ -572,6 +576,7 @@
 {
     _tADSRS* adsr = *adsrenv;
 
+    adsr->release = release;
     adsr->releaseRate = release * adsr->sampleRateInMs;
     adsr->releaseCoef = calcADSR3Coef(adsr->releaseRate, (float)adsr->targetRatioDR);
     adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -581,7 +586,6 @@
 void     tADSRS_setLeakFactor(tADSRS* const adsrenv, float leakFactor)
 {
     _tADSRS* adsr = *adsrenv;
-
     adsr->leakFactor = leakFactor;
 }
 
@@ -606,7 +610,6 @@
 {
     _tADSRS* adsr = *adsrenv;
 
-
     switch (adsr->state) {
         case env_idle:
             break;
@@ -641,7 +644,20 @@
     return adsr->output * adsr->gain;
 }
 
+void tADSRS_setSampleRate(tADSRS* const adsrenv, float sr)
+{
+    _tADSRS* adsr = *adsrenv;
+    
+    adsr->sampleRate = sr;
+    adsr->sampleRateInMs =  adsr->sampleRate * 0.001f;
+    
+    tADSRS_setAttack(adsrenv, adsr->attack);
+    tADSRS_setDecay(adsrenv, adsr->decay);
+    tADSRS_setRelease(adsrenv, adsr->release);
+}
 
+//================================================================================
+
 /* ADSR 4 */ // new version of our original table-based ADSR but with the table passed in by the user
 // use this if the size of the big ADSR tables is too much.
 void    tADSRT_init    (tADSRT* const adsrenv, float attack, float decay, float sustain, float release, float* expBuffer, int bufferSize, LEAF* const leaf)
@@ -663,7 +679,8 @@
     adsr->buff_size = bufferSize;
     adsr->buff_sizeMinusOne = bufferSize - 1;
 
-    adsr->bufferSizeDividedBySampleRateInMs = bufferSize / (leaf->sampleRate * 0.001f);
+    adsr->sampleRate = leaf->sampleRate;
+    adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
 
     if (attack < 0.0f)
         attack = 0.0f;
@@ -685,6 +702,9 @@
 
     adsr->sustain = sustain;
 
+    adsr->attack = attack;
+    adsr->decay = decay;
+    adsr->release = release;
     adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
     adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
     adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
@@ -707,7 +727,7 @@
     {
         attack = 0.0f;
     }
-
+    adsr->attack = attack;
     adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
 }
 
@@ -719,6 +739,7 @@
     {
         decay = 0.0f;
     }
+    adsr->decay = decay;
     adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
 }
 
@@ -739,6 +760,7 @@
     {
         release = 0.0f;
     }
+    adsr->release = release;
     adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
 }
 
@@ -988,8 +1010,18 @@
     return adsr->next;
 }
 
+void    tADSRT_setSampleRate (tADSRT* const adsrenv, float sr)
+{
+    _tADSRT* adsr = *adsrenv;
+    
+    adsr->sampleRate = sr;
+    adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
+    adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->attack;
+    adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->decay;
+    adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->release;
+    adsr->rampInc = adsr->bufferSizeDividedBySampleRateInMs / 8.0f;
+}
 
-
 /////-----------------
 /* Ramp */
 void    tRamp_init(tRamp* const r, float time, int samples_per_tick, LEAF* const leaf)
@@ -1005,7 +1037,8 @@
     
     LEAF* leaf = ramp->mempool->leaf;
     
-    ramp->inv_sr_ms = 1.0f/(leaf->sampleRate*0.001f);
+    ramp->sampleRate = leaf->sampleRate;
+    ramp->inv_sr_ms = 1.0f/(ramp->sampleRate*0.001f);
     ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
     ramp->curr = 0.0f;
     ramp->dest = 0.0f;
@@ -1026,7 +1059,6 @@
 void    tRamp_free (tRamp* const r)
 {
     _tRamp* ramp = *r;
-    
     mpool_free((char*)ramp, ramp->mempool);
 }
 
@@ -1082,18 +1114,18 @@
     return r->curr;
 }
 
-void    tRampSampleRateChanged(tRamp* const ramp)
+void    tRamp_setSampleRate(tRamp* const ramp, float sr)
 {
     _tRamp* r = *ramp;
-    LEAF* leaf = r->mempool->leaf;
     
-    r->inv_sr_ms = 1.0f / (leaf->sampleRate * 0.001f);
+    r->sampleRate = sr;
+    r->inv_sr_ms = 1.0f / (r->sampleRate * 0.001f);
     r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;
     r->inc = (r->dest - r->curr) * r->factor;
 }
 
+//===========================================================================================
 
-
 /* RampUpDown */
 void    tRampUpDown_init(tRampUpDown* const r, float upTime, float downTime, int samples_per_tick, LEAF* const leaf)
 {
@@ -1108,7 +1140,8 @@
     
     LEAF* leaf = ramp->mempool->leaf;
 
-    ramp->inv_sr_ms = 1.0f/(leaf->sampleRate*0.001f);
+    ramp->sampleRate = leaf->sampleRate;
+    ramp->inv_sr_ms = 1.0f/(ramp->sampleRate*0.001f);
     ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
     ramp->curr = 0.0f;
     ramp->dest = 0.0f;
@@ -1139,7 +1172,6 @@
 void    tRampUpDown_free  (tRampUpDown* const r)
 {
     _tRampUpDown* ramp = *r;
-
     mpool_free((char*)ramp, ramp->mempool);
 }
 
@@ -1258,7 +1290,6 @@
 void    tExpSmooth_free (tExpSmooth* const expsmooth)
 {
     _tExpSmooth* smooth = *expsmooth;
-    
     mpool_free((char*)smooth, smooth->mempool);
 }
 
@@ -1340,7 +1371,6 @@
 void    tSlide_free  (tSlide* const sl)
 {
     _tSlide* s = *sl;
-
     mpool_free((char*)s, s->mempool);
 }
 
--- a/leaf/Src/leaf-filters.c
+++ b/leaf/Src/leaf-filters.c
@@ -1,11 +1,11 @@
 /*==============================================================================
+ 
+ leaf-filter.c
+ Created: 20 Jan 2017 12:01:10pm
+ Author:  Michael R Mulshine
+ 
+ ==============================================================================*/
 
-    leaf-filter.c
-    Created: 20 Jan 2017 12:01:10pm
-    Author:  Michael R Mulshine
-
-==============================================================================*/
-
 #if _WIN32 || _WIN64
 
 #include "..\Inc\leaf-filters.h"
@@ -85,14 +85,17 @@
     _tMempool* m = *mp;
     _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m);
     f->mempool = m;
+    LEAF* leaf = f->mempool->leaf;
     
     f->gain = 1.0f;
     f->a0 = 1.0;
     
-    tOnePole_setFreq(ft, freq);
-    
     f->lastIn = 0.0f;
     f->lastOut = 0.0f;
+    
+    f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
+    
+    tOnePole_setFreq(ft, freq);
 }
 
 void    tOnePole_free   (tOnePole* const ft)
@@ -131,9 +134,9 @@
 void        tOnePole_setFreq        (tOnePole* const ft, float freq)
 {
     _tOnePole* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
-    f->b0 = freq * leaf->twoPiTimesInvSampleRate;
+    f->freq = freq;
+    f->b0 = f->freq * f->twoPiTimesInvSampleRate;
     f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
     f->a1 = 1.0f - f->b0;
 }
@@ -165,6 +168,15 @@
     return out;
 }
 
+void tOnePole_setSampleRate(tOnePole* const ft, float sr)
+{
+    _tOnePole* f = *ft;
+    f->twoPiTimesInvSampleRate = (1.0f/sr) * TWO_PI;
+    f->b0 = f->freq * f->twoPiTimesInvSampleRate;
+    f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+    f->a1 = 1.0f - f->b0;
+}
+
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
 void    tTwoPole_init(tTwoPole* const ft, LEAF* const leaf)
 {
@@ -176,6 +188,7 @@
     _tMempool* m = *mp;
     _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m);
     f->mempool = m;
+    LEAF* leaf = f->mempool->leaf;
     
     f->gain = 1.0f;
     f->a0 = 1.0;
@@ -183,12 +196,14 @@
     
     f->lastOut[0] = 0.0f;
     f->lastOut[1] = 0.0f;
+    
+    f->sampleRate = leaf->sampleRate;
+    f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
 }
 
 void    tTwoPole_free  (tTwoPole* const ft)
 {
     _tTwoPole* f = *ft;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -223,14 +238,12 @@
     f->a2 = a2;
 }
 
-
 void    tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, int normalize)
 {
     _tTwoPole* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
-    float sampleRate = leaf->sampleRate;
-    float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
+    float sampleRate = f->sampleRate;
+    float twoPiTimesInvSampleRate = f->twoPiTimesInvSampleRate;
     
     if (frequency < 0.0f)   frequency = 0.0f;
     if (frequency > (sampleRate * 0.49f))   frequency = sampleRate * 0.49f;
@@ -267,21 +280,20 @@
     f->gain = gain;
 }
 
-void     tTwoPoleSampleRateChanged (tTwoPole* const ft)
+void     tTwoPole_setSampleRate (tTwoPole* const ft, float sr)
 {
     _tTwoPole* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
-    float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
+    f->twoPiTimesInvSampleRate = (1.0f/sr) * TWO_PI;
     
     f->a2 = f->radius * f->radius;
-    f->a1 =  -2.0f * f->radius * cosf(f->frequency * twoPiTimesInvSampleRate);
+    f->a1 =  -2.0f * f->radius * cosf(f->frequency * f->twoPiTimesInvSampleRate);
     
     if ( f->normalize )
     {
         // Normalize the filter gain ... not terribly efficient.
-        float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * twoPiTimesInvSampleRate);
-        float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * twoPiTimesInvSampleRate);
+        float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * f->twoPiTimesInvSampleRate);
+        float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * f->twoPiTimesInvSampleRate);
         f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
     }
 }
@@ -297,10 +309,12 @@
     _tMempool* m = *mp;
     _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m);
     f->mempool = m;
+    LEAF* leaf  = f->mempool->leaf;
     
     f->gain = 1.0f;
     f->lastIn = 0.0f;
     f->lastOut = 0.0f;
+    f->invSampleRate = leaf->invSampleRate;
     tOneZero_setZero(ft, theZero);
 }
 
@@ -307,7 +321,6 @@
 void    tOneZero_free   (tOneZero* const ft)
 {
     _tOneZero* f = *ft;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -363,13 +376,12 @@
 float   tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )
 {
     _tOneZero* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
     if ( frequency <= 0.0f) frequency = 0.05f;
     
     f->frequency = frequency;
     
-    float omegaT = 2 * PI * frequency * leaf->invSampleRate;
+    float omegaT = 2 * PI * frequency * f->invSampleRate;
     float real = 0.0, imag = 0.0;
     
     real += f->b0;
@@ -391,6 +403,12 @@
     return phase / omegaT;
 }
 
+void    tOneZero_setSampleRate  (tOneZero* const ft, float sr)
+{
+    _tOneZero* f = *ft;
+    f->invSampleRate = 1.0f/sr;
+}
+
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
 void    tTwoZero_init(tTwoZero* const ft, LEAF* const leaf)
 {
@@ -402,7 +420,9 @@
     _tMempool* m = *mp;
     _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m);
     f->mempool = m;
+    LEAF* leaf = f->mempool->leaf;
     
+    f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
     f->gain = 1.0f;
     f->lastIn[0] = 0.0f;
     f->lastIn[1] = 0.0f;
@@ -411,7 +431,6 @@
 void    tTwoZero_free   (tTwoZero* const ft)
 {
     _tTwoZero* f = *ft;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -431,7 +450,6 @@
 void    tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)
 {
     _tTwoZero* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
     // Should also deal with frequency being > half sample rate / nyquist. See STK
     if (freq < 0.0f)    freq = 0.0f;
@@ -441,7 +459,7 @@
     f->radius = radius;
     
     f->b2 = radius * radius;
-    f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
+    f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
     
     // Normalize the filter gain. From STK.
     if ( f->b1 > 0.0f ) // Maximum at z = 0.
@@ -479,10 +497,11 @@
     f->gain = gain;
 }
 
-void tTwoZeroSampleRateChanged(tTwoZero* const ft)
+void tTwoZero_setSampleRate(tTwoZero* const ft, float sr)
 {
     _tTwoZero* f = *ft;
     
+    f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
     tTwoZero_setNotch(ft, f->frequency, f->radius);
 }
 
@@ -509,7 +528,6 @@
 void    tPoleZero_free      (tPoleZero* const pzf)
 {
     _tPoleZero* f = *pzf;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -611,6 +629,7 @@
     _tMempool* m = *mp;
     _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m);
     f->mempool = m;
+    LEAF* leaf = f->mempool->leaf;
     
     f->gain = 1.0f;
     
@@ -621,12 +640,13 @@
     f->lastIn[1] = 0.0f;
     f->lastOut[0] = 0.0f;
     f->lastOut[1] = 0.0f;
+    
+    f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
 }
 
 void    tBiQuad_free   (tBiQuad* const ft)
 {
     _tBiQuad* f = *ft;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -650,11 +670,10 @@
 void    tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int normalize)
 {
     _tBiQuad* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
     if (freq < 0.0f)    freq = 0.0f;
-    if (freq > (leaf->sampleRate * 0.49f))
-        freq = leaf->sampleRate * 0.49f;
+    if (freq > (f->sampleRate * 0.49f))
+        freq = f->sampleRate * 0.49f;
     if (radius < 0.0f)  radius = 0.0f;
     if (radius >= 1.0f)  radius = 1.0f;
     
@@ -663,7 +682,7 @@
     f->normalize = normalize;
     
     f->a2 = radius * radius;
-    f->a1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate);
+    f->a1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate);
     
     if (normalize)
     {
@@ -676,15 +695,14 @@
 void    tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)
 {
     _tBiQuad* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
     if (freq < 0.0f)    freq = 0.0f;
-    if (freq > (leaf->sampleRate * 0.49f))
-        freq = leaf->sampleRate * 0.49f;
+    if (freq > (f->sampleRate * 0.49f))
+        freq = f->sampleRate * 0.49f;
     if (radius < 0.0f)  radius = 0.0f;
     
     f->b2 = radius * radius;
-    f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
+    f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
     
     // Does not attempt to normalize filter gain.
 }
@@ -743,13 +761,15 @@
     f->gain = gain;
 }
 
-void    tBiQuadSampleRateChanged(tBiQuad* const ft)
+void    tBiQuad_setSampleRate(tBiQuad* const ft, float sr)
 {
     _tBiQuad* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
+    f->sampleRate = sr;
+    f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/f->sampleRate);
+    
     f->a2 = f->radius * f->radius;
-    f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf->twoPiTimesInvSampleRate);
+    f->a1 = -2.0f * f->radius * cosf(f->frequency * f->twoPiTimesInvSampleRate);
     
     if (f->normalize)
     {
@@ -764,12 +784,10 @@
 void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q, LEAF* const leaf)
 {
     tSVF_initToPool     (svff, type, freq, Q, &leaf->mempool);
-
     // or maybe this?
     /*
      * hp=1 bp=A/Q (where A is 10^(G/40) and G is gain in decibels) and lp = 1
      */
-
 }
 
 void    tSVF_initToPool     (tSVF* const svff, SVFType type, float freq, float Q, tMempool* const mp)
@@ -779,14 +797,17 @@
     svf->mempool = m;
     
     LEAF* leaf = svf->mempool->leaf;
-
+    
+    svf->sampleRate = leaf->sampleRate;
+    svf->invSampleRate = leaf->invSampleRate;
+    
     svf->type = type;
-
+    
     svf->ic1eq = 0;
     svf->ic2eq = 0;
     svf->Q = Q;
     svf->cutoff = freq;
-    svf->g = tanf(PI * freq * leaf->invSampleRate);
+    svf->g = tanf(PI * freq * svf->invSampleRate);
     svf->k = 1.0f/Q;
     svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
     svf->a2 = svf->g*svf->a1;
@@ -796,7 +817,7 @@
     svf->cB = 0.0f;
     svf->cBK = 0.0f;
     svf->cL = 1.0f;
-
+    
     if (type == SVFTypeLowpass)
     {
         svf->cH = 0.0f;
@@ -811,7 +832,7 @@
         svf->cBK = 0.0f;
         svf->cL = 0.0f;
     }
-
+    
     else if (type == SVFTypeHighpass)
     {
         svf->cH = 1.0f;
@@ -819,7 +840,7 @@
         svf->cBK = -1.0f;
         svf->cL = -1.0f;
     }
-
+    
     else if (type == SVFTypeNotch)
     {
         svf->cH = 1.0f;
@@ -827,7 +848,7 @@
         svf->cBK = -1.0f;
         svf->cL = 0.0f;
     }
-
+    
     else if (type == SVFTypePeak)
     {
         svf->cH = 1.0f;
@@ -840,7 +861,6 @@
 void    tSVF_free   (tSVF* const svff)
 {
     _tSVF* svf = *svff;
-    
     mpool_free((char*)svf, svf->mempool);
 }
 
@@ -866,10 +886,9 @@
 void     tSVF_setFreq(tSVF* const svff, float freq)
 {
     _tSVF* svf = *svff;
-    LEAF* leaf = svf->mempool->leaf;
     
-    svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);
-    svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);
+    svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
+    svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
     svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
     svf->a2 = svf->g * svf->a1;
     svf->a3 = svf->g * svf->a2;
@@ -880,7 +899,7 @@
     _tSVF* svf = *svff;
     svf->Q = Q;
     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;
@@ -889,16 +908,23 @@
 void    tSVF_setFreqAndQ(tSVF* const svff, float freq, float Q)
 {
     _tSVF* svf = *svff;
-    LEAF* leaf = svf->mempool->leaf;
     
-    svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);
+    svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
     svf->k = 1.0f/Q;
-    svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);
+    svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
     svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
     svf->a2 = svf->g * svf->a1;
     svf->a3 = svf->g * svf->a2;
 }
 
+void    tSVF_setSampleRate  (tSVF* const svff, float sr)
+{
+    _tSVF* svf = *svff;
+    svf->sampleRate = sr;
+    svf->invSampleRate = 1.0f/svf->sampleRate;
+    tSVF_setFreq(svff, svf->cutoff);
+}
+
 #if LEAF_INCLUDE_FILTERTAN_TABLE
 // Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.
 void   tEfficientSVF_init(tEfficientSVF* const svff, SVFType type, uint16_t input, float Q, LEAF* const leaf)
@@ -927,7 +953,6 @@
 void    tEfficientSVF_free (tEfficientSVF* const svff)
 {
     _tEfficientSVF* svf = *svff;
-    
     mpool_free((char*)svf, svf->mempool);
 }
 
@@ -983,10 +1008,10 @@
     _tMempool* m = *mp;
     _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m);
     f->mempool = m;
-    
     LEAF* leaf = f->mempool->leaf;
     
-    f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));
+    f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
+    f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
     f->ys = 0.0f;
     f->xs = 0.0f;
     
@@ -996,7 +1021,6 @@
 void tHighpass_free  (tHighpass* const ft)
 {
     _tHighpass* f = *ft;
-    
     mpool_free((char*)f, f->mempool);
 }
 
@@ -1003,11 +1027,9 @@
 void tHighpass_setFreq(tHighpass* const ft, float freq)
 {
     _tHighpass* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
     
     f->frequency = freq;
-    f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));
-    
+    f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
 }
 
 float tHighpass_getFreq(tHighpass* const ft)
@@ -1025,12 +1047,11 @@
     return f->ys;
 }
 
-void tHighpassSampleRateChanged(tHighpass* const ft)
+void tHighpass_setSampleRate(tHighpass* const ft, float sr)
 {
     _tHighpass* f = *ft;
-    LEAF* leaf = f->mempool->leaf;
-    
-    f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf->invSampleRate));
+    f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
+    f->R = (1.0f - (f->frequency * f->twoPiTimesInvSampleRate));
 }
 
 void tButterworth_init(tButterworth* const ft, int order, float f1, float f2, LEAF* const leaf)
@@ -1068,8 +1089,7 @@
 {
     _tButterworth* f = *ft;
     
-    for(int i = 0; i < f->numSVF; ++i)
-        tSVF_free(&f->svf[i]);
+    for (int i = 0; i < f->numSVF; ++i) tSVF_free(&f->svf[i]);
     
     mpool_free((char*)f->svf, f->mempool);
     mpool_free((char*)f, f->mempool);
@@ -1080,7 +1100,7 @@
     _tButterworth* f = *ft;
     
     for(int i = 0; i < f->numSVF; ++i)
-        samp = tSVF_tick(&f->svf[i], samp);
+    samp = tSVF_tick(&f->svf[i], samp);
     
     return samp;
 }
@@ -1109,18 +1129,18 @@
 
 void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
 {
-//    _tButterworth* f = *ft;
     tButterworth_setF1(ft, f1);
-    tButterworth_setF1(ft, f2);
-//    f->f1 = f1;
-//    f->f2 = f2;
-//    for(int i = 0; i < ((f->N)/2); ++i)
-//    {
-//        tSVF_setFreq(&f->low[i], f1);
-//        tSVF_setFreq(&f->high[i], f2);
-//    }
+    tButterworth_setF2(ft, f2);
 }
 
+void    tButterworth_setSampleRate  (tButterworth* const ft, float sr)
+{
+    _tButterworth* f = *ft;
+    for (int i = 0; i < f->numSVF; ++i) tSVF_setSampleRate(&f->svf[i], sr);
+}
+
+//================================================================================
+
 void    tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf)
 {
     tFIR_initToPool(firf, coeffs, numTaps, &leaf->mempool);
@@ -1173,7 +1193,7 @@
     _tMempool* m = *mp;
     _tMedianFilter* f = *mf = (_tMedianFilter*) mpool_alloc(sizeof(_tMedianFilter), m);
     f->mempool = m;
-
+    
     f->size = size;
     f->middlePosition = size / 2;
     f->last = size - 1;
@@ -1185,12 +1205,12 @@
         f->val[i] = 0.0f;
         f->age[i] = i;
     }
-
+    
 }
 void    tMedianFilter_free   (tMedianFilter* const mf)
 {
     _tMedianFilter* f = *mf;
-
+    
     mpool_free((char*)f->val, f->mempool);
     mpool_free((char*)f->age, f->mempool);
     mpool_free((char*)f, f->mempool);
@@ -1199,7 +1219,7 @@
 float   tMedianFilter_tick           (tMedianFilter* const mf, float input)
 {
     _tMedianFilter* f = *mf;
-
+    
     for(int i=0; i<f->size; i++) {
         int thisAge = f->age[i];
         if(thisAge == f->last) {
@@ -1210,7 +1230,7 @@
             f->age[i] = thisAge;
         }
     }
-
+    
     while( f->pos!=0 ) {
         float test = f->val[f->pos-1];
         if(input < test) {
@@ -1219,7 +1239,7 @@
             f->pos -= 1;
         } else {break;}
     }
-
+    
     while(f->pos != f->last) {
         float test = f->val[f->pos+1];
         if( input > test) {
@@ -1228,10 +1248,10 @@
             f->pos += 1;
         } else {break;}
     }
-
+    
     f->val[f->pos] = input;
     f->age[f->pos] = 0;
-
+    
     return  f->val[f->middlePosition];
 }
 
@@ -1250,16 +1270,17 @@
     
     LEAF* leaf = f->mempool->leaf;
     
-    f->fc   = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
+    f->sampleRate = leaf->sampleRate;
+    f->invSampleRate = leaf->invSampleRate;
+    f->fc   = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
     f->type = type;
     f->G    = ONE_OVER_SQRT2;
-    f->invG    = 1.0f/ONE_OVER_SQRT2;
+    f->invG = 1.0f/ONE_OVER_SQRT2;
     f->B    = bandWidth;
     f->m    = 0.0f;
     f->s1 = 0.0f;
     f->s2 = 0.0f;
-    f->sr = leaf->sampleRate;
-    f->inv_sr = leaf->invSampleRate;
+    
     tVZFilter_calcCoeffs(vf);
 }
 
@@ -1269,194 +1290,179 @@
     mpool_free((char*)f, f->mempool);
 }
 
-void    tVZFilter_setSampleRate  (tVZFilter* const vf, float sampleRate)
-{
-    _tVZFilter* f = *vf;
-    f->sr = sampleRate;
-    f->inv_sr = 1.0f/sampleRate;
-}
-
 float   tVZFilter_tick              (tVZFilter* const vf, float in)
 {
     _tVZFilter* f = *vf;
-
+    
     float yL, yB, yH;
-
+    
     // compute highpass output via Eq. 5.1:
     yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
-
+    
     // compute bandpass output by applying 1st integrator to highpass output:
     yB = tanhf(f->g*yH) + f->s1;
     f->s1 = f->g*yH + yB; // state update in 1st integrator
-
+    
     // compute lowpass output by applying 2nd integrator to bandpass output:
     yL = tanhf(f->g*yB) + f->s2;
     f->s2 = f->g*yB + yL; // state update in 2nd integrator
-
+    
     //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
     //
     //seems like that might look like this:
     // y = tanh(g*x) + s; // output computation
     // s = g*x + y; // state update
-
+    
     //instead of this:
     // y = g*x + s; // output computation
     // s = g*x + y; // state update
-
+    
     return f->cL*yL + f->cB*yB + f->cH*yH;
-
 }
 
 float   tVZFilter_tickEfficient             (tVZFilter* const vf, float in)
 {
     _tVZFilter* f = *vf;
-
+    
     float yL, yB, yH;
-
+    
     // compute highpass output via Eq. 5.1:
     yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
-
+    
     // compute bandpass output by applying 1st integrator to highpass output:
     yB = (f->g*yH) + f->s1;
     f->s1 = f->g*yH + yB; // state update in 1st integrator
-
+    
     // compute lowpass output by applying 2nd integrator to bandpass output:
     yL = (f->g*yB) + f->s2;
     f->s2 = f->g*yB + yL; // state update in 2nd integrator
-
+    
     //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
     //
     //seems like that might look like this:
     // y = tanh(g*x) + s; // output computation
     // s = g*x + y; // state update
-
+    
     //instead of this:
     // y = g*x + s; // output computation
     // s = g*x + y; // state update
-
+    
     return f->cL*yL + f->cB*yB + f->cH*yH;
-
 }
 
-
 void   tVZFilter_calcCoeffs           (tVZFilter* const vf)
 {
-
     _tVZFilter* f = *vf;
-    f->g = tanf(PI * f->fc * f->inv_sr);  // embedded integrator gain (Fig 3.11)
-
-      switch( f->type )
-      {
-      case Bypass:
+    f->g = tanf(PI * f->fc * f->invSampleRate);  // embedded integrator gain (Fig 3.11)
+    
+    switch( f->type )
+    {
+        case Bypass:
         {
-          f->R2 = f->invG;  // can we use an arbitrary value here, for example R2 = 1?
-          f->cL = 1.0f;
-          f->cB = f->R2;
-          f->cH = 1.0f;
+            f->R2 = f->invG;  // can we use an arbitrary value here, for example R2 = 1?
+            f->cL = 1.0f;
+            f->cB = f->R2;
+            f->cH = 1.0f;
         }
-        break;
-      case Lowpass:
+            break;
+        case Lowpass:
         {
             f->R2 = f->invG;
             f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;
         }
-        break;
-      case Highpass:
+            break;
+        case Highpass:
         {
             f->R2 = f->invG;
             f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;
         }
-        break;
-      case BandpassSkirt:
+            break;
+        case BandpassSkirt:
         {
             f->R2 = f->invG;
             f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;
         }
-        break;
-      case BandpassPeak:
+            break;
+        case BandpassPeak:
         {
             f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
             f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;
         }
-        break;
-      case BandReject:
+            break;
+        case BandReject:
         {
             f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
             f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;
         }
-        break;
-      case Bell:
+            break;
+        case Bell:
         {
             float fl = f->fc*powf(2.0f, (-f->B)*0.5f); // lower bandedge frequency (in Hz)
-            float wl = tanf(PI*fl*f->inv_sr);   // warped radian lower bandedge frequency /(2*fs)
+            float wl = tanf(PI*fl*f->invSampleRate);   // warped radian lower bandedge frequency /(2*fs)
             float r  = f->g/wl;
             r *= r;    // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the
-                                       // warped upper bandedge, wc the center
+            // warped upper bandedge, wc the center
             f->R2 = 2.0f*sqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));
             f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;
         }
-        break;
-      case Lowshelf:
+            break;
+        case Lowshelf:
         {
             float A = sqrtf(f->G);
-          f->g /= sqrtf(A);               // scale SVF-cutoff frequency for shelvers
-          f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);
-          f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;
+            f->g /= sqrtf(A);               // scale SVF-cutoff frequency for shelvers
+            f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);
+            f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;
         }
-        break;
-      case Highshelf:
+            break;
+        case Highshelf:
         {
-          float A = sqrtf(f->G);
-          f->g *= sqrtf(A);               // scale SVF-cutoff frequency for shelvers
-          f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);
-          f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;
+            float A = sqrtf(f->G);
+            f->g *= sqrtf(A);               // scale SVF-cutoff frequency for shelvers
+            f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);
+            f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;
         }
-        break;
-      case Allpass:
+            break;
+        case Allpass:
         {
             f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
             f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;
         }
-        break;
-
-        // experimental - maybe we must find better curves for cL, cB, cH:
-      case Morph:
+            break;
+            
+            // experimental - maybe we must find better curves for cL, cB, cH:
+        case Morph:
         {
             f->R2 = f->invG;
-          float x  = 2.0f*f->m-1.0f;
-
-          f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
-          f->cH = minimum( x, 0.0f); /*cH *= cH;*/
-          f->cB = 1.0f-x*x;
-
+            float x  = 2.0f*f->m-1.0f;
+            
+            f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
+            f->cH = minimum( x, 0.0f); /*cH *= cH;*/
+            f->cB = 1.0f-x*x;
+            
             // bottom line: we need to test different versions for how they feel when tweaking the
             // morph parameter
-
-          // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
-          // the magnitude response value at the cutoff frequency and scale back by the gain):
-          float s = f->G * sqrtf((f->R2*f->R2) / (f->cL*f->cL + f->cB*f->cB + f->cH*f->cH - 2.0f*f->cL*f->cH));
-          f->cL *= s; f->cB *= s; f->cH *= s;
+            
+            // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
+            // the magnitude response value at the cutoff frequency and scale back by the gain):
+            float s = f->G * sqrtf((f->R2*f->R2) / (f->cL*f->cL + f->cB*f->cB + f->cH*f->cH - 2.0f*f->cL*f->cH));
+            f->cL *= s; f->cB *= s; f->cH *= s;
         }
-        break;
-
-      }
-
-      f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g);  // factor for feedback precomputation
+            break;
+            
+    }
+    
+    f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g);  // factor for feedback precomputation
 }
 
 void   tVZFilter_calcCoeffsEfficientBP           (tVZFilter* const vf)
 {
-
     _tVZFilter* f = *vf;
-    f->g = fastertanf(PI * f->fc * f->inv_sr);  // embedded integrator gain (Fig 3.11)
+    f->g = fastertanf(PI * f->fc * f->invSampleRate);  // embedded integrator gain (Fig 3.11)
     f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
     f->cB = f->R2;
     f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g);  // factor for feedback precomputation
 }
 
-
-
-
 void   tVZFilter_setBandwidth               (tVZFilter* const vf, float B)
 {
     _tVZFilter* f = *vf;
@@ -1466,18 +1472,16 @@
 void   tVZFilter_setFreq           (tVZFilter* const vf, float freq)
 {
     _tVZFilter* f = *vf;
-    LEAF* leaf = f->mempool->leaf;
     
-    f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
+    f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
     tVZFilter_calcCoeffs(vf);
 }
 void   tVZFilter_setFreqAndBandwidth           (tVZFilter* const vf, float freq, float bw)
 {
     _tVZFilter* f = *vf;
-    LEAF* leaf = f->mempool->leaf;
     
     f->B = LEAF_clip(0.0f,bw, 100.0f);
-    f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
+    f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
     tVZFilter_calcCoeffs(vf);
 }
 
@@ -1484,15 +1488,12 @@
 void   tVZFilter_setFreqAndBandwidthEfficientBP           (tVZFilter* const vf, float freq, float bw)
 {
     _tVZFilter* f = *vf;
-    LEAF* leaf = f->mempool->leaf;
-
+    
     f->B = LEAF_clip(0.0f,bw, 100.0f);
-    f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
+    f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
     tVZFilter_calcCoeffsEfficientBP(vf);
 }
 
-
-
 void   tVZFilter_setGain                (tVZFilter* const vf, float gain)
 {
     _tVZFilter* f = *vf;
@@ -1501,8 +1502,6 @@
     tVZFilter_calcCoeffs(vf);
 }
 
-
-
 void   tVZFilter_setMorph               (tVZFilter* const vf, float morph)
 {
     _tVZFilter* f = *vf;
@@ -1520,25 +1519,32 @@
 float tVZFilter_BandwidthToR(tVZFilter* const vf, float B)
 {
     _tVZFilter* f = *vf;
-  float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)
-  float gl = tanf(PI*fl*f->inv_sr);   // warped radian lower bandedge frequency /(2*fs)
-  float r  = gl/f->g;            // ratio between warped lower bandedge- and center-frequencies
-                               // unwarped: r = pow(2, -B/2) -> approximation for low
-                               // center-frequencies
-  return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
+    float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)
+    float gl = tanf(PI*fl*f->invSampleRate);   // warped radian lower bandedge frequency /(2*fs)
+    float r  = gl/f->g;            // ratio between warped lower bandedge- and center-frequencies
+    // unwarped: r = pow(2, -B/2) -> approximation for low
+    // center-frequencies
+    return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
 }
 
 float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B)
 {
     _tVZFilter* f = *vf;
-  float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)
-  float gl = fastertanf(PI*fl*f->inv_sr);   // warped radian lower bandedge frequency /(2*fs)
-  float r  = gl/f->g;            // ratio between warped lower bandedge- and center-frequencies
-                               // unwarped: r = pow(2, -B/2) -> approximation for low
-                               // center-frequencies
-  return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
+    float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)
+    float gl = fastertanf(PI*fl*f->invSampleRate);   // warped radian lower bandedge frequency /(2*fs)
+    float r  = gl/f->g;            // ratio between warped lower bandedge- and center-frequencies
+    // unwarped: r = pow(2, -B/2) -> approximation for low
+    // center-frequencies
+    return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
 }
 
+void    tVZFilter_setSampleRate  (tVZFilter* const vf, float sr)
+{
+    _tVZFilter* f = *vf;
+    f->sampleRate = sr;
+    f->invSampleRate = 1.0f/f->sampleRate;
+    tVZFilter_calcCoeffs(vf);
+}
 
 
 
@@ -1549,26 +1555,28 @@
 
 void    tDiodeFilter_initToPool     (tDiodeFilter* const vf, float cutoff, float resonance, tMempool* const mp)
 {
-     _tMempool* m = *mp;
-     _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
-     f->mempool = m;
+    _tMempool* m = *mp;
+    _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
+    f->mempool = m;
     
     LEAF* leaf = f->mempool->leaf;
     
-     // initialization (the resonance factor is between 0 and 8 according to the article)
-     f->f = (float)tan((double)(PI * cutoff/leaf->sampleRate));
-     f->r = (7.f * resonance + 0.5f);
-     f->Vt = 0.5f;
-     f->n = 1.836f;
-     f->zi = 0.0f; //previous input value
-     f->gamma = f->Vt*f->n;
-     f->s0 = 0.01f;
-     f->s1 = 0.02f;
-     f->s2 = 0.03f;
-     f->s3 = 0.04f;
-     f->g0inv = 1.f/(2.f*f->Vt);
-     f->g1inv = 1.f/(2.f*f->gamma);
-     f->g2inv = 1.f/(6.f*f->gamma);
+    f->invSampleRate = leaf->invSampleRate;
+    f->cutoff = cutoff;
+    // initialization (the resonance factor is between 0 and 8 according to the article)
+    f->f = (float)tan((double)(PI * cutoff * f->invSampleRate));
+    f->r = (7.f * resonance + 0.5f);
+    f->Vt = 0.5f;
+    f->n = 1.836f;
+    f->zi = 0.0f; //previous input value
+    f->gamma = f->Vt*f->n;
+    f->s0 = 0.01f;
+    f->s1 = 0.02f;
+    f->s2 = 0.03f;
+    f->s3 = 0.04f;
+    f->g0inv = 1.f/(2.f*f->Vt);
+    f->g1inv = 1.f/(2.f*f->gamma);
+    f->g2inv = 1.f/(6.f*f->gamma);
 }
 
 void    tDiodeFilter_free   (tDiodeFilter* const vf)
@@ -1583,11 +1591,11 @@
     // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)
     float testVal = ((15.0f*a + 420.0f)*a + 945.0f);
     float output = 1.0f;
-
+    
     if (testVal!= 0.0f)
     {
-    	output = testVal;
-
+        output = testVal;
+        
     }
     return ((a + 105.0f)*a + 945.0f) / output;
 }
@@ -1595,12 +1603,12 @@
 float   tDiodeFilter_tick               (tDiodeFilter* const vf, float in)
 {
     _tDiodeFilter* f = *vf;
-
+    
     int errorCheck = 0;
     // the input x[n+1] is given by 'in', and x[n] by zi
     // input with half delay
     float ih = 0.5f * (in + f->zi);
-
+    
     // evaluate the non-linear factors
     float t0 = f->f*tanhXdX((ih - f->r * f->s3)*f->g0inv)*f->g0inv;
     float t1 = f->f*tanhXdX((f->s1-f->s0)*f->g1inv)*f->g1inv;
@@ -1607,19 +1615,17 @@
     float t2 = f->f*tanhXdX((f->s2-f->s1)*f->g1inv)*f->g1inv;
     float t3 = f->f*tanhXdX((f->s3-f->s2)*f->g1inv)*f->g1inv;
     float t4 = f->f*tanhXdX((f->s3)*f->g2inv)*f->g2inv;
-
-
-
+    
     // This formula gives the result for y3 thanks to MATLAB
     float y3 = (f->s2 + f->s3 + t2*(f->s1 + f->s2 + f->s3 + t1*(f->s0 + f->s1 + f->s2 + f->s3 + t0*in)) + t1*(2.0f*f->s2 + 2.0f*f->s3))*t3 + f->s3 + 2.0f*f->s3*t1 + t2*(2.0f*f->s3 + 3.0f*f->s3*t1);
     if (isnan(y3))
     {
-    	errorCheck = 1;
+        errorCheck = 1;
     }
     float tempy3denom = (t4 + t1*(2.0f*t4 + 4.0f) + t2*(t4 + t1*(t4 + f->r*t0 + 4.0f) + 3.0f) + 2.0f)*t3 + t4 + t1*(2.0f*t4 + 2.0f) + t2*(2.0f*t4 + t1*(3.0f*t4 + 3.0f) + 2.0f) + 1.0f;
     if (isnan(tempy3denom))
     {
-    	errorCheck = 2;
+        errorCheck = 2;
     }
     if (tempy3denom == 0.0f)
     {
@@ -1628,7 +1634,7 @@
     y3 = y3 / tempy3denom;
     if (isnan(y3))
     {
-    	errorCheck = 3;
+        errorCheck = 3;
     }
     if (t1 == 0.0f)
     {
@@ -1647,42 +1653,45 @@
     float y1 = (f->s2 - (1+t3+t2)*y2 + t3*y3) / (-t2);
     float y0 = (f->s1 - (1+t2+t1)*y1 + t2*y2) / (-t1);
     float xx = (in - f->r*y3);
-
+    
     // update state
     f->s0 += 2.0f * (t0*xx + t1*(y1-y0));
     if (isnan(f->s0))
     {
-    	errorCheck = 4;
+        errorCheck = 4;
     }
-
+    
     if (isinf(f->s0))
     {
-    	errorCheck = 5;
+        errorCheck = 5;
     }
     f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));
     f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));
     f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));
-
+    
     f->zi = in;
     return y3*f->r;
-
 }
 
-
-
 void    tDiodeFilter_setFreq     (tDiodeFilter* const vf, float cutoff)
 {
-     _tDiodeFilter* f = *vf;
-    LEAF* leaf = f->mempool->leaf;
+    _tDiodeFilter* f = *vf;
     
-     f->f = tanf(PI * LEAF_clip(10.0f, cutoff, 20000.0f) * leaf->invSampleRate);
+    f->cutoff = LEAF_clip(10.0f, cutoff, 20000.0f);
+    f->f = tanf(PI * f->cutoff * f->invSampleRate);
 }
 
-
 void    tDiodeFilter_setQ     (tDiodeFilter* const vf, float resonance)
 {
-     _tDiodeFilter* f = *vf;
-     f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
+    _tDiodeFilter* f = *vf;
+    f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
+}
 
+void    tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr)
+{
+    _tDiodeFilter* f = *vf;
+    
+    f->invSampleRate = 1.0f/sr;
+    f->f = tanf(PI * f->cutoff * f->invSampleRate);
 }
 
--- a/leaf/Src/leaf-instruments.c
+++ b/leaf/Src/leaf-instruments.c
@@ -141,6 +141,17 @@
     cowbell->useStick = useStick;
 }
 
+void t808Cowbell_setSampleRate(t808Cowbell* const cowbellInst, float sr)
+{
+    _t808Cowbell* cowbell = *cowbellInst;
+    
+    tSquare_setSampleRate(&cowbell->p[0], sr);
+    tSquare_setSampleRate(&cowbell->p[1], sr);
+    tSVF_setSampleRate(&cowbell->bandpassOsc, sr);
+    tSVF_setSampleRate(&cowbell->bandpassStick, sr);
+    tHighpass_setSampleRate(&cowbell->highpass, sr);
+}
+
 // ----------------- HIHAT ----------------------------//
 
 void t808Hihat_init(t808Hihat* const hihatInst, LEAF* const leaf)
@@ -309,6 +320,22 @@
     hihat->freq = freq;
 }
 
+void t808Hihat_setSampleRate(t808Hihat* const hihatInst, float sr)
+{
+    _t808Hihat* hihat = *hihatInst;
+    
+    for (int i = 0; i < 6; i++)
+    {
+        tSquare_setSampleRate(&hihat->p[i], sr);
+    }
+    
+    // need to fix SVF to be generic
+    tSVF_setSampleRate(&hihat->bandpassStick, sr);
+    tSVF_setSampleRate(&hihat->bandpassOsc, sr);
+    
+    tHighpass_setSampleRate(&hihat->highpass, sr);
+}
+
 // ----------------- SNARE ----------------------------//
 
 void t808Snare_init (t808Snare* const snareInst, LEAF* const leaf)
@@ -456,6 +483,18 @@
     return sample;
 }
 
+void t808Snare_setSampleRate(t808Snare* const snareInst, float sr)
+{
+    _t808Snare* snare = *snareInst;
+    
+    for (int i = 0; i < 2; i++)
+    {
+        tTriangle_setSampleRate(&snare->tone[i], sr);
+        tSVF_setSampleRate(&snare->toneLowpass[i], sr);
+    }
+    tSVF_setSampleRate(&snare->noiseLowpass, sr);
+}
+
 // ----------------- KICK ----------------------------//
 
 void t808Kick_init (t808Kick* const kickInst, LEAF* const leaf)
@@ -539,5 +578,13 @@
 void        t808Kick_setToneNoiseMix       (t808Kick* const kickInst, float toneNoiseMix);
 void        t808Kick_setNoiseFilterFreq    (t808Kick* const kickInst, float noiseFilterFreq);
 void        t808Kick_setNoiseFilterQ       (t808Kick* const kickInst, float noiseFilterQ);
+
+void        t808Kick_setSampleRate  (t808Kick* const kickInst, float sr)
+{
+    _t808Kick* kick = *kickInst;
+    
+    tCycle_setSampleRate(&kick->tone, sr);
+    tSVF_setSampleRate(&kick->toneLowpass, sr);
+}
 
 
--- a/leaf/Src/leaf-midi.c
+++ b/leaf/Src/leaf-midi.c
@@ -605,7 +605,15 @@
     return (poly->voices[voice][0] > 0) ? 1 : 0;
 }
 
-
+void tPoly_setSampleRate(tPoly* const polyh, float sr)
+{
+    _tPoly* poly = *polyh;
+    for (int i = 0; i < poly->maxNumVoices; i++)
+    {
+        tRamp_setSampleRate(&poly->ramps[i], sr);
+    }
+    tRamp_setSampleRate(&poly->pitchBendRamp, sr);
+}
 
 
 //tSimplePoly = much more efficient implementation without ramps and glide
--- a/leaf/Src/leaf-oscillators.c
+++ b/leaf/Src/leaf-oscillators.c
@@ -28,9 +28,11 @@
     _tMempool* m = *mp;
     _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->inc      =  0.0f;
     c->phase    =  0.0f;
+    c->invSampleRate = leaf->invSampleRate;
 }
 
 void    tCycle_free (tCycle* const cy)
@@ -43,13 +45,12 @@
 void     tCycle_setFreq(tCycle* const cy, float freq)
 {
     _tCycle* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
     if (!isfinite(freq)) return;
     
     c->freq  = freq;
 
-    c->inc = freq * leaf->invSampleRate;
+    c->inc = freq * c->invSampleRate;
     c->inc -= (int)c->inc;
 }
 
@@ -80,13 +81,12 @@
     return (samp0 + (samp1 - samp0) * frac);
 }
 
-void     tCycleSampleRateChanged (tCycle* const cy)
+void     tCycle_setSampleRate (tCycle* const cy, float sr)
 {
     _tCycle* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
-    c->inc = c->freq * leaf->invSampleRate;
-    c->inc -= (int)c->inc;
+    c->invSampleRate = 1.0f/sr;
+    tCycle_setFreq(cy, c->freq);
 }
 #endif // LEAF_INCLUDE_SINE_TABLE
 
@@ -103,9 +103,11 @@
     _tMempool* m = *mp;
     _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->inc      =  0.0f;
     c->phase    =  0.0f;
+    c->invSampleRate = leaf->invSampleRate;
     tTriangle_setFreq(cy, 220);
 }
 
@@ -119,15 +121,14 @@
 void tTriangle_setFreq(tTriangle* const cy, float freq)
 {
     _tTriangle* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
-    c->freq  = freq;
+    c->freq = freq;
     
-    c->inc = c->freq * leaf->invSampleRate;
+    c->inc = c->freq * c->invSampleRate;
     c->inc -= (int)c->inc;
     
     // abs for negative frequencies
-    c->w = fabsf(c->freq * (TRI_TABLE_SIZE * leaf->invSampleRate));
+    c->w = fabsf(c->freq * (TRI_TABLE_SIZE * c->invSampleRate));
     
     c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
     if (c->w < 0.0f) c->w = 0.0f;
@@ -173,13 +174,12 @@
     return oct0 + (oct1 - oct0) * c->w;
 }
 
-void     tTriangleSampleRateChanged (tTriangle* const cy)
+void     tTriangle_setSampleRate (tTriangle* const cy, float sr)
 {
     _tTriangle* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
-    c->inc = c->freq * leaf->invSampleRate;
-    c->inc -= (int)c->inc;
+    c->invSampleRate = 1.0f/sr;
+    tTriangle_setFreq(cy, c->freq);
 }
 #endif // LEAF_INCLUDE_TRIANGLE_TABLE
 
@@ -196,9 +196,11 @@
     _tMempool* m = *mp;
     _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->inc      =  0.0f;
     c->phase    =  0.0f;
+    c->invSampleRate = leaf->invSampleRate;
     tSquare_setFreq(cy, 220);
 }
 
@@ -212,15 +214,14 @@
 void    tSquare_setFreq(tSquare* const cy, float freq)
 {
     _tSquare* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
 
     c->freq  = freq;
     
-    c->inc = c->freq * leaf->invSampleRate;
+    c->inc = c->freq * c->invSampleRate;
     c->inc -= (int)c->inc;
     
     // abs for negative frequencies
-    c->w = fabsf(c->freq * (SQR_TABLE_SIZE * leaf->invSampleRate));
+    c->w = fabsf(c->freq * (SQR_TABLE_SIZE * c->invSampleRate));
     
     c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
     if (c->w < 0.0f) c->w = 0.0f;
@@ -265,13 +266,12 @@
     return oct0 + (oct1 - oct0) * c->w;
 }
 
-void     tSquareSampleRateChanged (tSquare* const cy)
+void     tSquare_setSampleRate (tSquare* const cy, float sr)
 {
     _tSquare* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
-    c->inc = c->freq * leaf->invSampleRate;
-    c->inc -= (int)c->inc;
+    c->invSampleRate = 1.0f/sr;
+    tSquare_setFreq(cy, c->freq);
 }
 #endif // LEAF_INCLUDE_SQUARE_TABLE
 
@@ -288,9 +288,11 @@
     _tMempool* m = *mp;
     _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->inc      = 0.0f;
     c->phase    = 0.0f;
+    c->invSampleRate = leaf->invSampleRate;
     tSawtooth_setFreq(cy, 220);
 }
 
@@ -304,15 +306,14 @@
 void    tSawtooth_setFreq(tSawtooth* const cy, float freq)
 {
     _tSawtooth* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
     c->freq  = freq;
     
-    c->inc = c->freq * leaf->invSampleRate;
+    c->inc = c->freq * c->invSampleRate;
     c->inc -= (int)c->inc;
     
     // abs for negative frequencies
-    c->w = fabsf(c->freq * (SAW_TABLE_SIZE * leaf->invSampleRate));
+    c->w = fabsf(c->freq * (SAW_TABLE_SIZE * c->invSampleRate));
     
     c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
     if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq
@@ -357,13 +358,12 @@
     return oct0 + (oct1 - oct0) * c->w;
 }
 
-void     tSawtoothSampleRateChanged (tSawtooth* const cy)
+void     tSawtooth_setSampleRate (tSawtooth* const cy, float sr)
 {
     _tSawtooth* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
-    c->inc = c->freq * leaf->invSampleRate;
-    c->inc -= (int)c->inc;
+    c->invSampleRate = 1.0f/sr;
+    tSawtooth_setFreq(cy, c->freq);
 }
 #endif // LEAF_INCLUDE_SAWTOOTH_TABLE
 
@@ -380,7 +380,9 @@
     _tMempool* m = *mp;
     _tPBTriangle* c = *osc = (_tPBTriangle*) mpool_alloc(sizeof(_tPBTriangle), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
 
+    c->invSampleRate = leaf->invSampleRate;
     c->inc      =  0.0f;
     c->phase    =  0.0f;
     c->skew     =  0.5f;
@@ -428,10 +430,9 @@
 void    tPBTriangle_setFreq       (tPBTriangle* const osc, float freq)
 {
     _tPBTriangle* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     c->freq  = freq;
-    c->inc = freq * leaf->invSampleRate;
+    c->inc = freq * c->invSampleRate;
 }
 
 void    tPBTriangle_setSkew       (tPBTriangle* const osc, float skew)
@@ -440,7 +441,15 @@
     c->skew = (skew + 1.0f) * 0.5f;
 }
 
+void     tPBTriangle_setSampleRate (tPBTriangle* const osc, float sr)
+{
+    _tPBTriangle* c = *osc;
+    
+    c->invSampleRate = 1.0f/sr;
+    tPBTriangle_setFreq(osc, c->freq);
+}
 
+
 //==============================================================================
 
 /* tPulse: Anti-aliased pulse waveform. */
@@ -454,7 +463,9 @@
     _tMempool* m = *mp;
     _tPBPulse* c = *osc = (_tPBPulse*) mpool_alloc(sizeof(_tPBPulse), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->invSampleRate = leaf->invSampleRate;
     c->inc      =  0.0f;
     c->phase    =  0.0f;
     c->width     =  0.5f;
@@ -487,10 +498,9 @@
 void    tPBPulse_setFreq     (tPBPulse* const osc, float freq)
 {
     _tPBPulse* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     c->freq  = freq;
-    c->inc = freq * leaf->invSampleRate;
+    c->inc = freq * c->invSampleRate;
 }
 
 void    tPBPulse_setWidth    (tPBPulse* const osc, float width)
@@ -499,6 +509,13 @@
     c->width = width;
 }
 
+void    tPBPulse_setSampleRate (tPBPulse* const osc, float sr)
+{
+    _tPBPulse* c = *osc;
+    
+    c->invSampleRate = 1.0f/sr;
+    tPBPulse_setFreq(osc, c->freq);
+}
 
 //==============================================================================
 
@@ -513,9 +530,11 @@
     _tMempool* m = *mp;
     _tPBSaw* c = *osc = (_tPBSaw*) mpool_alloc(sizeof(_tPBSaw), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->inc      =  0.0f;
     c->phase    =  0.0f;
+    c->invSampleRate = leaf->invSampleRate;
 }
 
 void    tPBSaw_free  (tPBSaw* const osc)
@@ -542,22 +561,21 @@
 void    tPBSaw_setFreq       (tPBSaw* const osc, float freq)
 {
     _tPBSaw* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     c->freq  = freq;
+    c->inc = freq * c->invSampleRate;
+}
+
+void    tPBSaw_setSampleRate (tPBSaw* const osc, float sr)
+{
+    _tPBSaw* c = *osc;
     
-    c->inc = freq * leaf->invSampleRate;
+    c->invSampleRate = 1.0f/sr;
+    tPBSaw_setFreq(osc, c->freq);
 }
 
 //========================================================================
 /* Phasor */
-void     tPhasorSampleRateChanged (tPhasor* const ph)
-{
-    _tPhasor* p = *ph;
-    LEAF* leaf = p->mempool->leaf;
-    
-    p->inc = p->freq * leaf->invSampleRate;
-};
 
 void    tPhasor_init(tPhasor* const ph, LEAF* const leaf)
 {
@@ -569,10 +587,12 @@
     _tMempool* m = *mp;
     _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m);
     p->mempool = m;
+    LEAF* leaf = p->mempool->leaf;
     
     p->phase = 0.0f;
     p->inc = 0.0f;
     p->phaseDidReset = 0;
+    p->invSampleRate = leaf->invSampleRate;
 }
 
 void    tPhasor_free (tPhasor* const ph)
@@ -585,11 +605,10 @@
 void    tPhasor_setFreq(tPhasor* const ph, float freq)
 {
     _tPhasor* p = *ph;
-    LEAF* leaf = p->mempool->leaf;
 
     p->freq  = freq;
     
-    p->inc = freq * leaf->invSampleRate;
+    p->inc = freq * p->invSampleRate;
     p->inc -= (int)p->inc;
 }
 
@@ -614,6 +633,15 @@
     return p->phase;
 }
 
+void     tPhasor_setSampleRate (tPhasor* const ph, float sr)
+{
+    _tPhasor* p = *ph;
+    
+    p->invSampleRate = 1.0f/sr;
+    tPhasor_setFreq(ph, p->freq);
+};
+
+//========================================================================
 /* Noise */
 void    tNoise_init(tNoise* const ns, NoiseType type, LEAF* const leaf)
 {
@@ -662,11 +690,6 @@
 //=================================================================================
 /* Neuron */
 
-void tNeuronSampleRateChanged(tNeuron* nr)
-{
-    
-}
-
 void tNeuron_init(tNeuron* const nr, LEAF* const leaf)
 {
     tNeuron_initToPool(nr, &leaf->mempool);
@@ -677,7 +700,7 @@
     _tMempool* m = *mp;
     _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);
     n->mempool = m;
-    
+
     tPoleZero_initToPool(&n->f, mp);
     
     tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -748,7 +771,6 @@
     n->V[0] = V1;
 }
 
-
 void tNeuron_setV2(tNeuron* const nr, float V2)
 {
     _tNeuron* n = *nr;
@@ -881,8 +903,6 @@
     n->current = current;
 }
 
-
-
 //----------------------------------------------------------------------------------------------------------
 
 void tMBPulse_init(tMBPulse* const osc, LEAF* const leaf)
@@ -895,7 +915,10 @@
     _tMempool* m = *pool;
     _tMBPulse* c = *osc = (_tMBPulse*) mpool_alloc(sizeof(_tMBPulse), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->invSampleRate = leaf->invSampleRate;
+    
     c->_init = true;
     c->amp = 1.0f;
     c->freq = 440.f;
@@ -918,7 +941,6 @@
 float tMBPulse_tick(tMBPulse* const osc)
 {
     _tMBPulse* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     int    j, k;
     float  freq, sync;
@@ -937,7 +959,7 @@
     if (c->_init) {
         p = 0.0f;
         
-        w = freq * leaf->invSampleRate;
+        w = freq * c->invSampleRate;
         b = 0.5f * (1.0f + c->waveform );
         
         /* for variable-width rectangular wave, we could do DC compensation with:
@@ -955,7 +977,7 @@
     //    a = 0.2 + 0.8 * vco->_port [FILT];
     a = 0.5f; // when a = 1, LPfilter is disabled
     
-    w = freq * leaf->invSampleRate;
+    w = freq * c->invSampleRate;
     b = 0.5f * (1.0f + c->waveform);
 
     if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;
@@ -1177,6 +1199,12 @@
     c->softsync = hardOrSoft > 0 ? 1 : 0;
 }
 
+void tMBPulse_setSampleRate(tMBPulse* const osc, float sr)
+{
+    _tMBPulse* c = *osc;
+    c->invSampleRate = 1.0f/sr;
+}
+
 //==========================================================================================================
 //==========================================================================================================
 
@@ -1190,7 +1218,9 @@
     _tMempool* m = *pool;
     _tMBTriangle* c = *osc = (_tMBTriangle*) mpool_alloc(sizeof(_tMBTriangle), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->invSampleRate = leaf->invSampleRate;
     c->amp = 1.0f;
     c->freq = 440.f;
     c->lastsyncin = 0.0f;
@@ -1213,7 +1243,6 @@
 float tMBTriangle_tick(tMBTriangle* const osc)
 {
     _tMBTriangle* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     int    j, k, dir;
     float  freq, sync;
@@ -1232,7 +1261,7 @@
     if (c->_init) {
         //        w = (exp2ap (freq[1] + vco->_port[OCTN] + vco->_port[TUNE] + expm[1] * vco->_port[EXPG] + 8.03136)
         //                + 1e3 * linm[1] * vco->_port[LING]) / SAMPLERATE;
-        w = freq * leaf->invSampleRate;
+        w = freq * c->invSampleRate;
         b = 0.5f * (1.0f + c->waveform);
         p = 0.5f * b;
         /* if we valued alias-free startup over low startup time, we could do:
@@ -1245,7 +1274,7 @@
     //    a = 0.2 + 0.8 * vco->_port [FILT];
     a = 0.5f; // when a = 1, LPfilter is disabled
     
-    w = freq * leaf->invSampleRate;
+    w = freq * c->invSampleRate;
     b = 0.5f * (1.0f + c->waveform);
     b1 = 1.0f - b;
     
@@ -1472,6 +1501,12 @@
     c->softsync = hardOrSoft > 0 ? 1 : 0;
 }
 
+void tMBTriangle_setSampleRate(tMBTriangle* const osc, float sr)
+{
+    _tMBTriangle* c = *osc;
+    c->invSampleRate = 1.0f/sr;
+}
+
 //==========================================================================================================
 //==========================================================================================================
 
@@ -1485,7 +1520,9 @@
     _tMempool* m = *pool;
     _tMBSaw* c = *osc = (_tMBSaw*) mpool_alloc(sizeof(_tMBSaw), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->invSampleRate = leaf->invSampleRate;
     c->_init = true;
     c->amp = 1.0f;
     c->freq = 440.f;
@@ -1507,7 +1544,6 @@
 float tMBSaw_tick(tMBSaw* const osc)
 {
     _tMBSaw* c = *osc;
-    LEAF* leaf = c->mempool->leaf;
     
     int    j;
     float  freq, sync;
@@ -1523,7 +1559,7 @@
     
     if (c->_init) {
         p = 0.5f;
-        w = freq * leaf->invSampleRate;
+        w = freq * c->invSampleRate;
         
         /* if we valued alias-free startup over low startup time, we could do:
          *   p -= w;
@@ -1534,7 +1570,7 @@
     //a = 0.2 + 0.8 * vco->_port [FILT];
     a = 0.5f; // when a = 1, LPfilter is disabled
     
-    w = freq * leaf->invSampleRate;
+    w = freq * c->invSampleRate;
 
     if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;
     // Should insert minblep for softsync?
@@ -1631,7 +1667,13 @@
     c->softsync = hardOrSoft > 0 ? 1 : 0;
 }
 
+void tMBSaw_setSampleRate(tMBSaw* const osc, float sr)
+{
+    _tMBSaw* c = *osc;
+    c->invSampleRate = 1.0f/sr;
+}
 
+
 // WaveTable
 void    tTable_init(tTable* const cy, float* waveTable, int size, LEAF* const leaf)
 {
@@ -1643,11 +1685,13 @@
     _tMempool* m = *mp;
     _tTable* c = *cy = (_tTable*)mpool_alloc(sizeof(_tTable), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->waveTable = waveTable;
     c->size = size;
     c->inc = 0.0f;
     c->phase = 0.0f;
+    c->invSampleRate = leaf->invSampleRate;
 }
 
 void    tTable_free(tTable* const cy)
@@ -1660,12 +1704,11 @@
 void     tTable_setFreq(tTable* const cy, float freq)
 {
     _tTable* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
     
     if (!isfinite(freq)) return;
     
     c->freq = freq;
-    c->inc = freq * leaf->invSampleRate;
+    c->inc = freq * c->invSampleRate;
     c->inc -= (int)c->inc;
 }
 
@@ -1695,13 +1738,11 @@
     return (samp0 + (samp1 - samp0) * fracPart);
 }
 
-void     tTableSampleRateChanged(tTable* const cy)
+void     tTable_setSampleRate(tTable* const cy, float sr)
 {
     _tTable* c = *cy;
-    LEAF* leaf = c->mempool->leaf;
-    
-    c->inc = c->freq * leaf->invSampleRate;
-    c->inc -= (int)c->inc;
+    c->invSampleRate = 1.0f/sr;
+    tTable_setFreq(cy, c->freq);
 }
 
 void tWaveTable_init(tWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
@@ -1714,9 +1755,14 @@
     _tMempool* m = *mp;
     _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->sampleRate = leaf->sampleRate;
+    
+    c->maxFreq = maxFreq;
+    
     // Determine base frequency
-    c->baseFreq = m->leaf->sampleRate / (float) size;
+    c->baseFreq = c->sampleRate / (float) size;
     c->invBaseFreq = 1.0f / c->baseFreq;
     
     // Determine how many tables we need
@@ -1723,7 +1769,7 @@
     // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing
     c->numTables = 2;
     float f = c->baseFreq;
-    while (f < maxFreq)
+    while (f < c->maxFreq)
     {
         c->numTables++;
         f *= 2.0f; // pass this multiplier in to set spacing of tables? would need to change setFreq too
@@ -1732,20 +1778,22 @@
     c->size = size;
     
     // Allocate memory for the tables
-    c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, m);
-    for (int t = 0; t < c->numTables; ++t)
+    c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
+    c->baseTable = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
+    c->tables[0] = c->baseTable;
+    for (int t = 1; t < c->numTables; ++t)
     {
-        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, m);
+        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
     }
     
     // Copy table
     for (int i = 0; i < c->size; ++i)
     {
-        c->tables[0][i] = table[i];
+        c->baseTable[i] = table[i];
     }
     
     // Make bandlimited copies
-    f = m->leaf->sampleRate * 0.25; //start at half nyquist
+    f = c->sampleRate * 0.25; //start at half nyquist
     // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
     tButterworth_initToPool(&c->bl, 8, -1.0f, f, mp);
     for (int t = 1; t < c->numTables; ++t)
@@ -1778,6 +1826,64 @@
     mpool_free((char*)c, c->mempool);
 }
 
+void tWaveTable_setSampleRate(tWaveTable* const cy, float sr)
+{
+    _tWaveTable* c = *cy;
+        
+    // Changing the sample rate of a wavetable requires up to partially reinitialize
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        mpool_free((char*)c->tables[t], c->mempool);
+    }
+    mpool_free((char*)c->tables, c->mempool);
+    
+    c->sampleRate = sr;
+    
+    // Determine base frequency
+    c->baseFreq = c->sampleRate / (float) c->size;
+    c->invBaseFreq = 1.0f / c->baseFreq;
+    
+    // Determine how many tables we need
+    // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing
+    c->numTables = 2;
+    float f = c->baseFreq;
+    while (f < c->maxFreq)
+    {
+        c->numTables++;
+        f *= 2.0f; // pass this multiplier in to set spacing of tables? would need to change setFreq too
+    }
+    
+    // Allocate memory for the tables
+    c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
+    c->tables[0] = c->baseTable;
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
+    }
+    
+    // Make bandlimited copies
+    f = c->sampleRate * 0.25; //start at half nyquist
+    // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
+    tButterworth_initToPool(&c->bl, 8, -1.0f, f, &c->mempool);
+    tButterworth_setSampleRate(&c->bl, c->sampleRate);
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        tButterworth_setF2(&c->bl, f);
+        // Do several passes here to prevent errors at the beginning of the waveform
+        // Not sure how many passes to do, seem to need more as the filter cutoff goes down
+        // 12 might be excessive but seems to work for now.
+        for (int p = 0; p < 12; ++p)
+        {
+            for (int i = 0; i < c->size; ++i)
+            {
+                c->tables[t][i] = tButterworth_tick(&c->bl, c->tables[t-1][i]);
+            }
+        }
+        f *= 0.5f; //halve the cutoff for next pass
+    }
+    tButterworth_free(&c->bl);
+}
+
 //=======================================================================================
 //=======================================================================================
 
@@ -1791,6 +1897,7 @@
     _tMempool* m = *mp;
     _tWaveOsc* c = *cy = (_tWaveOsc*) mpool_alloc(sizeof(_tWaveOsc), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
     c->table = *table;
 
@@ -1799,6 +1906,8 @@
     c->phaseOffset = 0.0f;
     c->aa = 0.5f;
     
+    c->invSampleRate = leaf->invSampleRate;
+    
     tWaveOsc_setFreq(cy, 220);
 }
 
@@ -1851,11 +1960,9 @@
 {
     _tWaveOsc* c = *cy;
     
-    LEAF* leaf = c->mempool->leaf;
-    
     c->freq  = freq;
     
-    c->inc = c->freq * leaf->invSampleRate;
+    c->inc = c->freq * c->invSampleRate;
     c->inc -= (int)c->inc;
     
     // abs for negative frequencies
@@ -1885,6 +1992,13 @@
     c->phaseOffset = phase - (int)phase;
 }
 
+void tWaveOsc_setSampleRate(tWaveOsc* const cy, float sr)
+{
+    _tWaveOsc* c = *cy;
+    c->invSampleRate = 1.0f/sr;
+    tWaveOsc_setFreq(cy, c->freq);
+}
+
 //================================================================================================
 //================================================================================================
 
@@ -2039,18 +2153,16 @@
     }
 }
 
-//void tWaveSynth_setIndexTable(tWaveSynth* const cy, int i, float* table, int size)
-//{
-//    _tWaveSynth* c = *cy;
-//    if (i >= c->numTables) return;
-//    if (
-//    tWaveTable_free(&c->tables[i]);
-//    tWaveTable_initToPool(&c->tables[i], table, size, c->maxFreq, &c->mempool);
-//    for (int v = 0; v < c->numVoices; ++v)
-//    {
-//        tWaveOsc_setFreq(&c->oscs[i][v], c->oscs[i][v]->freq);
-//    }
-//}
+void tWaveSynth_setSampleRate(tWaveSynth* const cy, float sr)
+{
+    _tWaveSynth* c = *cy;
+    
+    for (int i = 0; i < c->numTables; ++i)
+    {
+        tWaveTable_setSampleRate(&c->tables[i], sr);
+        for (int v = 0; v < c->numVoices; ++v) tWaveOsc_setSampleRate(&c->oscs[i][v], sr);
+    }
+}
 
 //=======================================================================================
 //=======================================================================================
@@ -2065,9 +2177,14 @@
     _tMempool* m = *mp;
     _tWaveTableS* c = *cy = (_tWaveTableS*) mpool_alloc(sizeof(_tWaveTableS), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->sampleRate = leaf->sampleRate;
+    
+    c->maxFreq = maxFreq;
+    
     // Determine base frequency
-    c->baseFreq = m->leaf->sampleRate / (float) size;
+    c->baseFreq = c->sampleRate / (float) size;
     c->invBaseFreq = 1.0f / c->baseFreq;
     
     // Determine how many tables we need
@@ -2082,23 +2199,24 @@
     // Allocate memory for the tables
     c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
     c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);
-    int n = size;
-    for (int t = 0; t < c->numTables; ++t)
+    c->sizes[0] = size;
+    c->baseTable = (float*) mpool_alloc(sizeof(float) * c->sizes[0], c->mempool);
+    c->tables[0] = c->baseTable;
+    for (int t = 1; t < c->numTables; ++t)
     {
-        c->sizes[t] = n;
-        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], m);
-        n = c->sizes[t] / 2;
+        c->sizes[t] = c->sizes[t-1] / 2;
+        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], c->mempool);
     }
     
     // Copy table
     for (int i = 0; i < c->sizes[0]; ++i)
     {
-        c->tables[0][i] = table[i];
+        c->baseTable[i] = table[i];
     }
     
     // Make bandlimited copies
     // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
-    tButterworth_initToPool(&c->bl, 8, -1.0f, m->leaf->sampleRate * 0.25f, mp);
+    tButterworth_initToPool(&c->bl, 8, -1.0f, c->sampleRate * 0.25f, mp);
     tOversampler_initToPool(&c->ds, 2, 1, mp);
     for (int t = 1; t < c->numTables; ++t)
     {
@@ -2130,6 +2248,67 @@
     mpool_free((char*)c, c->mempool);
 }
 
+void    tWaveTableS_setSampleRate(tWaveTableS* const cy, float sr)
+{
+    _tWaveTableS* c = *cy;
+    
+    int size = c->sizes[0];
+    
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        mpool_free((char*)c->tables[t], c->mempool);
+    }
+    mpool_free((char*)c->tables, c->mempool);
+    mpool_free((char*)c->sizes, c->mempool);
+    
+    c->sampleRate = sr;
+    
+    // Determine base frequency
+    c->baseFreq = c->sampleRate / (float) size;
+    c->invBaseFreq = 1.0f / c->baseFreq;
+    
+    // Determine how many tables we need
+    c->numTables = 2;
+    float f = c->baseFreq;
+    while (f < c->maxFreq)
+    {
+        c->numTables++;
+        f *= 2.0f; // pass this multiplier in to set spacing of tables?
+    }
+    
+    // Allocate memory for the tables
+    c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
+    c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);
+    c->tables[0] = c->baseTable;
+    c->sizes[0] = size;
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        c->sizes[t] = c->sizes[t-1] / 2;
+        c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], c->mempool);
+    }
+    
+    // Make bandlimited copies
+    // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
+    tButterworth_initToPool(&c->bl, 8, -1.0f, c->sampleRate * 0.25f, &c->mempool);
+    tButterworth_setSampleRate(&c->bl, c->sampleRate);
+    tOversampler_initToPool(&c->ds, 2, 1, &c->mempool);
+    for (int t = 1; t < c->numTables; ++t)
+    {
+        // Similar to tWaveTable, doing multiple passes here helps, but not sure what number is optimal
+        for (int p = 0; p < 12; ++p)
+        {
+            for (int i = 0; i < c->sizes[t]; ++i)
+            {
+                c->dsBuffer[0] = tButterworth_tick(&c->bl, c->tables[t-1][i*2]);
+                c->dsBuffer[1] = tButterworth_tick(&c->bl, c->tables[t-1][(i*2)+1]);
+                c->tables[t][i] = tOversampler_downsample(&c->ds, c->dsBuffer);
+            }
+        }
+    }
+    tOversampler_free(&c->ds);
+    tButterworth_free(&c->bl);
+}
+
 //================================================================================================
 //================================================================================================
 
@@ -2143,7 +2322,9 @@
     _tMempool* m = *mp;
     _tWaveOscS* c = *cy = (_tWaveOscS*) mpool_alloc(sizeof(_tWaveOscS), m);
     c->mempool = m;
+    LEAF* leaf = c->mempool->leaf;
     
+    c->invSampleRate = leaf->invSampleRate;
     c->inc = 0.0f;
     c->phase = 0.0f;
     c->phaseOffset = 0.0f;
@@ -2201,12 +2382,10 @@
 void tWaveOscS_setFreq(tWaveOscS* const cy, float freq)
 {
     _tWaveOscS* c = *cy;
-    
-    LEAF* leaf = c->mempool->leaf;
-    
+
     c->freq  = freq;
     
-    c->inc = c->freq * leaf->invSampleRate;
+    c->inc = c->freq * c->invSampleRate;
     c->inc -= (int)c->inc;
     
     // abs for negative frequencies
@@ -2233,6 +2412,13 @@
     c->phaseOffset = phase - (int)phase;
 }
 
+void tWaveOscS_setSampleRate(tWaveOscS* const cy, float sr)
+{
+    _tWaveOscS* c = *cy;
+    c->invSampleRate = 1.0f/sr;
+    tWaveOscS_setFreq(cy, c->freq);
+}
+
 //================================================================================================
 //================================================================================================
 
@@ -2384,6 +2570,16 @@
     for (int v = 0; v < c->numVoices; ++v)
     {
         tWaveOscS_setPhaseOffset(&c->oscs[i][v], phase);
+    }
+}
+
+void tWaveSynthS_setSampleRate(tWaveSynthS* const cy, float sr)
+{
+    _tWaveSynthS* c = *cy;
+    for (int i = 0; i < c->numTables; ++i)
+    {
+        tWaveTableS_setSampleRate(&c->tables[i], sr);
+        for (int v = 0; v < c->numVoices; ++v) tWaveOscS_setSampleRate(&c->oscs[i][v], sr);
     }
 }
 //
--- a/leaf/Src/leaf-physical.c
+++ b/leaf/Src/leaf-physical.c
@@ -29,6 +29,8 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
     
+    p->sampleRate = leaf->sampleRate;
+    
     if ( lowestFrequency <= 0.0f )  lowestFrequency = 10.0f;
     
     tNoise_initToPool(&p->noise, WhiteNoise, mp);
@@ -37,7 +39,7 @@
     
     tOneZero_initToPool(&p->loopFilter, 0.0f, mp);
     
-    tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);
+    tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
     tAllpassDelay_clear(&p->delayLine);
     
     tPluck_setFrequency(pl, 220.0f);
@@ -106,12 +108,11 @@
 void    tPluck_setFrequency  (tPluck* const pl, float frequency )
 {
     _tPluck* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     if ( frequency <= 0.0f )   frequency = 0.001f;
     
     // Delay = length - filter delay.
-    float delay = ( leaf->sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );
+    float delay = ( p->sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );
     
     tAllpassDelay_setDelay(&p->delayLine, delay );
     
@@ -118,7 +119,6 @@
     p->loopGain = 0.99f + (frequency * 0.000005f);
     
     if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;
-    
 }
 
 // Perform the control change specified by \e number and \e value (0.0 - 128.0).
@@ -127,10 +127,18 @@
     return;
 }
 
-void tPluckSampleRateChanged(tPluck* const pl)
+void tPluck_setSampleRate(tPluck* const pl, float sr)
 {
     _tPluck* p = *pl;
+    p->sampleRate = sr;
+    
+    tAllpassDelay_free(&p->delayLine);
+    tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, &p->mempool);
+    tAllpassDelay_clear(&p->delayLine);
+    
     tPluck_setFrequency(pl, p->lastFreq);
+    tOnePole_setSampleRate(&p->pickFilter, p->sampleRate);
+    tOneZero_setSampleRate(&p->loopFilter, p->sampleRate);
 }
 
 /* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -146,12 +154,14 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
     
+    p->sampleRate = leaf->sampleRate;
+    
     if ( lowestFrequency <= 0.0f )  lowestFrequency = 8.0f;
     
-    tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);
+    tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
     tAllpassDelay_clear(&p->delayLine);
     
-    tLinearDelay_initToPool(&p->combDelay, 0.0f, leaf->sampleRate * 2, mp);
+    tLinearDelay_initToPool(&p->combDelay, 0.0f, p->sampleRate * 2, mp);
     tLinearDelay_clear(&p->combDelay);
     
     tOneZero_initToPool(&p->filter, 0.0f, mp);
@@ -254,12 +264,11 @@
 void    tKarplusStrong_setFrequency  (tKarplusStrong* const pl, float frequency )
 {
     _tKarplusStrong* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     if ( frequency <= 0.0f )   frequency = 0.001f;
     
     p->lastFrequency = frequency;
-    p->lastLength = leaf->sampleRate / p->lastFrequency;
+    p->lastLength = p->sampleRate / p->lastFrequency;
     float delay = p->lastLength - 0.5f;
     tAllpassDelay_setDelay(&p->delayLine, delay);
     
@@ -270,7 +279,6 @@
     tKarplusStrong_setStretch(pl, p->stretching);
     
     tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
-    
 }
 
 // Set the stretch "factor" of the string (0.0 - 1.0).
@@ -277,12 +285,11 @@
 void    tKarplusStrong_setStretch         (tKarplusStrong* const pl, float stretch)
 {
     _tKarplusStrong* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     p->stretching = stretch;
     float coefficient;
     float freq = p->lastFrequency * 2.0f;
-    float dFreq = ( (0.5f * leaf->sampleRate) - freq ) * 0.25f;
+    float dFreq = ( (0.5f * p->sampleRate) - freq ) * 0.25f;
     float temp = 0.5f + (stretch * 0.5f);
     if ( temp > 0.9999f ) temp = 0.9999f;
     
@@ -293,7 +300,7 @@
         tBiQuad_setB0(&p->biquad[i], coefficient);
         tBiQuad_setB2(&p->biquad[i], 1.0f);
         
-        coefficient = -2.0f * temp * cosf(TWO_PI * freq / leaf->sampleRate);
+        coefficient = -2.0f * temp * cosf(TWO_PI * freq / p->sampleRate);
         tBiQuad_setA1(&p->biquad[i], coefficient);
         tBiQuad_setB1(&p->biquad[i], coefficient);
         
@@ -339,12 +346,26 @@
         tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );
 }
 
-void    tKarplusStrongSampleRateChanged (tKarplusStrong* const pl)
+void    tKarplusStrong_setSampleRate (tKarplusStrong* const pl, float sr)
 {
     _tKarplusStrong* p = *pl;
+    p->sampleRate = sr;
     
+    tAllpassDelay_free(&p->delayLine);
+    tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, &p->mempool);
+    tAllpassDelay_clear(&p->delayLine);
+    
+    tLinearDelay_free(&p->combDelay);
+    tLinearDelay_initToPool(&p->combDelay, 0.0f, p->sampleRate * 2, &p->mempool);
+    tLinearDelay_clear(&p->combDelay);
+    
     tKarplusStrong_setFrequency(pl, p->lastFrequency);
-    tKarplusStrong_setStretch(pl, p->stretching);
+    tOneZero_setSampleRate(&p->filter, p->sampleRate);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tBiQuad_setSampleRate(&p->biquad[i], p->sampleRate);
+    }
 }
 
 /* Simple Living String*/
@@ -365,8 +386,9 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
     
+    p->sampleRate = leaf->sampleRate;
     p->curr=0.0f;
-    tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+    tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
     tSimpleLivingString_setFreq(pl, freq);
     tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);
     tLinearDelay_clear(&p->delayLine);
@@ -393,11 +415,10 @@
 void     tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
 {
     _tSimpleLivingString* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     if (freq<20) freq=20;
     else if (freq>10000) freq=10000;
-    p->waveLengthInSamples = leaf->sampleRate/freq;
+    p->waveLengthInSamples = p->sampleRate/freq;
     tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
 }
 
@@ -466,6 +487,17 @@
     return p->curr;
 }
 
+void   tSimpleLivingString_setSampleRate(tSimpleLivingString* const pl, float sr)
+{
+    _tSimpleLivingString* p = *pl;
+    float freq = p->sampleRate/p->waveLengthInSamples;
+    p->sampleRate = sr;
+    p->waveLengthInSamples = p->sampleRate/freq;
+    tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
+    tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblocker, p->sampleRate);
+}
+
 /* Living String*/
 
 void    tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex,
@@ -484,8 +516,9 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
     
+    p->sampleRate = leaf->sampleRate;
     p->curr=0.0f;
-    tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+    tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
     tLivingString_setFreq(pl, freq);
     p->freq = freq;
     tExpSmooth_initToPool(&p->ppSmooth, pickPos, 0.01f, mp); // smoother for pick position
@@ -538,11 +571,10 @@
 void     tLivingString_setFreq(tLivingString* const pl, float freq)
 {    // NOTE: It is faster to set wavelength in samples directly
     _tLivingString* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     if (freq<20.f) freq=20.f;
     else if (freq>10000.f) freq=10000.f;
-    p->waveLengthInSamples = leaf->sampleRate/freq;
+    p->waveLengthInSamples = p->sampleRate/freq;
     tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
 }
 
@@ -658,7 +690,22 @@
     return p->curr;
 }
 
+void   tLivingString_setSampleRate(tLivingString* const pl, float sr)
+{
+    _tLivingString* p = *pl;
+    float freq = p->sampleRate/p->waveLengthInSamples;
+    p->sampleRate = sr;
+    p->waveLengthInSamples = p->sampleRate/freq;
+    tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
+    tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
+    tOnePole_setSampleRate(&p->nutFilter, p->sampleRate);
+    tOnePole_setSampleRate(&p->prepFilterU, p->sampleRate);
+    tOnePole_setSampleRate(&p->prepFilterL, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
+}
 
+
 //////////---------------------------
 /* Version of Living String with Hermite Interpolation */
 /*Living String experiment 2 */
@@ -681,8 +728,9 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
 
+    p->sampleRate = leaf->sampleRate;
     p->curr=0.0f;
-    tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.1f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+    tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.1f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
     tLivingString2_setFreq(pl, freq);
     p->freq = freq;
     p->prepPos = prepPos;
@@ -742,12 +790,12 @@
 void     tLivingString2_setFreq(tLivingString2* const pl, float freq)
 {    // NOTE: It is faster to set wavelength in samples directly
     _tLivingString2* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
+    
     if (freq<20.f) freq=20.f;
     else if (freq>10000.f) freq=10000.f;
     freq = freq*2;
     p->freq = freq;
-    p->waveLengthInSamples = (leaf->sampleRate/freq) - 1;
+    p->waveLengthInSamples = (p->sampleRate/p->freq) - 1;
     tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
 }
 
@@ -754,12 +802,12 @@
 void     tLivingString2_setWaveLength(tLivingString2* const pl, float waveLength)
 {
     _tLivingString2* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
+    
     waveLength = waveLength * 0.5f;
     if (waveLength<4.8f) waveLength=4.8f;
     else if (waveLength>2400.f) waveLength=2400.f;
     p->waveLengthInSamples = waveLength - 1;
-    p->freq = leaf->sampleRate / waveLength;
+    p->freq = p->sampleRate / waveLength;
     tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
 }
 
@@ -927,7 +975,6 @@
     tHermiteDelay_setDelay(&p->delLB, lowLen);
     tHermiteDelay_setDelay(&p->delUF, upLen);
     tHermiteDelay_setDelay(&p->delUB, upLen);
-
     
     uint32_t pickupPosInt;
     float pickupOut = 0.0f;
@@ -962,8 +1009,20 @@
     return p->curr;
 }
 
+void    tLivingString2_setSampleRate(tLivingString2* const pl, float sr)
+{
+    _tLivingString2* p = *pl;
+    p->sampleRate = sr;
+    p->waveLengthInSamples = (p->sampleRate/p->freq) - 1;
+    tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
+    tTwoZero_setSampleRate(&p->bridgeFilter, p->sampleRate);
+    tTwoZero_setSampleRate(&p->nutFilter, p->sampleRate);
+    tTwoZero_setSampleRate(&p->prepFilterU, p->sampleRate);
+    tTwoZero_setSampleRate(&p->prepFilterL, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
+}
 
-
 //////////---------------------------
 
 /* Complex Living String (has pick position and preparation position separated) */
@@ -984,8 +1043,9 @@
     p->mempool = m;
     LEAF* leaf = p->mempool->leaf;
 
+    p->sampleRate = leaf->sampleRate;
     p->curr=0.0f;
-    tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+    tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
     tComplexLivingString_setFreq(pl, freq);
     p->freq = freq;
     tExpSmooth_initToPool(&p->pickPosSmooth, pickPos, 0.01f, mp); // smoother for pick position
@@ -1050,11 +1110,10 @@
 void     tComplexLivingString_setFreq(tComplexLivingString* const pl, float freq)
 {    // NOTE: It is faster to set wavelength in samples directly
     _tComplexLivingString* p = *pl;
-    LEAF* leaf = p->mempool->leaf;
     
     if (freq<20.0f) freq=20.0f;
     else if (freq>10000.0f) freq=10000.0f;
-    p->waveLengthInSamples = leaf->sampleRate/freq;
+    p->waveLengthInSamples = p->sampleRate/freq;
     tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
 }
 
@@ -1205,7 +1264,20 @@
     return p->curr;
 }
 
-
+void    tComplexLivingString_setSampleRate(tComplexLivingString* const pl, float sr)
+{
+    _tComplexLivingString* p = *pl;
+    float freq = p->waveLengthInSamples/p->sampleRate;
+    p->sampleRate = sr;
+    p->waveLengthInSamples = p->sampleRate/freq;
+    tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
+    tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
+    tOnePole_setSampleRate(&p->nutFilter, p->sampleRate);
+    tOnePole_setSampleRate(&p->prepFilterU, p->sampleRate);
+    tOnePole_setSampleRate(&p->prepFilterL, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
+    tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
+}
 
 ///Reed Table model
 //default values from STK are 0.6 offset and -0.8 slope
--- a/leaf/Src/leaf-reverb.c
+++ b/leaf/Src/leaf-reverb.c
@@ -35,8 +35,11 @@
     
     r->inv_441 = 1.0f/44100.0f;
     
+    r->sampleRate = leaf->sampleRate;
+    r->invSampleRate = leaf->invSampleRate;
+    
     int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
-    double scaler = leaf->sampleRate * r->inv_441;
+    double scaler = r->sampleRate * r->inv_441;
     
     int delay, i;
     if (scaler != 1.0f)
@@ -85,14 +88,12 @@
 void    tPRCReverb_setT60(tPRCReverb* const rev, float t60)
 {
     _tPRCReverb* r = *rev;
-    LEAF* leaf = r->mempool->leaf;
     
     if ( t60 <= 0.0f ) t60 = 0.001f;
     
     r->t60 = t60;
     
-    r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf->invSampleRate / t60 ));
-    
+    r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * r->invSampleRate / t60 ));
 }
 
 void    tPRCReverb_setMix(tPRCReverb* const rev, float mix)
@@ -135,12 +136,40 @@
     return out;
 }
 
-void     tPRCReverbSampleRateChanged (tPRCReverb* const rev)
+void     tPRCReverb_setSampleRate (tPRCReverb* const rev, float sr)
 {
     _tPRCReverb* r = *rev;
-    LEAF* leaf = r->mempool->leaf;
     
-    r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf->invSampleRate / r->t60 ));
+    r->sampleRate = sr;
+    r->invSampleRate = 1.0f/r->sampleRate;
+    
+    int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
+    double scaler = r->sampleRate * r->inv_441;
+    
+    int delay, i;
+    if (scaler != 1.0f)
+    {
+        for (i=0; i<4; i++)
+        {
+            delay = (int) scaler * lengths[i];
+            
+            if ( (delay & 1) == 0)          delay++;
+            
+            while ( !LEAF_isPrime(delay) )  delay += 2;
+            
+            lengths[i] = delay;
+        }
+    }
+    
+    tDelay_free(&r->allpassDelays[0]);
+    tDelay_free(&r->allpassDelays[1]);
+    tDelay_free(&r->combDelay);
+    
+    tDelay_initToPool(&r->allpassDelays[0], lengths[0], lengths[0] * 2, &r->mempool);
+    tDelay_initToPool(&r->allpassDelays[1], lengths[1], lengths[1] * 2, &r->mempool);
+    tDelay_initToPool(&r->combDelay, lengths[2], lengths[2] * 2, &r->mempool);
+    
+    r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * r->invSampleRate / r->t60 ));
 }
 
 /* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -159,9 +188,11 @@
     if (t60 <= 0.0f) t60 = 0.001f;
     
     r->inv_441 = 1.0f/44100.0f;
+    r->sampleRate = leaf->sampleRate;
+    r->invSampleRate = leaf->invSampleRate;
     
     int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19}; // Delay lengths for 44100 Hz sample rate.
-    double scaler = leaf->sampleRate / 25641.0f;
+    double scaler = r->sampleRate * r->inv_441;// / 25641.0f;
     
     int delay, i;
     
@@ -179,7 +210,7 @@
     {
         tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, mp);
         tLinearDelay_clear(&r->combDelays[i]);
-        r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * leaf->invSampleRate / t60));
+        r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * r->invSampleRate / t60));
     }
     
     for ( i=0; i<8; i++ )
@@ -188,7 +219,6 @@
         tLinearDelay_clear(&r->allpassDelays[i]);
     }
     
-    
     tNReverb_setT60(rev, t60);
     r->allpassCoeff = 0.7f;
     r->mix = 0.3f;
@@ -214,14 +244,12 @@
 void    tNReverb_setT60(tNReverb* const rev, float t60)
 {
     _tNReverb* r = *rev;
-    LEAF* leaf = r->mempool->leaf;
     
-    if (t60 <= 0.0f)           t60 = 0.001f;
+    if (t60 <= 0.0f) t60 = 0.001f;
     
     r->t60 = t60;
     
-    for (int i=0; i<6; i++)   r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * leaf->invSampleRate / t60 ));
-    
+    for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * r->invSampleRate / t60 ));
 }
 
 void    tNReverb_setMix(tNReverb* const rev, float mix)
@@ -344,7 +372,6 @@
     output[0] = -( r->allpassCoeff * temp2 ) + temp + drymix;
     out = output[0];
 
-
     temp = tLinearDelay_getLastOut(&r->allpassDelays[5]);
     temp3 = r->allpassCoeff * temp;
     temp3 += temp1;
@@ -354,12 +381,44 @@
     r->lastOut = out;
 }
 
-void     tNReverbSampleRateChanged (tNReverb* const rev)
+void     tNReverb_setSampleRate (tNReverb* const rev, float sr)
 {
     _tNReverb* r = *rev;
-    LEAF* leaf = r->mempool->leaf;
     
-    for (int i=0; i<6; i++)   r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * leaf->invSampleRate / r->t60 ));
+    r->sampleRate = sr;
+    r->invSampleRate = 1.0f/r->sampleRate;
+    
+    int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19}; // Delay lengths for 44100 Hz sample rate.
+    double scaler = r->sampleRate * r->inv_441;// / 25641.0f;
+    
+    int delay, i;
+    
+    for (i=0; i < 15; i++)
+    {
+        delay = (int) scaler * lengths[i];
+        if ( (delay & 1) == 0)
+            delay++;
+        while ( !LEAF_isPrime(delay) )
+            delay += 2;
+        lengths[i] = delay;
+    }
+    
+    for ( i=0; i<6; i++ )
+    {
+        tLinearDelay_free(&r->combDelays[i]);
+        tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, &r->mempool);
+        tLinearDelay_clear(&r->combDelays[i]);
+        r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * r->invSampleRate / r->t60));
+    }
+    
+    for ( i=0; i<8; i++ )
+    {
+        tLinearDelay_free(&r->allpassDelays[i]);
+        tLinearDelay_initToPool(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2, &r->mempool);
+        tLinearDelay_clear(&r->allpassDelays[i]);
+    }
+    
+    tNReverb_setT60(rev, r->t60);
 }
 
 // ======================================DATTORRO=========================================
@@ -369,7 +428,6 @@
 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    tDattorroReverb_init              (tDattorroReverb* const rev, LEAF* const leaf)
 {
     tDattorroReverb_initToPool(rev, &leaf->mempool);
@@ -382,9 +440,11 @@
     r->mempool = m;
     LEAF* leaf = r->mempool->leaf;
     
+    r->sampleRate = leaf->sampleRate;
+    
     r->size_max = 2.0f;
     r->size = 1.f;
-    r->t = r->size * leaf->sampleRate * 0.001f;
+    r->t = r->size * r->sampleRate * 0.001f;
     r->frozen = 0;
     // INPUT
     tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);
@@ -426,16 +486,11 @@
     tCycle_initToPool(&r->f2_lfo, mp);
     tCycle_setFreq(&r->f2_lfo, 0.07f);
     
-    
     // PARAMETERS
     tDattorroReverb_setMix(rev, 0.5f);
-    
     tDattorroReverb_setInputDelay(rev,  0.f);
-    
     tDattorroReverb_setInputFilter(rev, 10000.f);
-    
     tDattorroReverb_setFeedbackFilter(rev, 5000.f);
-    
     tDattorroReverb_setFeedbackGain(rev, 0.4f);
 }
 
@@ -625,68 +680,67 @@
         in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
     }
 
+    // FEEDBACK 1
+    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;
+    
+    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;
+    
+    if (r->frozen)
+    {
+        f1_sample = 0.0f;
+    }
+    
+    r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
+    
+    // FEEDBACK 2
+    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;
+    
+    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;
+    
+    if (r->frozen)
+    {
+        f2_sample = 0.0f;
+    }
+    r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
+    
 
-        // FEEDBACK 1
-        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;
-
-        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;
-
-        if (r->frozen)
-        {
-            f1_sample = 0.0f;
-        }
-
-        r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
-
-        // FEEDBACK 2
-        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;
-
-        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;
-
-        if (r->frozen)
-        {
-            f2_sample = 0.0f;
-        }
-        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));
@@ -730,7 +784,7 @@
     r->mix = LEAF_clip(0.0f, mix, 1.0f);
 }
 
-void    tDattorroReverb_setFreeze            (tDattorroReverb* const rev, uint32_t freeze)
+void    tDattorroReverb_setFreeze            (tDattorroReverb* const rev, int freeze)
 {
     _tDattorroReverb* r = *rev;
     r->frozen = freeze;
@@ -772,10 +826,9 @@
 void    tDattorroReverb_setSize           (tDattorroReverb* const rev, float size)
 {
     _tDattorroReverb* r = *rev;
-    LEAF* leaf = r->mempool->leaf;
     
     r->size = LEAF_clip(0.01f, size*r->size_max, r->size_max);
-    r->t = r->size * leaf->sampleRate * 0.001f;
+    r->t = r->size * r->sampleRate * 0.001f;
     
     /*
      for (int i = 0; i < 4; i++)
@@ -834,4 +887,76 @@
 {
     _tDattorroReverb* r = *rev;
     r->feedback_gain = gain;
+}
+
+void    tDattorroReverb_setSampleRate   (tDattorroReverb* const rev, float sr)
+{
+    _tDattorroReverb* r = *rev;
+    tMempool* mp = &r->mempool;
+    
+    r->sampleRate = sr;
+    r->t = r->size * r->sampleRate * 0.001f;
+    
+    // INPUT
+    tTapeDelay_free(&r->in_delay);
+    
+    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);
+    
+    // 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);
+    
+    // INPUT
+    tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);
+    
+    for (int i = 0; i < 4; i++)
+    {
+        tAllpass_initToPool(&r->in_allpass[i], SAMP(in_allpass_delays[i]), SAMP(20.f), mp); // * r->size_max
+        tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+    }
+    
+    // FEEDBACK 1
+    tAllpass_initToPool(&r->f1_allpass, SAMP(30.51f), SAMP(100.f), mp); // * r->size_max
+    tAllpass_setGain(&r->f1_allpass, 0.7f);
+    
+    tTapeDelay_initToPool(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f) * r->size_max + 1, mp);
+    tTapeDelay_initToPool(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f) * r->size_max + 1, mp);
+    tTapeDelay_initToPool(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f) * r->size_max + 1, mp);
+    
+    // FEEDBACK 2
+    tAllpass_initToPool(&r->f2_allpass, SAMP(22.58f), SAMP(100.f), mp); // * r->size_max
+    tAllpass_setGain(&r->f2_allpass, 0.7f);
+    
+    tTapeDelay_initToPool(&r->f2_delay_1, SAMP(149.62f), SAMP(200.f) * r->size_max + 1, mp);
+    tTapeDelay_initToPool(&r->f2_delay_2, SAMP(60.48f), SAMP(100.f) * r->size_max + 1, mp);
+    tTapeDelay_initToPool(&r->f2_delay_3, SAMP(106.28f), SAMP(200.f) * r->size_max + 1, mp);
+    
+    tOnePole_setSampleRate(&r->in_filter, r->sampleRate);
+    tOnePole_setSampleRate(&r->f1_filter, r->sampleRate);
+    tHighpass_setSampleRate(&r->f1_hp, r->sampleRate);
+    tCycle_setSampleRate(&r->f1_lfo, r->sampleRate);
+    tOnePole_setSampleRate(&r->f2_filter, r->sampleRate);
+    tHighpass_setSampleRate(&r->f2_hp, r->sampleRate);
+    tCycle_setSampleRate(&r->f2_lfo, r->sampleRate);
+    
+    // PARAMETERS
+    tDattorroReverb_setSize(rev, r->size*0.5f);
+    tDattorroReverb_setMix(rev, r->mix);
+    tDattorroReverb_setInputDelay(rev,  r->predelay);
+    tDattorroReverb_setInputFilter(rev, r->input_filter);
+    tDattorroReverb_setFeedbackFilter(rev, r->feedback_filter);
+    tDattorroReverb_setFeedbackGain(rev, r->feedback_gain);
 }
--- a/leaf/Src/leaf-sampling.c
+++ b/leaf/Src/leaf-sampling.c
@@ -34,9 +34,10 @@
     _tMempool* m = *mp;
     _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);
     s->mempool = m;
+    LEAF* leaf = s->mempool->leaf;
     
     s->buff = (float*) mpool_alloc( sizeof(float) * length, m);
-    s->sampleRate = s->mempool->leaf->sampleRate;
+    s->sampleRate = leaf->sampleRate;
     s->channels = 1;
     s->bufferLength = length;
     s->recordedLength = 0;
@@ -191,13 +192,12 @@
     
     _tBuffer* s = *b;
     
-    p->leafInvSampleRate = leaf->invSampleRate;
-    p->leafSampleRate = leaf->sampleRate;
-    p->ticksPerSevenMs = 0.007f * p->leafSampleRate;
-    p->rateFactor = s->sampleRate * p->leafInvSampleRate;
+    p->invSampleRate = leaf->invSampleRate;
+    p->sampleRate = leaf->sampleRate;
+    p->ticksPerSevenMs = 0.007f * p->sampleRate;
+    p->rateFactor = s->sampleRate * p->invSampleRate;
     p->channels = s->channels;
 
-
     p->samp = s;
     
     p->active = 0;
@@ -255,9 +255,8 @@
     _tBuffer* s = *b;
     
     p->samp = s;
-    
 
-    p->rateFactor = s->sampleRate * p->leafInvSampleRate;
+    p->rateFactor = s->sampleRate * p->invSampleRate;
     p->channels = s->channels;
 
     p->start = 0;
@@ -268,8 +267,6 @@
     p->idx = 0.f;
 }
 
-
-
 float tSampler_tick        (tSampler* const sp)
 {
     _tSampler* p = *sp;
@@ -342,10 +339,7 @@
     int32_t fadeRightEnd = myEnd;// + (fadeLeftEnd - start);
     //    if (fadeRightEnd >= length) fadeRightEnd = length - 1;
     int32_t fadeRightStart = fadeRightEnd - cfxlen;
-    
 
-
-
     if (p->mode == PlayLoop)
     {
         
@@ -532,7 +526,6 @@
     return p->last;
 }
 
-
 float tSampler_tickStereo        (tSampler* const sp, float* outputArray)
 {
     _tSampler* p = *sp;
@@ -611,9 +604,6 @@
     //    if (fadeRightEnd >= length) fadeRightEnd = length - 1;
     int32_t fadeRightStart = fadeRightEnd - cfxlen;
 
-
-
-
     if (p->mode == PlayLoop)
     {
 
@@ -725,11 +715,8 @@
         }
     }
 
-
-
     attemptStartEndChange(sp);
 
-
     if (p->mode == PlayLoop)
     {
         if((int)p->idx < myStart)
@@ -782,9 +769,6 @@
         outputArray[i]  = outputArray[i] * sampleGain;
     }
 
-
-
-
     if (p->active < 0)
     {
         //if was fading out and reached silence
@@ -816,11 +800,8 @@
         }
     }
 
-
-
     p->last =  outputArray[0];
 
-
     return p->last;
 }
 
@@ -1089,6 +1070,18 @@
     p->iinc = 1.f / p->inc;
 }
 
+
+void tSampler_setSampleRate(tSampler* const sp, float sr)
+{
+    _tSampler* p = *sp;
+    _tBuffer* s = p->samp;
+    p->sampleRate = sr;
+    p->invSampleRate = 1.0f/p->sampleRate;
+    p->ticksPerSevenMs = 0.007f * p->sampleRate;
+    p->rateFactor = s->sampleRate * p->invSampleRate;
+    tRamp_setSampleRate(&p->gain, p->sampleRate);
+}
+
 //==============================================================================
 
 void    tAutoSampler_init   (tAutoSampler* const as, tBuffer* const b, LEAF* const leaf)
@@ -1212,6 +1205,11 @@
     ;
 }
 
+void    tAutoSampler_setSampleRate (tAutoSampler* const as, float sr)
+{
+    _tAutoSampler* a = *as;
+    tSampler_setSampleRate(&a->sampler, sr);
+}
 
 
 void tMBSampler_init(tMBSampler* const sp, tBuffer* const b, LEAF* const leaf)
@@ -1267,8 +1265,6 @@
     
     p->_p = 0.0f;
 }
-
-
 
 float tMBSampler_tick        (tMBSampler* const sp)
 {
--- a/leaf/Src/leaf.c
+++ b/leaf/Src/leaf.c
@@ -18,14 +18,12 @@
 
 #endif
 
-void LEAF_init(LEAF* const leaf, float sr, int blocksize, char* memory, size_t memorysize, float(*random)(void))
+void LEAF_init(LEAF* const leaf, float sr, char* memory, size_t memorysize, float(*random)(void))
 {
     leaf->_internal_mempool.leaf = leaf;
     leaf_pool_init(leaf, memory, memorysize);
     
     leaf->sampleRate = sr;
-
-    leaf->blockSize = blocksize;
     
     leaf->invSampleRate = 1.0f/sr;
     
@@ -45,13 +43,11 @@
     leaf->freeCount = 0;
 }
 
-
-#define LEAFSampleRateChanged(THIS) leaf.THIS.sampleRateChanged(&leaf.THIS)
-
 void LEAF_setSampleRate(LEAF* const leaf, float sampleRate)
 {
     leaf->sampleRate = sampleRate;
     leaf->invSampleRate = 1.0f/sampleRate;
+    leaf->twoPiTimesInvSampleRate = leaf->invSampleRate * TWO_PI;
 }
 
 float LEAF_getSampleRate(LEAF* const leaf)
--- a/leaf/leaf.h
+++ b/leaf/leaf.h
@@ -142,13 +142,12 @@
     
     //! Initialize the LEAF instance.
     /*!
-     @param sampleRate The audio sample rate.
-     @param blockSize The audio block size.
+     @param sampleRate The default sample rate for object initialized to this LEAF instance.
      @param memory A pointer to the memory that will make up the default mempool of a LEAF instance.
      @param memorySize The size of the memory that will make up the default mempool of a LEAF instance.
      @param random A pointer to a random number function. Should return a float >= 0 and < 1.
      */
-    void        LEAF_init            (LEAF* const leaf, float sampleRate, int blockSize, char* memory, size_t memorySize, float(*random)(void));
+    void        LEAF_init            (LEAF* const leaf, float sampleRate, char* memory, size_t memorySize, float(*random)(void));
     
     //! Set the sample rate of LEAF.
     /*!