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