History

added some fixes to several leaf objects and major bug fix to tSampler

spiricom committed 6 years ago

Commit 23faeb01 parent 53a6d7a10 files · +516 −85Browse files

Unified · Split

10 files
  1. leaf/Inc/leaf-filters.h +4 −1
  2. leaf/Inc/leaf-math.h +7 −0
  3. leaf/Inc/leaf-mempool.h +1 −1
  4. leaf/Inc/leaf-sampling.h +13 −3
  5. leaf/Src/leaf-analysis.c +1 −1
  6. leaf/Src/leaf-effects.c +2 −2
  7. leaf/Src/leaf-filters.c +70 −54
  8. leaf/Src/leaf-math.c +41 −1
  9. leaf/Src/leaf-mempool.c +4 −3
  10. leaf/Src/leaf-sampling.c +373 −19
leaf/Inc/leaf-filters.h+4−1
@@ -1012,13 +1012,16 @@ extern "C" { · 1011 unmodified lines
1012 float tVZFilter_tick (tVZFilter* const, float input);1012 float tVZFilter_tick (tVZFilter* const, float input);
1013 float tVZFilter_tickEfficient (tVZFilter* const vf, float in);1013 float tVZFilter_tickEfficient (tVZFilter* const vf, float in);
1014 void tVZFilter_calcCoeffs (tVZFilter* const);1014 void tVZFilter_calcCoeffs (tVZFilter* const);
1015 void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const);
1015 void tVZFilter_setBandwidth (tVZFilter* const, float bandWidth);1016 void tVZFilter_setBandwidth (tVZFilter* const, float bandWidth);
1016 void tVZFilter_setFreq (tVZFilter* const, float freq);1017 void tVZFilter_setFreq (tVZFilter* const, float freq);
1017 void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw);1018 void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw);
1019 void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw);
1018 void tVZFilter_setGain (tVZFilter* const, float gain);1020 void tVZFilter_setGain (tVZFilter* const, float gain);
1021
1019 void tVZFilter_setType (tVZFilter* const, VZFilterType type);1022 void tVZFilter_setType (tVZFilter* const, VZFilterType type);
1020 float tVZFilter_BandwidthToR (tVZFilter* const vf, float B);1023 float tVZFilter_BandwidthToR (tVZFilter* const vf, float B);
1021 1024 float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B);
1022 1025
1023 /*!1026 /*!
1024 @defgroup tdiodefilter tDiodeFilter1027 @defgroup tdiodefilter tDiodeFilter
leaf/Inc/leaf-math.h+7−0
@@ -138,6 +138,13 @@ extern "C" { · 137 unmodified lines
138 float fastcosf(float fAngle);138 float fastcosf(float fAngle);
139 139
140 float fastercosf(float fAngle);140 float fastercosf(float fAngle);
141
142 float fasttanf (float fAngle);
143
144
145 float fastertanf(float fAngle);
146
147
141 // alternative implementation for abs()148 // alternative implementation for abs()
142 // REQUIRES: 32 bit integers149 // REQUIRES: 32 bit integers
143 int fastabs_int(int in);150 int fastabs_int(int in);
leaf/Inc/leaf-mempool.h+1−1
@@ -112,7 +112,7 @@ extern "C" { · 111 unmodified lines
112 @param size The size of the chuck of memory to be used as a mempool.112 @param size The size of the chuck of memory to be used as a mempool.
113 @param poolTo A pointer to the tMempool to which a tMempool should be initialized.113 @param poolTo A pointer to the tMempool to which a tMempool should be initialized.
114 */114 */
115 void tMempool_initToPool (tMempool* const pool, char* memory, size_t size, tMempool* const poolTo);115 void tMempool_initToPool (tMempool* const mp, char* memory, size_t size, tMempool* const mem, LEAF* const leaf);
116 116
117 /*!117 /*!
118 @} */118 @} */
leaf/Inc/leaf-sampling.h+13−3
@@ -122,6 +122,8 @@ extern "C" { · 121 unmodified lines
122 uint32_t idx;122 uint32_t idx;
123 uint32_t bufferLength;123 uint32_t bufferLength;
124 uint32_t recordedLength;124 uint32_t recordedLength;
125 uint32_t channels;
126 uint32_t sampleRate;
125 RecordMode mode;127 RecordMode mode;
126 128
127 int active;129 int active;
@@ -130,7 +132,7 @@ extern "C" { · 2 unmodified lines
130 typedef _tBuffer* tBuffer;132 typedef _tBuffer* tBuffer;
131 133
132 void tBuffer_init (tBuffer* const, uint32_t length, LEAF* const leaf);134 void tBuffer_init (tBuffer* const, uint32_t length, LEAF* const leaf);
133 void tBuffer_initToPool (tBuffer* const, uint32_t length, tMempool* const);135 void tBuffer_initToPool (tBuffer* const sb, uint32_t length, tMempool* const mp, LEAF* const leaf);
134 void tBuffer_free (tBuffer* const);136 void tBuffer_free (tBuffer* const);
135 137
136 void tBuffer_tick (tBuffer* const, float sample);138 void tBuffer_tick (tBuffer* const, float sample);
@@ -138,6 +140,7 @@ extern "C" { · 1 unmodified line
138 float tBuffer_get (tBuffer* const, int idx);140 float tBuffer_get (tBuffer* const, int idx);
139 void tBuffer_record (tBuffer* const);141 void tBuffer_record (tBuffer* const);
140 void tBuffer_stop (tBuffer* const);142 void tBuffer_stop (tBuffer* const);
143 void tBuffer_setBuffer (tBuffer* const sb, float* externalBuffer, int length, int channels, int sampleRate);
141 int tBuffer_getRecordPosition (tBuffer* const);144 int tBuffer_getRecordPosition (tBuffer* const);
142 void tBuffer_setRecordPosition (tBuffer* const, int pos);145 void tBuffer_setRecordPosition (tBuffer* const, int pos);
143 void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);146 void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
@@ -224,6 +227,12 @@ extern "C" { · 80 unmodified lines
224 227
225 tBuffer samp;228 tBuffer samp;
226 229
230 float leafInvSampleRate;
231 float leafSampleRate;
232 float ticksPerSevenMs;
233 float rateFactor;
234 uint32_t channels;
235
227 tRamp gain;236 tRamp gain;
228 237
229 float idx;238 float idx;
@@ -254,10 +263,11 @@ extern "C" { · 24 unmodified lines
254 typedef _tSampler* tSampler;263 typedef _tSampler* tSampler;
255 264
256 void tSampler_init (tSampler* const, tBuffer* const, LEAF* const leaf);265 void tSampler_init (tSampler* const, tBuffer* const, LEAF* const leaf);
257 void tSampler_initToPool (tSampler* const, tBuffer* const, tMempool* const);266 void tSampler_initToPool (tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf);
258 void tSampler_free (tSampler* const);267 void tSampler_free (tSampler* const);
259 268
260 float tSampler_tick (tSampler* const);269 float tSampler_tick (tSampler* const);
270 float tSampler_tickStereo (tSampler* const sp, float* outputArray);
261 void tSampler_setSample (tSampler* const, tBuffer* const);271 void tSampler_setSample (tSampler* const, tBuffer* const);
262 void tSampler_setMode (tSampler* const, PlayMode mode);272 void tSampler_setMode (tSampler* const, PlayMode mode);
263 void tSampler_play (tSampler* const);273 void tSampler_play (tSampler* const);
@@ -343,7 +353,7 @@ extern "C" { · 79 unmodified lines
343 typedef _tAutoSampler* tAutoSampler;353 typedef _tAutoSampler* tAutoSampler;
344 354
345 void tAutoSampler_init (tAutoSampler* const, tBuffer* const, LEAF* const leaf);355 void tAutoSampler_init (tAutoSampler* const, tBuffer* const, LEAF* const leaf);
346 void tAutoSampler_initToPool (tAutoSampler* const, tBuffer* const, tMempool* const);356 void tAutoSampler_initToPool (tAutoSampler* const as, tBuffer* const b, tMempool* const mp, LEAF* const leaf);
347 void tAutoSampler_free (tAutoSampler* const);357 void tAutoSampler_free (tAutoSampler* const);
348 358
349 float tAutoSampler_tick (tAutoSampler* const, float input);359 float tAutoSampler_tick (tAutoSampler* const, float input);
leaf/Src/leaf-analysis.c+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
10 10
11#include "..\Inc\leaf-analysis.h"11#include "..\Inc\leaf-analysis.h"
12#include "..\Externals\d_fft_mayer.h"12#include "..\Externals\d_fft_mayer.h"
13 13#include <intrin.h>
14#else14#else
15 15
16#include "../Inc/leaf-analysis.h"16#include "../Inc/leaf-analysis.h"
leaf/Src/leaf-effects.c+2−2
@@ -288,7 +288,7 @@ void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int · 287 unmodified lines
288 {288 {
289// for(i=0; i<n; i++)289// for(i=0; i<n; i++)
290// {290// {
291 buf[i] = 0.0f;291 buf[0] = 0.0f;
292 return;292 return;
293// }293// }
294 }294 }
@@ -618,7 +618,7 @@ void tTalkboxFloat_lpc(float *buf, float *car, float* dl, float* Rt, int32_t n, · 323 unmodified lines
618 {618 {
619// for(i=0; i<n; i++)619// for(i=0; i<n; i++)
620// {620// {
621 buf[i] = 0.0f;621 buf[0] = 0.0f;
622 return;622 return;
623// }623// }
624 }624 }
leaf/Src/leaf-filters.c+70−54
@@ -1321,37 +1321,6 @@ float tVZFilter_tickEfficient (tVZFilter* const vf, float in) · 1320 unmodified lines
1321 1321
1322}1322}
1323 1323
1324float tVZFilter_tickEfficientBP (tVZFilter* const vf, float in)
1325{
1326 _tVZFilter* f = *vf;
1327
1328 float yL, yB, yH;
1329
1330 // compute highpass output via Eq. 5.1:
1331 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1332
1333 // compute bandpass output by applying 1st integrator to highpass output:
1334 yB = (f->g*yH) + f->s1;
1335 f->s1 = f->g*yH + yB; // state update in 1st integrator
1336
1337 // compute lowpass output by applying 2nd integrator to bandpass output:
1338 yL = (f->g*yB) + f->s2;
1339 f->s2 = f->g*yB + yL; // state update in 2nd integrator
1340
1341 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1342 //
1343 //seems like that might look like this:
1344 // y = tanh(g*x) + s; // output computation
1345 // s = g*x + y; // state update
1346
1347 //instead of this:
1348 // y = g*x + s; // output computation
1349 // s = g*x + y; // state update
1350
1351 return f->cL*yL + f->cB*yB + f->cH*yH;
1352
1353}
1354
1355 1324
1356void tVZFilter_calcCoeffs (tVZFilter* const vf)1325void tVZFilter_calcCoeffs (tVZFilter* const vf)
1357{1326{
@@ -1458,6 +1427,18 @@ void tVZFilter_calcCoeffs (tVZFilter* const vf) · 100 unmodified lines
1458 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation1427 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1459}1428}
1460 1429
1430void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const vf)
1431{
1432
1433 _tVZFilter* f = *vf;
1434 f->g = fastertanf(PI * f->fc * f->inv_sr); // embedded integrator gain (Fig 3.11)
1435 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1436 f->cB = f->R2;
1437 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1438}
1439
1440
1441
1461 1442
1462void tVZFilter_setBandwidth (tVZFilter* const vf, float B)1443void tVZFilter_setBandwidth (tVZFilter* const vf, float B)
1463{1444{
@@ -1483,14 +1464,28 @@ void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, · 19 unmodified lines
1483 tVZFilter_calcCoeffs(vf);1464 tVZFilter_calcCoeffs(vf);
1484}1465}
1485 1466
1467void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw)
1468{
1469 _tVZFilter* f = *vf;
1470 LEAF* leaf = f->mempool->leaf;
1471
1472 f->B = LEAF_clip(0.0f,bw, 100.0f);
1473 f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
1474 tVZFilter_calcCoeffsEfficientBP(vf);
1475}
1476
1477
1478
1486void tVZFilter_setGain (tVZFilter* const vf, float gain)1479void tVZFilter_setGain (tVZFilter* const vf, float gain)
1487{1480{
1488 _tVZFilter* f = *vf;1481 _tVZFilter* f = *vf;
1489 f->G = LEAF_clip(0.000001f, gain, 100.0f);1482 f->G = LEAF_clip(0.000001f, gain, 4000.0f);
1490 f->invG = 1.0f/f->G;1483 f->invG = 1.0f/f->G;
1491 tVZFilter_calcCoeffs(vf);1484 tVZFilter_calcCoeffs(vf);
1492}1485}
1493 1486
1487
1488
1494void tVZFilter_setMorph (tVZFilter* const vf, float morph)1489void tVZFilter_setMorph (tVZFilter* const vf, float morph)
1495{1490{
1496 _tVZFilter* f = *vf;1491 _tVZFilter* f = *vf;
@@ -1516,6 +1511,18 @@ float tVZFilter_BandwidthToR(tVZFilter* const vf, float B) · 19 unmodified lines
1516 return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));1511 return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1517}1512}
1518 1513
1514float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B)
1515{
1516 _tVZFilter* f = *vf;
1517 float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)
1518 float gl = fastertanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)
1519 float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1520 // unwarped: r = pow(2, -B/2) -> approximation for low
1521 // center-frequencies
1522 return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1523}
1524
1525
1519 1526
1520 1527
1521void tDiodeFilter_init (tDiodeFilter* const vf, float cutoff, float resonance, LEAF* const leaf)1528void tDiodeFilter_init (tDiodeFilter* const vf, float cutoff, float resonance, LEAF* const leaf)
@@ -1557,13 +1564,22 @@ float tanhXdX(float x) · 35 unmodified lines
1557{1564{
1558 float a = x*x;1565 float a = x*x;
1559 // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)1566 // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)
1560 return ((a + 105.0f)*a + 945.0f) / ((15.0f*a + 420.0f)*a + 945.0f);1567 float testVal = ((15.0f*a + 420.0f)*a + 945.0f);
1568 float output = 1.0f;
1569
1570 if (testVal!= 0.0f)
1571 {
1572 output = testVal;
1573
1574 }
1575 return ((a + 105.0f)*a + 945.0f) / output;
1561}1576}
1562 1577
1563float tDiodeFilter_tick (tDiodeFilter* const vf, float in)1578float tDiodeFilter_tick (tDiodeFilter* const vf, float in)
1564{1579{
1565 _tDiodeFilter* f = *vf;1580 _tDiodeFilter* f = *vf;
1566 1581
1582 int errorCheck = 0;
1567 // the input x[n+1] is given by 'in', and x[n] by zi1583 // the input x[n+1] is given by 'in', and x[n] by zi
1568 // input with half delay1584 // input with half delay
1569 float ih = 0.5f * (in + f->zi);1585 float ih = 0.5f * (in + f->zi);
@@ -1579,24 +1595,24 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 9 unmodified lines
1579 1595
1580 // This formula gives the result for y3 thanks to MATLAB1596 // This formula gives the result for y3 thanks to MATLAB
1581 float y3 = (f->s2 + f->s3 + t2*(f->s1 + f->s2 + f->s3 + t1*(f->s0 + f->s1 + f->s2 + f->s3 + t0*in)) + t1*(2.0f*f->s2 + 2.0f*f->s3))*t3 + f->s3 + 2.0f*f->s3*t1 + t2*(2.0f*f->s3 + 3.0f*f->s3*t1);1597 float y3 = (f->s2 + f->s3 + t2*(f->s1 + f->s2 + f->s3 + t1*(f->s0 + f->s1 + f->s2 + f->s3 + t0*in)) + t1*(2.0f*f->s2 + 2.0f*f->s3))*t3 + f->s3 + 2.0f*f->s3*t1 + t2*(2.0f*f->s3 + 3.0f*f->s3*t1);
1582// if (isnan(y3))1598 if (isnan(y3))
1583// {1599 {
1584// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);1600 errorCheck = 1;
1585// }1601 }
1586 float tempy3denom = (t4 + t1*(2.0f*t4 + 4.0f) + t2*(t4 + t1*(t4 + f->r*t0 + 4.0f) + 3.0f) + 2.0f)*t3 + t4 + t1*(2.0f*t4 + 2.0f) + t2*(2.0f*t4 + t1*(3.0f*t4 + 3.0f) + 2.0f) + 1.0f;1602 float tempy3denom = (t4 + t1*(2.0f*t4 + 4.0f) + t2*(t4 + t1*(t4 + f->r*t0 + 4.0f) + 3.0f) + 2.0f)*t3 + t4 + t1*(2.0f*t4 + 2.0f) + t2*(2.0f*t4 + t1*(3.0f*t4 + 3.0f) + 2.0f) + 1.0f;
1587// if (isnan(tempy3denom))1603 if (isnan(tempy3denom))
1588// {1604 {
1589// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);1605 errorCheck = 2;
1590// }1606 }
1591 if (tempy3denom == 0.0f)1607 if (tempy3denom == 0.0f)
1592 {1608 {
1593 tempy3denom = 0.000001f;1609 tempy3denom = 0.000001f;
1594 }1610 }
1595 y3 = y3 / tempy3denom;1611 y3 = y3 / tempy3denom;
1596// if (isnan(y3))1612 if (isnan(y3))
1597// {1613 {
1598// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);1614 errorCheck = 3;
1599// }1615 }
1600 if (t1 == 0.0f)1616 if (t1 == 0.0f)
1601 {1617 {
1602 t1 = 0.000001f;1618 t1 = 0.000001f;
@@ -1617,15 +1633,15 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 14 unmodified lines
1617 1633
1618 // update state1634 // update state
1619 f->s0 += 2.0f * (t0*xx + t1*(y1-y0));1635 f->s0 += 2.0f * (t0*xx + t1*(y1-y0));
1620// if (isnan(f->s0))1636 if (isnan(f->s0))
1621// {1637 {
1622// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);1638 errorCheck = 4;
1623// }1639 }
1624 1640
1625// if (isinf(f->s0))1641 if (isinf(f->s0))
1626// {1642 {
1627// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);1643 errorCheck = 5;
1628// }1644 }
1629 f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));1645 f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));
1630 f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));1646 f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));
1631 f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));1647 f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));
leaf/Src/leaf-math.c+41−1
@@ -99,7 +99,47 @@ float fastercosf(float fAngle) · 98 unmodified lines
99 return fResult;99 return fResult;
100}100}
101 101
102float fasttanf (float fAngle)
103{
104 float fASqr = fAngle*fAngle;
105 float fResult = 9.5168091e-03f;
106 fResult *= fASqr;
107 fResult += 2.900525e-03f;
108 fResult *= fASqr;
109 fResult += 2.45650893e-02f;
110 fResult *= fASqr;
111 fResult += 5.33740603e-02f;
112 fResult *= fASqr;
113 fResult += 1.333923995e-01f;
114 fResult *= fASqr;
115 fResult += 3.333314036e-01f;
116 fResult *= fASqr;
117 fResult += 1.0f;
118 fResult *= fAngle;
119 return fResult;
120}
102 121
122float fastertanf(float fAngle)
123{
124 float fASqr = fAngle*fAngle;
125 float fResult = 2.033e-01f;
126 fResult *= fASqr;
127 fResult += 3.1755e-01f;
128 fResult *= fASqr;
129 fResult += 1.0f;
130 fResult *= fAngle;
131 return fResult;
132}
133
134// from Heng Li, a combination of inverse square root (see wiki) and inversion: https://bits.stephan-brumme.com/inverse.html
135float fastsqrtf(float x)
136{
137 union { float f; uint32_t i; } z = { x };
138 z.i = 0x5f3759df - (z.i >> 1);
139 z.f *= (1.5f - (x * 0.5f * z.f * z.f));
140 z.i = 0x7EEEEEEE - z.i;
141 return z.f;
142}
103 143
104// alternative implementation for abs()144// alternative implementation for abs()
105// REQUIRES: 32 bit integers145// REQUIRES: 32 bit integers
@@ -114,7 +154,7 @@ int fastabs_int(int in){ · 8 unmodified lines
114 154
115// alternative implementation for abs()155// alternative implementation for abs()
116// REQUIRES: 32 bit floats156// REQUIRES: 32 bit floats
117inline float fastabsf(float f)157float fastabsf(float f)
118{158{
119 union159 union
120 {160 {
leaf/Src/leaf-mempool.c+4−3
@@ -410,7 +410,7 @@ static inline void delink_node(mpool_node_t* node) · 409 unmodified lines
410 410
411void tMempool_init(tMempool* const mp, char* memory, size_t size, LEAF* const leaf)411void tMempool_init(tMempool* const mp, char* memory, size_t size, LEAF* const leaf)
412{412{
413 tMempool_initToPool(mp, memory, size, &leaf->mempool);413 tMempool_initToPool(mp, memory, size, &leaf->mempool, leaf);
414}414}
415 415
416void tMempool_free(tMempool* const mp)416void tMempool_free(tMempool* const mp)
@@ -420,10 +420,11 @@ void tMempool_free(tMempool* const mp) · 3 unmodified lines
420 mpool_free((char*)m, m->mempool);420 mpool_free((char*)m, m->mempool);
421}421}
422 422
423void tMempool_initToPool (tMempool* const mp, char* memory, size_t size, tMempool* const mem)423void tMempool_initToPool (tMempool* const mp, char* memory, size_t size, tMempool* const mem, LEAF* const leaf)
424{424{
425 _tMempool* mm = *mem;425 _tMempool* mm = *mem;
426 _tMempool* m = *mp = (_tMempool*) mpool_alloc(sizeof(_tMempool), mm);426 _tMempool* m = *mp = (_tMempool*) mpool_alloc(sizeof(_tMempool), mm);
427 427 m->leaf = leaf;
428 mpool_create (memory, size, m);428 mpool_create (memory, size, m);
429}429}
430
leaf/Src/leaf-sampling.c+373−19
@@ -26,17 +26,18 @@ · 25 unmodified lines
26 26
27void tBuffer_init (tBuffer* const sb, uint32_t length, LEAF* const leaf)27void tBuffer_init (tBuffer* const sb, uint32_t length, LEAF* const leaf)
28{28{
29 tBuffer_initToPool(sb, length, &leaf->mempool);29 tBuffer_initToPool(sb, length, &leaf->mempool, leaf);
30}30}
31 31
32void tBuffer_initToPool (tBuffer* const sb, uint32_t length, tMempool* const mp)32void tBuffer_initToPool (tBuffer* const sb, uint32_t length, tMempool* const mp, LEAF* const leaf)
33{33{
34 _tMempool* m = *mp;34 _tMempool* m = *mp;
35 _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);35 _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);
36 s->mempool = m;36 s->mempool = m;
37 37
38 s->buff = (float*) mpool_alloc( sizeof(float) * length, m);38 s->buff = (float*) mpool_alloc( sizeof(float) * length, m);
39 39 s->sampleRate = leaf->sampleRate;
40 s->channels = 1;
40 s->bufferLength = length;41 s->bufferLength = length;
41 s->recordedLength = 0;42 s->recordedLength = 0;
42 s->active = 0;43 s->active = 0;
@@ -136,6 +137,17 @@ void tBuffer_clear (tBuffer* const sb) · 93 unmodified lines
136 137
137}138}
138 139
140void tBuffer_setBuffer(tBuffer* const sb, float* externalBuffer, int length, int channels, int sampleRate)
141{
142 _tBuffer* s = *sb;
143
144 s->buff = externalBuffer;
145 s->channels = channels;
146 s->sampleRate = sampleRate;
147 s->recordedLength = length/channels;
148 s->bufferLength = s->recordedLength;
149}
150
139uint32_t tBuffer_getBufferLength(tBuffer* const sb)151uint32_t tBuffer_getBufferLength(tBuffer* const sb)
140{152{
141 _tBuffer* s = *sb;153 _tBuffer* s = *sb;
@@ -168,10 +180,10 @@ static void attemptStartEndChange(tSampler* const sp); · 26 unmodified lines
168 180
169void tSampler_init(tSampler* const sp, tBuffer* const b, LEAF* const leaf)181void tSampler_init(tSampler* const sp, tBuffer* const b, LEAF* const leaf)
170{182{
171 tSampler_initToPool(sp, b, &leaf->mempool);183 tSampler_initToPool(sp, b, &leaf->mempool, leaf);
172}184}
173 185
174void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const mp)186void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf)
175{187{
176 _tMempool* m = *mp;188 _tMempool* m = *mp;
177 _tSampler* p = *sp = (_tSampler*) mpool_alloc(sizeof(_tSampler), m);189 _tSampler* p = *sp = (_tSampler*) mpool_alloc(sizeof(_tSampler), m);
@@ -179,18 +191,36 @@ void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const m · 1 unmodified line
179 191
180 _tBuffer* s = *b;192 _tBuffer* s = *b;
181 193
194 p->leafInvSampleRate = leaf->invSampleRate;
195 p->leafSampleRate = leaf->sampleRate;
196 p->ticksPerSevenMs = 0.007f * p->leafSampleRate;
197 p->rateFactor = s->sampleRate * p->leafInvSampleRate;
198 p->channels = s->channels;
199
200
182 p->samp = s;201 p->samp = s;
183 202
184 p->active = 0;203 p->active = 0;
185 204
186 p->start = 0;205 p->start = 0;
187 p->end = 0;206 p->end = p->samp->bufferLength - 1;
188 207
189 p->len = p->end - p->start;208 p->len = p->end - p->start;
190 209
191 p->idx = 0.f;210 p->idx = 0.f;
192 p->inc = 1.f;211 float rate = p->rateFactor; //adjust for sampling rate of buffer (may be different from leaf.sampleRate if audio file was loaded form SD card)
193 p->iinc = 1.f;212 if (rate < 0.f)
213 {
214 rate = -rate;
215 p->dir = -1;
216 }
217 else
218 {
219 p->dir = 1;
220 }
221
222 p->inc = rate;
223 p->iinc = 1.f / p->inc;
194 224
195 p->dir = 1;225 p->dir = 1;
196 p->flip = 1;226 p->flip = 1;
@@ -200,7 +230,7 @@ void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const m · 3 unmodified lines
200 230
201 p->cfxlen = 500; // default 300 sample crossfade231 p->cfxlen = 500; // default 300 sample crossfade
202 232
203 tRamp_initToPool(&p->gain, 7.0f, 1, mp);233 tRamp_initToPool(&p->gain, 5.0f, 1, mp);
204 tRamp_setVal(&p->gain, 0.f);234 tRamp_setVal(&p->gain, 0.f);
205 235
206 p->targetstart = -1;236 p->targetstart = -1;
@@ -226,6 +256,10 @@ void tSampler_setSample (tSampler* const sp, tBuffer* const b) · 19 unmodified lines
226 256
227 p->samp = s;257 p->samp = s;
228 258
259
260 p->rateFactor = s->sampleRate * p->leafInvSampleRate;
261 p->channels = s->channels;
262
229 p->start = 0;263 p->start = 0;
230 p->end = p->samp->bufferLength - 1;264 p->end = p->samp->bufferLength - 1;
231 265
@@ -452,7 +486,7 @@ float tSampler_tick (tSampler* const sp) · 220 unmodified lines
452 p->idx = myEnd;486 p->idx = myEnd;
453 }487 }
454 float ticksToEnd = rev ? ((idx - myStart) * p->iinc) : ((myEnd - idx) * p->iinc);488 float ticksToEnd = rev ? ((idx - myStart) * p->iinc) : ((myEnd - idx) * p->iinc);
455 if (ticksToEnd < (0.007f * leaf->sampleRate))489 if ((ticksToEnd < p->ticksPerSevenMs) && (p->active == 1))
456 {490 {
457 tRamp_setDest(&p->gain, 0.f);491 tRamp_setDest(&p->gain, 0.f);
458 p->active = -1;492 p->active = -1;
@@ -500,6 +534,299 @@ float tSampler_tick (tSampler* const sp) · 41 unmodified lines
500 return p->last;534 return p->last;
501}535}
502 536
537
538float tSampler_tickStereo (tSampler* const sp, float* outputArray)
539{
540 _tSampler* p = *sp;
541 LEAF* leaf = p->mempool->leaf;
542
543 attemptStartEndChange(sp);
544
545 if (p->active == 0) return 0.f;
546
547 if ((p->inc == 0.0f) || (p->len < 2))
548 {
549 // p->inCrossfade = 1;
550 return p->last;
551 }
552
553 float cfxsample[2] = {0.0f, 0.0f};
554 float crossfadeMix = 0.0f;
555 float flipsample[2] = {0.0f, 0.0f};
556 float flipMix = 0.0f;
557
558 float* buff = p->samp->buff;
559
560 // Variables so start is also before end
561 int myStart = p->start;
562 int myEnd = p->end;
563 if (p->flip < 0)
564 {
565 myStart = p->end;
566 myEnd = p->start;
567 }
568
569 // Get the direction and a reverse flag for some calcs
570 int dir = p->bnf * p->dir * p->flip;
571 int rev = 0;
572 if (dir < 0) rev = 1;
573
574 // Get the current integer index and alpha for interpolation
575 int idx = (int) p->idx;
576 float alpha = rev + (p->idx - idx) * dir;
577 idx += rev;
578
579 // Get the indexes for interpolation
580 int i1 = idx-(1*dir);
581 int i2 = idx;
582 int i3 = idx+(1*dir);
583 int i4 = idx+(2*dir);
584
585 int length = p->samp->recordedLength;
586
587 // Wrap as needed
588 i1 = (i1 < length*rev) ? i1 + (length * (1-rev)) : i1 - (length * rev);
589 i2 = (i2 < length*rev) ? i2 + (length * (1-rev)) : i2 - (length * rev);
590 i3 = (i3 < length*(1-rev)) ? i3 + (length * rev) : i3 - (length * (1-rev));
591 i4 = (i4 < length*(1-rev)) ? i4 + (length * rev) : i4 - (length * (1-rev));
592
593 outputArray[0] = LEAF_interpolate_hermite_x (buff[i1 * p->channels],
594 buff[i2 * p->channels],
595 buff[i3 * p->channels],
596 buff[i4 * p->channels],
597 alpha);
598
599 outputArray[1] = LEAF_interpolate_hermite_x (buff[(i1 * p->channels) + 1],
600 buff[(i2 * p->channels) + 1],
601 buff[(i3 * p->channels) + 1],
602 buff[(i4 * p->channels) + 1],
603 alpha);
604
605 int32_t cfxlen = p->cfxlen;
606 if (p->len * 0.25f < cfxlen) cfxlen = p->len * 0.25f;
607
608 // Determine crossfade points
609 int32_t fadeLeftStart = 0;
610 if (myStart >= cfxlen) fadeLeftStart = myStart - cfxlen;
611 int32_t fadeLeftEnd = fadeLeftStart + cfxlen;
612
613 int32_t fadeRightEnd = myEnd;// + (fadeLeftEnd - start);
614 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;
615 int32_t fadeRightStart = fadeRightEnd - cfxlen;
616
617
618
619
620 if (p->mode == PlayLoop)
621 {
622
623 int offset = 0;
624 int cdx = 0;
625 if ((fadeLeftStart <= idx) && (idx <= fadeLeftEnd))
626 {
627 offset = fadeLeftEnd - idx;
628 cdx = fadeRightEnd - offset;
629 p->inCrossfade = 1;
630 }
631 else if ((fadeRightStart <= idx) && (idx <= fadeRightEnd))
632 {
633 offset = idx - fadeRightStart;
634 cdx = fadeLeftStart + offset;
635 p->inCrossfade = 1;
636 }
637 else p->inCrossfade = 0;
638
639 if (p->inCrossfade)
640 {
641 int c1 = cdx-(1*dir);
642 int c2 = cdx;
643 int c3 = cdx+(1*dir);
644 int c4 = cdx+(2*dir);
645
646 // Wrap as needed
647 c1 = (c1 < length * rev) ? c1 + (length * (1-rev)) : c1 - (length * rev);
648 c2 = (c2 < length * rev) ? c2 + (length * (1-rev)) : c2 - (length * rev);
649 c3 = (c3 < length * (1-rev)) ? c3 + (length * rev) : c3 - (length * (1-rev));
650 c4 = (c4 < length * (1-rev)) ? c4 + (length * rev) : c4 - (length * (1-rev));
651
652 cfxsample[0] = LEAF_interpolate_hermite_x (buff[c1 * p->channels],
653 buff[c2 * p->channels],
654 buff[c3 * p->channels],
655 buff[c4 * p->channels],
656 alpha);
657
658 cfxsample[1] = LEAF_interpolate_hermite_x (buff[(c1 * p->channels) + 1],
659 buff[(c2 * p->channels) + 1],
660 buff[(c3 * p->channels) + 1],
661 buff[(c4 * p->channels) + 1],
662 alpha);
663
664 crossfadeMix = (float) offset / (float) cfxlen;
665 }
666
667 float flipLength = fabsf(p->flipIdx - p->flipStart);
668 if (flipLength > cfxlen)
669 {
670 p->flipStart = -1;
671 p->flipIdx = -1;
672 }
673 if (p->flipIdx >= 0)
674 {
675 if (p->flipStart == -1)
676 {
677 p->flipStart = p->idx;
678 p->flipIdx = p->idx;
679 }
680 flipLength = fabsf(p->flipIdx - p->flipStart);
681
682 int fdx = (int) p->flipIdx;
683 float falpha = (1-rev) - (p->flipIdx - fdx) * dir;
684 idx += (1-rev);
685
686 // Get the indexes for interpolation
687 int f1 = fdx+(1*dir);
688 int f2 = fdx;
689 int f3 = fdx-(1*dir);
690 int f4 = fdx-(2*dir);
691
692 // Wrap as needed
693 f1 = (f1 < length*(1-rev)) ? f1 + (length * rev) : f1 - (length * (1-rev));
694 f2 = (f2 < length*(1-rev)) ? f2 + (length * rev) : f2 - (length * (1-rev));
695 f3 = (f3 < length*rev) ? f3 + (length * (1-rev)) : f3 - (length * rev);
696 f4 = (f4 < length*rev) ? f4 + (length * (1-rev)) : f4 - (length * rev);
697
698 flipsample[0] = LEAF_interpolate_hermite_x (buff[f1 * p->channels],
699 buff[f2 * p->channels],
700 buff[f3 * p->channels],
701 buff[f4 * p->channels],
702 falpha);
703
704 flipsample[1] = LEAF_interpolate_hermite_x (buff[(f1 * p->channels) + 1],
705 buff[(f2 * p->channels) + 1],
706 buff[(f3 * p->channels) + 1],
707 buff[(f4 * p->channels) + 1],
708 falpha);
709
710 flipMix = (float) (cfxlen - flipLength) / (float) cfxlen;
711 }
712 }
713
714 float inc = fmodf(p->inc, (float)p->len);
715 p->idx += (dir * inc);
716 if (p->flipStart >= 0)
717 {
718 p->flipIdx += (-dir * inc);
719 if((int)p->flipIdx < 0)
720 {
721 p->idx += (float)length;
722 }
723 if((int)p->idx >= length)
724 {
725
726 p->idx -= (float)length;
727 }
728 }
729
730
731
732 attemptStartEndChange(sp);
733
734
735 if (p->mode == PlayLoop)
736 {
737 if((int)p->idx < myStart)
738 {
739 p->idx += (float)(fadeRightEnd - fadeLeftEnd);
740 }
741 if((int)p->idx > myEnd)
742 {
743
744 p->idx -= (float)(fadeRightEnd - fadeLeftEnd);
745 }
746 }
747 else if (p->mode == PlayBackAndForth)
748 {
749 if (p->idx < myStart)
750 {
751 p->bnf = -p->bnf;
752 p->idx = myStart + 1;
753 }
754 else if (p->idx > myEnd)
755 {
756 p->bnf = -p->bnf;
757 p->idx = myEnd - 1;
758 }
759 }
760
761
762 if (p->mode == PlayNormal)
763 {
764 if (p->idx < myStart)
765 {
766 p->idx = myStart;
767 }
768 else if (p->idx > myEnd)
769 {
770 p->idx = myEnd;
771 }
772 float ticksToEnd = rev ? ((idx - myStart) * p->iinc) : ((myEnd - idx) * p->iinc);
773 if ((ticksToEnd < p->ticksPerSevenMs) && (p->active == 1))
774 {
775 tRamp_setDest(&p->gain, 0.f);
776 p->active = -1;
777 }
778 }
779
780 float sampleGain = tRamp_tick(&p->gain);
781 for (int i = 0; i < p->channels; i++)
782 {
783 outputArray[i] = ((outputArray[i] * (1.0f - crossfadeMix)) + (cfxsample[i] * crossfadeMix)) * (1.0f - flipMix) + (flipsample[i] * flipMix);
784 outputArray[i] = outputArray[i] * sampleGain;
785 }
786
787
788
789
790 if (p->active < 0)
791 {
792 //if was fading out and reached silence
793 if (tRamp_sample(&p->gain) <= 0.0001f)
794 {
795 if (p->retrigger == 1)
796 {
797 p->active = 1;
798 p->retrigger = 0;
799 tRamp_setDest(&p->gain, 1.f);
800
801 if (p->dir > 0)
802 {
803 if (p->flip > 0) p->idx = p->start;
804 else p->idx = p->end;
805 }
806 else
807 {
808 if (p->flip > 0) p->idx = p->end;
809 else p->idx = p->start;
810 }
811 handleStartEndChange(&p);
812 }
813 else
814 {
815 p->active = 0;
816 }
817
818 }
819 }
820
821
822
823 p->last = outputArray[0];
824
825
826 return p->last;
827}
828
829
503void tSampler_setMode (tSampler* const sp, PlayMode mode)830void tSampler_setMode (tSampler* const sp, PlayMode mode)
504{831{
505 _tSampler* p = *sp;832 _tSampler* p = *sp;
@@ -518,14 +845,23 @@ void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length) · 12 unmodified lines
518void tSampler_play (tSampler* const sp)845void tSampler_play (tSampler* const sp)
519{846{
520 _tSampler* p = *sp;847 _tSampler* p = *sp;
521 848
522 if (p->active != 0)849 if (p->active > 0)
523 {850 {
524 p->active = -1;851 p->active = -1;
525 p->retrigger = 1;852 p->retrigger = 1;
526 853
527 tRamp_setDest(&p->gain, 0.f);854 tRamp_setDest(&p->gain, 0.f);
528 }855 }
856
857 else if (p->active < 0)
858 {
859 p->active = -1;
860 p->retrigger = 1;
861
862 //tRamp_setDest(&p->gain, 0.f);
863 }
864
529 else865 else
530 {866 {
531 p->active = 1;867 p->active = 1;
@@ -740,6 +1076,7 @@ void tSampler_setRate (tSampler* const sp, float rate) · 208 unmodified lines
740{1076{
741 _tSampler* p = *sp;1077 _tSampler* p = *sp;
742 1078
1079 rate = rate * p->rateFactor; //adjust for sampling rate of buffer (may be different from leaf.sampleRate if audio file was loaded form SD card)
743 if (rate < 0.f)1080 if (rate < 0.f)
744 {1081 {
745 rate = -rate;1082 rate = -rate;
@@ -758,17 +1095,17 @@ void tSampler_setRate (tSampler* const sp, float rate) · 12 unmodified lines
758 1095
759void tAutoSampler_init (tAutoSampler* const as, tBuffer* const b, LEAF* const leaf)1096void tAutoSampler_init (tAutoSampler* const as, tBuffer* const b, LEAF* const leaf)
760{1097{
761 tAutoSampler_initToPool(as, b, &leaf->mempool);1098 tAutoSampler_initToPool(as, b, &leaf->mempool, leaf);
762}1099}
763 1100
764void tAutoSampler_initToPool (tAutoSampler* const as, tBuffer* const b, tMempool* const mp)1101void tAutoSampler_initToPool (tAutoSampler* const as, tBuffer* const b, tMempool* const mp, LEAF* const leaf)
765{1102{
766 _tMempool* m = *mp;1103 _tMempool* m = *mp;
767 _tAutoSampler* a = *as = (_tAutoSampler*) mpool_alloc(sizeof(_tAutoSampler), m);1104 _tAutoSampler* a = *as = (_tAutoSampler*) mpool_alloc(sizeof(_tAutoSampler), m);
768 a->mempool = m;1105 a->mempool = m;
769 1106
770 tBuffer_setRecordMode(b, RecordOneShot);1107 tBuffer_setRecordMode(b, RecordOneShot);
771 tSampler_initToPool(&a->sampler, b, mp);1108 tSampler_initToPool(&a->sampler, b, mp, leaf);
772 tSampler_setMode(&a->sampler, PlayLoop);1109 tSampler_setMode(&a->sampler, PlayLoop);
773 tEnvelopeFollower_initToPool(&a->ef, 0.05f, 0.9999f, mp);1110 tEnvelopeFollower_initToPool(&a->ef, 0.05f, 0.9999f, mp);
774}1111}
@@ -939,7 +1276,7 @@ float tMBSampler_tick (tMBSampler* const sp) · 164 unmodified lines
939{1276{
940 _tMBSampler* c = *sp;1277 _tMBSampler* c = *sp;
941 1278
942 if (c->gain->curr == 0.0f && !c->active) return 0.0f;1279 if ((c->gain->curr == 0.0f) && (!c->active)) return 0.0f;
943 if (c->_w == 0.0f)1280 if (c->_w == 0.0f)
944 {1281 {
945 c->_last_w = 0.0f;1282 c->_last_w = 0.0f;
@@ -1031,8 +1368,10 @@ float tMBSampler_tick (tMBSampler* const sp) · 85 unmodified lines
1031 float nextSlope = (afterNext - next) / w;1368 float nextSlope = (afterNext - next) / w;
1032 float lastSlope = (last - beforeLast) / w;1369 float lastSlope = (last - beforeLast) / w;
1033 place_slope_dd(c->_f, j, p - start, w, nextSlope - lastSlope);1370 place_slope_dd(c->_f, j, p - start, w, nextSlope - lastSlope);
1034 1371 if (c->mode == PlayNormal)
1035 if (c->mode == PlayNormal) c->active = 0;1372 {
1373 c->active = 0;
1374 }
1036 else if (c->mode == PlayBackAndForth) w = -w;1375 else if (c->mode == PlayBackAndForth) w = -w;
1037 }1376 }
1038// else if (p < (float) start) { /* start has been set ahead of the current phase */1377// else if (p < (float) start) { /* start has been set ahead of the current phase */
@@ -1056,6 +1395,13 @@ float tMBSampler_tick (tMBSampler* const sp) · 17 unmodified lines
1056 int i = (int) f;1395 int i = (int) f;
1057 f -= i;1396 f -= i;
1058 next = buff[i] * (1.0f - f) + buff[i+1] * f;1397 next = buff[i] * (1.0f - f) + buff[i+1] * f;
1398
1399
1400 if ((end - p) < 480) // 480 samples should be enough to let the tExpSmooth go from 1 to 0 (10ms at 48k, 5ms at 192k)
1401 if (c->mode == PlayNormal)
1402 {
1403 tExpSmooth_setDest(&c->gain, 0.0f);
1404 }
1059 }1405 }
1060 1406
1061 if (c->_last_w < 0.0f)1407 if (c->_last_w < 0.0f)
@@ -1095,7 +1441,10 @@ float tMBSampler_tick (tMBSampler* const sp) · 33 unmodified lines
1095 float lastSlope = (last - beforeLast) / w;1441 float lastSlope = (last - beforeLast) / w;
1096 place_slope_dd(c->_f, j, end - p, w, nextSlope - lastSlope);1442 place_slope_dd(c->_f, j, end - p, w, nextSlope - lastSlope);
1097 1443
1098 if (c->mode == PlayNormal) c->active = 0;1444 if (c->mode == PlayNormal)
1445 {
1446 c->active = 0;
1447 }
1099 else if (c->mode == PlayBackAndForth) w = -w;1448 else if (c->mode == PlayBackAndForth) w = -w;
1100 }1449 }
1101// else if (p > (float) end) {1450// else if (p > (float) end) {
@@ -1115,6 +1464,11 @@ float tMBSampler_tick (tMBSampler* const sp) · 13 unmodified lines
1115// }1464// }
1116 else {1465 else {
1117 1466
1467 if ((p - start) < 480) // 480 samples should be enough to let the tExpSmooth go from 1 to 0 (10ms at 48k, 5ms at 192k)
1468 if (c->mode == PlayNormal)
1469 {
1470 tExpSmooth_setDest(&c->gain, 0.0f);
1471 }
1118 float f = p;1472 float f = p;
1119 int i = (int) f;1473 int i = (int) f;
1120 f -= i;1474 f -= i;

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