shithub: leaf

Download patch

ref: 8f147944afaaa41bf53b2a1ed3884e07984c401c
parent: c3197de0732d863167944ca00c82f3e7165c8409
author: Matthew Wang <mjw7@princeton.edu>
date: Tue May 5 12:05:45 EDT 2020

trying some period detection hysteresis options

--- a/LEAF/Inc/leaf-analysis.h
+++ b/LEAF/Inc/leaf-analysis.h
@@ -239,6 +239,10 @@
         
         float fidelityThreshold;
         
+        float history;
+        float alpha;
+        float tolerance;
+        
     } _tPeriodDetection;
     
     typedef _tPeriodDetection* tPeriodDetection;
@@ -253,6 +257,8 @@
     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);
     
     //==============================================================================
     
--- a/LEAF/Inc/leaf-effects.h
+++ b/LEAF/Inc/leaf-effects.h
@@ -264,6 +264,8 @@
     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/Src/leaf-analysis.c
+++ b/LEAF/Src/leaf-analysis.c
@@ -1,11 +1,11 @@
 /*==============================================================================
+ 
+ leaf-analysis.c
+ Created: 30 Nov 2018 11:56:49am
+ Author:  airship
+ 
+ ==============================================================================*/
 
-    leaf-analysis.c
-    Created: 30 Nov 2018 11:56:49am
-    Author:  airship
-
-==============================================================================*/
-
 #if _WIN32 || _WIN64
 
 #include "..\Inc\leaf-analysis.h"
@@ -504,7 +504,7 @@
     s->fidelity = 0.;
     s->minrms = DEFMINRMS;
     s->framesize = SNAC_FRAME_SIZE;
-
+    
     s->inputbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);
     s->processbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2), m);
     s->spectrumbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE / 2), m);
@@ -873,6 +873,10 @@
     p->timeConstant = DEFTIMECONSTANT;
     p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
     p->fidelityThreshold = 0.95;
+    
+    p->history = 0.0f;
+    p->alpha = 1.0f;
+    p->tolerance = 1.0f;
 }
 
 void    tPeriodDetection_freeFromPool       (tPeriodDetection* const pd, tMempool* const mp)
@@ -910,7 +914,15 @@
         tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
         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);
+        if (fidelity > p->fidelityThreshold)
+        {
+            float detected = tSNAC_getPeriod(&p->snac);
+            p->history = detected * p->alpha + (p->history * (1 - p->alpha));
+            float delta = 0.0f;
+            if (detected > p->history) delta = (detected / p->history) - 1.0f;
+            else delta = (p->history / detected) - 1.0f;
+            if (delta < p->tolerance) p->period = detected;
+        }
         
         p->curBlock++;
         if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
@@ -943,4 +955,17 @@
 {
     _tPeriodDetection* p = *pd;
     p->fidelityThreshold = threshold;
+}
+
+void tPeriodDetection_setAlpha            (tPeriodDetection* pd, float alpha)
+{
+    _tPeriodDetection* p = *pd;
+    p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
+}
+
+void tPeriodDetection_setTolerance        (tPeriodDetection* pd, float tolerance)
+{
+    _tPeriodDetection* p = *pd;
+    if (tolerance < 0.0f) p->tolerance = 0.0f;
+    else p->tolerance = tolerance;
 }
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -254,7 +254,7 @@
     v->pos = p0;
     v->FX = fx;
     
-
+    
     return o;
 }
 
@@ -517,12 +517,12 @@
 void    tSOLAD_initToPool       (tSOLAD* const wp, tMempool* const mp)
 {
     _tMempool* m = *mp;
-
+    
     _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);
     
     w->pitchfactor = 1.;
     w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);
-
+    
     solad_init(w);
 }
 
@@ -900,9 +900,9 @@
 void    tPitchShift_initToPool      (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)
 {
     _tMempool* m = *mp;
-
+    
     _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);
-
+    
     _tPeriodDetection* p = *pd;
     
     ps->p = pd;
@@ -1078,7 +1078,7 @@
     tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
     
     r->inputPeriod = 0.0f;
-
+    
     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);
@@ -1088,7 +1088,7 @@
     }
     
     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->outBuffers[i], r->bufSize, mp);
@@ -1259,7 +1259,7 @@
     }
     
     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->outBuffers[i], r->bufSize, mp);
@@ -1293,15 +1293,15 @@
     
     float tempPeriod = tPeriodDetection_tick(&r->pd, sample);
     if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
-	{
-		r->inputPeriod = tempPeriod;
-	}
-
-	for (int v = 0; v < r->numVoices; ++v)
-	{
-		r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
-	}
-
+    {
+        r->inputPeriod = tempPeriod;
+    }
+    
+    for (int v = 0; v < r->numVoices; ++v)
+    {
+        r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
+    }
+    
     return r->tickOutput;
 }
 
@@ -1376,10 +1376,22 @@
 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;
@@ -1413,7 +1425,7 @@
     fs->fsmooth = (float*) leaf_calloc(sizeof(float) * fs->ford);
     fs->ftvec = (float*) leaf_calloc(sizeof(float) * fs->ford);
     fs->fbuff = (float*) leaf_calloc(sizeof(float*) * fs->ford);
-
+    
     fs->falph = powf(0.001f, 40.0f * leaf.invSampleRate);
     fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
     fs->fhp = 0.0f;
@@ -1423,11 +1435,11 @@
     fs->fmutealph = powf(0.001f, 0.5f * leaf.invSampleRate);
     fs->cbi = 0;
     fs->intensity = 1.0f;
-	fs->invIntensity = 1.0f;
-	tHighpass_init(&fs->hp, 10.0f);
-	tHighpass_init(&fs->hp2, 10.0f);
-	tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
-	tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
+    fs->invIntensity = 1.0f;
+    tHighpass_init(&fs->hp, 10.0f);
+    tHighpass_init(&fs->hp2, 10.0f);
+    tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
+    tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
 }
 
 void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1445,8 +1457,8 @@
     leaf_free(fs->fbuff);
     tHighpass_free(&fs->hp);
     tHighpass_free(&fs->hp2);
-	tFeedbackLeveler_free(&fs->fbl1);
-	tFeedbackLeveler_free(&fs->fbl2);
+    tFeedbackLeveler_free(&fs->fbl1);
+    tFeedbackLeveler_free(&fs->fbl2);
     leaf_free(fs);
 }
 
@@ -1466,8 +1478,8 @@
     fs->ftvec = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
     
     fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
-
     
+    
     fs->falph = powf(0.001f, 10.0f * leaf.invSampleRate);
     fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
     fs->fhp = 0.0f;
@@ -1516,9 +1528,9 @@
     in = tFeedbackLeveler_tick(&fs->fbl1, in);
     in = tHighpass_tick(&fs->hp, in * fs->intensity);
     
-
+    
     float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
-
+    
     ford = fs->ford;
     falph = fs->falph;
     foma = (1.0f - falph);
@@ -1544,7 +1556,7 @@
         fb = fc - tf*fa;
         fa = fa - tf*fc;
     }
-
+    
     //return fa * 0.1f;
     return fa;
 }
@@ -1555,7 +1567,7 @@
     
     float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
     ford = fs->ford;
-
+    
     flpa = fs->flpa;
     flamb = fs->flamb;
     tf = fs->shiftFactor * (1.0f+flamb)/(1.0f-flamb);
@@ -1642,7 +1654,7 @@
     // ...and we're done messing with formants
     //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
     tf = tHighpass_tick(&fs->hp2, tanhf(tf));
-
+    
     return tf * fs->invIntensity;
 }
 
@@ -1656,21 +1668,21 @@
 void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
 {
     _tFormantShifter* fs = *fsr;
-
-
-
+    
+    
+    
     fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
-
-   // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
+    
+    // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
     //tFeedbackLeveler_setTargetLevel(&fs->fbl2, fs->intensity);
     //make sure you don't divide by zero, doofies
     if (fs->intensity != 0.0f)
     {
-    	fs->invIntensity = 1.0f/fs->intensity;
+        fs->invIntensity = 1.0f/fs->intensity;
     }
     else
     {
-    	fs->invIntensity = 1.0f;
+        fs->invIntensity = 1.0f;
     }
-
+    
 }
--- a/LEAF/Src/leaf-math.c
+++ b/LEAF/Src/leaf-math.c
@@ -262,11 +262,17 @@
 
 float   LEAF_clip(float min, float val, float max)
 {
-    
-    if (val < min) {
-        return min;
-    } else if (val > max) {
-        return max;
+    int tempmin = min;
+    int tempmax = max;
+    if (min > max)
+    {
+        tempmin = max;
+        tempmax = min;
+    }
+    if (val < tempmin) {
+        return tempmin;
+    } else if (val > tempmax) {
+        return tempmax;
     } else {
         return val;
     }