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
364364 float atk_coeff;
365365 float rel_coeff;
366366
367− int blocksize;
368− int samplerate;
367+ int blockSize;
368+ int sampleRate;
369369
370370 //RMS amplitude of previous block - used to decide if attack is present
371371 float prevAmp;
@@ -385,6 +385,7 @@ extern "C" { · 13 unmodified lines
385385 void tAttackDetection_setRelease (tAttackDetection* const, int inRel);
386386 void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
387387 int tAttackDetection_detect (tAttackDetection* const, float *in);
388+ void tAttackDetection_setSampleRate (tAttackDetection* const, float sr);
388389
389390 //==============================================================================
390391
@@ -593,6 +594,7 @@ extern "C" { · 202 unmodified lines
593594 float alpha;
594595 float tolerance;
595596
597+ float invSampleRate;
596598 } _tPeriodDetection;
597599
598600 typedef _tPeriodDetection* tPeriodDetection;
@@ -603,12 +605,13 @@ extern "C" { · 4 unmodified lines
603605
604606 float tPeriodDetection_tick (tPeriodDetection* const, float sample);
605607 float tPeriodDetection_getPeriod (tPeriodDetection* const);
606− float tPeriodDetection_getFidelity (tPeriodDetection* pd);
608+ float tPeriodDetection_getFidelity (tPeriodDetection* const);
607609 void tPeriodDetection_setHopSize (tPeriodDetection* const, int hs);
608610 void tPeriodDetection_setWindowSize (tPeriodDetection* const, int ws);
609611 void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const, float threshold);
610612 void tPeriodDetection_setAlpha (tPeriodDetection* const, float alpha);
611613 void tPeriodDetection_setTolerance (tPeriodDetection* const, float tolerance);
614+ void tPeriodDetection_setSampleRate (tPeriodDetection* const, float sr);
612615
613616 //==============================================================================
614617
@@ -644,7 +647,6 @@ extern "C" { · 29 unmodified lines
644647
645648 typedef struct _tZeroCrossingCollector
646649 {
647−
648650 tMempool mempool;
649651
650652 tZeroCrossingInfo* _info;
@@ -689,7 +691,6 @@ extern "C" { · 38 unmodified lines
689691
690692 typedef struct _tBitset
691693 {
692−
693694 tMempool mempool;
694695
695696 unsigned int _value_size;
@@ -718,7 +719,6 @@ extern "C" { · 22 unmodified lines
718719
719720 typedef struct _tBACF
720721 {
721−
722722 tMempool mempool;
723723
724724 tBitset _bitset;
@@ -806,7 +806,6 @@ extern "C" { · 81 unmodified lines
806806
807807 typedef struct _sub_collector
808808 {
809−
810809 tMempool mempool;
811810
812811 float _first_period;
@@ -845,6 +844,10 @@ extern "C" { · 32 unmodified lines
845844 unsigned int _num_pulses; // = 0;
846845 int _half_empty; // 0;
847846
847+ float sampleRate;
848+ float lowestFreq;
849+ float highestFreq;
850+
848851 tBACF _bacf;
849852
850853 } _tPeriodDetector;
@@ -866,6 +869,7 @@ extern "C" { · 15 unmodified lines
866869 int tPeriodDetector_isReset (tPeriodDetector* const detector);
867870
868871 void tPeriodDetector_setHysteresis (tPeriodDetector* const detector, float hysteresis);
872+ void tPeriodDetector_setSampleRate (tPeriodDetector* const detector, float sr);
869873
870874 //==============================================================================
871875
@@ -942,6 +946,8 @@ extern "C" { · 70 unmodified lines
942946 _pitch_info _current;
943947 int _frames_after_shift;// = 0;
944948
949+ float sampleRate;
950+
945951 } _tPitchDetector;
946952
947953 typedef _tPitchDetector* tPitchDetector;
@@ -958,7 +964,7 @@ extern "C" { · 10 unmodified lines
958964 int tPitchDetector_indeterminate (tPitchDetector* const detector);
959965
960966 void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis);
961−
967+ void tPitchDetector_setSampleRate (tPitchDetector* const detector, float sr);
962968
963969 //==============================================================================
964970
@@ -1041,6 +1047,8 @@ extern "C" { · 76 unmodified lines
10411047
10421048 float highest, lowest;
10431049 float thresh;
1050+
1051+ float sampleRate;
10441052
10451053 } _tDualPitchDetector;
10461054
@@ -1058,9 +1066,7 @@ extern "C" { · 11 unmodified lines
10581066
10591067 void tDualPitchDetector_setHysteresis (tDualPitchDetector* const detector, float hysteresis);
10601068 void tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const detector, float thresh);
1061−
1062−
1063−
1069+ void tDualPitchDetector_setSampleRate (tDualPitchDetector* const detector, float sr);
10641070
10651071 #ifdef __cplusplus
10661072 }
leaf/Inc/leaf-distortion.h+4−4
@@ -61,7 +61,6 @@ extern "C" { · 60 unmodified lines
6161
6262 typedef struct _tSampleReducer
6363 {
64−
6564 tMempool mempool;
6665 float invRatio;
6766 float hold;
@@ -124,9 +123,9 @@ extern "C" { · 56 unmodified lines
124123
125124 typedef struct _tOversampler
126125 {
127−
128126 tMempool mempool;
129127 int maxRatio;
128+ int allowHighQuality;
130129 int ratio;
131130 int offset;
132131 float* pCoeffs;
@@ -143,11 +142,12 @@ extern "C" { · 10 unmodified lines
143142 void tOversampler_free (tOversampler* const);
144143
145144 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);
147146 float tOversampler_tick (tOversampler* const, float input, float* oversample,
148147 float (*effectTick)(float));
149148 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);
151151
152152 //==============================================================================
153153
leaf/Inc/leaf-dynamics.h+2−0
@@ -69,6 +69,8 @@ extern "C" { · 68 unmodified lines
6969
7070 int isActive;
7171
72+ float sampleRate;
73+
7274 } _tCompressor;
7375
7476 typedef _tCompressor* tCompressor;
leaf/Inc/leaf-effects.h+89−69
@@ -1,7 +1,7 @@
11 /*==============================================================================
22
33 leaf-effects.h
4−
4+
55
66 ==============================================================================*/
77
@@ -20,8 +20,8 @@ extern "C" { · 12 unmodified lines
2020 #include "leaf-analysis.h"
2121 #include "leaf-envelopes.h"
2222
23−
24−
23+
24+
2525 //==============================================================================
2626
2727 /*!
@@ -89,7 +89,7 @@ extern "C" { · 61 unmodified lines
8989 @param talkbox A pointer to the relevant tTalkbox.
9090
9191 @} */
92−
92+
9393 #define NUM_TALKBOX_PARAM 4
9494
9595 typedef struct _tTalkbox
@@ -98,7 +98,7 @@ extern "C" { · 2 unmodified lines
9898 tMempool mempool;
9999
100100 float param[NUM_TALKBOX_PARAM];
101−
101+
102102 int bufsize;
103103 float* car0;
104104 float* car1;
@@ -117,7 +117,8 @@ extern "C" { · 12 unmodified lines
117117 float G;
118118 double* dl;
119119 double* Rt;
120−
120+
121+ float sampleRate;
121122
122123 } _tTalkbox;
123124
@@ -138,11 +139,12 @@ extern "C" { · 14 unmodified lines
138139 void tTalkbox_setWarpOn (tTalkbox* const voc, float warpOn);
139140 void tTalkbox_setFreeze (tTalkbox* const voc, float freeze);
140141 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);
141143
142144
143145 //==============================================================================
144146
145−
147+
146148 /*!
147149 @defgroup ttalkboxfloat tTalkboxFloat
148150 @ingroup effects
@@ -208,55 +210,58 @@ extern "C" { · 59 unmodified lines
208210 @param talkbox A pointer to the relevant tTalkboxFloat.
209211
210212 @} */
211−
213+
212214 typedef struct _tTalkboxFloat
213− {
214−
215− tMempool mempool;
216−
217− float param[NUM_TALKBOX_PARAM];
218−
219− int bufsize;
220− float* car0;
221− float* car1;
222− float* window;
223− float* buf0;
224− float* buf1;
225− float* k;
226− float warpFactor;
227− int32_t warpOn;
228− int freeze;
229− float emphasis;
230− int32_t K, N, O, pos;
231− float wet, dry, FX;
232− float d0, d1, d2, d3, d4;
233− float u0, u1, u2, u3, u4;
234− float G;
235− float* dl;
236− float* Rt;
237−
238− } _tTalkboxFloat;
239−
240− typedef _tTalkboxFloat* tTalkboxFloat;
241−
242− void tTalkboxFloat_init (tTalkboxFloat* const, int bufsize, LEAF* const leaf);
243− void tTalkboxFloat_initToPool (tTalkboxFloat* const, int bufsize, tMempool* const);
244− void tTalkboxFloat_free (tTalkboxFloat* const);
245−
246− float tTalkboxFloat_tick (tTalkboxFloat* const, float synth, float voice);
247− float tTalkboxFloat_tickFrozen (tTalkboxFloat* const voc, float synth, float voice);
248− void tTalkboxFloat_update (tTalkboxFloat* const);
249− void tTalkboxFloat_suspend (tTalkboxFloat* const);
250− void tTalkboxFloat_lpcDurbin (float *r, int p, float *k, float *g);
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);
252− void tTalkboxFloat_setQuality (tTalkboxFloat* const, float quality);
253− void tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);
254− void tTalkboxFloat_setWarpOn (tTalkboxFloat* const voc, int warpOn);
255− void tTalkboxFloat_setFreeze (tTalkboxFloat* const voc, int freeze);
256− void tTalkboxFloat_warpedAutocorrelate (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);
257− //==============================================================================
258−
259−
215+ {
216+
217+ tMempool mempool;
218+
219+ float param[NUM_TALKBOX_PARAM];
220+
221+ int bufsize;
222+ float* car0;
223+ float* car1;
224+ float* window;
225+ float* buf0;
226+ float* buf1;
227+ float* k;
228+ float warpFactor;
229+ int32_t warpOn;
230+ int freeze;
231+ float emphasis;
232+ int32_t K, N, O, pos;
233+ float wet, dry, FX;
234+ float d0, d1, d2, d3, d4;
235+ float u0, u1, u2, u3, u4;
236+ float G;
237+ float* dl;
238+ float* Rt;
239+
240+ float sampleRate;
241+
242+ } _tTalkboxFloat;
243+
244+ typedef _tTalkboxFloat* tTalkboxFloat;
245+
246+ void tTalkboxFloat_init (tTalkboxFloat* const, int bufsize, LEAF* const leaf);
247+ void tTalkboxFloat_initToPool (tTalkboxFloat* const, int bufsize, tMempool* const);
248+ void tTalkboxFloat_free (tTalkboxFloat* const);
249+
250+ float tTalkboxFloat_tick (tTalkboxFloat* const, float synth, float voice);
251+ float tTalkboxFloat_tickFrozen (tTalkboxFloat* const voc, float synth, float voice);
252+ void tTalkboxFloat_update (tTalkboxFloat* const);
253+ void tTalkboxFloat_suspend (tTalkboxFloat* const);
254+ void tTalkboxFloat_lpcDurbin (float *r, int p, float *k, float *g);
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);
256+ void tTalkboxFloat_setQuality (tTalkboxFloat* const, float quality);
257+ void tTalkboxFloat_setWarpFactor (tTalkboxFloat* const voc, float warp);
258+ void tTalkboxFloat_setWarpOn (tTalkboxFloat* const voc, int warpOn);
259+ void tTalkboxFloat_setFreeze (tTalkboxFloat* const voc, int freeze);
260+ void tTalkboxFloat_warpedAutocorrelate (float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda);
261+ void tTalkboxFloat_setSampleRate (tTalkboxFloat* const voc, float sr);
262+ //==============================================================================
263+
264+
260265 /*!
261266 @defgroup tvocoder tVocoder
262267 @ingroup effects
@@ -310,6 +315,7 @@ extern "C" { · 47 unmodified lines
310315 //filter coeffs and buffers - seems it's faster to leave this global than make local copy
311316 float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
312317
318+ float invSampleRate;
313319 } _tVocoder;
314320
315321 typedef _tVocoder* tVocoder;
@@ -321,6 +327,7 @@ extern "C" { · 5 unmodified lines
321327 float tVocoder_tick (tVocoder* const, float synth, float voice);
322328 void tVocoder_update (tVocoder* const);
323329 void tVocoder_suspend (tVocoder* const);
330+ void tVocoder_setSampleRate (tVocoder* const, float sr);
324331
325332 //==============================================================================
326333
@@ -369,7 +376,7 @@ extern "C" { · 42 unmodified lines
369376 @param pulse A pointer to the relevant tRosenbergGlottalPulse.
370377
371378 @} */
372−
379+
373380 typedef struct _tRosenbergGlottalPulse
374381 {
375382
@@ -380,22 +387,25 @@ extern "C" { · 4 unmodified lines
380387 float invPulseLengthMinusOpenLength;
381388 float freq;
382389 float inc;
390+ float invSampleRate;
383391 } _tRosenbergGlottalPulse;
384−
392+
385393 typedef _tRosenbergGlottalPulse* tRosenbergGlottalPulse;
386−
394+
387395 void tRosenbergGlottalPulse_init (tRosenbergGlottalPulse* const, LEAF* const leaf);
388396 void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const, tMempool* const);
389397 void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const);
390−
398+
391399 float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const);
392400 float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const gp);
393401 void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const, float freq);
394−
395− void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const, float openLength);
396−
397− void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const, float pulseLength);
398− void tRosenbergGlottalPulse_setOpenLengthAndPulseLength (tRosenbergGlottalPulse* const gp, float openLength, float pulseLength);
402+
403+ void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const, float openLength);
404+
405+ void tRosenbergGlottalPulse_setPulseLength (tRosenbergGlottalPulse* const, float pulseLength);
406+ void tRosenbergGlottalPulse_setOpenLengthAndPulseLength(tRosenbergGlottalPulse* const, float
407+ openLength, float pulseLength);
408+ void tRosenbergGlottalPulse_setSampleRate(tRosenbergGlottalPulse* const, float sr);
399409 //==============================================================================
400410
401411 /*!
@@ -421,7 +431,7 @@ extern "C" { · 19 unmodified lines
421431 @fn void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize)
422432 @brief Send one block of input samples, receive one block of output samples
423433 @param solad A pointer to the relevant tSOLAD.
424−
434+
425435 @fn void tSOLAD_setPeriod (tSOLAD *w, float period)
426436 @brief Set periodicity analysis data
427437 @param solad A pointer to the relevant tSOLAD.
@@ -440,11 +450,11 @@ extern "C" { · 12 unmodified lines
440450
441451 @} */
442452
443−//#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
444−//#define LOOPMASK (LOOPSIZE - 1)
453+ //#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
454+ //#define LOOPMASK (LOOPSIZE - 1)
445455 #define PITCHFACTORDEFAULT 1.0f
446456 #define INITPERIOD 64.0f
447−//#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
457+ //#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
448458 #define MINPERIOD 8.0f
449459
450460 typedef struct _tSOLAD
@@ -484,6 +494,7 @@ extern "C" { · 33 unmodified lines
484494 void tSOLAD_setReadLag (tSOLAD *w, float readlag);
485495 // reset state variables
486496 void tSOLAD_resetState (tSOLAD *w);
497+ void tSOLAD_setSampleRate (tSOLAD* const, float sr);
487498
488499 /*!
489500 @defgroup tpitchshift tPitchShift
@@ -536,6 +547,8 @@ extern "C" { · 46 unmodified lines
536547 int index;
537548
538549 float pickiness;
550+
551+ float sampleRate;
539552 } _tPitchShift;
540553
541554 typedef _tPitchShift* tPitchShift;
@@ -548,6 +561,7 @@ extern "C" { · 6 unmodified lines
548561 void tPitchShift_shiftTo (tPitchShift* const, float freq, float* in, float* out);
549562
550563 void tPitchShift_setPickiness (tPitchShift* const, float p);
564+ void tPitchShift_setSampleRate(tPitchShift* const, float sr);
551565
552566 /*!
553567 @defgroup tsimpleretune tSimpleRetune
@@ -620,7 +634,8 @@ extern "C" { · 66 unmodified lines
620634 void tSimpleRetune_tuneVoices (tSimpleRetune* const, float* t);
621635 void tSimpleRetune_tuneVoice (tSimpleRetune* const, int voice, float t);
622636 float tSimpleRetune_getInputFrequency (tSimpleRetune* const);
623−
637+ void tSimpleRetune_setSampleRate (tSimpleRetune* const, float sr);
638+
624639 /*!
625640 @defgroup tretune tRetune
626641 @ingroup effects
@@ -695,6 +710,7 @@ extern "C" { · 68 unmodified lines
695710 void tRetune_tuneVoices (tRetune* const, float* t);
696711 void tRetune_tuneVoice (tRetune* const, int voice, float t);
697712 float tRetune_getInputFrequency (tRetune* const);
713+ void tRetune_setSampleRate (tRetune* const, float sr);
698714
699715 //==============================================================================
700716
@@ -772,6 +788,8 @@ extern "C" { · 71 unmodified lines
772788 tHighpass hp2;
773789 tFeedbackLeveler fbl1;
774790 tFeedbackLeveler fbl2;
791+ float sampleRate;
792+ float invSampleRate;
775793 } _tFormantShifter;
776794
777795 typedef _tFormantShifter* tFormantShifter;
@@ -786,6 +804,7 @@ extern "C" { · 8 unmodified lines
786804 void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
787805 void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);
788806 void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);
807+ void tFormantShifter_setSampleRate (tFormantShifter* const fsr, float sr);
789808
790809 //==============================================================================
791810
@@ -796,3 +815,4 @@ extern "C" { · 4 unmodified lines
796815 #endif // LEAF_EFFECTS_H_INCLUDED
797816
798817 //==============================================================================
818+
leaf/Inc/leaf-envelopes.h+12−5
@@ -345,9 +345,11 @@ extern "C" { · 344 unmodified lines
345345 const float *exp_buff;
346346 uint32_t buff_size;
347347 uint32_t buff_sizeMinusOne;
348+ float sampleRate;
348349 float bufferSizeDividedBySampleRateInMs;
349350 float next;
350351
352+ float attack, decay, release;
351353 float attackInc, decayInc, releaseInc, rampInc;
352354
353355 uint32_t whichStage;
@@ -374,6 +376,7 @@ extern "C" { · 20 unmodified lines
374376 void tADSRT_setLeakFactor (tADSRT* const, float leakFactor);
375377 void tADSRT_on (tADSRT* const, float velocity);
376378 void tADSRT_off (tADSRT* const);
379+ void tADSRT_setSampleRate (tADSRT* const, float sr);
377380
378381 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
379382
@@ -444,9 +447,13 @@ extern "C" { · 64 unmodified lines
444447 {
445448
446449 tMempool mempool;
450+ float sampleRate;
447451 float sampleRateInMs;
448452 int state;
449453 float output;
454+ float attack;
455+ float decay;
456+ float release;
450457 float attackRate;
451458 float decayRate;
452459 float releaseRate;
@@ -481,6 +488,7 @@ extern "C" { · 28 unmodified lines
481488 void tADSRS_setLeakFactor (tADSRS* const, float leakFactor);
482489 void tADSRS_on (tADSRS* const, float velocity);
483490 void tADSRS_off (tADSRS* const);
491+ void tADSRS_setSampleRate (tADSRS* const, float sr);
484492
485493 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
486494
@@ -528,9 +536,9 @@ extern "C" { · 41 unmodified lines
528536
529537 typedef struct _tRamp
530538 {
531−
532539 tMempool mempool;
533540 float inc;
541+ float sampleRate;
534542 float inv_sr_ms;
535543 float minimum_time;
536544 float curr,dest;
@@ -550,6 +558,7 @@ extern "C" { · 13 unmodified lines
550558 void tRamp_setTime (tRamp* const, float time);
551559 void tRamp_setDest (tRamp* const, float dest);
552560 void tRamp_setVal (tRamp* const, float val);
561+ void tRamp_setSampleRate (tRamp* const, float sr);
553562
554563 /*!
555564 @defgroup trampupdown tRampUpDown
@@ -599,10 +608,10 @@ extern "C" { · 43 unmodified lines
599608
600609 typedef struct _tRampUpDown
601610 {
602−
603611 tMempool mempool;
604612 float upInc;
605613 float downInc;
614+ float sampleRate;
606615 float inv_sr_ms;
607616 float minimum_time;
608617 float curr,dest;
@@ -623,8 +632,7 @@ extern "C" { · 14 unmodified lines
623632 void tRampUpDown_setDownTime (tRampUpDown* const, float downTime);
624633 void tRampUpDown_setDest (tRampUpDown* const, float dest);
625634 void tRampUpDown_setVal (tRampUpDown* const, float val);
626−
627−
635+ void tRampUpDown_setSampleRate (tRampUpDown* const, float sr);
628636
629637 /*!
630638 @defgroup tslide tSlide
@@ -670,7 +678,6 @@ extern "C" { · 39 unmodified lines
670678
671679 typedef struct _tSlide
672680 {
673−
674681 tMempool mempool;
675682 float prevOut;
676683 float currentOut;
leaf/Inc/leaf-filters.h+31−17
@@ -143,10 +143,12 @@ extern "C" { · 142 unmodified lines
143143 {
144144
145145 tMempool mempool;
146+ float freq;
146147 float gain;
147148 float a0,a1;
148149 float b0,b1;
149150 float lastIn, lastOut;
151+ float twoPiTimesInvSampleRate;
150152 } _tOnePole;
151153
152154 typedef _tOnePole* tOnePole;
@@ -162,6 +164,7 @@ extern "C" { · 9 unmodified lines
162164 void tOnePole_setFreq (tOnePole* const, float freq);
163165 void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
164166 void tOnePole_setGain (tOnePole* const, float gain);
167+ void tOnePole_setSampleRate (tOnePole* const, float sr);
165168
166169 //==============================================================================
167170
@@ -228,6 +231,9 @@ extern "C" { · 60 unmodified lines
228231 int normalize;
229232
230233 float lastOut[2];
234+
235+ float sampleRate;
236+ float twoPiTimesInvSampleRate;
231237 } _tTwoPole;
232238
233239 typedef _tTwoPole* tTwoPole;
@@ -243,6 +249,7 @@ extern "C" { · 9 unmodified lines
243249 void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, int normalize);
244250 void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
245251 void tTwoPole_setGain (tTwoPole* const, float gain);
252+ void tTwoPole_setSampleRate (tTwoPole* const, float sr);
246253
247254 //==============================================================================
248255
@@ -298,11 +305,11 @@ extern "C" { · 49 unmodified lines
298305
299306 typedef struct _tOneZero
300307 {
301−
302308 tMempool mempool;
303309 float gain;
304310 float b0,b1;
305311 float lastIn, lastOut, frequency;
312+ float invSampleRate;
306313 } _tOneZero;
307314
308315 typedef _tOneZero* tOneZero;
@@ -317,7 +324,8 @@ extern "C" { · 8 unmodified lines
317324 void tOneZero_setZero (tOneZero* const, float theZero);
318325 void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
319326 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);
321329
322330 //==============================================================================
323331
@@ -374,15 +382,13 @@ extern "C" { · 50 unmodified lines
374382
375383 typedef struct _tTwoZero
376384 {
377−
378385 tMempool mempool;
379386
380387 float gain;
381388 float b0, b1, b2;
382−
383389 float frequency, radius;
384−
385390 float lastIn[2];
391+ float twoPiTimesInvSampleRate;
386392 } _tTwoZero;
387393
388394 typedef _tTwoZero* tTwoZero;
@@ -398,6 +404,7 @@ extern "C" { · 9 unmodified lines
398404 void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
399405 void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
400406 void tTwoZero_setGain (tTwoZero* const, float gain);
407+ void tTwoZero_setSampleRate (tTwoZero* const, float sr);
401408
402409 //==============================================================================
403410
@@ -552,7 +559,6 @@ extern "C" { · 148 unmodified lines
552559
553560 typedef struct _tBiQuad
554561 {
555−
556562 tMempool mempool;
557563
558564 float gain;
@@ -564,6 +570,9 @@ extern "C" { · 5 unmodified lines
564570
565571 float frequency, radius;
566572 int normalize;
573+
574+ float sampleRate;
575+ float twoPiTimesInvSampleRate;
567576 } _tBiQuad;
568577
569578 typedef _tBiQuad* tBiQuad;
@@ -582,6 +591,7 @@ extern "C" { · 12 unmodified lines
582591 void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, int normalize);
583592 void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
584593 void tBiQuad_setGain (tBiQuad* const, float gain);
594+ void tBiQuad_setSampleRate (tBiQuad* const, float sr);
585595
586596 //==============================================================================
587597
@@ -636,12 +646,13 @@ extern "C" { · 48 unmodified lines
636646
637647 typedef struct _tSVF
638648 {
639−
640649 tMempool mempool;
641650 SVFType type;
642651 float cutoff, Q;
643652 float ic1eq,ic2eq;
644653 float g,k,a1,a2,a3,cH,cB,cL,cBK;
654+ float sampleRate;
655+ float invSampleRate;
645656 } _tSVF;
646657
647658 typedef _tSVF* tSVF;
@@ -654,6 +665,7 @@ extern "C" { · 6 unmodified lines
654665 void tSVF_setFreq (tSVF* const, float freq);
655666 void tSVF_setQ (tSVF* const, float Q);
656667 void tSVF_setFreqAndQ (tSVF* const svff, float freq, float Q);
668+ void tSVF_setSampleRate (tSVF* const svff, float sr);
657669
658670 //==============================================================================
659671
@@ -749,10 +761,10 @@ extern "C" { · 89 unmodified lines
749761
750762 typedef struct _tHighpass
751763 {
752−
753764 tMempool mempool;
754765 float xs, ys, R;
755766 float frequency;
767+ float twoPiTimesInvSampleRate;
756768 } _tHighpass;
757769
758770 typedef _tHighpass* tHighpass;
@@ -764,6 +776,7 @@ extern "C" { · 5 unmodified lines
764776 float tHighpass_tick (tHighpass* const, float x);
765777 void tHighpass_setFreq (tHighpass* const, float freq);
766778 float tHighpass_getFreq (tHighpass* const);
779+ void tHighpass_setSampleRate (tHighpass* const, float sr);
767780
768781 //==============================================================================
769782
@@ -835,6 +848,7 @@ extern "C" { · 65 unmodified lines
835848 void tButterworth_setF1 (tButterworth* const, float in);
836849 void tButterworth_setF2 (tButterworth* const, float in);
837850 void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
851+ void tButterworth_setSampleRate (tButterworth* const, float sr);
838852
839853 //==============================================================================
840854
@@ -952,10 +966,6 @@ extern "C" { · 111 unmodified lines
952966 @brief Free a tVZFilter from its mempool.
953967 @param filter A pointer to the tVZFilter to free.
954968
955− @fn void tVZFilter_setSampleRate (tVZFilter* const, float sampleRate)
956− @brief
957− @param filter A pointer to the relevant tVZFilter.
958−
959969 @fn float tVZFilter_tick (tVZFilter* const, float input)
960970 @brief
961971 @param filter A pointer to the relevant tVZFilter.
@@ -991,6 +1001,10 @@ extern "C" { · 29 unmodified lines
9911001 @fn float tVZFilter_BandwidthToR (tVZFilter* const vf, float B)
9921002 @brief
9931003 @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.
9941008 
9951009 @} */
9961010
@@ -1012,7 +1026,6 @@ extern "C" { · 15 unmodified lines
10121026
10131027 typedef struct _tVZFilter
10141028 {
1015−
10161029 tMempool mempool;
10171030
10181031 VZFilterType type;
@@ -1032,8 +1045,8 @@ extern "C" { · 13 unmodified lines
10321045 float B; // bandwidth (in octaves)
10331046 float m; // morph parameter (0...1)
10341047
1035− float sr; //local sampling rate of filter (may be different from leaf sr if oversampled)
1036− float inv_sr;
1048+ float sampleRate; //local sampling rate of filter (may be different from leaf sr if oversampled)
1049+ float invSampleRate;
10371050 } _tVZFilter;
10381051
10391052 typedef _tVZFilter* tVZFilter;
@@ -1094,8 +1107,8 @@ extern "C" { · 54 unmodified lines
10941107 //diode ladder filter
10951108 typedef struct _tDiodeFilter
10961109 {
1097−
10981110 tMempool mempool;
1111+ float cutoff;
10991112 float f;
11001113 float r;
11011114 float Vt;
@@ -1106,6 +1119,7 @@ extern "C" { · 4 unmodified lines
11061119 float g1inv;
11071120 float g2inv;
11081121 float s0, s1, s2, s3;
1122+ float invSampleRate;
11091123 } _tDiodeFilter;
11101124
11111125 typedef _tDiodeFilter* tDiodeFilter;
@@ -1117,7 +1131,7 @@ extern "C" { · 5 unmodified lines
11171131 float tDiodeFilter_tick (tDiodeFilter* const, float input);
11181132 void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff);
11191133 void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance);
1120−
1134+ void tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr);
11211135
11221136 #ifdef __cplusplus
11231137 }
leaf/Inc/leaf-instruments.h+4−0
@@ -115,6 +115,7 @@ extern "C" { · 114 unmodified lines
115115 void t808Cowbell_setFreq (t808Cowbell* const, float freq);
116116 void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
117117 void t808Cowbell_setStick (t808Cowbell* const, int useStick);
118+ void t808Cowbell_setSampleRate (t808Cowbell* const, float sr);
118119
119120 //==============================================================================
120121
@@ -227,6 +228,7 @@ extern "C" { · 106 unmodified lines
227228 void t808Hihat_setOscFreq (t808Hihat* const, float freq);
228229 void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
229230 void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
231+ void t808Hihat_setSampleRate (t808Hihat* const, float sr);
230232
231233 //==============================================================================
232234
@@ -333,6 +335,7 @@ extern "C" { · 100 unmodified lines
333335 void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
334336 void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
335337 void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
338+ void t808Snare_setSampleRate (t808Snare* const, float sr);
336339
337340 //==============================================================================
338341
@@ -437,6 +440,7 @@ extern "C" { · 98 unmodified lines
437440 void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
438441 void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
439442 void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
443+ void t808kick_setSampleRate (t808Kick* const, float sr);
440444
441445 //==============================================================================
442446
leaf/Inc/leaf-midi.h+2−1
@@ -309,7 +309,8 @@ extern "C" { · 308 unmodified lines
309309 int tPoly_getKey (tPoly* const poly, uint8_t voice);
310310 int tPoly_getVelocity (tPoly* const poly, uint8_t voice);
311311 int tPoly_isOn (tPoly* const poly, uint8_t voice);
312−
312+ void tPoly_setSampleRate (tPoly* const poly, float sr);
313+
313314 //==============================================================================
314315
315316 /*! @}
leaf/Inc/leaf-oscillators.h+38−4
@@ -63,11 +63,11 @@ extern "C" { · 62 unmodified lines
6363
6464 typedef struct _tCycle
6565 {
66−
6766 tMempool mempool;
6867 // Underlying phasor
6968 float phase;
7069 float inc,freq;
70+ float invSampleRate;
7171 } _tCycle;
7272
7373 typedef _tCycle* tCycle;
@@ -78,6 +78,7 @@ extern "C" { · 4 unmodified lines
7878
7979 float tCycle_tick (tCycle* const osc);
8080 void tCycle_setFreq (tCycle* const osc, float freq);
81+ void tCycle_setSampleRate(tCycle* const osc, float sr);
8182
8283 //==============================================================================
8384
@@ -122,6 +123,7 @@ extern "C" { · 38 unmodified lines
122123 float inc,freq;
123124 int oct;
124125 float w;
126+ float invSampleRate;
125127 } _tTriangle;
126128
127129 typedef _tTriangle* tTriangle;
@@ -132,7 +134,7 @@ extern "C" { · 4 unmodified lines
132134
133135 float tTriangle_tick (tTriangle* const osc);
134136 void tTriangle_setFreq (tTriangle* const osc, float freq);
135−
137+ void tTriangle_setSampleRate (tTriangle* const osc, float sr);
136138
137139 //==============================================================================
138140
@@ -177,6 +179,7 @@ extern "C" { · 38 unmodified lines
177179 float inc,freq;
178180 int oct;
179181 float w;
182+ float invSampleRate;
180183 } _tSquare;
181184
182185 typedef _tSquare* tSquare;
@@ -187,6 +190,7 @@ extern "C" { · 4 unmodified lines
187190
188191 float tSquare_tick (tSquare* const osc);
189192 void tSquare_setFreq (tSquare* const osc, float freq);
193+ void tSquare_setSampleRate (tSquare* const osc, float sr);
190194
191195 /*!
192196 @} */
@@ -234,6 +238,7 @@ extern "C" { · 41 unmodified lines
234238 float inc,freq;
235239 int oct;
236240 float w;
241+ float invSampleRate;
237242 } _tSawtooth;
238243
239244 typedef _tSawtooth* tSawtooth;
@@ -244,6 +249,7 @@ extern "C" { · 4 unmodified lines
244249
245250 float tSawtooth_tick (tSawtooth* const osc);
246251 void tSawtooth_setFreq (tSawtooth* const osc, float freq);
252+ void tSawtooth_setSampleRate (tSawtooth* const osc, float sr);
247253
248254 //==============================================================================
249255
@@ -288,6 +294,7 @@ extern "C" { · 38 unmodified lines
288294 float inc,freq;
289295 float skew;
290296 float lastOut;
297+ float invSampleRate;
291298 } _tPBTriangle;
292299
293300 typedef _tPBTriangle* tPBTriangle;
@@ -299,6 +306,7 @@ extern "C" { · 5 unmodified lines
299306 float tPBTriangle_tick (tPBTriangle* const osc);
300307 void tPBTriangle_setFreq (tPBTriangle* const osc, float freq);
301308 void tPBTriangle_setSkew (tPBTriangle* const osc, float skew);
309+ void tPBTriangle_setSampleRate (tPBTriangle* const osc, float sr);
302310
303311 //==============================================================================
304312
@@ -342,6 +350,7 @@ extern "C" { · 37 unmodified lines
342350 float phase;
343351 float inc,freq;
344352 float width;
353+ float invSampleRate;
345354 } _tPBPulse;
346355
347356 typedef _tPBPulse* tPBPulse;
@@ -353,6 +362,7 @@ extern "C" { · 5 unmodified lines
353362 float tPBPulse_tick (tPBPulse* const osc);
354363 void tPBPulse_setFreq (tPBPulse* const osc, float freq);
355364 void tPBPulse_setWidth (tPBPulse* const osc, float width);
365+ void tPBPulse_setSampleRate (tPBPulse* const osc, float sr);
356366
357367 //==============================================================================
358368
@@ -391,6 +401,7 @@ extern "C" { · 32 unmodified lines
391401 tMempool mempool;
392402 float phase;
393403 float inc,freq;
404+ float invSampleRate;
394405 } _tPBSaw;
395406
396407 typedef _tPBSaw* tPBSaw;
@@ -401,6 +412,7 @@ extern "C" { · 4 unmodified lines
401412
402413 float tPBSaw_tick (tPBSaw* const osc);
403414 void tPBSaw_setFreq (tPBSaw* const osc, float freq);
415+ void tPBSaw_setSampleRate (tPBSaw* const osc, float sr);
404416
405417 //==============================================================================
406418
@@ -441,6 +453,7 @@ extern "C" { · 34 unmodified lines
441453 float phase;
442454 float inc,freq;
443455 uint8_t phaseDidReset;
456+ float invSampleRate;
444457 } _tPhasor;
445458
446459 typedef _tPhasor* tPhasor;
@@ -451,6 +464,7 @@ extern "C" { · 4 unmodified lines
451464
452465 float tPhasor_tick (tPhasor* const osc);
453466 void tPhasor_setFreq (tPhasor* const osc, float freq);
467+ void tPhasor_setSampleRate (tPhasor* const osc, float sr);
454468
455469 //==============================================================================
456470
@@ -643,9 +657,7 @@ extern "C" { · 186 unmodified lines
643657 void tNeuron_setV2 (tNeuron* const neuron, float V2);
644658 void tNeuron_setV3 (tNeuron* const neuron, float V3);
645659 void tNeuron_setTimeStep (tNeuron* const neuron, float timestep);
646−
647660
648−
649661 //==============================================================================
650662
651663
@@ -708,6 +720,7 @@ extern "C" { · 56 unmodified lines
708720 float _f [FILLEN + STEP_DD_PULSE_LENGTH];
709721 int _j, _k;
710722 bool _init;
723+ float invSampleRate;
711724 } _tMBPulse;
712725
713726 typedef _tMBPulse* tMBPulse;
@@ -721,6 +734,7 @@ extern "C" { · 7 unmodified lines
721734 void tMBPulse_setWidth(tMBPulse* const osc, float w);
722735 float tMBPulse_sync(tMBPulse* const osc, float sync);
723736 void tMBPulse_setSyncMode(tMBPulse* const osc, int hardOrSoft);
737+ void tMBPulse_setSampleRate (tMBPulse* const osc, float sr);
724738
725739 /*!
726740 @defgroup tmbtriangle tMBTriangle
@@ -779,6 +793,7 @@ extern "C" { · 52 unmodified lines
779793 float _f [FILLEN + LONGEST_DD_PULSE_LENGTH];
780794 int _j, _k;
781795 bool _init;
796+ float invSampleRate;
782797 } _tMBTriangle;
783798
784799 typedef _tMBTriangle* tMBTriangle;
@@ -792,6 +807,7 @@ extern "C" { · 7 unmodified lines
792807 void tMBTriangle_setWidth(tMBTriangle* const osc, float w);
793808 float tMBTriangle_sync(tMBTriangle* const osc, float sync);
794809 void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft);
810+ void tMBTriangle_setSampleRate (tMBTriangle* const osc, float sr);
795811
796812
797813 /*!
@@ -849,6 +865,7 @@ extern "C" { · 51 unmodified lines
849865 float _f [FILLEN + STEP_DD_PULSE_LENGTH];
850866 int _j;
851867 bool _init;
868+ float invSampleRate;
852869 } _tMBSaw;
853870
854871 typedef _tMBSaw* tMBSaw;
@@ -861,6 +878,7 @@ extern "C" { · 6 unmodified lines
861878 void tMBSaw_setFreq(tMBSaw* const osc, float f);
862879 float tMBSaw_sync(tMBSaw* const osc, float sync);
863880 void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft);
881+ void tMBSaw_setSampleRate (tMBSaw* const osc, float sr);
864882
865883 //==============================================================================
866884
@@ -908,6 +926,7 @@ extern "C" { · 41 unmodified lines
908926 int size;
909927 float inc, freq;
910928 float phase;
929+ float invSampleRate;
911930 } _tTable;
912931
913932 typedef _tTable* tTable;
@@ -918,6 +937,7 @@ extern "C" { · 4 unmodified lines
918937
919938 float tTable_tick(tTable* const osc);
920939 void tTable_setFreq(tTable* const osc, float freq);
940+ void tTable_setSampleRate (tTable* const osc, float sr);
921941
922942 //==============================================================================
923943
@@ -953,11 +973,14 @@ extern "C" { · 29 unmodified lines
953973 {
954974 tMempool mempool;
955975
976+ float* baseTable;
956977 float** tables;
957978 int size;
958979 int numTables;
980+ float maxFreq;
959981 float baseFreq, invBaseFreq;
960982 tButterworth bl;
983+ float sampleRate;
961984 } _tWaveTable;
962985
963986 typedef _tWaveTable* tWaveTable;
@@ -967,6 +990,7 @@ extern "C" { · 3 unmodified lines
967990 void tWaveTable_initToPool(tWaveTable* const osc, float* table, int size,
968991 float maxFreq, tMempool* const mempool);
969992 void tWaveTable_free(tWaveTable* const osc);
993+ void tWaveTable_setSampleRate (tWaveTable* const osc, float sr);
970994
971995 //==============================================================================
972996
@@ -995,6 +1019,7 @@ extern "C" { · 22 unmodified lines
9951019 float inc, freq;
9961020 float phase;
9971021 float phaseOffset;
1022+ float invSampleRate;
9981023
9991024 int oct;
10001025 float w;
@@ -1011,6 +1036,7 @@ extern "C" { · 10 unmodified lines
10111036 void tWaveOsc_setFreq(tWaveOsc* const osc, float freq);
10121037 void tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);
10131038 void tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);
1039+ void tWaveOsc_setSampleRate (tWaveOsc* const osc, float sr);
10141040
10151041 //==============================================================================
10161042
@@ -1087,6 +1113,7 @@ extern "C" { · 70 unmodified lines
10871113 void tWaveSynth_setIndexGain(tWaveSynth* const osc, int i, float gain);
10881114 void tWaveSynth_setIndexPhase(tWaveSynth* const osc, int i, float phase);
10891115 // void tWaveSynth_setIndexTable(tWaveSynth* const osc, int i, float* table, int size);
1116+ void tWaveSynth_setSampleRate (tWaveSynth* const osc, float sr);
10901117
10911118 //==============================================================================
10921119
@@ -1122,13 +1149,16 @@ extern "C" { · 29 unmodified lines
11221149 {
11231150 tMempool mempool;
11241151
1152+ float* baseTable;
11251153 float** tables;
11261154 int numTables;
11271155 int* sizes;
1156+ float maxFreq;
11281157 float baseFreq, invBaseFreq;
11291158 tButterworth bl;
11301159 float dsBuffer[2];
11311160 tOversampler ds;
1161+ float sampleRate;
11321162 } _tWaveTableS;
11331163
11341164 typedef _tWaveTableS* tWaveTableS;
@@ -1136,6 +1166,7 @@ extern "C" { · 1 unmodified line
11361166 void tWaveTableS_init(tWaveTableS* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
11371167 void tWaveTableS_initToPool(tWaveTableS* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
11381168 void tWaveTableS_free(tWaveTableS* const osc);
1169+ void tWaveTableS_setSampleRate (tWaveTableS* const osc, float sr);
11391170
11401171 /*!
11411172 @defgroup twaveoscs tWaveOscS
@@ -1182,6 +1213,7 @@ extern "C" { · 40 unmodified lines
11821213 float inc, freq;
11831214 float phase;
11841215 float phaseOffset;
1216+ float invSampleRate;
11851217 int oct;
11861218 float w;
11871219 float aa;
@@ -1197,6 +1229,7 @@ extern "C" { · 9 unmodified lines
11971229 void tWaveOscS_setFreq(tWaveOscS* const osc, float freq);
11981230 void tWaveOscS_setAntiAliasing(tWaveOscS* const osc, float aa);
11991231 void tWaveOscS_setPhaseOffset(tWaveOscS* const osc, float phase);
1232+ void tWaveOscS_setSampleRate (tWaveOscS* const osc, float sr);
12001233
12011234 //==============================================================================
12021235
@@ -1273,6 +1306,7 @@ extern "C" { · 70 unmodified lines
12731306 void tWaveSynthS_setIndexGain(tWaveSynthS* const osc, int i, float gain);
12741307 void tWaveSynthS_setIndexPhase(tWaveSynthS* const osc, int i, float phase);
12751308 // void tWaveSynthS_setIndexTable(tWaveSynthS* const osc, int i, float* table, int size);
1309+ void tWaveSynthS_setSampleRate (tWaveSynthS* const osc, float sr);
12761310
12771311 #ifdef __cplusplus
12781312 }
leaf/Inc/leaf-physical.h+71−63
@@ -71,7 +71,7 @@ extern "C" { · 70 unmodified lines
7171 @fn void tPluck_noteOff (tPluck* const, float amplitude )
7272 @brief Stop a note with the given amplitude (speed of decay)
7373 @param string A pointer to the relevant tPluck.
74−
74+
7575 @fn void tPluck_setFrequency (tPluck* const, float frequency )
7676 @brief Set instrument parameters for a particular frequency.
7777 @param string A pointer to the relevant tPluck.
@@ -79,7 +79,7 @@ extern "C" { · 1 unmodified line
7979 @fn void tPluck_controlChange (tPluck* const, int number, float value)
8080 @brief Perform the control change specified by \e number and \e value (0.0 - 128.0).
8181 @param string A pointer to the relevant tPluck.
82−
82+
8383 @fn float tPluck_getLastOut (tPluck* const)
8484 @brief
8585 @param string A pointer to the relevant tPluck.
@@ -100,7 +100,7 @@ extern "C" { · 14 unmodified lines
100100 float loopGain;
101101 float lastFreq;
102102
103− float sr;
103+ float sampleRate;
104104 } _tPluck;
105105
106106 typedef _tPluck* tPluck;
@@ -116,6 +116,7 @@ extern "C" { · 9 unmodified lines
116116 void tPluck_setFrequency (tPluck* const, float frequency );
117117 void tPluck_controlChange (tPluck* const, int number, float value);
118118 float tPluck_getLastOut (tPluck* const);
119+ void tPluck_setSampleRate (tPluck* const, float sr);
119120
120121 //==============================================================================
121122
@@ -146,7 +147,7 @@ extern "C" { · 24 unmodified lines
146147 @fn void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude)
147148 @brief Pluck the string.
148149 @param string A pointer to the relevant tKarplusStrong.
149−
150+
150151 @fn void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude)
151152 @brief Start a note with the given frequency and amplitude.
152153 @param string A pointer to the relevant tKarplusStrong.
@@ -210,6 +211,8 @@ extern "C" { · 57 unmodified lines
210211 float pickupPosition;
211212
212213 float lastOut;
214+
215+ float sampleRate;
213216 } _tKarplusStrong;
214217
215218 typedef _tKarplusStrong* tKarplusStrong;
@@ -307,6 +310,7 @@ extern "C" { · 91 unmodified lines
307310 tHighpass DCblocker;
308311 tFeedbackLeveler fbLev;
309312 tExpSmooth wlSmooth;
313+ float sampleRate;
310314 } _tSimpleLivingString;
311315
312316 typedef _tSimpleLivingString* tSimpleLivingString;
@@ -329,6 +333,7 @@ extern "C" { · 16 unmodified lines
329333 void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
330334 void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
331335 void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
336+ void tSimpleLivingString_setSampleRate (tSimpleLivingString* const, float sr);
332337
333338 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
334339
@@ -404,7 +409,6 @@ extern "C" { · 69 unmodified lines
404409
405410 typedef struct _tLivingString
406411 {
407−
408412 tMempool mempool;
409413 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
410414 float pickPos; // the pick position, dividing the string in two, in ratio
@@ -418,6 +422,7 @@ extern "C" { · 7 unmodified lines
418422 tHighpass DCblockerL, DCblockerU;
419423 tFeedbackLeveler fbLevU, fbLevL;
420424 tExpSmooth wlSmooth, ppSmooth;
425+ float sampleRate;
421426 } _tLivingString;
422427
423428 typedef _tLivingString* tLivingString;
@@ -442,10 +447,10 @@ extern "C" { · 18 unmodified lines
442447 void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
443448 void tLivingString_setLevStrength (tLivingString* const, float levStrength);
444449 void tLivingString_setLevMode (tLivingString* const, int levMode);
450+ void tLivingString_setSampleRate (tLivingString* const, float sr);
451+
452+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
445453
446−
447− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
448−
449454
450455 /*!
451456 @defgroup tlivingstring2 tLivingString2
@@ -524,55 +529,56 @@ extern "C" { · 72 unmodified lines
524529
525530 @} */
526531 typedef struct _tLivingString2
527− {
528−
529− tMempool mempool;
530− float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
531− float pickPos; // the pick position, dividing the string in two, in ratio
532− float prepPos; // the preparation position, dividing the string in two, in ratio
533− float pickupPos; // the preparation position, dividing the string in two, in ratio
534− float prepIndex; // the amount of pressure on the preparation position of the string (near 0=soft obj, near 1=hard obj)
535− float decay; // amplitude damping factor for the string (only active in mode 0)
536− int levMode;
537− float brightness;
538− float curr;
539− tHermiteDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
540− tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;
541− tHighpass DCblockerL, DCblockerU;
542− tFeedbackLeveler fbLevU, fbLevL;
543− tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;
544− } _tLivingString2;
545−
546− typedef _tLivingString2* tLivingString2;
547−
548− void tLivingString2_init (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
549− float brightness, float decay, float targetLev, float levSmoothFactor,
550− float levStrength, int levMode, LEAF* const leaf);
551− void tLivingString2_initToPool (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
552− float brightness, float decay, float targetLev, float levSmoothFactor,
553− float levStrength, int levMode, tMempool* const);
554− void tLivingString2_free (tLivingString2* const);
555−
556− float tLivingString2_tick (tLivingString2* const, float input);
557− float tLivingString2_sample (tLivingString2* const);
558− void tLivingString2_setFreq (tLivingString2* const, float freq);
559− void tLivingString2_setWaveLength (tLivingString2* const, float waveLength); // in samples
560− void tLivingString2_setPickPos (tLivingString2* const, float pickPos);
561− void tLivingString2_setPrepPos (tLivingString2* const, float prepPos);
562− void tLivingString2_setPickupPos (tLivingString2* const, float pickupPos);
563− void tLivingString2_setPrepIndex (tLivingString2* const, float prepIndex);
564− void tLivingString2_setBrightness (tLivingString2* const, float brightness);
565− 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);
567− void tLivingString2_setLevSmoothFactor (tLivingString2* const, float levSmoothFactor);
568− void tLivingString2_setLevStrength (tLivingString2* const, float levStrength);
569− void tLivingString2_setLevMode (tLivingString2* const, int levMode);
570−
571−
572−
573− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
574− // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
575−
532+ {
533+ tMempool mempool;
534+ float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
535+ float pickPos; // the pick position, dividing the string in two, in ratio
536+ float prepPos; // the preparation position, dividing the string in two, in ratio
537+ float pickupPos; // the preparation position, dividing the string in two, in ratio
538+ 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)
540+ int levMode;
541+ float brightness;
542+ float curr;
543+ tHermiteDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
544+ tTwoZero bridgeFilter, nutFilter, prepFilterU, prepFilterL;
545+ tHighpass DCblockerL, DCblockerU;
546+ tFeedbackLeveler fbLevU, fbLevL;
547+ tExpSmooth wlSmooth, ppSmooth, prpSmooth, puSmooth;
548+ float sampleRate;
549+ } _tLivingString2;
550+
551+ typedef _tLivingString2* tLivingString2;
552+
553+ void tLivingString2_init (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
554+ float brightness, float decay, float targetLev, float levSmoothFactor,
555+ float levStrength, int levMode, LEAF* const leaf);
556+ void tLivingString2_initToPool (tLivingString2* const, float freq, float pickPos, float prepPos, float pickupPos, float prepIndex,
557+ float brightness, float decay, float targetLev, float levSmoothFactor,
558+ float levStrength, int levMode, tMempool* const);
559+ void tLivingString2_free (tLivingString2* const);
560+
561+ float tLivingString2_tick (tLivingString2* const, float input);
562+ float tLivingString2_sample (tLivingString2* const);
563+ void tLivingString2_setFreq (tLivingString2* const, float freq);
564+ void tLivingString2_setWaveLength (tLivingString2* const, float waveLength); // in samples
565+ void tLivingString2_setPickPos (tLivingString2* const, float pickPos);
566+ void tLivingString2_setPrepPos (tLivingString2* const, float prepPos);
567+ void tLivingString2_setPickupPos (tLivingString2* const, float pickupPos);
568+ void tLivingString2_setPrepIndex (tLivingString2* const, float prepIndex);
569+ void tLivingString2_setBrightness (tLivingString2* const, float brightness);
570+ void tLivingString2_setDecay (tLivingString2* const, float decay); // from 0 to 1, gets converted to real decay factor
571+ void tLivingString2_setTargetLev (tLivingString2* const, float targetLev);
572+ void tLivingString2_setLevSmoothFactor (tLivingString2* const, float levSmoothFactor);
573+ void tLivingString2_setLevStrength (tLivingString2* const, float levStrength);
574+ void tLivingString2_setLevMode (tLivingString2* const, int levMode);
575+ void tLivingString2_setSampleRate (tLivingString2* const, float sr);
576+
577+
578+
579+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
580+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
581+
576582 /*!
577583 @defgroup tcomplexlivingstring tComplexLivingString
578584 @ingroup physical
@@ -649,7 +655,6 @@ extern "C" { · 70 unmodified lines
649655
650656 typedef struct _tComplexLivingString
651657 {
652−
653658 tMempool mempool;
654659 float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
655660 float pickPos; // the pick position, dividing the string, in ratio
@@ -665,10 +670,11 @@ extern "C" { · 9 unmodified lines
665670 tHighpass DCblockerL, DCblockerU;
666671 tFeedbackLeveler fbLevU, fbLevL;
667672 tExpSmooth wlSmooth, pickPosSmooth, prepPosSmooth;
673+ float sampleRate;
668674 } _tComplexLivingString;
669−
675+
670676 typedef _tComplexLivingString* tComplexLivingString;
671−
677+
672678 void tComplexLivingString_init (tComplexLivingString* const, float freq, float pickPos,
673679 float prepPos, float prepIndex, float dampFreq,
674680 float decay, float targetLev, float levSmoothFactor,
@@ -678,7 +684,7 @@ extern "C" { · 3 unmodified lines
678684 float decay, float targetLev, float levSmoothFactor,
679685 float levStrength, int levMode, tMempool* const);
680686 void tComplexLivingString_free (tComplexLivingString* const);
681−
687+
682688 float tComplexLivingString_tick (tComplexLivingString* const, float input);
683689 float tComplexLivingString_sample (tComplexLivingString* const);
684690 void tComplexLivingString_setFreq (tComplexLivingString* const, float freq);
@@ -692,9 +698,10 @@ extern "C" { · 7 unmodified lines
692698 void tComplexLivingString_setLevSmoothFactor (tComplexLivingString* const, float levSmoothFactor);
693699 void tComplexLivingString_setLevStrength (tComplexLivingString* const, float levStrength);
694700 void tComplexLivingString_setLevMode (tComplexLivingString* const, int levMode);
701+ void tComplexLivingString_setSampleRate (tComplexLivingString* const, float sr);
695702
696703 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
697−
704+
698705
699706 /*!
700707 @defgroup treedtable tReedTable
@@ -733,7 +740,7 @@ extern "C" { · 32 unmodified lines
733740 @param reed A pointer to the relevant tReedTable.
734741
735742 @} */
736−
743+
737744 typedef struct _tReedTable
738745 {
739746
@@ -762,3 +769,4 @@ extern "C" { · 22 unmodified lines
762769
763770 //==============================================================================
764771
772+
leaf/Inc/leaf-reverb.h+11−3
@@ -78,6 +78,8 @@ extern "C" { · 77 unmodified lines
7878 float mix, t60;
7979
8080 float inv_441;
81+ float sampleRate;
82+ float invSampleRate;
8183
8284 tDelay allpassDelays[2];
8385 tDelay combDelay;
@@ -97,6 +99,7 @@ extern "C" { · 13 unmodified lines
9799 float tPRCReverb_tick (tPRCReverb* const, float input);
98100 void tPRCReverb_setT60 (tPRCReverb* const, float t60);
99101 void tPRCReverb_setMix (tPRCReverb* const, float mix);
102+ void tPRCReverb_setSampleRate(tPRCReverb* const, float sr);
100103
101104 //==============================================================================
102105
@@ -149,7 +152,9 @@ extern "C" { · 46 unmodified lines
149152
150153 float mix, t60;
151154
152− float inv_sr, inv_441;
155+ float inv_441;
156+ float sampleRate;
157+ float invSampleRate;
153158
154159 tLinearDelay allpassDelays[8];
155160 tLinearDelay combDelays[6];
@@ -171,6 +176,7 @@ extern "C" { · 15 unmodified lines
171176 void tNReverb_tickStereo (tNReverb* const rev, float input, float* output);
172177 void tNReverb_setT60 (tNReverb* const, float t60);
173178 void tNReverb_setMix (tNReverb* const, float mix);
179+ void tNReverb_setSampleRate (tNReverb* const, float sr);
174180
175181 //==============================================================================
176182
@@ -245,12 +251,13 @@ extern "C" { · 68 unmodified lines
245251
246252 tMempool mempool;
247253
254+ float sampleRate;
248255 float predelay;
249256 float input_filter;
250257 float feedback_filter;
251258 float feedback_gain;
252259 float mix;
253− uint32_t frozen;
260+ int frozen;
254261
255262 float size, size_max, t;
256263
@@ -296,13 +303,14 @@ extern "C" { · 39 unmodified lines
296303 float tDattorroReverb_tick (tDattorroReverb* const, float input);
297304 void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);
298305 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);
300307 void tDattorroReverb_setHP (tDattorroReverb* const, float freq);
301308 void tDattorroReverb_setSize (tDattorroReverb* const, float size);
302309 void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
303310 void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
304311 void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
305312 void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);
313+ void tDattorroReverb_setSampleRate (tDattorroReverb* const, float sr);
306314
307315 #ifdef __cplusplus
308316 }
leaf/Inc/leaf-sampling.h+7−7
@@ -243,13 +243,12 @@ extern "C" { · 242 unmodified lines
243243
244244 typedef struct _tSampler
245245 {
246−
247246 tMempool mempool;
248247
249248 tBuffer samp;
250249
251− float leafInvSampleRate;
252− float leafSampleRate;
250+ float invSampleRate;
251+ float sampleRate;
253252 float ticksPerSevenMs;
254253 float rateFactor;
255254 uint32_t channels;
@@ -284,11 +283,11 @@ extern "C" { · 28 unmodified lines
284283 typedef _tSampler* tSampler;
285284
286285 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);
288287 void tSampler_free (tSampler* const);
289288
290289 float tSampler_tick (tSampler* const);
291− float tSampler_tickStereo (tSampler* const sp, float* outputArray);
290+ float tSampler_tickStereo (tSampler* const sp, float* outputArray);
292291 void tSampler_setSample (tSampler* const, tBuffer* const);
293292 void tSampler_setMode (tSampler* const, PlayMode mode);
294293 void tSampler_play (tSampler* const);
@@ -296,8 +295,9 @@ extern "C" { · 1 unmodified line
296295 void tSampler_setStart (tSampler* const, int32_t start);
297296 void tSampler_setEnd (tSampler* const, int32_t end);
298297 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);
300299 void tSampler_setRate (tSampler* const, float rate);
300+ void tSampler_setSampleRate (tSampler* const, float sr);
301301
302302 //==============================================================================
303303
@@ -388,7 +388,7 @@ extern "C" { · 84 unmodified lines
388388 void tAutoSampler_setWindowSize (tAutoSampler* const, uint32_t size);
389389 void tAutoSampler_setCrossfadeLength (tAutoSampler* const, uint32_t length);
390390 void tAutoSampler_setRate (tAutoSampler* const, float rate);
391−
391+ void tAutoSampler_setSampleRate (tAutoSampler* const, float sr);
392392
393393 /*!
394394 @defgroup tmbsampler tMBSampler
leaf/Src/leaf-analysis.c+75−39
@@ -360,25 +360,11 @@ void tAttackDetection_free (tAttackDetection* const ad) · 359 unmodified lines
360360 mpool_free((char*)a, a->mempool);
361361 }
362362
363−/*******Public Functions***********/
364−
365−
366363 void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)
367364 {
368365 _tAttackDetection* a = *ad;
369366
370− a->blocksize = size;
371−}
372−
373−void 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);
367+ a->blockSize = size;
382368 }
383369
384370 void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
@@ -391,17 +377,16 @@ void tAttackDetection_setAttack(tAttackDetection* const ad, int inAtk) · 6 unmodified lines
391377 {
392378 _tAttackDetection* a = *ad;
393379 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));
395381 }
396382
397383 void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)
398384 {
399385 _tAttackDetection* a = *ad;
400386 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));
402388 }
403389
404−
405390 int tAttackDetection_detect(tAttackDetection* const ad, float *in)
406391 {
407392 _tAttackDetection* a = *ad;
@@ -420,6 +405,16 @@ int tAttackDetection_detect(tAttackDetection* const ad, float *in) · 12 unmodified lines
420405 return result;
421406 }
422407
408+void 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+
423418 /*******Private Functions**********/
424419
425420 static 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
428423 LEAF* leaf = a->mempool->leaf;
429424
430425 a->env = 0;
431− a->blocksize = blocksize;
426+ a->blockSize = blocksize;
432427 a->threshold = DEFTHRESHOLD;
433− a->samplerate = leaf->sampleRate;
428+ a->sampleRate = leaf->sampleRate;
434429 a->prevAmp = 0;
435430
436431 a->env = 0;
@@ -445,7 +440,7 @@ static void atkdtk_envelope(tAttackDetection* const ad, float *in) · 8 unmodified lines
445440
446441 int i = 0;
447442 float tmp;
448− for(i = 0; i < a->blocksize; ++i){
443+ for(i = 0; i < a->blockSize; ++i){
449444 tmp = fastabsf(in[i]);
450445
451446 if(tmp > a->env)
@@ -845,6 +840,7 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, int buf · 393 unmodified lines
845840 p->mempool = m;
846841 LEAF* leaf = p->mempool->leaf;
847842
843+ p->invSampleRate = leaf->invSampleRate;
848844 p->inBuffer = in;
849845 p->bufSize = bufSize;
850846 p->frameSize = frameSize;
@@ -865,7 +861,7 @@ void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, int buf · 14 unmodified lines
865861 p->alpha = 1.0f;
866862 p->tolerance = 1.0f;
867863 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);
869865 p->fidelityThreshold = 0.95f;
870866 }
871867
@@ -878,7 +874,7 @@ void tPeriodDetection_free (tPeriodDetection* const pd) · 6 unmodified lines
878874 mpool_free((char*)p, p->mempool);
879875 }
880876
881−float tPeriodDetection_tick (tPeriodDetection* pd, float sample)
877+float tPeriodDetection_tick (tPeriodDetection* const pd, float sample)
882878 {
883879 _tPeriodDetection* p = *pd;
884880
@@ -913,49 +909,57 @@ float tPeriodDetection_tick (tPeriodDetection* pd, float sample) · 28 unmodified lines
913909 return p->period;
914910 }
915911
916−float tPeriodDetection_getPeriod(tPeriodDetection* pd)
912+float tPeriodDetection_getPeriod(tPeriodDetection* const pd)
917913 {
918914 _tPeriodDetection* p = *pd;
919915 return p->period;
920916 }
921917
922−float tPeriodDetection_getFidelity(tPeriodDetection* pd)
918+float tPeriodDetection_getFidelity(tPeriodDetection* const pd)
923919 {
924920 _tPeriodDetection* p = *pd;
925921 return tSNAC_getFidelity(&p->snac);
926922 }
927923
928−void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
924+void tPeriodDetection_setHopSize(tPeriodDetection* const pd, int hs)
929925 {
930926 _tPeriodDetection* p = *pd;
931927 p->hopSize = hs;
932928 }
933929
934−void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
930+void tPeriodDetection_setWindowSize(tPeriodDetection* const pd, int ws)
935931 {
936932 _tPeriodDetection* p = *pd;
937933 p->windowSize = ws;
938934 }
939935
940−void tPeriodDetection_setFidelityThreshold(tPeriodDetection* pd, float threshold)
936+void tPeriodDetection_setFidelityThreshold(tPeriodDetection* const pd, float threshold)
941937 {
942938 _tPeriodDetection* p = *pd;
943939 p->fidelityThreshold = threshold;
944940 }
945941
946−void tPeriodDetection_setAlpha (tPeriodDetection* pd, float alpha)
942+void tPeriodDetection_setAlpha (tPeriodDetection* const pd, float alpha)
947943 {
948944 _tPeriodDetection* p = *pd;
949945 p->alpha = LEAF_clip(0.0f, alpha, 1.0f);
950946 }
951947
952−void tPeriodDetection_setTolerance (tPeriodDetection* pd, float tolerance)
948+void tPeriodDetection_setTolerance (tPeriodDetection* const pd, float tolerance)
953949 {
954950 _tPeriodDetection* p = *pd;
955951 if (tolerance < 0.0f) p->tolerance = 0.0f;
956952 else p->tolerance = tolerance;
957953 }
958954
955+void 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+//==========================================================================================
959963
960964 void tZeroCrossingInfo_init (tZeroCrossingInfo* const zc, LEAF* const leaf)
961965 {
@@ -1522,8 +1526,12 @@ void tPeriodDetector_initToPool (tPeriodDetector* const detector, float lowe · 560 unmodified lines
15221526
15231527 LEAF* leaf = p->mempool->leaf;
15241528
1525− tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * leaf->sampleRate * 2.0f, hysteresis, mempool);
1526− p->_min_period = (1.0f / highestFreq) * leaf->sampleRate;
1529+ p->sampleRate = 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;
15271535 p->_range = highestFreq / lowestFreq;
15281536
15291537 int windowSize = tZeroCrossingCollector_getWindowSize(&p->_zc);
@@ -1670,6 +1678,18 @@ void tPeriodDetector_setHysteresis (tPeriodDetector* const detector, float · 140 unmodified lines
16701678 return tZeroCrossingCollector_setHysteresis(&p->_zc, hysteresis);
16711679 }
16721680
1681+void 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+
16731693 static inline void set_bitstream(tPeriodDetector* const detector)
16741694 {
16751695 _tPeriodDetector* p = *detector;
@@ -1901,11 +1921,13 @@ void tPitchDetector_initToPool (tPitchDetector* const detector, float lowes · 225 unmodified lines
19011921 _tMempool* m = *mempool;
19021922 _tPitchDetector* p = *detector = (_tPitchDetector*) mpool_alloc(sizeof(_tPitchDetector), m);
19031923 p->mempool = m;
1924+ LEAF* leaf = p->mempool->leaf;
19041925
19051926 tPeriodDetector_initToPool(&p->_pd, lowestFreq, highestFreq, -120.0f, mempool);
19061927 p->_current.frequency = 0.0f;
19071928 p->_current.periodicity = 0.0f;
19081929 p->_frames_after_shift = 0;
1930+ p->sampleRate = leaf->sampleRate;
19091931 }
19101932
19111933 void tPitchDetector_free (tPitchDetector* const detector)
@@ -1991,11 +2013,10 @@ float tPitchDetector_harmonic (tPitchDetector* const detector, int harmonicInd · 79 unmodified lines
19912013 float tPitchDetector_predictFrequency (tPitchDetector* const detector)
19922014 {
19932015 _tPitchDetector* p = *detector;
1994− LEAF* leaf = p->mempool->leaf;
19952016
19962017 float period = tPeriodDetector_predictPeriod(&p->_pd);
19972018 if (period > 0.0f)
1998− return leaf->sampleRate / period;
2019+ return p->sampleRate / period;
19992020 return 0.0f;
20002021 }
20012022
@@ -2009,18 +2030,23 @@ int tPitchDetector_indeterminate (tPitchDetector* const detector) · 7 unmodified lines
20092030 void tPitchDetector_setHysteresis (tPitchDetector* const detector, float hysteresis)
20102031 {
20112032 _tPitchDetector* p = *detector;
2012−
20132033 tPeriodDetector_setHysteresis(&p->_pd, hysteresis);
20142034 }
20152035
2036+void 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+
20162043 static inline float calculate_frequency(tPitchDetector* const detector)
20172044 {
20182045 _tPitchDetector* p = *detector;
2019− LEAF* leaf = p->mempool->leaf;
20202046
20212047 float period = p->_pd->_fundamental.period;
20222048 if (period > 0.0f)
2023− return leaf->sampleRate / period;
2049+ return p->sampleRate / period;
20242050 return 0.0f;
20252051 }
20262052
@@ -2131,9 +2157,12 @@ void tDualPitchDetector_initToPool (tDualPitchDetector* const detector, flo · 104 unmodified lines
21312157 _tMempool* m = *mempool;
21322158 _tDualPitchDetector* p = *detector = (_tDualPitchDetector*) mpool_alloc(sizeof(_tDualPitchDetector), m);
21332159 p->mempool = m;
2160+ LEAF* leaf = p->mempool->leaf;
21342161
21352162 tPeriodDetection_initToPool(&p->_pd1, inBuffer, bufSize, bufSize / 2, mempool);
21362163 tPitchDetector_initToPool(&p->_pd2, lowestFreq, highestFreq, mempool);
2164+
2165+ p->sampleRate = leaf->sampleRate;
21372166
21382167 p->_current.frequency = 0.0f;
21392168 p->_current.periodicity = 0.0f;
@@ -2159,7 +2188,6 @@ void tDualPitchDetector_free (tDualPitchDetector* const detector) · 19 unmodified lines
21592188 int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sample)
21602189 {
21612190 _tDualPitchDetector* p = *detector;
2162− LEAF* leaf = p->mempool->leaf;
21632191
21642192 tPeriodDetection_tick(&p->_pd1, sample);
21652193 int ready = tPitchDetector_tick(&p->_pd2, sample);
@@ -2172,7 +2200,7 @@ int tDualPitchDetector_tick (tDualPitchDetector* const detector, float sa · 6 unmodified lines
21722200 if (!pd2_indeterminate && period != 0.0f)
21732201 {
21742202 _pitch_info _i1;
2175− _i1.frequency = leaf->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);
2203+ _i1.frequency = p->sampleRate / tPeriodDetection_getPeriod(&p->_pd1);
21762204 _i1.periodicity = tPeriodDetection_getFidelity(&p->_pd1);
21772205 _pitch_info _i2 = p->_pd2->_current;
21782206
@@ -2276,6 +2304,14 @@ void tDualPitchDetector_setPeriodicityThreshold (tDualPitchDetector* const de · 97 unmodified lines
22762304 p->thresh = thresh;
22772305 }
22782306
2307+void 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+
22792315 static inline void compute_predicted_frequency(tDualPitchDetector* const detector)
22802316 {
22812317 _tDualPitchDetector* p = *detector;
leaf/Src/leaf-delay.c+0−3
@@ -346,9 +346,6 @@ float tLinearDelay_getGain (tLinearDelay* const dl) · 345 unmodified lines
346346 }
347347
348348
349−
350−
351−
352349 /// Hermite Interpolated Delay
353350 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
354351 void 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
9090
9191 os->offset = offset;
9292 os->maxRatio = maxRatio;
93+ os->allowHighQuality = extraQuality;
9394 os->ratio = os->maxRatio;
9495 int idx = (int)(log2f(os->ratio))-1+os->offset;
9596 os->numTaps = __leaf_tablesize_firNumTaps[idx];
@@ -318,7 +319,7 @@ void tOversampler_setRatio (tOversampler* const osr, int ratio) · 222 unmodified lines
318319 else if (ratio == 2 || ratio == 4 || ratio == 8 ||
319320 ratio == 16 || ratio == 32 || ratio == 64)
320321 {
321− os->ratio = os->ratio;
322+ os->ratio = ratio;
322323 int idx = (int)(log2f(os->ratio))-1+os->offset;
323324 os->numTaps = __leaf_tablesize_firNumTaps[idx];
324325 os->phaseLength = os->numTaps / os->ratio;
@@ -326,6 +327,23 @@ void tOversampler_setRatio (tOversampler* const osr, int ratio) · 1 unmodified line
326327 }
327328 }
328329
330+void 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+
329347 int tOversampler_getLatency(tOversampler* const osr)
330348 {
331349 _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
5151 _tMempool* m = *mp;
5252 _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m);
5353 c->mempool = m;
54+ LEAF* leaf = c->mempool->leaf;
5455
5556 c->tauAttack = 100;
5657 c->tauRelease = 100;
@@ -61,6 +62,8 @@ void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp) · 4 unmodified lines
6162 c->R = 0.5f; // compression Ratio
6263 c->M = 3.0f; // decibel Width of knee transition
6364 c->W = 1.0f; // decibel Make-up gain
65+
66+ c->sampleRate = leaf->sampleRate;
6467 }
6568
6669 void tCompressor_free (tCompressor* const comp)
@@ -73,7 +76,6 @@ void tCompressor_free (tCompressor* const comp) · 6 unmodified lines
7376 float tCompressor_tick(tCompressor* const comp, float in)
7477 {
7578 _tCompressor* c = *comp;
76− LEAF* leaf = c->mempool->leaf;
7779
7880 float slope, overshoot;
7981 float alphaAtt, alphaRel;
@@ -107,8 +109,8 @@ float tCompressor_tick(tCompressor* const comp, float in) · 27 unmodified lines
107109
108110 c->x_T[0] = out_db - in_db;
109111
110− alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * leaf->sampleRate));
111− alphaRel = expf(-1.0f/(0.001f * c->tauRelease * leaf->sampleRate));
112+ alphaAtt = expf(-1.0f/(0.001f * c->tauAttack * c->sampleRate));
113+ alphaRel = expf(-1.0f/(0.001f * c->tauRelease * c->sampleRate));
112114
113115 if (c->x_T[0] > c->y_T[1])
114116 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
4242 _tMempool* m = *mp;
4343 _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m);
4444 v->mempool = m;
45+ LEAF* leaf = v->mempool->leaf;
4546
4647 v->param[0] = 0.5f; //wet
4748 v->param[1] = 0.0f; //dry
@@ -62,6 +63,8 @@ void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* const mp) · 14 unmodified lines
6263 v->Rt = (double*) mpool_alloc(sizeof(double) * v->bufsize, m);
6364
6465 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
66+
67+ v->sampleRate = leaf->sampleRate;
6568
6669 tTalkbox_update(voc);
6770 tTalkbox_suspend(voc);
@@ -86,9 +89,8 @@ void tTalkbox_free (tTalkbox* const voc) · 18 unmodified lines
8689 void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
8790 {
8891 _tTalkbox* v = *voc;
89− LEAF* leaf = v->mempool->leaf;
9092
91− float fs = leaf->sampleRate;
93+ float fs = v->sampleRate;
9294 // if(fs < 8000.0f) fs = 8000.0f;
9395 // if(fs > 96000.0f) fs = 96000.0f;
9496
@@ -320,10 +322,9 @@ void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int · 225 unmodified lines
320322 void tTalkbox_setQuality(tTalkbox* const voc, float quality)
321323 {
322324 _tTalkbox* v = *voc;
323− LEAF* leaf = v->mempool->leaf;
324325
325326 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);
327328 if (v->O >= ORD_MAX)
328329 {
329330 v->O = ORD_MAX-1;
@@ -351,7 +352,12 @@ void tTalkbox_setFreeze(tTalkbox* const voc, float freeze) · 21 unmodified lines
351352 v->freeze = freeze;
352353 }
353354
354−
355+void tTalkbox_setSampleRate(tTalkbox* const voc, float sr)
356+{
357+ _tTalkbox* v = *voc;
358+ v->sampleRate = sr;
359+ tTalkbox_update(voc);
360+}
355361
356362 ////
357363
@@ -374,6 +380,7 @@ void tTalkboxFloat_initToPool (tTalkboxFloat* const voc, int bufsize, tMempool* · 16 unmodified lines
374380 _tMempool* m = *mp;
375381 _tTalkboxFloat* v = *voc = (_tTalkboxFloat*) mpool_alloc(sizeof(_tTalkboxFloat), m);
376382 v->mempool = m;
383+ LEAF* leaf = v->mempool->leaf;
377384
378385 v->param[0] = 0.5f; //wet
379386 v->param[1] = 0.0f; //dry
@@ -394,6 +401,8 @@ void tTalkboxFloat_initToPool (tTalkboxFloat* const voc, int bufsize, tMempool* · 14 unmodified lines
394401 v->Rt = (float*) mpool_alloc(sizeof(float) * v->bufsize, m);
395402
396403 v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m);
404+
405+ v->sampleRate = leaf->sampleRate;
397406
398407 tTalkboxFloat_update(voc);
399408 tTalkboxFloat_suspend(voc);
@@ -418,9 +427,8 @@ void tTalkboxFloat_free (tTalkboxFloat* const voc) · 18 unmodified lines
418427 void tTalkboxFloat_update(tTalkboxFloat* const voc) ///update internal parameters...
419428 {
420429 _tTalkboxFloat* v = *voc;
421− LEAF* leaf = v->mempool->leaf;
422430
423− float fs = leaf->sampleRate;
431+ float fs = v->sampleRate;
424432 // if(fs < 8000.0f) fs = 8000.0f;
425433 // if(fs > 96000.0f) fs = 96000.0f;
426434
@@ -656,10 +664,9 @@ void tTalkboxFloat_lpc(float *buf, float *car, float* dl, float* Rt, int32_t n, · 229 unmodified lines
656664 void tTalkboxFloat_setQuality(tTalkboxFloat* const voc, float quality)
657665 {
658666 _tTalkboxFloat* v = *voc;
659− LEAF* leaf = v->mempool->leaf;
660667
661668 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);
663670 if (v->O >= ORD_MAX)
664671 {
665672 v->O = ORD_MAX-1;
@@ -687,6 +694,12 @@ void tTalkboxFloat_setFreeze(tTalkboxFloat* const voc, int freeze) · 21 unmodified lines
687694 v->freeze = freeze;
688695 }
689696
697+void tTalkboxFloat_setSampleRate(tTalkboxFloat* const voc, float sr)
698+{
699+ _tTalkboxFloat* v = *voc;
700+ v->sampleRate = sr;
701+ tTalkboxFloat_update(voc);
702+}
690703
691704 //============================================================================================================
692705 // VOCODER
@@ -702,6 +715,9 @@ void tVocoder_initToPool (tVocoder* const voc, tMempool* const mp) · 9 unmodified lines
702715 _tMempool* m = *mp;
703716 _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m);
704717 v->mempool = m;
718+ LEAF* leaf = v->mempool->leaf;
719+
720+ v->invSampleRate = leaf->invSampleRate;
705721
706722 v->param[0] = 0.33f; //input select
707723 v->param[1] = 0.50f; //output dB
@@ -725,9 +741,8 @@ void tVocoder_free (tVocoder* const voc) · 17 unmodified lines
725741 void tVocoder_update (tVocoder* const voc)
726742 {
727743 _tVocoder* v = *voc;
728− LEAF* leaf = v->mempool->leaf;
729744
730− float tpofs = 6.2831853f * leaf->invSampleRate;
745+ float tpofs = 6.2831853f * v->invSampleRate;
731746
732747 float rr, th;
733748
@@ -871,7 +886,6 @@ float tVocoder_tick (tVocoder* const voc, float synth, float voice) · 137 unmodified lines
871886 if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability
872887
873888 return o;
874−
875889 }
876890
877891 void tVocoder_suspend (tVocoder* const voc)
@@ -885,6 +899,13 @@ void tVocoder_suspend (tVocoder* const voc) · 7 unmodified lines
885899 v->kval = 0;
886900 }
887901
902+void tVocoder_setSampleRate (tVocoder* const voc, float sr)
903+{
904+ _tVocoder* v = *voc;
905+ v->invSampleRate = 1.0f/sr;
906+ tVocoder_update(voc);
907+}
908+
888909
889910 /// Glottal Pulse (Rosenberg model)
890911
@@ -898,6 +919,9 @@ void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const gp, tMempo · 7 unmodified lines
898919 _tMempool* m = *mp;
899920 _tRosenbergGlottalPulse* g = *gp = (_tRosenbergGlottalPulse*) mpool_alloc(sizeof(_tRosenbergGlottalPulse), m);
900921 g->mempool = m;
922+ LEAF* leaf = g->mempool->leaf;
923+
924+ g->invSampleRate = leaf->invSampleRate;
901925
902926 g->phase = 0.0f;
903927 g->openLength = 0.0f;
@@ -972,10 +996,9 @@ float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const g · 68 unmodified lines
972996 void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const gp, float freq)
973997 {
974998 _tRosenbergGlottalPulse* g = *gp;
975− LEAF* leaf = g->mempool->leaf;
976999
9771000 g->freq = freq;
978− g->inc = freq * leaf->invSampleRate;
1001+ g->inc = freq * g->invSampleRate;
9791002 g->inc -= (int) g->inc;
9801003 }
9811004
@@ -1001,6 +1024,12 @@ void tRosenbergGlottalPulse_setOpenLengthAndPulseLength (tRosenbergG · 19 unmodified lines
10011024 g->invPulseLengthMinusOpenLength = 1.0f / (g->pulseLength - g->openLength);
10021025 }
10031026
1027+void 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+}
10041033
10051034
10061035 //============================================================================================================
@@ -1140,6 +1169,13 @@ void tSOLAD_resetState(tSOLAD* const wp) · 133 unmodified lines
11401169 w->blocksize = INITPERIOD;
11411170 }
11421171
1172+void 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+
11431179 /******************************************************************************/
11441180 /******************** private procedures **************************************/
11451181 /******************************************************************************/
@@ -1380,11 +1416,14 @@ void tPitchShift_initToPool (tPitchShift* const psr, tDualPitchDetector* const d · 234 unmodified lines
13801416 _tMempool* m = *mp;
13811417 _tPitchShift* ps = *psr = (_tPitchShift*) mpool_alloc(sizeof(_tPitchShift), m);
13821418 ps->mempool = m;
1419+ LEAF* leaf = ps->mempool->leaf;
13831420
13841421 ps->pd = *dpd;
13851422 ps->bufSize = bufSize;
13861423 ps->pickiness = 0.0f;
13871424
1425+ ps->sampleRate = leaf->sampleRate;
1426+
13881427 tSOLAD_initToPool(&ps->sola, pow(2.0, ceil(log2(ps->bufSize * 2.0))), mp);
13891428 tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
13901429 }
@@ -1400,13 +1439,12 @@ void tPitchShift_free (tPitchShift* const psr) · 9 unmodified lines
14001439 void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float* out)
14011440 {
14021441 _tPitchShift* ps = *psr;
1403− LEAF* leaf = ps->mempool->leaf;
14041442
14051443 float detected = tDualPitchDetector_getFrequency(&ps->pd);
14061444 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
14071445 if (detected > 0.0f && periodicity > ps->pickiness)
14081446 {
1409− float period = leaf->sampleRate / detected;
1447+ float period = ps->sampleRate / detected;
14101448 tSOLAD_setPeriod(&ps->sola, period);
14111449 tSOLAD_setPitchFactor(&ps->sola, factor);
14121450 }
@@ -1417,7 +1455,6 @@ void tPitchShift_shiftBy (tPitchShift* const psr, float factor, float* in, float · 4 unmodified lines
14171455 void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, float* out)
14181456 {
14191457 _tPitchShift* ps = *psr;
1420− LEAF* leaf = ps->mempool->leaf;
14211458
14221459 float detected = tDualPitchDetector_getFrequency(&ps->pd);
14231460 float periodicity = tDualPitchDetector_getPeriodicity(&ps->pd);
@@ -1425,7 +1462,7 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 1 unmodified line
14251462 {
14261463 float period = 1.0f / detected;
14271464 float factor = freq * period;
1428− tSOLAD_setPeriod(&ps->sola, leaf->sampleRate * period);
1465+ tSOLAD_setPeriod(&ps->sola, ps->sampleRate * period);
14291466 tSOLAD_setPitchFactor(&ps->sola, factor);
14301467 }
14311468
@@ -1435,10 +1472,15 @@ void tPitchShift_shiftTo (tPitchShift* const psr, float freq, float* in, floa · 3 unmodified lines
14351472 void tPitchShift_setPickiness (tPitchShift* const psr, float p)
14361473 {
14371474 _tPitchShift* ps = *psr;
1438−
14391475 ps->pickiness = p;
14401476 }
14411477
1478+void tPitchShift_setSampleRate(tPitchShift* const psr, float sr)
1479+{
1480+ _tPitchShift* ps = *psr;
1481+ tSOLAD_setSampleRate(&ps->sola, sr);
1482+}
1483+
14421484
14431485 //============================================================================================================
14441486 // SIMPLERETUNE
@@ -1571,6 +1613,16 @@ float tSimpleRetune_getInputFrequency (tSimpleRetune* const rt) · 126 unmodified lines
15711613 return tDualPitchDetector_getFrequency(&r->dp);
15721614 }
15731615
1616+void 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+
15741626 //============================================================================================================
15751627 // RETUNE
15761628 //============================================================================================================
@@ -1708,6 +1760,16 @@ float tRetune_getInputFrequency (tRetune* const rt) · 131 unmodified lines
17081760 return tDualPitchDetector_getFrequency(&r->dp);
17091761 }
17101762
1763+void 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+
17111773 //============================================================================================================
17121774 // FORMANTSHIFTER
17131775 //============================================================================================================
@@ -1738,14 +1800,16 @@ void tFormantShifter_initToPool (tFormantShifter* const fsr, int order, tMempool · 24 unmodified lines
17381800
17391801 fs->fbuff = (float*) mpool_calloc(sizeof(float*) * fs->ford, m);
17401802
1803+ fs->sampleRate = leaf->sampleRate;
1804+ fs->invSampleRate = leaf->invSampleRate;
17411805
1742− fs->falph = powf(0.001f, 10.0f * leaf->invSampleRate);
1743− fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * leaf->sampleRate)) - 0.1916f);
1806+ fs->falph = powf(0.001f, 10.0f * fs->invSampleRate);
1807+ fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f * fs->sampleRate)) - 0.1916f);
17441808 fs->fhp = 0.0f;
17451809 fs->flp = 0.0f;
1746− fs->flpa = powf(0.001f, 10.0f * leaf->invSampleRate);
1810+ fs->flpa = powf(0.001f, 10.0f * fs->invSampleRate);
17471811 fs->fmute = 1.0f;
1748− fs->fmutealph = powf(0.001f, 1.0f * leaf->invSampleRate);
1812+ fs->fmutealph = powf(0.001f, 1.0f * fs->invSampleRate);
17491813 fs->cbi = 0;
17501814 fs->intensity = 1.0f;
17511815 fs->invIntensity = 1.0f;
@@ -1927,8 +1991,6 @@ void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity) · 175 unmodified lines
19271991 {
19281992 _tFormantShifter* fs = *fsr;
19291993
1930−
1931−
19321994 fs->intensity = LEAF_clip(1.0f, intensity, 100.0f);
19331995
19341996 // tFeedbackLeveler_setTargetLevel(&fs->fbl1, fs->intensity);
@@ -1942,5 +2004,17 @@ void tFormantShifter_setIntensity(tFormantShifter* const fsr, float intensity) · 7 unmodified lines
19422004 {
19432005 fs->invIntensity = 1.0f;
19442006 }
2007+}
19452008
2009+void 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);
19462020 }
leaf/Src/leaf-electrical.c+10−0
@@ -222,6 +222,16 @@ void tWDF_setSampleRate(tWDF* const wdf, float sample_rate) · 221 unmodified lines
222222 {
223223 _tWDF* r = *wdf;
224224 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+ }
225235 }
226236
227237 uint8_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
118118 env->loop = loop;
119119 }
120120
121−
122121 void tEnvelope_on(tEnvelope* const envlp, float velocity)
123122 {
124123 _tEnvelope* env = *envlp;
@@ -495,7 +494,6 @@ float calcADSR3Coef(float rate, float targetRatio) · 370 unmodified lines
495494 return (rate <= 0.0f) ? 0.0f : expf(-logf((1.0f + targetRatio) / targetRatio) / rate);
496495 }
497496
498−
499497 void tADSRS_init(tADSRS* const adsrenv, float attack, float decay, float sustain, float release, LEAF* const leaf)
500498 {
501499 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
509507
510508 LEAF* leaf = adsr->mempool->leaf;
511509
512− adsr->sampleRateInMs = leaf->sampleRate * 0.001f;
510+ adsr->sampleRate = leaf->sampleRate;
511+ adsr->sampleRateInMs = adsr->sampleRate * 0.001f;
513512 adsr->targetRatioA = 0.3f;
514513 adsr->targetRatioDR = 0.0001f;
514+ adsr->attack = attack;
515515 adsr->attackRate = attack * adsr->sampleRateInMs;
516516 adsr->attackCoef = calcADSR3Coef(attack * adsr->sampleRateInMs, adsr->targetRatioA);
517517 adsr->attackBase = (1.0f + adsr->targetRatioA) * (1.0f - adsr->attackCoef);
518518
519+ adsr->decay = decay;
519520 adsr->decayRate = decay * adsr->sampleRateInMs;
520521 adsr->decayCoef = calcADSR3Coef(decay * adsr->sampleRateInMs,adsr-> targetRatioDR);
521522 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
523524 adsr->sustainLevel = sustain;
524525 adsr->decayBase = (adsr->sustainLevel - adsr->targetRatioDR) * (1.0f - adsr->decayCoef);
525526
527+ adsr->release = release;
526528 adsr->releaseRate = release * adsr->sampleRateInMs;
527529 adsr->releaseCoef = calcADSR3Coef(release * adsr->sampleRateInMs, adsr->targetRatioDR);
528530 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -546,6 +548,7 @@ void tADSRS_setAttack(tADSRS* const adsrenv, float attack) · 17 unmodified lines
546548 {
547549 _tADSRS* adsr = *adsrenv;
548550
551+ adsr->attack = attack;
549552 adsr->attackRate = attack * adsr->sampleRateInMs;
550553 adsr->attackCoef = calcADSR3Coef(adsr->attackRate, adsr->targetRatioA);
551554 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
555558 {
556559 _tADSRS* adsr = *adsrenv;
557560
561+ adsr->decay = decay;
558562 adsr->decayRate = decay * adsr->sampleRateInMs;
559563 adsr->decayCoef = calcADSR3Coef(adsr->decayRate,adsr-> targetRatioDR);
560564 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
572576 {
573577 _tADSRS* adsr = *adsrenv;
574578
579+ adsr->release = release;
575580 adsr->releaseRate = release * adsr->sampleRateInMs;
576581 adsr->releaseCoef = calcADSR3Coef(adsr->releaseRate, (float)adsr->targetRatioDR);
577582 adsr->releaseBase = -adsr->targetRatioDR * (1.0f - adsr->releaseCoef);
@@ -581,7 +586,6 @@ void tADSRS_setRelease(tADSRS* const adsrenv, float release) · 3 unmodified lines
581586 void tADSRS_setLeakFactor(tADSRS* const adsrenv, float leakFactor)
582587 {
583588 _tADSRS* adsr = *adsrenv;
584−
585589 adsr->leakFactor = leakFactor;
586590 }
587591
@@ -606,7 +610,6 @@ float tADSRS_tick(tADSRS* const adsrenv) · 18 unmodified lines
606610 {
607611 _tADSRS* adsr = *adsrenv;
608612
609−
610613 switch (adsr->state) {
611614 case env_idle:
612615 break;
@@ -641,6 +644,19 @@ float tADSRS_tick(tADSRS* const adsrenv) · 28 unmodified lines
641644 return adsr->output * adsr->gain;
642645 }
643646
647+void 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+//================================================================================
644660
645661 /* ADSR 4 */ // new version of our original table-based ADSR but with the table passed in by the user
646662 // 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
663679 adsr->buff_size = bufferSize;
664680 adsr->buff_sizeMinusOne = bufferSize - 1;
665681
666− adsr->bufferSizeDividedBySampleRateInMs = bufferSize / (leaf->sampleRate * 0.001f);
682+ adsr->sampleRate = leaf->sampleRate;
683+ adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
667684
668685 if (attack < 0.0f)
669686 attack = 0.0f;
@@ -685,6 +702,9 @@ void tADSRT_initToPool (tADSRT* const adsrenv, float attack, float decay, · 15 unmodified lines
685702
686703 adsr->sustain = sustain;
687704
705+ adsr->attack = attack;
706+ adsr->decay = decay;
707+ adsr->release = release;
688708 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
689709 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
690710 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
@@ -707,7 +727,7 @@ void tADSRT_setAttack(tADSRT* const adsrenv, float attack) · 16 unmodified lines
707727 {
708728 attack = 0.0f;
709729 }
710−
730+ adsr->attack = attack;
711731 adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / attack;
712732 }
713733
@@ -719,6 +739,7 @@ void tADSRT_setDecay(tADSRT* const adsrenv, float decay) · 5 unmodified lines
719739 {
720740 decay = 0.0f;
721741 }
742+ adsr->decay = decay;
722743 adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / decay;
723744 }
724745
@@ -739,6 +760,7 @@ void tADSRT_setRelease(tADSRT* const adsrenv, float release) · 14 unmodified lines
739760 {
740761 release = 0.0f;
741762 }
763+ adsr->release = release;
742764 adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
743765 }
744766
@@ -988,7 +1010,17 @@ float tADSRT_tickNoInterp(tADSRT* const adsrenv) · 243 unmodified lines
9881010 return adsr->next;
9891011 }
9901012
991−
1013+void 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+}
9921024
9931025 /////-----------------
9941026 /* Ramp */
@@ -1005,7 +1037,8 @@ void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, t · 10 unmodified lines
10051037
10061038 LEAF* leaf = ramp->mempool->leaf;
10071039
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);
10091042 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
10101043 ramp->curr = 0.0f;
10111044 ramp->dest = 0.0f;
@@ -1026,7 +1059,6 @@ void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, t · 14 unmodified lines
10261059 void tRamp_free (tRamp* const r)
10271060 {
10281061 _tRamp* ramp = *r;
1029−
10301062 mpool_free((char*)ramp, ramp->mempool);
10311063 }
10321064
@@ -1082,17 +1114,17 @@ float tRamp_sample(tRamp* const ramp) · 49 unmodified lines
10821114 return r->curr;
10831115 }
10841116
1085−void tRampSampleRateChanged(tRamp* const ramp)
1117+void tRamp_setSampleRate(tRamp* const ramp, float sr)
10861118 {
10871119 _tRamp* r = *ramp;
1088− LEAF* leaf = r->mempool->leaf;
10891120
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);
10911123 r->factor = (1.0f / r->time) * r->inv_sr_ms * (float)r->samples_per_tick;
10921124 r->inc = (r->dest - r->curr) * r->factor;
10931125 }
10941126
1095−
1127+//===========================================================================================
10961128
10971129 /* RampUpDown */
10981130 void 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
11081140
11091141 LEAF* leaf = ramp->mempool->leaf;
11101142
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);
11121145 ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
11131146 ramp->curr = 0.0f;
11141147 ramp->dest = 0.0f;
@@ -1139,7 +1172,6 @@ void tRampUpDown_initToPool(tRampUpDown* const r, float upTime, float downTim · 24 unmodified lines
11391172 void tRampUpDown_free (tRampUpDown* const r)
11401173 {
11411174 _tRampUpDown* ramp = *r;
1142−
11431175 mpool_free((char*)ramp, ramp->mempool);
11441176 }
11451177
@@ -1258,7 +1290,6 @@ void tExpSmooth_initToPool (tExpSmooth* const expsmooth, float val, float f · 112 unmodified lines
12581290 void tExpSmooth_free (tExpSmooth* const expsmooth)
12591291 {
12601292 _tExpSmooth* smooth = *expsmooth;
1261−
12621293 mpool_free((char*)smooth, smooth->mempool);
12631294 }
12641295
@@ -1340,7 +1371,6 @@ void tSlide_initToPool (tSlide* const sl, float upSlide, float downSlide, · 75 unmodified lines
13401371 void tSlide_free (tSlide* const sl)
13411372 {
13421373 _tSlide* s = *sl;
1343−
13441374 mpool_free((char*)s, s->mempool);
13451375 }
13461376
leaf/Src/leaf-filters.c+253−244
@@ -1,10 +1,10 @@
11 /*==============================================================================
2−
3− leaf-filter.c
4− Created: 20 Jan 2017 12:01:10pm
5− Author: Michael R Mulshine
6−
7−==============================================================================*/
2+
3+ leaf-filter.c
4+ Created: 20 Jan 2017 12:01:10pm
5+ Author: Michael R Mulshine
6+
7+ ==============================================================================*/
88
99 #if _WIN32 || _WIN64
1010
@@ -85,14 +85,17 @@ void tOnePole_initToPool (tOnePole* const ft, float freq, tMempool* const · 74 unmodified lines
8585 _tMempool* m = *mp;
8686 _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m);
8787 f->mempool = m;
88+ LEAF* leaf = f->mempool->leaf;
8889
8990 f->gain = 1.0f;
9091 f->a0 = 1.0;
9192
92− tOnePole_setFreq(ft, freq);
93−
9493 f->lastIn = 0.0f;
9594 f->lastOut = 0.0f;
95+
96+ f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
97+
98+ tOnePole_setFreq(ft, freq);
9699 }
97100
98101 void tOnePole_free (tOnePole* const ft)
@@ -131,9 +134,9 @@ void tOnePole_setPole(tOnePole* const ft, float thePole) · 32 unmodified lines
131134 void tOnePole_setFreq (tOnePole* const ft, float freq)
132135 {
133136 _tOnePole* f = *ft;
134− LEAF* leaf = f->mempool->leaf;
135137
136− f->b0 = freq * leaf->twoPiTimesInvSampleRate;
138+ f->freq = freq;
139+ f->b0 = f->freq * f->twoPiTimesInvSampleRate;
137140 f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
138141 f->a1 = 1.0f - f->b0;
139142 }
@@ -165,6 +168,15 @@ float tOnePole_tick(tOnePole* const ft, float input) · 25 unmodified lines
165168 return out;
166169 }
167170
171+void 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+
168180 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
169181 void tTwoPole_init(tTwoPole* const ft, LEAF* const leaf)
170182 {
@@ -176,6 +188,7 @@ void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp) · 5 unmodified lines
176188 _tMempool* m = *mp;
177189 _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m);
178190 f->mempool = m;
191+ LEAF* leaf = f->mempool->leaf;
179192
180193 f->gain = 1.0f;
181194 f->a0 = 1.0;
@@ -183,12 +196,14 @@ void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp) · 1 unmodified line
183196
184197 f->lastOut[0] = 0.0f;
185198 f->lastOut[1] = 0.0f;
199+
200+ f->sampleRate = leaf->sampleRate;
201+ f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
186202 }
187203
188204 void tTwoPole_free (tTwoPole* const ft)
189205 {
190206 _tTwoPole* f = *ft;
191−
192207 mpool_free((char*)f, f->mempool);
193208 }
194209
@@ -223,14 +238,12 @@ void tTwoPole_setA2(tTwoPole* const ft, float a2) · 28 unmodified lines
223238 f->a2 = a2;
224239 }
225240
226−
227241 void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, int normalize)
228242 {
229243 _tTwoPole* f = *ft;
230− LEAF* leaf = f->mempool->leaf;
231244
232− float sampleRate = leaf->sampleRate;
233− float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
245+ float sampleRate = f->sampleRate;
246+ float twoPiTimesInvSampleRate = f->twoPiTimesInvSampleRate;
234247
235248 if (frequency < 0.0f) frequency = 0.0f;
236249 if (frequency > (sampleRate * 0.49f)) frequency = sampleRate * 0.49f;
@@ -267,21 +280,20 @@ void tTwoPole_setGain(tTwoPole* const ft, float gain) · 30 unmodified lines
267280 f->gain = gain;
268281 }
269282
270−void tTwoPoleSampleRateChanged (tTwoPole* const ft)
283+void tTwoPole_setSampleRate (tTwoPole* const ft, float sr)
271284 {
272285 _tTwoPole* f = *ft;
273− LEAF* leaf = f->mempool->leaf;
274286
275− float twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
287+ f->twoPiTimesInvSampleRate = (1.0f/sr) * TWO_PI;
276288
277289 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);
279291
280292 if ( f->normalize )
281293 {
282294 // Normalize the filter gain ... not terribly efficient.
283− float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * twoPiTimesInvSampleRate);
284− float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * twoPiTimesInvSampleRate);
295+ float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * f->twoPiTimesInvSampleRate);
296+ float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * f->twoPiTimesInvSampleRate);
285297 f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
286298 }
287299 }
@@ -297,17 +309,18 @@ void tOneZero_initToPool (tOneZero* const ft, float theZero, tMempool* co · 9 unmodified lines
297309 _tMempool* m = *mp;
298310 _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m);
299311 f->mempool = m;
312+ LEAF* leaf = f->mempool->leaf;
300313
301314 f->gain = 1.0f;
302315 f->lastIn = 0.0f;
303316 f->lastOut = 0.0f;
317+ f->invSampleRate = leaf->invSampleRate;
304318 tOneZero_setZero(ft, theZero);
305319 }
306320
307321 void tOneZero_free (tOneZero* const ft)
308322 {
309323 _tOneZero* f = *ft;
310−
311324 mpool_free((char*)f, f->mempool);
312325 }
313326
@@ -363,13 +376,12 @@ void tOneZero_setGain(tOneZero *ft, float gain) · 49 unmodified lines
363376 float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )
364377 {
365378 _tOneZero* f = *ft;
366− LEAF* leaf = f->mempool->leaf;
367379
368380 if ( frequency <= 0.0f) frequency = 0.05f;
369381
370382 f->frequency = frequency;
371383
372− float omegaT = 2 * PI * frequency * leaf->invSampleRate;
384+ float omegaT = 2 * PI * frequency * f->invSampleRate;
373385 float real = 0.0, imag = 0.0;
374386
375387 real += f->b0;
@@ -391,6 +403,12 @@ float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency ) · 15 unmodified lines
391403 return phase / omegaT;
392404 }
393405
406+void tOneZero_setSampleRate (tOneZero* const ft, float sr)
407+{
408+ _tOneZero* f = *ft;
409+ f->invSampleRate = 1.0f/sr;
410+}
411+
394412 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
395413 void tTwoZero_init(tTwoZero* const ft, LEAF* const leaf)
396414 {
@@ -402,7 +420,9 @@ void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp) · 5 unmodified lines
402420 _tMempool* m = *mp;
403421 _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m);
404422 f->mempool = m;
423+ LEAF* leaf = f->mempool->leaf;
405424
425+ f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
406426 f->gain = 1.0f;
407427 f->lastIn[0] = 0.0f;
408428 f->lastIn[1] = 0.0f;
@@ -411,7 +431,6 @@ void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp) · 2 unmodified lines
411431 void tTwoZero_free (tTwoZero* const ft)
412432 {
413433 _tTwoZero* f = *ft;
414−
415434 mpool_free((char*)f, f->mempool);
416435 }
417436
@@ -431,7 +450,6 @@ float tTwoZero_tick(tTwoZero* const ft, float input) · 13 unmodified lines
431450 void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)
432451 {
433452 _tTwoZero* f = *ft;
434− LEAF* leaf = f->mempool->leaf;
435453
436454 // Should also deal with frequency being > half sample rate / nyquist. See STK
437455 if (freq < 0.0f) freq = 0.0f;
@@ -441,7 +459,7 @@ void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius) · 3 unmodified lines
441459 f->radius = radius;
442460
443461 f->b2 = radius * radius;
444− f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
462+ f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
445463
446464 // Normalize the filter gain. From STK.
447465 if ( f->b1 > 0.0f ) // Maximum at z = 0.
@@ -479,10 +497,11 @@ void tTwoZero_setGain(tTwoZero* const ft, float gain) · 31 unmodified lines
479497 f->gain = gain;
480498 }
481499
482−void tTwoZeroSampleRateChanged(tTwoZero* const ft)
500+void tTwoZero_setSampleRate(tTwoZero* const ft, float sr)
483501 {
484502 _tTwoZero* f = *ft;
485503
504+ f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
486505 tTwoZero_setNotch(ft, f->frequency, f->radius);
487506 }
488507
@@ -509,7 +528,6 @@ void tPoleZero_initToPool (tPoleZero* const pzf, tMempool* const mp) · 20 unmodified lines
509528 void tPoleZero_free (tPoleZero* const pzf)
510529 {
511530 _tPoleZero* f = *pzf;
512−
513531 mpool_free((char*)f, f->mempool);
514532 }
515533
@@ -611,6 +629,7 @@ void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp) · 95 unmodified lines
611629 _tMempool* m = *mp;
612630 _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m);
613631 f->mempool = m;
632+ LEAF* leaf = f->mempool->leaf;
614633
615634 f->gain = 1.0f;
616635
@@ -621,12 +640,13 @@ void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp) · 4 unmodified lines
621640 f->lastIn[1] = 0.0f;
622641 f->lastOut[0] = 0.0f;
623642 f->lastOut[1] = 0.0f;
643+
644+ f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
624645 }
625646
626647 void tBiQuad_free (tBiQuad* const ft)
627648 {
628649 _tBiQuad* f = *ft;
629−
630650 mpool_free((char*)f, f->mempool);
631651 }
632652
@@ -650,11 +670,10 @@ float tBiQuad_tick(tBiQuad* const ft, float input) · 17 unmodified lines
650670 void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int normalize)
651671 {
652672 _tBiQuad* f = *ft;
653− LEAF* leaf = f->mempool->leaf;
654673
655674 if (freq < 0.0f) freq = 0.0f;
656− if (freq > (leaf->sampleRate * 0.49f))
657− freq = leaf->sampleRate * 0.49f;
675+ if (freq > (f->sampleRate * 0.49f))
676+ freq = f->sampleRate * 0.49f;
658677 if (radius < 0.0f) radius = 0.0f;
659678 if (radius >= 1.0f) radius = 1.0f;
660679
@@ -663,7 +682,7 @@ void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int no · 2 unmodified lines
663682 f->normalize = normalize;
664683
665684 f->a2 = radius * radius;
666− f->a1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate);
685+ f->a1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate);
667686
668687 if (normalize)
669688 {
@@ -676,15 +695,14 @@ void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, int no · 6 unmodified lines
676695 void tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)
677696 {
678697 _tBiQuad* f = *ft;
679− LEAF* leaf = f->mempool->leaf;
680698
681699 if (freq < 0.0f) freq = 0.0f;
682− if (freq > (leaf->sampleRate * 0.49f))
683− freq = leaf->sampleRate * 0.49f;
700+ if (freq > (f->sampleRate * 0.49f))
701+ freq = f->sampleRate * 0.49f;
684702 if (radius < 0.0f) radius = 0.0f;
685703
686704 f->b2 = radius * radius;
687− f->b1 = -2.0f * radius * cosf(freq * leaf->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
705+ f->b1 = -2.0f * radius * cosf(freq * f->twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
688706
689707 // Does not attempt to normalize filter gain.
690708 }
@@ -743,13 +761,15 @@ void tBiQuad_setGain(tBiQuad* const ft, float gain) · 52 unmodified lines
743761 f->gain = gain;
744762 }
745763
746−void tBiQuadSampleRateChanged(tBiQuad* const ft)
764+void tBiQuad_setSampleRate(tBiQuad* const ft, float sr)
747765 {
748766 _tBiQuad* f = *ft;
749− LEAF* leaf = f->mempool->leaf;
767+
768+ f->sampleRate = sr;
769+ f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/f->sampleRate);
750770
751771 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);
753773
754774 if (f->normalize)
755775 {
@@ -764,12 +784,10 @@ void tBiQuadSampleRateChanged(tBiQuad* const ft) · 8 unmodified lines
764784 void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q, LEAF* const leaf)
765785 {
766786 tSVF_initToPool (svff, type, freq, Q, &leaf->mempool);
767−
768787 // or maybe this?
769788 /*
770789 * hp=1 bp=A/Q (where A is 10^(G/40) and G is gain in decibels) and lp = 1
771790 */
772−
773791 }
774792
775793 void 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
779797 svf->mempool = m;
780798
781799 LEAF* leaf = svf->mempool->leaf;
782−
800+
801+ svf->sampleRate = leaf->sampleRate;
802+ svf->invSampleRate = leaf->invSampleRate;
803+
783804 svf->type = type;
784−
805+
785806 svf->ic1eq = 0;
786807 svf->ic2eq = 0;
787808 svf->Q = Q;
788809 svf->cutoff = freq;
789− svf->g = tanf(PI * freq * leaf->invSampleRate);
810+ svf->g = tanf(PI * freq * svf->invSampleRate);
790811 svf->k = 1.0f/Q;
791812 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
792813 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
796817 svf->cB = 0.0f;
797818 svf->cBK = 0.0f;
798819 svf->cL = 1.0f;
799−
820+
800821 if (type == SVFTypeLowpass)
801822 {
802823 svf->cH = 0.0f;
@@ -811,7 +832,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 8 unmodified lines
811832 svf->cBK = 0.0f;
812833 svf->cL = 0.0f;
813834 }
814−
835+
815836 else if (type == SVFTypeHighpass)
816837 {
817838 svf->cH = 1.0f;
@@ -819,7 +840,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 1 unmodified line
819840 svf->cBK = -1.0f;
820841 svf->cL = -1.0f;
821842 }
822−
843+
823844 else if (type == SVFTypeNotch)
824845 {
825846 svf->cH = 1.0f;
@@ -827,7 +848,7 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 1 unmodified line
827848 svf->cBK = -1.0f;
828849 svf->cL = 0.0f;
829850 }
830−
851+
831852 else if (type == SVFTypePeak)
832853 {
833854 svf->cH = 1.0f;
@@ -840,7 +861,6 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 6 unmodified lines
840861 void tSVF_free (tSVF* const svff)
841862 {
842863 _tSVF* svf = *svff;
843−
844864 mpool_free((char*)svf, svf->mempool);
845865 }
846866
@@ -866,10 +886,9 @@ float tSVF_tick(tSVF* const svff, float v0) · 19 unmodified lines
866886 void tSVF_setFreq(tSVF* const svff, float freq)
867887 {
868888 _tSVF* svf = *svff;
869− LEAF* leaf = svf->mempool->leaf;
870889
871− svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);
872− svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);
890+ svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
891+ svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
873892 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
874893 svf->a2 = svf->g * svf->a1;
875894 svf->a3 = svf->g * svf->a2;
@@ -880,7 +899,7 @@ void tSVF_setQ(tSVF* const svff, float Q) · 4 unmodified lines
880899 _tSVF* svf = *svff;
881900 svf->Q = Q;
882901 svf->k = 1.0f/Q;
883−
902+
884903 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
885904 svf->a2 = svf->g * svf->a1;
886905 svf->a3 = svf->g * svf->a2;
@@ -889,16 +908,23 @@ void tSVF_setQ(tSVF* const svff, float Q) · 2 unmodified lines
889908 void tSVF_setFreqAndQ(tSVF* const svff, float freq, float Q)
890909 {
891910 _tSVF* svf = *svff;
892− LEAF* leaf = svf->mempool->leaf;
893911
894− svf->cutoff = LEAF_clip(0.0f, freq, leaf->sampleRate * 0.5f);
912+ svf->cutoff = LEAF_clip(0.0f, freq, svf->sampleRate * 0.5f);
895913 svf->k = 1.0f/Q;
896− svf->g = tanf(PI * svf->cutoff * leaf->invSampleRate);
914+ svf->g = tanf(PI * svf->cutoff * svf->invSampleRate);
897915 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
898916 svf->a2 = svf->g * svf->a1;
899917 svf->a3 = svf->g * svf->a2;
900918 }
901919
920+void 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+
902928 #if LEAF_INCLUDE_FILTERTAN_TABLE
903929 // Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.
904930 void 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
927953 void tEfficientSVF_free (tEfficientSVF* const svff)
928954 {
929955 _tEfficientSVF* svf = *svff;
930−
931956 mpool_free((char*)svf, svf->mempool);
932957 }
933958
@@ -983,10 +1008,10 @@ void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const m · 49 unmodified lines
9831008 _tMempool* m = *mp;
9841009 _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m);
9851010 f->mempool = m;
986−
9871011 LEAF* leaf = f->mempool->leaf;
9881012
989− f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));
1013+ f->twoPiTimesInvSampleRate = leaf->twoPiTimesInvSampleRate;
1014+ f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
9901015 f->ys = 0.0f;
9911016 f->xs = 0.0f;
9921017
@@ -996,18 +1021,15 @@ void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const m · 3 unmodified lines
9961021 void tHighpass_free (tHighpass* const ft)
9971022 {
9981023 _tHighpass* f = *ft;
999−
10001024 mpool_free((char*)f, f->mempool);
10011025 }
10021026
10031027 void tHighpass_setFreq(tHighpass* const ft, float freq)
10041028 {
10051029 _tHighpass* f = *ft;
1006− LEAF* leaf = f->mempool->leaf;
10071030
10081031 f->frequency = freq;
1009− f->R = (1.0f - (freq * leaf->twoPiTimesInvSampleRate));
1010−
1032+ f->R = (1.0f - (freq * f->twoPiTimesInvSampleRate));
10111033 }
10121034
10131035 float tHighpass_getFreq(tHighpass* const ft)
@@ -1025,12 +1047,11 @@ float tHighpass_tick(tHighpass* const ft, float x) · 11 unmodified lines
10251047 return f->ys;
10261048 }
10271049
1028−void tHighpassSampleRateChanged(tHighpass* const ft)
1050+void tHighpass_setSampleRate(tHighpass* const ft, float sr)
10291051 {
10301052 _tHighpass* f = *ft;
1031− LEAF* leaf = f->mempool->leaf;
1032−
1033− f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf->invSampleRate));
1053+ f->twoPiTimesInvSampleRate = TWO_PI * (1.0f/sr);
1054+ f->R = (1.0f - (f->frequency * f->twoPiTimesInvSampleRate));
10341055 }
10351056
10361057 void 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
10681089 {
10691090 _tButterworth* f = *ft;
10701091
1071− for(int i = 0; i < f->numSVF; ++i)
1072− tSVF_free(&f->svf[i]);
1092+ for (int i = 0; i < f->numSVF; ++i) tSVF_free(&f->svf[i]);
10731093
10741094 mpool_free((char*)f->svf, f->mempool);
10751095 mpool_free((char*)f, f->mempool);
@@ -1080,7 +1100,7 @@ float tButterworth_tick(tButterworth* const ft, float samp) · 4 unmodified lines
10801100 _tButterworth* f = *ft;
10811101
10821102 for(int i = 0; i < f->numSVF; ++i)
1083− samp = tSVF_tick(&f->svf[i], samp);
1103+ samp = tSVF_tick(&f->svf[i], samp);
10841104
10851105 return samp;
10861106 }
@@ -1109,18 +1129,18 @@ void tButterworth_setF2(tButterworth* const ft, float f2) · 22 unmodified lines
11091129
11101130 void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
11111131 {
1112−// _tButterworth* f = *ft;
11131132 tButterworth_setF1(ft, f1);
1114− tButterworth_setF1(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−// }
1133+ tButterworth_setF2(ft, f2);
11221134 }
11231135
1136+void 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+
11241144 void tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf)
11251145 {
11261146 tFIR_initToPool(firf, coeffs, numTaps, &leaf->mempool);
@@ -1173,7 +1193,7 @@ void tMedianFilter_initToPool (tMedianFilter* const mf, int size, tMempoo · 46 unmodified lines
11731193 _tMempool* m = *mp;
11741194 _tMedianFilter* f = *mf = (_tMedianFilter*) mpool_alloc(sizeof(_tMedianFilter), m);
11751195 f->mempool = m;
1176−
1196+
11771197 f->size = size;
11781198 f->middlePosition = size / 2;
11791199 f->last = size - 1;
@@ -1185,12 +1205,12 @@ void tMedianFilter_initToPool (tMedianFilter* const mf, int size, tMempoo · 5 unmodified lines
11851205 f->val[i] = 0.0f;
11861206 f->age[i] = i;
11871207 }
1188−
1208+
11891209 }
11901210 void tMedianFilter_free (tMedianFilter* const mf)
11911211 {
11921212 _tMedianFilter* f = *mf;
1193−
1213+
11941214 mpool_free((char*)f->val, f->mempool);
11951215 mpool_free((char*)f->age, f->mempool);
11961216 mpool_free((char*)f, f->mempool);
@@ -1199,7 +1219,7 @@ void tMedianFilter_free (tMedianFilter* const mf) · 2 unmodified lines
11991219 float tMedianFilter_tick (tMedianFilter* const mf, float input)
12001220 {
12011221 _tMedianFilter* f = *mf;
1202−
1222+
12031223 for(int i=0; i<f->size; i++) {
12041224 int thisAge = f->age[i];
12051225 if(thisAge == f->last) {
@@ -1210,7 +1230,7 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 4 unmodified lines
12101230 f->age[i] = thisAge;
12111231 }
12121232 }
1213−
1233+
12141234 while( f->pos!=0 ) {
12151235 float test = f->val[f->pos-1];
12161236 if(input < test) {
@@ -1219,7 +1239,7 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 2 unmodified lines
12191239 f->pos -= 1;
12201240 } else {break;}
12211241 }
1222−
1242+
12231243 while(f->pos != f->last) {
12241244 float test = f->val[f->pos+1];
12251245 if( input > test) {
@@ -1228,10 +1248,10 @@ float tMedianFilter_tick (tMedianFilter* const mf, float input) · 2 unmodified lines
12281248 f->pos += 1;
12291249 } else {break;}
12301250 }
1231−
1251+
12321252 f->val[f->pos] = input;
12331253 f->age[f->pos] = 0;
1234−
1254+
12351255 return f->val[f->middlePosition];
12361256 }
12371257
@@ -1250,16 +1270,17 @@ void tVZFilter_initToPool (tVZFilter* const vf, VZFilterType type, float · 12 unmodified lines
12501270
12511271 LEAF* leaf = f->mempool->leaf;
12521272
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);
12541276 f->type = type;
12551277 f->G = ONE_OVER_SQRT2;
1256− f->invG = 1.0f/ONE_OVER_SQRT2;
1278+ f->invG = 1.0f/ONE_OVER_SQRT2;
12571279 f->B = bandWidth;
12581280 f->m = 0.0f;
12591281 f->s1 = 0.0f;
12601282 f->s2 = 0.0f;
1261− f->sr = leaf->sampleRate;
1262− f->inv_sr = leaf->invSampleRate;
1283+
12631284 tVZFilter_calcCoeffs(vf);
12641285 }
12651286
@@ -1269,194 +1290,179 @@ void tVZFilter_free (tVZFilter* const vf) · 3 unmodified lines
12691290 mpool_free((char*)f, f->mempool);
12701291 }
12711292
1272−void 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−
12791293 float tVZFilter_tick (tVZFilter* const vf, float in)
12801294 {
12811295 _tVZFilter* f = *vf;
1282−
1296+
12831297 float yL, yB, yH;
1284−
1298+
12851299 // compute highpass output via Eq. 5.1:
12861300 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1287−
1301+
12881302 // compute bandpass output by applying 1st integrator to highpass output:
12891303 yB = tanhf(f->g*yH) + f->s1;
12901304 f->s1 = f->g*yH + yB; // state update in 1st integrator
1291−
1305+
12921306 // compute lowpass output by applying 2nd integrator to bandpass output:
12931307 yL = tanhf(f->g*yB) + f->s2;
12941308 f->s2 = f->g*yB + yL; // state update in 2nd integrator
1295−
1309+
12961310 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
12971311 //
12981312 //seems like that might look like this:
12991313 // y = tanh(g*x) + s; // output computation
13001314 // s = g*x + y; // state update
1301−
1315+
13021316 //instead of this:
13031317 // y = g*x + s; // output computation
13041318 // s = g*x + y; // state update
1305−
1319+
13061320 return f->cL*yL + f->cB*yB + f->cH*yH;
1307−
13081321 }
13091322
13101323 float tVZFilter_tickEfficient (tVZFilter* const vf, float in)
13111324 {
13121325 _tVZFilter* f = *vf;
1313−
1326+
13141327 float yL, yB, yH;
1315−
1328+
13161329 // compute highpass output via Eq. 5.1:
13171330 yH = (in - f->R2*f->s1 - f->g*f->s1 - f->s2) * f->h;
1318−
1331+
13191332 // compute bandpass output by applying 1st integrator to highpass output:
13201333 yB = (f->g*yH) + f->s1;
13211334 f->s1 = f->g*yH + yB; // state update in 1st integrator
1322−
1335+
13231336 // compute lowpass output by applying 2nd integrator to bandpass output:
13241337 yL = (f->g*yB) + f->s2;
13251338 f->s2 = f->g*yB + yL; // state update in 2nd integrator
1326−
1339+
13271340 //according to the Vadim paper, we could add saturation to this model by adding a tanh in the integration stage.
13281341 //
13291342 //seems like that might look like this:
13301343 // y = tanh(g*x) + s; // output computation
13311344 // s = g*x + y; // state update
1332−
1345+
13331346 //instead of this:
13341347 // y = g*x + s; // output computation
13351348 // s = g*x + y; // state update
1336−
1349+
13371350 return f->cL*yL + f->cB*yB + f->cH*yH;
1338−
13391351 }
13401352
1341−
13421353 void tVZFilter_calcCoeffs (tVZFilter* const vf)
13431354 {
1344−
13451355 _tVZFilter* f = *vf;
1346− f->g = tanf(PI * f->fc * f->inv_sr); // embedded integrator gain (Fig 3.11)
1347−
1348− switch( f->type )
1349− {
1350− case Bypass:
1356+ f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
1357+
1358+ switch( f->type )
1359+ {
1360+ case Bypass:
13511361 {
1352− f->R2 = f->invG; // can we use an arbitrary value here, for example R2 = 1?
1353− f->cL = 1.0f;
1354− f->cB = f->R2;
1355− f->cH = 1.0f;
1362+ f->R2 = f->invG; // can we use an arbitrary value here, for example R2 = 1?
1363+ f->cL = 1.0f;
1364+ f->cB = f->R2;
1365+ f->cH = 1.0f;
13561366 }
1357− break;
1358− case Lowpass:
1367+ break;
1368+ case Lowpass:
13591369 {
13601370 f->R2 = f->invG;
13611371 f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;
13621372 }
1363− break;
1364− case Highpass:
1373+ break;
1374+ case Highpass:
13651375 {
13661376 f->R2 = f->invG;
13671377 f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;
13681378 }
1369− break;
1370− case BandpassSkirt:
1379+ break;
1380+ case BandpassSkirt:
13711381 {
13721382 f->R2 = f->invG;
13731383 f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;
13741384 }
1375− break;
1376− case BandpassPeak:
1385+ break;
1386+ case BandpassPeak:
13771387 {
13781388 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
13791389 f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;
13801390 }
1381− break;
1382− case BandReject:
1391+ break;
1392+ case BandReject:
13831393 {
13841394 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
13851395 f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;
13861396 }
1387− break;
1388− case Bell:
1397+ break;
1398+ case Bell:
13891399 {
13901400 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)
13921402 float r = f->g/wl;
13931403 r *= r; // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the
1394− // warped upper bandedge, wc the center
1404+ // warped upper bandedge, wc the center
13951405 f->R2 = 2.0f*sqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));
13961406 f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;
13971407 }
1398− break;
1399− case Lowshelf:
1408+ break;
1409+ case Lowshelf:
14001410 {
14011411 float A = sqrtf(f->G);
1402− f->g /= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1403− 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;
1412+ f->g /= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1413+ f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f);
1414+ f->cL = f->G; f->cB = f->R2*A; f->cH = 1.0f;
14051415 }
1406− break;
1407− case Highshelf:
1416+ break;
1417+ case Highshelf:
14081418 {
1409− float A = sqrtf(f->G);
1410− f->g *= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1411− 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;
1419+ float A = sqrtf(f->G);
1420+ f->g *= sqrtf(A); // scale SVF-cutoff frequency for shelvers
1421+ f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f);
1422+ f->cL = 1.0f; f->cB = f->R2*A; f->cH = f->G;
14131423 }
1414− break;
1415− case Allpass:
1424+ break;
1425+ case Allpass:
14161426 {
14171427 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
14181428 f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;
14191429 }
1420− break;
1421−
1422− // experimental - maybe we must find better curves for cL, cB, cH:
1423− case Morph:
1430+ break;
1431+
1432+ // experimental - maybe we must find better curves for cL, cB, cH:
1433+ case Morph:
14241434 {
14251435 f->R2 = f->invG;
1426− float x = 2.0f*f->m-1.0f;
1427−
1428− f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
1429− f->cH = minimum( x, 0.0f); /*cH *= cH;*/
1430− f->cB = 1.0f-x*x;
1431−
1436+ float x = 2.0f*f->m-1.0f;
1437+
1438+ f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
1439+ f->cH = minimum( x, 0.0f); /*cH *= cH;*/
1440+ f->cB = 1.0f-x*x;
1441+
14321442 // bottom line: we need to test different versions for how they feel when tweaking the
14331443 // morph parameter
1434−
1435− // 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):
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));
1438− f->cL *= s; f->cB *= s; f->cH *= s;
1444+
1445+ // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
1446+ // the magnitude response value at the cutoff frequency and scale back by the gain):
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));
1448+ f->cL *= s; f->cB *= s; f->cH *= s;
14391449 }
1440− break;
1441−
1442− }
1443−
1444− f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
1450+ break;
1451+
1452+ }
1453+
1454+ f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
14451455 }
14461456
14471457 void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const vf)
14481458 {
1449−
14501459 _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)
14521461 f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
14531462 f->cB = f->R2;
14541463 f->h = 1.0f / (1.0f + f->R2*f->g + f->g*f->g); // factor for feedback precomputation
14551464 }
14561465
1457−
1458−
1459−
14601466 void tVZFilter_setBandwidth (tVZFilter* const vf, float B)
14611467 {
14621468 _tVZFilter* f = *vf;
@@ -1466,33 +1472,28 @@ void tVZFilter_setBandwidth (tVZFilter* const vf, float B) · 3 unmodified lines
14661472 void tVZFilter_setFreq (tVZFilter* const vf, float freq)
14671473 {
14681474 _tVZFilter* f = *vf;
1469− LEAF* leaf = f->mempool->leaf;
14701475
1471− f->fc = LEAF_clip(0.0f, freq, 0.5f * leaf->sampleRate);
1476+ f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
14721477 tVZFilter_calcCoeffs(vf);
14731478 }
14741479 void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw)
14751480 {
14761481 _tVZFilter* f = *vf;
1477− LEAF* leaf = f->mempool->leaf;
14781482
14791483 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);
14811485 tVZFilter_calcCoeffs(vf);
14821486 }
14831487
14841488 void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw)
14851489 {
14861490 _tVZFilter* f = *vf;
1487− LEAF* leaf = f->mempool->leaf;
1488−
1491+
14891492 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);
14911494 tVZFilter_calcCoeffsEfficientBP(vf);
14921495 }
14931496
1494−
1495−
14961497 void tVZFilter_setGain (tVZFilter* const vf, float gain)
14971498 {
14981499 _tVZFilter* f = *vf;
@@ -1501,8 +1502,6 @@ void tVZFilter_setGain (tVZFilter* const vf, float gain) · 2 unmodified lines
15011502 tVZFilter_calcCoeffs(vf);
15021503 }
15031504
1504−
1505−
15061505 void tVZFilter_setMorph (tVZFilter* const vf, float morph)
15071506 {
15081507 _tVZFilter* f = *vf;
@@ -1520,25 +1519,32 @@ void tVZFilter_setType (tVZFilter* const vf, VZFilterType type) · 11 unmodified lines
15201519 float tVZFilter_BandwidthToR(tVZFilter* const vf, float B)
15211520 {
15221521 _tVZFilter* f = *vf;
1523− 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)
1525− float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1526− // unwarped: r = pow(2, -B/2) -> approximation for low
1527− // center-frequencies
1528− return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1522+ float fl = f->fc*powf(2.0f, -B*0.5f); // lower bandedge frequency (in Hz)
1523+ float gl = tanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
1524+ float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1525+ // unwarped: r = pow(2, -B/2) -> approximation for low
1526+ // center-frequencies
1527+ return sqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
15291528 }
15301529
15311530 float tVZFilter_BandwidthToREfficientBP(tVZFilter* const vf, float B)
15321531 {
15331532 _tVZFilter* f = *vf;
1534− 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)
1536− float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1537− // unwarped: r = pow(2, -B/2) -> approximation for low
1538− // center-frequencies
1539− return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
1533+ float fl = f->fc*fastPowf(2.0f, -B * 0.5f); // lower bandedge frequency (in Hz)
1534+ float gl = fastertanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
1535+ float r = gl/f->g; // ratio between warped lower bandedge- and center-frequencies
1536+ // unwarped: r = pow(2, -B/2) -> approximation for low
1537+ // center-frequencies
1538+ return fastsqrtf((1.0f-r*r)*(1.0f-r*r)/(4.0f*r*r));
15401539 }
15411540
1541+void 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+}
15421548
15431549
15441550
@@ -1549,26 +1555,28 @@ void tDiodeFilter_init (tDiodeFilter* const vf, float cutoff, float · 4 unmodified lines
15491555
15501556 void tDiodeFilter_initToPool (tDiodeFilter* const vf, float cutoff, float resonance, tMempool* const mp)
15511557 {
1552− _tMempool* m = *mp;
1553− _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
1554− f->mempool = m;
1558+ _tMempool* m = *mp;
1559+ _tDiodeFilter* f = *vf = (_tDiodeFilter*) mpool_alloc(sizeof(_tDiodeFilter), m);
1560+ f->mempool = m;
15551561
15561562 LEAF* leaf = f->mempool->leaf;
15571563
1558− // initialization (the resonance factor is between 0 and 8 according to the article)
1559− f->f = (float)tan((double)(PI * cutoff/leaf->sampleRate));
1560− f->r = (7.f * resonance + 0.5f);
1561− f->Vt = 0.5f;
1562− f->n = 1.836f;
1563− f->zi = 0.0f; //previous input value
1564− f->gamma = f->Vt*f->n;
1565− f->s0 = 0.01f;
1566− f->s1 = 0.02f;
1567− f->s2 = 0.03f;
1568− f->s3 = 0.04f;
1569− f->g0inv = 1.f/(2.f*f->Vt);
1570− f->g1inv = 1.f/(2.f*f->gamma);
1571− f->g2inv = 1.f/(6.f*f->gamma);
1564+ f->invSampleRate = leaf->invSampleRate;
1565+ f->cutoff = cutoff;
1566+ // initialization (the resonance factor is between 0 and 8 according to the article)
1567+ f->f = (float)tan((double)(PI * cutoff * f->invSampleRate));
1568+ f->r = (7.f * resonance + 0.5f);
1569+ f->Vt = 0.5f;
1570+ f->n = 1.836f;
1571+ f->zi = 0.0f; //previous input value
1572+ f->gamma = f->Vt*f->n;
1573+ f->s0 = 0.01f;
1574+ f->s1 = 0.02f;
1575+ f->s2 = 0.03f;
1576+ f->s3 = 0.04f;
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);
15721580 }
15731581
15741582 void tDiodeFilter_free (tDiodeFilter* const vf)
@@ -1583,11 +1591,11 @@ float tanhXdX(float x) · 8 unmodified lines
15831591 // IIRC I got this as Pade-approx for tanh(sqrt(x))/sqrt(x)
15841592 float testVal = ((15.0f*a + 420.0f)*a + 945.0f);
15851593 float output = 1.0f;
1586−
1594+
15871595 if (testVal!= 0.0f)
15881596 {
1589− output = testVal;
1590−
1597+ output = testVal;
1598+
15911599 }
15921600 return ((a + 105.0f)*a + 945.0f) / output;
15931601 }
@@ -1595,31 +1603,29 @@ float tanhXdX(float x) · 1 unmodified line
15951603 float tDiodeFilter_tick (tDiodeFilter* const vf, float in)
15961604 {
15971605 _tDiodeFilter* f = *vf;
1598−
1606+
15991607 int errorCheck = 0;
16001608 // the input x[n+1] is given by 'in', and x[n] by zi
16011609 // input with half delay
16021610 float ih = 0.5f * (in + f->zi);
1603−
1611+
16041612 // evaluate the non-linear factors
16051613 float t0 = f->f*tanhXdX((ih - f->r * f->s3)*f->g0inv)*f->g0inv;
16061614 float t1 = f->f*tanhXdX((f->s1-f->s0)*f->g1inv)*f->g1inv;
16071615 float t2 = f->f*tanhXdX((f->s2-f->s1)*f->g1inv)*f->g1inv;
16081616 float t3 = f->f*tanhXdX((f->s3-f->s2)*f->g1inv)*f->g1inv;
16091617 float t4 = f->f*tanhXdX((f->s3)*f->g2inv)*f->g2inv;
1610−
1611−
1612−
1618+
16131619 // This formula gives the result for y3 thanks to MATLAB
16141620 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);
16151621 if (isnan(y3))
16161622 {
1617− errorCheck = 1;
1623+ errorCheck = 1;
16181624 }
16191625 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;
16201626 if (isnan(tempy3denom))
16211627 {
1622− errorCheck = 2;
1628+ errorCheck = 2;
16231629 }
16241630 if (tempy3denom == 0.0f)
16251631 {
@@ -1628,7 +1634,7 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 2 unmodified lines
16281634 y3 = y3 / tempy3denom;
16291635 if (isnan(y3))
16301636 {
1631− errorCheck = 3;
1637+ errorCheck = 3;
16321638 }
16331639 if (t1 == 0.0f)
16341640 {
@@ -1647,42 +1653,45 @@ float tDiodeFilter_tick (tDiodeFilter* const vf, float in) · 12 unmodified lines
16471653 float y1 = (f->s2 - (1+t3+t2)*y2 + t3*y3) / (-t2);
16481654 float y0 = (f->s1 - (1+t2+t1)*y1 + t2*y2) / (-t1);
16491655 float xx = (in - f->r*y3);
1650−
1656+
16511657 // update state
16521658 f->s0 += 2.0f * (t0*xx + t1*(y1-y0));
16531659 if (isnan(f->s0))
16541660 {
1655− errorCheck = 4;
1661+ errorCheck = 4;
16561662 }
1657−
1663+
16581664 if (isinf(f->s0))
16591665 {
1660− errorCheck = 5;
1666+ errorCheck = 5;
16611667 }
16621668 f->s1 += 2.0f * (t2*(y2-y1) - t1*(y1-y0));
16631669 f->s2 += 2.0f * (t3*(y3-y2) - t2*(y2-y1));
16641670 f->s3 += 2.0f * (-t4*(y3) - t3*(y3-y2));
1665−
1671+
16661672 f->zi = in;
16671673 return y3*f->r;
1668−
16691674 }
16701675
1671−
1672−
16731676 void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff)
16741677 {
1675− _tDiodeFilter* f = *vf;
1676− LEAF* leaf = f->mempool->leaf;
1678+ _tDiodeFilter* f = *vf;
16771679
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);
16791682 }
16801683
1681−
16821684 void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance)
16831685 {
1684− _tDiodeFilter* f = *vf;
1685− f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
1686+ _tDiodeFilter* f = *vf;
1687+ f->r = LEAF_clip(0.5, (7.f * resonance + 0.5f), 8.0f);
1688+}
16861689
1690+void 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);
16871696 }
16881697
leaf/Src/leaf-instruments.c+47−0
@@ -141,6 +141,17 @@ void t808Cowbell_setStick(t808Cowbell* const cowbellInst, int useStick) · 140 unmodified lines
141141 cowbell->useStick = useStick;
142142 }
143143
144+void 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+
144155 // ----------------- HIHAT ----------------------------//
145156
146157 void t808Hihat_init(t808Hihat* const hihatInst, LEAF* const leaf)
@@ -309,6 +320,22 @@ void t808Hihat_setOscFreq(t808Hihat* const hihatInst, float freq) · 162 unmodified lines
309320 hihat->freq = freq;
310321 }
311322
323+void 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+
312339 // ----------------- SNARE ----------------------------//
313340
314341 void t808Snare_init (t808Snare* const snareInst, LEAF* const leaf)
@@ -456,6 +483,18 @@ float t808Snare_tick(t808Snare* const snareInst) · 141 unmodified lines
456483 return sample;
457484 }
458485
486+void 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+
459498 // ----------------- KICK ----------------------------//
460499
461500 void t808Kick_init (t808Kick* const kickInst, LEAF* const leaf)
@@ -540,4 +579,12 @@ void t808Kick_setToneNoiseMix (t808Kick* const kickInst, float tone · 78 unmodified lines
540579 void t808Kick_setNoiseFilterFreq (t808Kick* const kickInst, float noiseFilterFreq);
541580 void t808Kick_setNoiseFilterQ (t808Kick* const kickInst, float noiseFilterQ);
542581
582+void 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+
543590
leaf/Src/leaf-midi.c+9−1
@@ -605,7 +605,15 @@ int tPoly_isOn(tPoly* const polyh, uint8_t voice) · 604 unmodified lines
605605 return (poly->voices[voice][0] > 0) ? 1 : 0;
606606 }
607607
608−
608+void 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+}
609617
610618
611619 //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
2828 _tMempool* m = *mp;
2929 _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m);
3030 c->mempool = m;
31+ LEAF* leaf = c->mempool->leaf;
3132
3233 c->inc = 0.0f;
3334 c->phase = 0.0f;
35+ c->invSampleRate = leaf->invSampleRate;
3436 }
3537
3638 void tCycle_free (tCycle* const cy)
@@ -43,13 +45,12 @@ void tCycle_free (tCycle* const cy) · 6 unmodified lines
4345 void tCycle_setFreq(tCycle* const cy, float freq)
4446 {
4547 _tCycle* c = *cy;
46− LEAF* leaf = c->mempool->leaf;
4748
4849 if (!isfinite(freq)) return;
4950
5051 c->freq = freq;
5152
52− c->inc = freq * leaf->invSampleRate;
53+ c->inc = freq * c->invSampleRate;
5354 c->inc -= (int)c->inc;
5455 }
5556
@@ -80,13 +81,12 @@ float tCycle_tick(tCycle* const cy) · 24 unmodified lines
8081 return (samp0 + (samp1 - samp0) * frac);
8182 }
8283
83−void tCycleSampleRateChanged (tCycle* const cy)
84+void tCycle_setSampleRate (tCycle* const cy, float sr)
8485 {
8586 _tCycle* c = *cy;
86− LEAF* leaf = c->mempool->leaf;
8787
88− c->inc = c->freq * leaf->invSampleRate;
89− c->inc -= (int)c->inc;
88+ c->invSampleRate = 1.0f/sr;
89+ tCycle_setFreq(cy, c->freq);
9090 }
9191 #endif // LEAF_INCLUDE_SINE_TABLE
9292
@@ -103,9 +103,11 @@ void tTriangle_initToPool (tTriangle* const cy, tMempool* const mp) · 10 unmodified lines
103103 _tMempool* m = *mp;
104104 _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m);
105105 c->mempool = m;
106+ LEAF* leaf = c->mempool->leaf;
106107
107108 c->inc = 0.0f;
108109 c->phase = 0.0f;
110+ c->invSampleRate = leaf->invSampleRate;
109111 tTriangle_setFreq(cy, 220);
110112 }
111113
@@ -119,15 +121,14 @@ void tTriangle_free (tTriangle* const cy) · 7 unmodified lines
119121 void tTriangle_setFreq(tTriangle* const cy, float freq)
120122 {
121123 _tTriangle* c = *cy;
122− LEAF* leaf = c->mempool->leaf;
123124
124− c->freq = freq;
125+ c->freq = freq;
125126
126− c->inc = c->freq * leaf->invSampleRate;
127+ c->inc = c->freq * c->invSampleRate;
127128 c->inc -= (int)c->inc;
128129
129130 // 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));
131132
132133 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
133134 if (c->w < 0.0f) c->w = 0.0f;
@@ -173,13 +174,12 @@ float tTriangle_tick(tTriangle* const cy) · 39 unmodified lines
173174 return oct0 + (oct1 - oct0) * c->w;
174175 }
175176
176−void tTriangleSampleRateChanged (tTriangle* const cy)
177+void tTriangle_setSampleRate (tTriangle* const cy, float sr)
177178 {
178179 _tTriangle* c = *cy;
179− LEAF* leaf = c->mempool->leaf;
180180
181− c->inc = c->freq * leaf->invSampleRate;
182− c->inc -= (int)c->inc;
181+ c->invSampleRate = 1.0f/sr;
182+ tTriangle_setFreq(cy, c->freq);
183183 }
184184 #endif // LEAF_INCLUDE_TRIANGLE_TABLE
185185
@@ -196,9 +196,11 @@ void tSquare_initToPool (tSquare* const cy, tMempool* const mp) · 10 unmodified lines
196196 _tMempool* m = *mp;
197197 _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m);
198198 c->mempool = m;
199+ LEAF* leaf = c->mempool->leaf;
199200
200201 c->inc = 0.0f;
201202 c->phase = 0.0f;
203+ c->invSampleRate = leaf->invSampleRate;
202204 tSquare_setFreq(cy, 220);
203205 }
204206
@@ -212,15 +214,14 @@ void tSquare_free (tSquare* const cy) · 7 unmodified lines
212214 void tSquare_setFreq(tSquare* const cy, float freq)
213215 {
214216 _tSquare* c = *cy;
215− LEAF* leaf = c->mempool->leaf;
216217
217218 c->freq = freq;
218219
219− c->inc = c->freq * leaf->invSampleRate;
220+ c->inc = c->freq * c->invSampleRate;
220221 c->inc -= (int)c->inc;
221222
222223 // 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));
224225
225226 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
226227 if (c->w < 0.0f) c->w = 0.0f;
@@ -265,13 +266,12 @@ float tSquare_tick(tSquare* const cy) · 38 unmodified lines
265266 return oct0 + (oct1 - oct0) * c->w;
266267 }
267268
268−void tSquareSampleRateChanged (tSquare* const cy)
269+void tSquare_setSampleRate (tSquare* const cy, float sr)
269270 {
270271 _tSquare* c = *cy;
271− LEAF* leaf = c->mempool->leaf;
272272
273− c->inc = c->freq * leaf->invSampleRate;
274− c->inc -= (int)c->inc;
273+ c->invSampleRate = 1.0f/sr;
274+ tSquare_setFreq(cy, c->freq);
275275 }
276276 #endif // LEAF_INCLUDE_SQUARE_TABLE
277277
@@ -288,9 +288,11 @@ void tSawtooth_initToPool (tSawtooth* const cy, tMempool* const mp) · 10 unmodified lines
288288 _tMempool* m = *mp;
289289 _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m);
290290 c->mempool = m;
291+ LEAF* leaf = c->mempool->leaf;
291292
292293 c->inc = 0.0f;
293294 c->phase = 0.0f;
295+ c->invSampleRate = leaf->invSampleRate;
294296 tSawtooth_setFreq(cy, 220);
295297 }
296298
@@ -304,15 +306,14 @@ void tSawtooth_free (tSawtooth* const cy) · 7 unmodified lines
304306 void tSawtooth_setFreq(tSawtooth* const cy, float freq)
305307 {
306308 _tSawtooth* c = *cy;
307− LEAF* leaf = c->mempool->leaf;
308309
309310 c->freq = freq;
310311
311− c->inc = c->freq * leaf->invSampleRate;
312+ c->inc = c->freq * c->invSampleRate;
312313 c->inc -= (int)c->inc;
313314
314315 // 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));
316317
317318 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
318319 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
357358 return oct0 + (oct1 - oct0) * c->w;
358359 }
359360
360−void tSawtoothSampleRateChanged (tSawtooth* const cy)
361+void tSawtooth_setSampleRate (tSawtooth* const cy, float sr)
361362 {
362363 _tSawtooth* c = *cy;
363− LEAF* leaf = c->mempool->leaf;
364364
365− c->inc = c->freq * leaf->invSampleRate;
366− c->inc -= (int)c->inc;
365+ c->invSampleRate = 1.0f/sr;
366+ tSawtooth_setFreq(cy, c->freq);
367367 }
368368 #endif // LEAF_INCLUDE_SAWTOOTH_TABLE
369369
@@ -380,7 +380,9 @@ void tPBTriangle_initToPool (tPBTriangle* const osc, tMempool* const mp) · 10 unmodified lines
380380 _tMempool* m = *mp;
381381 _tPBTriangle* c = *osc = (_tPBTriangle*) mpool_alloc(sizeof(_tPBTriangle), m);
382382 c->mempool = m;
383+ LEAF* leaf = c->mempool->leaf;
383384
385+ c->invSampleRate = leaf->invSampleRate;
384386 c->inc = 0.0f;
385387 c->phase = 0.0f;
386388 c->skew = 0.5f;
@@ -428,10 +430,9 @@ float tPBTriangle_tick (tPBTriangle* const osc) · 41 unmodified lines
428430 void tPBTriangle_setFreq (tPBTriangle* const osc, float freq)
429431 {
430432 _tPBTriangle* c = *osc;
431− LEAF* leaf = c->mempool->leaf;
432433
433434 c->freq = freq;
434− c->inc = freq * leaf->invSampleRate;
435+ c->inc = freq * c->invSampleRate;
435436 }
436437
437438 void tPBTriangle_setSkew (tPBTriangle* const osc, float skew)
@@ -440,6 +441,14 @@ void tPBTriangle_setSkew (tPBTriangle* const osc, float skew) · 2 unmodified lines
440441 c->skew = (skew + 1.0f) * 0.5f;
441442 }
442443
444+void 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+
443452
444453 //==============================================================================
445454
@@ -454,7 +463,9 @@ void tPBPulse_initToPool (tPBPulse* const osc, tMempool* const mp) · 8 unmodified lines
454463 _tMempool* m = *mp;
455464 _tPBPulse* c = *osc = (_tPBPulse*) mpool_alloc(sizeof(_tPBPulse), m);
456465 c->mempool = m;
466+ LEAF* leaf = c->mempool->leaf;
457467
468+ c->invSampleRate = leaf->invSampleRate;
458469 c->inc = 0.0f;
459470 c->phase = 0.0f;
460471 c->width = 0.5f;
@@ -487,10 +498,9 @@ float tPBPulse_tick (tPBPulse* const osc) · 26 unmodified lines
487498 void tPBPulse_setFreq (tPBPulse* const osc, float freq)
488499 {
489500 _tPBPulse* c = *osc;
490− LEAF* leaf = c->mempool->leaf;
491501
492502 c->freq = freq;
493− c->inc = freq * leaf->invSampleRate;
503+ c->inc = freq * c->invSampleRate;
494504 }
495505
496506 void tPBPulse_setWidth (tPBPulse* const osc, float width)
@@ -499,6 +509,13 @@ void tPBPulse_setWidth (tPBPulse* const osc, float width) · 2 unmodified lines
499509 c->width = width;
500510 }
501511
512+void 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+}
502519
503520 //==============================================================================
504521
@@ -513,9 +530,11 @@ void tPBSaw_initToPool (tPBSaw* const osc, tMempool* const mp) · 8 unmodified lines
513530 _tMempool* m = *mp;
514531 _tPBSaw* c = *osc = (_tPBSaw*) mpool_alloc(sizeof(_tPBSaw), m);
515532 c->mempool = m;
533+ LEAF* leaf = c->mempool->leaf;
516534
517535 c->inc = 0.0f;
518536 c->phase = 0.0f;
537+ c->invSampleRate = leaf->invSampleRate;
519538 }
520539
521540 void tPBSaw_free (tPBSaw* const osc)
@@ -542,22 +561,21 @@ float tPBSaw_tick (tPBSaw* const osc) · 20 unmodified lines
542561 void tPBSaw_setFreq (tPBSaw* const osc, float freq)
543562 {
544563 _tPBSaw* c = *osc;
545− LEAF* leaf = c->mempool->leaf;
546564
547565 c->freq = freq;
566+ c->inc = freq * c->invSampleRate;
567+}
568+
569+void tPBSaw_setSampleRate (tPBSaw* const osc, float sr)
570+{
571+ _tPBSaw* c = *osc;
548572
549− c->inc = freq * leaf->invSampleRate;
573+ c->invSampleRate = 1.0f/sr;
574+ tPBSaw_setFreq(osc, c->freq);
550575 }
551576
552577 //========================================================================
553578 /* Phasor */
554−void tPhasorSampleRateChanged (tPhasor* const ph)
555−{
556− _tPhasor* p = *ph;
557− LEAF* leaf = p->mempool->leaf;
558−
559− p->inc = p->freq * leaf->invSampleRate;
560−};
561579
562580 void tPhasor_init(tPhasor* const ph, LEAF* const leaf)
563581 {
@@ -569,10 +587,12 @@ void tPhasor_initToPool (tPhasor* const ph, tMempool* const mp) · 5 unmodified lines
569587 _tMempool* m = *mp;
570588 _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m);
571589 p->mempool = m;
590+ LEAF* leaf = p->mempool->leaf;
572591
573592 p->phase = 0.0f;
574593 p->inc = 0.0f;
575594 p->phaseDidReset = 0;
595+ p->invSampleRate = leaf->invSampleRate;
576596 }
577597
578598 void tPhasor_free (tPhasor* const ph)
@@ -585,11 +605,10 @@ void tPhasor_free (tPhasor* const ph) · 6 unmodified lines
585605 void tPhasor_setFreq(tPhasor* const ph, float freq)
586606 {
587607 _tPhasor* p = *ph;
588− LEAF* leaf = p->mempool->leaf;
589608
590609 p->freq = freq;
591610
592− p->inc = freq * leaf->invSampleRate;
611+ p->inc = freq * p->invSampleRate;
593612 p->inc -= (int)p->inc;
594613 }
595614
@@ -614,6 +633,15 @@ float tPhasor_tick(tPhasor* const ph) · 18 unmodified lines
614633 return p->phase;
615634 }
616635
636+void 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+//========================================================================
617645 /* Noise */
618646 void tNoise_init(tNoise* const ns, NoiseType type, LEAF* const leaf)
619647 {
@@ -662,11 +690,6 @@ float tNoise_tick(tNoise* const ns) · 42 unmodified lines
662690 //=================================================================================
663691 /* Neuron */
664692
665−void tNeuronSampleRateChanged(tNeuron* nr)
666−{
667−
668−}
669−
670693 void tNeuron_init(tNeuron* const nr, LEAF* const leaf)
671694 {
672695 tNeuron_initToPool(nr, &leaf->mempool);
@@ -677,7 +700,7 @@ void tNeuron_initToPool (tNeuron* const nr, tMempool* const mp) · 4 unmodified lines
677700 _tMempool* m = *mp;
678701 _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);
679702 n->mempool = m;
680−
703+
681704 tPoleZero_initToPool(&n->f, mp);
682705
683706 tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -748,7 +771,6 @@ void tNeuron_setV1(tNeuron* const nr, float V1) · 64 unmodified lines
748771 n->V[0] = V1;
749772 }
750773
751−
752774 void tNeuron_setV2(tNeuron* const nr, float V2)
753775 {
754776 _tNeuron* n = *nr;
@@ -881,8 +903,6 @@ void tNeuron_setCurrent (tNeuron* const nr, float current) · 126 unmodified lines
881903 n->current = current;
882904 }
883905
884−
885−
886906 //----------------------------------------------------------------------------------------------------------
887907
888908 void tMBPulse_init(tMBPulse* const osc, LEAF* const leaf)
@@ -895,6 +915,9 @@ void tMBPulse_initToPool(tMBPulse* const osc, tMempool* const pool) · 6 unmodified lines
895915 _tMempool* m = *pool;
896916 _tMBPulse* c = *osc = (_tMBPulse*) mpool_alloc(sizeof(_tMBPulse), m);
897917 c->mempool = m;
918+ LEAF* leaf = c->mempool->leaf;
919+
920+ c->invSampleRate = leaf->invSampleRate;
898921
899922 c->_init = true;
900923 c->amp = 1.0f;
@@ -918,7 +941,6 @@ void tMBPulse_free(tMBPulse* const osc) · 17 unmodified lines
918941 float tMBPulse_tick(tMBPulse* const osc)
919942 {
920943 _tMBPulse* c = *osc;
921− LEAF* leaf = c->mempool->leaf;
922944
923945 int j, k;
924946 float freq, sync;
@@ -937,7 +959,7 @@ float tMBPulse_tick(tMBPulse* const osc) · 12 unmodified lines
937959 if (c->_init) {
938960 p = 0.0f;
939961
940− w = freq * leaf->invSampleRate;
962+ w = freq * c->invSampleRate;
941963 b = 0.5f * (1.0f + c->waveform );
942964
943965 /* for variable-width rectangular wave, we could do DC compensation with:
@@ -955,7 +977,7 @@ float tMBPulse_tick(tMBPulse* const osc) · 11 unmodified lines
955977 // a = 0.2 + 0.8 * vco->_port [FILT];
956978 a = 0.5f; // when a = 1, LPfilter is disabled
957979
958− w = freq * leaf->invSampleRate;
980+ w = freq * c->invSampleRate;
959981 b = 0.5f * (1.0f + c->waveform);
960982
961983 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
11771199 c->softsync = hardOrSoft > 0 ? 1 : 0;
11781200 }
11791201
1202+void tMBPulse_setSampleRate(tMBPulse* const osc, float sr)
1203+{
1204+ _tMBPulse* c = *osc;
1205+ c->invSampleRate = 1.0f/sr;
1206+}
1207+
11801208 //==========================================================================================================
11811209 //==========================================================================================================
11821210
@@ -1190,7 +1218,9 @@ void tMBTriangle_initToPool(tMBTriangle* const osc, tMempool* const pool) · 7 unmodified lines
11901218 _tMempool* m = *pool;
11911219 _tMBTriangle* c = *osc = (_tMBTriangle*) mpool_alloc(sizeof(_tMBTriangle), m);
11921220 c->mempool = m;
1221+ LEAF* leaf = c->mempool->leaf;
11931222
1223+ c->invSampleRate = leaf->invSampleRate;
11941224 c->amp = 1.0f;
11951225 c->freq = 440.f;
11961226 c->lastsyncin = 0.0f;
@@ -1213,7 +1243,6 @@ void tMBTriangle_free(tMBTriangle* const osc) · 16 unmodified lines
12131243 float tMBTriangle_tick(tMBTriangle* const osc)
12141244 {
12151245 _tMBTriangle* c = *osc;
1216− LEAF* leaf = c->mempool->leaf;
12171246
12181247 int j, k, dir;
12191248 float freq, sync;
@@ -1232,7 +1261,7 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 12 unmodified lines
12321261 if (c->_init) {
12331262 // w = (exp2ap (freq[1] + vco->_port[OCTN] + vco->_port[TUNE] + expm[1] * vco->_port[EXPG] + 8.03136)
12341263 // + 1e3 * linm[1] * vco->_port[LING]) / SAMPLERATE;
1235− w = freq * leaf->invSampleRate;
1264+ w = freq * c->invSampleRate;
12361265 b = 0.5f * (1.0f + c->waveform);
12371266 p = 0.5f * b;
12381267 /* 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
12451274 // a = 0.2 + 0.8 * vco->_port [FILT];
12461275 a = 0.5f; // when a = 1, LPfilter is disabled
12471276
1248− w = freq * leaf->invSampleRate;
1277+ w = freq * c->invSampleRate;
12491278 b = 0.5f * (1.0f + c->waveform);
12501279 b1 = 1.0f - b;
12511280
@@ -1472,6 +1501,12 @@ void tMBTriangle_setSyncMode(tMBTriangle* const osc, int hardOrSoft) · 220 unmodified lines
14721501 c->softsync = hardOrSoft > 0 ? 1 : 0;
14731502 }
14741503
1504+void tMBTriangle_setSampleRate(tMBTriangle* const osc, float sr)
1505+{
1506+ _tMBTriangle* c = *osc;
1507+ c->invSampleRate = 1.0f/sr;
1508+}
1509+
14751510 //==========================================================================================================
14761511 //==========================================================================================================
14771512
@@ -1485,7 +1520,9 @@ void tMBSaw_initToPool(tMBSaw* const osc, tMempool* const pool) · 7 unmodified lines
14851520 _tMempool* m = *pool;
14861521 _tMBSaw* c = *osc = (_tMBSaw*) mpool_alloc(sizeof(_tMBSaw), m);
14871522 c->mempool = m;
1523+ LEAF* leaf = c->mempool->leaf;
14881524
1525+ c->invSampleRate = leaf->invSampleRate;
14891526 c->_init = true;
14901527 c->amp = 1.0f;
14911528 c->freq = 440.f;
@@ -1507,7 +1544,6 @@ void tMBSaw_free(tMBSaw* const osc) · 15 unmodified lines
15071544 float tMBSaw_tick(tMBSaw* const osc)
15081545 {
15091546 _tMBSaw* c = *osc;
1510− LEAF* leaf = c->mempool->leaf;
15111547
15121548 int j;
15131549 float freq, sync;
@@ -1523,7 +1559,7 @@ float tMBSaw_tick(tMBSaw* const osc) · 9 unmodified lines
15231559
15241560 if (c->_init) {
15251561 p = 0.5f;
1526− w = freq * leaf->invSampleRate;
1562+ w = freq * c->invSampleRate;
15271563
15281564 /* if we valued alias-free startup over low startup time, we could do:
15291565 * p -= w;
@@ -1534,7 +1570,7 @@ float tMBSaw_tick(tMBSaw* const osc) · 4 unmodified lines
15341570 //a = 0.2 + 0.8 * vco->_port [FILT];
15351571 a = 0.5f; // when a = 1, LPfilter is disabled
15361572
1537− w = freq * leaf->invSampleRate;
1573+ w = freq * c->invSampleRate;
15381574
15391575 if (sync > 0.0f && c->softsync > 0) c->syncdir = -c->syncdir;
15401576 // Should insert minblep for softsync?
@@ -1631,6 +1667,12 @@ void tMBSaw_setSyncMode(tMBSaw* const osc, int hardOrSoft) · 90 unmodified lines
16311667 c->softsync = hardOrSoft > 0 ? 1 : 0;
16321668 }
16331669
1670+void tMBSaw_setSampleRate(tMBSaw* const osc, float sr)
1671+{
1672+ _tMBSaw* c = *osc;
1673+ c->invSampleRate = 1.0f/sr;
1674+}
1675+
16341676
16351677 // WaveTable
16361678 void 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
16431685 _tMempool* m = *mp;
16441686 _tTable* c = *cy = (_tTable*)mpool_alloc(sizeof(_tTable), m);
16451687 c->mempool = m;
1688+ LEAF* leaf = c->mempool->leaf;
16461689
16471690 c->waveTable = waveTable;
16481691 c->size = size;
16491692 c->inc = 0.0f;
16501693 c->phase = 0.0f;
1694+ c->invSampleRate = leaf->invSampleRate;
16511695 }
16521696
16531697 void tTable_free(tTable* const cy)
@@ -1660,12 +1704,11 @@ void tTable_free(tTable* const cy) · 6 unmodified lines
16601704 void tTable_setFreq(tTable* const cy, float freq)
16611705 {
16621706 _tTable* c = *cy;
1663− LEAF* leaf = c->mempool->leaf;
16641707
16651708 if (!isfinite(freq)) return;
16661709
16671710 c->freq = freq;
1668− c->inc = freq * leaf->invSampleRate;
1711+ c->inc = freq * c->invSampleRate;
16691712 c->inc -= (int)c->inc;
16701713 }
16711714
@@ -1695,13 +1738,11 @@ float tTable_tick(tTable* const cy) · 23 unmodified lines
16951738 return (samp0 + (samp1 - samp0) * fracPart);
16961739 }
16971740
1698−void tTableSampleRateChanged(tTable* const cy)
1741+void tTable_setSampleRate(tTable* const cy, float sr)
16991742 {
17001743 _tTable* c = *cy;
1701− LEAF* leaf = c->mempool->leaf;
1702−
1703− c->inc = c->freq * leaf->invSampleRate;
1704− c->inc -= (int)c->inc;
1744+ c->invSampleRate = 1.0f/sr;
1745+ tTable_setFreq(cy, c->freq);
17051746 }
17061747
17071748 void 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
17141755 _tMempool* m = *mp;
17151756 _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);
17161757 c->mempool = m;
1758+ LEAF* leaf = c->mempool->leaf;
1759+
1760+ c->sampleRate = leaf->sampleRate;
1761+
1762+ c->maxFreq = maxFreq;
17171763
17181764 // Determine base frequency
1719− c->baseFreq = m->leaf->sampleRate / (float) size;
1765+ c->baseFreq = c->sampleRate / (float) size;
17201766 c->invBaseFreq = 1.0f / c->baseFreq;
17211767
17221768 // Determine how many tables we need
17231769 // Assume we need at least 2, the fundamental + one to account for setting extra anti aliasing
17241770 c->numTables = 2;
17251771 float f = c->baseFreq;
1726− while (f < maxFreq)
1772+ while (f < c->maxFreq)
17271773 {
17281774 c->numTables++;
17291775 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
17321778 c->size = size;
17331779
17341780 // Allocate memory for the tables
1735− c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, m);
1736− for (int t = 0; t < c->numTables; ++t)
1781+ c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
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)
17371785 {
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);
17391787 }
17401788
17411789 // Copy table
17421790 for (int i = 0; i < c->size; ++i)
17431791 {
1744− c->tables[0][i] = table[i];
1792+ c->baseTable[i] = table[i];
17451793 }
17461794
17471795 // Make bandlimited copies
1748− f = m->leaf->sampleRate * 0.25; //start at half nyquist
1796+ f = c->sampleRate * 0.25; //start at half nyquist
17491797 // Not worth going over order 8 I think, and even 8 is only marginally better than 4.
17501798 tButterworth_initToPool(&c->bl, 8, -1.0f, f, mp);
17511799 for (int t = 1; t < c->numTables; ++t)
@@ -1778,6 +1826,64 @@ void tWaveTable_free(tWaveTable* const cy) · 26 unmodified lines
17781826 mpool_free((char*)c, c->mempool);
17791827 }
17801828
1829+void 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+
17811887 //=======================================================================================
17821888 //=======================================================================================
17831889
@@ -1791,6 +1897,7 @@ void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* · 7 unmodified lines
17911897 _tMempool* m = *mp;
17921898 _tWaveOsc* c = *cy = (_tWaveOsc*) mpool_alloc(sizeof(_tWaveOsc), m);
17931899 c->mempool = m;
1900+ LEAF* leaf = c->mempool->leaf;
17941901
17951902 c->table = *table;
17961903
@@ -1799,6 +1906,8 @@ void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* · 2 unmodified lines
17991906 c->phaseOffset = 0.0f;
18001907 c->aa = 0.5f;
18011908
1909+ c->invSampleRate = leaf->invSampleRate;
1910+
18021911 tWaveOsc_setFreq(cy, 220);
18031912 }
18041913
@@ -1851,11 +1960,9 @@ void tWaveOsc_setFreq(tWaveOsc* const cy, float freq) · 46 unmodified lines
18511960 {
18521961 _tWaveOsc* c = *cy;
18531962
1854− LEAF* leaf = c->mempool->leaf;
1855−
18561963 c->freq = freq;
18571964
1858− c->inc = c->freq * leaf->invSampleRate;
1965+ c->inc = c->freq * c->invSampleRate;
18591966 c->inc -= (int)c->inc;
18601967
18611968 // abs for negative frequencies
@@ -1885,6 +1992,13 @@ void tWaveOsc_setPhaseOffset(tWaveOsc* const cy, float phase) · 23 unmodified lines
18851992 c->phaseOffset = phase - (int)phase;
18861993 }
18871994
1995+void 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+
18882002 //================================================================================================
18892003 //================================================================================================
18902004
@@ -2039,18 +2153,16 @@ void tWaveSynth_setIndexPhase(tWaveSynth* const cy, int i, float phase) · 148 unmodified lines
20392153 }
20402154 }
20412155
2042−//void tWaveSynth_setIndexTable(tWaveSynth* const cy, int i, float* table, int size)
2043−//{
2044−// _tWaveSynth* c = *cy;
2045−// if (i >= c->numTables) return;
2046−// if (
2047−// tWaveTable_free(&c->tables[i]);
2048−// tWaveTable_initToPool(&c->tables[i], table, size, c->maxFreq, &c->mempool);
2049−// for (int v = 0; v < c->numVoices; ++v)
2050−// {
2051−// tWaveOsc_setFreq(&c->oscs[i][v], c->oscs[i][v]->freq);
2052−// }
2053−//}
2156+void tWaveSynth_setSampleRate(tWaveSynth* const cy, float sr)
2157+{
2158+ _tWaveSynth* c = *cy;
2159+
2160+ for (int i = 0; i < c->numTables; ++i)
2161+ {
2162+ tWaveTable_setSampleRate(&c->tables[i], sr);
2163+ for (int v = 0; v < c->numVoices; ++v) tWaveOsc_setSampleRate(&c->oscs[i][v], sr);
2164+ }
2165+}
20542166
20552167 //=======================================================================================
20562168 //=======================================================================================
@@ -2065,9 +2177,14 @@ void tWaveTableS_initToPool(tWaveTableS* const cy, float* table, int size, float · 8 unmodified lines
20652177 _tMempool* m = *mp;
20662178 _tWaveTableS* c = *cy = (_tWaveTableS*) mpool_alloc(sizeof(_tWaveTableS), m);
20672179 c->mempool = m;
2180+ LEAF* leaf = c->mempool->leaf;
2181+
2182+ c->sampleRate = leaf->sampleRate;
2183+
2184+ c->maxFreq = maxFreq;
20682185
20692186 // Determine base frequency
2070− c->baseFreq = m->leaf->sampleRate / (float) size;
2187+ c->baseFreq = c->sampleRate / (float) size;
20712188 c->invBaseFreq = 1.0f / c->baseFreq;
20722189
20732190 // Determine how many tables we need
@@ -2082,23 +2199,24 @@ void tWaveTableS_initToPool(tWaveTableS* const cy, float* table, int size, float · 8 unmodified lines
20822199 // Allocate memory for the tables
20832200 c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, c->mempool);
20842201 c->sizes = (int*) mpool_alloc(sizeof(int) * c->numTables, c->mempool);
2085− int n = size;
2086− for (int t = 0; t < c->numTables; ++t)
2202+ c->sizes[0] = size;
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)
20872206 {
2088− c->sizes[t] = n;
2089− c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], m);
2090− n = c->sizes[t] / 2;
2207+ c->sizes[t] = c->sizes[t-1] / 2;
2208+ c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->sizes[t], c->mempool);
20912209 }
20922210
20932211 // Copy table
20942212 for (int i = 0; i < c->sizes[0]; ++i)
20952213 {
2096− c->tables[0][i] = table[i];
2214+ c->baseTable[i] = table[i];
20972215 }
20982216
20992217 // Make bandlimited copies
21002218 // 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);
21022220 tOversampler_initToPool(&c->ds, 2, 1, mp);
21032221 for (int t = 1; t < c->numTables; ++t)
21042222 {
@@ -2130,6 +2248,67 @@ void tWaveTableS_free(tWaveTableS* const cy) · 25 unmodified lines
21302248 mpool_free((char*)c, c->mempool);
21312249 }
21322250
2251+void 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+
21332312 //================================================================================================
21342313 //================================================================================================
21352314
@@ -2143,7 +2322,9 @@ void tWaveOscS_initToPool(tWaveOscS* const cy, tWaveTableS* const table, tMempoo · 7 unmodified lines
21432322 _tMempool* m = *mp;
21442323 _tWaveOscS* c = *cy = (_tWaveOscS*) mpool_alloc(sizeof(_tWaveOscS), m);
21452324 c->mempool = m;
2325+ LEAF* leaf = c->mempool->leaf;
21462326
2327+ c->invSampleRate = leaf->invSampleRate;
21472328 c->inc = 0.0f;
21482329 c->phase = 0.0f;
21492330 c->phaseOffset = 0.0f;
@@ -2201,12 +2382,10 @@ float tWaveOscS_tick(tWaveOscS* const cy) · 51 unmodified lines
22012382 void tWaveOscS_setFreq(tWaveOscS* const cy, float freq)
22022383 {
22032384 _tWaveOscS* c = *cy;
2204−
2205− LEAF* leaf = c->mempool->leaf;
2206−
2385+
22072386 c->freq = freq;
22082387
2209− c->inc = c->freq * leaf->invSampleRate;
2388+ c->inc = c->freq * c->invSampleRate;
22102389 c->inc -= (int)c->inc;
22112390
22122391 // abs for negative frequencies
@@ -2233,6 +2412,13 @@ void tWaveOscS_setPhaseOffset(tWaveOscS* const cy, float phase) · 20 unmodified lines
22332412 c->phaseOffset = phase - (int)phase;
22342413 }
22352414
2415+void 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+
22362422 //================================================================================================
22372423 //================================================================================================
22382424
@@ -2386,6 +2572,16 @@ void tWaveSynthS_setIndexPhase(tWaveSynthS* const cy, int i, float phase) · 147 unmodified lines
23862572 tWaveOscS_setPhaseOffset(&c->oscs[i][v], phase);
23872573 }
23882574 }
2575+
2576+void 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+}
23892585 //
23902586 //void tWaveSynthS_setIndexTable(tWaveSynthS* const cy, int i, float* table, int size)
23912587 //{
leaf/Src/leaf-physical.c+104−32
@@ -29,6 +29,8 @@ void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* · 28 unmodified lines
2929 p->mempool = m;
3030 LEAF* leaf = p->mempool->leaf;
3131
32+ p->sampleRate = leaf->sampleRate;
33+
3234 if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
3335
3436 tNoise_initToPool(&p->noise, WhiteNoise, mp);
@@ -37,7 +39,7 @@ void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* · 2 unmodified lines
3739
3840 tOneZero_initToPool(&p->loopFilter, 0.0f, mp);
3941
40− tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);
42+ tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
4143 tAllpassDelay_clear(&p->delayLine);
4244
4345 tPluck_setFrequency(pl, 220.0f);
@@ -106,19 +108,17 @@ void tPluck_noteOff (tPluck* const pl, float amplitude ) · 62 unmodified lines
106108 void tPluck_setFrequency (tPluck* const pl, float frequency )
107109 {
108110 _tPluck* p = *pl;
109− LEAF* leaf = p->mempool->leaf;
110111
111112 if ( frequency <= 0.0f ) frequency = 0.001f;
112113
113114 // 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 );
115116
116117 tAllpassDelay_setDelay(&p->delayLine, delay );
117118
118119 p->loopGain = 0.99f + (frequency * 0.000005f);
119120
120121 if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;
121−
122122 }
123123
124124 // 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
127127 return;
128128 }
129129
130−void tPluckSampleRateChanged(tPluck* const pl)
130+void tPluck_setSampleRate(tPluck* const pl, float sr)
131131 {
132132 _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+
133139 tPluck_setFrequency(pl, p->lastFreq);
140+ tOnePole_setSampleRate(&p->pickFilter, p->sampleRate);
141+ tOneZero_setSampleRate(&p->loopFilter, p->sampleRate);
134142 }
135143
136144 /* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -146,12 +154,14 @@ void tKarplusStrong_initToPool (tKarplusStrong* const pl, float lowestFrequ · 9 unmodified lines
146154 p->mempool = m;
147155 LEAF* leaf = p->mempool->leaf;
148156
157+ p->sampleRate = leaf->sampleRate;
158+
149159 if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
150160
151− tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf->sampleRate * 2, mp);
161+ tAllpassDelay_initToPool(&p->delayLine, 0.0f, p->sampleRate * 2, mp);
152162 tAllpassDelay_clear(&p->delayLine);
153163
154− tLinearDelay_initToPool(&p->combDelay, 0.0f, leaf->sampleRate * 2, mp);
164+ tLinearDelay_initToPool(&p->combDelay, 0.0f, p->sampleRate * 2, mp);
155165 tLinearDelay_clear(&p->combDelay);
156166
157167 tOneZero_initToPool(&p->filter, 0.0f, mp);
@@ -254,12 +264,11 @@ void tKarplusStrong_noteOff (tKarplusStrong* const pl, float amplitude · 96 unmodified lines
254264 void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency )
255265 {
256266 _tKarplusStrong* p = *pl;
257− LEAF* leaf = p->mempool->leaf;
258267
259268 if ( frequency <= 0.0f ) frequency = 0.001f;
260269
261270 p->lastFrequency = frequency;
262− p->lastLength = leaf->sampleRate / p->lastFrequency;
271+ p->lastLength = p->sampleRate / p->lastFrequency;
263272 float delay = p->lastLength - 0.5f;
264273 tAllpassDelay_setDelay(&p->delayLine, delay);
265274
@@ -270,19 +279,17 @@ void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency · 4 unmodified lines
270279 tKarplusStrong_setStretch(pl, p->stretching);
271280
272281 tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
273−
274282 }
275283
276284 // Set the stretch "factor" of the string (0.0 - 1.0).
277285 void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stretch)
278286 {
279287 _tKarplusStrong* p = *pl;
280− LEAF* leaf = p->mempool->leaf;
281288
282289 p->stretching = stretch;
283290 float coefficient;
284291 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;
286293 float temp = 0.5f + (stretch * 0.5f);
287294 if ( temp > 0.9999f ) temp = 0.9999f;
288295
@@ -293,7 +300,7 @@ void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stret · 4 unmodified lines
293300 tBiQuad_setB0(&p->biquad[i], coefficient);
294301 tBiQuad_setB2(&p->biquad[i], 1.0f);
295302
296− coefficient = -2.0f * temp * cosf(TWO_PI * freq / leaf->sampleRate);
303+ coefficient = -2.0f * temp * cosf(TWO_PI * freq / p->sampleRate);
297304 tBiQuad_setA1(&p->biquad[i], coefficient);
298305 tBiQuad_setB1(&p->biquad[i], coefficient);
299306
@@ -339,12 +346,26 @@ void tKarplusStrong_controlChange (tKarplusStrong* const pl, SKControlType ty · 39 unmodified lines
339346 tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );
340347 }
341348
342−void tKarplusStrongSampleRateChanged (tKarplusStrong* const pl)
349+void tKarplusStrong_setSampleRate (tKarplusStrong* const pl, float sr)
343350 {
344351 _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);
345361
346362 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+ }
348369 }
349370
350371 /* Simple Living String*/
@@ -365,8 +386,9 @@ void tSimpleLivingString_initToPool (tSimpleLivingString* const pl, float fr · 14 unmodified lines
365386 p->mempool = m;
366387 LEAF* leaf = p->mempool->leaf;
367388
389+ p->sampleRate = leaf->sampleRate;
368390 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)
370392 tSimpleLivingString_setFreq(pl, freq);
371393 tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);
372394 tLinearDelay_clear(&p->delayLine);
@@ -393,11 +415,10 @@ void tSimpleLivingString_free (tSimpleLivingString* const pl) · 20 unmodified lines
393415 void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
394416 {
395417 _tSimpleLivingString* p = *pl;
396− LEAF* leaf = p->mempool->leaf;
397418
398419 if (freq<20) freq=20;
399420 else if (freq>10000) freq=10000;
400− p->waveLengthInSamples = leaf->sampleRate/freq;
421+ p->waveLengthInSamples = p->sampleRate/freq;
401422 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
402423 }
403424
@@ -466,6 +487,17 @@ float tSimpleLivingString_sample(tSimpleLivingString* const pl) · 62 unmodified lines
466487 return p->curr;
467488 }
468489
490+void 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+
469501 /* Living String*/
470502
471503 void 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
484516 p->mempool = m;
485517 LEAF* leaf = p->mempool->leaf;
486518
519+ p->sampleRate = leaf->sampleRate;
487520 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)
489522 tLivingString_setFreq(pl, freq);
490523 p->freq = freq;
491524 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
538571 void tLivingString_setFreq(tLivingString* const pl, float freq)
539572 { // NOTE: It is faster to set wavelength in samples directly
540573 _tLivingString* p = *pl;
541− LEAF* leaf = p->mempool->leaf;
542574
543575 if (freq<20.f) freq=20.f;
544576 else if (freq>10000.f) freq=10000.f;
545− p->waveLengthInSamples = leaf->sampleRate/freq;
577+ p->waveLengthInSamples = p->sampleRate/freq;
546578 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
547579 }
548580
@@ -658,6 +690,21 @@ float tLivingString_sample(tLivingString* const pl) · 109 unmodified lines
658690 return p->curr;
659691 }
660692
693+void 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+
661708
662709 //////////---------------------------
663710 /* Version of Living String with Hermite Interpolation */
@@ -681,8 +728,9 @@ void tLivingString2_initToPool (tLivingString2* const pl, float freq, floa · 17 unmodified lines
681728 p->mempool = m;
682729 LEAF* leaf = p->mempool->leaf;
683730
731+ p->sampleRate = leaf->sampleRate;
684732 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)
686734 tLivingString2_setFreq(pl, freq);
687735 p->freq = freq;
688736 p->prepPos = prepPos;
@@ -742,24 +790,24 @@ void tLivingString2_free (tLivingString2* const pl) · 53 unmodified lines
742790 void tLivingString2_setFreq(tLivingString2* const pl, float freq)
743791 { // NOTE: It is faster to set wavelength in samples directly
744792 _tLivingString2* p = *pl;
745− LEAF* leaf = p->mempool->leaf;
793+
746794 if (freq<20.f) freq=20.f;
747795 else if (freq>10000.f) freq=10000.f;
748796 freq = freq*2;
749797 p->freq = freq;
750− p->waveLengthInSamples = (leaf->sampleRate/freq) - 1;
798+ p->waveLengthInSamples = (p->sampleRate/p->freq) - 1;
751799 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
752800 }
753801
754802 void tLivingString2_setWaveLength(tLivingString2* const pl, float waveLength)
755803 {
756804 _tLivingString2* p = *pl;
757− LEAF* leaf = p->mempool->leaf;
805+
758806 waveLength = waveLength * 0.5f;
759807 if (waveLength<4.8f) waveLength=4.8f;
760808 else if (waveLength>2400.f) waveLength=2400.f;
761809 p->waveLengthInSamples = waveLength - 1;
762− p->freq = leaf->sampleRate / waveLength;
810+ p->freq = p->sampleRate / waveLength;
763811 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
764812 }
765813
@@ -927,7 +975,6 @@ float tLivingString2_tick(tLivingString2* const pl, float input) · 161 unmodified lines
927975 tHermiteDelay_setDelay(&p->delLB, lowLen);
928976 tHermiteDelay_setDelay(&p->delUF, upLen);
929977 tHermiteDelay_setDelay(&p->delUB, upLen);
930−
931978
932979 uint32_t pickupPosInt;
933980 float pickupOut = 0.0f;
@@ -962,7 +1009,19 @@ float tLivingString2_sample(tLivingString2* const pl) · 28 unmodified lines
9621009 return p->curr;
9631010 }
9641011
965−
1012+void 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+}
9661025
9671026 //////////---------------------------
9681027
@@ -984,8 +1043,9 @@ void tComplexLivingString_initToPool (tComplexLivingString* const pl, floa · 15 unmodified lines
9841043 p->mempool = m;
9851044 LEAF* leaf = p->mempool->leaf;
9861045
1046+ p->sampleRate = leaf->sampleRate;
9871047 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)
9891049 tComplexLivingString_setFreq(pl, freq);
9901050 p->freq = freq;
9911051 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
10501110 void tComplexLivingString_setFreq(tComplexLivingString* const pl, float freq)
10511111 { // NOTE: It is faster to set wavelength in samples directly
10521112 _tComplexLivingString* p = *pl;
1053− LEAF* leaf = p->mempool->leaf;
10541113
10551114 if (freq<20.0f) freq=20.0f;
10561115 else if (freq>10000.0f) freq=10000.0f;
1057− p->waveLengthInSamples = leaf->sampleRate/freq;
1116+ p->waveLengthInSamples = p->sampleRate/freq;
10581117 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
10591118 }
10601119
@@ -1205,7 +1264,20 @@ float tComplexLivingString_sample(tComplexLivingString* const pl) · 144 unmodified lines
12051264 return p->curr;
12061265 }
12071266
1208−
1267+void 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+}
12091281
12101282 ///Reed Table model
12111283 //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
3535
3636 r->inv_441 = 1.0f/44100.0f;
3737
38+ r->sampleRate = leaf->sampleRate;
39+ r->invSampleRate = leaf->invSampleRate;
40+
3841 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;
4043
4144 int delay, i;
4245 if (scaler != 1.0f)
@@ -85,14 +88,12 @@ void tPRCRevert_clear(tPRCReverb* const rev) · 42 unmodified lines
8588 void tPRCReverb_setT60(tPRCReverb* const rev, float t60)
8689 {
8790 _tPRCReverb* r = *rev;
88− LEAF* leaf = r->mempool->leaf;
8991
9092 if ( t60 <= 0.0f ) t60 = 0.001f;
9193
9294 r->t60 = t60;
9395
94− r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf->invSampleRate / t60 ));
95−
96+ r->combCoeff = powf(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * r->invSampleRate / t60 ));
9697 }
9798
9899 void tPRCReverb_setMix(tPRCReverb* const rev, float mix)
@@ -135,12 +136,40 @@ float tPRCReverb_tick(tPRCReverb* const rev, float input) · 36 unmodified lines
135136 return out;
136137 }
137138
138−void tPRCReverbSampleRateChanged (tPRCReverb* const rev)
139+void tPRCReverb_setSampleRate (tPRCReverb* const rev, float sr)
139140 {
140141 _tPRCReverb* r = *rev;
141− LEAF* leaf = r->mempool->leaf;
142142
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 ));
144173 }
145174
146175 /* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
@@ -159,9 +188,11 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 12 unmodified lines
159188 if (t60 <= 0.0f) t60 = 0.001f;
160189
161190 r->inv_441 = 1.0f/44100.0f;
191+ r->sampleRate = leaf->sampleRate;
192+ r->invSampleRate = leaf->invSampleRate;
162193
163194 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;
165196
166197 int delay, i;
167198
@@ -179,7 +210,7 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 11 unmodified lines
179210 {
180211 tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2, mp);
181212 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));
183214 }
184215
185216 for ( i=0; i<8; i++ )
@@ -188,7 +219,6 @@ void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const · 2 unmodified lines
188219 tLinearDelay_clear(&r->allpassDelays[i]);
189220 }
190221
191−
192222 tNReverb_setT60(rev, t60);
193223 r->allpassCoeff = 0.7f;
194224 r->mix = 0.3f;
@@ -214,14 +244,12 @@ void tNReverb_free (tNReverb* const rev) · 19 unmodified lines
214244 void tNReverb_setT60(tNReverb* const rev, float t60)
215245 {
216246 _tNReverb* r = *rev;
217− LEAF* leaf = r->mempool->leaf;
218247
219− if (t60 <= 0.0f) t60 = 0.001f;
248+ if (t60 <= 0.0f) t60 = 0.001f;
220249
221250 r->t60 = t60;
222251
223− for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * leaf->invSampleRate / t60 ));
224−
252+ for (int i=0; i<6; i++) r->combCoeffs[i] = powf(10.0f, (-3.0f * tLinearDelay_getDelay(&r->combDelays[i]) * r->invSampleRate / t60 ));
225253 }
226254
227255 void tNReverb_setMix(tNReverb* const rev, float mix)
@@ -344,7 +372,6 @@ void tNReverb_tickStereo(tNReverb* const rev, float input, float* output) · 116 unmodified lines
344372 output[0] = -( r->allpassCoeff * temp2 ) + temp + drymix;
345373 out = output[0];
346374
347−
348375 temp = tLinearDelay_getLastOut(&r->allpassDelays[5]);
349376 temp3 = r->allpassCoeff * temp;
350377 temp3 += temp1;
@@ -354,12 +381,44 @@ void tNReverb_tickStereo(tNReverb* const rev, float input, float* output) · 3 unmodified lines
354381 r->lastOut = out;
355382 }
356383
357−void tNReverbSampleRateChanged (tNReverb* const rev)
384+void tNReverb_setSampleRate (tNReverb* const rev, float sr)
358385 {
359386 _tNReverb* r = *rev;
360− LEAF* leaf = r->mempool->leaf;
361387
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);
363422 }
364423
365424 // ======================================DATTORRO=========================================
@@ -369,7 +428,6 @@ void tNReverbSampleRateChanged (tNReverb* const rev) · 3 unmodified lines
369428 float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
370429 float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
371430
372−
373431 void tDattorroReverb_init (tDattorroReverb* const rev, LEAF* const leaf)
374432 {
375433 tDattorroReverb_initToPool(rev, &leaf->mempool);
@@ -382,9 +440,11 @@ void tDattorroReverb_initToPool (tDattorroReverb* const rev, tMempool* · 6 unmodified lines
382440 r->mempool = m;
383441 LEAF* leaf = r->mempool->leaf;
384442
443+ r->sampleRate = leaf->sampleRate;
444+
385445 r->size_max = 2.0f;
386446 r->size = 1.f;
387− r->t = r->size * leaf->sampleRate * 0.001f;
447+ r->t = r->size * r->sampleRate * 0.001f;
388448 r->frozen = 0;
389449 // INPUT
390450 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
426486 tCycle_initToPool(&r->f2_lfo, mp);
427487 tCycle_setFreq(&r->f2_lfo, 0.07f);
428488
429−
430489 // PARAMETERS
431490 tDattorroReverb_setMix(rev, 0.5f);
432−
433491 tDattorroReverb_setInputDelay(rev, 0.f);
434−
435492 tDattorroReverb_setInputFilter(rev, 10000.f);
436−
437493 tDattorroReverb_setFeedbackFilter(rev, 5000.f);
438−
439494 tDattorroReverb_setFeedbackGain(rev, 0.4f);
440495 }
441496
@@ -625,66 +680,65 @@ void tDattorroReverb_tickStereo (tDattorroReverb* const rev, floa · 183 unmodified lines
625680 in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
626681 }
627682
628−
629− // FEEDBACK 1
630− f1_sample = in_sample + r->f2_last; // + f2_last_out;
631−
632− tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
633−
634− f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
635−
636− f1_sample = tTapeDelay_tick(&r->f1_delay_1, f1_sample);
637−
638− f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
639−
640− f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
641−
642− f1_delay_2_sample = tTapeDelay_tick(&r->f1_delay_2, f1_sample * 0.5f);
643−
644− r->f1_delay_2_last = f1_delay_2_sample;
645−
646− f1_sample = r->f1_delay_2_last + f1_sample;
647−
648− f1_sample = tHighpass_tick(&r->f1_hp, f1_sample);
649−
650− f1_sample *= r->feedback_gain;
651−
652− if (r->frozen)
653− {
654− f1_sample = 0.0f;
655− }
656−
657− r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
658−
659− // FEEDBACK 2
660− f2_sample = in_sample + r->f1_last;
661−
662− tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
663−
664− f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
665−
666− f2_sample = tTapeDelay_tick(&r->f2_delay_1, f2_sample);
667−
668− f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
669−
670− f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
671−
672− f2_delay_2_sample = tTapeDelay_tick(&r->f2_delay_2, f2_sample * 0.5f);
673−
674− r->f2_delay_2_last = f2_delay_2_sample;
675−
676− f2_sample = r->f2_delay_2_last + f2_sample;
677−
678− f2_sample = tHighpass_tick(&r->f2_hp, f2_sample);
679−
680− f2_sample *= r->feedback_gain;
681−
682− if (r->frozen)
683− {
684− f2_sample = 0.0f;
685− }
686− r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
687−
683+ // FEEDBACK 1
684+ f1_sample = in_sample + r->f2_last; // + f2_last_out;
685+
686+ tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
687+
688+ f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
689+
690+ f1_sample = tTapeDelay_tick(&r->f1_delay_1, f1_sample);
691+
692+ f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
693+
694+ f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
695+
696+ f1_delay_2_sample = tTapeDelay_tick(&r->f1_delay_2, f1_sample * 0.5f);
697+
698+ r->f1_delay_2_last = f1_delay_2_sample;
699+
700+ f1_sample = r->f1_delay_2_last + f1_sample;
701+
702+ f1_sample = tHighpass_tick(&r->f1_hp, f1_sample);
703+
704+ f1_sample *= r->feedback_gain;
705+
706+ if (r->frozen)
707+ {
708+ f1_sample = 0.0f;
709+ }
710+
711+ r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
712+
713+ // FEEDBACK 2
714+ f2_sample = in_sample + r->f1_last;
715+
716+ tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
717+
718+ f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
719+
720+ f2_sample = tTapeDelay_tick(&r->f2_delay_1, f2_sample);
721+
722+ f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
723+
724+ f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
725+
726+ f2_delay_2_sample = tTapeDelay_tick(&r->f2_delay_2, f2_sample * 0.5f);
727+
728+ r->f2_delay_2_last = f2_delay_2_sample;
729+
730+ f2_sample = r->f2_delay_2_last + f2_sample;
731+
732+ f2_sample = tHighpass_tick(&r->f2_hp, f2_sample);
733+
734+ f2_sample *= r->feedback_gain;
735+
736+ if (r->frozen)
737+ {
738+ f2_sample = 0.0f;
739+ }
740+ r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
741+
688742
689743
690744 // TAP OUT 1
@@ -730,7 +784,7 @@ void tDattorroReverb_setMix (tDattorroReverb* const rev, float mix · 39 unmodified lines
730784 r->mix = LEAF_clip(0.0f, mix, 1.0f);
731785 }
732786
733−void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze)
787+void tDattorroReverb_setFreeze (tDattorroReverb* const rev, int freeze)
734788 {
735789 _tDattorroReverb* r = *rev;
736790 r->frozen = freeze;
@@ -772,10 +826,9 @@ void tDattorroReverb_setHP (tDattorroReverb* const rev, float freq) · 35 unmodified lines
772826 void tDattorroReverb_setSize (tDattorroReverb* const rev, float size)
773827 {
774828 _tDattorroReverb* r = *rev;
775− LEAF* leaf = r->mempool->leaf;
776829
777830 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;
779832
780833 /*
781834 for (int i = 0; i < 4; i++)
@@ -835,3 +888,75 @@ void tDattorroReverb_setFeedbackGain (tDattorroReverb* const rev, float gai · 53 unmodified lines
835888 _tDattorroReverb* r = *rev;
836889 r->feedback_gain = gain;
837890 }
891+
892+void 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
3434 _tMempool* m = *mp;
3535 _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m);
3636 s->mempool = m;
37+ LEAF* leaf = s->mempool->leaf;
3738
3839 s->buff = (float*) mpool_alloc( sizeof(float) * length, m);
39− s->sampleRate = s->mempool->leaf->sampleRate;
40+ s->sampleRate = leaf->sampleRate;
4041 s->channels = 1;
4142 s->bufferLength = length;
4243 s->recordedLength = 0;
@@ -191,13 +192,12 @@ void tSampler_initToPool(tSampler* const sp, tBuffer* const b, tMempool* const m · 148 unmodified lines
191192
192193 _tBuffer* s = *b;
193194
194− p->leafInvSampleRate = leaf->invSampleRate;
195− p->leafSampleRate = leaf->sampleRate;
196− p->ticksPerSevenMs = 0.007f * p->leafSampleRate;
197− p->rateFactor = s->sampleRate * p->leafInvSampleRate;
195+ p->invSampleRate = leaf->invSampleRate;
196+ p->sampleRate = leaf->sampleRate;
197+ p->ticksPerSevenMs = 0.007f * p->sampleRate;
198+ p->rateFactor = s->sampleRate * p->invSampleRate;
198199 p->channels = s->channels;
199200
200−
201201 p->samp = s;
202202
203203 p->active = 0;
@@ -255,9 +255,8 @@ void tSampler_setSample (tSampler* const sp, tBuffer* const b) · 51 unmodified lines
255255 _tBuffer* s = *b;
256256
257257 p->samp = s;
258−
259258
260− p->rateFactor = s->sampleRate * p->leafInvSampleRate;
259+ p->rateFactor = s->sampleRate * p->invSampleRate;
261260 p->channels = s->channels;
262261
263262 p->start = 0;
@@ -268,8 +267,6 @@ void tSampler_setSample (tSampler* const sp, tBuffer* const b) · 4 unmodified lines
268267 p->idx = 0.f;
269268 }
270269
271−
272−
273270 float tSampler_tick (tSampler* const sp)
274271 {
275272 _tSampler* p = *sp;
@@ -342,9 +339,6 @@ float tSampler_tick (tSampler* const sp) · 66 unmodified lines
342339 int32_t fadeRightEnd = myEnd;// + (fadeLeftEnd - start);
343340 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;
344341 int32_t fadeRightStart = fadeRightEnd - cfxlen;
345−
346−
347−
348342
349343 if (p->mode == PlayLoop)
350344 {
@@ -532,7 +526,6 @@ float tSampler_tick (tSampler* const sp) · 181 unmodified lines
532526 return p->last;
533527 }
534528
535−
536529 float tSampler_tickStereo (tSampler* const sp, float* outputArray)
537530 {
538531 _tSampler* p = *sp;
@@ -611,9 +604,6 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 72 unmodified lines
611604 // if (fadeRightEnd >= length) fadeRightEnd = length - 1;
612605 int32_t fadeRightStart = fadeRightEnd - cfxlen;
613606
614−
615−
616−
617607 if (p->mode == PlayLoop)
618608 {
619609
@@ -725,11 +715,8 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 105 unmodified lines
725715 }
726716 }
727717
728−
729−
730718 attemptStartEndChange(sp);
731719
732−
733720 if (p->mode == PlayLoop)
734721 {
735722 if((int)p->idx < myStart)
@@ -782,9 +769,6 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 46 unmodified lines
782769 outputArray[i] = outputArray[i] * sampleGain;
783770 }
784771
785−
786−
787−
788772 if (p->active < 0)
789773 {
790774 //if was fading out and reached silence
@@ -816,11 +800,8 @@ float tSampler_tickStereo (tSampler* const sp, float* outputArray) · 25 unmodified lines
816800 }
817801 }
818802
819−
820−
821803 p->last = outputArray[0];
822804
823−
824805 return p->last;
825806 }
826807
@@ -1089,6 +1070,18 @@ void tSampler_setRate (tSampler* const sp, float rate) · 262 unmodified lines
10891070 p->iinc = 1.f / p->inc;
10901071 }
10911072
1073+
1074+void 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+
10921085 //==============================================================================
10931086
10941087 void 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
12121205 ;
12131206 }
12141207
1208+void tAutoSampler_setSampleRate (tAutoSampler* const as, float sr)
1209+{
1210+ _tAutoSampler* a = *as;
1211+ tSampler_setSampleRate(&a->sampler, sr);
1212+}
12151213
12161214
12171215 void 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
12681266 p->_p = 0.0f;
12691267 }
12701268
1271−
1272−
12731269 float tMBSampler_tick (tMBSampler* const sp)
12741270 {
12751271 _tMBSampler* c = *sp;
leaf/Src/leaf.c+2−6
@@ -18,14 +18,12 @@ · 17 unmodified lines
1818
1919 #endif
2020
21−void LEAF_init(LEAF* const leaf, float sr, int blocksize, char* memory, size_t memorysize, float(*random)(void))
21+void LEAF_init(LEAF* const leaf, float sr, char* memory, size_t memorysize, float(*random)(void))
2222 {
2323 leaf->_internal_mempool.leaf = leaf;
2424 leaf_pool_init(leaf, memory, memorysize);
2525
2626 leaf->sampleRate = sr;
27−
28− leaf->blockSize = blocksize;
2927
3028 leaf->invSampleRate = 1.0f/sr;
3129
@@ -45,13 +43,11 @@ void LEAF_init(LEAF* const leaf, float sr, int blocksize, char* memory, size_t m · 13 unmodified lines
4543 leaf->freeCount = 0;
4644 }
4745
48−
49−#define LEAFSampleRateChanged(THIS) leaf.THIS.sampleRateChanged(&leaf.THIS)
50−
5146 void LEAF_setSampleRate(LEAF* const leaf, float sampleRate)
5247 {
5348 leaf->sampleRate = sampleRate;
5449 leaf->invSampleRate = 1.0f/sampleRate;
50+ leaf->twoPiTimesInvSampleRate = leaf->invSampleRate * TWO_PI;
5551 }
5652
5753 float LEAF_getSampleRate(LEAF* const leaf)
leaf/leaf.h+2−3
@@ -142,13 +142,12 @@ extern "C" { · 141 unmodified lines
142142
143143 //! Initialize the LEAF instance.
144144 /*!
145− @param sampleRate The audio sample rate.
146− @param blockSize The audio block size.
145+ @param sampleRate The default sample rate for object initialized to this LEAF instance.
147146 @param memory A pointer to the memory that will make up the default mempool of a LEAF instance.
148147 @param memorySize The size of the memory that will make up the default mempool of a LEAF instance.
149148 @param random A pointer to a random number function. Should return a float >= 0 and < 1.
150149 */
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));
152151
153152 //! Set the sample rate of LEAF.
154153 /*!

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