shithub: leaf

Download patch

ref: 11c878ea38a1b2ddb79d93db875f2af0d7c8c03b
parent: 1743088c2b89a80644dd680f355dab505f239871
author: Matthew Wang <mjw7@princeton.edu>
date: Wed Nov 4 13:10:01 EST 2020

getting new pitch detection working in retune and autotune

--- a/TestPlugin/Source/LEAFLink.cpp
+++ b/TestPlugin/Source/LEAFLink.cpp
@@ -20,9 +20,9 @@
 
 std::vector<juce::String> cSliderNames =  std::vector<juce::String>
 {
-    "on/off",
-    "mod freq",
-    "mod depth"
+    "slider1",
+    "slider2",
+    "slider3"
 };
 
 std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
--- a/TestPlugin/Source/MyTest.cpp
+++ b/TestPlugin/Source/MyTest.cpp
@@ -18,7 +18,8 @@
 tMBTriangle btri;
 tMBPulse bpulse;
 
-tDualPitchDetector detector;
+tRetune retune;
+tAutotune autotune;
 
 tCompressor compressor;
 
@@ -54,33 +55,8 @@
 {
     LEAF_init(&leaf, sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
     
-    tMBSaw_init(&bsaw, &leaf);
-    tMBTriangle_init(&btri, &leaf);
-    tMBPulse_init(&bpulse, &leaf);
-    
-    bufIn = (float*) leaf_alloc(&leaf, sizeof(float) * 4096);
-    bufOut = (float*) leaf_alloc(&leaf, sizeof(float) * 4096);
-    
-    tDualPitchDetector_init(&detector, mtof(48), mtof(84), &leaf);
-    
-    tCompressor_init(&compressor, &leaf);
-    
-    tSVF_init(&lp, SVFTypeLowpass, mtof(84) * 2.0f, 1.0f, &leaf);
-    tSVF_init(&hp, SVFTypeHighpass, mtof(48) * 0.5f, 1.0f, &leaf);
-    
-    tPeriodDetection_init(&pd, bufIn, bufOut, 4096, 1024, &leaf);
-    
-    tZeroCrossingCounter_init(&zc, 128, &leaf);
-    tEnvelopeFollower_init(&ef, 0.02f, 0.9999f, &leaf);
-    
-    tTriangle_init(&tri, &leaf);
-    tTriangle_setFreq(&tri, 100);
-    
-    tBuffer_init(&samp, 5.0f * leaf.sampleRate, &leaf);
-    tMBSampler_init(&sampler, &samp, &leaf);
-    
-    tMBSampler_setMode(&sampler, PlayLoop);
-    tMBSampler_setEnd(&sampler, samp->bufferLength);
+    tRetune_init(&retune, 1, 1024, &leaf);
+    tAutotune_init(&autotune, 1, 1024, &leaf);
 }
 
 inline double getSawFall(double angle) {
@@ -94,38 +70,8 @@
 
 float   LEAFTest_tick            (float input)
 {
-    tBuffer_tick(&samp, input);
-
-    return tMBSampler_tick(&sampler);
-    
-    
-//    tMBSaw_setFreq(&bsaw, x);
-//    tMBTriangle_setFreq(&btri, x);
-//    tMBPulse_setFreq(&bpulse, x);
-//
-//    tMBTriangle_setWidth(&btri, y);
-//    tMBPulse_setWidth(&bpulse, y);
-//
-////    return tMBSaw_tick(&bsaw);
-////    return tMBTriangle_tick(&btri);
-//    return tMBPulse_tick(&bpulse);
-    
-//    input = tSVF_tick(&hp, tSVF_tick(&lp, tCompressor_tick(&compressor, input)));
-//    
-////    float freq = 1.0f/tPeriodDetection_tick(&pd, input) * leaf.sampleRate;
-//    tDualPitchDetector_tick(&detector, input);
-//    float altFreq = tDualPitchDetector_getFrequency(&detector);
-//
-////    if (fabsf(1.0f - (freq / altFreq)) < 0.05f)
-////    if (tZeroCrossingCounter_tick(&zc, input) < 0.05 && freq > 0.0f)
-//    if (altFreq > 0.0f)
-//    {
-//        tTriangle_setFreq(&tri, altFreq);
-//    }
-//
-//    float g = tEnvelopeFollower_tick(&ef, input);
-//
-//    return tTriangle_tick(&tri) * g;
+//    return tRetune_tick(&retune, input);
+    return tAutotune_tick(&autotune, input);
 }
 
 int firstFrame = 1;
@@ -132,34 +78,16 @@
 bool lastState = false, lastPlayState = false;
 void    LEAFTest_block           (void)
 {
-    float periodicity = tDualPitchDetector_getPeriodicity(&detector);
-    if (periodicity > 0.99f)
-    {
-        DBG(tDualPitchDetector_getFrequency(&detector));
-        DBG(tDualPitchDetector_getPeriodicity(&detector));
-    }
-    
-    float val = getSliderValue("on/off");
-    
-    if (val > 0.5f && !sampler->active)
-    {
-        tBuffer_record(&samp);
-        tMBSampler_play(&sampler);
-    }
-    else if (val < 0.5f && sampler->active)
-    {
-        tMBSampler_stop(&sampler);
-    }
-    
-    val = getSliderValue("mod freq");
-    
-    tMBSampler_setStart(&sampler, val * 5.0f * leaf.sampleRate);
+    float val = getSliderValue("slider1");
+//    tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 0);
+    tAutotune_setFreq(&autotune, 300, 0);
 
+    val = getSliderValue("slider2");
+//    tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 1);
     
-    val = getSliderValue("mod depth");
-    
-    tMBSampler_setRate(&sampler, val * 8.0f - 4.0f);
-    
+    val = getSliderValue("slider3");
+//    tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 2);
+        
 }
 
 void    LEAFTest_controllerInput (int cnum, float cval)
--- a/leaf/Inc/leaf-analysis.h
+++ b/leaf/Inc/leaf-analysis.h
@@ -497,7 +497,7 @@
 #define DEFHOPSIZE 64
 #define DEFWINDOWSIZE 64
 #define FBA 20
-#define HPFREQ 40.0f
+#define HPFREQ 20.0f
     
     typedef struct _tPeriodDetection
     {
@@ -769,7 +769,6 @@
 
     typedef struct _tPeriodDetector
     {
-        
         tMempool mempool;
         
         tZeroCrossingCollector          _zc;
--- a/leaf/Inc/leaf-effects.h
+++ b/leaf/Inc/leaf-effects.h
@@ -510,38 +510,27 @@
     
     typedef struct _tPitchShift
     {
-        
         tMempool mempool;
         
+        _tDualPitchDetector* pd;
+        
         tSOLAD sola;
         tHighpass hp;
-        tPeriodDetection* p;
-        tDualPitchDetector dp;
         
         float* outBuffer;
-        int frameSize;
+        float* inBuffer;
         int bufSize;
-        
-        int framesPerBuffer;
-        int curBlock;
-        int lastBlock;
         int index;
-        
-        float pitchFactor;
-        float timeConstant;
-        float radius;
     } _tPitchShift;
     
     typedef _tPitchShift* tPitchShift;
     
-    void    tPitchShift_init            (tPitchShift* const, tPeriodDetection* const, tDualPitchDetector* const, float* out, int bufSize, LEAF* const leaf);
-    void    tPitchShift_initToPool      (tPitchShift* const, tPeriodDetection* const, tDualPitchDetector* const, float* out, int bufSize, tMempool* const);
-    void    tPitchShift_free            (tPitchShift* const);
+    void    tPitchShift_init (tPitchShift* const, tDualPitchDetector* const, LEAF* const leaf);
+    void    tPitchShift_initToPool (tPitchShift* const, tDualPitchDetector* const, tMempool* const);
+    void    tPitchShift_free (tPitchShift* const);
     
-    float   tPitchShift_shift           (tPitchShift* const);
-    float   tPitchShift_shiftToFunc     (tPitchShift* const, float (*fun)(float));
-    float   tPitchShift_shiftToFreq     (tPitchShift* const, float freq);
-    void    tPitchShift_setPitchFactor  (tPitchShift* const, float pf);
+    void    tPitchShift_shiftBy (tPitchShift* const, float factor, float* in, float* out, int bufSize);
+    void    tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out, int bufSize);
     
     /*!
      @defgroup tretune tRetune
@@ -577,35 +566,10 @@
      @brief
      @param
      
-     @fn void    tRetune_setTimeConstant     (tRetune* const, float tc)
-     @brief
-     @param
-     
-     @fn void    tRetune_setHopSize          (tRetune* const, int hs)
-     @brief
-     @param
-     
-     @fn void    tRetune_setWindowSize       (tRetune* const, int ws)
-     @brief
-     @param
-     
-     @fn void    tRetune_setFidelityThreshold(tRetune* const, float threshold)
-     @brief
-     @param
-     
-     @fn float   tRetune_getInputPeriod      (tRetune* const)
-     @brief
-     @param
-     
-     @fn float   tRetune_getInputFreq        (tRetune* const)
-     @brief
-     @param
-     
      @} */
     
     typedef struct _tRetune
     {
-        
         tMempool mempool;
         
         tDualPitchDetector dp;
@@ -613,40 +577,25 @@
         tPitchShift* ps;
         
         float* inBuffer;
-        float** outBuffers;
-        float* tickOutput;
-        int frameSize;
+        float* outBuffer;
+        float* lastOutBuffer;
         int bufSize;
+        int index;
         
-        uint16_t hopSize;
-        uint16_t windowSize;
-        uint8_t fba;
-        
-        float* pitchFactor;
-        float timeConstant;
-        float radius;
-        
-        float inputPeriod;
-        
+        float* pitchFactors;
         int numVoices;
     } _tRetune;
     
     typedef _tRetune* tRetune;
     
-    void    tRetune_init                (tRetune* const, int numVoices, int bufSize, int frameSize, LEAF* const leaf);
-    void    tRetune_initToPool          (tRetune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+    void    tRetune_init                (tRetune* const, int numVoices, int bufSize, LEAF* const leaf);
+    void    tRetune_initToPool          (tRetune* const, int numVoices, int bufSize, tMempool* const);
     void    tRetune_free                (tRetune* const);
     
-    float*  tRetune_tick                (tRetune* const, float sample);
+    float   tRetune_tick                (tRetune* const, float sample);
     void    tRetune_setNumVoices        (tRetune* const, int numVoices);
     void    tRetune_setPitchFactors     (tRetune* const, float pf);
     void    tRetune_setPitchFactor      (tRetune* const, float pf, int voice);
-    void    tRetune_setTimeConstant     (tRetune* const, float tc);
-    void    tRetune_setHopSize          (tRetune* const, int hs);
-    void    tRetune_setWindowSize       (tRetune* const, int ws);
-    void    tRetune_setFidelityThreshold(tRetune* const, float threshold);
-    float   tRetune_getInputPeriod      (tRetune* const);
-    float   tRetune_getInputFreq        (tRetune* const);
     
     /*!
      @defgroup tautotune tAutotune
@@ -718,7 +667,6 @@
     
     typedef struct _tAutotune
     {
-        
         tMempool mempool;
         
         tDualPitchDetector dp;
@@ -726,42 +674,25 @@
         tPitchShift* ps;
         
         float* inBuffer;
-        float** outBuffers;
-        float* tickOutput;
-        int frameSize;
+        float* outBuffer;
+        float* lastOutBuffer;
         int bufSize;
+        int index;
         
-        uint16_t hopSize;
-        uint16_t windowSize;
-        uint8_t fba;
-        
-        float* freq;
-        float timeConstant;
-        float radius;
-        
-        float inputPeriod;
-        int shiftOn;
+        float* freqs;
         int numVoices;
     } _tAutotune;
     
     typedef _tAutotune* tAutotune;
     
-    void    tAutotune_init                  (tAutotune* const, int numVoices, int bufSize, int frameSize, LEAF* const leaf);
-    void    tAutotune_initToPool            (tAutotune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+    void    tAutotune_init                  (tAutotune* const, int numVoices, int bufSize, LEAF* const leaf);
+    void    tAutotune_initToPool            (tAutotune* const, int numVoices, int bufSize, tMempool* const);
     void    tAutotune_free                  (tAutotune* const);
     
-    float*  tAutotune_tick                  (tAutotune* const, float sample);
+    float   tAutotune_tick                  (tAutotune* const, float sample);
     void    tAutotune_setNumVoices          (tAutotune* const, int numVoices);
     void    tAutotune_setFreqs              (tAutotune* const, float f);
     void    tAutotune_setFreq               (tAutotune* const, float f, int voice);
-    void    tAutotune_setTimeConstant       (tAutotune* const, float tc);
-    void    tAutotune_setHopSize            (tAutotune* const, int hs);
-    void    tAutotune_setWindowSize         (tAutotune* const, int ws);
-    void    tAutotune_setFidelityThreshold  (tAutotune* const, float threshold);
-    void    tAutotune_setAlpha              (tAutotune* const, float alpha);
-    void    tAutotune_setTolerance          (tAutotune* const, float tolerance);
-    float   tAutotune_getInputPeriod        (tAutotune* const);
-    float   tAutotune_getInputFreq          (tAutotune* const);
     
     //==============================================================================
     
--- a/leaf/Inc/leaf-math.h
+++ b/leaf/Inc/leaf-math.h
@@ -190,6 +190,8 @@
     double fasterexp(double x);
 
     float fasterexpf(float x);
+    
+    float fastsqrtf(float x);
 
     float mtof(float f);
     
--- a/leaf/Src/leaf-effects.c
+++ b/leaf/Src/leaf-effects.c
@@ -1010,7 +1010,6 @@
 /***************** static function declarations *******************************/
 /******************************************************************************/
 
-static void solad_init(_tSOLAD *w);
 static inline float read_sample(_tSOLAD *w, float floatindex);
 static void pitchdown(_tSOLAD *w, float *out);
 static void pitchup(_tSOLAD *w, float *out);
@@ -1032,9 +1031,13 @@
     w->mempool = m;
     
     w->pitchfactor = 1.;
-    w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);
+    w->delaybuf = (float*) mpool_calloc(sizeof(float) * LOOPSIZE, m);
 
-    solad_init(w);
+    w->timeindex = 0;
+    w->xfadevalue = -1;
+    w->period = INITPERIOD;
+    w->readlag = INITPERIOD;
+    w->blocksize = INITPERIOD;
 }
 
 void tSOLAD_free (tSOLAD* const wp)
@@ -1077,7 +1080,10 @@
 {
     _tSOLAD* w = *wp;
     
-    if (pitchfactor <= 0.0f) return;
+    if (pitchfactor <= 0.0f || pitchfactor > 1000.0f)
+    {
+        return;
+    }
     w->pitchfactor = pitchfactor;
 }
 
@@ -1101,11 +1107,16 @@
 {
     _tSOLAD* w = *wp;
     
-    int n = LOOPSIZE + 1;
+    int n = LOOPSIZE;
     float *buf = w->delaybuf;
     
     while(n--) *buf++ = 0;
-    solad_init(w);
+    
+    w->timeindex = 0;
+    w->xfadevalue = -1;
+    w->period = INITPERIOD;
+    w->readlag = INITPERIOD;
+    w->blocksize = INITPERIOD;
 }
 
 /******************************************************************************/
@@ -1182,7 +1193,7 @@
             xfadevalue -= xfadestep;
         }
         
-        *out++ = outputsample;
+        *out++ += outputsample;
         refindex += 1;
         readlag += readlagstep;
     }
@@ -1312,7 +1323,7 @@
             xfadevalue -= xfadestep;
         }
         
-        *out++ = outputsample;
+        *out++ += outputsample;
         refindex += 1;
         readlag -= readlagstep;
     }
@@ -1334,15 +1345,6 @@
     return (buf[index] + (fraction * (buf[index+1] - buf[index])));
 }
 
-static void solad_init(_tSOLAD* const w)
-{
-    w->timeindex = 0;
-    w->xfadevalue = -1;
-    w->period = INITPERIOD;
-    w->readlag = INITPERIOD;
-    w->blocksize = INITPERIOD;
-}
-
 //============================================================================================================
 // PITCHSHIFT
 //============================================================================================================
@@ -1349,62 +1351,49 @@
 
 static int pitchshift_attackdetect(_tPitchShift* ps)
 {
-    float envout;
-    
-    _tPeriodDetection* p = *ps->p;
-    
-    envout = tEnvPD_tick(&p->env);
-    
-    if (envout >= 1.0f)
-    {
-        p->lastmax = p->max;
-        if (envout > p->max)
-        {
-            p->max = envout;
-        }
-        else
-        {
-            p->deltamax = envout - p->max;
-            p->max = p->max * ps->radius;
-        }
-        p->deltamax = p->max - p->lastmax;
-    }
-    
-    p->fba = p->fba ? (p->fba - 1) : 0;
-    
-    return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
+//    float envout;
+//
+//    _tPeriodDetection* p = *ps->p;
+//
+//    envout = tEnvPD_tick(&p->env);
+//
+//    if (envout >= 1.0f)
+//    {
+//        p->lastmax = p->max;
+//        if (envout > p->max)
+//        {
+//            p->max = envout;
+//        }
+//        else
+//        {
+//            p->deltamax = envout - p->max;
+//            p->max = p->max * ps->radius;
+//        }
+//        p->deltamax = p->max - p->lastmax;
+//    }
+//
+//    p->fba = p->fba ? (p->fba - 1) : 0;
+//
+//    return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
 }
 
-void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* const pd, tDualPitchDetector* const dp, float* out, int bufSize, LEAF* const leaf)
+void tPitchShift_init (tPitchShift* const psr, tDualPitchDetector* const dpd, LEAF* const leaf)
 {
-    tPitchShift_initToPool(psr, pd, dp, out, bufSize, &leaf->mempool);
+    tPitchShift_initToPool(psr, dpd, &leaf->mempool);
 }
 
-void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, tDualPitchDetector* const dp, float* out, int bufSize, tMempool* const mp)
+void tPitchShift_initToPool (tPitchShift* const psr, tDualPitchDetector* const dpd, tMempool* const mp)
 {
     _tMempool* m = *mp;
     _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);
     ps->mempool = m;
     
-    _tPeriodDetection* p = *pd;
+    ps->pd = *dpd;
     
-    ps->p = pd;
-    
-    ps->outBuffer = out;
-    ps->bufSize = bufSize;
-    ps->frameSize = p->frameSize;
-    ps->framesPerBuffer = ps->bufSize / ps->frameSize;
-    ps->curBlock = 1;
-    ps->lastBlock = 0;
-    ps->index = 0;
-    ps->pitchFactor = 1.0f;
-    ps->dp = *dp;
-    
     tSOLAD_initToPool(&ps->sola, mp);
+    tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
     
     tHighpass_initToPool(&ps->hp, HPFREQ, mp);
-    
-    tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
 }
 
 void tPitchShift_free (tPitchShift* const psr)
@@ -1416,135 +1405,41 @@
     mpool_free((char*)ps, ps->mempool);
 }
 
-void tPitchShift_setPitchFactor(tPitchShift* psr, float pf)
+void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out, int bufSize)
 {
     _tPitchShift* ps = *psr;
+    LEAF* leaf = ps->mempool->leaf;
     
-    ps->pitchFactor = pf;
-}
-
-float tPitchShift_shift (tPitchShift* psr)
-{
-    _tPitchShift* ps = *psr;
-    _tPeriodDetection* p = *ps->p;
+    float period = leaf->sampleRate / tDualPitchDetector_getFrequency(&ps->pd);
+    tSOLAD_setPeriod(&ps->sola, period);
+    tSOLAD_setPitchFactor(&ps->sola, factor);
     
-    float period, out;
-    int i, iLast;
-    
-    i = p->i;
-    iLast = p->iLast;
-    
-    out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-
-    if (p->indexstore >= ps->frameSize)
-    {
-//        period = tPeriodDetection_getPeriod(&p);
-        period = 1.0f / tDualPitchDetector_getFrequency(&ps->dp);
-        
-        if(pitchshift_attackdetect(ps) == 1)
-        {
-            p->fba = 5;
-            tSOLAD_setReadLag(&ps->sola, p->windowSize);
-        }
-        
-        tSOLAD_setPeriod(&ps->sola, period);
-        tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-        
-        tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
-    }
-    
-    return out;
+    tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
 }
 
-float tPitchShift_shiftToFreq (tPitchShift* psr, float freq)
+void    tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out, int bufSize)
 {
     _tPitchShift* ps = *psr;
-    _tPeriodDetection* p = *ps->p;
     LEAF* leaf = ps->mempool->leaf;
     
-    float period = 0;
-    float out;
-    int i, iLast;
+    float period = 1.0f / tDualPitchDetector_getFrequency(&ps->pd);
+    float factor = freq * period;
+    tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);
+    tSOLAD_setPitchFactor(&ps->sola, factor);
     
-    i = p->i;
-    iLast = p->iLast;
-    
-    out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-    
-    if (p->indexstore >= ps->frameSize)
-    {
-//        period = tPeriodDetection_getPeriod(&p);
-        float f = tDualPitchDetector_getFrequency(&ps->dp);
-        if (f > 0) period = 1.0f / f;
-        
-        if(pitchshift_attackdetect(ps) == 1)
-        {
-            p->fba = 5;
-            tSOLAD_setReadLag(&ps->sola, p->windowSize);
-        }
-        
-        tSOLAD_setPeriod(&ps->sola, period * leaf->sampleRate);
-        
-        if (period != 0) ps->pitchFactor = freq * period;
-        else ps->pitchFactor = 1.0f;
-        
-        tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-        
-        tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
-    }
-    return out;
+    tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
 }
 
-float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float))
-{
-    _tPitchShift* ps = *psr;
-    _tPeriodDetection* p = *ps->p;
-    
-    float period, out;
-    int i, iLast;
-    
-    i = p->i;
-    iLast = p->iLast;
-    
-    out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-    
-    if (p->indexstore >= ps->frameSize)
-    {
-//        period = tPeriodDetection_getPeriod(&p);
-        period = 1.0f / tDualPitchDetector_getFrequency(&ps->dp);
-        
-        if(pitchshift_attackdetect(ps) == 1)
-        {
-            p->fba = 5;
-            tSOLAD_setReadLag(&ps->sola, p->windowSize);
-        }
-        
-        tSOLAD_setPeriod(&ps->sola, period);
-        
-        ps->pitchFactor = period/fun(period);
-        tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-        
-        tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
-        
-        ps->curBlock++;
-        if (ps->curBlock >= p->framesPerBuffer) ps->curBlock = 0;
-        ps->lastBlock++;
-        if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
-    }
-    
-    return out;
-}
-
 //============================================================================================================
 // RETUNE
 //============================================================================================================
 
-void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize, LEAF* const leaf)
+void tRetune_init(tRetune* const rt, int numVoices, int bufSize, LEAF* const leaf)
 {
-    tRetune_initToPool(rt, numVoices, bufSize, frameSize, &leaf->mempool);
+    tRetune_initToPool(rt, numVoices, bufSize, &leaf->mempool);
 }
 
-void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
+void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, tMempool* const mp)
 {
     _tMempool* m = *mp;
     _tRetune* r = *rt = (_tRetune*) mpool_alloc(sizeof(_tRetune), m);
@@ -1551,33 +1446,22 @@
     r->mempool = *mp;
     
     r->bufSize = bufSize;
-    r->frameSize = frameSize;
     r->numVoices = numVoices;
     
     r->inBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
-    r->outBuffers = (float**) mpool_calloc(sizeof(float*) * r->numVoices, m);
+    r->outBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
+    r->lastOutBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
     
-    r->hopSize = DEFHOPSIZE;
-    r->windowSize = DEFWINDOWSIZE;
-    r->fba = FBA;
-    tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
-    
-    r->inputPeriod = 0.0f;
+    r->index = 0;
 
     r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
-    r->pitchFactor = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
-    r->tickOutput = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
-    for (int i = 0; i < r->numVoices; ++i)
-    {
-        r->outBuffers[i] = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
-    }
+    r->pitchFactors = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
     
     tDualPitchDetector_initToPool(&r->dp, mtof(48), mtof(72), mp);
-    tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
 
     for (int i = 0; i < r->numVoices; ++i)
     {
-        tPitchShift_initToPool(&r->ps[i], &r->pd, &r->dp, r->outBuffers[i], r->bufSize, mp);
+        tPitchShift_initToPool(&r->ps[i], &r->dp, mp);
     }
 }
 
@@ -1590,30 +1474,34 @@
     for (int i = 0; i < r->numVoices; ++i)
     {
         tPitchShift_free(&r->ps[i]);
-        mpool_free((char*)r->outBuffers[i], r->mempool);
     }
-    mpool_free((char*)r->tickOutput, r->mempool);
-    mpool_free((char*)r->pitchFactor, r->mempool);
+    mpool_free((char*)r->pitchFactors, r->mempool);
     mpool_free((char*)r->ps, r->mempool);
     mpool_free((char*)r->inBuffer, r->mempool);
-    mpool_free((char*)r->outBuffers, r->mempool);
+    mpool_free((char*)r->outBuffer, r->mempool);
     mpool_free((char*)r, r->mempool);
 }
 
-float* tRetune_tick(tRetune* const rt, float sample)
+float tRetune_tick(tRetune* const rt, float sample)
 {
     _tRetune* r = *rt;
     
-    tPeriodDetection_tick(&r->pd, sample);
     tDualPitchDetector_tick(&r->dp, sample);
-    r->inputPeriod = 1.0f / tDualPitchDetector_getFrequency(&r->dp);
     
-    for (int v = 0; v < r->numVoices; ++v)
+    r->inBuffer[r->index] = sample;
+    float out = r->outBuffer[r->index];
+    r->outBuffer[r->index++] = 0.0f;
+    
+    if (r->index >= r->bufSize)
     {
-        r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
+        for (int i = 0; i < r->numVoices; ++i)
+        {
+            tPitchShift_shiftBy(&r->ps[i], r->pitchFactors[i], r->inBuffer, r->outBuffer, r->bufSize);
+        }
+        r->index = 0;
     }
     
-    return r->tickOutput;
+    return out;
 }
 
 void tRetune_setNumVoices(tRetune* const rt, int numVoices)
@@ -1621,11 +1509,10 @@
     _tRetune* r = *rt;
     
     int bufSize = r->bufSize;
-    int frameSize = r->frameSize;
     tMempool mempool = r->mempool;
     
     tRetune_free(rt);
-    tRetune_initToPool(rt, numVoices, bufSize, frameSize, &mempool);
+    tRetune_initToPool(rt, numVoices, bufSize, &mempool);
 }
 
 void tRetune_setPitchFactors(tRetune* const rt, float pf)
@@ -1634,8 +1521,7 @@
     
     for (int i = 0; i < r->numVoices; ++i)
     {
-        r->pitchFactor[i] = pf;
-        tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
+        r->pitchFactors[i] = pf;
     }
 }
 
@@ -1643,68 +1529,19 @@
 {
     _tRetune* r = *rt;
     
-    r->pitchFactor[voice] = pf;
-    tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
+    r->pitchFactors[voice] = pf;
 }
 
-void tRetune_setTimeConstant(tRetune* const rt, float tc)
-{
-    _tRetune* r = *rt;
-    LEAF* leaf = r->mempool->leaf;
-    
-    r->timeConstant = tc;
-    r->radius = expf(-1000.0f * r->hopSize * leaf->invSampleRate / r->timeConstant);
-}
-
-void tRetune_setHopSize(tRetune* const rt, int hs)
-{
-    _tRetune* r = *rt;
-    
-    r->hopSize = hs;
-    tPeriodDetection_setHopSize(&r->pd, r->hopSize);
-}
-
-void tRetune_setWindowSize(tRetune* const rt, int ws)
-{
-    _tRetune* r = *rt;
-    
-    r->windowSize = ws;
-    tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
-}
-
-void tRetune_setFidelityThreshold(tRetune* const rt, float threshold)
-{
-    _tRetune* r = *rt;
-    
-    tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
-}
-
-float tRetune_getInputPeriod(tRetune* const rt)
-{
-    _tRetune* r = *rt;
-    LEAF* leaf = r->mempool->leaf;
-
-    return (r->inputPeriod * leaf->invSampleRate);
-}
-
-float tRetune_getInputFreq(tRetune* const rt)
-{
-    _tRetune* r = *rt;
-    LEAF* leaf = r->mempool->leaf;
-    
-    return 1.0f/(r->inputPeriod * leaf->invSampleRate);
-}
-
 //============================================================================================================
 // AUTOTUNE
 //============================================================================================================
 
-void tAutotune_init (tAutotune* const rt, int numVoices, int bufSize, int frameSize, LEAF* const leaf)
+void tAutotune_init (tAutotune* const rt, int numVoices, int bufSize, LEAF* const leaf)
 {
-    tAutotune_initToPool(rt, numVoices, bufSize, frameSize, &leaf->mempool);
+    tAutotune_initToPool(rt, numVoices, bufSize, &leaf->mempool);
 }
 
-void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
+void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, tMempool* const mp)
 {
     _tMempool* m = *mp;
     _tAutotune* r = *rt = (_tAutotune*) mpool_alloc(sizeof(_tAutotune), m);
@@ -1711,35 +1548,23 @@
     r->mempool = *mp;
     
     r->bufSize = bufSize;
-    r->frameSize = frameSize;
     r->numVoices = numVoices;
     
-    r->inBuffer = (float*) mpool_alloc(sizeof(float) * r->bufSize, m);
-    r->outBuffers = (float**) mpool_alloc(sizeof(float*) * r->numVoices, m);
+    r->inBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
+    r->outBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
+    r->lastOutBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
     
-    r->hopSize = DEFHOPSIZE;
-    r->windowSize = DEFWINDOWSIZE;
-    r->fba = FBA;
-    tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
+    r->index = 0;
     
-    r->ps = (tPitchShift*) mpool_alloc(sizeof(tPitchShift) * r->numVoices, m);
-    r->freq = (float*) mpool_alloc(sizeof(float) * r->numVoices, m);
-    r->tickOutput = (float*) mpool_alloc(sizeof(float) * r->numVoices, m);
-    for (int i = 0; i < r->numVoices; ++i)
-    {
-        r->outBuffers[i] = (float*) mpool_alloc(sizeof(float) * r->bufSize, m);
-    }
+    r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
+    r->freqs = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
     
     tDualPitchDetector_initToPool(&r->dp, mtof(48), mtof(72), mp);
-    tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
-
+    
     for (int i = 0; i < r->numVoices; ++i)
     {
-        tPitchShift_initToPool(&r->ps[i], &r->pd, &r->dp, r->outBuffers[i], r->bufSize, mp);
+        tPitchShift_initToPool(&r->ps[i], &r->dp, mp);
     }
-    
-    r->inputPeriod = 0.0f;
-    r->shiftOn = 0;
 }
 
 void tAutotune_free (tAutotune* const rt)
@@ -1746,39 +1571,39 @@
 {
     _tAutotune* r = *rt;
     
+    tDualPitchDetector_free(&r->dp);
     tPeriodDetection_free(&r->pd);
     for (int i = 0; i < r->numVoices; ++i)
     {
         tPitchShift_free(&r->ps[i]);
-        mpool_free((char*)r->outBuffers[i], r->mempool);
     }
-    mpool_free((char*)r->tickOutput, r->mempool);
-    mpool_free((char*)r->freq, r->mempool);
+    mpool_free((char*)r->freqs, r->mempool);
     mpool_free((char*)r->ps, r->mempool);
     mpool_free((char*)r->inBuffer, r->mempool);
-    mpool_free((char*)r->outBuffers, r->mempool);
+    mpool_free((char*)r->outBuffer, r->mempool);
     mpool_free((char*)r, r->mempool);
 }
 
-float* tAutotune_tick(tAutotune* const rt, float sample)
+float tAutotune_tick(tAutotune* const rt, float sample)
 {
     _tAutotune* r = *rt;
     
-    tPeriodDetection_tick(&r->pd, sample);
     tDualPitchDetector_tick(&r->dp, sample);
-    r->inputPeriod = 1.0f / tDualPitchDetector_getFrequency(&r->dp);
     
-//    if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
-//    {
-//        r->inputPeriod = tempPeriod;
-//    }
-
-    for (int v = 0; v < r->numVoices; ++v)
+    r->inBuffer[r->index] = sample;
+    float out = r->outBuffer[r->index];
+    r->outBuffer[r->index++] = 0.0f;
+    
+    if (r->index >= r->bufSize)
     {
-        r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
+        for (int i = 0; i < r->numVoices; ++i)
+        {
+            tPitchShift_shiftTo(&r->ps[i], r->freqs[i], r->inBuffer, r->outBuffer, r->bufSize);
+        }
+        r->index = 0;
     }
-
-    return r->tickOutput;
+    
+    return out;
 }
 
 void tAutotune_setNumVoices(tAutotune* const rt, int numVoices)
@@ -1786,11 +1611,10 @@
     _tAutotune* r = *rt;
     
     int bufSize = r->bufSize;
-    int frameSize = r->frameSize;
     tMempool mempool = r->mempool;
     
     tAutotune_free(rt);
-    tAutotune_initToPool(rt, numVoices, bufSize, frameSize, &mempool);
+    tAutotune_initToPool(rt, numVoices, bufSize, &mempool);
 }
 
 void tAutotune_setFreqs(tAutotune* const rt, float f)
@@ -1799,7 +1623,7 @@
     
     for (int i = 0; i < r->numVoices; ++i)
     {
-        r->freq[i] = f;
+        r->freqs[i] = f;
     }
 }
 
@@ -1807,65 +1631,7 @@
 {
     _tAutotune* r = *rt;
     
-    r->freq[voice] = f;
-}
-
-void tAutotune_setTimeConstant(tAutotune* const rt, float tc)
-{
-    _tAutotune* r = *rt;
-    LEAF* leaf = r->mempool->leaf;
-    
-    r->timeConstant = tc;
-    r->radius = expf(-1000.0f * r->hopSize * leaf->invSampleRate / r->timeConstant);
-}
-
-void tAutotune_setHopSize(tAutotune* const rt, int hs)
-{
-    _tAutotune* r = *rt;
-    
-    r->hopSize = hs;
-    tPeriodDetection_setHopSize(&r->pd, r->hopSize);
-}
-
-void tAutotune_setWindowSize(tAutotune* const rt, int ws)
-{
-    _tAutotune* r = *rt;
-    
-    r->windowSize = ws;
-    tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
-}
-
-void tAutotune_setFidelityThreshold(tAutotune* const rt, float threshold)
-{
-    _tAutotune* r = *rt;
-
-    tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
-}
-
-void     tAutotune_setAlpha                (tAutotune* rt, float alpha)
-{
-    _tAutotune* r = *rt;
-    tPeriodDetection_setAlpha(&r->pd, alpha);
-}
-
-void     tAutotune_setTolerance            (tAutotune* rt, float tolerance)
-{
-    _tAutotune* r = *rt;
-    tPeriodDetection_setTolerance(&r->pd, tolerance);
-}
-
-float tAutotune_getInputPeriod(tAutotune* const rt)
-{
-    _tAutotune* r = *rt;
-    
-    return r->inputPeriod;
-}
-
-float tAutotune_getInputFreq(tAutotune* const rt)
-{
-    _tAutotune* r = *rt;
-    
-    return 1.0f/r->inputPeriod;
+    r->freqs[voice] = f;
 }
 
 //============================================================================================================