shithub: leaf

Download patch

ref: 39c879d74e7f30f0b69e8d32462bb825fca7ecfa
parent: 7e988acfc668efc5134163fa8da2774254ae4957
author: Matthew Wang <mjw7@princeton.edu>
date: Thu Feb 20 08:16:21 EST 2020

add fidelity threshold to PeriodDetection, Retune, Autotune

--- a/LEAF/Inc/leaf-analysis.h
+++ b/LEAF/Inc/leaf-analysis.h
@@ -152,6 +152,7 @@
     //==============================================================================
     
     // tSNAC: period detector
+    // from Katja Vetters http://www.katjaas.nl/helmholtz/helmholtz.html
 #define SNAC_FRAME_SIZE 1024           // default analysis framesize // should be the same as (or smaller than?) PS_FRAME_SIZE
 #define DEFOVERLAP 1                // default overlap
 #define DEFBIAS 0.2f        // default bias
@@ -228,6 +229,8 @@
         float lastmax;
         float deltamax;
         
+        float fidelityThreshold;
+        
     } _tPeriodDetection;
     
     typedef _tPeriodDetection* tPeriodDetection;
@@ -239,8 +242,9 @@
     
     float   tPeriodDetection_tick               (tPeriodDetection* const, float sample);
     float   tPeriodDetection_getPeriod          (tPeriodDetection* const);
-    void    tPeriodDetection_setHopSize         (tPeriodDetection* p, int hs);
-    void    tPeriodDetection_setWindowSize      (tPeriodDetection* p, int ws);
+    void    tPeriodDetection_setHopSize         (tPeriodDetection* const, int hs);
+    void    tPeriodDetection_setWindowSize      (tPeriodDetection* const, int ws);
+    void    tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
     
     //==============================================================================
     
--- a/LEAF/Inc/leaf-effects.h
+++ b/LEAF/Inc/leaf-effects.h
@@ -99,6 +99,7 @@
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
     /* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
+    // from Katja Vetters http://www.katjaas.nl/pitchshiftlowlatency/pitchshiftlowlatency.html
 #define LOOPSIZE (2048*2)      // (4096*2) // loop size must be power of two
 #define LOOPMASK (LOOPSIZE - 1)
 #define PITCHFACTORDEFAULT 1.0f
@@ -199,20 +200,21 @@
     
     typedef _tRetune* tRetune;
     
-    void    tRetune_init            (tRetune* const, int numVoices, int bufSize, int frameSize);
-    void    tRetune_free            (tRetune* const);
-    void    tRetune_initToPool      (tRetune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
-    void    tRetune_freeFromPool    (tRetune* const, tMempool* const);
+    void    tRetune_init                (tRetune* const, int numVoices, int bufSize, int frameSize);
+    void    tRetune_free                (tRetune* const);
+    void    tRetune_initToPool          (tRetune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+    void    tRetune_freeFromPool        (tRetune* const, tMempool* const);
     
-    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);
-    float   tRetune_getInputPeriod  (tRetune* const);
-    float   tRetune_getInputFreq    (tRetune* const);
+    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);
     
     // Autotune
     typedef struct _tAutotune
@@ -241,20 +243,21 @@
     
     typedef _tAutotune* tAutotune;
     
-    void    tAutotune_init              (tAutotune* const, int numVoices, int bufSize, int frameSize);
-    void    tAutotune_free              (tAutotune* const);
-    void    tAutotune_initToPool        (tAutotune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
-    void    tAutotune_freeFromPool      (tAutotune* const, tMempool* const);
+    void    tAutotune_init                  (tAutotune* const, int numVoices, int bufSize, int frameSize);
+    void    tAutotune_free                  (tAutotune* const);
+    void    tAutotune_initToPool            (tAutotune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+    void    tAutotune_freeFromPool          (tAutotune* const, tMempool* const);
     
-    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);
-    float   tAutotune_getInputPeriod    (tAutotune* const);
-    float   tAutotune_getInputFreq      (tAutotune* const);
+    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);
+    float   tAutotune_getInputPeriod        (tAutotune* const);
+    float   tAutotune_getInputFreq          (tAutotune* const);
     
     //==============================================================================
     
--- a/LEAF/Src/leaf-analysis.c
+++ b/LEAF/Src/leaf-analysis.c
@@ -872,6 +872,7 @@
     
     p->timeConstant = DEFTIMECONSTANT;
     p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
+    p->fidelityThreshold = 0.95;
 }
 
 void    tPeriodDetection_freeFromPool       (tPeriodDetection* const pd, tMempool* const mp)
@@ -907,7 +908,9 @@
         tEnvPD_processBlock(&p->env, &(p->inBuffer[i]));
         
         tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
-        p->period = tSNAC_getPeriod(&p->snac);
+        float fidelity = tSNAC_getFidelity(&p->snac);
+        // Fidelity threshold recommended by Katja Vetters is 0.95 for most instruments/voices http://www.katjaas.nl/helmholtz/helmholtz.html
+        if (fidelity > p->fidelityThreshold) p->period = tSNAC_getPeriod(&p->snac);
         
         p->curBlock++;
         if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
@@ -934,4 +937,10 @@
 {
     _tPeriodDetection* p = *pd;
     p->windowSize = ws;
+}
+
+void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold)
+{
+    _tPeriodDetection* p = *pd;
+    p->fidelityThreshold = threshold;
 }
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -1206,6 +1206,13 @@
     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;
@@ -1372,6 +1379,13 @@
     
     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);
 }
 
 float tAutotune_getInputPeriod(tAutotune* const rt)