History

fixed sampler and made other changes

spiricom committed 6 years ago

Commit 866c7c11 parent 19a991d13 files · +330 −223Browse files

Unified · Split

13 files
  1. .DS_Store +0 −0
  2. LEAF/.DS_Store +0 −0
  3. LEAF/Inc/.DS_Store +0 −0
  4. LEAF/Inc/leaf-effects.h +5 −4
  5. LEAF/Inc/leaf-math.h +10 −1
  6. LEAF/Inc/leaf-sampling.h +4 −3
  7. LEAF/Src/.DS_Store +0 −0
  8. LEAF/Src/leaf-distortion.c +10 −3
  9. LEAF/Src/leaf-effects.c +23 −6
  10. LEAF/Src/leaf-math.c +32 −3
  11. LEAF/Src/leaf-mempool.c +1 −1
  12. LEAF/Src/leaf-sampling.c +248 −205
  13. LEAF/leaf.h +1 −1
.DS_Store+0−0

Binary file not shown.

LEAF/.DS_Store+0−0

Binary file not shown.

LEAF/Inc/.DS_Store+0−0

Binary file not shown.

LEAF/Inc/leaf-effects.h+5−4
@@ -14,7 +14,7 @@ extern "C" { · 13 unmodified lines
14#endif14#endif
15 15
16 //==============================================================================16 //==============================================================================
17 17#include "leaf-dynamics.h"
18#include "leaf-global.h"18#include "leaf-global.h"
19#include "leaf-math.h"19#include "leaf-math.h"
20#include "leaf-analysis.h"20#include "leaf-analysis.h"
@@ -241,9 +241,6 @@ extern "C" { · 220 unmodified lines
241 //==============================================================================241 //==============================================================================
242 242
243 243
244#define FORD 7
245#define FORMANT_BUFFER_SIZE 2048
246
247 typedef struct _tFormantShifter244 typedef struct _tFormantShifter
248 {245 {
249 int ford;246 int ford;
@@ -267,6 +264,10 @@ extern "C" { · 17 unmodified lines
267 unsigned int cbi;264 unsigned int cbi;
268 float shiftFactor;265 float shiftFactor;
269 float intensity, invIntensity;266 float intensity, invIntensity;
267 tHighpass hp;
268 tHighpass hp2;
269 tFeedbackLeveler fbl1;
270 tFeedbackLeveler fbl2;
270 271
271 } _tFormantShifter;272 } _tFormantShifter;
272 273
LEAF/Inc/leaf-math.h+10−1
@@ -70,6 +70,8 @@ extern "C" { · 69 unmodified lines
70#define INV_TWO_TO_7 0.0078125f70#define INV_TWO_TO_7 0.0078125f
71#define TWO_TO_8 256.f71#define TWO_TO_8 256.f
72#define INV_TWO_TO_8 0.00390625f72#define INV_TWO_TO_8 0.00390625f
73#define TWO_TO_9 512.f
74#define INV_TWO_TO_9 0.001953125f
73#define TWO_TO_10 1024.f75#define TWO_TO_10 1024.f
74#define INV_TWO_TO_10 0.0009765625f76#define INV_TWO_TO_10 0.0009765625f
75#define TWO_TO_11 2048.f77#define TWO_TO_11 2048.f
@@ -88,6 +90,9 @@ extern "C" { · 12 unmodified lines
88#define TWO_TO_32 4294967296.0f90#define TWO_TO_32 4294967296.0f
89#define INV_TWO_TO_32 0.000000000232831f91#define INV_TWO_TO_32 0.000000000232831f
90 92
93
94#define LOGTEN 2.302585092994
95
91 // Jones shaper96 // Jones shaper
92 float LEAF_shaper (float input, float m_drive);97 float LEAF_shaper (float input, float m_drive);
93 float LEAF_reedTable (float input, float offset, float slope);98 float LEAF_reedTable (float input, float offset, float slope);
@@ -119,6 +124,7 @@ extern "C" { · 25 unmodified lines
119 124
120 // Hermite interpolation125 // Hermite interpolation
121 float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);126 float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);
127 float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx);
122 float LEAF_interpolation_linear (float A, float B, float t);128 float LEAF_interpolation_linear (float A, float B, float t);
123 129
124 float interpolate3max(float *buf, const int peakindex);130 float interpolate3max(float *buf, const int peakindex);
@@ -134,8 +140,11 @@ extern "C" { · 9 unmodified lines
134 140
135 float fastexp2f(float f);141 float fastexp2f(float f);
136 142
137#define LOGTEN 2.302585092994
138 143
144 void LEAF_crossfade(float fade, float* volumes);
145
146
147
139 float fast_mtof(float f);148 float fast_mtof(float f);
140 149
141 float fastexpf(float x);150 float fastexpf(float x);
LEAF/Inc/leaf-sampling.h+4−3
@@ -91,7 +91,7 @@ extern "C" { · 90 unmodified lines
91 int32_t end, targetend;91 int32_t end, targetend;
92 uint32_t len;92 uint32_t len;
93 uint32_t cfxlen;93 uint32_t cfxlen;
94 94 float numticks;
95 PlayMode mode;95 PlayMode mode;
96 int retrigger;96 int retrigger;
97 97
@@ -116,7 +116,9 @@ extern "C" { · 18 unmodified lines
116 void tSampler_setStart (tSampler* const, int32_t start);116 void tSampler_setStart (tSampler* const, int32_t start);
117 void tSampler_setEnd (tSampler* const, int32_t end);117 void tSampler_setEnd (tSampler* const, int32_t end);
118 118
119 void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length);119 static void handleStartEndChange(tSampler* const sp);
120
121 void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
120 122
121 void tSampler_setRate (tSampler* const, float rate);123 void tSampler_setRate (tSampler* const, float rate);
122 124
@@ -129,4 +131,3 @@ extern "C" { · 6 unmodified lines
129#endif // LEAF_SAMPLING_H_INCLUDED131#endif // LEAF_SAMPLING_H_INCLUDED
130 132
131//==============================================================================133//==============================================================================
132
LEAF/Src/.DS_Store+0−0

Binary file not shown.

LEAF/Src/leaf-distortion.c+10−3
@@ -1,8 +1,8 @@
1//1//
2// leaf-oversampler.c2// leaf-distortion.c
3// LEAF3// LEAF
4//4//
5// Created by Matthew Wang and Joshua Becker on 2/28/19.5// Created by Jeff Snyder, Matthew Wang, Michael Mulshine, and Joshua Becker
6// Copyright © 2019 Princeton University. All rights reserved.6// Copyright © 2019 Princeton University. All rights reserved.
7//7//
8 8
@@ -16,6 +16,8 @@ · 7 unmodified lines
16#include "../Inc/leaf-distortion.h"16#include "../Inc/leaf-distortion.h"
17#include "../Inc/leaf-tables.h"17#include "../Inc/leaf-tables.h"
18 18
19//testing
20#include "gpio.h"
19 21
20#endif22#endif
21 23
@@ -62,7 +64,7 @@ double tLockhartWavefolderLambert(double x, double ln) · 40 unmodified lines
62{64{
63 double thresh, w, expw, p, r, s, err;65 double thresh, w, expw, p, r, s, err;
64 // Error threshold66 // Error threshold
65 thresh = 10e-10;67 thresh = 10e-12;
66 // Initial guess (use previous value)68 // Initial guess (use previous value)
67 w = ln;69 w = ln;
68 70
@@ -77,10 +79,15 @@ double tLockhartWavefolderLambert(double x, double ln) · 8 unmodified lines
77 err = (p/(r-(p*s)));79 err = (p/(r-(p*s)));
78 80
79 if (fabs(err)<thresh) {81 if (fabs(err)<thresh) {
82
80 break;83 break;
81 }84 }
82 85
83 w = w - err;86 w = w - err;
87 if (i == 999)
88 {
89 //HAL_GPIO_WritePin(GPIOG, GPIO_PIN_7, GPIO_PIN_SET);
90 }
84 91
85 }92 }
86 return w;93 return w;
LEAF/Src/leaf-effects.c+23−6
@@ -645,7 +645,7 @@ float* tAutotune_tick(tAutotune* const rt, float sample) · 644 unmodified lines
645 _tAutotune* r = *rt;645 _tAutotune* r = *rt;
646 646
647 float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);647 float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
648 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants648 if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
649 {649 {
650 r->inputPeriod = tempPeriod;650 r->inputPeriod = tempPeriod;
651 }651 }
@@ -1253,6 +1253,7 @@ static void solad_init(_tSOLAD* const w) · 601 unmodified lines
1253//============================================================================================================1253//============================================================================================================
1254// FORMANTSHIFTER1254// FORMANTSHIFTER
1255//============================================================================================================1255//============================================================================================================
1256// algorithm from Tom Baran's autotalent code.
1256 1257
1257void tFormantShifter_init(tFormantShifter* const fsr, int bufsize, int order)1258void tFormantShifter_init(tFormantShifter* const fsr, int bufsize, int order)
1258{1259{
@@ -1286,6 +1287,10 @@ void tFormantShifter_init(tFormantShifter* const fsr, int bufsize, int order) · 27 unmodified lines
1286 fs->cbi = 0;1287 fs->cbi = 0;
1287 fs->intensity = 1.0f;1288 fs->intensity = 1.0f;
1288 fs->invIntensity = 1.0f;1289 fs->invIntensity = 1.0f;
1290 tHighpass_init(&fs->hp, 20.0f);
1291 tHighpass_init(&fs->hp2, 20.0f);
1292 tFeedbackLeveler_init(&fs->fbl1, 0.8f, .005f, 0.125, 1);
1293 tFeedbackLeveler_init(&fs->fbl2, 0.8f, .005f, 0.125, 1);
1289}1294}
1290 1295
1291void tFormantShifter_free(tFormantShifter* const fsr)1296void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1305,6 +1310,10 @@ void tFormantShifter_free(tFormantShifter* const fsr) · 13 unmodified lines
1305 leaf_free(fs->fbuff[i]);1310 leaf_free(fs->fbuff[i]);
1306 }1311 }
1307 leaf_free(fs->fbuff);1312 leaf_free(fs->fbuff);
1313 tHighpass_free(&fs->hp);
1314 tHighpass_free(&fs->hp2);
1315 tFeedbackLeveler_free(&fs->fbl1);
1316 tFeedbackLeveler_free(&fs->fbl2);
1308 leaf_free(fs);1317 leaf_free(fs);
1309}1318}
1310 1319
@@ -1317,9 +1326,10 @@ float tFormantShifter_tick(tFormantShifter* const fsr, float in) · 6 unmodified lines
1317float tFormantShifter_remove(tFormantShifter* const fsr, float in)1326float tFormantShifter_remove(tFormantShifter* const fsr, float in)
1318{1327{
1319 _tFormantShifter* fs = *fsr;1328 _tFormantShifter* fs = *fsr;
1329 in = tFeedbackLeveler_tick(&fs->fbl1, in);
1330 in = tHighpass_tick(&fs->hp, tanhf(in * fs->intensity));
1320 1331
1321 in *= fs->intensity;1332
1322
1323 float fa, fb, fc, foma, falph, ford, flamb, tf, fk;1333 float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
1324 int ti4;1334 int ti4;
1325 ford = fs->ford;1335 ford = fs->ford;
@@ -1361,10 +1371,9 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 35 unmodified lines
1361{1371{
1362 _tFormantShifter* fs = *fsr;1372 _tFormantShifter* fs = *fsr;
1363 1373
1364 float fa, fb, fc, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;1374 float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
1365 int ti4;1375 int ti4;
1366 ford = fs->ford;1376 ford = fs->ford;
1367 falph = fs->falph;
1368 1377
1369 flpa = fs->flpa;1378 flpa = fs->flpa;
1370 flamb = fs->flamb;1379 flamb = fs->flamb;
@@ -1451,7 +1460,9 @@ float tFormantShifter_add(tFormantShifter* const fsr, float in) · 80 unmodified lines
1451 fs->fmute = (1.0f-tf2) + tf2*fs->fmute;1460 fs->fmute = (1.0f-tf2) + tf2*fs->fmute;
1452 // now tf is signal output1461 // now tf is signal output
1453 // ...and we're done messing with formants1462 // ...and we're done messing with formants
1454 1463 tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
1464 //tf = tHighpass_tick(&fs->hp2, tanhf(tf));
1465
1455 return tf;1466 return tf;
1456}1467}
1457 1468
@@ -1465,7 +1476,13 @@ void tFormantShifter_setShiftFactor(tFormantShifter* const fsr, float shiftFacto · 7 unmodified lines
1465void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)1476void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
1466{1477{
1467 _tFormantShifter* fs = *fsr;1478 _tFormantShifter* fs = *fsr;
1479
1480
1481
1468 fs->intensity = intensity;1482 fs->intensity = intensity;
1483
1484 tFeedbackLeveler_setTargetLevel(&fs->fbl1, intensity);
1485 tFeedbackLeveler_setTargetLevel(&fs->fbl2, intensity);
1469 //make sure you don't divide by zero, doofies1486 //make sure you don't divide by zero, doofies
1470 if (fs->intensity != 0.0f)1487 if (fs->intensity != 0.0f)
1471 {1488 {
LEAF/Src/leaf-math.c+32−3
@@ -120,6 +120,19 @@ float fastexp2f(float x) · 119 unmodified lines
120 }120 }
121}121}
122 122
123
124/*
125you pass in a float array to get back two indexes representing the volumes of the left (index 0) and right (index 1) channels
126when t is -1, volumes[0] = 0, volumes[1] = 1
127when t = 0, volumes[0] = 0.707, volumes[1] = 0.707 (equal-power cross fade)
128when t = 1, volumes[0] = 1, volumes[1] = 0
129*/
130
131void LEAF_crossfade(float fade, float* volumes) {
132 volumes[0] = sqrtf(0.5f * (1.0f + fade));
133 volumes[1] = sqrtf(0.5f * (1.0f - fade));
134}
135
123// dope af136// dope af
124float LEAF_chebyshevT(float in, int n){137float LEAF_chebyshevT(float in, int n){
125 if (n == 0) return 1;138 if (n == 0) return 1;
@@ -363,14 +376,30 @@ float LEAF_interpolate_hermite (float A, float B, float C, float D, float alpha) · 237 unmodified lines
363{376{
364 alpha = LEAF_clip(0.0f, alpha, 1.0f);377 alpha = LEAF_clip(0.0f, alpha, 1.0f);
365 378
366 float a = -A/2.0f + (3.0f*B)/2.0f - (3.0f*C)/2.0f + D/2.0f;379 float a = -A*0.5f + (3.0f*B)*0.5f - (3.0f*C)*0.5f + D*0.5f;
367 float b = A - (5.0f*B)/2.0f + 2.0f*C - D / 2.0f;380 float b = A - (5.0f*B)*0.5f + 2.0f*C - D * 0.5f;
368 float c = -A/2.0f + C/2.0f;381 float c = -A*0.5f + C*0.5f;
369 float d = B;382 float d = B;
370 383
371 return a*alpha*alpha*alpha + b*alpha*alpha + c*alpha + d;384 return a*alpha*alpha*alpha + b*alpha*alpha + c*alpha + d;
372}385}
373 386
387
388// from http://www.musicdsp.org/archive.php?classid=5#93
389//xx is alpha (fractional part of sample value)
390//grabbed this from Tom Erbe's Delay pd code
391float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx)
392{
393 // 4-point, 3rd-order Hermite (x-form)
394 float c0 = yy1;
395 float c1 = 0.5f * (yy2 - yy0);
396 float y0my1 = yy0 - yy1;
397 float c3 = (yy1 - yy2) + 0.5f * (yy3 - y0my1 - yy2);
398 float c2 = y0my1 + c1 - c3;
399
400 return ((c3 * xx + c2) * xx + c1) * xx + c0;
401}
402
374// alpha, [0.0, 1.0]403// alpha, [0.0, 1.0]
375float LEAF_interpolation_linear (float A, float B, float alpha)404float LEAF_interpolation_linear (float A, float B, float alpha)
376{405{
LEAF/Src/leaf-mempool.c+1−1
@@ -281,6 +281,6 @@ static inline void delink_node(mpool_node_t* node) · 280 unmodified lines
281 281
282void leaf_mempool_overrun(void)282void leaf_mempool_overrun(void)
283{283{
284 284 //TODO: we should set up some kind of leaf_error method that reaches user space to notify library users of things that failed.
285}285}
286 286
LEAF/Src/leaf-sampling.c+248−205
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include "../Inc/leaf-sampling.h"19#include "../Inc/leaf-sampling.h"
20#include "../leaf.h"20#include "../leaf.h"
21 21
22
22#endif23#endif
23 24
24//==============================================================================25//==============================================================================
@@ -188,27 +189,60 @@ float tSampler_tick (tSampler* const sp) · 163 unmodified lines
188 _tSampler* p = *sp;189 _tSampler* p = *sp;
189 190
190 if (p->active == 0) return 0.f;191 if (p->active == 0) return 0.f;
191 192
192 if ((p->inc == 0.0f) || (p->len < 4))193 if ((p->inc == 0.0f) || (p->len == 0))
193 {194 {
194 updateStartEnd(sp);
195 return p->last;195 return p->last;
196 }196 }
197 197
198 // attemptStartEndChange(sp);198 attemptStartEndChange(sp);
199 199
200 float sample = 0.f;200 float sample = 0.f;
201 float cfxsample = 0.f;201 float cfxsample = 0.f;
202 float numticks;202 float numticks;
203 float g1 = 1.f, g2 = 0.f;203 float g1 = 1.f, g2 = 0.f;
204 204
205 float* buff = p->samp->buff;205 float* buff = p->samp->buff;
206 206
207 int dir = p->bnf * p->dir * p->flip;207 int dir = p->bnf * p->dir * p->flip;
208 208
209 int idx, revidx;209 int idx, revidx;
210 float alpha, revalpha;210 float alpha, revalpha;
211 211
212 int32_t start = p->start, end = p->end;
213 if (p->flip < 0)
214 {
215 start = p->end;
216 end = p->start;
217 }
218 if (p->mode == PlayLoop)
219 {
220
221 while((int)p->idx < start)
222 {
223 p->idx += (float)(p->len);
224 }
225 while((int)p->idx > end)
226 {
227
228 p->idx -= (float)(p->len);
229 }
230 }
231 else // == PlayBackAndForth
232 {
233 if (p->idx < start)
234 {
235 p->bnf = -p->bnf;
236 p->idx = start;
237 }
238 else if (p->idx > end)
239 {
240 p->bnf = -p->bnf;
241 p->idx = end;
242 }
243 }
244
245
212 246
213 idx = (int) p->idx;247 idx = (int) p->idx;
214 alpha = p->idx - idx;248 alpha = p->idx - idx;
@@ -217,157 +251,151 @@ float tSampler_tick (tSampler* const sp) · 2 unmodified lines
217 revalpha = 1.f - alpha;251 revalpha = 1.f - alpha;
218 252
219 253
220 int32_t start = p->start, end = p->end;254
221 if (p->flip < 0)255
222 {
223 start = p->end;
224 end = p->start;
225 }
226 256
227 uint32_t cfxlen = p->cfxlen;257 uint32_t cfxlen = p->cfxlen;
228 if (p->len < cfxlen) cfxlen = 0;//p->len;258 if (p->len < cfxlen) cfxlen = p->len * 0.25f;//p->len;
229 259
230 int length = p->samp->length;260 int length = p->samp->length;
231 261
232 // Check dir (direction) to interpolate properly
233 if (dir > 0)262 if (dir > 0)
263 { // num samples (hopping the increment size) to end of loop
264 numticks = (end-idx) * p->iinc;
265 }
266 else
234 {267 {
235 // FORWARD NORMAL SAMPLE268 numticks = (revidx-start) * p->iinc;
236 int i1 = ((idx-1) < 0) ? 0 : idx-1;
237 int i3 = ((idx+1) >= length) ? (idx) : (idx+1);
238 int i4 = ((idx+2) >= length) ? (length-1) : (idx+2);
239
240 sample = LEAF_interpolate_hermite (buff[i1],
241 buff[idx],
242 buff[i3],
243 buff[i4],
244 alpha);
245
246 // num samples to end of loop
247 numticks = (end-idx) * p->iinc;
248 // if (numticks > cfxlen)
249 // {
250 // updateStartEnd(sp);
251 // start = p->start;
252 // end = p->end;
253 // if (p->flip < 0)
254 // {
255 // start = p->end;
256 // end = p->start;
257 // }
258 // numticks = (end-idx) * p->iinc;
259 // }
260 //numsamps = (dir > 0) ? (end - idx) : (idx - start);
261 //numsamps *= p->iinc;
262
263 if (p->mode == PlayLoop)
264 {
265 if (numticks <= (float) cfxlen)
266 {
267 // CROSSFADE SAMPLE
268 int cdx = start - numticks * p->inc;
269 if (cdx < 1)
270 {
271 cdx = -cdx;
272
273 i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
274 i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
275 i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
276
277 cfxsample = LEAF_interpolate_hermite (buff[i1],
278 buff[cdx],
279 buff[i3],
280 buff[i4],
281 revalpha);
282 }
283 else
284 {
285 i1 = ((cdx-1) < 0) ? 0 : cdx-1;
286 i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
287 i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
288
289 cfxsample = LEAF_interpolate_hermite (buff[i1],
290 buff[cdx],
291 buff[i3],
292 buff[i4],
293 alpha);
294 }
295 g2 = (float) (cfxlen - numticks) / (float) cfxlen;
296 }
297 }
298 }269 }
270
271
272
273 if (cfxlen > 0) // necessary to avoid divide by zero, also a waste of computation otherwise
274 {
275
276 // Check dir (direction) to interpolate properly
277 if (dir > 0)
278 {
279 // FORWARD NORMAL SAMPLE
280 int i1 = ((idx-1) < 0) ? 0 : idx-1;
281 int i3 = ((idx+1) >= length) ? (idx) : (idx+1);
282 int i4 = ((idx+2) >= length) ? (length-1) : (idx+2);
283
284 sample = LEAF_interpolate_hermite (buff[i1],
285 buff[idx],
286 buff[i3],
287 buff[i4],
288 alpha);
289
290 if (p->mode == PlayLoop)
291 {
292
293
294
295 if (numticks <= (float) cfxlen)
296 {
297 // CROSSFADE SAMPLE
298 int cdx = start - (numticks * p->inc);
299 if (cdx < 1)
300 {
301 cdx = -cdx;
302
303 i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
304 i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
305 i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
306
307 cfxsample = LEAF_interpolate_hermite_x (buff[i1],
308 buff[cdx],
309 buff[i3],
310 buff[i4],
311 revalpha);
312 }
313 else
314 {
315 i1 = ((cdx-1) < 0) ? 0 : cdx-1;
316 i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
317 i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
318
319 cfxsample = LEAF_interpolate_hermite_x (buff[i1],
320 buff[cdx],
321 buff[i3],
322 buff[i4],
323 alpha);
324 }
325
326 g2 = (float) (cfxlen - numticks) / (float) cfxlen;
327
328 }
329
330 }
331
332 }
333 else
334 {
335 // REVERSE
336 int i1 = ((revidx+1) >= length) ? (length-1) : revidx+1;
337 int i3 = ((revidx-1) < 0) ? revidx : (revidx-1);
338 int i4 = ((revidx-2) < 0) ? 0 : (revidx-2);
339
340 sample = LEAF_interpolate_hermite_x (buff[i1],
341 buff[revidx],
342 buff[i3],
343 buff[i4],
344 revalpha);
345
346
347
348
349 if (p->mode == PlayLoop)
350 {
351 if (numticks <= (float) cfxlen)
352 {
353 // CROSSFADE SAMPLE
354 int cdx = end + (numticks * p->inc);
355 if (cdx > p->samp->length - 2)
356 {
357 cdx = end - (numticks * p->inc);
358
359 i1 = ((cdx-1) < 0) ? 0 : cdx-1;
360 i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
361 i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
362
363 cfxsample = LEAF_interpolate_hermite_x (buff[i1],
364 buff[cdx],
365 buff[i3],
366 buff[i4],
367 revalpha);
368 }
369 else
370 {
371 i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
372 i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
373 i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
374
375 cfxsample = LEAF_interpolate_hermite_x (buff[i1],
376 buff[cdx],
377 buff[i3],
378 buff[i4],
379 alpha);
380 }
381 g2 = (float) (cfxlen - numticks) / (float) cfxlen;
382 }
383 }
384 }
385 }
299 else386 else
300 {387 {
301 // REVERSE388 g2 = 0.0f;
302 int i1 = ((revidx+1) >= length) ? (length-1) : revidx+1;
303 int i3 = ((revidx-1) < 0) ? revidx : (revidx-1);
304 int i4 = ((revidx-2) < 0) ? 0 : (revidx-2);
305
306 sample = LEAF_interpolate_hermite (buff[i1],
307 buff[revidx],
308 buff[i3],
309 buff[i4],
310 revalpha);
311
312 numticks = (revidx-start) * p->iinc;
313
314 // still get clicks i think because updating start/end can put us in the middle of a crossfade
315 // if (numticks > cfxlen)
316 // {
317 // updateStartEnd(sp);
318 // start = p->start;
319 // end = p->end;
320 // if (p->flip < 0)
321 // {
322 // start = p->end;
323 // end = p->start;
324 // }
325 // numticks = (revidx-start) * p->iinc;
326 // }
327
328 if (p->mode == PlayLoop)
329 {
330 if (numticks <= (float) cfxlen)
331 {
332 // CROSSFADE SAMPLE
333 int cdx = end + numticks * p->inc;
334 if (cdx > p->samp->length - 2)
335 {
336 cdx = end - numticks * p->inc;
337
338 i1 = ((cdx-1) < 0) ? 0 : cdx-1;
339 i3 = ((cdx+1) >= length) ? (cdx) : (cdx+1);
340 i4 = ((cdx+2) >= length) ? (length-1) : (cdx+2);
341
342 cfxsample = LEAF_interpolate_hermite (buff[i1],
343 buff[cdx],
344 buff[i3],
345 buff[i4],
346 alpha);
347 }
348 else
349 {
350 i1 = ((cdx+1) >= length) ? (length-1) : cdx+1;
351 i3 = ((cdx-1) < 0) ? cdx : (cdx-1);
352 i4 = ((cdx-2) < 0) ? 0 : (cdx-2);
353
354 cfxsample = LEAF_interpolate_hermite (buff[i1],
355 buff[cdx],
356 buff[i3],
357 buff[i4],
358 revalpha);
359 }
360 g2 = (float) (cfxlen - numticks) / (float) cfxlen;
361 }
362 }
363 }389 }
364 390
365 391
366 float inc = fmod(p->inc, p->len);392 float inc = fmod(p->inc, p->len);
367 p->idx += (dir * inc);393 p->idx += (dir * inc);
368 394
395
396
369 // attemptStartEndChange(sp);397 // attemptStartEndChange(sp);
370 398
371 if (p->mode == PlayNormal)399 if (p->mode == PlayNormal)
372 {400 {
373 if (numticks < (0.007f * leaf.sampleRate))401 if (numticks < (0.007f * leaf.sampleRate))
@@ -376,36 +404,7 @@ float tSampler_tick (tSampler* const sp) · 2 unmodified lines
376 p->active = -1;404 p->active = -1;
377 }405 }
378 }406 }
379 else if (p->mode == PlayLoop)407
380 {
381 // mike's suggestion: make sure idx is within bounds of start and end (instead of targetstart/targetend stuff)
382 if (idx < start)
383 {
384 updateStartEnd(sp);
385 p->idx += (float)(p->len);
386 }
387 else if (idx > end)
388 {
389 updateStartEnd(sp);
390 p->idx -= (float)(p->len);
391 }
392 }
393 else // == PlayBackAndForth
394 {
395 if (p->idx < start)
396 {
397 updateStartEnd(sp);
398 p->bnf = -p->bnf;
399 p->idx = start;
400 }
401 else if (p->idx > end)
402 {
403 updateStartEnd(sp);
404 p->bnf = -p->bnf;
405 p->idx = end;
406 }
407 }
408
409 g1 = 1.f - g2;408 g1 = 1.f - g2;
410 409
411 sample = sample * g1 + cfxsample * g2;410 sample = sample * g1 + cfxsample * g2;
@@ -440,9 +439,12 @@ float tSampler_tick (tSampler* const sp) · 28 unmodified lines
440 439
441 }440 }
442 }441 }
443 442
443
444 p->last = sample;444 p->last = sample;
445 445
446
447
446 return p->last;448 return p->last;
447}449}
448 450
@@ -458,7 +460,7 @@ void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length) · 9 unmodified lines
458 460
459 uint32_t cfxlen = LEAF_clip(0, length, 1000);461 uint32_t cfxlen = LEAF_clip(0, length, 1000);
460 462
461 //if (cfxlen > p->len) cfxlen = p->len * 0.25f;463 if (cfxlen > (p->len * 0.25f)) cfxlen = p->len * 0.25f;
462 464
463 p->cfxlen = cfxlen;465 p->cfxlen = cfxlen;
464}466}
@@ -491,6 +493,7 @@ void tSampler_play (tSampler* const sp) · 26 unmodified lines
491 if (p->flip > 0) p->idx = p->end;493 if (p->flip > 0) p->idx = p->end;
492 else p->idx = p->start;494 else p->idx = p->start;
493 }495 }
496 handleStartEndChange(&p);
494 }497 }
495}498}
496 499
@@ -508,8 +511,8 @@ static void handleStartEndChange(tSampler* const sp) · 11 unmodified lines
508 _tSampler* p = *sp;511 _tSampler* p = *sp;
509 512
510 p->len = abs(p->end - p->start);513 p->len = abs(p->end - p->start);
511 514
512 //if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;515 if (p->len < (p->cfxlen * 0.25f)) p->cfxlen = p->len * 0.25f;
513 516
514 if (p->start > p->end)517 if (p->start > p->end)
515 {518 {
@@ -539,77 +542,117 @@ static void attemptStartEndChange(tSampler* const sp) · 23 unmodified lines
539static void updateStartEnd(tSampler* const sp)542static void updateStartEnd(tSampler* const sp)
540{543{
541 _tSampler* p = *sp;544 _tSampler* p = *sp;
545
546
547
542 if (p->targetstart >= 0)548 if (p->targetstart >= 0)
543 {549 {
544 p->start = p->targetstart;550 if (p->targetstart != p->end)
545 handleStartEndChange(sp);551 {
546 p->targetstart = -1;552 p->start = p->targetstart;
553 handleStartEndChange(sp);
554 p->targetstart = -1;
555 }
547 }556 }
548 if (p->targetend >= 0)557 if (p->targetend >= 0)
549 {558 {
550 p->end = p->targetend;559 if (p->targetend != p->start)
551 handleStartEndChange(sp);560 {
552 p->targetend = -1;561 p->end = p->targetend;
562 handleStartEndChange(sp);
563 p->targetend = -1;
564 }
553 }565 }
554}566}
555 567
556void tSampler_setStart (tSampler* const sp, int32_t start)568void tSampler_setStart (tSampler* const sp, int32_t start)
557{569{
558 _tSampler* p = *sp;570 _tSampler* p = *sp;
559 571
560 if (p->active)572 int tempflip;
573 if (start == p->end)
561 {574 {
562 int dir = p->bnf * p->dir * p->flip;575 return;
576 }
577 // if (p->active)
578 {
579
580 if (start > p->end)
581 {
582 tempflip = -1;
583 }
584 else
585 {
586 tempflip = 1;
587 }
588
589 int dir = p->bnf * p->dir * tempflip;
563 uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;590 uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;
564 if (p->flip > 0 && dir > 0) // start is start and we're playing forward591 if (tempflip > 0 && dir > 0) // start is start and we're playing forward
565 {592 {
566 if ((start > p->idx) || (p->end-p->idx <= cfxlen)) // start given is after current index or we're in a crossfade593 if (((start > p->idx) || (p->end-p->idx <= cfxlen)) && (start > p->end))// start given is after current index or we're in a crossfade
567 {594 {
568 p->targetstart = start;595 p->targetstart = start;
569 return;596 return;
570 }597 }
571 }598 }
572 else if (p->flip < 0 && dir < 0) // start is end and we're playing in reverse599 else if (tempflip < 0 && dir < 0) // start is end and we're playing in reverse
573 {600 {
574 if ((start < p->idx) || (p->idx-p->end <= cfxlen)) // start given is before current index or we're in a crossfade601 if (((start < p->idx) || (p->idx-p->end <= cfxlen)) && (start < p->end))// start given is before current index or we're in a crossfade
575 {602 {
576 p->targetstart = start;603 p->targetstart = start;
577 return;604 return;
578 }605 }
579 }606 }
580 }607 }
581 608
582 p->start = LEAF_clipInt(0, start, p->samp->length - 1);609 p->start = LEAF_clipInt(0, start, p->samp->length - 1);
583 handleStartEndChange(sp);610 handleStartEndChange(sp);
584 p->targetstart = -1;611 p->targetstart = -1;
612
585}613}
586 614
587void tSampler_setEnd (tSampler* const sp, int32_t end)615void tSampler_setEnd (tSampler* const sp, int32_t end)
588{616{
589 _tSampler* p = *sp;617 _tSampler* p = *sp;
590 618
591 if (p->active)619 int tempflip;
620
621 if (end == p->start)
592 {622 {
593 int dir = p->bnf * p->dir * p->flip;623 return;
624 }
625 //if (p->active)
626 {
627
628
629 if (p->start > end)
630 {
631 tempflip = -1;
632 }
633 else
634 {
635 tempflip = 1;
636 }
637 int dir = p->bnf * p->dir * tempflip;
594 uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;638 uint32_t cfxlen = (p->len < p->cfxlen) ? 0 : p->cfxlen;
595 if (p->flip > 0 && dir < 0) // end is end and we're playing in reverse639 if (tempflip > 0 && dir < 0) // end is end and we're playing in reverse
596 {640 {
597 if ((end < p->idx) || (p->idx-p->start <= cfxlen)) // end given is before current index or we're in a crossfade641 if (((end < p->idx) || (p->idx-p->start <= cfxlen)) && (end < p->start)) // end given is before current index or we're in a crossfade
598 {642 {
599 p->targetend = end;643 p->targetend = end;
600 return;644 return;
601 }645 }
602 }646 }
603 else if (p->flip < 0 && dir > 0) // end is start and we're playing forward647 else if (tempflip < 0 && dir > 0) // end is start and we're playing forward
604 {648 {
605 if ((end > p->idx) || (p->start-p->idx <= cfxlen)) // end given is after current index or we're in a crossfade649 if (((end > p->idx) || (p->start-p->idx <= cfxlen)) && (end > p->start)) // end given is after current index or we're in a crossfade
606 {650 {
607 p->targetend = end;651 p->targetend = end;
608 return;652 return;
609 }653 }
610 }654 }
611 }655 }
612
613 p->end = LEAF_clipInt(0, end, (p->samp->length - 1));656 p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
614 handleStartEndChange(sp);657 handleStartEndChange(sp);
615 p->targetend = -1;658 p->targetend = -1;
@@ -628,8 +671,8 @@ void tSampler_setRate (tSampler* const sp, float rate) · 12 unmodified lines
628 {671 {
629 p->dir = 1;672 p->dir = 1;
630 }673 }
631 674
632 p->inc = rate; //LEAF_clip(0.f, rate, 8.0f); any reason to clip this?675 p->inc = rate;
633 p->iinc = 1.f / p->inc;676 p->iinc = 1.f / p->inc;
634}677}
635 678
LEAF/leaf.h+1−1
@@ -45,13 +45,13 @@ · 44 unmodified lines
45#include "./Inc/leaf-mempool.h"45#include "./Inc/leaf-mempool.h"
46#include "./Inc/leaf-tables.h"46#include "./Inc/leaf-tables.h"
47#include "./Inc/leaf-distortion.h"47#include "./Inc/leaf-distortion.h"
48#include "./Inc/leaf-dynamics.h"
48#include "./Inc/leaf-oscillators.h"49#include "./Inc/leaf-oscillators.h"
49#include "./Inc/leaf-filters.h"50#include "./Inc/leaf-filters.h"
50#include "./Inc/leaf-delay.h"51#include "./Inc/leaf-delay.h"
51#include "./Inc/leaf-reverb.h"52#include "./Inc/leaf-reverb.h"
52#include "./Inc/leaf-effects.h"53#include "./Inc/leaf-effects.h"
53#include "./Inc/leaf-envelopes.h"54#include "./Inc/leaf-envelopes.h"
54#include "./Inc/leaf-dynamics.h"
55#include "./Inc/leaf-analysis.h"55#include "./Inc/leaf-analysis.h"
56#include "./Inc/leaf-instruments.h"56#include "./Inc/leaf-instruments.h"
57#include "./Inc/leaf-midi.h"57#include "./Inc/leaf-midi.h"

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t