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();