shithub: leaf

Download patch

ref: c6f34c374aac46d33bf9b9abc2e556033aa9194a
parent: 11c878ea38a1b2ddb79d93db875f2af0d7c8c03b
author: Matthew Wang <mjw7@princeton.edu>
date: Thu Nov 5 10:57:34 EST 2020

add highpass and transient detection from old pitchshift into solad

--- a/TestPlugin/Source/MyTest.cpp
+++ b/TestPlugin/Source/MyTest.cpp
@@ -55,8 +55,8 @@
 {
     LEAF_init(&leaf, sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
     
-    tRetune_init(&retune, 1, 1024, &leaf);
-    tAutotune_init(&autotune, 1, 1024, &leaf);
+    tRetune_init(&retune, 1, mtof(48), mtof(72), 2048, &leaf);
+    tAutotune_init(&autotune, 1, mtof(48), mtof(72), 2048, &leaf);
 }
 
 inline double getSawFall(double angle) {
--- a/leaf/Inc/leaf-analysis.h
+++ b/leaf/Inc/leaf-analysis.h
@@ -492,7 +492,7 @@
      
      @} */
     
-#define DEFPITCHRATIO 2.0f
+#define DEFPITCHRATIO 1.0f
 #define DEFTIMECONSTANT 100.0f
 #define DEFHOPSIZE 64
 #define DEFWINDOWSIZE 64
--- a/leaf/Inc/leaf-effects.h
+++ b/leaf/Inc/leaf-effects.h
@@ -439,9 +439,11 @@
     
     typedef struct _tSOLAD
     {
-        
         tMempool mempool;
         
+        tAttackDetection ad;
+        tHighpass hp;
+        
         uint16_t timeindex;              // current reference time, write index
         uint16_t blocksize;              // signal input / output block size
         float pitchfactor;        // pitch factor between 0.25 and 4
@@ -513,9 +515,7 @@
         tMempool mempool;
         
         _tDualPitchDetector* pd;
-        
         tSOLAD sola;
-        tHighpass hp;
         
         float* outBuffer;
         float* inBuffer;
@@ -573,7 +573,8 @@
         tMempool mempool;
         
         tDualPitchDetector dp;
-        tPeriodDetection pd;
+        float minInputFreq, maxInputFreq;
+        
         tPitchShift* ps;
         
         float* inBuffer;
@@ -588,8 +589,8 @@
     
     typedef _tRetune* tRetune;
     
-    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_init                (tRetune* const, int numVoices, float minInputFreq, float maxInputFreq,  int bufSize, LEAF* const leaf);
+    void    tRetune_initToPool          (tRetune* const,  int numVoices, float minInputFreq, float maxInputFreq, int bufSize, tMempool* const);
     void    tRetune_free                (tRetune* const);
     
     float   tRetune_tick                (tRetune* const, float sample);
@@ -631,38 +632,6 @@
      @brief
      @param
      
-     @fn void    tAutotune_setTimeConstant       (tAutotune* const, float tc)
-     @brief
-     @param
-     
-     @fn void    tAutotune_setHopSize            (tAutotune* const, int hs)
-     @brief
-     @param
-     
-     @fn void    tAutotune_setWindowSize         (tAutotune* const, int ws)
-     @brief
-     @param
-     
-     @fn void    tAutotune_setFidelityThreshold  (tAutotune* const, float threshold)
-     @brief
-     @param
-     
-     @fn void    tAutotune_setAlpha              (tAutotune* const, float alpha)
-     @brief
-     @param
-     
-     @fn void    tAutotune_setTolerance          (tAutotune* const, float tolerance)
-     @brief
-     @param
-     
-     @fn float   tAutotune_getInputPeriod        (tAutotune* const)
-     @brief
-     @param
-     
-     @fn float   tAutotune_getInputFreq          (tAutotune* const)
-     @brief
-     @param
-     
      @} */
     
     typedef struct _tAutotune
@@ -670,7 +639,8 @@
         tMempool mempool;
         
         tDualPitchDetector dp;
-        tPeriodDetection pd;
+        float minInputFreq, maxInputFreq;
+        
         tPitchShift* ps;
         
         float* inBuffer;
@@ -685,8 +655,8 @@
     
     typedef _tAutotune* tAutotune;
     
-    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_init                  (tAutotune* const, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, LEAF* const leaf);
+    void    tAutotune_initToPool            (tAutotune* const, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, tMempool* const);
     void    tAutotune_free                  (tAutotune* const);
     
     float   tAutotune_tick                  (tAutotune* const, float sample);
--- a/leaf/Src/leaf-analysis.c
+++ b/leaf/Src/leaf-analysis.c
@@ -363,12 +363,7 @@
 {
     _tAttackDetection* a = *ad;
     
-    if(!((size==64)|(size==128)|(size==256)|(size==512)|(size==1024)|(size==2048)))
-        size = DEFBLOCKSIZE;
     a->blocksize = size;
-    
-    return;
-    
 }
 
 void tAttackDetection_setSamplerate(tAttackDetection* const ad, int inRate)
--- a/leaf/Src/leaf-effects.c
+++ b/leaf/Src/leaf-effects.c
@@ -1038,6 +1038,9 @@
     w->period = INITPERIOD;
     w->readlag = INITPERIOD;
     w->blocksize = INITPERIOD;
+    
+    tAttackDetection_initToPool(&w->ad, INITPERIOD, 2, 2, mp);
+    tHighpass_initToPool(&w->hp, 20.0f, mp);
 }
 
 void tSOLAD_free (tSOLAD* const wp)
@@ -1056,9 +1059,23 @@
     int i = w->timeindex;
     int n = w->blocksize = blocksize;
     
-    if(!i) w->delaybuf[LOOPSIZE] = in[0];   // copy one sample for interpolation
-    while(n--) w->delaybuf[i++] = *in++;    // copy one input block to delay buffer
+    if(!i)
+    {
+        float sample = tHighpass_tick(&w->hp, in[0]);
+        w->delaybuf[0] = sample;
+        w->delaybuf[LOOPSIZE] = sample;   // copy one sample for interpolation
+        n--;
+        i++;
+        in++;
+    }
+    while(n--) w->delaybuf[i++] = tHighpass_tick(&w->hp, *in++);    // copy one input block to delay buffer
     
+    tAttackDetection_setBlocksize(&w->ad, n);
+    if (tAttackDetection_detect(&w->ad, in))
+    {
+        tSOLAD_setReadLag(wp, w->blocksize);
+    }
+    
     if(w->pitchfactor > 1) pitchup(w, out);
     else pitchdown(w, out);
     
@@ -1349,34 +1366,6 @@
 // PITCHSHIFT
 //============================================================================================================
 
-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;
-}
-
 void tPitchShift_init (tPitchShift* const psr, tDualPitchDetector* const dpd, LEAF* const leaf)
 {
     tPitchShift_initToPool(psr, dpd, &leaf->mempool);
@@ -1392,8 +1381,6 @@
     
     tSOLAD_initToPool(&ps->sola, mp);
     tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
-    
-    tHighpass_initToPool(&ps->hp, HPFREQ, mp);
 }
 
 void tPitchShift_free (tPitchShift* const psr)
@@ -1401,7 +1388,6 @@
     _tPitchShift* ps = *psr;
     
     tSOLAD_free(&ps->sola);
-    tHighpass_free(&ps->hp);
     mpool_free((char*)ps, ps->mempool);
 }
 
@@ -1410,10 +1396,14 @@
     _tPitchShift* ps = *psr;
     LEAF* leaf = ps->mempool->leaf;
     
-    float period = leaf->sampleRate / tDualPitchDetector_getFrequency(&ps->pd);
-    tSOLAD_setPeriod(&ps->sola, period);
-    tSOLAD_setPitchFactor(&ps->sola, factor);
-    
+    float detected = tDualPitchDetector_getFrequency(&ps->pd);
+    if (detected > 0.0f)
+    {
+        float period = leaf->sampleRate / detected;
+        tSOLAD_setPeriod(&ps->sola, period);
+        tSOLAD_setPitchFactor(&ps->sola, factor);
+    }
+        
     tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
 }
 
@@ -1422,10 +1412,14 @@
     _tPitchShift* ps = *psr;
     LEAF* leaf = ps->mempool->leaf;
     
-    float period = 1.0f / tDualPitchDetector_getFrequency(&ps->pd);
-    float factor = freq * period;
-    tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);
-    tSOLAD_setPitchFactor(&ps->sola, factor);
+    float detected = tDualPitchDetector_getFrequency(&ps->pd);
+    if (detected > 0.0f)
+    {
+        float period = 1.0f / detected;
+        float factor = freq * period;
+        tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);
+        tSOLAD_setPitchFactor(&ps->sola, factor);
+    }
     
     tSOLAD_ioSamples(&ps->sola, in, out, bufSize);
 }
@@ -1434,12 +1428,12 @@
 // RETUNE
 //============================================================================================================
 
-void tRetune_init(tRetune* const rt, int numVoices, int bufSize, LEAF* const leaf)
+void tRetune_init(tRetune* const rt, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, LEAF* const leaf)
 {
-    tRetune_initToPool(rt, numVoices, bufSize, &leaf->mempool);
+    tRetune_initToPool(rt, numVoices, minInputFreq, maxInputFreq, bufSize, &leaf->mempool);
 }
 
-void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, tMempool* const mp)
+void tRetune_initToPool (tRetune* const rt, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, tMempool* const mp)
 {
     _tMempool* m = *mp;
     _tRetune* r = *rt = (_tRetune*) mpool_alloc(sizeof(_tRetune), m);
@@ -1457,7 +1451,9 @@
     r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
     r->pitchFactors = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
     
-    tDualPitchDetector_initToPool(&r->dp, mtof(48), mtof(72), mp);
+    r->minInputFreq = minInputFreq;
+    r->maxInputFreq = maxInputFreq;
+    tDualPitchDetector_initToPool(&r->dp, r->minInputFreq, r->maxInputFreq, mp);
 
     for (int i = 0; i < r->numVoices; ++i)
     {
@@ -1470,7 +1466,6 @@
     _tRetune* r = *rt;
     
     tDualPitchDetector_free(&r->dp);
-    tPeriodDetection_free(&r->pd);
     for (int i = 0; i < r->numVoices; ++i)
     {
         tPitchShift_free(&r->ps[i]);
@@ -1509,10 +1504,12 @@
     _tRetune* r = *rt;
     
     int bufSize = r->bufSize;
+    float minInputFreq = r->minInputFreq;
+    float maxInputFreq = r->maxInputFreq;
     tMempool mempool = r->mempool;
     
     tRetune_free(rt);
-    tRetune_initToPool(rt, numVoices, bufSize, &mempool);
+    tRetune_initToPool(rt, minInputFreq, maxInputFreq, numVoices, bufSize, &mempool);
 }
 
 void tRetune_setPitchFactors(tRetune* const rt, float pf)
@@ -1536,12 +1533,12 @@
 // AUTOTUNE
 //============================================================================================================
 
-void tAutotune_init (tAutotune* const rt, int numVoices, int bufSize, LEAF* const leaf)
+void tAutotune_init (tAutotune* const rt, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, LEAF* const leaf)
 {
-    tAutotune_initToPool(rt, numVoices, bufSize, &leaf->mempool);
+    tAutotune_initToPool(rt, numVoices, minInputFreq, maxInputFreq, bufSize, &leaf->mempool);
 }
 
-void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, tMempool* const mp)
+void tAutotune_initToPool (tAutotune* const rt, int numVoices, float minInputFreq, float maxInputFreq, int bufSize, tMempool* const mp)
 {
     _tMempool* m = *mp;
     _tAutotune* r = *rt = (_tAutotune*) mpool_alloc(sizeof(_tAutotune), m);
@@ -1559,7 +1556,9 @@
     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);
+    r->minInputFreq = minInputFreq;
+    r->maxInputFreq = maxInputFreq;
+    tDualPitchDetector_initToPool(&r->dp, r->minInputFreq, r->maxInputFreq, mp);
     
     for (int i = 0; i < r->numVoices; ++i)
     {
@@ -1572,7 +1571,6 @@
     _tAutotune* r = *rt;
     
     tDualPitchDetector_free(&r->dp);
-    tPeriodDetection_free(&r->pd);
     for (int i = 0; i < r->numVoices; ++i)
     {
         tPitchShift_free(&r->ps[i]);
@@ -1611,10 +1609,12 @@
     _tAutotune* r = *rt;
     
     int bufSize = r->bufSize;
+    float minInputFreq = r->minInputFreq;
+    float maxInputFreq = r->maxInputFreq;
     tMempool mempool = r->mempool;
     
     tAutotune_free(rt);
-    tAutotune_initToPool(rt, numVoices, bufSize, &mempool);
+    tAutotune_initToPool(rt, minInputFreq, maxInputFreq, numVoices, bufSize, &mempool);
 }
 
 void tAutotune_setFreqs(tAutotune* const rt, float f)