shithub: leaf

Download patch

ref: 179138388fd1ca5562ed0b0ff822ed2da3d6114b
parent: ab484c753c21984df48a58a68f684f4c2016b19a
author: Matthew Wang <mjw7@princeton.edu>
date: Wed Aug 19 11:32:10 EDT 2020

improving minblep sampler

--- a/TestPlugin/Source/MyTest.cpp
+++ b/TestPlugin/Source/MyTest.cpp
@@ -59,11 +59,11 @@
     bufIn = (float*) leaf_alloc(sizeof(float) * 4096);
     bufOut = (float*) leaf_alloc(sizeof(float) * 4096);
     
-    tDualPitchDetector_init(&detector, mtof(53), mtof(77));
+    tDualPitchDetector_init(&detector, mtof(48), mtof(84));
     
     tCompressor_init(&compressor);
     
-    tSVF_init(&lp, SVFTypeLowpass, mtof(77) * 2.0f, 1.0f);
+    tSVF_init(&lp, SVFTypeLowpass, mtof(84) * 2.0f, 1.0f);
     tSVF_init(&hp, SVFTypeHighpass, mtof(48) * 0.5f, 1.0f);
     
     tPeriodDetection_init(&pd, bufIn, bufOut, 4096, 1024);
@@ -92,9 +92,9 @@
 
 float   LEAFTest_tick            (float input)
 {
-//    tBuffer_tick(&samp, input);
-//
-//    return tMBSampler_tick(&sampler);
+    tBuffer_tick(&samp, input);
+
+    return tMBSampler_tick(&sampler);
     
     
 //    tMBSaw_setFreq(&bsaw, x);
@@ -108,22 +108,22 @@
 ////    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;
+//    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;
 }
 
 int firstFrame = 1;
--- a/leaf/Inc/leaf-sampling.h
+++ b/leaf/Inc/leaf-sampling.h
@@ -427,7 +427,7 @@
         tExpSmooth gain;
         
         float    out;
-        float    last_delta;
+        float    last, beforeLast;
         float    amp;
         float    last_amp;
         float    syncin;
@@ -437,6 +437,7 @@
         int     _j;
         
         int     start, end;
+        int     currentLoopLength;
     } _tMBSampler;
     
     typedef _tMBSampler* tMBSampler;
--- a/leaf/Src/leaf-analysis.c
+++ b/leaf/Src/leaf-analysis.c
@@ -2102,7 +2102,6 @@
     }
 }
 
-static inline int within_octave(tDualPitchDetector* const detector, float f);
 static inline void compute_predicted_frequency(tDualPitchDetector* const detector);
 
 void    tDualPitchDetector_init (tDualPitchDetector* const detector, float lowestFreq, float highestFreq)
@@ -2162,7 +2161,7 @@
                 p->_first = 0;
                 p->_predicted_frequency = 0.0f;
             }
-            else if (within_octave(detector, i.frequency))
+            else
             {
                 p->_current = i;
                 p->_mean = (0.222222f * p->_current.frequency) + (0.777778f * p->_mean);
@@ -2212,13 +2211,6 @@
     tPitchDetector_setHysteresis(&p->_pd2, hysteresis);
 }
 
-static inline int within_octave(tDualPitchDetector* const detector, float f)
-{
-    _tDualPitchDetector* p = *detector;
-    
-    return (f > p->_mean) ? (f < (p->_mean * 2.0f)) : (f > (p->_mean * 0.5f));
-}
-
 static inline void compute_predicted_frequency(tDualPitchDetector* const detector)
 {
     _tDualPitchDetector* p = *detector;
@@ -2232,11 +2224,8 @@
             float error = f1 * 0.1f;
             if (fabsf(f1 - f2) < error)
             {
-                if (p->_first || within_octave(detector, f1))
-                {
-                    p->_predicted_frequency = f1;
-                    return;
-                }
+                p->_predicted_frequency = f1;
+                return;
             }
         }
     }
--- a/leaf/Src/leaf-sampling.c
+++ b/leaf/Src/leaf-sampling.c
@@ -896,6 +896,7 @@
         
     tExpSmooth_initToPool(&c->gain, 0.0f, 0.01f, mp);
     
+    c->last = 0.0f;
     c->amp = 1.0f;
     c->_p = 0.0f;
     c->_w = 1.0f;
@@ -905,6 +906,8 @@
     memset (c->_f, 0, (FILLEN + STEP_DD_PULSE_LENGTH) * sizeof (float));
 
     c->start = 0;
+    c->end = 1;
+    c->currentLoopLength = 1;
     tMBSampler_setEnd(sp, c->samp->bufferLength);
 }
 
@@ -936,8 +939,13 @@
     _tMBSampler* c = *sp;
     
     if (c->gain->curr == 0.0f && !c->active) return 0.0f;
-    if (c->_w == 0.0f) return c->out;
+    if (c->_w == 0.0f)
+    {
+        c->_last_w = 0.0f;
+        return c->out;
+    }
     
+    float last, beforeLast;
     int start, end, length;
     float* buff;
     int    j;
@@ -950,13 +958,14 @@
 
     buff = c->samp->buff;
     
+    last = c->last;
+    beforeLast = c->beforeLast;
     p = c->_p;  /* position */
-    w = c->_w;  /* rate */
+    w = fminf((float)c->currentLoopLength * 0.5f, c->_w);  /* rate */
     z = c->_z;  /* low pass filter state */
     j = c->_j;  /* index into buffer _f */
     
     length = end - start;
-    w = fminf((float)length * 0.5f, w);
 
     //a = 0.2 + 0.8 * vco->_port [FILT];
     a = 0.5f; // when a = 1, LPfilter is disabled
@@ -963,8 +972,7 @@
     
     p += w;
     
-    float next;
-    
+    float next, afterNext;
 //    if (syncin >= 1e-20f) {  /* sync to master */
 //
 //        float eof_offset = (syncin - 1e-20f) * w;
@@ -995,6 +1003,7 @@
 //        place_slope_dd(c->_f, j, p, w, (next - c->out) - c->last_delta);
 //
 //    } else
+    
     if (w > 0.0f) {
     
         if (p >= (float) end) {  /* normal phase reset */
@@ -1001,7 +1010,11 @@
         
             // start and end are never negative and end must also be greater than start
             // so this loop is fine
-            while (p >= (float) end) p -= (float) length;
+            while (p >= (float) end)
+            {
+                p -= (float) length;
+                c->currentLoopLength = length;
+            }
             
             float f = p;
             int i = (int) f;
@@ -1008,19 +1021,33 @@
             f -= i;
             next = buff[i] * (1.0f - f) + buff[i+1] * f;
             
-            place_step_dd(c->_f, j, p - start, w, next - c->out);
-            place_slope_dd(c->_f, j, p - start, w, (next - c->out) - c->last_delta);
+            f = p + w;
+            i = (int) f;
+            f -= i;
+            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
+ 
+            place_step_dd(c->_f, j, p - start, w, next - last);
+            float nextSlope = (afterNext - next) / w;
+            float lastSlope = (last - beforeLast) / w;
+            place_slope_dd(c->_f, j, p - start, w, nextSlope - lastSlope);
             
             if (c->mode == PlayNormal) c->active = 0;
             else if (c->mode == PlayBackAndForth) w = -w;
         }
 //        else if (p < (float) start) { /* start has been set ahead of the current phase */
-//
+//            
 //            p = (float) start;
 //            next = buff[start];
+//           
+//            float f = p + w;
+//            int i = (int) f;
+//            f -= i;
+//            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
 //
-//            place_step_dd(c->_f, j, p, w, next - c->last);
-//            place_slope_dd(c->_f, j, p, w, (next - c->last) - c->last_delta);
+//            place_step_dd(c->_f, j, 0, w, next - last);
+//            float nextSlope = (afterNext - next) / w;
+//            float lastSlope = (last - beforeLast) / w;
+//            place_slope_dd(c->_f, j, 0, w, nextSlope - lastSlope);
 //        }
         else {
             
@@ -1032,7 +1059,14 @@
 
         if (c->_last_w < 0.0f)
         {
-            place_slope_dd(c->_f, j, p - start, w, (next - c->out) - c->last_delta);
+            float f = p + w;
+            int i = (int) f;
+            f -= i;
+            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
+            
+            float nextSlope = (afterNext - next) / w;
+            float lastSlope = (last - beforeLast) / w;
+            place_slope_dd(c->_f, j, p - start, w, nextSlope - lastSlope);
         }
         
     } else { // if (w < 0.0f) {
@@ -1039,25 +1073,44 @@
         
         if (p < (float) start) {
         
-            while (p < (float) start) p += (float) length;
+            while (p < (float) start)
+            {
+                p += (float) length;
+                c->currentLoopLength = length;
+            }
             
             float f = p;
             int i = (int) f;
             f -= i;
             next = buff[i] * (1.0f - f) + buff[i+1] * f;
+
+            f = p + w;
+            i = (int) f;
+            f -= i;
+            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
+
+            place_step_dd(c->_f, j, end - p, w, next - last);
+            float nextSlope = (afterNext - next) / w;
+            float lastSlope = (last - beforeLast) / w;
+            place_slope_dd(c->_f, j, end - p, w, nextSlope - lastSlope);
             
-            place_step_dd(c->_f, j, end - p, w, next - c->out);
-            place_slope_dd(c->_f, j, end - p, w, (next - c->out) - c->last_delta);
-            
             if (c->mode == PlayNormal) c->active = 0;
             else if (c->mode == PlayBackAndForth) w = -w;
         }
-//        else if (p >= (float) end) {
+//        else if (p > (float) end) {
 //
-//            p = (float) end - 1;
-//            next = buff[end - 1];
-//            place_step_dd(c->_f, j, p, w, next - c->last);
-//            place_slope_dd(c->_f, j, p, w, (next - c->last) - c->last_delta);
+//            p = (float) end;
+//            next = buff[end];
+//
+//            float f = p + w;
+//            int i = (int) f;
+//            f -= i;
+//            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
+//
+//            place_step_dd(c->_f, j, 0, w, next - last);
+//            float nextSlope = (afterNext - next) / w;
+//            float lastSlope = (last - beforeLast) / w;
+//            place_slope_dd(c->_f, j, 0, w, nextSlope - lastSlope);
 //        }
         else {
             
@@ -1069,16 +1122,24 @@
         
         if (c->_last_w > 0.0f)
         {
-            place_slope_dd(c->_f, j, end - p, w, (next - c->out) - c->last_delta);
+            float f = p + w;
+            int i = (int) f;
+            f -= i;
+            afterNext = buff[i] * (1.0f - f) + buff[i+1] * f;
+            
+            float nextSlope = (afterNext - next) / w;
+            float lastSlope = (last - beforeLast) / w;
+            place_slope_dd(c->_f, j, end - p, w, nextSlope - lastSlope);
         }
     }
     
+    c->beforeLast = last;
+    c->last = next;
+    
     c->_f[j + DD_SAMPLE_DELAY] += next;
     
     z += a * (c->_f[j] - z); // LP filtering
     next = c->amp * z;
-    
-    c->last_delta = next - c->out;
     
     c->out = next;