ref: 866c7c185fdce7993d21d05fbc76a09558c5b4d5
parent: 19a991d12e072f63f39deaa24ae083d6ca417b71
author: spiricom <jeff@snyderphonics.com>
date: Sun Jan 5 16:22:30 EST 2020
fixed sampler and made other changes
binary files a/.DS_Store b/.DS_Store differ
binary files a/LEAF/.DS_Store b/LEAF/.DS_Store differ
binary files a/LEAF/Inc/.DS_Store b/LEAF/Inc/.DS_Store differ
--- a/LEAF/Inc/leaf-effects.h
+++ b/LEAF/Inc/leaf-effects.h
@@ -14,7 +14,7 @@
#endif
//==============================================================================
-
+#include "leaf-dynamics.h"
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-analysis.h"
@@ -241,9 +241,6 @@
//==============================================================================
-#define FORD 7
-#define FORMANT_BUFFER_SIZE 2048
-
typedef struct _tFormantShifter
{
int ford;
@@ -267,6 +264,10 @@
unsigned int cbi;
float shiftFactor;
float intensity, invIntensity;
+ tHighpass hp;
+ tHighpass hp2;
+ tFeedbackLeveler fbl1;
+ tFeedbackLeveler fbl2;
} _tFormantShifter;
--- a/LEAF/Inc/leaf-math.h
+++ b/LEAF/Inc/leaf-math.h
@@ -70,6 +70,8 @@
#define INV_TWO_TO_7 0.0078125f
#define TWO_TO_8 256.f
#define INV_TWO_TO_8 0.00390625f
+#define TWO_TO_9 512.f
+#define INV_TWO_TO_9 0.001953125f
#define TWO_TO_10 1024.f
#define INV_TWO_TO_10 0.0009765625f
#define TWO_TO_11 2048.f
@@ -88,6 +90,9 @@
#define TWO_TO_32 4294967296.0f
#define INV_TWO_TO_32 0.000000000232831f
+
+#define LOGTEN 2.302585092994
+
// Jones shaper
float LEAF_shaper (float input, float m_drive);
float LEAF_reedTable (float input, float offset, float slope);
@@ -119,6 +124,7 @@
// Hermite interpolation
float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);
+ float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx);
float LEAF_interpolation_linear (float A, float B, float t);
float interpolate3max(float *buf, const int peakindex);
@@ -134,8 +140,11 @@
float fastexp2f(float f);
-#define LOGTEN 2.302585092994
+ void LEAF_crossfade(float fade, float* volumes);
+
+
+
float fast_mtof(float f);
float fastexpf(float x);
--- a/LEAF/Inc/leaf-sampling.h
+++ b/LEAF/Inc/leaf-sampling.h
@@ -91,7 +91,7 @@
int32_t end, targetend;
uint32_t len;
uint32_t cfxlen;
-
+ float numticks;
PlayMode mode;
int retrigger;
@@ -116,7 +116,9 @@
void tSampler_setStart (tSampler* const, int32_t start);
void tSampler_setEnd (tSampler* const, int32_t end);
- void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length);
+ static void handleStartEndChange(tSampler* const sp);
+
+ void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
void tSampler_setRate (tSampler* const, float rate);
@@ -129,4 +131,3 @@
#endif // LEAF_SAMPLING_H_INCLUDED
//==============================================================================
-
binary files a/LEAF/Src/.DS_Store b/LEAF/Src/.DS_Store differ
--- a/LEAF/Src/leaf-distortion.c
+++ b/LEAF/Src/leaf-distortion.c
@@ -1,8 +1,8 @@
//
-// leaf-oversampler.c
+// leaf-distortion.c
// LEAF
//
-// Created by Matthew Wang and Joshua Becker on 2/28/19.
+// Created by Jeff Snyder, Matthew Wang, Michael Mulshine, and Joshua Becker
// Copyright © 2019 Princeton University. All rights reserved.
//
@@ -16,6 +16,8 @@
#include "../Inc/leaf-distortion.h"
#include "../Inc/leaf-tables.h"
+//testing
+#include "gpio.h"
#endif
@@ -62,7 +64,7 @@
{
double thresh, w, expw, p, r, s, err;
// Error threshold
- thresh = 10e-10;
+ thresh = 10e-12;
// Initial guess (use previous value)
w = ln;
@@ -77,10 +79,15 @@
err = (p/(r-(p*s)));
if (fabs(err)<thresh) {
+
break;
}
w = w - err;
+ if (i == 999)
+ {
+ //HAL_GPIO_WritePin(GPIOG, GPIO_PIN_7, GPIO_PIN_SET);
+ }
}
return w;
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -645,7 +645,7 @@
_tAutotune* r = *rt;
float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
- if (tempPeriod < 1000.0f) //to avoid trying to follow consonants
+ if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
{
r->inputPeriod = tempPeriod;
}
@@ -1253,6 +1253,7 @@
//============================================================================================================
// FORMANTSHIFTER
//============================================================================================================
+// algorithm from Tom Baran's autotalent code.
void tFormantShifter_init(tFormantShifter* const fsr, int bufsize, int order)
{
@@ -1286,6 +1287,10 @@
fs->cbi = 0;
fs->intensity = 1.0f;
fs->invIntensity = 1.0f;
+ tHighpass_init(&fs->hp, 20.0f);
+ tHighpass_init(&fs->hp2, 20.0f);
+ tFeedbackLeveler_init(&fs->fbl1, 0.8f, .005f, 0.125, 1);
+ tFeedbackLeveler_init(&fs->fbl2, 0.8f, .005f, 0.125, 1);
}
void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1305,6 +1310,10 @@
leaf_free(fs->fbuff[i]);
}
leaf_free(fs->fbuff);
+ tHighpass_free(&fs->hp);
+ tHighpass_free(&fs->hp2);
+ tFeedbackLeveler_free(&fs->fbl1);
+ tFeedbackLeveler_free(&fs->fbl2);
leaf_free(fs);
}
@@ -1317,9 +1326,10 @@
float tFormantShifter_remove(tFormantShifter* const fsr, float in)
{
_tFormantShifter* fs = *fsr;
+ in = tFeedbackLeveler_tick(&fs->fbl1, in);
+ in = tHighpass_tick(&fs->hp, tanhf(in * fs->intensity));
- in *= fs->intensity;
-
+
float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
int ti4;
ford = fs->ford;
@@ -1361,10 +1371,9 @@
{
_tFormantShifter* fs = *fsr;
- float fa, fb, fc, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
+ float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
int ti4;
ford = fs->ford;
- falph = fs->falph;
flpa = fs->flpa;
flamb = fs->flamb;
@@ -1451,7 +1460,9 @@
fs->fmute = (1.0f-tf2) + tf2*fs->fmute;
// now tf is signal output
// ...and we're done messing with formants
-
+ tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
+ //tf = tHighpass_tick(&fs->hp2, tanhf(tf));
+
return tf;
}
@@ -1465,7 +1476,13 @@
void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
{
_tFormantShifter* fs = *fsr;
+
+
+
fs->intensity = intensity;
+
+ tFeedbackLeveler_setTargetLevel(&fs->fbl1, intensity);
+ tFeedbackLeveler_setTargetLevel(&fs->fbl2, intensity);
//make sure you don't divide by zero, doofies
if (fs->intensity != 0.0f)
{
--- a/LEAF/Src/leaf-math.c
+++ b/LEAF/Src/leaf-math.c
@@ -120,6 +120,19 @@
}
}
+
+/*
+you pass in a float array to get back two indexes representing the volumes of the left (index 0) and right (index 1) channels
+when t is -1, volumes[0] = 0, volumes[1] = 1
+when t = 0, volumes[0] = 0.707, volumes[1] = 0.707 (equal-power cross fade)
+when t = 1, volumes[0] = 1, volumes[1] = 0
+*/
+
+void LEAF_crossfade(float fade, float* volumes) {
+ volumes[0] = sqrtf(0.5f * (1.0f + fade));
+ volumes[1] = sqrtf(0.5f * (1.0f - fade));
+}
+
// dope af
float LEAF_chebyshevT(float in, int n){
if (n == 0) return 1;
@@ -363,12 +376,28 @@
{
alpha = LEAF_clip(0.0f, alpha, 1.0f);
- float a = -A/2.0f + (3.0f*B)/2.0f - (3.0f*C)/2.0f + D/2.0f;
- float b = A - (5.0f*B)/2.0f + 2.0f*C - D / 2.0f;
- float c = -A/2.0f + C/2.0f;
+ float a = -A*0.5f + (3.0f*B)*0.5f - (3.0f*C)*0.5f + D*0.5f;
+ float b = A - (5.0f*B)*0.5f + 2.0f*C - D * 0.5f;
+ float c = -A*0.5f + C*0.5f;
float d = B;
return a*alpha*alpha*alpha + b*alpha*alpha + c*alpha + d;
+}
+
+
+// from http://www.musicdsp.org/archive.php?classid=5#93
+//xx is alpha (fractional part of sample value)
+//grabbed this from Tom Erbe's Delay pd code
+float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx)
+{
+ // 4-point, 3rd-order Hermite (x-form)
+ float c0 = yy1;
+ float c1 = 0.5f * (yy2 - yy0);
+ float y0my1 = yy0 - yy1;
+ float c3 = (yy1 - yy2) + 0.5f * (yy3 - y0my1 - yy2);
+ float c2 = y0my1 + c1 - c3;
+
+ return ((c3 * xx + c2) * xx + c1) * xx + c0;
}
// alpha, [0.0, 1.0]
--- a/LEAF/Src/leaf-mempool.c
+++ b/LEAF/Src/leaf-mempool.c
@@ -281,6 +281,6 @@
void leaf_mempool_overrun(void)
{
-
+ //TODO: we should set up some kind of leaf_error method that reaches user space to notify library users of things that failed.
}
--- a/LEAF/Src/leaf-sampling.c
+++ b/LEAF/Src/leaf-sampling.c
@@ -19,6 +19,7 @@
#include "../Inc/leaf-sampling.h"
#include "../leaf.h"
+
#endif
//==============================================================================
@@ -188,28 +189,61 @@
_tSampler* p = *sp;
if (p->active == 0) return 0.f;
-
- if ((p->inc == 0.0f) || (p->len < 4))
+
+ if ((p->inc == 0.0f) || (p->len == 0))
{
- updateStartEnd(sp);
return p->last;
}
-
- // attemptStartEndChange(sp);
-
+
+ attemptStartEndChange(sp);
+
float sample = 0.f;
float cfxsample = 0.f;
float numticks;
float g1 = 1.f, g2 = 0.f;
-
+
float* buff = p->samp->buff;
-
+
int dir = p->bnf * p->dir * p->flip;
int idx, revidx;
float alpha, revalpha;
+
+ int32_t start = p->start, end = p->end;
+ if (p->flip < 0)
+ {
+ start = p->end;
+ end = p->start;
+ }
+ if (p->mode == PlayLoop)
+ {
+
+ while((int)p->idx < start)
+ {
+ p->idx += (float)(p->len);
+ }
+ while((int)p->idx > end)
+ {
+
+ p->idx -= (float)(p->len);
+ }
+ }
+ else // == PlayBackAndForth
+ {
+ if (p->idx < start)
+ {
+ p->bnf = -p->bnf;
+ p->idx = start;
+ }
+ else if (p->idx > end)
+ {
+ p->bnf = -p->bnf;
+ p->idx = end;
+ }
+ }
+
+
-
idx = (int) p->idx;
alpha = p->idx - idx;
@@ -217,157 +251,151 @@
revalpha = 1.f - alpha;
- int32_t start = p->start, end = p->end;
- if (p->flip < 0)
- {
- start = p->end;
- end = p->start;
- }
+
+
uint32_t cfxlen = p->cfxlen;
- if (p->len < cfxlen) cfxlen = 0;//p->len;
+ if (p->len < cfxlen) cfxlen = p->len * 0.25f;//p->len;
int length = p->samp->length;
- // Check dir (direction) to interpolate properly
if (dir > 0)
+ { // num samples (hopping the increment size) to end of loop
+ numticks = (end-idx) * p->iinc;
+ }
+ else
{
- // FORWARD NORMAL SAMPLE
- int i1 = ((idx-1) < 0) ? 0 : idx-1;
- int i3 = ((idx+1) >= length) ? (idx) : (idx+1);
- int i4 = ((idx+2) >= length) ? (length-1) : (idx+2);
-
- sample = LEAF_interpolate_hermite (buff[i1],
- buff[idx],
- buff[i3],
- buff[i4],
- alpha);
-
- // num samples to end of loop
- numticks = (end-idx) * p->iinc;
- // if (numticks > cfxlen)
- // {
- // updateStartEnd(sp);
- // start = p->start;
- // end = p->end;
- // if (p->flip < 0)
- // {
- // start = p->end;
- // end = p->start;
- // }
- // numticks = (end-idx) * p->iinc;
- // }
- //numsamps = (dir > 0) ? (end - idx) : (idx - start);
- //numsamps *= p->iinc;
-
- if (p->mode == PlayLoop)
- {
- if (numticks <= (float) cfxlen)
- {
- // CROSSFADE SAMPLE
- int cdx = start - numticks * p->inc;
- if (cdx < 1)
- {
- cdx = -cdx;
-
- i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
- i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
- i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- revalpha);
- }
- else
- {
- i1 = ((cdx-1) < 0) ? 0 : cdx-1;
- i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
- i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- alpha);
- }
- g2 = (float) (cfxlen - numticks) / (float) cfxlen;
- }
- }
+ numticks = (revidx-start) * p->iinc;
}
+
+
+
+ if (cfxlen > 0) // necessary to avoid divide by zero, also a waste of computation otherwise
+ {
+
+ // Check dir (direction) to interpolate properly
+ if (dir > 0)
+ {
+ // FORWARD NORMAL SAMPLE
+ int i1 = ((idx-1) < 0) ? 0 : idx-1;
+ int i3 = ((idx+1) >= length) ? (idx) : (idx+1);
+ int i4 = ((idx+2) >= length) ? (length-1) : (idx+2);
+
+ sample = LEAF_interpolate_hermite (buff[i1],
+ buff[idx],
+ buff[i3],
+ buff[i4],
+ alpha);
+
+ if (p->mode == PlayLoop)
+ {
+
+
+
+ if (numticks <= (float) cfxlen)
+ {
+ // CROSSFADE SAMPLE
+ int cdx = start - (numticks * p->inc);
+ if (cdx < 1)
+ {
+ cdx = -cdx;
+
+ i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
+ i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
+ i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
+
+ cfxsample = LEAF_interpolate_hermite_x (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ revalpha);
+ }
+ else
+ {
+ i1 = ((cdx-1) < 0) ? 0 : cdx-1;
+ i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
+ i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
+
+ cfxsample = LEAF_interpolate_hermite_x (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ alpha);
+ }
+
+ g2 = (float) (cfxlen - numticks) / (float) cfxlen;
+
+ }
+
+ }
+
+ }
+ else
+ {
+ // REVERSE
+ int i1 = ((revidx+1) >= length) ? (length-1) : revidx+1;
+ int i3 = ((revidx-1) < 0) ? revidx : (revidx-1);
+ int i4 = ((revidx-2) < 0) ? 0 : (revidx-2);
+
+ sample = LEAF_interpolate_hermite_x (buff[i1],
+ buff[revidx],
+ buff[i3],
+ buff[i4],
+ revalpha);
+
+
+
+
+ if (p->mode == PlayLoop)
+ {
+ if (numticks <= (float) cfxlen)
+ {
+ // CROSSFADE SAMPLE
+ int cdx = end + (numticks * p->inc);
+ if (cdx > p->samp->length - 2)
+ {
+ cdx = end - (numticks * p->inc);
+
+ i1 = ((cdx-1) < 0) ? 0 : cdx-1;
+ i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
+ i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
+
+ cfxsample = LEAF_interpolate_hermite_x (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ revalpha);
+ }
+ else
+ {
+ i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
+ i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
+ i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
+
+ cfxsample = LEAF_interpolate_hermite_x (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ alpha);
+ }
+ g2 = (float) (cfxlen - numticks) / (float) cfxlen;
+ }
+ }
+ }
+ }
else
{
- // REVERSE
- int i1 = ((revidx+1) >= length) ? (length-1) : revidx+1;
- int i3 = ((revidx-1) < 0) ? revidx : (revidx-1);
- int i4 = ((revidx-2) < 0) ? 0 : (revidx-2);
-
- sample = LEAF_interpolate_hermite (buff[i1],
- buff[revidx],
- buff[i3],
- buff[i4],
- revalpha);
-
- numticks = (revidx-start) * p->iinc;
-
- // still get clicks i think because updating start/end can put us in the middle of a crossfade
- // if (numticks > cfxlen)
- // {
- // updateStartEnd(sp);
- // start = p->start;
- // end = p->end;
- // if (p->flip < 0)
- // {
- // start = p->end;
- // end = p->start;
- // }
- // numticks = (revidx-start) * p->iinc;
- // }
-
- if (p->mode == PlayLoop)
- {
- if (numticks <= (float) cfxlen)
- {
- // CROSSFADE SAMPLE
- int cdx = end + numticks * p->inc;
- if (cdx > p->samp->length - 2)
- {
- cdx = end - numticks * p->inc;
-
- i1 = ((cdx-1) < 0) ? 0 : cdx-1;
- i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
- i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- alpha);
- }
- else
- {
- i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
- i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
- i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- revalpha);
- }
- g2 = (float) (cfxlen - numticks) / (float) cfxlen;
- }
- }
+ g2 = 0.0f;
}
float inc = fmod(p->inc, p->len);
p->idx += (dir * inc);
-
+
+
+
// attemptStartEndChange(sp);
-
+
if (p->mode == PlayNormal)
{
if (numticks < (0.007f * leaf.sampleRate))
@@ -376,36 +404,7 @@
p->active = -1;
}
}
- else if (p->mode == PlayLoop)
- {
- // mike's suggestion: make sure idx is within bounds of start and end (instead of targetstart/targetend stuff)
- if (idx < start)
- {
- updateStartEnd(sp);
- p->idx += (float)(p->len);
- }
- else if (idx > end)
- {
- updateStartEnd(sp);
- p->idx -= (float)(p->len);
- }
- }
- else // == PlayBackAndForth
- {
- if (p->idx < start)
- {
- updateStartEnd(sp);
- p->bnf = -p->bnf;
- p->idx = start;
- }
- else if (p->idx > end)
- {
- updateStartEnd(sp);
- p->bnf = -p->bnf;
- p->idx = end;
- }
- }
-
+
g1 = 1.f - g2;
sample = sample * g1 + cfxsample * g2;
@@ -440,9 +439,12 @@
}
}
-
+
+
p->last = sample;
+
+
return p->last;
}
@@ -458,7 +460,7 @@
uint32_t cfxlen = LEAF_clip(0, length, 1000);
- //if (cfxlen > p->len) cfxlen = p->len * 0.25f;
+ if (cfxlen > (p->len * 0.25f)) cfxlen = p->len * 0.25f;
p->cfxlen = cfxlen;
}
@@ -491,6 +493,7 @@
if (p->flip > 0) p->idx = p->end;
else p->idx = p->start;
}
+ handleStartEndChange(&p);
}
}
@@ -508,9 +511,9 @@
_tSampler* p = *sp;
p->len = abs(p->end - p->start);
+
+ if (p->len < (p->cfxlen * 0.25f)) p->cfxlen = p->len * 0.25f;
- //if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;
-
if (p->start > p->end)
{
p->flip = -1;
@@ -539,17 +542,26 @@
static void updateStartEnd(tSampler* const sp)
{
_tSampler* p = *sp;
+
+
+
if (p->targetstart >= 0)
{
- p->start = p->targetstart;
- handleStartEndChange(sp);
- p->targetstart = -1;
+ if (p->targetstart != p->end)
+ {
+ p->start = p->targetstart;
+ handleStartEndChange(sp);
+ p->targetstart = -1;
+ }
}
if (p->targetend >= 0)
{
- p->end = p->targetend;
- handleStartEndChange(sp);
- p->targetend = -1;
+ if (p->targetend != p->start)
+ {
+ p->end = p->targetend;
+ handleStartEndChange(sp);
+ p->targetend = -1;
+ }
}
}
@@ -556,22 +568,37 @@
void tSampler_setStart (tSampler* const sp, int32_t start)
{
_tSampler* p = *sp;
-
- if (p->active)
+
+ int tempflip;
+ if (start == p->end)
{
- int dir = p->bnf * p->dir * p->flip;
+ return;
+ }
+ // if (p->active)
+ {
+
+ if (start > p->end)
+ {
+ tempflip = -1;
+ }
+ else
+ {
+ tempflip = 1;
+ }
+
+ int dir = p->bnf * p->dir * tempflip;
uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;
- if (p->flip > 0 && dir > 0) // start is start and we're playing forward
+ if (tempflip > 0 && dir > 0) // start is start and we're playing forward
{
- if ((start > p->idx) || (p->end-p->idx <= cfxlen)) // start given is after current index or we're in a crossfade
+ if (((start > p->idx) || (p->end-p->idx <= cfxlen)) && (start > p->end))// start given is after current index or we're in a crossfade
{
p->targetstart = start;
return;
}
}
- else if (p->flip < 0 && dir < 0) // start is end and we're playing in reverse
+ else if (tempflip < 0 && dir < 0) // start is end and we're playing in reverse
{
- if ((start < p->idx) || (p->idx-p->end <= cfxlen)) // start given is before current index or we're in a crossfade
+ if (((start < p->idx) || (p->idx-p->end <= cfxlen)) && (start < p->end))// start given is before current index or we're in a crossfade
{
p->targetstart = start;
return;
@@ -578,31 +605,48 @@
}
}
}
-
- p->start = LEAF_clipInt(0, start, p->samp->length - 1);
- handleStartEndChange(sp);
- p->targetstart = -1;
+
+ p->start = LEAF_clipInt(0, start, p->samp->length - 1);
+ handleStartEndChange(sp);
+ p->targetstart = -1;
+
}
void tSampler_setEnd (tSampler* const sp, int32_t end)
{
_tSampler* p = *sp;
-
- if (p->active)
+
+ int tempflip;
+
+ if (end == p->start)
{
- int dir = p->bnf * p->dir * p->flip;
+ return;
+ }
+ //if (p->active)
+ {
+
+
+ if (p->start > end)
+ {
+ tempflip = -1;
+ }
+ else
+ {
+ tempflip = 1;
+ }
+ int dir = p->bnf * p->dir * tempflip;
uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;
- if (p->flip > 0 && dir < 0) // end is end and we're playing in reverse
+ if (tempflip > 0 && dir < 0) // end is end and we're playing in reverse
{
- if ((end < p->idx) || (p->idx-p->start <= cfxlen)) // end given is before current index or we're in a crossfade
+ if (((end < p->idx) || (p->idx-p->start <= cfxlen)) && (end < p->start)) // end given is before current index or we're in a crossfade
{
p->targetend = end;
return;
}
}
- else if (p->flip < 0 && dir > 0) // end is start and we're playing forward
+ else if (tempflip < 0 && dir > 0) // end is start and we're playing forward
{
- if ((end > p->idx) || (p->start-p->idx <= cfxlen)) // end given is after current index or we're in a crossfade
+ if (((end > p->idx) || (p->start-p->idx <= cfxlen)) && (end > p->start)) // end given is after current index or we're in a crossfade
{
p->targetend = end;
return;
@@ -609,7 +653,6 @@
}
}
}
-
p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
handleStartEndChange(sp);
p->targetend = -1;
@@ -628,8 +671,8 @@
{
p->dir = 1;
}
-
- p->inc = rate; //LEAF_clip(0.f, rate, 8.0f); any reason to clip this?
+
+ p->inc = rate;
p->iinc = 1.f / p->inc;
}
--- a/LEAF/leaf.h
+++ b/LEAF/leaf.h
@@ -45,6 +45,7 @@
#include "./Inc/leaf-mempool.h"
#include "./Inc/leaf-tables.h"
#include "./Inc/leaf-distortion.h"
+#include "./Inc/leaf-dynamics.h"
#include "./Inc/leaf-oscillators.h"
#include "./Inc/leaf-filters.h"
#include "./Inc/leaf-delay.h"
@@ -51,7 +52,6 @@
#include "./Inc/leaf-reverb.h"
#include "./Inc/leaf-effects.h"
#include "./Inc/leaf-envelopes.h"
-#include "./Inc/leaf-dynamics.h"
#include "./Inc/leaf-analysis.h"
#include "./Inc/leaf-instruments.h"
#include "./Inc/leaf-midi.h"