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;