shithub: leaf

Download patch

ref: 3f1b8b2d3b1d4d83f2f020722ab02ed68caf56eb
parent: 54f35b1aa6be6f13704bdcedbe590fd0f12eb3cf
author: mulshine <mulshine@princeton.edu>
date: Thu Jan 31 11:19:48 EST 2019

Sampler crossfade gone.

--- a/LEAF/Inc/leaf-sample.h
+++ b/LEAF/Inc/leaf-sample.h
@@ -28,7 +28,7 @@
         RecordModeNil
     } RecordMode;
     
-    typedef struct _tSample
+    typedef struct _tBuffer
     {
         float* buff;
         
@@ -39,23 +39,23 @@
         
         int active;
         
-    } tSample;
+    } tBuffer;
 
-    void  tSample_init (tSample* const, uint32_t length);
-    void  tSample_free (tSample* const);
+    void  tBuffer_init (tBuffer* const, uint32_t length);
+    void  tBuffer_free (tBuffer* const);
     
-    void  tSample_tick (tSample* const, float sample);
+    void  tBuffer_tick (tBuffer* const, float sample);
     
-    void  tSample_read(tSample* const, float* buff, uint32_t len);
+    void  tBuffer_read(tBuffer* const, float* buff, uint32_t len);
     
-    float tSample_get (tSample* const, int idx);
+    float tBuffer_get (tBuffer* const, int idx);
     
-    void  tSample_start (tSample* const);
-    void  tSample_stop (tSample* const);
+    void  tBuffer_record (tBuffer* const);
+    void  tBuffer_stop (tBuffer* const);
     
-    void  tSample_setRecordMode (tSample* const, RecordMode mode);
+    void  tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
     
-    void  tSample_clear (tSample* const);
+    void  tBuffer_clear (tBuffer* const);
     
 //==============================================================================
     
@@ -67,12 +67,13 @@
         SampleModeNil
     } Mode;
     
-    typedef struct _tSamplePlayer
+    typedef struct _tSampler
     {
-        tSample* samp;
+        tBuffer* samp;
         
         float idx;
         float inc;
+        float iinc;
         int8_t dir;
         int8_t flip;
         
@@ -79,32 +80,32 @@
         int32_t start;
         int32_t end;
         uint32_t len;
-        uint32_t cnt;
+        uint32_t cfxlen;
     
         Mode mode;
         
         int active;
-        
-        float g1;
-        float g2;
-    } tSamplePlayer;
+
+    } tSampler;
     
-    void    tSamplePlayer_init      (tSamplePlayer* const, tSample* s);
-    void    tSamplePlayer_free      (tSamplePlayer* const);
+    void    tSampler_init      (tSampler* const, tBuffer* s);
+    void    tSampler_free      (tSampler* const);
     
-    float   tSamplePlayer_tick      (tSamplePlayer* const);
+    float   tSampler_tick      (tSampler* const);
 
-    void    tSamplePlayer_setSample (tSamplePlayer* const, tSample* s);
+    void    tSampler_setSample (tSampler* const, tBuffer* s);
     
-    void    tSamplePlayer_setMode   (tSamplePlayer* const, Mode mode);
+    void    tSampler_setMode   (tSampler* const, Mode mode);
     
-    void    tSamplePlayer_play      (tSamplePlayer* const);
-    void    tSamplePlayer_stop      (tSamplePlayer* const);
+    void    tSampler_play      (tSampler* const);
+    void    tSampler_stop      (tSampler* const);
     
-    void    tSamplePlayer_setStart  (tSamplePlayer* const, int32_t start);
-    void    tSamplePlayer_setEnd    (tSamplePlayer* const, int32_t end);
+    void    tSampler_setStart  (tSampler* const, int32_t start);
+    void    tSampler_setEnd    (tSampler* const, int32_t end);
     
-    void    tSamplePlayer_setRate   (tSamplePlayer* const, float rate);
+    void    tSampler_setCrossfadeLength  (tSampler* const p, uint32_t length);
+    
+    void    tSampler_setRate   (tSampler* const, float rate);
     
 //==============================================================================
     
--- a/LEAF/Src/leaf-sample.c
+++ b/LEAF/Src/leaf-sample.c
@@ -23,7 +23,7 @@
 
 //==============================================================================
 
-void  tSample_init (tSample* const s, uint32_t length)
+void  tBuffer_init (tBuffer* const s, uint32_t length)
 {
     s->buff = (float*) leaf_alloc( sizeof(float) * length);
     
@@ -33,16 +33,16 @@
     s->idx = 0;
     s->mode = RecordOneShot;
     
-    tSample_clear(s);
+    tBuffer_clear(s);
 }
 
-void  tSample_free (tSample* const s)
+void  tBuffer_free (tBuffer* const s)
 {
     leaf_free(s->buff);
     leaf_free(s);
 }
 
-void tSample_tick (tSample* const s, float sample)
+void tBuffer_tick (tBuffer* const s, float sample)
 {
     if (s->active == 1)
     {
@@ -54,7 +54,7 @@
         {
             if (s->mode == RecordOneShot)
             {
-                tSample_stop(s);
+                tBuffer_stop(s);
             }
             else if (s->mode == RecordLoop)
             {
@@ -64,7 +64,7 @@
     }
 }
 
-void  tSample_read(tSample* const s, float* buff, uint32_t len)
+void  tBuffer_read(tBuffer* const s, float* buff, uint32_t len)
 {
     for (int i = 0; i < s->length; i++)
     {
@@ -73,7 +73,7 @@
     }
 }
 
-float tSample_get (tSample* const s, int idx)
+float tBuffer_get (tBuffer* const s, int idx)
 {
     if ((idx < 0) || (idx >= s->length)) return 0.f;
     
@@ -80,23 +80,23 @@
     return s->buff[idx];
 }
 
-void  tSample_start(tSample* const s)
+void  tBuffer_record(tBuffer* const s)
 {
     s->active = 1;
     s->idx = 0;
 }
 
-void  tSample_stop(tSample* const s)
+void  tBuffer_stop(tBuffer* const s)
 {
     s->active = 0;
 }
 
-void  tSample_setRecordMode (tSample* const s, RecordMode mode)
+void  tBuffer_setRecordMode (tBuffer* const s, RecordMode mode)
 {
     s->mode = mode;
 }
 
-void  tSample_clear (tSample* const s)
+void  tBuffer_clear (tBuffer* const s)
 {
     for (int i = 0; i < s->length; i++)
     {
@@ -104,11 +104,9 @@
     }
 }
 
-//==============================================================================
-
-#define CFX 300
+//================================tSampler=====================================
 
-void tSamplePlayer_init         (tSamplePlayer* const p, tSample* s)
+void tSampler_init         (tSampler* const p, tBuffer* s)
 {
     p->samp = s;
     
@@ -121,30 +119,29 @@
     
     p->idx = 0.f;
     p->inc = 1.f;
+    p->iinc = 1.f;
     p->dir = 1;
     p->flip = 1;
     
     p->mode = Normal;
-
-    p->g1 = 1.f;
-    p->g2 = 0.f;
+    
+    p->cfxlen = 300; // default 300 sample crossfade
 }
 
-void tSamplePlayer_free         (tSamplePlayer* const p)
+void tSampler_free         (tSampler* const p)
 {
     leaf_free(p->samp);
     leaf_free(p);
 }
 
-float tSamplePlayer_tick        (tSamplePlayer* const p)
+float tSampler_tick        (tSampler* const p)
 {
-    if ((p->mode == Normal) && (p->cnt > 0))    p->active = 0;
-    
     if (p->active == 0 || (p->len < 4))         return 0.f;
     
     float sample = 0.f;
     float cfxsample = 0.f;
-    int cfx = CFX; // make this part of class
+    int numsamps;
+    float g1 = 1.f, g2 = 0.f;
     
     float* buff = p->samp->buff;
     
@@ -152,17 +149,17 @@
     
     int idx;
     float alpha;
-
-    if (dir > 0)
-    {
+
+    if (dir > 0)
+    {
     	idx = (int) p->idx;
     	alpha = p->idx - idx;
-    }
-    else
-    {
-    	idx = (int) (p->idx + 1.f); // we think this is because flooring on int works different when reading backwards
-    	alpha = (p->idx+1.f) - idx;
     }
+    else
+    {
+    	idx = (int) (p->idx + 1.f); // we think this is because flooring on int works different when reading backwards
+    	alpha = (p->idx+1.f) - idx;
+    }
     
     int32_t start = p->start, end = p->end;
     if (p->flip < 0)
@@ -178,10 +175,6 @@
         int i1 = idx-1;
         int i3 = idx+1;
         int i4 = idx+2;
-        
-        if (i1 < start)  i1 += p->len;
-        if (i3 > end)    i3 -= p->len;
-        if (i4 > end)    i4 -= p->len;
 
         sample =     LEAF_interpolate_hermite (buff[i1],
                                                buff[idx],
@@ -189,9 +182,11 @@
                                                buff[i4],
                                                alpha);
         
-        cfx = (end - idx) / p->inc; // num samples to end of loop,  use inverse increment
-
-        if (cfx <= CFX)
+        // num samples to end of loop
+        numsamps = (dir > 0) ? (end - idx) : (idx - start);
+        numsamps *= p->iinc;
+        
+        if (numsamps <= p->cfxlen)
         {
             // CROSSFADE SAMPLE
             float idxx =  p->idx - p->len;
@@ -207,9 +202,9 @@
                                                       buff[i4],
                                                       alpha);
             
-            //rprintf("cidx: %d\n", cdx);
+            g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
         }
-        else   cfx = CFX;
+        else   g2 = 0.f;
     }
     else
     {
@@ -217,11 +212,7 @@
         int i1 = idx+1;
         int i3 = idx-1;
         int i4 = idx-2;
-        
-        if (i1 > end)    i1 -= p->len;
-        if (i3 < start)  i3 += p->len;
-        if (i4 < start)  i4 += p->len;
-
+    
         sample =     LEAF_interpolate_hermite (buff[i1],
                                                buff[idx],
                                                buff[i3],
@@ -228,9 +219,9 @@
                                                buff[i4],
                                                1.0f-alpha);
         
-        cfx = (idx - start) / p->inc;
+        numsamps = (idx - start) / p->inc;
         
-        if (cfx <= CFX)
+        if (numsamps <= p->cfxlen)
         {
             // CROSSFADE SAMPLE
             float idxx =  p->idx + p->len + 1.f;
@@ -246,8 +237,10 @@
                                                       buff[i3],
                                                       buff[i4],
                                                       1.f-alpha);
+            
+            g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
         }
-        else   cfx = CFX;
+        else   g2 = 0.f;
     }
     
     p->idx += (dir * p->inc);
@@ -257,12 +250,10 @@
         if (idx <= start)
         {
             p->idx += (float)(p->len);
-            p->cnt++;
         }
         else if (idx >= end)
         {
             p->idx -= (float)(p->len);
-            p->cnt++;
         }
     }
     else // == BackAndForth
@@ -270,32 +261,37 @@
         if ((idx <= start) || (idx >= end))
         {
             p->dir = -p->dir;
-            p->cnt++;
         }
     }
     
-    p->g2 = (float) (CFX - cfx) / (float) CFX;
-    p->g1 = 1.f - p->g2;
+    g1 = 1.f - g2;
+    sample = sample * g1 + cfxsample * g2;
     
-    sample = sample * p->g1 + cfxsample * p->g2;
-    
     return sample;
 }
 
-void tSamplePlayer_setSample    (tSamplePlayer* const p, tSample* s)
+void tSampler_setSample    (tSampler* const p, tBuffer* s)
 {
     p->samp = s;
 }
 
-void tSamplePlayer_setMode      (tSamplePlayer* const p, Mode mode)
+void tSampler_setMode      (tSampler* const p, Mode mode)
 {
     p->mode = mode;
 }
 
-void tSamplePlayer_play         (tSamplePlayer* const p)
+void tSampler_setCrossfadeLength  (tSampler* const p, uint32_t length)
 {
+    uint32_t cfxlen = LEAF_clip(0, length, 1000);
+    
+    //if (cfxlen > p->len)  cfxlen = p->len * 0.25f;
+    
+    p->cfxlen = cfxlen;
+}
+
+void tSampler_play         (tSampler* const p)
+{
     p->active = 1;
-    p->cnt = 0;
     
     if (p->dir > 0)
     {
@@ -309,13 +305,17 @@
     }
 }
 
-void tSamplePlayer_stop         (tSamplePlayer* const p)
+void tSampler_stop         (tSampler* const p)
 {
     p->active = 0;
 }
 
-static void handleStartEndChange(tSamplePlayer* const p)
+static void handleStartEndChange(tSampler* const p)
 {
+    p->len = abs(p->end - p->start);
+    
+    //if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;
+    
     if (p->start > p->end)
     {
         p->flip = -1;
@@ -326,25 +326,21 @@
     }
 }
 
-void tSamplePlayer_setStart     (tSamplePlayer* const p, int32_t start)
+void tSampler_setStart     (tSampler* const p, int32_t start)
 {
     p->start = LEAF_clipInt(0, start, (p->samp->length - 1));
     
-    p->len = abs(p->end - p->start);
-    
     handleStartEndChange(p);
 }
 
-void tSamplePlayer_setEnd       (tSamplePlayer* const p, int32_t end)
+void tSampler_setEnd       (tSampler* const p, int32_t end)
 {
     p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
-
-    p->len = abs(p->end - p->start);
     
     handleStartEndChange(p);
 }
 
-void tSamplePlayer_setRate      (tSamplePlayer* const p, float rate)
+void tSampler_setRate      (tSampler* const p, float rate)
 {
     if (rate < 0.f)
     {
@@ -357,6 +353,7 @@
     }
     
     p->inc = LEAF_clip(0.f, rate, 8.0f);
+    p->iinc = 1.f / p->inc;
 }
 
 
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -23,7 +23,8 @@
 {
     "rate",
     "start",
-    "end"
+    "end",
+    "cfxlen"
 };
 
 std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -16,22 +16,24 @@
 static void leaf_pool_dump(void);
 static void run_pool_test(void);
 
-tSample sample;
+tBuffer sample;
 
-tSamplePlayer player;
+tSampler player;
 
 void    LEAFTest_init            (float sampleRate, int blockSize)
 {
     LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
 
-    tSample_init(&sample, leaf.sampleRate * 4);
+    tBuffer_init(&sample, leaf.sampleRate * 2);
     
-    tSamplePlayer_init(&player, &sample);
-    tSamplePlayer_setMode(&player, Loop);
+    tSampler_init(&player, &sample);
+    tSampler_setMode(&player, Loop);
     
     leaf_pool_report();
     
-    tSample_start(&sample);
+    tBuffer_record(&sample);
+    
+    tSampler_play(&player);
 }
 
 int timer = 0;
@@ -38,16 +40,9 @@
 
 float   LEAFTest_tick            (float input)
 {
-    tSample_tick(&sample, input);
+    tBuffer_tick(&sample, input);
     
-    timer++;
-    
-    if (player.active == 0 && timer >= leaf.sampleRate * 4)
-    {
-        tSamplePlayer_play(&player);
-    }
-    
-    return tSamplePlayer_tick(&player);
+    return tSampler_tick(&player);
 }
 
 bool lastState = false;
@@ -56,26 +51,30 @@
     float val = getSliderValue("rate");
     
     float rate = val * 16.0f - 8.0f;
-    tSamplePlayer_setRate(&player, rate);
+    tSampler_setRate(&player, rate);
     //DBG("rate: " + String(rate));
     
     val = getSliderValue("start");
     float start = val * sample.length;
-    tSamplePlayer_setStart(&player,  start);
+    tSampler_setStart(&player,  start);
     //DBG("start: " + String(start));
     
     val = getSliderValue("end");
     float end = val * sample.length;
-    tSamplePlayer_setEnd(&player, end);
+    tSampler_setEnd(&player, end);
     //DBG("end: " + String(end));
     
+    val = getSliderValue("cfxlen");
+    uint32_t cfxlen = val * 500;
+    tSampler_setCrossfadeLength(&player, cfxlen);
+    DBG("cfxlen: " + String(cfxlen));
+    
     bool state = getButtonState("sample");
     
     if (state && !lastState)
     {
         timer = 0;
-        tSamplePlayer_stop(&player);
-        tSample_start(&sample);
+        tBuffer_record(&sample);
     }
     
     lastState = state;
@@ -142,7 +141,7 @@
     }
     
     leaf_pool_report();
-    
+    
     DBG("ALLOC BUFFER 2");
     size = 25;
     
@@ -154,8 +153,6 @@
     {
         buffer[i] = (float)(i*2);
     }
-    
-    DBG("FREE BUFFER 2");
     leaf_free(buffer);
     
     leaf_pool_report();