History

add set sample rate function to all object that depend on sample rate

Matthew Wang committed 5 years ago

Commit 8b254651 parent 62e295128 files · +1496 −777Browse files

Unified · Split

28 files
  1. leaf/Inc/leaf-analysis.h +17 −11
  2. leaf/Inc/leaf-distortion.h +4 −4
  3. leaf/Inc/leaf-dynamics.h +2 −0
  4. leaf/Inc/leaf-effects.h +89 −69
  5. leaf/Inc/leaf-envelopes.h +12 −5
  6. leaf/Inc/leaf-filters.h +31 −17
  7. leaf/Inc/leaf-instruments.h +4 −0
  8. leaf/Inc/leaf-midi.h +2 −1
  9. leaf/Inc/leaf-oscillators.h +38 −4
  10. leaf/Inc/leaf-physical.h +71 −63
  11. leaf/Inc/leaf-reverb.h +11 −3
  12. leaf/Inc/leaf-sampling.h +7 −7
  13. leaf/Src/leaf-analysis.c +75 −39
  14. leaf/Src/leaf-delay.c +0 −3
  15. leaf/Src/leaf-distortion.c +19 −1
  16. leaf/Src/leaf-dynamics.c +5 −3
  17. leaf/Src/leaf-effects.c +99 −25
  18. leaf/Src/leaf-electrical.c +10 −0
  19. leaf/Src/leaf-envelopes.c +48 −18
  20. leaf/Src/leaf-filters.c +253 −244
  21. leaf/Src/leaf-instruments.c +47 −0
  22. leaf/Src/leaf-midi.c +9 −1
  23. leaf/Src/leaf-oscillators.c +298 −102
  24. leaf/Src/leaf-physical.c +104 −32
  25. leaf/Src/leaf-reverb.c +213 −88
  26. leaf/Src/leaf-sampling.c +24 −28
  27. leaf/Src/leaf.c +2 −6
  28. leaf/leaf.h +2 −3
leaf/Inc/leaf-analysis.h+17−11
@@ -364,8 +364,8 @@ extern "C" { · 363 unmodified lines
364 float atk_coeff;364 float atk_coeff;
365 float rel_coeff;365 float rel_coeff;
366 366
367 int blocksize;367 int blockSize;
368 int samplerate;368 int sampleRate;
369 369
370 //RMS amplitude of previous block - used to decide if attack is present370 //RMS amplitude of previous block - used to decide if attack is present
371 float prevAmp;371 float prevAmp;
@@ -385,6 +385,7 @@ extern "C" { · 13 unmodified lines
385 void tAttackDetection_setRelease (tAttackDetection* const, int inRel);385 void tAttackDetection_setRelease (tAttackDetection* const, int inRel);
386 void tAttackDetection_setThreshold (tAttackDetection* const, float thres);386 void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
387 int tAttackDetection_detect (tAttackDetection* const, float *in);387 int tAttackDetection_detect (tAttackDetection* const, float *in);
388 void tAttackDetection_setSampleRate (tAttackDetection* const, float sr);
388 389
389 //==============================================================================390 //==============================================================================
390 391
@@ -593,6 +594,7 @@ extern "C" { · 202 unmodified lines
593 float alpha;594 float alpha;
594 float tolerance;595 float tolerance;
595 596
597 float invSampleRate;
596 } _tPeriodDetection;598 } _tPeriodDetection;
597 599
598 typedef _tPeriodDetection* tPeriodDetection;600 typedef _tPeriodDetection* tPeriodDetection;
@@ -603,12 +605,13 @@ extern "C" { · 4 unmodified lines
603 605
604 float tPeriodDetection_tick (tPeriodDetection* const, float sample);606 float tPeriodDetection_tick (tPeriodDetection* const, float sample);
605 float tPeriodDetection_getPeriod (tPeriodDetection* const);607 float tPeriodDetection_getPeriod (tPeriodDetection* const);
606 float tPeriodDetection_getFidelity (tPeriodDetection* pd);608 float tPeriodDetection_getFidelity (tPeriodDetection* const);
607 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);609 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);
608 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);610 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);
609 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);611 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
610 void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);612 void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);
611 void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);613 void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);
614 void tPeriodDetection_setSampleRate (tPeriodDetection* const, float sr);
612 615
613 //==============================================================================616 //==============================================================================
614 617
@@ -644,7 +647,6 @@ extern "C" { · 29 unmodified lines
644 647
645 typedef struct _tZeroCrossingCollector648 typedef struct _tZeroCrossingCollector
646 {649 {
647
648 tMempool mempool;650 tMempool mempool;
649 651
650 tZeroCrossingInfo* _info;652 tZeroCrossingInfo* _info;
@@ -689,7 +691,6 @@ extern "C" { · 38 unmodified lines
689 691
690 typedef struct _tBitset692 typedef struct _tBitset
691 {693 {
692
693 tMempool mempool;694 tMempool mempool;
694 695
695 unsigned int _value_size;696 unsigned int _value_size;
@@ -718,7 +719,6 @@ extern "C" { · 22 unmodified lines
718 719
719 typedef struct _tBACF720 typedef struct _tBACF
720 {721 {
721
722 tMempool mempool;722 tMempool mempool;
723 723
724 tBitset _bitset;724 tBitset _bitset;
@@ -806,7 +806,6 @@ extern "C" { · 81 unmodified lines
806 806
807 typedef struct _sub_collector807 typedef struct _sub_collector
808 {808 {
809
810 tMempool mempool;809 tMempool mempool;
811 810
812 float _first_period;811 float _first_period;
@@ -845,6 +844,10 @@ extern "C" { · 32 unmodified lines
845 unsigned int _num_pulses; // = 0;844 unsigned int _num_pulses; // = 0;
846 int _half_empty; // 0;845 int _half_empty; // 0;
847 846
847 float sampleRate;
848 float lowestFreq;
849 float highestFreq;
850
848 tBACF _bacf;851 tBACF _bacf;
849 852
850 } _tPeriodDetector;853 } _tPeriodDetector;
@@ -866,6 +869,7 @@ extern "C" { · 15 unmodified lines
866 int tPeriodDetector_isReset (tPeriodDetector* const detector);869 int tPeriodDetector_isReset (tPeriodDetector* const detector);
867 870
868 void tPeriodDetector_setHysteresis (tPeriodDetector* const detector, float hysteresis);871 void tPeriodDetector_setHysteresis (tPeriodDetector* const detector, float hysteresis);
872 void tPeriodDetector_setSampleRate (tPeriodDetector* const detector, float sr);
869 873
870 //==============================================================================874 //==============================================================================
871 875
@@ -942,6 +946,8 @@ extern "C" { · 70 unmodified lines
942 _pitch_info _current;946 _pitch_info _current;
943 int _frames_after_shift;// = 0;947 int _frames_after_shift;// = 0;
944 948
949 float sampleRate;
950
945 } _tPitchDetector;951 } _tPitchDetector;
946 952
947 typedef _tPitchDetector* tPitchDetector;953 typedef _tPitchDetector* tPitchDetector;
@@ -958,7 +964,7 @@ extern "C" { · 10 unmodified lines
958 int tPitchDetector_indeterminate (tPitchDetector* const detector);964 int tPitchDetector_indeterminate (tPitchDetector* const detector);
959 965
960 void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis);966 void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis);
961 967 void tPitchDetector_setSampleRate (tPitchDetector* const detector, float sr);
962 968
963 //==============================================================================969 //==============================================================================
964 970
@@ -1041,6 +1047,8 @@ extern "C" { · 76 unmodified lines
1041 1047
1042 float highest, lowest;1048 float highest, lowest;
1043 float thresh;1049 float thresh;
1050
1051 float sampleRate;
1044 1052
1045 } _tDualPitchDetector;1053 } _tDualPitchDetector;
1046 1054
@@ -1058,9 +1066,7 @@ extern "C" { · 11 unmodified lines
1058 1066
1059 void tDualPitchDetector_setHysteresis (tDualPitchDetector* const detector, float hysteresis);1067 void tDualPitchDetector_setHysteresis (tDualPitchDetector* const detector, float hysteresis);
1060 void tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const detector, float thresh);1068 void tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const detector, float thresh);
1061 1069 void tDualPitchDetector_setSampleRate (tDualPitchDetector* const detector, float sr);
1062
1063
1064 1070
1065#ifdef __cplusplus1071#ifdef __cplusplus
1066}1072}
leaf/Inc/leaf-distortion.h+4−4
@@ -61,7 +61,6 @@ extern "C" { · 60 unmodified lines
61 61
62 typedef struct _tSampleReducer62 typedef struct _tSampleReducer
63 {63 {
64
65 tMempool mempool;64 tMempool mempool;
66 float invRatio;65 float invRatio;
67 float hold;66 float hold;
@@ -124,9 +123,9 @@ extern "C" { · 56 unmodified lines
124 123
125 typedef struct _tOversampler124 typedef struct _tOversampler
126 {125 {
127
128 tMempool mempool;126 tMempool mempool;
129 int maxRatio;127 int maxRatio;
128 int allowHighQuality;
130 int ratio;129 int ratio;
131 int offset;130 int offset;
132 float* pCoeffs;131 float* pCoeffs;
@@ -143,11 +142,12 @@ extern "C" { · 10 unmodified lines
143 void tOversampler_free (tOversampler* const);142 void tOversampler_free (tOversampler* const);
144 143
145 void tOversampler_upsample (tOversampler* const, float input, float* output);144 void tOversampler_upsample (tOversampler* const, float input, float* output);
146 float tOversampler_downsample (tOversampler* const os, float* input);145 float tOversampler_downsample (tOversampler* const, float* input);
147 float tOversampler_tick (tOversampler* const, float input, float* oversample,146 float tOversampler_tick (tOversampler* const, float input, float* oversample,
148 float (*effectTick)(float));147 float (*effectTick)(float));
149 void tOversampler_setRatio (tOversampler* const, int ratio);148 void tOversampler_setRatio (tOversampler* const, int ratio);
150 int tOversampler_getLatency (tOversampler* const os);149 void tOversampler_setQuality (tOversampler* const, int quality);
150 int tOversampler_getLatency (tOversampler* const);
151 151
152 //==============================================================================152 //==============================================================================
153 153
leaf/Inc/leaf-dynamics.h+2−0
@@ -69,6 +69,8 @@ extern "C" { · 68 unmodified lines
69 69
70 int isActive;70 int isActive;
71 71
72 float sampleRate;
73
72 } _tCompressor;74 } _tCompressor;
73 75
74 typedef _tCompressor* tCompressor;76 typedef _tCompressor* tCompressor;
leaf/Inc/leaf-effects.h+89−69
@@ -1,7 +1,7 @@
1/*==============================================================================1/*==============================================================================
2 2
3 leaf-effects.h3 leaf-effects.h
4 4
5 5
6 ==============================================================================*/6 ==============================================================================*/
7 7
@@ -20,8 +20,8 @@ extern "C" { · 12 unmodified lines
20#include "leaf-analysis.h"20#include "leaf-analysis.h"
21#include "leaf-envelopes.h"21#include "leaf-envelopes.h"
22 22
23 23
24 24
25 //==============================================================================25 //==============================================================================
26 26
27 /*!27 /*!
@@ -89,7 +89,7 @@ extern "C" { · 61 unmodified lines
89 @param talkbox A pointer to the relevant tTalkbox.89 @param talkbox A pointer to the relevant tTalkbox.
90 90
91 @} */91 @} */
92 92
93#define NUM_TALKBOX_PARAM 493#define NUM_TALKBOX_PARAM 4
94 94
95 typedef struct _tTalkbox95 typedef struct _tTalkbox
@@ -98,7 +98,7 @@ extern "C" { · 2 unmodified lines
98 tMempool mempool;98 tMempool mempool;
99 99
100 float param[NUM_TALKBOX_PARAM];100 float param[NUM_TALKBOX_PARAM];
101 101
102 int bufsize;102 int bufsize;
103 float* car0;103 float* car0;
104 float* car1;104 float* car1;
@@ -117,7 +117,8 @@ extern "C" { · 12 unmodified lines
117 float G;117 float G;
118 double* dl;118 double* dl;
119 double* Rt;119 double* Rt;
120 120
121 float sampleRate;
121 122
122 } _tTalkbox;123 } _tTalkbox;
123 124
@@ -138,11 +139,12 @@ extern "C" { · 14 unmodified lines
138 void tTalkbox_setWarpOn (tTalkbox* const voc, float warpOn);139 void tTalkbox_setWarpOn (tTalkbox* const voc, float warpOn);
139 void tTalkbox_setFreeze (tTalkbox* const voc, float freeze);140 void tTalkbox_setFreeze (tTalkbox* const voc, float freeze);
140 void tTalkbox_warpedAutocorrelate (float * x, double* dl, double* Rt, unsigned int L, float * R, unsigned int P, float lambda);141 void tTalkbox_warpedAutocorrelate (float * x, double* dl, double* Rt, unsigned int L, float * R, unsigned int P, float lambda);
142 void tTalkbox_setSampleRate (tTalkbox* const voc, float sr);
141 143
142 144
143 //==============================================================================145 //==============================================================================
144 146
145 147
146 /*!148 /*!
147 @defgroup ttalkboxfloat tTalkboxFloat149 @defgroup ttalkboxfloat tTalkboxFloat
148 @ingroup effects150 @ingroup effects
@@ -208,55 +210,58 @@ extern "C" { · 59 unmodified lines
208 @param talkbox A pointer to the relevant tTalkboxFloat.210 @param talkbox A pointer to the relevant tTalkboxFloat.
209 211
210 @} */212 @} */
211 213
212 typedef struct _tTalkboxFloat214 typedef struct _tTalkboxFloat
213 {215 {
214 216
215 tMempool mempool;217 tMempool mempool;
216 218
217 float param[NUM_TALKBOX_PARAM];219 float param[NUM_TALKBOX_PARAM];
218 220
219 int bufsize;221 int bufsize;
220 float* car0;222 float* car0;
221 float* car1;223 float* car1;
222 float* window;224 float* window;
223 float* buf0;225 float* buf0;
224 float* buf1;226 float* buf1;
225 float* k;227 float* k;
226 float warpFactor;228 float warpFactor;
227 int32_t warpOn;229 int32_t warpOn;
228 int freeze;230 int freeze;
229 float emphasis;231 float emphasis;
230 int32_t K, N, O, pos;232 int32_t K, N, O, pos;
231 float wet, dry, FX;233 float wet, dry, FX;
232 float d0, d1, d2, d3, d4;234 float d0, d1, d2, d3, d4;
233 float u0, u1, u2, u3, u4;235 float u0, u1, u2, u3, u4;
234 float G;236 float G;
235 float* dl;237 float* dl;
236 float* Rt;238 float* Rt;
237 239
238 } _tTalkboxFloat;240 float sampleRate;
239 241
240 typedef _tTalkboxFloat* tTalkboxFloat;242 } _tTalkboxFloat;
241 243
242 void tTalkboxFloat_init (tTalkboxFloat* const, int bufsize, LEAF* const leaf);244 typedef _tTalkboxFloat* tTalkboxFloat;
243 void tTalkboxFloat_initToPool (tTalkboxFloat* const, int bufsize, tMempool* const);245
244 void tTalkboxFloat_free (tTalkboxFloat* const);246 void tTalkboxFloat_init (tTalkboxFloat* const, int bufsize, LEAF* const leaf);
245 247 void tTalkboxFloat_initToPool (tTalkboxFloat* const, int bufsize, tMempool* const);
246 float tTalkboxFloat_tick (tTalkboxFloat* const, float synth, float voice);248 void tTalkboxFloat_free (tTalkboxFloat* const);
247 float tTalkboxFloat_tickFrozen (tTalkboxFloat* const voc, float synth, float voice);249
248 void tTalkboxFloat_update (tTalkboxFloat* const);250 float tTalkboxFloat_tick (tTalkboxFloat* const, float synth, float voice);
249 void tTalkboxFloat_suspend (tTalkboxFloat* const);251 float tTalkboxFloat_tickFrozen (tTalkboxFloat* const voc, float synth, float voice);
250 void tTalkboxFloat_lpcDurbin (float *r, int p, float *k, float *g);252 void tTalkboxFloat_update (tTalkboxFloat* const);
251 void tTalkboxFloat_lpc (float *buf, float *car, float* dl, float* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G);253 void tTalkboxFloat_suspend (tTalkboxFloat* const);
252 void tTalkboxFloat_setQuality (tTalkboxFloat* const, float quality);254 void tTalkboxFloat_lpcDurbin (float *r, int p, float *k, float *g);
253 void tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);255 void tTalkboxFloat_lpc (float *buf, float *car, float* dl, float* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G);
254 void tTalkboxFloat_setWarpOn (tTalkboxFloat* const voc, int warpOn);256 void tTalkboxFloat_setQuality (tTalkboxFloat* const, float quality);
255 void tTalkboxFloat_setFreeze (tTalkboxFloat* const voc, int freeze);257 void tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);
256 void tTalkboxFloat_warpedAutocorrelate (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);258 void tTalkboxFloat_setWarpOn (tTalkboxFloat* const voc, int warpOn);
257 //==============================================================================259 void tTalkboxFloat_setFreeze (tTalkboxFloat* const voc, int freeze);
258 260 void tTalkboxFloat_warpedAutocorrelate (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);
259 261 void tTalkboxFloat_setSampleRate (tTalkboxFloat* const voc, float sr);
262 //==============================================================================
263
264
260 /*!265 /*!
261 @defgroup tvocoder tVocoder266 @defgroup tvocoder tVocoder
262 @ingroup effects267 @ingroup effects
@@ -310,6 +315,7 @@ extern "C" { · 47 unmodified lines
310 //filter coeffs and buffers - seems it's faster to leave this global than make local copy315 //filter coeffs and buffers - seems it's faster to leave this global than make local copy
311 float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]316 float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
312 317
318 float invSampleRate;
313 } _tVocoder;319 } _tVocoder;
314 320
315 typedef _tVocoder* tVocoder;321 typedef _tVocoder* tVocoder;
@@ -321,6 +327,7 @@ extern "C" { · 5 unmodified lines
321 float tVocoder_tick (tVocoder* const, float synth, float voice);327 float tVocoder_tick (tVocoder* const, float synth, float voice);
322 void tVocoder_update (tVocoder* const);328 void tVocoder_update (tVocoder* const);
323 void tVocoder_suspend (tVocoder* const);329 void tVocoder_suspend (tVocoder* const);
330 void tVocoder_setSampleRate (tVocoder* const, float sr);
324 331
325 //==============================================================================332 //==============================================================================
326 333
@@ -369,7 +376,7 @@ extern "C" { · 42 unmodified lines
369 @param pulse A pointer to the relevant tRosenbergGlottalPulse.376 @param pulse A pointer to the relevant tRosenbergGlottalPulse.
370 377
371 @} */378 @} */
372 379
373 typedef struct _tRosenbergGlottalPulse380 typedef struct _tRosenbergGlottalPulse
374 {381 {
375 382
@@ -380,22 +387,25 @@ extern "C" { · 4 unmodified lines
380 float invPulseLengthMinusOpenLength;387 float invPulseLengthMinusOpenLength;
381 float freq;388 float freq;
382 float inc;389 float inc;
390 float invSampleRate;
383 } _tRosenbergGlottalPulse;391 } _tRosenbergGlottalPulse;
384 392
385 typedef _tRosenbergGlottalPulse* tRosenbergGlottalPulse;393 typedef _tRosenbergGlottalPulse* tRosenbergGlottalPulse;
386 394
387 void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const, LEAF* const leaf);395 void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const, LEAF* const leaf);
388 void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const, tMempool* const);396 void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const, tMempool* const);
389 void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const);397 void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const);
390 398
391 float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const);399 float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const);
392 float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const gp);400 float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const gp);
393 void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const, float freq);401 void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const, float freq);
394 402
395 void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const, float openLength);403 void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const, float openLength);
396 404
397 void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const, float pulseLength);405 void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const, float pulseLength);
398 void tRosenbergGlottalPulse_setOpenLengthAndPulseLength (tRosenbergGlottalPulse* const gp, float openLength, float pulseLength);406 void tRosenbergGlottalPulse_setOpenLengthAndPulseLength(tRosenbergGlottalPulse* const, float
407 openLength, float pulseLength);
408 void tRosenbergGlottalPulse_setSampleRate(tRosenbergGlottalPulse* const, float sr);
399 //==============================================================================409 //==============================================================================
400 410
401 /*!411 /*!
@@ -421,7 +431,7 @@ extern "C" { · 19 unmodified lines
421 @fn void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize)431 @fn void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize)
422 @brief Send one block of input samples, receive one block of output samples432 @brief Send one block of input samples, receive one block of output samples
423 @param solad A pointer to the relevant tSOLAD.433 @param solad A pointer to the relevant tSOLAD.
424 434
425 @fn void tSOLAD_setPeriod (tSOLAD *w, float period)435 @fn void tSOLAD_setPeriod (tSOLAD *w, float period)
426 @brief Set periodicity analysis data436 @brief Set periodicity analysis data
427 @param solad A pointer to the relevant tSOLAD.437 @param solad A pointer to the relevant tSOLAD.
@@ -440,11 +450,11 @@ extern "C" { · 12 unmodified lines
440 450
441 @} */451 @} */
442 452
443//#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two453 //#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
444//#define LOOPMASK (LOOPSIZE - 1)454 //#define LOOPMASK (LOOPSIZE - 1)
445#define PITCHFACTORDEFAULT 1.0f455#define PITCHFACTORDEFAULT 1.0f
446#define INITPERIOD 64.0f456#define INITPERIOD 64.0f
447//#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)457 //#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
448#define MINPERIOD 8.0f458#define MINPERIOD 8.0f
449 459
450 typedef struct _tSOLAD460 typedef struct _tSOLAD
@@ -484,6 +494,7 @@ extern "C" { · 33 unmodified lines
484 void tSOLAD_setReadLag (tSOLAD *w, float readlag);494 void tSOLAD_setReadLag (tSOLAD *w, float readlag);
485 // reset state variables495 // reset state variables
486 void tSOLAD_resetState (tSOLAD *w);496 void tSOLAD_resetState (tSOLAD *w);
497 void tSOLAD_setSampleRate (tSOLAD* const, float sr);
487 498
488 /*!499 /*!
489 @defgroup tpitchshift tPitchShift500 @defgroup tpitchshift tPitchShift
@@ -536,6 +547,8 @@ extern "C" { · 46 unmodified lines
536 int index;547 int index;
537 548
538 float pickiness;549 float pickiness;
550
551 float sampleRate;
539 } _tPitchShift;552 } _tPitchShift;
540 553
541 typedef _tPitchShift* tPitchShift;554 typedef _tPitchShift* tPitchShift;
@@ -548,6 +561,7 @@ extern "C" { · 6 unmodified lines
548 void tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out);561 void tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out);
549 562
550 void tPitchShift_setPickiness (tPitchShift* const, float p);563 void tPitchShift_setPickiness (tPitchShift* const, float p);
564 void tPitchShift_setSampleRate(tPitchShift* const, float sr);
551 565
552 /*!566 /*!
553 @defgroup tsimpleretune tSimpleRetune567 @defgroup tsimpleretune tSimpleRetune
@@ -620,7 +634,8 @@ extern "C" { · 66 unmodified lines
620 void tSimpleRetune_tuneVoices (tSimpleRetune* const, float* t);634 void tSimpleRetune_tuneVoices (tSimpleRetune* const, float* t);
621 void tSimpleRetune_tuneVoice (tSimpleRetune* const, int voice, float t);635 void tSimpleRetune_tuneVoice (tSimpleRetune* const, int voice, float t);
622 float tSimpleRetune_getInputFrequency (tSimpleRetune* const);636 float tSimpleRetune_getInputFrequency (tSimpleRetune* const);
623 637 void tSimpleRetune_setSampleRate (tSimpleRetune* const, float sr);
638
624 /*!639 /*!
625 @defgroup tretune tRetune640 @defgroup tretune tRetune
626 @ingroup effects641 @ingroup effects
@@ -695,6 +710,7 @@ extern "C" { · 68 unmodified lines
695 void tRetune_tuneVoices (tRetune* const, float* t);710 void tRetune_tuneVoices (tRetune* const, float* t);
696 void tRetune_tuneVoice (tRetune* const, int voice, float t);711 void tRetune_tuneVoice (tRetune* const, int voice, float t);
697 float tRetune_getInputFrequency (tRetune* const);712 float tRetune_getInputFrequency (tRetune* const);
713 void tRetune_setSampleRate (tRetune* const, float sr);
698 714
699 //==============================================================================715 //==============================================================================
700 716
@@ -772,6 +788,8 @@ extern "C" { · 71 unmodified lines
772 tHighpass hp2;788 tHighpass hp2;
773 tFeedbackLeveler fbl1;789 tFeedbackLeveler fbl1;
774 tFeedbackLeveler fbl2;790 tFeedbackLeveler fbl2;
791 float sampleRate;
792 float invSampleRate;
775 } _tFormantShifter;793 } _tFormantShifter;
776 794
777 typedef _tFormantShifter* tFormantShifter;795 typedef _tFormantShifter* tFormantShifter;
@@ -786,6 +804,7 @@ extern "C" { · 8 unmodified lines
786 void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);804 void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
787 void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);805 void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);
788 void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);806 void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);
807 void tFormantShifter_setSampleRate (tFormantShifter* const fsr, float sr);
789 808
790 //==============================================================================809 //==============================================================================
791 810
@@ -796,3 +815,4 @@ extern "C" { · 4 unmodified lines
796#endif // LEAF_EFFECTS_H_INCLUDED815#endif // LEAF_EFFECTS_H_INCLUDED
797 816
798//==============================================================================817//==============================================================================
818
leaf/Inc/leaf-envelopes.h+12−5
@@ -345,9 +345,11 @@ extern "C" { · 344 unmodified lines
345 const float *exp_buff;345 const float *exp_buff;
346 uint32_t buff_size;346 uint32_t buff_size;
347 uint32_t buff_sizeMinusOne;347 uint32_t buff_sizeMinusOne;
348 float sampleRate;
348 float bufferSizeDividedBySampleRateInMs;349 float bufferSizeDividedBySampleRateInMs;
349 float next;350 float next;
350 351
352 float attack, decay, release;
351 float attackInc, decayInc, releaseInc, rampInc;353 float attackInc, decayInc, releaseInc, rampInc;
352 354
353 uint32_t whichStage;355 uint32_t whichStage;
@@ -374,6 +376,7 @@ extern "C" { · 20 unmodified lines
374 void tADSRT_setLeakFactor (tADSRT* const, float leakFactor);376 void tADSRT_setLeakFactor (tADSRT* const, float leakFactor);
375 void tADSRT_on (tADSRT* const, float velocity);377 void tADSRT_on (tADSRT* const, float velocity);
376 void tADSRT_off (tADSRT* const);378 void tADSRT_off (tADSRT* const);
379 void tADSRT_setSampleRate (tADSRT* const, float sr);
377 380
378 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~381 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
379 382
@@ -444,9 +447,13 @@ extern "C" { · 64 unmodified lines
444 {447 {
445 448
446 tMempool mempool;449 tMempool mempool;
450 float sampleRate;
447 float sampleRateInMs;451 float sampleRateInMs;
448 int state;452 int state;
449 float output;453 float output;
454 float attack;
455 float decay;
456 float release;
450 float attackRate;457 float attackRate;
451 float decayRate;458 float decayRate;
452 float releaseRate;459 float releaseRate;
@@ -481,6 +488,7 @@ extern "C" { · 28 unmodified lines
481 void tADSRS_setLeakFactor (tADSRS* const, float leakFactor);488 void tADSRS_setLeakFactor (tADSRS* const, float leakFactor);
482 void tADSRS_on (tADSRS* const, float velocity);489 void tADSRS_on (tADSRS* const, float velocity);
483 void tADSRS_off (tADSRS* const);490 void tADSRS_off (tADSRS* const);
491 void tADSRS_setSampleRate (tADSRS* const, float sr);
484 492
485 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~493 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
486 494
@@ -528,9 +536,9 @@ extern "C" { · 41 unmodified lines
528 536
529 typedef struct _tRamp537 typedef struct _tRamp
530 {538 {
531
532 tMempool mempool;539 tMempool mempool;
533 float inc;540 float inc;
541 float sampleRate;
534 float inv_sr_ms;542 float inv_sr_ms;
535 float minimum_time;543 float minimum_time;
536 float curr,dest;544 float curr,dest;
@@ -550,6 +558,7 @@ extern "C" { · 13 unmodified lines
550 void tRamp_setTime (tRamp* const, float time);558 void tRamp_setTime (tRamp* const, float time);
551 void tRamp_setDest (tRamp* const, float dest);559 void tRamp_setDest (tRamp* const, float dest);
552 void tRamp_setVal (tRamp* const, float val);560 void tRamp_setVal (tRamp* const, float val);
561 void tRamp_setSampleRate (tRamp* const, float sr);
553 562
554 /*!563 /*!
555 @defgroup trampupdown tRampUpDown564 @defgroup trampupdown tRampUpDown
@@ -599,10 +608,10 @@ extern "C" { · 43 unmodified lines
599 608
600 typedef struct _tRampUpDown609 typedef struct _tRampUpDown
601 {610 {
602
603 tMempool mempool;611 tMempool mempool;
604 float upInc;612 float upInc;
605 float downInc;613 float downInc;
614 float sampleRate;
606 float inv_sr_ms;615 float inv_sr_ms;
607 float minimum_time;616 float minimum_time;
608 float curr,dest;617 float curr,dest;
@@ -623,8 +632,7 @@ extern "C" { · 14 unmodified lines
623 void tRampUpDown_setDownTime (tRampUpDown* const, float downTime);632 void tRampUpDown_setDownTime (tRampUpDown* const, float downTime);
624 void tRampUpDown_setDest (tRampUpDown* const, float dest);633 void tRampUpDown_setDest (tRampUpDown* const, float dest);
625 void tRampUpDown_setVal (tRampUpDown* const, float val);634 void tRampUpDown_setVal (tRampUpDown* const, float val);
626 635 void tRampUpDown_setSampleRate (tRampUpDown* const, float sr);
627
628 636
629 /*!637 /*!
630 @defgroup tslide tSlide638 @defgroup tslide tSlide
@@ -670,7 +678,6 @@ extern "C" { · 39 unmodified lines
670 678
671 typedef struct _tSlide679 typedef struct _tSlide
672 {680 {
673
674 tMempool mempool;681 tMempool mempool;
675 float prevOut;682 float prevOut;
676 float currentOut;683 float currentOut;
leaf/Inc/leaf-filters.h+31−17
@@ -143,10 +143,12 @@ extern "C" { · 142 unmodified lines
143 {143 {
144 144
145 tMempool mempool;145 tMempool mempool;
146 float freq;
146 float gain;147 float gain;
147 float a0,a1;148 float a0,a1;
148 float b0,b1;149 float b0,b1;
149 float lastIn, lastOut;150 float lastIn, lastOut;
151 float twoPiTimesInvSampleRate;
150 } _tOnePole;152 } _tOnePole;
151 153
152 typedef _tOnePole* tOnePole;154 typedef _tOnePole* tOnePole;
@@ -162,6 +164,7 @@ extern "C" { · 9 unmodified lines
162 void tOnePole_setFreq (tOnePole* const, float freq);164 void tOnePole_setFreq (tOnePole* const, float freq);
163 void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);165 void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
164 void tOnePole_setGain (tOnePole* const, float gain);166 void tOnePole_setGain (tOnePole* const, float gain);
167 void tOnePole_setSampleRate (tOnePole* const, float sr);
165 168
166 //==============================================================================169 //==============================================================================
167 170
@@ -228,6 +231,9 @@ extern "C" { · 60 unmodified lines
228 int normalize;231 int normalize;
229 232
230 float lastOut[2];233 float lastOut[2];
234
235 float sampleRate;
236 float twoPiTimesInvSampleRate;
231 } _tTwoPole;237 } _tTwoPole;
232 238
233 typedef _tTwoPole* tTwoPole;239 typedef _tTwoPole* tTwoPole;
@@ -243,6 +249,7 @@ extern "C" { · 9 unmodified lines
243 void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, int normalize);249 void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, int normalize);
244 void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);250 void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
245 void tTwoPole_setGain (tTwoPole* const, float gain);251 void tTwoPole_setGain (tTwoPole* const, float gain);
252 void tTwoPole_setSampleRate (tTwoPole* const, float sr);
246 253
247 //==============================================================================254 //==============================================================================
248 255
@@ -298,11 +305,11 @@ extern "C" { · 49 unmodified lines
298 305
299 typedef struct _tOneZero306 typedef struct _tOneZero
300 {307 {
301
302 tMempool mempool;308 tMempool mempool;
303 float gain;309 float gain;
304 float b0,b1;310 float b0,b1;
305 float lastIn, lastOut, frequency;311 float lastIn, lastOut, frequency;
312 float invSampleRate;
306 } _tOneZero;313 } _tOneZero;
307 314
308 typedef _tOneZero* tOneZero;315 typedef _tOneZero* tOneZero;
@@ -317,7 +324,8 @@ extern "C" { · 8 unmodified lines
317 void tOneZero_setZero (tOneZero* const, float theZero);324 void tOneZero_setZero (tOneZero* const, float theZero);
318 void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);325 void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
319 void tOneZero_setGain (tOneZero* const, float gain);326 void tOneZero_setGain (tOneZero* const, float gain);
320 float tOneZero_getPhaseDelay (tOneZero *f, float frequency);327 float tOneZero_getPhaseDelay (tOneZero* const, float frequency);
328 void tOneZero_setSampleRate (tOneZero* const, float sr);
321 329
322 //==============================================================================330 //==============================================================================
323 331
@@ -374,15 +382,13 @@ extern "C" { · 50 unmodified lines
374 382
375 typedef struct _tTwoZero383 typedef struct _tTwoZero
376 {384 {
377
378 tMempool mempool;385 tMempool mempool;
379 386
380 float gain;387 float gain;
381 float b0, b1, b2;388 float b0, b1, b2;
382
383 float frequency, radius;389 float frequency, radius;
384
385 float lastIn[2];390 float lastIn[2];
391 float twoPiTimesInvSampleRate;
386 } _tTwoZero;392 } _tTwoZero;
387 393
388 typedef _tTwoZero* tTwoZero;394 typedef _tTwoZero* tTwoZero;
@@ -398,6 +404,7 @@ extern "C" { · 9 unmodified lines
398 void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);404 void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
399 void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);405 void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
400 void tTwoZero_setGain (tTwoZero* const, float gain);406 void tTwoZero_setGain (tTwoZero* const, float gain);
407 void tTwoZero_setSampleRate (tTwoZero* const, float sr);
401 408
402 //==============================================================================409 //==============================================================================
403 410
@@ -552,7 +559,6 @@ extern "C" { · 148 unmodified lines
552 559
553 typedef struct _tBiQuad560 typedef struct _tBiQuad
554 {561 {
555
556 tMempool mempool;562 tMempool mempool;
557 563
558 float gain;564 float gain;
@@ -564,6 +570,9 @@ extern "C" { · 5 unmodified lines
564 570
565 float frequency, radius;571 float frequency, radius;
566 int normalize;572 int normalize;
573
574 float sampleRate;
575 float twoPiTimesInvSampleRate;
567 } _tBiQuad;576 } _tBiQuad;
568 577
569 typedef _tBiQuad* tBiQuad;578 typedef _tBiQuad* tBiQuad;
@@ -582,6 +591,7 @@ extern "C" { · 12 unmodified lines
582 void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, int normalize);591 void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, int normalize);
583 void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);592 void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
584 void tBiQuad_setGain (tBiQuad* const, float gain);593 void tBiQuad_setGain (tBiQuad* const, float gain);
594 void tBiQuad_setSampleRate (tBiQuad* const, float sr);
585 595
586 //==============================================================================596 //==============================================================================
587 597
@@ -636,12 +646,13 @@ extern "C" { · 48 unmodified lines
636 646
637 typedef struct _tSVF647 typedef struct _tSVF
638 {648 {
639
640 tMempool mempool;649 tMempool mempool;
641 SVFType type;650 SVFType type;
642 float cutoff, Q;651 float cutoff, Q;
643 float ic1eq,ic2eq;652 float ic1eq,ic2eq;
644 float g,k,a1,a2,a3,cH,cB,cL,cBK;653 float g,k,a1,a2,a3,cH,cB,cL,cBK;
654 float sampleRate;
655 float invSampleRate;
645 } _tSVF;656 } _tSVF;
646 657
647 typedef _tSVF* tSVF;658 typedef _tSVF* tSVF;
@@ -654,6 +665,7 @@ extern "C" { · 6 unmodified lines
654 void tSVF_setFreq (tSVF* const, float freq);665 void tSVF_setFreq (tSVF* const, float freq);
655 void tSVF_setQ (tSVF* const, float Q);666 void tSVF_setQ (tSVF* const, float Q);
656 void tSVF_setFreqAndQ (tSVF* const svff, float freq, float Q);667 void tSVF_setFreqAndQ (tSVF* const svff, float freq, float Q);
668 void tSVF_setSampleRate (tSVF* const svff, float sr);
657 669
658 //==============================================================================670 //==============================================================================
659 671
@@ -749,10 +761,10 @@ extern "C" { · 89 unmodified lines
749 761
750 typedef struct _tHighpass762 typedef struct _tHighpass
751 {763 {
752
753 tMempool mempool;764 tMempool mempool;
754 float xs, ys, R;765 float xs, ys, R;
755 float frequency;766 float frequency;
767 float twoPiTimesInvSampleRate;
756 } _tHighpass;768 } _tHighpass;
757 769
758 typedef _tHighpass* tHighpass;770 typedef _tHighpass* tHighpass;
@@ -764,6 +776,7 @@ extern "C" { · 5 unmodified lines
764 float tHighpass_tick (tHighpass* const, float x);776 float tHighpass_tick (tHighpass* const, float x);
765 void tHighpass_setFreq (tHighpass* const, float freq);777 void tHighpass_setFreq (tHighpass* const, float freq);
766 float tHighpass_getFreq (tHighpass* const);778 float tHighpass_getFreq (tHighpass* const);
779 void tHighpass_setSampleRate (tHighpass* const, float sr);
767 780
768 //==============================================================================781 //==============================================================================
769 782
@@ -835,6 +848,7 @@ extern "C" { · 65 unmodified lines
835 void tButterworth_setF1 (tButterworth* const, float in);848 void tButterworth_setF1 (tButterworth* const, float in);
836 void tButterworth_setF2 (tButterworth* const, float in);849 void tButterworth_setF2 (tButterworth* const, float in);
837 void tButterworth_setFreqs (tButterworth* const, float f1, float f2);850 void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
851 void tButterworth_setSampleRate (tButterworth* const, float sr);
838 852
839 //==============================================================================853 //==============================================================================
840 854
@@ -952,10 +966,6 @@ extern "C" { · 111 unmodified lines
952 @brief Free a tVZFilter from its mempool.966 @brief Free a tVZFilter from its mempool.
953 @param filter A pointer to the tVZFilter to free.967 @param filter A pointer to the tVZFilter to free.
954 968
955 @fn void tVZFilter_setSampleRate (tVZFilter* const, float sampleRate)
956 @brief
957 @param filter A pointer to the relevant tVZFilter.
958
959 @fn float tVZFilter_tick (tVZFilter* const, float input)969 @fn float tVZFilter_tick (tVZFilter* const, float input)
960 @brief970 @brief
961 @param filter A pointer to the relevant tVZFilter.971 @param filter A pointer to the relevant tVZFilter.
@@ -991,6 +1001,10 @@ extern "C" { · 29 unmodified lines
991 @fn float tVZFilter_BandwidthToR (tVZFilter* const vf, float B)1001 @fn float tVZFilter_BandwidthToR (tVZFilter* const vf, float B)
992 @brief1002 @brief
993 @param filter A pointer to the relevant tVZFilter.1003 @param filter A pointer to the relevant tVZFilter.
1004
1005 @fn void tVZFilter_setSampleRate (tVZFilter* const, float sampleRate)
1006 @brief
1007 @param filter A pointer to the relevant tVZFilter.
994 1008 
995 @} */1009 @} */
996 1010
@@ -1012,7 +1026,6 @@ extern "C" { · 15 unmodified lines
1012 1026
1013 typedef struct _tVZFilter1027 typedef struct _tVZFilter
1014 {1028 {
1015
1016 tMempool mempool;1029 tMempool mempool;
1017 1030
1018 VZFilterType type;1031 VZFilterType type;
@@ -1032,8 +1045,8 @@ extern "C" { · 13 unmodified lines
1032 float B; // bandwidth (in octaves)1045 float B; // bandwidth (in octaves)
1033 float m; // morph parameter (0...1)1046 float m; // morph parameter (0...1)
1034 1047
1035 float sr; //local sampling rate of filter (may be different from leaf sr if oversampled)1048 float sampleRate; //local sampling rate of filter (may be different from leaf sr if oversampled)
1036 float inv_sr;1049 float invSampleRate;
1037 } _tVZFilter;1050 } _tVZFilter;
1038 1051
1039 typedef _tVZFilter* tVZFilter;1052 typedef _tVZFilter* tVZFilter;
@@ -1094,8 +1107,8 @@ extern "C" { · 54 unmodified lines
1094 //diode ladder filter1107 //diode ladder filter
1095 typedef struct _tDiodeFilter1108 typedef struct _tDiodeFilter
1096 {1109 {
1097
1098 tMempool mempool;1110 tMempool mempool;
1111 float cutoff;
1099 float f;1112 float f;
1100 float r;1113 float r;
1101 float Vt;1114 float Vt;
@@ -1106,6 +1119,7 @@ extern "C" { · 4 unmodified lines
1106 float g1inv;1119 float g1inv;
1107 float g2inv;1120 float g2inv;
1108 float s0, s1, s2, s3;1121 float s0, s1, s2, s3;
1122 float invSampleRate;
1109 } _tDiodeFilter;1123 } _tDiodeFilter;
1110 1124
1111 typedef _tDiodeFilter* tDiodeFilter;1125 typedef _tDiodeFilter* tDiodeFilter;
@@ -1117,7 +1131,7 @@ extern "C" { · 5 unmodified lines
1117 float tDiodeFilter_tick (tDiodeFilter* const, float input);1131 float tDiodeFilter_tick (tDiodeFilter* const, float input);
1118 void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff);1132 void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff);
1119 void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance);1133 void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance);
1120 1134 void tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr);
1121 1135
1122#ifdef __cplusplus1136#ifdef __cplusplus
1123}1137}
leaf/Inc/leaf-instruments.h+4−0
@@ -115,6 +115,7 @@ extern "C" { · 114 unmodified lines
115 void t808Cowbell_setFreq (t808Cowbell* const, float freq);115 void t808Cowbell_setFreq (t808Cowbell* const, float freq);
116 void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);116 void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
117 void t808Cowbell_setStick (t808Cowbell* const, int useStick);117 void t808Cowbell_setStick (t808Cowbell* const, int useStick);
118 void t808Cowbell_setSampleRate (t808Cowbell* const, float sr);
118 119
119 //==============================================================================120 //==============================================================================
120 121
@@ -227,6 +228,7 @@ extern "C" { · 106 unmodified lines
227 void t808Hihat_setOscFreq (t808Hihat* const, float freq);228 void t808Hihat_setOscFreq (t808Hihat* const, float freq);
228 void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);229 void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
229 void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);230 void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
231 void t808Hihat_setSampleRate (t808Hihat* const, float sr);
230 232
231 //==============================================================================233 //==============================================================================
232 234
@@ -333,6 +335,7 @@ extern "C" { · 100 unmodified lines
333 void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);335 void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
334 void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);336 void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
335 void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);337 void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
338 void t808Snare_setSampleRate (t808Snare* const, float sr);
336 339
337 //==============================================================================340 //==============================================================================
338 341
@@ -437,6 +440,7 @@ extern "C" { · 98 unmodified lines
437 void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);440 void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
438 void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);441 void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
439 void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);442 void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
443 void t808kick_setSampleRate (t808Kick* const, float sr);
440 444
441 //==============================================================================445 //==============================================================================
442 446
leaf/Inc/leaf-midi.h+2−1
@@ -309,7 +309,8 @@ extern "C" { · 308 unmodified lines
309 int tPoly_getKey (tPoly* const poly, uint8_t voice);309 int tPoly_getKey (tPoly* const poly, uint8_t voice);
310 int tPoly_getVelocity (tPoly* const poly, uint8_t voice);310 int tPoly_getVelocity (tPoly* const poly, uint8_t voice);
311 int tPoly_isOn (tPoly* const poly, uint8_t voice);311 int tPoly_isOn (tPoly* const poly, uint8_t voice);
312 312 void tPoly_setSampleRate (tPoly* const poly, float sr);
313
313 //==============================================================================314 //==============================================================================
314 315
315 /*! @}316 /*! @}
leaf/Inc/leaf-oscillators.h+38−4
@@ -63,11 +63,11 @@ extern "C" { · 62 unmodified lines
63 63
64 typedef struct _tCycle64 typedef struct _tCycle
65 {65 {
66
67 tMempool mempool;66 tMempool mempool;
68 // Underlying phasor67 // Underlying phasor
69 float phase;68 float phase;
70 float inc,freq;69 float inc,freq;
70 float invSampleRate;
71 } _tCycle;71 } _tCycle;
72 72
73 typedef _tCycle* tCycle;73 typedef _tCycle* tCycle;
@@ -78,6 +78,7 @@ extern "C" { · 4 unmodified lines
78 78
79 float tCycle_tick (tCycle* const osc);79 float tCycle_tick (tCycle* const osc);
80 void tCycle_setFreq (tCycle* const osc, float freq);80 void tCycle_setFreq (tCycle* const osc, float freq);
81 void tCycle_setSampleRate(tCycle* const osc, float sr);
81 82
82 //==============================================================================83 //==============================================================================
83 84
@@ -122,6 +123,7 @@ extern "C" { · 38 unmodified lines
122 float inc,freq;123 float inc,freq;
123 int oct;124 int oct;
124 float w;125 float w;
126 float invSampleRate;
125 } _tTriangle;127 } _tTriangle;
126 128
127 typedef _tTriangle* tTriangle;129 typedef _tTriangle* tTriangle;
@@ -132,7 +134,7 @@ extern "C" { · 4 unmodified lines
132 134
133 float tTriangle_tick (tTriangle* const osc);135 float tTriangle_tick (tTriangle* const osc);
134 void tTriangle_setFreq (tTriangle* const osc, float freq);136 void tTriangle_setFreq (tTriangle* const osc, float freq);
135 137 void tTriangle_setSampleRate (tTriangle* const osc, float sr);
136 138
137 //==============================================================================139 //==============================================================================
138 140
@@ -177,6 +179,7 @@ extern "C" { · 38 unmodified lines
177 float inc,freq;179 float inc,freq;
178 int oct;180 int oct;
179 float w;181 float w;
182 float invSampleRate;
180 } _tSquare;183 } _tSquare;
181 184
182 typedef _tSquare* tSquare;185 typedef _tSquare* tSquare;
@@ -187,6 +190,7 @@ extern "C" { · 4 unmodified lines
187 190
188 float tSquare_tick (tSquare* const osc);191 float tSquare_tick (tSquare* const osc);
189 void tSquare_setFreq (tSquare* const osc, float freq);192 void tSquare_setFreq (tSquare* const osc, float freq);
193 void tSquare_setSampleRate (tSquare* const osc, float sr);
190 194
191 /*!195 /*!
192 @} */196 @} */
@@ -234,6 +238,7 @@ extern "C" { · 41 unmodified lines
234 float inc,freq;238 float inc,freq;
235 int oct;239 int oct;
236 float w;240 float w;
241 float invSampleRate;
237 } _tSawtooth;242 } _tSawtooth;
238 243
239 typedef _tSawtooth* tSawtooth;244 typedef _tSawtooth* tSawtooth;
@@ -244,6 +249,7 @@ extern "C" { · 4 unmodified lines
244 249
245 float tSawtooth_tick (tSawtooth* const osc);250 float tSawtooth_tick (tSawtooth* const osc);
246 void tSawtooth_setFreq (tSawtooth* const osc, float freq);251 void tSawtooth_setFreq (tSawtooth* const osc, float freq);
252 void tSawtooth_setSampleRate (tSawtooth* const osc, float sr);
247 253
248 //==============================================================================254 //==============================================================================
249 255
@@ -288,6 +294,7 @@ extern "C" { · 38 unmodified lines
288 float inc,freq;294 float inc,freq;
289 float skew;295 float skew;
290 float lastOut;296 float lastOut;
297 float invSampleRate;
291 } _tPBTriangle;298 } _tPBTriangle;
292 299
293 typedef _tPBTriangle* tPBTriangle;300 typedef _tPBTriangle* tPBTriangle;
@@ -299,6 +306,7 @@ extern "C" { · 5 unmodified lines
299 float tPBTriangle_tick (tPBTriangle* const osc);306 float tPBTriangle_tick (tPBTriangle* const osc);
300 void tPBTriangle_setFreq (tPBTriangle* const osc, float freq);307 void tPBTriangle_setFreq (tPBTriangle* const osc, float freq);
301 void tPBTriangle_setSkew (tPBTriangle* const osc, float skew);308 void tPBTriangle_setSkew (tPBTriangle* const osc, float skew);
309 void tPBTriangle_setSampleRate (tPBTriangle* const osc, float sr);
302 310
303 //==============================================================================311 //==============================================================================
304 312
@@ -342,6 +350,7 @@ extern "C" { · 37 unmodified lines
342 float phase;350 float phase;
343 float inc,freq;351 float inc,freq;
344 float width;352 float width;
353 float invSampleRate;
345 } _tPBPulse;354 } _tPBPulse;
346 355
347 typedef _tPBPulse* tPBPulse;356 typedef _tPBPulse* tPBPulse;
@@ -353,6 +362,7 @@ extern "C" { · 5 unmodified lines
353 float tPBPulse_tick (tPBPulse* const osc);362 float tPBPulse_tick (tPBPulse* const osc);
354 void tPBPulse_setFreq (tPBPulse* const osc, float freq);363 void tPBPulse_setFreq (tPBPulse* const osc, float freq);
355 void tPBPulse_setWidth (tPBPulse* const osc, float width);364 void tPBPulse_setWidth (tPBPulse* const osc, float width);
365 void tPBPulse_setSampleRate (tPBPulse* const osc, float sr);
356 366
357 //==============================================================================367 //==============================================================================
358 368
@@ -391,6 +401,7 @@ extern "C" { · 32 unmodified lines
391 tMempool mempool;401 tMempool mempool;
392 float phase;402 float phase;
393 float inc,freq;403 float inc,freq;
404 float invSampleRate;
394 } _tPBSaw;405 } _tPBSaw;
395 406
396 typedef _tPBSaw* tPBSaw;407 typedef _tPBSaw* tPBSaw;
@@ -401,6 +412,7 @@ extern "C" { · 4 unmodified lines
401 412
402 float tPBSaw_tick (tPBSaw* const osc);413 float tPBSaw_tick (tPBSaw* const osc);
403 void tPBSaw_setFreq (tPBSaw* const osc, float freq);414 void tPBSaw_setFreq (tPBSaw* const osc, float freq);
415 void tPBSaw_setSampleRate (tPBSaw* const osc, float sr);
404 416
405 //==============================================================================417 //==============================================================================
406 418
@@ -441,6 +453,7 @@ extern "C" { · 34 unmodified lines
441 float phase;453 float phase;
442 float inc,freq;454 float inc,freq;
443 uint8_t phaseDidReset;455 uint8_t phaseDidReset;
456 float invSampleRate;
444 } _tPhasor;457 } _tPhasor;
445 458
446 typedef _tPhasor* tPhasor;459 typedef _tPhasor* tPhasor;
@@ -451,6 +464,7 @@ extern "C" { · 4 unmodified lines
451 464
452 float tPhasor_tick (tPhasor* const osc);465 float tPhasor_tick (tPhasor* const osc);
453 void tPhasor_setFreq (tPhasor* const osc, float freq);466 void tPhasor_setFreq (tPhasor* const osc, float freq);
467 void tPhasor_setSampleRate (tPhasor* const osc, float sr);
454 468
455 //==============================================================================469 //==============================================================================
456 470
@@ -643,9 +657,7 @@ extern "C" { · 186 unmodified lines
643 void tNeuron_setV2 (tNeuron* const neuron, float V2);657 void tNeuron_setV2 (tNeuron* const neuron, float V2);
644 void tNeuron_setV3 (tNeuron* const neuron, float V3);658 void tNeuron_setV3 (tNeuron* const neuron, float V3);
645 void tNeuron_setTimeStep (tNeuron* const neuron, float timestep);659 void tNeuron_setTimeStep (tNeuron* const neuron, float timestep);
646
647 660
648
649 //==============================================================================661 //==============================================================================
650 662
651 663
@@ -708,6 +720,7 @@ extern "C" { · 56 unmodified lines
708 float _f [FILLEN + STEP_DD_PULSE_LENGTH];720 float _f [FILLEN + STEP_DD_PULSE_LENGTH];
709 int _j, _k;721 int _j, _k;
710 bool _init;722 bool _init;
723 float invSampleRate;
711 } _tMBPulse;724 } _tMBPulse;
712 725
713 typedef _tMBPulse* tMBPulse;726 typedef _tMBPulse* tMBPulse;
@@ -721,6 +734,7 @@ extern "C" { · 7 unmodified lines
721 void tMBPulse_setWidth(tMBPulse* const osc, float w);734 void tMBPulse_setWidth(tMBPulse* const osc, float w);
722 float tMBPulse_sync(tMBPulse* const osc, float sync);735 float tMBPulse_sync(tMBPulse* const osc, float sync);
723 void tMBPulse_setSyncMode(tMBPulse* const osc, int hardOrSoft);736 void tMBPulse_setSyncMode(tMBPulse* const osc, int hardOrSoft);
737 void tMBPulse_setSampleRate (tMBPulse* const osc, float sr);
724 738
725 /*!739 /*!
726 @defgroup tmbtriangle tMBTriangle740 @defgroup tmbtriangle tMBTriangle
@@ -779,6 +793,7 @@ extern "C" { · 52 unmodified lines
779 float _f [FILLEN + LONGEST_DD_PULSE_LENGTH];793 float _f [FILLEN + LONGEST_DD_PULSE_LENGTH];
780 int _j, _k;794 int _j, _k;
781 bool _init;795 bool _init;
796 float invSampleRate;
782 } _tMBTriangle;797 } _tMBTriangle;
783 798
784 typedef _tMBTriangle* tMBTriangle;799 typedef _tMBTriangle* tMBTriangle;
@@ -792,6 +807,7 @@ extern "C" { · 7 unmodified lines
792 void tMBTriangle_setWidth(tMBTriangle* const osc, float w);807 void tMBTriangle_setWidth(tMBTriangle* const osc, float w);
793 float tMBTriangle_sync(tMBTriangle* const osc, float sync);808 float tMBTriangle_sync(tMBTriangle* const osc, float sync);
794 void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft);809 void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft);
810 void tMBTriangle_setSampleRate (tMBTriangle* const osc, float sr);
795 811
796 812
797 /*!813 /*!
@@ -849,6 +865,7 @@ extern "C" { · 51 unmodified lines
849 float _f [FILLEN + STEP_DD_PULSE_LENGTH];865 float _f [FILLEN + STEP_DD_PULSE_LENGTH];
850 int _j;866 int _j;
851 bool _init;867 bool _init;
868 float invSampleRate;
852 } _tMBSaw;869 } _tMBSaw;
853 870
854 typedef _tMBSaw* tMBSaw;871 typedef _tMBSaw* tMBSaw;
@@ -861,6 +878,7 @@ extern "C" { · 6 unmodified lines
861 void tMBSaw_setFreq(tMBSaw* const osc, float f);878 void tMBSaw_setFreq(tMBSaw* const osc, float f);
862 float tMBSaw_sync(tMBSaw* const osc, float sync);879 float tMBSaw_sync(tMBSaw* const osc, float sync);
863 void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft);880 void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft);
881 void tMBSaw_setSampleRate (tMBSaw* const osc, float sr);
864 882
865 //==============================================================================883 //==============================================================================
866 884
@@ -908,6 +926,7 @@ extern "C" { · 41 unmodified lines
908 int size;926 int size;
909 float inc, freq;927 float inc, freq;
910 float phase;928 float phase;
929 float invSampleRate;
911 } _tTable;930 } _tTable;
912 931
913 typedef _tTable* tTable;932 typedef _tTable* tTable;
@@ -918,6 +937,7 @@ extern "C" { · 4 unmodified lines
918 937
919 float tTable_tick(tTable* const osc);938 float tTable_tick(tTable* const osc);
920 void tTable_setFreq(tTable* const osc, float freq);939 void tTable_setFreq(tTable* const osc, float freq);
940 void tTable_setSampleRate (tTable* const osc, float sr);
921 941
922 //==============================================================================942 //==============================================================================
923 943
@@ -953,11 +973,14 @@ extern "C" { · 29 unmodified lines
953 {973 {
954 tMempool mempool;974 tMempool mempool;
955 975
976 float* baseTable;
956 float** tables;977 float** tables;
957 int size;978 int size;
958 int numTables;979 int numTables;
980 float maxFreq;
959 float baseFreq, invBaseFreq;981 float baseFreq, invBaseFreq;
960 tButterworth bl;982 tButterworth bl;
983 float sampleRate;
961 } _tWaveTable;984 } _tWaveTable;
962 985
963 typedef _tWaveTable* tWaveTable;986 typedef _tWaveTable* tWaveTable;
@@ -967,6 +990,7 @@ extern "C" { · 3 unmodified lines
967 void tWaveTable_initToPool(tWaveTable* const osc, float* table, int size,990 void tWaveTable_initToPool(tWaveTable* const osc, float* table, int size,
968 float maxFreq, tMempool* const mempool);991 float maxFreq, tMempool* const mempool);
969 void tWaveTable_free(tWaveTable* const osc);992 void tWaveTable_free(tWaveTable* const osc);
993 void tWaveTable_setSampleRate (tWaveTable* const osc, float sr);
970 994
971 //==============================================================================995 //==============================================================================
972 996
@@ -995,6 +1019,7 @@ extern "C" { · 22 unmodified lines
995 float inc, freq;1019 float inc, freq;
996 float phase;1020 float phase;
997 float phaseOffset;1021 float phaseOffset;
1022 float invSampleRate;
998 1023
999 int oct;1024 int oct;
1000 float w;1025 float w;
@@ -1011,6 +1036,7 @@ extern "C" { · 10 unmodified lines
1011 void tWaveOsc_setFreq(tWaveOsc* const osc, float freq);1036 void tWaveOsc_setFreq(tWaveOsc* const osc, float freq);
1012 void tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);1037 void tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);
1013 void tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);1038 void tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);
1039 void tWaveOsc_setSampleRate (tWaveOsc* const osc, float sr);
1014 1040
1015 //==============================================================================1041 //==============================================================================
1016 1042
@@ -1087,6 +1113,7 @@ extern "C" { · 70 unmodified lines
1087 void tWaveSynth_setIndexGain(tWaveSynth* const osc, int i, float gain);1113 void tWaveSynth_setIndexGain(tWaveSynth* const osc, int i, float gain);
1088 void tWaveSynth_setIndexPhase(tWaveSynth* const osc, int i, float phase);1114 void tWaveSynth_setIndexPhase(tWaveSynth* const osc, int i, float phase);
1089// void tWaveSynth_setIndexTable(tWaveSynth* const osc, int i, float* table, int size);1115// void tWaveSynth_setIndexTable(tWaveSynth* const osc, int i, float* table, int size);
1116 void tWaveSynth_setSampleRate (tWaveSynth* const osc, float sr);
1090 1117
1091 //==============================================================================1118 //==============================================================================
1092 1119
@@ -1122,13 +1149,16 @@ extern "C" { · 29 unmodified lines
1122 {1149 {
1123 tMempool mempool;1150 tMempool mempool;
1124 1151
1152 float* baseTable;
1125 float** tables;1153 float** tables;
1126 int numTables;1154 int numTables;
1127 int* sizes;1155 int* sizes;
1156 float maxFreq;
1128 float baseFreq, invBaseFreq;1157 float baseFreq, invBaseFreq;
1129 tButterworth bl;1158 tButterworth bl;
1130 float dsBuffer[2];1159 float dsBuffer[2];
1131 tOversampler ds;1160 tOversampler ds;
1161 float sampleRate;
1132 } _tWaveTableS;1162 } _tWaveTableS;
1133 1163
1134 typedef _tWaveTableS* tWaveTableS;1164 typedef _tWaveTableS* tWaveTableS;
@@ -1136,6 +1166,7 @@ extern "C" { · 1 unmodified line
1136 void tWaveTableS_init(tWaveTableS* const osc, float* table, int size, float maxFreq, LEAF* const leaf);1166 void tWaveTableS_init(tWaveTableS* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
1137 void tWaveTableS_initToPool(tWaveTableS* const osc, float* table, int size, float maxFreq, tMempool* const mempool);1167 void tWaveTableS_initToPool(tWaveTableS* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
1138 void tWaveTableS_free(tWaveTableS* const osc);1168 void tWaveTableS_free(tWaveTableS* const osc);
1169 void tWaveTableS_setSampleRate (tWaveTableS* const osc, float sr);
1139 1170
1140 /*!1171 /*!
1141 @defgroup twaveoscs tWaveOscS1172 @defgroup twaveoscs tWaveOscS
@@ -1182,6 +1213,7 @@ extern "C" { · 40 unmodified lines
1182 float inc, freq;1213 float inc, freq;
1183 float phase;1214 float phase;
1184 float phaseOffset;1215 float phaseOffset;
1216 float invSampleRate;
1185 int oct;1217 int oct;
1186 float w;1218 float w;
1187 float aa;1219 float aa;
@@ -1197,6 +1229,7 @@ extern "C" { · 9 unmodified lines
1197 void tWaveOscS_setFreq(tWaveOscS* const osc, float freq);1229 void tWaveOscS_setFreq(tWaveOscS* const osc, float freq);
1198 void tWaveOscS_setAntiAliasing(tWaveOscS* const osc, float aa);1230 void tWaveOscS_setAntiAliasing(tWaveOscS* const osc, float aa);
1199 void tWaveOscS_setPhaseOffset(tWaveOscS* const osc, float phase);1231 void tWaveOscS_setPhaseOffset(tWaveOscS* const osc, float phase);
1232 void tWaveOscS_setSampleRate (tWaveOscS* const osc, float sr);
1200 1233
1201 //==============================================================================1234 //==============================================================================
1202 1235
@@ -1273,6 +1306,7 @@ extern "C" { · 70 unmodified lines
1273 void tWaveSynthS_setIndexGain(tWaveSynthS* const osc, int i, float gain);1306 void tWaveSynthS_setIndexGain(tWaveSynthS* const osc, int i, float gain);
1274 void tWaveSynthS_setIndexPhase(tWaveSynthS* const osc, int i, float phase);1307 void tWaveSynthS_setIndexPhase(tWaveSynthS* const osc, int i, float phase);
1275// void tWaveSynthS_setIndexTable(tWaveSynthS* const osc, int i, float* table, int size);1308// void tWaveSynthS_setIndexTable(tWaveSynthS* const osc, int i, float* table, int size);
1309 void tWaveSynthS_setSampleRate (tWaveSynthS* const osc, float sr);
1276 1310
1277#ifdef __cplusplus1311#ifdef __cplusplus
1278}1312}
leaf/Inc/leaf-physical.h+71−63
@@ -71,7 +71,7 @@ extern "C" { · 70 unmodified lines
71 @fn void tPluck_noteOff (tPluck* const, float amplitude )71 @fn void tPluck_noteOff (tPluck* const, float amplitude )
72 @brief Stop a note with the given amplitude (speed of decay)72 @brief Stop a note with the given amplitude (speed of decay)
73 @param string A pointer to the relevant tPluck.73 @param string A pointer to the relevant tPluck.
74 74
75 @fn void tPluck_setFrequency (tPluck* const, float frequency )75 @fn void tPluck_setFrequency (tPluck* const, float frequency )
76 @brief Set instrument parameters for a particular frequency.76 @brief Set instrument parameters for a particular frequency.
77 @param string A pointer to the relevant tPluck.77 @param string A pointer to the relevant tPluck.
@@ -79,7 +79,7 @@ extern "C" { · 1 unmodified line
79 @fn void tPluck_controlChange (tPluck* const, int number, float value)79 @fn void tPluck_controlChange (tPluck* const, int number, float value)
80 @brief Perform the control change specified by \e number and \e value (0.0 - 128.0).80 @brief Perform the control change specified by \e number and \e value (0.0 - 128.0).
81 @param string A pointer to the relevant tPluck.81 @param string A pointer to the relevant tPluck.
82 82
83 @fn float tPluck_getLastOut (tPluck* const)83 @fn float tPluck_getLastOut (tPluck* const)
84 @brief84 @brief
85 @param string A pointer to the relevant tPluck.85 @param string A pointer to the relevant tPluck.
@@ -100,7 +100,7 @@ extern "C" { · 14 unmodified lines
100 float loopGain;100 float loopGain;
101 float lastFreq;101 float lastFreq;
102 102
103 float sr;103 float sampleRate;
104 } _tPluck;104 } _tPluck;
105 105
106 typedef _tPluck* tPluck;106 typedef _tPluck* tPluck;
@@ -116,6 +116,7 @@ extern "C" { · 9 unmodified lines
116 void tPluck_setFrequency (tPluck* const, float frequency );116 void tPluck_setFrequency (tPluck* const, float frequency );
117 void tPluck_controlChange (tPluck* const, int number, float value);117 void tPluck_controlChange (tPluck* const, int number, float value);
118 float tPluck_getLastOut (tPluck* const);118 float tPluck_getLastOut (tPluck* const);
119 void tPluck_setSampleRate (tPluck* const, float sr);
119 120
120 //==============================================================================121 //==============================================================================
121 122
@@ -146,7 +147,7 @@ extern "C" { · 24 unmodified lines
146 @fn void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude)147 @fn void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude)
147 @brief Pluck the string.148 @brief Pluck the string.
148 @param string A pointer to the relevant tKarplusStrong.149 @param string A pointer to the relevant tKarplusStrong.
149 150
150 @fn void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude)151 @fn void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude)
151 @brief Start a note with the given frequency and amplitude.152 @brief Start a note with the given frequency and amplitude.
152 @param string A pointer to the relevant tKarplusStrong.153 @param string A pointer to the relevant tKarplusStrong.
@@ -210,6 +211,8 @@ extern "C" { · 57 unmodified lines
210 float pickupPosition;211 float pickupPosition;
211 212
212 float lastOut;213 float lastOut;
214
215 float sampleRate;
213 } _tKarplusStrong;216 } _tKarplusStrong;
214 217
215 typedef _tKarplusStrong* tKarplusStrong;218 typedef _tKarplusStrong* tKarplusStrong;
@@ -307,6 +310,7 @@ extern "C" { · 91 unmodified lines
307 tHighpass DCblocker;310 tHighpass DCblocker;
308 tFeedbackLeveler fbLev;311 tFeedbackLeveler fbLev;
309 tExpSmooth wlSmooth;312 tExpSmooth wlSmooth;
313 float sampleRate;
310 } _tSimpleLivingString;314 } _tSimpleLivingString;
311 315
312 typedef _tSimpleLivingString* tSimpleLivingString;316 typedef _tSimpleLivingString* tSimpleLivingString;
@@ -329,6 +333,7 @@ extern "C" { · 16 unmodified lines
329 void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);333 void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
330 void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);334 void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
331 void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);335 void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
336 void tSimpleLivingString_setSampleRate (tSimpleLivingString* const, float sr);
332 337
333 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~338 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
334 339
@@ -404,7 +409,6 @@ extern "C" { · 69 unmodified lines
404 409
405 typedef struct _tLivingString410 typedef struct _tLivingString
406 {411 {
407
408 tMempool mempool;412 tMempool mempool;
409 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length413 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
410 float pickPos; // the pick position, dividing the string in two, in ratio414 float pickPos; // the pick position, dividing the string in two, in ratio
@@ -418,6 +422,7 @@ extern "C" { · 7 unmodified lines
418 tHighpass DCblockerL, DCblockerU;422 tHighpass DCblockerL, DCblockerU;
419 tFeedbackLeveler fbLevU, fbLevL;423 tFeedbackLeveler fbLevU, fbLevL;
420 tExpSmooth wlSmooth, ppSmooth;424 tExpSmooth wlSmooth, ppSmooth;
425 float sampleRate;
421 } _tLivingString;426 } _tLivingString;
422 427
423 typedef _tLivingString* tLivingString;428 typedef _tLivingString* tLivingString;
@@ -442,10 +447,10 @@ extern "C" { · 18 unmodified lines
442 void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);447 void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
443 void tLivingString_setLevStrength (tLivingString* const, float levStrength);448 void tLivingString_setLevStrength (tLivingString* const, float levStrength);
444 void tLivingString_setLevMode (tLivingString* const, int levMode);449 void tLivingString_setLevMode (tLivingString* const, int levMode);
450 void tLivingString_setSampleRate (tLivingString* const, float sr);
451
452 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
445 453
446
447 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
448
449 454
450 /*!455 /*!
451 @defgroup tlivingstring2 tLivingString2456 @defgroup tlivingstring2 tLivingString2
@@ -524,55 +529,56 @@ extern "C" { · 72 unmodified lines
524 529
525 @} */530 @} */
526 typedef struct _tLivingString2531 typedef struct _tLivingString2
527 {532 {
528 533 tMempool mempool;
529 tMempool mempool;534 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
530 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length535 float pickPos; // the pick position, dividing the string in two, in ratio
531 float pickPos; // the pick position, dividing the string in two, in ratio536 float prepPos; // the preparation position, dividing the string in two, in ratio
532 float prepPos; // the preparation position, dividing the string in two, in ratio537 float pickupPos; // the preparation position, dividing the string in two, in ratio
533 float pickupPos; // the preparation position, dividing the string in two, in ratio538 float prepIndex; // the amount of pressure on the preparation position of the string (near 0=soft obj, near 1=hard obj)
534 float prepIndex; // the amount of pressure on the preparation position of the string (near 0=soft obj, near 1=hard obj)539 float decay; // amplitude damping factor for the string (only active in mode 0)
535 float decay; // amplitude damping factor for the string (only active in mode 0)540 int levMode;
536 int levMode;541 float brightness;
537 float brightness;542 float curr;
538 float curr;543 tHermiteDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
539 tHermiteDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model544 tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;
540 tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;545 tHighpass DCblockerL, DCblockerU;
541 tHighpass DCblockerL, DCblockerU;546 tFeedbackLeveler fbLevU, fbLevL;
542 tFeedbackLeveler fbLevU, fbLevL;547 tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;
543 tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;548 float sampleRate;
544 } _tLivingString2;549 } _tLivingString2;
545 550
546 typedef _tLivingString2* tLivingString2;551 typedef _tLivingString2* tLivingString2;
547 552
548 void tLivingString2_init (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,553 void tLivingString2_init (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
549 float brightness, float decay, float targetLev, float levSmoothFactor,554 float brightness, float decay, float targetLev, float levSmoothFactor,
550 float levStrength, int levMode, LEAF* const leaf);555 float levStrength, int levMode, LEAF* const leaf);
551 void tLivingString2_initToPool (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,556 void tLivingString2_initToPool (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
552 float brightness, float decay, float targetLev, float levSmoothFactor,557 float brightness, float decay, float targetLev, float levSmoothFactor,
553 float levStrength, int levMode, tMempool* const);558 float levStrength, int levMode, tMempool* const);
554 void tLivingString2_free (tLivingString2* const);559 void tLivingString2_free (tLivingString2* const);
555 560
556 float tLivingString2_tick (tLivingString2* const, float input);561 float tLivingString2_tick (tLivingString2* const, float input);
557 float tLivingString2_sample (tLivingString2* const);562 float tLivingString2_sample (tLivingString2* const);
558 void tLivingString2_setFreq (tLivingString2* const, float freq);563 void tLivingString2_setFreq (tLivingString2* const, float freq);
559 void tLivingString2_setWaveLength (tLivingString2* const, float waveLength); // in samples564 void tLivingString2_setWaveLength (tLivingString2* const, float waveLength); // in samples
560 void tLivingString2_setPickPos (tLivingString2* const, float pickPos);565 void tLivingString2_setPickPos (tLivingString2* const, float pickPos);
561 void tLivingString2_setPrepPos (tLivingString2* const, float prepPos);566 void tLivingString2_setPrepPos (tLivingString2* const, float prepPos);
562 void tLivingString2_setPickupPos (tLivingString2* const, float pickupPos);567 void tLivingString2_setPickupPos (tLivingString2* const, float pickupPos);
563 void tLivingString2_setPrepIndex (tLivingString2* const, float prepIndex);568 void tLivingString2_setPrepIndex (tLivingString2* const, float prepIndex);
564 void tLivingString2_setBrightness (tLivingString2* const, float brightness);569 void tLivingString2_setBrightness (tLivingString2* const, float brightness);
565 void tLivingString2_setDecay (tLivingString2* const, float decay); // from 0 to 1, gets converted to real decay factor570 void tLivingString2_setDecay (tLivingString2* const, float decay); // from 0 to 1, gets converted to real decay factor
566 void tLivingString2_setTargetLev (tLivingString2* const, float targetLev);571 void tLivingString2_setTargetLev (tLivingString2* const, float targetLev);
567 void tLivingString2_setLevSmoothFactor (tLivingString2* const, float levSmoothFactor);572 void tLivingString2_setLevSmoothFactor (tLivingString2* const, float levSmoothFactor);
568 void tLivingString2_setLevStrength (tLivingString2* const, float levStrength);573 void tLivingString2_setLevStrength (tLivingString2* const, float levStrength);
569 void tLivingString2_setLevMode (tLivingString2* const, int levMode);574 void tLivingString2_setLevMode (tLivingString2* const, int levMode);
570 575 void tLivingString2_setSampleRate (tLivingString2* const, float sr);
571 576
572 577
573 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~578
574 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~579 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
575 580 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
581
576 /*!582 /*!
577 @defgroup tcomplexlivingstring tComplexLivingString583 @defgroup tcomplexlivingstring tComplexLivingString
578 @ingroup physical584 @ingroup physical
@@ -649,7 +655,6 @@ extern "C" { · 70 unmodified lines
649 655
650 typedef struct _tComplexLivingString656 typedef struct _tComplexLivingString
651 {657 {
652
653 tMempool mempool;658 tMempool mempool;
654 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length659 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
655 float pickPos; // the pick position, dividing the string, in ratio660 float pickPos; // the pick position, dividing the string, in ratio
@@ -665,10 +670,11 @@ extern "C" { · 9 unmodified lines
665 tHighpass DCblockerL, DCblockerU;670 tHighpass DCblockerL, DCblockerU;
666 tFeedbackLeveler fbLevU, fbLevL;671 tFeedbackLeveler fbLevU, fbLevL;
667 tExpSmooth wlSmooth, pickPosSmooth, prepPosSmooth;672 tExpSmooth wlSmooth, pickPosSmooth, prepPosSmooth;
673 float sampleRate;
668 } _tComplexLivingString;674 } _tComplexLivingString;
669 675
670 typedef _tComplexLivingString* tComplexLivingString;676 typedef _tComplexLivingString* tComplexLivingString;
671 677
672 void tComplexLivingString_init (tComplexLivingString* const, float freq, float pickPos,678 void tComplexLivingString_init (tComplexLivingString* const, float freq, float pickPos,
673 float prepPos, float prepIndex, float dampFreq,679 float prepPos, float prepIndex, float dampFreq,
674 float decay, float targetLev, float levSmoothFactor,680 float decay, float targetLev, float levSmoothFactor,
@@ -678,7 +684,7 @@ extern "C" { · 3 unmodified lines
678 float decay, float targetLev, float levSmoothFactor,684 float decay, float targetLev, float levSmoothFactor,
679 float levStrength, int levMode, tMempool* const);685 float levStrength, int levMode, tMempool* const);
680 void tComplexLivingString_free (tComplexLivingString* const);686 void tComplexLivingString_free (tComplexLivingString* const);
681 687
682 float tComplexLivingString_tick (tComplexLivingString* const, float input);688 float tComplexLivingString_tick (tComplexLivingString* const, float input);
683 float tComplexLivingString_sample (tComplexLivingString* const);689 float tComplexLivingString_sample (tComplexLivingString* const);
684 void tComplexLivingString_setFreq (tComplexLivingString* const, float freq);690 void tComplexLivingString_setFreq (tComplexLivingString* const, float freq);
@@ -692,9 +698,10 @@ extern "C" { · 7 unmodified lines
692 void tComplexLivingString_setLevSmoothFactor (tComplexLivingString* const, float levSmoothFactor);698 void tComplexLivingString_setLevSmoothFactor (tComplexLivingString* const, float levSmoothFactor);
693 void tComplexLivingString_setLevStrength (tComplexLivingString* const, float levStrength);699 void tComplexLivingString_setLevStrength (tComplexLivingString* const, float levStrength);
694 void tComplexLivingString_setLevMode (tComplexLivingString* const, int levMode);700 void tComplexLivingString_setLevMode (tComplexLivingString* const, int levMode);
701 void tComplexLivingString_setSampleRate (tComplexLivingString* const, float sr);
695 702
696 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~703 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
697 704
698 705
699 /*!706 /*!
700 @defgroup treedtable tReedTable707 @defgroup treedtable tReedTable
@@ -733,7 +740,7 @@ extern "C" { · 32 unmodified lines
733 @param reed A pointer to the relevant tReedTable.740 @param reed A pointer to the relevant tReedTable.
734 741
735 @} */742 @} */
736 743
737 typedef struct _tReedTable744 typedef struct _tReedTable
738 {745 {
739 746
@@ -762,3 +769,4 @@ extern "C" { · 22 unmodified lines
762 769
763//==============================================================================770//==============================================================================
764 771
772
leaf/Inc/leaf-reverb.h+11−3
@@ -78,6 +78,8 @@ extern "C" { · 77 unmodified lines
78 float mix, t60;78 float mix, t60;
79 79
80 float inv_441;80 float inv_441;
81 float sampleRate;
82 float invSampleRate;
81 83
82 tDelay allpassDelays[2];84 tDelay allpassDelays[2];
83 tDelay combDelay;85 tDelay combDelay;
@@ -97,6 +99,7 @@ extern "C" { · 13 unmodified lines
97 float tPRCReverb_tick (tPRCReverb* const, float input);99 float tPRCReverb_tick (tPRCReverb* const, float input);
98 void tPRCReverb_setT60 (tPRCReverb* const, float t60);100 void tPRCReverb_setT60 (tPRCReverb* const, float t60);
99 void tPRCReverb_setMix (tPRCReverb* const, float mix);101 void tPRCReverb_setMix (tPRCReverb* const, float mix);
102 void tPRCReverb_setSampleRate(tPRCReverb* const, float sr);
100 103
101 //==============================================================================104 //==============================================================================
102 105
@@ -149,7 +152,9 @@ extern "C" { · 46 unmodified lines
149 152
150 float mix, t60;153 float mix, t60;
151 154
152 float inv_sr, inv_441;155 float inv_441;
156 float sampleRate;
157 float invSampleRate;
153 158
154 tLinearDelay allpassDelays[8];159 tLinearDelay allpassDelays[8];
155 tLinearDelay combDelays[6];160 tLinearDelay combDelays[6];
@@ -171,6 +176,7 @@ extern "C" { · 15 unmodified lines
171 void tNReverb_tickStereo (tNReverb* const rev, float input, float* output);176 void tNReverb_tickStereo (tNReverb* const rev, float input, float* output);
172 void tNReverb_setT60 (tNReverb* const, float t60);177 void tNReverb_setT60 (tNReverb* const, float t60);
173 void tNReverb_setMix (tNReverb* const, float mix);178 void tNReverb_setMix (tNReverb* const, float mix);
179 void tNReverb_setSampleRate (tNReverb* const, float sr);
174 180
175 //==============================================================================181 //==============================================================================
176 182
@@ -245,12 +251,13 @@ extern "C" { · 68 unmodified lines
245 251
246 tMempool mempool;252 tMempool mempool;
247 253
254 float sampleRate;
248 float predelay;255 float predelay;
249 float input_filter;256 float input_filter;
250 float feedback_filter;257 float feedback_filter;
251 float feedback_gain;258 float feedback_gain;
252 float mix;259 float mix;
253 uint32_t frozen;260 int frozen;
254 261
255 float size, size_max, t;262 float size, size_max, t;
256 263
@@ -296,13 +303,14 @@ extern "C" { · 39 unmodified lines
296 float tDattorroReverb_tick (tDattorroReverb* const, float input);303 float tDattorroReverb_tick (tDattorroReverb* const, float input);
297 void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);304 void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);
298 void tDattorroReverb_setMix (tDattorroReverb* const, float mix);305 void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
299 void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze);306 void tDattorroReverb_setFreeze (tDattorroReverb* const rev, int freeze);
300 void tDattorroReverb_setHP (tDattorroReverb* const, float freq);307 void tDattorroReverb_setHP (tDattorroReverb* const, float freq);
301 void tDattorroReverb_setSize (tDattorroReverb* const, float size);308 void tDattorroReverb_setSize (tDattorroReverb* const, float size);
302 void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);309 void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
303 void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);310 void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
304 void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);311 void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
305 void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);312 void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);
313 void tDattorroReverb_setSampleRate (tDattorroReverb* const, float sr);
306 314
307#ifdef __cplusplus315#ifdef __cplusplus
308}316}
leaf/Inc/leaf-sampling.h+7−7
@@ -243,13 +243,12 @@ extern "C" { · 242 unmodified lines
243 243
244 typedef struct _tSampler244 typedef struct _tSampler
245 {245 {
246
247 tMempool mempool;246 tMempool mempool;
248 247
249 tBuffer samp;248 tBuffer samp;
250 249
251 float leafInvSampleRate;250 float invSampleRate;
252 float leafSampleRate;251 float sampleRate;
253 float ticksPerSevenMs;252 float ticksPerSevenMs;
254 float rateFactor;253 float rateFactor;
255 uint32_t channels;254 uint32_t channels;
@@ -284,11 +283,11 @@ extern "C" { · 28 unmodified lines
284 typedef _tSampler* tSampler;283 typedef _tSampler* tSampler;
285 284
286 void tSampler_init (tSampler* const, tBuffer* const, LEAF* const leaf);285 void tSampler_init (tSampler* const, tBuffer* const, LEAF* const leaf);
287 void tSampler_initToPool (tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf);286 void tSampler_initToPool (tSampler* const sp, tBuffer* const b, tMempool* const mp, LEAF* const leaf);
288 void tSampler_free (tSampler* const);287 void tSampler_free (tSampler* const);
289 288
290 float tSampler_tick (tSampler* const);289 float tSampler_tick (tSampler* const);
291 float tSampler_tickStereo (tSampler* const sp, float* outputArray);290 float tSampler_tickStereo (tSampler* const sp, float* outputArray);
292 void tSampler_setSample (tSampler* const, tBuffer* const);291 void tSampler_setSample (tSampler* const, tBuffer* const);
293 void tSampler_setMode (tSampler* const, PlayMode mode);292 void tSampler_setMode (tSampler* const, PlayMode mode);
294 void tSampler_play (tSampler* const);293 void tSampler_play (tSampler* const);
@@ -296,8 +295,9 @@ extern "C" { · 1 unmodified line
296 void tSampler_setStart (tSampler* const, int32_t start);295 void tSampler_setStart (tSampler* const, int32_t start);
297 void tSampler_setEnd (tSampler* const, int32_t end);296 void tSampler_setEnd (tSampler* const, int32_t end);
298 void tSampler_setLength (tSampler* const, int32_t length);297 void tSampler_setLength (tSampler* const, int32_t length);
299 void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);298 void tSampler_setCrossfadeLength (tSampler* const, uint32_t length);
300 void tSampler_setRate (tSampler* const, float rate);299 void tSampler_setRate (tSampler* const, float rate);
300 void tSampler_setSampleRate (tSampler* const, float sr);
301 301
302 //==============================================================================302 //==============================================================================
303 303
@@ -388,7 +388,7 @@ extern "C" { · 84 unmodified lines
388 void tAutoSampler_setWindowSize (tAutoSampler* const, uint32_t size);388 void tAutoSampler_setWindowSize (tAutoSampler* const, uint32_t size);
389 void tAutoSampler_setCrossfadeLength (tAutoSampler* const, uint32_t length);389 void tAutoSampler_setCrossfadeLength (tAutoSampler* const, uint32_t length);
390 void tAutoSampler_setRate (tAutoSampler* const, float rate);390 void tAutoSampler_setRate (tAutoSampler* const, float rate);
391 391 void tAutoSampler_setSampleRate (tAutoSampler* const, float sr);
392 392
393 /*!393 /*!
394 @defgroup tmbsampler tMBSampler394 @defgroup tmbsampler tMBSampler
leaf/Src/leaf-analysis.c+75−39
@@ -360,25 +360,11 @@ void tAttackDetection_free (tAttackDetection* const ad) · 359 unmodified lines
360 mpool_free((char*)a, a->mempool);360 mpool_free((char*)a, a->mempool);
361}361}
362 362
363/*******Public Functions***********/
364
365
366void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)363void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)
367{364{
368 _tAttackDetection* a = *ad;365 _tAttackDetection* a = *ad;
369 366
370 a->blocksize = size;367 a->blockSize = size;
371}
372
373void tAttackDetection_setSamplerate(tAttackDetection* const ad, int inRate)
374{
375 _tAttackDetection* a = *ad;
376
377 a->samplerate = inRate;
378
379 //Reset atk and rel to recalculate coeff
380 tAttackDetection_setAttack(ad, a->atk);
381 tAttackDetection_setRelease(ad, a->rel);
382}368}
383 369
384void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)370void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
@@ -391,17 +377,16 @@ void tAttackDetection_setAttack(tAttackDetection* const ad, int inAtk) · 6 unmodified lines
391{377{
392 _tAttackDetection* a = *ad;378 _tAttackDetection* a = *ad;
393 a->atk = inAtk;379 a->atk = inAtk;
394 a->atk_coeff = powf(0.01f, 1.0f/(a->atk * a->samplerate * 0.001f));380 a->atk_coeff = powf(0.01f, 1.0f/(a->atk * a->sampleRate * 0.001f));
395}381}
396 382
397void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)383void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)
398{384{
399 _tAttackDetection* a = *ad;385 _tAttackDetection* a = *ad;
400 a->rel = inRel;386 a->rel = inRel;
401 a->rel_coeff = powf(0.01f, 1.0f/(a->rel * a->samplerate * 0.001f));387 a->rel_coeff = powf(0.01f, 1.0f/(a->rel * a->sampleRate * 0.001f));
402}388}
403 389
404
405int tAttackDetection_detect(tAttackDetection* const ad, float *in)390int tAttackDetection_detect(tAttackDetection* const ad, float *in)
406{391{
407 _tAttackDetection* a = *ad;392 _tAttackDetection* a = *ad;
@@ -420,6 +405,16 @@ int tAttackDetection_detect(tAttackDetection* const ad, float *in) · 12 unmodified lines
420 return result;405 return result;
421}406}
422 407
408void tAttackDetection_setSampleRate(tAttackDetection* const ad, float sr)
409{
410 _tAttackDetection* a = *ad;
411
412 a->sampleRate = sr;
413
414 tAttackDetection_setAttack(ad, a->atk);
415 tAttackDetection_setRelease(ad, a->rel);
416}
417
423/*******Private Functions**********/418/*******Private Functions**********/
424 419
425static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int rel)420static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
@@ -428,9 +423,9 @@ static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int · 2 unmodified lines
428 LEAF* leaf = a->mempool->leaf;423 LEAF* leaf = a->mempool->leaf;
429 424
430 a->env = 0;425 a->env = 0;
431 a->blocksize = blocksize;426 a->blockSize = blocksize;
432 a->threshold = DEFTHRESHOLD;427 a->threshold = DEFTHRESHOLD;
433 a->samplerate = leaf->sampleRate;428 a->sampleRate = leaf->sampleRate;
434 a->prevAmp = 0;429 a->prevAmp = 0;
435 430
436 a->env = 0;431 a->env = 0;
@@ -445,7 +440,7 @@ static void atkdtk_envelope(tAttackDetection* const ad, float *in) · 8 unmodified lines
445 440
446 int i = 0;441 int i = 0;
447 float tmp;442 float tmp;
448 for(i = 0; i < a->blocksize; ++i){443 for(i = 0; i < a->blockSize; ++i){
449 tmp = fastabsf(in[i]);444 tmp = fastabsf(in[i]);
450 445
451 if(tmp > a->env)446 if(tmp > a->env)
@@ -845,6 +840,7 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, int buf · 393 unmodified lines
845 p->mempool = m;840 p->mempool = m;
846 LEAF* leaf = p->mempool->leaf;841 LEAF* leaf = p->mempool->leaf;
847 842
843 p->invSampleRate = leaf->invSampleRate;
848 p->inBuffer = in;844 p->inBuffer = in;
849 p->bufSize = bufSize;845 p->bufSize = bufSize;
850 p->frameSize = frameSize;846 p->frameSize = frameSize;
@@ -865,7 +861,7 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, int buf · 14 unmodified lines
865 p->alpha = 1.0f;861 p->alpha = 1.0f;
866 p->tolerance = 1.0f;862 p->tolerance = 1.0f;
867 p->timeConstant = DEFTIMECONSTANT;863 p->timeConstant = DEFTIMECONSTANT;
868 p->radius = expf(-1000.0f * p->hopSize * leaf->invSampleRate / p->timeConstant);864 p->radius = expf(-1000.0f * p->hopSize * p->invSampleRate / p->timeConstant);
869 p->fidelityThreshold = 0.95f;865 p->fidelityThreshold = 0.95f;
870}866}
871 867
@@ -878,7 +874,7 @@ void tPeriodDetection_free (tPeriodDetection* const pd) · 6 unmodified lines
878 mpool_free((char*)p, p->mempool);874 mpool_free((char*)p, p->mempool);
879}875}
880 876
881float tPeriodDetection_tick (tPeriodDetection* pd, float sample)877float tPeriodDetection_tick (tPeriodDetection* const pd, float sample)
882{878{
883 _tPeriodDetection* p = *pd;879 _tPeriodDetection* p = *pd;
884 880
@@ -913,49 +909,57 @@ float tPeriodDetection_tick (tPeriodDetection* pd, float sample) · 28 unmodified lines
913 return p->period;909 return p->period;
914}910}
915 911
916float tPeriodDetection_getPeriod(tPeriodDetection* pd)912float tPeriodDetection_getPeriod(tPeriodDetection* const pd)
917{913{
918 _tPeriodDetection* p = *pd;914 _tPeriodDetection* p = *pd;
919 return p->period;915 return p->period;
920}916}
921 917
922float tPeriodDetection_getFidelity(tPeriodDetection* pd)918float tPeriodDetection_getFidelity(tPeriodDetection* const pd)
923{919{
924 _tPeriodDetection* p = *pd;920 _tPeriodDetection* p = *pd;
925 return tSNAC_getFidelity(&p->snac);921 return tSNAC_getFidelity(&p->snac);
926}922}
927 923
928void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)924void tPeriodDetection_setHopSize(tPeriodDetection* const pd, int hs)
929{925{
930 _tPeriodDetection* p = *pd;926 _tPeriodDetection* p = *pd;
931 p->hopSize = hs;927 p->hopSize = hs;
932}928}
933 929
934void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)930void tPeriodDetection_setWindowSize(tPeriodDetection* const pd, int ws)
935{931{
936 _tPeriodDetection* p = *pd;932 _tPeriodDetection* p = *pd;
937 p->windowSize = ws;933 p->windowSize = ws;
938}934}
939 935
940void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold)936void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const pd, float threshold)
941{937{
942 _tPeriodDetection* p = *pd;938 _tPeriodDetection* p = *pd;
943 p->fidelityThreshold = threshold;939 p->fidelityThreshold = threshold;
944}940}
945 941
946void tPeriodDetection_setAlpha (tPeriodDetection* pd, float alpha)942void tPeriodDetection_setAlpha (tPeriodDetection* const pd, float alpha)
947{943{
948 _tPeriodDetection* p = *pd;944 _tPeriodDetection* p = *pd;
949 p->alpha = LEAF_clip(0.0f, alpha, 1.0f);945 p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
950}946}
951 947
952void tPeriodDetection_setTolerance (tPeriodDetection* pd, float tolerance)948void tPeriodDetection_setTolerance (tPeriodDetection* const pd, float tolerance)
953{949{
954 _tPeriodDetection* p = *pd;950 _tPeriodDetection* p = *pd;
955 if (tolerance < 0.0f) p->tolerance = 0.0f;951 if (tolerance < 0.0f) p->tolerance = 0.0f;
956 else p->tolerance = tolerance;952 else p->tolerance = tolerance;
957}953}
958 954
955void tPeriodDetection_setSampleRate (tPeriodDetection* const pd, float sr)
956{
957 _tPeriodDetection* p = *pd;
958 p->invSampleRate = 1.0f/sr;
959 p->radius = expf(-1000.0f * p->hopSize * p->invSampleRate / p->timeConstant);
960}
961
962//==========================================================================================
959 963
960void tZeroCrossingInfo_init (tZeroCrossingInfo* const zc, LEAF* const leaf)964void tZeroCrossingInfo_init (tZeroCrossingInfo* const zc, LEAF* const leaf)
961{965{
@@ -1522,8 +1526,12 @@ void tPeriodDetector_initToPool (tPeriodDetector* const detector, float lowe · 560 unmodified lines
1522 1526
1523 LEAF* leaf = p->mempool->leaf;1527 LEAF* leaf = p->mempool->leaf;
1524 1528
1525 tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * leaf->sampleRate * 2.0f, hysteresis, mempool);1529 p->sampleRate = leaf->sampleRate;
1526 p->_min_period = (1.0f / highestFreq) * leaf->sampleRate;1530 p->lowestFreq = lowestFreq;
1531 p->highestFreq = highestFreq;
1532
1533 tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * p->sampleRate * 2.0f, hysteresis, mempool);
1534 p->_min_period = (1.0f / highestFreq) * p->sampleRate;
1527 p->_range = highestFreq / lowestFreq;1535 p->_range = highestFreq / lowestFreq;
1528 1536
1529 int windowSize = tZeroCrossingCollector_getWindowSize(&p->_zc);1537 int windowSize = tZeroCrossingCollector_getWindowSize(&p->_zc);
@@ -1670,6 +1678,18 @@ void tPeriodDetector_setHysteresis (tPeriodDetector* const detector, float · 140 unmodified lines
1670 return tZeroCrossingCollector_setHysteresis(&p->_zc, hysteresis);1678 return tZeroCrossingCollector_setHysteresis(&p->_zc, hysteresis);
1671}1679}
1672 1680
1681void tPeriodDetector_setSampleRate (tPeriodDetector* const detector, float sr)
1682{
1683 _tPeriodDetector* p = *detector;
1684 _tMempool* m = p->mempool;
1685 p->sampleRate = sr;
1686 float hysteresis = p->_zc->_hysteresis;
1687
1688 tZeroCrossingCollector_free(&p->_zc);
1689 tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / p->lowestFreq) * p->sampleRate * 2.0f, hysteresis, &m);
1690 p->_min_period = (1.0f / p->highestFreq) * p->sampleRate;
1691}
1692
1673static inline void set_bitstream(tPeriodDetector* const detector)1693static inline void set_bitstream(tPeriodDetector* const detector)
1674{1694{
1675 _tPeriodDetector* p = *detector;1695 _tPeriodDetector* p = *detector;
@@ -1901,11 +1921,13 @@ void tPitchDetector_initToPool (tPitchDetector* const detector, float lowes · 225 unmodified lines
1901 _tMempool* m = *mempool;1921 _tMempool* m = *mempool;
1902 _tPitchDetector* p = *detector = (_tPitchDetector*) mpool_alloc(sizeof(_tPitchDetector), m);1922 _tPitchDetector* p = *detector = (_tPitchDetector*) mpool_alloc(sizeof(_tPitchDetector), m);
1903 p->mempool = m;1923 p->mempool = m;
1924 LEAF* leaf = p->mempool->leaf;
1904 1925
1905 tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, -120.0f, mempool);1926 tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, -120.0f, mempool);
1906 p->_current.frequency = 0.0f;1927 p->_current.frequency = 0.0f;
1907 p->_current.periodicity = 0.0f;1928 p->_current.periodicity = 0.0f;
1908 p->_frames_after_shift = 0;1929 p->_frames_after_shift = 0;
1930 p->sampleRate = leaf->sampleRate;
1909}1931}
1910 1932
1911void tPitchDetector_free (tPitchDetector* const detector)1933void tPitchDetector_free (tPitchDetector* const detector)
@@ -1991,11 +2013,10 @@ float tPitchDetector_harmonic (tPitchDetector* const detector, int harmonicInd · 79 unmodified lines
1991float tPitchDetector_predictFrequency (tPitchDetector* const detector)2013float tPitchDetector_predictFrequency (tPitchDetector* const detector)
1992{2014{
1993 _tPitchDetector* p = *detector;2015 _tPitchDetector* p = *detector;
1994 LEAF* leaf = p->mempool->leaf;
1995 2016
1996 float period = tPeriodDetector_predictPeriod(&p->_pd);2017 float period = tPeriodDetector_predictPeriod(&p->_pd);
1997 if (period > 0.0f)2018 if (period > 0.0f)
1998 return leaf->sampleRate / period;2019 return p->sampleRate / period;
1999 return 0.0f;2020 return 0.0f;
2000}2021}
2001 2022
@@ -2009,18 +2030,23 @@ int tPitchDetector_indeterminate (tPitchDetector* const detector) · 7 unmodified lines
2009void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis)2030void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis)
2010{2031{
2011 _tPitchDetector* p = *detector;2032 _tPitchDetector* p = *detector;
2012
2013 tPeriodDetector_setHysteresis(&p->_pd, hysteresis);2033 tPeriodDetector_setHysteresis(&p->_pd, hysteresis);
2014}2034}
2015 2035
2036void tPitchDetector_setSampleRate (tPitchDetector* const detector, float sr)
2037{
2038 _tPitchDetector* p = *detector;
2039 p->sampleRate = sr;
2040 tPeriodDetector_setSampleRate(&p->_pd, p->sampleRate);
2041}
2042
2016static inline float calculate_frequency(tPitchDetector* const detector)2043static inline float calculate_frequency(tPitchDetector* const detector)
2017{2044{
2018 _tPitchDetector* p = *detector;2045 _tPitchDetector* p = *detector;
2019 LEAF* leaf = p->mempool->leaf;
2020 2046
2021 float period = p->_pd->_fundamental.period;2047 float period = p->_pd->_fundamental.period;
2022 if (period > 0.0f)2048 if (period > 0.0f)
2023 return leaf->sampleRate / period;2049 return p->sampleRate / period;
2024 return 0.0f;2050 return 0.0f;
2025}2051}
2026 2052
@@ -2131,9 +2157,12 @@ void tDualPitchDetector_initToPool (tDualPitchDetector* const detector, flo · 104 unmodified lines
2131 _tMempool* m = *mempool;2157 _tMempool* m = *mempool;
2132 _tDualPitchDetector* p = *detector = (_tDualPitchDetector*) mpool_alloc(sizeof(_tDualPitchDetector), m);2158 _tDualPitchDetector* p = *detector = (_tDualPitchDetector*) mpool_alloc(sizeof(_tDualPitchDetector), m);
2133 p->mempool = m;2159 p->mempool = m;
2160 LEAF* leaf = p->mempool->leaf;
2134 2161
2135 tPeriodDetection_initToPool(&p->_pd1, inBuffer, bufSize, bufSize / 2, mempool);2162 tPeriodDetection_initToPool(&p->_pd1, inBuffer, bufSize, bufSize / 2, mempool);
2136 tPitchDetector_initToPool(&p->_pd2, lowestFreq, highestFreq, mempool);2163 tPitchDetector_initToPool(&p->_pd2, lowestFreq, highestFreq, mempool);
2164
2165 p->sampleRate = leaf->sampleRate;
2137 2166
2138 p->_current.frequency = 0.0f;2167 p->_current.frequency = 0.0f;
2139 p->_current.periodicity = 0.0f;2168 p->_current.periodicity = 0.0f;
@@ -2159,7 +2188,6 @@ void tDualPitchDetector_free (tDualPitchDetector* const detector) · 19 unmodified lines
2159int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sample)2188int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sample)
2160{2189{
2161 _tDualPitchDetector* p = *detector;2190 _tDualPitchDetector* p = *detector;
2162 LEAF* leaf = p->mempool->leaf;
2163 2191
2164 tPeriodDetection_tick(&p->_pd1, sample);2192 tPeriodDetection_tick(&p->_pd1, sample);
2165 int ready = tPitchDetector_tick(&p->_pd2, sample);2193 int ready = tPitchDetector_tick(&p->_pd2, sample);
@@ -2172,7 +2200,7 @@ int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sa · 6 unmodified lines
2172 if (!pd2_indeterminate && period != 0.0f)2200 if (!pd2_indeterminate && period != 0.0f)
2173 {2201 {
2174 _pitch_info _i1;2202 _pitch_info _i1;
2175 _i1.frequency = leaf->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);2203 _i1.frequency = p->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);
2176 _i1.periodicity = tPeriodDetection_getFidelity(&p->_pd1);2204 _i1.periodicity = tPeriodDetection_getFidelity(&p->_pd1);
2177 _pitch_info _i2 = p->_pd2->_current;2205 _pitch_info _i2 = p->_pd2->_current;
2178 2206
@@ -2276,6 +2304,14 @@ void tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const de · 97 unmodified lines
2276 p->thresh = thresh;2304 p->thresh = thresh;
2277}2305}
2278 2306
2307void tDualPitchDetector_setSampleRate (tDualPitchDetector* const detector, float sr)
2308{
2309 _tDualPitchDetector* p = *detector;
2310 p->sampleRate = sr;
2311 tPeriodDetection_setSampleRate(&p->_pd1, p->sampleRate);
2312 tPitchDetector_setSampleRate(&p->_pd2, p->sampleRate);
2313}
2314
2279static inline void compute_predicted_frequency(tDualPitchDetector* const detector)2315static inline void compute_predicted_frequency(tDualPitchDetector* const detector)
2280{2316{
2281 _tDualPitchDetector* p = *detector;2317 _tDualPitchDetector* p = *detector;
leaf/Src/leaf-delay.c+0−3
@@ -346,9 +346,6 @@ float tLinearDelay_getGain (tLinearDelay* const dl) · 345 unmodified lines
346}346}
347 347
348 348
349
350
351
352/// Hermite Interpolated Delay349/// Hermite Interpolated Delay
353// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //350// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
354void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay, LEAF* const leaf)351void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay, LEAF* const leaf)
leaf/Src/leaf-distortion.c+19−1
@@ -90,6 +90,7 @@ void tOversampler_initToPool (tOversampler* const osr, int maxRatio, int extraQu · 89 unmodified lines
90 90
91 os->offset = offset;91 os->offset = offset;
92 os->maxRatio = maxRatio;92 os->maxRatio = maxRatio;
93 os->allowHighQuality = extraQuality;
93 os->ratio = os->maxRatio;94 os->ratio = os->maxRatio;
94 int idx = (int)(log2f(os->ratio))-1+os->offset;95 int idx = (int)(log2f(os->ratio))-1+os->offset;
95 os->numTaps = __leaf_tablesize_firNumTaps[idx];96 os->numTaps = __leaf_tablesize_firNumTaps[idx];
@@ -318,7 +319,7 @@ void tOversampler_setRatio (tOversampler* const osr, int ratio) · 222 unmodified lines
318 else if (ratio == 2 || ratio == 4 || ratio == 8 ||319 else if (ratio == 2 || ratio == 4 || ratio == 8 ||
319 ratio == 16 || ratio == 32 || ratio == 64)320 ratio == 16 || ratio == 32 || ratio == 64)
320 {321 {
321 os->ratio = os->ratio;322 os->ratio = ratio;
322 int idx = (int)(log2f(os->ratio))-1+os->offset;323 int idx = (int)(log2f(os->ratio))-1+os->offset;
323 os->numTaps = __leaf_tablesize_firNumTaps[idx];324 os->numTaps = __leaf_tablesize_firNumTaps[idx];
324 os->phaseLength = os->numTaps / os->ratio;325 os->phaseLength = os->numTaps / os->ratio;
@@ -326,6 +327,23 @@ void tOversampler_setRatio (tOversampler* const osr, int ratio) · 1 unmodified line
326 }327 }
327}328}
328 329
330void tOversampler_setQuality (tOversampler* const osr, int quality)
331{
332 _tOversampler* os = *osr;
333
334 if (!os->allowHighQuality) return;
335 int offset = 0;
336 if (quality > 0) offset = 6;
337 os->offset = offset;
338
339 if (os->ratio == 1) return;
340
341 int idx = (int)(log2f(os->ratio))-1+os->offset;
342 os->numTaps = __leaf_tablesize_firNumTaps[idx];
343 os->phaseLength = os->numTaps / os->ratio;
344 os->pCoeffs = (float*) __leaf_tableref_firCoeffs[idx];
345}
346
329int tOversampler_getLatency(tOversampler* const osr)347int tOversampler_getLatency(tOversampler* const osr)
330{348{
331 _tOversampler* os = *osr;349 _tOversampler* os = *osr;
leaf/Src/leaf-dynamics.c+5−3
@@ -51,6 +51,7 @@ void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp) · 50 unmodified lines
51 _tMempool* m = *mp;51 _tMempool* m = *mp;
52 _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m);52 _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m);
53 c->mempool = m;53 c->mempool = m;
54 LEAF* leaf = c->mempool->leaf;
54 55
55 c->tauAttack = 100;56 c->tauAttack = 100;
56 c->tauRelease = 100;57 c->tauRelease = 100;
@@ -61,6 +62,8 @@ void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp) · 4 unmodified lines
61 c->R = 0.5f; // compression Ratio62 c->R = 0.5f; // compression Ratio
62 c->M = 3.0f; // decibel Width of knee transition63 c->M = 3.0f; // decibel Width of knee transition
63 c->W = 1.0f; // decibel Make-up gain64 c->W = 1.0f; // decibel Make-up gain
65
66 c->sampleRate = leaf->sampleRate;
64}67}
65 68
66void tCompressor_free (tCompressor* const comp)69void tCompressor_free (tCompressor* const comp)
@@ -73,7 +76,6 @@ void tCompressor_free (tCompressor* const comp) · 6 unmodified lines
73float tCompressor_tick(tCompressor* const comp, float in)76float tCompressor_tick(tCompressor* const comp, float in)
74{77{
75 _tCompressor* c = *comp;78 _tCompressor* c = *comp;
76 LEAF* leaf = c->mempool->leaf;
77 79
78 float slope, overshoot;80 float slope, overshoot;
79 float alphaAtt, alphaRel;81 float alphaAtt, alphaRel;
@@ -107,8 +109,8 @@ float tCompressor_tick(tCompressor* const comp, float in) · 27 unmodified lines
107 109
108 c->x_T[0] = out_db - in_db;110 c->x_T[0] = out_db - in_db;
109 111
110 alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * leaf->sampleRate));112 alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * c->sampleRate));
111 alphaRel = expf(-1.0f/(0.001f * c->tauRelease * leaf->sampleRate));113 alphaRel = expf(-1.0f/(0.001f * c->tauRelease * c->sampleRate));
112 114
113 if (c->x_T[0] > c->y_T[1])115 if (c->x_T[0] > c->y_T[1])
114 c->y_T[0] = alphaAtt * c->y_T[1] + (1-alphaAtt) * c->x_T[0];116 c->y_T[0] = alphaAtt * c->y_T[1] + (1-alphaAtt) * c->x_T[0];
leaf/Src/leaf-effects.c+99−25
@@ -42,6 +42,7 @@ void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* const mp) · 41 unmodified lines
42 _tMempool* m = *mp;42 _tMempool* m = *mp;
43 _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m);43 _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m);
44 v->mempool = m;44 v->mempool = m;
45 LEAF* leaf = v->mempool->leaf;
45 46
46 v->param[0] = 0.5f; //wet47 v->param[0] = 0.5f; //wet
47 v->param[1] = 0.0f; //dry48 v->param[1] = 0.0f; //dry
@@ -62,6 +63,8 @@ void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* const mp) · 14 unmodified lines
62 v->Rt = (double*) mpool_alloc(sizeof(double) * v->bufsize, m);63 v->Rt = (double*) mpool_alloc(sizeof(double) * v->bufsize, m);
63 64
64 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);65 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
66
67 v->sampleRate = leaf->sampleRate;
65 68
66 tTalkbox_update(voc);69 tTalkbox_update(voc);
67 tTalkbox_suspend(voc);70 tTalkbox_suspend(voc);
@@ -86,9 +89,8 @@ void tTalkbox_free (tTalkbox* const voc) · 18 unmodified lines
86void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...89void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
87{90{
88 _tTalkbox* v = *voc;91 _tTalkbox* v = *voc;
89 LEAF* leaf = v->mempool->leaf;
90 92
91 float fs = leaf->sampleRate;93 float fs = v->sampleRate;
92// if(fs < 8000.0f) fs = 8000.0f;94// if(fs < 8000.0f) fs = 8000.0f;
93// if(fs > 96000.0f) fs = 96000.0f;95// if(fs > 96000.0f) fs = 96000.0f;
94 96
@@ -320,10 +322,9 @@ void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int · 225 unmodified lines
320void tTalkbox_setQuality(tTalkbox* const voc, float quality)322void tTalkbox_setQuality(tTalkbox* const voc, float quality)
321{323{
322 _tTalkbox* v = *voc;324 _tTalkbox* v = *voc;
323 LEAF* leaf = v->mempool->leaf;
324 325
325 v->param[3] = quality;326 v->param[3] = quality;
326 v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf->sampleRate);327 v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * v->sampleRate);
327 if (v->O >= ORD_MAX)328 if (v->O >= ORD_MAX)
328 {329 {
329 v->O = ORD_MAX-1;330 v->O = ORD_MAX-1;
@@ -351,7 +352,12 @@ void tTalkbox_setFreeze(tTalkbox* const voc, float freeze) · 21 unmodified lines
351 v->freeze = freeze;352 v->freeze = freeze;
352}353}
353 354
354 355void tTalkbox_setSampleRate(tTalkbox* const voc, float sr)
356{
357 _tTalkbox* v = *voc;
358 v->sampleRate = sr;
359 tTalkbox_update(voc);
360}
355 361
356////362////
357 363
@@ -374,6 +380,7 @@ void tTalkboxFloat_initToPool (tTalkboxFloat* const voc, int bufsize, tMempool* · 16 unmodified lines
374 _tMempool* m = *mp;380 _tMempool* m = *mp;
375 _tTalkboxFloat* v = *voc = (_tTalkboxFloat*) mpool_alloc(sizeof(_tTalkboxFloat), m);381 _tTalkboxFloat* v = *voc = (_tTalkboxFloat*) mpool_alloc(sizeof(_tTalkboxFloat), m);
376 v->mempool = m;382 v->mempool = m;
383 LEAF* leaf = v->mempool->leaf;
377 384
378 v->param[0] = 0.5f; //wet385 v->param[0] = 0.5f; //wet
379 v->param[1] = 0.0f; //dry386 v->param[1] = 0.0f; //dry
@@ -394,6 +401,8 @@ void tTalkboxFloat_initToPool (tTalkboxFloat* const voc, int bufsize, tMempool* · 14 unmodified lines
394 v->Rt = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);401 v->Rt = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
395 402
396 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);403 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
404
405 v->sampleRate = leaf->sampleRate;
397 406
398 tTalkboxFloat_update(voc);407 tTalkboxFloat_update(voc);
399 tTalkboxFloat_suspend(voc);408 tTalkboxFloat_suspend(voc);
@@ -418,9 +427,8 @@ void tTalkboxFloat_free (tTalkboxFloat* const voc) · 18 unmodified lines
418void tTalkboxFloat_update(tTalkboxFloat* const voc) ///update internal parameters...427void tTalkboxFloat_update(tTalkboxFloat* const voc) ///update internal parameters...
419{428{
420 _tTalkboxFloat* v = *voc;429 _tTalkboxFloat* v = *voc;
421 LEAF* leaf = v->mempool->leaf;
422 430
423 float fs = leaf->sampleRate;431 float fs = v->sampleRate;
424// if(fs < 8000.0f) fs = 8000.0f;432// if(fs < 8000.0f) fs = 8000.0f;
425// if(fs > 96000.0f) fs = 96000.0f;433// if(fs > 96000.0f) fs = 96000.0f;
426 434
@@ -656,10 +664,9 @@ void tTalkboxFloat_lpc(float *buf, float *car, float* dl, float* Rt, int32_t n, · 229 unmodified lines
656void tTalkboxFloat_setQuality(tTalkboxFloat* const voc, float quality)664void tTalkboxFloat_setQuality(tTalkboxFloat* const voc, float quality)
657{665{
658 _tTalkboxFloat* v = *voc;666 _tTalkboxFloat* v = *voc;
659 LEAF* leaf = v->mempool->leaf;
660 667
661 v->param[3] = quality;668 v->param[3] = quality;
662 v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf->sampleRate);669 v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * v->sampleRate);
663 if (v->O >= ORD_MAX)670 if (v->O >= ORD_MAX)
664 {671 {
665 v->O = ORD_MAX-1;672 v->O = ORD_MAX-1;
@@ -687,6 +694,12 @@ void tTalkboxFloat_setFreeze(tTalkboxFloat* const voc, int freeze) · 21 unmodified lines
687 v->freeze = freeze;694 v->freeze = freeze;
688}695}
689 696
697void tTalkboxFloat_setSampleRate(tTalkboxFloat* const voc, float sr)
698{
699 _tTalkboxFloat* v = *voc;
700 v->sampleRate = sr;
701 tTalkboxFloat_update(voc);
702}
690 703
691//============================================================================================================704//============================================================================================================
692// VOCODER705// VOCODER
@@ -702,6 +715,9 @@ void tVocoder_initToPool (tVocoder* const voc, tMempool* const mp) · 9 unmodified lines
702 _tMempool* m = *mp;715 _tMempool* m = *mp;
703 _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m);716 _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m);
704 v->mempool = m;717 v->mempool = m;
718 LEAF* leaf = v->mempool->leaf;
719
720 v->invSampleRate = leaf->invSampleRate;
705 721
706 v->param[0] = 0.33f; //input select722 v->param[0] = 0.33f; //input select
707 v->param[1] = 0.50f; //output dB723 v->param[1] = 0.50f; //output dB
@@ -725,9 +741,8 @@ void tVocoder_free (tVocoder* const voc) · 17 unmodified lines
725void tVocoder_update (tVocoder* const voc)741void tVocoder_update (tVocoder* const voc)
726{742{
727 _tVocoder* v = *voc;743 _tVocoder* v = *voc;
728 LEAF* leaf = v->mempool->leaf;
729 744
730 float tpofs = 6.2831853f * leaf->invSampleRate;745 float tpofs = 6.2831853f * v->invSampleRate;
731 746
732 float rr, th;747 float rr, th;
733 748
@@ -871,7 +886,6 @@ float tVocoder_tick (tVocoder* const voc, float synth, float voice) · 137 unmodified lines
871 if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability886 if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability
872 887
873 return o;888 return o;
874
875}889}
876 890
877void tVocoder_suspend (tVocoder* const voc)891void tVocoder_suspend (tVocoder* const voc)
@@ -885,6 +899,13 @@ void tVocoder_suspend (tVocoder* const voc) · 7 unmodified lines
885 v->kval = 0;899 v->kval = 0;
886}900}
887 901
902void tVocoder_setSampleRate (tVocoder* const voc, float sr)
903{
904 _tVocoder* v = *voc;
905 v->invSampleRate = 1.0f/sr;
906 tVocoder_update(voc);
907}
908
888 909
889/// Glottal Pulse (Rosenberg model)910/// Glottal Pulse (Rosenberg model)
890 911
@@ -898,6 +919,9 @@ void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const gp, tMempo · 7 unmodified lines
898 _tMempool* m = *mp;919 _tMempool* m = *mp;
899 _tRosenbergGlottalPulse* g = *gp = (_tRosenbergGlottalPulse*) mpool_alloc(sizeof(_tRosenbergGlottalPulse), m);920 _tRosenbergGlottalPulse* g = *gp = (_tRosenbergGlottalPulse*) mpool_alloc(sizeof(_tRosenbergGlottalPulse), m);
900 g->mempool = m;921 g->mempool = m;
922 LEAF* leaf = g->mempool->leaf;
923
924 g->invSampleRate = leaf->invSampleRate;
901 925
902 g->phase = 0.0f;926 g->phase = 0.0f;
903 g->openLength = 0.0f;927 g->openLength = 0.0f;
@@ -972,10 +996,9 @@ float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const g · 68 unmodified lines
972void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const gp, float freq)996void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const gp, float freq)
973{997{
974 _tRosenbergGlottalPulse* g = *gp;998 _tRosenbergGlottalPulse* g = *gp;
975 LEAF* leaf = g->mempool->leaf;
976 999
977 g->freq = freq;1000 g->freq = freq;
978 g->inc = freq * leaf->invSampleRate;1001 g->inc = freq * g->invSampleRate;
979 g->inc -= (int) g->inc;1002 g->inc -= (int) g->inc;
980}1003}
981 1004
@@ -1001,6 +1024,12 @@ void tRosenbergGlottalPulse_setOpenLengthAndPulseLength (tRosenbergG · 19 unmodified lines
1001 g->invPulseLengthMinusOpenLength = 1.0f / (g->pulseLength - g->openLength);1024 g->invPulseLengthMinusOpenLength = 1.0f / (g->pulseLength - g->openLength);
1002}1025}
1003 1026
1027void tRosenbergGlottalPulse_setSampleRate(tRosenbergGlottalPulse* const gp, float sr)
1028{
1029 _tRosenbergGlottalPulse* g = *gp;
1030 g->invSampleRate = 1.0f/sr;
1031 tRosenbergGlottalPulse_setFreq(gp, g->freq);
1032}
1004 1033
1005 1034
1006//============================================================================================================1035//============================================================================================================
@@ -1140,6 +1169,13 @@ void tSOLAD_resetState(tSOLAD* const wp) · 133 unmodified lines
1140 w->blocksize = INITPERIOD;1169 w->blocksize = INITPERIOD;
1141}1170}
1142 1171
1172void tSOLAD_setSampleRate(tSOLAD* const wp, float sr)
1173{
1174 _tSOLAD* w = *wp;
1175 tAttackDetection_setSampleRate(&w->ad, sr);
1176 tHighpass_setSampleRate(&w->hp, sr);
1177}
1178
1143/******************************************************************************/1179/******************************************************************************/
1144/******************** private procedures **************************************/1180/******************** private procedures **************************************/
1145/******************************************************************************/1181/******************************************************************************/
@@ -1380,11 +1416,14 @@ void tPitchShift_initToPool (tPitchShift* const psr, tDualPitchDetector* const d · 234 unmodified lines
1380 _tMempool* m = *mp;1416 _tMempool* m = *mp;
1381 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m);1417 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m);
1382 ps->mempool = m;1418 ps->mempool = m;
1419 LEAF* leaf = ps->mempool->leaf;
1383 1420
1384 ps->pd = *dpd;1421 ps->pd = *dpd;
1385 ps->bufSize = bufSize;1422 ps->bufSize = bufSize;
1386 ps->pickiness = 0.0f;1423 ps->pickiness = 0.0f;
1387 1424
1425 ps->sampleRate = leaf->sampleRate;
1426
1388 tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp);1427 tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp);
1389 tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);1428 tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
1390}1429}
@@ -1400,13 +1439,12 @@ void tPitchShift_free (tPitchShift* const psr) · 9 unmodified lines
1400void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out)1439void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out)
1401{1440{
1402 _tPitchShift* ps = *psr;1441 _tPitchShift* ps = *psr;
1403 LEAF* leaf = ps->mempool->leaf;
1404 1442
1405 float detected = tDualPitchDetector_getFrequency(&ps->pd);1443 float detected = tDualPitchDetector_getFrequency(&ps->pd);
1406 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);1444 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
1407 if (detected > 0.0f && periodicity > ps->pickiness)1445 if (detected > 0.0f && periodicity > ps->pickiness)
1408 {1446 {
1409 float period = leaf->sampleRate / detected;1447 float period = ps->sampleRate / detected;
1410 tSOLAD_setPeriod(&ps->sola, period);1448 tSOLAD_setPeriod(&ps->sola, period);
1411 tSOLAD_setPitchFactor(&ps->sola, factor);1449 tSOLAD_setPitchFactor(&ps->sola, factor);
1412 }1450 }
@@ -1417,7 +1455,6 @@ void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float · 4 unmodified lines
1417void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out)1455void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out)
1418{1456{
1419 _tPitchShift* ps = *psr;1457 _tPitchShift* ps = *psr;
1420 LEAF* leaf = ps->mempool->leaf;
1421 1458
1422 float detected = tDualPitchDetector_getFrequency(&ps->pd);1459 float detected = tDualPitchDetector_getFrequency(&ps->pd);
1423 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);1460 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
@@ -1425,7 +1462,7 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 1 unmodified line
1425 {1462 {
1426 float period = 1.0f / detected;1463 float period = 1.0f / detected;
1427 float factor = freq * period;1464 float factor = freq * period;
1428 tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);1465 tSOLAD_setPeriod(&ps->sola, ps->sampleRate * period);
1429 tSOLAD_setPitchFactor(&ps->sola, factor);1466 tSOLAD_setPitchFactor(&ps->sola, factor);
1430 }1467 }
1431 1468
@@ -1435,10 +1472,15 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 3 unmodified lines
1435void tPitchShift_setPickiness (tPitchShift* const psr, float p)1472void tPitchShift_setPickiness (tPitchShift* const psr, float p)
1436{1473{
1437 _tPitchShift* ps = *psr;1474 _tPitchShift* ps = *psr;
1438
1439 ps->pickiness = p;1475 ps->pickiness = p;
1440}1476}
1441 1477
1478void tPitchShift_setSampleRate(tPitchShift* const psr, float sr)
1479{
1480 _tPitchShift* ps = *psr;
1481 tSOLAD_setSampleRate(&ps->sola, sr);
1482}
1483
1442 1484
1443//============================================================================================================1485//============================================================================================================
1444// SIMPLERETUNE1486// SIMPLERETUNE
@@ -1571,6 +1613,16 @@ float tSimpleRetune_getInputFrequency (tSimpleRetune* const rt) · 126 unmodified lines
1571 return tDualPitchDetector_getFrequency(&r->dp);1613 return tDualPitchDetector_getFrequency(&r->dp);
1572}1614}
1573 1615
1616void tSimpleRetune_setSampleRate (tSimpleRetune* const rt, float sr)
1617{
1618 _tSimpleRetune* r = *rt;
1619 tDualPitchDetector_setSampleRate(&r->dp, sr);
1620 for (int i = 0; i < r->numVoices; ++i)
1621 {
1622 tPitchShift_setSampleRate(&r->ps[i], sr);
1623 }
1624}
1625
1574//============================================================================================================1626//============================================================================================================
1575// RETUNE1627// RETUNE
1576//============================================================================================================1628//============================================================================================================
@@ -1708,6 +1760,16 @@ float tRetune_getInputFrequency (tRetune* const rt) · 131 unmodified lines
1708 return tDualPitchDetector_getFrequency(&r->dp);1760 return tDualPitchDetector_getFrequency(&r->dp);
1709}1761}
1710 1762
1763void tRetune_setSampleRate(tRetune* const rt, float sr)
1764{
1765 _tRetune* r = *rt;
1766 tDualPitchDetector_setSampleRate(&r->dp, sr);
1767 for (int i = 0; i < r->numVoices; ++i)
1768 {
1769 tPitchShift_setSampleRate(&r->ps[i], sr);
1770 }
1771}
1772
1711//============================================================================================================1773//============================================================================================================
1712// FORMANTSHIFTER1774// FORMANTSHIFTER
1713//============================================================================================================1775//============================================================================================================
@@ -1738,14 +1800,16 @@ void tFormantShifter_initToPool (tFormantShifter* const fsr, int order, tMempool · 24 unmodified lines
1738 1800
1739 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);1801 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
1740 1802
1803 fs->sampleRate = leaf->sampleRate;
1804 fs->invSampleRate = leaf->invSampleRate;
1741 1805
1742 fs->falph = powf(0.001f, 10.0f * leaf->invSampleRate);1806 fs->falph = powf(0.001f, 10.0f * fs->invSampleRate);
1743 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * leaf->sampleRate)) - 0.1916f);1807 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * fs->sampleRate)) - 0.1916f);
1744 fs->fhp = 0.0f;1808 fs->fhp = 0.0f;
1745 fs->flp = 0.0f;1809 fs->flp = 0.0f;
1746 fs->flpa = powf(0.001f, 10.0f * leaf->invSampleRate);1810 fs->flpa = powf(0.001f, 10.0f * fs->invSampleRate);
1747 fs->fmute = 1.0f;1811 fs->fmute = 1.0f;
1748 fs->fmutealph = powf(0.001f, 1.0f * leaf->invSampleRate);1812 fs->fmutealph = powf(0.001f, 1.0f * fs->invSampleRate);
1749 fs->cbi = 0;1813 fs->cbi = 0;
1750 fs->intensity = 1.0f;1814 fs->intensity = 1.0f;
1751 fs->invIntensity = 1.0f;1815 fs->invIntensity = 1.0f;
@@ -1927,8 +1991,6 @@ void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity) · 175 unmodified lines
1927{1991{
1928 _tFormantShifter* fs = *fsr;1992 _tFormantShifter* fs = *fsr;
1929 1993
1930
1931
1932 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);1994 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
1933 1995
1934 // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);1996 // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
@@ -1942,5 +2004,17 @@ void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity) · 7 unmodified lines
1942 {2004 {
1943 fs->invIntensity = 1.0f;2005 fs->invIntensity = 1.0f;
1944 }2006 }
2007}
1945 2008
2009void tFormantShifter_setSampleRate(tFormantShifter* const fsr, float sr)
2010{
2011 _tFormantShifter* fs = *fsr;
2012 fs->sampleRate = sr;
2013 fs->invSampleRate = 1.0f/fs->sampleRate;
2014 fs->falph = powf(0.001f, 10.0f * fs->invSampleRate);
2015 fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * fs->sampleRate)) - 0.1916f);
2016 fs->flpa = powf(0.001f, 10.0f * fs->invSampleRate);
2017 fs->fmutealph = powf(0.001f, 1.0f * fs->invSampleRate);
2018 tHighpass_setSampleRate(&fs->hp, fs->sampleRate);
2019 tHighpass_setSampleRate(&fs->hp2, fs->sampleRate);
1946}2020}
leaf/Src/leaf-electrical.c+10−0
@@ -222,6 +222,16 @@ void tWDF_setSampleRate(tWDF* const wdf, float sample_rate) · 221 unmodified lines
222{222{
223 _tWDF* r = *wdf;223 _tWDF* r = *wdf;
224 r->sample_rate = sample_rate;224 r->sample_rate = sample_rate;
225 if (r->type == Capacitor)
226 {
227 r->port_conductance_up = r->sample_rate * 2.0f * r->value;
228 r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
229 }
230 else if (r->type == Inductor)
231 {
232 r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
233 r->port_conductance_up = 1.0f / r->port_resistance_up;
234 }
225}235}
226 236
227uint8_t tWDF_isLeaf(tWDF* const wdf)237uint8_t tWDF_isLeaf(tWDF* const wdf)
leaf/Src/leaf-envelopes.c+48−18
@@ -118,7 +118,6 @@ void tEnvelope_loop(tEnvelope* const envlp, int loop) · 117 unmodified lines
118 env->loop = loop;118 env->loop = loop;
119}119}
120 120
121
122void tEnvelope_on(tEnvelope* const envlp, float velocity)121void tEnvelope_on(tEnvelope* const envlp, float velocity)
123{122{
124 _tEnvelope* env = *envlp;123 _tEnvelope* env = *envlp;
@@ -495,7 +494,6 @@ float calcADSR3Coef(float rate, float targetRatio) · 370 unmodified lines
495 return (rate <= 0.0f) ? 0.0f : expf(-logf((1.0f + targetRatio) / targetRatio) / rate);494 return (rate <= 0.0f) ? 0.0f : expf(-logf((1.0f + targetRatio) / targetRatio) / rate);
496}495}
497 496
498
499void tADSRS_init(tADSRS* const adsrenv, float attack, float decay, float sustain, float release, LEAF* const leaf)497void tADSRS_init(tADSRS* const adsrenv, float attack, float decay, float sustain, float release, LEAF* const leaf)
500{498{
501 tADSRS_initToPool(adsrenv, attack, decay, sustain, release, &leaf->mempool);499 tADSRS_initToPool(adsrenv, attack, decay, sustain, release, &leaf->mempool);
@@ -509,13 +507,16 @@ void tADSRS_initToPool (tADSRS* const adsrenv, float attack, float decay, · 7 unmodified lines
509 507
510 LEAF* leaf = adsr->mempool->leaf;508 LEAF* leaf = adsr->mempool->leaf;
511 509
512 adsr->sampleRateInMs = leaf->sampleRate * 0.001f;510 adsr->sampleRate = leaf->sampleRate;
511 adsr->sampleRateInMs = adsr->sampleRate * 0.001f;
513 adsr->targetRatioA = 0.3f;512 adsr->targetRatioA = 0.3f;
514 adsr->targetRatioDR = 0.0001f;513 adsr->targetRatioDR = 0.0001f;
514 adsr->attack = attack;
515 adsr->attackRate = attack * adsr->sampleRateInMs;515 adsr->attackRate = attack * adsr->sampleRateInMs;
516 adsr->attackCoef = calcADSR3Coef(attack * adsr->sampleRateInMs, adsr->targetRatioA);516 adsr->attackCoef = calcADSR3Coef(attack * adsr->sampleRateInMs, adsr->targetRatioA);
517 adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);517 adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
518 518
519 adsr->decay = decay;
519 adsr->decayRate = decay * adsr->sampleRateInMs;520 adsr->decayRate = decay * adsr->sampleRateInMs;
520 adsr->decayCoef = calcADSR3Coef(decay * adsr->sampleRateInMs,adsr-> targetRatioDR);521 adsr->decayCoef = calcADSR3Coef(decay * adsr->sampleRateInMs,adsr-> targetRatioDR);
521 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);522 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
@@ -523,6 +524,7 @@ void tADSRS_initToPool (tADSRS* const adsrenv, float attack, float decay, · 1 unmodified line
523 adsr->sustainLevel = sustain;524 adsr->sustainLevel = sustain;
524 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);525 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
525 526
527 adsr->release = release;
526 adsr->releaseRate = release * adsr->sampleRateInMs;528 adsr->releaseRate = release * adsr->sampleRateInMs;
527 adsr->releaseCoef = calcADSR3Coef(release * adsr->sampleRateInMs, adsr->targetRatioDR);529 adsr->releaseCoef = calcADSR3Coef(release * adsr->sampleRateInMs, adsr->targetRatioDR);
528 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);530 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -546,6 +548,7 @@ void tADSRS_setAttack(tADSRS* const adsrenv, float attack) · 17 unmodified lines
546{548{
547 _tADSRS* adsr = *adsrenv;549 _tADSRS* adsr = *adsrenv;
548 550
551 adsr->attack = attack;
549 adsr->attackRate = attack * adsr->sampleRateInMs;552 adsr->attackRate = attack * adsr->sampleRateInMs;
550 adsr->attackCoef = calcADSR3Coef(adsr->attackRate, adsr->targetRatioA);553 adsr->attackCoef = calcADSR3Coef(adsr->attackRate, adsr->targetRatioA);
551 adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);554 adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
@@ -555,6 +558,7 @@ void tADSRS_setDecay(tADSRS* const adsrenv, float decay) · 3 unmodified lines
555{558{
556 _tADSRS* adsr = *adsrenv;559 _tADSRS* adsr = *adsrenv;
557 560
561 adsr->decay = decay;
558 adsr->decayRate = decay * adsr->sampleRateInMs;562 adsr->decayRate = decay * adsr->sampleRateInMs;
559 adsr->decayCoef = calcADSR3Coef(adsr->decayRate,adsr-> targetRatioDR);563 adsr->decayCoef = calcADSR3Coef(adsr->decayRate,adsr-> targetRatioDR);
560 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);564 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
@@ -572,6 +576,7 @@ void tADSRS_setRelease(tADSRS* const adsrenv, float release) · 11 unmodified lines
572{576{
573 _tADSRS* adsr = *adsrenv;577 _tADSRS* adsr = *adsrenv;
574 578
579 adsr->release = release;
575 adsr->releaseRate = release * adsr->sampleRateInMs;580 adsr->releaseRate = release * adsr->sampleRateInMs;
576 adsr->releaseCoef = calcADSR3Coef(adsr->releaseRate, (float)adsr->targetRatioDR);581 adsr->releaseCoef = calcADSR3Coef(adsr->releaseRate, (float)adsr->targetRatioDR);
577 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);582 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -581,7 +586,6 @@ void tADSRS_setRelease(tADSRS* const adsrenv, float release) · 3 unmodified lines
581void tADSRS_setLeakFactor(tADSRS* const adsrenv, float leakFactor)586void tADSRS_setLeakFactor(tADSRS* const adsrenv, float leakFactor)
582{587{
583 _tADSRS* adsr = *adsrenv;588 _tADSRS* adsr = *adsrenv;
584
585 adsr->leakFactor = leakFactor;589 adsr->leakFactor = leakFactor;
586}590}
587 591
@@ -606,7 +610,6 @@ float tADSRS_tick(tADSRS* const adsrenv) · 18 unmodified lines
606{610{
607 _tADSRS* adsr = *adsrenv;611 _tADSRS* adsr = *adsrenv;
608 612
609
610 switch (adsr->state) {613 switch (adsr->state) {
611 case env_idle:614 case env_idle:
612 break;615 break;
@@ -641,6 +644,19 @@ float tADSRS_tick(tADSRS* const adsrenv) · 28 unmodified lines
641 return adsr->output * adsr->gain;644 return adsr->output * adsr->gain;
642}645}
643 646
647void tADSRS_setSampleRate(tADSRS* const adsrenv, float sr)
648{
649 _tADSRS* adsr = *adsrenv;
650
651 adsr->sampleRate = sr;
652 adsr->sampleRateInMs = adsr->sampleRate * 0.001f;
653
654 tADSRS_setAttack(adsrenv, adsr->attack);
655 tADSRS_setDecay(adsrenv, adsr->decay);
656 tADSRS_setRelease(adsrenv, adsr->release);
657}
658
659//================================================================================
644 660
645/* ADSR 4 */ // new version of our original table-based ADSR but with the table passed in by the user661/* ADSR 4 */ // new version of our original table-based ADSR but with the table passed in by the user
646// use this if the size of the big ADSR tables is too much.662// use this if the size of the big ADSR tables is too much.
@@ -663,7 +679,8 @@ void tADSRT_initToPool (tADSRT* const adsrenv, float attack, float decay, · 16 unmodified lines
663 adsr->buff_size = bufferSize;679 adsr->buff_size = bufferSize;
664 adsr->buff_sizeMinusOne = bufferSize - 1;680 adsr->buff_sizeMinusOne = bufferSize - 1;
665 681
666 adsr->bufferSizeDividedBySampleRateInMs = bufferSize / (leaf->sampleRate * 0.001f);682 adsr->sampleRate = leaf->sampleRate;
683 adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
667 684
668 if (attack < 0.0f)685 if (attack < 0.0f)
669 attack = 0.0f;686 attack = 0.0f;
@@ -685,6 +702,9 @@ void tADSRT_initToPool (tADSRT* const adsrenv, float attack, float decay, · 15 unmodified lines
685 702
686 adsr->sustain = sustain;703 adsr->sustain = sustain;
687 704
705 adsr->attack = attack;
706 adsr->decay = decay;
707 adsr->release = release;
688 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;708 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
689 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;709 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
690 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;710 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
@@ -707,7 +727,7 @@ void tADSRT_setAttack(tADSRT* const adsrenv, float attack) · 16 unmodified lines
707 {727 {
708 attack = 0.0f;728 attack = 0.0f;
709 }729 }
710 730 adsr->attack = attack;
711 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;731 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
712}732}
713 733
@@ -719,6 +739,7 @@ void tADSRT_setDecay(tADSRT* const adsrenv, float decay) · 5 unmodified lines
719 {739 {
720 decay = 0.0f;740 decay = 0.0f;
721 }741 }
742 adsr->decay = decay;
722 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;743 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
723}744}
724 745
@@ -739,6 +760,7 @@ void tADSRT_setRelease(tADSRT* const adsrenv, float release) · 14 unmodified lines
739 {760 {
740 release = 0.0f;761 release = 0.0f;
741 }762 }
763 adsr->release = release;
742 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;764 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
743}765}
744 766
@@ -988,7 +1010,17 @@ float tADSRT_tickNoInterp(tADSRT* const adsrenv) · 243 unmodified lines
988 return adsr->next;1010 return adsr->next;
989}1011}
990 1012
991 1013void tADSRT_setSampleRate (tADSRT* const adsrenv, float sr)
1014{
1015 _tADSRT* adsr = *adsrenv;
1016
1017 adsr->sampleRate = sr;
1018 adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
1019 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->attack;
1020 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->decay;
1021 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->release;
1022 adsr->rampInc = adsr->bufferSizeDividedBySampleRateInMs / 8.0f;
1023}
992 1024
993/////-----------------1025/////-----------------
994/* Ramp */1026/* Ramp */
@@ -1005,7 +1037,8 @@ void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, t · 10 unmodified lines
1005 1037
1006 LEAF* leaf = ramp->mempool->leaf;1038 LEAF* leaf = ramp->mempool->leaf;
1007 1039
1008 ramp->inv_sr_ms = 1.0f/(leaf->sampleRate*0.001f);1040 ramp->sampleRate = leaf->sampleRate;
1041 ramp->inv_sr_ms = 1.0f/(ramp->sampleRate*0.001f);
1009 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;1042 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
1010 ramp->curr = 0.0f;1043 ramp->curr = 0.0f;
1011 ramp->dest = 0.0f;1044 ramp->dest = 0.0f;
@@ -1026,7 +1059,6 @@ void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, t · 14 unmodified lines
1026void tRamp_free (tRamp* const r)1059void tRamp_free (tRamp* const r)
1027{1060{
1028 _tRamp* ramp = *r;1061 _tRamp* ramp = *r;
1029
1030 mpool_free((char*)ramp, ramp->mempool);1062 mpool_free((char*)ramp, ramp->mempool);
1031}1063}
1032 1064
@@ -1082,17 +1114,17 @@ float tRamp_sample(tRamp* const ramp) · 49 unmodified lines
1082 return r->curr;1114 return r->curr;
1083}1115}
1084 1116
1085void tRampSampleRateChanged(tRamp* const ramp)1117void tRamp_setSampleRate(tRamp* const ramp, float sr)
1086{1118{
1087 _tRamp* r = *ramp;1119 _tRamp* r = *ramp;
1088 LEAF* leaf = r->mempool->leaf;
1089 1120
1090 r->inv_sr_ms = 1.0f / (leaf->sampleRate * 0.001f);1121 r->sampleRate = sr;
1122 r->inv_sr_ms = 1.0f / (r->sampleRate * 0.001f);
1091 r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;1123 r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;
1092 r->inc = (r->dest - r->curr) * r->factor;1124 r->inc = (r->dest - r->curr) * r->factor;
1093}1125}
1094 1126
1095 1127//===========================================================================================
1096 1128
1097/* RampUpDown */1129/* RampUpDown */
1098void tRampUpDown_init(tRampUpDown* const r, float upTime, float downTime, int samples_per_tick, LEAF* const leaf)1130void tRampUpDown_init(tRampUpDown* const r, float upTime, float downTime, int samples_per_tick, LEAF* const leaf)
@@ -1108,7 +1140,8 @@ void tRampUpDown_initToPool(tRampUpDown* const r, float upTime, float downTim · 9 unmodified lines
1108 1140
1109 LEAF* leaf = ramp->mempool->leaf;1141 LEAF* leaf = ramp->mempool->leaf;
1110 1142
1111 ramp->inv_sr_ms = 1.0f/(leaf->sampleRate*0.001f);1143 ramp->sampleRate = leaf->sampleRate;
1144 ramp->inv_sr_ms = 1.0f/(ramp->sampleRate*0.001f);
1112 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;1145 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
1113 ramp->curr = 0.0f;1146 ramp->curr = 0.0f;
1114 ramp->dest = 0.0f;1147 ramp->dest = 0.0f;
@@ -1139,7 +1172,6 @@ void tRampUpDown_initToPool(tRampUpDown* const r, float upTime, float downTim · 24 unmodified lines
1139void tRampUpDown_free (tRampUpDown* const r)1172void tRampUpDown_free (tRampUpDown* const r)
1140{1173{
1141 _tRampUpDown* ramp = *r;1174 _tRampUpDown* ramp = *r;
1142
1143 mpool_free((char*)ramp, ramp->mempool);1175 mpool_free((char*)ramp, ramp->mempool);
1144}1176}
1145 1177
@@ -1258,7 +1290,6 @@ void tExpSmooth_initToPool (tExpSmooth* const expsmooth, float val, float f · 112 unmodified lines
1258void tExpSmooth_free (tExpSmooth* const expsmooth)1290void tExpSmooth_free (tExpSmooth* const expsmooth)
1259{1291{
1260 _tExpSmooth* smooth = *expsmooth;1292 _tExpSmooth* smooth = *expsmooth;
1261
1262 mpool_free((char*)smooth, smooth->mempool);1293 mpool_free((char*)smooth, smooth->mempool);
1263}1294}
1264 1295
@@ -1340,7 +1371,6 @@ void tSlide_initToPool (tSlide* const sl, float upSlide, float downSlide, · 75 unmodified lines
1340void tSlide_free (tSlide* const sl)1371void tSlide_free (tSlide* const sl)
1341{1372{
1342 _tSlide* s = *sl;1373 _tSlide* s = *sl;
1343
1344 mpool_free((char*)s, s->mempool);1374 mpool_free((char*)s, s->mempool);
1345}1375}
1346 1376
leaf/Src/leaf-filters.c+253−244
@@ -1,10 +1,10 @@
1/*==============================================================================1/*==============================================================================
2 2
3 leaf-filter.c3 leaf-filter.c
4 Created: 20 Jan 2017 12:01:10pm4 Created: 20 Jan 2017 12:01:10pm
5 Author: Michael R Mulshine5 Author: Michael R Mulshine
6 6
7==============================================================================*/7 ==============================================================================*/
8 8
9#if _WIN32 || _WIN649#if _WIN32 || _WIN64
10 10
@@ -85,14 +85,17 @@ void tOnePole_initToPool (tOnePole* const ft, float freq, tMempool* const · 74 unmodified lines
85 _tMempool* m = *mp;85 _tMempool* m = *mp;
86 _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m);86 _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m);
87 f->mempool = m;87 f->mempool = m;
88 LEAF* leaf = f->mempool->leaf;
88 89
89 f->gain = 1.0f;90 f->gain = 1.0f;
90 f->a0 = 1.0;91 f->a0 = 1.0;
91 92
92 tOnePole_setFreq(ft, freq);
93
94 f->lastIn = 0.0f;93 f->lastIn = 0.0f;
95 f->lastOut = 0.0f;94 f->lastOut = 0.0f;
95
96 f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
97
98 tOnePole_setFreq(ft, freq);
96}99}
97 100
98void tOnePole_free (tOnePole* const ft)101void tOnePole_free (tOnePole* const ft)
@@ -131,9 +134,9 @@ void tOnePole_setPole(tOnePole* const ft, float thePole) · 32 unmodified lines
131void tOnePole_setFreq (tOnePole* const ft, float freq)134void tOnePole_setFreq (tOnePole* const ft, float freq)
132{135{
133 _tOnePole* f = *ft;136 _tOnePole* f = *ft;
134 LEAF* leaf = f->mempool->leaf;
135 137
136 f->b0 = freq * leaf->twoPiTimesInvSampleRate;138 f->freq = freq;
139 f->b0 = f->freq * f->twoPiTimesInvSampleRate;
137 f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);140 f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
138 f->a1 = 1.0f - f->b0;141 f->a1 = 1.0f - f->b0;
139}142}
@@ -165,6 +168,15 @@ float tOnePole_tick(tOnePole* const ft, float input) · 25 unmodified lines
165 return out;168 return out;
166}169}
167 170
171void tOnePole_setSampleRate(tOnePole* const ft, float sr)
172{
173 _tOnePole* f = *ft;
174 f->twoPiTimesInvSampleRate = (1.0f/sr) * TWO_PI;
175 f->b0 = f->freq * f->twoPiTimesInvSampleRate;
176 f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
177 f->a1 = 1.0f - f->b0;
178}
179
168// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //180// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
169void tTwoPole_init(tTwoPole* const ft, LEAF* const leaf)181void tTwoPole_init(tTwoPole* const ft, LEAF* const leaf)
170{182{
@@ -176,6 +188,7 @@ void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp) · 5 unmodified lines
176 _tMempool* m = *mp;188 _tMempool* m = *mp;
177 _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m);189 _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m);
178 f->mempool = m;190 f->mempool = m;
191 LEAF* leaf = f->mempool->leaf;
179 192
180 f->gain = 1.0f;193 f->gain = 1.0f;
181 f->a0 = 1.0;194 f->a0 = 1.0;
@@ -183,12 +196,14 @@ void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp) · 1 unmodified line
183 196
184 f->lastOut[0] = 0.0f;197 f->lastOut[0] = 0.0f;
185 f->lastOut[1] = 0.0f;198 f->lastOut[1] = 0.0f;
199
200 f->sampleRate = leaf->sampleRate;
201 f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
186}202}
187 203
188void tTwoPole_free (tTwoPole* const ft)204void tTwoPole_free (tTwoPole* const ft)
189{205{
190 _tTwoPole* f = *ft;206 _tTwoPole* f = *ft;
191
192 mpool_free((char*)f, f->mempool);207 mpool_free((char*)f, f->mempool);
193}208}
194 209
@@ -223,14 +238,12 @@ void tTwoPole_setA2(tTwoPole* const ft, float a2) · 28 unmodified lines
223 f->a2 = a2;238 f->a2 = a2;
224}239}
225 240
226
227void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, int normalize)241void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, int normalize)
228{242{
229 _tTwoPole* f = *ft;243 _tTwoPole* f = *ft;
230 LEAF* leaf = f->mempool->leaf;
231 244
232 float sampleRate = leaf->sampleRate;245 float sampleRate = f->sampleRate;
233 float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;246 float twoPiTimesInvSampleRate = f->twoPiTimesInvSampleRate;
234 247
235 if (frequency < 0.0f) frequency = 0.0f;248 if (frequency < 0.0f) frequency = 0.0f;
236 if (frequency > (sampleRate * 0.49f)) frequency = sampleRate * 0.49f;249 if (frequency > (sampleRate * 0.49f)) frequency = sampleRate * 0.49f;
@@ -267,21 +280,20 @@ void tTwoPole_setGain(tTwoPole* const ft, float gain) · 30 unmodified lines
267 f->gain = gain;280 f->gain = gain;
268}281}
269 282
270void tTwoPoleSampleRateChanged (tTwoPole* const ft)283void tTwoPole_setSampleRate (tTwoPole* const ft, float sr)
271{284{
272 _tTwoPole* f = *ft;285 _tTwoPole* f = *ft;
273 LEAF* leaf = f->mempool->leaf;
274 286
275 float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;287 f->twoPiTimesInvSampleRate = (1.0f/sr) * TWO_PI;
276 288
277 f->a2 = f->radius * f->radius;289 f->a2 = f->radius * f->radius;
278 f->a1 = -2.0f * f->radius * cosf(f->frequency * twoPiTimesInvSampleRate);290 f->a1 = -2.0f * f->radius * cosf(f->frequency * f->twoPiTimesInvSampleRate);
279 291
280 if ( f->normalize )292 if ( f->normalize )
281 {293 {
282 // Normalize the filter gain ... not terribly efficient.294 // Normalize the filter gain ... not terribly efficient.
283 float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * twoPiTimesInvSampleRate);295 float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * f->twoPiTimesInvSampleRate);
284 float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * twoPiTimesInvSampleRate);296 float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * f->twoPiTimesInvSampleRate);
285 f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );297 f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
286 }298 }
287}299}
@@ -297,17 +309,18 @@ void tOneZero_initToPool (tOneZero* const ft, float theZero, tMempool* co · 9 unmodified lines
297 _tMempool* m = *mp;309 _tMempool* m = *mp;
298 _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m);310 _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m);
299 f->mempool = m;311 f->mempool = m;
312 LEAF* leaf = f->mempool->leaf;
300 313
301 f->gain = 1.0f;314 f->gain = 1.0f;
302 f->lastIn = 0.0f;315 f->lastIn = 0.0f;
303 f->lastOut = 0.0f;316 f->lastOut = 0.0f;
317 f->invSampleRate = leaf->invSampleRate;
304 tOneZero_setZero(ft, theZero);318 tOneZero_setZero(ft, theZero);
305}319}
306 320
307void tOneZero_free (tOneZero* const ft)321void tOneZero_free (tOneZero* const ft)
308{322{
309 _tOneZero* f = *ft;323 _tOneZero* f = *ft;
310
311 mpool_free((char*)f, f->mempool);324 mpool_free((char*)f, f->mempool);
312}325}
313 326
@@ -363,13 +376,12 @@ void tOneZero_setGain(tOneZero *ft, float gain) · 49 unmodified lines
363float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )376float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )
364{377{
365 _tOneZero* f = *ft;378 _tOneZero* f = *ft;
366 LEAF* leaf = f->mempool->leaf;
367 379
368 if ( frequency <= 0.0f) frequency = 0.05f;380 if ( frequency <= 0.0f) frequency = 0.05f;
369 381
370 f->frequency = frequency;382 f->frequency = frequency;
371 383
372 float omegaT = 2 * PI * frequency * leaf->invSampleRate;384 float omegaT = 2 * PI * frequency * f->invSampleRate;
373 float real = 0.0, imag = 0.0;385 float real = 0.0, imag = 0.0;
374 386
375 real += f->b0;387 real += f->b0;
@@ -391,6 +403,12 @@ float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency ) · 15 unmodified lines
391 return phase / omegaT;403 return phase / omegaT;
392}404}
393 405
406void tOneZero_setSampleRate (tOneZero* const ft, float sr)
407{
408 _tOneZero* f = *ft;
409 f->invSampleRate = 1.0f/sr;
410}
411
394// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //412// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
395void tTwoZero_init(tTwoZero* const ft, LEAF* const leaf)413void tTwoZero_init(tTwoZero* const ft, LEAF* const leaf)
396{414{
@@ -402,7 +420,9 @@ void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp) · 5 unmodified lines
402 _tMempool* m = *mp;420 _tMempool* m = *mp;
403 _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m);421 _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m);
404 f->mempool = m;422 f->mempool = m;
423 LEAF* leaf = f->mempool->leaf;
405 424
425 f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
406 f->gain = 1.0f;426 f->gain = 1.0f;
407 f->lastIn[0] = 0.0f;427 f->lastIn[0] = 0.0f;
408 f->lastIn[1] = 0.0f;428 f->lastIn[1] = 0.0f;
@@ -411,7 +431,6 @@ void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp) · 2 unmodified lines
411void tTwoZero_free (tTwoZero* const ft)431void tTwoZero_free (tTwoZero* const ft)
412{432{
413 _tTwoZero* f = *ft;433 _tTwoZero* f = *ft;
414
415 mpool_free((char*)f, f->mempool);434 mpool_free((char*)f, f->mempool);
416}435}
417 436
@@ -431,7 +450,6 @@ float tTwoZero_tick(tTwoZero* const ft, float input) · 13 unmodified lines
431void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)450void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)
432{451{
433 _tTwoZero* f = *ft;452 _tTwoZero* f = *ft;
434 LEAF* leaf = f->mempool->leaf;
435 453
436 // Should also deal with frequency being > half sample rate / nyquist. See STK454 // Should also deal with frequency being > half sample rate / nyquist. See STK
437 if (freq < 0.0f) freq = 0.0f;455 if (freq < 0.0f) freq = 0.0f;
@@ -441,7 +459,7 @@ void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius) · 3 unmodified lines
441 f->radius = radius;459 f->radius = radius;
442 460
443 f->b2 = radius * radius;461 f->b2 = radius * radius;
444 f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION462 f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
445 463
446 // Normalize the filter gain. From STK.464 // Normalize the filter gain. From STK.
447 if ( f->b1 > 0.0f ) // Maximum at z = 0.465 if ( f->b1 > 0.0f ) // Maximum at z = 0.
@@ -479,10 +497,11 @@ void tTwoZero_setGain(tTwoZero* const ft, float gain) · 31 unmodified lines
479 f->gain = gain;497 f->gain = gain;
480}498}
481 499
482void tTwoZeroSampleRateChanged(tTwoZero* const ft)500void tTwoZero_setSampleRate(tTwoZero* const ft, float sr)
483{501{
484 _tTwoZero* f = *ft;502 _tTwoZero* f = *ft;
485 503
504 f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
486 tTwoZero_setNotch(ft, f->frequency, f->radius);505 tTwoZero_setNotch(ft, f->frequency, f->radius);
487}506}
488 507
@@ -509,7 +528,6 @@ void tPoleZero_initToPool (tPoleZero* const pzf, tMempool* const mp) · 20 unmodified lines
509void tPoleZero_free (tPoleZero* const pzf)528void tPoleZero_free (tPoleZero* const pzf)
510{529{
511 _tPoleZero* f = *pzf;530 _tPoleZero* f = *pzf;
512
513 mpool_free((char*)f, f->mempool);531 mpool_free((char*)f, f->mempool);
514}532}
515 533
@@ -611,6 +629,7 @@ void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp) · 95 unmodified lines
611 _tMempool* m = *mp;629 _tMempool* m = *mp;
612 _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m);630 _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m);
613 f->mempool = m;631 f->mempool = m;
632 LEAF* leaf = f->mempool->leaf;
614 633
615 f->gain = 1.0f;634 f->gain = 1.0f;
616 635
@@ -621,12 +640,13 @@ void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp) · 4 unmodified lines
621 f->lastIn[1] = 0.0f;640 f->lastIn[1] = 0.0f;
622 f->lastOut[0] = 0.0f;641 f->lastOut[0] = 0.0f;
623 f->lastOut[1] = 0.0f;642 f->lastOut[1] = 0.0f;
643
644 f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
624}645}
625 646
626void tBiQuad_free (tBiQuad* const ft)647void tBiQuad_free (tBiQuad* const ft)
627{648{
628 _tBiQuad* f = *ft;649 _tBiQuad* f = *ft;
629
630 mpool_free((char*)f, f->mempool);650 mpool_free((char*)f, f->mempool);
631}651}
632 652
@@ -650,11 +670,10 @@ float tBiQuad_tick(tBiQuad* const ft, float input) · 17 unmodified lines
650void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int normalize)670void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int normalize)
651{671{
652 _tBiQuad* f = *ft;672 _tBiQuad* f = *ft;
653 LEAF* leaf = f->mempool->leaf;
654 673
655 if (freq < 0.0f) freq = 0.0f;674 if (freq < 0.0f) freq = 0.0f;
656 if (freq > (leaf->sampleRate * 0.49f))675 if (freq > (f->sampleRate * 0.49f))
657 freq = leaf->sampleRate * 0.49f;676 freq = f->sampleRate * 0.49f;
658 if (radius < 0.0f) radius = 0.0f;677 if (radius < 0.0f) radius = 0.0f;
659 if (radius >= 1.0f) radius = 1.0f;678 if (radius >= 1.0f) radius = 1.0f;
660 679
@@ -663,7 +682,7 @@ void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int no · 2 unmodified lines
663 f->normalize = normalize;682 f->normalize = normalize;
664 683
665 f->a2 = radius * radius;684 f->a2 = radius * radius;
666 f->a1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate);685 f->a1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate);
667 686
668 if (normalize)687 if (normalize)
669 {688 {
@@ -676,15 +695,14 @@ void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int no · 6 unmodified lines
676void tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)695void tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)
677{696{
678 _tBiQuad* f = *ft;697 _tBiQuad* f = *ft;
679 LEAF* leaf = f->mempool->leaf;
680 698
681 if (freq < 0.0f) freq = 0.0f;699 if (freq < 0.0f) freq = 0.0f;
682 if (freq > (leaf->sampleRate * 0.49f))700 if (freq > (f->sampleRate * 0.49f))
683 freq = leaf->sampleRate * 0.49f;701 freq = f->sampleRate * 0.49f;
684 if (radius < 0.0f) radius = 0.0f;702 if (radius < 0.0f) radius = 0.0f;
685 703
686 f->b2 = radius * radius;704 f->b2 = radius * radius;
687 f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION705 f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
688 706
689 // Does not attempt to normalize filter gain.707 // Does not attempt to normalize filter gain.
690}708}
@@ -743,13 +761,15 @@ void tBiQuad_setGain(tBiQuad* const ft, float gain) · 52 unmodified lines
743 f->gain = gain;761 f->gain = gain;
744}762}
745 763
746void tBiQuadSampleRateChanged(tBiQuad* const ft)764void tBiQuad_setSampleRate(tBiQuad* const ft, float sr)
747{765{
748 _tBiQuad* f = *ft;766 _tBiQuad* f = *ft;
749 LEAF* leaf = f->mempool->leaf;767
768 f->sampleRate = sr;
769 f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/f->sampleRate);
750 770
751 f->a2 = f->radius * f->radius;771 f->a2 = f->radius * f->radius;
752 f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf->twoPiTimesInvSampleRate);772 f->a1 = -2.0f * f->radius * cosf(f->frequency * f->twoPiTimesInvSampleRate);
753 773
754 if (f->normalize)774 if (f->normalize)
755 {775 {
@@ -764,12 +784,10 @@ void tBiQuadSampleRateChanged(tBiQuad* const ft) · 8 unmodified lines
764void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q, LEAF* const leaf)784void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q, LEAF* const leaf)
765{785{
766 tSVF_initToPool (svff, type, freq, Q, &leaf->mempool);786 tSVF_initToPool (svff, type, freq, Q, &leaf->mempool);
767
768 // or maybe this?787 // or maybe this?
769 /*788 /*
770 * hp=1 bp=A/Q (where A is 10^(G/40) and G is gain in decibels) and lp = 1789 * hp=1 bp=A/Q (where A is 10^(G/40) and G is gain in decibels) and lp = 1
771 */790 */
772
773}791}
774 792
775void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q, tMempool* const mp)793void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q, tMempool* const mp)
@@ -779,14 +797,17 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 3 unmodified lines
779 svf->mempool = m;797 svf->mempool = m;
780 798
781 LEAF* leaf = svf->mempool->leaf;799 LEAF* leaf = svf->mempool->leaf;
782 800
801 svf->sampleRate = leaf->sampleRate;
802 svf->invSampleRate = leaf->invSampleRate;
803
783 svf->type = type;804 svf->type = type;
784 805
785 svf->ic1eq = 0;806 svf->ic1eq = 0;
786 svf->ic2eq = 0;807 svf->ic2eq = 0;
787 svf->Q = Q;808 svf->Q = Q;
788 svf->cutoff = freq;809 svf->cutoff = freq;
789 svf->g = tanf(PI * freq * leaf->invSampleRate);810 svf->g = tanf(PI * freq * svf->invSampleRate);
790 svf->k = 1.0f/Q;811 svf->k = 1.0f/Q;
791 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));812 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
792 svf->a2 = svf->g*svf->a1;813 svf->a2 = svf->g*svf->a1;
@@ -796,7 +817,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 3 unmodified lines
796 svf->cB = 0.0f;817 svf->cB = 0.0f;
797 svf->cBK = 0.0f;818 svf->cBK = 0.0f;
798 svf->cL = 1.0f;819 svf->cL = 1.0f;
799 820
800 if (type == SVFTypeLowpass)821 if (type == SVFTypeLowpass)
801 {822 {
802 svf->cH = 0.0f;823 svf->cH = 0.0f;
@@ -811,7 +832,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 8 unmodified lines
811 svf->cBK = 0.0f;832 svf->cBK = 0.0f;
812 svf->cL = 0.0f;833 svf->cL = 0.0f;
813 }834 }
814 835
815 else if (type == SVFTypeHighpass)836 else if (type == SVFTypeHighpass)
816 {837 {
817 svf->cH = 1.0f;838 svf->cH = 1.0f;
@@ -819,7 +840,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 1 unmodified line
819 svf->cBK = -1.0f;840 svf->cBK = -1.0f;
820 svf->cL = -1.0f;841 svf->cL = -1.0f;
821 }842 }
822 843
823 else if (type == SVFTypeNotch)844 else if (type == SVFTypeNotch)
824 {845 {
825 svf->cH = 1.0f;846 svf->cH = 1.0f;
@@ -827,7 +848,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 1 unmodified line
827 svf->cBK = -1.0f;848 svf->cBK = -1.0f;
828 svf->cL = 0.0f;849 svf->cL = 0.0f;
829 }850 }
830 851
831 else if (type == SVFTypePeak)852 else if (type == SVFTypePeak)
832 {853 {
833 svf->cH = 1.0f;854 svf->cH = 1.0f;
@@ -840,7 +861,6 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 6 unmodified lines
840void tSVF_free (tSVF* const svff)861void tSVF_free (tSVF* const svff)
841{862{
842 _tSVF* svf = *svff;863 _tSVF* svf = *svff;
843
844 mpool_free((char*)svf, svf->mempool);864 mpool_free((char*)svf, svf->mempool);
845}865}
846 866
@@ -866,10 +886,9 @@ float tSVF_tick(tSVF* const svff, float v0) · 19 unmodified lines
866void tSVF_setFreq(tSVF* const svff, float freq)886void tSVF_setFreq(tSVF* const svff, float freq)
867{887{
868 _tSVF* svf = *svff;888 _tSVF* svf = *svff;
869 LEAF* leaf = svf->mempool->leaf;
870 889
871 svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);890 svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
872 svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);891 svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
873 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));892 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
874 svf->a2 = svf->g * svf->a1;893 svf->a2 = svf->g * svf->a1;
875 svf->a3 = svf->g * svf->a2;894 svf->a3 = svf->g * svf->a2;
@@ -880,7 +899,7 @@ void tSVF_setQ(tSVF* const svff, float Q) · 4 unmodified lines
880 _tSVF* svf = *svff;899 _tSVF* svf = *svff;
881 svf->Q = Q;900 svf->Q = Q;
882 svf->k = 1.0f/Q;901 svf->k = 1.0f/Q;
883 902
884 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));903 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
885 svf->a2 = svf->g * svf->a1;904 svf->a2 = svf->g * svf->a1;
886 svf->a3 = svf->g * svf->a2;905 svf->a3 = svf->g * svf->a2;
@@ -889,16 +908,23 @@ void tSVF_setQ(tSVF* const svff, float Q) · 2 unmodified lines
889void tSVF_setFreqAndQ(tSVF* const svff, float freq, float Q)908void tSVF_setFreqAndQ(tSVF* const svff, float freq, float Q)
890{909{
891 _tSVF* svf = *svff;910 _tSVF* svf = *svff;
892 LEAF* leaf = svf->mempool->leaf;
893 911
894 svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);912 svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
895 svf->k = 1.0f/Q;913 svf->k = 1.0f/Q;
896 svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);914 svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
897 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));915 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
898 svf->a2 = svf->g * svf->a1;916 svf->a2 = svf->g * svf->a1;
899 svf->a3 = svf->g * svf->a2;917 svf->a3 = svf->g * svf->a2;
900}918}
901 919
920void tSVF_setSampleRate (tSVF* const svff, float sr)
921{
922 _tSVF* svf = *svff;
923 svf->sampleRate = sr;
924 svf->invSampleRate = 1.0f/svf->sampleRate;
925 tSVF_setFreq(svff, svf->cutoff);
926}
927
902#if LEAF_INCLUDE_FILTERTAN_TABLE928#if LEAF_INCLUDE_FILTERTAN_TABLE
903// Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.929// Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.
904void tEfficientSVF_init(tEfficientSVF* const svff, SVFType type, uint16_t input, float Q, LEAF* const leaf)930void tEfficientSVF_init(tEfficientSVF* const svff, SVFType type, uint16_t input, float Q, LEAF* const leaf)
@@ -927,7 +953,6 @@ void tEfficientSVF_initToPool (tEfficientSVF* const svff, SVFType type, ui · 22 unmodified lines
927void tEfficientSVF_free (tEfficientSVF* const svff)953void tEfficientSVF_free (tEfficientSVF* const svff)
928{954{
929 _tEfficientSVF* svf = *svff;955 _tEfficientSVF* svf = *svff;
930
931 mpool_free((char*)svf, svf->mempool);956 mpool_free((char*)svf, svf->mempool);
932}957}
933 958
@@ -983,10 +1008,10 @@ void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const m · 49 unmodified lines
983 _tMempool* m = *mp;1008 _tMempool* m = *mp;
984 _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m);1009 _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m);
985 f->mempool = m;1010 f->mempool = m;
986
987 LEAF* leaf = f->mempool->leaf;1011 LEAF* leaf = f->mempool->leaf;
988 1012
989 f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));1013 f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
1014 f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
990 f->ys = 0.0f;1015 f->ys = 0.0f;
991 f->xs = 0.0f;1016 f->xs = 0.0f;
992 1017
@@ -996,18 +1021,15 @@ void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const m · 3 unmodified lines
996void tHighpass_free (tHighpass* const ft)1021void tHighpass_free (tHighpass* const ft)
997{1022{
998 _tHighpass* f = *ft;1023 _tHighpass* f = *ft;
999
1000 mpool_free((char*)f, f->mempool);1024 mpool_free((char*)f, f->mempool);
1001}1025}
1002 1026
1003void tHighpass_setFreq(tHighpass* const ft, float freq)1027void tHighpass_setFreq(tHighpass* const ft, float freq)
1004{1028{
1005 _tHighpass* f = *ft;1029 _tHighpass* f = *ft;
1006 LEAF* leaf = f->mempool->leaf;
1007 1030
1008 f->frequency = freq;1031 f->frequency = freq;
1009 f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));1032 f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
1010
1011}1033}
1012 1034
1013float tHighpass_getFreq(tHighpass* const ft)1035float tHighpass_getFreq(tHighpass* const ft)
@@ -1025,12 +1047,11 @@ float tHighpass_tick(tHighpass* const ft, float x) · 11 unmodified lines
1025 return f->ys;1047 return f->ys;
1026}1048}
1027 1049
1028void tHighpassSampleRateChanged(tHighpass* const ft)1050void tHighpass_setSampleRate(tHighpass* const ft, float sr)
1029{1051{
1030 _tHighpass* f = *ft;1052 _tHighpass* f = *ft;
1031 LEAF* leaf = f->mempool->leaf;1053 f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
1032 1054 f->R = (1.0f - (f->frequency * f->twoPiTimesInvSampleRate));
1033 f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf->invSampleRate));
1034}1055}
1035 1056
1036void tButterworth_init(tButterworth* const ft, int order, float f1, float f2, LEAF* const leaf)1057void tButterworth_init(tButterworth* const ft, int order, float f1, float f2, LEAF* const leaf)
@@ -1068,8 +1089,7 @@ void tButterworth_free (tButterworth* const ft) · 31 unmodified lines
1068{1089{
1069 _tButterworth* f = *ft;1090 _tButterworth* f = *ft;
1070 1091
1071 for(int i = 0; i < f->numSVF; ++i)1092 for (int i = 0; i < f->numSVF; ++i) tSVF_free(&f->svf[i]);
1072 tSVF_free(&f->svf[i]);
1073 1093
1074 mpool_free((char*)f->svf, f->mempool);1094 mpool_free((char*)f->svf, f->mempool);
1075 mpool_free((char*)f, f->mempool);1095 mpool_free((char*)f, f->mempool);
@@ -1080,7 +1100,7 @@ float tButterworth_tick(tButterworth* const ft, float samp) · 4 unmodified lines
1080 _tButterworth* f = *ft;1100 _tButterworth* f = *ft;
1081 1101
1082 for(int i = 0; i < f->numSVF; ++i)1102 for(int i = 0; i < f->numSVF; ++i)
1083 samp = tSVF_tick(&f->svf[i], samp);1103 samp = tSVF_tick(&f->svf[i], samp);
1084 1104
1085 return samp;1105 return samp;
1086}1106}
@@ -1109,18 +1129,18 @@ void tButterworth_setF2(tButterworth* const ft, float f2) · 22 unmodified lines
1109 1129
1110void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)1130void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
1111{1131{
1112// _tButterworth* f = *ft;
1113 tButterworth_setF1(ft, f1);1132 tButterworth_setF1(ft, f1);
1114 tButterworth_setF1(ft, f2);1133 tButterworth_setF2(ft, f2);
1115// f->f1 = f1;
1116// f->f2 = f2;
1117// for(int i = 0; i < ((f->N)/2); ++i)
1118// {
1119// tSVF_setFreq(&f->low[i], f1);
1120// tSVF_setFreq(&f->high[i], f2);
1121// }
1122}1134}
1123 1135
1136void tButterworth_setSampleRate (tButterworth* const ft, float sr)
1137{
1138 _tButterworth* f = *ft;
1139 for (int i = 0; i < f->numSVF; ++i) tSVF_setSampleRate(&f->svf[i], sr);
1140}
1141
1142//================================================================================
1143
1124void tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf)1144void tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf)
1125{1145{
1126 tFIR_initToPool(firf, coeffs, numTaps, &leaf->mempool);1146 tFIR_initToPool(firf, coeffs, numTaps, &leaf->mempool);
@@ -1173,7 +1193,7 @@ void tMedianFilter_initToPool (tMedianFilter* const mf, int size, tMempoo · 46 unmodified lines
1173 _tMempool* m = *mp;1193 _tMempool* m = *mp;
1174 _tMedianFilter* f = *mf = (_tMedianFilter*) mpool_alloc(sizeof(_tMedianFilter), m);1194 _tMedianFilter* f = *mf = (_tMedianFilter*) mpool_alloc(sizeof(_tMedianFilter), m);
1175 f->mempool = m;1195 f->mempool = m;
1176 1196
1177 f->size = size;1197 f->size = size;
1178 f->middlePosition = size / 2;1198 f->middlePosition = size / 2;
1179 f->last = size - 1;1199 f->last = size - 1;
@@ -1185,12 +1205,12 @@ void tMedianFilter_initToPool (tMedianFilter* const mf, int size, tMempoo · 5 unmodified lines
1185 f->val[i] = 0.0f;1205 f->val[i] = 0.0f;
1186 f->age[i] = i;1206 f->age[i] = i;
1187 }1207 }
1188 1208
1189}1209}
1190void tMedianFilter_free (tMedianFilter* const mf)1210void tMedianFilter_free (tMedianFilter* const mf)
1191{1211{
1192 _tMedianFilter* f = *mf;1212 _tMedianFilter* f = *mf;
1193 1213
1194 mpool_free((char*)f->val, f->mempool);1214 mpool_free((char*)f->val, f->mempool);
1195 mpool_free((char*)f->age, f->mempool);1215 mpool_free((char*)f->age, f->mempool);
1196 mpool_free((char*)f, f->mempool);1216 mpool_free((char*)f, f->mempool);
@@ -1199,7 +1219,7 @@ void tMedianFilter_free (tMedianFilter* const mf) · 2 unmodified lines
1199float tMedianFilter_tick (tMedianFilter* const mf, float input)1219float tMedianFilter_tick (tMedianFilter* const mf, float input)
1200{1220{
1201 _tMedianFilter* f = *mf;1221 _tMedianFilter* f = *mf;
1202 1222
1203 for(int i=0; i<f->size; i++) {1223 for(int i=0; i<f->size; i++) {
1204 int thisAge = f->age[i];1224 int thisAge = f->age[i];
1205 if(thisAge == f->last) {1225 if(thisAge == f->last) {
@@ -1210,7 +1230,7 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 4 unmodified lines
1210 f->age[i] = thisAge;1230 f->age[i] = thisAge;
1211 }1231 }
1212 }1232 }
1213 1233
1214 while( f->pos!=0 ) {1234 while( f->pos!=0 ) {
1215 float test = f->val[f->pos-1];1235 float test = f->val[f->pos-1];
1216 if(input < test) {1236 if(input < test) {
@@ -1219,7 +1239,7 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 2 unmodified lines
1219 f->pos -= 1;1239 f->pos -= 1;
1220 } else {break;}1240 } else {break;}
1221 }1241 }
1222 1242
1223 while(f->pos != f->last) {1243 while(f->pos != f->last) {
1224 float test = f->val[f->pos+1];1244 float test = f->val[f->pos+1];
1225 if( input > test) {1245 if( input > test) {
@@ -1228,10 +1248,10 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 2 unmodified lines
1228 f->pos += 1;1248 f->pos += 1;
1229 } else {break;}1249 } else {break;}
1230 }1250 }
1231 1251
1232 f->val[f->pos] = input;1252 f->val[f->pos] = input;
1233 f->age[f->pos] = 0;1253 f->age[f->pos] = 0;
1234 1254
1235 return f->val[f->middlePosition];1255 return f->val[f->middlePosition];
1236}1256}
1237 1257
@@ -1250,16 +1270,17 @@ void tVZFilter_initToPool (tVZFilter* const vf, VZFilterType type, float · 12 unmodified lines
1250 1270
1251 LEAF* leaf = f->mempool->leaf;1271 LEAF* leaf = f->mempool->leaf;
1252 1272
1253 f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);1273 f->sampleRate = leaf->sampleRate;
1274 f->invSampleRate = leaf->invSampleRate;
1275 f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
1254 f->type = type;1276 f->type = type;
1255 f->G = ONE_OVER_SQRT2;1277 f->G = ONE_OVER_SQRT2;
1256 f->invG = 1.0f/ONE_OVER_SQRT2;1278 f->invG = 1.0f/ONE_OVER_SQRT2;
1257 f->B = bandWidth;1279 f->B = bandWidth;
1258 f->m = 0.0f;1280 f->m = 0.0f;
1259 f->s1 = 0.0f;1281 f->s1 = 0.0f;
1260 f->s2 = 0.0f;1282 f->s2 = 0.0f;
1261 f->sr = leaf->sampleRate;1283
1262 f->inv_sr = leaf->invSampleRate;
1263 tVZFilter_calcCoeffs(vf);1284 tVZFilter_calcCoeffs(vf);
1264}1285}
1265 1286
@@ -1269,194 +1290,179 @@ void tVZFilter_free (tVZFilter* const vf) · 3 unmodified lines
1269 mpool_free((char*)f, f->mempool);1290 mpool_free((char*)f, f->mempool);
1270}1291}
1271 1292
1272void tVZFilter_setSampleRate (tVZFilter* const vf, float sampleRate)
1273{
1274 _tVZFilter* f = *vf;
1275 f->sr = sampleRate;
1276 f->inv_sr = 1.0f/sampleRate;
1277}
1278
1279float tVZFilter_tick (tVZFilter* const vf, float in)1293float tVZFilter_tick (tVZFilter* const vf, float in)
1280{1294{
1281 _tVZFilter* f = *vf;1295 _tVZFilter* f = *vf;
1282 1296
1283 float yL, yB, yH;1297 float yL, yB, yH;
1284 1298
1285 // compute highpass output via Eq. 5.1:1299 // compute highpass output via Eq. 5.1:
1286 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;1300 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1287 1301
1288 // compute bandpass output by applying 1st integrator to highpass output:1302 // compute bandpass output by applying 1st integrator to highpass output:
1289 yB = tanhf(f->g*yH) + f->s1;1303 yB = tanhf(f->g*yH) + f->s1;
1290 f->s1 = f->g*yH + yB; // state update in 1st integrator1304 f->s1 = f->g*yH + yB; // state update in 1st integrator
1291 1305
1292 // compute lowpass output by applying 2nd integrator to bandpass output:1306 // compute lowpass output by applying 2nd integrator to bandpass output:
1293 yL = tanhf(f->g*yB) + f->s2;1307 yL = tanhf(f->g*yB) + f->s2;
1294 f->s2 = f->g*yB + yL; // state update in 2nd integrator1308 f->s2 = f->g*yB + yL; // state update in 2nd integrator
1295 1309
1296 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.1310 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1297 //1311 //
1298 //seems like that might look like this:1312 //seems like that might look like this:
1299 // y = tanh(g*x) + s; // output computation1313 // y = tanh(g*x) + s; // output computation
1300 // s = g*x + y; // state update1314 // s = g*x + y; // state update
1301 1315
1302 //instead of this:1316 //instead of this:
1303 // y = g*x + s; // output computation1317 // y = g*x + s; // output computation
1304 // s = g*x + y; // state update1318 // s = g*x + y; // state update
1305 1319
1306 return f->cL*yL + f->cB*yB + f->cH*yH;1320 return f->cL*yL + f->cB*yB + f->cH*yH;
1307
1308}1321}
1309 1322
1310float tVZFilter_tickEfficient (tVZFilter* const vf, float in)1323float tVZFilter_tickEfficient (tVZFilter* const vf, float in)
1311{1324{
1312 _tVZFilter* f = *vf;1325 _tVZFilter* f = *vf;
1313 1326
1314 float yL, yB, yH;1327 float yL, yB, yH;
1315 1328
1316 // compute highpass output via Eq. 5.1:1329 // compute highpass output via Eq. 5.1:
1317 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;1330 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1318 1331
1319 // compute bandpass output by applying 1st integrator to highpass output:1332 // compute bandpass output by applying 1st integrator to highpass output:
1320 yB = (f->g*yH) + f->s1;1333 yB = (f->g*yH) + f->s1;
1321 f->s1 = f->g*yH + yB; // state update in 1st integrator1334 f->s1 = f->g*yH + yB; // state update in 1st integrator
1322 1335
1323 // compute lowpass output by applying 2nd integrator to bandpass output:1336 // compute lowpass output by applying 2nd integrator to bandpass output:
1324 yL = (f->g*yB) + f->s2;1337 yL = (f->g*yB) + f->s2;
1325 f->s2 = f->g*yB + yL; // state update in 2nd integrator1338 f->s2 = f->g*yB + yL; // state update in 2nd integrator
1326 1339
1327 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.1340 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
1328 //1341 //
1329 //seems like that might look like this:1342 //seems like that might look like this:
1330 // y = tanh(g*x) + s; // output computation1343 // y = tanh(g*x) + s; // output computation
1331 // s = g*x + y; // state update1344 // s = g*x + y; // state update
1332 1345
1333 //instead of this:1346 //instead of this:
1334 // y = g*x + s; // output computation1347 // y = g*x + s; // output computation
1335 // s = g*x + y; // state update1348 // s = g*x + y; // state update
1336 1349
1337 return f->cL*yL + f->cB*yB + f->cH*yH;1350 return f->cL*yL + f->cB*yB + f->cH*yH;
1338
1339}1351}
1340 1352
1341
1342void tVZFilter_calcCoeffs (tVZFilter* const vf)1353void tVZFilter_calcCoeffs (tVZFilter* const vf)
1343{1354{
1344
1345 _tVZFilter* f = *vf;1355 _tVZFilter* f = *vf;
1346 f->g = tanf(PI * f->fc * f->inv_sr); // embedded integrator gain (Fig 3.11)1356 f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
1347 1357
1348 switch( f->type )1358 switch( f->type )
1349 {1359 {
1350 case Bypass:1360 case Bypass:
1351 {1361 {
1352 f->R2 = f->invG; // can we use an arbitrary value here, for example R2 = 1?1362 f->R2 = f->invG; // can we use an arbitrary value here, for example R2 = 1?
1353 f->cL = 1.0f;1363 f->cL = 1.0f;
1354 f->cB = f->R2;1364 f->cB = f->R2;
1355 f->cH = 1.0f;1365 f->cH = 1.0f;
1356 }1366 }
1357 break;1367 break;
1358 case Lowpass:1368 case Lowpass:
1359 {1369 {
1360 f->R2 = f->invG;1370 f->R2 = f->invG;
1361 f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;1371 f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;
1362 }1372 }
1363 break;1373 break;
1364 case Highpass:1374 case Highpass:
1365 {1375 {
1366 f->R2 = f->invG;1376 f->R2 = f->invG;
1367 f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;1377 f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;
1368 }1378 }
1369 break;1379 break;
1370 case BandpassSkirt:1380 case BandpassSkirt:
1371 {1381 {
1372 f->R2 = f->invG;1382 f->R2 = f->invG;
1373 f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;1383 f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;
1374 }1384 }
1375 break;1385 break;
1376 case BandpassPeak:1386 case BandpassPeak:
1377 {1387 {
1378 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);1388 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1379 f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;1389 f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;
1380 }1390 }
1381 break;1391 break;
1382 case BandReject:1392 case BandReject:
1383 {1393 {
1384 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);1394 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1385 f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;1395 f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;
1386 }1396 }
1387 break;1397 break;
1388 case Bell:1398 case Bell:
1389 {1399 {
1390 float fl = f->fc*powf(2.0f, (-f->B)*0.5f); // lower bandedge frequency (in Hz)1400 float fl = f->fc*powf(2.0f, (-f->B)*0.5f); // lower bandedge frequency (in Hz)
1391 float wl = tanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)1401 float wl = tanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
1392 float r = f->g/wl;1402 float r = f->g/wl;
1393 r *= r; // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the1403 r *= r; // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the
1394 // warped upper bandedge, wc the center1404 // warped upper bandedge, wc the center
1395 f->R2 = 2.0f*sqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));1405 f->R2 = 2.0f*sqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));
1396 f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;1406 f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;
1397 }1407 }
1398 break;1408 break;
1399 case Lowshelf:1409 case Lowshelf:
1400 {1410 {
1401 float A = sqrtf(f->G);1411 float A = sqrtf(f->G);
1402 f->g /= sqrtf(A); // scale SVF-cutoff frequency for shelvers1412 f->g /= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1403 f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);1413 f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);
1404 f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;1414 f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;
1405 }1415 }
1406 break;1416 break;
1407 case Highshelf:1417 case Highshelf:
1408 {1418 {
1409 float A = sqrtf(f->G);1419 float A = sqrtf(f->G);
1410 f->g *= sqrtf(A); // scale SVF-cutoff frequency for shelvers1420 f->g *= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1411 f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);1421 f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);
1412 f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;1422 f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;
1413 }1423 }
1414 break;1424 break;
1415 case Allpass:1425 case Allpass:
1416 {1426 {
1417 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);1427 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1418 f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;1428 f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;
1419 }1429 }
1420 break;1430 break;
1421 1431
1422 // experimental - maybe we must find better curves for cL, cB, cH:1432 // experimental - maybe we must find better curves for cL, cB, cH:
1423 case Morph:1433 case Morph:
1424 {1434 {
1425 f->R2 = f->invG;1435 f->R2 = f->invG;
1426 float x = 2.0f*f->m-1.0f;1436 float x = 2.0f*f->m-1.0f;
1427 1437
1428 f->cL = maximum(-x, 0.0f); /*cL *= cL;*/1438 f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
1429 f->cH = minimum( x, 0.0f); /*cH *= cH;*/1439 f->cH = minimum( x, 0.0f); /*cH *= cH;*/
1430 f->cB = 1.0f-x*x;1440 f->cB = 1.0f-x*x;
1431 1441
1432 // bottom line: we need to test different versions for how they feel when tweaking the1442 // bottom line: we need to test different versions for how they feel when tweaking the
1433 // morph parameter1443 // morph parameter
1434 1444
1435 // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by1445 // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
1436 // the magnitude response value at the cutoff frequency and scale back by the gain):1446 // the magnitude response value at the cutoff frequency and scale back by the gain):
1437 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));1447 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));
1438 f->cL *= s; f->cB *= s; f->cH *= s;1448 f->cL *= s; f->cB *= s; f->cH *= s;
1439 }1449 }
1440 break;1450 break;
1441 1451
1442 }1452 }
1443 1453
1444 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation1454 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1445}1455}
1446 1456
1447void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const vf)1457void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const vf)
1448{1458{
1449
1450 _tVZFilter* f = *vf;1459 _tVZFilter* f = *vf;
1451 f->g = fastertanf(PI * f->fc * f->inv_sr); // embedded integrator gain (Fig 3.11)1460 f->g = fastertanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
1452 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);1461 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
1453 f->cB = f->R2;1462 f->cB = f->R2;
1454 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation1463 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1455}1464}
1456 1465
1457
1458
1459
1460void tVZFilter_setBandwidth (tVZFilter* const vf, float B)1466void tVZFilter_setBandwidth (tVZFilter* const vf, float B)
1461{1467{
1462 _tVZFilter* f = *vf;1468 _tVZFilter* f = *vf;
@@ -1466,33 +1472,28 @@ void tVZFilter_setBandwidth (tVZFilter* const vf, float B) · 3 unmodified lines
1466void tVZFilter_setFreq (tVZFilter* const vf, float freq)1472void tVZFilter_setFreq (tVZFilter* const vf, float freq)
1467{1473{
1468 _tVZFilter* f = *vf;1474 _tVZFilter* f = *vf;
1469 LEAF* leaf = f->mempool->leaf;
1470 1475
1471 f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);1476 f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
1472 tVZFilter_calcCoeffs(vf);1477 tVZFilter_calcCoeffs(vf);
1473}1478}
1474void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw)1479void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw)
1475{1480{
1476 _tVZFilter* f = *vf;1481 _tVZFilter* f = *vf;
1477 LEAF* leaf = f->mempool->leaf;
1478 1482
1479 f->B = LEAF_clip(0.0f,bw, 100.0f);1483 f->B = LEAF_clip(0.0f,bw, 100.0f);
1480 f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);1484 f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
1481 tVZFilter_calcCoeffs(vf);1485 tVZFilter_calcCoeffs(vf);
1482}1486}
1483 1487
1484void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw)1488void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw)
1485{1489{
1486 _tVZFilter* f = *vf;1490 _tVZFilter* f = *vf;
1487 LEAF* leaf = f->mempool->leaf;1491
1488
1489 f->B = LEAF_clip(0.0f,bw, 100.0f);1492 f->B = LEAF_clip(0.0f,bw, 100.0f);
1490 f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);1493 f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
1491 tVZFilter_calcCoeffsEfficientBP(vf);1494 tVZFilter_calcCoeffsEfficientBP(vf);
1492}1495}
1493 1496
1494
1495
1496void tVZFilter_setGain (tVZFilter* const vf, float gain)1497void tVZFilter_setGain (tVZFilter* const vf, float gain)
1497{1498{
1498 _tVZFilter* f = *vf;1499 _tVZFilter* f = *vf;
@@ -1501,8 +1502,6 @@ void tVZFilter_setGain (tVZFilter* const vf, float gain) · 2 unmodified lines
1501 tVZFilter_calcCoeffs(vf);1502 tVZFilter_calcCoeffs(vf);
1502}1503}
1503 1504
1504
1505
1506void tVZFilter_setMorph (tVZFilter* const vf, float morph)1505void tVZFilter_setMorph (tVZFilter* const vf, float morph)
1507{1506{
1508 _tVZFilter* f = *vf;1507 _tVZFilter* f = *vf;
@@ -1520,25 +1519,32 @@ void tVZFilter_setType (tVZFilter* const vf, VZFilterType type) · 11 unmodified lines
1520float tVZFilter_BandwidthToR(tVZFilter* const vf, float B)1519float tVZFilter_BandwidthToR(tVZFilter* const vf, float B)
1521{1520{
1522 _tVZFilter* f = *vf;1521 _tVZFilter* f = *vf;
1523 float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)1522 float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)
1524 float gl = tanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)1523 float gl = tanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
1525 float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies1524 float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1526 // unwarped: r = pow(2, -B/2) -> approximation for low1525 // unwarped: r = pow(2, -B/2) -> approximation for low
1527 // center-frequencies1526 // center-frequencies
1528 return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));1527 return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1529}1528}
1530 1529
1531float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B)1530float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B)
1532{1531{
1533 _tVZFilter* f = *vf;1532 _tVZFilter* f = *vf;
1534 float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)1533 float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)
1535 float gl = fastertanf(PI*fl*f->inv_sr); // warped radian lower bandedge frequency /(2*fs)1534 float gl = fastertanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
1536 float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies1535 float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1537 // unwarped: r = pow(2, -B/2) -> approximation for low1536 // unwarped: r = pow(2, -B/2) -> approximation for low
1538 // center-frequencies1537 // center-frequencies
1539 return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));1538 return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1540}1539}
1541 1540
1541void tVZFilter_setSampleRate (tVZFilter* const vf, float sr)
1542{
1543 _tVZFilter* f = *vf;
1544 f->sampleRate = sr;
1545 f->invSampleRate = 1.0f/f->sampleRate;
1546 tVZFilter_calcCoeffs(vf);
1547}
1542 1548
1543 1549
1544 1550
@@ -1549,26 +1555,28 @@ void tDiodeFilter_init (tDiodeFilter* const vf, float cutoff, float · 4 unmodified lines
1549 1555
1550void tDiodeFilter_initToPool (tDiodeFilter* const vf, float cutoff, float resonance, tMempool* const mp)1556void tDiodeFilter_initToPool (tDiodeFilter* const vf, float cutoff, float resonance, tMempool* const mp)
1551{1557{
1552 _tMempool* m = *mp;1558 _tMempool* m = *mp;
1553 _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);1559 _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
1554 f->mempool = m;1560 f->mempool = m;
1555 1561
1556 LEAF* leaf = f->mempool->leaf;1562 LEAF* leaf = f->mempool->leaf;
1557 1563
1558 // initialization (the resonance factor is between 0 and 8 according to the article)1564 f->invSampleRate = leaf->invSampleRate;
1559 f->f = (float)tan((double)(PI * cutoff/leaf->sampleRate));1565 f->cutoff = cutoff;
1560 f->r = (7.f * resonance + 0.5f);1566 // initialization (the resonance factor is between 0 and 8 according to the article)
1561 f->Vt = 0.5f;1567 f->f = (float)tan((double)(PI * cutoff * f->invSampleRate));
1562 f->n = 1.836f;1568 f->r = (7.f * resonance + 0.5f);
1563 f->zi = 0.0f; //previous input value1569 f->Vt = 0.5f;
1564 f->gamma = f->Vt*f->n;1570 f->n = 1.836f;
1565 f->s0 = 0.01f;1571 f->zi = 0.0f; //previous input value
1566 f->s1 = 0.02f;1572 f->gamma = f->Vt*f->n;
1567 f->s2 = 0.03f;1573 f->s0 = 0.01f;
1568 f->s3 = 0.04f;1574 f->s1 = 0.02f;
1569 f->g0inv = 1.f/(2.f*f->Vt);1575 f->s2 = 0.03f;
1570 f->g1inv = 1.f/(2.f*f->gamma);1576 f->s3 = 0.04f;
1571 f->g2inv = 1.f/(6.f*f->gamma);1577 f->g0inv = 1.f/(2.f*f->Vt);
1578 f->g1inv = 1.f/(2.f*f->gamma);
1579 f->g2inv = 1.f/(6.f*f->gamma);
1572}1580}
1573 1581
1574void tDiodeFilter_free (tDiodeFilter* const vf)1582void tDiodeFilter_free (tDiodeFilter* const vf)
@@ -1583,11 +1591,11 @@ float tanhXdX(float x) · 8 unmodified lines
1583 // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)1591 // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)
1584 float testVal = ((15.0f*a + 420.0f)*a + 945.0f);1592 float testVal = ((15.0f*a + 420.0f)*a + 945.0f);
1585 float output = 1.0f;1593 float output = 1.0f;
1586 1594
1587 if (testVal!= 0.0f)1595 if (testVal!= 0.0f)
1588 {1596 {
1589 output = testVal;1597 output = testVal;
1590 1598
1591 }1599 }
1592 return ((a + 105.0f)*a + 945.0f) / output;1600 return ((a + 105.0f)*a + 945.0f) / output;
1593}1601}
@@ -1595,31 +1603,29 @@ float tanhXdX(float x) · 1 unmodified line
1595float tDiodeFilter_tick (tDiodeFilter* const vf, float in)1603float tDiodeFilter_tick (tDiodeFilter* const vf, float in)
1596{1604{
1597 _tDiodeFilter* f = *vf;1605 _tDiodeFilter* f = *vf;
1598 1606
1599 int errorCheck = 0;1607 int errorCheck = 0;
1600 // the input x[n+1] is given by 'in', and x[n] by zi1608 // the input x[n+1] is given by 'in', and x[n] by zi
1601 // input with half delay1609 // input with half delay
1602 float ih = 0.5f * (in + f->zi);1610 float ih = 0.5f * (in + f->zi);
1603 1611
1604 // evaluate the non-linear factors1612 // evaluate the non-linear factors
1605 float t0 = f->f*tanhXdX((ih - f->r * f->s3)*f->g0inv)*f->g0inv;1613 float t0 = f->f*tanhXdX((ih - f->r * f->s3)*f->g0inv)*f->g0inv;
1606 float t1 = f->f*tanhXdX((f->s1-f->s0)*f->g1inv)*f->g1inv;1614 float t1 = f->f*tanhXdX((f->s1-f->s0)*f->g1inv)*f->g1inv;
1607 float t2 = f->f*tanhXdX((f->s2-f->s1)*f->g1inv)*f->g1inv;1615 float t2 = f->f*tanhXdX((f->s2-f->s1)*f->g1inv)*f->g1inv;
1608 float t3 = f->f*tanhXdX((f->s3-f->s2)*f->g1inv)*f->g1inv;1616 float t3 = f->f*tanhXdX((f->s3-f->s2)*f->g1inv)*f->g1inv;
1609 float t4 = f->f*tanhXdX((f->s3)*f->g2inv)*f->g2inv;1617 float t4 = f->f*tanhXdX((f->s3)*f->g2inv)*f->g2inv;
1610 1618
1611
1612
1613 // This formula gives the result for y3 thanks to MATLAB1619 // This formula gives the result for y3 thanks to MATLAB
1614 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);1620 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);
1615 if (isnan(y3))1621 if (isnan(y3))
1616 {1622 {
1617 errorCheck = 1;1623 errorCheck = 1;
1618 }1624 }
1619 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;1625 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;
1620 if (isnan(tempy3denom))1626 if (isnan(tempy3denom))
1621 {1627 {
1622 errorCheck = 2;1628 errorCheck = 2;
1623 }1629 }
1624 if (tempy3denom == 0.0f)1630 if (tempy3denom == 0.0f)
1625 {1631 {
@@ -1628,7 +1634,7 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 2 unmodified lines
1628 y3 = y3 / tempy3denom;1634 y3 = y3 / tempy3denom;
1629 if (isnan(y3))1635 if (isnan(y3))
1630 {1636 {
1631 errorCheck = 3;1637 errorCheck = 3;
1632 }1638 }
1633 if (t1 == 0.0f)1639 if (t1 == 0.0f)
1634 {1640 {
@@ -1647,42 +1653,45 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 12 unmodified lines
1647 float y1 = (f->s2 - (1+t3+t2)*y2 + t3*y3) / (-t2);1653 float y1 = (f->s2 - (1+t3+t2)*y2 + t3*y3) / (-t2);
1648 float y0 = (f->s1 - (1+t2+t1)*y1 + t2*y2) / (-t1);1654 float y0 = (f->s1 - (1+t2+t1)*y1 + t2*y2) / (-t1);
1649 float xx = (in - f->r*y3);1655 float xx = (in - f->r*y3);
1650 1656
1651 // update state1657 // update state
1652 f->s0 += 2.0f * (t0*xx + t1*(y1-y0));1658 f->s0 += 2.0f * (t0*xx + t1*(y1-y0));
1653 if (isnan(f->s0))1659 if (isnan(f->s0))
1654 {1660 {
1655 errorCheck = 4;1661 errorCheck = 4;
1656 }1662 }
1657 1663
1658 if (isinf(f->s0))1664 if (isinf(f->s0))
1659 {1665 {
1660 errorCheck = 5;1666 errorCheck = 5;
1661 }1667 }
1662 f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));1668 f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));
1663 f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));1669 f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));
1664 f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));1670 f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));
1665 1671
1666 f->zi = in;1672 f->zi = in;
1667 return y3*f->r;1673 return y3*f->r;
1668
1669}1674}
1670 1675
1671
1672
1673void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff)1676void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff)
1674{1677{
1675 _tDiodeFilter* f = *vf;1678 _tDiodeFilter* f = *vf;
1676 LEAF* leaf = f->mempool->leaf;
1677 1679
1678 f->f = tanf(PI * LEAF_clip(10.0f, cutoff, 20000.0f) * leaf->invSampleRate);1680 f->cutoff = LEAF_clip(10.0f, cutoff, 20000.0f);
1681 f->f = tanf(PI * f->cutoff * f->invSampleRate);
1679}1682}
1680 1683
1681
1682void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance)1684void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance)
1683{1685{
1684 _tDiodeFilter* f = *vf;1686 _tDiodeFilter* f = *vf;
1685 f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);1687 f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
1688}
1686 1689
1690void tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr)
1691{
1692 _tDiodeFilter* f = *vf;
1693
1694 f->invSampleRate = 1.0f/sr;
1695 f->f = tanf(PI * f->cutoff * f->invSampleRate);
1687}1696}
1688 1697
leaf/Src/leaf-instruments.c+47−0
@@ -141,6 +141,17 @@ void t808Cowbell_setStick(t808Cowbell* const cowbellInst, int useStick) · 140 unmodified lines
141 cowbell->useStick = useStick;141 cowbell->useStick = useStick;
142}142}
143 143
144void t808Cowbell_setSampleRate(t808Cowbell* const cowbellInst, float sr)
145{
146 _t808Cowbell* cowbell = *cowbellInst;
147
148 tSquare_setSampleRate(&cowbell->p[0], sr);
149 tSquare_setSampleRate(&cowbell->p[1], sr);
150 tSVF_setSampleRate(&cowbell->bandpassOsc, sr);
151 tSVF_setSampleRate(&cowbell->bandpassStick, sr);
152 tHighpass_setSampleRate(&cowbell->highpass, sr);
153}
154
144// ----------------- HIHAT ----------------------------//155// ----------------- HIHAT ----------------------------//
145 156
146void t808Hihat_init(t808Hihat* const hihatInst, LEAF* const leaf)157void t808Hihat_init(t808Hihat* const hihatInst, LEAF* const leaf)
@@ -309,6 +320,22 @@ void t808Hihat_setOscFreq(t808Hihat* const hihatInst, float freq) · 162 unmodified lines
309 hihat->freq = freq;320 hihat->freq = freq;
310}321}
311 322
323void t808Hihat_setSampleRate(t808Hihat* const hihatInst, float sr)
324{
325 _t808Hihat* hihat = *hihatInst;
326
327 for (int i = 0; i < 6; i++)
328 {
329 tSquare_setSampleRate(&hihat->p[i], sr);
330 }
331
332 // need to fix SVF to be generic
333 tSVF_setSampleRate(&hihat->bandpassStick, sr);
334 tSVF_setSampleRate(&hihat->bandpassOsc, sr);
335
336 tHighpass_setSampleRate(&hihat->highpass, sr);
337}
338
312// ----------------- SNARE ----------------------------//339// ----------------- SNARE ----------------------------//
313 340
314void t808Snare_init (t808Snare* const snareInst, LEAF* const leaf)341void t808Snare_init (t808Snare* const snareInst, LEAF* const leaf)
@@ -456,6 +483,18 @@ float t808Snare_tick(t808Snare* const snareInst) · 141 unmodified lines
456 return sample;483 return sample;
457}484}
458 485
486void t808Snare_setSampleRate(t808Snare* const snareInst, float sr)
487{
488 _t808Snare* snare = *snareInst;
489
490 for (int i = 0; i < 2; i++)
491 {
492 tTriangle_setSampleRate(&snare->tone[i], sr);
493 tSVF_setSampleRate(&snare->toneLowpass[i], sr);
494 }
495 tSVF_setSampleRate(&snare->noiseLowpass, sr);
496}
497
459// ----------------- KICK ----------------------------//498// ----------------- KICK ----------------------------//
460 499
461void t808Kick_init (t808Kick* const kickInst, LEAF* const leaf)500void t808Kick_init (t808Kick* const kickInst, LEAF* const leaf)
@@ -540,4 +579,12 @@ void t808Kick_setToneNoiseMix (t808Kick* const kickInst, float tone · 78 unmodified lines
540void t808Kick_setNoiseFilterFreq (t808Kick* const kickInst, float noiseFilterFreq);579void t808Kick_setNoiseFilterFreq (t808Kick* const kickInst, float noiseFilterFreq);
541void t808Kick_setNoiseFilterQ (t808Kick* const kickInst, float noiseFilterQ);580void t808Kick_setNoiseFilterQ (t808Kick* const kickInst, float noiseFilterQ);
542 581
582void t808Kick_setSampleRate (t808Kick* const kickInst, float sr)
583{
584 _t808Kick* kick = *kickInst;
585
586 tCycle_setSampleRate(&kick->tone, sr);
587 tSVF_setSampleRate(&kick->toneLowpass, sr);
588}
589
543 590
leaf/Src/leaf-midi.c+9−1
@@ -605,7 +605,15 @@ int tPoly_isOn(tPoly* const polyh, uint8_t voice) · 604 unmodified lines
605 return (poly->voices[voice][0] > 0) ? 1 : 0;605 return (poly->voices[voice][0] > 0) ? 1 : 0;
606}606}
607 607
608 608void tPoly_setSampleRate(tPoly* const polyh, float sr)
609{
610 _tPoly* poly = *polyh;
611 for (int i = 0; i < poly->maxNumVoices; i++)
612 {
613 tRamp_setSampleRate(&poly->ramps[i], sr);
614 }
615 tRamp_setSampleRate(&poly->pitchBendRamp, sr);
616}
609 617
610 618
611//tSimplePoly = much more efficient implementation without ramps and glide619//tSimplePoly = much more efficient implementation without ramps and glide
leaf/Src/leaf-oscillators.c+298−102
@@ -28,9 +28,11 @@ void tCycle_initToPool (tCycle* const cy, tMempool* const mp) · 27 unmodified lines
28 _tMempool* m = *mp;28 _tMempool* m = *mp;
29 _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m);29 _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m);
30 c->mempool = m;30 c->mempool = m;
31 LEAF* leaf = c->mempool->leaf;
31 32
32 c->inc = 0.0f;33 c->inc = 0.0f;
33 c->phase = 0.0f;34 c->phase = 0.0f;
35 c->invSampleRate = leaf->invSampleRate;
34}36}
35 37
36void tCycle_free (tCycle* const cy)38void tCycle_free (tCycle* const cy)
@@ -43,13 +45,12 @@ void tCycle_free (tCycle* const cy) · 6 unmodified lines
43void tCycle_setFreq(tCycle* const cy, float freq)45void tCycle_setFreq(tCycle* const cy, float freq)
44{46{
45 _tCycle* c = *cy;47 _tCycle* c = *cy;
46 LEAF* leaf = c->mempool->leaf;
47 48
48 if (!isfinite(freq)) return;49 if (!isfinite(freq)) return;
49 50
50 c->freq = freq;51 c->freq = freq;
51 52
52 c->inc = freq * leaf->invSampleRate;53 c->inc = freq * c->invSampleRate;
53 c->inc -= (int)c->inc;54 c->inc -= (int)c->inc;
54}55}
55 56
@@ -80,13 +81,12 @@ float tCycle_tick(tCycle* const cy) · 24 unmodified lines
80 return (samp0 + (samp1 - samp0) * frac);81 return (samp0 + (samp1 - samp0) * frac);
81}82}
82 83
83void tCycleSampleRateChanged (tCycle* const cy)84void tCycle_setSampleRate (tCycle* const cy, float sr)
84{85{
85 _tCycle* c = *cy;86 _tCycle* c = *cy;
86 LEAF* leaf = c->mempool->leaf;
87 87
88 c->inc = c->freq * leaf->invSampleRate;88 c->invSampleRate = 1.0f/sr;
89 c->inc -= (int)c->inc;89 tCycle_setFreq(cy, c->freq);
90}90}
91#endif // LEAF_INCLUDE_SINE_TABLE91#endif // LEAF_INCLUDE_SINE_TABLE
92 92
@@ -103,9 +103,11 @@ void tTriangle_initToPool (tTriangle* const cy, tMempool* const mp) · 10 unmodified lines
103 _tMempool* m = *mp;103 _tMempool* m = *mp;
104 _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m);104 _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m);
105 c->mempool = m;105 c->mempool = m;
106 LEAF* leaf = c->mempool->leaf;
106 107
107 c->inc = 0.0f;108 c->inc = 0.0f;
108 c->phase = 0.0f;109 c->phase = 0.0f;
110 c->invSampleRate = leaf->invSampleRate;
109 tTriangle_setFreq(cy, 220);111 tTriangle_setFreq(cy, 220);
110}112}
111 113
@@ -119,15 +121,14 @@ void tTriangle_free (tTriangle* const cy) · 7 unmodified lines
119void tTriangle_setFreq(tTriangle* const cy, float freq)121void tTriangle_setFreq(tTriangle* const cy, float freq)
120{122{
121 _tTriangle* c = *cy;123 _tTriangle* c = *cy;
122 LEAF* leaf = c->mempool->leaf;
123 124
124 c->freq = freq;125 c->freq = freq;
125 126
126 c->inc = c->freq * leaf->invSampleRate;127 c->inc = c->freq * c->invSampleRate;
127 c->inc -= (int)c->inc;128 c->inc -= (int)c->inc;
128 129
129 // abs for negative frequencies130 // abs for negative frequencies
130 c->w = fabsf(c->freq * (TRI_TABLE_SIZE * leaf->invSampleRate));131 c->w = fabsf(c->freq * (TRI_TABLE_SIZE * c->invSampleRate));
131 132
132 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing133 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
133 if (c->w < 0.0f) c->w = 0.0f;134 if (c->w < 0.0f) c->w = 0.0f;
@@ -173,13 +174,12 @@ float tTriangle_tick(tTriangle* const cy) · 39 unmodified lines
173 return oct0 + (oct1 - oct0) * c->w;174 return oct0 + (oct1 - oct0) * c->w;
174}175}
175 176
176void tTriangleSampleRateChanged (tTriangle* const cy)177void tTriangle_setSampleRate (tTriangle* const cy, float sr)
177{178{
178 _tTriangle* c = *cy;179 _tTriangle* c = *cy;
179 LEAF* leaf = c->mempool->leaf;
180 180
181 c->inc = c->freq * leaf->invSampleRate;181 c->invSampleRate = 1.0f/sr;
182 c->inc -= (int)c->inc;182 tTriangle_setFreq(cy, c->freq);
183}183}
184#endif // LEAF_INCLUDE_TRIANGLE_TABLE184#endif // LEAF_INCLUDE_TRIANGLE_TABLE
185 185
@@ -196,9 +196,11 @@ void tSquare_initToPool (tSquare* const cy, tMempool* const mp) · 10 unmodified lines
196 _tMempool* m = *mp;196 _tMempool* m = *mp;
197 _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m);197 _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m);
198 c->mempool = m;198 c->mempool = m;
199 LEAF* leaf = c->mempool->leaf;
199 200
200 c->inc = 0.0f;201 c->inc = 0.0f;
201 c->phase = 0.0f;202 c->phase = 0.0f;
203 c->invSampleRate = leaf->invSampleRate;
202 tSquare_setFreq(cy, 220);204 tSquare_setFreq(cy, 220);
203}205}
204 206
@@ -212,15 +214,14 @@ void tSquare_free (tSquare* const cy) · 7 unmodified lines
212void tSquare_setFreq(tSquare* const cy, float freq)214void tSquare_setFreq(tSquare* const cy, float freq)
213{215{
214 _tSquare* c = *cy;216 _tSquare* c = *cy;
215 LEAF* leaf = c->mempool->leaf;
216 217
217 c->freq = freq;218 c->freq = freq;
218 219
219 c->inc = c->freq * leaf->invSampleRate;220 c->inc = c->freq * c->invSampleRate;
220 c->inc -= (int)c->inc;221 c->inc -= (int)c->inc;
221 222
222 // abs for negative frequencies223 // abs for negative frequencies
223 c->w = fabsf(c->freq * (SQR_TABLE_SIZE * leaf->invSampleRate));224 c->w = fabsf(c->freq * (SQR_TABLE_SIZE * c->invSampleRate));
224 225
225 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing226 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
226 if (c->w < 0.0f) c->w = 0.0f;227 if (c->w < 0.0f) c->w = 0.0f;
@@ -265,13 +266,12 @@ float tSquare_tick(tSquare* const cy) · 38 unmodified lines
265 return oct0 + (oct1 - oct0) * c->w;266 return oct0 + (oct1 - oct0) * c->w;
266}267}
267 268
268void tSquareSampleRateChanged (tSquare* const cy)269void tSquare_setSampleRate (tSquare* const cy, float sr)
269{270{
270 _tSquare* c = *cy;271 _tSquare* c = *cy;
271 LEAF* leaf = c->mempool->leaf;
272 272
273 c->inc = c->freq * leaf->invSampleRate;273 c->invSampleRate = 1.0f/sr;
274 c->inc -= (int)c->inc;274 tSquare_setFreq(cy, c->freq);
275}275}
276#endif // LEAF_INCLUDE_SQUARE_TABLE276#endif // LEAF_INCLUDE_SQUARE_TABLE
277 277
@@ -288,9 +288,11 @@ void tSawtooth_initToPool (tSawtooth* const cy, tMempool* const mp) · 10 unmodified lines
288 _tMempool* m = *mp;288 _tMempool* m = *mp;
289 _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m);289 _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m);
290 c->mempool = m;290 c->mempool = m;
291 LEAF* leaf = c->mempool->leaf;
291 292
292 c->inc = 0.0f;293 c->inc = 0.0f;
293 c->phase = 0.0f;294 c->phase = 0.0f;
295 c->invSampleRate = leaf->invSampleRate;
294 tSawtooth_setFreq(cy, 220);296 tSawtooth_setFreq(cy, 220);
295}297}
296 298
@@ -304,15 +306,14 @@ void tSawtooth_free (tSawtooth* const cy) · 7 unmodified lines
304void tSawtooth_setFreq(tSawtooth* const cy, float freq)306void tSawtooth_setFreq(tSawtooth* const cy, float freq)
305{307{
306 _tSawtooth* c = *cy;308 _tSawtooth* c = *cy;
307 LEAF* leaf = c->mempool->leaf;
308 309
309 c->freq = freq;310 c->freq = freq;
310 311
311 c->inc = c->freq * leaf->invSampleRate;312 c->inc = c->freq * c->invSampleRate;
312 c->inc -= (int)c->inc;313 c->inc -= (int)c->inc;
313 314
314 // abs for negative frequencies315 // abs for negative frequencies
315 c->w = fabsf(c->freq * (SAW_TABLE_SIZE * leaf->invSampleRate));316 c->w = fabsf(c->freq * (SAW_TABLE_SIZE * c->invSampleRate));
316 317
317 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing318 c->w = log2f_approx(c->w);//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
318 if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq319 if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq
@@ -357,13 +358,12 @@ float tSawtooth_tick(tSawtooth* const cy) · 38 unmodified lines
357 return oct0 + (oct1 - oct0) * c->w;358 return oct0 + (oct1 - oct0) * c->w;
358}359}
359 360
360void tSawtoothSampleRateChanged (tSawtooth* const cy)361void tSawtooth_setSampleRate (tSawtooth* const cy, float sr)
361{362{
362 _tSawtooth* c = *cy;363 _tSawtooth* c = *cy;
363 LEAF* leaf = c->mempool->leaf;
364 364
365 c->inc = c->freq * leaf->invSampleRate;365 c->invSampleRate = 1.0f/sr;
366 c->inc -= (int)c->inc;366 tSawtooth_setFreq(cy, c->freq);
367}367}
368#endif // LEAF_INCLUDE_SAWTOOTH_TABLE368#endif // LEAF_INCLUDE_SAWTOOTH_TABLE
369 369
@@ -380,7 +380,9 @@ void tPBTriangle_initToPool (tPBTriangle* const osc, tMempool* const mp) · 10 unmodified lines
380 _tMempool* m = *mp;380 _tMempool* m = *mp;
381 _tPBTriangle* c = *osc = (_tPBTriangle*) mpool_alloc(sizeof(_tPBTriangle), m);381 _tPBTriangle* c = *osc = (_tPBTriangle*) mpool_alloc(sizeof(_tPBTriangle), m);
382 c->mempool = m;382 c->mempool = m;
383 LEAF* leaf = c->mempool->leaf;
383 384
385 c->invSampleRate = leaf->invSampleRate;
384 c->inc = 0.0f;386 c->inc = 0.0f;
385 c->phase = 0.0f;387 c->phase = 0.0f;
386 c->skew = 0.5f;388 c->skew = 0.5f;
@@ -428,10 +430,9 @@ float tPBTriangle_tick (tPBTriangle* const osc) · 41 unmodified lines
428void tPBTriangle_setFreq (tPBTriangle* const osc, float freq)430void tPBTriangle_setFreq (tPBTriangle* const osc, float freq)
429{431{
430 _tPBTriangle* c = *osc;432 _tPBTriangle* c = *osc;
431 LEAF* leaf = c->mempool->leaf;
432 433
433 c->freq = freq;434 c->freq = freq;
434 c->inc = freq * leaf->invSampleRate;435 c->inc = freq * c->invSampleRate;
435}436}
436 437
437void tPBTriangle_setSkew (tPBTriangle* const osc, float skew)438void tPBTriangle_setSkew (tPBTriangle* const osc, float skew)
@@ -440,6 +441,14 @@ void tPBTriangle_setSkew (tPBTriangle* const osc, float skew) · 2 unmodified lines
440 c->skew = (skew + 1.0f) * 0.5f;441 c->skew = (skew + 1.0f) * 0.5f;
441}442}
442 443
444void tPBTriangle_setSampleRate (tPBTriangle* const osc, float sr)
445{
446 _tPBTriangle* c = *osc;
447
448 c->invSampleRate = 1.0f/sr;
449 tPBTriangle_setFreq(osc, c->freq);
450}
451
443 452
444//==============================================================================453//==============================================================================
445 454
@@ -454,7 +463,9 @@ void tPBPulse_initToPool (tPBPulse* const osc, tMempool* const mp) · 8 unmodified lines
454 _tMempool* m = *mp;463 _tMempool* m = *mp;
455 _tPBPulse* c = *osc = (_tPBPulse*) mpool_alloc(sizeof(_tPBPulse), m);464 _tPBPulse* c = *osc = (_tPBPulse*) mpool_alloc(sizeof(_tPBPulse), m);
456 c->mempool = m;465 c->mempool = m;
466 LEAF* leaf = c->mempool->leaf;
457 467
468 c->invSampleRate = leaf->invSampleRate;
458 c->inc = 0.0f;469 c->inc = 0.0f;
459 c->phase = 0.0f;470 c->phase = 0.0f;
460 c->width = 0.5f;471 c->width = 0.5f;
@@ -487,10 +498,9 @@ float tPBPulse_tick (tPBPulse* const osc) · 26 unmodified lines
487void tPBPulse_setFreq (tPBPulse* const osc, float freq)498void tPBPulse_setFreq (tPBPulse* const osc, float freq)
488{499{
489 _tPBPulse* c = *osc;500 _tPBPulse* c = *osc;
490 LEAF* leaf = c->mempool->leaf;
491 501
492 c->freq = freq;502 c->freq = freq;
493 c->inc = freq * leaf->invSampleRate;503 c->inc = freq * c->invSampleRate;
494}504}
495 505
496void tPBPulse_setWidth (tPBPulse* const osc, float width)506void tPBPulse_setWidth (tPBPulse* const osc, float width)
@@ -499,6 +509,13 @@ void tPBPulse_setWidth (tPBPulse* const osc, float width) · 2 unmodified lines
499 c->width = width;509 c->width = width;
500}510}
501 511
512void tPBPulse_setSampleRate (tPBPulse* const osc, float sr)
513{
514 _tPBPulse* c = *osc;
515
516 c->invSampleRate = 1.0f/sr;
517 tPBPulse_setFreq(osc, c->freq);
518}
502 519
503//==============================================================================520//==============================================================================
504 521
@@ -513,9 +530,11 @@ void tPBSaw_initToPool (tPBSaw* const osc, tMempool* const mp) · 8 unmodified lines
513 _tMempool* m = *mp;530 _tMempool* m = *mp;
514 _tPBSaw* c = *osc = (_tPBSaw*) mpool_alloc(sizeof(_tPBSaw), m);531 _tPBSaw* c = *osc = (_tPBSaw*) mpool_alloc(sizeof(_tPBSaw), m);
515 c->mempool = m;532 c->mempool = m;
533 LEAF* leaf = c->mempool->leaf;
516 534
517 c->inc = 0.0f;535 c->inc = 0.0f;
518 c->phase = 0.0f;536 c->phase = 0.0f;
537 c->invSampleRate = leaf->invSampleRate;
519}538}
520 539
521void tPBSaw_free (tPBSaw* const osc)540void tPBSaw_free (tPBSaw* const osc)
@@ -542,22 +561,21 @@ float tPBSaw_tick (tPBSaw* const osc) · 20 unmodified lines
542void tPBSaw_setFreq (tPBSaw* const osc, float freq)561void tPBSaw_setFreq (tPBSaw* const osc, float freq)
543{562{
544 _tPBSaw* c = *osc;563 _tPBSaw* c = *osc;
545 LEAF* leaf = c->mempool->leaf;
546 564
547 c->freq = freq;565 c->freq = freq;
566 c->inc = freq * c->invSampleRate;
567}
568
569void tPBSaw_setSampleRate (tPBSaw* const osc, float sr)
570{
571 _tPBSaw* c = *osc;
548 572
549 c->inc = freq * leaf->invSampleRate;573 c->invSampleRate = 1.0f/sr;
574 tPBSaw_setFreq(osc, c->freq);
550}575}
551 576
552//========================================================================577//========================================================================
553/* Phasor */578/* Phasor */
554void tPhasorSampleRateChanged (tPhasor* const ph)
555{
556 _tPhasor* p = *ph;
557 LEAF* leaf = p->mempool->leaf;
558
559 p->inc = p->freq * leaf->invSampleRate;
560};
561 579
562void tPhasor_init(tPhasor* const ph, LEAF* const leaf)580void tPhasor_init(tPhasor* const ph, LEAF* const leaf)
563{581{
@@ -569,10 +587,12 @@ void tPhasor_initToPool (tPhasor* const ph, tMempool* const mp) · 5 unmodified lines
569 _tMempool* m = *mp;587 _tMempool* m = *mp;
570 _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m);588 _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m);
571 p->mempool = m;589 p->mempool = m;
590 LEAF* leaf = p->mempool->leaf;
572 591
573 p->phase = 0.0f;592 p->phase = 0.0f;
574 p->inc = 0.0f;593 p->inc = 0.0f;
575 p->phaseDidReset = 0;594 p->phaseDidReset = 0;
595 p->invSampleRate = leaf->invSampleRate;
576}596}
577 597
578void tPhasor_free (tPhasor* const ph)598void tPhasor_free (tPhasor* const ph)
@@ -585,11 +605,10 @@ void tPhasor_free (tPhasor* const ph) · 6 unmodified lines
585void tPhasor_setFreq(tPhasor* const ph, float freq)605void tPhasor_setFreq(tPhasor* const ph, float freq)
586{606{
587 _tPhasor* p = *ph;607 _tPhasor* p = *ph;
588 LEAF* leaf = p->mempool->leaf;
589 608
590 p->freq = freq;609 p->freq = freq;
591 610
592 p->inc = freq * leaf->invSampleRate;611 p->inc = freq * p->invSampleRate;
593 p->inc -= (int)p->inc;612 p->inc -= (int)p->inc;
594}613}
595 614
@@ -614,6 +633,15 @@ float tPhasor_tick(tPhasor* const ph) · 18 unmodified lines
614 return p->phase;633 return p->phase;
615}634}
616 635
636void tPhasor_setSampleRate (tPhasor* const ph, float sr)
637{
638 _tPhasor* p = *ph;
639
640 p->invSampleRate = 1.0f/sr;
641 tPhasor_setFreq(ph, p->freq);
642};
643
644//========================================================================
617/* Noise */645/* Noise */
618void tNoise_init(tNoise* const ns, NoiseType type, LEAF* const leaf)646void tNoise_init(tNoise* const ns, NoiseType type, LEAF* const leaf)
619{647{
@@ -662,11 +690,6 @@ float tNoise_tick(tNoise* const ns) · 42 unmodified lines
662//=================================================================================690//=================================================================================
663/* Neuron */691/* Neuron */
664 692
665void tNeuronSampleRateChanged(tNeuron* nr)
666{
667
668}
669
670void tNeuron_init(tNeuron* const nr, LEAF* const leaf)693void tNeuron_init(tNeuron* const nr, LEAF* const leaf)
671{694{
672 tNeuron_initToPool(nr, &leaf->mempool);695 tNeuron_initToPool(nr, &leaf->mempool);
@@ -677,7 +700,7 @@ void tNeuron_initToPool (tNeuron* const nr, tMempool* const mp) · 4 unmodified lines
677 _tMempool* m = *mp;700 _tMempool* m = *mp;
678 _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);701 _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);
679 n->mempool = m;702 n->mempool = m;
680 703
681 tPoleZero_initToPool(&n->f, mp);704 tPoleZero_initToPool(&n->f, mp);
682 705
683 tPoleZero_setBlockZero(&n->f, 0.99f);706 tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -748,7 +771,6 @@ void tNeuron_setV1(tNeuron* const nr, float V1) · 64 unmodified lines
748 n->V[0] = V1;771 n->V[0] = V1;
749}772}
750 773
751
752void tNeuron_setV2(tNeuron* const nr, float V2)774void tNeuron_setV2(tNeuron* const nr, float V2)
753{775{
754 _tNeuron* n = *nr;776 _tNeuron* n = *nr;
@@ -881,8 +903,6 @@ void tNeuron_setCurrent (tNeuron* const nr, float current) · 126 unmodified lines
881 n->current = current;903 n->current = current;
882}904}
883 905
884
885
886//----------------------------------------------------------------------------------------------------------906//----------------------------------------------------------------------------------------------------------
887 907
888void tMBPulse_init(tMBPulse* const osc, LEAF* const leaf)908void tMBPulse_init(tMBPulse* const osc, LEAF* const leaf)
@@ -895,6 +915,9 @@ void tMBPulse_initToPool(tMBPulse* const osc, tMempool* const pool) · 6 unmodified lines
895 _tMempool* m = *pool;915 _tMempool* m = *pool;
896 _tMBPulse* c = *osc = (_tMBPulse*) mpool_alloc(sizeof(_tMBPulse), m);916 _tMBPulse* c = *osc = (_tMBPulse*) mpool_alloc(sizeof(_tMBPulse), m);
897 c->mempool = m;917 c->mempool = m;
918 LEAF* leaf = c->mempool->leaf;
919
920 c->invSampleRate = leaf->invSampleRate;
898 921
899 c->_init = true;922 c->_init = true;
900 c->amp = 1.0f;923 c->amp = 1.0f;
@@ -918,7 +941,6 @@ void tMBPulse_free(tMBPulse* const osc) · 17 unmodified lines
918float tMBPulse_tick(tMBPulse* const osc)941float tMBPulse_tick(tMBPulse* const osc)
919{942{
920 _tMBPulse* c = *osc;943 _tMBPulse* c = *osc;
921 LEAF* leaf = c->mempool->leaf;
922 944
923 int j, k;945 int j, k;
924 float freq, sync;946 float freq, sync;
@@ -937,7 +959,7 @@ float tMBPulse_tick(tMBPulse* const osc) · 12 unmodified lines
937 if (c->_init) {959 if (c->_init) {
938 p = 0.0f;960 p = 0.0f;
939 961
940 w = freq * leaf->invSampleRate;962 w = freq * c->invSampleRate;
941 b = 0.5f * (1.0f + c->waveform );963 b = 0.5f * (1.0f + c->waveform );
942 964
943 /* for variable-width rectangular wave, we could do DC compensation with:965 /* for variable-width rectangular wave, we could do DC compensation with:
@@ -955,7 +977,7 @@ float tMBPulse_tick(tMBPulse* const osc) · 11 unmodified lines
955 // a = 0.2 + 0.8 * vco->_port [FILT];977 // a = 0.2 + 0.8 * vco->_port [FILT];
956 a = 0.5f; // when a = 1, LPfilter is disabled978 a = 0.5f; // when a = 1, LPfilter is disabled
957 979
958 w = freq * leaf->invSampleRate;980 w = freq * c->invSampleRate;
959 b = 0.5f * (1.0f + c->waveform);981 b = 0.5f * (1.0f + c->waveform);
960 982
961 if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;983 if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;
@@ -1177,6 +1199,12 @@ void tMBPulse_setSyncMode(tMBPulse* const osc, int hardOrSoft) · 215 unmodified lines
1177 c->softsync = hardOrSoft > 0 ? 1 : 0;1199 c->softsync = hardOrSoft > 0 ? 1 : 0;
1178}1200}
1179 1201
1202void tMBPulse_setSampleRate(tMBPulse* const osc, float sr)
1203{
1204 _tMBPulse* c = *osc;
1205 c->invSampleRate = 1.0f/sr;
1206}
1207
1180//==========================================================================================================1208//==========================================================================================================
1181//==========================================================================================================1209//==========================================================================================================
1182 1210
@@ -1190,7 +1218,9 @@ void tMBTriangle_initToPool(tMBTriangle* const osc, tMempool* const pool) · 7 unmodified lines
1190 _tMempool* m = *pool;1218 _tMempool* m = *pool;
1191 _tMBTriangle* c = *osc = (_tMBTriangle*) mpool_alloc(sizeof(_tMBTriangle), m);1219 _tMBTriangle* c = *osc = (_tMBTriangle*) mpool_alloc(sizeof(_tMBTriangle), m);
1192 c->mempool = m;1220 c->mempool = m;
1221 LEAF* leaf = c->mempool->leaf;
1193 1222
1223 c->invSampleRate = leaf->invSampleRate;
1194 c->amp = 1.0f;1224 c->amp = 1.0f;
1195 c->freq = 440.f;1225 c->freq = 440.f;
1196 c->lastsyncin = 0.0f;1226 c->lastsyncin = 0.0f;
@@ -1213,7 +1243,6 @@ void tMBTriangle_free(tMBTriangle* const osc) · 16 unmodified lines
1213float tMBTriangle_tick(tMBTriangle* const osc)1243float tMBTriangle_tick(tMBTriangle* const osc)
1214{1244{
1215 _tMBTriangle* c = *osc;1245 _tMBTriangle* c = *osc;
1216 LEAF* leaf = c->mempool->leaf;
1217 1246
1218 int j, k, dir;1247 int j, k, dir;
1219 float freq, sync;1248 float freq, sync;
@@ -1232,7 +1261,7 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 12 unmodified lines
1232 if (c->_init) {1261 if (c->_init) {
1233 // w = (exp2ap (freq[1] + vco->_port[OCTN] + vco->_port[TUNE] + expm[1] * vco->_port[EXPG] + 8.03136)1262 // w = (exp2ap (freq[1] + vco->_port[OCTN] + vco->_port[TUNE] + expm[1] * vco->_port[EXPG] + 8.03136)
1234 // + 1e3 * linm[1] * vco->_port[LING]) / SAMPLERATE;1263 // + 1e3 * linm[1] * vco->_port[LING]) / SAMPLERATE;
1235 w = freq * leaf->invSampleRate;1264 w = freq * c->invSampleRate;
1236 b = 0.5f * (1.0f + c->waveform);1265 b = 0.5f * (1.0f + c->waveform);
1237 p = 0.5f * b;1266 p = 0.5f * b;
1238 /* if we valued alias-free startup over low startup time, we could do:1267 /* if we valued alias-free startup over low startup time, we could do:
@@ -1245,7 +1274,7 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 6 unmodified lines
1245 // a = 0.2 + 0.8 * vco->_port [FILT];1274 // a = 0.2 + 0.8 * vco->_port [FILT];
1246 a = 0.5f; // when a = 1, LPfilter is disabled1275 a = 0.5f; // when a = 1, LPfilter is disabled
1247 1276
1248 w = freq * leaf->invSampleRate;1277 w = freq * c->invSampleRate;
1249 b = 0.5f * (1.0f + c->waveform);1278 b = 0.5f * (1.0f + c->waveform);
1250 b1 = 1.0f - b;1279 b1 = 1.0f - b;
1251 1280
@@ -1472,6 +1501,12 @@ void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft) · 220 unmodified lines
1472 c->softsync = hardOrSoft > 0 ? 1 : 0;1501 c->softsync = hardOrSoft > 0 ? 1 : 0;
1473}1502}
1474 1503
1504void tMBTriangle_setSampleRate(tMBTriangle* const osc, float sr)
1505{
1506 _tMBTriangle* c = *osc;
1507 c->invSampleRate = 1.0f/sr;
1508}
1509
1475//==========================================================================================================1510//==========================================================================================================
1476//==========================================================================================================1511//==========================================================================================================
1477 1512
@@ -1485,7 +1520,9 @@ void tMBSaw_initToPool(tMBSaw* const osc, tMempool* const pool) · 7 unmodified lines
1485 _tMempool* m = *pool;1520 _tMempool* m = *pool;
1486 _tMBSaw* c = *osc = (_tMBSaw*) mpool_alloc(sizeof(_tMBSaw), m);1521 _tMBSaw* c = *osc = (_tMBSaw*) mpool_alloc(sizeof(_tMBSaw), m);
1487 c->mempool = m;1522 c->mempool = m;
1523 LEAF* leaf = c->mempool->leaf;
1488 1524
1525 c->invSampleRate = leaf->invSampleRate;
1489 c->_init = true;1526 c->_init = true;
1490 c->amp = 1.0f;1527 c->amp = 1.0f;
1491 c->freq = 440.f;1528 c->freq = 440.f;
@@ -1507,7 +1544,6 @@ void tMBSaw_free(tMBSaw* const osc) · 15 unmodified lines
1507float tMBSaw_tick(tMBSaw* const osc)1544float tMBSaw_tick(tMBSaw* const osc)
1508{1545{
1509 _tMBSaw* c = *osc;1546 _tMBSaw* c = *osc;
1510 LEAF* leaf = c->mempool->leaf;
1511 1547
1512 int j;1548 int j;
1513 float freq, sync;1549 float freq, sync;
@@ -1523,7 +1559,7 @@ float tMBSaw_tick(tMBSaw* const osc) · 9 unmodified lines
1523 1559
1524 if (c->_init) {1560 if (c->_init) {
1525 p = 0.5f;1561 p = 0.5f;
1526 w = freq * leaf->invSampleRate;1562 w = freq * c->invSampleRate;
1527 1563
1528 /* if we valued alias-free startup over low startup time, we could do:1564 /* if we valued alias-free startup over low startup time, we could do:
1529 * p -= w;1565 * p -= w;
@@ -1534,7 +1570,7 @@ float tMBSaw_tick(tMBSaw* const osc) · 4 unmodified lines
1534 //a = 0.2 + 0.8 * vco->_port [FILT];1570 //a = 0.2 + 0.8 * vco->_port [FILT];
1535 a = 0.5f; // when a = 1, LPfilter is disabled1571 a = 0.5f; // when a = 1, LPfilter is disabled
1536 1572
1537 w = freq * leaf->invSampleRate;1573 w = freq * c->invSampleRate;
1538 1574
1539 if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;1575 if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;
1540 // Should insert minblep for softsync?1576 // Should insert minblep for softsync?
@@ -1631,6 +1667,12 @@ void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft) · 90 unmodified lines
1631 c->softsync = hardOrSoft > 0 ? 1 : 0;1667 c->softsync = hardOrSoft > 0 ? 1 : 0;
1632}1668}
1633 1669
1670void tMBSaw_setSampleRate(tMBSaw* const osc, float sr)
1671{
1672 _tMBSaw* c = *osc;
1673 c->invSampleRate = 1.0f/sr;
1674}
1675
1634 1676
1635// WaveTable1677// WaveTable
1636void tTable_init(tTable* const cy, float* waveTable, int size, LEAF* const leaf)1678void tTable_init(tTable* const cy, float* waveTable, int size, LEAF* const leaf)
@@ -1643,11 +1685,13 @@ void tTable_initToPool(tTable* const cy, float* waveTable, int size, tMempool · 6 unmodified lines
1643 _tMempool* m = *mp;1685 _tMempool* m = *mp;
1644 _tTable* c = *cy = (_tTable*)mpool_alloc(sizeof(_tTable), m);1686 _tTable* c = *cy = (_tTable*)mpool_alloc(sizeof(_tTable), m);
1645 c->mempool = m;1687 c->mempool = m;
1688 LEAF* leaf = c->mempool->leaf;
1646 1689
1647 c->waveTable = waveTable;1690 c->waveTable = waveTable;
1648 c->size = size;1691 c->size = size;
1649 c->inc = 0.0f;1692 c->inc = 0.0f;
1650 c->phase = 0.0f;1693 c->phase = 0.0f;
1694 c->invSampleRate = leaf->invSampleRate;
1651}1695}
1652 1696
1653void tTable_free(tTable* const cy)1697void tTable_free(tTable* const cy)
@@ -1660,12 +1704,11 @@ void tTable_free(tTable* const cy) · 6 unmodified lines
1660void tTable_setFreq(tTable* const cy, float freq)1704void tTable_setFreq(tTable* const cy, float freq)
1661{1705{
1662 _tTable* c = *cy;1706 _tTable* c = *cy;
1663 LEAF* leaf = c->mempool->leaf;
1664 1707
1665 if (!isfinite(freq)) return;1708 if (!isfinite(freq)) return;
1666 1709
1667 c->freq = freq;1710 c->freq = freq;
1668 c->inc = freq * leaf->invSampleRate;1711 c->inc = freq * c->invSampleRate;
1669 c->inc -= (int)c->inc;1712 c->inc -= (int)c->inc;
1670}1713}
1671 1714
@@ -1695,13 +1738,11 @@ float tTable_tick(tTable* const cy) · 23 unmodified lines
1695 return (samp0 + (samp1 - samp0) * fracPart);1738 return (samp0 + (samp1 - samp0) * fracPart);
1696}1739}
1697 1740
1698void tTableSampleRateChanged(tTable* const cy)1741void tTable_setSampleRate(tTable* const cy, float sr)
1699{1742{
1700 _tTable* c = *cy;1743 _tTable* c = *cy;
1701 LEAF* leaf = c->mempool->leaf;1744 c->invSampleRate = 1.0f/sr;
1702 1745 tTable_setFreq(cy, c->freq);
1703 c->inc = c->freq * leaf->invSampleRate;
1704 c->inc -= (int)c->inc;
1705}1746}
1706 1747
1707void tWaveTable_init(tWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)1748void tWaveTable_init(tWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
@@ -1714,16 +1755,21 @@ void tWaveTable_initToPool(tWaveTable* const cy, float* table, int size, float m · 6 unmodified lines
1714 _tMempool* m = *mp;1755 _tMempool* m = *mp;
1715 _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);1756 _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);
1716 c->mempool = m;1757 c->mempool = m;
1758 LEAF* leaf = c->mempool->leaf;
1759
1760 c->sampleRate = leaf->sampleRate;
1761
1762 c->maxFreq = maxFreq;
1717 1763
1718 // Determine base frequency1764 // Determine base frequency
1719 c->baseFreq = m->leaf->sampleRate / (float) size;1765 c->baseFreq = c->sampleRate / (float) size;
1720 c->invBaseFreq = 1.0f / c->baseFreq;1766 c->invBaseFreq = 1.0f / c->baseFreq;
1721 1767
1722 // Determine how many tables we need1768 // Determine how many tables we need
1723 // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing1769 // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing
1724 c->numTables = 2;1770 c->numTables = 2;
1725 float f = c->baseFreq;1771 float f = c->baseFreq;
1726 while (f < maxFreq)1772 while (f < c->maxFreq)
1727 {1773 {
1728 c->numTables++;1774 c->numTables++;
1729 f *= 2.0f; // pass this multiplier in to set spacing of tables? would need to change setFreq too1775 f *= 2.0f; // pass this multiplier in to set spacing of tables? would need to change setFreq too
@@ -1732,20 +1778,22 @@ void tWaveTable_initToPool(tWaveTable* const cy, float* table, int size, float m · 2 unmodified lines
1732 c->size = size;1778 c->size = size;
1733 1779
1734 // Allocate memory for the tables1780 // Allocate memory for the tables
1735 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, m);1781 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
1736 for (int t = 0; t < c->numTables; ++t)1782 c->baseTable = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
1783 c->tables[0] = c->baseTable;
1784 for (int t = 1; t < c->numTables; ++t)
1737 {1785 {
1738 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, m);1786 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
1739 }1787 }
1740 1788
1741 // Copy table1789 // Copy table
1742 for (int i = 0; i < c->size; ++i)1790 for (int i = 0; i < c->size; ++i)
1743 {1791 {
1744 c->tables[0][i] = table[i];1792 c->baseTable[i] = table[i];
1745 }1793 }
1746 1794
1747 // Make bandlimited copies1795 // Make bandlimited copies
1748 f = m->leaf->sampleRate * 0.25; //start at half nyquist1796 f = c->sampleRate * 0.25; //start at half nyquist
1749 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.1797 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
1750 tButterworth_initToPool(&c->bl, 8, -1.0f, f, mp);1798 tButterworth_initToPool(&c->bl, 8, -1.0f, f, mp);
1751 for (int t = 1; t < c->numTables; ++t)1799 for (int t = 1; t < c->numTables; ++t)
@@ -1778,6 +1826,64 @@ void tWaveTable_free(tWaveTable* const cy) · 26 unmodified lines
1778 mpool_free((char*)c, c->mempool);1826 mpool_free((char*)c, c->mempool);
1779}1827}
1780 1828
1829void tWaveTable_setSampleRate(tWaveTable* const cy, float sr)
1830{
1831 _tWaveTable* c = *cy;
1832
1833 // Changing the sample rate of a wavetable requires up to partially reinitialize
1834 for (int t = 1; t < c->numTables; ++t)
1835 {
1836 mpool_free((char*)c->tables[t], c->mempool);
1837 }
1838 mpool_free((char*)c->tables, c->mempool);
1839
1840 c->sampleRate = sr;
1841
1842 // Determine base frequency
1843 c->baseFreq = c->sampleRate / (float) c->size;
1844 c->invBaseFreq = 1.0f / c->baseFreq;
1845
1846 // Determine how many tables we need
1847 // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing
1848 c->numTables = 2;
1849 float f = c->baseFreq;
1850 while (f < c->maxFreq)
1851 {
1852 c->numTables++;
1853 f *= 2.0f; // pass this multiplier in to set spacing of tables? would need to change setFreq too
1854 }
1855
1856 // Allocate memory for the tables
1857 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
1858 c->tables[0] = c->baseTable;
1859 for (int t = 1; t < c->numTables; ++t)
1860 {
1861 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, c->mempool);
1862 }
1863
1864 // Make bandlimited copies
1865 f = c->sampleRate * 0.25; //start at half nyquist
1866 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
1867 tButterworth_initToPool(&c->bl, 8, -1.0f, f, &c->mempool);
1868 tButterworth_setSampleRate(&c->bl, c->sampleRate);
1869 for (int t = 1; t < c->numTables; ++t)
1870 {
1871 tButterworth_setF2(&c->bl, f);
1872 // Do several passes here to prevent errors at the beginning of the waveform
1873 // Not sure how many passes to do, seem to need more as the filter cutoff goes down
1874 // 12 might be excessive but seems to work for now.
1875 for (int p = 0; p < 12; ++p)
1876 {
1877 for (int i = 0; i < c->size; ++i)
1878 {
1879 c->tables[t][i] = tButterworth_tick(&c->bl, c->tables[t-1][i]);
1880 }
1881 }
1882 f *= 0.5f; //halve the cutoff for next pass
1883 }
1884 tButterworth_free(&c->bl);
1885}
1886
1781//=======================================================================================1887//=======================================================================================
1782//=======================================================================================1888//=======================================================================================
1783 1889
@@ -1791,6 +1897,7 @@ void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* · 7 unmodified lines
1791 _tMempool* m = *mp;1897 _tMempool* m = *mp;
1792 _tWaveOsc* c = *cy = (_tWaveOsc*) mpool_alloc(sizeof(_tWaveOsc), m);1898 _tWaveOsc* c = *cy = (_tWaveOsc*) mpool_alloc(sizeof(_tWaveOsc), m);
1793 c->mempool = m;1899 c->mempool = m;
1900 LEAF* leaf = c->mempool->leaf;
1794 1901
1795 c->table = *table;1902 c->table = *table;
1796 1903
@@ -1799,6 +1906,8 @@ void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* · 2 unmodified lines
1799 c->phaseOffset = 0.0f;1906 c->phaseOffset = 0.0f;
1800 c->aa = 0.5f;1907 c->aa = 0.5f;
1801 1908
1909 c->invSampleRate = leaf->invSampleRate;
1910
1802 tWaveOsc_setFreq(cy, 220);1911 tWaveOsc_setFreq(cy, 220);
1803}1912}
1804 1913
@@ -1851,11 +1960,9 @@ void tWaveOsc_setFreq(tWaveOsc* const cy, float freq) · 46 unmodified lines
1851{1960{
1852 _tWaveOsc* c = *cy;1961 _tWaveOsc* c = *cy;
1853 1962
1854 LEAF* leaf = c->mempool->leaf;
1855
1856 c->freq = freq;1963 c->freq = freq;
1857 1964
1858 c->inc = c->freq * leaf->invSampleRate;1965 c->inc = c->freq * c->invSampleRate;
1859 c->inc -= (int)c->inc;1966 c->inc -= (int)c->inc;
1860 1967
1861 // abs for negative frequencies1968 // abs for negative frequencies
@@ -1885,6 +1992,13 @@ void tWaveOsc_setPhaseOffset(tWaveOsc* const cy, float phase) · 23 unmodified lines
1885 c->phaseOffset = phase - (int)phase;1992 c->phaseOffset = phase - (int)phase;
1886}1993}
1887 1994
1995void tWaveOsc_setSampleRate(tWaveOsc* const cy, float sr)
1996{
1997 _tWaveOsc* c = *cy;
1998 c->invSampleRate = 1.0f/sr;
1999 tWaveOsc_setFreq(cy, c->freq);
2000}
2001
1888//================================================================================================2002//================================================================================================
1889//================================================================================================2003//================================================================================================
1890 2004
@@ -2039,18 +2153,16 @@ void tWaveSynth_setIndexPhase(tWaveSynth* const cy, int i, float phase) · 148 unmodified lines
2039 }2153 }
2040}2154}
2041 2155
2042//void tWaveSynth_setIndexTable(tWaveSynth* const cy, int i, float* table, int size)2156void tWaveSynth_setSampleRate(tWaveSynth* const cy, float sr)
2043//{2157{
2044// _tWaveSynth* c = *cy;2158 _tWaveSynth* c = *cy;
2045// if (i >= c->numTables) return;2159
2046// if (2160 for (int i = 0; i < c->numTables; ++i)
2047// tWaveTable_free(&c->tables[i]);2161 {
2048// tWaveTable_initToPool(&c->tables[i], table, size, c->maxFreq, &c->mempool);2162 tWaveTable_setSampleRate(&c->tables[i], sr);
2049// for (int v = 0; v < c->numVoices; ++v)2163 for (int v = 0; v < c->numVoices; ++v) tWaveOsc_setSampleRate(&c->oscs[i][v], sr);
2050// {2164 }
2051// tWaveOsc_setFreq(&c->oscs[i][v], c->oscs[i][v]->freq);2165}
2052// }
2053//}
2054 2166
2055//=======================================================================================2167//=======================================================================================
2056//=======================================================================================2168//=======================================================================================
@@ -2065,9 +2177,14 @@ void tWaveTableS_initToPool(tWaveTableS* const cy, float* table, int size, float · 8 unmodified lines
2065 _tMempool* m = *mp;2177 _tMempool* m = *mp;
2066 _tWaveTableS* c = *cy = (_tWaveTableS*) mpool_alloc(sizeof(_tWaveTableS), m);2178 _tWaveTableS* c = *cy = (_tWaveTableS*) mpool_alloc(sizeof(_tWaveTableS), m);
2067 c->mempool = m;2179 c->mempool = m;
2180 LEAF* leaf = c->mempool->leaf;
2181
2182 c->sampleRate = leaf->sampleRate;
2183
2184 c->maxFreq = maxFreq;
2068 2185
2069 // Determine base frequency2186 // Determine base frequency
2070 c->baseFreq = m->leaf->sampleRate / (float) size;2187 c->baseFreq = c->sampleRate / (float) size;
2071 c->invBaseFreq = 1.0f / c->baseFreq;2188 c->invBaseFreq = 1.0f / c->baseFreq;
2072 2189
2073 // Determine how many tables we need2190 // Determine how many tables we need
@@ -2082,23 +2199,24 @@ void tWaveTableS_initToPool(tWaveTableS* const cy, float* table, int size, float · 8 unmodified lines
2082 // Allocate memory for the tables2199 // Allocate memory for the tables
2083 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);2200 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
2084 c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);2201 c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);
2085 int n = size;2202 c->sizes[0] = size;
2086 for (int t = 0; t < c->numTables; ++t)2203 c->baseTable = (float*) mpool_alloc(sizeof(float) * c->sizes[0], c->mempool);
2204 c->tables[0] = c->baseTable;
2205 for (int t = 1; t < c->numTables; ++t)
2087 {2206 {
2088 c->sizes[t] = n;2207 c->sizes[t] = c->sizes[t-1] / 2;
2089 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], m);2208 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], c->mempool);
2090 n = c->sizes[t] / 2;
2091 }2209 }
2092 2210
2093 // Copy table2211 // Copy table
2094 for (int i = 0; i < c->sizes[0]; ++i)2212 for (int i = 0; i < c->sizes[0]; ++i)
2095 {2213 {
2096 c->tables[0][i] = table[i];2214 c->baseTable[i] = table[i];
2097 }2215 }
2098 2216
2099 // Make bandlimited copies2217 // Make bandlimited copies
2100 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.2218 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
2101 tButterworth_initToPool(&c->bl, 8, -1.0f, m->leaf->sampleRate * 0.25f, mp);2219 tButterworth_initToPool(&c->bl, 8, -1.0f, c->sampleRate * 0.25f, mp);
2102 tOversampler_initToPool(&c->ds, 2, 1, mp);2220 tOversampler_initToPool(&c->ds, 2, 1, mp);
2103 for (int t = 1; t < c->numTables; ++t)2221 for (int t = 1; t < c->numTables; ++t)
2104 {2222 {
@@ -2130,6 +2248,67 @@ void tWaveTableS_free(tWaveTableS* const cy) · 25 unmodified lines
2130 mpool_free((char*)c, c->mempool);2248 mpool_free((char*)c, c->mempool);
2131}2249}
2132 2250
2251void tWaveTableS_setSampleRate(tWaveTableS* const cy, float sr)
2252{
2253 _tWaveTableS* c = *cy;
2254
2255 int size = c->sizes[0];
2256
2257 for (int t = 1; t < c->numTables; ++t)
2258 {
2259 mpool_free((char*)c->tables[t], c->mempool);
2260 }
2261 mpool_free((char*)c->tables, c->mempool);
2262 mpool_free((char*)c->sizes, c->mempool);
2263
2264 c->sampleRate = sr;
2265
2266 // Determine base frequency
2267 c->baseFreq = c->sampleRate / (float) size;
2268 c->invBaseFreq = 1.0f / c->baseFreq;
2269
2270 // Determine how many tables we need
2271 c->numTables = 2;
2272 float f = c->baseFreq;
2273 while (f < c->maxFreq)
2274 {
2275 c->numTables++;
2276 f *= 2.0f; // pass this multiplier in to set spacing of tables?
2277 }
2278
2279 // Allocate memory for the tables
2280 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
2281 c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);
2282 c->tables[0] = c->baseTable;
2283 c->sizes[0] = size;
2284 for (int t = 1; t < c->numTables; ++t)
2285 {
2286 c->sizes[t] = c->sizes[t-1] / 2;
2287 c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], c->mempool);
2288 }
2289
2290 // Make bandlimited copies
2291 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
2292 tButterworth_initToPool(&c->bl, 8, -1.0f, c->sampleRate * 0.25f, &c->mempool);
2293 tButterworth_setSampleRate(&c->bl, c->sampleRate);
2294 tOversampler_initToPool(&c->ds, 2, 1, &c->mempool);
2295 for (int t = 1; t < c->numTables; ++t)
2296 {
2297 // Similar to tWaveTable, doing multiple passes here helps, but not sure what number is optimal
2298 for (int p = 0; p < 12; ++p)
2299 {
2300 for (int i = 0; i < c->sizes[t]; ++i)
2301 {
2302 c->dsBuffer[0] = tButterworth_tick(&c->bl, c->tables[t-1][i*2]);
2303 c->dsBuffer[1] = tButterworth_tick(&c->bl, c->tables[t-1][(i*2)+1]);
2304 c->tables[t][i] = tOversampler_downsample(&c->ds, c->dsBuffer);
2305 }
2306 }
2307 }
2308 tOversampler_free(&c->ds);
2309 tButterworth_free(&c->bl);
2310}
2311
2133//================================================================================================2312//================================================================================================
2134//================================================================================================2313//================================================================================================
2135 2314
@@ -2143,7 +2322,9 @@ void tWaveOscS_initToPool(tWaveOscS* const cy, tWaveTableS* const table, tMempoo · 7 unmodified lines
2143 _tMempool* m = *mp;2322 _tMempool* m = *mp;
2144 _tWaveOscS* c = *cy = (_tWaveOscS*) mpool_alloc(sizeof(_tWaveOscS), m);2323 _tWaveOscS* c = *cy = (_tWaveOscS*) mpool_alloc(sizeof(_tWaveOscS), m);
2145 c->mempool = m;2324 c->mempool = m;
2325 LEAF* leaf = c->mempool->leaf;
2146 2326
2327 c->invSampleRate = leaf->invSampleRate;
2147 c->inc = 0.0f;2328 c->inc = 0.0f;
2148 c->phase = 0.0f;2329 c->phase = 0.0f;
2149 c->phaseOffset = 0.0f;2330 c->phaseOffset = 0.0f;
@@ -2201,12 +2382,10 @@ float tWaveOscS_tick(tWaveOscS* const cy) · 51 unmodified lines
2201void tWaveOscS_setFreq(tWaveOscS* const cy, float freq)2382void tWaveOscS_setFreq(tWaveOscS* const cy, float freq)
2202{2383{
2203 _tWaveOscS* c = *cy;2384 _tWaveOscS* c = *cy;
2204 2385
2205 LEAF* leaf = c->mempool->leaf;
2206
2207 c->freq = freq;2386 c->freq = freq;
2208 2387
2209 c->inc = c->freq * leaf->invSampleRate;2388 c->inc = c->freq * c->invSampleRate;
2210 c->inc -= (int)c->inc;2389 c->inc -= (int)c->inc;
2211 2390
2212 // abs for negative frequencies2391 // abs for negative frequencies
@@ -2233,6 +2412,13 @@ void tWaveOscS_setPhaseOffset(tWaveOscS* const cy, float phase) · 20 unmodified lines
2233 c->phaseOffset = phase - (int)phase;2412 c->phaseOffset = phase - (int)phase;
2234}2413}
2235 2414
2415void tWaveOscS_setSampleRate(tWaveOscS* const cy, float sr)
2416{
2417 _tWaveOscS* c = *cy;
2418 c->invSampleRate = 1.0f/sr;
2419 tWaveOscS_setFreq(cy, c->freq);
2420}
2421
2236//================================================================================================2422//================================================================================================
2237//================================================================================================2423//================================================================================================
2238 2424
@@ -2386,6 +2572,16 @@ void tWaveSynthS_setIndexPhase(tWaveSynthS* const cy, int i, float phase) · 147 unmodified lines
2386 tWaveOscS_setPhaseOffset(&c->oscs[i][v], phase);2572 tWaveOscS_setPhaseOffset(&c->oscs[i][v], phase);
2387 }2573 }
2388}2574}
2575
2576void tWaveSynthS_setSampleRate(tWaveSynthS* const cy, float sr)
2577{
2578 _tWaveSynthS* c = *cy;
2579 for (int i = 0; i < c->numTables; ++i)
2580 {
2581 tWaveTableS_setSampleRate(&c->tables[i], sr);
2582 for (int v = 0; v < c->numVoices; ++v) tWaveOscS_setSampleRate(&c->oscs[i][v], sr);
2583 }
2584}
2389//2585//
2390//void tWaveSynthS_setIndexTable(tWaveSynthS* const cy, int i, float* table, int size)2586//void tWaveSynthS_setIndexTable(tWaveSynthS* const cy, int i, float* table, int size)
2391//{2587//{
leaf/Src/leaf-physical.c+104−32
@@ -29,6 +29,8 @@ void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* · 28 unmodified lines
29 p->mempool = m;29 p->mempool = m;
30 LEAF* leaf = p->mempool->leaf;30 LEAF* leaf = p->mempool->leaf;
31 31
32 p->sampleRate = leaf->sampleRate;
33
32 if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;34 if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
33 35
34 tNoise_initToPool(&p->noise, WhiteNoise, mp);36 tNoise_initToPool(&p->noise, WhiteNoise, mp);
@@ -37,7 +39,7 @@ void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* · 2 unmodified lines
37 39
38 tOneZero_initToPool(&p->loopFilter, 0.0f, mp);40 tOneZero_initToPool(&p->loopFilter, 0.0f, mp);
39 41
40 tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);42 tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
41 tAllpassDelay_clear(&p->delayLine);43 tAllpassDelay_clear(&p->delayLine);
42 44
43 tPluck_setFrequency(pl, 220.0f);45 tPluck_setFrequency(pl, 220.0f);
@@ -106,19 +108,17 @@ void tPluck_noteOff (tPluck* const pl, float amplitude ) · 62 unmodified lines
106void tPluck_setFrequency (tPluck* const pl, float frequency )108void tPluck_setFrequency (tPluck* const pl, float frequency )
107{109{
108 _tPluck* p = *pl;110 _tPluck* p = *pl;
109 LEAF* leaf = p->mempool->leaf;
110 111
111 if ( frequency <= 0.0f ) frequency = 0.001f;112 if ( frequency <= 0.0f ) frequency = 0.001f;
112 113
113 // Delay = length - filter delay.114 // Delay = length - filter delay.
114 float delay = ( leaf->sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );115 float delay = ( p->sampleRate / frequency ) - tOneZero_getPhaseDelay(&p->loopFilter, frequency );
115 116
116 tAllpassDelay_setDelay(&p->delayLine, delay );117 tAllpassDelay_setDelay(&p->delayLine, delay );
117 118
118 p->loopGain = 0.99f + (frequency * 0.000005f);119 p->loopGain = 0.99f + (frequency * 0.000005f);
119 120
120 if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;121 if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;
121
122}122}
123 123
124// Perform the control change specified by \e number and \e value (0.0 - 128.0).124// Perform the control change specified by \e number and \e value (0.0 - 128.0).
@@ -127,10 +127,18 @@ void tPluck_controlChange (tPluck* const pl, int number, float value) · 2 unmodified lines
127 return;127 return;
128}128}
129 129
130void tPluckSampleRateChanged(tPluck* const pl)130void tPluck_setSampleRate(tPluck* const pl, float sr)
131{131{
132 _tPluck* p = *pl;132 _tPluck* p = *pl;
133 p->sampleRate = sr;
134
135 tAllpassDelay_free(&p->delayLine);
136 tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, &p->mempool);
137 tAllpassDelay_clear(&p->delayLine);
138
133 tPluck_setFrequency(pl, p->lastFreq);139 tPluck_setFrequency(pl, p->lastFreq);
140 tOnePole_setSampleRate(&p->pickFilter, p->sampleRate);
141 tOneZero_setSampleRate(&p->loopFilter, p->sampleRate);
134}142}
135 143
136/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */144/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -146,12 +154,14 @@ void tKarplusStrong_initToPool (tKarplusStrong* const pl, float lowestFrequ · 9 unmodified lines
146 p->mempool = m;154 p->mempool = m;
147 LEAF* leaf = p->mempool->leaf;155 LEAF* leaf = p->mempool->leaf;
148 156
157 p->sampleRate = leaf->sampleRate;
158
149 if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;159 if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
150 160
151 tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);161 tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
152 tAllpassDelay_clear(&p->delayLine);162 tAllpassDelay_clear(&p->delayLine);
153 163
154 tLinearDelay_initToPool(&p->combDelay, 0.0f, leaf->sampleRate * 2, mp);164 tLinearDelay_initToPool(&p->combDelay, 0.0f, p->sampleRate * 2, mp);
155 tLinearDelay_clear(&p->combDelay);165 tLinearDelay_clear(&p->combDelay);
156 166
157 tOneZero_initToPool(&p->filter, 0.0f, mp);167 tOneZero_initToPool(&p->filter, 0.0f, mp);
@@ -254,12 +264,11 @@ void tKarplusStrong_noteOff (tKarplusStrong* const pl, float amplitude · 96 unmodified lines
254void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency )264void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency )
255{265{
256 _tKarplusStrong* p = *pl;266 _tKarplusStrong* p = *pl;
257 LEAF* leaf = p->mempool->leaf;
258 267
259 if ( frequency <= 0.0f ) frequency = 0.001f;268 if ( frequency <= 0.0f ) frequency = 0.001f;
260 269
261 p->lastFrequency = frequency;270 p->lastFrequency = frequency;
262 p->lastLength = leaf->sampleRate / p->lastFrequency;271 p->lastLength = p->sampleRate / p->lastFrequency;
263 float delay = p->lastLength - 0.5f;272 float delay = p->lastLength - 0.5f;
264 tAllpassDelay_setDelay(&p->delayLine, delay);273 tAllpassDelay_setDelay(&p->delayLine, delay);
265 274
@@ -270,19 +279,17 @@ void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency · 4 unmodified lines
270 tKarplusStrong_setStretch(pl, p->stretching);279 tKarplusStrong_setStretch(pl, p->stretching);
271 280
272 tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );281 tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
273
274}282}
275 283
276// Set the stretch "factor" of the string (0.0 - 1.0).284// Set the stretch "factor" of the string (0.0 - 1.0).
277void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stretch)285void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stretch)
278{286{
279 _tKarplusStrong* p = *pl;287 _tKarplusStrong* p = *pl;
280 LEAF* leaf = p->mempool->leaf;
281 288
282 p->stretching = stretch;289 p->stretching = stretch;
283 float coefficient;290 float coefficient;
284 float freq = p->lastFrequency * 2.0f;291 float freq = p->lastFrequency * 2.0f;
285 float dFreq = ( (0.5f * leaf->sampleRate) - freq ) * 0.25f;292 float dFreq = ( (0.5f * p->sampleRate) - freq ) * 0.25f;
286 float temp = 0.5f + (stretch * 0.5f);293 float temp = 0.5f + (stretch * 0.5f);
287 if ( temp > 0.9999f ) temp = 0.9999f;294 if ( temp > 0.9999f ) temp = 0.9999f;
288 295
@@ -293,7 +300,7 @@ void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stret · 4 unmodified lines
293 tBiQuad_setB0(&p->biquad[i], coefficient);300 tBiQuad_setB0(&p->biquad[i], coefficient);
294 tBiQuad_setB2(&p->biquad[i], 1.0f);301 tBiQuad_setB2(&p->biquad[i], 1.0f);
295 302
296 coefficient = -2.0f * temp * cosf(TWO_PI * freq / leaf->sampleRate);303 coefficient = -2.0f * temp * cosf(TWO_PI * freq / p->sampleRate);
297 tBiQuad_setA1(&p->biquad[i], coefficient);304 tBiQuad_setA1(&p->biquad[i], coefficient);
298 tBiQuad_setB1(&p->biquad[i], coefficient);305 tBiQuad_setB1(&p->biquad[i], coefficient);
299 306
@@ -339,12 +346,26 @@ void tKarplusStrong_controlChange (tKarplusStrong* const pl, SKControlType ty · 39 unmodified lines
339 tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );346 tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );
340}347}
341 348
342void tKarplusStrongSampleRateChanged (tKarplusStrong* const pl)349void tKarplusStrong_setSampleRate (tKarplusStrong* const pl, float sr)
343{350{
344 _tKarplusStrong* p = *pl;351 _tKarplusStrong* p = *pl;
352 p->sampleRate = sr;
353
354 tAllpassDelay_free(&p->delayLine);
355 tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, &p->mempool);
356 tAllpassDelay_clear(&p->delayLine);
357
358 tLinearDelay_free(&p->combDelay);
359 tLinearDelay_initToPool(&p->combDelay, 0.0f, p->sampleRate * 2, &p->mempool);
360 tLinearDelay_clear(&p->combDelay);
345 361
346 tKarplusStrong_setFrequency(pl, p->lastFrequency);362 tKarplusStrong_setFrequency(pl, p->lastFrequency);
347 tKarplusStrong_setStretch(pl, p->stretching);363 tOneZero_setSampleRate(&p->filter, p->sampleRate);
364
365 for (int i = 0; i < 4; i++)
366 {
367 tBiQuad_setSampleRate(&p->biquad[i], p->sampleRate);
368 }
348}369}
349 370
350/* Simple Living String*/371/* Simple Living String*/
@@ -365,8 +386,9 @@ void tSimpleLivingString_initToPool (tSimpleLivingString* const pl, float fr · 14 unmodified lines
365 p->mempool = m;386 p->mempool = m;
366 LEAF* leaf = p->mempool->leaf;387 LEAF* leaf = p->mempool->leaf;
367 388
389 p->sampleRate = leaf->sampleRate;
368 p->curr=0.0f;390 p->curr=0.0f;
369 tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)391 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
370 tSimpleLivingString_setFreq(pl, freq);392 tSimpleLivingString_setFreq(pl, freq);
371 tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);393 tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);
372 tLinearDelay_clear(&p->delayLine);394 tLinearDelay_clear(&p->delayLine);
@@ -393,11 +415,10 @@ void tSimpleLivingString_free (tSimpleLivingString* const pl) · 20 unmodified lines
393void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)415void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
394{416{
395 _tSimpleLivingString* p = *pl;417 _tSimpleLivingString* p = *pl;
396 LEAF* leaf = p->mempool->leaf;
397 418
398 if (freq<20) freq=20;419 if (freq<20) freq=20;
399 else if (freq>10000) freq=10000;420 else if (freq>10000) freq=10000;
400 p->waveLengthInSamples = leaf->sampleRate/freq;421 p->waveLengthInSamples = p->sampleRate/freq;
401 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);422 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
402}423}
403 424
@@ -466,6 +487,17 @@ float tSimpleLivingString_sample(tSimpleLivingString* const pl) · 62 unmodified lines
466 return p->curr;487 return p->curr;
467}488}
468 489
490void tSimpleLivingString_setSampleRate(tSimpleLivingString* const pl, float sr)
491{
492 _tSimpleLivingString* p = *pl;
493 float freq = p->sampleRate/p->waveLengthInSamples;
494 p->sampleRate = sr;
495 p->waveLengthInSamples = p->sampleRate/freq;
496 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
497 tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
498 tHighpass_setSampleRate(&p->DCblocker, p->sampleRate);
499}
500
469/* Living String*/501/* Living String*/
470 502
471void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex,503void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex,
@@ -484,8 +516,9 @@ void tLivingString_initToPool (tLivingString* const pl, float freq, float · 12 unmodified lines
484 p->mempool = m;516 p->mempool = m;
485 LEAF* leaf = p->mempool->leaf;517 LEAF* leaf = p->mempool->leaf;
486 518
519 p->sampleRate = leaf->sampleRate;
487 p->curr=0.0f;520 p->curr=0.0f;
488 tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)521 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
489 tLivingString_setFreq(pl, freq);522 tLivingString_setFreq(pl, freq);
490 p->freq = freq;523 p->freq = freq;
491 tExpSmooth_initToPool(&p->ppSmooth, pickPos, 0.01f, mp); // smoother for pick position524 tExpSmooth_initToPool(&p->ppSmooth, pickPos, 0.01f, mp); // smoother for pick position
@@ -538,11 +571,10 @@ void tLivingString_free (tLivingString* const pl) · 46 unmodified lines
538void tLivingString_setFreq(tLivingString* const pl, float freq)571void tLivingString_setFreq(tLivingString* const pl, float freq)
539{ // NOTE: It is faster to set wavelength in samples directly572{ // NOTE: It is faster to set wavelength in samples directly
540 _tLivingString* p = *pl;573 _tLivingString* p = *pl;
541 LEAF* leaf = p->mempool->leaf;
542 574
543 if (freq<20.f) freq=20.f;575 if (freq<20.f) freq=20.f;
544 else if (freq>10000.f) freq=10000.f;576 else if (freq>10000.f) freq=10000.f;
545 p->waveLengthInSamples = leaf->sampleRate/freq;577 p->waveLengthInSamples = p->sampleRate/freq;
546 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);578 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
547}579}
548 580
@@ -658,6 +690,21 @@ float tLivingString_sample(tLivingString* const pl) · 109 unmodified lines
658 return p->curr;690 return p->curr;
659}691}
660 692
693void tLivingString_setSampleRate(tLivingString* const pl, float sr)
694{
695 _tLivingString* p = *pl;
696 float freq = p->sampleRate/p->waveLengthInSamples;
697 p->sampleRate = sr;
698 p->waveLengthInSamples = p->sampleRate/freq;
699 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
700 tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
701 tOnePole_setSampleRate(&p->nutFilter, p->sampleRate);
702 tOnePole_setSampleRate(&p->prepFilterU, p->sampleRate);
703 tOnePole_setSampleRate(&p->prepFilterL, p->sampleRate);
704 tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
705 tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
706}
707
661 708
662//////////---------------------------709//////////---------------------------
663/* Version of Living String with Hermite Interpolation */710/* Version of Living String with Hermite Interpolation */
@@ -681,8 +728,9 @@ void tLivingString2_initToPool (tLivingString2* const pl, float freq, floa · 17 unmodified lines
681 p->mempool = m;728 p->mempool = m;
682 LEAF* leaf = p->mempool->leaf;729 LEAF* leaf = p->mempool->leaf;
683 730
731 p->sampleRate = leaf->sampleRate;
684 p->curr=0.0f;732 p->curr=0.0f;
685 tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.1f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)733 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.1f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
686 tLivingString2_setFreq(pl, freq);734 tLivingString2_setFreq(pl, freq);
687 p->freq = freq;735 p->freq = freq;
688 p->prepPos = prepPos;736 p->prepPos = prepPos;
@@ -742,24 +790,24 @@ void tLivingString2_free (tLivingString2* const pl) · 53 unmodified lines
742void tLivingString2_setFreq(tLivingString2* const pl, float freq)790void tLivingString2_setFreq(tLivingString2* const pl, float freq)
743{ // NOTE: It is faster to set wavelength in samples directly791{ // NOTE: It is faster to set wavelength in samples directly
744 _tLivingString2* p = *pl;792 _tLivingString2* p = *pl;
745 LEAF* leaf = p->mempool->leaf;793
746 if (freq<20.f) freq=20.f;794 if (freq<20.f) freq=20.f;
747 else if (freq>10000.f) freq=10000.f;795 else if (freq>10000.f) freq=10000.f;
748 freq = freq*2;796 freq = freq*2;
749 p->freq = freq;797 p->freq = freq;
750 p->waveLengthInSamples = (leaf->sampleRate/freq) - 1;798 p->waveLengthInSamples = (p->sampleRate/p->freq) - 1;
751 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);799 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
752}800}
753 801
754void tLivingString2_setWaveLength(tLivingString2* const pl, float waveLength)802void tLivingString2_setWaveLength(tLivingString2* const pl, float waveLength)
755{803{
756 _tLivingString2* p = *pl;804 _tLivingString2* p = *pl;
757 LEAF* leaf = p->mempool->leaf;805
758 waveLength = waveLength * 0.5f;806 waveLength = waveLength * 0.5f;
759 if (waveLength<4.8f) waveLength=4.8f;807 if (waveLength<4.8f) waveLength=4.8f;
760 else if (waveLength>2400.f) waveLength=2400.f;808 else if (waveLength>2400.f) waveLength=2400.f;
761 p->waveLengthInSamples = waveLength - 1;809 p->waveLengthInSamples = waveLength - 1;
762 p->freq = leaf->sampleRate / waveLength;810 p->freq = p->sampleRate / waveLength;
763 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);811 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
764}812}
765 813
@@ -927,7 +975,6 @@ float tLivingString2_tick(tLivingString2* const pl, float input) · 161 unmodified lines
927 tHermiteDelay_setDelay(&p->delLB, lowLen);975 tHermiteDelay_setDelay(&p->delLB, lowLen);
928 tHermiteDelay_setDelay(&p->delUF, upLen);976 tHermiteDelay_setDelay(&p->delUF, upLen);
929 tHermiteDelay_setDelay(&p->delUB, upLen);977 tHermiteDelay_setDelay(&p->delUB, upLen);
930
931 978
932 uint32_t pickupPosInt;979 uint32_t pickupPosInt;
933 float pickupOut = 0.0f;980 float pickupOut = 0.0f;
@@ -962,7 +1009,19 @@ float tLivingString2_sample(tLivingString2* const pl) · 28 unmodified lines
962 return p->curr;1009 return p->curr;
963}1010}
964 1011
965 1012void tLivingString2_setSampleRate(tLivingString2* const pl, float sr)
1013{
1014 _tLivingString2* p = *pl;
1015 p->sampleRate = sr;
1016 p->waveLengthInSamples = (p->sampleRate/p->freq) - 1;
1017 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
1018 tTwoZero_setSampleRate(&p->bridgeFilter, p->sampleRate);
1019 tTwoZero_setSampleRate(&p->nutFilter, p->sampleRate);
1020 tTwoZero_setSampleRate(&p->prepFilterU, p->sampleRate);
1021 tTwoZero_setSampleRate(&p->prepFilterL, p->sampleRate);
1022 tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
1023 tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
1024}
966 1025
967//////////---------------------------1026//////////---------------------------
968 1027
@@ -984,8 +1043,9 @@ void tComplexLivingString_initToPool (tComplexLivingString* const pl, floa · 15 unmodified lines
984 p->mempool = m;1043 p->mempool = m;
985 LEAF* leaf = p->mempool->leaf;1044 LEAF* leaf = p->mempool->leaf;
986 1045
1046 p->sampleRate = leaf->sampleRate;
987 p->curr=0.0f;1047 p->curr=0.0f;
988 tExpSmooth_initToPool(&p->wlSmooth, leaf->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)1048 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
989 tComplexLivingString_setFreq(pl, freq);1049 tComplexLivingString_setFreq(pl, freq);
990 p->freq = freq;1050 p->freq = freq;
991 tExpSmooth_initToPool(&p->pickPosSmooth, pickPos, 0.01f, mp); // smoother for pick position1051 tExpSmooth_initToPool(&p->pickPosSmooth, pickPos, 0.01f, mp); // smoother for pick position
@@ -1050,11 +1110,10 @@ void tComplexLivingString_free (tComplexLivingString* const pl) · 58 unmodified lines
1050void tComplexLivingString_setFreq(tComplexLivingString* const pl, float freq)1110void tComplexLivingString_setFreq(tComplexLivingString* const pl, float freq)
1051{ // NOTE: It is faster to set wavelength in samples directly1111{ // NOTE: It is faster to set wavelength in samples directly
1052 _tComplexLivingString* p = *pl;1112 _tComplexLivingString* p = *pl;
1053 LEAF* leaf = p->mempool->leaf;
1054 1113
1055 if (freq<20.0f) freq=20.0f;1114 if (freq<20.0f) freq=20.0f;
1056 else if (freq>10000.0f) freq=10000.0f;1115 else if (freq>10000.0f) freq=10000.0f;
1057 p->waveLengthInSamples = leaf->sampleRate/freq;1116 p->waveLengthInSamples = p->sampleRate/freq;
1058 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);1117 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
1059}1118}
1060 1119
@@ -1205,7 +1264,20 @@ float tComplexLivingString_sample(tComplexLivingString* const pl) · 144 unmodified lines
1205 return p->curr;1264 return p->curr;
1206}1265}
1207 1266
1208 1267void tComplexLivingString_setSampleRate(tComplexLivingString* const pl, float sr)
1268{
1269 _tComplexLivingString* p = *pl;
1270 float freq = p->waveLengthInSamples/p->sampleRate;
1271 p->sampleRate = sr;
1272 p->waveLengthInSamples = p->sampleRate/freq;
1273 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
1274 tOnePole_setSampleRate(&p->bridgeFilter, p->sampleRate);
1275 tOnePole_setSampleRate(&p->nutFilter, p->sampleRate);
1276 tOnePole_setSampleRate(&p->prepFilterU, p->sampleRate);
1277 tOnePole_setSampleRate(&p->prepFilterL, p->sampleRate);
1278 tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
1279 tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
1280}
1209 1281
1210///Reed Table model1282///Reed Table model
1211//default values from STK are 0.6 offset and -0.8 slope1283//default values from STK are 0.6 offset and -0.8 slope
leaf/Src/leaf-reverb.c+213−88
@@ -35,8 +35,11 @@ void tPRCReverb_initToPool (tPRCReverb* const rev, float t60, tMempool* con · 34 unmodified lines
35 35
36 r->inv_441 = 1.0f/44100.0f;36 r->inv_441 = 1.0f/44100.0f;
37 37
38 r->sampleRate = leaf->sampleRate;
39 r->invSampleRate = leaf->invSampleRate;
40
38 int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.41 int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
39 double scaler = leaf->sampleRate * r->inv_441;42 double scaler = r->sampleRate * r->inv_441;
40 43
41 int delay, i;44 int delay, i;
42 if (scaler != 1.0f)45 if (scaler != 1.0f)
@@ -85,14 +88,12 @@ void tPRCRevert_clear(tPRCReverb* const rev) · 42 unmodified lines
85void tPRCReverb_setT60(tPRCReverb* const rev, float t60)88void tPRCReverb_setT60(tPRCReverb* const rev, float t60)
86{89{
87 _tPRCReverb* r = *rev;90 _tPRCReverb* r = *rev;
88 LEAF* leaf = r->mempool->leaf;
89 91
90 if ( t60 <= 0.0f ) t60 = 0.001f;92 if ( t60 <= 0.0f ) t60 = 0.001f;
91 93
92 r->t60 = t60;94 r->t60 = t60;
93 95
94 r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf->invSampleRate / t60 ));96 r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * r->invSampleRate / t60 ));
95
96}97}
97 98
98void tPRCReverb_setMix(tPRCReverb* const rev, float mix)99void tPRCReverb_setMix(tPRCReverb* const rev, float mix)
@@ -135,12 +136,40 @@ float tPRCReverb_tick(tPRCReverb* const rev, float input) · 36 unmodified lines
135 return out;136 return out;
136}137}
137 138
138void tPRCReverbSampleRateChanged (tPRCReverb* const rev)139void tPRCReverb_setSampleRate (tPRCReverb* const rev, float sr)
139{140{
140 _tPRCReverb* r = *rev;141 _tPRCReverb* r = *rev;
141 LEAF* leaf = r->mempool->leaf;
142 142
143 r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf->invSampleRate / r->t60 ));143 r->sampleRate = sr;
144 r->invSampleRate = 1.0f/r->sampleRate;
145
146 int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
147 double scaler = r->sampleRate * r->inv_441;
148
149 int delay, i;
150 if (scaler != 1.0f)
151 {
152 for (i=0; i<4; i++)
153 {
154 delay = (int) scaler * lengths[i];
155
156 if ( (delay & 1) == 0) delay++;
157
158 while ( !LEAF_isPrime(delay) ) delay += 2;
159
160 lengths[i] = delay;
161 }
162 }
163
164 tDelay_free(&r->allpassDelays[0]);
165 tDelay_free(&r->allpassDelays[1]);
166 tDelay_free(&r->combDelay);
167
168 tDelay_initToPool(&r->allpassDelays[0], lengths[0], lengths[0] * 2, &r->mempool);
169 tDelay_initToPool(&r->allpassDelays[1], lengths[1], lengths[1] * 2, &r->mempool);
170 tDelay_initToPool(&r->combDelay, lengths[2], lengths[2] * 2, &r->mempool);
171
172 r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * r->invSampleRate / r->t60 ));
144}173}
145 174
146/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */175/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -159,9 +188,11 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 12 unmodified lines
159 if (t60 <= 0.0f) t60 = 0.001f;188 if (t60 <= 0.0f) t60 = 0.001f;
160 189
161 r->inv_441 = 1.0f/44100.0f;190 r->inv_441 = 1.0f/44100.0f;
191 r->sampleRate = leaf->sampleRate;
192 r->invSampleRate = leaf->invSampleRate;
162 193
163 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.194 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.
164 double scaler = leaf->sampleRate / 25641.0f;195 double scaler = r->sampleRate * r->inv_441;// / 25641.0f;
165 196
166 int delay, i;197 int delay, i;
167 198
@@ -179,7 +210,7 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 11 unmodified lines
179 {210 {
180 tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, mp);211 tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, mp);
181 tLinearDelay_clear(&r->combDelays[i]);212 tLinearDelay_clear(&r->combDelays[i]);
182 r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * leaf->invSampleRate / t60));213 r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * r->invSampleRate / t60));
183 }214 }
184 215
185 for ( i=0; i<8; i++ )216 for ( i=0; i<8; i++ )
@@ -188,7 +219,6 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 2 unmodified lines
188 tLinearDelay_clear(&r->allpassDelays[i]);219 tLinearDelay_clear(&r->allpassDelays[i]);
189 }220 }
190 221
191
192 tNReverb_setT60(rev, t60);222 tNReverb_setT60(rev, t60);
193 r->allpassCoeff = 0.7f;223 r->allpassCoeff = 0.7f;
194 r->mix = 0.3f;224 r->mix = 0.3f;
@@ -214,14 +244,12 @@ void tNReverb_free (tNReverb* const rev) · 19 unmodified lines
214void tNReverb_setT60(tNReverb* const rev, float t60)244void tNReverb_setT60(tNReverb* const rev, float t60)
215{245{
216 _tNReverb* r = *rev;246 _tNReverb* r = *rev;
217 LEAF* leaf = r->mempool->leaf;
218 247
219 if (t60 <= 0.0f) t60 = 0.001f;248 if (t60 <= 0.0f) t60 = 0.001f;
220 249
221 r->t60 = t60;250 r->t60 = t60;
222 251
223 for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * leaf->invSampleRate / t60 ));252 for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * r->invSampleRate / t60 ));
224
225}253}
226 254
227void tNReverb_setMix(tNReverb* const rev, float mix)255void tNReverb_setMix(tNReverb* const rev, float mix)
@@ -344,7 +372,6 @@ void tNReverb_tickStereo(tNReverb* const rev, float input, float* output) · 116 unmodified lines
344 output[0] = -( r->allpassCoeff * temp2 ) + temp + drymix;372 output[0] = -( r->allpassCoeff * temp2 ) + temp + drymix;
345 out = output[0];373 out = output[0];
346 374
347
348 temp = tLinearDelay_getLastOut(&r->allpassDelays[5]);375 temp = tLinearDelay_getLastOut(&r->allpassDelays[5]);
349 temp3 = r->allpassCoeff * temp;376 temp3 = r->allpassCoeff * temp;
350 temp3 += temp1;377 temp3 += temp1;
@@ -354,12 +381,44 @@ void tNReverb_tickStereo(tNReverb* const rev, float input, float* output) · 3 unmodified lines
354 r->lastOut = out;381 r->lastOut = out;
355}382}
356 383
357void tNReverbSampleRateChanged (tNReverb* const rev)384void tNReverb_setSampleRate (tNReverb* const rev, float sr)
358{385{
359 _tNReverb* r = *rev;386 _tNReverb* r = *rev;
360 LEAF* leaf = r->mempool->leaf;
361 387
362 for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * leaf->invSampleRate / r->t60 ));388 r->sampleRate = sr;
389 r->invSampleRate = 1.0f/r->sampleRate;
390
391 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.
392 double scaler = r->sampleRate * r->inv_441;// / 25641.0f;
393
394 int delay, i;
395
396 for (i=0; i < 15; i++)
397 {
398 delay = (int) scaler * lengths[i];
399 if ( (delay & 1) == 0)
400 delay++;
401 while ( !LEAF_isPrime(delay) )
402 delay += 2;
403 lengths[i] = delay;
404 }
405
406 for ( i=0; i<6; i++ )
407 {
408 tLinearDelay_free(&r->combDelays[i]);
409 tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, &r->mempool);
410 tLinearDelay_clear(&r->combDelays[i]);
411 r->combCoeffs[i] = powf(10.0f, (-3.0f * (float)lengths[i] * r->invSampleRate / r->t60));
412 }
413
414 for ( i=0; i<8; i++ )
415 {
416 tLinearDelay_free(&r->allpassDelays[i]);
417 tLinearDelay_initToPool(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2, &r->mempool);
418 tLinearDelay_clear(&r->allpassDelays[i]);
419 }
420
421 tNReverb_setT60(rev, r->t60);
363}422}
364 423
365// ======================================DATTORRO=========================================424// ======================================DATTORRO=========================================
@@ -369,7 +428,6 @@ void tNReverbSampleRateChanged (tNReverb* const rev) · 3 unmodified lines
369float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };428float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
370float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };429float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
371 430
372
373void tDattorroReverb_init (tDattorroReverb* const rev, LEAF* const leaf)431void tDattorroReverb_init (tDattorroReverb* const rev, LEAF* const leaf)
374{432{
375 tDattorroReverb_initToPool(rev, &leaf->mempool);433 tDattorroReverb_initToPool(rev, &leaf->mempool);
@@ -382,9 +440,11 @@ void tDattorroReverb_initToPool (tDattorroReverb* const rev, tMempool* · 6 unmodified lines
382 r->mempool = m;440 r->mempool = m;
383 LEAF* leaf = r->mempool->leaf;441 LEAF* leaf = r->mempool->leaf;
384 442
443 r->sampleRate = leaf->sampleRate;
444
385 r->size_max = 2.0f;445 r->size_max = 2.0f;
386 r->size = 1.f;446 r->size = 1.f;
387 r->t = r->size * leaf->sampleRate * 0.001f;447 r->t = r->size * r->sampleRate * 0.001f;
388 r->frozen = 0;448 r->frozen = 0;
389 // INPUT449 // INPUT
390 tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);450 tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);
@@ -426,16 +486,11 @@ void tDattorroReverb_initToPool (tDattorroReverb* const rev, tMempool* · 35 unmodified lines
426 tCycle_initToPool(&r->f2_lfo, mp);486 tCycle_initToPool(&r->f2_lfo, mp);
427 tCycle_setFreq(&r->f2_lfo, 0.07f);487 tCycle_setFreq(&r->f2_lfo, 0.07f);
428 488
429
430 // PARAMETERS489 // PARAMETERS
431 tDattorroReverb_setMix(rev, 0.5f);490 tDattorroReverb_setMix(rev, 0.5f);
432
433 tDattorroReverb_setInputDelay(rev, 0.f);491 tDattorroReverb_setInputDelay(rev, 0.f);
434
435 tDattorroReverb_setInputFilter(rev, 10000.f);492 tDattorroReverb_setInputFilter(rev, 10000.f);
436
437 tDattorroReverb_setFeedbackFilter(rev, 5000.f);493 tDattorroReverb_setFeedbackFilter(rev, 5000.f);
438
439 tDattorroReverb_setFeedbackGain(rev, 0.4f);494 tDattorroReverb_setFeedbackGain(rev, 0.4f);
440}495}
441 496
@@ -625,66 +680,65 @@ void tDattorroReverb_tickStereo (tDattorroReverb* const rev, floa · 183 unmodified lines
625 in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);680 in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
626 }681 }
627 682
628 683 // FEEDBACK 1
629 // FEEDBACK 1684 f1_sample = in_sample + r->f2_last; // + f2_last_out;
630 f1_sample = in_sample + r->f2_last; // + f2_last_out;685
631 686 tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
632 tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));687
633 688 f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
634 f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);689
635 690 f1_sample = tTapeDelay_tick(&r->f1_delay_1, f1_sample);
636 f1_sample = tTapeDelay_tick(&r->f1_delay_1, f1_sample);691
637 692 f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
638 f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);693
639 694 f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
640 f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;695
641 696 f1_delay_2_sample = tTapeDelay_tick(&r->f1_delay_2, f1_sample * 0.5f);
642 f1_delay_2_sample = tTapeDelay_tick(&r->f1_delay_2, f1_sample * 0.5f);697
643 698 r->f1_delay_2_last = f1_delay_2_sample;
644 r->f1_delay_2_last = f1_delay_2_sample;699
645 700 f1_sample = r->f1_delay_2_last + f1_sample;
646 f1_sample = r->f1_delay_2_last + f1_sample;701
647 702 f1_sample = tHighpass_tick(&r->f1_hp, f1_sample);
648 f1_sample = tHighpass_tick(&r->f1_hp, f1_sample);703
649 704 f1_sample *= r->feedback_gain;
650 f1_sample *= r->feedback_gain;705
651 706 if (r->frozen)
652 if (r->frozen)707 {
653 {708 f1_sample = 0.0f;
654 f1_sample = 0.0f;709 }
655 }710
656 711 r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
657 r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);712
658 713 // FEEDBACK 2
659 // FEEDBACK 2714 f2_sample = in_sample + r->f1_last;
660 f2_sample = in_sample + r->f1_last;715
661 716 tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
662 tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));717
663 718 f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
664 f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);719
665 720 f2_sample = tTapeDelay_tick(&r->f2_delay_1, f2_sample);
666 f2_sample = tTapeDelay_tick(&r->f2_delay_1, f2_sample);721
667 722 f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
668 f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);723
669 724 f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
670 f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;725
671 726 f2_delay_2_sample = tTapeDelay_tick(&r->f2_delay_2, f2_sample * 0.5f);
672 f2_delay_2_sample = tTapeDelay_tick(&r->f2_delay_2, f2_sample * 0.5f);727
673 728 r->f2_delay_2_last = f2_delay_2_sample;
674 r->f2_delay_2_last = f2_delay_2_sample;729
675 730 f2_sample = r->f2_delay_2_last + f2_sample;
676 f2_sample = r->f2_delay_2_last + f2_sample;731
677 732 f2_sample = tHighpass_tick(&r->f2_hp, f2_sample);
678 f2_sample = tHighpass_tick(&r->f2_hp, f2_sample);733
679 734 f2_sample *= r->feedback_gain;
680 f2_sample *= r->feedback_gain;735
681 736 if (r->frozen)
682 if (r->frozen)737 {
683 {738 f2_sample = 0.0f;
684 f2_sample = 0.0f;739 }
685 }740 r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
686 r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);741
687
688 742
689 743
690 // TAP OUT 1744 // TAP OUT 1
@@ -730,7 +784,7 @@ void tDattorroReverb_setMix (tDattorroReverb* const rev, float mix · 39 unmodified lines
730 r->mix = LEAF_clip(0.0f, mix, 1.0f);784 r->mix = LEAF_clip(0.0f, mix, 1.0f);
731}785}
732 786
733void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze)787void tDattorroReverb_setFreeze (tDattorroReverb* const rev, int freeze)
734{788{
735 _tDattorroReverb* r = *rev;789 _tDattorroReverb* r = *rev;
736 r->frozen = freeze;790 r->frozen = freeze;
@@ -772,10 +826,9 @@ void tDattorroReverb_setHP (tDattorroReverb* const rev, float freq) · 35 unmodified lines
772void tDattorroReverb_setSize (tDattorroReverb* const rev, float size)826void tDattorroReverb_setSize (tDattorroReverb* const rev, float size)
773{827{
774 _tDattorroReverb* r = *rev;828 _tDattorroReverb* r = *rev;
775 LEAF* leaf = r->mempool->leaf;
776 829
777 r->size = LEAF_clip(0.01f, size*r->size_max, r->size_max);830 r->size = LEAF_clip(0.01f, size*r->size_max, r->size_max);
778 r->t = r->size * leaf->sampleRate * 0.001f;831 r->t = r->size * r->sampleRate * 0.001f;
779 832
780 /*833 /*
781 for (int i = 0; i < 4; i++)834 for (int i = 0; i < 4; i++)
@@ -835,3 +888,75 @@ void tDattorroReverb_setFeedbackGain (tDattorroReverb* const rev, float gai · 53 unmodified lines
835 _tDattorroReverb* r = *rev;888 _tDattorroReverb* r = *rev;
836 r->feedback_gain = gain;889 r->feedback_gain = gain;
837}890}
891
892void tDattorroReverb_setSampleRate (tDattorroReverb* const rev, float sr)
893{
894 _tDattorroReverb* r = *rev;
895 tMempool* mp = &r->mempool;
896
897 r->sampleRate = sr;
898 r->t = r->size * r->sampleRate * 0.001f;
899
900 // INPUT
901 tTapeDelay_free(&r->in_delay);
902
903 for (int i = 0; i < 4; i++)
904 {
905 tAllpass_free(&r->in_allpass[i]);
906 }
907
908 // FEEDBACK 1
909 tAllpass_free(&r->f1_allpass);
910
911 tTapeDelay_free(&r->f1_delay_1);
912 tTapeDelay_free(&r->f1_delay_2);
913 tTapeDelay_free(&r->f1_delay_3);
914
915 // FEEDBACK 2
916 tAllpass_free(&r->f2_allpass);
917
918 tTapeDelay_free(&r->f2_delay_1);
919 tTapeDelay_free(&r->f2_delay_2);
920 tTapeDelay_free(&r->f2_delay_3);
921
922 // INPUT
923 tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);
924
925 for (int i = 0; i < 4; i++)
926 {
927 tAllpass_initToPool(&r->in_allpass[i], SAMP(in_allpass_delays[i]), SAMP(20.f), mp); // * r->size_max
928 tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
929 }
930
931 // FEEDBACK 1
932 tAllpass_initToPool(&r->f1_allpass, SAMP(30.51f), SAMP(100.f), mp); // * r->size_max
933 tAllpass_setGain(&r->f1_allpass, 0.7f);
934
935 tTapeDelay_initToPool(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f) * r->size_max + 1, mp);
936 tTapeDelay_initToPool(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f) * r->size_max + 1, mp);
937 tTapeDelay_initToPool(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f) * r->size_max + 1, mp);
938
939 // FEEDBACK 2
940 tAllpass_initToPool(&r->f2_allpass, SAMP(22.58f), SAMP(100.f), mp); // * r->size_max
941 tAllpass_setGain(&r->f2_allpass, 0.7f);
942
943 tTapeDelay_initToPool(&r->f2_delay_1, SAMP(149.62f), SAMP(200.f) * r->size_max + 1, mp);
944 tTapeDelay_initToPool(&r->f2_delay_2, SAMP(60.48f), SAMP(100.f) * r->size_max + 1, mp);
945 tTapeDelay_initToPool(&r->f2_delay_3, SAMP(106.28f), SAMP(200.f) * r->size_max + 1, mp);
946
947 tOnePole_setSampleRate(&r->in_filter, r->sampleRate);
948 tOnePole_setSampleRate(&r->f1_filter, r->sampleRate);
949 tHighpass_setSampleRate(&r->f1_hp, r->sampleRate);
950 tCycle_setSampleRate(&r->f1_lfo, r->sampleRate);
951 tOnePole_setSampleRate(&r->f2_filter, r->sampleRate);
952 tHighpass_setSampleRate(&r->f2_hp, r->sampleRate);
953 tCycle_setSampleRate(&r->f2_lfo, r->sampleRate);
954
955 // PARAMETERS
956 tDattorroReverb_setSize(rev, r->size*0.5f);
957 tDattorroReverb_setMix(rev, r->mix);
958 tDattorroReverb_setInputDelay(rev, r->predelay);
959 tDattorroReverb_setInputFilter(rev, r->input_filter);
960 tDattorroReverb_setFeedbackFilter(rev, r->feedback_filter);
961 tDattorroReverb_setFeedbackGain(rev, r->feedback_gain);
962}
leaf/Src/leaf-sampling.c+24−28
@@ -34,9 +34,10 @@ void tBuffer_initToPool (tBuffer* const sb, uint32_t length, tMempool* const mp · 33 unmodified lines
34 _tMempool* m = *mp;34 _tMempool* m = *mp;
35 _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);35 _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);
36 s->mempool = m;36 s->mempool = m;
37 LEAF* leaf = s->mempool->leaf;
37 38
38 s->buff = (float*) mpool_alloc( sizeof(float) * length, m);39 s->buff = (float*) mpool_alloc( sizeof(float) * length, m);
39 s->sampleRate = s->mempool->leaf->sampleRate;40 s->sampleRate = leaf->sampleRate;
40 s->channels = 1;41 s->channels = 1;
41 s->bufferLength = length;42 s->bufferLength = length;
42 s->recordedLength = 0;43 s->recordedLength = 0;
@@ -191,13 +192,12 @@ void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const m · 148 unmodified lines
191 192
192 _tBuffer* s = *b;193 _tBuffer* s = *b;
193 194
194 p->leafInvSampleRate = leaf->invSampleRate;195 p->invSampleRate = leaf->invSampleRate;
195 p->leafSampleRate = leaf->sampleRate;196 p->sampleRate = leaf->sampleRate;
196 p->ticksPerSevenMs = 0.007f * p->leafSampleRate;197 p->ticksPerSevenMs = 0.007f * p->sampleRate;
197 p->rateFactor = s->sampleRate * p->leafInvSampleRate;198 p->rateFactor = s->sampleRate * p->invSampleRate;
198 p->channels = s->channels;199 p->channels = s->channels;
199 200
200
201 p->samp = s;201 p->samp = s;
202 202
203 p->active = 0;203 p->active = 0;
@@ -255,9 +255,8 @@ void tSampler_setSample (tSampler* const sp, tBuffer* const b) · 51 unmodified lines
255 _tBuffer* s = *b;255 _tBuffer* s = *b;
256 256
257 p->samp = s;257 p->samp = s;
258
259 258
260 p->rateFactor = s->sampleRate * p->leafInvSampleRate;259 p->rateFactor = s->sampleRate * p->invSampleRate;
261 p->channels = s->channels;260 p->channels = s->channels;
262 261
263 p->start = 0;262 p->start = 0;
@@ -268,8 +267,6 @@ void tSampler_setSample (tSampler* const sp, tBuffer* const b) · 4 unmodified lines
268 p->idx = 0.f;267 p->idx = 0.f;
269}268}
270 269
271
272
273float tSampler_tick (tSampler* const sp)270float tSampler_tick (tSampler* const sp)
274{271{
275 _tSampler* p = *sp;272 _tSampler* p = *sp;
@@ -342,9 +339,6 @@ float tSampler_tick (tSampler* const sp) · 66 unmodified lines
342 int32_t fadeRightEnd = myEnd;// + (fadeLeftEnd - start);339 int32_t fadeRightEnd = myEnd;// + (fadeLeftEnd - start);
343 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;340 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;
344 int32_t fadeRightStart = fadeRightEnd - cfxlen;341 int32_t fadeRightStart = fadeRightEnd - cfxlen;
345
346
347
348 342
349 if (p->mode == PlayLoop)343 if (p->mode == PlayLoop)
350 {344 {
@@ -532,7 +526,6 @@ float tSampler_tick (tSampler* const sp) · 181 unmodified lines
532 return p->last;526 return p->last;
533}527}
534 528
535
536float tSampler_tickStereo (tSampler* const sp, float* outputArray)529float tSampler_tickStereo (tSampler* const sp, float* outputArray)
537{530{
538 _tSampler* p = *sp;531 _tSampler* p = *sp;
@@ -611,9 +604,6 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 72 unmodified lines
611 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;604 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;
612 int32_t fadeRightStart = fadeRightEnd - cfxlen;605 int32_t fadeRightStart = fadeRightEnd - cfxlen;
613 606
614
615
616
617 if (p->mode == PlayLoop)607 if (p->mode == PlayLoop)
618 {608 {
619 609
@@ -725,11 +715,8 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 105 unmodified lines
725 }715 }
726 }716 }
727 717
728
729
730 attemptStartEndChange(sp);718 attemptStartEndChange(sp);
731 719
732
733 if (p->mode == PlayLoop)720 if (p->mode == PlayLoop)
734 {721 {
735 if((int)p->idx < myStart)722 if((int)p->idx < myStart)
@@ -782,9 +769,6 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 46 unmodified lines
782 outputArray[i] = outputArray[i] * sampleGain;769 outputArray[i] = outputArray[i] * sampleGain;
783 }770 }
784 771
785
786
787
788 if (p->active < 0)772 if (p->active < 0)
789 {773 {
790 //if was fading out and reached silence774 //if was fading out and reached silence
@@ -816,11 +800,8 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 25 unmodified lines
816 }800 }
817 }801 }
818 802
819
820
821 p->last = outputArray[0];803 p->last = outputArray[0];
822 804
823
824 return p->last;805 return p->last;
825}806}
826 807
@@ -1089,6 +1070,18 @@ void tSampler_setRate (tSampler* const sp, float rate) · 262 unmodified lines
1089 p->iinc = 1.f / p->inc;1070 p->iinc = 1.f / p->inc;
1090}1071}
1091 1072
1073
1074void tSampler_setSampleRate(tSampler* const sp, float sr)
1075{
1076 _tSampler* p = *sp;
1077 _tBuffer* s = p->samp;
1078 p->sampleRate = sr;
1079 p->invSampleRate = 1.0f/p->sampleRate;
1080 p->ticksPerSevenMs = 0.007f * p->sampleRate;
1081 p->rateFactor = s->sampleRate * p->invSampleRate;
1082 tRamp_setSampleRate(&p->gain, p->sampleRate);
1083}
1084
1092//==============================================================================1085//==============================================================================
1093 1086
1094void tAutoSampler_init (tAutoSampler* const as, tBuffer* const b, LEAF* const leaf)1087void tAutoSampler_init (tAutoSampler* const as, tBuffer* const b, LEAF* const leaf)
@@ -1212,6 +1205,11 @@ void tAutoSampler_setRate (tAutoSampler* const as, float rate) · 117 unmodified lines
1212 ;1205 ;
1213}1206}
1214 1207
1208void tAutoSampler_setSampleRate (tAutoSampler* const as, float sr)
1209{
1210 _tAutoSampler* a = *as;
1211 tSampler_setSampleRate(&a->sampler, sr);
1212}
1215 1213
1216 1214
1217void tMBSampler_init(tMBSampler* const sp, tBuffer* const b, LEAF* const leaf)1215void tMBSampler_init(tMBSampler* const sp, tBuffer* const b, LEAF* const leaf)
@@ -1268,8 +1266,6 @@ void tMBSampler_setSample (tMBSampler* const sp, tBuffer* const b) · 50 unmodified lines
1268 p->_p = 0.0f;1266 p->_p = 0.0f;
1269}1267}
1270 1268
1271
1272
1273float tMBSampler_tick (tMBSampler* const sp)1269float tMBSampler_tick (tMBSampler* const sp)
1274{1270{
1275 _tMBSampler* c = *sp;1271 _tMBSampler* c = *sp;
leaf/Src/leaf.c+2−6
@@ -18,14 +18,12 @@ · 17 unmodified lines
18 18
19#endif19#endif
20 20
21void LEAF_init(LEAF* const leaf, float sr, int blocksize, char* memory, size_t memorysize, float(*random)(void))21void LEAF_init(LEAF* const leaf, float sr, char* memory, size_t memorysize, float(*random)(void))
22{22{
23 leaf->_internal_mempool.leaf = leaf;23 leaf->_internal_mempool.leaf = leaf;
24 leaf_pool_init(leaf, memory, memorysize);24 leaf_pool_init(leaf, memory, memorysize);
25 25
26 leaf->sampleRate = sr;26 leaf->sampleRate = sr;
27
28 leaf->blockSize = blocksize;
29 27
30 leaf->invSampleRate = 1.0f/sr;28 leaf->invSampleRate = 1.0f/sr;
31 29
@@ -45,13 +43,11 @@ void LEAF_init(LEAF* const leaf, float sr, int blocksize, char* memory, size_t m · 13 unmodified lines
45 leaf->freeCount = 0;43 leaf->freeCount = 0;
46}44}
47 45
48
49#define LEAFSampleRateChanged(THIS) leaf.THIS.sampleRateChanged(&leaf.THIS)
50
51void LEAF_setSampleRate(LEAF* const leaf, float sampleRate)46void LEAF_setSampleRate(LEAF* const leaf, float sampleRate)
52{47{
53 leaf->sampleRate = sampleRate;48 leaf->sampleRate = sampleRate;
54 leaf->invSampleRate = 1.0f/sampleRate;49 leaf->invSampleRate = 1.0f/sampleRate;
50 leaf->twoPiTimesInvSampleRate = leaf->invSampleRate * TWO_PI;
55}51}
56 52
57float LEAF_getSampleRate(LEAF* const leaf)53float LEAF_getSampleRate(LEAF* const leaf)
leaf/leaf.h+2−3
@@ -142,13 +142,12 @@ extern "C" { · 141 unmodified lines
142 142
143 //! Initialize the LEAF instance.143 //! Initialize the LEAF instance.
144 /*!144 /*!
145 @param sampleRate The audio sample rate.145 @param sampleRate The default sample rate for object initialized to this LEAF instance.
146 @param blockSize The audio block size.
147 @param memory A pointer to the memory that will make up the default mempool of a LEAF instance.146 @param memory A pointer to the memory that will make up the default mempool of a LEAF instance.
148 @param memorySize The size of the memory that will make up the default mempool of a LEAF instance.147 @param memorySize The size of the memory that will make up the default mempool of a LEAF instance.
149 @param random A pointer to a random number function. Should return a float >= 0 and < 1.148 @param random A pointer to a random number function. Should return a float >= 0 and < 1.
150 */149 */
151 void LEAF_init (LEAF* const leaf, float sampleRate, int blockSize, char* memory, size_t memorySize, float(*random)(void));150 void LEAF_init (LEAF* const leaf, float sampleRate, char* memory, size_t memorySize, float(*random)(void));
152 151
153 //! Set the sample rate of LEAF.152 //! Set the sample rate of LEAF.
154 /*!153 /*!

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