shithub: leaf

Download patch

ref: 6c87e507028c0c63facde25ee24e6f482fe3e995
parent: 58869eabcb354df83a0833bf86c1d2a582a9b5ef
author: mulshine <mulshine@princeton.edu>
date: Thu Jan 24 11:39:14 EST 2019

Decent crossfade implemented.

--- a/LEAF/Inc/leaf-sample.h
+++ b/LEAF/Inc/leaf-sample.h
@@ -85,7 +85,8 @@
         
         int active;
         
-        float gain;
+        float g1;
+        float g2;
     } tSamplePlayer;
     
     void    tSamplePlayer_init      (tSamplePlayer* const, tSample* s);
--- a/LEAF/Src/leaf-sample.c
+++ b/LEAF/Src/leaf-sample.c
@@ -105,6 +105,8 @@
 }
 
 //==============================================================================
+
+#define CFX 50
 
 void tSamplePlayer_init         (tSamplePlayer* const p, tSample* s)
 {
@@ -124,7 +126,8 @@
     
     p->mode = Normal;
 
-    p->gain = 1.;
+    p->g1 = 1.f;
+    p->g2 = 0.f;
 }
 
 void tSamplePlayer_free         (tSamplePlayer* const p)
@@ -140,6 +143,7 @@
     if (p->active == 0 || (p->len < 4))         return 0.f;
     
     float sample = 0.f;
+    float cfxsample = 0.f;
     
     float* buff = p->samp->buff;
     
@@ -148,7 +152,7 @@
     int idx =  (int) p->idx;
     float alpha = p->idx - idx;
     
-    uint32_t start = p->start, end = p->end;
+    int32_t start = p->start, end = p->end;
     if (p->flip < 0)
     {
         start = p->end;
@@ -155,10 +159,13 @@
         end = p->start;
     }
     
+    p->g1 = 1.f;
+    p->g2 = 0.f;
+    
     // Check dir (direction) to interpolate properly
     if (dir > 0)
     {
-        // FORWARD
+        // FORWARD NORMAL SAMPLE
         int i1 = idx-1;
         int i3 = idx+1;
         int i4 = idx+2;
@@ -172,6 +179,24 @@
                                                buff[i3],
                                                buff[i4],
                                                alpha);
+        if ((end - idx) <= CFX)
+        {
+            // CROSSFADE SAMPLE
+            int cdx = idx - p->len;
+    
+            i1 = cdx-1;
+            i3 = cdx+1;
+            i4 = cdx+2;
+            
+            cfxsample =     LEAF_interpolate_hermite (buff[i1],
+                                                      buff[idx],
+                                                      buff[i3],
+                                                      buff[i4],
+                                                      alpha);
+            
+            p->g2 = (float) (CFX - (end - idx - 1)) / (float) CFX;
+            p->g1 = 1.f - p->g2;
+        }
     }
     else
     {
@@ -188,40 +213,53 @@
                                                buff[idx],
                                                buff[i3],
                                                buff[i4],
-                                               alpha);
+                                               1.0f-alpha);
+        
+        if ((idx - start) <= CFX)
+        {
+            // CROSSFADE SAMPLE
+            int cdx = idx + p->len;
+    
+            i1 = cdx+1;
+            i3 = cdx-1;
+            i4 = cdx-2;
+            
+            cfxsample =     LEAF_interpolate_hermite (buff[i1],
+                                                      buff[idx],
+                                                      buff[i3],
+                                                      buff[i4],
+                                                      alpha);
+            
+            p->g2 = (float) (CFX - (idx - start - 1)) / (float) CFX;
+            p->g1 = 1.f - p->g2;
+        }
     }
     
     p->idx += (dir * p->inc);
     
-    if (p->mode != BackAndForth)
+    if (p->mode != BackAndForth ) // == Normal or Loop
     {
-        // Check flip bit to change loop test
         if (idx <= start)
         {
-            // -inc
             p->idx += (float)(p->len);
             p->cnt++;
         }
         else if (idx >= end)
         {
-            // +inc
             p->idx -= (float)(p->len);
             p->cnt++;
         }
-
     }
-    else // BackAndForth
+    else // == BackAndForth
     {
-        if ((idx < start) || (idx > end))
+        if ((idx <= start) || (idx >= end))
         {
             p->dir = -p->dir;
-            p->idx += (2*p->inc);
             p->cnt++;
         }
     }
     
-    
-    return sample * p->gain;
+    return sample * p->g1 + cfxsample * p->g2;
 }
 
 void tSamplePlayer_setSample    (tSamplePlayer* const p, tSample* s)
@@ -238,6 +276,17 @@
 {
     p->active = 1;
     p->cnt = 0;
+    
+    if (p->dir > 0)
+    {
+        if (p->flip > 0)    p->idx = p->start;
+        else                p->idx = p->end;
+    }
+    else
+    {
+        if (p->flip > 0)    p->idx = p->end;
+        else                p->idx = p->start;
+    }
 }
 
 void tSamplePlayer_stop         (tSamplePlayer* const p)
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -57,17 +57,17 @@
     
     float rate = val * 16.0f - 8.0f;
     tSamplePlayer_setRate(&player, rate);
-    DBG("rate: " + String(rate));
+    //DBG("rate: " + String(rate));
     
     val = getSliderValue("start");
     float start = val * sample.length;
     tSamplePlayer_setStart(&player,  start);
-    DBG("start: " + String(start));
+    //DBG("start: " + String(start));
     
     val = getSliderValue("end");
     float end = val * sample.length;
     tSamplePlayer_setEnd(&player, end);
-    DBG("end: " + String(end));
+    //DBG("end: " + String(end));
     
     bool state = getButtonState("sample");