History

fixing file organization

Matthew Wang committed 6 years ago

Commit 5dc1c251 parent cf5c3f252 files · +54 −35876Browse files

Unified · Split

52 files
  1. .DS_Store +0 −0
  2. LEAF/.DS_Store +0 −0
  3. LEAF/.gitignore +0 −11
  4. LEAF/Externals/.DS_Store +0 −0
  5. LEAF/Externals/d_fft_mayer.c +0 −423
  6. LEAF/Externals/d_fft_mayer.h +0 −31
  7. LEAF/Externals/trigtbl.h +0 −173
  8. LEAF/Inc/leaf-analysis.h +0 −296
  9. LEAF/Inc/leaf-delay.h +0 −229
  10. LEAF/Inc/leaf-distortion.h +0 −164
  11. LEAF/Inc/leaf-dynamics.h +0 −122
  12. LEAF/Inc/leaf-effects.h +0 −360
  13. LEAF/Inc/leaf-electrical.h +0 −103
  14. LEAF/Inc/leaf-envelopes.h +0 −366
  15. LEAF/Inc/leaf-filters.h +0 −486
  16. LEAF/Inc/leaf-global.h +0 −52
  17. LEAF/Inc/leaf-instruments.h +0 −209
  18. LEAF/Inc/leaf-math.h +0 −212
  19. LEAF/Inc/leaf-mempool.h +0 −159
  20. LEAF/Inc/leaf-midi.h +0 −510
  21. LEAF/Inc/leaf-oscillators.h +0 −1143
  22. LEAF/Inc/leaf-physical.h +0 −259
  23. LEAF/Inc/leaf-reverb.h +0 −175
  24. LEAF/Inc/leaf-sampling.h +0 −188
  25. LEAF/Inc/leaf-tables.h +0 −104
  26. LEAF/Src/leaf-analysis.c +0 −1054
  27. LEAF/Src/leaf-delay.c +0 −928
  28. LEAF/Src/leaf-distortion.c +0 −695
  29. LEAF/Src/leaf-dynamics.c +0 −281
  30. LEAF/Src/leaf-effects.c +0 −1853
  31. LEAF/Src/leaf-electrical.c +0 −551
  32. LEAF/Src/leaf-envelopes.c +0 −1612
  33. LEAF/Src/leaf-filters.c +0 −1802
  34. LEAF/Src/leaf-instruments.c +0 −706
  35. LEAF/Src/leaf-math.c +0 −655
  36. LEAF/Src/leaf-mempool.c +0 −412
  37. LEAF/Src/leaf-midi.c +0 −980
  38. LEAF/Src/leaf-oscillators.c +0 −1660
  39. LEAF/Src/leaf-physical.c +0 −747
  40. LEAF/Src/leaf-reverb.c +0 −925
  41. LEAF/Src/leaf-sampling.c +0 −866
  42. LEAF/Src/leaf-tables.c +0 −14061
  43. LEAF/Src/leaf.c +0 −60
  44. LEAF/leaf.cpp +0 −45
  45. LEAF/leaf.h +0 −154
  46. LEAF_JUCEPlugin/.DS_Store +0 −0
  47. LEAF_JUCEPlugin/LEAF.jucer +59 −59
  48. LEAF_JUCEPlugin/Source/.DS_Store +0 −0
  49. LEAF_JUCEPlugin/Source/LEAFTest.h +1 −1
  50. leaf/.DS_Store +0 −0
  51. leaf/Externals/.DS_Store +0 −0
  52. leaf/leaf.h +1 −1
.DS_Store+0−0

Binary file not shown.

LEAF/.DS_Store+0−0

Binary file not shown.

LEAF/.gitignore+0−11
@@ -1,11 +0,0 @@
1−*.DS_Store
2−*.app
3−*.a
4−*.appex
5−*.vst
6−*.vst3
7−*.component
8−*.xcuserstate
9−*.zip
10−*.swp
11−*/Builds
LEAF/Externals/.DS_Store+0−0

Binary file not shown.

LEAF/Externals/d_fft_mayer.c+0−423
@@ -1,423 +0,0 @@
1−/*
2−** FFT and FHT routines
3−** Copyright 1988, 1993; Ron Mayer
4−**
5−** mayer_fht(fz,n);
6−** Does a hartley transform of "n" points in the array "fz".
7−** mayer_fft(n,real,imag)
8−** Does a fourier transform of "n" points of the "real" and
9−** "imag" arrays.
10−** mayer_ifft(n,real,imag)
11−** Does an inverse fourier transform of "n" points of the "real"
12−** and "imag" arrays.
13−** mayer_realfft(n,real)
14−** Does a real-valued fourier transform of "n" points of the
15−** "real" array. The real part of the transform ends
16−** up in the first half of the array and the imaginary part of the
17−** transform ends up in the second half of the array.
18−** mayer_realifft(n,real)
19−** The inverse of the realfft() routine above.
20−**
21−**
22−** NOTE: This routine uses at least 2 patented algorithms, and may be
23−** under the restrictions of a bunch of different organizations.
24−** Although I wrote it completely myself, it is kind of a derivative
25−** of a routine I once authored and released under the GPL, so it
26−** may fall under the free software foundation's restrictions;
27−** it was worked on as a Stanford Univ project, so they claim
28−** some rights to it; it was further optimized at work here, so
29−** I think this company claims parts of it. The patents are
30−** held by R. Bracewell (the FHT algorithm) and O. Buneman (the
31−** trig generator), both at Stanford Univ.
32−** If it were up to me, I'd say go do whatever you want with it;
33−** but it would be polite to give credit to the following people
34−** if you use this anywhere:
35−** Euler - probable inventor of the fourier transform.
36−** Gauss - probable inventor of the FFT.
37−** Hartley - probable inventor of the hartley transform.
38−** Buneman - for a really cool trig generator
39−** Mayer(me) - for authoring this particular version and
40−** including all the optimizations in one package.
41−** Thanks,
42−** Ron Mayer; mayer@acuson.com
43−**
44−*/
45−
46−/* This is a slightly modified version of Mayer's contribution; write
47−* msp@ucsd.edu for the original code. Kudos to Mayer for a fine piece
48−* of work. -msp
49−*/
50−
51−/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */
52−#ifdef _MSC_VER
53−#pragma warning( disable : 4305 ) /* uncast const double to float */
54−#pragma warning( disable : 4244 ) /* uncast double to float */
55−#pragma warning( disable : 4101 ) /* unused local variables */
56−#endif
57−
58−/* the following is needed only to declare pd_fft() as exportable in MSW */
59−#define t_sample float
60−
61−#define REAL t_sample
62−#define GOOD_TRIG
63−
64−#ifdef GOOD_TRIG
65−#else
66−#define FAST_TRIG
67−#endif
68−
69−#if defined(GOOD_TRIG)
70−#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
71−#define TRIG_VARS \
72− int t_lam=0;
73−#define TRIG_INIT(k,c,s) \
74− { \
75− int i; \
76− for (i=2 ; i<=k ; i++) \
77− {coswrk[i]=costab[i];sinwrk[i]=sintab[i];} \
78− t_lam = 0; \
79− c = 1; \
80− s = 0; \
81− }
82−#define TRIG_NEXT(k,c,s) \
83− { \
84− int i,j; \
85− (t_lam)++; \
86− for (i=0 ; !((1<<i)&t_lam) ; i++); \
87− i = k-i; \
88− s = sinwrk[i]; \
89− c = coswrk[i]; \
90− if (i>1) \
91− { \
92− for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
93− j = k - j; \
94− sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
95− coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
96− } \
97− }
98−#define TRIG_RESET(k,c,s)
99−#endif
100−
101−#if defined(FAST_TRIG)
102−#define TRIG_VARS \
103− REAL t_c,t_s;
104−#define TRIG_INIT(k,c,s) \
105− { \
106− t_c = costab[k]; \
107− t_s = sintab[k]; \
108− c = 1; \
109− s = 0; \
110− }
111−#define TRIG_NEXT(k,c,s) \
112− { \
113− REAL t = c; \
114− c = t*t_c - s*t_s; \
115− s = t*t_s + s*t_c; \
116− }
117−#define TRIG_RESET(k,c,s)
118−#endif
119−
120−static REAL halsec[20]=
121− {
122− 0,
123− 0,
124− .54119610014619698439972320536638942006107206337801,
125− .50979557910415916894193980398784391368261849190893,
126− .50241928618815570551167011928012092247859337193963,
127− .50060299823519630134550410676638239611758632599591,
128− .50015063602065098821477101271097658495974913010340,
129− .50003765191554772296778139077905492847503165398345,
130− .50000941253588775676512870469186533538523133757983,
131− .50000235310628608051401267171204408939326297376426,
132− .50000058827484117879868526730916804925780637276181,
133− .50000014706860214875463798283871198206179118093251,
134− .50000003676714377807315864400643020315103490883972,
135− .50000000919178552207366560348853455333939112569380,
136− .50000000229794635411562887767906868558991922348920,
137− .50000000057448658687873302235147272458812263401372
138− };
139−static REAL costab[20]=
140− {
141− .00000000000000000000000000000000000000000000000000,
142− .70710678118654752440084436210484903928483593768847,
143− .92387953251128675612818318939678828682241662586364,
144− .98078528040323044912618223613423903697393373089333,
145− .99518472667219688624483695310947992157547486872985,
146− .99879545620517239271477160475910069444320361470461,
147− .99969881869620422011576564966617219685006108125772,
148− .99992470183914454092164649119638322435060646880221,
149− .99998117528260114265699043772856771617391725094433,
150− .99999529380957617151158012570011989955298763362218,
151− .99999882345170190992902571017152601904826792288976,
152− .99999970586288221916022821773876567711626389934930,
153− .99999992646571785114473148070738785694820115568892,
154− .99999998161642929380834691540290971450507605124278,
155− .99999999540410731289097193313960614895889430318945,
156− .99999999885102682756267330779455410840053741619428
157− };
158−static REAL sintab[20]=
159− {
160− 1.0000000000000000000000000000000000000000000000000,
161− .70710678118654752440084436210484903928483593768846,
162− .38268343236508977172845998403039886676134456248561,
163− .19509032201612826784828486847702224092769161775195,
164− .09801714032956060199419556388864184586113667316749,
165− .04906767432741801425495497694268265831474536302574,
166− .02454122852291228803173452945928292506546611923944,
167− .01227153828571992607940826195100321214037231959176,
168− .00613588464915447535964023459037258091705788631738,
169− .00306795676296597627014536549091984251894461021344,
170− .00153398018628476561230369715026407907995486457522,
171− .00076699031874270452693856835794857664314091945205,
172− .00038349518757139558907246168118138126339502603495,
173− .00019174759731070330743990956198900093346887403385,
174− .00009587379909597734587051721097647635118706561284,
175− .00004793689960306688454900399049465887274686668768
176− };
177−static REAL coswrk[20]=
178− {
179− .00000000000000000000000000000000000000000000000000,
180− .70710678118654752440084436210484903928483593768847,
181− .92387953251128675612818318939678828682241662586364,
182− .98078528040323044912618223613423903697393373089333,
183− .99518472667219688624483695310947992157547486872985,
184− .99879545620517239271477160475910069444320361470461,
185− .99969881869620422011576564966617219685006108125772,
186− .99992470183914454092164649119638322435060646880221,
187− .99998117528260114265699043772856771617391725094433,
188− .99999529380957617151158012570011989955298763362218,
189− .99999882345170190992902571017152601904826792288976,
190− .99999970586288221916022821773876567711626389934930,
191− .99999992646571785114473148070738785694820115568892,
192− .99999998161642929380834691540290971450507605124278,
193− .99999999540410731289097193313960614895889430318945,
194− .99999999885102682756267330779455410840053741619428
195− };
196−static REAL sinwrk[20]=
197− {
198− 1.0000000000000000000000000000000000000000000000000,
199− .70710678118654752440084436210484903928483593768846,
200− .38268343236508977172845998403039886676134456248561,
201− .19509032201612826784828486847702224092769161775195,
202− .09801714032956060199419556388864184586113667316749,
203− .04906767432741801425495497694268265831474536302574,
204− .02454122852291228803173452945928292506546611923944,
205− .01227153828571992607940826195100321214037231959176,
206− .00613588464915447535964023459037258091705788631738,
207− .00306795676296597627014536549091984251894461021344,
208− .00153398018628476561230369715026407907995486457522,
209− .00076699031874270452693856835794857664314091945205,
210− .00038349518757139558907246168118138126339502603495,
211− .00019174759731070330743990956198900093346887403385,
212− .00009587379909597734587051721097647635118706561284,
213− .00004793689960306688454900399049465887274686668768
214− };
215−
216−
217−#define SQRT2_2 0.70710678118654752440084436210484
218−#define SQRT2 2*0.70710678118654752440084436210484
219−
220−void mayer_fht(REAL *fz, int n)
221−{
222−/* REAL a,b;
223−REAL c1,s1,s2,c2,s3,c3,s4,c4;
224− REAL f0,g0,f1,g1,f2,g2,f3,g3; */
225− int k,k1,k2,k3,k4,kx;
226− REAL *fi,*fn,*gi;
227− TRIG_VARS;
228−
229− for (k1=1,k2=0;k1<n;k1++)
230− {
231− REAL aa;
232− for (k=n>>1; (!((k2^=k)&k)); k>>=1);
233− if (k1>k2)
234− {
235− aa=fz[k1];fz[k1]=fz[k2];fz[k2]=aa;
236− }
237− }
238− for ( k=0 ; (1<<k)<n ; k++ );
239− k &= 1;
240− if (k==0)
241− {
242− for (fi=fz,fn=fz+n;fi<fn;fi+=4)
243− {
244− REAL f0,f1,f2,f3;
245− f1 = fi[0 ]-fi[1 ];
246− f0 = fi[0 ]+fi[1 ];
247− f3 = fi[2 ]-fi[3 ];
248− f2 = fi[2 ]+fi[3 ];
249− fi[2 ] = (f0-f2);
250− fi[0 ] = (f0+f2);
251− fi[3 ] = (f1-f3);
252− fi[1 ] = (f1+f3);
253− }
254− }
255− else
256− {
257− for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
258− {
259− REAL bs1,bc1,bs2,bc2,bs3,bc3,bs4,bc4,
260− bg0,bf0,bf1,bg1,bf2,bg2,bf3,bg3;
261− bc1 = fi[0 ] - gi[0 ];
262− bs1 = fi[0 ] + gi[0 ];
263− bc2 = fi[2 ] - gi[2 ];
264− bs2 = fi[2 ] + gi[2 ];
265− bc3 = fi[4 ] - gi[4 ];
266− bs3 = fi[4 ] + gi[4 ];
267− bc4 = fi[6 ] - gi[6 ];
268− bs4 = fi[6 ] + gi[6 ];
269− bf1 = (bs1 - bs2);
270− bf0 = (bs1 + bs2);
271− bg1 = (bc1 - bc2);
272− bg0 = (bc1 + bc2);
273− bf3 = (bs3 - bs4);
274− bf2 = (bs3 + bs4);
275− bg3 = SQRT2*bc4;
276− bg2 = SQRT2*bc3;
277− fi[4 ] = bf0 - bf2;
278− fi[0 ] = bf0 + bf2;
279− fi[6 ] = bf1 - bf3;
280− fi[2 ] = bf1 + bf3;
281− gi[4 ] = bg0 - bg2;
282− gi[0 ] = bg0 + bg2;
283− gi[6 ] = bg1 - bg3;
284− gi[2 ] = bg1 + bg3;
285− }
286− }
287− if (n<16) return;
288−
289− do
290− {
291− REAL s1,c1;
292− int ii;
293− k += 2;
294− k1 = 1 << k;
295− k2 = k1 << 1;
296− k4 = k2 << 1;
297− k3 = k2 + k1;
298− kx = k1 >> 1;
299− fi = fz;
300− gi = fi + kx;
301− fn = fz + n;
302− do
303− {
304− REAL g0,f0,f1,g1,f2,g2,f3,g3;
305− f1 = fi[0 ] - fi[k1];
306− f0 = fi[0 ] + fi[k1];
307− f3 = fi[k2] - fi[k3];
308− f2 = fi[k2] + fi[k3];
309− fi[k2] = f0 - f2;
310− fi[0 ] = f0 + f2;
311− fi[k3] = f1 - f3;
312− fi[k1] = f1 + f3;
313− g1 = gi[0 ] - gi[k1];
314− g0 = gi[0 ] + gi[k1];
315− g3 = SQRT2 * gi[k3];
316− g2 = SQRT2 * gi[k2];
317− gi[k2] = g0 - g2;
318− gi[0 ] = g0 + g2;
319− gi[k3] = g1 - g3;
320− gi[k1] = g1 + g3;
321− gi += k4;
322− fi += k4;
323− } while (fi<fn);
324− TRIG_INIT(k,c1,s1);
325− for (ii=1;ii<kx;ii++)
326− {
327− REAL c2,s2;
328− TRIG_NEXT(k,c1,s1);
329− c2 = c1*c1 - s1*s1;
330− s2 = 2*(c1*s1);
331− fn = fz + n;
332− fi = fz +ii;
333− gi = fz +k1-ii;
334− do
335− {
336− REAL a,b,g0,f0,f1,g1,f2,g2,f3,g3;
337− b = s2*fi[k1] - c2*gi[k1];
338− a = c2*fi[k1] + s2*gi[k1];
339− f1 = fi[0 ] - a;
340− f0 = fi[0 ] + a;
341− g1 = gi[0 ] - b;
342− g0 = gi[0 ] + b;
343− b = s2*fi[k3] - c2*gi[k3];
344− a = c2*fi[k3] + s2*gi[k3];
345− f3 = fi[k2] - a;
346− f2 = fi[k2] + a;
347− g3 = gi[k2] - b;
348− g2 = gi[k2] + b;
349− b = s1*f2 - c1*g3;
350− a = c1*f2 + s1*g3;
351− fi[k2] = f0 - a;
352− fi[0 ] = f0 + a;
353− gi[k3] = g1 - b;
354− gi[k1] = g1 + b;
355− b = c1*g2 - s1*f3;
356− a = s1*g2 + c1*f3;
357− gi[k2] = g0 - a;
358− gi[0 ] = g0 + a;
359− fi[k3] = f1 - b;
360− fi[k1] = f1 + b;
361− gi += k4;
362− fi += k4;
363− } while (fi<fn);
364− }
365− TRIG_RESET(k,c1,s1);
366− } while (k4<n);
367−}
368−
369−void mayer_fft(int n, REAL *real, REAL *imag)
370−{
371− REAL a,b,c,d;
372− REAL q,r,s,t;
373− int i,j,k;
374− for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
375− a = real[i]; b = real[j]; q=a+b; r=a-b;
376− c = imag[i]; d = imag[j]; s=c+d; t=c-d;
377− real[i] = (q+t)*.5; real[j] = (q-t)*.5;
378− imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
379− }
380− mayer_fht(real,n);
381− mayer_fht(imag,n);
382−}
383−
384−void mayer_ifft(int n, REAL *real, REAL *imag)
385−{
386− REAL a,b,c,d;
387− REAL q,r,s,t;
388− int i,j,k;
389− mayer_fht(real,n);
390− mayer_fht(imag,n);
391− for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
392− a = real[i]; b = real[j]; q=a+b; r=a-b;
393− c = imag[i]; d = imag[j]; s=c+d; t=c-d;
394− imag[i] = (s+r)*0.5; imag[j] = (s-r)*0.5;
395− real[i] = (q-t)*0.5; real[j] = (q+t)*0.5;
396− }
397−}
398−
399−void mayer_realfft(int n, REAL *real)
400−{
401− REAL a,b;
402− int i,j,k;
403− mayer_fht(real,n);
404− for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
405− a = real[i];
406− b = real[j];
407− real[j] = (a-b)*0.5;
408− real[i] = (a+b)*0.5;
409− }
410−}
411−
412−void mayer_realifft(int n, REAL *real)
413−{
414− REAL a,b;
415− int i,j,k;
416− for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
417− a = real[i];
418− b = real[j];
419− real[j] = (a-b);
420− real[i] = (a+b);
421− }
422− mayer_fht(real,n);
423−}
LEAF/Externals/d_fft_mayer.h+0−31
@@ -1,31 +0,0 @@
1−/*
2− * d_fft_mayer.h
3− *
4− * Created: 5/4/2017 10:33:59 PM
5− * Author: Kenny
6− */
7−
8−
9−#ifndef D_FFT_MAYER_H_
10−#define D_FFT_MAYER_H_
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16−typedef float t_sample; /* a float type at most the same size */
17−
18−#define REAL t_sample
19−
20−void mayer_fht(REAL *fz, int n);
21−void mayer_fft(int n, REAL *real, REAL *imag);
22−void mayer_ifft(int n, REAL *real, REAL *imag);
23−void mayer_realfft(int n, REAL *real);
24−void mayer_realifft(int n, REAL *real);
25−
26−
27−#ifdef __cplusplus
28−}
29−#endif
30−
31−#endif /* D_FFT_MAYER_H_ */
LEAF/Externals/trigtbl.h+0−173
@@ -1,173 +0,0 @@
1−
2−/*
3−** Please only distribute this with it's associated FHT routine.
4−** This algorithm is apparently patented(!) and the code copyrighted.
5−** See the comment with the fht routine for more info.
6−** -Thanks,
7−** Ron Mayer
8−*/
9−
10−#ifdef __cplusplus
11−extern "C" {
12−#endif
13−
14−#ifdef REAL
15−#else
16−#define REAL double
17−#endif
18−
19−#ifdef GOOD_TRIG
20−#else
21−#define FAST_TRIG
22−#endif
23−
24−#if defined(GOOD_TRIG)
25−#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
26−#define TRIG_VARS \
27− int t_lam=0;
28−#define TRIG_INIT(k,c,s) \
29− { \
30− int i; \
31− for (i=2 ; i<=k ; i++) \
32− {coswrk[i]=costab[i];sinwrk[i]=sintab[i];} \
33− t_lam = 0; \
34− c = 1; \
35− s = 0; \
36− }
37−#define TRIG_NEXT(k,c,s) \
38− { \
39− int i,j; \
40− (t_lam)++; \
41− for (i=0 ; !((1<<i)&t_lam) ; i++); \
42− i = k-i; \
43− s = sinwrk[i]; \
44− c = coswrk[i]; \
45− if (i>1) \
46− { \
47− for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
48− j = k - j; \
49− sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
50− coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
51− } \
52− }
53−#define TRIG_RESET(k,c,s)
54−#endif
55−
56−#if defined(FAST_TRIG)
57−#define TRIG_VARS \
58− REAL t_c,t_s;
59−#define TRIG_INIT(k,c,s) \
60− { \
61− t_c = costab[k]; \
62− t_s = sintab[k]; \
63− c = 1; \
64− s = 0; \
65− }
66−#define TRIG_NEXT(k,c,s) \
67− { \
68− REAL t = c; \
69− c = t*t_c - s*t_s; \
70− s = t*t_s + s*t_c; \
71− }
72−#define TRIG_RESET(k,c,s)
73−#endif
74−
75−static REAL halsec[20]=
76− {
77− 0,
78− 0,
79− .54119610014619698439972320536638942006107206337801,
80− .50979557910415916894193980398784391368261849190893,
81− .50241928618815570551167011928012092247859337193963,
82− .50060299823519630134550410676638239611758632599591,
83− .50015063602065098821477101271097658495974913010340,
84− .50003765191554772296778139077905492847503165398345,
85− .50000941253588775676512870469186533538523133757983,
86− .50000235310628608051401267171204408939326297376426,
87− .50000058827484117879868526730916804925780637276181,
88− .50000014706860214875463798283871198206179118093251,
89− .50000003676714377807315864400643020315103490883972,
90− .50000000919178552207366560348853455333939112569380,
91− .50000000229794635411562887767906868558991922348920,
92− .50000000057448658687873302235147272458812263401372
93− };
94−static REAL costab[20]=
95− {
96− .00000000000000000000000000000000000000000000000000,
97− .70710678118654752440084436210484903928483593768847,
98− .92387953251128675612818318939678828682241662586364,
99− .98078528040323044912618223613423903697393373089333,
100− .99518472667219688624483695310947992157547486872985,
101− .99879545620517239271477160475910069444320361470461,
102− .99969881869620422011576564966617219685006108125772,
103− .99992470183914454092164649119638322435060646880221,
104− .99998117528260114265699043772856771617391725094433,
105− .99999529380957617151158012570011989955298763362218,
106− .99999882345170190992902571017152601904826792288976,
107− .99999970586288221916022821773876567711626389934930,
108− .99999992646571785114473148070738785694820115568892,
109− .99999998161642929380834691540290971450507605124278,
110− .99999999540410731289097193313960614895889430318945,
111− .99999999885102682756267330779455410840053741619428
112− };
113−static REAL sintab[20]=
114− {
115− 1.0000000000000000000000000000000000000000000000000,
116− .70710678118654752440084436210484903928483593768846,
117− .38268343236508977172845998403039886676134456248561,
118− .19509032201612826784828486847702224092769161775195,
119− .09801714032956060199419556388864184586113667316749,
120− .04906767432741801425495497694268265831474536302574,
121− .02454122852291228803173452945928292506546611923944,
122− .01227153828571992607940826195100321214037231959176,
123− .00613588464915447535964023459037258091705788631738,
124− .00306795676296597627014536549091984251894461021344,
125− .00153398018628476561230369715026407907995486457522,
126− .00076699031874270452693856835794857664314091945205,
127− .00038349518757139558907246168118138126339502603495,
128− .00019174759731070330743990956198900093346887403385,
129− .00009587379909597734587051721097647635118706561284,
130− .00004793689960306688454900399049465887274686668768
131− };
132−static REAL coswrk[20]=
133− {
134− .00000000000000000000000000000000000000000000000000,
135− .70710678118654752440084436210484903928483593768847,
136− .92387953251128675612818318939678828682241662586364,
137− .98078528040323044912618223613423903697393373089333,
138− .99518472667219688624483695310947992157547486872985,
139− .99879545620517239271477160475910069444320361470461,
140− .99969881869620422011576564966617219685006108125772,
141− .99992470183914454092164649119638322435060646880221,
142− .99998117528260114265699043772856771617391725094433,
143− .99999529380957617151158012570011989955298763362218,
144− .99999882345170190992902571017152601904826792288976,
145− .99999970586288221916022821773876567711626389934930,
146− .99999992646571785114473148070738785694820115568892,
147− .99999998161642929380834691540290971450507605124278,
148− .99999999540410731289097193313960614895889430318945,
149− .99999999885102682756267330779455410840053741619428
150− };
151−static REAL sinwrk[20]=
152− {
153− 1.0000000000000000000000000000000000000000000000000,
154− .70710678118654752440084436210484903928483593768846,
155− .38268343236508977172845998403039886676134456248561,
156− .19509032201612826784828486847702224092769161775195,
157− .09801714032956060199419556388864184586113667316749,
158− .04906767432741801425495497694268265831474536302574,
159− .02454122852291228803173452945928292506546611923944,
160− .01227153828571992607940826195100321214037231959176,
161− .00613588464915447535964023459037258091705788631738,
162− .00306795676296597627014536549091984251894461021344,
163− .00153398018628476561230369715026407907995486457522,
164− .00076699031874270452693856835794857664314091945205,
165− .00038349518757139558907246168118138126339502603495,
166− .00019174759731070330743990956198900093346887403385,
167− .00009587379909597734587051721097647635118706561284,
168− .00004793689960306688454900399049465887274686668768
169− };
170−
171−#ifdef __cplusplus
172−}
173−#endif
LEAF/Inc/leaf-analysis.h+0−296
@@ -1,296 +0,0 @@
1−/*==============================================================================
2−
3− leaf-analysis.h
4− Created: 25 Oct 2019 10:30:52am
5− Author: Matthew Wang
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_ANALYSIS_H_INCLUDED
10−#define LEAF_ANALYSIS_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-global.h"
19−#include "leaf-mempool.h"
20−#include "leaf-math.h"
21−#include "leaf-filters.h"
22−#include "leaf-envelopes.h"
23−
24− /*!
25− * @internal
26− * Header.
27− * @include basic-oscillators.h
28− * @example basic-oscillators.c
29− * An example.
30− */
31−
32− //==============================================================================
33−
34− /* Envelope Follower */
35− typedef struct _tEnvelopeFollower
36− {
37− float y;
38− float a_thresh;
39− float d_coeff;
40−
41− } _tEnvelopeFollower;
42−
43− typedef _tEnvelopeFollower* tEnvelopeFollower;
44−
45− void tEnvelopeFollower_init (tEnvelopeFollower* const, float attackThreshold, float decayCoeff);
46− void tEnvelopeFollower_free (tEnvelopeFollower* const);
47− void tEnvelopeFollower_initToPool (tEnvelopeFollower* const, float attackThreshold, float decayCoeff, tMempool* const);
48− void tEnvelopeFollower_freeFromPool (tEnvelopeFollower* const, tMempool* const);
49−
50− float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x);
51− int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
52− int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
53−
54− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
55−
56− /* Zero Crossing Detector */
57− typedef struct _tZeroCrossing {
58− int count;
59− int maxWindowSize;
60− int currentWindowSize;
61− float invCurrentWindowSize;
62− float* inBuffer;
63− uint16_t* countBuffer;
64− int prevPosition;
65− int position;
66− } _tZeroCrossing;
67−
68− typedef _tZeroCrossing* tZeroCrossing;
69−
70− void tZeroCrossing_init (tZeroCrossing* const, int maxWindowSize);
71− void tZeroCrossing_free (tZeroCrossing* const);
72− void tZeroCrossing_initToPool (tZeroCrossing* const, int maxWindowSize, tMempool* const);
73− void tZeroCrossing_freeFromPool (tZeroCrossing* const, tMempool* const);
74−
75− float tZeroCrossing_tick (tZeroCrossing* const, float input);
76− void tZeroCrossing_setWindow (tZeroCrossing* const, float windowSize);
77−
78− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
79−
80− /* PowerEnvelopeFollower */
81− typedef struct _tPowerFollower {
82− float factor, oneminusfactor;
83− float curr;
84−
85− } _tPowerFollower;
86−
87− typedef _tPowerFollower* tPowerFollower;
88−
89− void tPowerFollower_init (tPowerFollower* const, float factor);
90− void tPowerFollower_free (tPowerFollower* const);
91− void tPowerFollower_initToPool (tPowerFollower* const, float factor, tMempool* const);
92− void tPowerFollower_freeFromPool (tPowerFollower* const, tMempool* const);
93−
94− float tPowerFollower_tick (tPowerFollower* const, float input);
95− float tPowerFollower_sample (tPowerFollower* const);
96− int tPowerFollower_setFactor (tPowerFollower* const, float factor);
97−
98− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
99−
100− // ENV~ from PD, modified for LEAF
101−#define MAXOVERLAP 32
102−#define INITVSTAKEN 64
103−#define ENV_WINDOW_SIZE 1024
104−#define ENV_HOP_SIZE 256
105−
106− typedef struct _tEnvPD
107− {
108− float buf[ENV_WINDOW_SIZE + INITVSTAKEN];
109− uint16_t x_phase; /* number of points since last output */
110− uint16_t x_period; /* requested period of output */
111− uint16_t x_realperiod; /* period rounded up to vecsize multiple */
112− uint16_t x_npoints; /* analysis window size in samples */
113− float x_result; /* result to output */
114− float x_sumbuf[MAXOVERLAP]; /* summing buffer */
115− float x_f;
116− uint16_t windowSize, hopSize, blockSize;
117− uint16_t x_allocforvs; /* extra buffer for DSP vector size */
118− } _tEnvPD;
119−
120− typedef _tEnvPD* tEnvPD;
121−
122− void tEnvPD_init (tEnvPD* const, int windowSize, int hopSize, int blockSize);
123− void tEnvPD_free (tEnvPD* const);
124− void tEnvPD_initToPool (tEnvPD* const, int windowSize, int hopSize, int blockSize, tMempool* const);
125− void tEnvPD_freeFromPool (tEnvPD* const, tMempool* const);
126−
127− float tEnvPD_tick (tEnvPD* const);
128− void tEnvPD_processBlock (tEnvPD* const, float* in);
129−
130− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
131−
132− /* tAttackDetection */
133−#define DEFBLOCKSIZE 1024
134−#define DEFTHRESHOLD 6
135−#define DEFATTACK 10
136−#define DEFRELEASE 10
137−
138− typedef struct _tAttackDetection
139− {
140− float env;
141−
142− //Attack & Release times in msec
143− int atk;
144− int rel;
145−
146− //Attack & Release coefficients based on times
147− float atk_coeff;
148− float rel_coeff;
149−
150− int blocksize;
151− int samplerate;
152−
153− //RMS amplitude of previous block - used to decide if attack is present
154− float prevAmp;
155−
156− float threshold;
157− } _tAttackDetection;
158−
159− typedef _tAttackDetection* tAttackDetection;
160−
161− void tAttackDetection_init (tAttackDetection* const, int blocksize, int atk, int rel);
162− void tAttackDetection_free (tAttackDetection* const);
163− void tAttackDetection_initToPool (tAttackDetection* const, int blocksize, int atk, int rel, tMempool* const);
164− void tAttackDetection_freeFromPool (tAttackDetection* const, tMempool* const);
165−
166− // set expected input blocksize
167− void tAttackDetection_setBlocksize (tAttackDetection* const, int size);
168−
169− // change atkDetector sample rate
170− void tAttackDetection_setSamplerate (tAttackDetection* const, int inRate);
171−
172− // set attack time and coeff
173− void tAttackDetection_setAttack (tAttackDetection* const, int inAtk);
174−
175− // set release time and coeff
176− void tAttackDetection_setRelease (tAttackDetection* const, int inRel);
177−
178− // set level above which values are identified as attacks
179− void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
180−
181− // find largest transient in input block, return index of attack
182− int tAttackDetection_detect (tAttackDetection* const, float *in);
183−
184− //==============================================================================
185−
186− // tSNAC: period detector
187− // from Katja Vetters http://www.katjaas.nl/helmholtz/helmholtz.html
188−#define SNAC_FRAME_SIZE 1024 // default analysis framesize // should be the same as (or smaller than?) PS_FRAME_SIZE
189−#define DEFOVERLAP 1 // default overlap
190−#define DEFBIAS 0.2f // default bias
191−#define DEFMINRMS 0.003f // default minimum RMS
192−#define SEEK 0.85f // seek-length as ratio of framesize
193−
194− typedef struct _tSNAC
195− {
196− float* inputbuf;
197− float* processbuf;
198− float* spectrumbuf;
199− float* biasbuf;
200− uint16_t timeindex;
201− uint16_t framesize;
202− uint16_t overlap;
203− uint16_t periodindex;
204−
205− float periodlength;
206− float fidelity;
207− float biasfactor;
208− float minrms;
209−
210− } _tSNAC;
211−
212− typedef _tSNAC* tSNAC;
213−
214− void tSNAC_init (tSNAC* const, int overlaparg);
215− void tSNAC_free (tSNAC* const);
216− void tSNAC_initToPool (tSNAC* const, int overlaparg, tMempool* const);
217− void tSNAC_freeFromPool (tSNAC* const, tMempool* const);
218−
219− void tSNAC_ioSamples (tSNAC *s, float *in, float *out, int size);
220− void tSNAC_setOverlap (tSNAC *s, int lap);
221− void tSNAC_setBias (tSNAC *s, float bias);
222− void tSNAC_setMinRMS (tSNAC *s, float rms);
223−
224− /*To get freq, perform SAMPLE_RATE/snac_getperiod() */
225− float tSNAC_getPeriod (tSNAC *s);
226− float tSNAC_getFidelity (tSNAC *s);
227−
228−#define DEFPITCHRATIO 2.0f
229−#define DEFTIMECONSTANT 100.0f
230−#define DEFHOPSIZE 64
231−#define DEFWINDOWSIZE 64
232−#define FBA 20
233−#define HPFREQ 40.0f
234−
235− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
236− // Period detection
237− typedef struct _tPeriodDetection
238− {
239− tEnvPD env;
240− tSNAC snac;
241− float* inBuffer;
242− float* outBuffer;
243− int frameSize;
244− int bufSize;
245− int framesPerBuffer;
246− int curBlock;
247− int lastBlock;
248− int i;
249− int indexstore;
250− int iLast;
251− int index;
252− float period;
253−
254− uint16_t hopSize;
255− uint16_t windowSize;
256− uint8_t fba;
257−
258− float timeConstant;
259− float radius;
260− float max;
261− float lastmax;
262− float deltamax;
263−
264− float fidelityThreshold;
265−
266− float history;
267− float alpha;
268− float tolerance;
269−
270− } _tPeriodDetection;
271−
272− typedef _tPeriodDetection* tPeriodDetection;
273−
274− void tPeriodDetection_init (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize);
275− void tPeriodDetection_free (tPeriodDetection* const);
276− void tPeriodDetection_initToPool (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize, tMempool* const);
277− void tPeriodDetection_freeFromPool (tPeriodDetection* const, tMempool* const);
278−
279− float tPeriodDetection_tick (tPeriodDetection* const, float sample);
280− float tPeriodDetection_getPeriod (tPeriodDetection* const);
281− void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);
282− void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);
283− void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
284− void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);
285− void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);
286−
287− //==============================================================================
288−
289−#ifdef __cplusplus
290−}
291−#endif
292−
293−#endif // LEAF_ANALYSIS_H_INCLUDED
294−
295−//==============================================================================
296−
LEAF/Inc/leaf-delay.h+0−229
@@ -1,229 +0,0 @@
1−/*==============================================================================
2−
3− leaf-delay.h
4− Created: 20 Jan 2017 12:01:24pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_DELAY_H_INCLUDED
10−#define LEAF_DELAY_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-math.h"
19−#include "leaf-mempool.h"
20−
21− /*!
22− * @internal
23− * Header.
24− * @include basic-oscillators.h
25− * @example basic-oscillators.c
26− * An example.
27− */
28−
29− //==============================================================================
30−
31− /* Non-interpolating delay, reimplemented from STK (Cook and Scavone). */
32− typedef struct _tDelay
33− {
34− float gain;
35− float* buff;
36−
37− float lastOut, lastIn;
38−
39− uint32_t inPoint, outPoint;
40−
41− uint32_t delay, maxDelay;
42−
43− } _tDelay;
44−
45− typedef _tDelay* tDelay;
46−
47− void tDelay_init (tDelay* const, uint32_t delay, uint32_t maxDelay);
48− void tDelay_free (tDelay* const);
49− void tDelay_initToPool (tDelay* const, uint32_t delay, uint32_t maxDelay, tMempool* const);
50− void tDelay_freeFromPool (tDelay* const, tMempool* const);
51−
52− void tDelay_clear (tDelay* const);
53− int tDelay_setDelay (tDelay* const, uint32_t delay);
54− uint32_t tDelay_getDelay (tDelay* const);
55− void tDelay_tapIn (tDelay* const, float in, uint32_t tapDelay);
56− float tDelay_tapOut (tDelay* const, uint32_t tapDelay);
57− float tDelay_addTo (tDelay* const, float value, uint32_t tapDelay);
58− float tDelay_tick (tDelay* const, float sample);
59− float tDelay_getLastOut (tDelay* const);
60− float tDelay_getLastIn (tDelay* const);
61−
62− //==============================================================================
63−
64− /* Linearly-interpolating delay, reimplemented from STK (Cook and Scavone). */
65− typedef struct _tLinearDelay
66− {
67− float gain;
68− float* buff;
69−
70− float lastOut, lastIn;
71−
72− uint32_t inPoint, outPoint;
73−
74− uint32_t maxDelay;
75−
76− float delay;
77−
78− float alpha, omAlpha;
79−
80− } _tLinearDelay;
81−
82− typedef _tLinearDelay* tLinearDelay;
83−
84− void tLinearDelay_init (tLinearDelay* const, float delay, uint32_t maxDelay);
85− void tLinearDelay_free (tLinearDelay* const);
86− void tLinearDelay_initToPool (tLinearDelay* const, float delay, uint32_t maxDelay, tMempool* const);
87− void tLinearDelay_freeFromPool(tLinearDelay* const, tMempool* const);
88− void tLinearDelay_clear (tLinearDelay* const dl);
89− int tLinearDelay_setDelay (tLinearDelay* const, float delay);
90− float tLinearDelay_getDelay (tLinearDelay* const);
91− void tLinearDelay_tapIn (tLinearDelay* const, float in, uint32_t tapDelay);
92− float tLinearDelay_tapOut (tLinearDelay* const, uint32_t tapDelay);
93− float tLinearDelay_addTo (tLinearDelay* const, float value, uint32_t tapDelay);
94− float tLinearDelay_tick (tLinearDelay* const, float sample);
95− void tLinearDelay_tickIn (tLinearDelay* const, float input);
96− float tLinearDelay_tickOut (tLinearDelay* const);
97− float tLinearDelay_getLastOut (tLinearDelay* const);
98− float tLinearDelay_getLastIn (tLinearDelay* const);
99−
100−
101−
102− //==============================================================================
103−
104− /* Hermite-interpolating delay, created by adapting STK linear delay with Hermite interpolation */
105− typedef struct _tHermiteDelay
106− {
107− float gain;
108− float* buff;
109−
110− float lastOut, lastIn;
111−
112− uint32_t inPoint, outPoint;
113−
114− uint32_t maxDelay;
115−
116− float delay;
117−
118− float alpha, omAlpha;
119−
120− } _tHermiteDelay;
121−
122− typedef _tHermiteDelay* tHermiteDelay;
123−
124− void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay);
125− void tHermiteDelay_free (tHermiteDelay* const dl);
126− void tHermiteDelay_initToPool (tHermiteDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp);
127− void tHermiteDelay_freeFromPool (tHermiteDelay* const dl, tMempool* const mp);
128− void tHermiteDelay_clear (tHermiteDelay* const dl);
129− float tHermiteDelay_tick (tHermiteDelay* const dl, float input);
130− void tHermiteDelay_tickIn (tHermiteDelay* const dl, float input);
131− float tHermiteDelay_tickOut (tHermiteDelay* const dl);
132− int tHermiteDelay_setDelay (tHermiteDelay* const dl, float delay);
133− float tHermiteDelay_tapOut (tHermiteDelay* const dl, uint32_t tapDelay);
134− void tHermiteDelay_tapIn (tHermiteDelay* const dl, float value, uint32_t tapDelay);
135− float tHermiteDelay_addTo (tHermiteDelay* const dl, float value, uint32_t tapDelay);
136− float tHermiteDelay_getDelay (tHermiteDelay* const dl);
137− float tHermiteDelay_getLastOut (tHermiteDelay* const dl);
138− float tHermiteDelay_getLastIn (tHermiteDelay* const dl);
139− void tHermiteDelay_setGain (tHermiteDelay* const dl, float gain);
140− float tHermiteDelay_getGain (tHermiteDelay* const dl);
141−
142−
143− //==============================================================================
144−
145− /* Allpass-interpolating delay, reimplemented from STK (Cook and Scavone). */
146− typedef struct _tAllpassDelay
147− {
148− float gain;
149− float* buff;
150−
151− float lastOut, lastIn;
152−
153− uint32_t inPoint, outPoint;
154−
155− uint32_t maxDelay;
156−
157− float delay;
158−
159− float alpha, omAlpha, coeff;
160−
161− float apInput;
162−
163− } _tAllpassDelay;
164−
165− typedef _tAllpassDelay* tAllpassDelay;
166−
167− void tAllpassDelay_init (tAllpassDelay* const, float delay, uint32_t maxDelay);
168− void tAllpassDelay_free (tAllpassDelay* const);
169− void tAllpassDelay_initToPool (tAllpassDelay* const, float delay, uint32_t maxDelay, tMempool* const);
170− void tAllpassDelay_freeFromPool(tAllpassDelay* const, tMempool* const);
171−
172− void tAllpassDelay_clear (tAllpassDelay* const);
173− int tAllpassDelay_setDelay (tAllpassDelay* const, float delay);
174− float tAllpassDelay_getDelay (tAllpassDelay* const);
175− void tAllpassDelay_tapIn (tAllpassDelay* const, float in, uint32_t tapDelay);
176− float tAllpassDelay_tapOut (tAllpassDelay* const, uint32_t tapDelay);
177− float tAllpassDelay_addTo (tAllpassDelay* const, float value, uint32_t tapDelay);
178− float tAllpassDelay_tick (tAllpassDelay* const, float sample);
179− float tAllpassDelay_getLastOut (tAllpassDelay* const);
180− float tAllpassDelay_getLastIn (tAllpassDelay* const);
181−
182− //==============================================================================
183−
184− /* Linear interpolating delay with fixed read and write pointers, variable rate. */
185− typedef struct _tTapeDelay
186− {
187− float gain;
188− float* buff;
189−
190− float lastOut, lastIn;
191−
192− uint32_t inPoint;
193−
194− uint32_t maxDelay;
195−
196− float delay, inc, idx;
197−
198− float apInput;
199−
200− } _tTapeDelay;
201−
202− typedef _tTapeDelay* tTapeDelay;
203−
204− void tTapeDelay_init (tTapeDelay* const, float delay, uint32_t maxDelay);
205− void tTapeDelay_free (tTapeDelay* const);
206− void tTapeDelay_initToPool (tTapeDelay* const, float delay, uint32_t maxDelay, tMempool* const);
207− void tTapeDelay_freeFromPool(tTapeDelay* const, tMempool* const);
208−
209− void tTapeDelay_clear (tTapeDelay* const);
210− void tTapeDelay_setDelay (tTapeDelay* const, float delay);
211− float tTapeDelay_getDelay (tTapeDelay* const);
212− void tTapeDelay_tapIn (tTapeDelay* const, float in, uint32_t tapDelay);
213− float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay);
214− float tTapeDelay_addTo (tTapeDelay* const, float value, uint32_t tapDelay);
215− float tTapeDelay_tick (tTapeDelay* const, float sample);
216− void tTapeDelay_incrementInPoint(tTapeDelay* const dl);
217− float tTapeDelay_getLastOut (tTapeDelay* const);
218− float tTapeDelay_getLastIn (tTapeDelay* const);
219−
220− //==============================================================================
221−
222−#ifdef __cplusplus
223−}
224−#endif
225−
226−#endif // LEAF_DELAY_H_INCLUDED
227−
228−//==============================================================================
229−
LEAF/Inc/leaf-distortion.h+0−164
@@ -1,164 +0,0 @@
1−/*==============================================================================
2−
3− leaf-distortion.h
4− Created: 25 Oct 2019 10:23:28am
5− Author: Matthew Wang
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_DISTORTION_H_INCLUDED
10−#define LEAF_DISTORTION_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-global.h"
19−#include "leaf-mempool.h"
20−#include "leaf-math.h"
21−
22− /*!
23− * @internal
24− * Header.
25− * @include basic-oscillators.h
26− * @example basic-oscillators.c
27− * An example.
28− */
29−
30− //==============================================================================
31−
32− typedef struct _tSampleReducer
33− {
34− float invRatio;
35− float hold;
36− uint32_t count;
37− } _tSampleReducer;
38−
39− typedef _tSampleReducer* tSampleReducer;
40−
41− void tSampleReducer_init (tSampleReducer* const);
42− void tSampleReducer_free (tSampleReducer* const);
43− void tSampleReducer_initToPool (tSampleReducer* const, tMempool* const);
44− void tSampleReducer_freeFromPool (tSampleReducer* const, tMempool* const);
45−
46− float tSampleReducer_tick (tSampleReducer* const, float input);
47−
48− // sampling ratio
49− void tSampleReducer_setRatio (tSampleReducer* const, float ratio);
50−
51− //==============================================================================
52−
53− typedef struct _tOversampler
54− {
55− int ratio;
56− float* pCoeffs;
57− float* upState;
58− float* downState;
59− int numTaps;
60− int phaseLength;
61− } _tOversampler;
62−
63− typedef _tOversampler* tOversampler;
64−
65− void tOversampler_init (tOversampler* const, int order, oBool extraQuality);
66− void tOversampler_free (tOversampler* const);
67− void tOversampler_initToPool (tOversampler* const, int order, oBool extraQuality, tMempool* const);
68− void tOversampler_freeFromPool (tOversampler* const, tMempool* const);
69−
70− void tOversampler_upsample (tOversampler* const, float input, float* output);
71− float tOversampler_downsample (tOversampler* const os, float* input);
72− float tOversampler_tick (tOversampler* const, float input, float (*effectTick)(float));
73− int tOversampler_getLatency (tOversampler* const os);
74−
75− //==============================================================================
76−
77− /* tLockhartWavefolder */
78−
79− typedef struct _tLockhartWavefolder
80− {
81− double Ln1;
82− double Fn1;
83− double xn1;
84−
85− double RL;
86− double R;
87− double VT;
88− double Is;
89−
90− double a;
91− double b;
92− double d;
93−
94− // Antialiasing error threshold
95− double AAthresh;
96− double half_a;
97− double longthing;
98−
99− double LambertThresh, w, expw, p, r, s, myerr;
100− double l;
101− double u, Ln, Fn;
102− double tempsDenom;
103− double tempErrDenom;
104− double tempOutDenom;
105−
106− } _tLockhartWavefolder;
107−
108− typedef _tLockhartWavefolder* tLockhartWavefolder;
109−
110− void tLockhartWavefolder_init (tLockhartWavefolder* const);
111− void tLockhartWavefolder_free (tLockhartWavefolder* const);
112− void tLockhartWavefolder_initToPool (tLockhartWavefolder* const, tMempool* const);
113− void tLockhartWavefolder_freeFromPool (tLockhartWavefolder* const, tMempool* const);
114−
115− float tLockhartWavefolder_tick (tLockhartWavefolder* const, float samp);
116−
117− //==============================================================================
118−
119− typedef struct _tCrusher
120− {
121− float srr;
122− float mult, div;
123− float rnd;
124−
125− uint32_t op; //which bitwise operation (0-7)
126−
127− float gain;
128− tSampleReducer sReducer;
129−
130− } _tCrusher;
131−
132− typedef _tCrusher* tCrusher;
133−
134− void tCrusher_init (tCrusher* const);
135− void tCrusher_free (tCrusher* const);
136− void tCrusher_initToPool (tCrusher* const, tMempool* const);
137− void tCrusher_freeFromPool (tCrusher* const, tMempool* const);
138−
139− float tCrusher_tick (tCrusher* const, float input);
140−
141− // 0.0 - 1.0
142− void tCrusher_setOperation (tCrusher* const, float op);
143−
144− // 0.0 - 1.0
145− void tCrusher_setQuality (tCrusher* const, float val);
146−
147− // what division to round to
148− void tCrusher_setRound (tCrusher* const, float rnd);
149−
150− // sampling ratio
151− void tCrusher_setSamplingRatio (tCrusher* const, float ratio);
152−
153− //==============================================================================
154−
155−
156−#ifdef __cplusplus
157−}
158−#endif
159−
160−#endif // LEAF_DISTORTION_H_INCLUDED
161−
162−//==============================================================================
163−
164−
LEAF/Inc/leaf-dynamics.h+0−122
@@ -1,122 +0,0 @@
1−/*==============================================================================
2−
3− leaf-dynamics.h
4− Created: 30 Nov 2018 11:57:05am
5− Author: airship
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_DYNAMICS_H_INCLUDED
10−#define LEAF_DYNAMICS_H_INCLUDED
11−
12−
13−#ifdef __cplusplus
14−extern "C" {
15−#endif
16−
17− //==============================================================================
18−
19−#include "leaf-global.h"
20−#include "leaf-math.h"
21−#include "leaf-mempool.h"
22−#include "leaf-analysis.h"
23−
24− /*!
25− * @internal
26− * Header.
27− * @include basic-oscillators.h
28− * @example basic-oscillators.c
29− * An example.
30− */
31−
32− //==============================================================================
33−
34− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
35−
36− /* Compressor */
37− typedef struct _tCompressor
38− {
39− float tauAttack, tauRelease;
40− float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain
41−
42− float x_G[2], y_G[2], x_T[2], y_T[2];
43−
44− oBool isActive;
45−
46− } _tCompressor;
47−
48− typedef _tCompressor* tCompressor;
49−
50− void tCompressor_init (tCompressor* const);
51− void tCompressor_free (tCompressor* const);
52− void tCompressor_initToPool (tCompressor* const, tMempool* const);
53− void tCompressor_freeFromPool(tCompressor* const, tMempool* const);
54−
55− float tCompressor_tick (tCompressor* const, float input);
56−
57− ///
58− /* Feedback leveller */
59− // An auto VCA that you put into a feedback circuit to make it stay at the same level.
60− // It can enforce level bidirectionally (amplifying and attenuating as needed) or
61− // just attenutating. The former option allows for infinite sustain strings, for example, while
62− // The latter option allows for decaying strings, which can never exceed
63− // a specific level.
64−
65− typedef struct _tFeedbackLeveler {
66− float targetLevel; // target power level
67− float strength; // how strongly level difference affects the VCA
68− int mode; // 0 for upwards limiting only, 1 for biderctional limiting
69− float curr;
70− tPowerFollower pwrFlw; // internal power follower needed for level tracking
71−
72− } _tFeedbackLeveler;
73−
74− typedef _tFeedbackLeveler* tFeedbackLeveler;
75−
76− void tFeedbackLeveler_init (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode);
77− void tFeedbackLeveler_free (tFeedbackLeveler* const);
78− void tFeedbackLeveler_initToPool (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode, tMempool* const);
79− void tFeedbackLeveler_freeFromPool (tFeedbackLeveler* const, tMempool* const);
80−
81− float tFeedbackLeveler_tick (tFeedbackLeveler* const, float input);
82− float tFeedbackLeveler_sample (tFeedbackLeveler* const);
83− void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const, float TargetLevel);
84− void tFeedbackLeveler_setFactor (tFeedbackLeveler* const, float factor);
85− void tFeedbackLeveler_setMode (tFeedbackLeveler* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
86− void tFeedbackLeveler_setStrength (tFeedbackLeveler* const, float strength);
87−
88−
89− //==============================================================================
90−
91−
92− //Threshold with hysteresis (like Max/MSP thresh~ object)
93−
94− typedef struct _tThreshold {
95− float highThresh, lowThresh;
96− int currentValue;
97−
98− } _tThreshold;
99−
100− typedef _tThreshold* tThreshold;
101−
102− void tThreshold_init (tThreshold* const, float low, float high);
103− void tThreshold_free (tThreshold* const);
104− void tThreshold_initToPool (tThreshold* const, float low, float high, tMempool* const);
105− void tThreshold_freeFromPool(tThreshold* const, tMempool* const);
106−
107− int tThreshold_tick (tThreshold* const, float input);
108− void tThreshold_setLow (tThreshold* const, float low);
109− void tThreshold_setHigh (tThreshold* const, float high);
110−
111−
112−
113− //////======================================================================
114−
115−#ifdef __cplusplus
116−}
117−#endif
118−
119−#endif // LEAF_DYNAMICS_H_INCLUDED
120−
121−//==============================================================================
122−
LEAF/Inc/leaf-effects.h+0−360
@@ -1,360 +0,0 @@
1−/*==============================================================================
2−
3− leaf-effects.h
4− Created: 20 Jan 2017 12:01:54pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_EFFECTS_H_INCLUDED
10−#define LEAF_EFFECTS_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−#include "leaf-global.h"
18−#include "leaf-math.h"
19−#include "leaf-mempool.h"
20−#include "leaf-dynamics.h"
21−#include "leaf-analysis.h"
22−#include "leaf-envelopes.h"
23−
24− /*!
25− * @internal
26− * Header.
27− * @include basic-oscillators.h
28− * @example basic-oscillators.c
29− * An example.
30− */
31−
32− //==============================================================================
33−
34− /* tTalkbox */
35−#define NUM_TALKBOX_PARAM 4
36−
37− typedef struct _tTalkbox
38− {
39− float param[NUM_TALKBOX_PARAM];
40−
41− int bufsize;
42− float* car0;
43− float* car1;
44− float* window;
45− float* buf0;
46− float* buf1;
47−
48− float warpFactor;
49− int32_t warpOn;
50−
51− float emphasis;
52− int32_t K, N, O, pos;
53− float wet, dry, FX;
54− float d0, d1, d2, d3, d4;
55− float u0, u1, u2, u3, u4;
56−
57−
58− } _tTalkbox;
59−
60− typedef _tTalkbox* tTalkbox;
61−
62− void tTalkbox_init (tTalkbox* const, int bufsize);
63− void tTalkbox_free (tTalkbox* const);
64− void tTalkbox_initToPool (tTalkbox* const, int bufsize, tMempool* const);
65− void tTalkbox_freeFromPool (tTalkbox* const, tMempool* const);
66−
67− float tTalkbox_tick (tTalkbox* const, float synth, float voice);
68− void tTalkbox_update (tTalkbox* const);
69− void tTalkbox_suspend (tTalkbox* const);
70− void tTalkbox_lpcDurbin (float *r, int p, float *k, float *g);
71− void tTalkbox_lpc (float *buf, float *car, int32_t n, int32_t o, float warp, int warpOn);
72− void tTalkbox_setQuality (tTalkbox* const, float quality);
73− void tTalkbox_setWarpFactor (tTalkbox* const voc, float warp);
74− void tTalkbox_setWarpOn (tTalkbox* const voc, float warpOn);
75− void tTalkbox_warpedAutocorrelate (float * x, unsigned int L, float * R, unsigned int P, float lambda);
76− //==============================================================================
77−
78− /* tVocoder */
79−#define NUM_VOCODER_PARAM 8
80−#define NBANDS 16
81−
82− typedef struct _tVocoder
83− {
84− float param[NUM_VOCODER_PARAM];
85−
86− float gain; //output level
87− float thru, high; //hf thru
88− float kout; //downsampled output
89− int32_t kval; //downsample counter
90− int32_t nbnd; //number of bands
91−
92− //filter coeffs and buffers - seems it's faster to leave this global than make local copy
93− float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
94−
95− } _tVocoder;
96−
97− typedef _tVocoder* tVocoder;
98−
99− void tVocoder_init (tVocoder* const);
100− void tVocoder_free (tVocoder* const);
101− void tVocoder_initToPool (tVocoder* const, tMempool* const);
102− void tVocoder_freeFromPool (tVocoder* const, tMempool* const);
103−
104− float tVocoder_tick (tVocoder* const, float synth, float voice);
105− void tVocoder_update (tVocoder* const);
106− void tVocoder_suspend (tVocoder* const);
107−
108− //==============================================================================
109−
110− // tRosenbergGlottalPulse
111−
112− typedef struct _tRosenbergGlottalPulse
113− {
114−
115− float phase;
116− float openLength;
117− float pulseLength;
118− float freq;
119− float inc;
120−
121−
122− } _tRosenbergGlottalPulse;
123−
124− typedef _tRosenbergGlottalPulse* tRosenbergGlottalPulse;
125−
126− void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const);
127− void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const);
128− void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const, tMempool* const);
129− void tRosenbergGlottalPulse_freeFromPool (tRosenbergGlottalPulse* const, tMempool* const);
130−
131− float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const);
132−
133− void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const, float freq);
134−
135− void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const, float openLength);
136−
137− void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const, float pulseLength);
138−
139− //==============================================================================
140−
141− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
142−
143− /* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
144− // from Katja Vetters http://www.katjaas.nl/pitchshiftlowlatency/pitchshiftlowlatency.html
145−#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
146−#define LOOPMASK (LOOPSIZE - 1)
147−#define PITCHFACTORDEFAULT 1.0f
148−#define INITPERIOD 64.0f
149−#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
150−#define MINPERIOD 8.0f
151−
152− typedef struct _tSOLAD
153− {
154− uint16_t timeindex; // current reference time, write index
155− uint16_t blocksize; // signal input / output block size
156− float pitchfactor; // pitch factor between 0.25 and 4
157− float readlag; // read pointer's lag behind write pointer
158− float period; // period length in input signal
159− float jump; // read pointer jump length and direction
160− float xfadelength; // crossfade length expressed at input sample rate
161− float xfadevalue; // crossfade phase and value
162−
163− float* delaybuf;
164−
165− } _tSOLAD;
166−
167− typedef _tSOLAD* tSOLAD;
168−
169− void tSOLAD_init (tSOLAD* const);
170− void tSOLAD_free (tSOLAD* const);
171− void tSOLAD_initToPool (tSOLAD* const, tMempool* const);
172− void tSOLAD_freeFromPool (tSOLAD* const, tMempool* const);
173−
174− // send one block of input samples, receive one block of output samples
175− void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
176− // set periodicity analysis data
177− void tSOLAD_setPeriod (tSOLAD *w, float period);
178− // set pitch factor between 0.25 and 4
179− void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);
180− // force readpointer lag
181− void tSOLAD_setReadLag (tSOLAD *w, float readlag);
182− // reset state variables
183− void tSOLAD_resetState (tSOLAD *w);
184−
185− // Pitch shift
186− typedef struct _tPitchShift
187− {
188− tSOLAD sola;
189− tHighpass hp;
190− tPeriodDetection* p;
191−
192− float* outBuffer;
193− int frameSize;
194− int bufSize;
195−
196− int framesPerBuffer;
197− int curBlock;
198− int lastBlock;
199− int index;
200−
201− float pitchFactor;
202− float timeConstant;
203− float radius;
204− } _tPitchShift;
205−
206− typedef _tPitchShift* tPitchShift;
207−
208− void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
209− void tPitchShift_free (tPitchShift* const);
210− void tPitchShift_initToPool (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize, tMempool* const);
211− void tPitchShift_freeFromPool (tPitchShift* const, tMempool* const);
212−
213− float tPitchShift_shift (tPitchShift* const);
214− float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
215− float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
216− void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
217−
218− // Retune
219− typedef struct _tRetune
220− {
221− tPeriodDetection pd;
222− tPitchShift* ps;
223−
224− float* inBuffer;
225− float** outBuffers;
226− float* tickOutput;
227− int frameSize;
228− int bufSize;
229−
230− uint16_t hopSize;
231− uint16_t windowSize;
232− uint8_t fba;
233−
234− float* pitchFactor;
235− float timeConstant;
236− float radius;
237−
238− float inputPeriod;
239−
240− int numVoices;
241− } _tRetune;
242−
243− typedef _tRetune* tRetune;
244−
245− void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
246− void tRetune_free (tRetune* const);
247− void tRetune_initToPool (tRetune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
248− void tRetune_freeFromPool (tRetune* const, tMempool* const);
249−
250− float* tRetune_tick (tRetune* const, float sample);
251− void tRetune_setNumVoices (tRetune* const, int numVoices);
252− void tRetune_setPitchFactors (tRetune* const, float pf);
253− void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
254− void tRetune_setTimeConstant (tRetune* const, float tc);
255− void tRetune_setHopSize (tRetune* const, int hs);
256− void tRetune_setWindowSize (tRetune* const, int ws);
257− void tRetune_setFidelityThreshold(tRetune* const, float threshold);
258− float tRetune_getInputPeriod (tRetune* const);
259− float tRetune_getInputFreq (tRetune* const);
260−
261− // Autotune
262− typedef struct _tAutotune
263− {
264− tPeriodDetection pd;
265− tPitchShift* ps;
266−
267− float* inBuffer;
268− float** outBuffers;
269− float* tickOutput;
270− int frameSize;
271− int bufSize;
272−
273− uint16_t hopSize;
274− uint16_t windowSize;
275− uint8_t fba;
276−
277− float* freq;
278− float timeConstant;
279− float radius;
280−
281− float inputPeriod;
282−
283− int numVoices;
284− } _tAutotune;
285−
286− typedef _tAutotune* tAutotune;
287−
288− void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
289− void tAutotune_free (tAutotune* const);
290− void tAutotune_initToPool (tAutotune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
291− void tAutotune_freeFromPool (tAutotune* const, tMempool* const);
292−
293− float* tAutotune_tick (tAutotune* const, float sample);
294− void tAutotune_setNumVoices (tAutotune* const, int numVoices);
295− void tAutotune_setFreqs (tAutotune* const, float f);
296− void tAutotune_setFreq (tAutotune* const, float f, int voice);
297− void tAutotune_setTimeConstant (tAutotune* const, float tc);
298− void tAutotune_setHopSize (tAutotune* const, int hs);
299− void tAutotune_setWindowSize (tAutotune* const, int ws);
300− void tAutotune_setFidelityThreshold (tAutotune* const, float threshold);
301− void tAutotune_setAlpha (tAutotune* const, float alpha);
302− void tAutotune_setTolerance (tAutotune* const, float tolerance);
303− float tAutotune_getInputPeriod (tAutotune* const);
304− float tAutotune_getInputFreq (tAutotune* const);
305−
306− //==============================================================================
307−
308−
309− typedef struct _tFormantShifter
310− {
311− int ford;
312− float falph;
313− float flamb;
314− float* fk;
315− float* fb;
316− float* fc;
317− float* frb;
318− float* frc;
319− float* fsig;
320− float* fsmooth;
321− float fhp;
322− float flp;
323− float flpa;
324− float* fbuff;
325− float* ftvec;
326− float fmute;
327− float fmutealph;
328− unsigned int cbi;
329− float shiftFactor;
330− float intensity, invIntensity;
331− tHighpass hp;
332− tHighpass hp2;
333− tFeedbackLeveler fbl1;
334− tFeedbackLeveler fbl2;
335−
336− } _tFormantShifter;
337−
338− typedef _tFormantShifter* tFormantShifter;
339−
340− void tFormantShifter_init (tFormantShifter* const, int order);
341− void tFormantShifter_free (tFormantShifter* const);
342− void tFormantShifter_initToPool (tFormantShifter* const, int order, tMempool* const);
343− void tFormantShifter_freeFromPool (tFormantShifter* const, tMempool* const);
344−
345− float tFormantShifter_tick (tFormantShifter* const, float input);
346− float tFormantShifter_remove (tFormantShifter* const, float input);
347− float tFormantShifter_add (tFormantShifter* const, float input);
348− void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
349− void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);
350− void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);
351−
352− //==============================================================================
353−
354−#ifdef __cplusplus
355−}
356−#endif
357−
358−#endif // LEAF_EFFECTS_H_INCLUDED
359−
360−//==============================================================================
LEAF/Inc/leaf-electrical.h+0−103
@@ -1,103 +0,0 @@
1−/*
2− * leaf-electrical.h
3− *
4− * Created on: Sep 25, 2019
5− * Author: jeffsnyder
6− */
7−
8−#ifndef LEAF_INC_LEAF_ELECTRICAL_H_
9−#define LEAF_INC_LEAF_ELECTRICAL_H_
10−
11−#ifdef __cplusplus
12−extern "C" {
13−#endif
14−
15− //==============================================================================
16−
17−#include "leaf-global.h"
18−#include "leaf-math.h"
19−#include "leaf-mempool.h"
20−
21− /*!
22− * @internal
23− * Header.
24− * @include basic-oscillators.h
25− * @example basic-oscillators.c
26− * An example.
27− */
28−
29− //==============================================================================
30−
31− typedef enum WDFComponentType
32− {
33− SeriesAdaptor = 0,
34− ParallelAdaptor,
35− Resistor,
36− Capacitor,
37− Inductor,
38− Inverter,
39− ResistiveSource,
40− IdealSource,
41− Diode,
42− DiodePair,
43− RootNil,
44− WDFComponentNil
45− } WDFComponentType;
46−
47− typedef struct _tWDF _tWDF; // needed to allow tWDF pointers in struct
48− typedef _tWDF* tWDF;
49− struct _tWDF
50− {
51− WDFComponentType type;
52− float port_resistance_up;
53− float port_resistance_left;
54− float port_resistance_right;
55− float port_conductance_up;
56− float port_conductance_left;
57− float port_conductance_right;
58− float incident_wave_up;
59− float incident_wave_left;
60− float incident_wave_right;
61− float reflected_wave_up;
62− float reflected_wave_left;
63− float reflected_wave_right;
64− float gamma_zero;
65− float sample_rate;
66− float value;
67− tWDF* child_left;
68− tWDF* child_right;
69− float (*get_port_resistance)(tWDF* const);
70− float (*get_reflected_wave_up)(tWDF* const, float);
71− float (*get_reflected_wave_down)(tWDF* const, float, float);
72− void (*set_incident_wave)(tWDF* const, float, float);
73− };
74−
75− //WDF Linear Components
76− void tWDF_init (tWDF* const, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
77− void tWDF_free (tWDF* const);
78− void tWDF_initToPool (tWDF* const, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR, tMempool* const);
79− void tWDF_freeFromPool (tWDF* const, tMempool* const);
80−
81− float tWDF_tick (tWDF* const, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
82−
83− void tWDF_setValue (tWDF* const, float value);
84− void tWDF_setSampleRate (tWDF* const, float sample_rate);
85− uint8_t tWDF_isLeaf (tWDF* const);
86−
87− float tWDF_getPortResistance (tWDF* const);
88− float tWDF_getReflectedWaveUp (tWDF* const, float input); //for tree, only uses input for resistive source
89− float tWDF_getReflectedWaveDown (tWDF* const, float input, float incident_wave); //for roots
90− void tWDF_setIncidentWave (tWDF* const, float incident_wave, float input);
91−
92− float tWDF_getVoltage (tWDF* const);
93− float tWDF_getCurrent (tWDF* const);
94−
95−
96− //==============================================================================
97−
98−#ifdef __cplusplus
99−}
100−#endif
101−
102−#endif /* LEAF_INC_LEAF_ELECTRICAL_H_ */
103−
LEAF/Inc/leaf-envelopes.h+0−366
@@ -1,366 +0,0 @@
1−/*
2− ==============================================================================
3−
4− leaf-envelopes.h
5− Created: 20 Jan 2017 12:02:17pm
6− Author: Michael R Mulshine
7−
8− ==============================================================================
9− */
10−
11−#ifndef LEAF_ENVELOPES_H_INCLUDED
12−#define LEAF_ENVELOPES_H_INCLUDED
13−
14−#ifdef __cplusplus
15−extern "C" {
16−#endif
17−
18− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
19−
20−#include "leaf-math.h"
21−#include "leaf-mempool.h"
22−#include "leaf-filters.h"
23−#include "leaf-delay.h"
24−#include "leaf-analysis.h"
25−#include "leaf-envelopes.h"
26−
27− /*!
28− * @internal
29− * Header.
30− * @include basic-oscillators.h
31− * @example basic-oscillators.c
32− * An example.
33− */
34−
35− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
36−
37− /* Attack-Decay envelope */
38− typedef struct _tEnvelope {
39−
40− const float *exp_buff;
41− const float *inc_buff;
42− uint32_t buff_size;
43−
44− float next;
45−
46− float attackInc, decayInc, rampInc;
47−
48− int inAttack, inDecay, inRamp;
49−
50− int loop;
51−
52− float gain, rampPeak;
53−
54− float attackPhase, decayPhase, rampPhase;
55−
56− } _tEnvelope;
57−
58− typedef _tEnvelope* tEnvelope;
59−
60− void tEnvelope_init (tEnvelope* const, float attack, float decay, int loop);
61− void tEnvelope_free (tEnvelope* const);
62− void tEnvelope_initToPool (tEnvelope* const, float attack, float decay, int loop, tMempool* const);
63− void tEnvelope_freeFromPool (tEnvelope* const, tMempool* const);
64−
65− float tEnvelope_tick (tEnvelope* const);
66− void tEnvelope_setAttack (tEnvelope* const, float attack);
67− void tEnvelope_setDecay (tEnvelope* const, float decay);
68− void tEnvelope_loop (tEnvelope* const, int loop);
69− void tEnvelope_on (tEnvelope* const, float velocity);
70−
71− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
72−
73−
74−
75− /* Exponential Smoother */
76− typedef struct _tExpSmooth {
77− float factor, oneminusfactor;
78− float curr,dest;
79−
80− } _tExpSmooth;
81−
82− typedef _tExpSmooth* tExpSmooth;
83−
84− void tExpSmooth_init (tExpSmooth* const, float val, float factor);
85− void tExpSmooth_free (tExpSmooth* const);
86− void tExpSmooth_initToPool (tExpSmooth* const, float val, float factor, tMempool* const);
87− void tExpSmooth_freeFromPool (tExpSmooth* const, tMempool* const);
88−
89− float tExpSmooth_tick (tExpSmooth* const);
90− float tExpSmooth_sample (tExpSmooth* const);
91− void tExpSmooth_setFactor (tExpSmooth* const, float factor);
92− void tExpSmooth_setDest (tExpSmooth* const, float dest);
93− void tExpSmooth_setVal (tExpSmooth* const, float val);
94− void tExpSmooth_setValAndDest(tExpSmooth* const expsmooth, float val);
95−
96− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
97−
98−
99− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
100−
101−
102− /* ADSR */
103− typedef struct _tADSR
104− {
105− const float *exp_buff;
106− const float *inc_buff;
107− uint32_t buff_size;
108−
109− float next;
110−
111− float attackInc, decayInc, releaseInc, rampInc;
112−
113− oBool inAttack, inDecay, inSustain, inRelease, inRamp;
114−
115− float sustain, gain, rampPeak, releasePeak;
116−
117− float attackPhase, decayPhase, releasePhase, rampPhase;
118−
119− float leakFactor;
120−
121−
122− } _tADSR;
123−
124− typedef _tADSR* tADSR;
125−
126− void tADSR_init (tADSR* const adsrenv, float attack, float decay, float sustain, float release);
127− void tADSR_free (tADSR* const);
128− void tADSR_initToPool (tADSR* const adsrenv, float attack, float decay, float sustain, float release, tMempool* const mp);
129− void tADSR_freeFromPool (tADSR* const, tMempool* const);
130−
131− float tADSR_tick (tADSR* const);
132− void tADSR_setAttack (tADSR* const, float attack);
133− void tADSR_setDecay (tADSR* const, float decay);
134− void tADSR_setSustain (tADSR* const, float sustain);
135− void tADSR_setRelease (tADSR* const, float release);
136− void tADSR_setLeakFactor (tADSR* const, float leakFactor);
137− void tADSR_on (tADSR* const, float velocity);
138− void tADSR_off (tADSR* const);
139−
140−
141−
142−
143− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
144−
145−
146−
147− /* ADSR2 */
148− typedef struct _tADSR2
149− {
150− float sampleRateInMs;
151− float attack;
152− float decay;
153− float release;
154− float attackLambda;
155− float decayLambda;
156− float releaseLambda;
157− float sustain;
158− float leakGain;
159− float leakFactor;
160− float targetGainSquared;
161− float factor;
162− float oneMinusFactor;
163− float gain;
164− uint8_t attacking;
165− uint8_t gate;
166− float env;
167− float envTarget;
168− } _tADSR2;
169−
170− typedef _tADSR2* tADSR2;
171−
172− void tADSR2_init (tADSR2* const, float attack, float decay, float sustain, float release);
173− void tADSR2_free (tADSR2* const);
174− void tADSR2_initToPool (tADSR2* const, float attack, float decay, float sustain, float release, tMempool* const);
175− void tADSR2_freeFromPool (tADSR2* const, tMempool* const);
176−
177− float tADSR2_tick (tADSR2* const);
178− void tADSR2_setAttack (tADSR2* const, float attack);
179− void tADSR2_setDecay (tADSR2* const, float decay);
180− void tADSR2_setSustain (tADSR2* const, float sustain);
181− void tADSR2_setRelease (tADSR2* const, float release);
182− void tADSR2_setLeakFactor (tADSR2* const, float leakFactor);
183− void tADSR2_on (tADSR2* const, float velocity);
184− void tADSR2_off (tADSR2* const);
185−
186−
187− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
188−
189− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
190− enum envState {
191− env_idle = 0,
192− env_attack,
193− env_decay,
194− env_sustain,
195− env_release,
196− env_ramp
197− };
198−
199− /* ADSR3 */
200− typedef struct _tADSR3
201− {
202− float sampleRateInMs;
203− int state;
204− float output;
205− float attackRate;
206− float decayRate;
207− float releaseRate;
208− float attackCoef;
209− float decayCoef;
210− float releaseCoef;
211− float sustainLevel;
212− float targetRatioA;
213− float targetRatioDR;
214− float attackBase;
215− float decayBase;
216− float releaseBase;
217− float leakFactor;
218− float targetGainSquared;
219− float factor;
220− float oneMinusFactor;
221− float gain;
222−
223− } _tADSR3;
224−
225− typedef _tADSR3* tADSR3;
226−
227− void tADSR3_init (tADSR3* const, float attack, float decay, float sustain, float release);
228− void tADSR3_free (tADSR3* const);
229− void tADSR3_initToPool (tADSR3* const, float attack, float decay, float sustain, float release, tMempool* const);
230− void tADSR3_freeFromPool (tADSR3* const, tMempool* const);
231−
232− float tADSR3_tick (tADSR3* const);
233− void tADSR3_setAttack (tADSR3* const, float attack);
234− void tADSR3_setDecay (tADSR3* const, float decay);
235− void tADSR3_setSustain (tADSR3* const, float sustain);
236− void tADSR3_setRelease (tADSR3* const, float release);
237− void tADSR3_setLeakFactor (tADSR3* const, float leakFactor);
238− void tADSR3_on (tADSR3* const, float velocity);
239− void tADSR3_off (tADSR3* const);
240−
241− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
242−
243− //ADSR4
244−
245−
246− typedef struct _tADSR4
247− {
248− const float *exp_buff;
249− uint32_t buff_size;
250− uint32_t buff_sizeMinusOne;
251− float bufferSizeDividedBySampleRateInMs;
252− float next;
253−
254− float attackInc, decayInc, releaseInc, rampInc;
255−
256− uint32_t whichStage;
257−
258− float sustain, gain, rampPeak, releasePeak;
259−
260− float attackPhase, decayPhase, releasePhase, rampPhase;
261−
262− float leakFactor;
263−
264−
265− } _tADSR4;
266−
267− typedef _tADSR4* tADSR4;
268−
269− void tADSR4_init (tADSR4* const, float attack, float decay, float sustain, float release, float* expBuffer, int bufferSize);
270− void tADSR4_free (tADSR4* const);
271− void tADSR4_initToPool (tADSR4* const, float attack, float decay, float sustain, float release, float* expBuffer, int bufferSize, tMempool* const);
272− void tADSR4_freeFromPool (tADSR4* const, tMempool* const);
273−
274− float tADSR4_tick (tADSR4* const);
275− float tADSR4_tickNoInterp (tADSR4* const adsrenv);
276− void tADSR4_setAttack (tADSR4* const, float attack);
277− void tADSR4_setDecay (tADSR4* const, float decay);
278− void tADSR4_setSustain (tADSR4* const, float sustain);
279− void tADSR4_setRelease (tADSR4* const, float release);
280− void tADSR4_setLeakFactor (tADSR4* const, float leakFactor);
281− void tADSR4_on (tADSR4* const, float velocity);
282− void tADSR4_off (tADSR4* const);
283− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
284−
285− /* Ramp */
286− typedef struct _tRamp {
287− float inc;
288− float inv_sr_ms;
289− float minimum_time;
290− float curr,dest;
291− float time;
292− float factor;
293− int samples_per_tick;
294−
295− } _tRamp;
296−
297− typedef _tRamp* tRamp;
298−
299− void tRamp_init (tRamp* const, float time, int samplesPerTick);
300− void tRamp_free (tRamp* const);
301− void tRamp_initToPool (tRamp* const, float time, int samplesPerTick, tMempool* const);
302− void tRamp_freeFromPool (tRamp* const, tMempool* const);
303−
304− float tRamp_tick (tRamp* const);
305− float tRamp_sample (tRamp* const);
306− void tRamp_setTime (tRamp* const, float time);
307− void tRamp_setDest (tRamp* const, float dest);
308− void tRamp_setVal (tRamp* const, float val);
309−
310− ///=============
311− /* Ramp Updown*/
312− typedef struct _tRampUpDown {
313− float upInc;
314− float downInc;
315− float inv_sr_ms;
316− float minimum_time;
317− float curr,dest;
318− float upTime;
319− float downTime;
320− int samples_per_tick;
321−
322− } _tRampUpDown;
323−
324− typedef _tRampUpDown* tRampUpDown;
325−
326− void tRampUpDown_init (tRampUpDown* const, float upTime, float downTime, int samplesPerTick);
327− void tRampUpDown_free (tRampUpDown* const);
328− void tRampUpDown_initToPool (tRampUpDown* const, float upTime, float downTime, int samplesPerTick, tMempool* const);
329− void tRampUpDown_freeFromPool (tRampUpDown* const, tMempool* const);
330−
331− float tRampUpDown_tick (tRampUpDown* const);
332− float tRampUpDown_sample (tRampUpDown* const);
333− void tRampUpDown_setUpTime (tRampUpDown* const, float upTime);
334− void tRampUpDown_setDownTime (tRampUpDown* const, float downTime);
335− void tRampUpDown_setDest (tRampUpDown* const, float dest);
336− void tRampUpDown_setVal (tRampUpDown* const, float val);
337−
338−
339− ///=========================
340− //Slide (based on Max/MSP's slide~)
341− typedef struct _tSlide {
342− float prevOut;
343− float currentOut;
344− float prevIn;
345− float invUpSlide;
346− float invDownSlide;
347−
348− } _tSlide;
349−
350− typedef _tSlide* tSlide;
351−
352− void tSlide_init (tSlide* const, float upSlide, float downSlide);
353− void tSlide_free (tSlide* const);
354− void tSlide_initToPool (tSlide* const, float upSlide, float downSlide, tMempool* const);
355− void tSlide_freeFromPool (tSlide* const, tMempool* const);
356−
357− float tSlide_tick (tSlide* const, float in);
358−
359−#ifdef __cplusplus
360−}
361−#endif
362−
363−#endif // LEAF_ENVELOPES_H_INCLUDED
364−
365−
366−
LEAF/Inc/leaf-filters.h+0−486
@@ -1,486 +0,0 @@
1−/*==============================================================================
2−
3− leaf-filters.h
4− Created: 20 Jan 2017 12:01:10pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_FILTERS_H_INCLUDED
10−#define LEAF_FILTERS_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-math.h"
19−#include "leaf-mempool.h"
20−#include "leaf-delay.h"
21−#include "leaf-tables.h"
22−
23− /*!
24− * @internal
25− * Header.
26− * @include basic-oscillators.h
27− * @example basic-oscillators.c
28− * An example.
29− */
30−
31− //==============================================================================
32−
33− /* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
34− typedef struct _tAllpass
35− {
36− float gain;
37−
38− tLinearDelay delay;
39−
40− float lastOut;
41−
42− } _tAllpass;
43−
44− typedef _tAllpass* tAllpass;
45−
46− void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
47− void tAllpass_free (tAllpass* const);
48− void tAllpass_initToPool (tAllpass* const, float initDelay, uint32_t maxDelay, tMempool* const);
49− void tAllpass_freeFromPool (tAllpass* const, tMempool* const);
50−
51− float tAllpass_tick (tAllpass* const, float input);
52− void tAllpass_setGain (tAllpass* const, float gain);
53− void tAllpass_setDelay (tAllpass* const, float delay);
54−
55−
56− //==============================================================================
57−
58− /* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
59− typedef struct _tOnePole
60− {
61− float gain;
62− float a0,a1;
63− float b0,b1;
64− float lastIn, lastOut;
65−
66−
67− } _tOnePole;
68−
69− typedef _tOnePole* tOnePole;
70−
71− void tOnePole_init (tOnePole* const, float thePole);
72− void tOnePole_free (tOnePole* const);
73− void tOnePole_initToPool (tOnePole* const, float thePole, tMempool* const);
74− void tOnePole_freeFromPool (tOnePole* const, tMempool* const);
75−
76− float tOnePole_tick (tOnePole* const, float input);
77− void tOnePole_setB0 (tOnePole* const, float b0);
78− void tOnePole_setA1 (tOnePole* const, float a1);
79− void tOnePole_setPole (tOnePole* const, float thePole);
80− void tOnePole_setFreq (tOnePole* const, float freq);
81− void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
82− void tOnePole_setGain (tOnePole* const, float gain);
83−
84− //==============================================================================
85−
86− /* TwoPole filter, reimplemented from STK (Cook and Scavone). */
87− typedef struct _tTwoPole
88− {
89− float gain;
90− float a0, a1, a2;
91− float b0;
92−
93− float radius, frequency;
94− oBool normalize;
95−
96− float lastOut[2];
97−
98− } _tTwoPole;
99−
100− typedef _tTwoPole* tTwoPole;
101−
102− void tTwoPole_init (tTwoPole* const);
103− void tTwoPole_free (tTwoPole* const);
104− void tTwoPole_initToPool (tTwoPole* const, tMempool* const);
105− void tTwoPole_freeFromPool (tTwoPole* const, tMempool* const);
106−
107− float tTwoPole_tick (tTwoPole* const, float input);
108− void tTwoPole_setB0 (tTwoPole* const, float b0);
109− void tTwoPole_setA1 (tTwoPole* const, float a1);
110− void tTwoPole_setA2 (tTwoPole* const, float a2);
111− void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, oBool normalize);
112− void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
113− void tTwoPole_setGain (tTwoPole* const, float gain);
114−
115− //==============================================================================
116−
117− /* OneZero filter, reimplemented from STK (Cook and Scavone). */
118− typedef struct _tOneZero
119− {
120− float gain;
121− float b0,b1;
122− float lastIn, lastOut, frequency;
123−
124− } _tOneZero;
125−
126− typedef _tOneZero* tOneZero;
127−
128− void tOneZero_init (tOneZero* const, float theZero);
129− void tOneZero_free (tOneZero* const);
130− void tOneZero_initToPool (tOneZero* const, float theZero, tMempool* const);
131− void tOneZero_freeFromPool (tOneZero* const, tMempool* const);
132−
133− float tOneZero_tick (tOneZero* const, float input);
134− void tOneZero_setB0 (tOneZero* const, float b0);
135− void tOneZero_setB1 (tOneZero* const, float b1);
136− void tOneZero_setZero (tOneZero* const, float theZero);
137− void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
138− void tOneZero_setGain (tOneZero* const, float gain);
139− float tOneZero_getPhaseDelay (tOneZero *f, float frequency );
140−
141− //==============================================================================
142−
143− /* TwoZero filter, reimplemented from STK (Cook and Scavone). */
144− typedef struct _tTwoZero
145− {
146− float gain;
147− float b0, b1, b2;
148−
149− float frequency, radius;
150−
151− float lastIn[2];
152−
153− } _tTwoZero;
154−
155− typedef _tTwoZero* tTwoZero;
156−
157− void tTwoZero_init (tTwoZero* const);
158− void tTwoZero_free (tTwoZero* const);
159− void tTwoZero_initToPool (tTwoZero* const, tMempool* const);
160− void tTwoZero_freeFromPool (tTwoZero* const, tMempool* const);
161−
162− float tTwoZero_tick (tTwoZero* const, float input);
163− void tTwoZero_setB0 (tTwoZero* const, float b0);
164− void tTwoZero_setB1 (tTwoZero* const, float b1);
165− void tTwoZero_setB2 (tTwoZero* const, float b2);
166− void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
167− void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
168− void tTwoZero_setGain (tTwoZero* const, float gain);
169−
170− //==============================================================================
171−
172− /* PoleZero filter, reimplemented from STK (Cook and Scavone). */
173− typedef struct _tPoleZero
174− {
175− float gain;
176− float a0,a1;
177− float b0,b1;
178−
179− float lastIn, lastOut;
180−
181− } _tPoleZero;
182−
183− typedef _tPoleZero* tPoleZero;
184−
185− void tPoleZero_init (tPoleZero* const);
186− void tPoleZero_free (tPoleZero* const);
187− void tPoleZero_initToPool (tPoleZero* const, tMempool* const);
188− void tPoleZero_freeFromPool (tPoleZero* const, tMempool* const);
189−
190− float tPoleZero_tick (tPoleZero* const, float input);
191− void tPoleZero_setB0 (tPoleZero* const, float b0);
192− void tPoleZero_setB1 (tPoleZero* const, float b1);
193− void tPoleZero_setA1 (tPoleZero* const, float a1);
194− void tPoleZero_setCoefficients (tPoleZero* const, float b0, float b1, float a1);
195− void tPoleZero_setAllpass (tPoleZero* const, float coeff);
196− void tPoleZero_setBlockZero (tPoleZero* const, float thePole);
197− void tPoleZero_setGain (tPoleZero* const, float gain);
198−
199− //==============================================================================
200−
201− /* BiQuad filter, reimplemented from STK (Cook and Scavone). */
202− typedef struct _tBiQuad
203− {
204− float gain;
205− float a0, a1, a2;
206− float b0, b1, b2;
207−
208− float lastIn[2];
209− float lastOut[2];
210−
211− float frequency, radius;
212− oBool normalize;
213− } _tBiQuad;
214−
215− typedef _tBiQuad* tBiQuad;
216−
217− void tBiQuad_init (tBiQuad* const);
218− void tBiQuad_free (tBiQuad* const);
219− void tBiQuad_initToPool (tBiQuad* const, tMempool* const);
220− void tBiQuad_freeFromPool (tBiQuad* const, tMempool* const);
221−
222− float tBiQuad_tick (tBiQuad* const, float input);
223− void tBiQuad_setB0 (tBiQuad* const, float b0);
224− void tBiQuad_setB1 (tBiQuad* const, float b1);
225− void tBiQuad_setB2 (tBiQuad* const, float b2);
226− void tBiQuad_setA1 (tBiQuad* const, float a1);
227− void tBiQuad_setA2 (tBiQuad* const, float a2);
228− void tBiQuad_setNotch (tBiQuad* const, float freq, float radius);
229− void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, oBool normalize);
230− void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
231− void tBiQuad_setGain (tBiQuad* const, float gain);
232−
233− //==============================================================================
234−
235−/* State Variable Filter, algorithm from Andy Simper. */
236− typedef enum SVFType
237− {
238− SVFTypeHighpass = 0,
239− SVFTypeLowpass,
240− SVFTypeBandpass,
241− SVFTypeNotch,
242− SVFTypePeak,
243− SVFTypeLowShelf,
244− SVFTypeHighShelf
245− } SVFType;
246−
247− typedef struct _tSVF
248− {
249− SVFType type;
250− float cutoff, Q;
251− float ic1eq,ic2eq;
252− float g,k,a1,a2,a3,cH,cB,cL,cBK;
253−
254−
255− } _tSVF;
256−
257− typedef _tSVF* tSVF;
258−
259− void tSVF_init (tSVF* const, SVFType type, float freq, float Q);
260− void tSVF_free (tSVF* const);
261− void tSVF_initToPool (tSVF* const, SVFType type, float freq, float Q, tMempool* const);
262− void tSVF_freeFromPool (tSVF* const, tMempool* const);
263−
264− float tSVF_tick (tSVF* const, float v0);
265− void tSVF_setFreq (tSVF* const, float freq);
266− void tSVF_setQ (tSVF* const, float Q);
267− void tSVF_setFreqAndQ (tSVF* const svff, float freq, float Q);
268− //==============================================================================
269−
270− /* Efficient State Variable Filter for 14-bit control input, [0, 4096). */
271− typedef struct _tEfficientSVF
272− {
273− SVFType type;
274− float cutoff, Q;
275− float ic1eq,ic2eq;
276− float g,k,a1,a2,a3;
277−
278− } _tEfficientSVF;
279−
280− typedef _tEfficientSVF* tEfficientSVF;
281−
282− void tEfficientSVF_init (tEfficientSVF* const, SVFType type, uint16_t input, float Q);
283− void tEfficientSVF_free (tEfficientSVF* const);
284− void tEfficientSVF_initToPool (tEfficientSVF* const, SVFType type, uint16_t input, float Q, tMempool* const);
285− void tEfficientSVF_freeFromPool (tEfficientSVF* const, tMempool* const);
286−
287− float tEfficientSVF_tick (tEfficientSVF* const, float v0);
288− void tEfficientSVF_setFreq (tEfficientSVF* const, uint16_t controlFreq);
289− void tEfficientSVF_setQ (tEfficientSVF* const, float Q);
290−
291− //==============================================================================
292−
293− /* Simple Highpass filter. */
294− typedef struct _tHighpass
295− {
296− float xs, ys, R;
297− float frequency;
298−
299− } _tHighpass;
300−
301− typedef _tHighpass* tHighpass;
302−
303− void tHighpass_init (tHighpass* const, float freq);
304− void tHighpass_free (tHighpass* const);
305− void tHighpass_initToPool (tHighpass* const, float freq, tMempool* const);
306− void tHighpass_freeFromPool (tHighpass* const, tMempool* const);
307−
308− float tHighpass_tick (tHighpass* const, float x);
309− void tHighpass_setFreq (tHighpass* const, float freq);
310− float tHighpass_getFreq (tHighpass* const);
311−
312− //==============================================================================
313−
314− // Butterworth Filter
315−#define NUM_SVF_BW 16
316− typedef struct _tButterworth
317− {
318− float gain;
319−
320− int N;
321−
322− tSVF low[NUM_SVF_BW];
323− tSVF high[NUM_SVF_BW];
324−
325− float f1,f2;
326−
327− } _tButterworth;
328−
329− typedef _tButterworth* tButterworth;
330−
331− void tButterworth_init (tButterworth* const, int N, float f1, float f2);
332− void tButterworth_free (tButterworth* const);
333− void tButterworth_initToPool (tButterworth* const, int N, float f1, float f2, tMempool* const);
334− void tButterworth_freeFromPool (tButterworth* const, tMempool* const);
335−
336− float tButterworth_tick (tButterworth* const, float input);
337− void tButterworth_setF1 (tButterworth* const, float in);
338− void tButterworth_setF2 (tButterworth* const, float in);
339− void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
340−
341− //==============================================================================
342−
343− typedef struct _tFIR
344− {
345− float* past;
346− float* coeff;
347− int numTaps;
348− } _tFIR;
349−
350− typedef _tFIR* tFIR;
351−
352− void tFIR_init (tFIR* const, float* coeffs, int numTaps);
353− void tFIR_free (tFIR* const);
354− void tFIR_initToPool (tFIR* const, float* coeffs, int numTaps, tMempool* const);
355− void tFIR_freeFromPool (tFIR* const, tMempool* const);
356−
357− float tFIR_tick (tFIR* const, float input);
358−
359−
360− //==============================================================================
361−
362−
363− typedef struct _tMedianFilter
364− {
365− float* val;
366− int* age;
367− int m;
368− int size;
369− int middlePosition;
370− int last;
371− int pos;
372− } _tMedianFilter;
373−
374− typedef _tMedianFilter* tMedianFilter;
375−
376− void tMedianFilter_init (tMedianFilter* const, int size);
377− void tMedianFilter_free (tMedianFilter* const);
378− void tMedianFilter_initToPool (tMedianFilter* const, int size, tMempool* const);
379− void tMedianFilter_freeFromPool (tMedianFilter* const, tMempool* const);
380−
381− float tMedianFilter_tick (tMedianFilter* const, float input);
382−
383−
384−
385−
386−
387− //Vadim Zavalishin style from VA book (from implementation in RSlib posted to kvr forum)
388−
389− typedef enum VZFilterType
390− {
391− Highpass = 0,
392− Lowpass,
393− BandpassSkirt,
394− BandpassPeak,
395− BandReject,
396− Bell,
397− Lowshelf,
398− Highshelf,
399− Morph,
400− Bypass,
401− Allpass
402− } VZFilterType;
403−
404−
405− typedef struct _tVZFilter
406− {
407− VZFilterType type;
408− // state:
409− float s1, s2;
410−
411− // filter coefficients:
412− float g; // embedded integrator gain
413− float R2; // twice the damping coefficient (R2 == 2*R == 1/Q)
414− float h; // factor for feedback (== 1/(1+2*R*g+g*g))
415− float cL, cB, cH; // coefficients for low-, band-, and highpass signals
416−
417− // parameters:
418− float fs; // sample-rate
419− float fc; // characteristic frequency
420− float G; // gain
421− float invG; //1/gain
422− float B; // bandwidth (in octaves)
423− float m; // morph parameter (0...1)
424−
425− float sr; //local sampling rate of filter (may be different from leaf sr if oversampled)
426− float inv_sr;
427−
428− } _tVZFilter;
429−
430− typedef _tVZFilter* tVZFilter;
431−
432− void tVZFilter_init (tVZFilter* const, VZFilterType type, float freq, float Q);
433− void tVZFilter_free (tVZFilter* const);
434− void tVZFilter_initToPool (tVZFilter* const, VZFilterType type, float freq, float Q, tMempool* const);
435− void tVZFilter_freeFromPool (tVZFilter* const, tMempool* const);
436− void tVZFilter_setSampleRate (tVZFilter* const, float sampleRate);
437− float tVZFilter_tick (tVZFilter* const, float input);
438− float tVZFilter_tickEfficient (tVZFilter* const vf, float in);
439− void tVZFilter_calcCoeffs (tVZFilter* const);
440− void tVZFilter_setBandwidth (tVZFilter* const, float bandWidth);
441− void tVZFilter_setFreq (tVZFilter* const, float freq);
442− void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw);
443− void tVZFilter_setGain (tVZFilter* const, float gain);
444− void tVZFilter_setType (tVZFilter* const, VZFilterType type);
445− float tVZFilter_BandwidthToR (tVZFilter* const vf, float B);
446−
447−
448−
449−
450− //diode ladder filter
451− typedef struct _tDiodeFilter
452− {
453−
454− float f;
455− float r;
456− float Vt;
457− float n;
458− float gamma;
459− float zi;
460− float g0inv;
461− float g1inv;
462− float g2inv;
463− float s0, s1, s2, s3;
464−
465− } _tDiodeFilter;
466−
467− typedef _tDiodeFilter* tDiodeFilter;
468−
469− void tDiodeFilter_init (tDiodeFilter* const, float freq, float Q);
470− void tDiodeFilter_free (tDiodeFilter* const);
471− void tDiodeFilter_initToPool (tDiodeFilter* const, float freq, float Q, tMempool* const);
472− void tDiodeFilter_freeFromPool (tDiodeFilter* const, tMempool* const);
473−
474− float tDiodeFilter_tick (tDiodeFilter* const, float input);
475− void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff);
476− void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance);
477−
478−
479−#ifdef __cplusplus
480−}
481−#endif
482−
483−#endif // LEAF_FILTERS_H_INCLUDED
484−
485−//==============================================================================
486−
LEAF/Inc/leaf-global.h+0−52
@@ -1,52 +0,0 @@
1−/*
2− ==============================================================================
3−
4− leaf-global.h
5− Created: 24 Oct 2019 2:24:38pm
6− Author: Matthew Wang
7−
8− ==============================================================================
9− */
10−
11−#ifndef LEAF_GLOBAL_H_INCLUDED
12−#define LEAF_GLOBAL_H_INCLUDED
13−
14−#ifdef __cplusplus
15−extern "C" {
16−#endif
17−
18−#include "leaf-mempool.h"
19−
20− /*!
21− * @ingroup leaf
22− * @brief The struct of the global LEAF instance `leaf`. Contains global variables and settings.
23− */
24− struct LEAF
25− {
26− ///@{
27− float sampleRate; //!< The current audio sample rate. Set with LEAF_setSampleRate().
28− float invSampleRate; //!< The inverse of the current sample rate.
29− int blockSize; //!< The audio block size.
30− float twoPiTimesInvSampleRate; //!< Two-pi times the inverse of the current sample rate.
31− float (*random)(void); //!< A pointer to the random() function provided on initialization.
32− int clearOnAllocation; //!< A flag that determines whether memory allocated from the LEAF memory pool will be cleared.
33− tMempool mempool; //!< The default LEAF mempool object.
34− _tMempool _mempool;
35− size_t header_size; //!< The size in bytes of memory region headers within mempools.
36− ///@}
37− };
38− typedef struct LEAF LEAF;
39−
40− extern LEAF leaf;
41−
42− //==============================================================================
43−
44−#ifdef __cplusplus
45−}
46−#endif
47−
48−#endif // LEAF_GLOBAL_H_INCLUDED
49−
50−//==============================================================================
51−
52−
LEAF/Inc/leaf-instruments.h+0−209
@@ -1,209 +0,0 @@
1−/*==============================================================================
2−
3− leaf-instruments.h
4− Created: 30 Nov 2018 10:24:44am
5− Author: airship
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_INSTRUMENTS_H_INCLUDED
10−#define LEAF_INSTRUMENTS_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-math.h"
19−#include "leaf-mempool.h"
20−#include "leaf-oscillators.h"
21−#include "leaf-filters.h"
22−#include "leaf-envelopes.h"
23−
24− /*!
25− * @internal
26− * Header.
27− * @include basic-oscillators.h
28− * @example basic-oscillators.c
29− * An example.
30− */
31−
32− //==============================================================================
33−
34− // 808 Cowbell
35− typedef struct _t808Cowbell {
36−
37− tSquare p[2];
38− tNoise stick;
39− tSVF bandpassOsc;
40− tSVF bandpassStick;
41− tEnvelope envGain;
42− tEnvelope envStick;
43− tEnvelope envFilter;
44− tHighpass highpass;
45− float oscMix;
46− float filterCutoff;
47− uint8_t useStick;
48−
49− } _t808Cowbell;
50−
51− typedef _t808Cowbell* t808Cowbell;
52−
53− void t808Cowbell_init (t808Cowbell* const, int useStick);
54− void t808Cowbell_free (t808Cowbell* const);
55− void t808Cowbell_initToPool (t808Cowbell* const, int useStick, tMempool* const);
56− void t808Cowbell_freeFromPool (t808Cowbell* const, tMempool* const);
57−
58− float t808Cowbell_tick (t808Cowbell* const);
59− void t808Cowbell_on (t808Cowbell* const, float vel);
60− void t808Cowbell_setDecay (t808Cowbell* const, float decay);
61− void t808Cowbell_setHighpassFreq (t808Cowbell* const, float freq);
62− void t808Cowbell_setBandpassFreq (t808Cowbell* const, float freq);
63− void t808Cowbell_setFreq (t808Cowbell* const, float freq);
64− void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
65− void t808Cowbell_setStick (t808Cowbell* const, int useStick);
66−
67− //==============================================================================
68−
69− // 808 Hihat
70− typedef struct _t808Hihat {
71−
72− // 6 Square waves
73− tSquare p[6];
74− tNoise n;
75− tSVF bandpassOsc;
76− tSVF bandpassStick;
77− tEnvelope envGain;
78− tEnvelope envStick;
79− tEnvelope noiseFMGain;
80− tHighpass highpass;
81− tNoise stick;
82−
83− float freq;
84− float stretch;
85− float FM_amount;
86− float oscNoiseMix;
87−
88− } _t808Hihat;
89−
90− typedef _t808Hihat* t808Hihat;
91−
92− void t808Hihat_init (t808Hihat* const);
93− void t808Hihat_free (t808Hihat* const);
94− void t808Hihat_initToPool (t808Hihat* const, tMempool* const);
95− void t808Hihat_freeFromPool (t808Hihat* const, tMempool* const);
96−
97− float t808Hihat_tick (t808Hihat* const);
98− void t808Hihat_on (t808Hihat* const, float vel);
99− void t808Hihat_setOscNoiseMix (t808Hihat* const, float oscNoiseMix);
100− void t808Hihat_setDecay (t808Hihat* const, float decay);
101− void t808Hihat_setHighpassFreq (t808Hihat* const, float freq);
102− void t808Hihat_setOscBandpassFreq (t808Hihat* const, float freq);
103− void t808Hihat_setOscBandpassQ (t808Hihat* const hihat, float Q);
104− void t808Hihat_setStickBandPassFreq (t808Hihat* const, float freq);
105− void t808Hihat_setStickBandPassQ (t808Hihat* const hihat, float Q);
106− void t808Hihat_setOscFreq (t808Hihat* const, float freq);
107− void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
108− void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
109−
110− //==============================================================================
111−
112− // 808 Snare
113− typedef struct _t808Snare {
114−
115− // Tone 1, Tone 2, Noise
116− tTriangle tone[2]; // Tri (not yet antialiased or wavetabled)
117− tNoise noiseOsc;
118− tSVF toneLowpass[2];
119− tSVF noiseLowpass; // Lowpass from SVF filter
120− tEnvelope toneEnvOsc[2];
121− tEnvelope toneEnvGain[2];
122− tEnvelope noiseEnvGain;
123− tEnvelope toneEnvFilter[2];
124− tEnvelope noiseEnvFilter;
125−
126− float toneGain[2];
127− float noiseGain;
128−
129− float toneNoiseMix;
130−
131− float tone1Freq, tone2Freq;
132−
133− float noiseFilterFreq;
134−
135− } _t808Snare;
136−
137− typedef _t808Snare* t808Snare;
138−
139− void t808Snare_init (t808Snare* const);
140− void t808Snare_free (t808Snare* const);
141− void t808Snare_initToPool (t808Snare* const, tMempool* const);
142− void t808Snare_freeFromPool (t808Snare* const, tMempool* const);
143−
144− float t808Snare_tick (t808Snare* const);
145− void t808Snare_on (t808Snare* const, float vel);
146− void t808Snare_setTone1Freq (t808Snare* const, float freq);
147− void t808Snare_setTone2Freq (t808Snare* const, float freq);
148− void t808Snare_setTone1Decay (t808Snare* const, float decay);
149− void t808Snare_setTone2Decay (t808Snare* const, float decay);
150− void t808Snare_setNoiseDecay (t808Snare* const, float decay);
151− void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
152− void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
153− void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
154−
155− //==============================================================================
156−
157− // 808 Kick
158− typedef struct _t808Kick {
159−
160−
161− tCycle tone; // Tri
162− tNoise noiseOsc;
163− tSVF toneLowpass;
164− tEnvelope toneEnvOscChirp;
165− tEnvelope toneEnvOscSigh;
166− tEnvelope toneEnvGain;
167− tEnvelope noiseEnvGain;
168− tEnvelope toneEnvFilter;
169−
170− float toneGain;
171− float noiseGain;
172−
173− float toneInitialFreq;
174− float sighAmountInHz;
175− float chirpRatioMinusOne;
176− float noiseFilterFreq;
177−
178− } _t808Kick;
179−
180− typedef _t808Kick* t808Kick;
181−
182− void t808Kick_init (t808Kick* const);
183− void t808Kick_free (t808Kick* const);
184− void t808Kick_initToPool (t808Kick* const, tMempool* const);
185− void t808Kick_freeFromPool (t808Kick* const, tMempool* const);
186−
187− float t808Kick_tick (t808Kick* const);
188− void t808Kick_on (t808Kick* const, float vel);
189− void t808Kick_setToneFreq (t808Kick* const, float freq);
190− void t808Kick_setToneDecay (t808Kick* const, float decay);
191− void t808Kick_setNoiseDecay (t808Kick* const, float decay);
192− void t808Kick_setSighAmount (t808Kick* const, float sigh);
193− void t808Kick_setChirpAmount (t808Kick* const, float chirp);
194− void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
195− void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
196− void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
197−
198− //==============================================================================
199−
200−#ifdef __cplusplus
201−}
202−#endif
203−
204−#endif // LEAF_INSTRUMENTS_H_INCLUDED
205−
206−//==============================================================================
207−
208−
209−
LEAF/Inc/leaf-math.h+0−212
@@ -1,212 +0,0 @@
1−/*==============================================================================
2−
3− leaf-math.h
4− Created: 22 Jan 2017 7:02:56pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_MATH_H_INCLUDED
10−#define LEAF_MATH_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16−#include "leaf-global.h"
17−#include "math.h"
18−#include "stdint.h"
19−#include "stdlib.h"
20−
21− //==============================================================================
22−
23− //==============================================================================
24−
25− typedef enum oBool
26− {
27− OTRUE = 1,
28− OFALSE = 0
29− }oBool;
30−
31− // Allows for bitwise operations on floats
32− union unholy_t { /* a union between a float and an integer */
33− float f;
34− int i;
35− };
36−
37−#define SQRT8 2.82842712475f
38−#define WSCALE 1.30612244898f
39−#define PI (3.14159265358979f)
40−#define TWO_PI (6.28318530717958f)
41−#define HALF_PI (1.570796326794897f)
42−
43−#define VSF 1.0e-38f
44−
45−#define MAX_DELAY 8192
46−#define INV_128 0.0078125f
47−
48−#define INV_20 0.05f
49−#define INV_40 0.025f
50−#define INV_80 0.0125f
51−#define INV_160 0.00625f
52−#define INV_320 0.003125f
53−#define INV_640 0.0015625f
54−#define INV_1280 0.00078125f
55−#define INV_2560 0.000390625f
56−#define INV_5120 0.0001953125f
57−#define INV_10240 0.00009765625f
58−#define INV_20480 0.000048828125f
59−
60−
61−#define INV_TWELVE 0.0833333333f
62−#define INV_440 0.0022727273f
63−
64−#define LOG2 0.3010299957f
65−#define INV_LOG2 3.321928095f
66−
67−#define SOS_M 343.0f
68−#define TWO_TO_5 32.0f
69−#define INV_TWO_TO_5 0.03125f
70−#define TWO_TO_7 128.f
71−#define INV_TWO_TO_7 0.0078125f
72−#define TWO_TO_8 256.f
73−#define INV_TWO_TO_8 0.00390625f
74−#define TWO_TO_9 512.f
75−#define INV_TWO_TO_9 0.001953125f
76−#define TWO_TO_10 1024.f
77−#define INV_TWO_TO_10 0.0009765625f
78−#define TWO_TO_11 2048.f
79−#define INV_TWO_TO_11 0.00048828125f
80−#define TWO_TO_12 4096.f
81−#define INV_TWO_TO_12 0.00024414062f
82−#define TWO_TO_15 32768.f
83−#define TWO_TO_16 65536.f
84−#define INV_TWO_TO_15 0.00003051757f
85−#define INV_TWO_TO_16 0.00001525878f
86−#define TWO_TO_16_MINUS_ONE 65535.0f
87−#define TWO_TO_23 8388608.0f
88−#define INV_TWO_TO_23 0.00000011920929f
89−#define TWO_TO_31 2147483648.0f
90−#define INV_TWO_TO_31 0.000000000465661f
91−#define TWO_TO_32 4294967296.0f
92−#define INV_TWO_TO_32 0.000000000232831f
93−
94−#define ONE_OVER_SQRT2 0.707106781186548f
95−
96−#define LOGTEN 2.302585092994
97−
98− // Jones shaper
99− float LEAF_shaper (float input, float m_drive);
100− float LEAF_reedTable (float input, float offset, float slope);
101−
102− float LEAF_reduct (float input, float ratio);
103− float LEAF_round (float input, float rnd);
104− float LEAF_bitwise_xor(float input, uint32_t op);
105−
106− float LEAF_reduct (float input, float ratio);
107− float LEAF_round (float input, float rnd);
108− float LEAF_bitwise_xor(float input, uint32_t op);
109−
110− float LEAF_clip (float min, float val, float max);
111− int LEAF_clipInt (int min, int val, int max);
112− float LEAF_softClip (float val, float thresh);
113− oBool LEAF_isPrime (uint64_t number );
114−
115− float LEAF_midiToFrequency (float f);
116− float LEAF_frequencyToMidi(float f);
117−
118− void LEAF_generate_sine (float* buffer, int size);
119− void LEAF_generate_sawtooth (float* buffer, float basefreq, int size);
120− void LEAF_generate_triangle (float* buffer, float basefreq, int size);
121− void LEAF_generate_square (float* buffer, float basefreq, int size);
122−
123− // dope af
124− float LEAF_chebyshevT(float in, int n);
125− float LEAF_CompoundChebyshevT(float in, int n, float* amps);
126−
127− // Hermite interpolation
128− float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);
129− float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx);
130− float LEAF_interpolation_linear (float A, float B, float t);
131−
132− float interpolate3max(float *buf, const int peakindex);
133− float interpolate3phase(float *buf, const int peakindex);
134−
135− // alternative implementation for abs()
136− // REQUIRES: 32 bit integers
137− int fastabs_int(int in);
138−
139− // alternative implementation for abs()
140− // REQUIRES: 32 bit floats
141− float fastabsf(float f);
142−
143− float fastexp2f(float f);
144−
145− float fastPowf(float a, float b) ;
146− double fastPow(double a, double b);
147−
148−
149− void LEAF_crossfade(float fade, float* volumes);
150−
151−
152− float LEAF_tanh(float x);
153− void LEAF_generate_sine(float* buffer, int size);
154− void LEAF_generate_sawtooth(float* buffer, float basefreq, int size);
155− void LEAF_generate_triangle(float* buffer, float basefreq, int size);
156− void LEAF_generate_square(float* buffer, float basefreq, int size);
157−
158− //0.001 base gives a good curve that goes from 1 to near zero
159− //1000 gives a good curve from -1.0 to 0.0
160− void LEAF_generate_exp(float* buffer, float base, float start, float end, float offset, int size);
161−
162− float LEAF_poly_blep(float t, float dt);
163− float LEAF_midiToFrequency(float f);
164−
165−
166− float fast_mtof(float f);
167−
168− double fastexp(double x);
169−
170− float fastexpf(float x);
171−
172− double fasterexp(double x);
173−
174− float fasterexpf(float x);
175−
176− float mtof(float f);
177−
178− float fast_mtof(float f);
179−
180− float faster_mtof(float f);
181−
182− float ftom(float f);
183−
184− float powtodb(float f);
185−
186− float rmstodb(float f);
187−
188− float dbtopow(float f);
189−
190− float dbtorms(float f);
191−
192− float atodb(float a);
193−
194− float dbtoa(float db);
195−
196− float fastdbtoa(float db);
197−
198− float maximum (float num1, float num2);
199−
200− float minimum (float num1, float num2);
201−
202−
203− //==============================================================================
204−
205−#ifdef __cplusplus
206−}
207−#endif
208−
209−#endif // LEAF_MATH_H_INCLUDED
210−
211−//==============================================================================
212−
LEAF/Inc/leaf-mempool.h+0−159
@@ -1,159 +0,0 @@
1−/*==============================================================================
2−
3− In short, mpool is distributed under so called "BSD license",
4−
5− Copyright (c) 2009-2010 Tatsuhiko Kubo <cubicdaiya@gmail.com>
6− All rights reserved.
7−
8− Redistribution and use in source and binary forms, with or without modification,
9− are permitted provided that the following conditions are met:
10−
11− * Redistributions of source code must retain the above copyright notice,
12− this list of conditions and the following disclaimer.
13−
14− * Redistributions in binary form must reproduce the above copyright notice,
15− this list of conditions and the following disclaimer in the documentation
16− and/or other materials provided with the distribution.
17−
18− * Neither the name of the authors nor the names of its contributors
19− may be used to endorse or promote products derived from this software
20− without specific prior written permission.
21−
22− THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23− "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24− LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25− A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26− OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27− SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28− TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29− PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30− LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31− NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32− SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33−
34− written by C99 style
35− ==============================================================================*/
36−
37−#ifndef LEAF_MPOOL_H_INCLUDED
38−#define LEAF_MPOOL_H_INCLUDED
39−
40−#ifdef __cplusplus
41−extern "C" {
42−#endif
43−
44− //==============================================================================
45−
46−#include <stdio.h>
47−#include <stdlib.h>
48−#include <string.h>
49−#include <stdbool.h>
50−
51− //==============================================================================
52−
53−#define MPOOL_ALIGN_SIZE (8)
54−
55− //#define size_t unsigned long
56−
57− /*!
58− * @defgroup tmempool tMempool
59− * @ingroup mempool
60− * An object that can contain an additional mempool for the allocation of LEAF objects.
61− * @{
62− */
63−
64− // node of free list
65− typedef struct mpool_node_t {
66− char *pool; // memory pool field
67− struct mpool_node_t *next; // next node pointer
68− struct mpool_node_t *prev; // prev node pointer
69− size_t size;
70− } mpool_node_t;
71−
72− typedef struct _tMempool
73− {
74− char* mpool; // start of the mpool
75− size_t usize; // used size of the pool
76− size_t msize; // max size of the pool
77− mpool_node_t* head; // first node of memory pool free list
78− } _tMempool;
79−
80− typedef _tMempool* tMempool;
81−
82− //! Initialize a tMempool for a given memory location and size to the default LEAF mempool.
83− /*!
84− @param pool A pointer to the tMempool to be initialized.
85− @param memory A pointer to the chunk of memory to be used as a mempool.
86− @param size The size of the chunk of memory to be used as a mempool.
87− */
88− void tMempool_init (tMempool* const pool, char* memory, size_t size);
89−
90−
91− //! Free a tMempool from the default LEAF mempool.
92− /*!
93− @param pool A pointer to the tMempool to be freed.
94− */
95− void tMempool_free (tMempool* const pool);
96−
97−
98− //! Initialize a tMempool for a given memory location and size to a specified mempool.
99− /*!
100− @param pool A pointer to the tMempool to be initialized.
101− @param memory A pointer to the chunk of memory to be used as a mempool.
102− @param size The size of the chuck of memory to be used as a mempool.
103− @param poolTo A pointer to the tMempool to which a tMempool should be initialized.
104− */
105− void tMempool_initToPool (tMempool* const pool, char* memory, size_t size, tMempool* const poolTo);
106−
107−
108− //! Free a tMempool from a specified mempool.
109− /*!
110− @param pool A pointer to the tMempool to be freed from the default LEAF mempool.
111− @param poolFrom A pointer to the tMempool from which a tMempool should be freed.
112− */
113− void tMempool_freeFromPool (tMempool* const pool, tMempool* const poolFrom);
114−
115− /*! @} */
116−
117− //==============================================================================
118−
119− // typedef struct mpool_t {
120− // char* mpool; // start of the mpool
121− // size_t usize; // used size of the pool
122− // size_t msize; // max size of the pool
123− // mpool_node_t* head; // first node of memory pool free list
124− // } mpool_t;
125−
126− void mpool_create (char* memory, size_t size, _tMempool* pool);
127−
128− char* mpool_alloc(size_t size, _tMempool* pool);
129− char* mpool_calloc(size_t asize, _tMempool* pool);
130−
131− void mpool_free(char* ptr, _tMempool* pool);
132−
133− size_t mpool_get_size(_tMempool* pool);
134− size_t mpool_get_used(_tMempool* pool);
135−
136− void leaf_pool_init(char* memory, size_t size);
137−
138− char* leaf_alloc(size_t size);
139− char* leaf_calloc(size_t size);
140−
141− void leaf_free(char* ptr);
142−
143− size_t leaf_pool_get_size(void);
144− size_t leaf_pool_get_used(void);
145−
146− char* leaf_pool_get_pool(void);
147−
148− void leaf_mempool_overrun(void);
149−
150−#ifdef __cplusplus
151−}
152−#endif
153−
154−#endif // LEAF_MPOOL_H
155−
156−//==============================================================================
157−
158−
159−
LEAF/Inc/leaf-midi.h+0−510
@@ -1,510 +0,0 @@
1−/*==============================================================================
2−
3− leaf-midi.h
4− Created: 30 Nov 2018 11:29:26am
5− Author: airship
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_MIDI_H_INCLUDED
10−#define LEAF_MIDI_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-global.h"
19−#include "leaf-mempool.h"
20−#include "leaf-math.h"
21−#include "leaf-envelopes.h"
22−
23− /*!
24− * @internal
25− * Header.
26− * @include basic-oscillators.h
27− * @example basic-oscillators.c
28− * An example.
29− */
30−
31− //==============================================================================
32−
33− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
34−
35− /*!
36− * @defgroup tstack tStack
37− * @ingroup midi
38− * @brief A basic stack of integers with a fixed max size of 128, used by tPoly to keep track of MIDI notes.
39− * @{
40− */
41−
42− // STACK implementation (fixed size)
43−#define STACK_SIZE 128
44− typedef struct _tStack
45− {
46− int data[STACK_SIZE];
47− uint16_t pos;
48− uint16_t size;
49− uint16_t capacity;
50− oBool ordered;
51−
52− } _tStack;
53−
54− typedef _tStack* tStack;
55−
56− //! Initialize a tStack to the default LEAF mempool.
57− /*!
58− @param stack A pointer to the tStack to be initialized.
59− */
60− void tStack_init (tStack* const stack);
61−
62−
63− //! Free a tStack from the default LEAF mempool.
64− /*!
65− @param stack A pointer to the tStack to be freed.
66− */
67− void tStack_free (tStack* const stack);
68−
69−
70− //! Initialize a tStack to a specified mempool.
71− /*!
72− @param stack A pointer to the tStack to be initialized.
73− @param pool A pointer to the tMempool to which the tStack should be initialized.
74− */
75− void tStack_initToPool (tStack* const stack, tMempool* const pool);
76−
77−
78− //! Free a tStack from a specified mempool.
79− /*!
80− @param stack A pointer to the tStack to be freed.
81− @param pool A pointer to the tMempool from which the tStack should be freed.
82− */
83− void tStack_freeFromPool (tStack* const stack, tMempool* const pool);
84−
85− //! Set the capacity of the stack.
86− /*!
87− @param stack A pointer to the relevant tStack.
88− @param cap The new capacity.
89− */
90− void tStack_setCapacity (tStack* const stack, uint16_t cap);
91−
92−
93− //! Add a value to the stack only if that value is not already in the stack.
94− /*!
95− @param stack A pointer to the relevant tStack.
96− @param item The value to be added.
97− */
98− int tStack_addIfNotAlreadyThere (tStack* const stack, uint16_t item);
99−
100−
101− //! Add a value to the stack.
102− /*!
103− @param stack A pointer to the relevant tStack.
104− @param item The value to be added.
105− */
106− void tStack_add (tStack* const stack, uint16_t item);
107−
108−
109− //! Remove a single instance of a value from the stack.
110− /*!
111− @param stack A pointer to the relevant tStack.
112− @param item The value to be removed.
113− */
114− int tStack_remove (tStack* const stack, uint16_t item);
115−
116−
117− //! Clear the stack.
118− /*!
119− @param stack A pointer to the relevant tStack.
120− */
121− void tStack_clear (tStack* const stack);
122−
123−
124− //! Get the first value in the stack.
125− /*!
126− @param stack A pointer to the relevant tStack.
127− @return The first value in the stack.
128− */
129− int tStack_first (tStack* const stack);
130−
131−
132− //! Get the current size of the stack.
133− /*!
134− @param stack A pointer to the relevant tStack.
135− @return The current size of the stack.
136− */
137− int tStack_getSize (tStack* const stack);
138−
139− //! Check if the stack contains a value, and if it does, get the index of that value.
140− /*!
141− @param stack A pointer to the relevant tStack.
142− @param item The value to check against the stack.
143− @return The index of the value or -1 if the stack does not contain the value.
144− */
145− int tStack_contains (tStack* const stack, uint16_t item);
146−
147− //! Get the next value in the stack, starting from the earliest added values.
148− /*!
149− @param stack A pointer to the relevant tStack.
150− @return The next value in the stack or -1 if there are no values in the stack.
151− */
152− int tStack_next (tStack* const stack);
153−
154− //! Get the value at a given index of the stack.
155− /*!
156− @param stack A pointer to the relevant tStack.
157− @param index The index of the stack from which to get a value.
158− @return The value at the given index.
159− */
160− int tStack_get (tStack* const stack, int index);
161−
162− /*! @} */
163−
164− /*!
165− * @defgroup tpoly tPoly
166− * @ingroup midi
167− * @brief An object for polyphonic handling.
168− * @{
169− */
170−
171− /* tPoly */
172− typedef struct _tPoly
173− {
174− tStack stack;
175− tStack orderStack;
176−
177− tRamp* ramps;
178− float* rampVals;
179− oBool* firstReceived;
180− float glideTime;
181− oBool pitchGlideIsActive;
182−
183− int numVoices;
184− int maxNumVoices;
185−
186− //int voices[POLY_NUM_MAX_VOICES][2];
187− int** voices;
188−
189− int notes[128][2];
190−
191− int CCs[128];
192−
193− uint8_t CCsRaw[128];
194−
195− int lastVoiceToChange;
196−
197− float pitchBend;
198− tRamp pitchBendRamp;
199−
200− int currentNote;
201− int currentVoice;
202− int currentVelocity;
203− int maxLength;
204−
205− } _tPoly;
206−
207− typedef _tPoly* tPoly;
208−
209− /* MPoly*/
210− //! Initialize a tPoly to the default LEAF mempool.
211− /*!
212− @param poly A pointer to the tPoly to be initialized.
213− @param maxNumVoices The maximum number of voices this tPoly can handle at once.
214− */
215− void tPoly_init (tPoly* const poly, int maxNumVoices);
216−
217−
218− //! Free a tPoly from the default LEAF mempool.
219− /*!
220− @param poly A pointer to the tPoly to be freed.
221− */
222− void tPoly_free (tPoly* const poly);
223−
224−
225− //! Initialize a tPoly to a specified mempool.
226− /*!
227− @param poly A pointer to the tPoly to be initialized.
228− @param pool A pointer to the tMempool to which the tPoly should be initialized.
229− */
230− void tPoly_initToPool (tPoly* const poly, int maxNumVoices, tMempool* const pool);
231−
232−
233− //! Free a tPoly from a specified mempool.
234− /*!
235− @param poly A pointer to the tPoly to be freed.
236− @param pool A pointer to the tMempool from which the tPoly should be freed.
237− */
238− void tPoly_freeFromPool (tPoly* const poly, tMempool* const pool);
239−
240− //! Add a note with a given velocity to the poly handler.
241− /*!
242− @param poly A pointer to the relevant tPoly.
243− @param note The MIDI note number to add.
244− @param vel The MIDI velocity of the note to add.
245− @return The voice that will play the note.
246− */
247− int tPoly_noteOn (tPoly* const poly, int note, uint8_t vel);
248−
249−
250− //! Remove a note from the poly handler.
251− /*!
252− @param poly A pointer to the relevant tPoly.
253− @param note The MIDI note number to remove.
254− @return The voice that was playing the removed note.
255− */
256− int tPoly_noteOff (tPoly* const poly, uint8_t note);
257−
258− void tPoly_orderedAddToStack (tPoly* const poly, uint8_t note);
259−
260−
261− //! Set the number of voices available to play notes.
262− /*!
263− @param poly A pointer to the relevant tPoly.
264− @param numVoices The new number of available voices. Cannot be greater than the max number voices given in tPoly_init().
265− */
266− void tPoly_setNumVoices (tPoly* const poly, uint8_t numVoices);
267−
268− //! Set whether pitch glide over note changes in voices is active.
269− /*!
270− @param poly A pointer to the relevant tPoly.
271− @param isActive Whether pitch glide should be active or not.
272− */
273− void tPoly_setPitchGlideActive (tPoly* const poly, oBool isActive);
274−
275− //! Set how long pitch glide over note changes in voices takes.
276− /*!
277− @param poly A pointer to the relevant tPoly.
278− @param t The time to glide in milliseconds.
279− */
280− void tPoly_setPitchGlideTime (tPoly* const poly, float t);
281−
282− //! Set the amount of pitch bend
283− /*!
284− @param poly A pointer to the relevant tPoly.
285− @param pitchBend The new amount of pitch bend.
286− */
287− void tPoly_setPitchBend (tPoly* const poly, float pitchBend);
288− void tPoly_setBendGlideTime (tPoly* const poly, float t);
289− void tPoly_setBendSamplesPerTick (tPoly* const poly, float t);
290−
291−
292− //! Execute all tick-rate changes in the poly handler's pitch, including glide and bend.
293− /*!
294− @param poly A pointer to the relevant tPoly.
295− */
296− void tPoly_tickPitch (tPoly* const poly);
297−
298−
299− //! Execute the tick-rate change of the poly handler's pitch glide.
300− /*!
301− @param poly A pointer to the relevant tPoly.
302− */
303− void tPoly_tickPitchGlide (tPoly* const poly);
304−
305−
306− //! Execute the tick-rate change of the poly handler's pitch bend.
307− /*!
308− @param poly A pointer to the relevant tPoly.
309− */
310− void tPoly_tickPitchBend (tPoly* const poly);
311−
312−
313− //! Get the current number of voices available to play notes.
314− /*!
315− @param poly A pointer to the relevant tPoly.
316− @return The current number of voices available to play notes.
317− */
318− int tPoly_getNumVoices (tPoly* const poly);
319−
320− //! Get the number of voices currently playing notes.
321− /*!
322− @param poly A pointer to the relevant tPoly.
323− @return The number of voices currently playing notes.
324− */
325− int tPoly_getNumActiveVoices (tPoly* const poly);
326−
327− //! Get the current pitch of a given voice.
328− /*!
329− @param poly A pointer to the relevant tPoly.
330− @param voice The voice to get the pitch of.
331− @return The current pitch of the given voice as a fractional MIDI note number.
332− */
333− float tPoly_getPitch (tPoly* const poly, uint8_t voice);
334−
335−
336− //! Get the current MIDI note number of a given voice.
337− /*!
338− @param poly A pointer to the relevant tPoly.
339− @param voice The voice to get the MIDI note number of.
340− @return The MIDI note number of the given voice.
341− */
342− int tPoly_getKey (tPoly* const poly, uint8_t voice);
343−
344−
345− //! Get the current MIDI velocity of a given voice.
346− /*!
347− @param poly A pointer to the relevant tPoly.
348− @param voice The voice to get the MIDI velocity of.
349− @return The current MIDI velocity of the given voice.
350− */
351− int tPoly_getVelocity (tPoly* const poly, uint8_t voice);
352−
353−
354− //! Get the current play state of a given voice.
355− /*!
356− @param poly A pointer to the relevant tPoly.
357− @param voice The voice to get the state of.
358− @return The current play state of the given voice.
359− */
360− int tPoly_isOn (tPoly* const poly, uint8_t voice);
361−
362− /*! @} */
363−
364− //==============================================================================
365−
366−
367− /* tPoly */
368− typedef struct _tSimplePoly
369− {
370− tStack stack;
371−
372− int numVoices;
373− int maxNumVoices;
374− int** voices;
375− int stealing_on;
376− int recover_stolen;
377−
378− int notes[128][2];
379− } _tSimplePoly;
380−
381− typedef _tSimplePoly* tSimplePoly;
382−
383− //! Initialize a tPoly to the default LEAF mempool.
384− /*!
385− @param poly A pointer to the tPoly to be initialized.
386− @param maxNumVoices The maximum number of voices this tPoly can handle at once.
387− */
388− void tSimplePoly_init (tSimplePoly* const poly, int maxNumVoices);
389−
390−
391− //! Free a tPoly from the default LEAF mempool.
392− /*!
393− @param poly A pointer to the tPoly to be freed.
394− */
395− void tSimplePoly_free (tSimplePoly* const poly);
396−
397−
398− //! Initialize a tPoly to a specified mempool.
399− /*!
400− @param poly A pointer to the tPoly to be initialized.
401− @param pool A pointer to the tMempool to which the tPoly should be initialized.
402− */
403− void tSimplePoly_initToPool (tSimplePoly* const poly, int maxNumVoices, tMempool* const pool);
404−
405−
406− //! Free a tPoly from a specified mempool.
407− /*!
408− @param poly A pointer to the tPoly to be freed.
409− @param pool A pointer to the tMempool from which the tPoly should be freed.
410− */
411− void tSimplePoly_freeFromPool (tSimplePoly* const poly, tMempool* const pool);
412−
413− //! Add a note with a given velocity to the poly handler.
414− /*!
415− @param poly A pointer to the relevant tPoly.
416− @param note The MIDI note number to add.
417− @param vel The MIDI velocity of the note to add.
418− @return The voice that will play the note.
419− */
420− int tSimplePoly_noteOn (tSimplePoly* const poly, int note, uint8_t vel);
421−
422−
423− //! Remove a note from the poly handler.
424− /*!
425− @param poly A pointer to the relevant tPoly.
426− @param note The MIDI note number to remove.
427− @return The voice that was playing the removed note.
428− */
429− int tSimplePoly_noteOff (tSimplePoly* const poly, uint8_t note);
430−
431−
432−
433− void tSimplePoly_deactivateVoice(tSimplePoly* const polyh, uint8_t voice);
434−
435− int tSimplePoly_markPendingNoteOff(tSimplePoly* const polyh, uint8_t note);
436−
437−
438− //find if there is a voice with that note -- useful for note offs where you want to wait to remove it from the poly until the release phase of the envelope is finished
439− int tSimplePoly_findVoiceAssignedToNote(tSimplePoly* const polyh, uint8_t note);
440−
441− //! Set the number of voices available to play notes.
442− /*!
443− @param poly A pointer to the relevant tPoly.
444− @param numVoices The new number of available voices. Cannot be greater than the max number voices given in tPoly_init().
445− */
446− void tSimplePoly_setNumVoices (tSimplePoly* const poly, uint8_t numVoices);
447−
448− //! Set whether pitch glide over note changes in voices is active.
449− /*!
450− @param poly A pointer to the relevant tPoly.
451− @param isActive Whether pitch glide should be active or not.
452− */
453−
454− //! Get the current number of voices available to play notes.
455− /*!
456− @param poly A pointer to the relevant tPoly.
457− @return The current number of voices available to play notes.
458− */
459− int tSimplePoly_getNumVoices (tSimplePoly* const poly);
460−
461− //! Get the number of voices currently playing notes.
462− /*!
463− @param poly A pointer to the relevant tPoly.
464− @return The number of voices currently playing notes.
465− */
466− int tSimplePoly_getNumActiveVoices (tSimplePoly* const poly);
467−
468− //! Get the current MIDI note number of a given voice.
469− /*!
470− @param poly A pointer to the relevant tPoly.
471− @param voice The voice to get the MIDI note number of.
472− @return The MIDI note number of the given voice.
473− */
474−
475− int tSimplePoly_getPitch (tSimplePoly* const poly, uint8_t voice);
476−
477−
478− //this one returns negative one if the voice is inactive
479− int tSimplePoly_getPitchAndCheckActive(tSimplePoly* const polyh, uint8_t voice);
480−
481−
482− //! Get the current MIDI velocity of a given voice.
483− /*!
484− @param poly A pointer to the relevant tPoly.
485− @param voice The voice to get the MIDI velocity of.
486− @return The current MIDI velocity of the given voice.
487− */
488− int tSimplePoly_getVelocity (tSimplePoly* const poly, uint8_t voice);
489−
490−
491− //! Get the current play state of a given voice.
492− /*!
493− @param poly A pointer to the relevant tPoly.
494− @param voice The voice to get the state of.
495− @return The current play state of the given voice.
496− */
497− int tSimplePoly_isOn (tSimplePoly* const poly, uint8_t voice);
498−
499− /*! @} */
500− //==============================================================================
501−
502−#ifdef __cplusplus
503−}
504−#endif
505−
506−#endif // LEAF_MIDI_H_INCLUDED
507−
508−//==============================================================================
509−
510−
LEAF/Inc/leaf-oscillators.h+0−1143
@@ -1,1143 +0,0 @@
1−/*==============================================================================
2− leaf-oscillators.h
3− Created: 20 Jan 2017 12:00:58pm
4− Author: Michael R Mulshine
5− ==============================================================================*/
6−
7−#ifndef LEAF_OSCILLATORS_H_INCLUDED
8−#define LEAF_OSCILLATORS_H_INCLUDED
9−
10−#ifdef __cplusplus
11−extern "C" {
12−#endif
13−
14− //==============================================================================
15−
16−#include "leaf-math.h"
17−#include "leaf-mempool.h"
18−#include "leaf-tables.h"
19−#include "leaf-filters.h"
20−
21− /*!
22− * Header.
23− * @include basic-oscillators.h
24− * @example basic-oscillators.c
25− * An example.
26− */
27−
28− //==============================================================================
29−
30− typedef struct _tCycle
31− {
32− // Underlying phasor
33− float phase;
34− float inc,freq;
35− } _tCycle;
36−
37− typedef _tCycle* tCycle;
38−
39− /*!
40− * @defgroup tcycle tCycle
41− * @ingroup oscillators
42− * @brief A cycle/sine waveform oscillator. Uses wavetable synthesis.
43− * @{
44− */
45−
46− //! Initialize a tCycle to the default LEAF mempool.
47− /*!
48− @param osc A pointer to the tCycle to be initialized.
49− */
50− void tCycle_init (tCycle* const osc);
51−
52−
53− //! Free a tCycle from the default LEAF mempool.
54− /*!
55− @param osc A pointer to the tCycle to be freed.
56− */
57− void tCycle_free (tCycle* const osc);
58−
59−
60− //! Initialize a tCycle to a specified mempool.
61− /*!
62− @param osc A pointer to the tCycle to be initialized.
63− @param pool A pointer to the tMempool to which the tCycle should be initialized.
64− */
65− void tCycle_initToPool (tCycle* const osc, tMempool* const pool);
66−
67−
68− //! Free a tCycle from a specified mempool.
69− /*!
70− @param osc A pointer to the tCycle to be freed.
71− @param pool A pointer to the tMempool from which the tCycle should be freed.
72− */
73− void tCycle_freeFromPool (tCycle* const osc, tMempool* const pool);
74−
75−
76− //! Tick a tCycle oscillator.
77− /*!
78− @param osc A pointer to the relevant tCycle.
79− @return The ticked sample as a float from -1 to 1.
80− */
81− float tCycle_tick (tCycle* const osc);
82−
83−
84− //! Set the frequency of a tCycle oscillator.
85− /*!
86− @param osc A pointer to the relevant tCycle.
87− @param freq The frequency to set the oscillator to.
88− */
89− void tCycle_setFreq (tCycle* const osc, float freq);
90−
91− /*! @} */
92−
93− //==============================================================================
94−
95− /* tTriangle: Anti-aliased Triangle waveform using wavetable interpolation. Wavetables constructed from sine components. */
96− typedef struct _tTriangle
97− {
98− // Underlying phasor
99− float phase;
100− float inc,freq;
101− int oct;
102− float w;
103− } _tTriangle;
104−
105− typedef _tTriangle* tTriangle;
106−
107− /*!
108− * @defgroup ttriangle tTriangle
109− * @ingroup oscillators
110− * @brief An anti-aliased triangle waveform oscillator. Uses wavetable synthesis.
111− * @{
112− */
113−
114− //! Initialize a tTriangle to the default LEAF mempool.
115− /*!
116− @param osc A pointer to the tTriangle to be initialized.
117− */
118− void tTriangle_init (tTriangle* const osc);
119−
120−
121− //! Free a tTriangle from the default LEAF mempool.
122− /*!
123− @param osc A pointer to the tTriangle to be freed.
124− */
125− void tTriangle_free (tTriangle* const osc);
126−
127−
128− //! Initialize a tTriangle to a specified mempool.
129− /*!
130− @param osc A pointer to the tTriangle to be initialized.
131− @param pool A pointer to the tMempool to which the tTriangle should be initialized.
132− */
133− void tTriangle_initToPool (tTriangle* const osc, tMempool* const pool);
134−
135−
136− //! Free a tTriangle from a specified mempool.
137− /*!
138− @param osc A pointer to the tTriangle to be freed.
139− @param pool A pointer to the tMempool from which the tTriangle should be freed.
140− */
141− void tTriangle_freeFromPool (tTriangle* const osc, tMempool* const pool);
142−
143−
144− //! Tick a tTriangle oscillator.
145− /*!
146− @param osc A pointer to the relevant tTriangle.
147− @return The ticked sample as a float from -1 to 1.
148− */
149− float tTriangle_tick (tTriangle* const osc);
150−
151−
152− //! Set the frequency of a tTriangle oscillator.
153− /*!
154− @param osc A pointer to the relevant tTriangle.
155− @param freq The frequency to set the oscillator to.
156− */
157− void tTriangle_setFreq (tTriangle* const osc, float freq);
158−
159− /*! @} */
160−
161− //==============================================================================
162−
163− /* tSquare: Anti-aliased Square waveform using wavetable interpolation. Wavetables constructed from sine components. */
164− typedef struct _tSquare
165− {
166− // Underlying phasor
167− float phase;
168− float inc,freq;
169− int oct;
170− float w;
171− } _tSquare;
172−
173− typedef _tSquare* tSquare;
174−
175− /*!
176− * @defgroup tsquare tSquare
177− * @ingroup oscillators
178− * @brief An anti-aliased square waveform oscillator. Uses wavetable synthesis.
179− * @{
180− */
181−
182− //! Initialize a tSquare to the default LEAF mempool.
183− /*!
184− @param osc A pointer to the tSquare to be initialized.
185− */
186− void tSquare_init (tSquare* const osc);
187−
188−
189− //! Free a tSquare from the default LEAF mempool.
190− /*!
191− @param osc A pointer to the tSquare to be freed.
192− */
193− void tSquare_free (tSquare* const osc);
194−
195−
196− //! Initialize a tSquare to a specified mempool.
197− /*!
198− @param osc A pointer to the tSquare to be initialized.
199− @param pool A pointer to the tMempool to which the tSquare should be initialized.
200− */
201− void tSquare_initToPool (tSquare* const osc, tMempool* const);
202−
203−
204− //! Free a tSquare from a specified mempool.
205− /*!
206− @param osc A pointer to the tSquare to be freed.
207− @param pool A pointer to the tMempool from which the tSquare should be freed.
208− */
209− void tSquare_freeFromPool(tSquare* const osc, tMempool* const);
210−
211−
212− //! Tick a tSquare oscillator.
213− /*!
214− @param osc A pointer to the relevant tSquare.
215− @return The ticked sample as a float from -1 to 1.
216− */
217− float tSquare_tick (tSquare* const osc);
218−
219−
220− //! Set the frequency of a tSquare oscillator.
221− /*!
222− @param osc A pointer to the relevant tSquare.
223− @param freq The frequency to set the oscillator to.
224− */
225− void tSquare_setFreq (tSquare* const osc, float freq);
226−
227− /*! @} */
228−
229− //==============================================================================
230−
231− /* tSawtooth: Anti-aliased Sawtooth waveform using wavetable interpolation. Wavetables constructed from sine components. */
232− typedef struct _tSawtooth
233− {
234− // Underlying phasor
235− float phase;
236− float inc,freq;
237− int oct;
238− float w;
239− } _tSawtooth;
240−
241− typedef _tSawtooth* tSawtooth;
242−
243− /*!
244− * @defgroup tsawtooth tSawtooth
245− * @ingroup oscillators
246− * @brief An anti-aliased sawtooth waveform oscillator. Uses wavetable synthesis.
247− * @{
248− */
249−
250− //! Initialize a tSawtooth to the default LEAF mempool.
251− /*!
252− @param osc A pointer to the tSawtooth to be initialized.
253− */
254− void tSawtooth_init (tSawtooth* const osc);
255−
256−
257− //! Free a tSawtooth from the default LEAF mempool.
258− /*!
259− @param osc A pointer to the tSawtooth to be freed.
260− */
261− void tSawtooth_free (tSawtooth* const osc);
262−
263−
264− //! Initialize a tSawtooth to a specified mempool.
265− /*!
266− @param osc A pointer to the tSawtooth to be initialized.
267− @param pool A pointer to the tMempool to which the tSawtooth should be initialized.
268− */
269− void tSawtooth_initToPool (tSawtooth* const osc, tMempool* const pool);
270−
271−
272− //! Free a tSawtooth from a specified mempool.
273− /*!
274− @param osc A pointer to the tSawtooth to be freed.
275− @param pool A pointer to the tMempool from which the tSawtooth should be freed.
276− */
277− void tSawtooth_freeFromPool (tSawtooth* const osc, tMempool* const pool);
278−
279−
280− //! Tick a tSawtooth oscillator.
281− /*!
282− @param osc A pointer to the relevant tSawtooth.
283− @return The ticked sample as a float from -1 to 1.
284− */
285− float tSawtooth_tick (tSawtooth* const osc);
286−
287−
288− //! Set the frequency of a tSawtooth oscillator.
289− /*!
290− @param osc A pointer to the relevant tSawtooth.
291− @param freq The frequency to set the oscillator to.
292− */
293− void tSawtooth_setFreq (tSawtooth* const osc, float freq);
294−
295− /*! @} */
296−
297− //==============================================================================
298−
299− typedef struct _tSine
300− {
301− float* sine;
302− int size;
303− float phase;
304− float inc,freq;
305− } _tSine;
306−
307− typedef _tSine* tSine;
308−
309− /*!
310− * @defgroup tsine tSine
311− * @ingroup oscillators
312− * @brief A cycle/sine waveform oscillator.
313− * @{
314− */
315−
316− //! Initialize a tSine to the default LEAF mempool.
317− /*!
318− @param osc A pointer to the tSine to be initialized.
319− */
320− void tSine_init (tSine* const osc, int size);
321−
322−
323− //! Free a tSine from the default LEAF mempool.
324− /*!
325− @param osc A pointer to the tSine to be freed.
326− */
327− void tSine_free (tSine* const osc);
328−
329−
330− //! Initialize a tSine to a specified mempool.
331− /*!
332− @param osc A pointer to the tSine to be initialized.
333− @param pool A pointer to the tMempool to which the tSine should be initialized.
334− */
335− void tSine_initToPool (tSine* const osc, int size, tMempool* const pool);
336−
337−
338− //! Free a tSine from a specified mempool.
339− /*!
340− @param osc A pointer to the tSine to be freed.
341− @param pool A pointer to the tMempool from which the tSine should be freed.
342− */
343− void tSine_freeFromPool (tSine* const osc, tMempool* const pool);
344−
345−
346− //! Tick a tSine oscillator.
347− /*!
348− @param osc A pointer to the relevant tSine.
349− @return The ticked sample as a float from -1 to 1.
350− */
351− float tSine_tick (tSine* const osc);
352−
353−
354− //! Set the frequency of a tSine oscillator.
355− /*!
356− @param osc A pointer to the relevant tSine.
357− @param freq The frequency to set the oscillator to.
358− */
359− void tSine_setFreq (tSine* const osc, float freq);
360−
361− /*! @} */
362−
363− //==============================================================================
364−
365− /* tTri: Anti-aliased Triangle waveform using wavetable interpolation. */
366− typedef struct _tTri
367− {
368− float phase;
369− float inc,freq;
370− float skew;
371− float lastOut;
372− } _tTri;
373−
374− typedef _tTri* tTri;
375−
376− /*!
377− * @defgroup tTri tTri
378− * @ingroup oscillators
379− * @brief An anti-aliased triangle waveform oscillator.
380− * @{
381− */
382−
383− //! Initialize a tTri to the default LEAF mempool.
384− /*!
385− @param osc A pointer to the tTri to be initialized.
386− */
387− void tTri_init (tTri* const osc);
388−
389−
390− //! Free a tTri from the default LEAF mempool.
391− /*!
392− @param osc A pointer to the tTri to be freed.
393− */
394− void tTri_free (tTri* const osc);
395−
396−
397− //! Initialize a tTri to a specified mempool.
398− /*!
399− @param osc A pointer to the tTri to be initialized.
400− @param pool A pointer to the tMempool to which the tTri should be initialized.
401− */
402− void tTri_initToPool (tTri* const osc, tMempool* const pool);
403−
404−
405− //! Free a tTri from a specified mempool.
406− /*!
407− @param osc A pointer to the tTri to be freed.
408− @param pool A pointer to the tMempool from which the tTri should be freed.
409− */
410− void tTri_freeFromPool (tTri* const osc, tMempool* const pool);
411−
412−
413− //! Tick a tTri oscillator.
414− /*!
415− @param osc A pointer to the relevant tTri.
416− @return The ticked sample as a float from -1 to 1.
417− */
418− float tTri_tick (tTri* const osc);
419−
420−
421− //! Set the frequency of a tTri oscillator.
422− /*!
423− @param osc A pointer to the relevant tTriangle.
424− @param freq The frequency to set the oscillator to.
425− */
426− void tTri_setFreq (tTri* const osc, float freq);
427−
428− void tTri_setSkew (tTri* const osc, float skew);
429−
430− /*! @} */
431−
432− //==============================================================================
433−
434− /* tPulse: Anti-aliased Square waveform. */
435− typedef struct _tPulse
436− {
437− float phase;
438− float inc,freq;
439− float width;
440− } _tPulse;
441−
442− typedef _tPulse* tPulse;
443−
444− /*!
445− * @defgroup tPulse tPulse
446− * @ingroup oscillators
447− * @brief An anti-aliased pulse waveform oscillator with changeable pulse width.
448− * @{
449− */
450−
451− //! Initialize a tPulse to the default LEAF mempool.
452− /*!
453− @param osc A pointer to the tPulse to be initialized.
454− */
455− void tPulse_init (tPulse* const osc);
456−
457−
458− //! Free a tPulse from the default LEAF mempool.
459− /*!
460− @param osc A pointer to the tPulse to be freed.
461− */
462− void tPulse_free (tPulse* const osc);
463−
464−
465− //! Initialize a tPulse to a specified mempool.
466− /*!
467− @param osc A pointer to the tPulse to be initialized.
468− @param pool A pointer to the tMempool to which the tPulse should be initialized.
469− */
470− void tPulse_initToPool (tPulse* const osc, tMempool* const);
471−
472−
473− //! Free a tPulse from a specified mempool.
474− /*!
475− @param osc A pointer to the tPulse to be freed.
476− @param pool A pointer to the tMempool from which the tPulse should be freed.
477− */
478− void tPulse_freeFromPool(tPulse* const osc, tMempool* const);
479−
480−
481− //! Tick a tPulse oscillator.
482− /*!
483− @param osc A pointer to the relevant tPulse.
484− @return The ticked sample as a float from -1 to 1.
485− */
486− float tPulse_tick (tPulse* const osc);
487−
488−
489− //! Set the frequency of a tPulse oscillator.
490− /*!
491− @param osc A pointer to the relevant tPulse.
492− @param freq The frequency to set the oscillator to.
493− */
494− void tPulse_setFreq (tPulse* const osc, float freq);
495−
496− void tPulse_setWidth (tPulse* const osc, float width);
497−
498− /*! @} */
499−
500− //==============================================================================
501−
502− /* tSawtooth: Anti-aliased Sawtooth waveform. */
503− typedef struct _tSaw
504− {
505− float phase;
506− float inc,freq;
507− } _tSaw;
508−
509− typedef _tSaw* tSaw;
510−
511− /*!
512− * @defgroup tsaw tSaw
513− * @ingroup oscillators
514− * @brief An anti-aliased sawtooth waveform oscillator. Uses wavetable synthesis.
515− * @{
516− */
517−
518− //! Initialize a tSaw to the default LEAF mempool.
519− /*!
520− @param osc A pointer to the tSaw to be initialized.
521− */
522− void tSaw_init (tSaw* const osc);
523−
524−
525− //! Free a tSaw from the default LEAF mempool.
526− /*!
527− @param osc A pointer to the tSaw to be freed.
528− */
529− void tSaw_free (tSaw* const osc);
530−
531−
532− //! Initialize a tSaw to a specified mempool.
533− /*!
534− @param osc A pointer to the tSaw to be initialized.
535− @param pool A pointer to the tMempool to which the tSaw should be initialized.
536− */
537− void tSaw_initToPool (tSaw* const osc, tMempool* const pool);
538−
539−
540− //! Free a tSaw from a specified mempool.
541− /*!
542− @param osc A pointer to the tSaw to be freed.
543− @param pool A pointer to the tMempool from which the tSaw should be freed.
544− */
545− void tSaw_freeFromPool (tSaw* const osc, tMempool* const pool);
546−
547−
548− //! Tick a tSaw oscillator.
549− /*!
550− @param osc A pointer to the relevant tSaw.
551− @return The ticked sample as a float from -1 to 1.
552− */
553− float tSaw_tick (tSaw* const osc);
554−
555−
556− //! Set the frequency of a tSaw oscillator.
557− /*!
558− @param osc A pointer to the relevant tSaw.
559− @param freq The frequency to set the oscillator to.
560− */
561− void tSaw_setFreq (tSaw* const osc, float freq);
562−
563− /*! @} */
564−
565− //==============================================================================
566−
567− /* tPhasor: Aliasing phasor [0.0, 1.0) */
568− typedef struct _tPhasor
569− {
570− float phase;
571− float inc,freq;
572− uint8_t phaseDidReset;
573−
574− } _tPhasor;
575−
576− typedef _tPhasor* tPhasor;
577−
578− /*!
579− * @defgroup tphasor Phasor
580− * @ingroup oscillators
581− * @brief An aliasing phasor.
582− * @{
583− */
584−
585− //! Initialize a tPhasor to the default LEAF mempool.
586− /*!
587− @param osc A pointer to the tPhasor to be initialized.
588− */
589− void tPhasor_init (tPhasor* const osc);
590−
591−
592− //! Free a tPhasor from the default LEAF mempool.
593− /*!
594− @param osc A pointer to the tPhasor to be freed.
595− */
596− void tPhasor_free (tPhasor* const osc);
597−
598−
599− //! Initialize a tPhasor to a specified mempool.
600− /*!
601− @param osc A pointer to the tPhasor to be initialized.
602− @param pool A pointer to the tMempool to which the tPhasor should be initialized.
603− */
604− void tPhasor_initToPool (tPhasor* const osc, tMempool* const);
605−
606−
607− //! Free a tPhasor from a specified mempool.
608− /*!
609− @param osc A pointer to the tPhasor to be freed.
610− @param pool A pointer to the tMempool from which the tPhasor should be freed.
611− */
612− void tPhasor_freeFromPool(tPhasor* const osc, tMempool* const);
613−
614−
615− //! Tick a tPhasor oscillator.
616− /*!
617− @param osc A pointer to the relevant tPhasor.
618− @return The ticked sample as a float from 0 to 1.
619− */
620− float tPhasor_tick (tPhasor* const osc);
621−
622−
623− //! Set the frequency of a tPhasor oscillator.
624− /*!
625− @param osc A pointer to the relevant tPhasor.
626− @param freq The frequency to set the oscillator to.
627− */
628− void tPhasor_setFreq (tPhasor* const osc, float freq);
629−
630− /*! @} */
631−
632− //==============================================================================
633−
634− /*!
635− * @defgroup tnoise tNoise
636− * @ingroup oscillators
637− * @brief A noise generator.
638− * @{
639− */
640−
641− /* tNoise. WhiteNoise, PinkNoise. */
642− /*!
643− * Noise types
644− */
645− enum NoiseType
646− {
647− WhiteNoise, //!< White noise. Full spectrum.
648− PinkNoise, //!< Pink noise. Inverse frequency-proportional spectrum.
649− NoiseTypeNil,
650− };
651−
652− typedef enum NoiseType NoiseType;
653−
654− typedef struct _tNoise
655− {
656− NoiseType type;
657− float pinkb0, pinkb1, pinkb2;
658− float(*rand)(void);
659−
660− } _tNoise;
661−
662− typedef _tNoise* tNoise;
663−
664− //! Initialize a tNoise to the default LEAF mempool.
665− /*!
666− @param osc A pointer to the tNoise to be initialized.
667− */
668− void tNoise_init (tNoise* const noise, NoiseType type);
669−
670−
671− //! Free a tNoise from the default LEAF mempool.
672− /*!
673− @param osc A pointer to the tNoise to be freed.
674− */
675− void tNoise_free (tNoise* const noise);
676−
677−
678− //! Initialize a tNoise to a specified mempool.
679− /*!
680− @param osc A pointer to the tNoise to be initialized.
681− @param pool A pointer to the tMempool to which the tNoise should be initialized.
682− */
683− void tNoise_initToPool (tNoise* const noise, NoiseType type, tMempool* const);
684−
685−
686− //! Free a tNoise from a specified mempool.
687− /*!
688− @param osc A pointer to the tNoise to be freed.
689− @param pool A pointer to the tMempool from which the tNoise should be freed.
690− */
691− void tNoise_freeFromPool (tNoise* const noise, tMempool* const);
692−
693−
694− //! Tick a tNoise oscillator.
695− /*!
696− @param osc A pointer to the relevant tNoise.
697− @return The ticked sample as a float from -1 to 1.
698− */
699− float tNoise_tick (tNoise* const noise);
700−
701− /*! @} */
702−
703− //==============================================================================
704−
705− /*!
706− * @defgroup tneuron tNeuron
707− * @ingroup oscillators
708− * @brief A model of a neuron, adapted to act as an oscillator.
709− * @{
710− */
711−
712− /*!
713− * Neuron modes
714− */
715− enum NeuronMode
716− {
717− NeuronNormal, //!< Normal operation
718− NeuronTanh, //!< Tanh voltage shaping
719− NeuronAaltoShaper, //!< Aalto voltage shaping
720− NeuronModeNil
721− };
722− typedef enum NeuronMode NeuronMode;
723−
724− typedef struct _tNeuron
725− {
726− tPoleZero f;
727−
728− NeuronMode mode;
729−
730− float voltage, current;
731− float timeStep;
732−
733− float alpha[3];
734− float beta[3];
735− float rate[3];
736− float V[3];
737− float P[3];
738− float gK, gN, gL, C;
739− } _tNeuron;
740−
741− typedef _tNeuron* tNeuron;
742−
743− //! Initialize a tNeuron to the default LEAF mempool.
744− /*!
745− @param neuron A pointer to the tNeuron to be initialized.
746− */
747− void tNeuron_init (tNeuron* const neuron);
748−
749−
750− //! Free a tNeuron from the default LEAF mempool.
751− /*!
752− @param neuron A pointer to the tNeuron to be freed.
753− */
754− void tNeuron_free (tNeuron* const neuron);
755−
756−
757− //! Initialize a tNeuron to a specified mempool.
758− /*!
759− @param neuron A pointer to the tNeuron to be initialized.
760− @param pool A pointer to the tMempool to which the tNeuron should be initialized.
761− */
762− void tNeuron_initToPool (tNeuron* const neuron, tMempool* const pool);
763−
764−
765− //! Free a tNeuron from a specified mempool.
766− /*!
767− @param neuron A pointer to the tNeuron to be freed.
768− @param pool A pointer to the tMempool from which the tNeuron should be freed.
769− */
770− void tNeuron_freeFromPool(tNeuron* const neuron, tMempool* const pool);
771−
772−
773− //! Reset the neuron model.
774− /*!
775− @param neuron A pointer to the relevant tNeuron.
776− */
777− void tNeuron_reset (tNeuron* const neuron);
778−
779−
780− //! Tick a tNeuron oscillator.
781− /*!
782− @param neuron A pointer to the relevant tNeuron.
783− @return The ticked sample as a float from -1 to 1.
784− */
785− float tNeuron_tick (tNeuron* const neuron);
786−
787−
788− //! Set the tNeuron shaping mode.
789− /*!
790− @param neuron A pointer to the relevant tNeuron.
791− @param mode The mode to set the tNeuron to.
792− */
793− void tNeuron_setMode (tNeuron* const neuron, NeuronMode mode);
794−
795−
796− //! Set the current.
797− /*!
798− @param neuron A pointer to the relevant tNeuron.
799− @param current The new current.
800− */
801− void tNeuron_setCurrent (tNeuron* const neuron, float current);
802−
803−
804− //! Set the potassium value.
805− /*!
806− @param neuron A pointer to the relevant tNeuron.
807− @param K The new potassium.
808− */
809− void tNeuron_setK (tNeuron* const neuron, float K);
810−
811−
812− //! Set the chloride value.
813− /*!
814− @param neuron A pointer to the relevant tNeuron.
815− @param L The new chloride value.
816− */
817− void tNeuron_setL (tNeuron* const neuron, float L);
818−
819−
820− //! Set the sodium value.
821− /*!
822− @param neuron A pointer to the relevant tNeuron.
823− @param N The new sodium value.
824− */
825− void tNeuron_setN (tNeuron* const neuron, float N);
826−
827−
828− //! Set the calcium value.
829− /*!
830− @param neuron A pointer to the relevant tNeuron.
831− @param C The new calcium.
832− */
833− void tNeuron_setC (tNeuron* const neuron, float C);
834−
835−
836− //! Set the V1 value.
837− /*!
838− @param neuron A pointer to the relevant tNeuron.
839− @param V1 The new V1.
840− */
841− void tNeuron_setV1 (tNeuron* const neuron, float V1);
842−
843−
844− //! Set the V2 value.
845− /*!
846− @param neuron A pointer to the relevant tNeuron.
847− @param V2 The new V2.
848− */
849− void tNeuron_setV2 (tNeuron* const neuron, float V2);
850−
851−
852− //! Set the V3 value.
853− /*!
854− @param neuron A pointer to the relevant tNeuron.
855− @param V3 The new V3.
856− */
857− void tNeuron_setV3 (tNeuron* const neuron, float V3);
858−
859−
860− //! Set the time step.
861− /*!
862− @param neuron A pointer to the relevant tNeuron.
863− @param timestep The new time step
864− */
865− void tNeuron_setTimeStep (tNeuron* const neuron, float timestep);
866−
867− /*! @} */
868−
869− //==============================================================================
870−
871− typedef struct _tMinBLEP
872− {
873− float coeffs[6];
874−
875− // FilterState
876− float* x1, x2, y1, y2;
877−
878− float ratio, lastRatio;
879−
880− float overSamplingRatio;
881− int zeroCrossings;
882−
883− float lastValue;
884− float lastDelta; // previous derivative ...
885−
886− // Tweaking the Blep F
887− float proportionalBlepFreq;
888− uint8_t returnDerivative; // set this to return the FIRST DERIVATIVE of the blep (for first der. discontinuities)
889−
890− int blepIndex;
891− int numActiveBleps;
892− //currentActiveBlepOffsets;
893− float* offset;
894− float* freqMultiple;
895− float* pos_change_magnitude;
896− float* vel_change_magnitude;
897−
898− int minBlepSize;
899− float* minBlepArray;
900− float* minBlepDerivArray;
901− } _tMinBLEP;
902−
903− typedef _tMinBLEP* tMinBLEP;
904−
905− void tMinBLEP_init (tMinBLEP* const minblep, int zeroCrossings, int oversamplerRatio);
906− void tMinBLEP_free (tMinBLEP* const minblep);
907− void tMinBLEP_initToPool (tMinBLEP* const minblep, int zeroCrossings, int oversamplerRatio, tMempool* const pool);
908− void tMinBLEP_freeFromPool (tMinBLEP* const minblep, tMempool* const pool);
909−
910− // pass in audio, identify discontinuities and return the audio with minbleps inserted
911− float tMinBLEP_tick (tMinBLEP* const minblep, float input);
912− void tMinBLEP_buildBLEP (tMinBLEP* const minblep);
913− void tMinBLEP_addBLEP (tMinBLEP* const minblep, float offset, float posChange, float velChange);
914−
915− void tMinBLEP_setOversamplingRatio (tMinBLEP* const minblep, float ratio);
916− void tMinBLEP_setNumZeroCrossings (tMinBLEP* const minblep, int numCrossings);
917−
918− //==============================================================================
919−
920− /* tMBTriangle: Anti-aliased Triangle waveform using wavetable interpolation. */
921− typedef struct _tMBTriangle
922− {
923− float phase;
924− float inc,freq;
925− float skew;
926− float lastOut;
927−
928− tMinBLEP minBlep;
929− tHighpass dcBlock;
930− } _tMBTriangle;
931−
932− typedef _tMBTriangle* tMBTriangle;
933−
934− /*!
935− * @defgroup tMBTriangle tMBTriangle
936− * @ingroup oscillators
937− * @brief An anti-aliased triangle waveform oscillator.
938− * @{
939− */
940−
941− //! Initialize a tMBTriangle to the default LEAF mempool.
942− /*!
943− @param osc A pointer to the tMBTriangle to be initialized.
944− */
945− void tMBTriangle_init (tMBTriangle* const osc);
946−
947−
948− //! Free a tMBTriangle from the default LEAF mempool.
949− /*!
950− @param osc A pointer to the tMBTriangle to be freed.
951− */
952− void tMBTriangle_free (tMBTriangle* const osc);
953−
954−
955− //! Initialize a tMBTriangle to a specified mempool.
956− /*!
957− @param osc A pointer to the tMBTriangle to be initialized.
958− @param pool A pointer to the tMempool to which the tMBTriangle should be initialized.
959− */
960− void tMBTriangle_initToPool (tMBTriangle* const osc, tMempool* const pool);
961−
962−
963− //! Free a tMBTriangle from a specified mempool.
964− /*!
965− @param osc A pointer to the tMBTriangle to be freed.
966− @param pool A pointer to the tMempool from which the tMBTriangle should be freed.
967− */
968− void tMBTriangle_freeFromPool (tMBTriangle* const osc, tMempool* const pool);
969−
970−
971− //! Tick a tMBTriangle oscillator.
972− /*!
973− @param osc A pointer to the relevant tMBTriangle.
974− @return The ticked sample as a float from -1 to 1.
975− */
976− float tMBTriangle_tick (tMBTriangle* const osc);
977−
978−
979− //! Set the frequency of a tMBTriangle oscillator.
980− /*!
981− @param osc A pointer to the relevant tMBTriangleangle.
982− @param freq The frequency to set the oscillator to.
983− */
984− void tMBTriangle_setFreq (tMBTriangle* const osc, float freq);
985−
986− void tMBTriangle_setSkew (tMBTriangle* const osc, float skew);
987−
988− void tMBTriangle_sync (tMBTriangle* const osc, float phase);
989−
990− /*! @} */
991−
992− //==============================================================================
993−
994− /* tMBPulse: Anti-aliased Square waveform. */
995− typedef struct _tMBPulse
996− {
997− float phase;
998− float inc,freq;
999− float width;
1000−
1001− tMinBLEP minBlep;
1002− tHighpass dcBlock;
1003− } _tMBPulse;
1004−
1005− typedef _tMBPulse* tMBPulse;
1006−
1007− /*!
1008− * @defgroup tMBPulse tMBPulse
1009− * @ingroup oscillators
1010− * @brief An anti-aliased pulse waveform oscillator with changeable pulse width.
1011− * @{
1012− */
1013−
1014− //! Initialize a tMBPulse to the default LEAF mempool.
1015− /*!
1016− @param osc A pointer to the tMBPulse to be initialized.
1017− */
1018− void tMBPulse_init (tMBPulse* const osc);
1019−
1020−
1021− //! Free a tMBPulse from the default LEAF mempool.
1022− /*!
1023− @param osc A pointer to the tMBPulse to be freed.
1024− */
1025− void tMBPulse_free (tMBPulse* const osc);
1026−
1027−
1028− //! Initialize a tMBPulse to a specified mempool.
1029− /*!
1030− @param osc A pointer to the tMBPulse to be initialized.
1031− @param pool A pointer to the tMempool to which the tMBPulse should be initialized.
1032− */
1033− void tMBPulse_initToPool (tMBPulse* const osc, tMempool* const);
1034−
1035−
1036− //! Free a tMBPulse from a specified mempool.
1037− /*!
1038− @param osc A pointer to the tMBPulse to be freed.
1039− @param pool A pointer to the tMempool from which the tMBPulse should be freed.
1040− */
1041− void tMBPulse_freeFromPool(tMBPulse* const osc, tMempool* const);
1042−
1043−
1044− //! Tick a tMBPulse oscillator.
1045− /*!
1046− @param osc A pointer to the relevant tMBPulse.
1047− @return The ticked sample as a float from -1 to 1.
1048− */
1049− float tMBPulse_tick (tMBPulse* const osc);
1050−
1051−
1052− //! Set the frequency of a tMBPulse oscillator.
1053− /*!
1054− @param osc A pointer to the relevant tMBPulse.
1055− @param freq The frequency to set the oscillator to.
1056− */
1057− void tMBPulse_setFreq (tMBPulse* const osc, float freq);
1058−
1059− void tMBPulse_setWidth (tMBPulse* const osc, float width);
1060−
1061− void tMBPulse_sync (tMBPulse* const osc, float phase);
1062−
1063−
1064− /*! @} */
1065−
1066− //==============================================================================
1067−
1068− /* tMBSawtooth: Anti-aliased Sawtooth waveform. */
1069− typedef struct _tMBSaw
1070− {
1071− float phase;
1072− float inc,freq;
1073−
1074− tMinBLEP minBlep;
1075− tHighpass dcBlock;
1076− } _tMBSaw;
1077−
1078− typedef _tMBSaw* tMBSaw;
1079−
1080− /*!
1081− * @defgroup tMBSaw tMBSaw
1082− * @ingroup oscillators
1083− * @brief An anti-aliased sawtooth waveform oscillator. Uses wavetable synthesis.
1084− * @{
1085− */
1086−
1087− //! Initialize a tMBSaw to the default LEAF mempool.
1088− /*!
1089− @param osc A pointer to the tMBSaw to be initialized.
1090− */
1091− void tMBSaw_init (tMBSaw* const osc);
1092−
1093−
1094− //! Free a tMBSaw from the default LEAF mempool.
1095− /*!
1096− @param osc A pointer to the tMBSaw to be freed.
1097− */
1098− void tMBSaw_free (tMBSaw* const osc);
1099−
1100−
1101− //! Initialize a tMBSaw to a specified mempool.
1102− /*!
1103− @param osc A pointer to the tMBSaw to be initialized.
1104− @param pool A pointer to the tMempool to which the tMBSaw should be initialized.
1105− */
1106− void tMBSaw_initToPool (tMBSaw* const osc, tMempool* const pool);
1107−
1108−
1109− //! Free a tMBSaw from a specified mempool.
1110− /*!
1111− @param osc A pointer to the tMBSaw to be freed.
1112− @param pool A pointer to the tMempool from which the tMBSaw should be freed.
1113− */
1114− void tMBSaw_freeFromPool (tMBSaw* const osc, tMempool* const pool);
1115−
1116−
1117− //! Tick a tMBSaw oscillator.
1118− /*!
1119− @param osc A pointer to the relevant tMBSaw.
1120− @return The ticked sample as a float from -1 to 1.
1121− */
1122− float tMBSaw_tick (tMBSaw* const osc);
1123−
1124−
1125− //! Set the frequency of a tMBSaw oscillator.
1126− /*!
1127− @param osc A pointer to the relevant tMBSaw.
1128− @param freq The frequency to set the oscillator to.
1129− */
1130− void tMBSaw_setFreq (tMBSaw* const osc, float freq);
1131−
1132− void tMBSaw_sync (tMBSaw* const osc, float phase);
1133−
1134− /*! @} */
1135−
1136−#ifdef __cplusplus
1137−}
1138−#endif
1139−
1140−#endif // LEAF_OSCILLATORS_H_INCLUDED
1141−
1142−//==============================================================================
1143−
LEAF/Inc/leaf-physical.h+0−259
@@ -1,259 +0,0 @@
1−/*
2− ==============================================================================
3−
4− leaf-physical.h
5− Created: 30 Nov 2018 10:41:55am
6− Author: airship
7−
8− ==============================================================================
9− */
10−
11−#ifndef LEAF_PHYSICAL_H_INCLUDED
12−#define LEAF_PHYSICAL_H_INCLUDED
13−
14−#ifdef __cplusplus
15−extern "C" {
16−#endif
17−
18− //==============================================================================
19−
20−#include "leaf-global.h"
21−#include "leaf-math.h"
22−#include "leaf-mempool.h"
23−#include "leaf-delay.h"
24−#include "leaf-filters.h"
25−#include "leaf-oscillators.h"
26−#include "leaf-envelopes.h"
27−#include "leaf-dynamics.h"
28−
29− /*!
30− * @internal
31− * Header.
32− * @include basic-oscillators.h
33− * @example basic-oscillators.c
34− * An example.
35− */
36−
37− //==============================================================================
38−
39− /* Karplus Strong model */
40− typedef struct _tPluck
41− {
42− tAllpassDelay delayLine; // Allpass or Linear?? big difference...
43− tOneZero loopFilter;
44− tOnePole pickFilter;
45− tNoise noise;
46−
47− float lastOut;
48− float loopGain;
49− float lastFreq;
50−
51− float sr;
52−
53− } _tPluck;
54−
55− typedef _tPluck* tPluck;
56−
57− void tPluck_init (tPluck* const, float lowestFrequency); //float delayBuff[DELAY_LENGTH]);
58− void tPluck_free (tPluck* const);
59− void tPluck_initToPool (tPluck* const, float lowestFrequency, tMempool* const);
60− void tPluck_freeFromPool (tPluck* const, tMempool* const);
61−
62− float tPluck_tick (tPluck* const);
63−
64− // Pluck the string.
65− void tPluck_pluck (tPluck* const, float amplitude);
66−
67− // Start a note with the given frequency and amplitude.;
68− void tPluck_noteOn (tPluck* const, float frequency, float amplitude );
69−
70− // Stop a note with the given amplitude (speed of decay).
71− void tPluck_noteOff (tPluck* const, float amplitude );
72−
73− // Set instrument parameters for a particular frequency.
74− void tPluck_setFrequency (tPluck* const, float frequency );
75−
76− // Perform the control change specified by \e number and \e value (0.0 - 128.0).
77− void tPluck_controlChange (tPluck* const, int number, float value);
78−
79− // tPluck Utilities.
80− float tPluck_getLastOut (tPluck* const);
81−
82− //==============================================================================
83−
84− typedef enum SKControlType
85− {
86− SKPickPosition = 0,
87− SKStringDamping,
88− SKDetune,
89− SKControlTypeNil
90− } SKControlType;
91−
92− /* Stif Karplus Strong model */
93− typedef struct _tKarplusStrong
94− {
95− tAllpassDelay delayLine;
96− tLinearDelay combDelay;
97− tOneZero filter;
98− tNoise noise;
99− tBiQuad biquad[4];
100−
101− uint32_t length;
102− float loopGain;
103− float baseLoopGain;
104− float lastFrequency;
105− float lastLength;
106− float stretching;
107− float pluckAmplitude;
108− float pickupPosition;
109−
110− float lastOut;
111−
112− } _tKarplusStrong;
113−
114− typedef _tKarplusStrong* tKarplusStrong;
115−
116− void tKarplusStrong_init (tKarplusStrong* const, float lowestFrequency); // float delayBuff[2][DELAY_LENGTH]);
117− void tKarplusStrong_free (tKarplusStrong* const);
118− void tKarplusStrong_initToPool (tKarplusStrong* const, float lowestFrequency, tMempool* const);
119− void tKarplusStrong_freeFromPool (tKarplusStrong* const, tMempool* const);
120−
121− float tKarplusStrong_tick (tKarplusStrong* const);
122−
123− // Pluck the string.
124− void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude);
125−
126− // Start a note with the given frequency and amplitude.;
127− void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude );
128−
129− // Stop a note with the given amplitude (speed of decay).
130− void tKarplusStrong_noteOff (tKarplusStrong* const, float amplitude );
131−
132− // Set instrument parameters for a particular frequency.
133− void tKarplusStrong_setFrequency (tKarplusStrong* const, float frequency );
134−
135− // Perform the control change specified by \e number and \e value (0.0 - 128.0).
136− // Use SKPickPosition, SKStringDamping, or SKDetune for type.
137− void tKarplusStrong_controlChange (tKarplusStrong* const, SKControlType type, float value);
138−
139− // Set the stretch "factor" of the string (0.0 - 1.0).
140− void tKarplusStrong_setStretch (tKarplusStrong* const, float stretch );
141−
142− // Set the pluck or "excitation" position along the string (0.0 - 1.0).
143− void tKarplusStrong_setPickupPosition (tKarplusStrong* const, float position );
144−
145− // Set the base loop gain.
146− void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const, float aGain );
147−
148− // tKarplusStrong utilities.
149− float tKarplusStrong_getLastOut (tKarplusStrong* const);
150−
151− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
152−
153− /* Simple Living String */
154− typedef struct _tSimpleLivingString {
155− float freq, waveLengthInSamples; // the frequency of the string, determining delay length
156− float dampFreq; // frequency for the bridge LP filter, in Hz
157− float decay; // amplitude damping factor for the string (only active in mode 0)
158− float levMode;
159− float curr;
160− tLinearDelay delayLine;
161− tOnePole bridgeFilter;
162− tHighpass DCblocker;
163− tFeedbackLeveler fbLev;
164− tExpSmooth wlSmooth;
165− } _tSimpleLivingString;
166−
167− typedef _tSimpleLivingString* tSimpleLivingString;
168−
169− void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq,
170− float decay, float targetLev, float levSmoothFactor,
171− float levStrength, int levMode);
172− void tSimpleLivingString_free (tSimpleLivingString* const);
173− void tSimpleLivingString_initToPool (tSimpleLivingString* const, float freq, float dampFreq,
174− float decay, float targetLev, float levSmoothFactor,
175− float levStrength, int levMode, tMempool* const);
176− void tSimpleLivingString_freeFromPool (tSimpleLivingString* const, tMempool* const);
177−
178− float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
179− float tSimpleLivingString_sample (tSimpleLivingString* const);
180− void tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
181− void tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
182− void tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
183− void tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
184− void tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
185− void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
186− void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
187− void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
188−
189− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
190−
191− /* Living String */
192− typedef struct _tLivingString {
193− float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
194− float pickPos; // the pick position, dividing the string in two, in ratio
195− float prepIndex; // the amount of pressure on the pickpoint of the string (near 0=soft obj, near 1=hard obj)
196− float dampFreq; // frequency for the bridge LP filter, in Hz
197− float decay; // amplitude damping factor for the string (only active in mode 0)
198− float levMode;
199− float curr;
200− tLinearDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
201− tOnePole bridgeFilter, nutFilter, prepFilterU, prepFilterL;
202− tHighpass DCblockerL, DCblockerU;
203− tFeedbackLeveler fbLevU, fbLevL;
204− tExpSmooth wlSmooth, ppSmooth;
205− } _tLivingString;
206−
207− typedef _tLivingString* tLivingString;
208−
209− void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex,
210− float dampFreq, float decay, float targetLev, float levSmoothFactor,
211− float levStrength, int levMode);
212− void tLivingString_free (tLivingString* const);
213− void tLivingString_initToPool (tLivingString* const, float freq, float pickPos, float prepIndex,
214− float dampFreq, float decay, float targetLev, float levSmoothFactor,
215− float levStrength, int levMode, tMempool* const);
216− void tLivingString_freeFromPool (tLivingString* const, tMempool* const);
217−
218− float tLivingString_tick (tLivingString* const, float input);
219− float tLivingString_sample (tLivingString* const);
220− void tLivingString_setFreq (tLivingString* const, float freq);
221− void tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
222− void tLivingString_setPickPos (tLivingString* const, float pickPos);
223− void tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
224− void tLivingString_setDampFreq (tLivingString* const, float dampFreq);
225− void tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
226− void tLivingString_setTargetLev (tLivingString* const, float targetLev);
227− void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
228− void tLivingString_setLevStrength (tLivingString* const, float levStrength);
229− void tLivingString_setLevMode (tLivingString* const, int levMode);
230−
231− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
232−
233− //Reed Table - borrowed from STK
234− typedef struct _tReedTable {
235− float offset, slope;
236− } _tReedTable;
237−
238− typedef _tReedTable* tReedTable;
239−
240− void tReedTable_init (tReedTable* const, float offset, float slope);
241− void tReedTable_free (tReedTable* const);
242− void tReedTable_initToPool (tReedTable* const, float offset, float slope, tMempool* const);
243− void tReedTable_freeFromPool (tReedTable* const, tMempool* const);
244−
245− float tReedTable_tick (tReedTable* const, float input);
246− float tReedTable_tanh_tick (tReedTable* const, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
247− void tReedTable_setOffset (tReedTable* const, float offset);
248− void tReedTable_setSlope (tReedTable* const, float slope);
249−
250− //==============================================================================
251−
252−#ifdef __cplusplus
253−}
254−#endif
255−
256−#endif // LEAF_PHYSICAL_H_INCLUDED
257−
258−//==============================================================================
259−
LEAF/Inc/leaf-reverb.h+0−175
@@ -1,175 +0,0 @@
1−/*==============================================================================
2−
3− leaf-reverb.h
4− Created: 20 Jan 2017 12:02:04pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#ifndef LEAF_REVERB_H_INCLUDED
10−#define LEAF_REVERB_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16− //==============================================================================
17−
18−#include "leaf-global.h"
19−#include "leaf-math.h"
20−#include "leaf-mempool.h"
21−#include "leaf-delay.h"
22−#include "leaf-filters.h"
23−#include "leaf-oscillators.h"
24−
25− /*!
26− * @internal
27− * Header.
28− * @include basic-oscillators.h
29− * @example basic-oscillators.c
30− * An example.
31− */
32−
33− //==============================================================================
34−
35− /* PRCReverb: Reverb, reimplemented from STK (Cook and Scavone). */
36− typedef struct _tPRCReverb
37− {
38− float mix, t60;
39−
40− float inv_441;
41−
42− tDelay allpassDelays[2];
43− tDelay combDelay;
44− float allpassCoeff;
45− float combCoeff;
46−
47− float lastIn, lastOut;
48−
49− } _tPRCReverb;
50−
51− typedef _tPRCReverb* tPRCReverb;
52−
53− void tPRCReverb_init (tPRCReverb* const, float t60);
54− void tPRCReverb_free (tPRCReverb* const);
55− void tPRCReverb_initToPool (tPRCReverb* const, float t60, tMempool* const);
56− void tPRCReverb_freeFromPool (tPRCReverb* const, tMempool* const);
57−
58− void tPRCReverb_clear (tPRCReverb* const);
59− float tPRCReverb_tick (tPRCReverb* const, float input);
60−
61− // Set reverb time in seconds.
62− void tPRCReverb_setT60 (tPRCReverb* const, float t60);
63−
64− // Set mix between dry input and wet output signal.
65− void tPRCReverb_setMix (tPRCReverb* const, float mix);
66−
67− //==============================================================================
68−
69− /* NReverb: Reverb, reimplemented from STK (Cook and Scavone). */
70− typedef struct _tNReverb
71− {
72− float mix, t60;
73−
74− float inv_sr, inv_441;
75−
76− tLinearDelay allpassDelays[8];
77− tLinearDelay combDelays[6];
78− float allpassCoeff;
79− float combCoeffs[6];
80− float lowpassState;
81−
82− float lastIn, lastOut;
83−
84− } _tNReverb;
85−
86− typedef _tNReverb* tNReverb;
87−
88− void tNReverb_init (tNReverb* const, float t60);
89− void tNReverb_free (tNReverb* const);
90− void tNReverb_initToPool (tNReverb* const, float t60, tMempool* const);
91− void tNReverb_freeFromPool (tNReverb* const, tMempool* const);
92−
93− void tNReverb_clear (tNReverb* const);
94− float tNReverb_tick (tNReverb* const, float input);
95− void tNReverb_tickStereo (tNReverb* const rev, float input, float* output);
96−
97− // Set reverb time in seconds.
98− void tNReverb_setT60 (tNReverb* const, float t60);
99−
100− // Set mix between dry input and wet output signal.
101− void tNReverb_setMix (tNReverb* const, float mix);
102−
103− //==============================================================================
104−
105− typedef struct _tDattorroReverb
106− {
107− float predelay;
108− float input_filter;
109− float feedback_filter;
110− float feedback_gain;
111− float mix;
112− uint32_t frozen;
113−
114− float size, size_max, t;
115−
116− float f1_delay_2_last,
117− f2_delay_2_last;
118−
119− float f1_last,
120− f2_last;
121−
122− // INPUT
123− tTapeDelay in_delay;
124− tOnePole in_filter;
125− tAllpass in_allpass[4];
126−
127− // FEEDBACK 1
128− tAllpass f1_allpass;
129− tTapeDelay f1_delay_1;
130− tOnePole f1_filter;
131− tTapeDelay f1_delay_2;
132− tTapeDelay f1_delay_3;
133− tHighpass f1_hp;
134−
135− tCycle f1_lfo;
136−
137− // FEEDBACK 2
138− tAllpass f2_allpass;
139− tTapeDelay f2_delay_1;
140− tOnePole f2_filter;
141− tTapeDelay f2_delay_2;
142− tTapeDelay f2_delay_3;
143− tHighpass f2_hp;
144−
145− tCycle f2_lfo;
146−
147− } _tDattorroReverb;
148−
149− typedef _tDattorroReverb* tDattorroReverb;
150−
151− void tDattorroReverb_init (tDattorroReverb* const);
152− void tDattorroReverb_free (tDattorroReverb* const);
153− void tDattorroReverb_initToPool (tDattorroReverb* const, tMempool* const);
154− void tDattorroReverb_freeFromPool (tDattorroReverb* const, tMempool* const);
155−
156− void tDattorroReverb_clear (tDattorroReverb* const);
157− float tDattorroReverb_tick (tDattorroReverb* const, float input);
158− void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);
159− void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
160− void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze);
161− void tDattorroReverb_setHP (tDattorroReverb* const, float freq);
162− void tDattorroReverb_setSize (tDattorroReverb* const, float size);
163− void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
164− void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
165− void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
166− void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);
167−
168−#ifdef __cplusplus
169−}
170−#endif
171−
172−#endif // LEAF_REVERB_H_INCLUDED
173−
174−//==============================================================================
175−
LEAF/Inc/leaf-sampling.h+0−188
@@ -1,188 +0,0 @@
1−/*==============================================================================
2−
3− leaf-sampling.h
4− Created: 23 Jan 2019 11:22:09am
5− Author: Mike Mulshine
6−
7− ==============================================================================*/
8−
9−
10−#ifndef LEAF_SAMPLING_H_INCLUDED
11−#define LEAF_SAMPLING_H_INCLUDED
12−
13−#ifdef __cplusplus
14−extern "C" {
15−#endif
16−
17− //==============================================================================
18−
19−#include "leaf-global.h"
20−#include "leaf-math.h"
21−#include "leaf-mempool.h"
22−#include "leaf-envelopes.h"
23−#include "leaf-mempool.h"
24−#include "leaf-analysis.h"
25−
26− /*!
27− * @internal
28− * Header.
29− * @include basic-oscillators.h
30− * @example basic-oscillators.c
31− * An example.
32− */
33−
34− //==============================================================================
35−
36− typedef enum RecordMode
37− {
38− RecordOneShot = 0,
39− RecordLoop,
40− RecordModeNil
41− } RecordMode;
42−
43− typedef struct _tBuffer
44− {
45− float* buff;
46−
47− uint32_t idx;
48− uint32_t bufferLength;
49− uint32_t recordedLength;
50− RecordMode mode;
51−
52− int active;
53−
54− } _tBuffer;
55−
56− typedef _tBuffer* tBuffer;
57−
58− void tBuffer_init (tBuffer* const, uint32_t length);
59− void tBuffer_free (tBuffer* const);
60− void tBuffer_initToPool (tBuffer* const, uint32_t length, tMempool* const);
61− void tBuffer_freeFromPool (tBuffer* const, tMempool* const);
62−
63− void tBuffer_tick (tBuffer* const, float sample);
64−
65− void tBuffer_read (tBuffer* const, float* buff, uint32_t len);
66−
67− float tBuffer_get (tBuffer* const, int idx);
68−
69− void tBuffer_record (tBuffer* const);
70− void tBuffer_stop (tBuffer* const);
71− int tBuffer_getRecordPosition (tBuffer* const);
72−
73− void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
74−
75− void tBuffer_clear (tBuffer* const);
76−
77− uint32_t tBuffer_getBufferLength (tBuffer* const);
78− uint32_t tBuffer_getRecordedLength (tBuffer* const sb);
79−
80− //==============================================================================
81−
82− typedef enum PlayMode
83− {
84− PlayNormal,
85− PlayLoop,
86− PlayBackAndForth,
87− PlayModeNil
88− } PlayMode;
89−
90− typedef struct _tSampler
91− {
92− tBuffer samp;
93−
94− tRamp gain;
95−
96− float idx;
97− float inc;
98− float last;
99− float iinc;
100− int8_t dir;
101− int8_t flip;
102− int8_t bnf;
103−
104− int32_t start, targetstart;
105− int32_t end, targetend;
106−
107− uint32_t len;
108− uint32_t cfxlen;
109− float numticks;
110− PlayMode mode;
111− int retrigger;
112−
113− int active;
114−
115− uint8_t inCrossfade;
116−
117− float flipStart;
118− float flipIdx;
119−
120− } _tSampler;
121−
122− typedef _tSampler* tSampler;
123−
124− void tSampler_init (tSampler* const, tBuffer* const);
125− void tSampler_free (tSampler* const);
126− void tSampler_initToPool (tSampler* const, tBuffer* const, tMempool* const);
127− void tSampler_freeFromPool (tSampler* const, tMempool* const);
128−
129− float tSampler_tick (tSampler* const);
130−
131− void tSampler_setSample (tSampler* const, tBuffer* const);
132−
133− void tSampler_setMode (tSampler* const, PlayMode mode);
134−
135− void tSampler_play (tSampler* const);
136− void tSampler_stop (tSampler* const);
137−
138− void tSampler_setStart (tSampler* const, int32_t start);
139− void tSampler_setEnd (tSampler* const, int32_t end);
140− void tSampler_setLength (tSampler* const, int32_t length);
141−
142− void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
143−
144− void tSampler_setRate (tSampler* const, float rate);
145−
146− //==============================================================================
147−
148− typedef struct _tAutoSampler
149− {
150− tSampler sampler;
151− tEnvelopeFollower ef;
152− uint32_t windowSize;
153− float threshold;
154− float previousPower;
155− uint32_t sampleCounter;
156− uint32_t powerCounter;
157− uint8_t sampleTriggered;
158− } _tAutoSampler;
159−
160− typedef _tAutoSampler* tAutoSampler;
161−
162− void tAutoSampler_init (tAutoSampler* const, tBuffer* const);
163− void tAutoSampler_free (tAutoSampler* const);
164− void tAutoSampler_initToPool (tAutoSampler* const, tBuffer* const, tMempool* const);
165− void tAutoSampler_freeFromPool (tAutoSampler* const, tMempool* const);
166−
167− float tAutoSampler_tick (tAutoSampler* const, float input);
168−
169− void tAutoSampler_setBuffer (tAutoSampler* const, tBuffer* const);
170−
171− void tAutoSampler_setMode (tAutoSampler* const, PlayMode mode);
172−
173− void tAutoSampler_play (tAutoSampler* const);
174− void tAutoSampler_stop (tAutoSampler* const);
175−
176− void tAutoSampler_setThreshold (tAutoSampler* const, float thresh);
177− void tAutoSampler_setWindowSize (tAutoSampler* const, uint32_t size);
178− void tAutoSampler_setCrossfadeLength (tAutoSampler* const, uint32_t length);
179−
180− void tAutoSampler_setRate (tAutoSampler* const, float rate);
181−
182−#ifdef __cplusplus
183−}
184−#endif
185−
186−#endif // LEAF_SAMPLING_H_INCLUDED
187−
188−//==============================================================================
LEAF/Inc/leaf-tables.h+0−104
@@ -1,104 +0,0 @@
1−/*==============================================================================
2−
3− leaf-tables.h
4− Created: 4 Dec 2016 9:42:41pm
5− Author: Michael R Mulshine
6−
7−==============================================================================*/
8−
9−#ifndef LEAF_TABLES_H_INCLUDED
10−#define LEAF_TABLES_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
14−#endif
15−
16−//==============================================================================
17−
18−#include "leaf-math.h"
19−
20−//==============================================================================
21−
22−#define USE_SAWTOOTH_TABLE 1
23−#define USE_SQUARE_TABLE 1
24−#define USE_TRIANGLE_TABLE 1
25−#define USE_SHAPER_TABLE 1
26−
27−#define SINE_TABLE_SIZE 2048
28−#define SAW_TABLE_SIZE 2048
29−#define SQR_TABLE_SIZE 2048
30−#define TRI_TABLE_SIZE 2048
31−#define EXP_DECAY_TABLE_SIZE 65536
32−#define ATTACK_DECAY_INC_TABLE_SIZE 65536
33−#define TANH1_TABLE_SIZE 65536
34−#define DECAY_COEFF_TABLE_SIZE 4096
35−#define MTOF1_TABLE_SIZE 4096
36−#define FILTERTAN_TABLE_SIZE 4096
37−
38−#define SHAPER1_TABLE_SIZE 65536
39−extern const float __leaf_table_shaper1[SHAPER1_TABLE_SIZE];
40−
41−#define COEFFS_SIZE 32
42−extern const float* __leaf_tableref_firCoeffs[COEFFS_SIZE];
43−extern const float __leaf_tablesize_firNumTaps[COEFFS_SIZE];
44−extern const float __leaf_table_fir2XLow[32];
45−extern const float __leaf_table_fir4XLow[64];
46−extern const float __leaf_table_fir8XLow[64];
47−extern const float __leaf_table_fir16XLow[128];
48−extern const float __leaf_table_fir32XLow[256];
49−extern const float __leaf_table_fir64XLow[256];
50−extern const float __leaf_table_fir2XHigh[128];
51−extern const float __leaf_table_fir4XHigh[256];
52−extern const float __leaf_table_fir8XHigh[256];
53−extern const float __leaf_table_fir16XHigh[512];
54−extern const float __leaf_table_fir32XHigh[512];
55−extern const float __leaf_table_fir64XHigh[1024];
56−
57−typedef enum TableName
58−{
59− T20 = 0,
60− T40,
61− T80,
62− T160,
63− T320,
64− T640,
65− T1280,
66− T2560,
67− T5120,
68− T10240,
69− T20480,
70− TableNameNil
71−} TableName;
72−
73−// mtof lookup table based on input range [0.0,1.0) in 4096 increments - midi frequency values scaled between m25 and m134 (from the Snyderphonics DrumBox code)
74−
75−extern const float __leaf_table_exp_decay[EXP_DECAY_TABLE_SIZE];
76−extern const float __leaf_table_attack_decay_inc[ATTACK_DECAY_INC_TABLE_SIZE];
77−
78−extern const float __leaf_table_filtertan[FILTERTAN_TABLE_SIZE];
79−
80−extern const float __leaf_table_mtof1[MTOF1_TABLE_SIZE];
81−extern const float __leaf_table_decayCoeffTable[DECAY_COEFF_TABLE_SIZE];
82−
83−extern const float __leaf_table_tanh1[TANH1_TABLE_SIZE];
84−
85−//==============================================================================
86−
87−/* Sine wave table ripped from http://aquaticus.info/pwm-sine-wave. */
88−extern const float __leaf_table_sinewave[SINE_TABLE_SIZE];
89−
90−extern const float __leaf_table_sawtooth[11][SAW_TABLE_SIZE];
91−
92−extern const float __leaf_table_triangle[11][TRI_TABLE_SIZE];
93−
94−extern const float __leaf_table_squarewave[11][SQR_TABLE_SIZE];
95−
96−//==============================================================================
97−
98−#ifdef __cplusplus
99−}
100−#endif
101−
102−#endif // LEAF_TABLES_H_INCLUDED
103−
104−//==============================================================================
LEAF/Src/leaf-analysis.c+0−1054
@@ -1,1054 +0,0 @@
1−/*==============================================================================
2−
3− leaf-analysis.c
4− Created: 30 Nov 2018 11:56:49am
5− Author: airship
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-analysis.h"
12−#include "..\Externals\d_fft_mayer.h"
13−
14−#else
15−
16−#include "../Inc/leaf-analysis.h"
17−#include "../Externals/d_fft_mayer.h"
18−
19−#endif
20−
21−//===========================================================================
22−/* Envelope Follower */
23−//===========================================================================
24−
25−void tEnvelopeFollower_init(tEnvelopeFollower* const ef, float attackThreshold, float decayCoeff)
26−{
27− _tEnvelopeFollower* e = *ef = (_tEnvelopeFollower*) leaf_alloc(sizeof(_tEnvelopeFollower));
28−
29− e->y = 0.0f;
30− e->a_thresh = attackThreshold;
31− e->d_coeff = decayCoeff;
32−}
33−
34−void tEnvelopeFollower_free(tEnvelopeFollower* const ef)
35−{
36− _tEnvelopeFollower* e = *ef;
37−
38− leaf_free((char*)e);
39−}
40−
41−void tEnvelopeFollower_initToPool (tEnvelopeFollower* const ef, float attackThreshold, float decayCoeff, tMempool* const mp)
42−{
43− _tMempool* m = *mp;
44− _tEnvelopeFollower* e = *ef = (_tEnvelopeFollower*) mpool_alloc(sizeof(_tEnvelopeFollower), m);
45−
46− e->y = 0.0f;
47− e->a_thresh = attackThreshold;
48− e->d_coeff = decayCoeff;
49−}
50−
51−void tEnvelopeFollower_freeFromPool (tEnvelopeFollower* const ef, tMempool* const mp)
52−{
53− _tMempool* m = *mp;
54− _tEnvelopeFollower* e = *ef;
55−
56− mpool_free((char*)e, m);
57−}
58−
59−float tEnvelopeFollower_tick(tEnvelopeFollower* const ef, float x)
60−{
61− _tEnvelopeFollower* e = *ef;
62−
63− if (x < 0.0f ) x = -x; /* Absolute value. */
64−
65− if ((x >= e->y) && (x > e->a_thresh)) e->y = x; /* If we hit a peak, ride the peak to the top. */
66− else e->y = e->y * e->d_coeff; /* Else, exponential decay of output. */
67−
68− //ef->y = envelope_pow[(uint16_t)(ef->y * (float)UINT16_MAX)] * ef->d_coeff; //not quite the right behavior - too much loss of precision?
69− //ef->y = powf(ef->y, 1.000009f) * ef->d_coeff; // too expensive
70−
71− if( e->y < VSF) e->y = 0.0f;
72−
73− return e->y;
74−}
75−
76−int tEnvelopeFollower_decayCoeff(tEnvelopeFollower* const ef, float decayCoeff)
77−{
78− _tEnvelopeFollower* e = *ef;
79− return e->d_coeff = decayCoeff;
80−}
81−
82−int tEnvelopeFollower_attackThresh(tEnvelopeFollower* const ef, float attackThresh)
83−{
84− _tEnvelopeFollower* e = *ef;
85− return e->a_thresh = attackThresh;
86−}
87−
88−
89−
90−
91−
92−// zero crossing detector
93−
94−void tZeroCrossing_init (tZeroCrossing* const zc, int maxWindowSize)
95−{
96− tZeroCrossing_initToPool (zc, maxWindowSize, &leaf.mempool);
97−}
98−void tZeroCrossing_free (tZeroCrossing* const zc)
99−{
100− tZeroCrossing_freeFromPool (zc, &leaf.mempool);
101−}
102−void tZeroCrossing_initToPool (tZeroCrossing* const zc, int maxWindowSize, tMempool* const mp)
103−{
104− _tMempool* m = *mp;
105− _tZeroCrossing* z = *zc = (_tZeroCrossing*) mpool_alloc(sizeof(_tZeroCrossing), m);
106−
107− z->count = 0;
108− z->maxWindowSize = maxWindowSize;
109− z->currentWindowSize = maxWindowSize;
110− z->invCurrentWindowSize = 1.0f / maxWindowSize;
111− z->position = 0;
112− z->prevPosition = maxWindowSize;
113− z->inBuffer = (float*) mpool_calloc(sizeof(float) * maxWindowSize, m);
114− z->countBuffer = (uint16_t*) mpool_calloc(sizeof(uint16_t) * maxWindowSize, m);
115−}
116−
117−void tZeroCrossing_freeFromPool (tZeroCrossing* const zc, tMempool* const mp)
118−{
119− _tMempool* m = *mp;
120− _tZeroCrossing* z = *zc;
121− mpool_free((char*)z->inBuffer, m);
122− mpool_free((char*)z->countBuffer, m);
123− mpool_free((char*)z, m);
124−}
125−
126−//returns proportion of zero crossings within window size (0.0 would be none in window, 1.0 would be all zero crossings)
127−float tZeroCrossing_tick (tZeroCrossing* const zc, float input)
128−{
129− _tZeroCrossing* z = *zc;
130−
131− z->inBuffer[z->position] = input;
132− int futurePosition = ((z->position + 1) % z->currentWindowSize);
133− float output = 0.0f;
134−
135− //add new value to count
136− if ((z->inBuffer[z->position] * z->inBuffer[z->prevPosition]) < 0.0f)
137− {
138− //zero crossing happened, add it to the count array
139− z->countBuffer[z->position] = 1;
140− z->count++;
141− }
142− else
143− {
144− z->countBuffer[z->position] = 0;
145− }
146−
147− //remove oldest value from count
148− if (z->countBuffer[futurePosition] > 0)
149− {
150− z->count--;
151− if (z->count < 0)
152− {
153− z->count = 0;
154− }
155− }
156−
157− z->prevPosition = z->position;
158− z->position = futurePosition;
159−
160− output = z->count * z->invCurrentWindowSize;
161−
162− return output;
163−}
164−
165−
166−void tZeroCrossing_setWindow (tZeroCrossing* const zc, float windowSize)
167−{
168− _tZeroCrossing* z = *zc;
169− if (windowSize <= z->maxWindowSize)
170− {
171− z->currentWindowSize = windowSize;
172− }
173− else
174− {
175− z->currentWindowSize = z->maxWindowSize;
176− }
177− z->invCurrentWindowSize = 1.0f / z->currentWindowSize;
178−}
179−
180−
181−
182−
183−
184−//===========================================================================
185−/* Power Follower */
186−//===========================================================================
187−void tPowerFollower_init(tPowerFollower* const pf, float factor)
188−{
189− _tPowerFollower* p = *pf = (_tPowerFollower*) leaf_alloc(sizeof(_tPowerFollower));
190−
191− p->curr=0.0f;
192− p->factor=factor;
193− p->oneminusfactor=1.0f-factor;
194−}
195−
196−void tPowerFollower_free(tPowerFollower* const pf)
197−{
198− _tPowerFollower* p = *pf;
199−
200− leaf_free((char*)p);
201−}
202−
203−void tPowerFollower_initToPool (tPowerFollower* const pf, float factor, tMempool* const mp)
204−{
205− _tMempool* m = *mp;
206− _tPowerFollower* p = *pf = (_tPowerFollower*) mpool_alloc(sizeof(_tPowerFollower), m);
207−
208− p->curr=0.0f;
209− p->factor=factor;
210− p->oneminusfactor=1.0f-factor;
211−}
212−
213−void tPowerFollower_freeFromPool (tPowerFollower* const pf, tMempool* const mp)
214−{
215− _tMempool* m = *mp;
216− _tPowerFollower* p = *pf;
217−
218− mpool_free((char*)p, m);
219−}
220−
221−int tPowerFollower_setFactor(tPowerFollower* const pf, float factor)
222−{
223− _tPowerFollower* p = *pf;
224−
225− if (factor<0) factor=0;
226− if (factor>1) factor=1;
227− p->factor=factor;
228− p->oneminusfactor=1.0f-factor;
229− return 0;
230−}
231−
232−float tPowerFollower_tick(tPowerFollower* const pf, float input)
233−{
234− _tPowerFollower* p = *pf;
235− p->curr = p->factor*input*input+p->oneminusfactor*p->curr;
236− return p->curr;
237−}
238−
239−float tPowerFollower_sample(tPowerFollower* const pf)
240−{
241− _tPowerFollower* p = *pf;
242− return p->curr;
243−}
244−
245−
246−
247−
248−//===========================================================================
249−/* ---------------- env~ - simple envelope follower. ----------------- */
250−//===========================================================================
251−
252−void tEnvPD_init(tEnvPD* const xpd, int ws, int hs, int bs)
253−{
254− _tEnvPD* x = *xpd = (_tEnvPD*) leaf_calloc(sizeof(_tEnvPD));
255−
256− int period = hs, npoints = ws;
257−
258− int i;
259−
260− if (npoints < 1) npoints = 1024;
261− if (period < 1) period = npoints/2;
262− if (period < npoints / MAXOVERLAP + 1)
263− period = npoints / MAXOVERLAP + 1;
264−
265− x->x_npoints = npoints;
266− x->x_phase = 0;
267− x->x_period = period;
268−
269− x->windowSize = npoints;
270− x->hopSize = period;
271− x->blockSize = bs;
272−
273− for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0.0f;
274− for (i = 0; i < npoints; i++)
275− x->buf[i] = (1.0f - cosf((TWO_PI * i) / npoints))/npoints;
276− for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0.0f;
277−
278− x->x_f = 0.0f;
279−
280− x->x_allocforvs = INITVSTAKEN;
281−
282− // ~ ~ ~ dsp ~ ~ ~
283− if (x->x_period % x->blockSize)
284− {
285− x->x_realperiod = x->x_period + x->blockSize - (x->x_period % x->blockSize);
286− }
287− else
288− {
289− x->x_realperiod = x->x_period;
290− }
291− // ~ ~ ~ ~ ~ ~ ~ ~
292−}
293−
294−void tEnvPD_free (tEnvPD* const xpd)
295−{
296− _tEnvPD* x = *xpd;
297−
298− leaf_free((char*)x);
299−}
300−
301−void tEnvPD_initToPool (tEnvPD* const xpd, int ws, int hs, int bs, tMempool* const mp)
302−{
303− _tMempool* m = *mp;
304− _tEnvPD* x = *xpd = (_tEnvPD*) mpool_calloc(sizeof(_tEnvPD), m);
305−
306− int period = hs, npoints = ws;
307−
308− int i;
309−
310− if (npoints < 1) npoints = 1024;
311− if (period < 1) period = npoints/2;
312− if (period < npoints / MAXOVERLAP + 1)
313− period = npoints / MAXOVERLAP + 1;
314−
315− x->x_npoints = npoints;
316− x->x_phase = 0;
317− x->x_period = period;
318−
319− x->windowSize = npoints;
320− x->hopSize = period;
321− x->blockSize = bs;
322−
323− for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
324− for (i = 0; i < npoints; i++)
325− x->buf[i] = (1.0f - cosf((2 * PI * i) / npoints))/npoints;
326− for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0;
327−
328− x->x_f = 0;
329−
330− x->x_allocforvs = INITVSTAKEN;
331−
332− // ~ ~ ~ dsp ~ ~ ~
333− if (x->x_period % x->blockSize)
334− {
335− x->x_realperiod = x->x_period + x->blockSize - (x->x_period % x->blockSize);
336− }
337− else
338− {
339− x->x_realperiod = x->x_period;
340− }
341− // ~ ~ ~ ~ ~ ~ ~ ~
342−}
343−
344−void tEnvPD_freeFromPool (tEnvPD* const xpd, tMempool* const mp)
345−{
346− _tMempool* m = *mp;
347− _tEnvPD* x = *xpd;
348−
349− mpool_free((char*)x, m);
350−}
351−
352−float tEnvPD_tick (tEnvPD* const xpd)
353−{
354− _tEnvPD* x = *xpd;
355− return powtodb(x->x_result);
356−}
357−
358−void tEnvPD_processBlock(tEnvPD* const xpd, float* in)
359−{
360− _tEnvPD* x = *xpd;
361−
362− int n = x->blockSize;
363−
364− int count;
365− t_sample *sump;
366− in += n;
367− for (count = x->x_phase, sump = x->x_sumbuf;
368− count < x->x_npoints; count += x->x_realperiod, sump++)
369− {
370− t_sample *hp = x->buf + count;
371− t_sample *fp = in;
372− t_sample sum = *sump;
373− int i;
374−
375− for (i = 0; i < n; i++)
376− {
377− fp--;
378− sum += *hp++ * (*fp * *fp);
379− }
380− *sump = sum;
381− }
382− sump[0] = 0;
383− x->x_phase -= n;
384− if (x->x_phase < 0)
385− {
386− x->x_result = x->x_sumbuf[0];
387− for (count = x->x_realperiod, sump = x->x_sumbuf;
388− count < x->x_npoints; count += x->x_realperiod, sump++)
389− sump[0] = sump[1];
390− sump[0] = 0;
391− x->x_phase = x->x_realperiod - n;
392− }
393−}
394−
395−//===========================================================================
396−// ATTACKDETECTION
397−//===========================================================================
398−/********Private function prototypes**********/
399−static void atkdtk_init(tAttackDetection* const a, int blocksize, int atk, int rel);
400−static void atkdtk_envelope(tAttackDetection* const a, float *in);
401−
402−/********Constructor/Destructor***************/
403−
404−void tAttackDetection_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
405−{
406− *ad = (_tAttackDetection*) leaf_alloc(sizeof(_tAttackDetection));
407−
408− atkdtk_init(ad, blocksize, atk, rel);
409−}
410−
411−void tAttackDetection_free(tAttackDetection* const ad)
412−{
413− _tAttackDetection* a = *ad;
414−
415− leaf_free((char*)a);
416−}
417−
418−void tAttackDetection_initToPool (tAttackDetection* const ad, int blocksize, int atk, int rel, tMempool* const mp)
419−{
420− _tMempool* m = *mp;
421− *ad = (_tAttackDetection*) mpool_alloc(sizeof(_tAttackDetection), m);
422−
423− atkdtk_init(ad, blocksize, atk, rel);
424−}
425−
426−void tAttackDetection_freeFromPool (tAttackDetection* const ad, tMempool* const mp)
427−{
428− _tMempool* m = *mp;
429− _tAttackDetection* a = *ad;
430−
431− mpool_free((char*)a, m);
432−}
433−
434−/*******Public Functions***********/
435−
436−
437−void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)
438−{
439− _tAttackDetection* a = *ad;
440−
441− if(!((size==64)|(size==128)|(size==256)|(size==512)|(size==1024)|(size==2048)))
442− size = DEFBLOCKSIZE;
443− a->blocksize = size;
444−
445− return;
446−
447−}
448−
449−void tAttackDetection_setSamplerate(tAttackDetection* const ad, int inRate)
450−{
451− _tAttackDetection* a = *ad;
452−
453− a->samplerate = inRate;
454−
455− //Reset atk and rel to recalculate coeff
456− tAttackDetection_setAttack(ad, a->atk);
457− tAttackDetection_setRelease(ad, a->rel);
458−}
459−
460−void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
461−{
462− _tAttackDetection* a = *ad;
463− a->threshold = thres;
464−}
465−
466−void tAttackDetection_setAttack(tAttackDetection* const ad, int inAtk)
467−{
468− _tAttackDetection* a = *ad;
469− a->atk = inAtk;
470− a->atk_coeff = pow(0.01, 1.0/(a->atk * a->samplerate * 0.001));
471−}
472−
473−void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)
474−{
475− _tAttackDetection* a = *ad;
476− a->rel = inRel;
477− a->rel_coeff = pow(0.01, 1.0/(a->rel * a->samplerate * 0.001));
478−}
479−
480−
481−int tAttackDetection_detect(tAttackDetection* const ad, float *in)
482−{
483− _tAttackDetection* a = *ad;
484−
485− int result;
486−
487− atkdtk_envelope(ad, in);
488−
489− if(a->env >= a->prevAmp*2) //2 times greater = 6dB increase
490− result = 1;
491− else
492− result = 0;
493−
494− a->prevAmp = a->env;
495−
496− return result;
497−}
498−
499−/*******Private Functions**********/
500−
501−static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
502−{
503− _tAttackDetection* a = *ad;
504−
505− a->env = 0;
506− a->blocksize = blocksize;
507− a->threshold = DEFTHRESHOLD;
508− a->samplerate = leaf.sampleRate;
509− a->prevAmp = 0;
510−
511− a->env = 0;
512−
513− tAttackDetection_setAttack(ad, atk);
514− tAttackDetection_setRelease(ad, rel);
515−}
516−
517−static void atkdtk_envelope(tAttackDetection* const ad, float *in)
518−{
519− _tAttackDetection* a = *ad;
520−
521− int i = 0;
522− float tmp;
523− for(i = 0; i < a->blocksize; ++i){
524− tmp = fastabsf(in[i]);
525−
526− if(tmp > a->env)
527− a->env = a->atk_coeff * (a->env - tmp) + tmp;
528− else
529− a->env = a->rel_coeff * (a->env - tmp) + tmp;
530− }
531−
532−}
533−
534−//===========================================================================
535−// SNAC
536−//===========================================================================
537−/******************************************************************************/
538−/***************************** private procedures *****************************/
539−/******************************************************************************/
540−
541−#define REALFFT mayer_realfft
542−#define REALIFFT mayer_realifft
543−
544−static void snac_analyzeframe(tSNAC* const s);
545−static void snac_autocorrelation(tSNAC* const s);
546−static void snac_normalize(tSNAC* const s);
547−static void snac_pickpeak(tSNAC* const s);
548−static void snac_periodandfidelity(tSNAC* const s);
549−static void snac_biasbuf(tSNAC* const s);
550−static float snac_spectralpeak(tSNAC* const s, float periodlength);
551−
552−
553−/******************************************************************************/
554−/******************************** constructor, destructor *********************/
555−/******************************************************************************/
556−
557−
558−void tSNAC_init(tSNAC* const snac, int overlaparg)
559−{
560− _tSNAC* s = *snac = (_tSNAC*) leaf_calloc(sizeof(_tSNAC));
561−
562− s->biasfactor = DEFBIAS;
563− s->timeindex = 0;
564− s->periodindex = 0;
565− s->periodlength = 0.;
566− s->fidelity = 0.;
567− s->minrms = DEFMINRMS;
568− s->framesize = SNAC_FRAME_SIZE;
569−
570− s->inputbuf = (float*) leaf_calloc(sizeof(float) * SNAC_FRAME_SIZE);
571− s->processbuf = (float*) leaf_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2));
572− s->spectrumbuf = (float*) leaf_calloc(sizeof(float) * (SNAC_FRAME_SIZE / 2));
573− s->biasbuf = (float*) leaf_calloc(sizeof(float) * SNAC_FRAME_SIZE);
574−
575− snac_biasbuf(snac);
576− tSNAC_setOverlap(snac, overlaparg);
577−}
578−
579−void tSNAC_free(tSNAC* const snac)
580−{
581− _tSNAC* s = *snac;
582−
583− leaf_free((char*)s->inputbuf);
584− leaf_free((char*)s->processbuf);
585− leaf_free((char*)s->spectrumbuf);
586− leaf_free((char*)s->biasbuf);
587− leaf_free((char*)s);
588−}
589−
590−void tSNAC_initToPool (tSNAC* const snac, int overlaparg, tMempool* const mp)
591−{
592− _tMempool* m = *mp;
593− _tSNAC* s = *snac = (_tSNAC*) mpool_alloc(sizeof(_tSNAC), m);
594−
595− s->biasfactor = DEFBIAS;
596− s->timeindex = 0;
597− s->periodindex = 0;
598− s->periodlength = 0.;
599− s->fidelity = 0.;
600− s->minrms = DEFMINRMS;
601− s->framesize = SNAC_FRAME_SIZE;
602−
603− s->inputbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);
604− s->processbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE * 2), m);
605− s->spectrumbuf = (float*) mpool_calloc(sizeof(float) * (SNAC_FRAME_SIZE / 2), m);
606− s->biasbuf = (float*) mpool_calloc(sizeof(float) * SNAC_FRAME_SIZE, m);
607−
608− snac_biasbuf(snac);
609− tSNAC_setOverlap(snac, overlaparg);
610−}
611−
612−void tSNAC_freeFromPool (tSNAC* const snac, tMempool* const mp)
613−{
614− _tMempool* m = *mp;
615− _tSNAC* s = *snac;
616−
617− mpool_free((char*)s->inputbuf, m);
618− mpool_free((char*)s->processbuf, m);
619− mpool_free((char*)s->spectrumbuf, m);
620− mpool_free((char*)s->biasbuf, m);
621− mpool_free((char*)s, m);
622−}
623−
624−/******************************************************************************/
625−/************************** public access functions****************************/
626−/******************************************************************************/
627−
628−
629−void tSNAC_ioSamples(tSNAC* const snac, float *in, float *out, int size)
630−{
631− _tSNAC* s = *snac;
632−
633− int timeindex = s->timeindex;
634− int mask = s->framesize - 1;
635− int outindex = 0;
636− float *inputbuf = s->inputbuf;
637− float *processbuf = s->processbuf;
638−
639− // call analysis function when it is time
640− if(!(timeindex & (s->framesize / s->overlap - 1))) snac_analyzeframe(snac);
641−
642− while(size--)
643− {
644− inputbuf[timeindex] = *in++;
645− out[outindex++] = processbuf[timeindex++];
646− timeindex &= mask;
647− }
648− s->timeindex = timeindex;
649−}
650−
651−void tSNAC_setOverlap(tSNAC* const snac, int lap)
652−{
653− _tSNAC* s = *snac;
654− if(!((lap==1)|(lap==2)|(lap==4)|(lap==8))) lap = DEFOVERLAP;
655− s->overlap = lap;
656−}
657−
658−
659−void tSNAC_setBias(tSNAC* const snac, float bias)
660−{
661− _tSNAC* s = *snac;
662− if(bias > 1.) bias = 1.;
663− if(bias < 0.) bias = 0.;
664− s->biasfactor = bias;
665− snac_biasbuf(snac);
666− return;
667−}
668−
669−
670−void tSNAC_setMinRMS(tSNAC* const snac, float rms)
671−{
672− _tSNAC* s = *snac;
673− if(rms > 1.) rms = 1.;
674− if(rms < 0.) rms = 0.;
675− s->minrms = rms;
676− return;
677−}
678−
679−
680−float tSNAC_getPeriod(tSNAC* const snac)
681−{
682− _tSNAC* s = *snac;
683− return(s->periodlength);
684−}
685−
686−
687−float tSNAC_getFidelity(tSNAC* const snac)
688−{
689− _tSNAC* s = *snac;
690− return(s->fidelity);
691−}
692−
693−
694−/******************************************************************************/
695−/***************************** private procedures *****************************/
696−/******************************************************************************/
697−
698−
699−// main analysis function
700−static void snac_analyzeframe(tSNAC* const snac)
701−{
702− _tSNAC* s = *snac;
703−
704− int n, tindex = s->timeindex;
705− int framesize = s->framesize;
706− int mask = framesize - 1;
707− float norm = 1. / sqrt((float)(framesize * 2));
708−
709− float *inputbuf = s->inputbuf;
710− float *processbuf = s->processbuf;
711−
712− // copy input to processing buffers
713− for(n=0; n<framesize; n++)
714− {
715− processbuf[n] = inputbuf[tindex] * norm;
716− tindex++;
717− tindex &= mask;
718− }
719−
720− // zeropadding
721− for(n=framesize; n<(framesize<<1); n++) processbuf[n] = 0.;
722−
723− // call analysis procedures
724− snac_autocorrelation(snac);
725− snac_normalize(snac);
726− snac_pickpeak(snac);
727− snac_periodandfidelity(snac);
728−}
729−
730−
731−static void snac_autocorrelation(tSNAC* const snac)
732−{
733− _tSNAC* s = *snac;
734−
735− int n, m;
736− int framesize = s->framesize;
737− int fftsize = framesize * 2;
738− float *processbuf = s->processbuf;
739− float *spectrumbuf = s->spectrumbuf;
740−
741− REALFFT(fftsize, processbuf);
742−
743− // compute power spectrum
744− processbuf[0] *= processbuf[0]; // DC
745− processbuf[framesize] *= processbuf[framesize]; // Nyquist
746−
747− for(n=1; n<framesize; n++)
748− {
749− processbuf[n] = processbuf[n] * processbuf[n]
750− + processbuf[fftsize-n] * processbuf[fftsize-n]; // imag coefficients appear reversed
751− processbuf[fftsize-n] = 0.;
752− }
753−
754− // store power spectrum up to SR/4 for possible later use
755− for(m=0; m<(framesize>>1); m++)
756− {
757− spectrumbuf[m] = processbuf[m];
758− }
759−
760− // transform power spectrum to autocorrelation function
761− REALIFFT(fftsize, processbuf);
762− return;
763−}
764−
765−
766−static void snac_normalize(tSNAC* const snac)
767−{
768− _tSNAC* s = *snac;
769−
770− int framesize = s->framesize;
771− int framesizeplustimeindex = s->framesize + s->timeindex;
772− int timeindexminusone = s->timeindex - 1;
773− int n, m;
774− int mask = framesize - 1;
775− int seek = framesize * SEEK;
776− float *inputbuf = s->inputbuf;
777− float *processbuf= s->processbuf;
778− float signal1, signal2;
779−
780− // minimum RMS implemented as minimum autocorrelation at index 0
781− // functionally equivalent to white noise floor
782− float rms = s->minrms / sqrt(1.0f / (float)framesize);
783− float minrzero = rms * rms;
784− float rzero = processbuf[0];
785− if(rzero < minrzero) rzero = minrzero;
786− double normintegral = (double)rzero * 2.;
787−
788− // normalize biased autocorrelation function
789− // inputbuf is circular buffer: timeindex may be non-zero when overlap > 1
790− processbuf[0] = 1;
791− for(n=1, m=s->timeindex+1; n<seek; n++, m++)
792− {
793− signal1 = inputbuf[(n + timeindexminusone)&mask];
794− signal2 = inputbuf[(framesizeplustimeindex - n)&mask];
795− normintegral -= (double)(signal1 * signal1 + signal2 * signal2);
796− processbuf[n] /= (float)normintegral * 0.5f;
797− }
798−
799− // flush instable function tail
800− for(n = seek; n<framesize; n++) processbuf[n] = 0.;
801− return;
802−}
803−
804−
805−static void snac_periodandfidelity(tSNAC* const snac)
806−{
807− _tSNAC* s = *snac;
808−
809− float periodlength;
810−
811− if(s->periodindex)
812− {
813− periodlength = (float)s->periodindex +
814− interpolate3phase(s->processbuf, s->periodindex);
815− if(periodlength < 8) periodlength = snac_spectralpeak(snac, periodlength);
816− s->periodlength = periodlength;
817− s->fidelity = interpolate3max(s->processbuf, s->periodindex);
818− }
819− return;
820−}
821−
822−// select the peak which most probably represents period length
823−static void snac_pickpeak(tSNAC* const snac)
824−{
825− _tSNAC* s = *snac;
826−
827− int n, peakindex=0;
828− int seek = s->framesize * SEEK;
829− float *processbuf= s->processbuf;
830− float maxvalue = 0.;
831− float biasedpeak;
832− float *biasbuf = s->biasbuf;
833−
834− // skip main lobe
835− for(n=1; n<seek; n++)
836− {
837− if(processbuf[n] < 0.) break;
838− }
839−
840− // find interpolated / biased maximum in SNAC function
841− // interpolation finds the 'real maximum'
842− // biasing favours the first candidate
843− for(; n<seek-1; n++)
844− {
845− if(processbuf[n] >= processbuf[n-1])
846− {
847− if(processbuf[n] > processbuf[n+1]) // we have a local peak
848− {
849− biasedpeak = interpolate3max(processbuf, n) * biasbuf[n];
850−
851− if(biasedpeak > maxvalue)
852− {
853− maxvalue = biasedpeak;
854− peakindex = n;
855− }
856− }
857− }
858− }
859− s->periodindex = peakindex;
860− return;
861−}
862−
863−
864−// verify period length via frequency domain (up till SR/4)
865−// frequency domain is more precise than lag domain for period lengths < 8
866−// argument 'periodlength' is initial estimation from autocorrelation
867−static float snac_spectralpeak(tSNAC* const snac, float periodlength)
868−{
869− _tSNAC* s = *snac;
870−
871− if(periodlength < 4.0f) return periodlength;
872−
873− float max = 0.;
874− int n, startbin, stopbin, peakbin = 0;
875− int spectrumsize = s->framesize>>1;
876− float *spectrumbuf = s->spectrumbuf;
877− float peaklocation = (float)(s->framesize * 2.0f) / periodlength;
878−
879− startbin = (int)(peaklocation * 0.8f + 0.5f);
880− if(startbin < 1) startbin = 1;
881− stopbin = (int)(peaklocation * 1.25f + 0.5f);
882− if(stopbin >= spectrumsize - 1) stopbin = spectrumsize - 1;
883−
884− for(n=startbin; n<stopbin; n++)
885− {
886− if(spectrumbuf[n] >= spectrumbuf[n-1])
887− {
888− if(spectrumbuf[n] > spectrumbuf[n+1])
889− {
890− if(spectrumbuf[n] > max)
891− {
892− max = spectrumbuf[n];
893− peakbin = n;
894− }
895− }
896− }
897− }
898−
899− // calculate amplitudes in peak region
900− for(n=(peakbin-1); n<(peakbin+2); n++)
901− {
902− spectrumbuf[n] = sqrtf(spectrumbuf[n]);
903− }
904−
905− peaklocation = (float)peakbin + interpolate3phase(spectrumbuf, peakbin);
906− periodlength = (float)(s->framesize * 2.0f) / peaklocation;
907−
908− return periodlength;
909−}
910−
911−
912−// modified logarithmic bias function
913−static void snac_biasbuf(tSNAC* const snac)
914−{
915− _tSNAC* s = *snac;
916−
917− int n;
918− int maxperiod = (int)(s->framesize * (float)SEEK);
919− float bias = s->biasfactor / logf((float)(maxperiod - 4));
920− float *biasbuf = s->biasbuf;
921−
922− for(n=0; n<5; n++) // periods < 5 samples can't be tracked
923− {
924− biasbuf[n] = 0.0f;
925− }
926−
927− for(n=5; n<maxperiod; n++)
928− {
929− biasbuf[n] = 1.0f - (float)logf(n - 4) * bias;
930− }
931−}
932−
933−//===========================================================================
934−// PERIODDETECTION
935−//===========================================================================
936−void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)
937−{
938− tPeriodDetection_initToPool(pd, in, out, bufSize, frameSize, &leaf.mempool);
939−}
940−
941−void tPeriodDetection_free (tPeriodDetection* const pd)
942−{
943− tPeriodDetection_freeFromPool(pd, &leaf.mempool);
944−}
945−
946−void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize, tMempool* const mp)
947−{
948− _tMempool* m = *mp;
949− _tPeriodDetection* p = *pd = (_tPeriodDetection*) mpool_calloc(sizeof(_tPeriodDetection), m);
950−
951− p->inBuffer = in;
952− p->outBuffer = out;
953− p->bufSize = bufSize;
954− p->frameSize = frameSize;
955− p->framesPerBuffer = p->bufSize / p->frameSize;
956− p->curBlock = 1;
957− p->lastBlock = 0;
958− p->index = 0;
959−
960− p->hopSize = DEFHOPSIZE;
961− p->windowSize = DEFWINDOWSIZE;
962− p->fba = FBA;
963−
964− tEnvPD_initToPool(&p->env, p->windowSize, p->hopSize, p->frameSize, mp);
965−
966− tSNAC_initToPool(&p->snac, DEFOVERLAP, mp);
967−
968− p->timeConstant = DEFTIMECONSTANT;
969− p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
970− p->fidelityThreshold = 0.95;
971−}
972−
973−void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempool* const mp)
974−{
975− _tMempool* m = *mp;
976− _tPeriodDetection* p = *pd;
977−
978− tEnvPD_freeFromPool(&p->env, mp);
979− tSNAC_freeFromPool(&p->snac, mp);
980− mpool_free((char*)p, m);
981−}
982−
983−float tPeriodDetection_tick (tPeriodDetection* pd, float sample)
984−{
985− _tPeriodDetection* p = *pd;
986−
987− int i, iLast;
988−
989− i = (p->curBlock*p->frameSize);
990− iLast = (p->lastBlock*p->frameSize)+p->index;
991−
992− p->i = i;
993− p->iLast = iLast;
994−
995− p->inBuffer[i+p->index] = sample;
996−
997− p->index++;
998− p->indexstore = p->index;
999− if (p->index >= p->frameSize)
1000− {
1001− p->index = 0;
1002−
1003− tEnvPD_processBlock(&p->env, &(p->inBuffer[i]));
1004−
1005− tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
1006− float fidelity = tSNAC_getFidelity(&p->snac);
1007− // Fidelity threshold recommended by Katja Vetters is 0.95 for most instruments/voices http://www.katjaas.nl/helmholtz/helmholtz.html
1008− if (fidelity > p->fidelityThreshold) p->period = tSNAC_getPeriod(&p->snac);
1009−
1010− p->curBlock++;
1011− if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
1012− p->lastBlock++;
1013− if (p->lastBlock >= p->framesPerBuffer) p->lastBlock = 0;
1014− }
1015−
1016− return p->period;
1017−}
1018−
1019−float tPeriodDetection_getPeriod(tPeriodDetection* pd)
1020−{
1021− _tPeriodDetection* p = *pd;
1022− return p->period;
1023−}
1024−
1025−void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
1026−{
1027− _tPeriodDetection* p = *pd;
1028− p->hopSize = hs;
1029−}
1030−
1031−void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
1032−{
1033− _tPeriodDetection* p = *pd;
1034− p->windowSize = ws;
1035−}
1036−
1037−void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold)
1038−{
1039− _tPeriodDetection* p = *pd;
1040− p->fidelityThreshold = threshold;
1041−}
1042−
1043−void tPeriodDetection_setAlpha (tPeriodDetection* pd, float alpha)
1044−{
1045− _tPeriodDetection* p = *pd;
1046− p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
1047−}
1048−
1049−void tPeriodDetection_setTolerance (tPeriodDetection* pd, float tolerance)
1050−{
1051− _tPeriodDetection* p = *pd;
1052− if (tolerance < 0.0f) p->tolerance = 0.0f;
1053− else p->tolerance = tolerance;
1054−}
LEAF/Src/leaf-delay.c+0−928
@@ -1,928 +0,0 @@
1−/*==============================================================================
2−
3− leaf-delay.c
4− Created: 20 Jan 2017 12:01:24pm
5− Author: Michael R Mulshine
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-delay.h"
12−#include "..\leaf.h"
13−
14−#else
15−
16−#include "../Inc/leaf-delay.h"
17−#include "../leaf.h"
18−
19−#endif
20−
21−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Delay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
22−void tDelay_init (tDelay* const dl, uint32_t delay, uint32_t maxDelay)
23−{
24− tDelay_initToPool(dl, delay, maxDelay, &leaf.mempool);
25−}
26−
27−void tDelay_free(tDelay* const dl)
28−{
29− tDelay_freeFromPool(dl, &leaf.mempool);
30−}
31−
32−void tDelay_initToPool (tDelay* const dl, uint32_t delay, uint32_t maxDelay, tMempool* const mp)
33−{
34− _tMempool* m = *mp;
35− _tDelay* d = *dl = (_tDelay*) mpool_alloc(sizeof(_tDelay), m);
36−
37− d->maxDelay = maxDelay;
38−
39− d->delay = delay;
40−
41− d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m);
42−
43− d->inPoint = 0;
44− d->outPoint = 0;
45−
46− d->lastIn = 0.0f;
47− d->lastOut = 0.0f;
48−
49− d->gain = 1.0f;
50−
51− tDelay_setDelay(dl, d->delay);
52−}
53−
54−void tDelay_freeFromPool (tDelay* const dl, tMempool* const mp)
55−{
56− _tMempool* m = *mp;
57− _tDelay* d = *dl;
58−
59− mpool_free((char*)d->buff, m);
60− mpool_free((char*)d, m);
61−}
62−
63−void tDelay_clear(tDelay* const dl)
64−{
65− _tDelay* d = *dl;
66− for (int i = 0; i < d->maxDelay; i++)
67− {
68− d->buff[i] = 0;
69− }
70−}
71−
72−float tDelay_tick (tDelay* const dl, float input)
73−{
74− _tDelay* d = *dl;
75−
76− // Input
77− d->lastIn = input;
78− d->buff[d->inPoint] = input * d->gain;
79− if (++(d->inPoint) == d->maxDelay) d->inPoint = 0;
80−
81− // Output
82− d->lastOut = d->buff[d->outPoint];
83− if (++(d->outPoint) == d->maxDelay) d->outPoint = 0;
84−
85− return d->lastOut;
86−}
87−
88−int tDelay_setDelay (tDelay* const dl, uint32_t delay)
89−{
90− _tDelay* d = *dl;
91−
92− d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
93−
94− // read chases write
95− if ( d->inPoint >= delay ) d->outPoint = d->inPoint - d->delay;
96− else d->outPoint = d->maxDelay + d->inPoint - d->delay;
97−
98− return 0;
99−}
100−
101−float tDelay_tapOut (tDelay* const dl, uint32_t tapDelay)
102−{
103− _tDelay* d = *dl;
104−
105− int32_t tap = d->inPoint - tapDelay - 1;
106−
107− // Check for wraparound.
108− while ( tap < 0 ) tap += d->maxDelay;
109−
110− return d->buff[tap];
111−
112−}
113−
114−void tDelay_tapIn (tDelay* const dl, float value, uint32_t tapDelay)
115−{
116− _tDelay* d = *dl;
117−
118− int32_t tap = d->inPoint - tapDelay - 1;
119−
120− // Check for wraparound.
121− while ( tap < 0 ) tap += d->maxDelay;
122−
123− d->buff[tap] = value;
124−}
125−
126−float tDelay_addTo (tDelay* const dl, float value, uint32_t tapDelay)
127−{
128− _tDelay* d = *dl;
129−
130− int32_t tap = d->inPoint - tapDelay - 1;
131−
132− // Check for wraparound.
133− while ( tap < 0 ) tap += d->maxDelay;
134−
135− return (d->buff[tap] += value);
136−}
137−
138−uint32_t tDelay_getDelay (tDelay* const dl)
139−{
140− _tDelay* d = *dl;
141− return d->delay;
142−}
143−
144−float tDelay_getLastOut (tDelay* const dl)
145−{
146− _tDelay* d = *dl;
147− return d->lastOut;
148−}
149−
150−float tDelay_getLastIn (tDelay* const dl)
151−{
152− _tDelay* d = *dl;
153− return d->lastIn;
154−}
155−
156−void tDelay_setGain (tDelay* const dl, float gain)
157−{
158− _tDelay* d = *dl;
159− if (gain < 0.0f) d->gain = 0.0f;
160− else d->gain = gain;
161−}
162−
163−float tDelay_getGain (tDelay* const dl)
164−{
165− _tDelay* d = *dl;
166− return d->gain;
167−}
168−
169−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
170−void tLinearDelay_init (tLinearDelay* const dl, float delay, uint32_t maxDelay)
171−{
172− tLinearDelay_initToPool(dl, delay, maxDelay, &leaf.mempool);
173−}
174−
175−void tLinearDelay_free(tLinearDelay* const dl)
176−{
177− tLinearDelay_freeFromPool(dl, &leaf.mempool);
178−}
179−
180−void tLinearDelay_initToPool (tLinearDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
181−{
182− _tMempool* m = *mp;
183− _tLinearDelay* d = *dl = (_tLinearDelay*) mpool_alloc(sizeof(_tLinearDelay), m);
184−
185− d->maxDelay = maxDelay;
186−
187− if (delay > maxDelay) d->delay = maxDelay;
188− else if (delay < 0.0f) d->delay = 0.0f;
189− else d->delay = delay;
190−
191− d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m);
192−
193− d->gain = 1.0f;
194−
195− d->lastIn = 0.0f;
196− d->lastOut = 0.0f;
197−
198− d->inPoint = 0;
199− d->outPoint = 0;
200−
201− tLinearDelay_setDelay(dl, d->delay);
202−}
203−
204−void tLinearDelay_freeFromPool(tLinearDelay* const dl, tMempool* const mp)
205−{
206− _tMempool* m = *mp;
207− _tLinearDelay* d = *dl;
208−
209− mpool_free((char*)d->buff, m);
210− mpool_free((char*)d, m);
211−}
212−
213−void tLinearDelay_clear(tLinearDelay* const dl)
214−{
215− _tLinearDelay* d = *dl;
216− for (int i = 0; i < d->maxDelay; i++)
217− {
218− d->buff[i] = 0;
219− }
220−}
221−
222−float tLinearDelay_tick (tLinearDelay* const dl, float input)
223−{
224− _tLinearDelay* d = *dl;
225−
226− d->buff[d->inPoint] = input * d->gain;
227−
228− // Increment input pointer modulo length.
229− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
230−
231− uint32_t idx = (uint32_t) d->outPoint;
232− // First 1/2 of interpolation
233− d->lastOut = d->buff[idx] * d->omAlpha;
234− // Second 1/2 of interpolation
235− if ((idx + 1) < d->maxDelay)
236− d->lastOut += d->buff[idx+1] * d->alpha;
237− else
238− d->lastOut += d->buff[0] * d->alpha;
239−
240− // Increment output pointer modulo length
241− if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
242−
243− return d->lastOut;
244−}
245−
246−void tLinearDelay_tickIn (tLinearDelay* const dl, float input)
247−{
248− _tLinearDelay* d = *dl;
249−
250− d->buff[d->inPoint] = input * d->gain;
251−
252− // Increment input pointer modulo length.
253− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
254−}
255−
256−float tLinearDelay_tickOut (tLinearDelay* const dl)
257−{
258− _tLinearDelay* d = *dl;
259−
260− uint32_t idx = (uint32_t) d->outPoint;
261− // First 1/2 of interpolation
262− d->lastOut = d->buff[idx] * d->omAlpha;
263− // Second 1/2 of interpolation
264− if ((idx + 1) < d->maxDelay)
265− d->lastOut += d->buff[idx+1] * d->alpha;
266− else
267− d->lastOut += d->buff[0] * d->alpha;
268−
269− // Increment output pointer modulo length
270− if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
271−
272− return d->lastOut;
273−}
274−
275−int tLinearDelay_setDelay (tLinearDelay* const dl, float delay)
276−{
277− _tLinearDelay* d = *dl;
278−
279− d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
280−
281− float outPointer = d->inPoint - d->delay;
282−
283− while ( outPointer < 0 )
284− outPointer += d->maxDelay; // modulo maximum length
285−
286− d->outPoint = (uint32_t) outPointer; // integer part
287−
288− d->alpha = outPointer - d->outPoint; // fractional part
289− d->omAlpha = 1.0f - d->alpha;
290−
291− if ( d->outPoint == d->maxDelay ) d->outPoint = 0;
292−
293− return 0;
294−}
295−
296−float tLinearDelay_tapOut (tLinearDelay* const dl, uint32_t tapDelay)
297−{
298− _tLinearDelay* d = *dl;
299−
300− uint32_t tap = d->inPoint - tapDelay - 1;
301− // Check for wraparound.
302− while ( tap < 0 ) tap += d->maxDelay;
303−
304− return d->buff[tap];
305−}
306−
307−void tLinearDelay_tapIn (tLinearDelay* const dl, float value, uint32_t tapDelay)
308−{
309− _tLinearDelay* d = *dl;
310−
311− uint32_t tap = d->inPoint - tapDelay - 1;
312−
313− // Check for wraparound.
314− while ( tap < 0 ) tap += d->maxDelay;
315−
316− d->buff[tap] = value;
317−}
318−
319−float tLinearDelay_addTo (tLinearDelay* const dl, float value, uint32_t tapDelay)
320−{
321− _tLinearDelay* d = *dl;
322−
323− int32_t tap = d->inPoint - tapDelay - 1;
324−
325− // Check for wraparound.
326− while ( tap < 0 ) tap += d->maxDelay;
327−
328− return (d->buff[tap] += value);
329−}
330−
331−float tLinearDelay_getDelay (tLinearDelay* const dl)
332−{
333− _tLinearDelay* d = *dl;
334− return d->delay;
335−}
336−
337−float tLinearDelay_getLastOut (tLinearDelay* const dl)
338−{
339− _tLinearDelay* d = *dl;
340− return d->lastOut;
341−}
342−
343−float tLinearDelay_getLastIn (tLinearDelay* const dl)
344−{
345− _tLinearDelay* d = *dl;
346− return d->lastIn;
347−}
348−
349−void tLinearDelay_setGain (tLinearDelay* const dl, float gain)
350−{
351− _tLinearDelay* d = *dl;
352− if (gain < 0.0f) d->gain = 0.0f;
353− else d->gain = gain;
354−}
355−
356−float tLinearDelay_getGain (tLinearDelay* const dl)
357−{
358− _tLinearDelay* d = *dl;
359− return d->gain;
360−}
361−
362−
363−
364−
365−
366−/// Hermite Interpolated Delay
367−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
368−void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay)
369−{
370− tHermiteDelay_initToPool(dl, delay, maxDelay, &leaf.mempool);
371−}
372−
373−void tHermiteDelay_free(tHermiteDelay* const dl)
374−{
375− tHermiteDelay_freeFromPool(dl, &leaf.mempool);
376−}
377−
378−void tHermiteDelay_initToPool (tHermiteDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
379−{
380− _tMempool* m = *mp;
381− _tHermiteDelay* d = *dl = (_tHermiteDelay*) mpool_alloc(sizeof(_tHermiteDelay), m);
382−
383− d->maxDelay = maxDelay;
384−
385− if (delay > maxDelay) d->delay = maxDelay;
386− else if (delay < 0.0f) d->delay = 0.0f;
387− else d->delay = delay;
388−
389− d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m);
390−
391− d->gain = 1.0f;
392−
393− d->lastIn = 0.0f;
394− d->lastOut = 0.0f;
395−
396− d->inPoint = 0;
397− d->outPoint = 0;
398−
399− tHermiteDelay_setDelay(dl, d->delay);
400−}
401−
402−void tHermiteDelay_freeFromPool(tHermiteDelay* const dl, tMempool* const mp)
403−{
404− _tMempool* m = *mp;
405− _tHermiteDelay* d = *dl;
406−
407− mpool_free((char*)d->buff, m);
408− mpool_free((char*)d, m);
409−}
410−
411−
412−void tHermiteDelay_clear(tHermiteDelay* const dl)
413−{
414− _tHermiteDelay* d = *dl;
415− for (int i = 0; i < d->maxDelay; i++)
416− {
417− d->buff[i] = 0;
418− }
419−}
420−
421−float tHermiteDelay_tick (tHermiteDelay* const dl, float input)
422−{
423− _tHermiteDelay* d = *dl;
424−
425− d->buff[d->inPoint] = input * d->gain;
426−
427− // Increment input pointer modulo length.
428− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
429−
430−
431− uint32_t idx = (uint32_t) d->outPoint;
432− d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
433− d->buff[idx],
434− d->buff[(idx + 1) % d->maxDelay],
435− d->buff[(idx + 2) % d->maxDelay],
436− d->alpha);
437−
438− // Increment output pointer modulo length
439− if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
440−
441− return d->lastOut;
442−}
443−
444−void tHermiteDelay_tickIn (tHermiteDelay* const dl, float input)
445−{
446− _tHermiteDelay* d = *dl;
447−
448− d->buff[d->inPoint] = input * d->gain;
449−
450− // Increment input pointer modulo length.
451− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
452−}
453−
454−float tHermiteDelay_tickOut (tHermiteDelay* const dl)
455−{
456− _tHermiteDelay* d = *dl;
457−
458− uint32_t idx = (uint32_t) d->outPoint;
459−
460−
461−
462− d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
463− d->buff[idx],
464− d->buff[(idx + 1) % d->maxDelay],
465− d->buff[(idx + 2) % d->maxDelay],
466− d->alpha);
467−
468− // Increment output pointer modulo length
469− if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
470−
471− return d->lastOut;
472−}
473−
474−int tHermiteDelay_setDelay (tHermiteDelay* const dl, float delay)
475−{
476− _tHermiteDelay* d = *dl;
477−
478− d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
479−
480− float outPointer = d->inPoint - d->delay;
481−
482− while ( outPointer < 0 )
483− outPointer += d->maxDelay; // modulo maximum length
484−
485− d->outPoint = (uint32_t) outPointer; // integer part
486−
487− d->alpha = outPointer - d->outPoint; // fractional part
488− d->omAlpha = 1.0f - d->alpha;
489−
490− if ( d->outPoint == d->maxDelay ) d->outPoint = 0;
491−
492− return 0;
493−}
494−
495−float tHermiteDelay_tapOut (tHermiteDelay* const dl, uint32_t tapDelay)
496−{
497− _tHermiteDelay* d = *dl;
498−
499− uint32_t tap = d->inPoint - tapDelay - 1;
500−
501− // Check for wraparound.
502− while ( tap < 0 ) tap += d->maxDelay;
503−
504− return d->buff[tap];
505−
506−}
507−
508−void tHermiteDelay_tapIn (tHermiteDelay* const dl, float value, uint32_t tapDelay)
509−{
510− _tHermiteDelay* d = *dl;
511−
512− int32_t tap = d->inPoint - tapDelay - 1;
513−
514− // Check for wraparound.
515− while ( tap < 0 ) tap += d->maxDelay;
516−
517− d->buff[tap] = value;
518−}
519−
520−float tHermiteDelay_addTo (tHermiteDelay* const dl, float value, uint32_t tapDelay)
521−{
522− _tHermiteDelay* d = *dl;
523−
524− int32_t tap = d->inPoint - tapDelay - 1;
525−
526− // Check for wraparound.
527− while ( tap < 0 ) tap += d->maxDelay;
528−
529− return (d->buff[tap] += value);
530−}
531−
532−float tHermiteDelay_getDelay (tHermiteDelay* const dl)
533−{
534− _tHermiteDelay* d = *dl;
535− return d->delay;
536−}
537−
538−float tHermiteDelay_getLastOut (tHermiteDelay* const dl)
539−{
540− _tHermiteDelay* d = *dl;
541− return d->lastOut;
542−}
543−
544−float tHermiteDelay_getLastIn (tHermiteDelay* const dl)
545−{
546− _tHermiteDelay* d = *dl;
547− return d->lastIn;
548−}
549−
550−void tHermiteDelay_setGain (tHermiteDelay* const dl, float gain)
551−{
552− _tHermiteDelay* d = *dl;
553− if (gain < 0.0f) d->gain = 0.0f;
554− else d->gain = gain;
555−}
556−
557−float tHermiteDelay_getGain (tHermiteDelay* const dl)
558−{
559− _tHermiteDelay* d = *dl;
560− return d->gain;
561−}
562−
563−
564−
565−
566−
567−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ AllpassDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
568−void tAllpassDelay_init (tAllpassDelay* const dl, float delay, uint32_t maxDelay)
569−{
570− tAllpassDelay_initToPool(dl, delay, maxDelay, &leaf.mempool);
571−}
572−
573−void tAllpassDelay_free(tAllpassDelay* const dl)
574−{
575− tAllpassDelay_freeFromPool(dl, &leaf.mempool);
576−}
577−
578−void tAllpassDelay_initToPool (tAllpassDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
579−{
580− _tMempool* m = *mp;
581− _tAllpassDelay* d = *dl = (_tAllpassDelay*) mpool_alloc(sizeof(_tAllpassDelay), m);
582−
583− d->maxDelay = maxDelay;
584−
585− if (delay > maxDelay) d->delay = maxDelay;
586− else if (delay < 0.0f) d->delay = 0.0f;
587− else d->delay = delay;
588−
589− d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m);
590−
591− d->gain = 1.0f;
592−
593− d->lastIn = 0.0f;
594− d->lastOut = 0.0f;
595−
596− d->inPoint = 0;
597− d->outPoint = 0;
598−
599− tAllpassDelay_setDelay(dl, d->delay);
600−
601− d->apInput = 0.0f;
602−}
603−
604−void tAllpassDelay_freeFromPool(tAllpassDelay* const dl, tMempool* const mp)
605−{
606− _tMempool* m = *mp;
607− _tAllpassDelay* d = *dl;
608−
609− mpool_free((char*)d->buff, m);
610− mpool_free((char*)d, m);
611−}
612−
613−void tAllpassDelay_clear(tAllpassDelay* const dl)
614−{
615− _tAllpassDelay* d = *dl;
616− for (int i = 0; i < d->maxDelay; i++)
617− {
618− d->buff[i] = 0;
619− }
620−}
621−
622−float tAllpassDelay_tick (tAllpassDelay* const dl, float input)
623−{
624− _tAllpassDelay* d = *dl;
625−
626− d->buff[d->inPoint] = input * d->gain;
627−
628− // Increment input pointer modulo length.
629− if ( ++(d->inPoint) >= d->maxDelay ) d->inPoint = 0;
630−
631− // Do allpass interpolation delay.
632− float out = d->lastOut * -d->coeff;
633− out += d->apInput + ( d->coeff * d->buff[d->outPoint] );
634− d->lastOut = out;
635−
636− // Save allpass input
637− d->apInput = d->buff[d->outPoint];
638−
639− // Increment output pointer modulo length.
640− if (++(d->outPoint) >= d->maxDelay ) d->outPoint = 0;
641−
642− return d->lastOut;
643−}
644−
645−int tAllpassDelay_setDelay (tAllpassDelay* const dl, float delay)
646−{
647− _tAllpassDelay* d = *dl;
648−
649− d->delay = LEAF_clip(0.5f, delay, d->maxDelay);
650−
651− // outPoint chases inPoint
652− float outPointer = (float)d->inPoint - d->delay + 1.0f;
653−
654− while ( outPointer < 0 ) outPointer += d->maxDelay; // mod max length
655−
656− d->outPoint = (uint32_t) outPointer; // integer part
657−
658− if ( d->outPoint >= d->maxDelay ) d->outPoint = 0;
659−
660− d->alpha = 1.0f + (float)d->outPoint - outPointer; // fractional part
661−
662− if ( d->alpha < 0.5f )
663− {
664− // The optimal range for alpha is about 0.5 - 1.5 in order to
665− // achieve the flattest phase delay response.
666−
667− d->outPoint += 1;
668−
669− if ( d->outPoint >= d->maxDelay ) d->outPoint -= d->maxDelay;
670−
671− d->alpha += 1.0f;
672− }
673−
674− d->coeff = (1.0f - d->alpha) / (1.0f + d->alpha); // coefficient for allpass
675−
676− return 0;
677−}
678−
679−float tAllpassDelay_tapOut (tAllpassDelay* const dl, uint32_t tapDelay)
680−{
681− _tAllpassDelay* d = *dl;
682−
683− int32_t tap = d->inPoint - tapDelay - 1;
684−
685− // Check for wraparound.
686− while ( tap < 0 ) tap += d->maxDelay;
687−
688− return d->buff[tap];
689−
690−}
691−
692−void tAllpassDelay_tapIn (tAllpassDelay* const dl, float value, uint32_t tapDelay)
693−{
694− _tAllpassDelay* d = *dl;
695−
696− int32_t tap = d->inPoint - tapDelay - 1;
697−
698− // Check for wraparound.
699− while ( tap < 0 ) tap += d->maxDelay;
700−
701− d->buff[tap] = value;
702−}
703−
704−float tAllpassDelay_addTo (tAllpassDelay* const dl, float value, uint32_t tapDelay)
705−{
706− _tAllpassDelay* d = *dl;
707−
708− int32_t tap = d->inPoint - tapDelay - 1;
709−
710− // Check for wraparound.
711− while ( tap < 0 ) tap += d->maxDelay;
712−
713− return (d->buff[tap] += value);
714−}
715−
716−float tAllpassDelay_getDelay (tAllpassDelay* const dl)
717−{
718− _tAllpassDelay* d = *dl;
719− return d->delay;
720−}
721−
722−float tAllpassDelay_getLastOut (tAllpassDelay* const dl)
723−{
724− _tAllpassDelay* d = *dl;
725− return d->lastOut;
726−}
727−
728−float tAllpassDelay_getLastIn (tAllpassDelay* const dl)
729−{
730− _tAllpassDelay* d = *dl;
731− return d->lastIn;
732−}
733−
734−void tAllpassDelay_setGain (tAllpassDelay* const dl, float gain)
735−{
736− _tAllpassDelay* d = *dl;
737− if (gain < 0.0f) d->gain = 0.0f;
738− else d->gain = gain;
739−}
740−
741−float tAllpassDelay_getGain (tAllpassDelay* const dl)
742−{
743− _tAllpassDelay* d = *dl;
744− return d->gain;
745−}
746−
747−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TapeDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
748−void tTapeDelay_init (tTapeDelay* const dl, float delay, uint32_t maxDelay)
749−{
750− tTapeDelay_initToPool(dl, delay, maxDelay, &leaf.mempool);
751−}
752−
753−void tTapeDelay_free(tTapeDelay* const dl)
754−{
755− tTapeDelay_freeFromPool(dl, &leaf.mempool);
756−}
757−
758−void tTapeDelay_initToPool (tTapeDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
759−{
760− _tMempool* m = *mp;
761− _tTapeDelay* d = *dl = (_tTapeDelay*) mpool_alloc(sizeof(_tTapeDelay), m);
762−
763− d->maxDelay = maxDelay;
764−
765− d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m);
766−
767− d->gain = 1.0f;
768−
769− d->lastIn = 0.0f;
770− d->lastOut = 0.0f;
771−
772− d->idx = 0.0f;
773− d->inc = 1.0f;
774− d->inPoint = 0;
775−
776− tTapeDelay_setDelay(dl, delay);
777−}
778−
779−void tTapeDelay_freeFromPool(tTapeDelay* const dl, tMempool* const mp)
780−{
781− _tMempool* m = *mp;
782− _tTapeDelay* d = *dl;
783−
784− mpool_free((char*)d->buff, m);
785− mpool_free((char*)d, m);
786−}
787−
788−void tTapeDelay_clear(tTapeDelay* const dl)
789−{
790− _tTapeDelay* d = *dl;
791− for (int i = 0; i < d->maxDelay; i++)
792− {
793− d->buff[i] = 0;
794− }
795−}
796−
797−//#define SMOOTH_FACTOR 10.f
798−
799−float tTapeDelay_tick (tTapeDelay* const dl, float input)
800−{
801− _tTapeDelay* d = *dl;
802−
803− d->buff[d->inPoint] = input * d->gain;
804−
805− // Increment input pointer modulo length.
806− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
807−
808− int idx = (int) d->idx;
809− float alpha = d->idx - idx;
810−
811− d->lastOut = LEAF_interpolate_hermite_x (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
812− d->buff[idx],
813− d->buff[(idx + 1) % d->maxDelay],
814− d->buff[(idx + 2) % d->maxDelay],
815− alpha);
816−
817− float diff = (d->inPoint - d->idx);
818− while (diff < 0.f) diff += d->maxDelay;
819−
820− d->inc = 1.0f + (diff - d->delay) / d->delay; //* SMOOTH_FACTOR;
821−
822− d->idx += d->inc;
823−
824− if (d->idx >= d->maxDelay) d->idx = 0.0f;
825−
826− if (d->lastOut)
827− return d->lastOut;
828− return 0.0f;
829−}
830−
831−void tTapeDelay_incrementInPoint(tTapeDelay* const dl)
832−{
833− _tTapeDelay* d = *dl;
834− // Increment input pointer modulo length.
835− if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
836−}
837−
838−
839−void tTapeDelay_setRate(tTapeDelay* const dl, float rate)
840−{
841− _tTapeDelay* d = *dl;
842− d->inc = rate;
843−}
844−
845−void tTapeDelay_setDelay (tTapeDelay* const dl, float delay)
846−{
847− _tTapeDelay* d = *dl;
848− d->delay = LEAF_clip(1.f, delay, d->maxDelay);
849−}
850−
851−float tTapeDelay_tapOut (tTapeDelay* const dl, float tapDelay)
852−{
853− _tTapeDelay* d = *dl;
854−
855− float tap = (float) d->inPoint - tapDelay - 1.f;
856−
857− // Check for wraparound.
858− while ( tap < 0.f ) tap += (float)d->maxDelay;
859−
860− int idx = (int) tap;
861−
862− float alpha = tap - idx;
863−
864− float samp = LEAF_interpolate_hermite_x (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
865− d->buff[idx],
866− d->buff[(idx + 1) % d->maxDelay],
867− d->buff[(idx + 2) % d->maxDelay],
868− alpha);
869−
870− return samp;
871−
872−}
873−
874−void tTapeDelay_tapIn (tTapeDelay* const dl, float value, uint32_t tapDelay)
875−{
876− _tTapeDelay* d = *dl;
877−
878− int32_t tap = d->inPoint - tapDelay - 1;
879−
880− // Check for wraparound.
881− while ( tap < 0 ) tap += d->maxDelay;
882−
883− d->buff[tap] = value;
884−}
885−
886−float tTapeDelay_addTo (tTapeDelay* const dl, float value, uint32_t tapDelay)
887−{
888− _tTapeDelay* d = *dl;
889−
890− int32_t tap = d->inPoint - tapDelay - 1;
891−
892− // Check for wraparound.
893− while ( tap < 0 ) tap += d->maxDelay;
894−
895− return (d->buff[tap] += value);
896−}
897−
898−float tTapeDelay_getDelay (tTapeDelay *dl)
899−{
900− _tTapeDelay* d = *dl;
901− return d->delay;
902−}
903−
904−float tTapeDelay_getLastOut (tTapeDelay* const dl)
905−{
906− _tTapeDelay* d = *dl;
907− return d->lastOut;
908−}
909−
910−float tTapeDelay_getLastIn (tTapeDelay* const dl)
911−{
912− _tTapeDelay* d = *dl;
913− return d->lastIn;
914−}
915−
916−void tTapeDelay_setGain (tTapeDelay* const dl, float gain)
917−{
918− _tTapeDelay* d = *dl;
919− if (gain < 0.0f) d->gain = 0.0f;
920− else d->gain = gain;
921−}
922−
923−float tTapeDelay_getGain (tTapeDelay* const dl)
924−{
925− _tTapeDelay* d = *dl;
926− return d->gain;
927−}
928−
LEAF/Src/leaf-distortion.c+0−695
@@ -1,695 +0,0 @@
1−//
2−// leaf-distortion.c
3−// LEAF
4−//
5−// Created by Jeff Snyder, Matthew Wang, Michael Mulshine, and Joshua Becker
6−// Copyright © 2019 Princeton University. All rights reserved.
7−//
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-distortion.h"
12−#include "..\Inc\leaf-tables.h"
13−#else
14−
15−
16−#include "../Inc/leaf-distortion.h"
17−#include "../Inc/leaf-tables.h"
18−
19−#endif
20−
21−//============================================================================================================
22−// Sample-Rate reducer
23−//============================================================================================================
24−
25−
26−void tSampleReducer_init(tSampleReducer* const sr)
27−{
28− _tSampleReducer* s = *sr = (_tSampleReducer*) leaf_alloc(sizeof(_tSampleReducer));
29−
30− s->invRatio = 1.0f;
31− s->hold = 0.0f;
32− s->count = 0;
33−}
34−
35−void tSampleReducer_free (tSampleReducer* const sr)
36−{
37− _tSampleReducer* s = *sr;
38−
39− leaf_free((char*)s);
40−}
41−
42−void tSampleReducer_initToPool (tSampleReducer* const sr, tMempool* const mp)
43−{
44− _tMempool* m = *mp;
45− _tSampleReducer* s = *sr = (_tSampleReducer*) mpool_alloc(sizeof(_tSampleReducer), m);
46−
47− s->invRatio = 1.0f;
48− s->hold = 0.0f;
49− s->count = 0;
50−}
51−
52−void tSampleReducer_freeFromPool (tSampleReducer* const sr, tMempool* const mp)
53−{
54− _tMempool* m = *mp;
55− _tSampleReducer* s = *sr;
56−
57− mpool_free((char*)s, m);
58−}
59−
60−float tSampleReducer_tick(tSampleReducer* const sr, float input)
61−{
62− _tSampleReducer* s = *sr;
63− if (s->count > s->invRatio)
64− {
65− s->hold = input;
66− s->count = 0;
67− }
68−
69− s->count++;
70− return s->hold;
71−}
72−
73−
74−void tSampleReducer_setRatio(tSampleReducer* const sr, float ratio)
75−{
76− _tSampleReducer* s = *sr;
77− if ((ratio <= 1.0f) && (ratio >= 0.0f))
78− s->invRatio = 1.0f / ratio;
79−
80−}
81−
82−//============================================================================================================
83−// Oversampler
84−//============================================================================================================
85−// Latency is equal to the phase length (numTaps / ratio)
86−void tOversampler_init(tOversampler* const osr, int ratio, oBool extraQuality)
87−{
88− _tOversampler* os = *osr = (_tOversampler*) leaf_alloc(sizeof(_tOversampler));
89−
90− uint8_t offset = 0;
91− if (extraQuality) offset = 6;
92− if (ratio == 2 || ratio == 4 ||
93− ratio == 8 || ratio == 16 ||
94− ratio == 32 || ratio == 64) {
95− os->ratio = ratio;
96− int idx = (int)(log2f(os->ratio))-1+offset;
97− os->numTaps = __leaf_tablesize_firNumTaps[idx];
98− os->phaseLength = os->numTaps / os->ratio;
99− os->pCoeffs = (float*) __leaf_tableref_firCoeffs[idx];
100− os->upState = (float*) leaf_alloc(sizeof(float) * os->numTaps * 2);
101− os->downState = (float*) leaf_alloc(sizeof(float) * os->numTaps * 2);
102− }
103−}
104−
105−void tOversampler_free(tOversampler* const osr)
106−{
107− _tOversampler* os = *osr;
108−
109− leaf_free((char*)os->upState);
110− leaf_free((char*)os->downState);
111− leaf_free((char*)os);
112−}
113−
114−void tOversampler_initToPool (tOversampler* const osr, int ratio, oBool extraQuality, tMempool* const mp)
115−{
116− _tMempool* m = *mp;
117− _tOversampler* os = *osr = (_tOversampler*) mpool_alloc(sizeof(_tOversampler), m);
118−
119− uint8_t offset = 0;
120− if (extraQuality) offset = 6;
121− if (ratio == 2 || ratio == 4 ||
122− ratio == 8 || ratio == 16 ||
123− ratio == 32 || ratio == 64) {
124− os->ratio = ratio;
125− int idx = (int)(log2f(os->ratio))-1+offset;
126− os->numTaps = __leaf_tablesize_firNumTaps[idx];
127− os->phaseLength = os->numTaps / os->ratio;
128− os->pCoeffs = (float*) __leaf_tableref_firCoeffs[idx];
129− os->upState = (float*) mpool_alloc(sizeof(float) * os->numTaps * 2, m);
130− os->downState = (float*) mpool_alloc(sizeof(float) * os->numTaps * 2, m);
131− }
132−}
133−
134−void tOversampler_freeFromPool (tOversampler* const osr, tMempool* const mp)
135−{
136− _tMempool* m = *mp;
137− _tOversampler* os = *osr;
138−
139− mpool_free((char*)os->upState, m);
140− mpool_free((char*)os->downState, m);
141− mpool_free((char*)os, m);
142−}
143−
144−float tOversampler_tick(tOversampler* const osr, float input, float (*effectTick)(float))
145−{
146− _tOversampler* os = *osr;
147−
148− float buf[os->ratio];
149−
150− tOversampler_upsample(osr, input, buf);
151−
152− for (int i = 0; i < os->ratio; ++i) {
153− buf[i] = effectTick(buf[i]);
154− }
155−
156− return tOversampler_downsample(osr, buf);
157−}
158−
159−// From CMSIS DSP Library
160−void tOversampler_upsample(tOversampler* const osr, float input, float* output)
161−{
162− _tOversampler* os = *osr;
163−
164− float *pState = os->upState; /* State pointer */
165− float *pCoeffs = os->pCoeffs; /* Coefficient pointer */
166− float *pStateCur;
167− float *ptr1; /* Temporary pointer for state buffer */
168− float *ptr2; /* Temporary pointer for coefficient buffer */
169− float sum0; /* Accumulators */
170− uint32_t i, tapCnt; /* Loop counters */
171− uint32_t phaseLen = os->phaseLength; /* Length of each polyphase filter component */
172− uint32_t j;
173−
174− /* os->pState buffer contains previous frame (phaseLen - 1) samples */
175− /* pStateCur points to the location where the new input data should be written */
176− pStateCur = os->upState + (phaseLen - 1U);
177−
178− /* Copy new input sample into the state buffer */
179− *pStateCur = input;
180−
181− /* Address modifier index of coefficient buffer */
182− j = 1U;
183−
184− /* Loop over the Interpolation factor. */
185− i = os->ratio;
186−
187− while (i > 0U)
188− {
189− /* Set accumulator to zero */
190− sum0 = 0.0f;
191−
192− /* Initialize state pointer */
193− ptr1 = pState;
194−
195− /* Initialize coefficient pointer */
196− ptr2 = pCoeffs + (os->ratio - j);
197−
198− /* Loop over the polyPhase length.
199− Repeat until we've computed numTaps-(4*os->L) coefficients. */
200−
201− /* Initialize tapCnt with number of samples */
202− tapCnt = phaseLen;
203−
204− while (tapCnt > 0U)
205− {
206− /* Perform the multiply-accumulate */
207− sum0 += *ptr1++ * *ptr2;
208−
209− /* Upsampling is done by stuffing L-1 zeros between each sample.
210− * So instead of multiplying zeros with coefficients,
211− * Increment the coefficient pointer by interpolation factor times. */
212− ptr2 += os->ratio;
213−
214− /* Decrement loop counter */
215− tapCnt--;
216− }
217−
218− /* The result is in the accumulator, store in the destination buffer. */
219− *output++ = sum0 * os->ratio;
220−
221− /* Increment the address modifier index of coefficient buffer */
222− j++;
223−
224− /* Decrement the loop counter */
225− i--;
226− }
227−
228− /* Advance the state pointer by 1
229− * to process the next group of interpolation factor number samples */
230− pState = pState + 1;
231−
232− /* Processing is complete.
233− Now copy the last phaseLen - 1 samples to the satrt of the state buffer.
234− This prepares the state buffer for the next function call. */
235−
236− /* Points to the start of the state buffer */
237− pStateCur = os->upState;
238−
239− /* Initialize tapCnt with number of samples */
240− tapCnt = (phaseLen - 1U);
241−
242− /* Copy data */
243− while (tapCnt > 0U)
244− {
245− *pStateCur++ = *pState++;
246−
247− /* Decrement loop counter */
248− tapCnt--;
249− }
250−}
251−
252−// From CMSIS DSP Library
253−float tOversampler_downsample(tOversampler *const osr, float* input)
254−{
255− _tOversampler* os = *osr;
256−
257− float *pState = os->downState; /* State pointer */
258− float *pCoeffs = os->pCoeffs; /* Coefficient pointer */
259− float *pStateCur; /* Points to the current sample of the state */
260− float *px0; /* Temporary pointer for state buffer */
261− float *pb; /* Temporary pointer for coefficient buffer */
262− float x0, c0; /* Temporary variables to hold state and coefficient values */
263− float acc0; /* Accumulator */
264− uint32_t numTaps = os->numTaps; /* Number of filter coefficients in the filter */
265− uint32_t i, tapCnt;
266− float output;
267−
268− /* os->pState buffer contains previous frame (numTaps - 1) samples */
269− /* pStateCur points to the location where the new input data should be written */
270− pStateCur = os->downState + (numTaps - 1U);
271−
272− /* Copy decimation factor number of new input samples into the state buffer */
273− i = os->ratio;
274−
275− do
276− {
277− *pStateCur++ = *input++;
278−
279− } while (--i);
280−
281− /* Set accumulator to zero */
282− acc0 = 0.0f;
283−
284− /* Initialize state pointer */
285− px0 = pState;
286−
287− /* Initialize coeff pointer */
288− pb = pCoeffs;
289−
290− /* Initialize tapCnt with number of taps */
291− tapCnt = numTaps;
292−
293− while (tapCnt > 0U)
294− {
295− /* Read coefficients */
296− c0 = *pb++;
297−
298− /* Fetch 1 state variable */
299− x0 = *px0++;
300−
301− /* Perform the multiply-accumulate */
302− acc0 += x0 * c0;
303−
304− /* Decrement loop counter */
305− tapCnt--;
306− }
307−
308− /* Advance the state pointer by the decimation factor
309− * to process the next group of decimation factor number samples */
310− pState = pState + os->ratio;
311−
312− /* The result is in the accumulator, store in the destination buffer. */
313− output = acc0;
314−
315− /* Processing is complete.
316− Now copy the last numTaps - 1 samples to the start of the state buffer.
317− This prepares the state buffer for the next function call. */
318−
319− /* Points to the start of the state buffer */
320− pStateCur = os->downState;
321−
322− /* Initialize tapCnt with number of taps */
323− tapCnt = (numTaps - 1U);
324−
325− /* Copy data */
326− while (tapCnt > 0U)
327− {
328− *pStateCur++ = *pState++;
329−
330− /* Decrement loop counter */
331− tapCnt--;
332− }
333−
334− return output;
335−}
336−
337−int tOversampler_getLatency(tOversampler* const osr)
338−{
339− _tOversampler* os = *osr;
340− return os->phaseLength;
341−}
342−
343−//============================================================================================================
344−// WAVEFOLDER
345−//============================================================================================================
346−
347−
348−//from the paper: Virtual Analog Model of the Lockhart Wavefolder
349−//by Fabián Esqueda, Henri Pöntynen, Julian D. Parker and Stefan Bilbao
350−
351−void tLockhartWavefolder_init(tLockhartWavefolder* const wf)
352−{
353− tLockhartWavefolder_initToPool (wf, &leaf.mempool);
354−}
355−
356−void tLockhartWavefolder_free(tLockhartWavefolder* const wf)
357−{
358− _tLockhartWavefolder* w = *wf;
359−
360− leaf_free((char*)w);
361−}
362−
363−void tLockhartWavefolder_initToPool (tLockhartWavefolder* const wf, tMempool* const mp)
364−{
365− _tMempool* m = *mp;
366− _tLockhartWavefolder* w = *wf = (_tLockhartWavefolder*) mpool_alloc(sizeof(_tLockhartWavefolder), m);
367−
368− w->Ln1 = 0.0;
369− w->Fn1 = 0.0;
370− w->xn1 = 0.0;
371−
372− w->RL = 7.5e3;
373− w->R = 15e3;
374− w->VT = 26e-3;
375− w->Is = 10e-16;
376−
377− w->a = 2.0*w->RL/w->R;
378− w->b = (w->R+2.0*w->RL)/(w->VT*w->R);
379− w->d = (w->RL*w->Is)/w->VT;
380− w->half_a = 0.5 * w->a;
381− w->longthing = (0.5*w->VT/w->b);
382−
383−
384− // Antialiasing error threshold
385− w->AAthresh = 10e-10; //10
386−
387− w->LambertThresh = 10e-10; //12 //was 8
388−
389−
390− w->w = 0.0f;
391− w->expw = 0.0f;
392− w->p = 0.0f;
393− w->r = 0.0f;
394− w->s= 0.0f;
395− w->myerr = 0.0f;
396− w->l = 0.0f;
397− w->u = 0.0f;
398− w->Ln = 0.0f;
399− w->Fn = 0.0f;
400− w->tempsDenom = 0.0f;
401− w->tempErrDenom = 0.0f;
402− w->tempOutDenom = 0.0f;
403−
404−
405−}
406−
407−void tLockhartWavefolder_freeFromPool (tLockhartWavefolder* const wf, tMempool* const mp)
408−{
409− _tMempool* m = *mp;
410− _tLockhartWavefolder* w = *wf;
411−
412− mpool_free((char*)w, m);
413−}
414−
415−
416−
417−double tLockhartWavefolderLambert(tLockhartWavefolder* const wf, double x, double ln)
418−{
419− _tLockhartWavefolder* mwf = *wf;
420−
421−
422− // Initial guess (use previous value)
423− mwf->w = ln;
424−
425− // Haley's method (Sec. 4.2 of the paper)
426− for(int i=0; i<3000; i+=1) { //1000
427−
428− mwf->expw = exp(mwf->w);
429− /*
430− if (isinf(mwf->expw) || isnan(mwf->expw))
431− {
432− mwf->expw = 10e-5;
433− LEAF_error();
434− }
435− */
436− mwf->p = mwf->w*mwf->expw - x;
437− /*
438− if (isinf(mwf->p) || isnan(mwf->p))
439− {
440− mwf->p = 10e-5;
441− LEAF_error();
442− }
443− */
444− mwf->r = (mwf->w+1.0)*mwf->expw;
445− /*
446− if (isinf(mwf->r) || isnan(mwf->r))
447− {
448− mwf->r = 10e-5;
449− LEAF_error();
450− }
451− */
452− mwf->tempsDenom = (2.0*(mwf->w+1.0));
453− /*
454− if ((mwf->tempsDenom == 0.0) || isinf(mwf->tempsDenom) || isnan(mwf->tempsDenom))
455− {
456− mwf->tempsDenom = 10e-5;
457− LEAF_error();
458− }
459− */
460− mwf->s = (mwf->w+2.0)/mwf->tempsDenom;
461− /*
462− if (isnan(mwf->s) || isinf(mwf->s))
463− {
464− mwf->s = 10e-5;
465− LEAF_error();
466− }
467− */
468− mwf->tempErrDenom = (mwf->r-(mwf->p*mwf->s));
469− /*
470− if ((mwf->tempErrDenom == 0.0) || isinf(mwf->tempErrDenom) || isnan(mwf->tempErrDenom))
471− {
472− mwf->tempErrDenom = 10e-5;
473− LEAF_error();
474− }
475− */
476− mwf->myerr = (mwf->p/mwf->tempErrDenom);
477− /*
478− if (isnan(mwf->myerr) || isinf(mwf->myerr))
479− {
480− mwf->myerr = 10e-5;
481− LEAF_error();
482− }
483− */
484−
485− if ((fabs(mwf->myerr))<mwf->LambertThresh) {
486−
487− break;
488− }
489−
490− mwf->w = mwf->w - mwf->myerr;
491−
492− /*
493− if (isinf(mwf->w) || isnan(mwf->w))
494− {
495− mwf->w = 10e-5;
496− LEAF_error();
497− }
498−*/
499−
500− }
501− return mwf->w;
502−}
503−
504−float tLockhartWavefolder_tick(tLockhartWavefolder* const wf, float in)
505−{
506− _tLockhartWavefolder* w = *wf;
507−
508− float out = 0.0f;
509−
510− // Compute Antiderivative
511− w->l = (in > 0.0) - (in < 0.0);
512− w->u = w->d*exp(w->l*w->b*in);
513− /*
514− if ((w->u == 0.0) || isinf(w->u) || isnan(w->u))
515− {
516− w->u = 10e-5;
517− LEAF_error();
518− }
519− */
520−
521− w->Ln = tLockhartWavefolderLambert(wf,w->u,w->Ln1);
522− /*
523− if ((w->Ln == 0.0) || isinf(w->Ln) || isnan(w->Ln))
524− {
525− w->Ln = 10e-5;
526− LEAF_error();
527− }
528−*/
529− w->Fn = (w->longthing*(w->Ln*(w->Ln + 2.0))) - (w->half_a*in*in);
530− /*
531− if ((w->Fn == 0.0) || isinf(w->Fn) || isnan(w->Fn))
532− {
533− w->Fn = 10e-5;
534− LEAF_error();
535− }
536− */
537− // Check for ill-conditioning
538−
539− if (fabs(in-w->xn1)<w->AAthresh)
540− {
541−
542− // Compute Averaged Wavefolder Output
543− double xn = 0.5*(in+w->xn1);
544− w->u = w->d*exp(w->l*w->b*xn);
545− /*
546− if ((w->u == 0.0) || isinf(w->u) || isnan(w->u))
547− {
548− w->u = 10e-5;
549− LEAF_error();
550−
551− }
552− */
553− w->Ln = tLockhartWavefolderLambert(wf,w->u,w->Ln1);
554− /*
555− if ((w->Ln == 0.0) || isinf(w->Ln) || isnan(w->Ln))
556− {
557− w->Ln = 10e-5;
558− LEAF_error();
559− }
560− */
561− out = (float)((w->l*w->VT*w->Ln) - (w->a*xn));
562−
563− }
564− else
565− {
566−
567− // Apply AA Form
568− w->tempOutDenom = (in-w->xn1);
569− /*
570− if ((w->tempOutDenom == 0.0) || isinf(w->tempOutDenom))
571− {
572− w->tempOutDenom = 10e-5;
573− LEAF_error();
574− }
575− */
576− out = ((w->Fn-w->Fn1)/w->tempOutDenom);
577− /*
578− if (isinf(out) || isnan(out))
579− {
580− out = 10e-5;
581− LEAF_error();
582− }
583− */
584−
585− }
586−
587− // Update States
588− w->Ln1 = w->Ln;
589− w->Fn1 = w->Fn;
590− w->xn1 = (double)in;
591−
592− return out;
593−}
594−
595−//============================================================================================================
596−// CRUSHER
597−//============================================================================================================
598−#define SCALAR 5000.f
599−
600−void tCrusher_init (tCrusher* const cr)
601−{
602− _tCrusher* c = *cr = (_tCrusher*) leaf_alloc(sizeof(_tCrusher));
603−
604− c->op = 4;
605− c->div = SCALAR;
606− c->rnd = 0.25f;
607− c->srr = 0.25f;
608− tSampleReducer_init(&c->sReducer);
609− c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
610−}
611−
612−void tCrusher_free (tCrusher* const cr)
613−{
614− _tCrusher* c = *cr;
615− tSampleReducer_free(&c->sReducer);
616− leaf_free((char*)c);
617−}
618−
619−void tCrusher_initToPool (tCrusher* const cr, tMempool* const mp)
620−{
621− _tMempool* m = *mp;
622− _tCrusher* c = *cr = (_tCrusher*) mpool_alloc(sizeof(_tCrusher), m);
623−
624− c->op = 4;
625− c->div = SCALAR;
626− c->rnd = 0.25f;
627− c->srr = 0.25f;
628− tSampleReducer_initToPool(&c->sReducer, mp);
629− c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
630−}
631−
632−void tCrusher_freeFromPool (tCrusher* const cr, tMempool* const mp)
633−{
634− _tMempool* m = *mp;
635− _tCrusher* c = *cr;
636− tSampleReducer_freeFromPool(&c->sReducer, mp);
637− mpool_free((char*)c, m);
638−}
639−
640−float tCrusher_tick (tCrusher* const cr, float input)
641−{
642− _tCrusher* c = *cr;
643−
644− float sample = input;
645−
646− sample *= SCALAR; // SCALAR is 5000 by default
647−
648− sample = (int32_t) sample;
649−
650− sample /= c->div;
651−
652− sample = LEAF_bitwise_xor(sample, c->op << 23);
653−
654− sample = LEAF_clip(-1.f, sample, 1.f);
655−
656− sample = LEAF_round(sample, c->rnd);
657−
658− sample = tSampleReducer_tick(&c->sReducer, sample);
659−
660− return sample * c->gain;
661−
662−}
663−
664−void tCrusher_setOperation (tCrusher* const cr, float op)
665−{
666− _tCrusher* c = *cr;
667− c->op = (uint32_t) (op * 8.0f);
668−}
669−
670−// 0.0 - 1.0
671−void tCrusher_setQuality (tCrusher* const cr, float val)
672−{
673− _tCrusher* c = *cr;
674−
675− val = LEAF_clip(0.0f, val, 1.0f);
676−
677− c->div = 0.01f + val * SCALAR;
678−
679− c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
680−}
681−
682−// what decimal to round to
683−void tCrusher_setRound (tCrusher* const cr, float rnd)
684−{
685− _tCrusher* c = *cr;
686− c->rnd = fabsf(rnd);
687−}
688−
689−void tCrusher_setSamplingRatio (tCrusher* const cr, float ratio)
690−{
691− _tCrusher* c = *cr;
692− c->srr = ratio;
693− tSampleReducer_setRatio(&c->sReducer, ratio);
694−
695−}
LEAF/Src/leaf-dynamics.c+0−281
@@ -1,281 +0,0 @@
1−/*==============================================================================
2−
3− leaf-dynamics.c
4− Created: 30 Nov 2018 11:56:49am
5− Author: airship
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-dynamics.h"
12−
13−#else
14−
15−#include "../Inc/leaf-dynamics.h"
16−
17−#endif
18−
19−//==============================================================================
20−
21−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Compressor ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
22−
23−/*
24− tCompressor* tCompressorInit(int tauAttack, int tauRelease)
25− {
26− tCompressor* c = &leaf.tCompressorRegistry[leaf.registryIndex[T_COMPRESSOR]++];
27−
28− c->tauAttack = tauAttack;
29− c->tauRelease = tauRelease;
30−
31− c->x_G[0] = 0.0f, c->x_G[1] = 0.0f,
32− c->y_G[0] = 0.0f, c->y_G[1] = 0.0f,
33− c->x_T[0] = 0.0f, c->x_T[1] = 0.0f,
34− c->y_T[0] = 0.0f, c->y_T[1] = 0.0f;
35−
36− c->T = 0.0f; // Threshold
37− c->R = 1.0f; // compression Ratio
38− c->M = 0.0f; // decibel Make-up gain
39− c->W = 0.0f; // decibel Width of knee transition
40−
41− return c;
42− }
43− */
44−void tCompressor_init(tCompressor* const comp)
45−{
46− _tCompressor* c = *comp = (_tCompressor*) leaf_alloc(sizeof(_tCompressor));
47−
48− c->tauAttack = 100;
49− c->tauRelease = 100;
50−
51− c->isActive = OFALSE;
52−
53− c->T = 0.0f; // Threshold
54− c->R = 0.5f; // compression Ratio
55− c->M = 3.0f; // decibel Width of knee transition
56− c->W = 1.0f; // decibel Make-up gain
57−}
58−
59−void tCompressor_free(tCompressor* const comp)
60−{
61− _tCompressor* c = *comp;
62−
63− leaf_free((char*)c);
64−}
65−
66−void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp)
67−{
68− _tMempool* m = *mp;
69− _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m);
70−
71− c->tauAttack = 100;
72− c->tauRelease = 100;
73−
74− c->isActive = OFALSE;
75−
76− c->T = 0.0f; // Threshold
77− c->R = 0.5f; // compression Ratio
78− c->M = 3.0f; // decibel Width of knee transition
79− c->W = 1.0f; // decibel Make-up gain
80−}
81−
82−void tCompressor_freeFromPool(tCompressor* const comp, tMempool* const mp)
83−{
84− _tMempool* m = *mp;
85− _tCompressor* c = *comp;
86−
87− mpool_free((char*)c, m);
88−}
89−
90−float tCompressor_tick(tCompressor* const comp, float in)
91−{
92− _tCompressor* c = *comp;
93−
94− float slope, overshoot;
95− float alphaAtt, alphaRel;
96−
97− float in_db = 20.0f * log10f( fmaxf( fabsf( in), 0.000001f)), out_db = 0.0f;
98−
99− c->y_T[1] = c->y_T[0];
100−
101− slope = c->R - 1.0f; // feed-forward topology; was 1/C->R - 1
102−
103− overshoot = in_db - c->T;
104−
105−
106− if (overshoot <= -(c->W * 0.5f))
107− {
108− out_db = in_db;
109− c->isActive = OFALSE;
110− }
111− else if ((overshoot > -(c->W * 0.5f)) && (overshoot < (c->W * 0.5f)))
112− {
113− out_db = in_db + slope * (powf((overshoot + c->W*0.5f),2) / (2.0f * c->W)); // .^ 2 ???
114− c->isActive = OTRUE;
115− }
116− else if (overshoot >= (c->W * 0.5f))
117− {
118− out_db = in_db + slope * overshoot;
119− c->isActive = OTRUE;
120− }
121−
122−
123−
124− c->x_T[0] = out_db - in_db;
125−
126− alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * leaf.sampleRate));
127− alphaRel = expf(-1.0f/(0.001f * c->tauRelease * leaf.sampleRate));
128−
129− if (c->x_T[0] > c->y_T[1])
130− c->y_T[0] = alphaAtt * c->y_T[1] + (1-alphaAtt) * c->x_T[0];
131− else
132− c->y_T[0] = alphaRel * c->y_T[1] + (1-alphaRel) * c->x_T[0];
133−
134− float attenuation = powf(10.0f, ((c->M - c->y_T[0])/20.0f));
135−
136− return attenuation * in;
137−}
138−
139−/* Feedback Leveler */
140−
141−void tFeedbackLeveler_init(tFeedbackLeveler* const fb, float targetLevel, float factor, float strength, int mode)
142−{
143− _tFeedbackLeveler* p = *fb = (_tFeedbackLeveler*) leaf_alloc(sizeof(_tFeedbackLeveler));
144−
145− p->curr=0.0f;
146− p->targetLevel=targetLevel;
147− tPowerFollower_init(&p->pwrFlw,factor);
148− p->mode=mode;
149− p->strength=strength;
150−}
151−
152−void tFeedbackLeveler_free(tFeedbackLeveler* const fb)
153−{
154− _tFeedbackLeveler* p = *fb;
155−
156− tPowerFollower_free(&p->pwrFlw);
157− leaf_free((char*)p);
158−}
159−
160−void tFeedbackLeveler_initToPool (tFeedbackLeveler* const fb, float targetLevel, float factor, float strength, int mode, tMempool* const mp)
161−{
162− _tMempool* m = *mp;
163− _tFeedbackLeveler* p = *fb = (_tFeedbackLeveler*) mpool_alloc(sizeof(_tFeedbackLeveler), m);
164−
165− p->curr=0.0f;
166− p->targetLevel=targetLevel;
167− tPowerFollower_initToPool(&p->pwrFlw,factor, mp);
168− p->mode=mode;
169− p->strength=strength;
170−}
171−
172−void tFeedbackLeveler_freeFromPool (tFeedbackLeveler* const fb, tMempool* const mp)
173−{
174− _tMempool* m = *mp;
175− _tFeedbackLeveler* p = *fb;
176−
177− tPowerFollower_freeFromPool(&p->pwrFlw, mp);
178− mpool_free((char*)p, m);
179−}
180−
181−void tFeedbackLeveler_setStrength(tFeedbackLeveler* const fb, float strength)
182−{ // strength is how strongly level diff is affecting the amp ratio
183− // try 0.125 for a start
184− _tFeedbackLeveler* p = *fb;
185− p->strength=strength;
186−}
187−
188−void tFeedbackLeveler_setFactor(tFeedbackLeveler* const fb, float factor)
189−{
190− _tFeedbackLeveler* p = *fb;
191− tPowerFollower_setFactor(&p->pwrFlw,factor);
192−}
193−
194−void tFeedbackLeveler_setMode(tFeedbackLeveler* const fb, int mode)
195−{ // 0 for decaying with upwards lev limiting, 1 for constrained absolute level (also downwards limiting)
196− _tFeedbackLeveler* p = *fb;
197− p->mode=mode;
198−}
199−
200−float tFeedbackLeveler_tick(tFeedbackLeveler* const fb, float input)
201−{
202− _tFeedbackLeveler* p = *fb;
203− float levdiff=(tPowerFollower_tick(&p->pwrFlw, input)-p->targetLevel);
204− if (p->mode==0 && levdiff<0.0f) levdiff=0.0f;
205− p->curr=input*(1.0f-p->strength*levdiff);
206− return p->curr;
207−}
208−
209−float tFeedbackLeveler_sample(tFeedbackLeveler* const fb)
210−{
211− _tFeedbackLeveler* p = *fb;
212− return p->curr;
213−}
214−
215−
216−void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const fb, float TargetLevel)
217−{
218− _tFeedbackLeveler* p = *fb;
219− p->targetLevel=TargetLevel;
220−}
221−
222−
223−
224−void tThreshold_init(tThreshold* const th, float low, float high)
225−{
226− tThreshold_initToPool(th, low, high, &leaf.mempool);
227−}
228−
229−void tThreshold_free(tThreshold* const th)
230−{
231− tThreshold_freeFromPool(th, &leaf.mempool);
232−}
233−
234−void tThreshold_initToPool (tThreshold* const th, float low, float high, tMempool* const mp)
235−{
236− _tMempool* m = *mp;
237− _tThreshold* t = *th = (_tThreshold*) mpool_alloc(sizeof(_tThreshold), m);
238−
239− t->highThresh = high;
240− t->lowThresh = low;
241−
242− t->currentValue = 0;
243−}
244−
245−void tThreshold_freeFromPool(tThreshold* const th, tMempool* const mp)
246−{
247− _tMempool* m = *mp;
248− _tThreshold* t = *th;
249−
250− mpool_free((char*)t, m);
251−}
252−
253−int tThreshold_tick(tThreshold* const th, float in)
254−{
255− _tThreshold* t = *th;
256−
257− if (in >= t->highThresh)
258− {
259− t->currentValue = 1;
260− }
261− else if (in <= t->lowThresh)
262− {
263− t->currentValue = 0;
264− }
265−
266− return t->currentValue;
267−}
268−
269−void tThreshold_setLow(tThreshold* const th, float low)
270−{
271− _tThreshold* t = *th;
272−
273− t->lowThresh = low;
274−}
275−
276−void tThreshold_setHigh(tThreshold* const th, float high)
277−{
278− _tThreshold* t = *th;
279−
280− t->highThresh = high;
281−}
LEAF/Src/leaf-effects.c+0−1853
@@ -1,1853 +0,0 @@
1−/*==============================================================================
2−
3− leaf-vocoder.c
4− Created: 20 Jan 2017 12:01:54pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-effects.c"
12−#include "..\leaf.h"
13−
14−#else
15−
16−#include "../Inc/leaf-effects.h"
17−#include "../leaf.h"
18−
19−#endif
20−
21−
22−
23−//============================================================================================================
24−// TALKBOX
25−//============================================================================================================
26−
27−//LPC vocoder adapted from MDA's excellent open source talkbox plugin code
28−void tTalkbox_init(tTalkbox* const voc, int bufsize)
29−{
30−
31− _tTalkbox* v = *voc = (_tTalkbox*) leaf_alloc(sizeof(_tTalkbox));
32−
33− v->param[0] = 0.5f; //wet
34− v->param[1] = 0.0f; //dry
35− v->param[2] = 0; // Swap
36− v->param[3] = 1.0f; //quality
37− v->warpFactor = 0.0f;
38− v->warpOn = 0;
39− v->bufsize = bufsize;
40−
41− v->car0 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
42− v->car1 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
43− v->window = (float*) leaf_alloc(sizeof(float) * v->bufsize);
44− v->buf0 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
45− v->buf1 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
46−
47− tTalkbox_update(voc);
48− tTalkbox_suspend(voc);
49−}
50−
51−void tTalkbox_free(tTalkbox* const voc)
52−{
53− _tTalkbox* v = *voc;
54−
55− leaf_free((char*)v->buf1);
56− leaf_free((char*)v->buf0);
57− leaf_free((char*)v->window);
58− leaf_free((char*)v->car1);
59− leaf_free((char*)v->car0);
60−
61− leaf_free((char*)v);
62−}
63−
64−void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* const mp)
65−{
66− _tMempool* m = *mp;
67− _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m);
68−
69− v->param[0] = 0.5f; //wet
70− v->param[1] = 0.0f; //dry
71− v->param[2] = 0; // Swap
72− v->param[3] = 1.0f; //quality
73− v->warpFactor = 0.0f;
74− v->warpOn = 0;
75− v->bufsize = bufsize;
76−
77− v->car0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
78− v->car1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
79− v->window = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
80− v->buf0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
81− v->buf1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
82−
83− tTalkbox_update(voc);
84− tTalkbox_suspend(voc);
85−}
86−
87−void tTalkbox_freeFromPool (tTalkbox* const voc, tMempool* const mp)
88−{
89− _tMempool* m = *mp;
90− _tTalkbox* v = *voc;
91−
92− mpool_free((char*)v->buf1, m);
93− mpool_free((char*)v->buf0, m);
94− mpool_free((char*)v->window, m);
95− mpool_free((char*)v->car1, m);
96− mpool_free((char*)v->car0, m);
97−
98− mpool_free((char*)v, m);
99−}
100−
101−void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
102−{
103− _tTalkbox* v = *voc;
104−
105− float fs = leaf.sampleRate;
106− if(fs < 8000.0f) fs = 8000.0f;
107− if(fs > 96000.0f) fs = 96000.0f;
108−
109− int32_t n = (int32_t)(0.01633f * fs); //this sets the window time to 16ms if the buffer is large enough. Buffer needs to be at least 784 samples at 48000
110− if(n > v->bufsize) n = v->bufsize;
111−
112− //O = (VstInt32)(0.0005f * fs);
113− v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * fs);
114−
115− if(n != v->N) //recalc hanning window
116− {
117− v->N = n;
118− float dp = TWO_PI / v->N;
119− float p = 0.0f;
120− for(n=0; n<v->N; n++)
121− {
122− v->window[n] = 0.5f - 0.5f * cosf(p);
123− p += dp;
124− }
125− }
126− v->wet = 0.5f * v->param[0] * v->param[0];
127− v->dry = 2.0f * v->param[1] * v->param[1];
128−}
129−
130−void tTalkbox_suspend(tTalkbox* const voc) ///clear any buffers...
131−{
132− _tTalkbox* v = *voc;
133−
134− v->pos = v->K = 0;
135− v->emphasis = 0.0f;
136− v->FX = 0;
137−
138− v->u0 = v->u1 = v->u2 = v->u3 = v->u4 = 0.0f;
139− v->d0 = v->d1 = v->d2 = v->d3 = v->d4 = 0.0f;
140−
141− for (int32_t i = 0; i < v->bufsize; i++)
142− {
143− v->buf0[i] = 0;
144− v->buf1[i] = 0;
145− v->car0[i] = 0;
146− v->car1[i] = 0;
147− }
148−}
149−
150−// warped autocorrelation adapted from ten.enegatum@liam's post on music-dsp 2004-04-07 09:37:51
151−//find the order-P autocorrelation array, R, for the sequence x of length L and warping of lambda
152−//wAutocorrelate(&pfSrc[stIndex],siglen,R,P,0);
153−void tTalkbox_warpedAutocorrelate(float * x, unsigned int L, float * R, unsigned int P, float lambda)
154−{
155− double dl[L];
156− double Rt[L];
157− double r1,r2,r1t;
158− R[0]=0;
159− Rt[0]=0;
160− r1=0;
161− r2=0;
162− r1t=0;
163− for(int32_t k=0; k<L;k++)
164− {
165− Rt[0] += (double)(x[k]) * (double)(x[k]);
166−
167− dl[k]= r1 - (double)(lambda) * (double)(x[k]-r2);
168− r1 = x[k];
169− r2 = dl[k];
170− }
171− for(int32_t i=1; i<=P; i++)
172− {
173− Rt[i]=0;
174− r1=0;
175− r2=0;
176− for(unsigned int k=0; k<L;k++)
177− {
178− Rt[i] += (double) (dl[k]) * (double)(x[k]);
179−
180− r1t = dl[k];
181− dl[k]= r1 - (double)(lambda) * (double)(r1t-r2);
182− r1 = r1t;
183− r2 = dl[k];
184− }
185− }
186− for(int32_t i=0; i<=P; i++)
187− {
188− R[i]=(float)(Rt[i]);
189− }
190−
191−}
192−
193−
194−
195−#define ORD_MAX 35 // Was 100.
196−// order is defined by the set_quality function.
197−// it's set to max out at 0.0005 of sample rate (if you don't go above 1.0f in the quality setting) == at 48000 that's 24.
198−// -JS
199−void tTalkbox_lpc(float *buf, float *car, int32_t n, int32_t o, float warp, int warpOn)
200−{
201− float z[ORD_MAX], r[ORD_MAX], k[ORD_MAX], G, x;
202− int32_t i, j, nn=n;
203−
204− if (warpOn == 0)
205− {
206− for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed
207− {
208− z[j] = r[j] = 0.0f;
209− for(i=0; i<nn; i++) r[j] += buf[i] * buf[i+j]; //autocorrelation
210− }
211− }
212− else
213− {
214− for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed
215− {
216− z[j] = r[j] = 0.0f;
217− }
218− tTalkbox_warpedAutocorrelate(buf, n, r, o, warp);
219− }
220−
221− r[0] *= 1.001f; //stability fix
222−
223− float min = 0.00001f;
224− if(r[0] < min) { for(i=0; i<n; i++) buf[i] = 0.0f; return; }
225−
226− tTalkbox_lpcDurbin(r, o, k, &G); //calc reflection coeffs
227−
228− //this is for stability to keep reflection coefficients inside the unit circle
229− //but in Harma's papers I've seen 0.998. just needs to be less than 1 it seems but maybe some wiggle room to avoid instability from floating point precision -JS
230− for(i=0; i<=o; i++)
231− {
232− if(k[i] > 0.995f) k[i] = 0.995f; else if(k[i] < -0.995f) k[i] = -.995f;
233− }
234−
235− for(i=0; i<n; i++)
236− {
237− x = G * car[i];
238− for(j=o; j>0; j--) //lattice filter
239− {
240− x -= k[j] * z[j-1];
241− z[j] = z[j-1] + k[j] * x;
242− }
243− buf[i] = z[0] = x; //output buf[] will be windowed elsewhere
244− }
245−}
246−
247−
248−void tTalkbox_lpcDurbin(float *r, int p, float *k, float *g)
249−{
250− int i, j;
251− float a[ORD_MAX], at[ORD_MAX], e=r[0];
252−
253− for(i=0; i<=p; i++) a[i] = 0.0f; //probably don't need to clear at[] or k[]
254− at[0] = 0.0f;
255− for(i=1; i<=p; i++)
256− {
257− k[i] = -r[i];
258−
259− for(j=1; j<i; j++)
260− {
261− at[j] = a[j];
262− k[i] -= a[j] * r[i-j];
263− }
264− if(fabs(e) < 1.0e-20f) { e = 0.0f; break; }
265− k[i] /= e;
266−
267− a[i] = k[i];
268− for(j=1; j<i; j++) a[j] = at[j] + k[i] * at[i-j];
269−
270− e *= 1.0f - k[i] * k[i];
271− }
272−
273− if(e < 1.0e-20f) e = 0.0f;
274− *g = sqrtf(e);
275−}
276−
277−float tTalkbox_tick(tTalkbox* const voc, float synth, float voice)
278−{
279− _tTalkbox* v = *voc;
280−
281− int32_t p0=v->pos, p1 = (v->pos + v->N/2) % v->N;
282− float e=v->emphasis, w, o, x, fx=v->FX;
283− float p, q, h0=0.3f, h1=0.77f;
284−
285− o = voice;
286− x = synth;
287−
288−
289−
290− p = v->d0 + h0 * x; v->d0 = v->d1; v->d1 = x - h0 * p;
291− q = v->d2 + h1 * v->d4; v->d2 = v->d3; v->d3 = v->d4 - h1 * q;
292− v->d4 = x;
293− x = p + q;
294−
295− if(v->K++)
296− {
297− v->K = 0;
298−
299− v->car0[p0] = v->car1[p1] = x; //carrier input
300−
301− x = o - e; e = o; //6dB/oct pre-emphasis
302−
303− w = v->window[p0]; fx = v->buf0[p0] * w; v->buf0[p0] = x * w; //50% overlapping hanning windows
304− if(++p0 >= v->N) { tTalkbox_lpc(v->buf0, v->car0, v->N, v->O, v->warpFactor, v->warpOn); p0 = 0; }
305−
306− w = 1.0f - w; fx += v->buf1[p1] * w; v->buf1[p1] = x * w;
307− if(++p1 >= v->N) { tTalkbox_lpc(v->buf1, v->car1, v->N, v->O, v->warpFactor, v->warpOn); p1 = 0; }
308− }
309−
310− p = v->u0 + h0 * fx; v->u0 = v->u1; v->u1 = fx - h0 * p;
311− q = v->u2 + h1 * v->u4; v->u2 = v->u3; v->u3 = v->u4 - h1 * q;
312− v->u4 = fx;
313− x = p + q;
314−
315− o = x;
316−
317− v->emphasis = e;
318− v->pos = p0;
319− v->FX = fx;
320−
321−
322− return o;
323−}
324−
325−void tTalkbox_setQuality(tTalkbox* const voc, float quality)
326−{
327− _tTalkbox* v = *voc;
328−
329− v->param[3] = quality;
330− v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate);
331− if (v->O >= ORD_MAX)
332− {
333− v->O = ORD_MAX-1;
334− }
335−}
336−
337−void tTalkbox_setWarpFactor(tTalkbox* const voc, float warpFactor)
338−{
339− _tTalkbox* v = *voc;
340−
341− v->warpFactor = warpFactor;
342−}
343−
344−void tTalkbox_setWarpOn(tTalkbox* const voc, float warpOn)
345−{
346− _tTalkbox* v = *voc;
347−
348− v->warpOn = warpOn;
349−}
350−
351−
352−//============================================================================================================
353−// VOCODER
354−//============================================================================================================
355−
356−void tVocoder_init (tVocoder* const voc)
357−{
358− _tVocoder* v = *voc = (_tVocoder*) leaf_alloc(sizeof(_tVocoder));
359−
360− v->param[0] = 0.33f; //input select
361− v->param[1] = 0.50f; //output dB
362− v->param[2] = 0.40f; //hi thru
363− v->param[3] = 0.40f; //hi band
364− v->param[4] = 0.16f; //envelope
365− v->param[5] = 0.55f; //filter q
366− v->param[6] = 0.6667f;//freq range
367− v->param[7] = 0.33f; //num bands
368−
369− tVocoder_update(voc);
370−}
371−
372−void tVocoder_free (tVocoder* const voc)
373−{
374− _tVocoder* v = *voc;
375−
376− leaf_free((char*)v);
377−}
378−
379−void tVocoder_initToPool (tVocoder* const voc, tMempool* const mp)
380−{
381− _tMempool* m = *mp;
382− _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m);
383−
384− v->param[0] = 0.33f; //input select
385− v->param[1] = 0.50f; //output dB
386− v->param[2] = 0.40f; //hi thru
387− v->param[3] = 0.40f; //hi band
388− v->param[4] = 0.16f; //envelope
389− v->param[5] = 0.55f; //filter q
390− v->param[6] = 0.6667f;//freq range
391− v->param[7] = 0.33f; //num bands
392−
393− tVocoder_update(voc);
394−}
395−
396−void tVocoder_freeFromPool (tVocoder* const voc, tMempool* const mp)
397−{
398− _tMempool* m = *mp;
399− _tVocoder* v = *voc;
400−
401− mpool_free((char*)v, m);
402−}
403−
404−void tVocoder_update (tVocoder* const voc)
405−{
406− _tVocoder* v = *voc;
407−
408− float tpofs = 6.2831853f * leaf.invSampleRate;
409−
410− float rr, th, re;
411−
412− float sh;
413−
414− int32_t i;
415−
416− v->gain = (float)pow(10.0f, 2.0f * v->param[1] - 3.0f * v->param[5] - 2.0f);
417−
418− v->thru = (float)pow(10.0f, 0.5f + 2.0f * v->param[1]);
419− v->high = v->param[3] * v->param[3] * v->param[3] * v->thru;
420− v->thru *= v->param[2] * v->param[2] * v->param[2];
421−
422− if(v->param[7]<0.5f)
423− {
424− v->nbnd=8;
425− re=0.003f;
426− v->f[1][2] = 3000.0f;
427− v->f[2][2] = 2200.0f;
428− v->f[3][2] = 1500.0f;
429− v->f[4][2] = 1080.0f;
430− v->f[5][2] = 700.0f;
431− v->f[6][2] = 390.0f;
432− v->f[7][2] = 190.0f;
433− }
434− else
435− {
436− v->nbnd=16;
437− re=0.0015f;
438− v->f[ 1][2] = 5000.0f; //+1000
439− v->f[ 2][2] = 4000.0f; //+750
440− v->f[ 3][2] = 3250.0f; //+500
441− v->f[ 4][2] = 2750.0f; //+450
442− v->f[ 5][2] = 2300.0f; //+300
443− v->f[ 6][2] = 2000.0f; //+250
444− v->f[ 7][2] = 1750.0f; //+250
445− v->f[ 8][2] = 1500.0f; //+250
446− v->f[ 9][2] = 1250.0f; //+250
447− v->f[10][2] = 1000.0f; //+250
448− v->f[11][2] = 750.0f; //+210
449− v->f[12][2] = 540.0f; //+190
450− v->f[13][2] = 350.0f; //+155
451− v->f[14][2] = 195.0f; //+100
452− v->f[15][2] = 95.0f;
453− }
454−
455− if(v->param[4]<0.05f) //freeze
456− {
457− for(i=0;i<v->nbnd;i++) v->f[i][12]=0.0f;
458− }
459− else
460− {
461− v->f[0][12] = (float)pow(10.0, -1.7 - 2.7f * v->param[4]); //envelope speed
462−
463− rr = 0.022f / (float)v->nbnd; //minimum proportional to frequency to stop distortion
464− for(i=1;i<v->nbnd;i++)
465− {
466− v->f[i][12] = (float)(0.025 - rr * (double)i);
467− if(v->f[0][12] < v->f[i][12]) v->f[i][12] = v->f[0][12];
468− }
469− v->f[0][12] = 0.5f * v->f[0][12]; //only top band is at full rate
470− }
471−
472− rr = 1.0 - pow(10.0f, -1.0f - 1.2f * v->param[5]);
473− sh = (float)pow(2.0f, 3.0f * v->param[6] - 1.0f); //filter bank range shift
474−
475− for(i=1;i<v->nbnd;i++)
476− {
477− v->f[i][2] *= sh;
478− th = acos((2.0 * rr * cos(tpofs * v->f[i][2])) / (1.0 + rr * rr));
479− v->f[i][0] = (float)(2.0 * rr * cos(th)); //a0
480− v->f[i][1] = (float)(-rr * rr); //a1
481− //was .98
482− v->f[i][2] *= 0.96f; //shift 2nd stage slightly to stop high resonance peaks
483− th = acos((2.0 * rr * cos(tpofs * v->f[i][2])) / (1.0 + rr * rr));
484− v->f[i][2] = (float)(2.0 * rr * cos(th));
485− }
486−}
487−
488−float tVocoder_tick (tVocoder* const voc, float synth, float voice)
489−{
490− _tVocoder* v = *voc;
491−
492− float a, b, o=0.0f, aa, bb, oo = v->kout, g = v->gain, ht = v->thru, hh = v->high, tmp;
493− uint32_t i, k = v->kval, nb = v->nbnd;
494−
495− a = voice; //speech
496− b = synth; //synth
497−
498− tmp = a - v->f[0][7]; //integrate modulator for HF band and filter bank pre-emphasis
499− v->f[0][7] = a;
500− a = tmp;
501−
502− if(tmp<0.0f) tmp = -tmp;
503− v->f[0][11] -= v->f[0][12] * (v->f[0][11] - tmp); //high band envelope
504− o = v->f[0][11] * (ht * a + hh * (b - v->f[0][3])); //high band + high thru
505−
506− v->f[0][3] = b; //integrate carrier for HF band
507−
508− if(++k & 0x1) //this block runs at half sample rate
509− {
510− oo = 0.0f;
511− aa = a + v->f[0][9] - v->f[0][8] - v->f[0][8]; //apply zeros here instead of in each reson
512− v->f[0][9] = v->f[0][8]; v->f[0][8] = a;
513− bb = b + v->f[0][5] - v->f[0][4] - v->f[0][4];
514− v->f[0][5] = v->f[0][4]; v->f[0][4] = b;
515−
516− for(i=1; i<nb; i++) //filter bank: 4th-order band pass
517− {
518− tmp = v->f[i][0] * v->f[i][3] + v->f[i][1] * v->f[i][4] + bb;
519− v->f[i][4] = v->f[i][3];
520− v->f[i][3] = tmp;
521− tmp += v->f[i][2] * v->f[i][5] + v->f[i][1] * v->f[i][6];
522− v->f[i][6] = v->f[i][5];
523− v->f[i][5] = tmp;
524−
525− tmp = v->f[i][0] * v->f[i][7] + v->f[i][1] * v->f[i][8] + aa;
526− v->f[i][8] = v->f[i][7];
527− v->f[i][7] = tmp;
528− tmp += v->f[i][2] * v->f[i][9] + v->f[i][1] * v->f[i][10];
529− v->f[i][10] = v->f[i][9];
530− v->f[i][9] = tmp;
531−
532− if(tmp<0.0f) tmp = -tmp;
533− v->f[i][11] -= v->f[i][12] * (v->f[i][11] - tmp);
534− oo += v->f[i][5] * v->f[i][11];
535− }
536− }
537− o += oo * g; //effect of interpolating back up to Fs would be minimal (aliasing >16kHz)
538−
539− v->kout = oo;
540− v->kval = k & 0x1;
541− if(fabs(v->f[0][11])<1.0e-10) v->f[0][11] = 0.0f; //catch HF envelope denormal
542−
543− for(i=1;i<nb;i++)
544− if(fabs(v->f[i][3])<1.0e-10 || fabs(v->f[i][7])<1.0e-10)
545− for(k=3; k<12; k++) v->f[i][k] = 0.0f; //catch reson & envelope denormals
546−
547− if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability
548−
549− return o;
550−
551−}
552−
553−void tVocoder_suspend (tVocoder* const voc)
554−{
555− _tVocoder* v = *voc;
556−
557− int32_t i, j;
558−
559− for(i=0; i<v->nbnd; i++) for(j=3; j<12; j++) v->f[i][j] = 0.0f; //zero band filters and envelopes
560− v->kout = 0.0f;
561− v->kval = 0;
562−}
563−
564−
565−
566−/// Glottal Pulse (Rosenberg model)
567−
568−void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const gp)
569−{
570− tRosenbergGlottalPulse_initToPool(gp, &leaf.mempool);
571−}
572−void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const gp)
573−{
574− tRosenbergGlottalPulse_freeFromPool(gp, &leaf.mempool);
575−}
576−void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const gp, tMempool* const mp)
577−{
578−
579− _tMempool* m = *mp;
580− _tRosenbergGlottalPulse* g = *gp = (_tRosenbergGlottalPulse*) mpool_alloc(sizeof(_tRosenbergGlottalPulse), m);
581−
582− g->phase = 0.0f;
583− g->openLength = 0.0f;
584− g->pulseLength = 0.0f;
585− g->freq = 0.0f;
586− g->inc = 0.0f;
587−
588−
589−}
590−void tRosenbergGlottalPulse_freeFromPool (tRosenbergGlottalPulse* const gp, tMempool* const mp)
591−{
592− _tMempool* m = *mp;
593− _tRosenbergGlottalPulse* g = *gp;
594− mpool_free((char*)g, m);
595−}
596−
597−float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const gp)
598−{
599− _tRosenbergGlottalPulse* g = *gp;
600−
601− float output = 0.0f;
602−
603− // Phasor increment
604− g->phase += g->inc;
605− while (g->phase >= 1.0f) g->phase -= 1.0f;
606− while (g->phase < 0.0f) g->phase += 1.0f;
607−
608− if (g->phase < g->openLength)
609− {
610− output = 0.5f*(1.0f-cosf(PI * g->phase));
611− }
612−
613− else if (g->phase < g->pulseLength)
614− {
615− output = cosf(HALF_PI * (g->phase-g->openLength)/(g->pulseLength-g->openLength));
616− }
617−
618− else
619− {
620− output = 0.0f;
621− }
622− return output;
623−}
624−
625−void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const gp, float freq)
626−{
627− _tRosenbergGlottalPulse* g = *gp;
628− g->freq = freq;
629− g->inc = freq * leaf.invSampleRate;
630−}
631−
632−void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const gp, float openLength)
633−{
634− _tRosenbergGlottalPulse* g = *gp;
635− g->openLength = openLength;
636−}
637−
638−void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const gp, float pulseLength)
639−{
640− _tRosenbergGlottalPulse* g = *gp;
641− g->pulseLength = pulseLength;
642−}
643−
644−
645−
646−
647−//============================================================================================================
648−// SOLAD
649−//============================================================================================================
650−/******************************************************************************/
651−/***************** static function declarations *******************************/
652−/******************************************************************************/
653−
654−static void solad_init(_tSOLAD *w);
655−static inline float read_sample(_tSOLAD *w, float floatindex);
656−static void pitchdown(_tSOLAD *w, float *out);
657−static void pitchup(_tSOLAD *w, float *out);
658−
659−/******************************************************************************/
660−/***************** public access functions ************************************/
661−/******************************************************************************/
662−
663−// init
664−void tSOLAD_init(tSOLAD* const wp)
665−{
666− _tSOLAD* w = *wp = (_tSOLAD*) leaf_calloc(sizeof(_tSOLAD));
667−
668− w->pitchfactor = 1.;
669− w->delaybuf = (float*) leaf_calloc(sizeof(float) * (LOOPSIZE+16));
670−
671− solad_init(w);
672−}
673−
674−void tSOLAD_free(tSOLAD* const wp)
675−{
676− _tSOLAD* w = *wp;
677−
678− leaf_free((char*)w->delaybuf);
679− leaf_free((char*)w);
680−}
681−
682−void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)
683−{
684− _tMempool* m = *mp;
685−
686− _tSOLAD* w = *wp = (_tSOLAD*) mpool_calloc(sizeof(_tSOLAD), m);
687−
688− w->pitchfactor = 1.;
689− w->delaybuf = (float*) mpool_calloc(sizeof(float) * (LOOPSIZE+16), m);
690−
691− solad_init(w);
692−}
693−
694−void tSOLAD_freeFromPool (tSOLAD* const wp, tMempool* const mp)
695−{
696− _tMempool* m = *mp;
697− _tSOLAD* w = *wp;
698−
699− mpool_free((char*)w->delaybuf, m);
700− mpool_free((char*)w, m);
701−}
702−
703−// send one block of input samples, receive one block of output samples
704−void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize)
705−{
706− _tSOLAD* w = *wp;
707−
708− int i = w->timeindex;
709− int n = w->blocksize = blocksize;
710−
711− if(!i) w->delaybuf[LOOPSIZE] = in[0]; // copy one sample for interpolation
712− while(n--) w->delaybuf[i++] = *in++; // copy one input block to delay buffer
713−
714− if(w->pitchfactor > 1) pitchup(w, out);
715− else pitchdown(w, out);
716−
717− w->timeindex += blocksize;
718− w->timeindex &= LOOPMASK;
719−}
720−
721−// set periodicity analysis data
722−void tSOLAD_setPeriod(tSOLAD* const wp, float period)
723−{
724− _tSOLAD* w = *wp;
725−
726− if(period > MAXPERIOD) period = MAXPERIOD;
727− if(period > MINPERIOD) w->period = period; // ignore period when too small
728−}
729−
730−// set pitch factor between 0.25 and 4
731−void tSOLAD_setPitchFactor(tSOLAD* const wp, float pitchfactor)
732−{
733− _tSOLAD* w = *wp;
734−
735− if (pitchfactor <= 0.0f) return;
736− w->pitchfactor = pitchfactor;
737−}
738−
739−// force readpointer lag
740−void tSOLAD_setReadLag(tSOLAD* const wp, float readlag)
741−{
742− _tSOLAD* w = *wp;
743−
744− if(readlag < 0) readlag = 0;
745− if(readlag < w->readlag) // do not jump backward, only forward
746− {
747− w->jump = w->readlag - readlag;
748− w->readlag = readlag;
749− w->xfadelength = readlag;
750− w->xfadevalue = 1;
751− }
752−}
753−
754−// reset state variables
755−void tSOLAD_resetState(tSOLAD* const wp)
756−{
757− _tSOLAD* w = *wp;
758−
759− int n = LOOPSIZE + 1;
760− float *buf = w->delaybuf;
761−
762− while(n--) *buf++ = 0;
763− solad_init(w);
764−}
765−
766−/******************************************************************************/
767−/******************** private procedures **************************************/
768−/******************************************************************************/
769−
770−/*
771− Function pitchdown() is called to read samples from the delay buffer when pitch
772− factor is between 0.25 and 1. The read pointer lags behind because of the slowed
773− down speed, and it must jump forward towards the write pointer soon as there is
774− sufficient space to jump. That is, if there is at least one period of the input
775− signal between read pointer and write pointer. When short periods follow up on
776− long periods, the read pointer may have space to jump over more than one period
777− lenghts. Jump length must be [periodlength ^ 2] in any case.
778−
779− A linear crossfade function joins the jump-from point with the jump-to point.
780− The crossfade must be completed before another read pointer jump is allowed.
781− Length of the crossfade function is stored as a number of samples in terms of
782− the input sample rate. This length is dynamically translated
783− to a crossfade length expressed in output reading rate, according to pitch
784− factor which can change before the crossfade is completed. Crossfade length does
785− not cover an invariable length in periods for all pitch transposition factors.
786− For pitch factors from 0.5 till 1, crossfade length is stretched in the
787− output just as much as the signal itself, as crossfade speed is set to equal
788− pitch factor. For pitch factors below 0.5, the read pointer wants to jump
789− forward before one period is read, therefore the crossfade length as expressed
790− in output periods must be shorter. Crossfade speed is set to [1 - pitchfactor]
791− for those cases. Pitch factor 0.5 is the natural switch point between crossfade
792− speeds [pitchfactor] and [1 - pitchfactor] because 0.5 == 1 - 0.5. The crossfade
793− speed modification for pitch factors below 0.5 also means that much of the
794− original signal content will be skipped.
795− */
796−
797−
798−static void pitchdown(_tSOLAD* const w, float *out)
799−{
800− int n = w->blocksize;
801− float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values!
802− float pitchfactor = w->pitchfactor;
803− float period = w->period;
804− float readlag = w->readlag;
805− float readlagstep = 1 - pitchfactor;
806− float jump = w->jump;
807− float xfadevalue = w->xfadevalue;
808− float xfadelength = w->xfadelength;
809− float xfadespeed, xfadestep, readindex, outputsample;
810−
811− if(pitchfactor > 0.5) xfadespeed = pitchfactor;
812− else xfadespeed = 1 - pitchfactor;
813− xfadestep = xfadespeed / xfadelength;
814−
815− while(n--)
816− {
817− if(readlag > period) // check if read pointer may jump forward...
818− {
819− if(xfadevalue <= 0) // ...but do not interrupt crossfade
820− {
821− jump = period; // jump forward
822− while((jump * 2) < readlag) jump *= 2; // use available space
823− readlag -= jump; // reduce read pointer lag
824− xfadevalue = 1; // start crossfade
825− xfadelength = period - 1;
826− xfadestep = xfadespeed / xfadelength;
827− }
828− }
829−
830− readindex = refindex - readlag;
831− outputsample = read_sample(w, readindex);
832−
833− if(xfadevalue > 0)
834− {
835− outputsample *= (1 - xfadevalue); // fadein
836− outputsample += read_sample(w, readindex - jump) * xfadevalue; // fadeout
837− xfadevalue -= xfadestep;
838− }
839−
840− *out++ = outputsample;
841− refindex += 1;
842− readlag += readlagstep;
843− }
844−
845− w->jump = jump; // state variables
846− w->readlag = readlag;
847− w->xfadevalue = xfadevalue;
848− w->xfadelength = xfadelength;
849−}
850−
851−
852−/*
853− Function pitchup() for pitch factors above 1 is more complicated than
854− pitchdown(). The read pointer increments faster than the write pointer and a
855− backward jump must happen in time, reckoning with the crossfade region. The read
856− pointer backward jump length is always one period. In order to minimize the area
857− of signal duplicates, crossfade length is aimed at [period / pitchfactor].
858− This leads to a crossfade speed of [pitchfactor * pitchfactor].
859−
860− Some samples for the fade out (but not all of them) must already be in the
861− buffer, otherwise we will run out of input samples before the crossfade is
862− completed. The ratio of past samples and future samples for a crossfade of any
863− length is as follows:
864−
865− past samples: xfadelength * (1 - 1 / pitchfactor)
866− future samples: xfadelength * (1 / pitchfactor)
867−
868− For example in the case of pitch factor 1.5 this would be:
869−
870− past samples: xfadelength * (1 - 1 / 1.5) = xfadelength * 1 / 3
871− future samples: xfadelength * (1 / 1.5) = xfadelength * 2 / 3
872−
873− In the case of pitch factor 4 this would be:
874−
875− past samples: xfadelength * (1 - 1 / 4) = xfadelength * 3 / 4
876− future samples: xfadelength * (1 / 4) = xfadelength * 1 / 4
877−
878− The read pointer lag must therefore preserve a minimum dependent on pitch
879− factor. The minimum is called 'limit' here:
880−
881− limit = period * (pitchfactor - 1) / pitchfactor * pitchfactor
882−
883− Components of this expression are combined to reuse them in operations, while
884− (pitchfactor - 1) is changed to (pitchfactor - 0.99) to avoid numerical
885− resolution issues for pitch factors slightly above 1:
886−
887− xfadespeed = pitchfactor * pitchfactor
888− limitfactor = (pitchfactor - 0.99) / xfadespeed
889− limit = period * limitfactor
890−
891− When read lag is smaller than this limit, the read pointer must preferably
892− jump backward, unless a previous crossfade is not yet completed. Crossfades must
893− preferably be completed, unless the read pointer lag becomes smaller than zero.
894− With fluctuating period lengths and pitch factors, the readpointer lag limit may
895− change from one input block to the next in such a way that the actual lag is
896− suddenly much smaller than the limit, and the intended crossfade length can not
897− be applied. Therefore the crossfade length is simply calculated from the
898− available amount of samples for all cases, like so:
899−
900− xfadelength = readlag / limitfactor
901−
902− For most occurrences, this will amount to a crossfade length reduced to
903− [period / pitchfactor] in the output for pitch factors above 1, while in some
904− cases it will be considerably shorter. Fortunately, an incidental aberration of
905− the intended crossfade length hardly ever creates an audible artifact. The
906− reason to specify preferred crossfade length according to pitch factor is to
907− minimize the impression of echoes without sacrificing too much of the signal
908− content. The readpointer jump length remains one period in any case.
909−
910− Sometimes, the input signal periodicity may decrease substantially between one
911− signal block and the next. In such cases it may be possible for the read pointer
912− to jump forward and reduce latency. For every signal block, a check on this
913− possibility is done. A previous crossfade must be completed before a forward
914− jump is allowed.
915− */
916−static void pitchup(_tSOLAD* const w, float *out)
917−{
918− int n = w->blocksize;
919− float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values
920− float pitchfactor = w->pitchfactor;
921− float period = w->period;
922− float readlag = w->readlag;
923− float jump = w->jump;
924− float xfadevalue = w->xfadevalue;
925− float xfadelength = w->xfadelength;
926−
927− float readlagstep = pitchfactor - 1;
928− float xfadespeed = pitchfactor * pitchfactor;
929− float xfadestep = xfadespeed / xfadelength;
930− float limitfactor = (pitchfactor - (float)0.99) / xfadespeed;
931− float limit = period * limitfactor;
932− float readindex, outputsample;
933−
934− if((readlag > (period + 2 * limit)) & (xfadevalue < 0))
935− {
936− jump = period; // jump forward
937− while((jump * 2) < (readlag - 2 * limit)) jump *= 2; // use available space
938− readlag -= jump; // reduce read pointer lag
939− xfadevalue = 1; // start crossfade
940− xfadelength = period - 1;
941− xfadestep = xfadespeed / xfadelength;
942− }
943−
944− while(n--)
945− {
946− if(readlag < limit) // check if read pointer should jump backward...
947− {
948− if((xfadevalue < 0) | (readlag < 0)) // ...but try not to interrupt crossfade
949− {
950− xfadelength = readlag / limitfactor;
951− if(xfadelength < 1) xfadelength = 1;
952− xfadestep = xfadespeed / xfadelength;
953−
954− jump = -period; // jump backward
955− readlag += period; // increase read pointer lag
956− xfadevalue = 1; // start crossfade
957− }
958− }
959−
960− readindex = refindex - readlag;
961− outputsample = read_sample(w, readindex);
962−
963− if(xfadevalue > 0)
964− {
965− outputsample *= (1 - xfadevalue);
966− outputsample += read_sample(w, readindex - jump) * xfadevalue;
967− xfadevalue -= xfadestep;
968− }
969−
970− *out++ = outputsample;
971− refindex += 1;
972− readlag -= readlagstep;
973− }
974−
975− w->readlag = readlag; // state variables
976− w->jump = jump;
977− w->xfadelength = xfadelength;
978− w->xfadevalue = xfadevalue;
979−}
980−
981−// read one sample from delay buffer, with linear interpolation
982−static inline float read_sample(_tSOLAD* const w, float floatindex)
983−{
984− int index = (int)floatindex;
985− float fraction = floatindex - (float)index;
986− float *buf = w->delaybuf;
987− index &= LOOPMASK;
988−
989− return (buf[index] + (fraction * (buf[index+1] - buf[index])));
990−}
991−
992−static void solad_init(_tSOLAD* const w)
993−{
994− w->timeindex = 0;
995− w->xfadevalue = -1;
996− w->period = INITPERIOD;
997− w->readlag = INITPERIOD;
998− w->blocksize = INITPERIOD;
999−}
1000−
1001−//============================================================================================================
1002−// PITCHSHIFT
1003−//============================================================================================================
1004−
1005−static int pitchshift_attackdetect(_tPitchShift* ps)
1006−{
1007− float envout;
1008−
1009− _tPeriodDetection* p = *ps->p;
1010−
1011− envout = tEnvPD_tick(&p->env);
1012−
1013− if (envout >= 1.0f)
1014− {
1015− p->lastmax = p->max;
1016− if (envout > p->max)
1017− {
1018− p->max = envout;
1019− }
1020− else
1021− {
1022− p->deltamax = envout - p->max;
1023− p->max = p->max * ps->radius;
1024− }
1025− p->deltamax = p->max - p->lastmax;
1026− }
1027−
1028− p->fba = p->fba ? (p->fba - 1) : 0;
1029−
1030− return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
1031−}
1032−
1033−void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* pd, float* out, int bufSize)
1034−{
1035− _tPitchShift* ps = *psr = (_tPitchShift*) leaf_calloc(sizeof(_tPitchShift));
1036− _tPeriodDetection* p = *pd;
1037−
1038− ps->p = pd;
1039−
1040− ps->outBuffer = out;
1041− ps->bufSize = bufSize;
1042− ps->frameSize = p->frameSize;
1043− ps->framesPerBuffer = ps->bufSize / ps->frameSize;
1044− ps->curBlock = 1;
1045− ps->lastBlock = 0;
1046− ps->index = 0;
1047− ps->pitchFactor = 1.0f;
1048−
1049− tSOLAD_init(&ps->sola);
1050−
1051− tHighpass_init(&ps->hp, HPFREQ);
1052−
1053− tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
1054−}
1055−
1056−void tPitchShift_free(tPitchShift* const psr)
1057−{
1058− _tPitchShift* ps = *psr;
1059−
1060− tSOLAD_free(&ps->sola);
1061− tHighpass_free(&ps->hp);
1062− leaf_free((char*)ps);
1063−}
1064−
1065−void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)
1066−{
1067− _tMempool* m = *mp;
1068−
1069− _tPitchShift* ps = *psr = (_tPitchShift*) mpool_calloc(sizeof(_tPitchShift), m);
1070−
1071− _tPeriodDetection* p = *pd;
1072−
1073− ps->p = pd;
1074−
1075− ps->outBuffer = out;
1076− ps->bufSize = bufSize;
1077− ps->frameSize = p->frameSize;
1078− ps->framesPerBuffer = ps->bufSize / ps->frameSize;
1079− ps->curBlock = 1;
1080− ps->lastBlock = 0;
1081− ps->index = 0;
1082− ps->pitchFactor = 1.0f;
1083−
1084− tSOLAD_initToPool(&ps->sola, mp);
1085−
1086− tHighpass_initToPool(&ps->hp, HPFREQ, mp);
1087−
1088− tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
1089−}
1090−
1091−void tPitchShift_freeFromPool (tPitchShift* const psr, tMempool* const mp)
1092−{
1093− _tMempool* m = *mp;
1094− _tPitchShift* ps = *psr;
1095−
1096− tSOLAD_freeFromPool(&ps->sola, mp);
1097− tHighpass_freeFromPool(&ps->hp, mp);
1098− mpool_free((char*)ps, m);
1099−}
1100−
1101−void tPitchShift_setPitchFactor(tPitchShift* psr, float pf)
1102−{
1103− _tPitchShift* ps = *psr;
1104−
1105− ps->pitchFactor = pf;
1106−}
1107−
1108−float tPitchShift_shift (tPitchShift* psr)
1109−{
1110− _tPitchShift* ps = *psr;
1111− _tPeriodDetection* p = *ps->p;
1112−
1113− float period, out;
1114− int i, iLast;
1115−
1116− i = p->i;
1117− iLast = p->iLast;
1118−
1119− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
1120−
1121− if (p->indexstore >= ps->frameSize)
1122− {
1123− period = tPeriodDetection_getPeriod(&p);
1124−
1125− if(pitchshift_attackdetect(ps) == 1)
1126− {
1127− p->fba = 5;
1128− tSOLAD_setReadLag(&ps->sola, p->windowSize);
1129− }
1130−
1131− tSOLAD_setPeriod(&ps->sola, period);
1132− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
1133−
1134− tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
1135− }
1136−
1137− return out;
1138−}
1139−
1140−float tPitchShift_shiftToFreq (tPitchShift* psr, float freq)
1141−{
1142− _tPitchShift* ps = *psr;
1143− _tPeriodDetection* p = *ps->p;
1144−
1145− float period, out;
1146− int i, iLast;
1147−
1148− i = p->i;
1149− iLast = p->iLast;
1150−
1151− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
1152−
1153− if (p->indexstore >= ps->frameSize)
1154− {
1155− period = tPeriodDetection_getPeriod(&p);
1156−
1157− if(pitchshift_attackdetect(ps) == 1)
1158− {
1159− p->fba = 5;
1160− tSOLAD_setReadLag(&ps->sola, p->windowSize);
1161− }
1162−
1163− tSOLAD_setPeriod(&ps->sola, period);
1164−
1165− if (period != 0) ps->pitchFactor = period*freq*leaf.invSampleRate;
1166− else ps->pitchFactor = 1.0f;
1167−
1168− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
1169−
1170− tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
1171− }
1172− return out;
1173−}
1174−
1175−float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float))
1176−{
1177− _tPitchShift* ps = *psr;
1178− _tPeriodDetection* p = *ps->p;
1179−
1180− float period, out;
1181− int i, iLast;
1182−
1183− i = p->i;
1184− iLast = p->iLast;
1185−
1186− out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
1187−
1188− if (p->indexstore >= ps->frameSize)
1189− {
1190− period = tPeriodDetection_getPeriod(&p);
1191−
1192− if(pitchshift_attackdetect(ps) == 1)
1193− {
1194− p->fba = 5;
1195− tSOLAD_setReadLag(&ps->sola, p->windowSize);
1196− }
1197−
1198− tSOLAD_setPeriod(&ps->sola, period);
1199−
1200− ps->pitchFactor = period/fun(period);
1201− tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
1202−
1203− tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
1204−
1205− ps->curBlock++;
1206− if (ps->curBlock >= p->framesPerBuffer) ps->curBlock = 0;
1207− ps->lastBlock++;
1208− if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
1209− }
1210−
1211− return out;
1212−}
1213−
1214−//============================================================================================================
1215−// RETUNE
1216−//============================================================================================================
1217−
1218−void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)
1219−{
1220− tRetune_initToPool(rt, numVoices, bufSize, frameSize, &leaf.mempool);
1221−}
1222−
1223−void tRetune_free(tRetune* const rt)
1224−{
1225− tRetune_freeFromPool(rt, &leaf.mempool);
1226−}
1227−
1228−void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
1229−{
1230− _tMempool* m = *mp;
1231− _tRetune* r = *rt = (_tRetune*) mpool_alloc(sizeof(_tRetune), m);
1232−
1233− r->bufSize = bufSize;
1234− r->frameSize = frameSize;
1235− r->numVoices = numVoices;
1236−
1237− r->inBuffer = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
1238− r->outBuffers = (float**) mpool_calloc(sizeof(float*) * r->numVoices, m);
1239−
1240− r->hopSize = DEFHOPSIZE;
1241− r->windowSize = DEFWINDOWSIZE;
1242− r->fba = FBA;
1243− tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
1244−
1245− r->inputPeriod = 0.0f;
1246−
1247− r->ps = (tPitchShift*) mpool_calloc(sizeof(tPitchShift) * r->numVoices, m);
1248− r->pitchFactor = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
1249− r->tickOutput = (float*) mpool_calloc(sizeof(float) * r->numVoices, m);
1250− for (int i = 0; i < r->numVoices; ++i)
1251− {
1252− r->outBuffers[i] = (float*) mpool_calloc(sizeof(float) * r->bufSize, m);
1253− }
1254−
1255− tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1256−
1257− for (int i = 0; i < r->numVoices; ++i)
1258− {
1259− tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
1260− }
1261−}
1262−
1263−void tRetune_freeFromPool (tRetune* const rt, tMempool* const mp)
1264−{
1265− _tMempool* m = *mp;
1266− _tRetune* r = *rt;
1267−
1268− tPeriodDetection_freeFromPool(&r->pd, mp);
1269− for (int i = 0; i < r->numVoices; ++i)
1270− {
1271− tPitchShift_freeFromPool(&r->ps[i], mp);
1272− mpool_free((char*)r->outBuffers[i], m);
1273− }
1274− mpool_free((char*)r->tickOutput, m);
1275− mpool_free((char*)r->pitchFactor, m);
1276− mpool_free((char*)r->ps, m);
1277− mpool_free((char*)r->inBuffer, m);
1278− mpool_free((char*)r->outBuffers, m);
1279− mpool_free((char*)r, m);
1280−}
1281−
1282−float* tRetune_tick(tRetune* const rt, float sample)
1283−{
1284− _tRetune* r = *rt;
1285−
1286− r->inputPeriod = tPeriodDetection_tick(&r->pd, sample);
1287−
1288− for (int v = 0; v < r->numVoices; ++v)
1289− {
1290− r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
1291− }
1292−
1293− return r->tickOutput;
1294−}
1295−
1296−void tRetune_setNumVoices(tRetune* const rt, int numVoices)
1297−{
1298− _tRetune* r = *rt;
1299−
1300− for (int i = 0; i < r->numVoices; ++i)
1301− {
1302− tPitchShift_free(&r->ps[i]);
1303− leaf_free((char*)r->outBuffers[i]);
1304− }
1305− leaf_free((char*)r->tickOutput);
1306− leaf_free((char*)r->pitchFactor);
1307− leaf_free((char*)r->ps);
1308− leaf_free((char*)r->outBuffers);
1309−
1310− r->numVoices = numVoices;
1311−
1312− r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
1313− r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
1314− r->pitchFactor = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1315− r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1316− for (int i = 0; i < r->numVoices; ++i)
1317− {
1318− r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
1319− tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
1320− }
1321−}
1322−
1323−void tRetune_setPitchFactors(tRetune* const rt, float pf)
1324−{
1325− _tRetune* r = *rt;
1326−
1327− for (int i = 0; i < r->numVoices; ++i)
1328− {
1329− r->pitchFactor[i] = pf;
1330− tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
1331− }
1332−}
1333−
1334−void tRetune_setPitchFactor(tRetune* const rt, float pf, int voice)
1335−{
1336− _tRetune* r = *rt;
1337−
1338− r->pitchFactor[voice] = pf;
1339− tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
1340−}
1341−
1342−void tRetune_setTimeConstant(tRetune* const rt, float tc)
1343−{
1344− _tRetune* r = *rt;
1345−
1346− r->timeConstant = tc;
1347− r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
1348−}
1349−
1350−void tRetune_setHopSize(tRetune* const rt, int hs)
1351−{
1352− _tRetune* r = *rt;
1353−
1354− r->hopSize = hs;
1355− tPeriodDetection_setHopSize(&r->pd, r->hopSize);
1356−}
1357−
1358−void tRetune_setWindowSize(tRetune* const rt, int ws)
1359−{
1360− _tRetune* r = *rt;
1361−
1362− r->windowSize = ws;
1363− tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
1364−}
1365−
1366−void tRetune_setFidelityThreshold(tRetune* const rt, float threshold)
1367−{
1368− _tRetune* r = *rt;
1369−
1370− tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
1371−}
1372−
1373−float tRetune_getInputPeriod(tRetune* const rt)
1374−{
1375− _tRetune* r = *rt;
1376−
1377− return (r->inputPeriod * leaf.invSampleRate);
1378−}
1379−
1380−float tRetune_getInputFreq(tRetune* const rt)
1381−{
1382− _tRetune* r = *rt;
1383−
1384− return 1.0f/(r->inputPeriod * leaf.invSampleRate);
1385−}
1386−
1387−//============================================================================================================
1388−// AUTOTUNE
1389−//============================================================================================================
1390−
1391−void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)
1392−{
1393− tAutotune_initToPool(rt, numVoices, bufSize, frameSize, &leaf.mempool);
1394−}
1395−
1396−void tAutotune_free(tAutotune* const rt)
1397−{
1398− tAutotune_freeFromPool(rt, &leaf.mempool);
1399−}
1400−
1401−void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
1402−{
1403− _tMempool* m = *mp;
1404− _tAutotune* r = *rt = (_tAutotune*) mpool_alloc(sizeof(_tAutotune), m);
1405−
1406− r->bufSize = bufSize;
1407− r->frameSize = frameSize;
1408− r->numVoices = numVoices;
1409−
1410− r->inBuffer = (float*) mpool_alloc(sizeof(float) * r->bufSize, m);
1411− r->outBuffers = (float**) mpool_alloc(sizeof(float*) * r->numVoices, m);
1412−
1413− r->hopSize = DEFHOPSIZE;
1414− r->windowSize = DEFWINDOWSIZE;
1415− r->fba = FBA;
1416− tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
1417−
1418− r->ps = (tPitchShift*) mpool_alloc(sizeof(tPitchShift) * r->numVoices, m);
1419− r->freq = (float*) mpool_alloc(sizeof(float) * r->numVoices, m);
1420− r->tickOutput = (float*) mpool_alloc(sizeof(float) * r->numVoices, m);
1421− for (int i = 0; i < r->numVoices; ++i)
1422− {
1423− r->outBuffers[i] = (float*) mpool_alloc(sizeof(float) * r->bufSize, m);
1424− }
1425−
1426− tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
1427−
1428− for (int i = 0; i < r->numVoices; ++i)
1429− {
1430− tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
1431− }
1432−
1433− r->inputPeriod = 0.0f;
1434−}
1435−
1436−void tAutotune_freeFromPool (tAutotune* const rt, tMempool* const mp)
1437−{
1438− _tMempool* m = *mp;
1439− _tAutotune* r = *rt;
1440−
1441− tPeriodDetection_freeFromPool(&r->pd, mp);
1442− for (int i = 0; i < r->numVoices; ++i)
1443− {
1444− tPitchShift_freeFromPool(&r->ps[i], mp);
1445− mpool_free((char*)r->outBuffers[i], m);
1446− }
1447− mpool_free((char*)r->tickOutput, m);
1448− mpool_free((char*)r->freq, m);
1449− mpool_free((char*)r->ps, m);
1450− mpool_free((char*)r->inBuffer, m);
1451− mpool_free((char*)r->outBuffers, m);
1452− mpool_free((char*)r, m);
1453−}
1454−
1455−float* tAutotune_tick(tAutotune* const rt, float sample)
1456−{
1457− _tAutotune* r = *rt;
1458−
1459− float tempPeriod = tPeriodDetection_tick(&r->pd, sample);
1460− if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
1461− {
1462− r->inputPeriod = tempPeriod;
1463− }
1464−
1465− for (int v = 0; v < r->numVoices; ++v)
1466− {
1467− r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
1468− }
1469−
1470− return r->tickOutput;
1471−}
1472−
1473−void tAutotune_setNumVoices(tAutotune* const rt, int numVoices)
1474−{
1475− _tAutotune* r = *rt;
1476−
1477− for (int i = 0; i < r->numVoices; ++i)
1478− {
1479− tPitchShift_free(&r->ps[i]);
1480− leaf_free((char*)r->outBuffers[i]);
1481− }
1482− leaf_free((char*)r->tickOutput);
1483− leaf_free((char*)r->freq);
1484− leaf_free((char*)r->ps);
1485− leaf_free((char*)r->outBuffers);
1486−
1487− r->numVoices = numVoices;
1488−
1489− r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
1490− r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
1491− r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1492− r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
1493− for (int i = 0; i < r->numVoices; ++i)
1494− {
1495− r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
1496− tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
1497− }
1498−}
1499−
1500−void tAutotune_setFreqs(tAutotune* const rt, float f)
1501−{
1502− _tAutotune* r = *rt;
1503−
1504− for (int i = 0; i < r->numVoices; ++i)
1505− {
1506− r->freq[i] = f;
1507− }
1508−}
1509−
1510−void tAutotune_setFreq(tAutotune* const rt, float f, int voice)
1511−{
1512− _tAutotune* r = *rt;
1513−
1514− r->freq[voice] = f;
1515−}
1516−
1517−void tAutotune_setTimeConstant(tAutotune* const rt, float tc)
1518−{
1519− _tAutotune* r = *rt;
1520−
1521− r->timeConstant = tc;
1522− r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
1523−}
1524−
1525−void tAutotune_setHopSize(tAutotune* const rt, int hs)
1526−{
1527− _tAutotune* r = *rt;
1528−
1529− r->hopSize = hs;
1530− tPeriodDetection_setHopSize(&r->pd, r->hopSize);
1531−}
1532−
1533−void tAutotune_setWindowSize(tAutotune* const rt, int ws)
1534−{
1535− _tAutotune* r = *rt;
1536−
1537− r->windowSize = ws;
1538− tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
1539−}
1540−
1541−void tAutotune_setFidelityThreshold(tAutotune* const rt, float threshold)
1542−{
1543− _tAutotune* r = *rt;
1544−
1545− tPeriodDetection_setFidelityThreshold(&r->pd, threshold);
1546−}
1547−
1548−void tAutotune_setAlpha (tAutotune* rt, float alpha)
1549−{
1550− _tAutotune* r = *rt;
1551− tPeriodDetection_setAlpha(&r->pd, alpha);
1552−}
1553−
1554−void tAutotune_setTolerance (tAutotune* rt, float tolerance)
1555−{
1556− _tAutotune* r = *rt;
1557− tPeriodDetection_setTolerance(&r->pd, tolerance);
1558−}
1559−
1560−float tAutotune_getInputPeriod(tAutotune* const rt)
1561−{
1562− _tAutotune* r = *rt;
1563−
1564− return r->inputPeriod;
1565−}
1566−
1567−float tAutotune_getInputFreq(tAutotune* const rt)
1568−{
1569− _tAutotune* r = *rt;
1570−
1571− return 1.0f/r->inputPeriod;
1572−}
1573−
1574−//============================================================================================================
1575−// FORMANTSHIFTER
1576−//============================================================================================================
1577−// algorithm from Tom Baran's autotalent code.
1578−
1579−void tFormantShifter_init(tFormantShifter* const fsr, int order)
1580−{
1581− _tFormantShifter* fs = *fsr = (_tFormantShifter*) leaf_alloc(sizeof(_tFormantShifter));
1582−
1583− fs->ford = order;
1584− fs->fk = (float*) leaf_calloc(sizeof(float) * fs->ford);
1585− fs->fb = (float*) leaf_calloc(sizeof(float) * fs->ford);
1586− fs->fc = (float*) leaf_calloc(sizeof(float) * fs->ford);
1587− fs->frb = (float*) leaf_calloc(sizeof(float) * fs->ford);
1588− fs->frc = (float*) leaf_calloc(sizeof(float) * fs->ford);
1589− fs->fsig = (float*) leaf_calloc(sizeof(float) * fs->ford);
1590− fs->fsmooth = (float*) leaf_calloc(sizeof(float) * fs->ford);
1591− fs->ftvec = (float*) leaf_calloc(sizeof(float) * fs->ford);
1592− fs->fbuff = (float*) leaf_calloc(sizeof(float*) * fs->ford);
1593−
1594− fs->falph = powf(0.001f, 40.0f * leaf.invSampleRate);
1595− fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
1596− fs->fhp = 0.0f;
1597− fs->flp = 0.0f;
1598− fs->flpa = powf(0.001f, 10.0f * leaf.invSampleRate);
1599− fs->fmute = 1.0f;
1600− fs->fmutealph = powf(0.001f, 0.5f * leaf.invSampleRate);
1601− fs->cbi = 0;
1602− fs->intensity = 1.0f;
1603− fs->invIntensity = 1.0f;
1604− tHighpass_init(&fs->hp, 10.0f);
1605− tHighpass_init(&fs->hp2, 10.0f);
1606− tFeedbackLeveler_init(&fs->fbl1, 0.99f, 0.005f, 0.125f, 0);
1607− tFeedbackLeveler_init(&fs->fbl2, 0.99f, 0.005f, 0.125f, 0);
1608−}
1609−
1610−void tFormantShifter_free(tFormantShifter* const fsr)
1611−{
1612− _tFormantShifter* fs = *fsr;
1613−
1614− leaf_free((char*)fs->fk);
1615− leaf_free((char*)fs->fb);
1616− leaf_free((char*)fs->fc);
1617− leaf_free((char*)fs->frb);
1618− leaf_free((char*)fs->frc);
1619− leaf_free((char*)fs->fsig);
1620− leaf_free((char*)fs->fsmooth);
1621− leaf_free((char*)fs->ftvec);
1622− leaf_free((char*)fs->fbuff);
1623− tHighpass_free(&fs->hp);
1624− tHighpass_free(&fs->hp2);
1625− tFeedbackLeveler_free(&fs->fbl1);
1626− tFeedbackLeveler_free(&fs->fbl2);
1627− leaf_free((char*)fs);
1628−}
1629−
1630−void tFormantShifter_initToPool (tFormantShifter* const fsr, int order, tMempool* const mp)
1631−{
1632− _tMempool* m = *mp;
1633− _tFormantShifter* fs = *fsr = (_tFormantShifter*) mpool_alloc(sizeof(_tFormantShifter), m);
1634−
1635− fs->ford = order;
1636− fs->fk = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1637− fs->fb = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1638− fs->fc = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1639− fs->frb = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1640− fs->frc = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1641− fs->fsig = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1642− fs->fsmooth = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1643− fs->ftvec = (float*) mpool_calloc(sizeof(float) * fs->ford, m);
1644−
1645− fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
1646−
1647−
1648− fs->falph = powf(0.001f, 10.0f * leaf.invSampleRate);
1649− fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
1650− fs->fhp = 0.0f;
1651− fs->flp = 0.0f;
1652− fs->flpa = powf(0.001f, 10.0f * leaf.invSampleRate);
1653− fs->fmute = 1.0f;
1654− fs->fmutealph = powf(0.001f, 1.0f * leaf.invSampleRate);
1655− fs->cbi = 0;
1656− fs->intensity = 1.0f;
1657− fs->invIntensity = 1.0f;
1658− tHighpass_initToPool(&fs->hp, 20.0f, mp);
1659− tHighpass_initToPool(&fs->hp2, 20.0f, mp);
1660− tFeedbackLeveler_initToPool(&fs->fbl1, 0.8f, .005f, 0.125, 1, mp);
1661− tFeedbackLeveler_initToPool(&fs->fbl2, 0.8f, .005f, 0.125, 1, mp);
1662−}
1663−
1664−void tFormantShifter_freeFromPool (tFormantShifter* const fsr, tMempool* const mp)
1665−{
1666− _tMempool* m = *mp;
1667− _tFormantShifter* fs = *fsr;
1668−
1669− mpool_free((char*)fs->fk, m);
1670− mpool_free((char*)fs->fb, m);
1671− mpool_free((char*)fs->fc, m);
1672− mpool_free((char*)fs->frb, m);
1673− mpool_free((char*)fs->frc, m);
1674− mpool_free((char*)fs->fsig, m);
1675− mpool_free((char*)fs->fsmooth, m);
1676− mpool_free((char*)fs->ftvec, m);
1677− mpool_free((char*)fs->fbuff, m);
1678− tHighpass_freeFromPool(&fs->hp, mp);
1679− tHighpass_freeFromPool(&fs->hp2, mp);
1680− tFeedbackLeveler_freeFromPool(&fs->fbl1, mp);
1681− tFeedbackLeveler_freeFromPool(&fs->fbl2, mp);
1682− mpool_free((char*)fs, m);
1683−}
1684−
1685−float tFormantShifter_tick(tFormantShifter* const fsr, float in)
1686−{
1687− return tFormantShifter_add(fsr, tFormantShifter_remove(fsr, in));
1688−}
1689−
1690−float tFormantShifter_remove(tFormantShifter* const fsr, float in)
1691−{
1692− _tFormantShifter* fs = *fsr;
1693− in = tFeedbackLeveler_tick(&fs->fbl1, in);
1694− in = tHighpass_tick(&fs->hp, in * fs->intensity);
1695−
1696−
1697− float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
1698−
1699− ford = fs->ford;
1700− falph = fs->falph;
1701− foma = (1.0f - falph);
1702− flamb = fs->flamb;
1703−
1704− tf = in;
1705−
1706− fa = tf - fs->fhp;
1707− fs->fhp = tf;
1708− fb = fa;
1709− for(int i = 0; i < ford; i++)
1710− {
1711− fs->fsig[i] = fa*fa*foma + fs->fsig[i]*falph;
1712− fc = (fb - fs->fc[i])*flamb + fs->fb[i];
1713− fs->fc[i] = fc;
1714− fs->fb[i] = fb;
1715− fk = fa*fc*foma + fs->fk[i]*falph;
1716− fs->fk[i] = fk;
1717− tf = fk/(fs->fsig[i] + 0.000001f);
1718− tf = tf*foma + fs->fsmooth[i]*falph;
1719− fs->fsmooth[i] = tf;
1720− fs->fbuff[i] = tf;
1721− fb = fc - tf*fa;
1722− fa = fa - tf*fc;
1723− }
1724−
1725− //return fa * 0.1f;
1726− return fa;
1727−}
1728−
1729−float tFormantShifter_add(tFormantShifter* const fsr, float in)
1730−{
1731− _tFormantShifter* fs = *fsr;
1732−
1733− float fa, fb, fc, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
1734− ford = fs->ford;
1735−
1736− flpa = fs->flpa;
1737− flamb = fs->flamb;
1738− tf = fs->shiftFactor * (1.0f+flamb)/(1.0f-flamb);
1739− frlamb = (tf-1.0f)/(tf+1.0f);
1740−
1741− tf2 = in;
1742− fa = 0.0f;
1743− fb = fa;
1744− for (int i=0; i<ford; i++)
1745− {
1746− fc = (fb-fs->frc[i])*frlamb + fs->frb[i];
1747− tf = fs->fbuff[i];
1748− fb = fc - tf*fa;
1749− fs->ftvec[i] = tf*fc;
1750− fa = fa - fs->ftvec[i];
1751− }
1752− tf = -fa;
1753− for (int i=ford-1; i>=0; i--)
1754− {
1755− tf = tf + fs->ftvec[i];
1756− }
1757− f0resp = tf;
1758−
1759− // second time: compute 1-response
1760− fa = 1.0f;
1761− fb = fa;
1762− for (int i=0; i<ford; i++)
1763− {
1764− fc = (fb-fs->frc[i])*frlamb + fs->frb[i];
1765− tf = fs->fbuff[i];
1766− fb = fc - tf*fa;
1767− fs->ftvec[i] = tf*fc;
1768− fa = fa - fs->ftvec[i];
1769− }
1770− tf = -fa;
1771− for (int i=ford-1; i>=0; i--)
1772− {
1773− tf = tf + fs->ftvec[i];
1774− }
1775− f1resp = tf;
1776−
1777− // now solve equations for output, based on 0-response and 1-response
1778− tf = 2.0f*tf2;
1779− tf2 = tf;
1780− tf = (1.0f - f1resp + f0resp);
1781− if (tf!=0.0f)
1782− {
1783− tf2 = (tf2 + f0resp) / tf;
1784− }
1785− else
1786− {
1787− tf2 = 0.0f;
1788− }
1789−
1790− // third time: update delay registers
1791− fa = tf2;
1792− fb = fa;
1793− for (int i=0; i<ford; i++)
1794− {
1795− fc = (fb-fs->frc[i])*frlamb + fs->frb[i];
1796− fs->frc[i] = fc;
1797− fs->frb[i] = fb;
1798− tf = fs->fbuff[i];
1799− fb = fc - tf*fa;
1800− fa = fa - tf*fc;
1801− }
1802− tf = tf2;
1803− tf = tf + flpa * fs->flp; // lowpass post-emphasis filter
1804− fs->flp = tf;
1805−
1806− // Bring up the gain slowly when formant correction goes from disabled
1807− // to enabled, while things stabilize.
1808− if (fs->fmute>0.5f)
1809− {
1810− tf = tf*(fs->fmute - 0.5f)*2.0f;
1811− }
1812− else
1813− {
1814− tf = 0.0f;
1815− }
1816− tf2 = fs->fmutealph;
1817− fs->fmute = (1.0f-tf2) + tf2*fs->fmute;
1818− // now tf is signal output
1819− // ...and we're done messing with formants
1820− //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
1821− tf = tHighpass_tick(&fs->hp2, tanhf(tf));
1822−
1823− return tf * fs->invIntensity;
1824−}
1825−
1826−// 1.0f is no change, 2.0f is an octave up, 0.5f is an octave down
1827−void tFormantShifter_setShiftFactor(tFormantShifter* const fsr, float shiftFactor)
1828−{
1829− _tFormantShifter* fs = *fsr;
1830− fs->shiftFactor = shiftFactor;
1831−}
1832−
1833−void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity)
1834−{
1835− _tFormantShifter* fs = *fsr;
1836−
1837−
1838−
1839− fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
1840−
1841− // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
1842− //tFeedbackLeveler_setTargetLevel(&fs->fbl2, fs->intensity);
1843− //make sure you don't divide by zero, doofies
1844− if (fs->intensity != 0.0f)
1845− {
1846− fs->invIntensity = 1.0f/fs->intensity;
1847− }
1848− else
1849− {
1850− fs->invIntensity = 1.0f;
1851− }
1852−
1853−}
LEAF/Src/leaf-electrical.c+0−551
@@ -1,551 +0,0 @@
1−/*
2− * leaf-electrical.c
3− *
4− * Created on: Sep 25, 2019
5− * Author: jeffsnyder
6− */
7−
8−#if _WIN32 || _WIN64
9−
10−#include "..\Inc\leaf-electrical.h"
11−#include "..\leaf.h"
12−
13−#else
14−
15−#include "../Inc/leaf-electrical.h"
16−#include "../leaf.h"
17−
18−#endif
19−
20−//==============================================================================
21−
22−static float get_port_resistance_for_resistor(tWDF* const r);
23−static float get_port_resistance_for_capacitor(tWDF* const r);
24−static float get_port_resistance_for_inductor(tWDF* const r);
25−static float get_port_resistance_for_resistive(tWDF* const r);
26−static float get_port_resistance_for_inverter(tWDF* const r);
27−static float get_port_resistance_for_series(tWDF* const r);
28−static float get_port_resistance_for_parallel(tWDF* const r);
29−static float get_port_resistance_for_root(tWDF* const r);
30−
31−static void set_incident_wave_for_leaf(tWDF* const r, float incident_wave, float input);
32−static void set_incident_wave_for_leaf_inverted(tWDF* const r, float incident_wave, float input);
33−static void set_incident_wave_for_inverter(tWDF* const r, float incident_wave, float input);
34−static void set_incident_wave_for_series(tWDF* const r, float incident_wave, float input);
35−static void set_incident_wave_for_parallel(tWDF* const r, float incident_wave, float input);
36−
37−static float get_reflected_wave_for_resistor(tWDF* const r, float input);
38−static float get_reflected_wave_for_capacitor(tWDF* const r, float input);
39−static float get_reflected_wave_for_resistive(tWDF* const r, float input);
40−static float get_reflected_wave_for_inverter(tWDF* const r, float input);
41−static float get_reflected_wave_for_series(tWDF* const r, float input);
42−static float get_reflected_wave_for_parallel(tWDF* const r, float input);
43−
44−static float get_reflected_wave_for_ideal(tWDF* const n, float input, float incident_wave);
45−static float get_reflected_wave_for_diode(tWDF* const n, float input, float incident_wave);
46−static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave);
47−
48−static void wdf_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
49−{
50− _tWDF* r = *wdf;
51−
52− r->type = type;
53− r->child_left = rL;
54− r->child_right = rR;
55− r->incident_wave_up = 0.0f;
56− r->incident_wave_left = 0.0f;
57− r->incident_wave_right = 0.0f;
58− r->reflected_wave_up = 0.0f;
59− r->reflected_wave_left = 0.0f;
60− r->reflected_wave_right = 0.0f;
61− r->sample_rate = leaf.sampleRate;
62− r->value = value;
63−
64− tWDF* child;
65− if (r->child_left != NULL) child = r->child_left;
66− else child = r->child_right;
67−
68− if (r->type == Resistor)
69− {
70− r->port_resistance_up = r->value;
71− r->port_conductance_up = 1.0f / r->value;
72−
73− r->get_port_resistance = &get_port_resistance_for_resistor;
74− r->get_reflected_wave_up = &get_reflected_wave_for_resistor;
75− r->set_incident_wave = &set_incident_wave_for_leaf;
76− }
77− else if (r->type == Capacitor)
78− {
79− r->port_conductance_up = r->sample_rate * 2.0f * r->value;
80− r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
81−
82− r->get_port_resistance = &get_port_resistance_for_capacitor;
83− r->get_reflected_wave_up = &get_reflected_wave_for_capacitor;
84− r->set_incident_wave = &set_incident_wave_for_leaf;
85− }
86− else if (r->type == Inductor)
87− {
88− r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
89− r->port_conductance_up = 1.0f / r->port_resistance_up;
90−
91− r->get_port_resistance = &get_port_resistance_for_inductor;
92− r->get_reflected_wave_up = &get_reflected_wave_for_capacitor; // same as capacitor
93− r->set_incident_wave = &set_incident_wave_for_leaf_inverted;
94− }
95− else if (r->type == ResistiveSource)
96− {
97− r->port_resistance_up = r->value;
98− r->port_conductance_up = 1.0f / r->port_resistance_up;
99−
100− r->get_port_resistance = &get_port_resistance_for_resistive;
101− r->get_reflected_wave_up = &get_reflected_wave_for_resistive;
102− r->set_incident_wave = &set_incident_wave_for_leaf;
103− }
104− else if (r->type == Inverter)
105− {
106− r->port_resistance_up = tWDF_getPortResistance(r->child_left);
107− r->port_conductance_up = 1.0f / r->port_resistance_up;
108−
109− r->get_port_resistance = &get_port_resistance_for_inverter;
110− r->get_reflected_wave_up = &get_reflected_wave_for_inverter;
111− r->set_incident_wave = &set_incident_wave_for_inverter;
112− }
113− else if (r->type == SeriesAdaptor)
114− {
115− r->port_resistance_left = tWDF_getPortResistance(r->child_left);
116− r->port_resistance_right = tWDF_getPortResistance(r->child_right);
117− r->port_resistance_up = r->port_resistance_left + r->port_resistance_right;
118− r->port_conductance_up = 1.0f / r->port_resistance_up;
119− r->port_conductance_left = 1.0f / r->port_resistance_left;
120− r->port_conductance_right = 1.0f / r->port_resistance_right;
121− r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
122−
123− r->get_port_resistance = &get_port_resistance_for_series;
124− r->get_reflected_wave_up = &get_reflected_wave_for_series;
125− r->set_incident_wave = &set_incident_wave_for_series;
126− }
127− else if (r->type == ParallelAdaptor)
128− {
129− r->port_resistance_left = tWDF_getPortResistance(r->child_left);
130− r->port_resistance_right = tWDF_getPortResistance(r->child_right);
131− r->port_resistance_up = (r->port_resistance_left * r->port_resistance_right) / (r->port_resistance_left + r->port_resistance_right);
132− r->port_conductance_up = 1.0f / r->port_resistance_up;
133− r->port_conductance_left = 1.0f / r->port_resistance_left;
134− r->port_conductance_right = 1.0f / r->port_resistance_right;
135− r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
136−
137− r->get_port_resistance = &get_port_resistance_for_parallel;
138− r->get_reflected_wave_up = &get_reflected_wave_for_parallel;
139− r->set_incident_wave = &set_incident_wave_for_parallel;
140− }
141− else if (r->type == IdealSource)
142− {
143− r->port_resistance_up = tWDF_getPortResistance(child);
144− r->port_conductance_up = 1.0f / r->port_resistance_up;
145−
146− r->get_reflected_wave_down = &get_reflected_wave_for_ideal;
147− r->get_port_resistance = &get_port_resistance_for_root;
148− }
149− else if (r->type == Diode)
150− {
151− r->port_resistance_up = tWDF_getPortResistance(child);
152− r->port_conductance_up = 1.0f / r->port_resistance_up;
153−
154− r->get_reflected_wave_down = &get_reflected_wave_for_diode;
155− r->get_port_resistance = &get_port_resistance_for_root;
156− }
157− else if (r->type == DiodePair)
158− {
159− r->port_resistance_up = tWDF_getPortResistance(child);
160− r->port_conductance_up = 1.0f / r->port_resistance_up;
161−
162− r->get_reflected_wave_down = &get_reflected_wave_for_diode_pair;
163− r->get_port_resistance = &get_port_resistance_for_root;
164− }
165−}
166−//WDF
167−void tWDF_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
168−{
169− *wdf = (_tWDF*) leaf_alloc(sizeof(_tWDF));
170−
171− wdf_init(wdf, type, value, rL, rR);
172−}
173−
174−void tWDF_free(tWDF* const wdf)
175−{
176− _tWDF* r = *wdf;
177−
178− leaf_free((char*)r);
179−}
180−
181−void tWDF_initToPool (tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR, tMempool* const mp)
182−{
183− _tMempool* m = *mp;
184− *wdf = (_tWDF*) mpool_alloc(sizeof(_tWDF), m);
185−
186− wdf_init(wdf, type, value, rL, rR);
187−}
188−
189−void tWDF_freeFromPool (tWDF* const wdf, tMempool* const mp)
190−{
191− _tMempool* m = *mp;
192− _tWDF* r = *wdf;
193−
194− mpool_free((char*)r, m);
195−}
196−
197−float tWDF_tick(tWDF* const wdf, float sample, tWDF* const outputPoint, uint8_t paramsChanged)
198−{
199− _tWDF* r = *wdf;
200−
201− tWDF* child;
202− if (r->child_left != NULL) child = r->child_left;
203− else child = r->child_right;
204−
205− //step 0 : update port resistances if something changed
206− if (paramsChanged) tWDF_getPortResistance(wdf);
207−
208− //step 1 : set inputs to what they should be
209− float input = sample;
210−
211− //step 2 : scan the waves up the tree
212− r->incident_wave_up = tWDF_getReflectedWaveUp(child, input);
213−
214− //step 3 : do root scattering computation
215− r->reflected_wave_up = tWDF_getReflectedWaveDown(wdf, input, r->incident_wave_up);
216−
217− //step 4 : propogate waves down the tree
218− tWDF_setIncidentWave(child, r->reflected_wave_up, input);
219−
220− //step 5 : grab whatever voltages or currents we want as outputs
221− return tWDF_getVoltage(outputPoint);
222−}
223−
224−void tWDF_setValue(tWDF* const wdf, float value)
225−{
226− _tWDF* r = *wdf;
227− r->value = value;
228−}
229−
230−void tWDF_setSampleRate(tWDF* const wdf, float sample_rate)
231−{
232− _tWDF* r = *wdf;
233− r->sample_rate = sample_rate;
234−}
235−
236−uint8_t tWDF_isLeaf(tWDF* const wdf)
237−{
238− _tWDF* r = *wdf;
239− if (r->child_left == NULL && r->child_right == NULL) return 1;
240− return 0;
241−}
242−
243−float tWDF_getPortResistance(tWDF* const wdf)
244−{
245− _tWDF* r = *wdf;
246− return r->get_port_resistance(wdf);
247−}
248−
249−void tWDF_setIncidentWave(tWDF* const wdf, float incident_wave, float input)
250−{
251− _tWDF* r = *wdf;
252− r->set_incident_wave(wdf, incident_wave, input);
253−}
254−
255−float tWDF_getReflectedWaveUp(tWDF* const wdf, float input)
256−{
257− _tWDF* r = *wdf;
258− return r->get_reflected_wave_up(wdf, input);
259−}
260−
261−float tWDF_getReflectedWaveDown(tWDF* const wdf, float input, float incident_wave)
262−{
263− _tWDF* r = *wdf;
264− return r->get_reflected_wave_down(wdf, input, incident_wave);
265−}
266−
267−float tWDF_getVoltage(tWDF* const wdf)
268−{
269− _tWDF* r = *wdf;
270− return ((r->incident_wave_up * 0.5f) + (r->reflected_wave_up * 0.5f));
271−}
272−
273−float tWDF_getCurrent(tWDF* const wdf)
274−{
275− _tWDF* r = *wdf;
276− return (((r->incident_wave_up * 0.5f) - (r->reflected_wave_up * 0.5f)) * r->port_conductance_up);
277−}
278−
279−//============ Static Functions to be Pointed To ====================
280−//===================================================================
281−//============ Get and Calculate Port Resistances ===================
282−
283−static float get_port_resistance_for_resistor(tWDF* const wdf)
284−{
285− _tWDF* r = *wdf;
286−
287− r->port_resistance_up = r->value;
288− r->port_conductance_up = 1.0f / r->value;
289−
290− return r->port_resistance_up;
291−}
292−
293−static float get_port_resistance_for_capacitor(tWDF* const wdf)
294−{
295− _tWDF* r = *wdf;
296−
297− r->port_conductance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
298− r->port_resistance_up = (1.0f / r->port_conductance_up);
299−
300− return r->port_resistance_up;
301−}
302−
303−static float get_port_resistance_for_inductor(tWDF* const wdf)
304−{
305− _tWDF* r = *wdf;
306−
307− r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
308− r->port_conductance_up = (1.0f / r->port_resistance_up);
309−
310− return r->port_resistance_up;
311−}
312−
313−static float get_port_resistance_for_resistive(tWDF* const wdf)
314−{
315− _tWDF* r = *wdf;
316−
317− r->port_resistance_up = r->value;
318− r->port_conductance_up = 1.0f / r->port_resistance_up;
319−
320− return r->port_resistance_up;
321−}
322−
323−static float get_port_resistance_for_inverter(tWDF* const wdf)
324−{
325− _tWDF* r = *wdf;
326−
327− r->port_resistance_up = tWDF_getPortResistance(r->child_left);
328− r->port_conductance_up = 1.0f / r->port_resistance_up;
329−
330− return r->port_resistance_up;
331−}
332−
333−static float get_port_resistance_for_series(tWDF* const wdf)
334−{
335− _tWDF* r = *wdf;
336−
337− r->port_resistance_left = tWDF_getPortResistance(r->child_left);
338− r->port_resistance_right = tWDF_getPortResistance(r->child_right);
339− r->port_resistance_up = r->port_resistance_left + r->port_resistance_right;
340− r->port_conductance_up = 1.0f / r->port_resistance_up;
341− r->port_conductance_left = 1.0f / r->port_resistance_left;
342− r->port_conductance_right = 1.0f / r->port_resistance_right;
343− r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
344−
345− return r->port_resistance_up;
346−}
347−
348−static float get_port_resistance_for_parallel(tWDF* const wdf)
349−{
350− _tWDF* r = *wdf;
351−
352− r->port_resistance_left = tWDF_getPortResistance(r->child_left);
353− r->port_resistance_right = tWDF_getPortResistance(r->child_right);
354− r->port_resistance_up = (r->port_resistance_left * r->port_resistance_right) / (r->port_resistance_left + r->port_resistance_right);
355− r->port_conductance_up = 1.0f / r->port_resistance_up;
356− r->port_conductance_left = 1.0f / r->port_resistance_left;
357− r->port_conductance_right = 1.0f / r->port_resistance_right;
358− r->gamma_zero = 1.0f / (r->port_conductance_right + r->port_conductance_left);
359−
360− return r->port_resistance_up;
361−}
362−
363−static float get_port_resistance_for_root(tWDF* const wdf)
364−{
365− _tWDF* r = *wdf;
366−
367− tWDF* child;
368− if (r->child_left != NULL) child = r->child_left;
369− else child = r->child_right;
370−
371− r->port_resistance_up = tWDF_getPortResistance(child);
372− r->port_conductance_up = 1.0f / r->port_resistance_up;
373−
374− return r->port_resistance_up;
375−}
376−
377−//===================================================================
378−//================ Set Incident Waves ===============================
379−
380−static void set_incident_wave_for_leaf(tWDF* const wdf, float incident_wave, float input)
381−{
382− _tWDF* r = *wdf;
383− r->incident_wave_up = incident_wave;
384−}
385−
386−static void set_incident_wave_for_leaf_inverted(tWDF* const wdf, float incident_wave, float input)
387−{
388− _tWDF* r = *wdf;
389− r->incident_wave_up = -1.0f * incident_wave;
390−}
391−
392−static void set_incident_wave_for_inverter(tWDF* const wdf, float incident_wave, float input)
393−{
394− _tWDF* r = *wdf;
395− r->incident_wave_up = incident_wave;
396− tWDF_setIncidentWave(r->child_left, -1.0f * incident_wave, input);
397−}
398−
399−static void set_incident_wave_for_series(tWDF* const wdf, float incident_wave, float input)
400−{
401− _tWDF* r = *wdf;
402−
403− r->incident_wave_up = incident_wave;
404− float gamma_left = r->port_resistance_left * r->gamma_zero;
405− float gamma_right = r->port_resistance_right * r->gamma_zero;
406− float left_wave = tWDF_getReflectedWaveUp(r->child_left, input);
407− float right_wave = tWDF_getReflectedWaveUp(r->child_right, input);
408−// downPorts[0]->b = yl * ( downPorts[0]->a * ((1.0 / yl) - 1) - downPorts[1]->a - descendingWave );
409−// downPorts[1]->b = yr * ( downPorts[1]->a * ((1.0 / yr) - 1) - downPorts[0]->a - descendingWave );
410− tWDF_setIncidentWave(r->child_left, (-1.0f * gamma_left * incident_wave) + (gamma_right * left_wave) - (gamma_left * right_wave), input);
411− tWDF_setIncidentWave(r->child_right, (-1.0f * gamma_right * incident_wave) + (gamma_left * right_wave) - (gamma_right * left_wave), input);
412− // From rt-wdf
413−// tWDF_setIncidentWave(r->child_left, gamma_left * (left_wave * ((1.0f / gamma_left) - 1.0f) - right_wave - incident_wave));
414−// tWDF_setIncidentWave(r->child_right, gamma_right * (right_wave * ((1.0f / gamma_right) - 1.0f) - left_wave - incident_wave));
415−
416−}
417−
418−static void set_incident_wave_for_parallel(tWDF* const wdf, float incident_wave, float input)
419−{
420− _tWDF* r = *wdf;
421−
422− r->incident_wave_up = incident_wave;
423− float gamma_left = r->port_conductance_left * r->gamma_zero;
424− float gamma_right = r->port_conductance_right * r->gamma_zero;
425− float left_wave = tWDF_getReflectedWaveUp(r->child_left, input);
426− float right_wave = tWDF_getReflectedWaveUp(r->child_right, input);
427−// downPorts[0]->b = ( ( dl - 1 ) * downPorts[0]->a + dr * downPorts[1]->a + du * descendingWave );
428−// downPorts[1]->b = ( dl * downPorts[0]->a + ( dr - 1 ) * downPorts[1]->a + du * descendingWave );
429− tWDF_setIncidentWave(r->child_left, (gamma_left - 1.0f) * left_wave + gamma_right * right_wave + incident_wave, input);
430− tWDF_setIncidentWave(r->child_right, gamma_left * left_wave + (gamma_right - 1.0f) * right_wave + incident_wave, input);
431−}
432−
433−//===================================================================
434−//================ Get Reflected Waves ==============================
435−
436−static float get_reflected_wave_for_resistor(tWDF* const wdf, float input)
437−{
438− _tWDF* r = *wdf;
439− r->reflected_wave_up = 0.0f;
440− return r->reflected_wave_up;
441−}
442−
443−static float get_reflected_wave_for_capacitor(tWDF* const wdf, float input)
444−{
445− _tWDF* r = *wdf;
446− r->reflected_wave_up = r->incident_wave_up;
447− return r->reflected_wave_up;
448−}
449−
450−static float get_reflected_wave_for_resistive(tWDF* const wdf, float input)
451−{
452− _tWDF* r = *wdf;
453− r->reflected_wave_up = input;
454− return r->reflected_wave_up;
455−}
456−
457−static float get_reflected_wave_for_inverter(tWDF* const wdf, float input)
458−{
459− _tWDF* r = *wdf;
460− r->reflected_wave_up = -1.0f * tWDF_getReflectedWaveUp(r->child_left, input);
461− return r->reflected_wave_up;
462−}
463−
464−static float get_reflected_wave_for_series(tWDF* const wdf, float input)
465−{
466− _tWDF* r = *wdf;
467− //-( downPorts[0]->a + downPorts[1]->a );
468− r->reflected_wave_up = (-1.0f * (tWDF_getReflectedWaveUp(r->child_left, input) + tWDF_getReflectedWaveUp(r->child_right, input)));
469− return r->reflected_wave_up;
470−}
471−
472−static float get_reflected_wave_for_parallel(tWDF* const wdf, float input)
473−{
474− _tWDF* r = *wdf;
475−
476− float gamma_left = r->port_conductance_left * r->gamma_zero;
477− float gamma_right = r->port_conductance_right * r->gamma_zero;
478− //return ( dl * downPorts[0]->a + dr * downPorts[1]->a );
479− r->reflected_wave_up = (gamma_left * tWDF_getReflectedWaveUp(r->child_left, input) + gamma_right * tWDF_getReflectedWaveUp(r->child_right, input));
480− return r->reflected_wave_up;
481−}
482−
483−static float get_reflected_wave_for_ideal(tWDF* const wdf, float input, float incident_wave)
484−{
485− return (2.0f * input) - incident_wave;
486−}
487−
488−#define l2A 0.1640425613334452f
489−#define l2B -1.098865286222744f
490−#define l2Y 3.148297929334117f
491−#define l2K -2.213475204444817f
492−static float log2Approximation(float x)
493−{
494− return (l2A * x*x*x) + (l2B * x*x) + (l2Y * x) + l2K;
495−}
496−
497−#define wX1 -3.684303659906469f
498−#define wX2 1.972967391708859f
499−#define wA 9.451797158780131e-3f
500−#define wB 0.1126446405111627f
501−#define wY 0.4451353886588814f
502−#define wK 0.5836596684310648f
503−static float wrightOmega3(float x)
504−{
505− if (x <= wX1)
506− {
507− return 0;
508− }
509− else if (x < wX2)
510− {
511− return (wA * x*x*x) + (wB * x*x) + (wY * x) + wK;
512− }
513− else
514− {
515− return x - logf(x);
516− }
517−}
518−
519−static float wrightOmegaApproximation(float x)
520−{
521− float w3 = wrightOmega3(x);
522− return w3 - ((w3 - expf(x - w3)) / (w3 + 1.0f));
523−}
524−
525−static float lambertW(float a, float r, float I, float iVT)
526−{
527− return wrightOmegaApproximation(((a + r*I) * iVT) + log((r * I) * iVT));
528−}
529−
530−#define Is_DIODE 2.52e-9f
531−#define VT_DIODE 0.02585f
532−static float get_reflected_wave_for_diode(tWDF* const wdf, float input, float incident_wave)
533−{
534− _tWDF* n = *wdf;
535−
536− float a = incident_wave;
537− float r = n->port_resistance_up;
538− return a + 2.0f*r*Is_DIODE - 2.0f*VT_DIODE*lambertW(a, r, Is_DIODE, 1.0f/VT_DIODE);
539−}
540−
541−static float get_reflected_wave_for_diode_pair(tWDF* const wdf, float input, float incident_wave)
542−{
543− _tWDF* n = *wdf;
544−
545− float a = incident_wave;
546− float sgn = 0.0f;
547− if (a > 0.0f) sgn = 1.0f;
548− else if (a < 0.0f) sgn = -1.0f;
549− float r = n->port_resistance_up;
550− return a + 2 * sgn * (r*Is_DIODE - VT_DIODE*lambertW(sgn*a, r, Is_DIODE, 1.0f/VT_DIODE));
551−}
LEAF/Src/leaf-envelopes.c+0−1612
@@ -1,1612 +0,0 @@
1−/*
2− ==============================================================================
3−
4− leaf-envelopes.c
5− Created: 20 Jan 2017 12:02:17pm
6− Author: Michael R Mulshine
7−
8− ==============================================================================
9−*/
10−
11−
12−#if _WIN32 || _WIN64
13−
14−#include "..\Inc\leaf-envelopes.h"
15−#include "..\Inc\leaf-tables.h"
16−#include "..\leaf.h"
17−
18−#else
19−
20−#include "../Inc/leaf-envelopes.h"
21−#include "../Inc/leaf-tables.h"
22−#include "../leaf.h"
23−
24−#endif
25−
26−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Envelope ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
27−void tEnvelope_init(tEnvelope* const envlp, float attack, float decay, int loop)
28−{
29− _tEnvelope* env = *envlp = (_tEnvelope*) leaf_alloc(sizeof(_tEnvelope));
30−
31− env->exp_buff = __leaf_table_exp_decay;
32− env->inc_buff = __leaf_table_attack_decay_inc;
33− env->buff_size = sizeof(__leaf_table_exp_decay);
34−
35− env->loop = loop;
36−
37− if (attack > 8192.0f)
38− attack = 8192.0f;
39− if (attack < 0.0f)
40− attack = 0.0f;
41−
42− if (decay > 8192.0f)
43− decay = 8192.0f;
44− if (decay < 0.0f)
45− decay = 0.0f;
46−
47− int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
48− int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
49− int16_t rampIndex = ((int16_t)(2.0f * 8.0f))-1;
50−
51− if (attackIndex < 0)
52− attackIndex = 0;
53− if (decayIndex < 0)
54− decayIndex = 0;
55− if (rampIndex < 0)
56− rampIndex = 0;
57−
58− env->inRamp = OFALSE;
59− env->inAttack = OFALSE;
60− env->inDecay = OFALSE;
61−
62− env->attackInc = env->inc_buff[attackIndex];
63− env->decayInc = env->inc_buff[decayIndex];
64− env->rampInc = env->inc_buff[rampIndex];
65−}
66−
67−void tEnvelope_free(tEnvelope* const envlp)
68−{
69− _tEnvelope* env = *envlp;
70− leaf_free((char*)env);
71−}
72−
73−void tEnvelope_initToPool (tEnvelope* const envlp, float attack, float decay, int loop, tMempool* const mp)
74−{
75− _tMempool* m = *mp;
76− _tEnvelope* env = *envlp = (_tEnvelope*) mpool_alloc(sizeof(_tEnvelope), m);
77−
78− env->exp_buff = __leaf_table_exp_decay;
79− env->inc_buff = __leaf_table_attack_decay_inc;
80− env->buff_size = sizeof(__leaf_table_exp_decay);
81−
82− env->loop = loop;
83−
84− if (attack > 8192.0f)
85− attack = 8192.0f;
86− if (attack < 0.0f)
87− attack = 0.0f;
88−
89− if (decay > 8192.0f)
90− decay = 8192.0f;
91− if (decay < 0.0f)
92− decay = 0.0f;
93−
94− int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
95− int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
96− int16_t rampIndex = ((int16_t)(2.0f * 8.0f))-1;
97−
98− if (attackIndex < 0)
99− attackIndex = 0;
100− if (decayIndex < 0)
101− decayIndex = 0;
102− if (rampIndex < 0)
103− rampIndex = 0;
104−
105− env->inRamp = OFALSE;
106− env->inAttack = OFALSE;
107− env->inDecay = OFALSE;
108−
109− env->attackInc = env->inc_buff[attackIndex];
110− env->decayInc = env->inc_buff[decayIndex];
111− env->rampInc = env->inc_buff[rampIndex];
112−}
113−
114−void tEnvelope_freeFromPool (tEnvelope* const envlp, tMempool* const mp)
115−{
116− _tMempool* m = *mp;
117− _tEnvelope* env = *envlp;
118− mpool_free((char*)env, m);
119−}
120−
121−void tEnvelope_setAttack(tEnvelope* const envlp, float attack)
122−{
123− _tEnvelope* env = *envlp;
124−
125− int32_t attackIndex;
126−
127− if (attack < 0.0f) {
128− attackIndex = 0.0f;
129− } else if (attack < 8192.0f) {
130− attackIndex = ((int32_t)(attack * 8.0f))-1;
131− } else {
132− attackIndex = ((int32_t)(8192.0f * 8.0f))-1;
133− }
134−
135− env->attackInc = env->inc_buff[attackIndex];
136−}
137−
138−void tEnvelope_setDecay(tEnvelope* const envlp, float decay)
139−{
140− _tEnvelope* env = *envlp;
141−
142− int32_t decayIndex;
143−
144− if (decay < 0.0f) {
145− decayIndex = 0;
146− } else if (decay < 8192.0f) {
147− decayIndex = ((int32_t)(decay * 8.0f)) - 1;
148− } else {
149− decayIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
150− }
151−
152− env->decayInc = env->inc_buff[decayIndex];
153−}
154−
155−void tEnvelope_loop(tEnvelope* const envlp, int loop)
156−{
157− _tEnvelope* env = *envlp;
158− env->loop = loop;
159−}
160−
161−
162−void tEnvelope_on(tEnvelope* const envlp, float velocity)
163−{
164− _tEnvelope* env = *envlp;
165−
166− if (env->inAttack || env->inDecay) // In case envelope retriggered while it is still happening.
167− {
168− env->rampPhase = 0;
169− env->inRamp = OTRUE;
170− env->rampPeak = env->next;
171− }
172− else // Normal start.
173− {
174− env->inAttack = OTRUE;
175− }
176−
177−
178− env->attackPhase = 0;
179− env->decayPhase = 0;
180− env->inDecay = OFALSE;
181− env->gain = velocity;
182−}
183−
184−float tEnvelope_tick(tEnvelope* const envlp)
185−{
186− _tEnvelope* env = *envlp;
187−
188− if (env->inRamp)
189− {
190− if (env->rampPhase > UINT16_MAX)
191− {
192− env->inRamp = OFALSE;
193− env->inAttack = OTRUE;
194− env->next = 0.0f;
195− }
196− else
197− {
198− env->next = env->rampPeak * env->exp_buff[(uint32_t)env->rampPhase];
199− }
200−
201− env->rampPhase += env->rampInc;
202− }
203−
204− if (env->inAttack)
205− {
206−
207− // If attack done, time to turn around.
208− if (env->attackPhase > UINT16_MAX)
209− {
210− env->inDecay = OTRUE;
211− env->inAttack = OFALSE;
212− env->next = env->gain * 1.0f;
213− }
214− else
215− {
216− // do interpolation !
217− env->next = env->gain * env->exp_buff[UINT16_MAX - (uint32_t)env->attackPhase]; // inverted and backwards to get proper rising exponential shape/perception
218− }
219−
220− // Increment envelope attack.
221− env->attackPhase += env->attackInc;
222−
223− }
224−
225− if (env->inDecay)
226− {
227−
228− // If decay done, finish.
229− if (env->decayPhase >= UINT16_MAX)
230− {
231− env->inDecay = OFALSE;
232−
233− if (env->loop)
234− {
235− env->attackPhase = 0;
236− env->decayPhase = 0;
237− env->inAttack = OTRUE;
238− }
239− else
240− {
241− env->next = 0.0f;
242− }
243−
244− } else {
245−
246− env->next = env->gain * (env->exp_buff[(uint32_t)env->decayPhase]); // do interpolation !
247− }
248−
249− // Increment envelope decay;
250− env->decayPhase += env->decayInc;
251− }
252−
253− return env->next;
254−}
255−
256−
257−
258−/* ADSR */
259−void tADSR_init(tADSR* const adsrenv, float attack, float decay, float sustain, float release)
260−{
261− tADSR_initToPool(adsrenv, attack, decay, sustain, release, &leaf.mempool);
262−}
263−
264−void tADSR_free(tADSR* const adsrenv)
265−{
266− tADSR_freeFromPool(adsrenv, &leaf.mempool);
267−}
268−
269−void tADSR_initToPool (tADSR* const adsrenv, float attack, float decay, float sustain, float release, tMempool* const mp)
270−{
271− _tMempool* m = *mp;
272− _tADSR* adsr = *adsrenv = (_tADSR*) mpool_alloc(sizeof(_tADSR), m);
273−
274− adsr->exp_buff = __leaf_table_exp_decay;
275− adsr->inc_buff = __leaf_table_attack_decay_inc;
276− adsr->buff_size = sizeof(__leaf_table_exp_decay);
277−
278− if (attack > 8192.0f)
279− attack = 8192.0f;
280− if (attack < 0.0f)
281− attack = 0.0f;
282−
283− if (decay > 8192.0f)
284− decay = 8192.0f;
285− if (decay < 0.0f)
286− decay = 0.0f;
287−
288− if (sustain > 1.0f)
289− sustain = 1.0f;
290− if (sustain < 0.0f)
291− sustain = 0.0f;
292−
293− if (release > 8192.0f)
294− release = 8192.0f;
295− if (release < 0.0f)
296− release = 0.0f;
297−
298− int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
299− int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
300− int16_t releaseIndex = ((int16_t)(release * 8.0f))-1;
301− int16_t rampIndex = ((int16_t)(2.0f * 8.0f))-1;
302−
303− if (attackIndex < 0)
304− attackIndex = 0;
305− if (decayIndex < 0)
306− decayIndex = 0;
307− if (releaseIndex < 0)
308− releaseIndex = 0;
309− if (rampIndex < 0)
310− rampIndex = 0;
311−
312− adsr->next = 0.0f;
313−
314− adsr->inRamp = OFALSE;
315− adsr->inAttack = OFALSE;
316− adsr->inDecay = OFALSE;
317− adsr->inSustain = OFALSE;
318− adsr->inRelease = OFALSE;
319−
320− adsr->sustain = sustain;
321−
322− adsr->attackInc = adsr->inc_buff[attackIndex];
323− adsr->decayInc = adsr->inc_buff[decayIndex];
324− adsr->releaseInc = adsr->inc_buff[releaseIndex];
325− adsr->rampInc = adsr->inc_buff[rampIndex];
326−
327− adsr->leakFactor = 1.0f;
328−}
329−
330−void tADSR_freeFromPool (tADSR* const adsrenv, tMempool* const mp)
331−{
332− _tMempool* m = *mp;
333− _tADSR* adsr = *adsrenv;
334− mpool_free((char*)adsr, m);
335−}
336−
337−void tADSR_setAttack(tADSR* const adsrenv, float attack)
338−{
339− _tADSR* adsr = *adsrenv;
340−
341− int32_t attackIndex;
342−
343− if (attack < 0.0f) {
344− attackIndex = 0.0f;
345− } else if (attack < 8192.0f) {
346− attackIndex = ((int32_t)(attack * 8.0f))-1;
347− } else {
348− attackIndex = ((int32_t)(8192.0f * 8.0f))-1;
349− }
350−
351− adsr->attackInc = adsr->inc_buff[attackIndex];
352−}
353−
354−void tADSR_setDecay(tADSR* const adsrenv, float decay)
355−{
356− _tADSR* adsr = *adsrenv;
357−
358− int32_t decayIndex;
359−
360− if (decay < 0.0f) {
361− decayIndex = 0.0f;
362− } else if (decay < 8192.0f) {
363− decayIndex = ((int32_t)(decay * 8.0f)) - 1;
364− } else {
365− decayIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
366− }
367−
368− adsr->decayInc = adsr->inc_buff[decayIndex];
369−}
370−
371−void tADSR_setSustain(tADSR* const adsrenv, float sustain)
372−{
373− _tADSR* adsr = *adsrenv;
374−
375− if (sustain > 1.0f) adsr->sustain = 1.0f;
376− else if (sustain < 0.0f) adsr->sustain = 0.0f;
377− else adsr->sustain = sustain;
378−}
379−
380−void tADSR_setRelease(tADSR* const adsrenv, float release)
381−{
382− _tADSR* adsr = *adsrenv;
383−
384− int32_t releaseIndex;
385−
386− if (release < 0.0f) {
387− releaseIndex = 0.0f;
388− } else if (release < 8192.0f) {
389− releaseIndex = ((int32_t)(release * 8.0f)) - 1;
390− } else {
391− releaseIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
392− }
393−
394− adsr->releaseInc = adsr->inc_buff[releaseIndex];
395−}
396−
397−// 0.999999 is slow leak, 0.9 is fast leak
398−void tADSR_setLeakFactor(tADSR* const adsrenv, float leakFactor)
399−{
400− _tADSR* adsr = *adsrenv;
401−
402−
403− adsr->leakFactor = leakFactor;
404−}
405−
406−void tADSR_on(tADSR* const adsrenv, float velocity)
407−{
408− _tADSR* adsr = *adsrenv;
409−
410− if ((adsr->inAttack || adsr->inDecay) || (adsr->inSustain || adsr->inRelease)) // In case ADSR retriggered while it is still happening.
411− {
412− adsr->rampPhase = 0;
413− adsr->inRamp = OTRUE;
414− adsr->rampPeak = adsr->next;
415− }
416− else // Normal start.
417− {
418− adsr->inAttack = OTRUE;
419− }
420−
421− adsr->attackPhase = 0;
422− adsr->decayPhase = 0;
423− adsr->releasePhase = 0;
424− adsr->inDecay = OFALSE;
425− adsr->inSustain = OFALSE;
426− adsr->inRelease = OFALSE;
427− adsr->gain = velocity;
428−}
429−
430−void tADSR_off(tADSR* const adsrenv)
431−{
432− _tADSR* adsr = *adsrenv;
433−
434− if (adsr->inRelease) return;
435−
436− adsr->inAttack = OFALSE;
437− adsr->inDecay = OFALSE;
438− adsr->inSustain = OFALSE;
439− adsr->inRelease = OTRUE;
440−
441− adsr->releasePeak = adsr->next;
442−}
443−
444−float tADSR_tick(tADSR* const adsrenv)
445−{
446− _tADSR* adsr = *adsrenv;
447−
448−
449− if (adsr->inRamp)
450− {
451− if (adsr->rampPhase > UINT16_MAX)
452− {
453− adsr->inRamp = OFALSE;
454− adsr->inAttack = OTRUE;
455− adsr->next = 0.0f;
456− }
457− else
458− {
459− adsr->next = adsr->rampPeak * adsr->exp_buff[(uint32_t)adsr->rampPhase];
460− }
461−
462− adsr->rampPhase += adsr->rampInc;
463− }
464−
465− if (adsr->inAttack)
466− {
467−
468− // If attack done, time to turn around.
469− if (adsr->attackPhase > UINT16_MAX)
470− {
471− adsr->inDecay = OTRUE;
472− adsr->inAttack = OFALSE;
473− adsr->next = adsr->gain * 1.0f;
474− }
475− else
476− {
477− // do interpolation !
478− adsr->next = adsr->gain * adsr->exp_buff[UINT16_MAX - (uint32_t)adsr->attackPhase]; // inverted and backwards to get proper rising exponential shape/perception
479− }
480−
481− // Increment ADSR attack.
482− adsr->attackPhase += adsr->attackInc;
483−
484− }
485−
486− if (adsr->inDecay)
487− {
488−
489− // If decay done, sustain.
490− if (adsr->decayPhase >= UINT16_MAX)
491− {
492− adsr->inDecay = OFALSE;
493− adsr->inSustain = OTRUE;
494− adsr->next = adsr->gain * adsr->sustain;
495− }
496−
497− else
498− {
499− adsr->next = (adsr->gain * (adsr->sustain + ((adsr->exp_buff[(uint32_t)adsr->decayPhase]) * (1.0f - adsr->sustain)))) * adsr->leakFactor; // do interpolation !
500− }
501−
502− // Increment ADSR decay.
503− adsr->decayPhase += adsr->decayInc;
504− }
505−
506− if (adsr->inSustain)
507− {
508− adsr->next = adsr->next * adsr->leakFactor;
509− }
510−
511− if (adsr->inRelease)
512− {
513− // If release done, finish.
514− if (adsr->releasePhase >= UINT16_MAX)
515− {
516− adsr->inRelease = OFALSE;
517− adsr->next = 0.0f;
518− }
519− else {
520−
521− adsr->next = adsr->releasePeak * (adsr->exp_buff[(uint32_t)adsr->releasePhase]); // do interpolation !
522− }
523−
524− // Increment envelope release;
525− adsr->releasePhase += adsr->releaseInc;
526− }
527−
528−
529− return adsr->next;
530−}
531−
532−
533−
534−
535−/* ADSR 2*/
536−//This one is adapted from the VCV Rack code
537−//-JS
538−
539−
540−
541−const float ADSR2_MIN_TIME = 1e-3f;
542−const float ADSR2_INV_MIN_TIME = 1000.0f;
543−const float ADSR2_MAX_TIME = 10.f;
544−const float ADSR2_LAMBDA_BASE = 10000.0f;
545−
546−
547−void tADSR2_init(tADSR2* const adsrenv, float attack, float decay, float sustain, float release)
548−{
549− tADSR2_initToPool(adsrenv, attack, decay, sustain, release, &leaf.mempool);
550−}
551−
552−void tADSR2_free(tADSR2* const adsrenv)
553−{
554− tADSR2_freeFromPool(adsrenv, &leaf.mempool);
555−}
556−
557−void tADSR2_initToPool (tADSR2* const adsrenv, float attack, float decay, float sustain, float release, tMempool* const mp)
558−{
559− _tMempool* m = *mp;
560− _tADSR2* adsr = *adsrenv = (_tADSR2*) mpool_alloc(sizeof(_tADSR2), m);
561− adsr->sampleRateInMs = leaf.sampleRate * 0.001f;
562− adsr->attack = LEAF_clip(0.0f, attack * 0.001f, 1.0f);
563− adsr->attackLambda = powf(ADSR2_LAMBDA_BASE, -adsr->attack) * ADSR2_INV_MIN_TIME;
564−
565−
566− adsr->decay = LEAF_clip(0.0f, decay * 0.001f, 1.0f);
567− adsr->decayLambda = powf(ADSR2_LAMBDA_BASE, -adsr->decay) * ADSR2_INV_MIN_TIME;
568−
569−
570− adsr->sustain= sustain;
571−
572−
573− adsr->release = LEAF_clip(0.0f, release * 0.001f, 1.0f);
574− adsr->releaseLambda = powf(ADSR2_LAMBDA_BASE, -adsr->release) * ADSR2_INV_MIN_TIME;
575−
576− adsr->attacking = 0;
577− adsr->gate = 0;
578− adsr->gain = 1.0f;
579− adsr->targetGainSquared = 1.0f;
580− adsr->factor = 0.01f;
581− adsr->oneMinusFactor = 0.99f;
582− adsr->env = 0.0f;
583− adsr->leakFactor = 1.0f;
584−}
585−
586−void tADSR2_freeFromPool (tADSR2* const adsrenv, tMempool* const mp)
587−{
588− _tMempool* m = *mp;
589− _tADSR2* adsr = *adsrenv;
590− mpool_free((char*)adsr, m);
591−}
592−
593−void tADSR2_setAttack(tADSR2* const adsrenv, float attack)
594−{
595− _tADSR2* adsr = *adsrenv;
596− adsr->attack = LEAF_clip(0.0f, attack * 0.001f, 1.0f);
597− adsr->attackLambda = fastPow(ADSR2_LAMBDA_BASE, -adsr->attack) * ADSR2_INV_MIN_TIME;
598−
599−}
600−
601−void tADSR2_setDecay(tADSR2* const adsrenv, float decay)
602−{
603− _tADSR2* adsr = *adsrenv;
604− adsr->decay = LEAF_clip(0.0f, decay * 0.001f, 1.0f);
605− adsr->decayLambda = fastPow(ADSR2_LAMBDA_BASE, -adsr->decay) * ADSR2_INV_MIN_TIME;
606−
607−}
608−
609−void tADSR2_setSustain(tADSR2* const adsrenv, float sustain)
610−{
611− _tADSR2* adsr = *adsrenv;
612− adsr->sustain = sustain;
613−
614− if (adsr->gate)
615− {
616− if (adsr->attacking == 0)
617− {
618− adsr->envTarget = sustain;
619− }
620− }
621−}
622−
623−void tADSR2_setRelease(tADSR2* const adsrenv, float release)
624−{
625− _tADSR2* adsr = *adsrenv;
626− adsr->release = LEAF_clip(0.0f, release * 0.001f, 1.0f);
627− adsr->releaseLambda = fastPow(ADSR2_LAMBDA_BASE, -adsr->release) * ADSR2_INV_MIN_TIME;
628−}
629−
630−// 0.999999 is slow leak, 0.9 is fast leak
631−void tADSR2_setLeakFactor(tADSR2* const adsrenv, float leakFactor)
632−{
633− _tADSR2* adsr = *adsrenv;
634−
635− adsr->leakFactor = leakFactor;
636−}
637−
638−void tADSR2_on(tADSR2* const adsrenv, float velocity)
639−{
640− _tADSR2* adsr = *adsrenv;
641− adsr->targetGainSquared = velocity * velocity;
642− adsr->envTarget = 1.2f;
643− adsr->leakGain = 1.0f;
644− adsr->gate = 1;
645− adsr->attacking = 1;
646−}
647−
648−void tADSR2_off(tADSR2* const adsrenv)
649−{
650− _tADSR2* adsr = *adsrenv;
651− adsr->gate = 0;
652− adsr->envTarget = 0.0f;
653−}
654−
655−float tADSR2_tick(tADSR2* const adsrenv)
656−{
657− _tADSR2* adsr = *adsrenv;
658− float lambda;
659−
660− if (adsr->gate)
661− {
662− if (adsr->attacking)
663− {
664− lambda = adsr->attackLambda;
665− }
666− else
667− {
668− lambda = adsr->decayLambda;
669− }
670− }
671− else
672− {
673− lambda = adsr->releaseLambda;
674− }
675−
676−
677− // Adjust env
678− adsr->env += (adsr->envTarget - adsr->env) * lambda * leaf.invSampleRate;
679−
680− // Turn off attacking state if envelope is HIGH
681− if (adsr->env >= 1.0f)
682− {
683− adsr->attacking = 0;
684− adsr->envTarget = adsr->sustain;
685− }
686−
687− //smooth the gain value -- this is not ideal, a retrigger while the envelope is still going with a new gain will cause a jump, although it will be smoothed quickly. Maybe doing the math so the range is computed based on the gain rather than 0.->1. is preferable? But that's harder to get the exponential curve right without a lookup.
688− adsr->gain = ((adsr->factor*adsr->targetGainSquared)+(adsr->oneMinusFactor*adsr->gain));
689− adsr->leakGain *= adsr->leakFactor;
690− return adsr->env * adsr->gain * adsr->leakGain;
691−}
692−
693−/* ADSR 3*/
694−//This one doesn't use any lookup table - by Nigel Redmon from his blog. Thanks, Nigel!
695−//-JS
696−
697−float calcADSR3Coef(double rate, double targetRatio)
698−{
699− return (rate <= 0.0f) ? 0.0f : exp(-log((1.0 + targetRatio) / targetRatio) / rate);
700−}
701−
702−
703−void tADSR3_init(tADSR3* const adsrenv, float attack, float decay, float sustain, float release)
704−{
705− tADSR3_initToPool(adsrenv, attack, decay, sustain, release, &leaf.mempool);
706−}
707−
708−void tADSR3_free(tADSR3* const adsrenv)
709−{
710− tADSR3_freeFromPool(adsrenv, &leaf.mempool);
711−}
712−
713−void tADSR3_initToPool (tADSR3* const adsrenv, float attack, float decay, float sustain, float release, tMempool* const mp)
714−{
715− _tMempool* m = *mp;
716− _tADSR3* adsr = *adsrenv = (_tADSR3*) mpool_alloc(sizeof(_tADSR3), m);
717− adsr->sampleRateInMs = leaf.sampleRate * 0.001f;
718− adsr->targetRatioA = 0.3f;
719− adsr->targetRatioDR = 0.0001f;
720− adsr->attackRate = attack * adsr->sampleRateInMs;
721− adsr->attackCoef = calcADSR3Coef(attack * adsr->sampleRateInMs, adsr->targetRatioA);
722− adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
723−
724− adsr->decayRate = decay * adsr->sampleRateInMs;
725− adsr->decayCoef = calcADSR3Coef(decay * adsr->sampleRateInMs,adsr-> targetRatioDR);
726− adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
727−
728− adsr->sustainLevel = sustain;
729− adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
730−
731− adsr->releaseRate = release * adsr->sampleRateInMs;
732− adsr->releaseCoef = calcADSR3Coef(release * adsr->sampleRateInMs, adsr->targetRatioDR);
733− adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
734−
735− adsr->state = env_idle;
736− adsr->gain = 1.0f;
737− adsr->targetGainSquared = 1.0f;
738− adsr->factor = 0.01f;
739− adsr->oneMinusFactor = 0.99f;
740− adsr->output = 0.0f;
741− adsr->leakFactor = 1.0f;
742−}
743−
744−void tADSR3_freeFromPool (tADSR3* const adsrenv, tMempool* const mp)
745−{
746− _tMempool* m = *mp;
747− _tADSR3* adsr = *adsrenv;
748− mpool_free((char*)adsr, m);
749−}
750−
751−void tADSR3_setAttack(tADSR3* const adsrenv, float attack)
752−{
753− _tADSR3* adsr = *adsrenv;
754−
755− adsr->attackRate = attack * adsr->sampleRateInMs;
756− adsr->attackCoef = calcADSR3Coef(adsr->attackRate, adsr->targetRatioA);
757− adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
758−}
759−
760−void tADSR3_setDecay(tADSR3* const adsrenv, float decay)
761−{
762− _tADSR3* adsr = *adsrenv;
763−
764− adsr->decayRate = decay * adsr->sampleRateInMs;
765− adsr->decayCoef = calcADSR3Coef(adsr->decayRate,adsr-> targetRatioDR);
766− adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
767−}
768−
769−void tADSR3_setSustain(tADSR3* const adsrenv, float sustain)
770−{
771− _tADSR3* adsr = *adsrenv;
772−
773− adsr->sustainLevel = sustain;
774− adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
775−}
776−
777−void tADSR3_setRelease(tADSR3* const adsrenv, float release)
778−{
779− _tADSR3* adsr = *adsrenv;
780−
781− adsr->releaseRate = release * adsr->sampleRateInMs;
782− adsr->releaseCoef = calcADSR3Coef(adsr->releaseRate, adsr->targetRatioDR);
783− adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
784−}
785−
786−// 0.999999 is slow leak, 0.9 is fast leak
787−void tADSR3_setLeakFactor(tADSR3* const adsrenv, float leakFactor)
788−{
789− _tADSR3* adsr = *adsrenv;
790−
791− adsr->leakFactor = leakFactor;
792−}
793−
794−void tADSR3_on(tADSR3* const adsrenv, float velocity)
795−{
796− _tADSR3* adsr = *adsrenv;
797− adsr->state = env_attack;
798− adsr->targetGainSquared = velocity * velocity;
799−}
800−
801−void tADSR3_off(tADSR3* const adsrenv)
802−{
803− _tADSR3* adsr = *adsrenv;
804−
805− if (adsr->state != env_idle)
806− {
807− adsr->state = env_release;
808− }
809−}
810−
811−float tADSR3_tick(tADSR3* const adsrenv)
812−{
813− _tADSR3* adsr = *adsrenv;
814−
815−
816− switch (adsr->state) {
817− case env_idle:
818− break;
819− case env_attack:
820− adsr->output = adsr->attackBase + adsr->output * adsr->attackCoef;
821− if (adsr->output >= 1.0f) {
822− adsr->output = 1.0f;
823− adsr->state = env_decay;
824− }
825− break;
826− case env_decay:
827− adsr->output = adsr->decayBase + adsr->output * adsr->decayCoef * adsr->leakFactor;
828− if (adsr->output <= adsr->sustainLevel) {
829− adsr->output = adsr->sustainLevel;
830− adsr->state = env_sustain;
831− }
832− break;
833− case env_sustain:
834− adsr->output = adsr->output * adsr->leakFactor;
835− break;
836− case env_release:
837− adsr->output = adsr->releaseBase + adsr->output * adsr->releaseCoef;
838− if (adsr->output <= 0.0f) {
839− adsr->output = 0.0f;
840− adsr->state = env_idle;
841− }
842− }
843− //smooth the gain value -- this is not ideal, a retrigger while the envelope is still going with a new gain will cause a jump, although it will be smoothed quickly. Maybe doing the math so the range is computed based on the gain rather than 0.->1. is preferable? But that's harder to get the exponential curve right without a lookup.
844− adsr->gain = (adsr->factor*adsr->targetGainSquared)+(adsr->oneMinusFactor*adsr->gain);
845− return adsr->output * adsr->gain;
846−}
847−
848−
849−/* ADSR 4 */ // new version of our original table-based ADSR but with the table passed in by the user
850−// use this if the size of the big ADSR tables is too much.
851−void tADSR4_init (tADSR4* const adsrenv, float attack, float decay, float sustain, float release, float* expBuffer, int bufferSize)
852−{
853− tADSR4_initToPool (adsrenv, attack, decay, sustain, release, expBuffer, bufferSize, &leaf.mempool);
854−}
855−
856−void tADSR4_free(tADSR4* const adsrenv)
857−{
858− tADSR4_freeFromPool(adsrenv, &leaf.mempool);
859−}
860−
861−//initialize with an exponential function that decays -- i.e. a call to LEAF_generate_exp(expBuffer, 0.001f, 0.0f, 1.0f, -0.0008f, EXP_BUFFER_SIZE);
862−//times are in ms
863−void tADSR4_initToPool (tADSR4* const adsrenv, float attack, float decay, float sustain, float release, float* expBuffer, int bufferSize, tMempool* const mp)
864−{
865− _tMempool* m = *mp;
866− _tADSR4* adsr = *adsrenv = (_tADSR4*) mpool_alloc(sizeof(_tADSR4), m);
867−
868− adsr->exp_buff = expBuffer;
869− adsr->buff_size = bufferSize;
870− adsr->buff_sizeMinusOne = bufferSize - 1;
871−
872− adsr->bufferSizeDividedBySampleRateInMs = bufferSize / (leaf.sampleRate * 0.001f);
873−
874− if (attack < 0.0f)
875− attack = 0.0f;
876−
877− if (decay < 0.0f)
878− decay = 0.0f;
879−
880− if (sustain > 1.0f)
881− sustain = 1.0f;
882− if (sustain < 0.0f)
883− sustain = 0.0f;
884−
885− if (release < 0.0f)
886− release = 0.0f;
887−
888− adsr->next = 0.0f;
889−
890− adsr->whichStage = env_idle;
891−
892− adsr->sustain = sustain;
893−
894− adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
895− adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
896− adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
897− adsr->rampInc = adsr->bufferSizeDividedBySampleRateInMs / 8.0f;
898−
899− adsr->leakFactor = 1.0f;
900−}
901−
902−void tADSR4_freeFromPool (tADSR4* const adsrenv, tMempool* const mp)
903−{
904− _tMempool* m = *mp;
905− _tADSR4* adsr = *adsrenv;
906− mpool_free((char*)adsr, m);
907−}
908−
909−void tADSR4_setAttack(tADSR4* const adsrenv, float attack)
910−{
911− _tADSR4* adsr = *adsrenv;
912−
913− if (attack < 0.0f)
914− {
915− attack = 0.0f;
916− }
917−
918− adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
919−}
920−
921−void tADSR4_setDecay(tADSR4* const adsrenv, float decay)
922−{
923− _tADSR4* adsr = *adsrenv;
924−
925− if (decay < 0.0f)
926− {
927− decay = 0.0f;
928− }
929− adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
930−}
931−
932−void tADSR4_setSustain(tADSR4* const adsrenv, float sustain)
933−{
934− _tADSR4* adsr = *adsrenv;
935−
936− if (sustain > 1.0f) adsr->sustain = 1.0f;
937− else if (sustain < 0.0f) adsr->sustain = 0.0f;
938− else adsr->sustain = sustain;
939−}
940−
941−void tADSR4_setRelease(tADSR4* const adsrenv, float release)
942−{
943− _tADSR4* adsr = *adsrenv;
944−
945− if (release < 0.0f)
946− {
947− release = 0.0f;
948− }
949− adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
950−}
951−
952−// 0.999999 is slow leak, 0.9 is fast leak
953−void tADSR4_setLeakFactor(tADSR4* const adsrenv, float leakFactor)
954−{
955− _tADSR4* adsr = *adsrenv;
956−
957−
958− adsr->leakFactor = leakFactor;
959−}
960−
961−void tADSR4_on(tADSR4* const adsrenv, float velocity)
962−{
963− _tADSR4* adsr = *adsrenv;
964−
965− if (adsr->whichStage != env_idle) // In case ADSR retriggered while it is still happening.
966− {
967− adsr->rampPhase = 0;
968− adsr->whichStage = env_ramp;
969− adsr->rampPeak = adsr->next;
970− }
971− else // Normal start.
972− {
973− adsr->whichStage = env_attack;
974− }
975−
976− adsr->attackPhase = 0;
977− adsr->decayPhase = 0;
978− adsr->releasePhase = 0;
979− adsr->gain = velocity;
980−}
981−
982−void tADSR4_off(tADSR4* const adsrenv)
983−{
984− _tADSR4* adsr = *adsrenv;
985−
986− if (adsr->whichStage == env_idle)
987− {
988− return;
989− }
990− else
991− {
992− adsr->whichStage = env_release;
993− adsr->releasePeak = adsr->next;
994− }
995−}
996−
997−float tADSR4_tick(tADSR4* const adsrenv)
998−{
999− _tADSR4* adsr = *adsrenv;
1000−
1001− switch (adsr->whichStage)
1002− {
1003− case env_ramp:
1004− if (adsr->rampPhase > adsr->buff_sizeMinusOne)
1005− {
1006− adsr->whichStage = env_attack;
1007− adsr->next = 0.0f;
1008− }
1009− else
1010− {
1011− uint32_t intPart = (uint32_t)adsr->rampPhase;
1012− float floatPart = adsr->rampPhase - intPart;
1013− float secondValue;
1014− if (adsr->rampPhase + 1.0f > adsr->buff_sizeMinusOne)
1015− {
1016− secondValue = 0.0f;
1017− }
1018− else
1019− {
1020− secondValue = adsr->exp_buff[(uint32_t)((adsr->rampPhase)+1)];
1021− }
1022− adsr->next = adsr->rampPeak * LEAF_interpolation_linear(adsr->exp_buff[intPart], secondValue, floatPart);
1023− }
1024−
1025− adsr->rampPhase += adsr->rampInc;
1026− break;
1027−
1028−
1029− case env_attack:
1030−
1031− // If attack done, time to turn around.
1032− if (adsr->attackPhase > adsr->buff_sizeMinusOne)
1033− {
1034− adsr->whichStage = env_decay;
1035− adsr->next = adsr->gain;
1036− }
1037− else
1038− {
1039− // do interpolation !
1040− uint32_t intPart = (uint32_t)adsr->attackPhase;
1041− float floatPart = adsr->attackPhase - intPart;
1042− float secondValue;
1043− if (adsr->attackPhase + 1.0f > adsr->buff_sizeMinusOne)
1044− {
1045− secondValue = 0.0f;
1046− }
1047− else
1048− {
1049− secondValue = adsr->exp_buff[(uint32_t)((adsr->attackPhase)+1)];
1050− }
1051−
1052− adsr->next = adsr->gain * (1.0f - LEAF_interpolation_linear(adsr->exp_buff[intPart], secondValue, floatPart)); // inverted and backwards to get proper rising exponential shape/perception
1053− }
1054−
1055− // Increment ADSR attack.
1056− adsr->attackPhase += adsr->attackInc;
1057− break;
1058−
1059− case env_decay:
1060−
1061− // If decay done, sustain.
1062− if (adsr->decayPhase > adsr->buff_sizeMinusOne)
1063− {
1064− adsr->whichStage = env_sustain;
1065− adsr->next = adsr->gain * adsr->sustain;
1066− }
1067−
1068− else
1069− {
1070− uint32_t intPart = (uint32_t)adsr->decayPhase;
1071− float floatPart = adsr->decayPhase - intPart;
1072− float secondValue;
1073− if (adsr->decayPhase + 1.0f > adsr->buff_sizeMinusOne)
1074− {
1075− secondValue = 0.0f;
1076− }
1077− else
1078− {
1079− secondValue = adsr->exp_buff[(uint32_t)((adsr->decayPhase)+1)];
1080− }
1081− float interpValue = (LEAF_interpolation_linear(adsr->exp_buff[intPart], secondValue, floatPart));
1082− adsr->next = (adsr->gain * (adsr->sustain + (interpValue * (1.0f - adsr->sustain)))) * adsr->leakFactor; // do interpolation !
1083− }
1084−
1085− // Increment ADSR decay.
1086− adsr->decayPhase += adsr->decayInc;
1087− break;
1088−
1089− case env_sustain:
1090− adsr->next = adsr->next * adsr->leakFactor;
1091− break;
1092−
1093− case env_release:
1094− // If release done, finish.
1095− if (adsr->releasePhase > adsr->buff_sizeMinusOne)
1096− {
1097− adsr->whichStage = env_idle;
1098− adsr->next = 0.0f;
1099− }
1100− else {
1101− uint32_t intPart = (uint32_t)adsr->releasePhase;
1102− float floatPart = adsr->releasePhase - intPart;
1103− float secondValue;
1104− if (adsr->releasePhase + 1.0f > adsr->buff_sizeMinusOne)
1105− {
1106− secondValue = 0.0f;
1107− }
1108− else
1109− {
1110− secondValue = adsr->exp_buff[(uint32_t)((adsr->releasePhase)+1)];
1111− }
1112− adsr->next = adsr->releasePeak * (LEAF_interpolation_linear(adsr->exp_buff[intPart], secondValue, floatPart)); // do interpolation !
1113− }
1114−
1115− // Increment envelope release;
1116− adsr->releasePhase += adsr->releaseInc;
1117− break;
1118− }
1119− return adsr->next;
1120−}
1121−
1122−float tADSR4_tickNoInterp(tADSR4* const adsrenv)
1123−{
1124− _tADSR4* adsr = *adsrenv;
1125−
1126− switch (adsr->whichStage)
1127− {
1128− case env_ramp:
1129− if (adsr->rampPhase > adsr->buff_sizeMinusOne)
1130− {
1131− adsr->whichStage = env_attack;
1132− adsr->next = 0.0f;
1133− }
1134− else
1135− {
1136− adsr->next = adsr->rampPeak * adsr->exp_buff[(uint32_t)adsr->rampPhase];
1137− }
1138−
1139− adsr->rampPhase += adsr->rampInc;
1140− break;
1141−
1142−
1143− case env_attack:
1144−
1145− // If attack done, time to turn around.
1146− if (adsr->attackPhase > adsr->buff_sizeMinusOne)
1147− {
1148− adsr->whichStage = env_decay;
1149− adsr->next = adsr->gain;
1150− }
1151− else
1152− {
1153− adsr->next = adsr->gain * (1.0f - adsr->exp_buff[(uint32_t)adsr->attackPhase]); // inverted and backwards to get proper rising exponential shape/perception
1154− }
1155−
1156− // Increment ADSR attack.
1157− adsr->attackPhase += adsr->attackInc;
1158− break;
1159−
1160− case env_decay:
1161−
1162− // If decay done, sustain.
1163− if (adsr->decayPhase > adsr->buff_sizeMinusOne)
1164− {
1165− adsr->whichStage = env_sustain;
1166− adsr->next = adsr->gain * adsr->sustain;
1167− }
1168−
1169− else
1170− {
1171− adsr->next = (adsr->gain * (adsr->sustain + (adsr->exp_buff[(uint32_t)adsr->decayPhase] * (1.0f - adsr->sustain)))) * adsr->leakFactor;
1172− }
1173−
1174− // Increment ADSR decay.
1175− adsr->decayPhase += adsr->decayInc;
1176− break;
1177−
1178− case env_sustain:
1179− adsr->next = adsr->next * adsr->leakFactor;
1180− break;
1181−
1182− case env_release:
1183− // If release done, finish.
1184− if (adsr->releasePhase > adsr->buff_sizeMinusOne)
1185− {
1186− adsr->whichStage = env_idle;
1187− adsr->next = 0.0f;
1188− }
1189− else {
1190− adsr->next = adsr->releasePeak * adsr->exp_buff[(uint32_t)adsr->releasePhase];
1191− }
1192−
1193− // Increment envelope release;
1194− adsr->releasePhase += adsr->releaseInc;
1195− break;
1196− }
1197− return adsr->next;
1198−}
1199−
1200−
1201−
1202−/////-----------------
1203−/* Ramp */
1204−void tRamp_init(tRamp* const r, float time, int samples_per_tick)
1205−{
1206− _tRamp* ramp = *r = (_tRamp*) leaf_alloc(sizeof(_tRamp));
1207−
1208− ramp->inv_sr_ms = 1.0f/(leaf.sampleRate*0.001f);
1209− ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
1210− ramp->curr = 0.0f;
1211− ramp->dest = 0.0f;
1212−
1213− if (time < ramp->minimum_time)
1214− {
1215− ramp->time = ramp->minimum_time;
1216− }
1217− else
1218− {
1219− ramp->time = time;
1220− }
1221− ramp->factor = (1.0f / ramp->time) * ramp->inv_sr_ms;
1222− ramp->samples_per_tick = samples_per_tick;
1223− ramp->inc = ((ramp->dest - ramp->curr) / ramp->time * ramp->inv_sr_ms) * (float)ramp->samples_per_tick;
1224−}
1225−
1226−void tRamp_free(tRamp* const r)
1227−{
1228− _tRamp* ramp = *r;
1229−
1230− leaf_free((char*)ramp);
1231−}
1232−
1233−void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, tMempool* const mp)
1234−{
1235− _tMempool* m = *mp;
1236− _tRamp* ramp = *r = (_tRamp*) mpool_alloc(sizeof(_tRamp), m);
1237−
1238− ramp->inv_sr_ms = 1.0f/(leaf.sampleRate*0.001f);
1239− ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
1240− ramp->curr = 0.0f;
1241− ramp->dest = 0.0f;
1242−
1243− if (time < ramp->minimum_time)
1244− {
1245− ramp->time = ramp->minimum_time;
1246− }
1247− else
1248− {
1249− ramp->time = time;
1250− }
1251− ramp->samples_per_tick = samples_per_tick;
1252− ramp->factor = (1.0f / ramp->time) * ramp->inv_sr_ms * (float)ramp->samples_per_tick;
1253− ramp->inc = (ramp->dest - ramp->curr) * ramp->factor;
1254−}
1255−
1256−void tRamp_freeFromPool (tRamp* const r, tMempool* const mp)
1257−{
1258− _tMempool* m = *mp;
1259− _tRamp* ramp = *r;
1260−
1261− mpool_free((char*)ramp, m);
1262−}
1263−
1264−void tRamp_setTime(tRamp* const ramp, float time)
1265−{
1266− _tRamp* r = *ramp;
1267−
1268− if (time < r->minimum_time)
1269− {
1270− r->time = r->minimum_time;
1271− }
1272− else
1273− {
1274− r->time = time;
1275− }
1276− r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;
1277− r->inc = (r->dest - r->curr) * r->factor;
1278−
1279−}
1280−
1281−void tRamp_setDest(tRamp* const ramp, float dest)
1282−{
1283− _tRamp* r = *ramp;
1284− r->dest = dest;
1285− r->inc = (r->dest - r->curr) * r->factor;
1286−}
1287−
1288−void tRamp_setVal(tRamp* const ramp, float val)
1289−{
1290− _tRamp* r = *ramp;
1291− r->curr = val;
1292− r->inc = (r->dest - r->curr) * r->factor;
1293−}
1294−
1295−float tRamp_tick(tRamp* const ramp)
1296−{
1297− _tRamp* r = *ramp;
1298−
1299− r->curr += r->inc;
1300−
1301− if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f)))
1302− {
1303− r->inc = 0.0f;
1304− r->curr=r->dest;
1305− }
1306−
1307− return r->curr;
1308−}
1309−
1310−float tRamp_sample(tRamp* const ramp)
1311−{
1312− _tRamp* r = *ramp;
1313− return r->curr;
1314−}
1315−
1316−void tRampSampleRateChanged(tRamp* const ramp)
1317−{
1318− _tRamp* r = *ramp;
1319− r->inv_sr_ms = 1.0f / (leaf.sampleRate * 0.001f);
1320− r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;
1321− r->inc = (r->dest - r->curr) * r->factor;
1322−}
1323−
1324−
1325−
1326−/* RampUpDown */
1327−void tRampUpDown_init(tRampUpDown* const r, float upTime, float downTime, int samples_per_tick)
1328−{
1329− tRampUpDown_initToPool(r, upTime, downTime, samples_per_tick, &leaf.mempool);
1330−}
1331−
1332−void tRampUpDown_free(tRampUpDown* const r)
1333−{
1334− tRampUpDown_freeFromPool(r, &leaf.mempool);
1335−}
1336−
1337−void tRampUpDown_initToPool(tRampUpDown* const r, float upTime, float downTime, int samples_per_tick, tMempool* const mp)
1338−{
1339− _tMempool* m = *mp;
1340− _tRampUpDown* ramp = *r = (_tRampUpDown*) mpool_alloc(sizeof(_tRampUpDown), m);
1341−
1342− ramp->inv_sr_ms = 1.0f/(leaf.sampleRate*0.001f);
1343− ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
1344− ramp->curr = 0.0f;
1345− ramp->dest = 0.0f;
1346−
1347− if (upTime < ramp->minimum_time)
1348− {
1349− ramp->upTime = ramp->minimum_time;
1350− }
1351− else
1352− {
1353− ramp->upTime = upTime;
1354− }
1355−
1356− if (downTime < ramp->minimum_time)
1357− {
1358− ramp->downTime = ramp->minimum_time;
1359− }
1360− else
1361− {
1362− ramp->downTime = downTime;
1363− }
1364−
1365− ramp->samples_per_tick = samples_per_tick;
1366− ramp->upInc = ((ramp->dest - ramp->curr) / ramp->upTime * ramp->inv_sr_ms) * (float)ramp->samples_per_tick;
1367− ramp->downInc = ((ramp->dest - ramp->curr) / ramp->downTime * ramp->inv_sr_ms) * (float)ramp->samples_per_tick;
1368−}
1369−
1370−void tRampUpDown_freeFromPool (tRampUpDown* const r, tMempool* const mp)
1371−{
1372− _tMempool* m = *mp;
1373− _tRampUpDown* ramp = *r;
1374−
1375− mpool_free((char*)ramp, m);
1376−}
1377−
1378−void tRampUpDown_setUpTime(tRampUpDown* const ramp, float upTime)
1379−{
1380− _tRampUpDown* r = *ramp;
1381−
1382− if (upTime < r->minimum_time)
1383− {
1384− r->upTime = r->minimum_time;
1385− }
1386− else
1387− {
1388− r->upTime = upTime;
1389− }
1390− r->upInc = ((r->dest - r->curr) / r->upTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1391−}
1392−
1393−
1394−void tRampUpDown_setDownTime(tRampUpDown* const ramp, float downTime)
1395−{
1396− _tRampUpDown* r = *ramp;
1397−
1398− if (downTime < r->minimum_time)
1399− {
1400− r->downTime = r->minimum_time;
1401− }
1402− else
1403− {
1404− r->downTime = downTime;
1405− }
1406− r->downInc = ((r->dest - r->curr) / r->downTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1407−}
1408−
1409−void tRampUpDown_setDest(tRampUpDown* const ramp, float dest)
1410−{
1411− _tRampUpDown* r = *ramp;
1412− r->dest = dest;
1413− r->upInc = ((r->dest - r->curr) / r->upTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1414− r->downInc = ((r->dest - r->curr) / r->downTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1415−}
1416−
1417−void tRampUpDown_setVal(tRampUpDown* const ramp, float val)
1418−{
1419− _tRampUpDown* r = *ramp;
1420− r->curr = val;
1421− r->upInc = ((r->dest - r->curr) / r->upTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1422− r->downInc = ((r->dest - r->curr) / r->downTime * r->inv_sr_ms) * (float)r->samples_per_tick;
1423−}
1424−
1425−float tRampUpDown_tick(tRampUpDown* const ramp)
1426−{
1427− _tRampUpDown* r = *ramp;
1428− float test;
1429−
1430− if (r->dest < r->curr)
1431− {
1432− test = r->curr + r->downInc;
1433− if (test > r->dest)
1434− {
1435− r->curr = test;
1436− }
1437− else
1438− {
1439− r->downInc = 0.0f;
1440− r->curr = r->dest;
1441− }
1442− }
1443− else if (r->dest > r->curr)
1444− {
1445− test = r->curr + r->upInc;
1446− if (test < r->dest)
1447− {
1448− r->curr = test;
1449− }
1450− else
1451− {
1452− r->upInc = 0.0f;
1453− r->curr = r->dest;
1454− }
1455− }
1456− return r->curr;
1457−}
1458−
1459−float tRampUpDown_sample(tRampUpDown* const ramp)
1460−{
1461− _tRampUpDown* r = *ramp;
1462− return r->curr;
1463−}
1464−
1465−
1466−
1467−
1468−
1469−
1470−/* Exponential Smoother */
1471−void tExpSmooth_init(tExpSmooth* const expsmooth, float val, float factor)
1472−{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
1473− _tExpSmooth* smooth = *expsmooth = (_tExpSmooth*) leaf_alloc(sizeof(_tExpSmooth));
1474−
1475− smooth->curr=val;
1476− smooth->dest=val;
1477− if (factor<0) factor=0;
1478− if (factor>1) factor=1;
1479− smooth->factor=factor;
1480− smooth->oneminusfactor=1.0f-factor;
1481−}
1482−
1483−void tExpSmooth_free(tExpSmooth* const expsmooth)
1484−{
1485− _tExpSmooth* smooth = *expsmooth;
1486−
1487− leaf_free((char*)smooth);
1488−}
1489−
1490−void tExpSmooth_initToPool (tExpSmooth* const expsmooth, float val, float factor, tMempool* const mp)
1491−{
1492− _tMempool* m = *mp;
1493− _tExpSmooth* smooth = *expsmooth = (_tExpSmooth*) mpool_alloc(sizeof(_tExpSmooth), m);
1494−
1495− smooth->curr=val;
1496− smooth->dest=val;
1497− if (factor<0) factor=0;
1498− if (factor>1) factor=1;
1499− smooth->factor=factor;
1500− smooth->oneminusfactor=1.0f-factor;
1501−}
1502−
1503−void tExpSmooth_freeFromPool (tExpSmooth* const expsmooth, tMempool* const mp)
1504−{
1505− _tMempool* m = *mp;
1506− _tExpSmooth* smooth = *expsmooth;
1507−
1508− mpool_free((char*)smooth, m);
1509−}
1510−
1511−void tExpSmooth_setFactor(tExpSmooth* const expsmooth, float factor)
1512−{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
1513− _tExpSmooth* smooth = *expsmooth;
1514−
1515− if (factor<0)
1516− factor=0;
1517− else
1518− if (factor>1) factor=1;
1519− smooth->factor=factor;
1520− smooth->oneminusfactor=1.0f-factor;
1521−}
1522−
1523−void tExpSmooth_setDest(tExpSmooth* const expsmooth, float dest)
1524−{
1525− _tExpSmooth* smooth = *expsmooth;
1526− smooth->dest=dest;
1527−}
1528−
1529−void tExpSmooth_setVal(tExpSmooth* const expsmooth, float val)
1530−{
1531− _tExpSmooth* smooth = *expsmooth;
1532− smooth->curr=val;
1533−}
1534−
1535−void tExpSmooth_setValAndDest(tExpSmooth* const expsmooth, float val)
1536−{
1537− _tExpSmooth* smooth = *expsmooth;
1538− smooth->curr=val;
1539− smooth->dest=val;
1540−}
1541−
1542−float tExpSmooth_tick(tExpSmooth* const expsmooth)
1543−{
1544− _tExpSmooth* smooth = *expsmooth;
1545− smooth->curr = smooth->factor*smooth->dest+smooth->oneminusfactor*smooth->curr;
1546− return smooth->curr;
1547−}
1548−
1549−float tExpSmooth_sample(tExpSmooth* const expsmooth)
1550−{
1551− _tExpSmooth* smooth = *expsmooth;
1552− return smooth->curr;
1553−}
1554−
1555−//tSlide is based on the max/msp slide~ object
1556−////
1557−
1558−void tSlide_init (tSlide* const sl, float upSlide, float downSlide)
1559−{
1560− tSlide_initToPool (sl, upSlide, downSlide, &leaf.mempool);
1561−}
1562−void tSlide_free (tSlide* const sl)
1563−{
1564− tSlide_freeFromPool (sl, &leaf.mempool);
1565−}
1566−void tSlide_initToPool (tSlide* const sl, float upSlide, float downSlide, tMempool* const mp)
1567−{
1568− _tMempool* m = *mp;
1569− _tSlide* s = *sl = (_tSlide*) mpool_alloc(sizeof(_tSlide), m);
1570− s->prevIn = 0.0f;
1571− s->currentOut = 0.0f;
1572− s->prevOut = 0.0f;
1573− if (upSlide < 1.0f)
1574− {
1575− upSlide = 1.0f;
1576− }
1577−
1578− if (downSlide < 1.0f)
1579− {
1580− downSlide = 1.0f;
1581− }
1582− s->invUpSlide = 1.0f / upSlide;
1583− s->invDownSlide = 1.0f / downSlide;
1584−}
1585−
1586−void tSlide_freeFromPool (tSlide* const sl, tMempool* const mp)
1587−{
1588− _tMempool* m = *mp;
1589− _tSlide* s = *sl;
1590−
1591− mpool_free((char*)s, m);
1592−}
1593−
1594−float tSlide_tick(tSlide* const sl, float in)
1595−{
1596− _tSlide* s = *sl;
1597−
1598−
1599− if (in >= s->prevOut)
1600− {
1601− s->currentOut = s->prevOut + ((in - s->prevOut) * s->invUpSlide);
1602− }
1603− else
1604− {
1605− s->currentOut = s->prevOut + ((in - s->prevOut) * s->invDownSlide);
1606− }
1607− if (s->currentOut < VSF) s->currentOut = 0.0f;
1608− s->prevIn = in;
1609− s->prevOut = s->currentOut;
1610− return s->currentOut;
1611−}
1612−
LEAF/Src/leaf-filters.c+0−1802
@@ -1,1802 +0,0 @@
1−/*==============================================================================
2−
3− leaf-filter.c
4− Created: 20 Jan 2017 12:01:10pm
5− Author: Michael R Mulshine
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-filters.h"
12−#include "..\Inc\leaf-tables.h"
13−#include "..\leaf.h"
14−
15−#else
16−
17−#include "../Inc/leaf-filters.h"
18−#include "../Inc/leaf-tables.h"
19−#include "../leaf.h"
20−//#include "tim.h"
21−#endif
22−
23−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
24−void tAllpass_init(tAllpass* const ft, float initDelay, uint32_t maxDelay)
25−{
26− _tAllpass* f = *ft = (_tAllpass*) leaf_alloc(sizeof(_tAllpass));
27−
28− f->gain = 0.7f;
29−
30− f->lastOut = 0.0f;
31−
32− tLinearDelay_init(&f->delay, initDelay, maxDelay);
33−}
34−
35−void tAllpass_free(tAllpass* const ft)
36−{
37− _tAllpass* f = *ft;
38−
39− tLinearDelay_free(&f->delay);
40− leaf_free((char*)f);
41−}
42−
43−void tAllpass_initToPool (tAllpass* const ft, float initDelay, uint32_t maxDelay, tMempool* const mp)
44−{
45− _tMempool* m = *mp;
46− _tAllpass* f = *ft = (_tAllpass*) mpool_alloc(sizeof(_tAllpass), m);
47−
48− f->gain = 0.7f;
49−
50− f->lastOut = 0.0f;
51−
52− tLinearDelay_initToPool(&f->delay, initDelay, maxDelay, mp);
53−}
54−
55−void tAllpass_freeFromPool (tAllpass* const ft, tMempool* const mp)
56−{
57− _tMempool* m = *mp;
58− _tAllpass* f = *ft;
59−
60− tLinearDelay_freeFromPool(&f->delay, mp);
61− mpool_free((char*)f, m);
62−}
63−
64−void tAllpass_setDelay(tAllpass* const ft, float delay)
65−{
66− _tAllpass* f = *ft;
67−
68− tLinearDelay_setDelay(&f->delay, delay);
69−}
70−
71−void tAllpass_setGain(tAllpass* const ft, float gain)
72−{
73− _tAllpass* f = *ft;
74−
75− f->gain = gain;
76−}
77−
78−float tAllpass_tick(tAllpass* const ft, float input)
79−{
80− _tAllpass* f = *ft;
81−
82− float s1 = (-f->gain) * f->lastOut + input;
83−
84− float s2 = tLinearDelay_tick(&f->delay, s1) + (f->gain) * input;
85−
86− f->lastOut = s2;
87−
88− return f->lastOut;
89−}
90−
91−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
92−void tOnePole_init(tOnePole* const ft, float freq)
93−{
94− _tOnePole* f = *ft = (_tOnePole*) leaf_alloc(sizeof(_tOnePole));
95−
96− f->gain = 1.0f;
97− f->a0 = 1.0;
98−
99− tOnePole_setFreq(ft, freq);
100−
101− f->lastIn = 0.0f;
102− f->lastOut = 0.0f;
103−}
104−
105−void tOnePole_free(tOnePole* const ft)
106−{
107− _tOnePole* f = *ft;
108−
109− leaf_free((char*)f);
110−}
111−
112−void tOnePole_initToPool (tOnePole* const ft, float freq, tMempool* const mp)
113−{
114− _tMempool* m = *mp;
115− _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m);
116−
117− f->gain = 1.0f;
118− f->a0 = 1.0;
119−
120− tOnePole_setFreq(ft, freq);
121−
122− f->lastIn = 0.0f;
123− f->lastOut = 0.0f;
124−}
125−
126−void tOnePole_freeFromPool (tOnePole* const ft, tMempool* const mp)
127−{
128− _tMempool* m = *mp;
129− _tOnePole* f = *ft;
130−
131− mpool_free((char*)f, m);
132−}
133−
134−void tOnePole_setB0(tOnePole* const ft, float b0)
135−{
136− _tOnePole* f = *ft;
137− f->b0 = b0;
138−}
139−
140−void tOnePole_setA1(tOnePole* const ft, float a1)
141−{
142− _tOnePole* f = *ft;
143− if (a1 >= 1.0f) a1 = 0.999999f;
144− f->a1 = a1;
145−}
146−
147−void tOnePole_setPole(tOnePole* const ft, float thePole)
148−{
149− _tOnePole* f = *ft;
150−
151− if (thePole >= 1.0f) thePole = 0.999999f;
152−
153− // Normalize coefficients for peak unity gain.
154− if (thePole > 0.0f) f->b0 = (1.0f - thePole);
155− else f->b0 = (1.0f + thePole);
156−
157− f->a1 = -thePole;
158−}
159−
160−void tOnePole_setFreq (tOnePole* const ft, float freq)
161−{
162− _tOnePole* f = *ft;
163− f->b0 = freq * leaf.twoPiTimesInvSampleRate;
164− f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
165− f->a1 = 1.0f - f->b0;
166−}
167−
168−void tOnePole_setCoefficients(tOnePole* const ft, float b0, float a1)
169−{
170− _tOnePole* f = *ft;
171− if (a1 >= 1.0f) a1 = 0.999999f;
172− f->b0 = b0;
173− f->a1 = a1;
174−}
175−
176−void tOnePole_setGain(tOnePole* const ft, float gain)
177−{
178− _tOnePole* f = *ft;
179− f->gain = gain;
180−}
181−
182−float tOnePole_tick(tOnePole* const ft, float input)
183−{
184− _tOnePole* f = *ft;
185−
186− float in = input * f->gain;
187− float out = (f->b0 * in) + (f->a1 * f->lastOut);
188−
189− f->lastIn = in;
190− f->lastOut = out;
191−
192− return out;
193−}
194−
195−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
196−void tTwoPole_init(tTwoPole* const ft)
197−{
198− _tTwoPole* f = *ft = (_tTwoPole*) leaf_alloc(sizeof(_tTwoPole));
199−
200− f->gain = 1.0f;
201− f->a0 = 1.0;
202− f->b0 = 1.0;
203−
204− f->lastOut[0] = 0.0f;
205− f->lastOut[1] = 0.0f;
206−}
207−
208−void tTwoPole_free(tTwoPole* const ft)
209−{
210− _tTwoPole* f = *ft;
211−
212− leaf_free((char*)f);
213−}
214−
215−void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp)
216−{
217− _tMempool* m = *mp;
218− _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m);
219−
220− f->gain = 1.0f;
221− f->a0 = 1.0;
222− f->b0 = 1.0;
223−
224− f->lastOut[0] = 0.0f;
225− f->lastOut[1] = 0.0f;
226−}
227−
228−void tTwoPole_freeFromPool (tTwoPole* const ft, tMempool* const mp)
229−{
230− _tMempool* m = *mp;
231− _tTwoPole* f = *ft;
232−
233− mpool_free((char*)f, m);
234−}
235−
236−float tTwoPole_tick(tTwoPole* const ft, float input)
237−{
238− _tTwoPole* f = *ft;
239−
240− float in = input * f->gain;
241− float out = (f->b0 * in) - (f->a1 * f->lastOut[0]) - (f->a2 * f->lastOut[1]);
242−
243− f->lastOut[1] = f->lastOut[0];
244− f->lastOut[0] = out;
245−
246− return out;
247−}
248−
249−void tTwoPole_setB0(tTwoPole* const ft, float b0)
250−{
251− _tTwoPole* f = *ft;
252− f->b0 = b0;
253−}
254−
255−void tTwoPole_setA1(tTwoPole* const ft, float a1)
256−{
257− _tTwoPole* f = *ft;
258− f->a1 = a1;
259−}
260−
261−void tTwoPole_setA2(tTwoPole* const ft, float a2)
262−{
263− _tTwoPole* f = *ft;
264− f->a2 = a2;
265−}
266−
267−
268−void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, oBool normalize)
269−{
270− _tTwoPole* f = *ft;
271−
272− if (frequency < 0.0f) frequency = 0.0f;
273− if (frequency > (leaf.sampleRate * 0.49f)) frequency = leaf.sampleRate * 0.49f;
274− if (radius < 0.0f) radius = 0.0f;
275− if (radius >= 1.0f) radius = 0.999999f;
276−
277− f->radius = radius;
278− f->frequency = frequency;
279− f->normalize = normalize;
280−
281− f->a2 = radius * radius;
282− f->a1 = -2.0f * radius * cosf(frequency * leaf.twoPiTimesInvSampleRate);
283−
284− if ( normalize )
285− {
286− // Normalize the filter gain ... not terribly efficient.
287− float real = 1 - radius + (f->a2 - radius) * cosf(2 * frequency * leaf.twoPiTimesInvSampleRate);
288− float imag = (f->a2 - radius) * sinf(2 * frequency * leaf.twoPiTimesInvSampleRate);
289− f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
290− }
291−}
292−
293−void tTwoPole_setCoefficients(tTwoPole* const ft, float b0, float a1, float a2)
294−{
295− _tTwoPole* f = *ft;
296− f->b0 = b0;
297− f->a1 = a1;
298− f->a2 = a2;
299−}
300−
301−void tTwoPole_setGain(tTwoPole* const ft, float gain)
302−{
303− _tTwoPole* f = *ft;
304− f->gain = gain;
305−}
306−
307−void tTwoPoleSampleRateChanged (tTwoPole* const ft)
308−{
309− _tTwoPole* f = *ft;
310−
311− f->a2 = f->radius * f->radius;
312− f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
313−
314− if ( f->normalize )
315− {
316− // Normalize the filter gain ... not terribly efficient.
317− float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
318− float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
319− f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
320− }
321−}
322−
323−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OneZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
324−void tOneZero_init(tOneZero* const ft, float theZero)
325−{
326− _tOneZero* f = *ft = (_tOneZero*) leaf_alloc(sizeof(_tOneZero));
327−
328− f->gain = 1.0f;
329− f->lastIn = 0.0f;
330− f->lastOut = 0.0f;
331− tOneZero_setZero(ft, theZero);
332−}
333−
334−void tOneZero_free(tOneZero* const ft)
335−{
336− _tOneZero* f = *ft;
337−
338− leaf_free((char*)f);
339−}
340−
341−void tOneZero_initToPool (tOneZero* const ft, float theZero, tMempool* const mp)
342−{
343− _tMempool* m = *mp;
344− _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m);
345−
346− f->gain = 1.0f;
347− f->lastIn = 0.0f;
348− f->lastOut = 0.0f;
349− tOneZero_setZero(ft, theZero);
350−}
351−
352−void tOneZero_freeFromPool (tOneZero* const ft, tMempool* const mp)
353−{
354− _tMempool* m = *mp;
355− _tOneZero* f = *ft;
356−
357− mpool_free((char*)f, m);
358−}
359−
360−float tOneZero_tick(tOneZero* const ft, float input)
361−{
362− _tOneZero* f = *ft;
363−
364− float in = input * f->gain;
365− float out = f->b1 * f->lastIn + f->b0 * in;
366−
367− f->lastIn = in;
368−
369− return out;
370−}
371−
372−void tOneZero_setZero(tOneZero* const ft, float theZero)
373−{
374− _tOneZero* f = *ft;
375−
376− if (theZero > 0.0f) f->b0 = 1.0f / (1.0f + theZero);
377− else f->b0 = 1.0f / (1.0f - theZero);
378−
379− f->b1 = -theZero * f->b0;
380−
381−}
382−
383−void tOneZero_setB0(tOneZero* const ft, float b0)
384−{
385− _tOneZero* f = *ft;
386−
387− f->b0 = b0;
388−}
389−
390−void tOneZero_setB1(tOneZero* const ft, float b1)
391−{
392− _tOneZero* f = *ft;
393− f->b1 = b1;
394−}
395−
396−void tOneZero_setCoefficients(tOneZero* const ft, float b0, float b1)
397−{
398− _tOneZero* f = *ft;
399− f->b0 = b0;
400− f->b1 = b1;
401−}
402−
403−void tOneZero_setGain(tOneZero *ft, float gain)
404−{
405− _tOneZero* f = *ft;
406− f->gain = gain;
407−}
408−
409−float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )
410−{
411− _tOneZero* f = *ft;
412−
413− if ( frequency <= 0.0f) frequency = 0.05f;
414−
415− f->frequency = frequency;
416−
417− float omegaT = 2 * PI * frequency * leaf.invSampleRate;
418− float real = 0.0, imag = 0.0;
419−
420− real += f->b0;
421−
422− real += f->b1 * cosf(omegaT);
423− imag -= f->b1 * sinf(omegaT);
424−
425− real *= f->gain;
426− imag *= f->gain;
427−
428− float phase = atan2f( imag, real );
429−
430− real = 0.0; imag = 0.0;
431−
432− phase -= atan2f( imag, real );
433−
434− phase = fmodf( -phase, 2 * PI );
435−
436− return phase / omegaT;
437−}
438−
439−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
440−void tTwoZero_init(tTwoZero* const ft)
441−{
442− _tTwoZero* f = *ft = (_tTwoZero*) leaf_alloc(sizeof(_tTwoZero));
443−
444− f->gain = 1.0f;
445− f->lastIn[0] = 0.0f;
446− f->lastIn[1] = 0.0f;
447−}
448−
449−void tTwoZero_free(tTwoZero* const ft)
450−{
451− _tTwoZero* f = *ft;
452−
453− leaf_free((char*)f);
454−}
455−
456−void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp)
457−{
458− _tMempool* m = *mp;
459− _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m);
460−
461− f->gain = 1.0f;
462− f->lastIn[0] = 0.0f;
463− f->lastIn[1] = 0.0f;
464−}
465−
466−void tTwoZero_freeFromPool (tTwoZero* const ft, tMempool* const mp)
467−{
468− _tMempool* m = *mp;
469− _tTwoZero* f = *ft;
470−
471− mpool_free((char*)f, m);
472−}
473−
474−float tTwoZero_tick(tTwoZero* const ft, float input)
475−{
476− _tTwoZero* f = *ft;
477−
478− float in = input * f->gain;
479− float out = f->b2 * f->lastIn[1] + f->b1 * f->lastIn[0] + f->b0 * in;
480−
481− f->lastIn[1] = f->lastIn[0];
482− f->lastIn[0] = in;
483−
484− return out;
485−}
486−
487−void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)
488−{
489− _tTwoZero* f = *ft;
490−
491− // Should also deal with frequency being > half sample rate / nyquist. See STK
492− if (freq < 0.0f) freq = 0.0f;
493− if (radius < 0.0f) radius = 0.0f;
494−
495− f->frequency = freq;
496− f->radius = radius;
497−
498− f->b2 = radius * radius;
499− f->b1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
500−
501− // Normalize the filter gain. From STK.
502− if ( f->b1 > 0.0f ) // Maximum at z = 0.
503− f->b0 = 1.0f / ( 1.0f + f->b1 + f->b2 );
504− else // Maximum at z = -1.
505− f->b0 = 1.0f / ( 1.0f - f->b1 + f->b2 );
506− f->b1 *= f->b0;
507− f->b2 *= f->b0;
508−
509−}
510−
511−void tTwoZero_setB0(tTwoZero* const ft, float b0)
512−{
513− _tTwoZero* f = *ft;
514− f->b0 = b0;
515−}
516−
517−void tTwoZero_setB1(tTwoZero* const ft, float b1)
518−{
519− _tTwoZero* f = *ft;
520− f->b1 = b1;
521−}
522−
523−void tTwoZero_setCoefficients(tTwoZero* const ft, float b0, float b1, float b2)
524−{
525− _tTwoZero* f = *ft;
526− f->b0 = b0;
527− f->b1 = b1;
528− f->b2 = b2;
529−}
530−
531−void tTwoZero_setGain(tTwoZero* const ft, float gain)
532−{
533− _tTwoZero* f = *ft;
534− f->gain = gain;
535−}
536−
537−void tTwoZeroSampleRateChanged(tTwoZero* const ft)
538−{
539− _tTwoZero* f = *ft;
540−
541− tTwoZero_setNotch(ft, f->frequency, f->radius);
542−}
543−
544−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PoleZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
545−void tPoleZero_init(tPoleZero* const pzf)
546−{
547− _tPoleZero* f = *pzf = (_tPoleZero*) leaf_alloc(sizeof(_tPoleZero));
548−
549− f->gain = 1.0f;
550− f->b0 = 1.0;
551− f->a0 = 1.0;
552−
553− f->lastIn = 0.0f;
554− f->lastOut = 0.0f;
555−}
556−
557−void tPoleZero_free(tPoleZero* const pzf)
558−{
559− _tPoleZero* f = *pzf;
560−
561− leaf_free((char*)f);
562−}
563−
564−void tPoleZero_initToPool (tPoleZero* const pzf, tMempool* const mp)
565−{
566− _tMempool* m = *mp;
567− _tPoleZero* f = *pzf = (_tPoleZero*) mpool_alloc(sizeof(_tPoleZero), m);
568−
569− f->gain = 1.0f;
570− f->b0 = 1.0;
571− f->a0 = 1.0;
572−
573− f->lastIn = 0.0f;
574− f->lastOut = 0.0f;
575−}
576−
577−void tPoleZero_freeFromPool (tPoleZero* const pzf, tMempool* const mp)
578−{
579− _tMempool* m = *mp;
580− _tPoleZero* f = *pzf;
581−
582− mpool_free((char*)f, m);
583−}
584−
585−void tPoleZero_setB0(tPoleZero* const pzf, float b0)
586−{
587− _tPoleZero* f = *pzf;
588− f->b0 = b0;
589−}
590−
591−void tPoleZero_setB1(tPoleZero* const pzf, float b1)
592−{
593− _tPoleZero* f = *pzf;
594− f->b1 = b1;
595−}
596−
597−void tPoleZero_setA1(tPoleZero* const pzf, float a1)
598−{
599− _tPoleZero* f = *pzf;
600−
601− if (a1 >= 1.0f) // a1 should be less than 1.0
602− {
603− a1 = 0.999999f;
604− }
605−
606− f->a1 = a1;
607−}
608−
609−void tPoleZero_setCoefficients(tPoleZero* const pzf, float b0, float b1, float a1)
610−{
611− _tPoleZero* f = *pzf;
612−
613− if (a1 >= 1.0f) // a1 should be less than 1.0
614− {
615− a1 = 0.999999f;
616− }
617−
618− f->b0 = b0;
619− f->b1 = b1;
620− f->a1 = a1;
621−}
622−
623−void tPoleZero_setAllpass(tPoleZero* const pzf, float coeff)
624−{
625− _tPoleZero* f = *pzf;
626−
627− if (coeff >= 1.0f) // allpass coefficient >= 1.0 makes filter unstable
628− {
629− coeff = 0.999999f;
630− }
631−
632− f->b0 = coeff;
633− f->b1 = 1.0f;
634− f->a0 = 1.0f;
635− f->a1 = coeff;
636−}
637−
638−void tPoleZero_setBlockZero(tPoleZero* const pzf, float thePole)
639−{
640− _tPoleZero* f = *pzf;
641−
642− if (thePole >= 1.0f) // allpass coefficient >= 1.0 makes filter unstable
643− {
644− thePole = 0.999999f;
645− }
646−
647− f->b0 = 1.0f;
648− f->b1 = -1.0f;
649− f->a0 = 1.0f;
650− f->a1 = -thePole;
651−}
652−
653−void tPoleZero_setGain(tPoleZero* const pzf, float gain)
654−{
655− _tPoleZero* f = *pzf;
656− f->gain = gain;
657−}
658−
659−float tPoleZero_tick(tPoleZero* const pzf, float input)
660−{
661− _tPoleZero* f = *pzf;
662−
663− float in = input * f->gain;
664− float out = (f->b0 * in) + (f->b1 * f->lastIn) - (f->a1 * f->lastOut);
665−
666− f->lastIn = in;
667− f->lastOut = out;
668−
669− return out;
670−}
671−
672−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ BiQuad Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
673−void tBiQuad_init(tBiQuad* const ft)
674−{
675− _tBiQuad* f = *ft = (_tBiQuad*) leaf_alloc(sizeof(_tBiQuad));
676−
677− f->gain = 1.0f;
678−
679− f->b0 = 0.0f;
680− f->a0 = 0.0f;
681−
682− f->lastIn[0] = 0.0f;
683− f->lastIn[1] = 0.0f;
684− f->lastOut[0] = 0.0f;
685− f->lastOut[1] = 0.0f;
686−}
687−
688−void tBiQuad_free(tBiQuad* const ft)
689−{
690− _tBiQuad* f = *ft;
691−
692− leaf_free((char*)f);
693−}
694−
695−void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp)
696−{
697− _tMempool* m = *mp;
698− _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m);
699−
700− f->gain = 1.0f;
701−
702− f->b0 = 0.0f;
703− f->a0 = 0.0f;
704−
705− f->lastIn[0] = 0.0f;
706− f->lastIn[1] = 0.0f;
707− f->lastOut[0] = 0.0f;
708− f->lastOut[1] = 0.0f;
709−}
710−
711−void tBiQuad_freeFromPool (tBiQuad* const ft, tMempool* const mp)
712−{
713− _tMempool* m = *mp;
714− _tBiQuad* f = *ft;
715−
716− mpool_free((char*)f, m);
717−}
718−
719−float tBiQuad_tick(tBiQuad* const ft, float input)
720−{
721− _tBiQuad* f = *ft;
722−
723− float in = input * f->gain;
724− float out = f->b0 * in + f->b1 * f->lastIn[0] + f->b2 * f->lastIn[1];
725− out -= f->a2 * f->lastOut[1] + f->a1 * f->lastOut[0];
726−
727− f->lastIn[1] = f->lastIn[0];
728− f->lastIn[0] = in;
729−
730− f->lastOut[1] = f->lastOut[0];
731− f->lastOut[0] = out;
732−
733− return out;
734−}
735−
736−void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, oBool normalize)
737−{
738− _tBiQuad* f = *ft;
739−
740− if (freq < 0.0f) freq = 0.0f;
741− if (freq > (leaf.sampleRate * 0.49f)) freq = leaf.sampleRate * 0.49f;
742− if (radius < 0.0f) radius = 0.0f;
743− if (radius >= 1.0f) radius = 1.0f;
744−
745− f->frequency = freq;
746− f->radius = radius;
747− f->normalize = normalize;
748−
749− f->a2 = radius * radius;
750− f->a1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate);
751−
752− if (normalize)
753− {
754− f->b0 = 0.5f - 0.5f * f->a2;
755− f->b1 = 0.0f;
756− f->b2 = -f->b0;
757− }
758−}
759−
760−void tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)
761−{
762− _tBiQuad* f = *ft;
763−
764− if (freq < 0.0f) freq = 0.0f;
765− if (freq > (leaf.sampleRate * 0.49f)) freq = leaf.sampleRate * 0.49f;
766− if (radius < 0.0f) radius = 0.0f;
767−
768− f->b2 = radius * radius;
769− f->b1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
770−
771− // Does not attempt to normalize filter gain.
772−}
773−
774−void tBiQuad_setEqualGainZeros(tBiQuad* const ft)
775−{
776− _tBiQuad* f = *ft;
777− f->b0 = 1.0f;
778− f->b1 = 0.0f;
779− f->b2 = -1.0f;
780−}
781−
782−void tBiQuad_setB0(tBiQuad* const ft, float b0)
783−{
784− _tBiQuad* f = *ft;
785− f->b0 = b0;
786−}
787−
788−void tBiQuad_setB1(tBiQuad* const ft, float b1)
789−{
790− _tBiQuad* f = *ft;
791− f->b1 = b1;
792−}
793−
794−void tBiQuad_setB2(tBiQuad* const ft, float b2)
795−{
796− _tBiQuad* f = *ft;
797− f->b2 = b2;
798−}
799−
800−void tBiQuad_setA1(tBiQuad* const ft, float a1)
801−{
802− _tBiQuad* f = *ft;
803− f->a1 = a1;
804−}
805−
806−void tBiQuad_setA2(tBiQuad* const ft, float a2)
807−{
808− _tBiQuad* f = *ft;
809− f->a2 = a2;
810−}
811−
812−void tBiQuad_setCoefficients(tBiQuad* const ft, float b0, float b1, float b2, float a1, float a2)
813−{
814− _tBiQuad* f = *ft;
815− f->b0 = b0;
816− f->b1 = b1;
817− f->b2 = b2;
818− f->a1 = a1;
819− f->a2 = a2;
820−}
821−
822−void tBiQuad_setGain(tBiQuad* const ft, float gain)
823−{
824− _tBiQuad* f = *ft;
825− f->gain = gain;
826−}
827−
828−void tBiQuadSampleRateChanged(tBiQuad* const ft)
829−{
830− _tBiQuad* f = *ft;
831− f->a2 = f->radius * f->radius;
832− f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
833−
834− if (f->normalize)
835− {
836− f->b0 = 0.5f - 0.5f * f->a2;
837− f->b1 = 0.0f;
838− f->b2 = -f->b0;
839− }
840−}
841−
842−// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanf
843−// is calculated when frequency changes.
844−void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q)
845−{
846− tSVF_initToPool (svff, type, freq, Q, &leaf.mempool);
847−
848− // or maybe this?
849− /*
850− * hp=1 bp=A/Q (where A is 10^(G/40) and G is gain in decibels) and lp = 1
851− */
852−
853−}
854−
855−void tSVF_free(tSVF* const svff)
856−{
857− tSVF_freeFromPool (svff, &leaf.mempool);
858−}
859−
860−void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q, tMempool* const mp)
861−{
862− _tMempool* m = *mp;
863− _tSVF* svf = *svff = (_tSVF*) mpool_alloc(sizeof(_tSVF), m);
864−
865− svf->type = type;
866−
867− svf->ic1eq = 0;
868− svf->ic2eq = 0;
869− svf->Q = Q;
870− svf->cutoff = freq;
871− svf->g = tanf(PI * freq * leaf.invSampleRate);
872− svf->k = 1.0f/Q;
873− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
874− svf->a2 = svf->g*svf->a1;
875− svf->a3 = svf->g*svf->a2;
876− svf->cH = 0.0f;
877− svf->cB = 0.0f;
878− svf->cL = 1.0f;
879−
880− if (type == SVFTypeLowpass)
881− {
882− svf->cH = 0.0f;
883− svf->cB = 0.0f;
884− svf->cBK = 0.0f;
885− svf->cL = 1.0f;
886− }
887− else if (type == SVFTypeBandpass)
888− {
889− svf->cH = 0.0f;
890− svf->cB = 1.0f;
891− svf->cBK = 0.0f;
892− svf->cL = 0.0f;
893− }
894−
895− else if (type == SVFTypeHighpass)
896− {
897− svf->cH = 1.0f;
898− svf->cB = 0.0f;
899− svf->cBK = -1.0f;
900− svf->cL = -1.0f;
901− }
902−
903− else if (type == SVFTypeNotch)
904− {
905− svf->cH = 1.0f;
906− svf->cB = 0.0f;
907− svf->cBK = -1.0f;
908− svf->cL = 0.0f;
909− }
910−
911−
912− else if (type == SVFTypePeak)
913− {
914− svf->cH = 1.0f;
915− svf->cB = 0.0f;
916− svf->cBK = -1.0f;
917− svf->cL = -2.0f;
918− }
919−}
920−
921−void tSVF_freeFromPool (tSVF* const svff, tMempool* const mp)
922−{
923− _tMempool* m = *mp;
924− _tSVF* svf = *svff;
925−
926− mpool_free((char*)svf, m);
927−}
928−
929−float tSVF_tick(tSVF* const svff, float v0)
930−{
931− _tSVF* svf = *svff;
932−
933− float v1,v2,v3;
934− v3 = v0 - svf->ic2eq;
935− v1 = (svf->a1 * svf->ic1eq) + (svf->a2 * v3);
936− v2 = svf->ic2eq + (svf->a2 * svf->ic1eq) + (svf->a3 * v3);
937− svf->ic1eq = (2.0f * v1) - svf->ic1eq;
938− svf->ic2eq = (2.0f * v2) - svf->ic2eq;
939−
940− return (v0 * svf->cH) + (v1 * svf->cB) + (svf->k * v1 * svf->cBK) + (v2 * svf->cL);
941−}
942−
943−void tSVF_setFreq(tSVF* const svff, float freq)
944−{
945− _tSVF* svf = *svff;
946− svf->cutoff = freq;
947− svf->g = tanf(PI * freq * leaf.invSampleRate);
948− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
949− svf->a2 = svf->g * svf->a1;
950− svf->a3 = svf->g * svf->a2;
951−}
952−
953−void tSVF_setQ(tSVF* const svff, float Q)
954−{
955− _tSVF* svf = *svff;
956− svf->Q = Q;
957− svf->k = 1.0f/Q;
958−
959− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
960− svf->a2 = svf->g * svf->a1;
961− svf->a3 = svf->g * svf->a2;
962−}
963−
964−void tSVF_setFreqAndQ(tSVF* const svff, float freq, float Q)
965−{
966− _tSVF* svf = *svff;
967− svf->k = 1.0f/Q;
968− svf->g = tanf(PI * freq * leaf.invSampleRate);
969− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
970− svf->a2 = svf->g * svf->a1;
971− svf->a3 = svf->g * svf->a2;
972−}
973−
974−// Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.
975−void tEfficientSVF_init(tEfficientSVF* const svff, SVFType type, uint16_t input, float Q)
976−{
977− _tEfficientSVF* svf = *svff = (_tEfficientSVF*) leaf_alloc(sizeof(_tEfficientSVF));
978−
979− svf->type = type;
980−
981− svf->ic1eq = 0;
982− svf->ic2eq = 0;
983−
984− svf->g = __leaf_table_filtertan[input];
985− svf->k = 1.0f/Q;
986− svf->a1 = 1.0f/(1.0f+svf->g*(svf->g+svf->k));
987− svf->a2 = svf->g*svf->a1;
988− svf->a3 = svf->g*svf->a2;
989−}
990−
991−void tEfficientSVF_free(tEfficientSVF* const svff)
992−{
993− _tEfficientSVF* svf = *svff;
994−
995− leaf_free((char*)svf);
996−}
997−
998−void tEfficientSVF_initToPool (tEfficientSVF* const svff, SVFType type, uint16_t input, float Q, tMempool* const mp)
999−{
1000− _tMempool* m = *mp;
1001− _tEfficientSVF* svf = *svff = (_tEfficientSVF*) mpool_alloc(sizeof(_tEfficientSVF), m);
1002−
1003− svf->type = type;
1004−
1005− svf->ic1eq = 0;
1006− svf->ic2eq = 0;
1007−
1008− svf->g = __leaf_table_filtertan[input];
1009− svf->k = 1.0f/Q;
1010− svf->a1 = 1.0f/(1.0f+svf->g*(svf->g+svf->k));
1011− svf->a2 = svf->g*svf->a1;
1012− svf->a3 = svf->g*svf->a2;
1013−}
1014−
1015−void tEfficientSVF_freeFromPool (tEfficientSVF* const svff, tMempool* const mp)
1016−{
1017− _tMempool* m = *mp;
1018− _tEfficientSVF* svf = *svff;
1019−
1020− mpool_free((char*)svf, m);
1021−}
1022−
1023−float tEfficientSVF_tick(tEfficientSVF* const svff, float v0)
1024−{
1025− _tEfficientSVF* svf = *svff;
1026−
1027− float v1,v2,v3;
1028− v3 = v0 - svf->ic2eq;
1029− v1 = (svf->a1 * svf->ic1eq) + (svf->a2 * v3);
1030− v2 = svf->ic2eq + (svf->a2 * svf->ic1eq) + (svf->a3 * v3);
1031− svf->ic1eq = (2.0f * v1) - svf->ic1eq;
1032− svf->ic2eq = (2.0f * v2) - svf->ic2eq;
1033−
1034− if (svf->type == SVFTypeLowpass) return v2;
1035− else if (svf->type == SVFTypeBandpass) return v1;
1036− else if (svf->type == SVFTypeHighpass) return v0 - (svf->k * v1) - v2;
1037− else if (svf->type == SVFTypeNotch) return v0 - (svf->k * v1);
1038− else if (svf->type == SVFTypePeak) return v0 - (svf->k * v1) - (2.0f * v2);
1039− else return 0.0f;
1040−
1041−}
1042−
1043−void tEfficientSVF_setFreq(tEfficientSVF* const svff, uint16_t input)
1044−{
1045− _tEfficientSVF* svf = *svff;
1046−
1047− svf->g = __leaf_table_filtertan[input];
1048− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
1049− svf->a2 = svf->g * svf->a1;
1050− svf->a3 = svf->g * svf->a2;
1051−}
1052−
1053−void tEfficientSVF_setQ(tEfficientSVF* const svff, float Q)
1054−{
1055− _tEfficientSVF* svf = *svff;
1056−
1057− svf->k = 1.0f/Q;
1058− svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
1059− svf->a2 = svf->g * svf->a1;
1060− svf->a3 = svf->g * svf->a2;
1061−}
1062−
1063−/* Highpass */
1064−void tHighpass_init(tHighpass* const ft, float freq)
1065−{
1066− _tHighpass* f = *ft = (_tHighpass*) leaf_alloc(sizeof(_tHighpass));
1067−
1068− f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
1069− f->ys = 0.0f;
1070− f->xs = 0.0f;
1071−
1072− f->frequency = freq;
1073−}
1074−
1075−void tHighpass_free(tHighpass* const ft)
1076−{
1077− _tHighpass* f = *ft;
1078−
1079− leaf_free((char*)f);
1080−}
1081−
1082−void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const mp)
1083−{
1084− _tMempool* m = *mp;
1085− _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m);
1086−
1087− f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
1088− f->ys = 0.0f;
1089− f->xs = 0.0f;
1090−
1091− f->frequency = freq;
1092−}
1093−
1094−void tHighpass_freeFromPool (tHighpass* const ft, tMempool* const mp)
1095−{
1096− _tMempool* m = *mp;
1097− _tHighpass* f = *ft;
1098−
1099− mpool_free((char*)f, m);
1100−}
1101−
1102−void tHighpass_setFreq(tHighpass* const ft, float freq)
1103−{
1104− _tHighpass* f = *ft;
1105− f->frequency = freq;
1106− f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
1107−
1108−}
1109−
1110−float tHighpass_getFreq(tHighpass* const ft)
1111−{
1112− _tHighpass* f = *ft;
1113− return f->frequency;
1114−}
1115−
1116−// From JOS DC Blocker
1117−float tHighpass_tick(tHighpass* const ft, float x)
1118−{
1119− _tHighpass* f = *ft;
1120− f->ys = x - f->xs + f->R * f->ys;
1121− f->xs = x;
1122− return f->ys;
1123−}
1124−
1125−void tHighpassSampleRateChanged(tHighpass* const ft)
1126−{
1127− _tHighpass* f = *ft;
1128− f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf.invSampleRate));
1129−}
1130−
1131−void tButterworth_init(tButterworth* const ft, int N, float f1, float f2)
1132−{
1133− _tButterworth* f = *ft = (_tButterworth*) leaf_alloc(sizeof(_tButterworth));
1134−
1135− f->f1 = f1;
1136− f->f2 = f2;
1137− f->gain = 1.0f;
1138−
1139− f->N = N;
1140−
1141− if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW;
1142−
1143− for(int i = 0; i < N/2; ++i)
1144− {
1145− tSVF_init(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
1146− tSVF_init(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
1147− }
1148−}
1149−
1150−void tButterworth_free(tButterworth* const ft)
1151−{
1152− _tButterworth* f = *ft;
1153−
1154− for(int i = 0; i < f->N/2; ++i)
1155− {
1156− tSVF_free(&f->low[i]);
1157− tSVF_free(&f->high[i]);
1158− }
1159−
1160− leaf_free((char*)f);
1161−}
1162−
1163−void tButterworth_initToPool (tButterworth* const ft, int N, float f1, float f2, tMempool* const mp)
1164−{
1165− _tMempool* m = *mp;
1166− _tButterworth* f = *ft = (_tButterworth*) mpool_alloc(sizeof(_tButterworth), m);
1167−
1168− f->f1 = f1;
1169− f->f2 = f2;
1170− f->gain = 1.0f;
1171−
1172− f->N = N;
1173−
1174− if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW;
1175−
1176− for(int i = 0; i < N/2; ++i)
1177− {
1178− tSVF_initToPool(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp);
1179− tSVF_initToPool(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp);
1180− }
1181−}
1182−
1183−void tButterworth_freeFromPool (tButterworth* const ft, tMempool* const mp)
1184−{
1185− _tMempool* m = *mp;
1186− _tButterworth* f = *ft;
1187−
1188− for(int i = 0; i < f->N/2; ++i)
1189− {
1190− tSVF_freeFromPool(&f->low[i], mp);
1191− tSVF_freeFromPool(&f->high[i], mp);
1192− }
1193−
1194− mpool_free((char*)f, m);
1195−}
1196−
1197−float tButterworth_tick(tButterworth* const ft, float samp)
1198−{
1199− _tButterworth* f = *ft;
1200−
1201− for(int i = 0; i < ((f->N)/2); ++i)
1202− {
1203− samp = tSVF_tick(&f->low[i],samp);
1204− samp = tSVF_tick(&f->high[i],samp);
1205− }
1206− return samp;
1207−}
1208−
1209−void tButterworth_setF1(tButterworth* const ft, float f1)
1210−{
1211− _tButterworth* f = *ft;
1212−
1213− f->f1 = f1;
1214− for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->low[i], f1);
1215−}
1216−
1217−void tButterworth_setF2(tButterworth* const ft, float f2)
1218−{
1219− _tButterworth* f = *ft;
1220−
1221− f->f2 = f2;
1222− for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->high[i], f2);
1223−}
1224−
1225−void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
1226−{
1227− _tButterworth* f = *ft;
1228−
1229− f->f1 = f1;
1230− f->f2 = f2;
1231− for(int i = 0; i < ((f->N)/2); ++i)
1232− {
1233− tSVF_setFreq(&f->low[i], f1);
1234− tSVF_setFreq(&f->high[i], f2);
1235− }
1236−}
1237−
1238−void tFIR_init(tFIR* const firf, float* coeffs, int numTaps)
1239−{
1240− _tFIR* fir = *firf = (_tFIR*) leaf_alloc(sizeof(_tFIR));
1241−
1242− fir->numTaps = numTaps;
1243− fir->coeff = coeffs;
1244− fir->past = (float*)leaf_alloc(sizeof(float) * fir->numTaps);
1245− for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
1246−}
1247−
1248−void tFIR_free(tFIR* const firf)
1249−{
1250− _tFIR* fir = *firf;
1251−
1252− leaf_free((char*)fir->past);
1253− leaf_free((char*)fir);
1254−}
1255−
1256−void tFIR_initToPool (tFIR* const firf, float* coeffs, int numTaps, tMempool* const mp)
1257−{
1258− _tMempool* m = *mp;
1259− _tFIR* fir = *firf = (_tFIR*) mpool_alloc(sizeof(_tFIR), m);
1260−
1261− fir->numTaps = numTaps;
1262− fir->coeff = coeffs;
1263− fir->past = (float*) mpool_alloc(sizeof(float) * fir->numTaps, m);
1264− for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
1265−}
1266−
1267−void tFIR_freeFromPool (tFIR* const firf, tMempool* const mp)
1268−{
1269− _tMempool* m = *mp;
1270− _tFIR* fir = *firf;
1271−
1272− mpool_free((char*)fir->past, m);
1273− mpool_free((char*)fir, m);
1274−}
1275−
1276−float tFIR_tick(tFIR* const firf, float input)
1277−{
1278− _tFIR* fir = *firf;
1279−
1280− fir->past[0] = input;
1281− float y = 0.0f;
1282− for (int i = 0; i < fir->numTaps; ++i) y += fir->past[i]*fir->coeff[i];
1283− for (int i = fir->numTaps-1; i > 0; --i) fir->past[i] = fir->past[i-1];
1284− return y;
1285−}
1286−
1287−//---------------------------------------------
1288−////
1289−/// Median filter implemented based on James McCartney's median filter in Supercollider,
1290−/// translated from a Gen~ port of the Supercollider code that I believe was made by Rodrigo Costanzo and which I got from PA Tremblay - JS
1291−
1292−
1293−void tMedianFilter_init (tMedianFilter* const f, int size)
1294−{
1295− tMedianFilter_initToPool(f, size, &leaf.mempool);
1296−}
1297−void tMedianFilter_free (tMedianFilter* const f)
1298−{
1299− tMedianFilter_freeFromPool(f, &leaf.mempool);
1300−}
1301−void tMedianFilter_initToPool (tMedianFilter* const mf, int size, tMempool* const mp)
1302−{
1303− _tMempool* m = *mp;
1304− _tMedianFilter* f = *mf = (_tMedianFilter*) mpool_alloc(sizeof(_tMedianFilter), m);
1305−
1306− f->size = size;
1307− f->middlePosition = size / 2;
1308− f->last = size - 1;
1309− f->pos = -1;
1310− f->val = (float*) mpool_alloc(sizeof(float) * size, m);
1311− f->age = (int*) mpool_alloc(sizeof(int) * size, m);
1312− for (int i = 0; i < f->size; ++i)
1313− {
1314− f->val[i] = 0.0f;
1315− f->age[i] = i;
1316− }
1317−
1318−}
1319−void tMedianFilter_freeFromPool (tMedianFilter* const mf, tMempool* const mp)
1320−{
1321− _tMempool* m = *mp;
1322− _tMedianFilter* f = *mf;
1323−
1324− mpool_free((char*)f->val, m);
1325− mpool_free((char*)f->age, m);
1326− mpool_free((char*)f, m);
1327−}
1328−
1329−float tMedianFilter_tick (tMedianFilter* const mf, float input)
1330−{
1331− _tMedianFilter* f = *mf;
1332−
1333− for(int i=0; i<f->size; i++) {
1334− int thisAge = f->age[i];
1335− if(thisAge == f->last) {
1336− f->pos = i;
1337− }
1338− else {
1339− thisAge++;
1340− f->age[i] = thisAge;
1341− }
1342− }
1343−
1344− while( f->pos!=0 ) {
1345− float test = f->val[f->pos-1];
1346− if(input < test) {
1347− f->val[f->pos]=test;
1348− f->age[f->pos]=f->age[f->pos-1];
1349− f->pos -= 1;
1350− } else {break;}
1351− }
1352−
1353− while(f->pos != f->last) {
1354− float test = f->val[f->pos+1];
1355− if( input > test) {
1356− f->val[f->pos] = test;
1357− f->age[f->pos] = f->age[f->pos+1];
1358− f->pos += 1;
1359− } else {break;}
1360− }
1361−
1362− f->val[f->pos] = input;
1363− f->age[f->pos] = 0;
1364−
1365− return f->val[f->middlePosition];
1366−}
1367−
1368−/////
1369−
1370−void tVZFilter_init (tVZFilter* const vf, VZFilterType type, float freq, float bandWidth)
1371−{
1372− tVZFilter_initToPool(vf, type, freq, bandWidth, &leaf.mempool);
1373−}
1374−
1375−void tVZFilter_free (tVZFilter* const vf)
1376−{
1377− tVZFilter_freeFromPool(vf, &leaf.mempool);
1378−}
1379−void tVZFilter_initToPool (tVZFilter* const vf, VZFilterType type, float freq, float bandWidth, tMempool* const mp)
1380−{
1381−
1382− _tMempool* m = *mp;
1383− _tVZFilter* f = *vf = (_tVZFilter*) mpool_alloc(sizeof(_tVZFilter), m);
1384− f->fc = freq;
1385− f->type = type;
1386− f->G = ONE_OVER_SQRT2;
1387− f->invG = 1.0f/ONE_OVER_SQRT2;
1388− f->B = bandWidth;
1389− f->m = 0.0f;
1390− f->s1 = 0.0f;
1391− f->s2 = 0.0f;
1392− f->sr = leaf.sampleRate;
1393− f->inv_sr = leaf.invSampleRate;
1394− tVZFilter_calcCoeffs(vf);
1395−
1396−
1397−}
1398−void tVZFilter_freeFromPool (tVZFilter* const vf, tMempool* const mp)
1399−{
1400− _tMempool* m = *mp;
1401− _tVZFilter* f = *vf = (_tVZFilter*) mpool_alloc(sizeof(_tVZFilter), m);
1402− mpool_free((char*)f, m);
1403−}
1404−
1405−void tVZFilter_setSampleRate (tVZFilter* const vf, float sampleRate)
1406−{
1407− _tVZFilter* f = *vf;
1408− f->sr = sampleRate;
1409− f->inv_sr = 1.0f/sampleRate;
1410−}
1411−
1412−float tVZFilter_tick (tVZFilter* const vf, float in)
1413−{
1414− _tVZFilter* f = *vf;
1415−
1416− float yL, yB, yH;
1417−
1418− // compute highpass output via Eq. 5.1:
1419− yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1420−
1421− // compute bandpass output by applying 1st integrator to highpass output:
1422− yB = tanhf(f->g*yH) + f->s1;
1423− f->s1 = f->g*yH + yB; // state update in 1st integrator
1424−
1425− // compute lowpass output by applying 2nd integrator to bandpass output:
1426− yL = tanhf(f->g*yB) + f->s2;
1427− f->s2 = f->g*yB + yL; // state update in 2nd integrator
1428−
1429− //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1430− //
1431− //seems like that might look like this:
1432− // y = tanh(g*x) + s; // output computation
1433− // s = g*x + y; // state update
1434−
1435− //instead of this:
1436− // y = g*x + s; // output computation
1437− // s = g*x + y; // state update
1438−
1439− return f->cL*yL + f->cB*yB + f->cH*yH;
1440−
1441−}
1442−
1443−float tVZFilter_tickEfficient (tVZFilter* const vf, float in)
1444−{
1445− _tVZFilter* f = *vf;
1446−
1447− float yL, yB, yH;
1448−
1449− // compute highpass output via Eq. 5.1:
1450− yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1451−
1452− // compute bandpass output by applying 1st integrator to highpass output:
1453− yB = (f->g*yH) + f->s1;
1454− f->s1 = f->g*yH + yB; // state update in 1st integrator
1455−
1456− // compute lowpass output by applying 2nd integrator to bandpass output:
1457− yL = (f->g*yB) + f->s2;
1458− f->s2 = f->g*yB + yL; // state update in 2nd integrator
1459−
1460− //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1461− //
1462− //seems like that might look like this:
1463− // y = tanh(g*x) + s; // output computation
1464− // s = g*x + y; // state update
1465−
1466− //instead of this:
1467− // y = g*x + s; // output computation
1468− // s = g*x + y; // state update
1469−
1470− return f->cL*yL + f->cB*yB + f->cH*yH;
1471−
1472−}
1473−
1474−float tVZFilter_tickEfficientBP (tVZFilter* const vf, float in)
1475−{
1476− _tVZFilter* f = *vf;
1477−
1478− float yL, yB, yH;
1479−
1480− // compute highpass output via Eq. 5.1:
1481− yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1482−
1483− // compute bandpass output by applying 1st integrator to highpass output:
1484− yB = (f->g*yH) + f->s1;
1485− f->s1 = f->g*yH + yB; // state update in 1st integrator
1486−
1487− // compute lowpass output by applying 2nd integrator to bandpass output:
1488− yL = (f->g*yB) + f->s2;
1489− f->s2 = f->g*yB + yL; // state update in 2nd integrator
1490−
1491− //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1492− //
1493− //seems like that might look like this:
1494− // y = tanh(g*x) + s; // output computation
1495− // s = g*x + y; // state update
1496−
1497− //instead of this:
1498− // y = g*x + s; // output computation
1499− // s = g*x + y; // state update
1500−
1501− return f->cL*yL + f->cB*yB + f->cH*yH;
1502−
1503−}
1504−
1505−
1506−void tVZFilter_calcCoeffs (tVZFilter* const vf)
1507−{
1508−
1509− _tVZFilter* f = *vf;
1510− f->g = tanf(PI * f->fc * f->inv_sr); // embedded integrator gain (Fig 3.11)
1511−
1512− switch( f->type )
1513− {
1514− case Bypass:
1515− {
1516− f->R2 = f->invG; // can we use an arbitrary value here, for example R2 = 1?
1517− f->cL = 1.0f;
1518− f->cB = f->R2;
1519− f->cH = 1.0f;
1520− }
1521− break;
1522− case Lowpass:
1523− {
1524− f->R2 = f->invG;
1525− f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;
1526− }
1527− break;
1528− case Highpass:
1529− {
1530− f->R2 = f->invG;
1531− f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;
1532− }
1533− break;
1534− case BandpassSkirt:
1535− {
1536− f->R2 = f->invG;
1537− f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;
1538− }
1539− break;
1540− case BandpassPeak:
1541− {
1542− f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1543− f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;
1544− }
1545− break;
1546− case BandReject:
1547− {
1548− f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1549− f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;
1550− }
1551− break;
1552− case Bell:
1553− {
1554− float fl = f->fc*powf(2.0f, (-f->B)*0.5f); // lower bandedge frequency (in Hz)
1555− float wl = tanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)
1556− float r = f->g/wl;
1557− r *= r; // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the
1558− // warped upper bandedge, wc the center
1559− f->R2 = 2.0f*sqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));
1560− f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;
1561− }
1562− break;
1563− case Lowshelf:
1564− {
1565− float A = sqrtf(f->G);
1566− f->g /= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1567− f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);
1568− f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;
1569− }
1570− break;
1571− case Highshelf:
1572− {
1573− float A = sqrtf(f->G);
1574− f->g *= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1575− f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);
1576− f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;
1577− }
1578− break;
1579− case Allpass:
1580− {
1581− f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1582− f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;
1583− }
1584− break;
1585−
1586− // experimental - maybe we must find better curves for cL, cB, cH:
1587− case Morph:
1588− {
1589− f->R2 = f->invG;
1590− float x = 2.0f*f->m-1.0f;
1591−
1592− f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
1593− f->cH = minimum( x, 0.0f); /*cH *= cH;*/
1594− f->cB = 1.0f-x*x;
1595−
1596− // bottom line: we need to test different versions for how they feel when tweaking the
1597− // morph parameter
1598−
1599− // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
1600− // the magnitude response value at the cutoff frequency and scale back by the gain):
1601− float s = f->G * sqrtf((f->R2*f->R2) / (f->cL*f->cL + f->cB*f->cB + f->cH*f->cH - 2.0f*f->cL*f->cH));
1602− f->cL *= s; f->cB *= s; f->cH *= s;
1603− }
1604− break;
1605−
1606− }
1607−
1608− f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1609−}
1610−
1611−
1612−void tVZFilter_setBandwidth (tVZFilter* const vf, float B)
1613−{
1614− _tVZFilter* f = *vf;
1615− f->B = LEAF_clip(0.0f, B, 100.0f);
1616− tVZFilter_calcCoeffs(vf);
1617−}
1618−void tVZFilter_setFreq (tVZFilter* const vf, float freq)
1619−{
1620− _tVZFilter* f = *vf;
1621− f->fc = LEAF_clip(0.0f, freq, 0.5f*leaf.sampleRate);
1622− tVZFilter_calcCoeffs(vf);
1623−}
1624−void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw)
1625−{
1626− _tVZFilter* f = *vf;
1627− f->B = LEAF_clip(0.0f,bw, 100.0f);
1628− f->fc = LEAF_clip(0.0f, freq, 0.5f*leaf.sampleRate);
1629− tVZFilter_calcCoeffs(vf);
1630−}
1631−
1632−void tVZFilter_setGain (tVZFilter* const vf, float gain)
1633−{
1634− _tVZFilter* f = *vf;
1635− f->G = LEAF_clip(0.000001f, gain, 100.0f);
1636− f->invG = 1.0f/f->G;
1637− tVZFilter_calcCoeffs(vf);
1638−}
1639−
1640−void tVZFilter_setMorph (tVZFilter* const vf, float morph)
1641−{
1642− _tVZFilter* f = *vf;
1643− f->m = LEAF_clip(0.0f, morph, 1.0f);
1644− tVZFilter_calcCoeffs(vf);
1645−}
1646−
1647−void tVZFilter_setType (tVZFilter* const vf, VZFilterType type)
1648−{
1649− _tVZFilter* f = *vf;
1650− f->type = type;
1651− tVZFilter_calcCoeffs(vf);
1652−}
1653−
1654−float tVZFilter_BandwidthToR(tVZFilter* const vf, float B)
1655−{
1656− _tVZFilter* f = *vf;
1657− float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)
1658− float gl = tanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)
1659− float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1660− // unwarped: r = pow(2, -B/2) -> approximation for low
1661− // center-frequencies
1662− return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1663−}
1664−
1665−
1666−
1667−void tDiodeFilter_init (tDiodeFilter* const vf, float cutoff, float resonance)
1668−{
1669− tDiodeFilter_initToPool(vf, cutoff, resonance, &leaf.mempool);
1670−}
1671−
1672−void tDiodeFilter_free (tDiodeFilter* const vf)
1673−{
1674− tDiodeFilter_freeFromPool(vf, &leaf.mempool);
1675−}
1676−void tDiodeFilter_initToPool (tDiodeFilter* const vf, float cutoff, float resonance, tMempool* const mp)
1677−{
1678−
1679− _tMempool* m = *mp;
1680− _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
1681− // initialization (the resonance factor is between 0 and 8 according to the article)
1682− f->f = tan(PI * cutoff/leaf.sampleRate);
1683− f->r = (7.f * resonance + 0.5f);
1684− f->Vt = 0.5f;
1685− f->n = 1.836f;
1686− f->zi = 0.0f; //previous input value
1687− f->gamma = f->Vt*f->n;
1688− f->s0 = 0.01f;
1689− f->s1 = 0.02f;
1690− f->s2 = 0.03f;
1691− f->s3 = 0.04f;
1692− f->g0inv = 1.f/(2.f*f->Vt);
1693− f->g1inv = 1.f/(2.f*f->gamma);
1694− f->g2inv = 1.f/(6.f*f->gamma);
1695−
1696−
1697−}
1698−void tDiodeFilter_freeFromPool (tDiodeFilter* const vf, tMempool* const mp)
1699−{
1700− _tMempool* m = *mp;
1701− _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
1702− mpool_free((char*)f, m);
1703−}
1704−
1705−float tanhXdX(float x)
1706−{
1707− float a = x*x;
1708− // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)
1709− return ((a + 105.0f)*a + 945.0f) / ((15.0f*a + 420.0f)*a + 945.0f);
1710−}
1711−
1712−float tDiodeFilter_tick (tDiodeFilter* const vf, float in)
1713−{
1714− _tDiodeFilter* f = *vf;
1715−
1716− // the input x[n+1] is given by 'in', and x[n] by zi
1717− // input with half delay
1718− float ih = 0.5f * (in + f->zi);
1719−
1720− // evaluate the non-linear factors
1721− float t0 = f->f*tanhXdX((ih - f->r * f->s3)*f->g0inv)*f->g0inv;
1722− float t1 = f->f*tanhXdX((f->s1-f->s0)*f->g1inv)*f->g1inv;
1723− float t2 = f->f*tanhXdX((f->s2-f->s1)*f->g1inv)*f->g1inv;
1724− float t3 = f->f*tanhXdX((f->s3-f->s2)*f->g1inv)*f->g1inv;
1725− float t4 = f->f*tanhXdX((f->s3)*f->g2inv)*f->g2inv;
1726−
1727−
1728−
1729− // This formula gives the result for y3 thanks to MATLAB
1730− 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);
1731−// if (isnan(y3))
1732−// {
1733−// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);
1734−// }
1735− 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;
1736−// if (isnan(tempy3denom))
1737−// {
1738−// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);
1739−// }
1740− if (tempy3denom == 0.0f)
1741− {
1742− tempy3denom = 0.000001f;
1743− }
1744− y3 = y3 / tempy3denom;
1745−// if (isnan(y3))
1746−// {
1747−// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);
1748−// }
1749− if (t1 == 0.0f)
1750− {
1751− t1 = 0.000001f;
1752− }
1753− if (t2 == 0.0f)
1754− {
1755− t2 = 0.000001f;
1756− }
1757− if (t3 == 0.0f)
1758− {
1759− t3 = 0.000001f;
1760− }
1761− // Other outputs
1762− float y2 = (f->s3 - (1+t4+t3)*y3) / (-t3);
1763− float y1 = (f->s2 - (1+t3+t2)*y2 + t3*y3) / (-t2);
1764− float y0 = (f->s1 - (1+t2+t1)*y1 + t2*y2) / (-t1);
1765− float xx = (in - f->r*y3);
1766−
1767− // update state
1768− f->s0 += 2.0f * (t0*xx + t1*(y1-y0));
1769−// if (isnan(f->s0))
1770−// {
1771−// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);
1772−// }
1773−
1774−// if (isinf(f->s0))
1775−// {
1776−// __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400);
1777−// }
1778− f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));
1779− f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));
1780− f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));
1781−
1782− f->zi = in;
1783− return y3*f->r;
1784−
1785−}
1786−
1787−
1788−
1789−void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff)
1790−{
1791− _tDiodeFilter* f = *vf;
1792− f->f = tanf(PI * LEAF_clip(10.0f, cutoff, 20000.0f)*leaf.invSampleRate);
1793−}
1794−
1795−
1796−void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance)
1797−{
1798− _tDiodeFilter* f = *vf;
1799− f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
1800−
1801−}
1802−
LEAF/Src/leaf-instruments.c+0−706
@@ -1,706 +0,0 @@
1−/*==============================================================================
2−
3− leaf-instruments.c
4− Created: 30 Nov 2018 10:24:21am
5− Author: airship
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-instruments.h"
12−
13−#else
14−
15−#include "../Inc/leaf-instruments.h"
16−
17−#endif
18−
19−// ----------------- COWBELL ----------------------------//
20−
21−void t808Cowbell_init(t808Cowbell* const cowbellInst, int useStick)
22−{
23− _t808Cowbell* cowbell = *cowbellInst = (_t808Cowbell*) leaf_alloc(sizeof(_t808Cowbell));
24−
25− tSquare_init(&cowbell->p[0]);
26− tSquare_setFreq(&cowbell->p[0], 540.0f);
27−
28− tSquare_init(&cowbell->p[1]);
29− tSquare_setFreq(&cowbell->p[1], 1.48148f * 540.0f);
30−
31− cowbell->oscMix = 0.5f;
32−
33− tSVF_init(&cowbell->bandpassOsc, SVFTypeBandpass, 2500, 1.0f);
34−
35− tSVF_init(&cowbell->bandpassStick, SVFTypeBandpass, 1800, 1.0f);
36−
37− tEnvelope_init(&cowbell->envGain, 5.0f, 100.0f, OFALSE);
38−
39− tEnvelope_init(&cowbell->envFilter, 5.0, 100.0f, OFALSE);
40−
41− tHighpass_init(&cowbell->highpass, 1000.0f);
42−
43− tNoise_init(&cowbell->stick, WhiteNoise);
44−
45− tEnvelope_init(&cowbell->envStick, 5.0f, 5.0f, 0);
46−
47− cowbell->useStick = useStick;
48−}
49−
50−void t808Cowebell_free(t808Cowbell* const cowbellInst)
51−{
52− _t808Cowbell* cowbell = *cowbellInst;
53−
54− tSquare_free(&cowbell->p[0]);
55− tSquare_free(&cowbell->p[1]);
56− tSVF_free(&cowbell->bandpassOsc);
57− tSVF_free(&cowbell->bandpassStick);
58− tEnvelope_free(&cowbell->envGain);
59− tEnvelope_free(&cowbell->envFilter);
60− tHighpass_free(&cowbell->highpass);
61− tNoise_free(&cowbell->stick);
62− tEnvelope_free(&cowbell->envStick);
63− leaf_free((char*)cowbell);
64−}
65−
66−void t808Cowbell_initToPool (t808Cowbell* const cowbellInst, int useStick, tMempool* const mp)
67−{
68− _tMempool* m = *mp;
69− _t808Cowbell* cowbell = *cowbellInst = (_t808Cowbell*) mpool_alloc(sizeof(_t808Cowbell), m);
70−
71− tSquare_initToPool(&cowbell->p[0], mp);
72− tSquare_setFreq(&cowbell->p[0], 540.0f);
73−
74− tSquare_initToPool(&cowbell->p[1], mp);
75− tSquare_setFreq(&cowbell->p[1], 1.48148f * 540.0f);
76−
77− cowbell->oscMix = 0.5f;
78−
79− tSVF_initToPool(&cowbell->bandpassOsc, SVFTypeBandpass, 2500, 1.0f, mp);
80−
81− tSVF_initToPool(&cowbell->bandpassStick, SVFTypeBandpass, 1800, 1.0f, mp);
82−
83− tEnvelope_initToPool(&cowbell->envGain, 5.0f, 100.0f, OFALSE, mp);
84−
85− tEnvelope_initToPool(&cowbell->envFilter, 5.0, 100.0f, OFALSE, mp);
86−
87− tHighpass_initToPool(&cowbell->highpass, 1000.0f, mp);
88−
89− tNoise_initToPool(&cowbell->stick, WhiteNoise, mp);
90−
91− tEnvelope_initToPool(&cowbell->envStick, 5.0f, 5.0f, 0, mp);
92−
93− cowbell->useStick = useStick;
94−}
95−
96−void t808Cowbell_freeFromPool (t808Cowbell* const cowbellInst, tMempool* const mp)
97−{
98− _tMempool* m = *mp;
99− _t808Cowbell* cowbell = *cowbellInst;
100−
101− tSquare_freeFromPool(&cowbell->p[0], mp);
102− tSquare_freeFromPool(&cowbell->p[1], mp);
103− tSVF_freeFromPool(&cowbell->bandpassOsc, mp);
104− tSVF_freeFromPool(&cowbell->bandpassStick, mp);
105− tEnvelope_freeFromPool(&cowbell->envGain, mp);
106− tEnvelope_freeFromPool(&cowbell->envFilter, mp);
107− tHighpass_freeFromPool(&cowbell->highpass, mp);
108− tNoise_freeFromPool(&cowbell->stick, mp);
109− tEnvelope_freeFromPool(&cowbell->envStick, mp);
110− mpool_free((char*)cowbell, m);
111−}
112−
113−void t808Cowbell_on(t808Cowbell* const cowbellInst, float vel)
114−{
115− _t808Cowbell* cowbell = *cowbellInst;
116−
117− tEnvelope_on(&cowbell->envGain, vel);
118−
119− if (cowbell->useStick)
120− tEnvelope_on(&cowbell->envStick,vel);
121−}
122−
123−float t808Cowbell_tick(t808Cowbell* const cowbellInst)
124−{
125− _t808Cowbell* cowbell = *cowbellInst;
126−
127− float sample = 0.0f;
128−
129− // Mix oscillators.
130− sample = (cowbell->oscMix * tSquare_tick(&cowbell->p[0])) + ((1.0f-cowbell->oscMix) * tSquare_tick(&cowbell->p[1]));
131−
132− // Filter dive and filter.
133− tSVF_setFreq(&cowbell->bandpassOsc, cowbell->filterCutoff + 1000.0f * tEnvelope_tick(&cowbell->envFilter));
134− sample = tSVF_tick(&cowbell->bandpassOsc,sample);
135−
136− sample *= (0.9f * tEnvelope_tick(&cowbell->envGain));
137−
138− if (cowbell->useStick)
139− sample += (0.1f * tEnvelope_tick(&cowbell->envStick) * tSVF_tick(&cowbell->bandpassStick, tNoise_tick(&cowbell->stick)));
140−
141−
142− sample = tHighpass_tick(&cowbell->highpass, sample);
143−
144− return sample;
145−}
146−
147−void t808Cowbell_setDecay(t808Cowbell* const cowbellInst, float decay)
148−{
149− _t808Cowbell* cowbell = *cowbellInst;
150− tEnvelope_setDecay(&cowbell->envGain,decay);
151−}
152−
153−void t808Cowbell_setHighpassFreq(t808Cowbell *cowbellInst, float freq)
154−{
155− _t808Cowbell* cowbell = *cowbellInst;
156− tHighpass_setFreq(&cowbell->highpass,freq);
157−}
158−
159−void t808Cowbell_setBandpassFreq(t808Cowbell* const cowbellInst, float freq)
160−{
161− _t808Cowbell* cowbell = *cowbellInst;
162− cowbell->filterCutoff = freq;
163−}
164−
165−void t808Cowbell_setFreq(t808Cowbell* const cowbellInst, float freq)
166−{
167− _t808Cowbell* cowbell = *cowbellInst;
168− tSquare_setFreq(&cowbell->p[0],freq);
169− tSquare_setFreq(&cowbell->p[1],1.48148f*freq);
170−}
171−
172−void t808Cowbell_setOscMix(t808Cowbell* const cowbellInst, float oscMix)
173−{
174− _t808Cowbell* cowbell = *cowbellInst;
175− cowbell->oscMix = oscMix;
176−}
177−
178−void t808Cowbell_setStick(t808Cowbell* const cowbellInst, int useStick)
179−{
180− _t808Cowbell* cowbell = *cowbellInst;
181− cowbell->useStick = useStick;
182−}
183−
184−// ----------------- HIHAT ----------------------------//
185−
186−void t808Hihat_init(t808Hihat* const hihatInst)
187−{
188− _t808Hihat* hihat = *hihatInst = (_t808Hihat*) leaf_alloc(sizeof(_t808Hihat));
189−
190− for (int i = 0; i < 6; i++)
191− {
192− tSquare_init(&hihat->p[i]);
193− }
194−
195− tNoise_init(&hihat->stick, PinkNoise);
196− tNoise_init(&hihat->n, WhiteNoise);
197−
198− // need to fix SVF to be generic
199− tSVF_init(&hihat->bandpassStick, SVFTypeBandpass,2500.0f,1.2f);
200− tSVF_init(&hihat->bandpassOsc, SVFTypeBandpass,3500.0f,0.3f);
201−
202− tEnvelope_init(&hihat->envGain, 0.0f, 50.0f, OFALSE);
203− tEnvelope_init(&hihat->envStick, 0.0f, 7.0f, OFALSE);
204−
205−
206− tHighpass_init(&hihat->highpass, 7000.0f);
207−
208− hihat->freq = 40.0f;
209− hihat->stretch = 0.0f;
210−
211− tSquare_setFreq(&hihat->p[0], 2.0f * hihat->freq);
212− tSquare_setFreq(&hihat->p[1], 3.00f * hihat->freq);
213− tSquare_setFreq(&hihat->p[2], 4.16f * hihat->freq);
214− tSquare_setFreq(&hihat->p[3], 5.43f * hihat->freq);
215− tSquare_setFreq(&hihat->p[4], 6.79f * hihat->freq);
216− tSquare_setFreq(&hihat->p[5], 8.21f * hihat->freq);
217−}
218−
219−void t808Hihat_free(t808Hihat* const hihatInst)
220−{
221− _t808Hihat* hihat = *hihatInst;
222−
223− for (int i = 0; i < 6; i++)
224− {
225− tSquare_free(&hihat->p[i]);
226− }
227−
228− tNoise_free(&hihat->stick);
229− tNoise_free(&hihat->n);
230−
231− // need to fix SVF to be generic
232− tSVF_free(&hihat->bandpassStick);
233− tSVF_free(&hihat->bandpassOsc);
234− tEnvelope_free(&hihat->envGain);
235− tEnvelope_free(&hihat->envStick);
236−
237− tHighpass_free(&hihat->highpass);
238−
239− leaf_free((char*)hihat);
240−}
241−
242−void t808Hihat_initToPool (t808Hihat* const hihatInst, tMempool* const mp)
243−{
244− _tMempool* m = *mp;
245− _t808Hihat* hihat = *hihatInst = (_t808Hihat*) mpool_alloc(sizeof(_t808Hihat), m);
246−
247− for (int i = 0; i < 6; i++)
248− {
249− tSquare_initToPool(&hihat->p[i], mp);
250− }
251−
252− tNoise_initToPool(&hihat->stick, PinkNoise, mp);
253− tNoise_initToPool(&hihat->n, WhiteNoise, mp);
254−
255− // need to fix SVF to be generic
256− tSVF_initToPool(&hihat->bandpassStick, SVFTypeBandpass,2500.0f,1.2f, mp);
257− tSVF_initToPool(&hihat->bandpassOsc, SVFTypeBandpass,3500.0f,0.3f, mp);
258−
259− tEnvelope_initToPool(&hihat->envGain, 0.0f, 50.0f, OFALSE, mp);
260− tEnvelope_initToPool(&hihat->envStick, 0.0f, 7.0f, OFALSE, mp);
261−
262−
263− tHighpass_initToPool(&hihat->highpass, 7000.0f, mp);
264−
265− hihat->freq = 40.0f;
266− hihat->stretch = 0.0f;
267−
268− tSquare_setFreq(&hihat->p[0], 2.0f * hihat->freq);
269− tSquare_setFreq(&hihat->p[1], 3.00f * hihat->freq);
270− tSquare_setFreq(&hihat->p[2], 4.16f * hihat->freq);
271− tSquare_setFreq(&hihat->p[3], 5.43f * hihat->freq);
272− tSquare_setFreq(&hihat->p[4], 6.79f * hihat->freq);
273− tSquare_setFreq(&hihat->p[5], 8.21f * hihat->freq);
274−}
275−
276−void t808Hihat_freeFromPool (t808Hihat* const hihatInst, tMempool* const mp)
277−{
278− _tMempool* m = *mp;
279− _t808Hihat* hihat = *hihatInst;
280−
281− for (int i = 0; i < 6; i++)
282− {
283− tSquare_freeFromPool(&hihat->p[i], mp);
284− }
285−
286− tNoise_freeFromPool(&hihat->stick, mp);
287− tNoise_freeFromPool(&hihat->n, mp);
288−
289− // need to fix SVF to be generic
290− tSVF_freeFromPool(&hihat->bandpassStick, mp);
291− tSVF_freeFromPool(&hihat->bandpassOsc, mp);
292− tEnvelope_freeFromPool(&hihat->envGain, mp);
293− tEnvelope_freeFromPool(&hihat->envStick, mp);
294−
295− tHighpass_freeFromPool(&hihat->highpass, mp);
296−
297− mpool_free((char*)hihat, m);
298−}
299−
300−void t808Hihat_on(t808Hihat* const hihatInst, float vel)
301−{
302− _t808Hihat* hihat = *hihatInst;
303− tEnvelope_on(&hihat->envGain, vel);
304− tEnvelope_on(&hihat->envStick, vel);
305−}
306−
307−void t808Hihat_setOscNoiseMix(t808Hihat* const hihatInst, float oscNoiseMix)
308−{
309− _t808Hihat* hihat = *hihatInst;
310− hihat->oscNoiseMix = oscNoiseMix;
311−}
312−
313−float t808Hihat_tick(t808Hihat* const hihatInst)
314−{
315− _t808Hihat* hihat = *hihatInst;
316−
317− float sample = 0.0f;
318− float gainScale = 0.1666f;
319−
320− float myNoise = tNoise_tick(&hihat->n);
321−
322− tSquare_setFreq(&hihat->p[0], ((2.0f + hihat->stretch) * hihat->freq));
323− tSquare_setFreq(&hihat->p[1], ((3.00f + hihat->stretch) * hihat->freq));
324− tSquare_setFreq(&hihat->p[2], ((4.16f + hihat->stretch) * hihat->freq));
325− tSquare_setFreq(&hihat->p[3], ((5.43f + hihat->stretch) * hihat->freq));
326− tSquare_setFreq(&hihat->p[4], ((6.79f + hihat->stretch) * hihat->freq));
327− tSquare_setFreq(&hihat->p[5], ((8.21f + hihat->stretch) * hihat->freq));
328−
329− for (int i = 0; i < 6; i++)
330− {
331− sample += tSquare_tick(&hihat->p[i]);
332− }
333−
334− sample *= gainScale;
335−
336− sample = (hihat->oscNoiseMix * sample) + ((1.0f-hihat->oscNoiseMix) * myNoise);
337−
338− sample = tSVF_tick(&hihat->bandpassOsc, sample);
339−
340− float myGain = tEnvelope_tick(&hihat->envGain);
341− sample *= (myGain*myGain);//square the output gain envelope
342− sample = tHighpass_tick(&hihat->highpass, sample);
343− sample += ((0.5f * tEnvelope_tick(&hihat->envStick)) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick)));
344− sample = tanhf(sample * 2.0f);
345−
346− return sample;
347−}
348−
349−void t808Hihat_setDecay(t808Hihat* const hihatInst, float decay)
350−{
351− _t808Hihat* hihat = *hihatInst;
352− tEnvelope_setDecay(&hihat->envGain,decay);
353−}
354−
355−void t808Hihat_setHighpassFreq(t808Hihat* const hihatInst, float freq)
356−{
357− _t808Hihat* hihat = *hihatInst;
358− tHighpass_setFreq(&hihat->highpass,freq);
359−}
360−
361−void t808Hihat_setStretch(t808Hihat* const hihatInst, float stretch)
362−{
363− _t808Hihat* hihat = *hihatInst;
364− hihat->stretch = stretch;
365−}
366−
367−void t808Hihat_setFM(t808Hihat* const hihatInst, float FM_amount)
368−{
369− _t808Hihat* hihat = *hihatInst;
370− hihat->FM_amount = FM_amount;
371−}
372−
373−void t808Hihat_setOscBandpassFreq(t808Hihat* const hihatInst, float freq)
374−{
375− _t808Hihat* hihat = *hihatInst;
376− tSVF_setFreq(&hihat->bandpassOsc,freq);
377−}
378−
379−void t808Hihat_setOscBandpassQ(t808Hihat* const hihatInst, float Q)
380−{
381− _t808Hihat* hihat = *hihatInst;
382− tSVF_setQ(&hihat->bandpassOsc,Q);
383−}
384−
385−void t808Hihat_setStickBandPassFreq(t808Hihat* const hihatInst, float freq)
386−{
387− _t808Hihat* hihat = *hihatInst;
388− tSVF_setFreq(&hihat->bandpassStick,freq);
389−}
390−
391−void t808Hihat_setStickBandPassQ(t808Hihat* const hihatInst, float Q)
392−{
393− _t808Hihat* hihat = *hihatInst;
394− tSVF_setQ(&hihat->bandpassStick,Q);
395−}
396−
397−void t808Hihat_setOscFreq(t808Hihat* const hihatInst, float freq)
398−{
399− _t808Hihat* hihat = *hihatInst;
400− hihat->freq = freq;
401−}
402−
403−// ----------------- SNARE ----------------------------//
404−
405−void t808Snare_init(t808Snare* const snareInst)
406−{
407− _t808Snare* snare = *snareInst = (_t808Snare*) leaf_alloc(sizeof(_t808Snare));
408−
409− float ratio[2] = {1.0, 1.5};
410− for (int i = 0; i < 2; i++)
411− {
412− tTriangle_init(&snare->tone[i]);
413−
414− tTriangle_setFreq(&snare->tone[i], ratio[i] * 400.0f);
415− tSVF_init(&snare->toneLowpass[i], SVFTypeLowpass, 4000, 1.0f);
416− tEnvelope_init(&snare->toneEnvOsc[i], 0.0f, 50.0f, OFALSE);
417− tEnvelope_init(&snare->toneEnvGain[i], 1.0f, 150.0f, OFALSE);
418− tEnvelope_init(&snare->toneEnvFilter[i], 1.0f, 2000.0f, OFALSE);
419−
420− snare->toneGain[i] = 0.5f;
421− }
422−
423− snare->tone1Freq = ratio[0] * 100.0f;
424− snare->tone2Freq = ratio[1] * 100.0f;
425− snare->noiseFilterFreq = 3000.0f;
426− tNoise_init(&snare->noiseOsc, WhiteNoise);
427− tSVF_init(&snare->noiseLowpass, SVFTypeLowpass, 12000.0f, 0.8f);
428− tEnvelope_init(&snare->noiseEnvGain, 0.0f, 100.0f, OFALSE);
429− tEnvelope_init(&snare->noiseEnvFilter, 0.0f, 1000.0f, OFALSE);
430− snare->noiseGain = 1.0f;
431−}
432−
433−void t808Snare_free (t808Snare* const snareInst)
434−{
435− _t808Snare* snare = *snareInst;
436−
437− for (int i = 0; i < 2; i++)
438− {
439− tTriangle_free(&snare->tone[i]);
440− tSVF_free(&snare->toneLowpass[i]);
441− tEnvelope_free(&snare->toneEnvOsc[i]);
442− tEnvelope_free(&snare->toneEnvGain[i]);
443− tEnvelope_free(&snare->toneEnvFilter[i]);
444− }
445−
446− tNoise_free(&snare->noiseOsc);
447− tSVF_free(&snare->noiseLowpass);
448− tEnvelope_free(&snare->noiseEnvGain);
449− tEnvelope_free(&snare->noiseEnvFilter);
450−
451− leaf_free((char*)snare);
452−}
453−
454−void t808Snare_initToPool (t808Snare* const snareInst, tMempool* const mp)
455−{
456− _tMempool* m = *mp;
457− _t808Snare* snare = *snareInst = (_t808Snare*) mpool_alloc(sizeof(_t808Snare), m);
458−
459− float ratio[2] = {1.0, 1.5};
460− for (int i = 0; i < 2; i++)
461− {
462− tTriangle_initToPool(&snare->tone[i], mp);
463−
464− tTriangle_setFreq(&snare->tone[i], ratio[i] * 400.0f);
465− tSVF_initToPool(&snare->toneLowpass[i], SVFTypeLowpass, 4000, 1.0f, mp);
466− tEnvelope_initToPool(&snare->toneEnvOsc[i], 0.0f, 50.0f, OFALSE, mp);
467− tEnvelope_initToPool(&snare->toneEnvGain[i], 1.0f, 150.0f, OFALSE, mp);
468− tEnvelope_initToPool(&snare->toneEnvFilter[i], 1.0f, 2000.0f, OFALSE, mp);
469−
470− snare->toneGain[i] = 0.5f;
471− }
472−
473− snare->tone1Freq = ratio[0] * 100.0f;
474− snare->tone2Freq = ratio[1] * 100.0f;
475− snare->noiseFilterFreq = 3000.0f;
476− tNoise_initToPool(&snare->noiseOsc, WhiteNoise, mp);
477− tSVF_initToPool(&snare->noiseLowpass, SVFTypeLowpass, 12000.0f, 0.8f, mp);
478− tEnvelope_initToPool(&snare->noiseEnvGain, 0.0f, 100.0f, OFALSE, mp);
479− tEnvelope_initToPool(&snare->noiseEnvFilter, 0.0f, 1000.0f, OFALSE, mp);
480− snare->noiseGain = 1.0f;
481−}
482−
483−void t808Snare_freeFromPool (t808Snare* const snareInst, tMempool* const mp)
484−{
485− _tMempool* m = *mp;
486− _t808Snare* snare = *snareInst;
487−
488− for (int i = 0; i < 2; i++)
489− {
490− tTriangle_freeFromPool(&snare->tone[i], mp);
491− tSVF_freeFromPool(&snare->toneLowpass[i], mp);
492− tEnvelope_freeFromPool(&snare->toneEnvOsc[i], mp);
493− tEnvelope_freeFromPool(&snare->toneEnvGain[i], mp);
494− tEnvelope_freeFromPool(&snare->toneEnvFilter[i], mp);
495− }
496−
497− tNoise_freeFromPool(&snare->noiseOsc, mp);
498− tSVF_freeFromPool(&snare->noiseLowpass, mp);
499− tEnvelope_freeFromPool(&snare->noiseEnvGain, mp);
500− tEnvelope_freeFromPool(&snare->noiseEnvFilter, mp);
501−
502− mpool_free((char*)snare, m);
503−}
504−
505−void t808Snare_on(t808Snare* const snareInst, float vel)
506−{
507− _t808Snare* snare = *snareInst;
508−
509− for (int i = 0; i < 2; i++)
510− {
511− tEnvelope_on(&snare->toneEnvOsc[i], vel);
512− tEnvelope_on(&snare->toneEnvGain[i], vel);
513− tEnvelope_on(&snare->toneEnvFilter[i], vel);
514− }
515−
516− tEnvelope_on(&snare->noiseEnvGain, vel);
517− tEnvelope_on(&snare->noiseEnvFilter, vel);
518−}
519−
520−void t808Snare_setTone1Freq(t808Snare* const snareInst, float freq)
521−{
522− _t808Snare* snare = *snareInst;
523− snare->tone1Freq = freq;
524− tTriangle_setFreq(&snare->tone[0], freq);
525−}
526−
527−void t808Snare_setTone2Freq(t808Snare* const snareInst, float freq)
528−{
529− _t808Snare* snare = *snareInst;
530− snare->tone2Freq = freq;
531− tTriangle_setFreq(&snare->tone[1],freq);
532−}
533−
534−void t808Snare_setTone1Decay(t808Snare* const snareInst, float decay)
535−{
536− _t808Snare* snare = *snareInst;
537− tEnvelope_setDecay(&snare->toneEnvGain[0],decay);
538−}
539−
540−void t808Snare_setTone2Decay(t808Snare* const snareInst, float decay)
541−{
542− _t808Snare* snare = *snareInst;
543− tEnvelope_setDecay(&snare->toneEnvGain[1],decay);
544−}
545−
546−void t808Snare_setNoiseDecay(t808Snare* const snareInst, float decay)
547−{
548− _t808Snare* snare = *snareInst;
549− tEnvelope_setDecay(&snare->noiseEnvGain,decay);
550−}
551−
552−void t808Snare_setToneNoiseMix(t808Snare* const snareInst, float toneNoiseMix)
553−{
554− _t808Snare* snare = *snareInst;
555− snare->toneNoiseMix = toneNoiseMix;
556−}
557−
558−void t808Snare_setNoiseFilterFreq(t808Snare* const snareInst, float noiseFilterFreq)
559−{
560− _t808Snare* snare = *snareInst;
561− snare->noiseFilterFreq = noiseFilterFreq;
562−}
563−
564−void t808Snare_setNoiseFilterQ(t808Snare* const snareInst, float noiseFilterQ)
565−{
566− _t808Snare* snare = *snareInst;
567− tSVF_setQ(&snare->noiseLowpass, noiseFilterQ);
568−}
569−
570−static float tone[2];
571−
572−float t808Snare_tick(t808Snare* const snareInst)
573−{
574− _t808Snare* snare = *snareInst;
575−
576− for (int i = 0; i < 2; i++)
577− {
578− tTriangle_setFreq(&snare->tone[i], snare->tone1Freq + (20.0f * tEnvelope_tick(&snare->toneEnvOsc[i])));
579− tone[i] = tTriangle_tick(&snare->tone[i]);
580−
581− tSVF_setFreq(&snare->toneLowpass[i], 2000.0f + (500.0f * tEnvelope_tick(&snare->toneEnvFilter[i])));
582− tone[i] = tSVF_tick(&snare->toneLowpass[i], tone[i]) * tEnvelope_tick(&snare->toneEnvGain[i]);
583− }
584−
585− float noise = tNoise_tick(&snare->noiseOsc);
586− tSVF_setFreq(&snare->noiseLowpass, snare->noiseFilterFreq + (1000.0f * tEnvelope_tick(&snare->noiseEnvFilter)));
587− noise = tSVF_tick(&snare->noiseLowpass, noise) * tEnvelope_tick(&snare->noiseEnvGain);
588−
589− float sample = (snare->toneNoiseMix)*(tone[0] * snare->toneGain[0] + tone[1] * snare->toneGain[1]) + (1.0f-snare->toneNoiseMix) * (noise * snare->noiseGain);
590− sample = tanhf(sample * 2.0f);
591− return sample;
592−}
593−
594−// ----------------- KICK ----------------------------//
595−
596−void t808Kick_init (t808Kick* const kickInst)
597−{
598− _t808Kick* kick = *kickInst = (_t808Kick*) leaf_alloc(sizeof(_t808Kick));
599−
600− tCycle_init(&kick->tone);
601− kick->toneInitialFreq = 40.0f;
602− kick->sighAmountInHz = 7.0f;
603− kick->chirpRatioMinusOne = 3.3f;
604− tCycle_setFreq(&kick->tone, 50.0f);
605− tSVF_init(&kick->toneLowpass, SVFTypeLowpass, 2000.0f, 0.5f);
606− tEnvelope_init(&kick->toneEnvOscChirp, 0.0f, 20.0f, OFALSE);
607− tEnvelope_init(&kick->toneEnvOscSigh, 0.0f, 2500.0f, OFALSE);
608− tEnvelope_init(&kick->toneEnvGain, 0.0f, 800.0f, OFALSE);
609− tNoise_init(&kick->noiseOsc, PinkNoise);
610− tEnvelope_init(&kick->noiseEnvGain, 0.0f, 1.0f, OFALSE);
611− kick->noiseGain = 0.3f;
612−}
613−
614−void t808Kick_free (t808Kick* const kickInst)
615−{
616− _t808Kick* kick = *kickInst;
617−
618− tCycle_free(&kick->tone);
619− tSVF_free(&kick->toneLowpass);
620− tEnvelope_free(&kick->toneEnvOscChirp);
621− tEnvelope_free(&kick->toneEnvOscSigh);
622− tEnvelope_free(&kick->toneEnvGain);
623− tNoise_free(&kick->noiseOsc);
624− tEnvelope_free(&kick->noiseEnvGain);
625−
626− leaf_free((char*)kick);
627−}
628−
629−void t808Kick_initToPool (t808Kick* const kickInst, tMempool* const mp)
630−{
631− _tMempool* m = *mp;
632− _t808Kick* kick = *kickInst = (_t808Kick*) mpool_alloc(sizeof(_t808Kick), m);
633−
634− tCycle_initToPool(&kick->tone, mp);
635− kick->toneInitialFreq = 40.0f;
636− kick->sighAmountInHz = 7.0f;
637− kick->chirpRatioMinusOne = 3.3f;
638− tCycle_setFreq(&kick->tone, 50.0f);
639− tSVF_initToPool(&kick->toneLowpass, SVFTypeLowpass, 2000.0f, 0.5f, mp);
640− tEnvelope_initToPool(&kick->toneEnvOscChirp, 0.0f, 20.0f, OFALSE, mp);
641− tEnvelope_initToPool(&kick->toneEnvOscSigh, 0.0f, 2500.0f, OFALSE, mp);
642− tEnvelope_initToPool(&kick->toneEnvGain, 0.0f, 800.0f, OFALSE, mp);
643− tNoise_initToPool(&kick->noiseOsc, PinkNoise, mp);
644− tEnvelope_initToPool(&kick->noiseEnvGain, 0.0f, 1.0f, OFALSE, mp);
645− kick->noiseGain = 0.3f;
646−}
647−
648−void t808Kick_freeFromPool (t808Kick* const kickInst, tMempool* const mp)
649−{
650− _tMempool* m = *mp;
651− _t808Kick* kick = *kickInst;
652−
653− tCycle_freeFromPool(&kick->tone, mp);
654− tSVF_freeFromPool(&kick->toneLowpass, mp);
655− tEnvelope_freeFromPool(&kick->toneEnvOscChirp, mp);
656− tEnvelope_freeFromPool(&kick->toneEnvOscSigh, mp);
657− tEnvelope_freeFromPool(&kick->toneEnvGain, mp);
658− tNoise_freeFromPool(&kick->noiseOsc, mp);
659− tEnvelope_freeFromPool(&kick->noiseEnvGain, mp);
660−
661− mpool_free((char*)kick, m);
662−}
663−
664−float t808Kick_tick (t808Kick* const kickInst)
665−{
666− _t808Kick* kick = *kickInst;
667−
668− tCycle_setFreq(&kick->tone, (kick->toneInitialFreq * (1.0f + (kick->chirpRatioMinusOne * tEnvelope_tick(&kick->toneEnvOscChirp)))) + (kick->sighAmountInHz * tEnvelope_tick(&kick->toneEnvOscSigh)));
669− float sample = tCycle_tick(&kick->tone) * tEnvelope_tick(&kick->toneEnvGain);
670− sample+= tNoise_tick(&kick->noiseOsc) * tEnvelope_tick(&kick->noiseEnvGain);
671− //add distortion here
672− sample = tSVF_tick(&kick->toneLowpass, sample);
673− return sample;
674−}
675−
676−void t808Kick_on (t808Kick* const kickInst, float vel)
677−{
678− _t808Kick* kick = *kickInst;
679− tEnvelope_on(&kick->toneEnvOscChirp, vel);
680− tEnvelope_on(&kick->toneEnvOscSigh, vel);
681− tEnvelope_on(&kick->toneEnvGain, vel);
682− tEnvelope_on(&kick->noiseEnvGain, vel);
683−
684−}
685−void t808Kick_setToneFreq (t808Kick* const kickInst, float freq)
686−{
687− _t808Kick* kick = *kickInst;
688− kick->toneInitialFreq = freq;
689−
690−}
691−
692−void t808Kick_setToneDecay (t808Kick* const kickInst, float decay)
693−{
694− _t808Kick* kick = *kickInst;
695− tEnvelope_setDecay(&kick->toneEnvGain,decay);
696− tEnvelope_setDecay(&kick->toneEnvGain,decay * 3.0f);
697−}
698−
699−void t808Kick_setNoiseDecay (t808Kick* const kickInst, float decay);
700−void t808Kick_setSighAmount (t808Kick* const kickInst, float sigh);
701−void t808Kick_setChirpAmount (t808Kick* const kickInst, float chirp);
702−void t808Kick_setToneNoiseMix (t808Kick* const kickInst, float toneNoiseMix);
703−void t808Kick_setNoiseFilterFreq (t808Kick* const kickInst, float noiseFilterFreq);
704−void t808Kick_setNoiseFilterQ (t808Kick* const kickInst, float noiseFilterQ);
705−
706−
LEAF/Src/leaf-math.c+0−655
@@ -1,655 +0,0 @@
1−/*==============================================================================
2−
3− leaf-math.c
4− Created: 22 Jan 2017 7:02:56pm
5− Author: Michael R Mulshine
6−
7− ==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-math.h"
12−#include "..\Inc\leaf-tables.h"
13−
14−#else
15−
16−#include "../Inc/leaf-math.h"
17−#include "../Inc/leaf-tables.h"
18−
19−#endif
20−
21−
22−#define EXPONENTIAL_TABLE_SIZE 65536
23−
24−#define log10f_fast(x) (log2f_approx(x)*0.3010299956639812f)
25−
26−// This is a fast approximation to log2() found on http://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html credited to this post https://community.arm.com/developer/tools-software/tools/f/armds-forum/4292/cmsis-dsp-new-functionality-proposal/22621#22621
27−// Y = C[0]*F*F*F + C[1]*F*F + C[2]*F + C[3] + E;
28−float log2f_approx(float X) {
29− float Y, F;
30− int E;
31− F = frexpf(fabsf(X), &E);
32− Y = 1.23149591368684f;
33− Y *= F;
34− Y += -4.11852516267426f;
35− Y *= F;
36− Y += 6.02197014179219f;
37− Y *= F;
38− Y += -3.13396450166353f;
39− Y += E;
40− return(Y);
41−}
42−
43−float interpolate3max(float *buf, const int peakindex)
44−{
45− float a = buf[peakindex-1];
46− float b = buf[peakindex];
47− float c = buf[peakindex+1];
48− float realpeak;
49−
50− realpeak = b + (float)0.125 * (c - a) * (c - a) / ((float)2. * b - a - c);
51−
52− return(realpeak);
53−}
54−
55−float interpolate3phase(float *buf, const int peakindex)
56−{
57− float a = buf[peakindex-1];
58− float b = buf[peakindex];
59− float c = buf[peakindex+1];
60− float fraction;
61−
62− fraction = ((float)0.5 * (c - a)) / ((float)2. * b - a - c);
63−
64− return(fraction);
65−}
66−
67−// alternative implementation for abs()
68−// REQUIRES: 32 bit integers
69−int fastabs_int(int in){
70− unsigned int r;
71− int const mask = in >> 31;
72−
73− r = (in ^ mask) - mask;
74−
75− return (r);
76−}
77−
78−// alternative implementation for abs()
79−// REQUIRES: 32 bit floats
80−float fastabsf(float f)
81−{
82− union
83− {
84− float f;
85− unsigned int ui;
86− }alias;
87−
88− alias.f = f;
89− alias.ui &= 0x7fffffff;
90− return alias.f;
91−}
92−
93−double fastexp(double x) {
94− x = 1.0 + (x * 0.0009765625);
95− x *= x; x *= x; x *= x; x *= x;
96− x *= x; x *= x; x *= x; x *= x;
97− x *= x; x *= x;
98− return x;
99−}
100−
101−float fastexpf(float x) {
102− x = 1.0f + (x * 0.0009765625f);
103− x *= x; x *= x; x *= x; x *= x;
104− x *= x; x *= x; x *= x; x *= x;
105− x *= x; x *= x;
106− return x;
107−}
108−
109−double fasterexp(double x) {
110− x = 1.0 + (x * 0.00390625);
111− x *= x; x *= x; x *= x; x *= x;
112− x *= x; x *= x; x *= x; x *= x;
113− return x;
114−}
115−
116−float fasterexpf(float x) {
117− x = 1.0f + (x * 0.00390625f);
118− x *= x; x *= x; x *= x; x *= x;
119− x *= x; x *= x; x *= x; x *= x;
120− return x;
121−}
122−
123−// fast floating-point exp2 function taken from Robert Bristow Johnson's
124−// post in the music-dsp list on Date: Tue, 02 Sep 2014 16:50:11 -0400
125−float fastexp2f(float x)
126−{
127− if (x >= -127.0)
128− {
129− float accumulator, xPower;
130− union {float f; int32_t i;} xBits;
131−
132− xBits.i = (int32_t)(x + 4096.0f) - 4096L; /* integer part */
133− x -= (float)(xBits.i); /* fractional part */
134−
135− accumulator = 1.0f + 0.69303212081966f*x;
136− xPower = x*x;
137− accumulator += 0.24137976293709f*xPower;
138− xPower *= x;
139− accumulator += 0.05203236900844f*xPower;
140− xPower *= x;
141− accumulator += 0.01355574723481f*xPower;
142−
143− xBits.i += 127; /* bias integer part */
144− xBits.i<<= 23; /* move biased int part into exponent bits */
145−
146− return accumulator * xBits.f;
147− }
148− else
149− {
150− return 0.0f;
151− }
152−}
153−
154−
155−float fastPowf(float a, float b) {
156− union
157− {
158− float d; int x;
159− }
160− u = { a };
161−
162− u.x = (int)(b * (u.x - 1064866805) + 1064866805);
163− return u.d;
164−}
165−
166−
167−double fastPow(double a, double b) {
168− union {
169− double d;
170− int x[2];
171− } u = { a };
172−
173− u.x[1] = (int)(b * (u.x[1] - 1072632447) + 1072632447);
174−
175− u.x[0] = 0;
176− return u.d;
177−}
178−
179−
180−
181−
182−
183−/*
184− you pass in a float array to get back two indexes representing the volumes of the left (index 0) and right (index 1) channels
185− when t is -1, volumes[0] = 0, volumes[1] = 1
186− when t = 0, volumes[0] = 0.707, volumes[1] = 0.707 (equal-power cross fade)
187− when t = 1, volumes[0] = 1, volumes[1] = 0
188− */
189−
190−void LEAF_crossfade(float fade, float* volumes) {
191− volumes[0] = sqrtf(0.5f * (1.0f + fade));
192− volumes[1] = sqrtf(0.5f * (1.0f - fade));
193−}
194−
195−// dope af
196−float LEAF_chebyshevT(float in, int n){
197− if (n == 0) return 1;
198− else if (n == 1) return in;
199− else return 2.0f * in * LEAF_chebyshevT(in, n-1) - LEAF_chebyshevT(in, n-2);
200−}
201−
202−#if !(_WIN32 || _WIN64)
203−float LEAF_CompoundChebyshevT(float in, int n, float* amps){
204− float T[n+1];
205− T[0] = 1.0f;
206− T[1] = in;
207− for (int i = 2; i <= n; ++i)
208− T[i] = 2*in*T[i-1] - T[i-2];
209− float out = 0;
210− float amp = 0;
211− for (int i = 0; i < n; ++i){
212− out += amps[i]*T[i+1];
213− amp += amps[i];
214− }
215− return out / amp ;
216−}
217−#endif
218−
219−float LEAF_frequencyToMidi(float f)
220−{
221− return (69.0f + 12.0f * log2f(f * INV_440));
222−}
223−
224−// Jones shaper
225−float LEAF_shaper(float input, float m_drive)
226−{
227− float fx = input * 2.0f; // prescale
228− float w, c, xc, xc2, xc4;
229−
230− xc = LEAF_clip(-SQRT8, fx, SQRT8);
231− xc2 = xc*xc;
232− c = 0.5f*fx*(3.0f - (xc2));
233− xc4 = xc2 * xc2;
234− w = (1.0f - xc2*0.25f + xc4*0.015625f) * WSCALE;
235− float shaperOut = w*(c+ 0.05f*xc2)*(m_drive + 0.75f);
236− shaperOut *= 0.5f; // post_scale
237− return shaperOut;
238−}
239−
240−// round input to nearest rnd
241−float LEAF_round (float input, float rnd)
242−{
243− rnd = fabsf(rnd);
244−
245− if (rnd <= 0.0000001f) return input;
246−
247− float scale = 1.f / rnd;
248−
249− return roundf(input * scale) / scale;
250−}
251−
252−
253−
254−float LEAF_bitwise_xor(float input, uint32_t op)
255−{
256− union unholy_t unholy;
257− unholy.f = input;
258− unholy.i = (unholy.i ^ op);
259−
260− return unholy.f;
261−}
262−
263−float LEAF_reedTable(float input, float offset, float slope)
264−{
265− float output = offset + (slope * input);
266− if ( output > 1.0f) output = 1.0f;
267− if ( output < -1.0f) output = -1.0f;
268− return output;
269−}
270−
271−float LEAF_softClip(float val, float thresh)
272−{
273− float x;
274−
275− if(val > thresh)
276− {
277− x = thresh / val;
278− return (1.0f - x) * (1.0f - thresh) + thresh;
279− }
280− else if(val < -thresh)
281− {
282− x = -thresh / val;
283− return -((1.0f - x) * (1.0f - thresh) + thresh);
284− }
285− else
286− {
287− return val;
288− }
289−}
290−
291−float LEAF_clip(float min, float val, float max)
292−{
293− float tempmin = min;
294− float tempmax = max;
295− if (min > max)
296− {
297− tempmin = max;
298− tempmax = min;
299− }
300− if (val < tempmin) {
301− return tempmin;
302− } else if (val > tempmax) {
303− return tempmax;
304− } else {
305− return val;
306− }
307−}
308−
309−int LEAF_clipInt(int min, int val, int max)
310−{
311− int tempmin = min;
312− int tempmax = max;
313− if (min > max)
314− {
315− tempmin = max;
316− tempmax = min;
317− }
318− if (val < tempmin) {
319− return tempmin;
320− } else if (val > tempmax) {
321− return tempmax;
322− } else {
323− return val;
324− }
325−}
326−
327−oBool LEAF_isPrime(uint64_t number )
328−{
329− if ( number == 2 ) return OTRUE;
330− if ( number & 1 ) {
331− for ( int i=3; i<(int)sqrt((double)number)+1; i+=2 )
332− if ( (number % i) == 0 ) return OFALSE;
333− return OTRUE; // prime
334− }
335− else return OFALSE; // even
336−}
337−
338−// Adapted from MusicDSP: http://www.musicdsp.org/showone.php?id=238
339−float LEAF_tanh(float x)
340−{
341−
342− if( x < -3.0f )
343− return -1.0f;
344− else if( x > 3.0f )
345− return 1.0f;
346− else
347− return x * ( 27.0f + x * x ) / ( 27.0f + 9.0f * x * x );
348−}
349−
350−
351−void LEAF_generate_sine(float* buffer, int size)
352−{
353− float phase;
354− for (int i = 0; i < size; i++)
355− {
356− phase = (float) i / (float) size;
357− buffer[i] = sinf(phase * TWO_PI);
358− }
359−}
360−
361−void LEAF_generate_sawtooth(float* buffer, float basefreq, int size)
362−{
363− int harmonic = 1;
364− float phase = 0.0f;
365− float freq = harmonic * basefreq;
366− float amp;
367−
368− while (freq < (leaf.sampleRate * 0.5))
369− {
370− amp = 1.0f / harmonic;
371− for (int i = 0; i < size; i++)
372− {
373− phase = (float) i / (float) size;
374− buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
375− }
376−
377− harmonic++;
378− freq = harmonic * basefreq;
379− }
380−}
381−
382−
383−void LEAF_generate_triangle(float* buffer, float basefreq, int size)
384−{
385− int harmonic = 1;
386− float phase = 0.0f;
387− float freq = harmonic * basefreq;
388− float amp = 1.0f;
389−
390− int count = 0;
391− float mult = 1.0f;
392−
393− while (freq < (leaf.sampleRate * 0.5))
394− {
395− amp = 1.0f / (float)(harmonic * harmonic);
396−
397− if (count % 2) mult = -1.0f;
398− else mult = 1.0f;
399−
400− for (int i = 0; i < size; i++)
401− {
402− phase = (float) i / (float) size;
403− buffer[i] += (mult * amp * sinf(harmonic * phase * TWO_PI));
404− }
405−
406− count++;
407− harmonic += 2;
408− freq = harmonic * basefreq;
409− }
410−}
411−
412−void LEAF_generate_square(float* buffer, float basefreq, int size)
413−{
414− int harmonic = 1;
415− float phase = 0.0f;
416− float freq = harmonic * basefreq;
417− float amp = 1.0f;
418−
419− while (freq < (leaf.sampleRate * 0.5))
420− {
421− amp = 1.0f / (float)(harmonic);
422−
423− for (int i = 0; i < size; i++)
424− {
425− phase = (float) i / (float) size;
426− buffer[i] += (amp * sinf(harmonic * phase * TWO_PI));
427− }
428−
429− harmonic += 2;
430− freq = harmonic * basefreq;
431− }
432−}
433−
434−
435−//0.001 base gives a good curve that goes from 1 to near zero
436−void LEAF_generate_exp(float* buffer, float base, float start, float end, float offset, int size)
437−{
438− float increment = (end - start) / (float)size;
439− float x = start;
440− for (int i = 0; i < size; i++)
441− {
442− buffer[i] = powf(base, x) + offset;
443− x += increment;
444− }
445−}
446−
447−
448−// http://www.martin-finke.de/blog/articles/audio-plugins-018-polyblep-oscillator/
449−// http://www.kvraudio.com/forum/viewtopic.php?t=375517
450−// t = phase, dt = inc, assuming 0-1 phase
451−// assumes discontinuity at 0, so offset inputs as needed
452−float LEAF_poly_blep(float t, float dt)
453−{
454− // 0 <= t < 1
455− if (t < dt) {
456− t /= dt;
457− return t+t - t*t - 1.0f;
458− }
459− // -1 < t < 0
460− else if (t > 1.0f - dt) {
461− t = (t - 1.0f) / dt;
462− return t*t + t+t + 1.0f;
463− }
464− // 0 otherwise
465− else return 0.0f;
466−
467−//
468−// float y = 0.0f;
469−// if (t < 2.0f * dt)
470−// {
471−// float x = t / dt;
472−// float u = 2.0f - x;
473−// u *= u;
474−// u *= u;
475−// y += u;
476−// if (t < dt) {
477−// float v = 1.0f - x;
478−// v *= v;
479−// v *= v;
480−// y -= 4.0f * v;
481−// }
482−// }
483−// else if (t > 1.0f - (2.0f * dt))
484−// {
485−// float x = (t - 1.0f) / dt;
486−// float u = 2.0f - x;
487−// u *= u;
488−// u *= u;
489−// y += u;
490−// if (t > 1.0f - dt) {
491−// float v = 1.0f - x;
492−// v *= v;
493−// v *= v;
494−// y += 4.0f * v;
495−// }
496−// }
497−// return y / 12.0f;
498−}
499−
500−
501−//-----------------------------------------------------------------------------
502−// name: mtof()
503−// desc: midi to freq, from PD source
504−//-----------------------------------------------------------------------------
505−float LEAF_midiToFrequency(float f)
506−{
507− if( f <= -1500.0f ) return (0);
508− else if( f > 1499.0f ) return (LEAF_midiToFrequency(1499.0f));
509− else return ( powf(2.0f, (f - 69.0f) * 0.083333333333333f) * 440.0f );
510−}
511−
512−
513−// alpha, [0.0, 1.0]
514−float LEAF_interpolate_hermite (float A, float B, float C, float D, float alpha)
515−{
516− alpha = LEAF_clip(0.0f, alpha, 1.0f);
517−
518− float a = -A*0.5f + (3.0f*B)*0.5f - (3.0f*C)*0.5f + D*0.5f;
519− float b = A - (5.0f*B)*0.5f + 2.0f*C - D * 0.5f;
520− float c = -A*0.5f + C*0.5f;
521− float d = B;
522−
523− return a*alpha*alpha*alpha + b*alpha*alpha + c*alpha + d;
524−}
525−
526−
527−// from http://www.musicdsp.org/archive.php?classid=5#93
528−//xx is alpha (fractional part of sample value)
529−//grabbed this from Tom Erbe's Delay pd code
530−float LEAF_interpolate_hermite_x(float yy0, float yy1, float yy2, float yy3, float xx)
531−{
532− // 4-point, 3rd-order Hermite (x-form)
533− float c0 = yy1;
534− float c1 = 0.5f * (yy2 - yy0);
535− float y0my1 = yy0 - yy1;
536− float c3 = (yy1 - yy2) + 0.5f * (yy3 - y0my1 - yy2);
537− float c2 = y0my1 + c1 - c3;
538−
539− return ((c3 * xx + c2) * xx + c1) * xx + c0;
540−}
541−
542−// alpha, [0.0, 1.0]
543−float LEAF_interpolation_linear (float A, float B, float alpha)
544−{
545− alpha = LEAF_clip(0.0f, alpha, 1.0f);
546−
547− float omAlpha = 1.0f - alpha;
548−
549− // First 1/2 of interpolation
550− float out = A * omAlpha;
551−
552− out += B * alpha;
553−
554− return out;
555−}
556−
557−#define LOGTEN 2.302585092994
558−
559−float mtof(float f)
560−{
561− if (f <= -1500.0f) return(0);
562− else if (f > 1499.0f) return(mtof(1499.0f));
563− else return (8.17579891564f * expf(0.0577622650f * f));
564−}
565−
566−float fast_mtof(float f)
567−{
568− return (8.17579891564f * fastexpf(0.0577622650f * f));
569−}
570−
571−float faster_mtof(float f)
572−{
573− return (8.17579891564f * fastexpf(0.0577622650f * f));
574−}
575−
576−float ftom(float f)
577−{
578− return (f > 0 ? 17.3123405046f * logf(.12231220585f * f) : -1500.0f);
579−}
580−
581−float powtodb(float f)
582−{
583− if (f <= 0) return (0);
584− else
585− {
586− float val = 100.0f + 10.0f/LOGTEN * logf(f);
587− return (val < 0.0f ? 0.0f : val);
588− }
589−}
590−
591−float rmstodb(float f)
592−{
593− if (f <= 0) return (0);
594− else
595− {
596− float val = 100 + 20.f/LOGTEN * log(f);
597− return (val < 0 ? 0 : val);
598− }
599−}
600−
601−float dbtopow(float f)
602−{
603− if (f <= 0)
604− return(0);
605− else
606− {
607− if (f > 870.0f)
608− f = 870.0f;
609− return (expf((LOGTEN * 0.1f) * (f-100.0f)));
610− }
611−}
612−
613−float dbtorms(float f)
614−{
615− if (f <= 0)
616− return(0);
617− else
618− {
619− if (f > 485.0f)
620− f = 485.0f;
621− }
622− return (expf((LOGTEN * 0.05f) * (f-100.0f)));
623−}
624−
625−
626−float atodb(float a)
627−{
628− return 20.0f*log10f(a);
629−}
630−
631−float dbtoa(float db)
632−{
633− return powf(10.0f, db * 0.05f);
634− //return expf(0.115129254649702f * db); //faster version from http://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html
635−}
636−
637−
638−float fastdbtoa(float db)
639−{
640− //return powf(10.0f, db * 0.05f);
641− return expf(0.115129254649702f * db); //faster version from http://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html
642−}
643−
644−
645−float maximum (float num1, float num2)
646−{
647− return (num1 > num2 ) ? num1 : num2;
648−}
649−
650−float minimum (float num1, float num2)
651−{
652− return (num1 < num2 ) ? num1 : num2;
653−}
654−
655−
LEAF/Src/leaf-mempool.c+0−412
@@ -1,412 +0,0 @@
1−
2−/** mpool source significantly modified by Mike Mulshine, Jeff Snyder, et al., Princeton University Music Department **/
3−
4−/**
5− In short, mpool is distributed under so called "BSD license",
6−
7− Copyright (c) 2009-2010 Tatsuhiko Kubo <cubicdaiya@gmail.com>
8− All rights reserved.
9−
10− Redistribution and use in source and binary forms, with or without modification,
11− are permitted provided that the following conditions are met:
12−
13− * Redistributions of source code must retain the above copyright notice,
14− this list of conditions and the following disclaimer.
15−
16− * Redistributions in binary form must reproduce the above copyright notice,
17− this list of conditions and the following disclaimer in the documentation
18− and/or other materials provided with the distribution.
19−
20− * Neither the name of the authors nor the names of its contributors
21− may be used to endorse or promote products derived from this software
22− without specific prior written permission.
23−
24− THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25− "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26− LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27− A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28− OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29− SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
30− TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31− PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32− LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33− NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34− SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35− */
36−
37−/* written with C99 style */
38−
39−#if _WIN32 || _WIN64
40−
41−#include "..\Inc\leaf-mempool.h"
42−#include "..\leaf.h"
43−
44−#else
45−
46−#include "../Inc/leaf-mempool.h"
47−#include "../leaf.h"
48−
49−#endif
50−
51−/**
52− * private function
53− */
54−static inline size_t mpool_align(size_t size);
55−static inline mpool_node_t* create_node(char* block_location, mpool_node_t* next, mpool_node_t* prev, size_t size);
56−static inline void delink_node(mpool_node_t* node);
57−
58−/**
59− * create memory pool
60− */
61−void mpool_create (char* memory, size_t size, _tMempool* pool)
62−{
63− leaf.header_size = mpool_align(sizeof(mpool_node_t));
64−
65− pool->mpool = (char*)memory;
66− pool->usize = 0;
67− pool->msize = size;
68−
69− pool->head = create_node(pool->mpool, NULL, NULL, pool->msize-leaf.header_size);
70−
71− /*
72− for (int i = 0; i < pool->head->size; i++)
73− {
74− memory[i+leaf.header_size]=0;
75− }
76− */
77− //is zeroing out the memory necessary? This takes a long time on large pools - JS
78−}
79−
80−void leaf_pool_init(char* memory, size_t size)
81−{
82− mpool_create(memory, size, &leaf._mempool);
83−
84− leaf.mempool = &leaf._mempool;
85−}
86−
87−/**
88− * allocate memory from memory pool
89− */
90−char* mpool_alloc(size_t asize, _tMempool* pool)
91−{
92− // If the head is NULL, the mempool is full
93− if (pool->head == NULL)
94− {
95− leaf_mempool_overrun();
96− return NULL;
97− }
98−
99− // Should we alloc the first block large enough or check all blocks and pick the one closest in size?
100− size_t size_to_alloc = mpool_align(asize);
101− mpool_node_t* node_to_alloc = pool->head;
102−
103− // Traverse the free list for a large enough block
104− while (node_to_alloc->size < size_to_alloc)
105− {
106− node_to_alloc = node_to_alloc->next;
107−
108− // If we reach the end of the free list, there
109− // are no blocks large enough, return NULL
110− if (node_to_alloc == NULL)
111− {
112− leaf_mempool_overrun();
113− return NULL;
114− }
115− }
116−
117− // Create a new node after the node to be allocated if there is enough space
118− mpool_node_t* new_node;
119− size_t leftover = node_to_alloc->size - size_to_alloc;
120− node_to_alloc->size = size_to_alloc;
121− if (leftover > leaf.header_size)
122− {
123− long offset = (char*) node_to_alloc - (char*) pool->mpool;
124− offset += leaf.header_size + node_to_alloc->size;
125− new_node = create_node(&pool->mpool[offset],
126− node_to_alloc->next,
127− node_to_alloc->prev,
128− leftover - leaf.header_size);
129− }
130− else
131− {
132− // Add any leftover space to the allocated node to avoid fragmentation
133− node_to_alloc->size += leftover;
134−
135− new_node = node_to_alloc->next;
136− }
137−
138− // Update the head if we are allocating the first node of the free list
139− // The head will be NULL if there is no space left
140− if (pool->head == node_to_alloc)
141− {
142− pool->head = new_node;
143− }
144−
145− // Remove the allocated node from the free list
146− delink_node(node_to_alloc);
147−
148− pool->usize += leaf.header_size + node_to_alloc->size;
149−
150− if (leaf.clearOnAllocation > 0)
151− {
152− char* new_pool = (char*)node_to_alloc->pool;
153− for (int i = 0; i < node_to_alloc->size; i++) new_pool[i] = 0;
154− }
155−
156− // Return the pool of the allocated node;
157− return node_to_alloc->pool;
158−}
159−
160−
161−/**
162− * allocate memory from memory pool and also clear that memory to be blank
163− */
164−char* mpool_calloc(size_t asize, _tMempool* pool)
165−{
166− // If the head is NULL, the mempool is full
167− if (pool->head == NULL)
168− {
169− leaf_mempool_overrun();
170− return NULL;
171− }
172−
173− // Should we alloc the first block large enough or check all blocks and pick the one closest in size?
174− size_t size_to_alloc = mpool_align(asize);
175− mpool_node_t* node_to_alloc = pool->head;
176−
177− // Traverse the free list for a large enough block
178− while (node_to_alloc->size < size_to_alloc)
179− {
180− node_to_alloc = node_to_alloc->next;
181−
182− // If we reach the end of the free list, there
183− // are no blocks large enough, return NULL
184− if (node_to_alloc == NULL)
185− {
186− leaf_mempool_overrun();
187− return NULL;
188− }
189− }
190−
191− // Create a new node after the node to be allocated if there is enough space
192− mpool_node_t* new_node;
193− size_t leftover = node_to_alloc->size - size_to_alloc;
194− node_to_alloc->size = size_to_alloc;
195− if (leftover > leaf.header_size)
196− {
197− long offset = (char*) node_to_alloc - (char*) pool->mpool;
198− offset += leaf.header_size + node_to_alloc->size;
199− new_node = create_node(&pool->mpool[offset],
200− node_to_alloc->next,
201− node_to_alloc->prev,
202− leftover - leaf.header_size);
203− }
204− else
205− {
206− // Add any leftover space to the allocated node to avoid fragmentation
207− node_to_alloc->size += leftover;
208−
209− new_node = node_to_alloc->next;
210− }
211−
212− // Update the head if we are allocating the first node of the free list
213− // The head will be NULL if there is no space left
214− if (pool->head == node_to_alloc)
215− {
216− pool->head = new_node;
217− }
218−
219− // Remove the allocated node from the free list
220− delink_node(node_to_alloc);
221−
222− pool->usize += leaf.header_size + node_to_alloc->size;
223− // Format the new pool
224− char* new_pool = (char*)node_to_alloc->pool;
225− for (int i = 0; i < node_to_alloc->size; i++) new_pool[i] = 0;
226− // Return the pool of the allocated node;
227− return node_to_alloc->pool;
228−}
229−
230−char* leaf_alloc(size_t size)
231−{
232− //printf("alloc %i\n", size);
233− char* block = mpool_alloc(size, &leaf._mempool);
234−
235− if (block == NULL) leaf_mempool_overrun();
236−
237− return block;
238−}
239−
240−char* leaf_calloc(size_t size)
241−{
242− //printf("alloc %i\n", size);
243− char* block = mpool_calloc(size, &leaf._mempool);
244−
245− if (block == NULL) leaf_mempool_overrun();
246−
247−
248− return block;
249−}
250−
251−void mpool_free(char* ptr, _tMempool* pool)
252−{
253− //if (ptr < pool->mpool || ptr >= pool->mpool + pool->msize)
254− // Get the node at the freed space
255− mpool_node_t* freed_node = (mpool_node_t*) (ptr - leaf.header_size);
256−
257− pool->usize -= leaf.header_size + freed_node->size;
258−
259− // Check each node in the list against the newly freed one to see if it's adjacent in memory
260− mpool_node_t* other_node = pool->head;
261− mpool_node_t* next_node;
262− while (other_node != NULL)
263− {
264− next_node = other_node->next;
265− // Check if a node is directly after the freed node
266− if ((long) freed_node + (leaf.header_size + freed_node->size) == (long) other_node)
267− {
268− // Increase freed node's size
269− freed_node->size += leaf.header_size + other_node->size;
270− // If we are merging with the head, move the head forward
271− if (other_node == pool->head) pool->head = pool->head->next;
272− // Delink the merged node
273− delink_node(other_node);
274− }
275−
276− // Check if a node is directly before the freed node
277− else if ((long) other_node + (leaf.header_size + other_node->size) == (long) freed_node)
278− {
279− // Increase the merging node's size
280− other_node->size += leaf.header_size + freed_node->size;
281−
282− if (other_node != pool->head)
283− {
284− // Delink the merging node
285− delink_node(other_node);
286− // Attach the merging node to the head
287− other_node->next = pool->head;
288− // Merge
289− freed_node = other_node;
290− }
291− else
292− {
293− // If we are merging with the head, move the head forward
294− pool->head = pool->head->next;
295− // Merge
296− freed_node = other_node;
297− }
298− }
299−
300− other_node = next_node;
301− }
302−
303− // Ensure the freed node is attached to the head
304− freed_node->next = pool->head;
305− if (pool->head != NULL) pool->head->prev = freed_node;
306− pool->head = freed_node;
307−
308− // Format the freed pool
309− // char* freed_pool = (char*)freed_node->pool;
310− // for (int i = 0; i < freed_node->size; i++) freed_pool[i] = 0;
311−}
312−
313−void leaf_free(char* ptr)
314−{
315− mpool_free(ptr, &leaf._mempool);
316−}
317−
318−size_t mpool_get_size(_tMempool* pool)
319−{
320− return pool->msize;
321−}
322−
323−size_t mpool_get_used(_tMempool* pool)
324−{
325− return pool->usize;
326−}
327−
328−size_t leaf_pool_get_size(void)
329−{
330− return mpool_get_size(&leaf._mempool);
331−}
332−
333−size_t leaf_pool_get_used(void)
334−{
335− return mpool_get_used(&leaf._mempool);
336−}
337−
338−char* leaf_pool_get_pool(void)
339−{
340− char* buff = leaf._mempool.mpool;
341−
342− return buff;
343−}
344−
345−/**
346− * align byte boundary
347− */
348−static inline size_t mpool_align(size_t size) {
349− return (size + (MPOOL_ALIGN_SIZE - 1)) & ~(MPOOL_ALIGN_SIZE - 1);
350−}
351−
352−static inline mpool_node_t* create_node(char* block_location, mpool_node_t* next, mpool_node_t* prev, size_t size)
353−{
354− mpool_node_t* node = (mpool_node_t*)block_location;
355− node->pool = block_location + leaf.header_size;
356− node->next = next;
357− node->prev = prev;
358− node->size = size;
359−
360− return node;
361−}
362−
363−static inline void delink_node(mpool_node_t* node)
364−{
365− // If there is a node after the node to remove
366− if (node->next != NULL)
367− {
368− // Close the link
369− node->next->prev = node->prev;
370− }
371− // If there is a node before the node to remove
372− if (node->prev != NULL)
373− {
374− // Close the link
375− node->prev->next = node->next;
376− }
377−
378− node->next = NULL;
379− node->prev = NULL;
380−}
381−
382−void leaf_mempool_overrun(void)
383−{
384− LEAF_error(1);
385− //TODO: we should make a set of real error codes that are in an enum type
386−}
387−
388−void tMempool_init(tMempool* const mp, char* memory, size_t size)
389−{
390− tMempool_initToPool(mp, memory, size, &leaf.mempool);
391−}
392−
393−void tMempool_free(tMempool* const mp)
394−{
395− tMempool_freeFromPool(mp, &leaf.mempool);
396−}
397−
398−void tMempool_initToPool (tMempool* const mp, char* memory, size_t size, tMempool* const mem)
399−{
400− _tMempool* mm = *mem;
401− _tMempool* m = *mp = (_tMempool*) mpool_alloc(sizeof(_tMempool), mm);
402−
403− mpool_create (memory, size, m);
404−}
405−
406−void tMempool_freeFromPool (tMempool* const mp, tMempool* const mem)
407−{
408− _tMempool* mm = *mem;
409− _tMempool* m = *mp;
410−
411− mpool_free((char*)m, mm);
412−}
LEAF/Src/leaf-midi.c+0−980
@@ -1,980 +0,0 @@
1−/*==============================================================================
2−
3− leaf-midi.c
4− Created: 30 Nov 2018 11:29:16am
5− Author: airship
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-midi.h"
12−
13−#else
14−
15−#include "../Inc/leaf-midi.h"
16−
17−#endif
18−
19−//====================================================================================
20−/* Stack */
21−//====================================================================================
22−
23−void tStack_init(tStack* const stack)
24−{
25− _tStack* ns = *stack = (_tStack*) leaf_alloc(sizeof(_tStack));
26−
27− ns->ordered = OFALSE;
28− ns->size = 0;
29− ns->pos = 0;
30− ns->capacity = STACK_SIZE;
31−
32− for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
33−}
34−
35−void tStack_free(tStack* const stack)
36−{
37− _tStack* ns = *stack;
38−
39− leaf_free((char*)ns);
40−}
41−
42−void tStack_initToPool (tStack* const stack, tMempool* const mp)
43−{
44− _tMempool* m = *mp;
45− _tStack* ns = *stack = (_tStack*) mpool_alloc(sizeof(_tStack), m);
46−
47− ns->ordered = OFALSE;
48− ns->size = 0;
49− ns->pos = 0;
50− ns->capacity = STACK_SIZE;
51−
52− for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
53−}
54−
55−void tStack_freeFromPool (tStack* const stack, tMempool* const mp)
56−{
57− _tMempool* m = *mp;
58− _tStack* ns = *stack;
59−
60− mpool_free((char*)ns, m);
61−}
62−
63−// If stack contains note, returns index. Else returns -1;
64−int tStack_contains(tStack* const stack, uint16_t noteVal)
65−{
66− _tStack* ns = *stack;
67− for (int i = 0; i < ns->size; i++)
68− {
69− if (ns->data[i] == noteVal) return i;
70− }
71− return -1;
72−}
73−
74−void tStack_add(tStack* const stack, uint16_t noteVal)
75−{
76− _tStack* ns = *stack;
77−
78− uint8_t j;
79−
80− int whereToInsert = 0;
81− if (ns->ordered)
82− {
83− for (j = 0; j < ns->size; j++)
84− {
85− if (noteVal > ns->data[j])
86− {
87− if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
88− {
89− whereToInsert = j+1;
90− break;
91− }
92− }
93− }
94− }
95−
96− //first move notes that are already in the stack one position to the right
97− for (j = ns->size; j > whereToInsert; j--)
98− {
99− ns->data[j] = ns->data[(j - 1)];
100− }
101−
102− //then, insert the new note into the front of the stack
103− ns->data[whereToInsert] = noteVal;
104−
105− ns->size++;
106−}
107−
108−int tStack_addIfNotAlreadyThere(tStack* const stack, uint16_t noteVal)
109−{
110− _tStack* ns = *stack;
111−
112− uint8_t j;
113−
114− int added = 0;
115−
116− if (tStack_contains(stack, noteVal) == -1)
117− {
118− int whereToInsert = 0;
119− if (ns->ordered)
120− {
121− for (j = 0; j < ns->size; j++)
122− {
123− if (noteVal > ns->data[j])
124− {
125− if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
126− {
127− whereToInsert = j+1;
128− break;
129− }
130− }
131− }
132− }
133−
134− //first move notes that are already in the stack one position to the right
135− for (j = ns->size; j > whereToInsert; j--)
136− {
137− ns->data[j] = ns->data[(j - 1)];
138− }
139−
140− //then, insert the new note into the front of the stack
141− ns->data[whereToInsert] = noteVal;
142−
143− ns->size++;
144−
145− added = 1;
146− }
147−
148− return added;
149−}
150−
151−// Remove noteVal. return 1 if removed, 0 if not
152−int tStack_remove(tStack* const stack, uint16_t noteVal)
153−{
154− _tStack* ns = *stack;
155−
156− uint8_t k;
157− int foundIndex = tStack_contains(stack, noteVal);
158− int removed = 0;
159−
160− if (foundIndex >= 0)
161− {
162− for (k = 0; k < (ns->size - foundIndex); k++)
163− {
164− if ((k+foundIndex) >= (ns->capacity - 1))
165− {
166− ns->data[k + foundIndex] = -1;
167− }
168− else
169− {
170− ns->data[k + foundIndex] = ns->data[k + foundIndex + 1];
171− if ((k + foundIndex) == (ns->size - 1))
172− {
173− ns->data[k + foundIndex + 1] = -1;
174− }
175− }
176−
177− }
178− // in case it got put on the stack multiple times
179− foundIndex--;
180− ns->size--;
181− removed = 1;
182− }
183−
184− return removed;
185−}
186−
187−// Doesn't change size of data types
188−void tStack_setCapacity(tStack* const stack, uint16_t cap)
189−{
190− _tStack* ns = *stack;
191−
192− if (cap <= 0)
193− ns->capacity = 1;
194− else if (cap <= STACK_SIZE)
195− ns->capacity = cap;
196− else
197− ns->capacity = STACK_SIZE;
198−
199− for (int i = cap; i < STACK_SIZE; i++)
200− {
201− if ((int)ns->data[i] != -1)
202− {
203− ns->data[i] = -1;
204− ns->size -= 1;
205− }
206− }
207−
208− if (ns->pos >= cap)
209− {
210− ns->pos = 0;
211− }
212−}
213−
214−int tStack_getSize(tStack* const stack)
215−{
216− _tStack* ns = *stack;
217−
218− return ns->size;
219−}
220−
221−void tStack_clear(tStack* const stack)
222−{
223− _tStack* ns = *stack;
224−
225− for (int i = 0; i < STACK_SIZE; i++)
226− {
227− ns->data[i] = -1;
228− }
229− ns->pos = 0;
230− ns->size = 0;
231−}
232−
233−// Next item in order of addition to stack. Return 0-31 if there is a next item to move to. Returns -1 otherwise.
234−int tStack_next(tStack* const stack)
235−{
236− _tStack* ns = *stack;
237−
238− int step = 0;
239− if (ns->size != 0) // if there is at least one note in the stack
240− {
241− if (ns->pos > 0) // if you're not at the most recent note (first one), then go backward in the array (moving from earliest to latest)
242− {
243− ns->pos--;
244− }
245− else
246− {
247− ns->pos = (ns->size - 1); // if you are the most recent note, go back to the earliest note in the array
248− }
249−
250− step = ns->data[ns->pos];
251− return step;
252− }
253− else
254− {
255− return -1;
256− }
257−}
258−
259−int tStack_get(tStack* const stack, int which)
260−{
261− _tStack* ns = *stack;
262− return ns->data[which];
263−}
264−
265−int tStack_first(tStack* const stack)
266−{
267− _tStack* ns = *stack;
268− return ns->data[0];
269−}
270−
271−
272−// POLY
273−void tPoly_init(tPoly* const polyh, int maxNumVoices)
274−{
275− _tPoly* poly = *polyh = (_tPoly*) leaf_alloc(sizeof(_tPoly));
276−
277− poly->numVoices = maxNumVoices;
278− poly->maxNumVoices = maxNumVoices;
279− poly->lastVoiceToChange = 0;
280−
281− // Arp mode stuff
282− poly->currentVoice = 0;
283− poly->maxLength = 128;
284− poly->currentNote = -1;
285−
286− //default learned CCs and notes are just the CCs 1-128 - notes are skipped
287− for (int i = 0; i < 128; i++)
288− {
289− poly->notes[i][0] = 0;
290− poly->notes[i][1] = -1;
291− }
292−
293− poly->glideTime = 5.0f;
294−
295− poly->ramps = (tRamp*) leaf_alloc(sizeof(tRamp) * poly->maxNumVoices);
296− poly->rampVals = (float*) leaf_alloc(sizeof(float) * poly->maxNumVoices);
297− poly->firstReceived = (oBool*) leaf_alloc(sizeof(oBool) * poly->maxNumVoices);
298− poly->voices = (int**) leaf_alloc(sizeof(int*) * poly->maxNumVoices);
299−
300− for (int i = 0; i < poly->maxNumVoices; ++i)
301− {
302− poly->voices[i] = (int*) leaf_alloc(sizeof(int) * 2);
303− poly->voices[i][0] = -1;
304− poly->firstReceived[i] = OFALSE;
305−
306− tRamp_init(&poly->ramps[i], poly->glideTime, 1);
307− }
308−
309− poly->pitchBend = 0.0f;
310−
311− tRamp_init(&poly->pitchBendRamp, 1.0f, 1);
312− tStack_init(&poly->stack);
313− tStack_init(&poly->orderStack);
314−
315− poly->pitchGlideIsActive = OFALSE;
316−}
317−
318−void tPoly_free(tPoly* const polyh)
319−{
320− _tPoly* poly = *polyh;
321−
322− for (int i = 0; i < poly->maxNumVoices; i++)
323− {
324− tRamp_free(&poly->ramps[i]);
325− leaf_free((char*)poly->voices[i]);
326− }
327− tRamp_free(&poly->pitchBendRamp);
328− tStack_free(&poly->stack);
329− tStack_free(&poly->orderStack);
330−
331− leaf_free((char*)poly->voices);
332− leaf_free((char*)poly->ramps);
333− leaf_free((char*)poly->rampVals);
334− leaf_free((char*)poly->firstReceived);
335−
336− leaf_free((char*)poly);
337−}
338−
339−void tPoly_initToPool (tPoly* const polyh, int maxNumVoices, tMempool* const mp)
340−{
341− _tMempool* m = *mp;
342− _tPoly* poly = *polyh = (_tPoly*) mpool_alloc(sizeof(_tPoly), m);
343−
344− poly->numVoices = maxNumVoices;
345− poly->maxNumVoices = maxNumVoices;
346− poly->lastVoiceToChange = 0;
347−
348− // Arp mode stuff
349− poly->currentVoice = 0;
350− poly->maxLength = 128;
351− poly->currentNote = -1;
352−
353− //default learned CCs and notes are just the CCs 1-128 - notes are skipped
354− for (int i = 0; i < 128; i++)
355− {
356− poly->notes[i][0] = 0;
357− poly->notes[i][1] = -1;
358− }
359−
360− poly->glideTime = 5.0f;
361−
362− poly->ramps = (tRamp*) mpool_alloc(sizeof(tRamp) * poly->maxNumVoices, m);
363− poly->rampVals = (float*) mpool_alloc(sizeof(float) * poly->maxNumVoices, m);
364− poly->firstReceived = (oBool*) mpool_alloc(sizeof(oBool) * poly->maxNumVoices, m);
365− poly->voices = (int**) mpool_alloc(sizeof(int*) * poly->maxNumVoices, m);
366−
367− for (int i = 0; i < poly->maxNumVoices; ++i)
368− {
369− poly->voices[i] = (int*) mpool_alloc(sizeof(int) * 2, m);
370− poly->voices[i][0] = -1;
371− poly->firstReceived[i] = OFALSE;
372−
373− tRamp_initToPool(&poly->ramps[i], poly->glideTime, 1, mp);
374− }
375−
376− poly->pitchBend = 0.0f;
377−
378− tRamp_initToPool(&poly->pitchBendRamp, 1.0f, 1, mp);
379− tStack_initToPool(&poly->stack, mp);
380− tStack_initToPool(&poly->orderStack, mp);
381−
382− poly->pitchGlideIsActive = OFALSE;
383−}
384−
385−void tPoly_freeFromPool (tPoly* const polyh, tMempool* const mp)
386−{
387− _tMempool* m = *mp;
388− _tPoly* poly = *polyh;
389−
390− for (int i = 0; i < poly->maxNumVoices; i++)
391− {
392− tRamp_freeFromPool(&poly->ramps[i], mp);
393− mpool_free((char*)poly->voices[i], m);
394− }
395− tRamp_freeFromPool(&poly->pitchBendRamp, mp);
396− tStack_freeFromPool(&poly->stack, mp);
397− tStack_freeFromPool(&poly->orderStack, mp);
398−
399− mpool_free((char*)poly->voices, m);
400− mpool_free((char*)poly->ramps, m);
401− mpool_free((char*)poly->rampVals, m);
402− mpool_free((char*)poly->firstReceived, m);
403−
404− mpool_free((char*)poly, m);
405−}
406−
407−void tPoly_tickPitch(tPoly* polyh)
408−{
409− tPoly_tickPitchGlide(polyh);
410− tPoly_tickPitchBend(polyh);
411−}
412−
413−void tPoly_tickPitchGlide(tPoly* polyh)
414−{
415− _tPoly* poly = *polyh;
416− for (int i = 0; i < poly->maxNumVoices; ++i)
417− {
418− tRamp_tick(&poly->ramps[i]);
419− }
420−}
421−
422−void tPoly_tickPitchBend(tPoly* polyh)
423−{
424− _tPoly* poly = *polyh;
425− tRamp_tick(&poly->pitchBendRamp);
426−}
427−
428−void tPoly_setPitchBend(tPoly* const polyh, float pitchBend)
429−{
430− _tPoly* poly = *polyh;
431− poly->pitchBend = pitchBend;
432− tRamp_setDest(&poly->pitchBendRamp, poly->pitchBend);
433−}
434−
435−int tPoly_noteOn(tPoly* const polyh, int note, uint8_t vel)
436−{
437− _tPoly* poly = *polyh;
438−
439− // if not in keymap or already on stack, dont do anything. else, add that note.
440− if (tStack_contains(&poly->stack, note) >= 0) return -1;
441− else
442− {
443− tPoly_orderedAddToStack(polyh, note);
444− tStack_add(&poly->stack, note);
445−
446− int alteredVoice = -1;
447− oBool found = OFALSE;
448− for (int i = 0; i < poly->numVoices; i++)
449− {
450− if (poly->voices[i][0] < 0) // if inactive voice, give this note to voice
451− {
452− if (!poly->firstReceived[i] || !poly->pitchGlideIsActive)
453− {
454− tRamp_setVal(&poly->ramps[i], note);
455− poly->firstReceived[i] = OTRUE;
456− }
457−
458− found = OTRUE;
459−
460− poly->voices[i][0] = note;
461− poly->voices[i][1] = vel;
462− poly->lastVoiceToChange = i;
463− poly->notes[note][0] = vel;
464− poly->notes[note][1] = i;
465−
466− tRamp_setDest(&poly->ramps[i], poly->voices[i][0]);
467−
468− alteredVoice = i;
469− break;
470− }
471− }
472−
473− if (!found) //steal
474− {
475− int whichVoice, whichNote;
476− for (int j = tStack_getSize(&poly->stack) - 1; j >= 0; j--)
477− {
478− whichNote = tStack_get(&poly->stack, j);
479− whichVoice = poly->notes[whichNote][1];
480− if (whichVoice >= 0)
481− {
482− poly->lastVoiceToChange = whichVoice;
483− int oldNote = poly->voices[whichVoice][0];
484− poly->voices[whichVoice][0] = note;
485− poly->voices[whichVoice][1] = vel;
486− poly->notes[oldNote][1] = -1; //mark the stolen voice as inactive (in the second dimension of the notes array)
487− poly->notes[note][0] = vel;
488− poly->notes[note][1] = whichVoice;
489−
490− if (poly->pitchGlideIsActive)
491− {
492− tRamp_setTime(&poly->ramps[whichVoice], poly->glideTime);
493− }
494− else
495− {
496− tRamp_setVal(&poly->ramps[whichVoice], note);
497− }
498− tRamp_setDest(&poly->ramps[whichVoice], poly->voices[whichVoice][0]);
499−
500− alteredVoice = whichVoice;
501−
502− break;
503− }
504− }
505− }
506− return alteredVoice;
507− }
508−}
509−
510−
511−int16_t noteToTest = -1;
512−
513−int tPoly_noteOff(tPoly* const polyh, uint8_t note)
514−{
515− _tPoly* poly = *polyh;
516−
517− tStack_remove(&poly->stack, note);
518− tStack_remove(&poly->orderStack, note);
519− poly->notes[note][0] = 0;
520− poly->notes[note][1] = -1;
521−
522− int deactivatedVoice = -1;
523− for (int i = 0; i < poly->maxNumVoices; i++)
524− {
525− if (poly->voices[i][0] == note)
526− {
527− poly->voices[i][0] = -1;
528− poly->voices[i][1] = 0;
529− poly->lastVoiceToChange = i;
530− deactivatedVoice = i;
531− break;
532− }
533− }
534− /*
535− //monophonic handling
536− if ((poly->numVoices == 1) && (tStack_getSize(poly->stack) > 0))
537− {
538− int oldNote = tStack_first(poly->stack);
539− poly->voices[0][0] = oldNote;
540− poly->voices[0][1] = poly->notes[oldNote][0];
541− poly->lastVoiceToChange = 0;
542− }
543− */
544−
545− //grab old notes off the stack if there are notes waiting to replace the free voice
546− if (deactivatedVoice >= 0)
547− {
548− for (int j = 0; j < tStack_getSize(&poly->stack); ++j)
549− {
550− noteToTest = tStack_get(&poly->stack, j);
551−
552− if (poly->notes[noteToTest][1] < 0) //if there is a stolen note waiting (marked inactive but on the stack)
553− {
554− poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note
555− if (poly->pitchGlideIsActive)
556− {
557− tRamp_setTime(&poly->ramps[deactivatedVoice], poly->glideTime);
558− }
559− else
560− {
561− tRamp_setVal(&poly->ramps[deactivatedVoice], noteToTest);
562− }
563− tRamp_setDest(&poly->ramps[deactivatedVoice], poly->voices[deactivatedVoice][0]);
564− poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][0]; // set the velocity of the voice to be the velocity of that note
565− poly->notes[noteToTest][1] = deactivatedVoice; //mark that it is no longer stolen and is now active
566− return -1;
567− }
568− }
569− }
570− return deactivatedVoice;
571−}
572−
573−void tPoly_orderedAddToStack(tPoly* const polyh, uint8_t noteVal)
574−{
575− _tPoly* poly = *polyh;
576−
577− uint8_t j;
578− int myPitch, thisPitch, nextPitch;
579−
580− tStack ns = poly->orderStack;
581−
582− int whereToInsert = 0;
583−
584− for (j = 0; j < ns->size; j++)
585− {
586− myPitch = noteVal;
587− thisPitch = ns->data[j];
588− nextPitch = ns->data[j+1];
589−
590− if (myPitch > thisPitch)
591− {
592− if ((myPitch < nextPitch) || (nextPitch == -1))
593− {
594− whereToInsert = j+1;
595− break;
596− }
597− }
598− }
599−
600− //first move notes that are already in the stack one position to the right
601− for (j = ns->size; j > whereToInsert; j--)
602− {
603− ns->data[j] = ns->data[(j - 1)];
604− }
605−
606− //then, insert the new note into the front of the stack
607− ns->data[whereToInsert] = noteVal;
608−
609− ns->size++;
610−
611−}
612−
613−void tPoly_setNumVoices(tPoly* const polyh, uint8_t numVoices)
614−{
615− _tPoly* poly = *polyh;
616− poly->numVoices = (numVoices > poly->maxNumVoices) ? poly->maxNumVoices : numVoices;
617−}
618−
619−void tPoly_setPitchGlideActive(tPoly* const polyh, oBool isActive)
620−{
621− _tPoly* poly = *polyh;
622− poly->pitchGlideIsActive = isActive;
623−}
624−
625−void tPoly_setPitchGlideTime(tPoly* const polyh, float t)
626−{
627− _tPoly* poly = *polyh;
628− poly->glideTime = t;
629− for (int i = 0; i < poly->maxNumVoices; ++i)
630− {
631− tRamp_setTime(&poly->ramps[i], poly->glideTime);
632− }
633−}
634−
635−void tPoly_setBendGlideTime(tPoly* const polyh, float t)
636−{
637− _tPoly* poly = *polyh;
638− tRamp_setTime(&poly->pitchBendRamp, t);
639−}
640−
641−void tPoly_setBendSamplesPerTick(tPoly* const polyh, float t)
642−{
643− _tPoly* poly = *polyh;
644− poly->pitchBendRamp->samples_per_tick = t;
645−}
646−
647−int tPoly_getNumVoices(tPoly* const polyh)
648−{
649− _tPoly* poly = *polyh;
650− return poly->numVoices;
651−}
652−
653−int tPoly_getNumActiveVoices(tPoly* const polyh)
654−{
655− _tPoly* poly = *polyh;
656− return LEAF_clip(0, tStack_getSize(&poly->stack), poly->numVoices);
657−}
658−
659−float tPoly_getPitch(tPoly* const polyh, uint8_t voice)
660−{
661− _tPoly* poly = *polyh;
662− return tRamp_sample(&poly->ramps[voice]) + tRamp_sample(&poly->pitchBendRamp);
663−}
664−
665−int tPoly_getKey(tPoly* const polyh, uint8_t voice)
666−{
667− _tPoly* poly = *polyh;
668− return poly->voices[voice][0];
669−}
670−
671−int tPoly_getVelocity(tPoly* const polyh, uint8_t voice)
672−{
673− _tPoly* poly = *polyh;
674− return poly->voices[voice][1];
675−}
676−
677−int tPoly_isOn(tPoly* const polyh, uint8_t voice)
678−{
679− _tPoly* poly = *polyh;
680− return (poly->voices[voice][0] > 0) ? 1 : 0;
681−}
682−
683−
684−
685−
686−//tSimplePoly = much more efficient implementation without ramps and glide
687−
688−
689−// SIMPLE POLY
690−void tSimplePoly_init(tSimplePoly* const polyh, int maxNumVoices)
691−{
692− tSimplePoly_initToPool(polyh, maxNumVoices, &leaf.mempool);
693−}
694−
695−void tSimplePoly_free(tSimplePoly* const polyh)
696−{
697− tSimplePoly_freeFromPool(polyh, &leaf.mempool);
698−}
699−
700−void tSimplePoly_initToPool (tSimplePoly* const polyh, int maxNumVoices, tMempool* const mp)
701−{
702− _tMempool* m = *mp;
703− _tSimplePoly* poly = *polyh = (_tSimplePoly*) mpool_alloc(sizeof(_tSimplePoly), m);
704−
705− poly->numVoices = maxNumVoices;
706− poly->maxNumVoices = maxNumVoices;
707−
708− for (int i = 0; i < 128; i++)
709− {
710− poly->notes[i][0] = -1;
711− poly->notes[i][1] = 0;
712− }
713− poly->stealing_on = 1;
714− poly->recover_stolen = 1;
715− poly->voices = (int**) mpool_alloc(sizeof(int*) * poly->maxNumVoices, m);
716−
717− for (int i = 0; i < poly->maxNumVoices; ++i)
718− {
719− poly->voices[i] = (int*) mpool_alloc(sizeof(int) * 3, m);
720− poly->voices[i][0] = -1;
721− }
722− tStack_initToPool(&poly->stack, mp);
723−
724−}
725−
726−void tSimplePoly_freeFromPool (tSimplePoly* const polyh, tMempool* const mp)
727−{
728− _tMempool* m = *mp;
729− _tSimplePoly* poly = *polyh;
730−
731− for (int i = 0; i < poly->maxNumVoices; i++)
732− {
733− mpool_free((char*)poly->voices[i], m);
734− }
735− tStack_freeFromPool(&poly->stack, mp);
736− mpool_free((char*)poly->voices, m);
737− mpool_free((char*)poly, m);
738−}
739−
740−int tSimplePoly_noteOn(tSimplePoly* const polyh, int note, uint8_t vel)
741−{
742− _tSimplePoly* poly = *polyh;
743− int whichVoice, whichNote, oldNote, alteredVoice;
744− // if not in keymap or already on stack, dont do anything. else, add that note.
745− if (tStack_contains(&poly->stack, note) >= 0) return -1;
746− else
747− {
748− alteredVoice = -1;
749− oBool found = OFALSE;
750− for (int i = 0; i < poly->numVoices; i++)
751− {
752− if (poly->voices[i][0] == -1) // if inactive voice, give this note to voice
753− {
754−
755− found = OTRUE;
756−
757− poly->voices[i][0] = note;
758− poly->voices[i][1] = vel;
759− poly->notes[note][0] = i;
760− poly->notes[note][1] = vel;
761− poly->voices[i][2] = note; // voices[i][2] is the output midi note, (avoiding the -1 when a voice is inactive)
762−
763− alteredVoice = i;
764− tStack_add(&poly->stack, note);
765− break;
766− }
767− }
768− if (!found)
769− {
770− //second preference is grabbing one that is in release phase but not finished sounding yet
771− for (int i = 0 ; i < poly->numVoices; i++)
772− {
773− if (poly->voices[i][0] == -2) // if voice is released but still sounding, take over this voice
774− {
775−
776− found = OTRUE;
777−
778− poly->voices[i][0] = note;
779− poly->voices[i][1] = vel;
780− poly->notes[note][0] = i;
781− poly->notes[note][1] = vel;
782− poly->voices[i][2] = note; // voices[i][2] is the output midi note, (avoiding the -1 when a voice is inactive)
783−
784− alteredVoice = i;
785− tStack_add(&poly->stack, note);
786− break;
787− }
788− }
789− }
790− if ((!found) && (poly->stealing_on)) //steal
791− {
792− for (int j = tStack_getSize(&poly->stack) - 1; j >= 0; j--)
793− {
794− whichNote = tStack_get(&poly->stack, j);
795− whichVoice = poly->notes[whichNote][0];
796− if (whichVoice >= 0)
797− {
798− oldNote = poly->voices[whichVoice][0];
799− poly->voices[whichVoice][0] = note;
800− poly->voices[whichVoice][1] = vel;
801− poly->notes[oldNote][0] = -3; //mark the stolen voice as stolen (in the second dimension of the notes array)
802− poly->notes[note][0] = whichVoice;
803− poly->notes[note][1] = vel;
804−
805− poly->voices[whichVoice][2] = note;
806−
807− alteredVoice = whichVoice;
808− tStack_add(&poly->stack, note);
809− break;
810− }
811− }
812− }
813− return alteredVoice;
814− }
815−}
816−
817−
818−
819−int tSimplePoly_noteOff(tSimplePoly* const polyh, uint8_t note)
820−{
821− _tSimplePoly* poly = *polyh;
822− int16_t noteToTest = -1;
823−
824− tStack_remove(&poly->stack, note);
825− poly->notes[note][0] = -1;
826−
827− int deactivatedVoice = -1;
828− for (int i = 0; i < poly->maxNumVoices; i++)
829− {
830− if (poly->voices[i][0] == note)
831− {
832− poly->voices[i][0] = -1;
833− poly->voices[i][1] = 0;
834− deactivatedVoice = i;
835− break;
836− }
837− }
838−
839− if (poly->recover_stolen)
840− {
841− //grab old notes off the stack if there are notes waiting to replace the free voice
842− if (deactivatedVoice >= 0)
843− {
844− for (int j = 0; j < tStack_getSize(&poly->stack); ++j)
845− {
846− noteToTest = tStack_get(&poly->stack, j);
847−
848− if (poly->notes[noteToTest][0] == -3) //if there is a stolen note waiting (marked inactive but on the stack)
849− {
850− poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note
851− poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][1]; // set the velocity of the voice to be the velocity of that note
852− poly->voices[deactivatedVoice][2] = noteToTest;
853− poly->notes[noteToTest][0] = deactivatedVoice; //mark that it is no longer stolen and is now active
854− return -1;
855− }
856− }
857− }
858− }
859− return deactivatedVoice;
860−}
861−
862−
863−void tSimplePoly_deactivateVoice(tSimplePoly* const polyh, uint8_t voice)
864−{
865− _tSimplePoly* poly = *polyh;
866−
867− if (poly->voices[voice][0] == -2) //only do this if the voice is waiting for deactivation (not already reassigned while waiting)
868− {
869− poly->voices[voice][0] = -1;
870− poly->voices[voice][1] = 0;
871− if (poly->recover_stolen)
872− {
873− //grab old notes off the stack if there are notes waiting to replace the free voice
874− for (int j = 0; j < tStack_getSize(&poly->stack); ++j)
875− {
876− noteToTest = tStack_get(&poly->stack, j);
877−
878− if (poly->notes[noteToTest][0] == -3) //if there is a stolen note waiting (marked inactive but on the stack)
879− {
880− poly->voices[voice][0] = noteToTest; //set the newly free voice to use the old stolen note
881− poly->voices[voice][1] = poly->notes[noteToTest][1]; // set the velocity of the voice to be the velocity of that note
882− poly->voices[voice][2] = noteToTest;
883− poly->notes[noteToTest][0] = voice; //mark that it is no longer stolen and is now active
884− }
885− }
886− }
887− }
888−}
889−
890−int tSimplePoly_findVoiceAssignedToNote(tSimplePoly* const polyh, uint8_t note)
891−{
892− _tSimplePoly* poly = *polyh;
893−
894−
895− int voiceWithThatNote = -1;
896− for (int i = 0; i < poly->maxNumVoices; i++)
897− {
898− if (poly->voices[i][0] == note)
899− {
900− voiceWithThatNote = i;
901− break;
902− }
903− }
904− return voiceWithThatNote;
905−}
906−
907−
908−int tSimplePoly_markPendingNoteOff(tSimplePoly* const polyh, uint8_t note)
909−{
910− _tSimplePoly* poly = *polyh;
911− int deactivatedVoice = -1;
912−
913− if (tStack_remove(&poly->stack, note))
914−
915− {
916−
917− poly->notes[note][0] = -2;
918−
919−
920−
921− for (int i = 0; i < poly->maxNumVoices; i++)
922− {
923− if (poly->voices[i][0] == note)
924− {
925− poly->voices[i][0] = -2;
926− poly->voices[i][1] = 0;
927− deactivatedVoice = i;
928− break;
929− }
930− }
931−
932−
933− }
934− return deactivatedVoice;
935−}
936−
937−void tSimplePoly_setNumVoices(tSimplePoly* const polyh, uint8_t numVoices)
938−{
939− _tSimplePoly* poly = *polyh;
940− poly->numVoices = (numVoices > poly->maxNumVoices) ? poly->maxNumVoices : numVoices;
941−}
942−
943−
944−int tSimplePoly_getNumVoices(tSimplePoly* const polyh)
945−{
946− _tSimplePoly* poly = *polyh;
947− return poly->numVoices;
948−}
949−
950−int tSimplePoly_getNumActiveVoices(tSimplePoly* const polyh)
951−{
952− _tSimplePoly* poly = *polyh;
953− return LEAF_clip(0, tStack_getSize(&poly->stack), poly->numVoices);
954−}
955−
956−
957−int tSimplePoly_getPitch(tSimplePoly* const polyh, uint8_t voice)
958−{
959− _tSimplePoly* poly = *polyh;
960− return poly->voices[voice][2];
961−}
962−
963−//this one returns negative one if the voice is inactive
964−int tSimplePoly_getPitchAndCheckActive(tSimplePoly* const polyh, uint8_t voice)
965−{
966− _tSimplePoly* poly = *polyh;
967− return poly->voices[voice][0];
968−}
969−
970−int tSimplePoly_getVelocity(tSimplePoly* const polyh, uint8_t voice)
971−{
972− _tSimplePoly* poly = *polyh;
973− return poly->voices[voice][1];
974−}
975−
976−int tSimplePoly_isOn(tSimplePoly* const polyh, uint8_t voice)
977−{
978− _tSimplePoly* poly = *polyh;
979− return (poly->voices[voice][0] > 0) ? 1 : 0;
980−}
LEAF/Src/leaf-oscillators.c+0−1660
@@ -1,1660 +0,0 @@
1−/*==============================================================================
2− leaf-oscillators.c
3− Created: 20 Jan 2017 12:00:58pm
4− Author: Michael R Mulshine
5− ==============================================================================*/
6−
7−#if _WIN32 || _WIN64
8−
9−#include "..\Inc\leaf-oscillators.h"
10−#include "..\leaf.h"
11−
12−#else
13−
14−#include "../Inc/leaf-oscillators.h"
15−#include "../leaf.h"
16−
17−#endif
18−
19−// Cycle
20−void tCycle_init(tCycle* const cy)
21−{
22− tCycle_initToPool(cy, &leaf.mempool);
23−}
24−
25−void tCycle_free(tCycle* const cy)
26−{
27− tCycle_freeFromPool(cy, &leaf.mempool);
28−}
29−
30−void tCycle_initToPool (tCycle* const cy, tMempool* const mp)
31−{
32− _tMempool* m = *mp;
33− _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m);
34−
35− c->inc = 0.0f;
36− c->phase = 0.0f;
37−
38−}
39−
40−void tCycle_freeFromPool (tCycle* const cy, tMempool* const mp)
41−{
42− _tMempool* m = *mp;
43− _tCycle* c = *cy;
44−
45− mpool_free((char*)c, m);
46−}
47−
48−void tCycle_setFreq(tCycle* const cy, float freq)
49−{
50− _tCycle* c = *cy;
51−
52− c->freq = freq;
53−
54− c->inc = freq * leaf.invSampleRate;
55−}
56−
57−//need to check bounds and wrap table properly to allow through-zero FM
58−float tCycle_tick(tCycle* const cy)
59−{
60− _tCycle* c = *cy;
61− float temp;;
62− int intPart;;
63− float fracPart;
64− float samp0;
65− float samp1;
66−
67− // Phasor increment
68− c->phase += c->inc;
69− while (c->phase >= 1.0f) c->phase -= 1.0f;
70− while (c->phase < 0.0f) c->phase += 1.0f;
71−
72− // Wavetable synthesis
73−
74− temp = SINE_TABLE_SIZE * c->phase;
75− intPart = (int)temp;
76− fracPart = temp - (float)intPart;
77− samp0 = __leaf_table_sinewave[intPart];
78− if (++intPart >= SINE_TABLE_SIZE) intPart = 0;
79− samp1 = __leaf_table_sinewave[intPart];
80−
81− return (samp0 + (samp1 - samp0) * fracPart);
82−
83−}
84−
85−void tCycleSampleRateChanged (tCycle* const cy)
86−{
87− _tCycle* c = *cy;
88−
89− c->inc = c->freq * leaf.invSampleRate;
90−}
91−
92−//========================================================================
93−/* Triangle */
94−void tTriangle_init(tTriangle* const cy)
95−{
96− tTriangle_initToPool(cy, &leaf.mempool);
97−}
98−
99−void tTriangle_free(tTriangle* const cy)
100−{
101− tTriangle_freeFromPool(cy, &leaf.mempool);
102−}
103−
104−void tTriangle_initToPool (tTriangle* const cy, tMempool* const mp)
105−{
106− _tMempool* m = *mp;
107− _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m);
108−
109− c->inc = 0.0f;
110− c->phase = 0.0f;
111− tTriangle_setFreq(cy, 220);
112−}
113−
114−void tTriangle_freeFromPool (tTriangle* const cy, tMempool* const mp)
115−{
116− _tMempool* m = *mp;
117− _tTriangle* c = *cy;
118−
119− mpool_free((char*)c, m);
120−}
121−
122−void tTriangle_setFreq(tTriangle* const cy, float freq)
123−{
124− _tTriangle* c = *cy;
125−
126− c->freq = freq;
127−
128− c->inc = c->freq * leaf.invSampleRate;
129−
130− c->w = c->freq * INV_20;
131− for (c->oct = 0; c->w > 2.0f; c->oct++)
132− {
133− c->w = 0.5f * c->w;
134− }
135− c->w = 2.0f - c->w;
136−}
137−
138−
139−float tTriangle_tick(tTriangle* const cy)
140−{
141− _tTriangle* c = *cy;
142−
143− // Phasor increment
144− c->phase += c->inc;
145− while (c->phase >= 1.0f) c->phase -= 1.0f;
146− while (c->phase < 0.0f) c->phase += 1.0f;
147−
148− float out = 0.0f;
149−
150− int idx = (int)(c->phase * TRI_TABLE_SIZE);
151−
152− // Wavetable synthesis
153− out = __leaf_table_triangle[c->oct+1][idx] +
154− (__leaf_table_triangle[c->oct][idx] - __leaf_table_triangle[c->oct+1][idx]) * c->w;
155−
156− return out;
157−}
158−
159−void tTriangleSampleRateChanged (tTriangle* const cy)
160−{
161− _tTriangle* c = *cy;
162−
163− c->inc = c->freq * leaf.invSampleRate;
164−}
165−
166−//========================================================================
167−/* Square */
168−void tSquare_init(tSquare* const cy)
169−{
170− tSquare_initToPool(cy, &leaf.mempool);
171−}
172−
173−void tSquare_free(tSquare* const cy)
174−{
175− tSquare_freeFromPool(cy, &leaf.mempool);
176−}
177−
178−void tSquare_initToPool (tSquare* const cy, tMempool* const mp)
179−{
180− _tMempool* m = *mp;
181− _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m);
182−
183− c->inc = 0.0f;
184− c->phase = 0.0f;
185− tSquare_setFreq(cy, 220);
186−}
187−
188−void tSquare_freeFromPool(tSquare* const cy, tMempool* const mp)
189−{
190− _tMempool* m = *mp;
191− _tSquare* c = *cy;
192−
193− mpool_free((char*)c, m);
194−}
195−
196−void tSquare_setFreq(tSquare* const cy, float freq)
197−{
198− _tSquare* c = *cy;
199−
200− c->freq = freq;
201−
202− c->inc = c->freq * leaf.invSampleRate;
203−
204− c->w = c->freq * INV_20;
205− for (c->oct = 0; c->w > 2.0f; c->oct++)
206− {
207− c->w = 0.5f * c->w;
208− }
209− c->w = 2.0f - c->w;
210−}
211−
212−float tSquare_tick(tSquare* const cy)
213−{
214− _tSquare* c = *cy;
215−
216− // Phasor increment
217− c->phase += c->inc;
218− while (c->phase >= 1.0f) c->phase -= 1.0f;
219− while (c->phase < 0.0f) c->phase += 1.0f;
220−
221− float out = 0.0f;
222−
223− int idx = (int)(c->phase * SQR_TABLE_SIZE);
224−
225− // Wavetable synthesis
226− out = __leaf_table_squarewave[c->oct+1][idx] +
227− (__leaf_table_squarewave[c->oct][idx] - __leaf_table_squarewave[c->oct+1][idx]) * c->w;
228−
229− return out;
230−}
231−
232−void tSquareSampleRateChanged (tSquare* const cy)
233−{
234− _tSquare* c = *cy;
235−
236− c->inc = c->freq * leaf.invSampleRate;
237−}
238−
239−//=====================================================================
240−// Sawtooth
241−void tSawtooth_init(tSawtooth* const cy)
242−{
243− tSawtooth_initToPool(cy, &leaf.mempool);
244−}
245−
246−void tSawtooth_free(tSawtooth* const cy)
247−{
248− tSawtooth_freeFromPool(cy, &leaf.mempool);
249−}
250−
251−void tSawtooth_initToPool (tSawtooth* const cy, tMempool* const mp)
252−{
253− _tMempool* m = *mp;
254− _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m);
255−
256− c->inc = 0.0f;
257− c->phase = 0.0f;
258− tSawtooth_setFreq(cy, 220);
259−}
260−
261−void tSawtooth_freeFromPool (tSawtooth* const cy, tMempool* const mp)
262−{
263− _tMempool* m = *mp;
264− _tSawtooth* c = *cy;
265−
266− mpool_free((char*)c, m);
267−}
268−
269−void tSawtooth_setFreq(tSawtooth* const cy, float freq)
270−{
271− _tSawtooth* c = *cy;
272−
273− c->freq = freq;
274−
275− c->inc = c->freq * leaf.invSampleRate;
276−
277− c->w = c->freq * INV_20;
278− for (c->oct = 0; c->w > 2.0f; c->oct++)
279− {
280− c->w = 0.5f * c->w;
281− }
282− c->w = 2.0f - c->w;
283−}
284−
285−float tSawtooth_tick(tSawtooth* const cy)
286−{
287− _tSawtooth* c = *cy;
288−
289− // Phasor increment
290− c->phase += c->inc;
291− while (c->phase >= 1.0f) c->phase -= 1.0f;
292− while (c->phase < 0.0f) c->phase += 1.0f;
293−
294− float out = 0.0f;
295−
296− int idx = (int)(c->phase * SAW_TABLE_SIZE);
297−
298− // Wavetable synthesis
299− out = __leaf_table_sawtooth[c->oct+1][idx] +
300− (__leaf_table_sawtooth[c->oct][idx] - __leaf_table_sawtooth[c->oct+1][idx]) * c->w;
301−
302− return out;
303−}
304−
305−void tSawtoothSampleRateChanged (tSawtooth* const cy)
306−{
307− _tSawtooth* c = *cy;
308−
309− c->inc = c->freq * leaf.invSampleRate;
310−}
311−
312−//========================================================================
313−// Sine
314−void tSine_init(tSine* const cy, int size)
315−{
316− tSine_initToPool(cy, size, &leaf.mempool);
317−}
318−
319−void tSine_free(tSine* const cy)
320−{
321− tSine_freeFromPool(cy, &leaf.mempool);
322−}
323−
324−void tSine_initToPool (tSine* const cy, int size, tMempool* const mp)
325−{
326− _tMempool* m = *mp;
327− _tSine* c = *cy = (_tSine*) mpool_alloc(sizeof(_tSine), m);
328−
329− c->size = size;
330− c->sine = (float*) mpool_alloc(sizeof(float) * c->size, m);
331− LEAF_generate_sine(c->sine, size);
332− c->inc = 0.0f;
333− c->phase = 0.0f;
334−}
335−
336−void tSine_freeFromPool (tSine* const cy, tMempool* const mp)
337−{
338− _tMempool* m = *mp;
339− _tSine* c = *cy;
340−
341− mpool_free((char*)c->sine, m);
342− mpool_free((char*)c, m);
343−}
344−
345−void tSine_setFreq(tSine* const cy, float freq)
346−{
347− _tSine* c = *cy;
348−
349− c->freq = freq;
350− c->inc = freq * leaf.invSampleRate;
351−}
352−
353−float tSine_tick(tSine* const cy)
354−{
355− _tSine* c = *cy;
356− float temp;
357− int intPart;
358− float fracPart;
359− float samp0;
360− float samp1;
361−
362− // Phasor increment
363− c->phase += c->inc;
364− while (c->phase >= 1.0f) c->phase -= 1.0f;
365− while (c->phase < 0.0f) c->phase += 1.0f;
366−
367− // Wavetable synthesis
368−
369− temp = c->size * c->phase;
370− intPart = (int)temp;
371− fracPart = temp - (float)intPart;
372− samp0 = c->sine[intPart];
373− if (++intPart >= c->size) intPart = 0;
374− samp1 = c->sine[intPart];
375−
376− return (samp0 + (samp1 - samp0) * fracPart);
377−
378−}
379−
380−void tSineSampleRateChanged (tSine* const cy)
381−{
382− _tSine* c = *cy;
383−
384− c->inc = c->freq * leaf.invSampleRate;
385−}
386−
387−//==============================================================================
388−
389−/* tTri: Anti-aliased Triangle waveform. */
390−void tTri_init (tTri* const osc)
391−{
392− tTri_initToPool(osc, &leaf.mempool);
393−}
394−
395−void tTri_free (tTri* const osc)
396−{
397− tTri_freeFromPool(osc, &leaf.mempool);
398−}
399−
400−void tTri_initToPool (tTri* const osc, tMempool* const mp)
401−{
402− _tMempool* m = *mp;
403− _tTri* c = *osc = (_tTri*) mpool_alloc(sizeof(_tTri), m);
404−
405− c->inc = 0.0f;
406− c->phase = 0.0f;
407− c->skew = 0.5f;
408− c->lastOut = 0.0f;
409−}
410−
411−void tTri_freeFromPool (tTri* const cy, tMempool* const mp)
412−{
413− _tMempool* m = *mp;
414− _tTri* c = *cy;
415−
416− mpool_free((char*)c, m);
417−}
418−
419−float tTri_tick (tTri* const osc)
420−{
421− _tTri* c = *osc;
422−
423− float out;
424− float skew;
425−
426− if (c->phase < c->skew)
427− {
428− out = 1.0f;
429− skew = (1.0f - c->skew) * 2.0f;
430− }
431− else
432− {
433− out = -1.0f;
434− skew = c->skew * 2.0f;
435− }
436−
437− out += LEAF_poly_blep(c->phase, c->inc);
438− out -= LEAF_poly_blep(fmod(c->phase + (1.0f - c->skew), 1.0f), c->inc);
439−
440− out = (skew * c->inc * out) + ((1 - c->inc) * c->lastOut);
441− c->lastOut = out;
442−
443− c->phase += c->inc;
444− if (c->phase >= 1.0f)
445− {
446− c->phase -= 1.0f;
447− }
448−
449− return out;
450−}
451−
452−void tTri_setFreq (tTri* const osc, float freq)
453−{
454− _tTri* c = *osc;
455−
456− c->freq = freq;
457− c->inc = freq * leaf.invSampleRate;
458−}
459−
460−void tTri_setSkew (tTri* const osc, float skew)
461−{
462− _tTri* c = *osc;
463− c->skew = (skew + 1.0f) * 0.5f;
464−}
465−
466−
467−//==============================================================================
468−
469−/* tPulse: Anti-aliased pulse waveform. */
470−void tPulse_init (tPulse* const osc)
471−{
472− tPulse_initToPool(osc, &leaf.mempool);
473−}
474−
475−void tPulse_free (tPulse* const osc)
476−{
477− tPulse_freeFromPool(osc, &leaf.mempool);
478−}
479−
480−void tPulse_initToPool (tPulse* const osc, tMempool* const mp)
481−{
482− _tMempool* m = *mp;
483− _tPulse* c = *osc = (_tPulse*) mpool_alloc(sizeof(_tPulse), m);
484−
485− c->inc = 0.0f;
486− c->phase = 0.0f;
487− c->width = 0.5f;
488−}
489−
490−void tPulse_freeFromPool(tPulse* const osc, tMempool* const mp)
491−{
492− _tMempool* m = *mp;
493− _tPulse* c = *osc;
494−
495− mpool_free((char*)c, m);
496−}
497−
498−float tPulse_tick (tPulse* const osc)
499−{
500− _tPulse* c = *osc;
501−
502− float out;
503− if (c->phase < c->width) out = 1.0f;
504− else out = -1.0f;
505− out += LEAF_poly_blep(c->phase, c->inc);
506− out -= LEAF_poly_blep(fmod(c->phase + (1.0f - c->width), 1.0f), c->inc);
507−
508− c->phase += c->inc;
509− if (c->phase >= 1.0f)
510− {
511− c->phase -= 1.0f;
512− }
513−
514− return out;
515−}
516−
517−void tPulse_setFreq (tPulse* const osc, float freq)
518−{
519− _tPulse* c = *osc;
520−
521− c->freq = freq;
522− c->inc = freq * leaf.invSampleRate;
523−}
524−
525−void tPulse_setWidth (tPulse* const osc, float width)
526−{
527− _tPulse* c = *osc;
528− c->width = width;
529−}
530−
531−
532−//==============================================================================
533−
534−/* tSawtooth: Anti-aliased Sawtooth waveform. */
535−void tSaw_init (tSaw* const osc)
536−{
537− tSaw_initToPool(osc, &leaf.mempool);
538−}
539−
540−void tSaw_free (tSaw* const osc)
541−{
542− tSaw_freeFromPool(osc, &leaf.mempool);
543−}
544−
545−void tSaw_initToPool (tSaw* const osc, tMempool* const mp)
546−{
547− _tMempool* m = *mp;
548− _tSaw* c = *osc = (_tSaw*) mpool_alloc(sizeof(_tSaw), m);
549−
550− c->inc = 0.0f;
551− c->phase = 0.0f;
552−}
553−
554−void tSaw_freeFromPool (tSaw* const osc, tMempool* const mp)
555−{
556− _tMempool* m = *mp;
557− _tSaw* c = *osc;
558−
559− mpool_free((char*)c, m);
560−}
561−
562−float tSaw_tick (tSaw* const osc)
563−{
564− _tSaw* c = *osc;
565−
566− float out = (c->phase * 2.0f) - 1.0f;
567− out -= LEAF_poly_blep(c->phase, c->inc);
568−
569− c->phase += c->inc;
570− if (c->phase >= 1.0f)
571− {
572− c->phase -= 1.0f;
573− }
574−
575− return out;
576−}
577−
578−void tSaw_setFreq (tSaw* const osc, float freq)
579−{
580− _tSaw* c = *osc;
581−
582− c->freq = freq;
583−
584− c->inc = freq * leaf.invSampleRate;
585−}
586−
587−//========================================================================
588−/* Phasor */
589−void tPhasorSampleRateChanged (tPhasor* const ph)
590−{
591− _tPhasor* p = *ph;
592−
593− p->inc = p->freq * leaf.invSampleRate;
594−};
595−
596−void tPhasor_init(tPhasor* const ph)
597−{
598− tPhasor_initToPool(ph, &leaf.mempool);
599−}
600−
601−void tPhasor_free(tPhasor* const ph)
602−{
603− tPhasor_freeFromPool(ph, &leaf.mempool);
604−}
605−
606−void tPhasor_initToPool (tPhasor* const ph, tMempool* const mp)
607−{
608− _tMempool* m = *mp;
609− _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m);
610−
611− p->phase = 0.0f;
612− p->inc = 0.0f;
613− p->phaseDidReset = 0;
614−}
615−
616−void tPhasor_freeFromPool(tPhasor* const ph, tMempool* const mp)
617−{
618− _tMempool* m = *mp;
619− _tPhasor* p = *ph;
620−
621− mpool_free((char*)p, m);
622−}
623−
624−void tPhasor_setFreq(tPhasor* const ph, float freq)
625−{
626− _tPhasor* p = *ph;
627−
628− p->freq = freq;
629−
630− p->inc = freq * leaf.invSampleRate;
631−}
632−
633−float tPhasor_tick(tPhasor* const ph)
634−{
635− _tPhasor* p = *ph;
636−
637− p->phase += p->inc;
638−
639−
640− p->phaseDidReset = 0;
641− if (p->phase >= 1.0f)
642− {
643− p->phaseDidReset = 1;
644− p->phase -= 1.0f;
645− }
646−
647− return p->phase;
648−}
649−
650−/* Noise */
651−void tNoise_init(tNoise* const ns, NoiseType type)
652−{
653− tNoise_initToPool(ns, type, &leaf.mempool);
654−}
655−
656−void tNoise_free(tNoise* const ns)
657−{
658− tNoise_freeFromPool(ns, &leaf.mempool);
659−}
660−
661−void tNoise_initToPool (tNoise* const ns, NoiseType type, tMempool* const mp)
662−{
663− _tMempool* m = *mp;
664− _tNoise* n = *ns = (_tNoise*) mpool_alloc(sizeof(_tNoise), m);
665−
666− n->type = type;
667− n->rand = leaf.random;
668−}
669−
670−void tNoise_freeFromPool (tNoise* const ns, tMempool* const mp)
671−{
672− _tMempool* m = *mp;
673− _tNoise* n = *ns;
674−
675− mpool_free((char*)n, m);
676−}
677−
678−float tNoise_tick(tNoise* const ns)
679−{
680− _tNoise* n = *ns;
681−
682− float rand = (n->rand() * 2.0f) - 1.0f;
683−
684− if (n->type == PinkNoise)
685− {
686− float tmp;
687− n->pinkb0 = 0.99765f * n->pinkb0 + rand * 0.0990460f;
688− n->pinkb1 = 0.96300f * n->pinkb1 + rand * 0.2965164f;
689− n->pinkb2 = 0.57000f * n->pinkb2 + rand * 1.0526913f;
690− tmp = n->pinkb0 + n->pinkb1 + n->pinkb2 + rand * 0.1848f;
691− return (tmp * 0.05f);
692− }
693− else // WhiteNoise
694− {
695− return rand;
696− }
697−}
698−
699−//=================================================================================
700−/* Neuron */
701−
702−void tNeuronSampleRateChanged(tNeuron* nr)
703−{
704−
705−}
706−
707−void tNeuron_init(tNeuron* const nr)
708−{
709− tNeuron_initToPool(nr, &leaf.mempool);
710−}
711−
712−void tNeuron_free(tNeuron* const nr)
713−{
714− tNeuron_freeFromPool(nr, &leaf.mempool);
715−}
716−
717−void tNeuron_initToPool (tNeuron* const nr, tMempool* const mp)
718−{
719− _tMempool* m = *mp;
720− _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);
721−
722− tPoleZero_initToPool(&n->f, mp);
723−
724− tPoleZero_setBlockZero(&n->f, 0.99f);
725−
726− n->timeStep = 1.0f / 50.0f;
727−
728− n->current = 0.0f; // 100.0f for sound
729− n->voltage = 0.0f;
730−
731− n->mode = NeuronNormal;
732−
733− n->P[0] = 0.0f;
734− n->P[1] = 0.0f;
735− n->P[2] = 1.0f;
736−
737− n->V[0] = -12.0f;
738− n->V[1] = 115.0f;
739− n->V[2] = 10.613f;
740−
741− n->gK = 36.0f;
742− n->gN = 120.0f;
743− n->gL = 0.3f;
744− n->C = 1.0f;
745−
746− n->rate[2] = n->gL/n->C;
747−}
748−
749−void tNeuron_freeFromPool(tNeuron* const nr, tMempool* const mp)
750−{
751− _tMempool* m = *mp;
752− _tNeuron* n = *nr;
753−
754− tPoleZero_free(&n->f);
755− mpool_free((char*)n, m);
756−}
757−
758−void tNeuron_reset(tNeuron* const nr)
759−{
760− _tNeuron* n = *nr;
761−
762− tPoleZero_setBlockZero(&n->f, 0.99f);
763−
764− n->timeStep = 1.0f / 50.0f;
765−
766− n->current = 0.0f; // 100.0f for sound
767− n->voltage = 0.0f;
768−
769− n->mode = NeuronNormal;
770−
771− n->P[0] = 0.0f;
772− n->P[1] = 0.0f;
773− n->P[2] = 1.0f;
774−
775− n->V[0] = -12.0f;
776− n->V[1] = 115.0f;
777− n->V[2] = 10.613f;
778−
779− n->gK = 36.0f;
780− n->gN = 120.0f;
781− n->gL = 0.3f;
782− n->C = 1.0f;
783−
784− n->rate[2] = n->gL/n->C;
785−}
786−
787−void tNeuron_setV1(tNeuron* const nr, float V1)
788−{
789− _tNeuron* n = *nr;
790− n->V[0] = V1;
791−}
792−
793−
794−void tNeuron_setV2(tNeuron* const nr, float V2)
795−{
796− _tNeuron* n = *nr;
797− n->V[1] = V2;
798−}
799−
800−void tNeuron_setV3(tNeuron* const nr, float V3)
801−{
802− _tNeuron* n = *nr;
803− n->V[2] = V3;
804−}
805−
806−void tNeuron_setTimeStep(tNeuron* const nr, float timeStep)
807−{
808− _tNeuron* n = *nr;
809− n->timeStep = timeStep;
810−}
811−
812−void tNeuron_setK(tNeuron* const nr, float K)
813−{
814− _tNeuron* n = *nr;
815− n->gK = K;
816−}
817−
818−void tNeuron_setL(tNeuron* const nr, float L)
819−{
820− _tNeuron* n = *nr;
821− n->gL = L;
822− n->rate[2] = n->gL/n->C;
823−}
824−
825−void tNeuron_setN(tNeuron* const nr, float N)
826−{
827− _tNeuron* n = *nr;
828− n->gN = N;
829−}
830−
831−void tNeuron_setC(tNeuron* const nr, float C)
832−{
833− _tNeuron* n = *nr;
834− n->C = C;
835− n->rate[2] = n->gL/n->C;
836−}
837−
838−float tNeuron_tick(tNeuron* const nr)
839−{
840− _tNeuron* n = *nr;
841−
842− float output = 0.0f;
843− float voltage = n->voltage;
844−
845− n->alpha[0] = (0.01f * (10.0f - voltage)) / (expf((10.0f - voltage)/10.0f) - 1.0f);
846− n->alpha[1] = (0.1f * (25.0f-voltage)) / (expf((25.0f-voltage)/10.0f) - 1.0f);
847− n->alpha[2] = (0.07f * expf((-1.0f * voltage)/20.0f));
848−
849− n->beta[0] = (0.125f * expf((-1.0f* voltage)/80.0f));
850− n->beta[1] = (4.0f * expf((-1.0f * voltage)/18.0f));
851− n->beta[2] = (1.0f / (expf((30.0f-voltage)/10.0f) + 1.0f));
852−
853− for (int i = 0; i < 3; i++)
854− {
855− n->P[i] = (n->alpha[i] * n->timeStep) + ((1.0f - ((n->alpha[i] + n->beta[i]) * n->timeStep)) * n->P[i]);
856−
857− if (n->P[i] > 1.0f) n->P[i] = 0.0f;
858− else if (n->P[i] < -1.0f) n->P[i] = 0.0f;
859− }
860− // rate[0]= k ; rate[1] = Na ; rate[2] = l
861− n->rate[0] = ((n->gK * powf(n->P[0], 4.0f)) / n->C);
862− n->rate[1] = ((n->gN * powf(n->P[1], 3.0f) * n->P[2]) / n->C);
863−
864− //calculate the final membrane voltage based on the computed variables
865− n->voltage = voltage +
866− (n->timeStep * n->current / n->C) -
867− (n->timeStep * ( n->rate[0] * (voltage - n->V[0]) + n->rate[1] * (voltage - n->V[1]) + n->rate[2] * (voltage - n->V[2])));
868−
869− if (n->mode == NeuronTanh)
870− {
871− n->voltage = 100.0f * tanhf(0.01f * n->voltage);
872− }
873− else if (n->mode == NeuronAaltoShaper)
874− {
875− float shapeVoltage = 0.01f * n->voltage;
876−
877− float w, c, xc, xc2, xc4;
878−
879− float sqrt8 = 2.82842712475f;
880−
881− float wscale = 1.30612244898f;
882− float m_drive = 1.0f;
883−
884− xc = LEAF_clip(-sqrt8, shapeVoltage, sqrt8);
885−
886− xc2 = xc*xc;
887−
888− c = 0.5f * shapeVoltage * (3.0f - (xc2));
889−
890− xc4 = xc2 * xc2;
891−
892− w = (1.0f - xc2 * 0.25f + xc4 * 0.015625f) * wscale;
893−
894− shapeVoltage = w * (c + 0.05f * xc2) * (m_drive + 0.75f);
895−
896− n->voltage = 100.0f * shapeVoltage;
897− }
898−
899−
900− if (n->voltage > 100.0f) n->voltage = 100.0f;
901− else if (n->voltage < -100.) n->voltage = -100.0f;
902−
903− //(inputCurrent + (voltage - ((voltage * timeStep) / timeConstant)) + P[0] + P[1] + P[2]) => voltage;
904− // now we should have a result
905− //set the output voltage to the "step" ugen, which controls the DAC.
906− output = n->voltage * 0.01f; // volts
907−
908− output = tPoleZero_tick(&n->f, output);
909−
910− return output;
911−
912−}
913−
914−void tNeuron_setMode (tNeuron* const nr, NeuronMode mode)
915−{
916− _tNeuron* n = *nr;
917− n->mode = mode;
918−}
919−
920−void tNeuron_setCurrent (tNeuron* const nr, float current)
921−{
922− _tNeuron* n = *nr;
923− n->current = current;
924−}
925−
926−
927−
928−void tMinBLEP_init (tMinBLEP* const minblep, int zeroCrossings, int oversamplerRatio)
929−{
930− tMinBLEP_initToPool(minblep, zeroCrossings, oversamplerRatio, &leaf.mempool);
931−}
932−
933−void tMinBLEP_free (tMinBLEP* const minblep)
934−{
935− tMinBLEP_freeFromPool(minblep, &leaf.mempool);
936−}
937−
938−void tMinBLEP_initToPool (tMinBLEP* const minblep, int zeroCrossings, int oversamplerRatio, tMempool* const mp)
939−{
940− _tMempool* m = *mp;
941− _tMinBLEP* mb = *minblep = (_tMinBLEP*) mpool_alloc(sizeof(_tMinBLEP), m);
942−
943− mb->overSamplingRatio = zeroCrossings;
944− mb->zeroCrossings = oversamplerRatio;
945− mb->returnDerivative = 0;
946− mb->proportionalBlepFreq = (float) mb->zeroCrossings / (float) mb->overSamplingRatio; // defaults to NyQuist ....
947−
948− mb->lastValue = 0;
949− mb->lastDelta = 0;
950−
951−// float* x1, x2, y1, y2;
952− // AA FILTER
953−// zeromem (coefficients, sizeof (coefficients));
954−
955− mb->minBlepSize = (mb->zeroCrossings * 2 * mb->overSamplingRatio) + 1;
956−
957− mb->ratio = 1;
958− mb->lastRatio = 1;
959−
960−// createLowPass (ratio);
961−// resetFilters();
962−
963− mb->blepIndex = 0;
964− mb->numActiveBleps = 0;
965− //currentActiveBlepOffsets;
966−
967− // These probably don't need to be this large
968− mb->offset = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
969−// mb->freqMultiple = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
970− mb->pos_change_magnitude = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
971− mb->vel_change_magnitude = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
972−
973− mb->minBlepArray = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
974− mb->minBlepDerivArray = (float*) mpool_alloc(sizeof(float) * mb->minBlepSize, m);
975−
976− tMinBLEP_buildBLEP(minblep);
977−}
978−
979−void tMinBLEP_freeFromPool (tMinBLEP* const minblep, tMempool* const mp)
980−{
981− _tMempool* m = *mp;
982− _tMinBLEP* mb = *minblep;
983−
984− mpool_free((char*)mb->offset, m);
985−// mpool_free(mb->freqMultiple, m);
986− mpool_free((char*)mb->pos_change_magnitude, m);
987− mpool_free((char*)mb->vel_change_magnitude, m);
988−
989− mpool_free((char*)mb->minBlepArray, m);
990− mpool_free((char*)mb->minBlepDerivArray, m);
991−
992− mpool_free((char*)mb, m);
993−}
994−
995−// SINC Function
996−static float SINC(float x)
997−{
998− float pix;
999−
1000− if(x == 0.0f)
1001− return 1.0f;
1002− else
1003− {
1004− pix = PI * x;
1005− return sinf(pix) / pix;
1006− }
1007−}
1008−
1009−// Generate Blackman Window
1010−static void BlackmanWindow(int n, float *w)
1011−{
1012− int m = n - 1;
1013− int i;
1014− float f1, f2, fm;
1015−
1016− fm = (float)m;
1017− for(i = 0; i <= m; i++)
1018− {
1019− f1 = (2.0f * PI * (float)i) / fm;
1020− f2 = 2.0f * f1;
1021− w[i] = 0.42f - (0.5f * cosf(f1)) + (0.08f * cosf(f2));
1022− }
1023−}
1024−
1025−// Discrete Fourier Transform
1026−static void DFT(int n, float *realTime, float *imagTime, float *realFreq, float *imagFreq)
1027−{
1028− int k, i;
1029− float sr, si, p;
1030−
1031− for(k = 0; k < n; k++)
1032− {
1033− realFreq[k] = 0.0f;
1034− imagFreq[k] = 0.0f;
1035− }
1036−
1037− for(k = 0; k < n; k++)
1038− for(i = 0; i < n; i++)
1039− {
1040− p = (2.0f * PI * (float)(k * i)) / n;
1041− sr = cosf(p);
1042− si = -sinf(p);
1043− realFreq[k] += (realTime[i] * sr) - (imagTime[i] * si);
1044− imagFreq[k] += (realTime[i] * si) + (imagTime[i] * sr);
1045− }
1046−}
1047−
1048−// Inverse Discrete Fourier Transform
1049−static void InverseDFT(int n, float *realTime, float *imagTime, float *realFreq, float *imagFreq)
1050−{
1051− int k, i;
1052− float sr, si, p;
1053−
1054− for(k = 0; k < n; k++)
1055− {
1056− realTime[k] = 0.0f;
1057− imagTime[k] = 0.0f;
1058− }
1059−
1060− for(k = 0; k < n; k++)
1061− {
1062− for(i = 0; i < n; i++)
1063− {
1064− p = (2.0f * PI * (float)(k * i)) / n;
1065− sr = cosf(p);
1066− si = -sinf(p);
1067− realTime[k] += (realFreq[i] * sr) + (imagFreq[i] * si);
1068− imagTime[k] += (realFreq[i] * si) - (imagFreq[i] * sr);
1069− }
1070− realTime[k] /= n;
1071− imagTime[k] /= n;
1072− }
1073−}
1074−
1075−// Complex Absolute Value
1076−static float complexabs(float x, float y)
1077−{
1078− return sqrtf((x * x) + (y * y));
1079−}
1080−
1081−// Complex Exponential
1082−static void complexexp(float x, float y, float *zx, float *zy)
1083−{
1084− float expx;
1085−
1086− expx = expf(x);
1087− *zx = expx * cosf(y);
1088− *zy = expx * sinf(y);
1089−}
1090−
1091−// Compute Real Cepstrum Of Signal
1092−static void RealCepstrum(int n, float *signal, float *realCepstrum)
1093−{
1094− int i;
1095−
1096− float realTime[n];
1097− float imagTime[n];
1098− float realFreq[n];
1099− float imagFreq[n];
1100−
1101− // Compose Complex FFT Input
1102−
1103− for(i = 0; i < n; i++)
1104− {
1105− realTime[i] = signal[i];
1106− imagTime[i] = 0.0f;
1107− }
1108−
1109− // Perform DFT
1110−
1111− DFT(n, realTime, imagTime, realFreq, imagFreq);
1112−
1113− // Calculate Log Of Absolute Value
1114−
1115− for(i = 0; i < n; i++)
1116− {
1117− realFreq[i] = logf(complexabs(realFreq[i], imagFreq[i]));
1118− imagFreq[i] = 0.0f;
1119− }
1120−
1121− // Perform Inverse FFT
1122−
1123− InverseDFT(n, realTime, imagTime, realFreq, imagFreq);
1124−
1125− // Output Real Part Of FFT
1126− for(i = 0; i < n; i++)
1127− realCepstrum[i] = realTime[i];
1128−}
1129−
1130−// Compute Minimum Phase Reconstruction Of Signal
1131−static void MinimumPhase(int n, float *realCepstrum, float *minimumPhase)
1132−{
1133− int i, nd2;
1134− float realTime[n];
1135− float imagTime[n];
1136− float realFreq[n];
1137− float imagFreq[n];
1138−
1139− nd2 = n / 2;
1140−
1141− if((n % 2) == 1)
1142− {
1143− realTime[0] = realCepstrum[0];
1144− for(i = 1; i < nd2; i++)
1145− realTime[i] = 2.0f * realCepstrum[i];
1146− for(i = nd2; i < n; i++)
1147− realTime[i] = 0.0f;
1148− }
1149− else
1150− {
1151− realTime[0] = realCepstrum[0];
1152− for(i = 1; i < nd2; i++)
1153− realTime[i] = 2.0f * realCepstrum[i];
1154− realTime[nd2] = realCepstrum[nd2];
1155− for(i = nd2 + 1; i < n; i++)
1156− realTime[i] = 0.0f;
1157− }
1158−
1159− for(i = 0; i < n; i++)
1160− imagTime[i] = 0.0f;
1161−
1162− DFT(n, realTime, imagTime, realFreq, imagFreq);
1163−
1164− for(i = 0; i < n; i++)
1165− complexexp(realFreq[i], imagFreq[i], &realFreq[i], &imagFreq[i]);
1166−
1167− InverseDFT(n, realTime, imagTime, realFreq, imagFreq);
1168−
1169− for(i = 0; i < n; i++)
1170− minimumPhase[i] = realTime[i];
1171−}
1172−
1173−
1174−// Generate the MinBLEP
1175−void tMinBLEP_buildBLEP(tMinBLEP* const minblep)
1176−{
1177− _tMinBLEP* m = *minblep;
1178−
1179− int i, n;
1180− float r, a, b;
1181−
1182− n = m->minBlepSize;
1183−
1184− // Generate Sinc
1185−
1186− a = -m->overSamplingRatio;
1187− b = m->overSamplingRatio;
1188− for(i = 0; i < n; i++)
1189− {
1190− r = ((float)i) / ((float)(n - 1));
1191− m->minBlepArray[i] = SINC(a + (r * (b - a)));
1192− m->minBlepDerivArray[i] = 0;
1193− }
1194−
1195− // Window Sinc
1196−
1197− BlackmanWindow(n, m->minBlepDerivArray);
1198− for(i = 0; i < n; i++)
1199− m->minBlepArray[i] *= m->minBlepDerivArray[i];
1200−
1201− // Minimum Phase Reconstruction
1202−
1203− RealCepstrum(n, m->minBlepArray, m->minBlepDerivArray);
1204− MinimumPhase(n, m->minBlepDerivArray, m->minBlepArray);
1205−
1206− // Integrate Into MinBLEP
1207− a = 0.0f;
1208− float secondInt = 0.0f;
1209− for(i = 0; i < n; i++)
1210− {
1211− a += m->minBlepArray[i];
1212− m->minBlepArray[i] = a;
1213−
1214− secondInt += a;
1215− m->minBlepDerivArray[i] = secondInt;
1216− }
1217−
1218− // Normalize
1219− a = m->minBlepArray[n - 1];
1220− a = 1.0f / a;
1221− b = 0.0f;
1222− for(i = 0; i < n; i++)
1223− {
1224− m->minBlepArray[i] *= a;
1225− b = fmaxf(b, m->minBlepDerivArray[i]);
1226− }
1227−
1228− // Normalize ...
1229− b = 1.0f/b;
1230− for (i = 0; i < n; i++)
1231− {
1232− m->minBlepDerivArray[i] *= b;
1233− m->minBlepDerivArray[i] -= ((float)i) / ((float) n-1);
1234−
1235− // SUBTRACT 1 and invert so the signal (so it goes 1->0)
1236− m->minBlepArray[i] -= 1.0f;
1237− m->minBlepArray[i] = -m->minBlepArray[i];
1238− }
1239−}
1240−
1241−void tMinBLEP_addBLEP (tMinBLEP* const minblep, float offset, float posChange, float velChange)
1242−{
1243− _tMinBLEP* m = *minblep;
1244−
1245− int n = m->minBlepSize;
1246−
1247− m->offset[m->blepIndex] = offset;
1248−// m->freqMultiple[m->blepIndex] = m->overSamplingRatio*m->proportionalBlepFreq;
1249− m->pos_change_magnitude[m->blepIndex] = posChange;
1250− m->vel_change_magnitude[m->blepIndex] = velChange;
1251−
1252− m->blepIndex++;
1253− if (m->blepIndex >= n) m->blepIndex = 0;
1254−
1255− m->numActiveBleps++;
1256−}
1257−
1258−float tMinBLEP_tick (tMinBLEP* const minblep, float input)
1259−{
1260− _tMinBLEP* m = *minblep;
1261− // PROCESS ALL BLEPS -
1262− /// for each offset, copy a portion of the blep array to the output ....
1263−
1264− float sample = input;
1265−
1266− int n = m->minBlepSize;
1267−
1268− for (int blep = 1; blep <= m->numActiveBleps; blep++)
1269− {
1270− int i = (m->blepIndex - blep + n) % n;
1271− float adjusted_Freq = m->overSamplingRatio*m->proportionalBlepFreq;//m->freqMultiple[i];
1272− float exactPosition = m->offset[i];
1273−
1274− float blepPosExact = adjusted_Freq*(exactPosition + 1); // +1 because this needs to trigger on the LOW SAMPLE
1275− float blepPosSample = 0;
1276− float fraction = modff(blepPosExact, &blepPosSample);
1277−
1278− // LIMIT the scaling on the derivative array
1279− // otherwise, it can get TOO large
1280− float depthLimited = m->proportionalBlepFreq; //jlimit<double>(.1, 1, proportionalBlepFreq);
1281− float blepDeriv_PosExact = depthLimited*m->overSamplingRatio*(exactPosition + 1);
1282− float blepDeriv_Sample = 0;
1283− float fraction_Deriv = modff(blepDeriv_PosExact, &blepDeriv_Sample);
1284−
1285−
1286− // DONE ... we reached the end ...
1287− if (((int) blepPosExact > n) && ((int) blepDeriv_PosExact > n))
1288− break;
1289−
1290− // BLEP has not yet occurred ...
1291− if (blepPosExact < 0)
1292− continue;
1293−
1294−
1295− // 0TH ORDER COMPENSATION ::::
1296− /// add the BLEP to compensate for discontinuties in the POSITION
1297− if ( fabs(m->pos_change_magnitude[i]) > 0 && blepPosSample < n)
1298− {
1299− // LINEAR INTERPOLATION ::::
1300− float lowValue = m->minBlepArray[(int) blepPosSample];
1301− float hiValue = lowValue;
1302−
1303− if ((int) blepPosSample + 1 < n)
1304− hiValue = m->minBlepArray[(int) blepPosSample + 1];
1305−
1306− float delta = hiValue - lowValue;
1307− float exactValue = lowValue + fraction*delta;
1308−
1309− // SCALE by the discontinuity magnitude
1310− exactValue *= m->pos_change_magnitude[i];
1311−
1312− // ADD to the thruput
1313− sample += exactValue;
1314− }
1315−
1316−
1317− // 1ST ORDER COMPENSATION ::::
1318− /// add the BLEP DERIVATIVE to compensate for discontinuties in the VELOCITY
1319− if ( fabs(m->vel_change_magnitude[i]) > 0 && blepDeriv_PosExact < n)
1320− {
1321−
1322− // LINEAR INTERPOLATION ::::
1323− double lowValue = m->minBlepDerivArray[(int) blepDeriv_PosExact];
1324− double hiValue = lowValue;
1325−
1326− if ((int) blepDeriv_PosExact + 1 < n)
1327− hiValue = m->minBlepDerivArray[(int) blepDeriv_PosExact + 1];
1328−
1329− double delta = hiValue - lowValue;
1330− double exactValue = lowValue + fraction_Deriv*delta;
1331−
1332− // SCALE by the discontinuity magnitude`
1333− exactValue *= m->vel_change_magnitude[i];
1334−
1335− // ADD to the thruput
1336− sample += exactValue;
1337−
1338− }
1339−
1340− // UPDATE ::::
1341− m->offset[i] += 1.0f;
1342− if (m->offset[i] * adjusted_Freq > n)
1343− {
1344− m->numActiveBleps--;
1345− }
1346− }
1347− return sample;
1348−}
1349−
1350−//==============================================================================
1351−
1352−/* tMBTriangle: Anti-aliased Triangle waveform. */
1353−void tMBTriangle_init (tMBTriangle* const osc)
1354−{
1355− tMBTriangle_initToPool(osc, &leaf.mempool);
1356−}
1357−
1358−void tMBTriangle_free (tMBTriangle* const osc)
1359−{
1360− tMBTriangle_freeFromPool(osc, &leaf.mempool);
1361−}
1362−
1363−void tMBTriangle_initToPool (tMBTriangle* const osc, tMempool* const mp)
1364−{
1365− _tMempool* m = *mp;
1366− _tMBTriangle* c = *osc = (_tMBTriangle*) mpool_alloc(sizeof(_tMBTriangle), m);
1367−
1368− c->inc = 0.0f;
1369− c->phase = 0.0f;
1370− c->skew = 0.5f;
1371− c->lastOut = 0.0f;
1372−
1373− tMinBLEP_initToPool(&c->minBlep, 16, 32, mp);
1374− tHighpass_initToPool(&c->dcBlock, 5.0f, mp);
1375−}
1376−
1377−void tMBTriangle_freeFromPool (tMBTriangle* const cy, tMempool* const mp)
1378−{
1379− _tMempool* m = *mp;
1380− _tMBTriangle* c = *cy;
1381−
1382− tMinBLEP_freeFromPool(&c->minBlep, mp);
1383− tHighpass_freeFromPool(&c->dcBlock, mp);
1384−
1385− mpool_free((char*)c, m);
1386−}
1387−
1388−float tMBTriangle_tick (tMBTriangle* const osc)
1389−{
1390− _tMBTriangle* c = *osc;
1391−
1392− float out;
1393−
1394− c->phase += c->inc;
1395− if (c->phase >= 1.0f)
1396− {
1397− c->phase -= 1.0f;
1398− float offset = 1.0f - ((c->inc - c->phase) / c->inc);
1399− tMinBLEP_addBLEP(&c->minBlep, offset, -2, 0.0f);
1400− }
1401− if (c->skew <= c->phase && c->phase < c->skew + c->inc)
1402− {
1403− float offset = 1.0f - ((c->inc - c->phase + c->skew) / c->inc);
1404− tMinBLEP_addBLEP(&c->minBlep, offset, 2, 0.0f);
1405− }
1406−
1407− if (c->phase < c->skew)
1408− {
1409− out = (1.0f - c->skew) * 2.0f;
1410− }
1411− else
1412− {
1413− out = -c->skew * 2.0f;
1414− }
1415−
1416− out = tMinBLEP_tick(&c->minBlep, out);// - phasor->inc * 2.0f;
1417−
1418− out = (c->inc * out) + ((1 - c->inc) * c->lastOut);
1419− c->lastOut = out;
1420−
1421− return tHighpass_tick(&c->dcBlock, out * 4.0f);
1422−
1423−// float offset;
1424−// float vel = 2;
1425−// c->phase += c->inc;
1426−// if (c->phase >= 1.0f)
1427−// {
1428−// c->phase -= 1.0f;
1429−// offset = 1.0f - ((c->inc - c->phase) / c->inc);
1430−// tMinBLEP_addBLEP(&c->minBlep, offset, 0.0f, -vel);
1431−// }
1432−// if (c->skew <= c->phase && c->phase < c->skew + c->inc)
1433−// {
1434−// offset = 1.0f - ((c->inc - c->phase + c->skew) / c->inc);
1435−// tMinBLEP_addBLEP(&c->minBlep, offset, 0.0f, vel);
1436−// }
1437−//
1438−// float out;
1439−// if (c->phase < c->skew) out = 1.0f - (c->phase / c->skew);
1440−// else out = (c->phase - c->skew) / (1 - c->skew);
1441−//
1442−// out = (out - 0.5f) * 2.0f;
1443−//
1444−//// return tHighpass_tick(&c->dcBlock, tMinBLEP_tick(&c->minBlep, out));
1445−// return tMinBLEP_tick(&c->minBlep, out);
1446−}
1447−
1448−void tMBTriangle_setFreq (tMBTriangle* const osc, float freq)
1449−{
1450− _tMBTriangle* c = *osc;
1451−
1452− c->freq = freq;
1453− c->inc = freq * leaf.invSampleRate;
1454−
1455−// tHighpass_setFreq(&c->dcBlock, freq*0.5);
1456−}
1457−
1458−void tMBTriangle_setSkew (tMBTriangle* const osc, float skew)
1459−{
1460− _tMBTriangle* c = *osc;
1461− c->skew = (skew + 1.0f) * 0.5f;
1462−}
1463−
1464−void tMBTriangle_sync (tMBTriangle* const osc, float phase)
1465−{
1466− _tMBTriangle* c = *osc;
1467−
1468− phase += 0.5f;
1469−
1470− int intPart = (int) phase;
1471− phase = phase - (float) intPart;
1472−
1473− float before, after;
1474−
1475− if (c->phase < c->skew) before = (1.0f - c->skew - c->phase) * 2.0f;
1476− else before = -(c->skew - c->phase) * 2.0f;
1477−
1478− if (phase < c->skew) after = (1.0f - c->skew - c->phase) * 2.0f;
1479− else after = -(c->skew - c->phase) * 2.0f;
1480−
1481− c->phase = phase;
1482−
1483− float offset = 0.0f;//1.0f - ((c->inc - c->phase) / c->inc);
1484− tMinBLEP_addBLEP(&c->minBlep, offset, before - after, 0.0f);
1485−
1486− if (c->phase < c->skew) c->lastOut = 1.0f - (c->phase / c->skew);
1487− else c->lastOut = (c->phase - c->skew) / (1.0f - c->skew);
1488−}
1489−
1490−//==============================================================================
1491−
1492−/* tMBPulse: Anti-aliased pulse waveform. */
1493−void tMBPulse_init (tMBPulse* const osc)
1494−{
1495− tMBPulse_initToPool(osc, &leaf.mempool);
1496−}
1497−
1498−void tMBPulse_free (tMBPulse* const osc)
1499−{
1500− tMBPulse_freeFromPool(osc, &leaf.mempool);
1501−}
1502−
1503−void tMBPulse_initToPool (tMBPulse* const osc, tMempool* const mp)
1504−{
1505− _tMempool* m = *mp;
1506− _tMBPulse* c = *osc = (_tMBPulse*) mpool_alloc(sizeof(_tMBPulse), m);
1507−
1508− c->inc = 0.0f;
1509− c->phase = 0.0f;
1510− c->width = 0.5f;
1511−
1512− tMinBLEP_initToPool(&c->minBlep, 16, 32, mp);
1513− tHighpass_initToPool(&c->dcBlock, 10.0f, mp);
1514−}
1515−
1516−void tMBPulse_freeFromPool(tMBPulse* const osc, tMempool* const mp)
1517−{
1518− _tMempool* m = *mp;
1519− _tMBPulse* c = *osc;
1520−
1521− tMinBLEP_freeFromPool(&c->minBlep, mp);
1522− tHighpass_freeFromPool(&c->dcBlock, mp);
1523−
1524− mpool_free((char*)c, m);
1525−}
1526−
1527−float tMBPulse_tick (tMBPulse* const osc)
1528−{
1529− _tMBPulse* c = *osc;
1530−
1531−
1532−
1533− c->phase += c->inc;
1534− if (c->phase >= 1.0f)
1535− {
1536− c->phase -= 1.0f;
1537− float offset = 1.0f - ((c->inc - c->phase) / c->inc);
1538− tMinBLEP_addBLEP(&c->minBlep, offset, -2.0f, 0.0f);
1539− }
1540− if (c->width <= c->phase && c->phase < c->width + c->inc)
1541− {
1542− float offset = 1.0f - ((c->inc - c->phase + c->width) / c->inc);
1543− tMinBLEP_addBLEP(&c->minBlep, offset, 2.0f, 0.0f);
1544− }
1545−
1546− float out;
1547− if (c->phase < c->width) out = 1.0f;
1548− else out = -1.0f;
1549−
1550− return tHighpass_tick(&c->dcBlock, tMinBLEP_tick(&c->minBlep, out));
1551−}
1552−
1553−void tMBPulse_setFreq (tMBPulse* const osc, float freq)
1554−{
1555− _tMBPulse* c = *osc;
1556−
1557− c->freq = freq;
1558− c->inc = freq * leaf.invSampleRate;
1559−}
1560−
1561−void tMBPulse_setWidth (tMBPulse* const osc, float width)
1562−{
1563− _tMBPulse* c = *osc;
1564− c->width = width;
1565−}
1566−
1567−void tMBPulse_sync (tMBPulse* const osc, float phase)
1568−{
1569− _tMBPulse* c = *osc;
1570− int intPart = (int) phase;
1571− phase = phase - (float) intPart;
1572−
1573− float before, after;
1574−
1575− if (c->phase < c->width) before = 1.0f;
1576− else before = -1.0f;
1577−
1578− if (phase < c->width) after = 1.0;
1579− else after = -1.0f;
1580−
1581− float offset = 0.0f;//1.0f - ((c->inc - c->phase) / c->inc);
1582− tMinBLEP_addBLEP(&c->minBlep, offset, before - after, 0.0f);
1583−
1584− c->phase = phase;
1585−}
1586−
1587−
1588−//==============================================================================
1589−
1590−/* tMBSawtooth: Anti-aliased Sawtooth waveform. */
1591−void tMBSaw_init (tMBSaw* const osc)
1592−{
1593− tMBSaw_initToPool(osc, &leaf.mempool);
1594−}
1595−
1596−void tMBSaw_free (tMBSaw* const osc)
1597−{
1598− tMBSaw_freeFromPool(osc, &leaf.mempool);
1599−}
1600−
1601−void tMBSaw_initToPool (tMBSaw* const osc, tMempool* const mp)
1602−{
1603− _tMempool* m = *mp;
1604− _tMBSaw* c = *osc = (_tMBSaw*) mpool_alloc(sizeof(_tMBSaw), m);
1605−
1606− c->inc = 0.0f;
1607− c->phase = 0.0f;
1608−
1609− tMinBLEP_initToPool(&c->minBlep, 16, 32, mp);
1610− tHighpass_initToPool(&c->dcBlock, 10.0f, mp);
1611−}
1612−
1613−void tMBSaw_freeFromPool (tMBSaw* const osc, tMempool* const mp)
1614−{
1615− _tMempool* m = *mp;
1616− _tMBSaw* c = *osc;
1617−
1618− tMinBLEP_freeFromPool(&c->minBlep, mp);
1619− tHighpass_freeFromPool(&c->dcBlock, mp);
1620−
1621− mpool_free((char*)c, m);
1622−}
1623−
1624−float tMBSaw_tick (tMBSaw* const osc)
1625−{
1626− _tMBSaw* c = *osc;
1627−
1628− c->phase += c->inc;
1629− if (c->phase >= 1.0f)
1630− {
1631− c->phase -= 1.0f;
1632− float offset = 1.0f - ((c->inc - c->phase) / c->inc);
1633− tMinBLEP_addBLEP(&c->minBlep, offset, 2.0f, 0.0f);
1634− }
1635−
1636− float out = (c->phase * 2.0f) - 1.0f;
1637−
1638− return tHighpass_tick(&c->dcBlock, tMinBLEP_tick(&c->minBlep, out));
1639−}
1640−
1641−void tMBSaw_setFreq (tMBSaw* const osc, float freq)
1642−{
1643− _tMBSaw* c = *osc;
1644−
1645− c->freq = freq;
1646−
1647− c->inc = freq * leaf.invSampleRate;
1648−}
1649−
1650−void tMBSaw_sync (tMBSaw* const osc, float phase)
1651−{
1652− _tMBSaw* c = *osc;
1653− int intPart = (int) phase;
1654− phase = phase - (float) intPart;
1655−
1656− float offset = 0.0f;//1.0f - ((c->inc - phase +) / c->inc);
1657− tMinBLEP_addBLEP(&c->minBlep, offset, (c->phase - phase) * 2.0f, 0.0f);
1658−
1659− c->phase = phase;
1660−}
LEAF/Src/leaf-physical.c+0−747
@@ -1,747 +0,0 @@
1−/*==============================================================================
2−
3− leaf-string.c
4− Created: 30 Nov 2018 10:41:42am
5− Author: airship
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-physical.h"
12−
13−#else
14−
15−#include "../Inc/leaf-physical.h"
16−
17−#endif
18−
19−/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tPluck ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
20−void tPluck_init (tPluck* const pl, float lowestFrequency)
21−{
22− tPluck_initToPool(pl, lowestFrequency, &leaf.mempool);
23−}
24−
25−void tPluck_free (tPluck* const pl)
26−{
27− tPluck_freeFromPool(pl, &leaf.mempool);
28−}
29−
30−void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* const mp)
31−{
32− _tMempool* m = *mp;
33− _tPluck* p = *pl = (_tPluck*) mpool_alloc(sizeof(_tPluck), m);
34−
35− if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
36−
37− tNoise_initToPool(&p->noise, WhiteNoise, mp);
38−
39− tOnePole_initToPool(&p->pickFilter, 0.0f, mp);
40−
41− tOneZero_initToPool(&p->loopFilter, 0.0f, mp);
42−
43− tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf.sampleRate * 2, mp);
44− tAllpassDelay_clear(&p->delayLine);
45−
46− tPluck_setFrequency(pl, 220.0f);
47−}
48−
49−void tPluck_freeFromPool (tPluck* const pl, tMempool* const mp)
50−{
51− _tMempool* m = *mp;
52− _tPluck* p = *pl;
53−
54− tNoise_freeFromPool(&p->noise, mp);
55− tOnePole_freeFromPool(&p->pickFilter, mp);
56− tOneZero_freeFromPool(&p->loopFilter, mp);
57− tAllpassDelay_freeFromPool(&p->delayLine, mp);
58−
59− mpool_free((char*)p, m);
60−}
61−
62−float tPluck_getLastOut (tPluck* const pl)
63−{
64− _tPluck* p = *pl;
65− return p->lastOut;
66−}
67−
68−float tPluck_tick (tPluck* const pl)
69−{
70− _tPluck* p = *pl;
71− return (p->lastOut = 3.0f * tAllpassDelay_tick(&p->delayLine, tOneZero_tick(&p->loopFilter, tAllpassDelay_getLastOut(&p->delayLine) * p->loopGain ) ));
72−}
73−
74−void tPluck_pluck (tPluck* const pl, float amplitude)
75−{
76− _tPluck* p = *pl;
77−
78− if ( amplitude < 0.0f) amplitude = 0.0f;
79− else if (amplitude > 1.0f) amplitude = 1.0f;
80−
81− tOnePole_setPole(&p->pickFilter, 0.999f - (amplitude * 0.15f));
82− tOnePole_setGain(&p->pickFilter, amplitude * 0.5f );
83−
84− // Fill delay with noise additively with current contents.
85− for ( uint32_t i = 0; i < (uint32_t)tAllpassDelay_getDelay(&p->delayLine); i++ )
86− tAllpassDelay_tick(&p->delayLine, 0.6f * tAllpassDelay_getLastOut(&p->delayLine) + tOnePole_tick(&p->pickFilter, tNoise_tick(&p->noise) ) );
87−}
88−
89−// Start a note with the given frequency and amplitude.;
90−void tPluck_noteOn (tPluck* const pl, float frequency, float amplitude )
91−{
92− _tPluck* p = *pl;
93− p->lastFreq = frequency;
94− tPluck_setFrequency( pl, frequency );
95− tPluck_pluck( pl, amplitude );
96−}
97−
98−// Stop a note with the given amplitude (speed of decay).
99−void tPluck_noteOff (tPluck* const pl, float amplitude )
100−{
101− _tPluck* p = *pl;
102−
103− if ( amplitude < 0.0f) amplitude = 0.0f;
104− else if (amplitude > 1.0f) amplitude = 1.0f;
105−
106− p->loopGain = 1.0f - amplitude;
107−}
108−
109−// Set instrument parameters for a particular frequency.
110−void tPluck_setFrequency (tPluck* const pl, float frequency )
111−{
112− _tPluck* p = *pl;
113−
114− if ( frequency <= 0.0f ) frequency = 0.001f;
115−
116− // Delay = length - filter delay.
117− float delay = ( leaf.sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );
118−
119− tAllpassDelay_setDelay(&p->delayLine, delay );
120−
121− p->loopGain = 0.99f + (frequency * 0.000005f);
122−
123− if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;
124−
125−}
126−
127−// Perform the control change specified by \e number and \e value (0.0 - 128.0).
128−void tPluck_controlChange (tPluck* const pl, int number, float value)
129−{
130− return;
131−}
132−
133−void tPluckSampleRateChanged(tPluck* const pl)
134−{
135− _tPluck* p = *pl;
136− tPluck_setFrequency(pl, p->lastFreq);
137−}
138−
139−/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
140−void tKarplusStrong_init (tKarplusStrong* const pl, float lowestFrequency)
141−{
142− tKarplusStrong_initToPool(pl, lowestFrequency, &leaf.mempool);
143−}
144−
145−void tKarplusStrong_free (tKarplusStrong* const pl)
146−{
147− tKarplusStrong_freeFromPool(pl, &leaf.mempool);
148−}
149−
150−void tKarplusStrong_initToPool (tKarplusStrong* const pl, float lowestFrequency, tMempool* const mp)
151−{
152− _tMempool* m = *mp;
153− _tKarplusStrong* p = *pl = (_tKarplusStrong*) mpool_alloc(sizeof(_tKarplusStrong), m);
154−
155− if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
156−
157− tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf.sampleRate * 2, mp);
158− tAllpassDelay_clear(&p->delayLine);
159−
160− tLinearDelay_initToPool(&p->combDelay, 0.0f, leaf.sampleRate * 2, mp);
161− tLinearDelay_clear(&p->combDelay);
162−
163− tOneZero_initToPool(&p->filter, 0.0f, mp);
164−
165− tNoise_initToPool(&p->noise, WhiteNoise, mp);
166−
167− for (int i = 0; i < 4; i++)
168− {
169− tBiQuad_initToPool(&p->biquad[i], mp);
170− }
171−
172− p->pluckAmplitude = 0.3f;
173− p->pickupPosition = 0.4f;
174−
175− p->stretching = 0.9999f;
176− p->baseLoopGain = 0.995f;
177− p->loopGain = 0.999f;
178−
179− tKarplusStrong_setFrequency( pl, 220.0f );
180−}
181−
182−void tKarplusStrong_freeFromPool (tKarplusStrong* const pl, tMempool* const mp)
183−{
184− _tMempool* m = *mp;
185− _tKarplusStrong* p = *pl;
186−
187− tAllpassDelay_freeFromPool(&p->delayLine, mp);
188− tLinearDelay_freeFromPool(&p->combDelay, mp);
189− tOneZero_freeFromPool(&p->filter, mp);
190− tNoise_freeFromPool(&p->noise, mp);
191−
192− for (int i = 0; i < 4; i++)
193− {
194− tBiQuad_freeFromPool(&p->biquad[i], mp);
195− }
196−
197− mpool_free((char*)p, m);
198−}
199−
200−float tKarplusStrong_getLastOut (tKarplusStrong* const pl)
201−{
202− _tKarplusStrong* p = *pl;
203− return p->lastOut;
204−}
205−
206−float tKarplusStrong_tick (tKarplusStrong* const pl)
207−{
208− _tKarplusStrong* p = *pl;
209−
210− float temp = tAllpassDelay_getLastOut(&p->delayLine) * p->loopGain;
211−
212− // Calculate allpass stretching.
213− for (int i=0; i<4; i++) temp = tBiQuad_tick(&p->biquad[i],temp);
214−
215− // Moving average filter.
216− temp = tOneZero_tick(&p->filter, temp);
217−
218− float out = tAllpassDelay_tick(&p->delayLine, temp);
219− out = out - tLinearDelay_tick(&p->combDelay, out);
220− p->lastOut = out;
221−
222− return p->lastOut;
223−}
224−
225−void tKarplusStrong_pluck (tKarplusStrong* const pl, float amplitude)
226−{
227− _tKarplusStrong* p = *pl;
228−
229− if ( amplitude < 0.0f) amplitude = 0.0f;
230− else if (amplitude > 1.0f) amplitude = 1.0f;
231−
232− p->pluckAmplitude = amplitude;
233−
234− for ( uint32_t i=0; i < (uint32_t)tAllpassDelay_getDelay(&p->delayLine); i++ )
235− {
236− // Fill delay with noise additively with current contents.
237− tAllpassDelay_tick(&p->delayLine, (tAllpassDelay_getLastOut(&p->delayLine) * 0.6f) + 0.4f * tNoise_tick(&p->noise) * p->pluckAmplitude );
238− //delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
239− }
240−}
241−
242−// Start a note with the given frequency and amplitude.;
243−void tKarplusStrong_noteOn (tKarplusStrong* const pl, float frequency, float amplitude )
244−{
245− tKarplusStrong_setFrequency( pl, frequency );
246− tKarplusStrong_pluck( pl, amplitude );
247−}
248−
249−// Stop a note with the given amplitude (speed of decay).
250−void tKarplusStrong_noteOff (tKarplusStrong* const pl, float amplitude )
251−{
252− _tKarplusStrong* p = *pl;
253−
254− if ( amplitude < 0.0f) amplitude = 0.0f;
255− else if (amplitude > 1.0f) amplitude = 1.0f;
256−
257− p->loopGain = 1.0f - amplitude;
258−}
259−
260−// Set instrument parameters for a particular frequency.
261−void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency )
262−{
263− _tKarplusStrong* p = *pl;
264−
265− if ( frequency <= 0.0f ) frequency = 0.001f;
266−
267− p->lastFrequency = frequency;
268− p->lastLength = leaf.sampleRate / p->lastFrequency;
269− float delay = p->lastLength - 0.5f;
270− tAllpassDelay_setDelay(&p->delayLine, delay);
271−
272− // MAYBE MODIFY LOOP GAINS
273− p->loopGain = p->baseLoopGain + (frequency * 0.000005f);
274− if (p->loopGain >= 1.0f) p->loopGain = 0.99999f;
275−
276− tKarplusStrong_setStretch(pl, p->stretching);
277−
278− tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
279−
280−}
281−
282−// Set the stretch "factor" of the string (0.0 - 1.0).
283−void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stretch )
284−{
285− _tKarplusStrong* p = *pl;
286−
287− p->stretching = stretch;
288− float coefficient;
289− float freq = p->lastFrequency * 2.0f;
290− float dFreq = ( (0.5f * leaf.sampleRate) - freq ) * 0.25f;
291− float temp = 0.5f + (stretch * 0.5f);
292− if ( temp > 0.9999f ) temp = 0.9999f;
293−
294− for ( int i=0; i<4; i++ )
295− {
296− coefficient = temp * temp;
297− tBiQuad_setA2(&p->biquad[i], coefficient);
298− tBiQuad_setB0(&p->biquad[i], coefficient);
299− tBiQuad_setB2(&p->biquad[i], 1.0f);
300−
301− coefficient = -2.0f * temp * cos(TWO_PI * freq / leaf.sampleRate);
302− tBiQuad_setA1(&p->biquad[i], coefficient);
303− tBiQuad_setB1(&p->biquad[i], coefficient);
304−
305− freq += dFreq;
306− }
307−}
308−
309−// Set the pluck or "excitation" position along the string (0.0 - 1.0).
310−void tKarplusStrong_setPickupPosition (tKarplusStrong* const pl, float position )
311−{
312− _tKarplusStrong* p = *pl;
313−
314− if (position < 0.0f) p->pickupPosition = 0.0f;
315− else if (position <= 1.0f) p->pickupPosition = position;
316− else p->pickupPosition = 1.0f;
317−
318− tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength);
319−}
320−
321−// Set the base loop gain.
322−void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const pl, float aGain )
323−{
324− _tKarplusStrong* p = *pl;
325−
326− p->baseLoopGain = aGain;
327− p->loopGain = p->baseLoopGain + (p->lastFrequency * 0.000005f);
328− if ( p->loopGain > 0.99999f ) p->loopGain = 0.99999f;
329−}
330−
331−// Perform the control change specified by \e number and \e value (0.0 - 128.0).
332−void tKarplusStrong_controlChange (tKarplusStrong* const pl, SKControlType type, float value)
333−{
334− if ( value < 0.0f ) value = 0.0f;
335− else if (value > 128.0f) value = 128.0f;
336−
337− float normalizedValue = value * INV_128;
338−
339− if (type == SKPickPosition) // 4
340− tKarplusStrong_setPickupPosition( pl, normalizedValue );
341− else if (type == SKStringDamping) // 11
342− tKarplusStrong_setBaseLoopGain( pl, 0.97f + (normalizedValue * 0.03f) );
343− else if (type == SKDetune) // 1
344− tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );
345−}
346−
347−void tKarplusStrongSampleRateChanged (tKarplusStrong* const pl)
348−{
349− _tKarplusStrong* p = *pl;
350−
351− tKarplusStrong_setFrequency(pl, p->lastFrequency);
352− tKarplusStrong_setStretch(pl, p->stretching);
353−}
354−
355−/* Simple Living String*/
356−
357−void tSimpleLivingString_init(tSimpleLivingString* const pl, float freq, float dampFreq,
358− float decay, float targetLev, float levSmoothFactor,
359− float levStrength, int levMode)
360−{
361− tSimpleLivingString_initToPool(pl, freq, dampFreq, decay, targetLev, levSmoothFactor, levStrength, levMode, &leaf.mempool);
362−}
363−
364−void tSimpleLivingString_free(tSimpleLivingString* const pl)
365−{
366− tSimpleLivingString_freeFromPool(pl, &leaf.mempool);
367−}
368−
369−void tSimpleLivingString_initToPool (tSimpleLivingString* const pl, float freq, float dampFreq,
370− float decay, float targetLev, float levSmoothFactor,
371− float levStrength, int levMode, tMempool* const mp)
372−{
373− _tMempool* m = *mp;
374− _tSimpleLivingString* p = *pl = (_tSimpleLivingString*) mpool_alloc(sizeof(_tSimpleLivingString), m);
375−
376− p->curr=0.0f;
377− tExpSmooth_initToPool(&p->wlSmooth, leaf.sampleRate/freq, 0.01, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
378− tSimpleLivingString_setFreq(pl, freq);
379− tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);
380− tLinearDelay_clear(&p->delayLine);
381− tOnePole_initToPool(&p->bridgeFilter, dampFreq, mp);
382− tHighpass_initToPool(&p->DCblocker,13, mp);
383− p->decay=decay;
384− tFeedbackLeveler_initToPool(&p->fbLev, targetLev, levSmoothFactor, levStrength, levMode, mp);
385− p->levMode=levMode;
386−}
387−
388−void tSimpleLivingString_freeFromPool (tSimpleLivingString* const pl, tMempool* const mp)
389−{
390− _tMempool* m = *mp;
391− _tSimpleLivingString* p = *pl;
392−
393− tExpSmooth_freeFromPool(&p->wlSmooth, mp);
394− tLinearDelay_freeFromPool(&p->delayLine, mp);
395− tOnePole_freeFromPool(&p->bridgeFilter, mp);
396− tHighpass_freeFromPool(&p->DCblocker, mp);
397− tFeedbackLeveler_freeFromPool(&p->fbLev, mp);
398−
399− mpool_free((char*)p, m);
400−}
401−
402−void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
403−{
404− _tSimpleLivingString* p = *pl;
405−
406− if (freq<20) freq=20;
407− else if (freq>10000) freq=10000;
408− p->waveLengthInSamples = leaf.sampleRate/freq;
409− tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
410−}
411−
412−void tSimpleLivingString_setWaveLength(tSimpleLivingString* const pl, float waveLength)
413−{
414− _tSimpleLivingString* p = *pl;
415−
416− if (waveLength<4.8) waveLength=4.8;
417− else if (waveLength>2400) waveLength=2400;
418− p->waveLengthInSamples = waveLength;
419− tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
420−}
421−
422−void tSimpleLivingString_setDampFreq(tSimpleLivingString* const pl, float dampFreq)
423−{
424− _tSimpleLivingString* p = *pl;
425− tOnePole_setFreq(&p->bridgeFilter, dampFreq);
426−}
427−
428−void tSimpleLivingString_setDecay(tSimpleLivingString* const pl, float decay)
429−{
430− _tSimpleLivingString* p = *pl;
431− p->decay=decay;
432−}
433−
434−void tSimpleLivingString_setTargetLev(tSimpleLivingString* const pl, float targetLev)
435−{
436− _tSimpleLivingString* p = *pl;
437− tFeedbackLeveler_setTargetLevel(&p->fbLev, targetLev);
438−}
439−
440−void tSimpleLivingString_setLevSmoothFactor(tSimpleLivingString* const pl, float levSmoothFactor)
441−{
442− _tSimpleLivingString* p = *pl;
443− tFeedbackLeveler_setFactor(&p->fbLev, levSmoothFactor);
444−}
445−
446−void tSimpleLivingString_setLevStrength(tSimpleLivingString* const pl, float levStrength)
447−{
448− _tSimpleLivingString* p = *pl;
449− tFeedbackLeveler_setStrength(&p->fbLev, levStrength);
450−}
451−
452−void tSimpleLivingString_setLevMode(tSimpleLivingString* const pl, int levMode)
453−{
454− _tSimpleLivingString* p = *pl;
455− tFeedbackLeveler_setMode(&p->fbLev, levMode);
456− p->levMode=levMode;
457−}
458−
459−float tSimpleLivingString_tick(tSimpleLivingString* const pl, float input)
460−{
461− _tSimpleLivingString* p = *pl;
462−
463− float stringOut=tOnePole_tick(&p->bridgeFilter,tLinearDelay_tickOut(&p->delayLine));
464− float stringInput=tHighpass_tick(&p->DCblocker, tFeedbackLeveler_tick(&p->fbLev, (p->levMode==0?p->decay*stringOut:stringOut)+input));
465− tLinearDelay_tickIn(&p->delayLine, stringInput);
466− tLinearDelay_setDelay(&p->delayLine, tExpSmooth_tick(&p->wlSmooth));
467− p->curr = stringOut;
468− return p->curr;
469−}
470−
471−float tSimpleLivingString_sample(tSimpleLivingString* const pl)
472−{
473− _tSimpleLivingString* p = *pl;
474− return p->curr;
475−}
476−
477−/* Living String*/
478−
479−void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex,
480− float dampFreq, float decay, float targetLev, float levSmoothFactor,
481− float levStrength, int levMode)
482−{
483− tLivingString_initToPool(pl, freq, pickPos, prepIndex, dampFreq, decay, targetLev, levSmoothFactor, levStrength, levMode, &leaf.mempool);
484−}
485−
486−void tLivingString_free(tLivingString* const pl)
487−{
488− tLivingString_freeFromPool(pl, &leaf.mempool);
489−}
490−
491−void tLivingString_initToPool (tLivingString* const pl, float freq, float pickPos, float prepIndex,
492− float dampFreq, float decay, float targetLev, float levSmoothFactor,
493− float levStrength, int levMode, tMempool* const mp)
494−{
495− _tMempool* m = *mp;
496− _tLivingString* p = *pl = (_tLivingString*) mpool_alloc(sizeof(_tLivingString), m);
497−
498− p->curr=0.0f;
499− tExpSmooth_initToPool(&p->wlSmooth, leaf.sampleRate/freq, 0.01, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
500− tLivingString_setFreq(pl, freq);
501− p->freq = freq;
502− tExpSmooth_initToPool(&p->ppSmooth, pickPos, 0.01, mp); // smoother for pick position
503− tLivingString_setPickPos(pl, pickPos);
504− p->prepIndex=prepIndex;
505− tLinearDelay_initToPool(&p->delLF,p->waveLengthInSamples, 2400, mp);
506− tLinearDelay_initToPool(&p->delUF,p->waveLengthInSamples, 2400, mp);
507− tLinearDelay_initToPool(&p->delUB,p->waveLengthInSamples, 2400, mp);
508− tLinearDelay_initToPool(&p->delLB,p->waveLengthInSamples, 2400, mp);
509− tLinearDelay_clear(&p->delLF);
510− tLinearDelay_clear(&p->delUF);
511− tLinearDelay_clear(&p->delUB);
512− tLinearDelay_clear(&p->delLB);
513− p->dampFreq = dampFreq;
514− tOnePole_initToPool(&p->bridgeFilter, dampFreq, mp);
515− tOnePole_initToPool(&p->nutFilter, dampFreq, mp);
516− tOnePole_initToPool(&p->prepFilterU, dampFreq, mp);
517− tOnePole_initToPool(&p->prepFilterL, dampFreq, mp);
518− tHighpass_initToPool(&p->DCblockerU,13, mp);
519− tHighpass_initToPool(&p->DCblockerL,13, mp);
520− p->decay=decay;
521− p->prepIndex = prepIndex;
522− tFeedbackLeveler_initToPool(&p->fbLevU, targetLev, levSmoothFactor, levStrength, levMode, mp);
523− tFeedbackLeveler_initToPool(&p->fbLevL, targetLev, levSmoothFactor, levStrength, levMode, mp);
524− p->levMode=levMode;
525−}
526−
527−void tLivingString_freeFromPool (tLivingString* const pl, tMempool* const mp)
528−{
529− _tMempool* m = *mp;
530− _tLivingString* p = *pl;
531−
532− tExpSmooth_freeFromPool(&p->wlSmooth, mp);
533− tExpSmooth_freeFromPool(&p->ppSmooth, mp);
534− tLinearDelay_freeFromPool(&p->delLF, mp);
535− tLinearDelay_freeFromPool(&p->delUF, mp);
536− tLinearDelay_freeFromPool(&p->delUB, mp);
537− tLinearDelay_freeFromPool(&p->delLB, mp);
538− tOnePole_freeFromPool(&p->bridgeFilter, mp);
539− tOnePole_freeFromPool(&p->nutFilter, mp);
540− tOnePole_freeFromPool(&p->prepFilterU, mp);
541− tOnePole_freeFromPool(&p->prepFilterL, mp);
542− tHighpass_freeFromPool(&p->DCblockerU, mp);
543− tHighpass_freeFromPool(&p->DCblockerL, mp);
544− tFeedbackLeveler_freeFromPool(&p->fbLevU, mp);
545− tFeedbackLeveler_freeFromPool(&p->fbLevL, mp);
546−
547− mpool_free((char*)p, m);
548−}
549−
550−void tLivingString_setFreq(tLivingString* const pl, float freq)
551−{ // NOTE: It is faster to set wavelength in samples directly
552− _tLivingString* p = *pl;
553− if (freq<20) freq=20;
554− else if (freq>10000) freq=10000;
555− p->waveLengthInSamples = leaf.sampleRate/freq;
556− tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
557−}
558−
559−void tLivingString_setWaveLength(tLivingString* const pl, float waveLength)
560−{
561− _tLivingString* p = *pl;
562− if (waveLength<4.8) waveLength=4.8;
563− else if (waveLength>2400) waveLength=2400;
564− p->waveLengthInSamples = waveLength;
565− tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
566−}
567−
568−void tLivingString_setPickPos(tLivingString* const pl, float pickPos)
569−{ // between 0 and 1
570− _tLivingString* p = *pl;
571− if (pickPos<0.f) pickPos=0.f;
572− else if (pickPos>1.f) pickPos=1.f;
573− p->pickPos = pickPos;
574− tExpSmooth_setDest(&p->ppSmooth, p->pickPos);
575−}
576−
577−void tLivingString_setPrepIndex(tLivingString* const pl, float prepIndex)
578−{ // between 0 and 1
579− _tLivingString* p = *pl;
580− if (prepIndex<0.f) prepIndex=0.f;
581− else if (prepIndex>1.f) prepIndex=1.f;
582− p->prepIndex = prepIndex;
583−}
584−
585−void tLivingString_setDampFreq(tLivingString* const pl, float dampFreq)
586−{
587− _tLivingString* p = *pl;
588− tOnePole_setFreq(&p->bridgeFilter, dampFreq);
589− tOnePole_setFreq(&p->nutFilter, dampFreq);
590− tOnePole_setFreq(&p->prepFilterU, dampFreq);
591− tOnePole_setFreq(&p->prepFilterL, dampFreq);
592−}
593−
594−void tLivingString_setDecay(tLivingString* const pl, float decay)
595−{
596− _tLivingString* p = *pl;
597− p->decay=decay;
598−}
599−
600−void tLivingString_setTargetLev(tLivingString* const pl, float targetLev)
601−{
602− _tLivingString* p = *pl;
603− tFeedbackLeveler_setTargetLevel(&p->fbLevU, targetLev);
604− tFeedbackLeveler_setTargetLevel(&p->fbLevL, targetLev);
605−}
606−
607−void tLivingString_setLevSmoothFactor(tLivingString* const pl, float levSmoothFactor)
608−{
609− _tLivingString* p = *pl;
610− tFeedbackLeveler_setFactor(&p->fbLevU, levSmoothFactor);
611− tFeedbackLeveler_setFactor(&p->fbLevL, levSmoothFactor);
612−}
613−
614−void tLivingString_setLevStrength(tLivingString* const pl, float levStrength)
615−{
616− _tLivingString* p = *pl;
617− tFeedbackLeveler_setStrength(&p->fbLevU, levStrength);
618− tFeedbackLeveler_setStrength(&p->fbLevL, levStrength);
619−}
620−
621−void tLivingString_setLevMode(tLivingString* const pl, int levMode)
622−{
623− _tLivingString* p = *pl;
624− tFeedbackLeveler_setMode(&p->fbLevU, levMode);
625− tFeedbackLeveler_setMode(&p->fbLevL, levMode);
626− p->levMode=levMode;
627−}
628−
629−float tLivingString_tick(tLivingString* const pl, float input)
630−{
631− _tLivingString* p = *pl;
632−
633− // from pickPos upwards=forwards
634− float fromLF=tLinearDelay_tickOut(&p->delLF);
635− float fromUF=tLinearDelay_tickOut(&p->delUF);
636− float fromUB=tLinearDelay_tickOut(&p->delUB);
637− float fromLB=tLinearDelay_tickOut(&p->delLB);
638− // into upper half of string, from nut, going backwards
639− float fromNut=-tFeedbackLeveler_tick(&p->fbLevU, (p->levMode==0?p->decay:1)*tHighpass_tick(&p->DCblockerU, tOnePole_tick(&p->nutFilter, fromUF)));
640− tLinearDelay_tickIn(&p->delUB, fromNut);
641− // into lower half of string, from pickpoint, going backwards
642− float fromLowerPrep=-tOnePole_tick(&p->prepFilterL, fromLF);
643− float intoLower=p->prepIndex*fromLowerPrep+(1.0f - p->prepIndex)*fromUB+input;
644− tLinearDelay_tickIn(&p->delLB, intoLower);
645− // into lower half of string, from bridge
646− float fromBridge=-tFeedbackLeveler_tick(&p->fbLevL, (p->levMode==0?p->decay:1.0f)*tHighpass_tick(&p->DCblockerL, tOnePole_tick(&p->bridgeFilter, fromLB)));
647− tLinearDelay_tickIn(&p->delLF, fromBridge);
648− // into upper half of string, from pickpoint, going forwards/upwards
649− float fromUpperPrep=-tOnePole_tick(&p->prepFilterU, fromUB);
650− float intoUpper=p->prepIndex*fromUpperPrep+(1.0f - p->prepIndex)*fromLF+input;
651− tLinearDelay_tickIn(&p->delUF, intoUpper);
652− // update all delay lengths
653− float pickP=tExpSmooth_tick(&p->ppSmooth);
654− float wLen=tExpSmooth_tick(&p->wlSmooth);
655− float lowLen=pickP*wLen;
656− float upLen=(1.0f-pickP)*wLen;
657− tLinearDelay_setDelay(&p->delLF, lowLen);
658− tLinearDelay_setDelay(&p->delLB, lowLen);
659− tLinearDelay_setDelay(&p->delUF, upLen);
660− tLinearDelay_setDelay(&p->delUB, upLen);
661− p->curr = fromBridge;
662− return p->curr;
663−}
664−
665−float tLivingString_sample(tLivingString* const pl)
666−{
667− _tLivingString* p = *pl;
668− return p->curr;
669−}
670−
671−///Reed Table model
672−//default values from STK are 0.6 offset and -0.8 slope
673−
674−void tReedTable_init (tReedTable* const pm, float offset, float slope)
675−{
676− _tReedTable* p = *pm = (_tReedTable*) leaf_alloc(sizeof(_tReedTable));
677−
678− p->offset = offset;
679− p->slope = slope;
680−}
681−
682−void tReedTable_free (tReedTable* const pm)
683−{
684− _tReedTable* p = *pm;
685−
686− leaf_free((char*)p);
687−}
688−
689−void tReedTable_initToPool (tReedTable* const pm, float offset, float slope, tMempool* const mp)
690−{
691− _tMempool* m = *mp;
692− _tReedTable* p = *pm = (_tReedTable*) mpool_alloc(sizeof(_tReedTable), m);
693−
694− p->offset = offset;
695− p->slope = slope;
696−}
697−
698−void tReedTable_freeFromPool (tReedTable* const pm, tMempool* const mp)
699−{
700− _tMempool* m = *mp;
701− _tReedTable* p = *pm;
702−
703− mpool_free((char*)p, m);
704−}
705−
706−float tReedTable_tick (tReedTable* const pm, float input)
707−{
708− _tReedTable* p = *pm;
709−
710− // The input is differential pressure across the reed.
711− float output = p->offset + (p->slope * input);
712−
713− // If output is > 1, the reed has slammed shut and the
714− // reflection function value saturates at 1.0.
715− if ( output > 1.0f) output = 1.0f;
716−
717− // This is nearly impossible in a physical system, but
718− // a reflection function value of -1.0 corresponds to
719− // an open end (and no discontinuity in bore profile).
720− if ( output < -1.0f) output = -1.0f;
721−
722− return output;
723−}
724−
725−float tReedTable_tanh_tick (tReedTable* const pm, float input)
726−{
727− _tReedTable* p = *pm;
728−
729− // The input is differential pressure across the reed.
730− float output = p->offset + (p->slope * input);
731−
732− // If output is > 1, the reed has slammed shut and the
733− // reflection function value saturates at 1.0.
734− return tanhf(output);
735−}
736−
737−void tReedTable_setOffset (tReedTable* const pm, float offset)
738−{
739− _tReedTable* p = *pm;
740− p->offset = offset;
741−}
742−
743−void tReedTable_setSlope (tReedTable* const pm, float slope)
744−{
745− _tReedTable* p = *pm;
746− p->slope = slope;
747−}
LEAF/Src/leaf-reverb.c+0−925
@@ -1,925 +0,0 @@
1−/*==============================================================================
2−
3− leaf-reverb.c
4− Created: 20 Jan 2017 12:02:04pm
5− Author: Michael R Mulshine
6−
7−==============================================================================*/
8−
9−#if _WIN32 || _WIN64
10−
11−#include "..\Inc\leaf-reverb.h"
12−#include "..\leaf.h"
13−
14−#else
15−
16−#include "../Inc/leaf-reverb.h"
17−#include "../leaf.h"
18−
19−#endif
20−
21−// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PRCReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
22−void tPRCReverb_init(tPRCReverb* const rev, float t60)
23−{
24− _tPRCReverb* r = *rev = (_tPRCReverb*) leaf_alloc(sizeof(_tPRCReverb));
25−
26− if (t60 <= 0.0f) t60 = 0.001f;
27−
28− r->inv_441 = 1.0f/44100.0f;
29−
30− int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
31− double scaler = leaf.sampleRate * r->inv_441;
32−
33− int delay, i;
34− if (scaler != 1.0f)
35− {
36− for (i=0; i<4; i++)
37− {
38− delay = (int) scaler * lengths[i];
39−
40− if ( (delay & 1) == 0) delay++;
41−
42− while ( !LEAF_isPrime(delay) ) delay += 2;
43−
44− lengths[i] = delay;
45− }
46− }
47−
48− tDelay_init(&r->allpassDelays[0], lengths[0], lengths[0] * 2);
49− tDelay_init(&r->allpassDelays[1], lengths[1], lengths[1] * 2);
50− tDelay_init(&r->combDelay, lengths[2], lengths[2] * 2);
51−
52− tPRCReverb_setT60(rev, t60);
53−
54− r->allpassCoeff = 0.7f;
55− r->mix = 0.5f;
56−}
57−
58−void tPRCReverb_free(tPRCReverb* const rev)
59−{
60− _tPRCReverb* r = *rev;
61−
62− tDelay_free(&r->allpassDelays[0]);
63− tDelay_free(&r->allpassDelays[1]);
64− tDelay_free(&r->combDelay);
65− leaf_free((char*)r);
66−}
67−
68−void tPRCReverb_initToPool (tPRCReverb* const rev, float t60, tMempool* const mp)
69−{
70− _tMempool* m = *mp;
71− _tPRCReverb* r = *rev = (_tPRCReverb*) mpool_alloc(sizeof(_tPRCReverb), m);
72−
73− if (t60 <= 0.0f) t60 = 0.001f;
74−
75− r->inv_441 = 1.0f/44100.0f;
76−
77− int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
78− double scaler = leaf.sampleRate * r->inv_441;
79−
80− int delay, i;
81− if (scaler != 1.0f)
82− {
83− for (i=0; i<4; i++)
84− {
85− delay = (int) scaler * lengths[i];
86−
87− if ( (delay & 1) == 0) delay++;
88−
89− while ( !LEAF_isPrime(delay) ) delay += 2;
90−
91− lengths[i] = delay;
92− }
93− }
94−
95− tDelay_initToPool(&r->allpassDelays[0], lengths[0], lengths[0] * 2, mp);
96− tDelay_initToPool(&r->allpassDelays[1], lengths[1], lengths[1] * 2, mp);
97− tDelay_initToPool(&r->combDelay, lengths[2], lengths[2] * 2, mp);
98−
99− tPRCReverb_setT60(rev, t60);
100−
101− r->allpassCoeff = 0.7f;
102− r->mix = 0.5f;
103−}
104−
105−void tPRCReverb_freeFromPool (tPRCReverb* const rev, tMempool* const mp)
106−{
107− _tMempool* m = *mp;
108− _tPRCReverb* r = *rev;
109−
110− tDelay_freeFromPool(&r->allpassDelays[0], mp);
111− tDelay_freeFromPool(&r->allpassDelays[1], mp);
112− tDelay_freeFromPool(&r->combDelay, mp);
113− mpool_free((char*)r, m);
114−}
115−
116−void tPRCRevert_clear(tPRCReverb* const rev)
117−{
118− _tPRCReverb* r = *rev;
119−
120− tDelay_clear(&r->allpassDelays[0]);
121− tDelay_clear(&r->allpassDelays[1]);
122− tDelay_clear(&r->combDelay);
123−}
124−
125−void tPRCReverb_setT60(tPRCReverb* const rev, float t60)
126−{
127− _tPRCReverb* r = *rev;
128−
129− if ( t60 <= 0.0f ) t60 = 0.001f;
130−
131− r->t60 = t60;
132−
133− r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf.invSampleRate / t60 ));
134−
135−}
136−
137−void tPRCReverb_setMix(tPRCReverb* const rev, float mix)
138−{
139− _tPRCReverb* r = *rev;
140− r->mix = mix;
141−}
142−
143−float tPRCReverb_tick(tPRCReverb* const rev, float input)
144−{
145− _tPRCReverb* r = *rev;
146−
147− float temp, temp0, temp1, temp2;
148− float out;
149−
150− r->lastIn = input;
151−
152− temp = tDelay_getLastOut(&r->allpassDelays[0]);
153− temp0 = r->allpassCoeff * temp;
154− temp0 += input;
155− tDelay_tick(&r->allpassDelays[0], temp0);
156− temp0 = -( r->allpassCoeff * temp0) + temp;
157−
158− temp = tDelay_getLastOut(&r->allpassDelays[1]);
159− temp1 = r->allpassCoeff * temp;
160− temp1 += temp0;
161− tDelay_tick(&r->allpassDelays[1], temp1);
162− temp1 = -(r->allpassCoeff * temp1) + temp;
163−
164− temp2 = temp1 + ( r->combCoeff * tDelay_getLastOut(&r->combDelay));
165−
166− out = r->mix * tDelay_tick(&r->combDelay, temp2);
167−
168− temp = (1.0f - r->mix) * input;
169−
170− out += temp;
171−
172− r->lastOut = out;
173−
174− return out;
175−}
176−
177−void tPRCReverbSampleRateChanged (tPRCReverb* const rev)
178−{
179− _tPRCReverb* r = *rev;
180− r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf.invSampleRate / r->t60 ));
181−}
182−
183−/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
184−void tNReverb_init(tNReverb* const rev, float t60)
185−{
186− _tNReverb* r = *rev = (_tNReverb*) leaf_alloc(sizeof(_tNReverb));
187−
188− if (t60 <= 0.0f) t60 = 0.001f;
189−
190− r->inv_441 = 1.0f/44100.0f;
191−
192− int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19}; // Delay lengths for 44100 Hz sample rate.
193− double scaler = leaf.sampleRate / 25641.0f;
194−
195− int delay, i;
196−
197− for (i=0; i < 15; i++)
198− {
199− delay = (int) scaler * lengths[i];
200− if ( (delay & 1) == 0)
201− delay++;
202− while ( !LEAF_isPrime(delay) )
203− delay += 2;
204− lengths[i] = delay;
205− }
206−
207− for ( i=0; i<6; i++ )
208− {
209− tLinearDelay_init(&r->combDelays[i], lengths[i], lengths[i] * 2.0f);
210− tLinearDelay_clear(&r->combDelays[i]);
211− r->combCoeffs[i] = pow(10.0, (-3 * lengths[i] * leaf.invSampleRate / t60));
212− }
213−
214− for ( i=0; i<8; i++ )
215− {
216− tLinearDelay_init(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2.0f);
217− tLinearDelay_clear(&r->allpassDelays[i]);
218− }
219−
220−
221− tNReverb_setT60(rev, t60);
222− r->allpassCoeff = 0.7f;
223− r->mix = 0.3f;
224−}
225−
226−void tNReverb_free(tNReverb* const rev)
227−{
228− _tNReverb* r = *rev;
229−
230− for (int i = 0; i < 6; i++)
231− {
232− tLinearDelay_free(&r->combDelays[i]);
233− }
234−
235− for (int i = 0; i < 8; i++)
236− {
237− tLinearDelay_free(&r->allpassDelays[i]);
238− }
239−
240− leaf_free((char*)r);
241−}
242−
243−void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const mp)
244−{
245− _tMempool* m = *mp;
246− _tNReverb* r = *rev = (_tNReverb*) mpool_alloc(sizeof(_tNReverb), m);
247−
248− if (t60 <= 0.0f) t60 = 0.001f;
249−
250− r->inv_441 = 1.0f/44100.0f;
251−
252− int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19}; // Delay lengths for 44100 Hz sample rate.

673 more lines aren’t shown here.

LEAF/Src/leaf-sampling.c+0−866

This diff is large: its 867 lines aren’t shown here.

LEAF/Src/leaf-tables.c+0−14061

This diff is large: its 14062 lines aren’t shown here.

LEAF/Src/leaf.c+0−60

This diff is large: its 61 lines aren’t shown here.

LEAF/leaf.cpp+0−45

This diff is large: its 46 lines aren’t shown here.

LEAF/leaf.h+0−154

This diff is large: its 155 lines aren’t shown here.

LEAF_JUCEPlugin/.DS_Store+0−0

Binary file not shown.

LEAF_JUCEPlugin/LEAF.jucer+59−59

This diff is large: its 126 lines aren’t shown here.

LEAF_JUCEPlugin/Source/.DS_Store+0−0

Binary file not shown.

LEAF_JUCEPlugin/Source/LEAFTest.h+1−1

This diff is large: its 9 lines aren’t shown here.

leaf/.DS_Store+0−0

Binary file not shown.

leaf/Externals/.DS_Store+0−0

Binary file not shown.

leaf/leaf.h+1−1

This diff is large: its 9 lines aren’t shown here.

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