ref: 765bd487689586be946653397bcaf6d08cdbd4cc
parent: bc99f48aca15efd07cb81853172b95e83076314f
author: spiricom <jeff@snyderphonics.com>
date: Sat Jan 25 07:49:22 EST 2020
fixed linear interpolater, added hermite interpolation, fixed issues in formant shifter
binary files a/.DS_Store b/.DS_Store differ
--- a/LEAF/Inc/leaf-analysis.h
+++ b/LEAF/Inc/leaf-analysis.h
@@ -33,12 +33,14 @@
typedef _tEnvelopeFollower* tEnvelopeFollower;
- void tEnvelopeFollower_init (tEnvelopeFollower* const, float attackThreshold, float decayCoeff);
- void tEnvelopeFollower_free (tEnvelopeFollower* const);
+ void tEnvelopeFollower_init (tEnvelopeFollower* const, float attackThreshold, float decayCoeff);
+ void tEnvelopeFollower_free (tEnvelopeFollower* const);
+ void tEnvelopeFollower_initToPool (tEnvelopeFollower* const, float attackThreshold, float decayCoeff, tMempool* const);
+ void tEnvelopeFollower_freeFromPool (tEnvelopeFollower* const, tMempool* const);
- float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x);
- int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
- int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
+ float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x);
+ int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
+ int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -51,12 +53,15 @@
typedef _tPowerFollower* tPowerFollower;
- void tPowerFollower_init (tPowerFollower* const, float factor);
- void tPowerFollower_free (tPowerFollower* const);
- float tPowerFollower_tick (tPowerFollower* const, float input);
- float tPowerFollower_sample (tPowerFollower* const);
- int tPowerFollower_setFactor (tPowerFollower* const, float factor);
+ void tPowerFollower_init (tPowerFollower* const, float factor);
+ void tPowerFollower_free (tPowerFollower* const);
+ void tPowerFollower_initToPool (tPowerFollower* const, float factor, tMempool* const);
+ void tPowerFollower_freeFromPool (tPowerFollower* const, tMempool* const);
+ float tPowerFollower_tick (tPowerFollower* const, float input);
+ float tPowerFollower_sample (tPowerFollower* const);
+ int tPowerFollower_setFactor (tPowerFollower* const, float factor);
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
// ENV~ from PD, modified for LEAF
@@ -81,11 +86,14 @@
typedef _tEnvPD* tEnvPD;
- void tEnvPD_init (tEnvPD* const, int windowSize, int hopSize, int blockSize);
- void tEnvPD_free (tEnvPD* const);
- float tEnvPD_tick (tEnvPD* const);
- void tEnvPD_processBlock (tEnvPD* const, float* in);
+ void tEnvPD_init (tEnvPD* const, int windowSize, int hopSize, int blockSize);
+ void tEnvPD_free (tEnvPD* const);
+ void tEnvPD_initToPool (tEnvPD* const, int windowSize, int hopSize, int blockSize, tMempool* const);
+ void tEnvPD_freeFromPool (tEnvPD* const, tMempool* const);
+ float tEnvPD_tick (tEnvPD* const);
+ void tEnvPD_processBlock (tEnvPD* const, float* in);
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* tAttackDetection */
@@ -117,27 +125,28 @@
typedef _tAttackDetection* tAttackDetection;
- void tAttackDetection_init (tAttackDetection* const, int blocksize);
- void tAttackDetection_init_expanded (tAttackDetection* const, int blocksize, int atk, int rel);
- void tAttackDetection_free (tAttackDetection* const);
+ void tAttackDetection_init (tAttackDetection* const, int blocksize, int atk, int rel);
+ void tAttackDetection_free (tAttackDetection* const);
+ void tAttackDetection_initToPool (tAttackDetection* const, int blocksize, int atk, int rel, tMempool* const);
+ void tAttackDetection_freeFromPool (tAttackDetection* const, tMempool* const);
// set expected input blocksize
- void tAttackDetection_setBlocksize (tAttackDetection* const, int size);
+ void tAttackDetection_setBlocksize (tAttackDetection* const, int size);
// change atkDetector sample rate
- void tAttackDetection_setSamplerate (tAttackDetection* const, int inRate);
+ void tAttackDetection_setSamplerate (tAttackDetection* const, int inRate);
// set attack time and coeff
- void tAttackDetection_setAtk (tAttackDetection* const, int inAtk);
+ void tAttackDetection_setAttack (tAttackDetection* const, int inAtk);
// set release time and coeff
- void tAttackDetection_setRel (tAttackDetection* const, int inRel);
+ void tAttackDetection_setRelease (tAttackDetection* const, int inRel);
// set level above which values are identified as attacks
- void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
+ void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
// find largest transient in input block, return index of attack
- int tAttackDetection_detect (tAttackDetection* const, float *in);
+ int tAttackDetection_detect (tAttackDetection* const, float *in);
//==============================================================================
@@ -168,8 +177,10 @@
typedef _tSNAC* tSNAC;
- void tSNAC_init (tSNAC* const, int overlaparg); // constructor
- void tSNAC_free (tSNAC* const); // destructor
+ void tSNAC_init (tSNAC* const, int overlaparg);
+ void tSNAC_free (tSNAC* const);
+ void tSNAC_initToPool (tSNAC* const, int overlaparg, tMempool* const);
+ void tSNAC_freeFromPool (tSNAC* const, tMempool* const);
void tSNAC_ioSamples (tSNAC *s, float *in, float *out, int size);
void tSNAC_setOverlap (tSNAC *s, int lap);
@@ -178,7 +189,7 @@
/*To get freq, perform SAMPLE_RATE/snac_getperiod() */
float tSNAC_getPeriod (tSNAC *s);
- float tSNAC_getfidelity (tSNAC *s);
+ float tSNAC_getFidelity (tSNAC *s);
#define DEFPITCHRATIO 2.0f
#define DEFTIMECONSTANT 100.0f
@@ -220,12 +231,14 @@
typedef _tPeriodDetection* tPeriodDetection;
- void tPeriodDetection_init (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize);
- void tPeriodDetection_free (tPeriodDetection* const);
+ void tPeriodDetection_init (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize);
+ void tPeriodDetection_free (tPeriodDetection* const);
+ void tPeriodDetection_initToPool (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize, tMempool* const);
+ void tPeriodDetection_freeFromPool (tPeriodDetection* const, tMempool* const);
- float tPeriodDetection_findPeriod (tPeriodDetection* const, float sample);
- void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);
- void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);
+ float tPeriodDetection_findPeriod (tPeriodDetection* const, float sample);
+ void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);
+ void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);
//==============================================================================
--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -16,6 +16,7 @@
//==============================================================================
#include "leaf-math.h"
+#include "leaf-mempool.h"
//==============================================================================
@@ -35,17 +36,19 @@
typedef _tDelay* tDelay;
- void tDelay_init (tDelay* const, uint32_t delay, uint32_t maxDelay);
+ void tDelay_init (tDelay* const, uint32_t delay, uint32_t maxDelay);
void tDelay_free (tDelay* const);
+ void tDelay_initToPool (tDelay* const, uint32_t delay, uint32_t maxDelay, tMempool* const);
+ void tDelay_freeFromPool (tDelay* const, tMempool* const);
- int tDelay_setDelay (tDelay* const, uint32_t delay);
- uint32_t tDelay_getDelay (tDelay* const);
- void tDelay_tapIn (tDelay* const, float in, uint32_t tapDelay);
- float tDelay_tapOut (tDelay* const, uint32_t tapDelay);
- float tDelay_addTo (tDelay* const, float value, uint32_t tapDelay);
- float tDelay_tick (tDelay* const, float sample);
- float tDelay_getLastOut (tDelay* const);
- float tDelay_getLastIn (tDelay* const);
+ int tDelay_setDelay (tDelay* const, uint32_t delay);
+ uint32_t tDelay_getDelay (tDelay* const);
+ void tDelay_tapIn (tDelay* const, float in, uint32_t tapDelay);
+ float tDelay_tapOut (tDelay* const, uint32_t tapDelay);
+ float tDelay_addTo (tDelay* const, float value, uint32_t tapDelay);
+ float tDelay_tick (tDelay* const, float sample);
+ float tDelay_getLastOut (tDelay* const);
+ float tDelay_getLastIn (tDelay* const);
//==============================================================================
@@ -69,21 +72,66 @@
typedef _tLinearDelay* tLinearDelay;
- void tLinearDelay_init (tLinearDelay* const, float delay, uint32_t maxDelay);
- void tLinearDelay_free (tLinearDelay* const);
+ void tLinearDelay_init (tLinearDelay* const, float delay, uint32_t maxDelay);
+ void tLinearDelay_free (tLinearDelay* const);
+ void tLinearDelay_initToPool (tLinearDelay* const, float delay, uint32_t maxDelay, tMempool* const);
+ void tLinearDelay_freeFromPool(tLinearDelay* const, tMempool* const);
+ void tLinearDelay_clear (tLinearDelay* const dl);
+ int tLinearDelay_setDelay (tLinearDelay* const, float delay);
+ float tLinearDelay_getDelay (tLinearDelay* const);
+ void tLinearDelay_tapIn (tLinearDelay* const, float in, uint32_t tapDelay);
+ float tLinearDelay_tapOut (tLinearDelay* const, uint32_t tapDelay);
+ float tLinearDelay_addTo (tLinearDelay* const, float value, uint32_t tapDelay);
+ float tLinearDelay_tick (tLinearDelay* const, float sample);
+ void tLinearDelay_tickIn (tLinearDelay* const, float input);
+ float tLinearDelay_tickOut (tLinearDelay* const);
+ float tLinearDelay_getLastOut (tLinearDelay* const);
+ float tLinearDelay_getLastIn (tLinearDelay* const);
- int tLinearDelay_setDelay (tLinearDelay* const, float delay);
- float tLinearDelay_getDelay (tLinearDelay* const);
- void tLinearDelay_tapIn (tLinearDelay* const, float in, uint32_t tapDelay);
- float tLinearDelay_tapOut (tLinearDelay* const, float tapDelay);
- float tLinearDelay_addTo (tLinearDelay* const, float value, uint32_t tapDelay);
- float tLinearDelay_tick (tLinearDelay* const, float sample);
- void tLinearDelay_tickIn (tLinearDelay* const, float input);
- float tLinearDelay_tickOut (tLinearDelay* const);
- float tLinearDelay_getLastOut (tLinearDelay* const);
- float tLinearDelay_getLastIn (tLinearDelay* const);
-
+
+
//==============================================================================
+
+ /* Hermite-interpolating delay, created by adapting STK linear delay with Hermite interpolation */
+ typedef struct _tHermiteDelay
+ {
+ float gain;
+ float* buff;
+
+ float lastOut, lastIn;
+
+ uint32_t inPoint, outPoint;
+
+ uint32_t maxDelay;
+
+ float delay;
+
+ float alpha, omAlpha;
+
+ } _tHermiteDelay;
+
+ typedef _tHermiteDelay* tHermiteDelay;
+
+ void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay);
+ void tHermiteDelay_free (tHermiteDelay* const dl);
+ void tHermiteDelay_initToPool (tHermiteDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp);
+ void tHermiteDelay_freeFromPool (tHermiteDelay* const dl, tMempool* const mp);
+ void tHermiteDelay_clear (tHermiteDelay* const dl);
+ float tHermiteDelay_tick (tHermiteDelay* const dl, float input);
+ void tHermiteDelay_tickIn (tHermiteDelay* const dl, float input);
+ float tHermiteDelay_tickOut (tHermiteDelay* const dl);
+ int tHermiteDelay_setDelay (tHermiteDelay* const dl, float delay);
+ float tHermiteDelay_tapOut (tHermiteDelay* const dl, uint32_t tapDelay);
+ void tHermiteDelay_tapIn (tHermiteDelay* const dl, float value, uint32_t tapDelay);
+ float tHermiteDelay_addTo (tHermiteDelay* const dl, float value, uint32_t tapDelay);
+ float tHermiteDelay_getDelay (tHermiteDelay* const dl);
+ float tHermiteDelay_getLastOut (tHermiteDelay* const dl);
+ float tHermiteDelay_getLastIn (tHermiteDelay* const dl);
+ void tHermiteDelay_setGain (tHermiteDelay* const dl, float gain);
+ float tHermiteDelay_getGain (tHermiteDelay* const dl);
+
+
+ //==============================================================================
/* Allpass-interpolating delay, reimplemented from STK (Cook and Scavone). */
typedef struct _tAllpassDelay
@@ -107,17 +155,19 @@
typedef _tAllpassDelay* tAllpassDelay;
- void tAllpassDelay_init (tAllpassDelay* const, float delay, uint32_t maxDelay);
- void tAllpassDelay_free (tAllpassDelay* const);
+ void tAllpassDelay_init (tAllpassDelay* const, float delay, uint32_t maxDelay);
+ void tAllpassDelay_free (tAllpassDelay* const);
+ void tAllpassDelay_initToPool (tAllpassDelay* const, float delay, uint32_t maxDelay, tMempool* const);
+ void tAllpassDelay_freeFromPool(tAllpassDelay* const, tMempool* const);
- int tAllpassDelay_setDelay (tAllpassDelay* const, float delay);
- float tAllpassDelay_getDelay (tAllpassDelay* const);
- void tAllpassDelay_tapIn (tAllpassDelay* const, float in, uint32_t tapDelay);
- float tAllpassDelay_tapOut (tAllpassDelay* const, uint32_t tapDelay);
- float tAllpassDelay_addTo (tAllpassDelay* const, float value, uint32_t tapDelay);
- float tAllpassDelay_tick (tAllpassDelay* const, float sample);
- float tAllpassDelay_getLastOut (tAllpassDelay* const);
- float tAllpassDelay_getLastIn (tAllpassDelay* const);
+ int tAllpassDelay_setDelay (tAllpassDelay* const, float delay);
+ float tAllpassDelay_getDelay (tAllpassDelay* const);
+ void tAllpassDelay_tapIn (tAllpassDelay* const, float in, uint32_t tapDelay);
+ float tAllpassDelay_tapOut (tAllpassDelay* const, uint32_t tapDelay);
+ float tAllpassDelay_addTo (tAllpassDelay* const, float value, uint32_t tapDelay);
+ float tAllpassDelay_tick (tAllpassDelay* const, float sample);
+ float tAllpassDelay_getLastOut (tAllpassDelay* const);
+ float tAllpassDelay_getLastIn (tAllpassDelay* const);
//==============================================================================
@@ -141,18 +191,20 @@
typedef _tTapeDelay* tTapeDelay;
- void tTapeDelay_init (tTapeDelay* const, float delay, uint32_t maxDelay);
- void tTapeDelay_free (tTapeDelay* const);
+ void tTapeDelay_init (tTapeDelay* const, float delay, uint32_t maxDelay);
+ void tTapeDelay_free (tTapeDelay* const);
+ void tTapeDelay_initToPool (tTapeDelay* const, float delay, uint32_t maxDelay, tMempool* const);
+ void tTapeDelay_freeFromPool(tTapeDelay* const, tMempool* const);
- void tTapeDelay_setDelay (tTapeDelay* const, float delay);
- float tTapeDelay_getDelay (tTapeDelay* const);
- void tTapeDelay_tapIn (tTapeDelay* const, float in, uint32_t tapDelay);
- float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay);
- float tTapeDelay_addTo (tTapeDelay* const, float value, uint32_t tapDelay);
- float tTapeDelay_tick (tTapeDelay* const, float sample);
- void tTapeDelay_incrementInPoint(tTapeDelay* const dl);
- float tTapeDelay_getLastOut (tTapeDelay* const);
- float tTapeDelay_getLastIn (tTapeDelay* const);
+ void tTapeDelay_setDelay (tTapeDelay* const, float delay);
+ float tTapeDelay_getDelay (tTapeDelay* const);
+ void tTapeDelay_tapIn (tTapeDelay* const, float in, uint32_t tapDelay);
+ float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay);
+ float tTapeDelay_addTo (tTapeDelay* const, float value, uint32_t tapDelay);
+ float tTapeDelay_tick (tTapeDelay* const, float sample);
+ void tTapeDelay_incrementInPoint(tTapeDelay* const dl);
+ float tTapeDelay_getLastOut (tTapeDelay* const);
+ float tTapeDelay_getLastIn (tTapeDelay* const);
//==============================================================================
--- a/LEAF/Inc/leaf-distortion.h
+++ b/LEAF/Inc/leaf-distortion.h
@@ -21,6 +21,51 @@
//==============================================================================
+ typedef struct _tSampleReducer
+ {
+ float invRatio;
+ float hold;
+ uint32_t count;
+ } _tSampleReducer;
+
+ typedef _tSampleReducer* tSampleReducer;
+
+ void tSampleReducer_init (tSampleReducer* const);
+ void tSampleReducer_free (tSampleReducer* const);
+ void tSampleReducer_initToPool (tSampleReducer* const, tMempool* const);
+ void tSampleReducer_freeFromPool (tSampleReducer* const, tMempool* const);
+
+ float tSampleReducer_tick (tSampleReducer* const, float input);
+
+ // sampling ratio
+ void tSampleReducer_setRatio (tSampleReducer* const, float ratio);
+
+ //==============================================================================
+
+ typedef struct _tOversampler
+ {
+ int ratio;
+ float* pCoeffs;
+ float* upState;
+ float* downState;
+ int numTaps;
+ int phaseLength;
+ } _tOversampler;
+
+ typedef _tOversampler* tOversampler;
+
+ void tOversampler_init (tOversampler* const, int order, oBool extraQuality);
+ void tOversampler_free (tOversampler* const);
+ void tOversampler_initToPool (tOversampler* const, int order, oBool extraQuality, tMempool* const);
+ void tOversampler_freeFromPool (tOversampler* const, tMempool* const);
+
+ void tOversampler_upsample (tOversampler* const, float input, float* output);
+ float tOversampler_downsample (tOversampler* const os, float* input);
+ float tOversampler_tick (tOversampler* const, float input, float (*effectTick)(float));
+ int tOversampler_getLatency (tOversampler* const os);
+
+ //==============================================================================
+
/* tLockhartWavefolder */
typedef struct _tLockhartWavefolder
@@ -49,30 +94,11 @@
void tLockhartWavefolder_init (tLockhartWavefolder* const);
void tLockhartWavefolder_free (tLockhartWavefolder* const);
+ void tLockhartWavefolder_initToPool (tLockhartWavefolder* const, tMempool* const);
+ void tLockhartWavefolder_freeFromPool (tLockhartWavefolder* const, tMempool* const);
float tLockhartWavefolder_tick (tLockhartWavefolder* const, float samp);
-
- //==============================================================================
-
-
- typedef struct _tSampleReducer
- {
- float invRatio;
- float hold;
- uint32_t count;
- } _tSampleReducer;
-
- typedef _tSampleReducer* tSampleReducer;
-
- void tSampleReducer_init (tSampleReducer* const);
- void tSampleReducer_free (tSampleReducer* const);
-
- float tSampleReducer_tick (tSampleReducer* const, float input);
-
- // sampling ratio
- void tSampleReducer_setRatio (tSampleReducer* const, float ratio);
-
//==============================================================================
typedef struct _tCrusher
@@ -92,6 +118,8 @@
void tCrusher_init (tCrusher* const);
void tCrusher_free (tCrusher* const);
+ void tCrusher_initToPool (tCrusher* const, tMempool* const);
+ void tCrusher_freeFromPool (tCrusher* const, tMempool* const);
float tCrusher_tick (tCrusher* const, float input);
@@ -106,29 +134,6 @@
// sampling ratio
void tCrusher_setSamplingRatio (tCrusher* const, float ratio);
-
-
- //==============================================================================
-
-
- typedef struct _tOversampler
- {
- int ratio;
- float* pCoeffs;
- float* upState;
- float* downState;
- int numTaps;
- int phaseLength;
- } _tOversampler;
-
- typedef _tOversampler* tOversampler;
-
- void tOversampler_init(tOversampler* const, int order, oBool extraQuality);
- void tOversampler_free(tOversampler* const);
- void tOversampler_upsample(tOversampler* const, float input, float* output);
- float tOversampler_downsample(tOversampler* const os, float* input);
- float tOversampler_tick(tOversampler* const, float input, float (*effectTick)(float));
- int tOversampler_getLatency(tOversampler* const os);
//==============================================================================
--- a/LEAF/Inc/leaf-dynamics.h
+++ b/LEAF/Inc/leaf-dynamics.h
@@ -18,6 +18,7 @@
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-analysis.h"
//==============================================================================
@@ -38,10 +39,13 @@
typedef _tCompressor* tCompressor;
- void tCompressor_init (tCompressor* const);
- void tCompressor_free (tCompressor* const);
- float tCompressor_tick (tCompressor* const, float input);
+ void tCompressor_init (tCompressor* const);
+ void tCompressor_free (tCompressor* const);
+ void tCompressor_initToPool (tCompressor* const, tMempool* const);
+ void tCompressor_freeFromPool(tCompressor* const, tMempool* const);
+ float tCompressor_tick (tCompressor* const, float input);
+
///
/* Feedback leveller */
// An auto VCA that you put into a feedback circuit to make it stay at the same level.
@@ -61,15 +65,17 @@
typedef _tFeedbackLeveler* tFeedbackLeveler;
- void tFeedbackLeveler_init (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode);
- void tFeedbackLeveler_free (tFeedbackLeveler* const);
+ void tFeedbackLeveler_init (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode);
+ void tFeedbackLeveler_free (tFeedbackLeveler* const);
+ void tFeedbackLeveler_initToPool (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode, tMempool* const);
+ void tFeedbackLeveler_freeFromPool (tFeedbackLeveler* const, tMempool* const);
- float tFeedbackLeveler_tick (tFeedbackLeveler* const, float input);
- float tFeedbackLeveler_sample (tFeedbackLeveler* const);
- void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const, float TargetLevel);
- void tFeedbackLeveler_setFactor (tFeedbackLeveler* const, float factor);
- void tFeedbackLeveler_setMode (tFeedbackLeveler* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
- void tFeedbackLeveler_setStrength (tFeedbackLeveler* const, float strength);
+ float tFeedbackLeveler_tick (tFeedbackLeveler* const, float input);
+ float tFeedbackLeveler_sample (tFeedbackLeveler* const);
+ void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const, float TargetLevel);
+ void tFeedbackLeveler_setFactor (tFeedbackLeveler* const, float factor);
+ void tFeedbackLeveler_setMode (tFeedbackLeveler* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
+ void tFeedbackLeveler_setStrength (tFeedbackLeveler* const, float strength);
//==============================================================================
--- a/LEAF/Inc/leaf-effects.h
+++ b/LEAF/Inc/leaf-effects.h
@@ -14,9 +14,10 @@
#endif
//==============================================================================
-#include "leaf-dynamics.h"
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
+#include "leaf-dynamics.h"
#include "leaf-analysis.h"
//==============================================================================
@@ -45,15 +46,18 @@
typedef _tTalkbox* tTalkbox;
- void tTalkbox_init (tTalkbox* const, int bufsize);
- void tTalkbox_free (tTalkbox* const);
- float tTalkbox_tick (tTalkbox* const, float synth, float voice);
- void tTalkbox_update (tTalkbox* const);
- void tTalkbox_suspend (tTalkbox* const);
- void tTalkbox_lpcDurbin (float *r, int p, float *k, float *g);
- void tTalkbox_lpc (float *buf, float *car, int32_t n, int32_t o);
- void tTalkbox_setQuality (tTalkbox* const, float quality);
+ void tTalkbox_init (tTalkbox* const, int bufsize);
+ void tTalkbox_free (tTalkbox* const);
+ void tTalkbox_initToPool (tTalkbox* const, int bufsize, tMempool* const);
+ void tTalkbox_freeFromPool (tTalkbox* const, tMempool* const);
+ float tTalkbox_tick (tTalkbox* const, float synth, float voice);
+ void tTalkbox_update (tTalkbox* const);
+ void tTalkbox_suspend (tTalkbox* const);
+ void tTalkbox_lpcDurbin (float *r, int p, float *k, float *g);
+ void tTalkbox_lpc (float *buf, float *car, int32_t n, int32_t o);
+ void tTalkbox_setQuality (tTalkbox* const, float quality);
+
//==============================================================================
/* tVocoder */
@@ -77,12 +81,15 @@
typedef _tVocoder* tVocoder;
- void tVocoder_init (tVocoder* const);
- void tVocoder_free (tVocoder* const);
- float tVocoder_tick (tVocoder* const, float synth, float voice);
- void tVocoder_update (tVocoder* const);
- void tVocoder_suspend (tVocoder* const);
+ void tVocoder_init (tVocoder* const);
+ void tVocoder_free (tVocoder* const);
+ void tVocoder_initToPool (tVocoder* const, tMempool* const);
+ void tVocoder_freeFromPool (tVocoder* const, tMempool* const);
+ float tVocoder_tick (tVocoder* const, float synth, float voice);
+ void tVocoder_update (tVocoder* const);
+ void tVocoder_suspend (tVocoder* const);
+
//==============================================================================
@@ -117,6 +124,9 @@
void tSOLAD_init (tSOLAD* const);
void tSOLAD_free (tSOLAD* const);
+ void tSOLAD_initToPool (tSOLAD* const, tMempool* const);
+ void tSOLAD_freeFromPool (tSOLAD* const, tMempool* const);
+
// send one block of input samples, receive one block of output samples
void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
// set periodicity analysis data
@@ -151,13 +161,16 @@
typedef _tPitchShift* tPitchShift;
- void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
- void tPitchShift_free (tPitchShift* const);
- float tPitchShift_shift (tPitchShift* const);
- float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
- float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
- void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
+ void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
+ void tPitchShift_free (tPitchShift* const);
+ void tPitchShift_initToPool (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize, tMempool* const);
+ void tPitchShift_freeFromPool (tPitchShift* const, tMempool* const);
+ float tPitchShift_shift (tPitchShift* const);
+ float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
+ float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
+ void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
+
// Retune
typedef struct _tRetune
{
@@ -185,18 +198,20 @@
typedef _tRetune* tRetune;
- void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
- void tRetune_free (tRetune* const);
+ void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
+ void tRetune_free (tRetune* const);
+ void tRetune_initToPool (tRetune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+ void tRetune_freeFromPool (tRetune* const, tMempool* const);
- float* tRetune_tick (tRetune* const, float sample);
- void tRetune_setNumVoices (tRetune* const, int numVoices);
- void tRetune_setPitchFactors (tRetune* const, float pf);
- void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
- void tRetune_setTimeConstant (tRetune* const, float tc);
- void tRetune_setHopSize (tRetune* const, int hs);
- void tRetune_setWindowSize (tRetune* const, int ws);
- float tRetune_getInputPeriod (tRetune* const);
- float tRetune_getInputFreq (tRetune* const);
+ float* tRetune_tick (tRetune* const, float sample);
+ void tRetune_setNumVoices (tRetune* const, int numVoices);
+ void tRetune_setPitchFactors (tRetune* const, float pf);
+ void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
+ void tRetune_setTimeConstant (tRetune* const, float tc);
+ void tRetune_setHopSize (tRetune* const, int hs);
+ void tRetune_setWindowSize (tRetune* const, int ws);
+ float tRetune_getInputPeriod (tRetune* const);
+ float tRetune_getInputFreq (tRetune* const);
// Autotune
typedef struct _tAutotune
@@ -225,18 +240,20 @@
typedef _tAutotune* tAutotune;
- void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
- void tAutotune_free (tAutotune* const);
+ void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
+ void tAutotune_free (tAutotune* const);
+ void tAutotune_initToPool (tAutotune* const, int numVoices, int bufSize, int frameSize, tMempool* const);
+ void tAutotune_freeFromPool (tAutotune* const, tMempool* const);
- float* tAutotune_tick (tAutotune* const, float sample);
- void tAutotune_setNumVoices (tAutotune* const, int numVoices);
- void tAutotune_setFreqs (tAutotune* const, float f);
- void tAutotune_setFreq (tAutotune* const, float f, int voice);
- void tAutotune_setTimeConstant (tAutotune* const, float tc);
- void tAutotune_setHopSize (tAutotune* const, int hs);
- void tAutotune_setWindowSize (tAutotune* const, int ws);
- float tAutotune_getInputPeriod (tAutotune* const);
- float tAutotune_getInputFreq (tAutotune* const);
+ float* tAutotune_tick (tAutotune* const, float sample);
+ void tAutotune_setNumVoices (tAutotune* const, int numVoices);
+ void tAutotune_setFreqs (tAutotune* const, float f);
+ void tAutotune_setFreq (tAutotune* const, float f, int voice);
+ void tAutotune_setTimeConstant (tAutotune* const, float tc);
+ void tAutotune_setHopSize (tAutotune* const, int hs);
+ void tAutotune_setWindowSize (tAutotune* const, int ws);
+ float tAutotune_getInputPeriod (tAutotune* const);
+ float tAutotune_getInputFreq (tAutotune* const);
//==============================================================================
@@ -273,15 +290,17 @@
typedef _tFormantShifter* tFormantShifter;
- void tFormantShifter_init (tFormantShifter* const, int bufsize, int order);
- void tFormantShifter_free (tFormantShifter* const);
+ void tFormantShifter_init (tFormantShifter* const, int bufsize, int order);
+ void tFormantShifter_free (tFormantShifter* const);
+ void tFormantShifter_initToPool (tFormantShifter* const, int bufsize, int order, tMempool* const);
+ void tFormantShifter_freeFromPool (tFormantShifter* const, tMempool* const);
- float tFormantShifter_tick (tFormantShifter* const, float input);
- float tFormantShifter_remove (tFormantShifter* const, float input);
- float tFormantShifter_add (tFormantShifter* const, float input);
- void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
- void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);
- void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);
+ float tFormantShifter_tick (tFormantShifter* const, float input);
+ float tFormantShifter_remove (tFormantShifter* const, float input);
+ float tFormantShifter_add (tFormantShifter* const, float input);
+ void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
+ void tFormantShifter_setShiftFactor (tFormantShifter* const, float shiftFactor);
+ void tFormantShifter_setIntensity (tFormantShifter* const, float intensity);
//==============================================================================
--- a/LEAF/Inc/leaf-electrical.h
+++ b/LEAF/Inc/leaf-electrical.h
@@ -16,6 +16,7 @@
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
//==============================================================================
@@ -64,21 +65,24 @@
};
//WDF Linear Components
- void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
- void tWDF_free(tWDF* const r);
- float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
+ void tWDF_init (tWDF* const, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
+ void tWDF_free (tWDF* const);
+ void tWDF_initToPool (tWDF* const, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR, tMempool* const);
+ void tWDF_freeFromPool (tWDF* const, tMempool* const);
- void tWDF_setValue(tWDF* const r, float value);
- void tWDF_setSampleRate(tWDF* const r, float sample_rate);
- uint8_t tWDF_isLeaf(tWDF* const r);
+ float tWDF_tick (tWDF* const, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
- float tWDF_getPortResistance(tWDF* const r);
- float tWDF_getReflectedWaveUp(tWDF* const r, float input); //for tree, only uses input for resistive source
- float tWDF_getReflectedWaveDown(tWDF* const r, float input, float incident_wave); //for roots
- void tWDF_setIncidentWave(tWDF* const r, float incident_wave, float input);
+ void tWDF_setValue (tWDF* const, float value);
+ void tWDF_setSampleRate (tWDF* const, float sample_rate);
+ uint8_t tWDF_isLeaf (tWDF* const);
- float tWDF_getVoltage(tWDF* const r);
- float tWDF_getCurrent(tWDF* const r);
+ float tWDF_getPortResistance (tWDF* const);
+ float tWDF_getReflectedWaveUp (tWDF* const, float input); //for tree, only uses input for resistive source
+ float tWDF_getReflectedWaveDown (tWDF* const, float input, float incident_wave); //for roots
+ void tWDF_setIncidentWave (tWDF* const, float incident_wave, float input);
+
+ float tWDF_getVoltage (tWDF* const);
+ float tWDF_getCurrent (tWDF* const);
//==============================================================================
--- a/LEAF/Inc/leaf-envelopes.h
+++ b/LEAF/Inc/leaf-envelopes.h
@@ -18,6 +18,7 @@
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-filters.h"
#include "leaf-delay.h"
@@ -26,8 +27,8 @@
/* Attack-Decay envelope */
typedef struct _tEnvelope {
- const float *exp_buff;
- const float *inc_buff;
+ const float *exp_buff;
+ const float *inc_buff;
uint32_t buff_size;
float next;
@@ -46,14 +47,16 @@
typedef _tEnvelope* tEnvelope;
- void tEnvelope_init (tEnvelope* const, float attack, float decay, oBool loop);
- void tEnvelope_free (tEnvelope* const);
+ void tEnvelope_init (tEnvelope* const, float attack, float decay, oBool loop);
+ void tEnvelope_free (tEnvelope* const);
+ void tEnvelope_initToPool (tEnvelope* const, float attack, float decay, oBool loop, tMempool* const);
+ void tEnvelope_freeFromPool (tEnvelope* const, tMempool* const);
- float tEnvelope_tick (tEnvelope* const);
- void tEnvelope_setAttack (tEnvelope* const, float attack);
- void tEnvelope_setDecay (tEnvelope* const, float decay);
- void tEnvelope_loop (tEnvelope* const, oBool loop);
- void tEnvelope_on (tEnvelope* const, float velocity);
+ float tEnvelope_tick (tEnvelope* const);
+ void tEnvelope_setAttack (tEnvelope* const, float attack);
+ void tEnvelope_setDecay (tEnvelope* const, float decay);
+ void tEnvelope_loop (tEnvelope* const, oBool loop);
+ void tEnvelope_on (tEnvelope* const, float velocity);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -60,8 +63,8 @@
/* ADSR */
typedef struct _tADSR
{
- const float *exp_buff;
- const float *inc_buff;
+ const float *exp_buff;
+ const float *inc_buff;
uint32_t buff_size;
float next;
@@ -78,16 +81,18 @@
typedef _tADSR* tADSR;
- void tADSR_init (tADSR* const, float attack, float decay, float sustain, float release);
- void tADSR_free (tADSR* const);
+ void tADSR_init (tADSR* const, float attack, float decay, float sustain, float release);
+ void tADSR_free (tADSR* const);
+ void tADSR_initToPool (tADSR* const, float attack, float decay, float sustain, float release, tMempool* const);
+ void tADSR_freeFromPool (tADSR* const, tMempool* const);
- float tADSR_tick (tADSR* const);
- void tADSR_setAttack (tADSR* const, float attack);
- void tADSR_setDecay (tADSR* const, float decay);
- void tADSR_setSustain(tADSR* const, float sustain);
- void tADSR_setRelease(tADSR* const, float release);
- void tADSR_on (tADSR* const, float velocity);
- void tADSR_off (tADSR* const);
+ float tADSR_tick (tADSR* const);
+ void tADSR_setAttack (tADSR* const, float attack);
+ void tADSR_setDecay (tADSR* const, float decay);
+ void tADSR_setSustain (tADSR* const, float sustain);
+ void tADSR_setRelease (tADSR* const, float release);
+ void tADSR_on (tADSR* const, float velocity);
+ void tADSR_off (tADSR* const);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -106,14 +111,16 @@
typedef _tRamp* tRamp;
- void tRamp_init (tRamp* const, float time, int samplesPerTick);
- void tRamp_free (tRamp* const);
+ void tRamp_init (tRamp* const, float time, int samplesPerTick);
+ void tRamp_free (tRamp* const);
+ void tRamp_initToPool (tRamp* const, float time, int samplesPerTick, tMempool* const);
+ void tRamp_freeFromPool (tRamp* const, tMempool* const);
- float tRamp_tick (tRamp* const);
- float tRamp_sample (tRamp* const);
- void tRamp_setTime (tRamp* const, float time);
- void tRamp_setDest (tRamp* const, float dest);
- void tRamp_setVal (tRamp* const, float val);
+ float tRamp_tick (tRamp* const);
+ float tRamp_sample (tRamp* const);
+ void tRamp_setTime (tRamp* const, float time);
+ void tRamp_setDest (tRamp* const, float dest);
+ void tRamp_setVal (tRamp* const, float val);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -126,14 +133,16 @@
typedef _tExpSmooth* tExpSmooth;
- void tExpSmooth_init (tExpSmooth* const, float val, float factor);
- void tExpSmooth_free (tExpSmooth* const);
+ void tExpSmooth_init (tExpSmooth* const, float val, float factor);
+ void tExpSmooth_free (tExpSmooth* const);
+ void tExpSmooth_initToPool (tExpSmooth* const, float val, float factor, tMempool* const);
+ void tExpSmooth_freeFromPool (tExpSmooth* const, tMempool* const);
- float tExpSmooth_tick (tExpSmooth* const);
- float tExpSmooth_sample (tExpSmooth* const);
- void tExpSmooth_setFactor (tExpSmooth* const, float factor);
- void tExpSmooth_setDest (tExpSmooth* const, float dest);
- void tExpSmooth_setVal (tExpSmooth* const, float val);
+ float tExpSmooth_tick (tExpSmooth* const);
+ float tExpSmooth_sample (tExpSmooth* const);
+ void tExpSmooth_setFactor (tExpSmooth* const, float factor);
+ void tExpSmooth_setDest (tExpSmooth* const, float dest);
+ void tExpSmooth_setVal (tExpSmooth* const, float val);
#ifdef __cplusplus
}
--- a/LEAF/Inc/leaf-filters.h
+++ b/LEAF/Inc/leaf-filters.h
@@ -16,6 +16,7 @@
//==============================================================================
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-delay.h"
#include "leaf-tables.h"
@@ -34,12 +35,14 @@
typedef _tAllpass* tAllpass;
- void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
- void tAllpass_free (tAllpass* const);
+ void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
+ void tAllpass_free (tAllpass* const);
+ void tAllpass_initToPool (tAllpass* const, float initDelay, uint32_t maxDelay, tMempool* const);
+ void tAllpass_freeFromPool (tAllpass* const, tMempool* const);
- float tAllpass_tick (tAllpass* const, float input);
- void tAllpass_setGain (tAllpass* const, float gain);
- void tAllpass_setDelay (tAllpass* const f, float delay);
+ float tAllpass_tick (tAllpass* const, float input);
+ void tAllpass_setGain (tAllpass* const, float gain);
+ void tAllpass_setDelay (tAllpass* const, float delay);
//==============================================================================
@@ -57,16 +60,18 @@
typedef _tOnePole* tOnePole;
- void tOnePole_init (tOnePole* const, float thePole);
- void tOnePole_free (tOnePole* const);
+ void tOnePole_init (tOnePole* const, float thePole);
+ void tOnePole_free (tOnePole* const);
+ void tOnePole_initToPool (tOnePole* const, float thePole, tMempool* const);
+ void tOnePole_freeFromPool (tOnePole* const, tMempool* const);
- float tOnePole_tick (tOnePole* const, float input);
- void tOnePole_setB0 (tOnePole* const, float b0);
- void tOnePole_setA1 (tOnePole* const, float a1);
- void tOnePole_setPole (tOnePole* const, float thePole);
- void tOnePole_setFreq (tOnePole* const, float freq);
- void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
- void tOnePole_setGain (tOnePole* const, float gain);
+ float tOnePole_tick (tOnePole* const, float input);
+ void tOnePole_setB0 (tOnePole* const, float b0);
+ void tOnePole_setA1 (tOnePole* const, float a1);
+ void tOnePole_setPole (tOnePole* const, float thePole);
+ void tOnePole_setFreq (tOnePole* const, float freq);
+ void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
+ void tOnePole_setGain (tOnePole* const, float gain);
//==============================================================================
@@ -86,16 +91,18 @@
typedef _tTwoPole* tTwoPole;
- void tTwoPole_init (tTwoPole* const);
- void tTwoPole_free (tTwoPole* const);
+ void tTwoPole_init (tTwoPole* const);
+ void tTwoPole_free (tTwoPole* const);
+ void tTwoPole_initToPool (tTwoPole* const, tMempool* const);
+ void tTwoPole_freeFromPool (tTwoPole* const, tMempool* const);
- float tTwoPole_tick (tTwoPole* const, float input);
- void tTwoPole_setB0 (tTwoPole* const, float b0);
- void tTwoPole_setA1 (tTwoPole* const, float a1);
- void tTwoPole_setA2 (tTwoPole* const, float a2);
- void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, oBool normalize);
- void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
- void tTwoPole_setGain (tTwoPole* const, float gain);
+ float tTwoPole_tick (tTwoPole* const, float input);
+ void tTwoPole_setB0 (tTwoPole* const, float b0);
+ void tTwoPole_setA1 (tTwoPole* const, float a1);
+ void tTwoPole_setA2 (tTwoPole* const, float a2);
+ void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, oBool normalize);
+ void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
+ void tTwoPole_setGain (tTwoPole* const, float gain);
//==============================================================================
@@ -110,16 +117,19 @@
typedef _tOneZero* tOneZero;
- void tOneZero_init (tOneZero* const, float theZero);
- void tOneZero_free (tOneZero* const);
- float tOneZero_tick (tOneZero* const, float input);
- void tOneZero_setB0 (tOneZero* const, float b0);
- void tOneZero_setB1 (tOneZero* const, float b1);
- void tOneZero_setZero (tOneZero* const, float theZero);
- void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
- void tOneZero_setGain (tOneZero* const, float gain);
- float tOneZero_getPhaseDelay(tOneZero *f, float frequency );
+ void tOneZero_init (tOneZero* const, float theZero);
+ void tOneZero_free (tOneZero* const);
+ void tOneZero_initToPool (tOneZero* const, float theZero, tMempool* const);
+ void tOneZero_freeFromPool (tOneZero* const, tMempool* const);
+ float tOneZero_tick (tOneZero* const, float input);
+ void tOneZero_setB0 (tOneZero* const, float b0);
+ void tOneZero_setB1 (tOneZero* const, float b1);
+ void tOneZero_setZero (tOneZero* const, float theZero);
+ void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
+ void tOneZero_setGain (tOneZero* const, float gain);
+ float tOneZero_getPhaseDelay (tOneZero *f, float frequency );
+
//==============================================================================
/* TwoZero filter, reimplemented from STK (Cook and Scavone). */
@@ -136,16 +146,18 @@
typedef _tTwoZero* tTwoZero;
- void tTwoZero_init (tTwoZero* const);
- void tTwoZero_free (tTwoZero* const);
+ void tTwoZero_init (tTwoZero* const);
+ void tTwoZero_free (tTwoZero* const);
+ void tTwoZero_initToPool (tTwoZero* const, tMempool* const);
+ void tTwoZero_freeFromPool (tTwoZero* const, tMempool* const);
- float tTwoZero_tick (tTwoZero* const, float input);
- void tTwoZero_setB0 (tTwoZero* const, float b0);
- void tTwoZero_setB1 (tTwoZero* const, float b1);
- void tTwoZero_setB2 (tTwoZero* const, float b2);
- void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
- void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
- void tTwoZero_setGain (tTwoZero* const, float gain);
+ float tTwoZero_tick (tTwoZero* const, float input);
+ void tTwoZero_setB0 (tTwoZero* const, float b0);
+ void tTwoZero_setB1 (tTwoZero* const, float b1);
+ void tTwoZero_setB2 (tTwoZero* const, float b2);
+ void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
+ void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
+ void tTwoZero_setGain (tTwoZero* const, float gain);
//==============================================================================
@@ -162,17 +174,19 @@
typedef _tPoleZero* tPoleZero;
- void tPoleZero_init (tPoleZero* const);
- void tPoleZero_free (tPoleZero* const);
+ void tPoleZero_init (tPoleZero* const);
+ void tPoleZero_free (tPoleZero* const);
+ void tPoleZero_initToPool (tPoleZero* const, tMempool* const);
+ void tPoleZero_freeFromPool (tPoleZero* const, tMempool* const);
- float tPoleZero_tick (tPoleZero* const, float input);
- void tPoleZero_setB0 (tPoleZero* const, float b0);
- void tPoleZero_setB1 (tPoleZero* const, float b1);
- void tPoleZero_setA1 (tPoleZero* const, float a1);
- void tPoleZero_setCoefficients (tPoleZero* const, float b0, float b1, float a1);
- void tPoleZero_setAllpass (tPoleZero* const, float coeff);
- void tPoleZero_setBlockZero (tPoleZero* const, float thePole);
- void tPoleZero_setGain (tPoleZero* const, float gain);
+ float tPoleZero_tick (tPoleZero* const, float input);
+ void tPoleZero_setB0 (tPoleZero* const, float b0);
+ void tPoleZero_setB1 (tPoleZero* const, float b1);
+ void tPoleZero_setA1 (tPoleZero* const, float a1);
+ void tPoleZero_setCoefficients (tPoleZero* const, float b0, float b1, float a1);
+ void tPoleZero_setAllpass (tPoleZero* const, float coeff);
+ void tPoleZero_setBlockZero (tPoleZero* const, float thePole);
+ void tPoleZero_setGain (tPoleZero* const, float gain);
//==============================================================================
@@ -192,19 +206,21 @@
typedef _tBiQuad* tBiQuad;
- void tBiQuad_init (tBiQuad* const);
- void tBiQuad_free (tBiQuad* const);
+ void tBiQuad_init (tBiQuad* const);
+ void tBiQuad_free (tBiQuad* const);
+ void tBiQuad_initToPool (tBiQuad* const, tMempool* const);
+ void tBiQuad_freeFromPool (tBiQuad* const, tMempool* const);
- float tBiQuad_tick (tBiQuad* const, float input);
- void tBiQuad_setB0 (tBiQuad* const, float b0);
- void tBiQuad_setB1 (tBiQuad* const, float b1);
- void tBiQuad_setB2 (tBiQuad* const, float b2);
- void tBiQuad_setA1 (tBiQuad* const, float a1);
- void tBiQuad_setA2 (tBiQuad* const, float a2);
- void tBiQuad_setNotch (tBiQuad* const, float freq, float radius);
- void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, oBool normalize);
- void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
- void tBiQuad_setGain (tBiQuad* const, float gain);
+ float tBiQuad_tick (tBiQuad* const, float input);
+ void tBiQuad_setB0 (tBiQuad* const, float b0);
+ void tBiQuad_setB1 (tBiQuad* const, float b1);
+ void tBiQuad_setB2 (tBiQuad* const, float b2);
+ void tBiQuad_setA1 (tBiQuad* const, float a1);
+ void tBiQuad_setA2 (tBiQuad* const, float a2);
+ void tBiQuad_setNotch (tBiQuad* const, float freq, float radius);
+ void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, oBool normalize);
+ void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
+ void tBiQuad_setGain (tBiQuad* const, float gain);
//==============================================================================
@@ -229,12 +245,14 @@
typedef _tSVF* tSVF;
- void tSVF_init (tSVF* const, SVFType type, float freq, float Q);
- void tSVF_free (tSVF* const);
+ void tSVF_init (tSVF* const, SVFType type, float freq, float Q);
+ void tSVF_free (tSVF* const);
+ void tSVF_initToPool (tSVF* const, SVFType type, float freq, float Q, tMempool* const);
+ void tSVF_freeFromPool (tSVF* const, tMempool* const);
- float tSVF_tick (tSVF* const, float v0);
- void tSVF_setFreq (tSVF* const, float freq);
- void tSVF_setQ (tSVF* const, float Q);
+ float tSVF_tick (tSVF* const, float v0);
+ void tSVF_setFreq (tSVF* const, float freq);
+ void tSVF_setQ (tSVF* const, float Q);
//==============================================================================
@@ -250,12 +268,14 @@
typedef _tEfficientSVF* tEfficientSVF;
- void tEfficientSVF_init (tEfficientSVF* const, SVFType type, uint16_t controlFreq, float Q);
- void tEfficientSVF_free (tEfficientSVF* const);
+ void tEfficientSVF_init (tEfficientSVF* const, SVFType type, uint16_t input, float Q);
+ void tEfficientSVF_free (tEfficientSVF* const);
+ void tEfficientSVF_initToPool (tEfficientSVF* const, SVFType type, uint16_t input, float Q, tMempool* const);
+ void tEfficientSVF_freeFromPool (tEfficientSVF* const, tMempool* const);
- float tEfficientSVF_tick (tEfficientSVF* const, float v0);
- void tEfficientSVF_setFreq (tEfficientSVF* const, uint16_t controlFreq);
- void tEfficientSVF_setQ (tEfficientSVF* const, float Q);
+ float tEfficientSVF_tick (tEfficientSVF* const, float v0);
+ void tEfficientSVF_setFreq (tEfficientSVF* const, uint16_t controlFreq);
+ void tEfficientSVF_setQ (tEfficientSVF* const, float Q);
//==============================================================================
@@ -269,12 +289,14 @@
typedef _tHighpass* tHighpass;
- void tHighpass_init (tHighpass* const, float freq);
- void tHighpass_free (tHighpass* const);
+ void tHighpass_init (tHighpass* const, float freq);
+ void tHighpass_free (tHighpass* const);
+ void tHighpass_initToPool (tHighpass* const, float freq, tMempool* const);
+ void tHighpass_freeFromPool (tHighpass* const, tMempool* const);
- float tHighpass_tick (tHighpass* const, float x);
- void tHighpass_setFreq (tHighpass* const, float freq);
- float tHighpass_getFreq (tHighpass* const);
+ float tHighpass_tick (tHighpass* const, float x);
+ void tHighpass_setFreq (tHighpass* const, float freq);
+ float tHighpass_getFreq (tHighpass* const);
//==============================================================================
@@ -295,13 +317,15 @@
typedef _tButterworth* tButterworth;
- void tButterworth_init (tButterworth* const, int N, float f1, float f2);
- void tButterworth_free (tButterworth* const);
+ void tButterworth_init (tButterworth* const, int N, float f1, float f2);
+ void tButterworth_free (tButterworth* const);
+ void tButterworth_initToPool (tButterworth* const, int N, float f1, float f2, tMempool* const);
+ void tButterworth_freeFromPool (tButterworth* const, tMempool* const);
- float tButterworth_tick (tButterworth* const, float input);
- void tButterworth_setF1 (tButterworth* const, float in);
- void tButterworth_setF2 (tButterworth* const, float in);
- void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
+ float tButterworth_tick (tButterworth* const, float input);
+ void tButterworth_setF1 (tButterworth* const, float in);
+ void tButterworth_setF2 (tButterworth* const, float in);
+ void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
//==============================================================================
@@ -310,16 +334,17 @@
float* past;
float* coeff;
int numTaps;
-
} _tFIR;
typedef _tFIR* tFIR;
- void tFIR_init (tFIR* const, float* coeffs, int numTaps);
- void tFIR_free (tFIR* const);
+ void tFIR_init (tFIR* const, float* coeffs, int numTaps);
+ void tFIR_free (tFIR* const);
+ void tFIR_initToPool (tFIR* const, float* coeffs, int numTaps, tMempool* const);
+ void tFIR_freeFromPool (tFIR* const, tMempool* const);
- float tFIR_tick (tFIR* const, float input);
- void tFIR_coeffs (tFIR* const, float in);
+ float tFIR_tick (tFIR* const, float input);
+ void tFIR_coeffs (tFIR* const, float in);
//==============================================================================
--- a/LEAF/Inc/leaf-global.h
+++ b/LEAF/Inc/leaf-global.h
@@ -1,13 +1,13 @@
/*
- ==============================================================================
+ ==============================================================================
+
+ leaf-global.h
+ Created: 24 Oct 2019 2:24:38pm
+ Author: Matthew Wang
+
+ ==============================================================================
+ */
- leaf-global.h
- Created: 24 Oct 2019 2:24:38pm
- Author: Matthew Wang
-
- ==============================================================================
-*/
-
#ifndef LEAF_GLOBAL_H_INCLUDED
#define LEAF_GLOBAL_H_INCLUDED
@@ -14,18 +14,18 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-typedef struct _LEAF
-{
- float sampleRate;
- float invSampleRate;
- int blockSize;
- float twoPiTimesInvSampleRate;
- float (*random)(void);
-} LEAF;
-
-extern LEAF leaf; // The global instance of LEAF.
+ typedef struct _LEAF
+ {
+ float sampleRate;
+ float invSampleRate;
+ int blockSize;
+ float twoPiTimesInvSampleRate;
+ float (*random)(void);
+ } LEAF;
+
+ extern LEAF leaf; // The global instance of LEAF.
+
//==============================================================================
#ifdef __cplusplus
@@ -35,3 +35,4 @@
#endif // LEAF_GLOBAL_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-instruments.h
+++ b/LEAF/Inc/leaf-instruments.h
@@ -42,17 +42,20 @@
typedef _t808Cowbell* t808Cowbell;
- void t808Cowbell_init (t808Cowbell* const, int useStick);
- void t808Cowbell_free (t808Cowbell* const);
- float t808Cowbell_tick (t808Cowbell* const);
- void t808Cowbell_on (t808Cowbell* const, float vel);
- void t808Cowbell_setDecay (t808Cowbell* const, float decay);
- void t808Cowbell_setHighpassFreq (t808Cowbell* const, float freq);
- void t808Cowbell_setBandpassFreq (t808Cowbell* const, float freq);
- void t808Cowbell_setFreq (t808Cowbell* const, float freq);
- void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
- void t808Cowbell_setStick (t808Cowbell* const, int useStick);
+ void t808Cowbell_init (t808Cowbell* const, int useStick);
+ void t808Cowbell_free (t808Cowbell* const);
+ void t808Cowbell_initToPool (t808Cowbell* const, int useStick, tMempool* const);
+ void t808Cowbell_freeFromPool (t808Cowbell* const, tMempool* const);
+ float t808Cowbell_tick (t808Cowbell* const);
+ void t808Cowbell_on (t808Cowbell* const, float vel);
+ void t808Cowbell_setDecay (t808Cowbell* const, float decay);
+ void t808Cowbell_setHighpassFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setBandpassFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
+ void t808Cowbell_setStick (t808Cowbell* const, int useStick);
+
//==============================================================================
// 808 Hihat
@@ -78,21 +81,23 @@
typedef _t808Hihat* t808Hihat;
- void t808Hihat_init (t808Hihat* const);
- void t808Hihat_free (t808Hihat* const);
+ void t808Hihat_init (t808Hihat* const);
+ void t808Hihat_free (t808Hihat* const);
+ void t808Hihat_initToPool (t808Hihat* const, tMempool* const);
+ void t808Hihat_freeFromPool (t808Hihat* const, tMempool* const);
- float t808Hihat_tick (t808Hihat* const);
- void t808Hihat_on (t808Hihat* const, float vel);
- void t808Hihat_setOscNoiseMix (t808Hihat* const, float oscNoiseMix);
- void t808Hihat_setDecay (t808Hihat* const, float decay);
- void t808Hihat_setHighpassFreq (t808Hihat* const, float freq);
- void t808Hihat_setOscBandpassFreq (t808Hihat* const, float freq);
- void t808Hihat_setOscBandpassQ (t808Hihat* const hihat, float Q);
- void t808Hihat_setStickBandPassFreq (t808Hihat* const, float freq);
- void t808Hihat_setStickBandPassQ (t808Hihat* const hihat, float Q);
- void t808Hihat_setOscFreq (t808Hihat* const, float freq);
- void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
- void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
+ float t808Hihat_tick (t808Hihat* const);
+ void t808Hihat_on (t808Hihat* const, float vel);
+ void t808Hihat_setOscNoiseMix (t808Hihat* const, float oscNoiseMix);
+ void t808Hihat_setDecay (t808Hihat* const, float decay);
+ void t808Hihat_setHighpassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setOscBandpassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setOscBandpassQ (t808Hihat* const hihat, float Q);
+ void t808Hihat_setStickBandPassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setStickBandPassQ (t808Hihat* const hihat, float Q);
+ void t808Hihat_setOscFreq (t808Hihat* const, float freq);
+ void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
+ void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
//==============================================================================
@@ -123,19 +128,21 @@
typedef _t808Snare* t808Snare;
- void t808Snare_init (t808Snare* const);
- void t808Snare_free (t808Snare* const);
+ void t808Snare_init (t808Snare* const);
+ void t808Snare_free (t808Snare* const);
+ void t808Snare_initToPool (t808Snare* const, tMempool* const);
+ void t808Snare_freeFromPool (t808Snare* const, tMempool* const);
- float t808Snare_tick (t808Snare* const);
- void t808Snare_on (t808Snare* const, float vel);
- void t808Snare_setTone1Freq (t808Snare* const, float freq);
- void t808Snare_setTone2Freq (t808Snare* const, float freq);
- void t808Snare_setTone1Decay (t808Snare* const, float decay);
- void t808Snare_setTone2Decay (t808Snare* const, float decay);
- void t808Snare_setNoiseDecay (t808Snare* const, float decay);
- void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
- void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
- void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
+ float t808Snare_tick (t808Snare* const);
+ void t808Snare_on (t808Snare* const, float vel);
+ void t808Snare_setTone1Freq (t808Snare* const, float freq);
+ void t808Snare_setTone2Freq (t808Snare* const, float freq);
+ void t808Snare_setTone1Decay (t808Snare* const, float decay);
+ void t808Snare_setTone2Decay (t808Snare* const, float decay);
+ void t808Snare_setNoiseDecay (t808Snare* const, float decay);
+ void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
+ void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
+ void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
//==============================================================================
@@ -164,19 +171,21 @@
typedef _t808Kick* t808Kick;
- void t808Kick_init (t808Kick* const);
- void t808Kick_free (t808Kick* const);
+ void t808Kick_init (t808Kick* const);
+ void t808Kick_free (t808Kick* const);
+ void t808Kick_initToPool (t808Kick* const, tMempool* const);
+ void t808Kick_freeFromPool (t808Kick* const, tMempool* const);
- float t808Kick_tick (t808Kick* const);
- void t808Kick_on (t808Kick* const, float vel);
- void t808Kick_setToneFreq (t808Kick* const, float freq);
- void t808Kick_setToneDecay (t808Kick* const, float decay);
- void t808Kick_setNoiseDecay (t808Kick* const, float decay);
- void t808Kick_setSighAmount (t808Kick* const, float sigh);
- void t808Kick_setChirpAmount (t808Kick* const, float chirp);
- void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
- void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
- void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
+ float t808Kick_tick (t808Kick* const);
+ void t808Kick_on (t808Kick* const, float vel);
+ void t808Kick_setToneFreq (t808Kick* const, float freq);
+ void t808Kick_setToneDecay (t808Kick* const, float decay);
+ void t808Kick_setNoiseDecay (t808Kick* const, float decay);
+ void t808Kick_setSighAmount (t808Kick* const, float sigh);
+ void t808Kick_setChirpAmount (t808Kick* const, float chirp);
+ void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
+ void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
+ void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
//==============================================================================
--- a/LEAF/Inc/leaf-mempool.h
+++ b/LEAF/Inc/leaf-mempool.h
@@ -1,38 +1,38 @@
/*==============================================================================
- In short, mpool is distributed under so called "BSD license",
-
- Copyright (c) 2009-2010 Tatsuhiko Kubo <cubicdaiya@gmail.com>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- * Neither the name of the authors nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ In short, mpool is distributed under so called "BSD license",
+
+ Copyright (c) 2009-2010 Tatsuhiko Kubo <cubicdaiya@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
- written by C99 style
-==============================================================================*/
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of the authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ written by C99 style
+ ==============================================================================*/
#ifndef LEAF_MPOOL_H_INCLUDED
#define LEAF_MPOOL_H_INCLUDED
@@ -41,60 +41,76 @@
extern "C" {
#endif
-//==============================================================================
-
+ //==============================================================================
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
-//==============================================================================
-
+ //==============================================================================
+
#define MPOOL_ALIGN_SIZE (8)
-
-//#define size_t unsigned long
-
-/**
- * memory pool structure
- */
-
-// node of free list
-typedef struct mpool_node_t {
- void *pool; // memory pool field
- struct mpool_node_t *next; // next node pointer
- struct mpool_node_t *prev; // prev node pointer
- size_t size;
-} mpool_node_t;
-
-typedef struct mpool_t {
- void* mpool; // start of the mpool
- size_t usize; // used size of the pool
- size_t msize; // max size of the pool
- mpool_node_t* head; // first node of memory pool free list
-} mpool_t;
-
-void mpool_create (char* memory, size_t size, mpool_t* pool);
-
-void *mpool_alloc(size_t size, mpool_t* pool);
-void mpool_free(void* ptr, mpool_t* pool);
-
-size_t mpool_get_size(mpool_t* pool);
-size_t mpool_get_used(mpool_t* pool);
-
-void leaf_pool_init(char* memory, size_t size);
-
-void* leaf_alloc(size_t size);
-void leaf_free(void* ptr);
-
-size_t leaf_pool_get_size(void);
-size_t leaf_pool_get_used(void);
-
-void* leaf_pool_get_pool(void);
-
-void leaf_mempool_overrun(void);
-//==============================================================================
-
+ //#define size_t unsigned long
+
+ /**
+ * memory pool structure
+ */
+
+ // node of free list
+ typedef struct mpool_node_t {
+ void *pool; // memory pool field
+ struct mpool_node_t *next; // next node pointer
+ struct mpool_node_t *prev; // prev node pointer
+ size_t size;
+ } mpool_node_t;
+
+ typedef struct mpool_t {
+ void* mpool; // start of the mpool
+ size_t usize; // used size of the pool
+ size_t msize; // max size of the pool
+ mpool_node_t* head; // first node of memory pool free list
+ } mpool_t;
+
+ void mpool_create (char* memory, size_t size, mpool_t* pool);
+
+ void* mpool_alloc(size_t size, mpool_t* pool);
+ void* mpool_allocAndClear(size_t asize, mpool_t* pool);
+ void mpool_free(void* ptr, mpool_t* pool);
+
+ size_t mpool_get_size(mpool_t* pool);
+ size_t mpool_get_used(mpool_t* pool);
+
+ void leaf_pool_init(char* memory, size_t size);
+
+ void* leaf_alloc(size_t size);
+ void* leaf_allocAndClear(size_t size);
+ void leaf_free(void* ptr);
+
+ size_t leaf_pool_get_size(void);
+ size_t leaf_pool_get_used(void);
+
+ void* leaf_pool_get_pool(void);
+
+ void leaf_mempool_overrun(void);
+
+ // User object for creating additional mempools
+
+ typedef struct _tMempool
+ {
+ mpool_t* pool;
+ } _tMempool;
+
+ typedef _tMempool* tMempool;
+
+ void tMempool_init (tMempool* const, char* memory, size_t size);
+ void tMempool_free (tMempool* const);
+ void tMempool_initToPool (tMempool* const, char* memory, size_t size, tMempool* const);
+ void tMempool_freeFromPool (tMempool* const, tMempool* const);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -102,5 +118,6 @@
#endif // LEAF_MPOOL_H
//==============================================================================
+
--- a/LEAF/Inc/leaf-midi.h
+++ b/LEAF/Inc/leaf-midi.h
@@ -40,6 +40,8 @@
void tStack_init (tStack* const);
void tStack_free (tStack* const);
+ void tStack_initToPool (tStack* const, tMempool* const);
+ void tStack_freeFromPool (tStack* const, tMempool* const);
void tStack_setCapacity (tStack* const, uint16_t cap);
int tStack_addIfNotAlreadyThere (tStack* const, uint16_t item);
@@ -91,28 +93,30 @@
typedef _tPoly* tPoly;
/* MPoly*/
- void tPoly_init(tPoly* const, int maxNumVoices);
- void tPoly_free(tPoly* const);
+ void tPoly_init (tPoly* const, int maxNumVoices);
+ void tPoly_free (tPoly* const);
+ void tPoly_initToPool (tPoly* const, int maxNumVoices, tMempool* const);
+ void tPoly_freeFromPool (tPoly* const, tMempool* const);
//ADDING A NOTE
- int tPoly_noteOn(tPoly* const, int note, uint8_t vel);
- int tPoly_noteOff(tPoly* const, uint8_t note);
- void tPoly_orderedAddToStack(tPoly* const, uint8_t noteVal);
- void tPoly_setNumVoices(tPoly* const, uint8_t numVoices);
+ int tPoly_noteOn (tPoly* const, int note, uint8_t vel);
+ int tPoly_noteOff (tPoly* const, uint8_t note);
+ void tPoly_orderedAddToStack (tPoly* const, uint8_t noteVal);
+ void tPoly_setNumVoices (tPoly* const, uint8_t numVoices);
- void tPoly_setPitchBend(tPoly* const, float pitchBend);
- void tPoly_setPitchGlideActive(tPoly* const, oBool isActive);
- void tPoly_setPitchGlideTime(tPoly* const, float t);
- void tPoly_tickPitch(tPoly* const);
- void tPoly_tickPitchGlide(tPoly* const);
- void tPoly_tickPitchBend(tPoly* const);
+ void tPoly_setPitchBend (tPoly* const, float pitchBend);
+ void tPoly_setPitchGlideActive (tPoly* const, oBool isActive);
+ void tPoly_setPitchGlideTime (tPoly* const, float t);
+ void tPoly_tickPitch (tPoly* const);
+ void tPoly_tickPitchGlide (tPoly* const);
+ void tPoly_tickPitchBend (tPoly* const);
- int tPoly_getNumVoices(tPoly* const);
- int tPoly_getNumActiveVoices(tPoly* const);
- float tPoly_getPitch(tPoly* const, uint8_t voice);
- int tPoly_getKey(tPoly* const, uint8_t voice);
- int tPoly_getVelocity(tPoly* const, uint8_t voice);
- int tPoly_isOn(tPoly* const, uint8_t voice);
+ int tPoly_getNumVoices (tPoly* const);
+ int tPoly_getNumActiveVoices (tPoly* const);
+ float tPoly_getPitch (tPoly* const, uint8_t voice);
+ int tPoly_getKey (tPoly* const, uint8_t voice);
+ int tPoly_getVelocity (tPoly* const, uint8_t voice);
+ int tPoly_isOn (tPoly* const, uint8_t voice);
//==============================================================================
--- a/LEAF/Inc/leaf-oscillators.h
+++ b/LEAF/Inc/leaf-oscillators.h
@@ -14,6 +14,7 @@
//==============================================================================
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-filters.h"
//==============================================================================
@@ -25,14 +26,18 @@
float phase;
float inc,freq;
- } tCycle;
+ } _tCycle;
- void tCycle_init (tCycle* const);
- void tCycle_free (tCycle* const);
+ typedef _tCycle* tCycle;
- float tCycle_tick (tCycle* const);
- int tCycle_setFreq (tCycle* const, float freq);
+ void tCycle_init (tCycle* const);
+ void tCycle_free (tCycle* const);
+ void tCycle_initToPool (tCycle* const, tMempool* const);
+ void tCycle_freeFromPool (tCycle* const, tMempool* const);
+ float tCycle_tick (tCycle* const);
+ int tCycle_setFreq (tCycle* const, float freq);
+
//==============================================================================
/* tTriangle: Anti-aliased Triangle waveform using wavetable interpolation. Wavetables constructed from sine components. */
@@ -42,14 +47,18 @@
float phase;
float inc,freq;
- } tTriangle;
+ } _tTriangle;
- void tTriangle_init (tTriangle* const);
- void tTriangle_free (tTriangle* const);
+ typedef _tTriangle* tTriangle;
- float tTriangle_tick (tTriangle* const);
- int tTriangle_setFreq (tTriangle* const, float freq);
+ void tTriangle_init (tTriangle* const);
+ void tTriangle_free (tTriangle* const);
+ void tTriangle_initToPool (tTriangle* const, tMempool* const);
+ void tTriangle_freeFromPool (tTriangle* const, tMempool* const);
+ float tTriangle_tick (tTriangle* const);
+ int tTriangle_setFreq (tTriangle* const, float freq);
+
//==============================================================================
/* tSquare: Anti-aliased Square waveform using wavetable interpolation. Wavetables constructed from sine components. */
@@ -59,14 +68,18 @@
float phase;
float inc,freq;
- } tSquare;
+ } _tSquare;
- void tSquare_init (tSquare* const);
- void tSquare_free (tSquare* const);
+ typedef _tSquare* tSquare;
- float tSquare_tick (tSquare* const);
- int tSquare_setFreq (tSquare* const, float freq);
+ void tSquare_init (tSquare* const);
+ void tSquare_free (tSquare* const);
+ void tSquare_initToPool (tSquare* const, tMempool* const);
+ void tSquare_freeFromPool(tSquare* const, tMempool* const);
+ float tSquare_tick (tSquare* const);
+ int tSquare_setFreq (tSquare* const, float freq);
+
//==============================================================================
/* tSawtooth: Anti-aliased Sawtooth waveform using wavetable interpolation. Wavetables constructed from sine components. */
@@ -76,14 +89,18 @@
float phase;
float inc,freq;
- } tSawtooth;
+ } _tSawtooth;
- void tSawtooth_init (tSawtooth* const);
- void tSawtooth_free (tSawtooth* const);
+ typedef _tSawtooth* tSawtooth;
- float tSawtooth_tick (tSawtooth* const);
- int tSawtooth_setFreq (tSawtooth* const, float freq);
+ void tSawtooth_init (tSawtooth* const);
+ void tSawtooth_free (tSawtooth* const);
+ void tSawtooth_initToPool (tSawtooth* const, tMempool* const);
+ void tSawtooth_freeFromPool (tSawtooth* const, tMempool* const);
+ float tSawtooth_tick (tSawtooth* const);
+ int tSawtooth_setFreq (tSawtooth* const, float freq);
+
//==============================================================================
/* tPhasor: Aliasing phasor [0.0, 1.0) */
@@ -92,14 +109,18 @@
float phase;
float inc,freq;
- } tPhasor;
+ } _tPhasor;
- void tPhasor_init (tPhasor* const);
- void tPhasor_free (tPhasor* const);
+ typedef _tPhasor* tPhasor;
- float tPhasor_tick (tPhasor* const);
- int tPhasor_setFreq (tPhasor* const, float freq);
+ void tPhasor_init (tPhasor* const);
+ void tPhasor_free (tPhasor* const);
+ void tPhasor_initToPool (tPhasor* const, tMempool* const);
+ void tPhasor_freeFromPool(tPhasor* const, tMempool* const);
+ float tPhasor_tick (tPhasor* const);
+ int tPhasor_setFreq (tPhasor* const, float freq);
+
//==============================================================================
/* tNoise. WhiteNoise, PinkNoise. */
@@ -116,13 +137,17 @@
float pinkb0, pinkb1, pinkb2;
float(*rand)(void);
- } tNoise;
+ } _tNoise;
- void tNoise_init (tNoise* const, NoiseType type);
- void tNoise_free (tNoise* const);
+ typedef _tNoise* tNoise;
- float tNoise_tick (tNoise* const);
+ void tNoise_init (tNoise* const, NoiseType type);
+ void tNoise_free (tNoise* const);
+ void tNoise_initToPool (tNoise* const, NoiseType type, tMempool* const);
+ void tNoise_freeFromPool (tNoise* const, tMempool* const);
+ float tNoise_tick (tNoise* const);
+
//==============================================================================
/* tNeuron */
@@ -149,24 +174,28 @@
float V[3];
float P[3];
float gK, gN, gL, C;
- } tNeuron;
+ } _tNeuron;
- void tNeuron_init (tNeuron* const);
- void tNeuron_free (tNeuron* const);
+ typedef _tNeuron* tNeuron;
- void tNeuron_reset (tNeuron* const);
- float tNeuron_Tick (tNeuron* const);
- void tNeuron_setMode (tNeuron* const, NeuronMode mode);
- void tNeuron_setCurrent (tNeuron* const, float current);
- void tNeuron_setK (tNeuron* const, float K);
- void tNeuron_setL (tNeuron* const, float L);
- void tNeuron_setN (tNeuron* const, float N);
- void tNeuron_setC (tNeuron* const, float C);
- void tNeuron_setV1 (tNeuron* const, float V1);
- void tNeuron_setV2 (tNeuron* const, float V2);
- void tNeuron_setV3 (tNeuron* const, float V3);
- void tNeuron_setTimeStep (tNeuron* const, float timestep);
+ void tNeuron_init (tNeuron* const);
+ void tNeuron_free (tNeuron* const);
+ void tNeuron_initToPool (tNeuron* const, tMempool* const);
+ void tNeuron_freeFromPool(tNeuron* const, tMempool* const);
+ void tNeuron_reset (tNeuron* const);
+ float tNeuron_tick (tNeuron* const);
+ void tNeuron_setMode (tNeuron* const, NeuronMode mode);
+ void tNeuron_setCurrent (tNeuron* const, float current);
+ void tNeuron_setK (tNeuron* const, float K);
+ void tNeuron_setL (tNeuron* const, float L);
+ void tNeuron_setN (tNeuron* const, float N);
+ void tNeuron_setC (tNeuron* const, float C);
+ void tNeuron_setV1 (tNeuron* const, float V1);
+ void tNeuron_setV2 (tNeuron* const, float V2);
+ void tNeuron_setV3 (tNeuron* const, float V3);
+ void tNeuron_setTimeStep (tNeuron* const, float timestep);
+
//==============================================================================
#ifdef __cplusplus
@@ -176,3 +205,4 @@
#endif // LEAF_OSCILLATORS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-physical.h
+++ b/LEAF/Inc/leaf-physical.h
@@ -19,6 +19,7 @@
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-delay.h"
#include "leaf-filters.h"
#include "leaf-oscillators.h"
@@ -45,28 +46,30 @@
typedef _tPluck* tPluck;
- void tPluck_init (tPluck* const, float lowestFrequency); //float delayBuff[DELAY_LENGTH]);
- void tPluck_free (tPluck* const);
+ void tPluck_init (tPluck* const, float lowestFrequency); //float delayBuff[DELAY_LENGTH]);
+ void tPluck_free (tPluck* const);
+ void tPluck_initToPool (tPluck* const, float lowestFrequency, tMempool* const);
+ void tPluck_freeFromPool (tPluck* const, tMempool* const);
- float tPluck_tick (tPluck* const);
+ float tPluck_tick (tPluck* const);
// Pluck the string.
- void tPluck_pluck (tPluck* const, float amplitude);
+ void tPluck_pluck (tPluck* const, float amplitude);
// Start a note with the given frequency and amplitude.;
- void tPluck_noteOn (tPluck* const, float frequency, float amplitude );
+ void tPluck_noteOn (tPluck* const, float frequency, float amplitude );
// Stop a note with the given amplitude (speed of decay).
- void tPluck_noteOff (tPluck* const, float amplitude );
+ void tPluck_noteOff (tPluck* const, float amplitude );
// Set instrument parameters for a particular frequency.
- void tPluck_setFrequency (tPluck* const, float frequency );
+ void tPluck_setFrequency (tPluck* const, float frequency );
// Perform the control change specified by \e number and \e value (0.0 - 128.0).
- void tPluck_controlChange (tPluck* const, int number, float value);
+ void tPluck_controlChange (tPluck* const, int number, float value);
// tPluck Utilities.
- float tPluck_getLastOut (tPluck* const);
+ float tPluck_getLastOut (tPluck* const);
//==============================================================================
@@ -102,38 +105,40 @@
typedef _tKarplusStrong* tKarplusStrong;
- void tKarplusStrong_init (tKarplusStrong* const, float lowestFrequency); // float delayBuff[2][DELAY_LENGTH]);
- void tKarplusStrong_free (tKarplusStrong* const);
+ void tKarplusStrong_init (tKarplusStrong* const, float lowestFrequency); // float delayBuff[2][DELAY_LENGTH]);
+ void tKarplusStrong_free (tKarplusStrong* const);
+ void tKarplusStrong_initToPool (tKarplusStrong* const, float lowestFrequency, tMempool* const);
+ void tKarplusStrong_freeFromPool (tKarplusStrong* const, tMempool* const);
- float tKarplusStrong_tick (tKarplusStrong* const);
+ float tKarplusStrong_tick (tKarplusStrong* const);
// Pluck the string.
- void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude);
+ void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude);
// Start a note with the given frequency and amplitude.;
- void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude );
+ void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude );
// Stop a note with the given amplitude (speed of decay).
- void tKarplusStrong_noteOff (tKarplusStrong* const, float amplitude );
+ void tKarplusStrong_noteOff (tKarplusStrong* const, float amplitude );
// Set instrument parameters for a particular frequency.
- void tKarplusStrong_setFrequency (tKarplusStrong* const, float frequency );
+ void tKarplusStrong_setFrequency (tKarplusStrong* const, float frequency );
// Perform the control change specified by \e number and \e value (0.0 - 128.0).
// Use SKPickPosition, SKStringDamping, or SKDetune for type.
- void tKarplusStrong_controlChange (tKarplusStrong* const, SKControlType type, float value);
+ void tKarplusStrong_controlChange (tKarplusStrong* const, SKControlType type, float value);
// Set the stretch "factor" of the string (0.0 - 1.0).
- void tKarplusStrong_setStretch (tKarplusStrong* const, float stretch );
+ void tKarplusStrong_setStretch (tKarplusStrong* const, float stretch );
// Set the pluck or "excitation" position along the string (0.0 - 1.0).
- void tKarplusStrong_setPickupPosition (tKarplusStrong* const, float position );
+ void tKarplusStrong_setPickupPosition (tKarplusStrong* const, float position );
// Set the base loop gain.
- void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const, float aGain );
+ void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const, float aGain );
// tKarplusStrong utilities.
- float tKarplusStrong_getLastOut (tKarplusStrong* const);
+ float tKarplusStrong_getLastOut (tKarplusStrong* const);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -153,18 +158,25 @@
typedef _tSimpleLivingString* tSimpleLivingString;
- void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode);
- void tSimpleLivingString_free (tSimpleLivingString* const);
- float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
- float tSimpleLivingString_sample (tSimpleLivingString* const);
- void tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
- void tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
- void tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
- void tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
+ void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq,
+ float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode);
+ void tSimpleLivingString_free (tSimpleLivingString* const);
+ void tSimpleLivingString_initToPool (tSimpleLivingString* const, float freq, float dampFreq,
+ float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode, tMempool* const);
+ void tSimpleLivingString_freeFromPool (tSimpleLivingString* const, tMempool* const);
+
+ float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
+ float tSimpleLivingString_sample (tSimpleLivingString* const);
+ void tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
+ void tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
+ void tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
+ void tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
void tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
- void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
- void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
+ void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
+ void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -186,19 +198,25 @@
typedef _tLivingString* tLivingString;
- void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex, float dampFreq, float decay,
- float targetLev, float levSmoothFactor, float levStrength, int levMode);
- void tLivingString_free (tLivingString* const);
- float tLivingString_tick (tLivingString* const, float input);
- float tLivingString_sample (tLivingString* const);
+ void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex,
+ float dampFreq, float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode);
+ void tLivingString_free (tLivingString* const);
+ void tLivingString_initToPool (tLivingString* const, float freq, float pickPos, float prepIndex,
+ float dampFreq, float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode, tMempool* const);
+ void tLivingString_freeFromPool (tLivingString* const, tMempool* const);
+
+ float tLivingString_tick (tLivingString* const, float input);
+ float tLivingString_sample (tLivingString* const);
void tLivingString_setFreq (tLivingString* const, float freq);
- void tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
- void tLivingString_setPickPos (tLivingString* const, float pickPos);
- void tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
+ void tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
+ void tLivingString_setPickPos (tLivingString* const, float pickPos);
+ void tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
void tLivingString_setDampFreq (tLivingString* const, float dampFreq);
- void tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
- void tLivingString_setTargetLev (tLivingString* const, float targetLev);
- void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
+ void tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
+ void tLivingString_setTargetLev (tLivingString* const, float targetLev);
+ void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
void tLivingString_setLevStrength (tLivingString* const, float levStrength);
void tLivingString_setLevMode (tLivingString* const, int levMode);
@@ -211,12 +229,15 @@
typedef _tReedTable* tReedTable;
- void tReedTable_init (tReedTable* const, float offset, float slope);
- void tReedTable_free (tReedTable* const);
- float tReedTable_tick (tReedTable* const, float input);
- float tReedTable_tanh_tick (tReedTable* const p, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
- void tReedTable_setOffset (tReedTable* const, float offset);
- void tReedTable_setSlope (tReedTable* const, float slope);
+ void tReedTable_init (tReedTable* const, float offset, float slope);
+ void tReedTable_free (tReedTable* const);
+ void tReedTable_initToPool (tReedTable* const, float offset, float slope, tMempool* const);
+ void tReedTable_freeFromPool (tReedTable* const, tMempool* const);
+
+ float tReedTable_tick (tReedTable* const, float input);
+ float tReedTable_tanh_tick (tReedTable* const, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
+ void tReedTable_setOffset (tReedTable* const, float offset);
+ void tReedTable_setSlope (tReedTable* const, float slope);
//==============================================================================
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -17,6 +17,7 @@
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-delay.h"
#include "leaf-filters.h"
#include "leaf-oscillators.h"
@@ -41,16 +42,18 @@
typedef _tPRCReverb* tPRCReverb;
- void tPRCReverb_init (tPRCReverb* const, float t60);
- void tPRCReverb_free (tPRCReverb* const);
+ void tPRCReverb_init (tPRCReverb* const, float t60);
+ void tPRCReverb_free (tPRCReverb* const);
+ void tPRCReverb_initToPool (tPRCReverb* const, float t60, tMempool* const);
+ void tPRCReverb_freeFromPool (tPRCReverb* const, tMempool* const);
- float tPRCReverb_tick (tPRCReverb* const, float input);
+ float tPRCReverb_tick (tPRCReverb* const, float input);
// Set reverb time in seconds.
- void tPRCReverb_setT60 (tPRCReverb* const, float t60);
+ void tPRCReverb_setT60 (tPRCReverb* const, float t60);
// Set mix between dry input and wet output signal.
- void tPRCReverb_setMix (tPRCReverb* const, float mix);
+ void tPRCReverb_setMix (tPRCReverb* const, float mix);
//==============================================================================
@@ -73,17 +76,19 @@
typedef _tNReverb* tNReverb;
- void tNReverb_init (tNReverb* const, float t60);
- void tNReverb_free (tNReverb* const);
+ void tNReverb_init (tNReverb* const, float t60);
+ void tNReverb_free (tNReverb* const);
+ void tNReverb_initToPool (tNReverb* const, float t60, tMempool* const);
+ void tNReverb_freeFromPool (tNReverb* const, tMempool* const);
- float tNReverb_tick (tNReverb* const, float input);
- void tNReverb_tickStereo(tNReverb* const rev, float input, float* output);
+ float tNReverb_tick (tNReverb* const, float input);
+ void tNReverb_tickStereo (tNReverb* const rev, float input, float* output);
// Set reverb time in seconds.
- void tNReverb_setT60 (tNReverb* const, float t60);
+ void tNReverb_setT60 (tNReverb* const, float t60);
// Set mix between dry input and wet output signal.
- void tNReverb_setMix (tNReverb* const, float mix);
+ void tNReverb_setMix (tNReverb* const, float mix);
//==============================================================================
@@ -135,11 +140,13 @@
void tDattorroReverb_init (tDattorroReverb* const);
void tDattorroReverb_free (tDattorroReverb* const);
+ void tDattorroReverb_initToPool (tDattorroReverb* const, tMempool* const);
+ void tDattorroReverb_freeFromPool (tDattorroReverb* const, tMempool* const);
float tDattorroReverb_tick (tDattorroReverb* const, float input);
void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);
void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
- void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze);
+ void tDattorroReverb_setFreeze (tDattorroReverb* const rev, uint32_t freeze);
void tDattorroReverb_setHP (tDattorroReverb* const, float freq);
void tDattorroReverb_setSize (tDattorroReverb* const, float size);
void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
--- a/LEAF/Inc/leaf-sampling.h
+++ b/LEAF/Inc/leaf-sampling.h
@@ -18,6 +18,7 @@
#include "leaf-global.h"
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-envelopes.h"
#include "leaf-mempool.h"
@@ -45,27 +46,27 @@
typedef _tBuffer* tBuffer;
- void tBuffer_init (tBuffer* const, uint32_t length);
- void tBuffer_init_locate (tBuffer* const sb, uint32_t length, mpool_t* pool);
- void tBuffer_free (tBuffer* const);
- void tBuffer_free_locate (tBuffer* const sb, mpool_t* pool);
+ void tBuffer_init (tBuffer* const, uint32_t length);
+ void tBuffer_free (tBuffer* const);
+ void tBuffer_initToPool (tBuffer* const, uint32_t length, tMempool* const);
+ void tBuffer_freeFromPool (tBuffer* const, tMempool* const);
- void tBuffer_tick (tBuffer* const, float sample);
+ void tBuffer_tick (tBuffer* const, float sample);
- void tBuffer_read(tBuffer* const, float* buff, uint32_t len);
+ void tBuffer_read (tBuffer* const, float* buff, uint32_t len);
- float tBuffer_get (tBuffer* const, int idx);
+ float tBuffer_get (tBuffer* const, int idx);
- void tBuffer_record (tBuffer* const);
- void tBuffer_stop (tBuffer* const);
- int tBuffer_getRecordPosition(tBuffer* const);
+ void tBuffer_record (tBuffer* const);
+ void tBuffer_stop (tBuffer* const);
+ int tBuffer_getRecordPosition (tBuffer* const);
- void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
+ void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
- void tBuffer_clear (tBuffer* const);
+ void tBuffer_clear (tBuffer* const);
- uint32_t tBuffer_getBufferLength(tBuffer* const);
- uint32_t tBuffer_getRecordedLength(tBuffer* const sb);
+ uint32_t tBuffer_getBufferLength (tBuffer* const);
+ uint32_t tBuffer_getRecordedLength (tBuffer* const sb);
//==============================================================================
@@ -106,26 +107,28 @@
typedef _tSampler* tSampler;
- void tSampler_init (tSampler* const, tBuffer* const);
- void tSampler_free (tSampler* const);
+ void tSampler_init (tSampler* const, tBuffer* const);
+ void tSampler_free (tSampler* const);
+ void tSampler_initToPool (tSampler* const, tBuffer* const, tMempool* const);
+ void tSampler_freeFromPool (tSampler* const, tMempool* const);
- float tSampler_tick (tSampler* const);
+ float tSampler_tick (tSampler* const);
- void tSampler_setSample (tSampler* const, tBuffer* const);
+ void tSampler_setSample (tSampler* const, tBuffer* const);
- void tSampler_setMode (tSampler* const, PlayMode mode);
+ void tSampler_setMode (tSampler* const, PlayMode mode);
- void tSampler_play (tSampler* const);
- void tSampler_stop (tSampler* const);
+ void tSampler_play (tSampler* const);
+ void tSampler_stop (tSampler* const);
- void tSampler_setStart (tSampler* const, int32_t start);
- void tSampler_setEnd (tSampler* const, int32_t end);
+ void tSampler_setStart (tSampler* const, int32_t start);
+ void tSampler_setEnd (tSampler* const, int32_t end);
- static void handleStartEndChange(tSampler* const sp);
+ static void handleStartEndChange (tSampler* const sp);
- void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
+ void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length);
- void tSampler_setRate (tSampler* const, float rate);
+ void tSampler_setRate (tSampler* const, float rate);
//==============================================================================
--- a/LEAF/Src/leaf-analysis.c
+++ b/LEAF/Src/leaf-analysis.c
@@ -38,6 +38,24 @@
leaf_free(e);
}
+void tEnvelopeFollower_initToPool (tEnvelopeFollower* const ef, float attackThreshold, float decayCoeff, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEnvelopeFollower* e = *ef = (_tEnvelopeFollower*) mpool_alloc(sizeof(_tEnvelopeFollower), m->pool);
+
+ e->y = 0.0f;
+ e->a_thresh = attackThreshold;
+ e->d_coeff = decayCoeff;
+}
+
+void tEnvelopeFollower_freeFromPool (tEnvelopeFollower* const ef, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEnvelopeFollower* e = *ef;
+
+ mpool_free(e, m->pool);
+}
+
float tEnvelopeFollower_tick(tEnvelopeFollower* const ef, float x)
{
_tEnvelopeFollower* e = *ef;
@@ -68,9 +86,6 @@
}
-
-
-
//===========================================================================
/* Power Follower */
//===========================================================================
@@ -90,6 +105,24 @@
leaf_free(p);
}
+void tPowerFollower_initToPool (tPowerFollower* const pf, float factor, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPowerFollower* p = *pf = (_tPowerFollower*) mpool_alloc(sizeof(_tPowerFollower), m->pool);
+
+ p->curr=0.0f;
+ p->factor=factor;
+ p->oneminusfactor=1.0f-factor;
+}
+
+void tPowerFollower_freeFromPool (tPowerFollower* const pf, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPowerFollower* p = *pf;
+
+ mpool_free(p, m->pool);
+}
+
int tPowerFollower_setFactor(tPowerFollower* const pf, float factor)
{
_tPowerFollower* p = *pf;
@@ -123,7 +156,7 @@
void tEnvPD_init(tEnvPD* const xpd, int ws, int hs, int bs)
{
- _tEnvPD* x = *xpd = (_tEnvPD*) leaf_alloc(sizeof(_tEnvPD));
+ _tEnvPD* x = *xpd = (_tEnvPD*) leaf_allocAndClear(sizeof(_tEnvPD));
int period = hs, npoints = ws;
@@ -142,6 +175,56 @@
x->hopSize = period;
x->blockSize = bs;
+ for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0.0f;
+ for (i = 0; i < npoints; i++)
+ x->buf[i] = (1.0f - cosf((TWO_PI * i) / npoints))/npoints;
+ for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0.0f;
+
+ x->x_f = 0.0f;
+
+ x->x_allocforvs = INITVSTAKEN;
+
+ // ~ ~ ~ dsp ~ ~ ~
+ if (x->x_period % x->blockSize)
+ {
+ x->x_realperiod = x->x_period + x->blockSize - (x->x_period % x->blockSize);
+ }
+ else
+ {
+ x->x_realperiod = x->x_period;
+ }
+ // ~ ~ ~ ~ ~ ~ ~ ~
+}
+
+void tEnvPD_free (tEnvPD* const xpd)
+{
+ _tEnvPD* x = *xpd;
+
+ leaf_free(x);
+}
+
+void tEnvPD_initToPool (tEnvPD* const xpd, int ws, int hs, int bs, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEnvPD* x = *xpd = (_tEnvPD*) mpool_alloc(sizeof(_tEnvPD), m->pool);
+
+ int period = hs, npoints = ws;
+
+ int i;
+
+ if (npoints < 1) npoints = 1024;
+ if (period < 1) period = npoints/2;
+ if (period < npoints / MAXOVERLAP + 1)
+ period = npoints / MAXOVERLAP + 1;
+
+ x->x_npoints = npoints;
+ x->x_phase = 0;
+ x->x_period = period;
+
+ x->windowSize = npoints;
+ x->hopSize = period;
+ x->blockSize = bs;
+
for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
for (i = 0; i < npoints; i++)
x->buf[i] = (1.0f - cosf((2 * PI * i) / npoints))/npoints;
@@ -163,11 +246,12 @@
// ~ ~ ~ ~ ~ ~ ~ ~
}
-void tEnvPD_free (tEnvPD* const xpd)
+void tEnvPD_freeFromPool (tEnvPD* const xpd, tMempool* const mp)
{
+ _tMempool* m = *mp;
_tEnvPD* x = *xpd;
- leaf_free(x);
+ mpool_free(x, m->pool);
}
float tEnvPD_tick (tEnvPD* const xpd)
@@ -222,25 +306,34 @@
/********Constructor/Destructor***************/
-void tAttackDetection_init(tAttackDetection* const ad, int blocksize)
+void tAttackDetection_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
{
*ad = (_tAttackDetection*) leaf_alloc(sizeof(_tAttackDetection));
- atkdtk_init(ad, blocksize, DEFATTACK, DEFRELEASE);
+ atkdtk_init(ad, blocksize, atk, rel);
}
-void tAttackDetection_init_expanded(tAttackDetection* const ad, int blocksize, int atk, int rel)
+void tAttackDetection_free(tAttackDetection* const ad)
{
- *ad = (_tAttackDetection*) leaf_alloc(sizeof(_tAttackDetection));
+ _tAttackDetection* a = *ad;
+ leaf_free(a);
+}
+
+void tAttackDetection_initToPool (tAttackDetection* const ad, int blocksize, int atk, int rel, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ *ad = (_tAttackDetection*) mpool_alloc(sizeof(_tAttackDetection), m->pool);
+
atkdtk_init(ad, blocksize, atk, rel);
}
-void tAttackDetection_free(tAttackDetection* const ad)
+void tAttackDetection_freeFromPool (tAttackDetection* const ad, tMempool* const mp)
{
+ _tMempool* m = *mp;
_tAttackDetection* a = *ad;
- leaf_free(a);
+ mpool_free(a, m->pool);
}
/*******Public Functions***********/
@@ -265,8 +358,8 @@
a->samplerate = inRate;
//Reset atk and rel to recalculate coeff
- tAttackDetection_setAtk(ad, a->atk);
- tAttackDetection_setRel(ad, a->rel);
+ tAttackDetection_setAttack(ad, a->atk);
+ tAttackDetection_setRelease(ad, a->rel);
}
void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
@@ -275,7 +368,7 @@
a->threshold = thres;
}
-void tAttackDetection_setAtk(tAttackDetection* const ad, int inAtk)
+void tAttackDetection_setAttack(tAttackDetection* const ad, int inAtk)
{
_tAttackDetection* a = *ad;
a->atk = inAtk;
@@ -282,7 +375,7 @@
a->atk_coeff = pow(0.01, 1.0/(a->atk * a->samplerate * 0.001));
}
-void tAttackDetection_setRel(tAttackDetection* const ad, int inRel)
+void tAttackDetection_setRelease(tAttackDetection* const ad, int inRel)
{
_tAttackDetection* a = *ad;
a->rel = inRel;
@@ -322,8 +415,8 @@
a->env = 0;
- tAttackDetection_setAtk(ad, atk);
- tAttackDetection_setRel(ad, rel);
+ tAttackDetection_setAttack(ad, atk);
+ tAttackDetection_setRelease(ad, rel);
}
static void atkdtk_envelope(tAttackDetection* const ad, float *in)
@@ -344,98 +437,6 @@
}
//===========================================================================
-// PERIODDETECTION
-//===========================================================================
-void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)
-{
- _tPeriodDetection* p = *pd = (_tPeriodDetection*) leaf_alloc(sizeof(_tPeriodDetection));
-
- p->inBuffer = in;
- p->outBuffer = out;
- p->bufSize = bufSize;
- p->frameSize = frameSize;
- p->framesPerBuffer = p->bufSize / p->frameSize;
- p->curBlock = 1;
- p->lastBlock = 0;
- p->index = 0;
-
- p->hopSize = DEFHOPSIZE;
- p->windowSize = DEFWINDOWSIZE;
- p->fba = FBA;
-
- tEnvPD_init(&p->env, p->windowSize, p->hopSize, p->frameSize);
-
- tSNAC_init(&p->snac, DEFOVERLAP);
-
- p->timeConstant = DEFTIMECONSTANT;
- p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
-}
-
-void tPeriodDetection_free (tPeriodDetection* const pd)
-{
- _tPeriodDetection* p = *pd;
-
- tEnvPD_free(&p->env);
- tSNAC_free(&p->snac);
- leaf_free(p);
-}
-
-float tPeriodDetection_findPeriod (tPeriodDetection* pd, float sample)
-{
- _tPeriodDetection* p = *pd;
-
- int i, iLast;
-
- i = (p->curBlock*p->frameSize);
- iLast = (p->lastBlock*p->frameSize)+p->index;
-
- p->i = i;
- p->iLast = iLast;
-
- p->inBuffer[i+p->index] = sample;
-
- p->index++;
- p->indexstore = p->index;
- if (p->index >= p->frameSize)
- {
- p->index = 0;
-
- tEnvPD_processBlock(&p->env, &(p->inBuffer[i]));
-
- tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
- p->period = tSNAC_getPeriod(&p->snac);
-
- p->curBlock++;
- if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
- p->lastBlock++;
- if (p->lastBlock >= p->framesPerBuffer) p->lastBlock = 0;
- }
-
- // changed from period to p->period
- return p->period;
-}
-
-void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
-{
- _tPeriodDetection* p = *pd;
- p->hopSize = hs;
-}
-
-void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
-{
- _tPeriodDetection* p = *pd;
- p->windowSize = ws;
-}
-
-
-
-
-
-
-
-
-
-//===========================================================================
// SNAC
//===========================================================================
/******************************************************************************/
@@ -461,7 +462,7 @@
void tSNAC_init(tSNAC* const snac, int overlaparg)
{
- _tSNAC* s = *snac = (_tSNAC*) leaf_alloc(sizeof(_tSNAC));
+ _tSNAC* s = *snac = (_tSNAC*) leaf_allocAndClear(sizeof(_tSNAC));
s->biasfactor = DEFBIAS;
s->timeindex = 0;
@@ -471,10 +472,10 @@
s->minrms = DEFMINRMS;
s->framesize = SNAC_FRAME_SIZE;
- s->inputbuf = (float*) leaf_alloc(sizeof(float) * SNAC_FRAME_SIZE);
- s->processbuf = (float*) leaf_alloc(sizeof(float) * (SNAC_FRAME_SIZE * 2));
- s->spectrumbuf = (float*) leaf_alloc(sizeof(float) * (SNAC_FRAME_SIZE / 2));
- s->biasbuf = (float*) leaf_alloc(sizeof(float) * SNAC_FRAME_SIZE);
+ s->inputbuf = (float*) leaf_allocAndClear(sizeof(float) * SNAC_FRAME_SIZE);
+ s->processbuf = (float*) leaf_allocAndClear(sizeof(float) * (SNAC_FRAME_SIZE * 2));
+ s->spectrumbuf = (float*) leaf_allocAndClear(sizeof(float) * (SNAC_FRAME_SIZE / 2));
+ s->biasbuf = (float*) leaf_allocAndClear(sizeof(float) * SNAC_FRAME_SIZE);
snac_biasbuf(snac);
tSNAC_setOverlap(snac, overlaparg);
@@ -490,6 +491,41 @@
leaf_free(s->biasbuf);
leaf_free(s);
}
+
+void tSNAC_initToPool (tSNAC* const snac, int overlaparg, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSNAC* s = *snac = (_tSNAC*) mpool_alloc(sizeof(_tSNAC), m->pool);
+
+ s->biasfactor = DEFBIAS;
+ s->timeindex = 0;
+ s->periodindex = 0;
+ s->periodlength = 0.;
+ s->fidelity = 0.;
+ s->minrms = DEFMINRMS;
+ s->framesize = SNAC_FRAME_SIZE;
+
+ s->inputbuf = (float*) mpool_allocAndClear(sizeof(float) * SNAC_FRAME_SIZE, m->pool);
+ s->processbuf = (float*) mpool_allocAndClear(sizeof(float) * (SNAC_FRAME_SIZE * 2), m->pool);
+ s->spectrumbuf = (float*) mpool_allocAndClear(sizeof(float) * (SNAC_FRAME_SIZE / 2), m->pool);
+ s->biasbuf = (float*) mpool_allocAndClear(sizeof(float) * SNAC_FRAME_SIZE, m->pool);
+
+ snac_biasbuf(snac);
+ tSNAC_setOverlap(snac, overlaparg);
+}
+
+void tSNAC_freeFromPool (tSNAC* const snac, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSNAC* s = *snac;
+
+ mpool_free(s->inputbuf, m->pool);
+ mpool_free(s->processbuf, m->pool);
+ mpool_free(s->spectrumbuf, m->pool);
+ mpool_free(s->biasbuf, m->pool);
+ mpool_free(s, m->pool);
+}
+
/******************************************************************************/
/************************** public access functions****************************/
/******************************************************************************/
@@ -737,17 +773,17 @@
{
_tSNAC* s = *snac;
- if(periodlength < 4.) return periodlength;
+ if(periodlength < 4.0f) return periodlength;
float max = 0.;
int n, startbin, stopbin, peakbin = 0;
int spectrumsize = s->framesize>>1;
float *spectrumbuf = s->spectrumbuf;
- float peaklocation = (float)(s->framesize * 2.) / periodlength;
+ float peaklocation = (float)(s->framesize * 2.0f) / periodlength;
- startbin = (int)(peaklocation * 0.8 + 0.5);
+ startbin = (int)(peaklocation * 0.8f + 0.5f);
if(startbin < 1) startbin = 1;
- stopbin = (int)(peaklocation * 1.25 + 0.5);
+ stopbin = (int)(peaklocation * 1.25f + 0.5f);
if(stopbin >= spectrumsize - 1) stopbin = spectrumsize - 1;
for(n=startbin; n<stopbin; n++)
@@ -768,7 +804,7 @@
// calculate amplitudes in peak region
for(n=(peakbin-1); n<(peakbin+2); n++)
{
- spectrumbuf[n] = sqrt(spectrumbuf[n]);
+ spectrumbuf[n] = sqrtf(spectrumbuf[n]);
}
peaklocation = (float)peakbin + interpolate3phase(spectrumbuf, peakbin);
@@ -785,17 +821,137 @@
int n;
int maxperiod = (int)(s->framesize * (float)SEEK);
- float bias = s->biasfactor / log((float)(maxperiod - 4));
+ float bias = s->biasfactor / logf((float)(maxperiod - 4));
float *biasbuf = s->biasbuf;
for(n=0; n<5; n++) // periods < 5 samples can't be tracked
{
- biasbuf[n] = 0.;
+ biasbuf[n] = 0.0f;
}
for(n=5; n<maxperiod; n++)
{
- biasbuf[n] = 1.0f - (float)log(n - 4) * bias;
+ biasbuf[n] = 1.0f - (float)logf(n - 4) * bias;
}
+}
+
+//===========================================================================
+// PERIODDETECTION
+//===========================================================================
+void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)
+{
+ _tPeriodDetection* p = *pd = (_tPeriodDetection*) leaf_allocAndClear(sizeof(_tPeriodDetection));
+
+ p->inBuffer = in;
+ p->outBuffer = out;
+ p->bufSize = bufSize;
+ p->frameSize = frameSize;
+ p->framesPerBuffer = p->bufSize / p->frameSize;
+ p->curBlock = 1;
+ p->lastBlock = 0;
+ p->index = 0;
+
+ p->hopSize = DEFHOPSIZE;
+ p->windowSize = DEFWINDOWSIZE;
+ p->fba = FBA;
+
+ tEnvPD_init(&p->env, p->windowSize, p->hopSize, p->frameSize);
+
+ tSNAC_init(&p->snac, DEFOVERLAP);
+
+ p->timeConstant = DEFTIMECONSTANT;
+ p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
+}
+
+void tPeriodDetection_free (tPeriodDetection* const pd)
+{
+ _tPeriodDetection* p = *pd;
+
+ tEnvPD_free(&p->env);
+ tSNAC_free(&p->snac);
+ leaf_free(p);
+}
+
+void tPeriodDetection_initToPool (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPeriodDetection* p = *pd = (_tPeriodDetection*) mpool_alloc(sizeof(_tPeriodDetection), m->pool);
+
+ p->inBuffer = in;
+ p->outBuffer = out;
+ p->bufSize = bufSize;
+ p->frameSize = frameSize;
+ p->framesPerBuffer = p->bufSize / p->frameSize;
+ p->curBlock = 1;
+ p->lastBlock = 0;
+ p->index = 0;
+
+ p->hopSize = DEFHOPSIZE;
+ p->windowSize = DEFWINDOWSIZE;
+ p->fba = FBA;
+
+ tEnvPD_initToPool(&p->env, p->windowSize, p->hopSize, p->frameSize, mp);
+
+ tSNAC_initToPool(&p->snac, DEFOVERLAP, mp);
+
+ p->timeConstant = DEFTIMECONSTANT;
+ p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
+}
+
+void tPeriodDetection_freeFromPool (tPeriodDetection* const pd, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPeriodDetection* p = *pd;
+
+ tEnvPD_freeFromPool(&p->env, mp);
+ tSNAC_freeFromPool(&p->snac, mp);
+ mpool_free(p, m->pool);
+}
+
+float tPeriodDetection_findPeriod (tPeriodDetection* pd, float sample)
+{
+ _tPeriodDetection* p = *pd;
+
+ int i, iLast;
+
+ i = (p->curBlock*p->frameSize);
+ iLast = (p->lastBlock*p->frameSize)+p->index;
+
+ p->i = i;
+ p->iLast = iLast;
+
+ p->inBuffer[i+p->index] = sample;
+
+ p->index++;
+ p->indexstore = p->index;
+ if (p->index >= p->frameSize)
+ {
+ p->index = 0;
+
+ tEnvPD_processBlock(&p->env, &(p->inBuffer[i]));
+
+ tSNAC_ioSamples(&p->snac, &(p->inBuffer[i]), &(p->outBuffer[i]), p->frameSize);
+ p->period = tSNAC_getPeriod(&p->snac);
+
+ p->curBlock++;
+ if (p->curBlock >= p->framesPerBuffer) p->curBlock = 0;
+ p->lastBlock++;
+ if (p->lastBlock >= p->framesPerBuffer) p->lastBlock = 0;
+ }
+
+ // changed from period to p->period
+ return p->period;
+}
+
+void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
+{
+ _tPeriodDetection* p = *pd;
+ p->hopSize = hs;
+}
+
+void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
+{
+ _tPeriodDetection* p = *pd;
+ p->windowSize = ws;
}
--- a/LEAF/Src/leaf-delay.c
+++ b/LEAF/Src/leaf-delay.c
@@ -19,7 +19,7 @@
#endif
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Delay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tDelay_init (tDelay* const dl, uint32_t delay, uint32_t maxDelay)
+void tDelay_init (tDelay* const dl, uint32_t delay, uint32_t maxDelay)
{
_tDelay* d = *dl = (_tDelay*) leaf_alloc(sizeof(_tDelay));
@@ -48,6 +48,37 @@
leaf_free(d);
}
+void tDelay_initToPool (tDelay* const dl, uint32_t delay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tDelay* d = *dl = (_tDelay*) mpool_alloc(sizeof(_tDelay), m->pool);
+
+ d->maxDelay = maxDelay;
+
+ d->delay = delay;
+
+ d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m->pool);
+
+ d->inPoint = 0;
+ d->outPoint = 0;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->gain = 1.0f;
+
+ tDelay_setDelay(dl, d->delay);
+}
+
+void tDelay_freeFromPool (tDelay* const dl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tDelay* d = *dl;
+
+ mpool_free(d->buff, m->pool);
+ mpool_free(d, m->pool);
+}
+
float tDelay_tick (tDelay* const dl, float input)
{
_tDelay* d = *dl;
@@ -177,6 +208,51 @@
leaf_free(d);
}
+void tLinearDelay_initToPool (tLinearDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLinearDelay* d = *dl = (_tLinearDelay*) mpool_alloc(sizeof(_tLinearDelay), m->pool);
+
+ d->maxDelay = maxDelay;
+
+ if (delay > maxDelay) d->delay = maxDelay;
+ else if (delay < 0.0f) d->delay = 0.0f;
+ else d->delay = delay;
+
+ d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m->pool);
+
+ d->gain = 1.0f;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->inPoint = 0;
+ d->outPoint = 0;
+
+ tLinearDelay_setDelay(dl, d->delay);
+}
+
+void tLinearDelay_freeFromPool(tLinearDelay* const dl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLinearDelay* d = *dl;
+
+ mpool_free(d->buff, m->pool);
+ mpool_free(d, m->pool);
+}
+
+
+void tLinearDelay_clear(tLinearDelay* const dl)
+{
+ _tLinearDelay* d = *dl;
+ for (int i = 0; i < d->maxDelay; i++)
+ {
+ d->buff[i] = 0;
+ }
+
+
+}
+
float tLinearDelay_tick (tLinearDelay* const dl, float input)
{
_tLinearDelay* d = *dl;
@@ -186,15 +262,15 @@
// Increment input pointer modulo length.
if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
-
uint32_t idx = (uint32_t) d->outPoint;
-
- d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
- d->buff[idx],
- d->buff[(idx + 1) % d->maxDelay],
- d->buff[(idx + 2) % d->maxDelay],
- d->alpha);
-
+ // First 1/2 of interpolation
+ d->lastOut = d->buff[idx] * d->omAlpha;
+ // Second 1/2 of interpolation
+ if ((idx + 1) < d->maxDelay)
+ d->lastOut += d->buff[idx+1] * d->alpha;
+ else
+ d->lastOut += d->buff[0] * d->alpha;
+
// Increment output pointer modulo length
if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
@@ -215,18 +291,19 @@
{
_tLinearDelay* d = *dl;
- uint32_t idx = (uint32_t) d->outPoint;
+ uint32_t idx = (uint32_t) d->outPoint;
+ // First 1/2 of interpolation
+ d->lastOut = d->buff[idx] * d->omAlpha;
+ // Second 1/2 of interpolation
+ if ((idx + 1) < d->maxDelay)
+ d->lastOut += d->buff[idx+1] * d->alpha;
+ else
+ d->lastOut += d->buff[0] * d->alpha;
- d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
- d->buff[idx],
- d->buff[(idx + 1) % d->maxDelay],
- d->buff[(idx + 2) % d->maxDelay],
- d->alpha);
+ // Increment output pointer modulo length
+ if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
- // Increment output pointer modulo length
- if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
-
- return d->lastOut;
+ return d->lastOut;
}
int tLinearDelay_setDelay (tLinearDelay* const dl, float delay)
@@ -250,31 +327,15 @@
return 0;
}
-float tLinearDelay_tapOut (tLinearDelay* const dl, float tapDelay)
+float tLinearDelay_tapOut (tLinearDelay* const dl, uint32_t tapDelay)
{
_tLinearDelay* d = *dl;
- float tap = (float) d->inPoint - tapDelay - 1.f;
-
+ uint32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
- while ( tap < 0.f ) tap += (float)d->maxDelay;
-
- float alpha = tap - (int)tap;
- float omAlpha = 1.f - alpha;
-
- int ptx = (int) tap;
+ while ( tap < 0 ) tap += d->maxDelay;
- // First 1/2 of interpolation
- float samp = d->buff[ptx] * omAlpha;
-
- // Second 1/2 of interpolation
- if ((ptx + 1) < d->maxDelay)
- samp += d->buff[ptx+1] * d->alpha;
- else
- samp += d->buff[0] * d->alpha;
-
- return samp;
-
+ return d->buff[tap];
}
void tLinearDelay_tapIn (tLinearDelay* const dl, float value, uint32_t tapDelay)
@@ -281,7 +342,7 @@
{
_tLinearDelay* d = *dl;
- int32_t tap = d->inPoint - tapDelay - 1;
+ uint32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
while ( tap < 0 ) tap += d->maxDelay;
@@ -332,6 +393,234 @@
return d->gain;
}
+
+
+
+
+/// Hermite Interpolated Delay
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tHermiteDelay_init (tHermiteDelay* const dl, float delay, uint32_t maxDelay)
+{
+ _tHermiteDelay* d = *dl = (_tHermiteDelay*) leaf_alloc(sizeof(_tHermiteDelay));
+
+ d->maxDelay = maxDelay;
+
+ if (delay > maxDelay) d->delay = maxDelay;
+ else if (delay < 0.0f) d->delay = 0.0f;
+ else d->delay = delay;
+
+ d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
+
+ d->gain = 1.0f;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->inPoint = 0;
+ d->outPoint = 0;
+
+ tHermiteDelay_setDelay(dl, d->delay);
+}
+
+void tHermiteDelay_free(tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+
+ leaf_free(d->buff);
+ leaf_free(d);
+}
+
+void tHermiteDelay_initToPool (tHermiteDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tHermiteDelay* d = *dl = (_tHermiteDelay*) mpool_alloc(sizeof(_tHermiteDelay), m->pool);
+
+ d->maxDelay = maxDelay;
+
+ if (delay > maxDelay) d->delay = maxDelay;
+ else if (delay < 0.0f) d->delay = 0.0f;
+ else d->delay = delay;
+
+ d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m->pool);
+
+ d->gain = 1.0f;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->inPoint = 0;
+ d->outPoint = 0;
+
+ tHermiteDelay_setDelay(dl, d->delay);
+}
+
+void tHermiteDelay_freeFromPool(tHermiteDelay* const dl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tHermiteDelay* d = *dl;
+
+ mpool_free(d->buff, m->pool);
+ mpool_free(d, m->pool);
+}
+
+
+void tHermiteDelay_clear(tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+ for (int i = 0; i < d->maxDelay; i++)
+ {
+ d->buff[i] = 0;
+ }
+
+
+}
+
+float tHermiteDelay_tick (tHermiteDelay* const dl, float input)
+{
+ _tHermiteDelay* d = *dl;
+
+ d->buff[d->inPoint] = input * d->gain;
+
+ // Increment input pointer modulo length.
+ if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
+
+
+ uint32_t idx = (uint32_t) d->outPoint;
+ d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
+ d->buff[idx],
+ d->buff[(idx + 1) % d->maxDelay],
+ d->buff[(idx + 2) % d->maxDelay],
+ d->alpha);
+
+ // Increment output pointer modulo length
+ if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
+
+ return d->lastOut;
+}
+
+void tHermiteDelay_tickIn (tHermiteDelay* const dl, float input)
+{
+ _tHermiteDelay* d = *dl;
+
+ d->buff[d->inPoint] = input * d->gain;
+
+ // Increment input pointer modulo length.
+ if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
+}
+
+float tHermiteDelay_tickOut (tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+
+ uint32_t idx = (uint32_t) d->outPoint;
+
+
+
+ d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
+ d->buff[idx],
+ d->buff[(idx + 1) % d->maxDelay],
+ d->buff[(idx + 2) % d->maxDelay],
+ d->alpha);
+
+ // Increment output pointer modulo length
+ if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
+
+ return d->lastOut;
+}
+
+int tHermiteDelay_setDelay (tHermiteDelay* const dl, float delay)
+{
+ _tHermiteDelay* d = *dl;
+
+ d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
+
+ float outPointer = d->inPoint - d->delay;
+
+ while ( outPointer < 0 )
+ outPointer += d->maxDelay; // modulo maximum length
+
+ d->outPoint = (uint32_t) outPointer; // integer part
+
+ d->alpha = outPointer - d->outPoint; // fractional part
+ d->omAlpha = 1.0f - d->alpha;
+
+ if ( d->outPoint == d->maxDelay ) d->outPoint = 0;
+
+ return 0;
+}
+
+float tHermiteDelay_tapOut (tHermiteDelay* const dl, uint32_t tapDelay)
+{
+ _tHermiteDelay* d = *dl;
+
+ uint32_t tap = d->inPoint - tapDelay - 1;
+
+ // Check for wraparound.
+ while ( tap < 0 ) tap += d->maxDelay;
+
+ return d->buff[tap];
+
+}
+
+void tHermiteDelay_tapIn (tHermiteDelay* const dl, float value, uint32_t tapDelay)
+{
+ _tHermiteDelay* d = *dl;
+
+ int32_t tap = d->inPoint - tapDelay - 1;
+
+ // Check for wraparound.
+ while ( tap < 0 ) tap += d->maxDelay;
+
+ d->buff[tap] = value;
+}
+
+float tHermiteDelay_addTo (tHermiteDelay* const dl, float value, uint32_t tapDelay)
+{
+ _tHermiteDelay* d = *dl;
+
+ int32_t tap = d->inPoint - tapDelay - 1;
+
+ // Check for wraparound.
+ while ( tap < 0 ) tap += d->maxDelay;
+
+ return (d->buff[tap] += value);
+}
+
+float tHermiteDelay_getDelay (tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+ return d->delay;
+}
+
+float tHermiteDelay_getLastOut (tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+ return d->lastOut;
+}
+
+float tHermiteDelay_getLastIn (tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+ return d->lastIn;
+}
+
+void tHermiteDelay_setGain (tHermiteDelay* const dl, float gain)
+{
+ _tHermiteDelay* d = *dl;
+ if (gain < 0.0f) d->gain = 0.0f;
+ else d->gain = gain;
+}
+
+float tHermiteDelay_getGain (tHermiteDelay* const dl)
+{
+ _tHermiteDelay* d = *dl;
+ return d->gain;
+}
+
+
+
+
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ AllpassDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
void tAllpassDelay_init (tAllpassDelay* const dl, float delay, uint32_t maxDelay)
{
@@ -366,6 +655,41 @@
leaf_free(d);
}
+void tAllpassDelay_initToPool (tAllpassDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAllpassDelay* d = *dl = (_tAllpassDelay*) mpool_alloc(sizeof(_tAllpassDelay), m->pool);
+
+ d->maxDelay = maxDelay;
+
+ if (delay > maxDelay) d->delay = maxDelay;
+ else if (delay < 0.0f) d->delay = 0.0f;
+ else d->delay = delay;
+
+ d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m->pool);
+
+ d->gain = 1.0f;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->inPoint = 0;
+ d->outPoint = 0;
+
+ tAllpassDelay_setDelay(dl, d->delay);
+
+ d->apInput = 0.0f;
+}
+
+void tAllpassDelay_freeFromPool(tAllpassDelay* const dl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAllpassDelay* d = *dl;
+
+ mpool_free(d->buff, m->pool);
+ mpool_free(d, m->pool);
+}
+
float tAllpassDelay_tick (tAllpassDelay* const dl, float input)
{
_tAllpassDelay* d = *dl;
@@ -520,6 +844,36 @@
leaf_free(d);
}
+void tTapeDelay_initToPool (tTapeDelay* const dl, float delay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTapeDelay* d = *dl = (_tTapeDelay*) mpool_alloc(sizeof(_tTapeDelay), m->pool);
+
+ d->maxDelay = maxDelay;
+
+ d->buff = (float*) mpool_alloc(sizeof(float) * maxDelay, m->pool);
+
+ d->gain = 1.0f;
+
+ d->lastIn = 0.0f;
+ d->lastOut = 0.0f;
+
+ d->idx = 0.0f;
+ d->inc = 1.0f;
+ d->inPoint = 0;
+
+ tTapeDelay_setDelay(dl, delay);
+}
+
+void tTapeDelay_freeFromPool(tTapeDelay* const dl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTapeDelay* d = *dl;
+
+ mpool_free(d->buff, m->pool);
+ mpool_free(d, m->pool);
+}
+
//#define SMOOTH_FACTOR 10.f
float tTapeDelay_tick (tTapeDelay* const dl, float input)
@@ -534,7 +888,7 @@
int idx = (int) d->idx;
float alpha = d->idx - idx;
- d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
+ d->lastOut = LEAF_interpolate_hermite_x (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
d->buff[idx],
d->buff[(idx + 1) % d->maxDelay],
d->buff[(idx + 2) % d->maxDelay],
@@ -585,7 +939,7 @@
float alpha = tap - idx;
- float samp = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
+ float samp = LEAF_interpolate_hermite_x (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
d->buff[idx],
d->buff[(idx + 1) % d->maxDelay],
d->buff[(idx + 2) % d->maxDelay],
--- a/LEAF/Src/leaf-distortion.c
+++ b/LEAF/Src/leaf-distortion.c
@@ -17,232 +17,58 @@
#include "../Inc/leaf-tables.h"
//testing
-#include "gpio.h"
+//#include "gpio.h"
#endif
//============================================================================================================
-// WAVEFOLDER
+// Sample-Rate reducer
//============================================================================================================
-//from the paper: Virtual Analog Model of the Lockhart Wavefolder
-//by Fabián Esqueda, Henri Pöntynen, Julian D. Parker and Stefan Bilbao
-
-void tLockhartWavefolder_init(tLockhartWavefolder* const wf)
+void tSampleReducer_init(tSampleReducer* const sr)
{
- _tLockhartWavefolder* w = *wf = (_tLockhartWavefolder*) leaf_alloc(sizeof(_tLockhartWavefolder));
+ _tSampleReducer* s = *sr = (_tSampleReducer*) leaf_alloc(sizeof(_tSampleReducer));
- w->Ln1 = 0.0;
- w->Fn1 = 0.0;
- w->xn1 = 0.0f;
-
- w->RL = 7.5e3;
- w->R = 15e3;
- w->VT = 26e-3;
- w->Is = 10e-16;
-
- w->a = 2.0*w->RL/w->R;
- w->b = (w->R+2.0*w->RL)/(w->VT*w->R);
- w->d = (w->RL*w->Is)/w->VT;
- w->half_a = 0.5 * w->a;
- w->longthing = (0.5*w->VT/w->b);
-
-
- // Antialiasing error threshold
- w->thresh = 10e-10;
+ s->invRatio = 1.0f;
+ s->hold = 0.0f;
+ s->count = 0;
}
-void tLockhartWavefolder_free(tLockhartWavefolder* const wf)
+void tSampleReducer_free (tSampleReducer* const sr)
{
- _tLockhartWavefolder* w = *wf;
+ _tSampleReducer* s = *sr;
- leaf_free(w);
+ leaf_free(s);
}
-double tLockhartWavefolderLambert(double x, double ln)
+void tSampleReducer_initToPool (tSampleReducer* const sr, tMempool* const mp)
{
- double thresh, w, expw, p, r, s, err;
- // Error threshold
- thresh = 10e-12;
- // Initial guess (use previous value)
- w = ln;
+ _tMempool* m = *mp;
+ _tSampleReducer* s = *sr = (_tSampleReducer*) mpool_alloc(sizeof(_tSampleReducer), m->pool);
- // Haley's method (Sec. 4.2 of the paper)
- for(int i=0; i<1000; i+=1) {
-
- expw = exp(w);
-
- p = w*expw - x;
- r = (w+1.0)*expw;
- s = (w+2.0)/(2.0*(w+1.0));
- err = (p/(r-(p*s)));
-
- if (fabs(err)<thresh) {
-
- break;
- }
-
- w = w - err;
- if (i == 999)
- {
- //HAL_GPIO_WritePin(GPIOG, GPIO_PIN_7, GPIO_PIN_SET);
- }
-
- }
- return w;
+ s->invRatio = 1.0f;
+ s->hold = 0.0f;
+ s->count = 0;
}
-float tLockhartWavefolder_tick(tLockhartWavefolder* const wf, float samp)
+void tSampleReducer_freeFromPool (tSampleReducer* const sr, tMempool* const mp)
{
- _tLockhartWavefolder* w = *wf;
+ _tMempool* m = *mp;
+ _tSampleReducer* s = *sr;
- float out = 0.0f;
-
- // Compute Antiderivative
- int l = (samp > 0.0f) - (samp < 0.0f);
- double u = w->d*exp(l*w->b*samp);
- double Ln = tLockhartWavefolderLambert(u,w->Ln1);
- double Fn = w->longthing*(Ln*(Ln + 2.0)) - w->half_a*samp*samp;
-
- // Check for ill-conditioning
- if (fabs(samp-w->xn1)<w->thresh) {
-
- // Compute Averaged Wavefolder Output
- float xn = 0.5f*(samp+w->xn1);
- u = w->d*exp(l*w->b*xn);
- Ln = tLockhartWavefolderLambert(u,w->Ln1);
- out = (float) (l*w->VT*Ln - w->a*xn);
-
- }
- else {
-
- // Apply AA Form
- out = (float) ((Fn-w->Fn1)/(samp-w->xn1));
- }
-
- // Update States
- w->Ln1 = Ln;
- w->Fn1 = Fn;
- w->xn1 = samp;
-
- return out;
+ mpool_free(s, m->pool);
}
-//============================================================================================================
-// CRUSHER
-//============================================================================================================
-#define SCALAR 5000.f
-
-void tCrusher_init (tCrusher* const cr)
-{
- _tCrusher* c = *cr = (_tCrusher*) leaf_alloc(sizeof(_tCrusher));
-
- c->op = 4;
- c->div = SCALAR;
- c->rnd = 0.25f;
- c->srr = 0.25f;
- tSampleReducer_init(&c->sReducer);
- c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
-}
-
-void tCrusher_free (tCrusher* const cr)
-{
- _tCrusher* c = *cr;
- tSampleReducer_free(&c->sReducer);
- leaf_free(c);
-}
-
-float tCrusher_tick (tCrusher* const cr, float input)
-{
- _tCrusher* c = *cr;
-
- float sample = input;
-
- sample *= SCALAR; // SCALAR is 5000 by default
-
- sample = (int32_t) sample;
-
- sample /= c->div;
-
- sample = LEAF_bitwise_xor(sample, c->op << 23);
-
- sample = LEAF_clip(-1.f, sample, 1.f);
-
- sample = LEAF_round(sample, c->rnd);
-
- sample = tSampleReducer_tick(&c->sReducer, sample);
-
- return sample * c->gain;
-
-}
-
-void tCrusher_setOperation (tCrusher* const cr, float op)
-{
- _tCrusher* c = *cr;
- c->op = (uint32_t) (op * 8.0f);
-}
-
-// 0.0 - 1.0
-void tCrusher_setQuality (tCrusher* const cr, float val)
-{
- _tCrusher* c = *cr;
-
- val = LEAF_clip(0.0f, val, 1.0f);
-
- c->div = 0.01f + val * SCALAR;
-
- c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
-}
-
-// what decimal to round to
-void tCrusher_setRound (tCrusher* const cr, float rnd)
-{
- _tCrusher* c = *cr;
- c->rnd = fabsf(rnd);
-}
-
-void tCrusher_setSamplingRatio (tCrusher* const cr, float ratio)
-{
- _tCrusher* c = *cr;
- c->srr = ratio;
- tSampleReducer_setRatio(&c->sReducer, ratio);
-
-}
-
-//============================================================================================================
-// Sample-Rate reducer
-//============================================================================================================
-
-
-void tSampleReducer_init(tSampleReducer* const sr)
-{
- _tSampleReducer* s = *sr = (_tSampleReducer*) leaf_alloc(sizeof(_tSampleReducer));
-
-
-
- s->invRatio = 1.0f;
- s->hold = 0.0f;
- s->count = 0;
-
-}
-
-void tSampleReducer_free (tSampleReducer* const sr)
-{
- _tSampleReducer* s = *sr;
-
- leaf_free(s);
-}
-
float tSampleReducer_tick(tSampleReducer* const sr, float input)
{
- _tSampleReducer* s = *sr;
+ _tSampleReducer* s = *sr;
if (s->count > s->invRatio)
{
s->hold = input;
s->count = 0;
}
-
+
s->count++;
return s->hold;
}
@@ -250,10 +76,10 @@
void tSampleReducer_setRatio(tSampleReducer* const sr, float ratio)
{
- _tSampleReducer* s = *sr;
- if ((ratio <= 1.0f) && (ratio >= 0.0f))
- s->invRatio = 1.0f / ratio;
-
+ _tSampleReducer* s = *sr;
+ if ((ratio <= 1.0f) && (ratio >= 0.0f))
+ s->invRatio = 1.0f / ratio;
+
}
//============================================================================================================
@@ -288,6 +114,36 @@
leaf_free(os);
}
+void tOversampler_initToPool (tOversampler* const osr, int ratio, oBool extraQuality, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tOversampler* os = *osr = (_tOversampler*) mpool_alloc(sizeof(_tOversampler), m->pool);
+
+ uint8_t offset = 0;
+ if (extraQuality) offset = 6;
+ if (ratio == 2 || ratio == 4 ||
+ ratio == 8 || ratio == 16 ||
+ ratio == 32 || ratio == 64) {
+ os->ratio = ratio;
+ int idx = (int)(log2f(os->ratio))-1+offset;
+ os->numTaps = firNumTaps[idx];
+ os->phaseLength = os->numTaps / os->ratio;
+ os->pCoeffs = (float*) firCoeffs[idx];
+ os->upState = mpool_alloc(sizeof(float) * os->numTaps * 2, m->pool);
+ os->downState = mpool_alloc(sizeof(float) * os->numTaps * 2, m->pool);
+ }
+}
+
+void tOversampler_freeFromPool (tOversampler* const osr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tOversampler* os = *osr;
+
+ mpool_free(os->upState, m->pool);
+ mpool_free(os->downState, m->pool);
+ mpool_free(os, m->pool);
+}
+
float tOversampler_tick(tOversampler* const osr, float input, float (*effectTick)(float))
{
_tOversampler* os = *osr;
@@ -485,4 +341,247 @@
{
_tOversampler* os = *osr;
return os->phaseLength;
+}
+
+//============================================================================================================
+// WAVEFOLDER
+//============================================================================================================
+
+
+//from the paper: Virtual Analog Model of the Lockhart Wavefolder
+//by Fabián Esqueda, Henri Pöntynen, Julian D. Parker and Stefan Bilbao
+
+void tLockhartWavefolder_init(tLockhartWavefolder* const wf)
+{
+ _tLockhartWavefolder* w = *wf = (_tLockhartWavefolder*) leaf_alloc(sizeof(_tLockhartWavefolder));
+
+ w->Ln1 = 0.0;
+ w->Fn1 = 0.0;
+ w->xn1 = 0.0f;
+
+ w->RL = 7.5e3;
+ w->R = 15e3;
+ w->VT = 26e-3;
+ w->Is = 10e-16;
+
+ w->a = 2.0*w->RL/w->R;
+ w->b = (w->R+2.0*w->RL)/(w->VT*w->R);
+ w->d = (w->RL*w->Is)/w->VT;
+ w->half_a = 0.5 * w->a;
+ w->longthing = (0.5*w->VT/w->b);
+
+
+ // Antialiasing error threshold
+ w->thresh = 10e-10;
+}
+
+void tLockhartWavefolder_free(tLockhartWavefolder* const wf)
+{
+ _tLockhartWavefolder* w = *wf;
+
+ leaf_free(w);
+}
+
+void tLockhartWavefolder_initToPool (tLockhartWavefolder* const wf, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLockhartWavefolder* w = *wf = (_tLockhartWavefolder*) mpool_alloc(sizeof(_tLockhartWavefolder), m->pool);
+
+ w->Ln1 = 0.0;
+ w->Fn1 = 0.0;
+ w->xn1 = 0.0f;
+
+ w->RL = 7.5e3;
+ w->R = 15e3;
+ w->VT = 26e-3;
+ w->Is = 10e-16;
+
+ w->a = 2.0*w->RL/w->R;
+ w->b = (w->R+2.0*w->RL)/(w->VT*w->R);
+ w->d = (w->RL*w->Is)/w->VT;
+ w->half_a = 0.5 * w->a;
+ w->longthing = (0.5*w->VT/w->b);
+
+
+ // Antialiasing error threshold
+ w->thresh = 10e-10;
+}
+
+void tLockhartWavefolder_freeFromPool (tLockhartWavefolder* const wf, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLockhartWavefolder* w = *wf;
+
+ mpool_free(w, m->pool);
+}
+
+double tLockhartWavefolderLambert(double x, double ln)
+{
+ double thresh, w, expw, p, r, s, err;
+ // Error threshold
+ thresh = 10e-12;
+ // Initial guess (use previous value)
+ w = ln;
+
+ // Haley's method (Sec. 4.2 of the paper)
+ for(int i=0; i<1000; i+=1) {
+
+ expw = exp(w);
+
+ p = w*expw - x;
+ r = (w+1.0)*expw;
+ s = (w+2.0)/(2.0*(w+1.0));
+ err = (p/(r-(p*s)));
+
+ if (fabs(err)<thresh) {
+
+ break;
+ }
+
+ w = w - err;
+ if (i == 999)
+ {
+ //HAL_GPIO_WritePin(GPIOG, GPIO_PIN_7, GPIO_PIN_SET);
+ }
+
+ }
+ return w;
+}
+
+float tLockhartWavefolder_tick(tLockhartWavefolder* const wf, float samp)
+{
+ _tLockhartWavefolder* w = *wf;
+
+ float out = 0.0f;
+
+ // Compute Antiderivative
+ int l = (samp > 0.0f) - (samp < 0.0f);
+ double u = w->d*exp(l*w->b*samp);
+ double Ln = tLockhartWavefolderLambert(u,w->Ln1);
+ double Fn = w->longthing*(Ln*(Ln + 2.0)) - w->half_a*samp*samp;
+
+ // Check for ill-conditioning
+ if (fabs(samp-w->xn1)<w->thresh) {
+
+ // Compute Averaged Wavefolder Output
+ float xn = 0.5f*(samp+w->xn1);
+ u = w->d*exp(l*w->b*xn);
+ Ln = tLockhartWavefolderLambert(u,w->Ln1);
+ out = (float) (l*w->VT*Ln - w->a*xn);
+
+ }
+ else {
+
+ // Apply AA Form
+ out = (float) ((Fn-w->Fn1)/(samp-w->xn1));
+ }
+
+ // Update States
+ w->Ln1 = Ln;
+ w->Fn1 = Fn;
+ w->xn1 = samp;
+
+ return out;
+}
+
+//============================================================================================================
+// CRUSHER
+//============================================================================================================
+#define SCALAR 5000.f
+
+void tCrusher_init (tCrusher* const cr)
+{
+ _tCrusher* c = *cr = (_tCrusher*) leaf_alloc(sizeof(_tCrusher));
+
+ c->op = 4;
+ c->div = SCALAR;
+ c->rnd = 0.25f;
+ c->srr = 0.25f;
+ tSampleReducer_init(&c->sReducer);
+ c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
+}
+
+void tCrusher_free (tCrusher* const cr)
+{
+ _tCrusher* c = *cr;
+ tSampleReducer_free(&c->sReducer);
+ leaf_free(c);
+}
+
+void tCrusher_initToPool (tCrusher* const cr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tCrusher* c = *cr = (_tCrusher*) mpool_alloc(sizeof(_tCrusher), m->pool);
+
+ c->op = 4;
+ c->div = SCALAR;
+ c->rnd = 0.25f;
+ c->srr = 0.25f;
+ tSampleReducer_initToPool(&c->sReducer, mp);
+ c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
+}
+
+void tCrusher_freeFromPool (tCrusher* const cr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tCrusher* c = *cr;
+ tSampleReducer_freeFromPool(&c->sReducer, mp);
+ mpool_free(c, m->pool);
+}
+
+float tCrusher_tick (tCrusher* const cr, float input)
+{
+ _tCrusher* c = *cr;
+
+ float sample = input;
+
+ sample *= SCALAR; // SCALAR is 5000 by default
+
+ sample = (int32_t) sample;
+
+ sample /= c->div;
+
+ sample = LEAF_bitwise_xor(sample, c->op << 23);
+
+ sample = LEAF_clip(-1.f, sample, 1.f);
+
+ sample = LEAF_round(sample, c->rnd);
+
+ sample = tSampleReducer_tick(&c->sReducer, sample);
+
+ return sample * c->gain;
+
+}
+
+void tCrusher_setOperation (tCrusher* const cr, float op)
+{
+ _tCrusher* c = *cr;
+ c->op = (uint32_t) (op * 8.0f);
+}
+
+// 0.0 - 1.0
+void tCrusher_setQuality (tCrusher* const cr, float val)
+{
+ _tCrusher* c = *cr;
+
+ val = LEAF_clip(0.0f, val, 1.0f);
+
+ c->div = 0.01f + val * SCALAR;
+
+ c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
+}
+
+// what decimal to round to
+void tCrusher_setRound (tCrusher* const cr, float rnd)
+{
+ _tCrusher* c = *cr;
+ c->rnd = fabsf(rnd);
+}
+
+void tCrusher_setSamplingRatio (tCrusher* const cr, float ratio)
+{
+ _tCrusher* c = *cr;
+ c->srr = ratio;
+ tSampleReducer_setRatio(&c->sReducer, ratio);
+
}
--- a/LEAF/Src/leaf-dynamics.c
+++ b/LEAF/Src/leaf-dynamics.c
@@ -63,6 +63,30 @@
leaf_free(c);
}
+void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tCompressor* c = *comp = (_tCompressor*) mpool_alloc(sizeof(_tCompressor), m->pool);
+
+ c->tauAttack = 100;
+ c->tauRelease = 100;
+
+ c->isActive = OFALSE;
+
+ c->T = 0.0f; // Threshold
+ c->R = 0.5f; // compression Ratio
+ c->M = 3.0f; // decibel Width of knee transition
+ c->W = 1.0f; // decibel Make-up gain
+}
+
+void tCompressor_freeFromPool(tCompressor* const comp, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tCompressor* c = *comp;
+
+ mpool_free(c, m->pool);
+}
+
float tCompressor_tick(tCompressor* const comp, float in)
{
_tCompressor* c = *comp;
@@ -133,6 +157,27 @@
leaf_free(p);
}
+void tFeedbackLeveler_initToPool (tFeedbackLeveler* const fb, float targetLevel, float factor, float strength, int mode, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFeedbackLeveler* p = *fb = (_tFeedbackLeveler*) mpool_alloc(sizeof(_tFeedbackLeveler), m->pool);
+
+ p->curr=0.0f;
+ p->targetLevel=targetLevel;
+ tPowerFollower_initToPool(&p->pwrFlw,factor, mp);
+ p->mode=mode;
+ p->strength=strength;
+}
+
+void tFeedbackLeveler_freeFromPool (tFeedbackLeveler* const fb, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFeedbackLeveler* p = *fb;
+
+ tPowerFollower_freeFromPool(&p->pwrFlw, mp);
+ mpool_free(p, m->pool);
+}
+
void tFeedbackLeveler_setStrength(tFeedbackLeveler* const fb, float strength)
{ // strength is how strongly level diff is affecting the amp ratio
// try 0.125 for a start
@@ -156,8 +201,8 @@
{
_tFeedbackLeveler* p = *fb;
float levdiff=(tPowerFollower_tick(&p->pwrFlw, input)-p->targetLevel);
- if (p->mode==0 && levdiff<0) levdiff=0;
- p->curr=input*(1-p->strength*levdiff);
+ if (p->mode==0 && levdiff<0.0f) levdiff=0.0f;
+ p->curr=input*(1.0f-p->strength*levdiff);
return p->curr;
}
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -59,6 +59,42 @@
leaf_free(v);
}
+void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTalkbox* v = *voc = (_tTalkbox*) mpool_alloc(sizeof(_tTalkbox), m->pool);
+
+ v->param[0] = 0.5f; //wet
+ v->param[1] = 0.0f; //dry
+ v->param[2] = 0; // Swap
+ v->param[3] = 1.0f; //quality
+
+ v->bufsize = bufsize;
+
+ v->car0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m->pool);
+ v->car1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m->pool);
+ v->window = (float*) mpool_alloc(sizeof(float) * v->bufsize, m->pool);
+ v->buf0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m->pool);
+ v->buf1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m->pool);
+
+ tTalkbox_update(voc);
+ tTalkbox_suspend(voc);
+}
+
+void tTalkbox_freeFromPool (tTalkbox* const voc, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTalkbox* v = *voc;
+
+ mpool_free(v->buf1, m->pool);
+ mpool_free(v->buf0, m->pool);
+ mpool_free(v->window, m->pool);
+ mpool_free(v->car1, m->pool);
+ mpool_free(v->car0, m->pool);
+
+ mpool_free(v, m->pool);
+}
+
void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
{
_tTalkbox* v = *voc;
@@ -266,6 +302,31 @@
leaf_free(v);
}
+void tVocoder_initToPool (tVocoder* const voc, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tVocoder* v = *voc = (_tVocoder*) mpool_alloc(sizeof(_tVocoder), m->pool);
+
+ v->param[0] = 0.33f; //input select
+ v->param[1] = 0.50f; //output dB
+ v->param[2] = 0.40f; //hi thru
+ v->param[3] = 0.40f; //hi band
+ v->param[4] = 0.16f; //envelope
+ v->param[5] = 0.55f; //filter q
+ v->param[6] = 0.6667f;//freq range
+ v->param[7] = 0.33f; //num bands
+
+ tVocoder_update(voc);
+}
+
+void tVocoder_freeFromPool (tVocoder* const voc, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tVocoder* v = *voc;
+
+ mpool_free(v, m->pool);
+}
+
void tVocoder_update (tVocoder* const voc)
{
_tVocoder* v = *voc;
@@ -427,499 +488,6 @@
}
//============================================================================================================
-// RETUNE
-//============================================================================================================
-
-void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)
-{
- _tRetune* r = *rt = (_tRetune*) leaf_alloc(sizeof(_tRetune));
-
- r->bufSize = bufSize;
- r->frameSize = frameSize;
- r->numVoices = numVoices;
-
- r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
-
- r->hopSize = DEFHOPSIZE;
- r->windowSize = DEFWINDOWSIZE;
- r->fba = FBA;
- tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
-
- r->inputPeriod = 0.0f;
-
- r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
- r->pitchFactor = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- }
-
- tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
- }
-}
-
-void tRetune_free(tRetune* const rt)
-{
- _tRetune* r = *rt;
-
- tPeriodDetection_free(&r->pd);
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_free(&r->ps[i]);
- leaf_free(r->outBuffers[i]);
- }
- leaf_free(r->tickOutput);
- leaf_free(r->pitchFactor);
- leaf_free(r->ps);
- leaf_free(r->inBuffer);
- leaf_free(r->outBuffers);
- leaf_free(r);
-}
-
-float* tRetune_tick(tRetune* const rt, float sample)
-{
- _tRetune* r = *rt;
-
- r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
-
- for (int v = 0; v < r->numVoices; ++v)
- {
- r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
- }
-
- return r->tickOutput;
-}
-
-void tRetune_setNumVoices(tRetune* const rt, int numVoices)
-{
- _tRetune* r = *rt;
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_free(&r->ps[i]);
- leaf_free(r->outBuffers[i]);
- }
- leaf_free(r->tickOutput);
- leaf_free(r->pitchFactor);
- leaf_free(r->ps);
- leaf_free(r->outBuffers);
-
- r->numVoices = numVoices;
-
- r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
- r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
- r->pitchFactor = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
- }
-
-
-}
-
-void tRetune_setPitchFactors(tRetune* const rt, float pf)
-{
- _tRetune* r = *rt;
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->pitchFactor[i] = pf;
- tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
- }
-}
-
-void tRetune_setPitchFactor(tRetune* const rt, float pf, int voice)
-{
- _tRetune* r = *rt;
-
- r->pitchFactor[voice] = pf;
- tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
-}
-
-void tRetune_setTimeConstant(tRetune* const rt, float tc)
-{
- _tRetune* r = *rt;
-
- r->timeConstant = tc;
- r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
-}
-
-void tRetune_setHopSize(tRetune* const rt, int hs)
-{
- _tRetune* r = *rt;
-
- r->hopSize = hs;
- tPeriodDetection_setHopSize(&r->pd, r->hopSize);
-}
-
-void tRetune_setWindowSize(tRetune* const rt, int ws)
-{
- _tRetune* r = *rt;
-
- r->windowSize = ws;
- tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
-}
-
-float tRetune_getInputPeriod(tRetune* const rt)
-{
- _tRetune* r = *rt;
-
- return r->inputPeriod;
-}
-
-float tRetune_getInputFreq(tRetune* const rt)
-{
- _tRetune* r = *rt;
-
- return 1.0f/r->inputPeriod;
-}
-
-//============================================================================================================
-// AUTOTUNE
-//============================================================================================================
-
-void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)
-{
- _tAutotune* r = *rt = (_tAutotune*) leaf_alloc(sizeof(_tAutotune));
-
- r->bufSize = bufSize;
- r->frameSize = frameSize;
- r->numVoices = numVoices;
-
- r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
-
- r->hopSize = DEFHOPSIZE;
- r->windowSize = DEFWINDOWSIZE;
- r->fba = FBA;
- tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
-
-
-
- r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
- r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- }
-
- tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
- }
-
- r->inputPeriod = 0.0f;
-}
-
-void tAutotune_free(tAutotune* const rt)
-{
- _tAutotune* r = *rt;
-
- tPeriodDetection_free(&r->pd);
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_free(&r->ps[i]);
- leaf_free(r->outBuffers[i]);
- }
- leaf_free(r->tickOutput);
- leaf_free(r->freq);
- leaf_free(r->ps);
- leaf_free(r->inBuffer);
- leaf_free(r->outBuffers);
- leaf_free(r);
-}
-
-float* tAutotune_tick(tAutotune* const rt, float sample)
-{
- _tAutotune* r = *rt;
-
- float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
- if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
- {
- r->inputPeriod = tempPeriod;
- }
-
- for (int v = 0; v < r->numVoices; ++v)
- {
- r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
- }
-
- return r->tickOutput;
-}
-
-void tAutotune_setNumVoices(tAutotune* const rt, int numVoices)
-{
- _tAutotune* r = *rt;
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- tPitchShift_free(&r->ps[i]);
- leaf_free(r->outBuffers[i]);
- }
- leaf_free(r->tickOutput);
- leaf_free(r->freq);
- leaf_free(r->ps);
- leaf_free(r->outBuffers);
-
- r->numVoices = numVoices;
-
- r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
- r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
- r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
- tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
- }
-
-
-}
-
-void tAutotune_setFreqs(tAutotune* const rt, float f)
-{
- _tAutotune* r = *rt;
-
- for (int i = 0; i < r->numVoices; ++i)
- {
- r->freq[i] = f;
- }
-}
-
-void tAutotune_setFreq(tAutotune* const rt, float f, int voice)
-{
- _tAutotune* r = *rt;
-
- r->freq[voice] = f;
-}
-
-void tAutotune_setTimeConstant(tAutotune* const rt, float tc)
-{
- _tAutotune* r = *rt;
-
- r->timeConstant = tc;
- r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
-}
-
-void tAutotune_setHopSize(tAutotune* const rt, int hs)
-{
- _tAutotune* r = *rt;
-
- r->hopSize = hs;
- tPeriodDetection_setHopSize(&r->pd, r->hopSize);
-}
-
-void tAutotune_setWindowSize(tAutotune* const rt, int ws)
-{
- _tAutotune* r = *rt;
-
- r->windowSize = ws;
- tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
-}
-
-float tAutotune_getInputPeriod(tAutotune* const rt)
-{
- _tAutotune* r = *rt;
-
- return r->inputPeriod;
-}
-
-float tAutotune_getInputFreq(tAutotune* const rt)
-{
- _tAutotune* r = *rt;
-
- return 1.0f/r->inputPeriod;
-}
-
-//============================================================================================================
-// PITCHSHIFT
-//============================================================================================================
-
-static int pitchshift_attackdetect(_tPitchShift* ps)
-{
- float envout;
-
- _tPeriodDetection* p = *ps->p;
-
- envout = tEnvPD_tick(&p->env);
-
- if (envout >= 1.0f)
- {
- p->lastmax = p->max;
- if (envout > p->max)
- {
- p->max = envout;
- }
- else
- {
- p->deltamax = envout - p->max;
- p->max = p->max * ps->radius;
- }
- p->deltamax = p->max - p->lastmax;
- }
-
- p->fba = p->fba ? (p->fba - 1) : 0;
-
- return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
-}
-
-void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* pd, float* out, int bufSize)
-{
- _tPitchShift* ps = *psr = (_tPitchShift*) leaf_alloc(sizeof(_tPitchShift));
- _tPeriodDetection* p = *pd;
-
- ps->p = pd;
-
- ps->outBuffer = out;
- ps->bufSize = bufSize;
- ps->frameSize = p->frameSize;
- ps->framesPerBuffer = ps->bufSize / ps->frameSize;
- ps->curBlock = 1;
- ps->lastBlock = 0;
- ps->index = 0;
- ps->pitchFactor = 1.0f;
-
- tSOLAD_init(&ps->sola);
-
- tHighpass_init(&ps->hp, HPFREQ);
-
- tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
-}
-
-void tPitchShift_free(tPitchShift* const psr)
-{
- _tPitchShift* ps = *psr;
-
- tSOLAD_free(&ps->sola);
- tHighpass_free(&ps->hp);
- leaf_free(ps);
-}
-
-void tPitchShift_setPitchFactor(tPitchShift* psr, float pf)
-{
- _tPitchShift* ps = *psr;
-
- ps->pitchFactor = pf;
-}
-
-float tPitchShift_shift (tPitchShift* psr)
-{
- _tPitchShift* ps = *psr;
- _tPeriodDetection* p = *ps->p;
-
- float period, out;
- int i, iLast;
-
- i = p->i;
- iLast = p->iLast;
-
- out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-
- if (p->indexstore >= ps->frameSize)
- {
- period = p->period;
-
- if(pitchshift_attackdetect(ps) == 1)
- {
- p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, p->windowSize);
- }
-
- tSOLAD_setPeriod(&ps->sola, period);
- tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-
- tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
- }
-
- return out;
-}
-
-float tPitchShift_shiftToFreq (tPitchShift* psr, float freq)
-{
- _tPitchShift* ps = *psr;
- _tPeriodDetection* p = *ps->p;
-
- float period, out;
- int i, iLast;
-
- i = p->i;
- iLast = p->iLast;
-
- out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-
- if (p->indexstore >= ps->frameSize)
- {
- period = p->period;
-
- if(pitchshift_attackdetect(ps) == 1)
- {
- p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, p->windowSize);
- }
-
- tSOLAD_setPeriod(&ps->sola, period);
-
- if (period != 0) ps->pitchFactor = period*freq*leaf.invSampleRate;
- else ps->pitchFactor = 1.0f;
-
- tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-
- tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
- }
- return out;
-}
-
-float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float))
-{
- _tPitchShift* ps = *psr;
- _tPeriodDetection* p = *ps->p;
-
- float period, out;
- int i, iLast;
-
- i = p->i;
- iLast = p->iLast;
-
- out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
-
- if (p->indexstore >= ps->frameSize)
- {
- period = p->period;
-
- if(pitchshift_attackdetect(ps) == 1)
- {
- p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, p->windowSize);
- }
-
- tSOLAD_setPeriod(&ps->sola, period);
-
- ps->pitchFactor = period/fun(period);
- tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
-
- tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
-
- ps->curBlock++;
- if (ps->curBlock >= p->framesPerBuffer) ps->curBlock = 0;
- ps->lastBlock++;
- if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
- }
-
- return out;
-}
-
-//============================================================================================================
// SOLAD
//============================================================================================================
/******************************************************************************/
@@ -938,10 +506,10 @@
// init
void tSOLAD_init(tSOLAD* const wp)
{
- _tSOLAD* w = *wp = (_tSOLAD*) leaf_alloc(sizeof(_tSOLAD));
+ _tSOLAD* w = *wp = (_tSOLAD*) leaf_allocAndClear(sizeof(_tSOLAD));
w->pitchfactor = 1.;
- w->delaybuf = (float*) leaf_alloc(sizeof(float) * (LOOPSIZE+16));
+ w->delaybuf = (float*) leaf_allocAndClear(sizeof(float) * (LOOPSIZE+16));
solad_init(w);
}
@@ -953,6 +521,25 @@
leaf_free(w);
}
+void tSOLAD_initToPool (tSOLAD* const wp, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSOLAD* w = *wp = (_tSOLAD*) mpool_allocAndClear(sizeof(_tSOLAD), m->pool);
+
+ w->pitchfactor = 1.;
+ w->delaybuf = (float*) mpool_allocAndClear(sizeof(float) * (LOOPSIZE+16), m->pool);
+ solad_init(w);
+}
+
+void tSOLAD_freeFromPool (tSOLAD* const wp, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSOLAD* w = *wp;
+
+ mpool_free(w->delaybuf, m->pool);
+ mpool_free(w, m->pool);
+}
+
// send one block of input samples, receive one block of output samples
void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize)
{
@@ -1250,7 +837,645 @@
w->readlag = INITPERIOD;
w->blocksize = INITPERIOD;
}
+
//============================================================================================================
+// PITCHSHIFT
+//============================================================================================================
+
+static int pitchshift_attackdetect(_tPitchShift* ps)
+{
+ float envout;
+
+ _tPeriodDetection* p = *ps->p;
+
+ envout = tEnvPD_tick(&p->env);
+
+ if (envout >= 1.0f)
+ {
+ p->lastmax = p->max;
+ if (envout > p->max)
+ {
+ p->max = envout;
+ }
+ else
+ {
+ p->deltamax = envout - p->max;
+ p->max = p->max * ps->radius;
+ }
+ p->deltamax = p->max - p->lastmax;
+ }
+
+ p->fba = p->fba ? (p->fba - 1) : 0;
+
+ return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
+}
+
+void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* pd, float* out, int bufSize)
+{
+ _tPitchShift* ps = *psr = (_tPitchShift*) leaf_allocAndClear(sizeof(_tPitchShift));
+ _tPeriodDetection* p = *pd;
+
+ ps->p = pd;
+
+ ps->outBuffer = out;
+ ps->bufSize = bufSize;
+ ps->frameSize = p->frameSize;
+ ps->framesPerBuffer = ps->bufSize / ps->frameSize;
+ ps->curBlock = 1;
+ ps->lastBlock = 0;
+ ps->index = 0;
+ ps->pitchFactor = 1.0f;
+
+ tSOLAD_init(&ps->sola);
+
+ tHighpass_init(&ps->hp, HPFREQ);
+
+ tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
+}
+
+void tPitchShift_free(tPitchShift* const psr)
+{
+ _tPitchShift* ps = *psr;
+
+ tSOLAD_free(&ps->sola);
+ tHighpass_free(&ps->hp);
+ leaf_free(ps);
+}
+
+void tPitchShift_initToPool (tPitchShift* const psr, tPeriodDetection* const pd, float* out, int bufSize, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPitchShift* ps = *psr = (_tPitchShift*) mpool_allocAndClear(sizeof(_tPitchShift), m->pool);
+ _tPeriodDetection* p = *pd;
+
+ ps->p = pd;
+
+ ps->outBuffer = out;
+ ps->bufSize = bufSize;
+ ps->frameSize = p->frameSize;
+ ps->framesPerBuffer = ps->bufSize / ps->frameSize;
+ ps->curBlock = 1;
+ ps->lastBlock = 0;
+ ps->index = 0;
+ ps->pitchFactor = 1.0f;
+
+ tSOLAD_initToPool(&ps->sola, mp);
+
+ tHighpass_initToPool(&ps->hp, HPFREQ, mp);
+
+ tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
+}
+
+void tPitchShift_freeFromPool (tPitchShift* const psr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPitchShift* ps = *psr;
+
+ tSOLAD_freeFromPool(&ps->sola, mp);
+ tHighpass_freeFromPool(&ps->hp, mp);
+ mpool_free(ps, m->pool);
+}
+
+void tPitchShift_setPitchFactor(tPitchShift* psr, float pf)
+{
+ _tPitchShift* ps = *psr;
+
+ ps->pitchFactor = pf;
+}
+
+float tPitchShift_shift (tPitchShift* psr)
+{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
+ float period, out;
+ int i, iLast;
+
+ i = p->i;
+ iLast = p->iLast;
+
+ out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
+
+ if (p->indexstore >= ps->frameSize)
+ {
+ period = p->period;
+
+ if(pitchshift_attackdetect(ps) == 1)
+ {
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
+ }
+
+ tSOLAD_setPeriod(&ps->sola, period);
+ tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
+
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+ }
+
+ return out;
+}
+
+float tPitchShift_shiftToFreq (tPitchShift* psr, float freq)
+{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
+ float period, out;
+ int i, iLast;
+
+ i = p->i;
+ iLast = p->iLast;
+
+ out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
+
+ if (p->indexstore >= ps->frameSize)
+ {
+ period = p->period;
+
+ if(pitchshift_attackdetect(ps) == 1)
+ {
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
+ }
+
+ tSOLAD_setPeriod(&ps->sola, period);
+
+ if (period != 0) ps->pitchFactor = period*freq*leaf.invSampleRate;
+ else ps->pitchFactor = 1.0f;
+
+ tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
+
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+ }
+ return out;
+}
+
+float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float))
+{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
+ float period, out;
+ int i, iLast;
+
+ i = p->i;
+ iLast = p->iLast;
+
+ out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
+
+ if (p->indexstore >= ps->frameSize)
+ {
+ period = p->period;
+
+ if(pitchshift_attackdetect(ps) == 1)
+ {
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
+ }
+
+ tSOLAD_setPeriod(&ps->sola, period);
+
+ ps->pitchFactor = period/fun(period);
+ tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
+
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+
+ ps->curBlock++;
+ if (ps->curBlock >= p->framesPerBuffer) ps->curBlock = 0;
+ ps->lastBlock++;
+ if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
+ }
+
+ return out;
+}
+
+//============================================================================================================
+// RETUNE
+//============================================================================================================
+
+void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)
+{
+ _tRetune* r = *rt = (_tRetune*) leaf_allocAndClear(sizeof(_tRetune));
+
+ r->bufSize = bufSize;
+ r->frameSize = frameSize;
+ r->numVoices = numVoices;
+
+ r->inBuffer = (float*) leaf_allocAndClear(sizeof(float) * r->bufSize);
+ r->outBuffers = (float**) leaf_allocAndClear(sizeof(float*) * r->numVoices);
+
+ r->hopSize = DEFHOPSIZE;
+ r->windowSize = DEFWINDOWSIZE;
+ r->fba = FBA;
+ tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
+
+ r->inputPeriod = 0.0f;
+
+ r->ps = (tPitchShift*) leaf_allocAndClear(sizeof(tPitchShift) * r->numVoices);
+ r->pitchFactor = (float*) leaf_allocAndClear(sizeof(float) * r->numVoices);
+ r->tickOutput = (float*) leaf_allocAndClear(sizeof(float) * r->numVoices);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) leaf_allocAndClear(sizeof(float) * r->bufSize);
+ }
+
+ tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
+ }
+}
+
+void tRetune_free(tRetune* const rt)
+{
+ _tRetune* r = *rt;
+
+ tPeriodDetection_free(&r->pd);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_free(&r->ps[i]);
+ leaf_free(r->outBuffers[i]);
+ }
+ leaf_free(r->tickOutput);
+ leaf_free(r->pitchFactor);
+ leaf_free(r->ps);
+ leaf_free(r->inBuffer);
+ leaf_free(r->outBuffers);
+ leaf_free(r);
+}
+
+void tRetune_initToPool (tRetune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tRetune* r = *rt = (_tRetune*) mpool_alloc(sizeof(_tRetune), m->pool);
+
+ r->bufSize = bufSize;
+ r->frameSize = frameSize;
+ r->numVoices = numVoices;
+
+ r->inBuffer = (float*) mpool_allocAndClear(sizeof(float) * r->bufSize, m->pool);
+ r->outBuffers = (float**) mpool_allocAndClear(sizeof(float*) * r->numVoices, m->pool);
+
+ r->hopSize = DEFHOPSIZE;
+ r->windowSize = DEFWINDOWSIZE;
+ r->fba = FBA;
+ tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
+
+ r->inputPeriod = 0.0f;
+
+ r->ps = (tPitchShift*) mpool_allocAndClear(sizeof(tPitchShift) * r->numVoices, m->pool);
+ r->pitchFactor = (float*) mpool_allocAndClear(sizeof(float) * r->numVoices, m->pool);
+ r->tickOutput = (float*) mpool_allocAndClear(sizeof(float) * r->numVoices, m->pool);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) mpool_allocAndClear(sizeof(float) * r->bufSize, m->pool);
+ }
+
+ tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
+ }
+}
+
+void tRetune_freeFromPool (tRetune* const rt, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tRetune* r = *rt;
+
+ tPeriodDetection_freeFromPool(&r->pd, mp);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_freeFromPool(&r->ps[i], mp);
+ mpool_free(r->outBuffers[i], m->pool);
+ }
+ mpool_free(r->tickOutput, m->pool);
+ mpool_free(r->pitchFactor, m->pool);
+ mpool_free(r->ps, m->pool);
+ mpool_free(r->inBuffer, m->pool);
+ mpool_free(r->outBuffers, m->pool);
+ mpool_free(r, m->pool);
+}
+
+float* tRetune_tick(tRetune* const rt, float sample)
+{
+ _tRetune* r = *rt;
+
+ r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
+
+ for (int v = 0; v < r->numVoices; ++v)
+ {
+ r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
+ }
+
+ return r->tickOutput;
+}
+
+void tRetune_setNumVoices(tRetune* const rt, int numVoices)
+{
+ _tRetune* r = *rt;
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_free(&r->ps[i]);
+ leaf_free(r->outBuffers[i]);
+ }
+ leaf_free(r->tickOutput);
+ leaf_free(r->pitchFactor);
+ leaf_free(r->ps);
+ leaf_free(r->outBuffers);
+
+ r->numVoices = numVoices;
+
+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
+ r->pitchFactor = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
+ }
+
+
+}
+
+void tRetune_setPitchFactors(tRetune* const rt, float pf)
+{
+ _tRetune* r = *rt;
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->pitchFactor[i] = pf;
+ tPitchShift_setPitchFactor(&r->ps[i], r->pitchFactor[i]);
+ }
+}
+
+void tRetune_setPitchFactor(tRetune* const rt, float pf, int voice)
+{
+ _tRetune* r = *rt;
+
+ r->pitchFactor[voice] = pf;
+ tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
+}
+
+void tRetune_setTimeConstant(tRetune* const rt, float tc)
+{
+ _tRetune* r = *rt;
+
+ r->timeConstant = tc;
+ r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
+}
+
+void tRetune_setHopSize(tRetune* const rt, int hs)
+{
+ _tRetune* r = *rt;
+
+ r->hopSize = hs;
+ tPeriodDetection_setHopSize(&r->pd, r->hopSize);
+}
+
+void tRetune_setWindowSize(tRetune* const rt, int ws)
+{
+ _tRetune* r = *rt;
+
+ r->windowSize = ws;
+ tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
+}
+
+float tRetune_getInputPeriod(tRetune* const rt)
+{
+ _tRetune* r = *rt;
+
+ return r->inputPeriod;
+}
+
+float tRetune_getInputFreq(tRetune* const rt)
+{
+ _tRetune* r = *rt;
+
+ return 1.0f/r->inputPeriod;
+}
+
+//============================================================================================================
+// AUTOTUNE
+//============================================================================================================
+
+void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)
+{
+ _tAutotune* r = *rt = (_tAutotune*) leaf_alloc(sizeof(_tAutotune));
+
+ r->bufSize = bufSize;
+ r->frameSize = frameSize;
+ r->numVoices = numVoices;
+
+ r->inBuffer = (float*) leaf_alloc(sizeof(float) * r->bufSize);
+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
+
+ r->hopSize = DEFHOPSIZE;
+ r->windowSize = DEFWINDOWSIZE;
+ r->fba = FBA;
+ tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
+
+
+
+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
+ r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
+ }
+
+ tPeriodDetection_init(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize);
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
+ }
+
+ r->inputPeriod = 0.0f;
+}
+
+void tAutotune_free(tAutotune* const rt)
+{
+ _tAutotune* r = *rt;
+
+ tPeriodDetection_free(&r->pd);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_free(&r->ps[i]);
+ leaf_free(r->outBuffers[i]);
+ }
+ leaf_free(r->tickOutput);
+ leaf_free(r->freq);
+ leaf_free(r->ps);
+ leaf_free(r->inBuffer);
+ leaf_free(r->outBuffers);
+ leaf_free(r);
+}
+
+void tAutotune_initToPool (tAutotune* const rt, int numVoices, int bufSize, int frameSize, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAutotune* r = *rt = (_tAutotune*) mpool_alloc(sizeof(_tAutotune), m->pool);
+
+ r->bufSize = bufSize;
+ r->frameSize = frameSize;
+ r->numVoices = numVoices;
+
+ r->inBuffer = (float*) mpool_alloc(sizeof(float) * r->bufSize, m->pool);
+ r->outBuffers = (float**) mpool_alloc(sizeof(float*) * r->numVoices, m->pool);
+
+ r->hopSize = DEFHOPSIZE;
+ r->windowSize = DEFWINDOWSIZE;
+ r->fba = FBA;
+ tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
+
+
+
+ r->ps = (tPitchShift*) mpool_alloc(sizeof(tPitchShift) * r->numVoices, m->pool);
+ r->freq = (float*) mpool_alloc(sizeof(float) * r->numVoices, m->pool);
+ r->tickOutput = (float*) mpool_alloc(sizeof(float) * r->numVoices, m->pool);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) mpool_alloc(sizeof(float) * r->bufSize, m->pool);
+ }
+
+ tPeriodDetection_initToPool(&r->pd, r->inBuffer, r->outBuffers[0], r->bufSize, r->frameSize, mp);
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_initToPool(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize, mp);
+ }
+
+ r->inputPeriod = 0.0f;
+}
+
+void tAutotune_freeFromPool (tAutotune* const rt, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAutotune* r = *rt;
+
+ tPeriodDetection_freeFromPool(&r->pd, mp);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_freeFromPool(&r->ps[i], mp);
+ mpool_free(r->outBuffers[i], m->pool);
+ }
+ mpool_free(r->tickOutput, m->pool);
+ mpool_free(r->freq, m->pool);
+ mpool_free(r->ps, m->pool);
+ mpool_free(r->inBuffer, m->pool);
+ mpool_free(r->outBuffers, m->pool);
+ mpool_free(r, m->pool);
+}
+
+float* tAutotune_tick(tAutotune* const rt, float sample)
+{
+ _tAutotune* r = *rt;
+
+ float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
+ if (tempPeriod < 1000.0f) //to avoid trying to follow consonants JS
+ {
+ r->inputPeriod = tempPeriod;
+ }
+
+ for (int v = 0; v < r->numVoices; ++v)
+ {
+ r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
+ }
+
+ return r->tickOutput;
+}
+
+void tAutotune_setNumVoices(tAutotune* const rt, int numVoices)
+{
+ _tAutotune* r = *rt;
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ tPitchShift_free(&r->ps[i]);
+ leaf_free(r->outBuffers[i]);
+ }
+ leaf_free(r->tickOutput);
+ leaf_free(r->freq);
+ leaf_free(r->ps);
+ leaf_free(r->outBuffers);
+
+ r->numVoices = numVoices;
+
+ r->outBuffers = (float**) leaf_alloc(sizeof(float*) * r->numVoices);
+ r->ps = (tPitchShift*) leaf_alloc(sizeof(tPitchShift) * r->numVoices);
+ r->freq = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ r->tickOutput = (float*) leaf_alloc(sizeof(float) * r->numVoices);
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->outBuffers[i] = (float*) leaf_alloc(sizeof(float) * r->bufSize);
+ tPitchShift_init(&r->ps[i], &r->pd, r->outBuffers[i], r->bufSize);
+ }
+
+
+}
+
+void tAutotune_setFreqs(tAutotune* const rt, float f)
+{
+ _tAutotune* r = *rt;
+
+ for (int i = 0; i < r->numVoices; ++i)
+ {
+ r->freq[i] = f;
+ }
+}
+
+void tAutotune_setFreq(tAutotune* const rt, float f, int voice)
+{
+ _tAutotune* r = *rt;
+
+ r->freq[voice] = f;
+}
+
+void tAutotune_setTimeConstant(tAutotune* const rt, float tc)
+{
+ _tAutotune* r = *rt;
+
+ r->timeConstant = tc;
+ r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
+}
+
+void tAutotune_setHopSize(tAutotune* const rt, int hs)
+{
+ _tAutotune* r = *rt;
+
+ r->hopSize = hs;
+ tPeriodDetection_setHopSize(&r->pd, r->hopSize);
+}
+
+void tAutotune_setWindowSize(tAutotune* const rt, int ws)
+{
+ _tAutotune* r = *rt;
+
+ r->windowSize = ws;
+ tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
+}
+
+float tAutotune_getInputPeriod(tAutotune* const rt)
+{
+ _tAutotune* r = *rt;
+
+ return r->inputPeriod;
+}
+
+float tAutotune_getInputFreq(tAutotune* const rt)
+{
+ _tAutotune* r = *rt;
+
+ return 1.0f/r->inputPeriod;
+}
+
+//============================================================================================================
// FORMANTSHIFTER
//============================================================================================================
// algorithm from Tom Baran's autotalent code.
@@ -1289,8 +1514,8 @@
fs->invIntensity = 1.0f;
tHighpass_init(&fs->hp, 20.0f);
tHighpass_init(&fs->hp2, 20.0f);
- tFeedbackLeveler_init(&fs->fbl1, 0.8f, .005f, 0.125, 1);
- tFeedbackLeveler_init(&fs->fbl2, 0.8f, .005f, 0.125, 1);
+ tFeedbackLeveler_init(&fs->fbl1, 0.8f, 0.01f, 0.125f, 0);
+ tFeedbackLeveler_init(&fs->fbl2, 0.8f, 0.01f, 0.125f, 0);
}
void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1317,7 +1542,69 @@
leaf_free(fs);
}
+void tFormantShifter_initToPool (tFormantShifter* const fsr, int bufsize, int order, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFormantShifter* fs = *fsr = (_tFormantShifter*) mpool_alloc(sizeof(_tFormantShifter), m->pool);
+
+ fs->ford = order;
+ fs->bufsize = bufsize;
+ fs->fk = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->fb = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->fc = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->frb = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->frc = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->fsig = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->fsmooth = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+ fs->ftvec = (float*) mpool_alloc(sizeof(float) * fs->ford, m->pool);
+
+ fs->fbuff = (float**) mpool_alloc(sizeof(float*) * fs->ford, m->pool);
+ for (int i = 0; i < fs->ford; i++)
+ {
+ fs->fbuff[i] = (float*) mpool_alloc(sizeof(float) * fs->bufsize, m->pool);
+ }
+
+ fs->falph = powf(0.001f, 80.0f / (leaf.sampleRate));
+ fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
+ fs->fhp = 0.0f;
+ fs->flp = 0.0f;
+ fs->flpa = powf(0.001f, 10.0f / (leaf.sampleRate));
+ fs->fmute = 1.0f;
+ fs->fmutealph = powf(0.001f, 1.0f / (leaf.sampleRate));
+ fs->cbi = 0;
+ fs->intensity = 1.0f;
+ fs->invIntensity = 1.0f;
+ tHighpass_initToPool(&fs->hp, 20.0f, mp);
+ tHighpass_initToPool(&fs->hp2, 20.0f, mp);
+ tFeedbackLeveler_initToPool(&fs->fbl1, 0.8f, .005f, 0.125, 1, mp);
+ tFeedbackLeveler_initToPool(&fs->fbl2, 0.8f, .005f, 0.125, 1, mp);
+}
+void tFormantShifter_freeFromPool (tFormantShifter* const fsr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFormantShifter* fs = *fsr;
+
+ mpool_free(fs->fk, m->pool);
+ mpool_free(fs->fb, m->pool);
+ mpool_free(fs->fc, m->pool);
+ mpool_free(fs->frb, m->pool);
+ mpool_free(fs->frc, m->pool);
+ mpool_free(fs->fsig, m->pool);
+ mpool_free(fs->fsmooth, m->pool);
+ mpool_free(fs->ftvec, m->pool);
+ for (int i = 0; i < fs->ford; i++)
+ {
+ mpool_free(fs->fbuff[i], m->pool);
+ }
+ mpool_free(fs->fbuff, m->pool);
+ tHighpass_freeFromPool(&fs->hp, mp);
+ tHighpass_freeFromPool(&fs->hp2, mp);
+ tFeedbackLeveler_freeFromPool(&fs->fbl1, mp);
+ tFeedbackLeveler_freeFromPool(&fs->fbl2, mp);
+ mpool_free(fs, m->pool);
+}
+
float tFormantShifter_tick(tFormantShifter* const fsr, float in)
{
return tFormantShifter_add(fsr, tFormantShifter_remove(fsr, in));
@@ -1326,8 +1613,8 @@
float tFormantShifter_remove(tFormantShifter* const fsr, float in)
{
_tFormantShifter* fs = *fsr;
- in = tFeedbackLeveler_tick(&fs->fbl1, in);
- in = tHighpass_tick(&fs->hp, tanhf(in * fs->intensity));
+ in = tFeedbackLeveler_tick(&fs->fbl1, in * fs->intensity);
+ in = tHighpass_tick(&fs->hp, in);
float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
@@ -1363,8 +1650,8 @@
{
fs->cbi = 0;
}
-
- return fa * fs->invIntensity;
+ return fa;
+ //return fa * fs->invIntensity;
}
float tFormantShifter_add(tFormantShifter* const fsr, float in)
@@ -1460,8 +1747,8 @@
fs->fmute = (1.0f-tf2) + tf2*fs->fmute;
// now tf is signal output
// ...and we're done messing with formants
- tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
- //tf = tHighpass_tick(&fs->hp2, tanhf(tf));
+ //tf = tFeedbackLeveler_tick(&fs->fbl2, tf);
+ tf = tHighpass_tick(&fs->hp2, tanhf(tf));
return tf;
}
--- a/LEAF/Src/leaf-electrical.c
+++ b/LEAF/Src/leaf-electrical.c
@@ -45,22 +45,21 @@
static float get_reflected_wave_for_diode(tWDF* const n, float input, float incident_wave);
static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave);
-//WDF
-void tWDF_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
+static void wdf_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
{
- _tWDF* r = *wdf = (_tWDF*) leaf_alloc(sizeof(_tWDF));
+ _tWDF* r = *wdf;
- r->type = type;
+ r->type = type;
r->child_left = rL;
r->child_right = rR;
- r->incident_wave_up = 0.0f;
- r->incident_wave_left = 0.0f;
- r->incident_wave_right = 0.0f;
- r->reflected_wave_up = 0.0f;
- r->reflected_wave_left = 0.0f;
- r->reflected_wave_right = 0.0f;
- r->sample_rate = leaf.sampleRate;
- r->value = value;
+ r->incident_wave_up = 0.0f;
+ r->incident_wave_left = 0.0f;
+ r->incident_wave_right = 0.0f;
+ r->reflected_wave_up = 0.0f;
+ r->reflected_wave_left = 0.0f;
+ r->reflected_wave_right = 0.0f;
+ r->sample_rate = leaf.sampleRate;
+ r->value = value;
tWDF* child;
if (r->child_left != NULL) child = r->child_left;
@@ -67,23 +66,23 @@
else child = r->child_right;
if (r->type == Resistor)
- {
- r->port_resistance_up = r->value;
- r->port_conductance_up = 1.0f / r->value;
-
- r->get_port_resistance = &get_port_resistance_for_resistor;
- r->get_reflected_wave_up = &get_reflected_wave_for_resistor;
- r->set_incident_wave = &set_incident_wave_for_leaf;
- }
- else if (r->type == Capacitor)
- {
+ {
+ r->port_resistance_up = r->value;
+ r->port_conductance_up = 1.0f / r->value;
+
+ r->get_port_resistance = &get_port_resistance_for_resistor;
+ r->get_reflected_wave_up = &get_reflected_wave_for_resistor;
+ r->set_incident_wave = &set_incident_wave_for_leaf;
+ }
+ else if (r->type == Capacitor)
+ {
r->port_conductance_up = r->sample_rate * 2.0f * r->value;
- r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
-
- r->get_port_resistance = &get_port_resistance_for_capacitor;
- r->get_reflected_wave_up = &get_reflected_wave_for_capacitor;
- r->set_incident_wave = &set_incident_wave_for_leaf;
- }
+ r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
+
+ r->get_port_resistance = &get_port_resistance_for_capacitor;
+ r->get_reflected_wave_up = &get_reflected_wave_for_capacitor;
+ r->set_incident_wave = &set_incident_wave_for_leaf;
+ }
else if (r->type == Inductor)
{
r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
@@ -93,8 +92,8 @@
r->get_reflected_wave_up = &get_reflected_wave_for_capacitor; // same as capacitor
r->set_incident_wave = &set_incident_wave_for_leaf_inverted;
}
- else if (r->type == ResistiveSource)
- {
+ else if (r->type == ResistiveSource)
+ {
r->port_resistance_up = r->value;
r->port_conductance_up = 1.0f / r->port_resistance_up;
@@ -101,7 +100,7 @@
r->get_port_resistance = &get_port_resistance_for_resistive;
r->get_reflected_wave_up = &get_reflected_wave_for_resistive;
r->set_incident_wave = &set_incident_wave_for_leaf;
- }
+ }
else if (r->type == Inverter)
{
r->port_resistance_up = tWDF_getPortResistance(r->child_left);
@@ -164,6 +163,13 @@
r->get_port_resistance = &get_port_resistance_for_root;
}
}
+//WDF
+void tWDF_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
+{
+ *wdf = (_tWDF*) leaf_alloc(sizeof(_tWDF));
+
+ wdf_init(wdf, type, value, rL, rR);
+}
void tWDF_free(tWDF* const wdf)
{
@@ -170,6 +176,22 @@
_tWDF* r = *wdf;
leaf_free(r);
+}
+
+void tWDF_initToPool (tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ *wdf = (_tWDF*) mpool_alloc(sizeof(_tWDF), m->pool);
+
+ wdf_init(wdf, type, value, rL, rR);
+}
+
+void tWDF_freeFromPool (tWDF* const wdf, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tWDF* r = *wdf;
+
+ mpool_free(r, m->pool);
}
float tWDF_tick(tWDF* const wdf, float sample, tWDF* const outputPoint, uint8_t paramsChanged)
--- a/LEAF/Src/leaf-envelopes.c
+++ b/LEAF/Src/leaf-envelopes.c
@@ -62,7 +62,6 @@
env->attackInc = env->inc_buff[attackIndex];
env->decayInc = env->inc_buff[decayIndex];
env->rampInc = env->inc_buff[rampIndex];
-
}
void tEnvelope_free(tEnvelope* const envlp)
@@ -71,6 +70,54 @@
leaf_free(env);
}
+void tEnvelope_initToPool (tEnvelope* const envlp, float attack, float decay, oBool loop, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEnvelope* env = *envlp = (_tEnvelope*) mpool_alloc(sizeof(_tEnvelope), m->pool);
+
+ env->exp_buff = exp_decay;
+ env->inc_buff = attack_decay_inc;
+ env->buff_size = sizeof(exp_decay);
+
+ env->loop = loop;
+
+ if (attack > 8192.0f)
+ attack = 8192.0f;
+ if (attack < 0.0f)
+ attack = 0.0f;
+
+ if (decay > 8192.0f)
+ decay = 8192.0f;
+ if (decay < 0.0f)
+ decay = 0.0f;
+
+ int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
+ int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
+ int16_t rampIndex = ((int16_t)(2.0f * 8.0f))-1;
+
+ if (attackIndex < 0)
+ attackIndex = 0;
+ if (decayIndex < 0)
+ decayIndex = 0;
+ if (rampIndex < 0)
+ rampIndex = 0;
+
+ env->inRamp = OFALSE;
+ env->inAttack = OFALSE;
+ env->inDecay = OFALSE;
+
+ env->attackInc = env->inc_buff[attackIndex];
+ env->decayInc = env->inc_buff[decayIndex];
+ env->rampInc = env->inc_buff[rampIndex];
+}
+
+void tEnvelope_freeFromPool (tEnvelope* const envlp, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEnvelope* env = *envlp;
+ mpool_free(env, m->pool);
+}
+
void tEnvelope_setAttack(tEnvelope* const envlp, float attack)
{
_tEnvelope* env = *envlp;
@@ -270,6 +317,71 @@
leaf_free(adsr);
}
+void tADSR_initToPool (tADSR* const adsrenv, float attack, float decay, float sustain, float release, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tADSR* adsr = *adsrenv = (_tADSR*) mpool_alloc(sizeof(_tADSR), m->pool);
+
+ adsr->exp_buff = exp_decay;
+ adsr->inc_buff = attack_decay_inc;
+ adsr->buff_size = sizeof(exp_decay);
+
+ if (attack > 8192.0f)
+ attack = 8192.0f;
+ if (attack < 0.0f)
+ attack = 0.0f;
+
+ if (decay > 8192.0f)
+ decay = 8192.0f;
+ if (decay < 0.0f)
+ decay = 0.0f;
+
+ if (sustain > 1.0f)
+ sustain = 1.0f;
+ if (sustain < 0.0f)
+ sustain = 0.0f;
+
+ if (release > 8192.0f)
+ release = 8192.0f;
+ if (release < 0.0f)
+ release = 0.0f;
+
+ int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
+ int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
+ int16_t releaseIndex = ((int16_t)(release * 8.0f))-1;
+ int16_t rampIndex = ((int16_t)(2.0f * 8.0f))-1;
+
+ if (attackIndex < 0)
+ attackIndex = 0;
+ if (decayIndex < 0)
+ decayIndex = 0;
+ if (releaseIndex < 0)
+ releaseIndex = 0;
+ if (rampIndex < 0)
+ rampIndex = 0;
+
+ adsr->inRamp = OFALSE;
+ adsr->inAttack = OFALSE;
+ adsr->inDecay = OFALSE;
+ adsr->inSustain = OFALSE;
+ adsr->inRelease = OFALSE;
+
+ adsr->sustain = sustain;
+
+ adsr->attackInc = adsr->inc_buff[attackIndex];
+ adsr->decayInc = adsr->inc_buff[decayIndex];
+ adsr->releaseInc = adsr->inc_buff[releaseIndex];
+ adsr->rampInc = adsr->inc_buff[rampIndex];
+}
+
+void tADSR_freeFromPool (tADSR* const adsrenv, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tADSR* adsr = *adsrenv;
+
+ mpool_free(adsr, m->pool);
+}
+
void tADSR_setAttack(tADSR* const adsrenv, float attack)
{
_tADSR* adsr = *adsrenv;
@@ -479,6 +591,37 @@
leaf_free(ramp);
}
+void tRamp_initToPool (tRamp* const r, float time, int samples_per_tick, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tRamp* ramp = *r = (_tRamp*) mpool_alloc(sizeof(_tRamp), m->pool);
+
+ ramp->inv_sr_ms = 1.0f/(leaf.sampleRate*0.001f);
+ ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
+ ramp->curr = 0.0f;
+ ramp->dest = 0.0f;
+
+ if (time < ramp->minimum_time)
+ {
+ ramp->time = ramp->minimum_time;
+ }
+ else
+ {
+ ramp->time = time;
+ }
+
+ ramp->samples_per_tick = samples_per_tick;
+ ramp->inc = ((ramp->dest - ramp->curr) / ramp->time * ramp->inv_sr_ms) * (float)ramp->samples_per_tick;
+}
+
+void tRamp_freeFromPool (tRamp* const r, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tRamp* ramp = *r;
+
+ mpool_free(ramp, m->pool);
+}
+
void tRamp_setTime(tRamp* const ramp, float time)
{
_tRamp* r = *ramp;
@@ -558,6 +701,27 @@
_tExpSmooth* smooth = *expsmooth;
leaf_free(smooth);
+}
+
+void tExpSmooth_initToPool (tExpSmooth* const expsmooth, float val, float factor, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tExpSmooth* smooth = *expsmooth = (_tExpSmooth*) mpool_alloc(sizeof(_tExpSmooth), m->pool);
+
+ smooth->curr=val;
+ smooth->dest=val;
+ if (factor<0) factor=0;
+ if (factor>1) factor=1;
+ smooth->factor=factor;
+ smooth->oneminusfactor=1.0f-factor;
+}
+
+void tExpSmooth_freeFromPool (tExpSmooth* const expsmooth, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tExpSmooth* smooth = *expsmooth;
+
+ mpool_free(smooth, m->pool);
}
void tExpSmooth_setFactor(tExpSmooth* const expsmooth, float factor)
--- a/LEAF/Src/leaf-filters.c
+++ b/LEAF/Src/leaf-filters.c
@@ -40,6 +40,27 @@
leaf_free(f);
}
+void tAllpass_initToPool (tAllpass* const ft, float initDelay, uint32_t maxDelay, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAllpass* f = *ft = (_tAllpass*) mpool_alloc(sizeof(_tAllpass), m->pool);
+
+ f->gain = 0.7f;
+
+ f->lastOut = 0.0f;
+
+ tLinearDelay_initToPool(&f->delay, initDelay, maxDelay, mp);
+}
+
+void tAllpass_freeFromPool (tAllpass* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tAllpass* f = *ft;
+
+ tLinearDelay_freeFromPool(&f->delay, mp);
+ mpool_free(f, m->pool);
+}
+
void tAllpass_setDelay(tAllpass* const ft, float delay)
{
_tAllpass* f = *ft;
@@ -67,79 +88,238 @@
return f->lastOut;
}
-void tButterworth_init(tButterworth* const ft, int N, float f1, float f2)
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tOnePole_init(tOnePole* const ft, float freq)
{
- _tButterworth* f = *ft = (_tButterworth*) leaf_alloc(sizeof(_tButterworth));
+ _tOnePole* f = *ft = (_tOnePole*) leaf_alloc(sizeof(_tOnePole));
- f->f1 = f1;
- f->f2 = f2;
- f->gain = 1.0f;
+ f->gain = 1.0f;
+ f->a0 = 1.0;
- f->N = N;
+ tOnePole_setFreq(ft, freq);
- if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW;
+ f->lastIn = 0.0f;
+ f->lastOut = 0.0f;
+}
- for(int i = 0; i < N/2; ++i)
- {
- tSVF_init(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
- tSVF_init(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
- }
+void tOnePole_free(tOnePole* const ft)
+{
+ _tOnePole* f = *ft;
+
+ leaf_free(f);
}
-void tButterworth_free(tButterworth* const ft)
+void tOnePole_initToPool (tOnePole* const ft, float freq, tMempool* const mp)
{
- _tButterworth* f = *ft;
+ _tMempool* m = *mp;
+ _tOnePole* f = *ft = (_tOnePole*) mpool_alloc(sizeof(_tOnePole), m->pool);
- for(int i = 0; i < f->N/2; ++i)
- {
- tSVF_free(&f->low[i]);
- tSVF_free(&f->high[i]);
- }
+ f->gain = 1.0f;
+ f->a0 = 1.0;
+ tOnePole_setFreq(ft, freq);
+
+ f->lastIn = 0.0f;
+ f->lastOut = 0.0f;
+}
+
+void tOnePole_freeFromPool (tOnePole* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tOnePole* f = *ft;
+
+ mpool_free(f, m->pool);
+}
+
+void tOnePole_setB0(tOnePole* const ft, float b0)
+{
+ _tOnePole* f = *ft;
+ f->b0 = b0;
+}
+
+void tOnePole_setA1(tOnePole* const ft, float a1)
+{
+ _tOnePole* f = *ft;
+ if (a1 >= 1.0f) a1 = 0.999999f;
+ f->a1 = a1;
+}
+
+void tOnePole_setPole(tOnePole* const ft, float thePole)
+{
+ _tOnePole* f = *ft;
+
+ if (thePole >= 1.0f) thePole = 0.999999f;
+
+ // Normalize coefficients for peak unity gain.
+ if (thePole > 0.0f) f->b0 = (1.0f - thePole);
+ else f->b0 = (1.0f + thePole);
+
+ f->a1 = -thePole;
+}
+
+void tOnePole_setFreq (tOnePole* const ft, float freq)
+{
+ _tOnePole* f = *ft;
+ f->b0 = freq * leaf.twoPiTimesInvSampleRate;
+ f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+ f->a1 = 1.0f - f->b0;
+}
+
+void tOnePole_setCoefficients(tOnePole* const ft, float b0, float a1)
+{
+ _tOnePole* f = *ft;
+ if (a1 >= 1.0f) a1 = 0.999999f;
+ f->b0 = b0;
+ f->a1 = a1;
+}
+
+void tOnePole_setGain(tOnePole* const ft, float gain)
+{
+ _tOnePole* f = *ft;
+ f->gain = gain;
+}
+
+float tOnePole_tick(tOnePole* const ft, float input)
+{
+ _tOnePole* f = *ft;
+
+ float in = input * f->gain;
+ float out = (f->b0 * in) + (f->a1 * f->lastOut);
+
+ f->lastIn = in;
+ f->lastOut = out;
+
+ return out;
+}
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tTwoPole_init(tTwoPole* const ft)
+{
+ _tTwoPole* f = *ft = (_tTwoPole*) leaf_alloc(sizeof(_tTwoPole));
+
+ f->gain = 1.0f;
+ f->a0 = 1.0;
+ f->b0 = 1.0;
+
+ f->lastOut[0] = 0.0f;
+ f->lastOut[1] = 0.0f;
+}
+
+void tTwoPole_free(tTwoPole* const ft)
+{
+ _tTwoPole* f = *ft;
+
leaf_free(f);
}
-float tButterworth_tick(tButterworth* const ft, float samp)
+void tTwoPole_initToPool (tTwoPole* const ft, tMempool* const mp)
{
- _tButterworth* f = *ft;
+ _tMempool* m = *mp;
+ _tTwoPole* f = *ft = (_tTwoPole*) mpool_alloc(sizeof(_tTwoPole), m->pool);
- for(int i = 0; i < ((f->N)/2); ++i)
- {
- samp = tSVF_tick(&f->low[i],samp);
- samp = tSVF_tick(&f->high[i],samp);
- }
- return samp;
+ f->gain = 1.0f;
+ f->a0 = 1.0;
+ f->b0 = 1.0;
+
+ f->lastOut[0] = 0.0f;
+ f->lastOut[1] = 0.0f;
}
-void tButterworth_setF1(tButterworth* const ft, float f1)
+void tTwoPole_freeFromPool (tTwoPole* const ft, tMempool* const mp)
{
- _tButterworth* f = *ft;
+ _tMempool* m = *mp;
+ _tTwoPole* f = *ft;
- f->f1 = f1;
- for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->low[i], f1);
+ mpool_free(f, m->pool);
}
-void tButterworth_setF2(tButterworth* const ft, float f2)
+float tTwoPole_tick(tTwoPole* const ft, float input)
{
- _tButterworth* f = *ft;
+ _tTwoPole* f = *ft;
- f->f2 = f2;
- for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->high[i], f2);
+ float in = input * f->gain;
+ float out = (f->b0 * in) - (f->a1 * f->lastOut[0]) - (f->a2 * f->lastOut[1]);
+
+ f->lastOut[1] = f->lastOut[0];
+ f->lastOut[0] = out;
+
+ return out;
}
-void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
+void tTwoPole_setB0(tTwoPole* const ft, float b0)
{
- _tButterworth* f = *ft;
+ _tTwoPole* f = *ft;
+ f->b0 = b0;
+}
+
+void tTwoPole_setA1(tTwoPole* const ft, float a1)
+{
+ _tTwoPole* f = *ft;
+ f->a1 = a1;
+}
+
+void tTwoPole_setA2(tTwoPole* const ft, float a2)
+{
+ _tTwoPole* f = *ft;
+ f->a2 = a2;
+}
+
+
+void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, oBool normalize)
+{
+ _tTwoPole* f = *ft;
- f->f1 = f1;
- f->f2 = f2;
- for(int i = 0; i < ((f->N)/2); ++i)
- {
- tSVF_setFreq(&f->low[i], f1);
- tSVF_setFreq(&f->high[i], f2);
- }
+ if (frequency < 0.0f) frequency = 0.0f;
+ if (frequency > (leaf.sampleRate * 0.49f)) frequency = leaf.sampleRate * 0.49f;
+ if (radius < 0.0f) radius = 0.0f;
+ if (radius >= 1.0f) radius = 0.999999f;
+
+ f->radius = radius;
+ f->frequency = frequency;
+ f->normalize = normalize;
+
+ f->a2 = radius * radius;
+ f->a1 = -2.0f * radius * cosf(frequency * leaf.twoPiTimesInvSampleRate);
+
+ if ( normalize )
+ {
+ // Normalize the filter gain ... not terribly efficient.
+ float real = 1 - radius + (f->a2 - radius) * cosf(2 * frequency * leaf.twoPiTimesInvSampleRate);
+ float imag = (f->a2 - radius) * sinf(2 * frequency * leaf.twoPiTimesInvSampleRate);
+ f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
+ }
}
+void tTwoPole_setCoefficients(tTwoPole* const ft, float b0, float a1, float a2)
+{
+ _tTwoPole* f = *ft;
+ f->b0 = b0;
+ f->a1 = a1;
+ f->a2 = a2;
+}
+
+void tTwoPole_setGain(tTwoPole* const ft, float gain)
+{
+ _tTwoPole* f = *ft;
+ f->gain = gain;
+}
+
+void tTwoPoleSampleRateChanged (tTwoPole* const ft)
+{
+ _tTwoPole* f = *ft;
+
+ f->a2 = f->radius * f->radius;
+ f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
+
+ if ( f->normalize )
+ {
+ // Normalize the filter gain ... not terribly efficient.
+ float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
+ float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
+ f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
+ }
+}
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OneZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
void tOneZero_init(tOneZero* const ft, float theZero)
{
@@ -158,6 +338,25 @@
leaf_free(f);
}
+void tOneZero_initToPool (tOneZero* const ft, float theZero, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tOneZero* f = *ft = (_tOneZero*) mpool_alloc(sizeof(_tOneZero), m->pool);
+
+ f->gain = 1.0f;
+ f->lastIn = 0.0f;
+ f->lastOut = 0.0f;
+ tOneZero_setZero(ft, theZero);
+}
+
+void tOneZero_freeFromPool (tOneZero* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tOneZero* f = *ft;
+
+ mpool_free(f, m->pool);
+}
+
float tOneZero_tick(tOneZero* const ft, float input)
{
_tOneZero* f = *ft;
@@ -254,6 +453,24 @@
leaf_free(f);
}
+void tTwoZero_initToPool (tTwoZero* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTwoZero* f = *ft = (_tTwoZero*) mpool_alloc(sizeof(_tTwoZero), m->pool);
+
+ f->gain = 1.0f;
+ f->lastIn[0] = 0.0f;
+ f->lastIn[1] = 0.0f;
+}
+
+void tTwoZero_freeFromPool (tTwoZero* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTwoZero* f = *ft;
+
+ mpool_free(f, m->pool);
+}
+
float tTwoZero_tick(tTwoZero* const ft, float input)
{
_tTwoZero* f = *ft;
@@ -324,202 +541,33 @@
tTwoZero_setNotch(ft, f->frequency, f->radius);
}
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tOnePole_init(tOnePole* const ft, float freq)
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PoleZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tPoleZero_init(tPoleZero* const pzf)
{
- _tOnePole* f = *ft = (_tOnePole*) leaf_alloc(sizeof(_tOnePole));
+ _tPoleZero* f = *pzf = (_tPoleZero*) leaf_alloc(sizeof(_tPoleZero));
f->gain = 1.0f;
+ f->b0 = 1.0;
f->a0 = 1.0;
-
- tOnePole_setFreq(ft, freq);
f->lastIn = 0.0f;
f->lastOut = 0.0f;
}
-void tOnePole_free(tOnePole* const ft)
+void tPoleZero_free(tPoleZero* const pzf)
{
- _tOnePole* f = *ft;
+ _tPoleZero* f = *pzf;
leaf_free(f);
}
-void tOnePole_setB0(tOnePole* const ft, float b0)
+void tPoleZero_initToPool (tPoleZero* const pzf, tMempool* const mp)
{
- _tOnePole* f = *ft;
- f->b0 = b0;
-}
-
-void tOnePole_setA1(tOnePole* const ft, float a1)
-{
- _tOnePole* f = *ft;
- if (a1 >= 1.0f) a1 = 0.999999f;
- f->a1 = a1;
-}
-
-void tOnePole_setPole(tOnePole* const ft, float thePole)
-{
- _tOnePole* f = *ft;
+ _tMempool* m = *mp;
+ _tPoleZero* f = *pzf = (_tPoleZero*) mpool_alloc(sizeof(_tPoleZero), m->pool);
- if (thePole >= 1.0f) thePole = 0.999999f;
-
- // Normalize coefficients for peak unity gain.
- if (thePole > 0.0f) f->b0 = (1.0f - thePole);
- else f->b0 = (1.0f + thePole);
-
- f->a1 = -thePole;
-}
-
-void tOnePole_setFreq (tOnePole* const ft, float freq)
-{
- _tOnePole* f = *ft;
- f->b0 = freq * leaf.twoPiTimesInvSampleRate;
- f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
- f->a1 = 1.0f - f->b0;
-}
-
-void tOnePole_setCoefficients(tOnePole* const ft, float b0, float a1)
-{
- _tOnePole* f = *ft;
- if (a1 >= 1.0f) a1 = 0.999999f;
- f->b0 = b0;
- f->a1 = a1;
-}
-
-void tOnePole_setGain(tOnePole* const ft, float gain)
-{
- _tOnePole* f = *ft;
- f->gain = gain;
-}
-
-float tOnePole_tick(tOnePole* const ft, float input)
-{
- _tOnePole* f = *ft;
-
- float in = input * f->gain;
- float out = (f->b0 * in) + (f->a1 * f->lastOut);
-
- f->lastIn = in;
- f->lastOut = out;
-
- return out;
-}
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tTwoPole_init(tTwoPole* const ft)
-{
- _tTwoPole* f = *ft = (_tTwoPole*) leaf_alloc(sizeof(_tTwoPole));
-
f->gain = 1.0f;
- f->a0 = 1.0;
f->b0 = 1.0;
-
- f->lastOut[0] = 0.0f;
- f->lastOut[1] = 0.0f;
-}
-
-void tTwoPole_free(tTwoPole* const ft)
-{
- _tTwoPole* f = *ft;
-
- leaf_free(f);
-}
-
-float tTwoPole_tick(tTwoPole* const ft, float input)
-{
- _tTwoPole* f = *ft;
-
- float in = input * f->gain;
- float out = (f->b0 * in) - (f->a1 * f->lastOut[0]) - (f->a2 * f->lastOut[1]);
-
- f->lastOut[1] = f->lastOut[0];
- f->lastOut[0] = out;
-
- return out;
-}
-
-void tTwoPole_setB0(tTwoPole* const ft, float b0)
-{
- _tTwoPole* f = *ft;
- f->b0 = b0;
-}
-
-void tTwoPole_setA1(tTwoPole* const ft, float a1)
-{
- _tTwoPole* f = *ft;
- f->a1 = a1;
-}
-
-void tTwoPole_setA2(tTwoPole* const ft, float a2)
-{
- _tTwoPole* f = *ft;
- f->a2 = a2;
-}
-
-
-void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, oBool normalize)
-{
- _tTwoPole* f = *ft;
-
- if (frequency < 0.0f) frequency = 0.0f;
- if (frequency > (leaf.sampleRate * 0.49f)) frequency = leaf.sampleRate * 0.49f;
- if (radius < 0.0f) radius = 0.0f;
- if (radius >= 1.0f) radius = 0.999999f;
-
- f->radius = radius;
- f->frequency = frequency;
- f->normalize = normalize;
-
- f->a2 = radius * radius;
- f->a1 = -2.0f * radius * cosf(frequency * leaf.twoPiTimesInvSampleRate);
-
- if ( normalize )
- {
- // Normalize the filter gain ... not terribly efficient.
- float real = 1 - radius + (f->a2 - radius) * cosf(2 * frequency * leaf.twoPiTimesInvSampleRate);
- float imag = (f->a2 - radius) * sinf(2 * frequency * leaf.twoPiTimesInvSampleRate);
- f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
- }
-}
-
-void tTwoPole_setCoefficients(tTwoPole* const ft, float b0, float a1, float a2)
-{
- _tTwoPole* f = *ft;
- f->b0 = b0;
- f->a1 = a1;
- f->a2 = a2;
-}
-
-void tTwoPole_setGain(tTwoPole* const ft, float gain)
-{
- _tTwoPole* f = *ft;
- f->gain = gain;
-}
-
-void tTwoPoleSampleRateChanged (tTwoPole* const ft)
-{
- _tTwoPole* f = *ft;
-
- f->a2 = f->radius * f->radius;
- f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
-
- if ( f->normalize )
- {
- // Normalize the filter gain ... not terribly efficient.
- float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
- float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
- f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
- }
-}
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PoleZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tPoleZero_init(tPoleZero* const pzf)
-{
- _tPoleZero* f = *pzf = (_tPoleZero*) leaf_alloc(sizeof(_tPoleZero));
-
- f->gain = 1.0f;
- f->b0 = 1.0;
f->a0 = 1.0;
f->lastIn = 0.0f;
@@ -526,11 +574,12 @@
f->lastOut = 0.0f;
}
-void tPoleZero_free(tPoleZero* const pzf)
+void tPoleZero_freeFromPool (tPoleZero* const pzf, tMempool* const mp)
{
+ _tMempool* m = *mp;
_tPoleZero* f = *pzf;
- leaf_free(f);
+ mpool_free(f, m->pool);
}
void tPoleZero_setB0(tPoleZero* const pzf, float b0)
@@ -643,6 +692,30 @@
leaf_free(f);
}
+void tBiQuad_initToPool (tBiQuad* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tBiQuad* f = *ft = (_tBiQuad*) mpool_alloc(sizeof(_tBiQuad), m->pool);
+
+ f->gain = 1.0f;
+
+ f->b0 = 0.0f;
+ f->a0 = 0.0f;
+
+ f->lastIn[0] = 0.0f;
+ f->lastIn[1] = 0.0f;
+ f->lastOut[0] = 0.0f;
+ f->lastOut[1] = 0.0f;
+}
+
+void tBiQuad_freeFromPool (tBiQuad* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tBiQuad* f = *ft;
+
+ mpool_free(f, m->pool);
+}
+
float tBiQuad_tick(tBiQuad* const ft, float input)
{
_tBiQuad* f = *ft;
@@ -766,59 +839,35 @@
}
}
-/* Highpass */
-void tHighpass_init(tHighpass* const ft, float freq)
+// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanf
+// is calculated when frequency changes.
+void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q)
{
- _tHighpass* f = *ft = (_tHighpass*) leaf_alloc(sizeof(_tHighpass));
+ _tSVF* svf = *svff = (_tSVF*) leaf_alloc(sizeof(_tSVF));
- f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
- f->ys = 0.0f;
- f->xs = 0.0f;
+ svf->type = type;
- f->frequency = freq;
-}
-
-void tHighpass_free(tHighpass* const ft)
-{
- _tHighpass* f = *ft;
+ svf->ic1eq = 0;
+ svf->ic2eq = 0;
- leaf_free(f);
+ svf->g = tanf(PI * freq * leaf.invSampleRate);
+ svf->k = 1.0f/Q;
+ svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
+ svf->a2 = svf->g*svf->a1;
+ svf->a3 = svf->g*svf->a2;
}
-void tHighpass_setFreq(tHighpass* const ft, float freq)
+void tSVF_free(tSVF* const svff)
{
- _tHighpass* f = *ft;
- f->frequency = freq;
- f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
+ _tSVF* svf = *svff;
+ leaf_free(svf);
}
-float tHighpass_getFreq(tHighpass* const ft)
+void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q, tMempool* const mp)
{
- _tHighpass* f = *ft;
- return f->frequency;
-}
-
-// From JOS DC Blocker
-float tHighpass_tick(tHighpass* const ft, float x)
-{
- _tHighpass* f = *ft;
- f->ys = x - f->xs + f->R * f->ys;
- f->xs = x;
- return f->ys;
-}
-
-void tHighpassSampleRateChanged(tHighpass* const ft)
-{
- _tHighpass* f = *ft;
- f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf.invSampleRate));
-}
-
-// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanf
-// is calculated when frequency changes.
-void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q)
-{
- _tSVF* svf = *svff = (_tSVF*) leaf_alloc(sizeof(_tSVF));
+ _tMempool* m = *mp;
+ _tSVF* svf = *svff = (_tSVF*) mpool_alloc(sizeof(_tSVF), m->pool);
svf->type = type;
@@ -825,19 +874,19 @@
svf->ic1eq = 0;
svf->ic2eq = 0;
- float a1,a2,a3,g,k;
svf->g = tanf(PI * freq * leaf.invSampleRate);
svf->k = 1.0f/Q;
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
- svf->a2 = g*a1;
- svf->a3 = g*a2;
+ svf->a2 = svf->g*svf->a1;
+ svf->a3 = svf->g*svf->a2;
}
-void tSVF_free(tSVF* const svff)
+void tSVF_freeFromPool (tSVF* const svff, tMempool* const mp)
{
+ _tMempool* m = *mp;
_tSVF* svf = *svff;
- leaf_free(svf);
+ mpool_free(svf, m->pool);
}
float tSVF_tick(tSVF* const svff, float v0)
@@ -890,12 +939,11 @@
svf->ic1eq = 0;
svf->ic2eq = 0;
- float a1,a2,a3,g,k;
svf->g = filtertan[input];
svf->k = 1.0f/Q;
- svf->a1 = 1.0f/(1.0f+g*(g+k));
- svf->a2 = g*a1;
- svf->a3 = g*a2;
+ svf->a1 = 1.0f/(1.0f+svf->g*(svf->g+svf->k));
+ svf->a2 = svf->g*svf->a1;
+ svf->a3 = svf->g*svf->a2;
}
void tEfficientSVF_free(tEfficientSVF* const svff)
@@ -905,6 +953,31 @@
leaf_free(svf);
}
+void tEfficientSVF_initToPool (tEfficientSVF* const svff, SVFType type, uint16_t input, float Q, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEfficientSVF* svf = *svff = (_tEfficientSVF*) mpool_alloc(sizeof(_tEfficientSVF), m->pool);
+
+ svf->type = type;
+
+ svf->ic1eq = 0;
+ svf->ic2eq = 0;
+
+ svf->g = filtertan[input];
+ svf->k = 1.0f/Q;
+ svf->a1 = 1.0f/(1.0f+svf->g*(svf->g+svf->k));
+ svf->a2 = svf->g*svf->a1;
+ svf->a3 = svf->g*svf->a2;
+}
+
+void tEfficientSVF_freeFromPool (tEfficientSVF* const svff, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tEfficientSVF* svf = *svff;
+
+ mpool_free(svf, m->pool);
+}
+
float tEfficientSVF_tick(tEfficientSVF* const svff, float v0)
{
_tEfficientSVF* svf = *svff;
@@ -945,6 +1018,181 @@
svf->a3 = svf->g * svf->a2;
}
+/* Highpass */
+void tHighpass_init(tHighpass* const ft, float freq)
+{
+ _tHighpass* f = *ft = (_tHighpass*) leaf_alloc(sizeof(_tHighpass));
+
+ f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
+ f->ys = 0.0f;
+ f->xs = 0.0f;
+
+ f->frequency = freq;
+}
+
+void tHighpass_free(tHighpass* const ft)
+{
+ _tHighpass* f = *ft;
+
+ leaf_free(f);
+}
+
+void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tHighpass* f = *ft = (_tHighpass*) mpool_alloc(sizeof(_tHighpass), m->pool);
+
+ f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
+ f->ys = 0.0f;
+ f->xs = 0.0f;
+
+ f->frequency = freq;
+}
+
+void tHighpass_freeFromPool (tHighpass* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tHighpass* f = *ft;
+
+ mpool_free(f, m->pool);
+}
+
+void tHighpass_setFreq(tHighpass* const ft, float freq)
+{
+ _tHighpass* f = *ft;
+ f->frequency = freq;
+ f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
+
+}
+
+float tHighpass_getFreq(tHighpass* const ft)
+{
+ _tHighpass* f = *ft;
+ return f->frequency;
+}
+
+// From JOS DC Blocker
+float tHighpass_tick(tHighpass* const ft, float x)
+{
+ _tHighpass* f = *ft;
+ f->ys = x - f->xs + f->R * f->ys;
+ f->xs = x;
+ return f->ys;
+}
+
+void tHighpassSampleRateChanged(tHighpass* const ft)
+{
+ _tHighpass* f = *ft;
+ f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf.invSampleRate));
+}
+
+void tButterworth_init(tButterworth* const ft, int N, float f1, float f2)
+{
+ _tButterworth* f = *ft = (_tButterworth*) leaf_alloc(sizeof(_tButterworth));
+
+ f->f1 = f1;
+ f->f2 = f2;
+ f->gain = 1.0f;
+
+ f->N = N;
+
+ if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW;
+
+ for(int i = 0; i < N/2; ++i)
+ {
+ tSVF_init(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
+ tSVF_init(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)));
+ }
+}
+
+void tButterworth_free(tButterworth* const ft)
+{
+ _tButterworth* f = *ft;
+
+ for(int i = 0; i < f->N/2; ++i)
+ {
+ tSVF_free(&f->low[i]);
+ tSVF_free(&f->high[i]);
+ }
+
+ leaf_free(f);
+}
+
+void tButterworth_initToPool (tButterworth* const ft, int N, float f1, float f2, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tButterworth* f = *ft = (_tButterworth*) mpool_alloc(sizeof(_tButterworth), m->pool);
+
+ f->f1 = f1;
+ f->f2 = f2;
+ f->gain = 1.0f;
+
+ f->N = N;
+
+ if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW;
+
+ for(int i = 0; i < N/2; ++i)
+ {
+ tSVF_initToPool(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp);
+ tSVF_initToPool(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp);
+ }
+}
+
+void tButterworth_freeFromPool (tButterworth* const ft, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tButterworth* f = *ft;
+
+ for(int i = 0; i < f->N/2; ++i)
+ {
+ tSVF_freeFromPool(&f->low[i], mp);
+ tSVF_freeFromPool(&f->high[i], mp);
+ }
+
+ mpool_free(f, m->pool);
+}
+
+float tButterworth_tick(tButterworth* const ft, float samp)
+{
+ _tButterworth* f = *ft;
+
+ for(int i = 0; i < ((f->N)/2); ++i)
+ {
+ samp = tSVF_tick(&f->low[i],samp);
+ samp = tSVF_tick(&f->high[i],samp);
+ }
+ return samp;
+}
+
+void tButterworth_setF1(tButterworth* const ft, float f1)
+{
+ _tButterworth* f = *ft;
+
+ f->f1 = f1;
+ for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->low[i], f1);
+}
+
+void tButterworth_setF2(tButterworth* const ft, float f2)
+{
+ _tButterworth* f = *ft;
+
+ f->f2 = f2;
+ for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->high[i], f2);
+}
+
+void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
+{
+ _tButterworth* f = *ft;
+
+ f->f1 = f1;
+ f->f2 = f2;
+ for(int i = 0; i < ((f->N)/2); ++i)
+ {
+ tSVF_setFreq(&f->low[i], f1);
+ tSVF_setFreq(&f->high[i], f2);
+ }
+}
+
void tFIR_init(tFIR* const firf, float* coeffs, int numTaps)
{
_tFIR* fir = *firf = (_tFIR*) leaf_alloc(sizeof(_tFIR));
@@ -955,6 +1203,34 @@
for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
}
+void tFIR_free(tFIR* const firf)
+{
+ _tFIR* fir = *firf;
+
+ leaf_free(fir->past);
+ leaf_free(fir);
+}
+
+void tFIR_initToPool (tFIR* const firf, float* coeffs, int numTaps, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFIR* fir = *firf = (_tFIR*) mpool_alloc(sizeof(_tFIR), m->pool);
+
+ fir->numTaps = numTaps;
+ fir->coeff = coeffs;
+ fir->past = (float*) mpool_alloc(sizeof(float) * fir->numTaps, m->pool);
+ for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
+}
+
+void tFIR_freeFromPool (tFIR* const firf, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tFIR* fir = *firf;
+
+ mpool_free(fir->past, m->pool);
+ mpool_free(fir, m->pool);
+}
+
float tFIR_tick(tFIR* const firf, float input)
{
_tFIR* fir = *firf;
@@ -964,12 +1240,4 @@
for (int i = 0; i < fir->numTaps; ++i) y += fir->past[i]*fir->coeff[i];
for (int i = fir->numTaps-1; i > 0; --i) fir->past[i] = fir->past[i-1];
return y;
-}
-
-void tFIR_free(tFIR* const firf)
-{
- _tFIR* fir = *firf;
-
- leaf_free(fir->past);
- leaf_free(fir);
}
--- a/LEAF/Src/leaf-instruments.c
+++ b/LEAF/Src/leaf-instruments.c
@@ -63,6 +63,53 @@
leaf_free(cowbell);
}
+void t808Cowbell_initToPool (t808Cowbell* const cowbellInst, int useStick, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Cowbell* cowbell = *cowbellInst = (_t808Cowbell*) mpool_alloc(sizeof(_t808Cowbell), m->pool);
+
+ tSquare_initToPool(&cowbell->p[0], mp);
+ tSquare_setFreq(&cowbell->p[0], 540.0f);
+
+ tSquare_initToPool(&cowbell->p[1], mp);
+ tSquare_setFreq(&cowbell->p[1], 1.48148f * 540.0f);
+
+ cowbell->oscMix = 0.5f;
+
+ tSVF_initToPool(&cowbell->bandpassOsc, SVFTypeBandpass, 2500, 1.0f, mp);
+
+ tSVF_initToPool(&cowbell->bandpassStick, SVFTypeBandpass, 1800, 1.0f, mp);
+
+ tEnvelope_initToPool(&cowbell->envGain, 5.0f, 100.0f, OFALSE, mp);
+
+ tEnvelope_initToPool(&cowbell->envFilter, 5.0, 100.0f, OFALSE, mp);
+
+ tHighpass_initToPool(&cowbell->highpass, 1000.0f, mp);
+
+ tNoise_initToPool(&cowbell->stick, WhiteNoise, mp);
+
+ tEnvelope_initToPool(&cowbell->envStick, 5.0f, 5.0f, 0, mp);
+
+ cowbell->useStick = useStick;
+}
+
+void t808Cowbell_freeFromPool (t808Cowbell* const cowbellInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Cowbell* cowbell = *cowbellInst;
+
+ tSquare_freeFromPool(&cowbell->p[0], mp);
+ tSquare_freeFromPool(&cowbell->p[1], mp);
+ tSVF_freeFromPool(&cowbell->bandpassOsc, mp);
+ tSVF_freeFromPool(&cowbell->bandpassStick, mp);
+ tEnvelope_freeFromPool(&cowbell->envGain, mp);
+ tEnvelope_freeFromPool(&cowbell->envFilter, mp);
+ tHighpass_freeFromPool(&cowbell->highpass, mp);
+ tNoise_freeFromPool(&cowbell->stick, mp);
+ tEnvelope_freeFromPool(&cowbell->envStick, mp);
+ mpool_free(cowbell, m->pool);
+}
+
void t808Cowbell_on(t808Cowbell* const cowbellInst, float vel)
{
_t808Cowbell* cowbell = *cowbellInst;
@@ -192,6 +239,64 @@
leaf_free(hihat);
}
+void t808Hihat_initToPool (t808Hihat* const hihatInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Hihat* hihat = *hihatInst = (_t808Hihat*) mpool_alloc(sizeof(_t808Hihat), m->pool);
+
+ for (int i = 0; i < 6; i++)
+ {
+ tSquare_initToPool(&hihat->p[i], mp);
+ }
+
+ tNoise_initToPool(&hihat->stick, PinkNoise, mp);
+ tNoise_initToPool(&hihat->n, WhiteNoise, mp);
+
+ // need to fix SVF to be generic
+ tSVF_initToPool(&hihat->bandpassStick, SVFTypeBandpass,2500.0f,1.2f, mp);
+ tSVF_initToPool(&hihat->bandpassOsc, SVFTypeBandpass,3500.0f,0.3f, mp);
+
+ tEnvelope_initToPool(&hihat->envGain, 0.0f, 50.0f, OFALSE, mp);
+ tEnvelope_initToPool(&hihat->envStick, 0.0f, 7.0f, OFALSE, mp);
+
+
+ tHighpass_initToPool(&hihat->highpass, 7000.0f, mp);
+
+ hihat->freq = 40.0f;
+ hihat->stretch = 0.0f;
+
+ tSquare_setFreq(&hihat->p[0], 2.0f * hihat->freq);
+ tSquare_setFreq(&hihat->p[1], 3.00f * hihat->freq);
+ tSquare_setFreq(&hihat->p[2], 4.16f * hihat->freq);
+ tSquare_setFreq(&hihat->p[3], 5.43f * hihat->freq);
+ tSquare_setFreq(&hihat->p[4], 6.79f * hihat->freq);
+ tSquare_setFreq(&hihat->p[5], 8.21f * hihat->freq);
+}
+
+void t808Hihat_freeFromPool (t808Hihat* const hihatInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Hihat* hihat = *hihatInst;
+
+ for (int i = 0; i < 6; i++)
+ {
+ tSquare_freeFromPool(&hihat->p[i], mp);
+ }
+
+ tNoise_freeFromPool(&hihat->stick, mp);
+ tNoise_freeFromPool(&hihat->n, mp);
+
+ // need to fix SVF to be generic
+ tSVF_freeFromPool(&hihat->bandpassStick, mp);
+ tSVF_freeFromPool(&hihat->bandpassOsc, mp);
+ tEnvelope_freeFromPool(&hihat->envGain, mp);
+ tEnvelope_freeFromPool(&hihat->envStick, mp);
+
+ tHighpass_freeFromPool(&hihat->highpass, mp);
+
+ mpool_free(hihat, m->pool);
+}
+
void t808Hihat_on(t808Hihat* const hihatInst, float vel)
{
_t808Hihat* hihat = *hihatInst;
@@ -289,8 +394,6 @@
tSVF_setQ(&hihat->bandpassStick,Q);
}
-
-
void t808Hihat_setOscFreq(t808Hihat* const hihatInst, float freq)
{
_t808Hihat* hihat = *hihatInst;
@@ -348,6 +451,57 @@
leaf_free(snare);
}
+void t808Snare_initToPool (t808Snare* const snareInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Snare* snare = *snareInst = (_t808Snare*) mpool_alloc(sizeof(_t808Snare), m->pool);
+
+ float ratio[2] = {1.0, 1.5};
+ for (int i = 0; i < 2; i++)
+ {
+ tTriangle_initToPool(&snare->tone[i], mp);
+
+ tTriangle_setFreq(&snare->tone[i], ratio[i] * 400.0f);
+ tSVF_initToPool(&snare->toneLowpass[i], SVFTypeLowpass, 4000, 1.0f, mp);
+ tEnvelope_initToPool(&snare->toneEnvOsc[i], 0.0f, 50.0f, OFALSE, mp);
+ tEnvelope_initToPool(&snare->toneEnvGain[i], 1.0f, 150.0f, OFALSE, mp);
+ tEnvelope_initToPool(&snare->toneEnvFilter[i], 1.0f, 2000.0f, OFALSE, mp);
+
+ snare->toneGain[i] = 0.5f;
+ }
+
+ snare->tone1Freq = ratio[0] * 100.0f;
+ snare->tone2Freq = ratio[1] * 100.0f;
+ snare->noiseFilterFreq = 3000.0f;
+ tNoise_initToPool(&snare->noiseOsc, WhiteNoise, mp);
+ tSVF_initToPool(&snare->noiseLowpass, SVFTypeLowpass, 12000.0f, 0.8f, mp);
+ tEnvelope_initToPool(&snare->noiseEnvGain, 0.0f, 100.0f, OFALSE, mp);
+ tEnvelope_initToPool(&snare->noiseEnvFilter, 0.0f, 1000.0f, OFALSE, mp);
+ snare->noiseGain = 1.0f;
+}
+
+void t808Snare_freeFromPool (t808Snare* const snareInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Snare* snare = *snareInst;
+
+ for (int i = 0; i < 2; i++)
+ {
+ tTriangle_freeFromPool(&snare->tone[i], mp);
+ tSVF_freeFromPool(&snare->toneLowpass[i], mp);
+ tEnvelope_freeFromPool(&snare->toneEnvOsc[i], mp);
+ tEnvelope_freeFromPool(&snare->toneEnvGain[i], mp);
+ tEnvelope_freeFromPool(&snare->toneEnvFilter[i], mp);
+ }
+
+ tNoise_freeFromPool(&snare->noiseOsc, mp);
+ tSVF_freeFromPool(&snare->noiseLowpass, mp);
+ tEnvelope_freeFromPool(&snare->noiseEnvGain, mp);
+ tEnvelope_freeFromPool(&snare->noiseEnvFilter, mp);
+
+ mpool_free(snare, m->pool);
+}
+
void t808Snare_on(t808Snare* const snareInst, float vel)
{
_t808Snare* snare = *snareInst;
@@ -470,6 +624,41 @@
tEnvelope_free(&kick->noiseEnvGain);
leaf_free(kick);
+}
+
+void t808Kick_initToPool (t808Kick* const kickInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Kick* kick = *kickInst = (_t808Kick*) mpool_alloc(sizeof(_t808Kick), m->pool);
+
+ tCycle_initToPool(&kick->tone, mp);
+ kick->toneInitialFreq = 40.0f;
+ kick->sighAmountInHz = 7.0f;
+ kick->chirpRatioMinusOne = 3.3f;
+ tCycle_setFreq(&kick->tone, 50.0f);
+ tSVF_initToPool(&kick->toneLowpass, SVFTypeLowpass, 2000.0f, 0.5f, mp);
+ tEnvelope_initToPool(&kick->toneEnvOscChirp, 0.0f, 20.0f, OFALSE, mp);
+ tEnvelope_initToPool(&kick->toneEnvOscSigh, 0.0f, 2500.0f, OFALSE, mp);
+ tEnvelope_initToPool(&kick->toneEnvGain, 0.0f, 800.0f, OFALSE, mp);
+ tNoise_initToPool(&kick->noiseOsc, PinkNoise, mp);
+ tEnvelope_initToPool(&kick->noiseEnvGain, 0.0f, 1.0f, OFALSE, mp);
+ kick->noiseGain = 0.3f;
+}
+
+void t808Kick_freeFromPool (t808Kick* const kickInst, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _t808Kick* kick = *kickInst;
+
+ tCycle_freeFromPool(&kick->tone, mp);
+ tSVF_freeFromPool(&kick->toneLowpass, mp);
+ tEnvelope_freeFromPool(&kick->toneEnvOscChirp, mp);
+ tEnvelope_freeFromPool(&kick->toneEnvOscSigh, mp);
+ tEnvelope_freeFromPool(&kick->toneEnvGain, mp);
+ tNoise_freeFromPool(&kick->noiseOsc, mp);
+ tEnvelope_freeFromPool(&kick->noiseEnvGain, mp);
+
+ mpool_free(kick, m->pool);
}
float t808Kick_tick (t808Kick* const kickInst)
--- a/LEAF/Src/leaf-mempool.c
+++ b/LEAF/Src/leaf-mempool.c
@@ -77,8 +77,6 @@
}
}
-
-
void leaf_pool_init(char* memory, size_t size)
{
mpool_create(memory, size, &leaf_pool);
@@ -143,6 +141,68 @@
return node_to_alloc->pool;
}
+
+/**
+ * allocate memory from memory pool and also clear that memory to be blank
+ */
+void* mpool_allocAndClear(size_t asize, mpool_t* pool)
+{
+ // If the head is NULL, the mempool is full
+ if (pool->head == NULL) return NULL;
+
+ // Should we alloc the first block large enough or check all blocks and pick the one closest in size?
+ size_t size_to_alloc = mpool_align(asize);
+ mpool_node_t* node_to_alloc = pool->head;
+
+ // Traverse the free list for a large enough block
+ while (node_to_alloc->size < size_to_alloc)
+ {
+ node_to_alloc = node_to_alloc->next;
+
+ // If we reach the end of the free list, there
+ // are no blocks large enough, return NULL
+ if (node_to_alloc == NULL) return NULL;
+ }
+
+ // Create a new node after the node to be allocated if there is enough space
+ mpool_node_t* new_node;
+ size_t leftover = node_to_alloc->size - size_to_alloc;
+ node_to_alloc->size = size_to_alloc;
+ if (leftover > header_size)
+ {
+ long offset = (char*) node_to_alloc - (char*) pool->mpool;
+ offset += header_size + node_to_alloc->size;
+ new_node = create_node(&pool->mpool[offset],
+ node_to_alloc->next,
+ node_to_alloc->prev,
+ leftover - header_size);
+ }
+ else
+ {
+ // Add any leftover space to the allocated node to avoid fragmentation
+ node_to_alloc->size += leftover;
+
+ new_node = node_to_alloc->next;
+ }
+
+ // Update the head if we are allocating the first node of the free list
+ // The head will be NULL if there is no space left
+ if (pool->head == node_to_alloc)
+ {
+ pool->head = new_node;
+ }
+
+ // Remove the allocated node from the free list
+ delink_node(node_to_alloc);
+
+ pool->usize += header_size + node_to_alloc->size;
+ // Format the new pool
+ char* new_pool = (char*)node_to_alloc->pool;
+ for (int i = 0; i < node_to_alloc->size; i++) new_pool[i] = 0;
+ // Return the pool of the allocated node;
+ return node_to_alloc->pool;
+}
+
void* leaf_alloc(size_t size)
{
//printf("alloc %i\n", size);
@@ -153,6 +213,17 @@
return block;
}
+void* leaf_allocAndClear(size_t size)
+{
+ //printf("alloc %i\n", size);
+ void* block = mpool_allocAndClear(size, &leaf_pool);
+
+ if (block == NULL) leaf_mempool_overrun();
+
+
+ return block;
+}
+
void mpool_free(void* ptr, mpool_t* pool)
{
//if (ptr < pool->mpool || ptr >= pool->mpool + pool->msize)
@@ -211,8 +282,8 @@
pool->head = freed_node;
// Format the freed pool
- char* freed_pool = (char*)freed_node->pool;
- for (int i = 0; i < freed_node->size; i++) freed_pool[i] = 0;
+// char* freed_pool = (char*)freed_node->pool;
+// for (int i = 0; i < freed_node->size; i++) freed_pool[i] = 0;
}
void leaf_free(void* ptr)
@@ -289,3 +360,32 @@
//TODO: we should set up some kind of leaf_error method that reaches user space to notify library users of things that failed.
}
+void tMempool_init(tMempool* const mp, char* memory, size_t size)
+{
+ _tMempool* m = *mp = (_tMempool*) leaf_alloc(sizeof(_tMempool));
+
+ mpool_create (memory, size, m->pool);
+}
+
+void tMempool_free(tMempool* const mp)
+{
+ _tMempool* m = *mp;
+
+ leaf_free(m);
+}
+
+void tMempool_initToPool (tMempool* const mp, char* memory, size_t size, tMempool* const mem)
+{
+ _tMempool* mm = *mem;
+ _tMempool* m = *mp = (_tMempool*) mpool_alloc(sizeof(_tMempool), mm->pool);
+
+ mpool_create (memory, size, m->pool);
+}
+
+void tMempool_freeFromPool (tMempool* const mp, tMempool* const mem)
+{
+ _tMempool* mm = *mem;
+ _tMempool* m = *mp;
+
+ mpool_free(m, mm->pool);
+}
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -16,6 +16,259 @@
#endif
+//====================================================================================
+/* Stack */
+//====================================================================================
+
+void tStack_init(tStack* const stack)
+{
+ _tStack* ns = *stack = (_tStack*) leaf_alloc(sizeof(_tStack));
+
+ ns->ordered = OFALSE;
+ ns->size = 0;
+ ns->pos = 0;
+ ns->capacity = STACK_SIZE;
+
+ for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
+}
+
+void tStack_free(tStack* const stack)
+{
+ _tStack* ns = *stack;
+
+ leaf_free(ns);
+}
+
+void tStack_initToPool (tStack* const stack, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tStack* ns = *stack = (_tStack*) mpool_alloc(sizeof(_tStack), m->pool);
+
+ ns->ordered = OFALSE;
+ ns->size = 0;
+ ns->pos = 0;
+ ns->capacity = STACK_SIZE;
+
+ for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
+}
+
+void tStack_freeFromPool (tStack* const stack, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tStack* ns = *stack;
+
+ mpool_free(ns, m->pool);
+}
+
+// If stack contains note, returns index. Else returns -1;
+int tStack_contains(tStack* const stack, uint16_t noteVal)
+{
+ _tStack* ns = *stack;
+ for (int i = 0; i < ns->size; i++)
+ {
+ if (ns->data[i] == noteVal) return i;
+ }
+ return -1;
+}
+
+void tStack_add(tStack* const stack, uint16_t noteVal)
+{
+ _tStack* ns = *stack;
+
+ uint8_t j;
+
+ int whereToInsert = 0;
+ if (ns->ordered)
+ {
+ for (j = 0; j < ns->size; j++)
+ {
+ if (noteVal > ns->data[j])
+ {
+ if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
+ {
+ whereToInsert = j+1;
+ break;
+ }
+ }
+ }
+ }
+
+ //first move notes that are already in the stack one position to the right
+ for (j = ns->size; j > whereToInsert; j--)
+ {
+ ns->data[j] = ns->data[(j - 1)];
+ }
+
+ //then, insert the new note into the front of the stack
+ ns->data[whereToInsert] = noteVal;
+
+ ns->size++;
+}
+
+int tStack_addIfNotAlreadyThere(tStack* const stack, uint16_t noteVal)
+{
+ _tStack* ns = *stack;
+
+ uint8_t j;
+
+ int added = 0;
+
+ if (tStack_contains(stack, noteVal) == -1)
+ {
+ int whereToInsert = 0;
+ if (ns->ordered)
+ {
+ for (j = 0; j < ns->size; j++)
+ {
+ if (noteVal > ns->data[j])
+ {
+ if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
+ {
+ whereToInsert = j+1;
+ break;
+ }
+ }
+ }
+ }
+
+ //first move notes that are already in the stack one position to the right
+ for (j = ns->size; j > whereToInsert; j--)
+ {
+ ns->data[j] = ns->data[(j - 1)];
+ }
+
+ //then, insert the new note into the front of the stack
+ ns->data[whereToInsert] = noteVal;
+
+ ns->size++;
+
+ added = 1;
+ }
+
+ return added;
+}
+
+// Remove noteVal. return 1 if removed, 0 if not
+int tStack_remove(tStack* const stack, uint16_t noteVal)
+{
+ _tStack* ns = *stack;
+
+ uint8_t k;
+ int foundIndex = tStack_contains(stack, noteVal);
+ int removed = 0;
+
+ if (foundIndex >= 0)
+ {
+ for (k = 0; k < (ns->size - foundIndex); k++)
+ {
+ if ((k+foundIndex) >= (ns->capacity - 1))
+ {
+ ns->data[k + foundIndex] = -1;
+ }
+ else
+ {
+ ns->data[k + foundIndex] = ns->data[k + foundIndex + 1];
+ if ((k + foundIndex) == (ns->size - 1))
+ {
+ ns->data[k + foundIndex + 1] = -1;
+ }
+ }
+
+ }
+ // in case it got put on the stack multiple times
+ foundIndex--;
+ ns->size--;
+ removed = 1;
+ }
+
+ return removed;
+}
+
+// Doesn't change size of data types
+void tStack_setCapacity(tStack* const stack, uint16_t cap)
+{
+ _tStack* ns = *stack;
+
+ if (cap <= 0)
+ ns->capacity = 1;
+ else if (cap <= STACK_SIZE)
+ ns->capacity = cap;
+ else
+ ns->capacity = STACK_SIZE;
+
+ for (int i = cap; i < STACK_SIZE; i++)
+ {
+ if ((int)ns->data[i] != -1)
+ {
+ ns->data[i] = -1;
+ ns->size -= 1;
+ }
+ }
+
+ if (ns->pos >= cap)
+ {
+ ns->pos = 0;
+ }
+}
+
+int tStack_getSize(tStack* const stack)
+{
+ _tStack* ns = *stack;
+
+ return ns->size;
+}
+
+void tStack_clear(tStack* const stack)
+{
+ _tStack* ns = *stack;
+
+ for (int i = 0; i < STACK_SIZE; i++)
+ {
+ ns->data[i] = -1;
+ }
+ ns->pos = 0;
+ ns->size = 0;
+}
+
+// Next item in order of addition to stack. Return 0-31 if there is a next item to move to. Returns -1 otherwise.
+int tStack_next(tStack* const stack)
+{
+ _tStack* ns = *stack;
+
+ int step = 0;
+ if (ns->size != 0) // if there is at least one note in the stack
+ {
+ if (ns->pos > 0) // if you're not at the most recent note (first one), then go backward in the array (moving from earliest to latest)
+ {
+ ns->pos--;
+ }
+ else
+ {
+ ns->pos = (ns->size - 1); // if you are the most recent note, go back to the earliest note in the array
+ }
+
+ step = ns->data[ns->pos];
+ return step;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+int tStack_get(tStack* const stack, int which)
+{
+ _tStack* ns = *stack;
+ return ns->data[which];
+}
+
+int tStack_first(tStack* const stack)
+{
+ _tStack* ns = *stack;
+ return ns->data[0];
+}
+
+
// POLY
void tPoly_init(tPoly* const polyh, int maxNumVoices)
{
@@ -83,6 +336,74 @@
leaf_free(poly);
}
+void tPoly_initToPool (tPoly* const polyh, int maxNumVoices, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPoly* poly = *polyh = (_tPoly*) mpool_alloc(sizeof(_tPoly), m->pool);
+
+ poly->numVoices = maxNumVoices;
+ poly->maxNumVoices = maxNumVoices;
+ poly->lastVoiceToChange = 0;
+
+ // Arp mode stuff
+ poly->currentVoice = 0;
+ poly->maxLength = 128;
+ poly->currentNote = -1;
+
+ //default learned CCs and notes are just the CCs 1-128 - notes are skipped
+ for (int i = 0; i < 128; i++)
+ {
+ poly->notes[i][0] = 0;
+ poly->notes[i][1] = -1;
+ }
+
+ poly->glideTime = 5.0f;
+
+ poly->ramps = (tRamp*) mpool_alloc(sizeof(tRamp) * poly->maxNumVoices, m->pool);
+ poly->rampVals = (float*) mpool_alloc(sizeof(float) * poly->maxNumVoices, m->pool);
+ poly->firstReceived = (oBool*) mpool_alloc(sizeof(oBool) * poly->maxNumVoices, m->pool);
+ poly->voices = (int**) mpool_alloc(sizeof(int*) * poly->maxNumVoices, m->pool);
+
+ for (int i = 0; i < poly->maxNumVoices; ++i)
+ {
+ poly->voices[i] = (int*) mpool_alloc(sizeof(int) * 2, m->pool);
+ poly->voices[i][0] = -1;
+ poly->firstReceived[i] = OFALSE;
+
+ tRamp_initToPool(&poly->ramps[i], poly->glideTime, 1, mp);
+ }
+
+ poly->pitchBend = 0.0f;
+
+ tRamp_initToPool(&poly->pitchBendRamp, 1.0f, 1, mp);
+ tStack_initToPool(&poly->stack, mp);
+ tStack_initToPool(&poly->orderStack, mp);
+
+ poly->pitchGlideIsActive = OFALSE;
+}
+
+void tPoly_freeFromPool (tPoly* const polyh, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPoly* poly = *polyh;
+
+ for (int i = 0; i < poly->maxNumVoices; i++)
+ {
+ tRamp_freeFromPool(&poly->ramps[i], mp);
+ mpool_free(poly->voices[i], m->pool);
+ }
+ tRamp_freeFromPool(&poly->pitchBendRamp, mp);
+ tStack_freeFromPool(&poly->stack, mp);
+ tStack_freeFromPool(&poly->orderStack, mp);
+
+ mpool_free(poly->voices, m->pool);
+ mpool_free(poly->ramps, m->pool);
+ mpool_free(poly->rampVals, m->pool);
+ mpool_free(poly->firstReceived, m->pool);
+
+ mpool_free(poly, m->pool);
+}
+
void tPoly_tickPitch(tPoly* polyh)
{
tPoly_tickPitchGlide(polyh);
@@ -331,237 +652,4 @@
{
_tPoly* poly = *polyh;
return (poly->voices[voice][0] > 0) ? 1 : 0;
-}
-
-
-//====================================================================================
-/* Stack */
-//====================================================================================
-
-void tStack_init(tStack* const stack)
-{
- _tStack* ns = *stack = (_tStack*) leaf_alloc(sizeof(_tStack));
-
- ns->ordered = OFALSE;
- ns->size = 0;
- ns->pos = 0;
- ns->capacity = STACK_SIZE;
-
- for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
-}
-
-void tStack_free(tStack* const stack)
-{
- _tStack* ns = *stack;
-
- leaf_free(ns);
-}
-
-// If stack contains note, returns index. Else returns -1;
-int tStack_contains(tStack* const stack, uint16_t noteVal)
-{
- _tStack* ns = *stack;
- for (int i = 0; i < ns->size; i++)
- {
- if (ns->data[i] == noteVal) return i;
- }
- return -1;
-}
-
-void tStack_add(tStack* const stack, uint16_t noteVal)
-{
- _tStack* ns = *stack;
-
- uint8_t j;
-
- int whereToInsert = 0;
- if (ns->ordered)
- {
- for (j = 0; j < ns->size; j++)
- {
- if (noteVal > ns->data[j])
- {
- if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
- {
- whereToInsert = j+1;
- break;
- }
- }
- }
- }
-
- //first move notes that are already in the stack one position to the right
- for (j = ns->size; j > whereToInsert; j--)
- {
- ns->data[j] = ns->data[(j - 1)];
- }
-
- //then, insert the new note into the front of the stack
- ns->data[whereToInsert] = noteVal;
-
- ns->size++;
-}
-
-int tStack_addIfNotAlreadyThere(tStack* const stack, uint16_t noteVal)
-{
- _tStack* ns = *stack;
-
- uint8_t j;
-
- int added = 0;
-
- if (tStack_contains(stack, noteVal) == -1)
- {
- int whereToInsert = 0;
- if (ns->ordered)
- {
- for (j = 0; j < ns->size; j++)
- {
- if (noteVal > ns->data[j])
- {
- if ((noteVal < ns->data[j+1]) || (ns->data[j+1] == -1))
- {
- whereToInsert = j+1;
- break;
- }
- }
- }
- }
-
- //first move notes that are already in the stack one position to the right
- for (j = ns->size; j > whereToInsert; j--)
- {
- ns->data[j] = ns->data[(j - 1)];
- }
-
- //then, insert the new note into the front of the stack
- ns->data[whereToInsert] = noteVal;
-
- ns->size++;
-
- added = 1;
- }
-
- return added;
-}
-
-
-// Remove noteVal. return 1 if removed, 0 if not
-int tStack_remove(tStack* const stack, uint16_t noteVal)
-{
- _tStack* ns = *stack;
-
- uint8_t k;
- int foundIndex = tStack_contains(stack, noteVal);
- int removed = 0;
-
- if (foundIndex >= 0)
- {
- for (k = 0; k < (ns->size - foundIndex); k++)
- {
- if ((k+foundIndex) >= (ns->capacity - 1))
- {
- ns->data[k + foundIndex] = -1;
- }
- else
- {
- ns->data[k + foundIndex] = ns->data[k + foundIndex + 1];
- if ((k + foundIndex) == (ns->size - 1))
- {
- ns->data[k + foundIndex + 1] = -1;
- }
- }
-
- }
- // in case it got put on the stack multiple times
- foundIndex--;
- ns->size--;
- removed = 1;
- }
-
- return removed;
-}
-
-// Doesn't change size of data types
-void tStack_setCapacity(tStack* const stack, uint16_t cap)
-{
- _tStack* ns = *stack;
-
- if (cap <= 0)
- ns->capacity = 1;
- else if (cap <= STACK_SIZE)
- ns->capacity = cap;
- else
- ns->capacity = STACK_SIZE;
-
- for (int i = cap; i < STACK_SIZE; i++)
- {
- if ((int)ns->data[i] != -1)
- {
- ns->data[i] = -1;
- ns->size -= 1;
- }
- }
-
- if (ns->pos >= cap)
- {
- ns->pos = 0;
- }
-}
-
-int tStack_getSize(tStack* const stack)
-{
- _tStack* ns = *stack;
-
- return ns->size;
-}
-
-void tStack_clear(tStack* const stack)
-{
- _tStack* ns = *stack;
-
- for (int i = 0; i < STACK_SIZE; i++)
- {
- ns->data[i] = -1;
- }
- ns->pos = 0;
- ns->size = 0;
-}
-
-// Next item in order of addition to stack. Return 0-31 if there is a next item to move to. Returns -1 otherwise.
-int tStack_next(tStack* const stack)
-{
- _tStack* ns = *stack;
-
- int step = 0;
- if (ns->size != 0) // if there is at least one note in the stack
- {
- if (ns->pos > 0) // if you're not at the most recent note (first one), then go backward in the array (moving from earliest to latest)
- {
- ns->pos--;
- }
- else
- {
- ns->pos = (ns->size - 1); // if you are the most recent note, go back to the earliest note in the array
- }
-
- step = ns->data[ns->pos];
- return step;
- }
- else
- {
- return -1;
- }
-}
-
-int tStack_get(tStack* const stack, int which)
-{
- _tStack* ns = *stack;
- return ns->data[which];
-}
-
-int tStack_first(tStack* const stack)
-{
- _tStack* ns = *stack;
- return ns->data[0];
}
--- a/LEAF/Src/leaf-oscillators.c
+++ b/LEAF/Src/leaf-oscillators.c
@@ -19,19 +19,42 @@
#endif
// Cycle
-void tCycle_init(tCycle* const c)
+void tCycle_init(tCycle* const cy)
{
+ _tCycle* c = *cy = (_tCycle*) leaf_alloc(sizeof(_tCycle));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tCycle_free(tCycle* const c)
+void tCycle_free(tCycle* const cy)
{
+ _tCycle* c = *cy;
+ leaf_free(c);
}
-int tCycle_setFreq(tCycle* const c, float freq)
+void tCycle_initToPool (tCycle* const cy, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tCycle* c = *cy = (_tCycle*) mpool_alloc(sizeof(_tCycle), m->pool);
+
+ c->inc = 0.0f;
+ c->phase = 0.0f;
+}
+
+void tCycle_freeFromPool (tCycle* const cy, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tCycle* c = *cy;
+
+ mpool_free(c, m->pool);
+}
+
+int tCycle_setFreq(tCycle* const cy, float freq)
+{
+ _tCycle* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -40,8 +63,10 @@
return 0;
}
-float tCycle_tick(tCycle* const c)
+float tCycle_tick(tCycle* const cy)
{
+ _tCycle* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -56,31 +81,51 @@
return (samp0 + (samp1 - samp0) * fracPart);
}
-void tCycleSampleRateChanged (tCycle* const c)
+void tCycleSampleRateChanged (tCycle* const cy)
{
+ _tCycle* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Triangle */
-void tTriangle_start(tTriangle* const c)
+void tTriangle_init(tTriangle* const cy)
{
+ _tTriangle* c = *cy = (_tTriangle*) leaf_alloc(sizeof(_tTriangle));
+ c->inc = 0.0f;
+ c->phase = 0.0f;
}
-void tTriangle_init(tTriangle* const c)
+void tTriangle_free(tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+
+ leaf_free(c);
+}
+
+void tTriangle_initToPool (tTriangle* const cy, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tTriangle* c = *cy = (_tTriangle*) mpool_alloc(sizeof(_tTriangle), m->pool);
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tTriangle_free(tTriangle* const c)
+void tTriangle_freeFromPool (tTriangle* const cy, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tTriangle* c = *cy;
+ mpool_free(c, m->pool);
}
-int tTriangle_setFreq(tTriangle* const c, float freq)
+int tTriangle_setFreq(tTriangle* const cy, float freq)
{
+ _tTriangle* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -90,8 +135,10 @@
}
-float tTriangle_tick(tTriangle* const c)
+float tTriangle_tick(tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -165,26 +212,51 @@
return out;
}
-void tTriangleSampleRateChanged (tTriangle* const c)
+void tTriangleSampleRateChanged (tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Square */
-void tSquare_init(tSquare* const c)
+void tSquare_init(tSquare* const cy)
{
+ _tSquare* c = *cy = (_tSquare*) leaf_alloc(sizeof(_tSquare));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tSquare_free(tSquare* const c)
+void tSquare_free(tSquare* const cy)
{
+ _tSquare* c = *cy;
+ leaf_free(c);
}
-int tSquare_setFreq(tSquare* const c, float freq)
+void tSquare_initToPool (tSquare* const cy, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tSquare* c = *cy = (_tSquare*) mpool_alloc(sizeof(_tSquare), m->pool);
+
+ c->inc = 0.0f;
+ c->phase = 0.0f;
+}
+
+void tSquare_freeFromPool(tSquare* const cy, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSquare* c = *cy;
+
+ mpool_free(c, m->pool);
+}
+
+int tSquare_setFreq(tSquare* const cy, float freq)
+{
+ _tSquare* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -193,8 +265,10 @@
return 0;
}
-float tSquare_tick(tSquare* const c)
+float tSquare_tick(tSquare* const cy)
{
+ _tSquare* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -267,26 +341,51 @@
return out;
}
-void tSquareSampleRateChanged (tSquare* const c)
+void tSquareSampleRateChanged (tSquare* const cy)
{
+ _tSquare* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//=====================================================================
// Sawtooth
-void tSawtooth_init(tSawtooth* const c)
+void tSawtooth_init(tSawtooth* const cy)
{
+ _tSawtooth* c = *cy = (_tSawtooth*) leaf_alloc(sizeof(_tSawtooth));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tSawtooth_free(tSawtooth* const c)
+void tSawtooth_free(tSawtooth* const cy)
{
+ _tSawtooth* c = *cy;
+ leaf_free(c);
}
-int tSawtooth_setFreq(tSawtooth* const c, float freq)
+void tSawtooth_initToPool (tSawtooth* const cy, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tSawtooth* c = *cy = (_tSawtooth*) mpool_alloc(sizeof(_tSawtooth), m->pool);
+
+ c->inc = 0.0f;
+ c->phase = 0.0f;
+}
+
+void tSawtooth_freeFromPool (tSawtooth* const cy, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSawtooth* c = *cy;
+
+ mpool_free(c, m->pool);
+}
+
+int tSawtooth_setFreq(tSawtooth* const cy, float freq)
+{
+ _tSawtooth* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -295,8 +394,10 @@
return 0;
}
-float tSawtooth_tick(tSawtooth* const c)
+float tSawtooth_tick(tSawtooth* const cy)
{
+ _tSawtooth* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -370,31 +471,58 @@
return out;
}
-void tSawtoothSampleRateChanged (tSawtooth* const c)
+void tSawtoothSampleRateChanged (tSawtooth* const cy)
{
+ _tSawtooth* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Phasor */
-void tPhasorSampleRateChanged (tPhasor* const p)
+void tPhasorSampleRateChanged (tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+
p->inc = p->freq * leaf.invSampleRate;
};
-void tPhasor_init(tPhasor* const p)
+void tPhasor_init(tPhasor* const ph)
{
+ _tPhasor* p = *ph = (_tPhasor*) leaf_alloc(sizeof(_tPhasor));
+
p->phase = 0.0f;
p->inc = 0.0f;
}
-void tPhasor_free(tPhasor* const p)
+void tPhasor_free(tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+ leaf_free(p);
}
-int tPhasor_setFreq(tPhasor* const p, float freq)
+void tPhasor_initToPool (tPhasor* const ph, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tPhasor* p = *ph = (_tPhasor*) mpool_alloc(sizeof(_tPhasor), m->pool);
+
+ p->phase = 0.0f;
+ p->inc = 0.0f;
+}
+
+void tPhasor_freeFromPool(tPhasor* const ph, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPhasor* p = *ph;
+
+ mpool_free(p, m->pool);
+}
+
+int tPhasor_setFreq(tPhasor* const ph, float freq)
+{
+ _tPhasor* p = *ph;
+
if (freq < 0.0f) freq = 0.0f;
p->freq = freq;
@@ -403,8 +531,10 @@
return 0;
}
-float tPhasor_tick(tPhasor* const p)
+float tPhasor_tick(tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+
p->phase += p->inc;
if (p->phase >= 1.0f) p->phase -= 1.0f;
@@ -413,19 +543,42 @@
}
/* Noise */
-void tNoise_init(tNoise* const n, NoiseType type)
+void tNoise_init(tNoise* const ns, NoiseType type)
{
+ _tNoise* n = *ns = (_tNoise*) leaf_alloc(sizeof(_tNoise));
+
n->type = type;
n->rand = leaf.random;
}
-void tNoise_free(tNoise* const n)
+void tNoise_free(tNoise* const ns)
{
+ _tNoise* n = *ns;
+ leaf_free(n);
}
-float tNoise_tick(tNoise* const n)
+void tNoise_initToPool (tNoise* const ns, NoiseType type, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tNoise* n = *ns = (_tNoise*) mpool_alloc(sizeof(_tNoise), m->pool);
+
+ n->type = type;
+ n->rand = leaf.random;
+}
+
+void tNoise_freeFromPool (tNoise* const ns, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tNoise* n = *ns;
+
+ mpool_free(n, m->pool);
+}
+
+float tNoise_tick(tNoise* const ns)
+{
+ _tNoise* n = *ns;
+
float rand = (n->rand() * 2.0f) - 1.0f;
if (n->type == PinkNoise)
@@ -446,13 +599,15 @@
//=================================================================================
/* Neuron */
-void tNeuronSampleRateChanged(tNeuron* n)
+void tNeuronSampleRateChanged(tNeuron* nr)
{
}
-void tNeuron_init(tNeuron* const n)
+void tNeuron_init(tNeuron* const nr)
{
+ _tNeuron* n = *nr = (_tNeuron*) leaf_alloc(sizeof(_tNeuron));
+
tPoleZero_init(&n->f);
tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -480,14 +635,21 @@
n->rate[2] = n->gL/n->C;
}
-void tNeuron_free(tNeuron* const n)
+void tNeuron_free(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
+
tPoleZero_free(&n->f);
+ leaf_free(n);
}
-void tNeuron_reset(tNeuron* const n)
+void tNeuron_initToPool (tNeuron* const nr, tMempool* const mp)
{
+ _tMempool* m = *mp;
+ _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m->pool);
+ tPoleZero_initToPool(&n->f, mp);
+
tPoleZero_setBlockZero(&n->f, 0.99f);
n->timeStep = 1.0f / 50.0f;
@@ -513,52 +675,99 @@
n->rate[2] = n->gL/n->C;
}
+void tNeuron_freeFromPool(tNeuron* const nr, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tNeuron* n = *nr;
+
+ tPoleZero_free(&n->f);
+ mpool_free(n, m->pool);
+}
-void tNeuron_setV1(tNeuron* const n, float V1)
+void tNeuron_reset(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
+
+ tPoleZero_setBlockZero(&n->f, 0.99f);
+
+ n->timeStep = 1.0f / 50.0f;
+
+ n->current = 0.0f; // 100.0f for sound
+ n->voltage = 0.0f;
+
+ n->mode = NeuronNormal;
+
+ n->P[0] = 0.0f;
+ n->P[1] = 0.0f;
+ n->P[2] = 1.0f;
+
+ n->V[0] = -12.0f;
+ n->V[1] = 115.0f;
+ n->V[2] = 10.613f;
+
+ n->gK = 36.0f;
+ n->gN = 120.0f;
+ n->gL = 0.3f;
+ n->C = 1.0f;
+
+ n->rate[2] = n->gL/n->C;
+}
+
+void tNeuron_setV1(tNeuron* const nr, float V1)
+{
+ _tNeuron* n = *nr;
n->V[0] = V1;
}
-void tNeuron_setV2(tNeuron* const n, float V2)
+void tNeuron_setV2(tNeuron* const nr, float V2)
{
+ _tNeuron* n = *nr;
n->V[1] = V2;
}
-void tNeuron_setV3(tNeuron* const n, float V3)
+void tNeuron_setV3(tNeuron* const nr, float V3)
{
+ _tNeuron* n = *nr;
n->V[2] = V3;
}
-void tNeuron_setTimeStep(tNeuron* const n, float timeStep)
+void tNeuron_setTimeStep(tNeuron* const nr, float timeStep)
{
+ _tNeuron* n = *nr;
n->timeStep = timeStep;
}
-void tNeuron_setK(tNeuron* const n, float K)
+void tNeuron_setK(tNeuron* const nr, float K)
{
+ _tNeuron* n = *nr;
n->gK = K;
}
-void tNeuron_setL(tNeuron* const n, float L)
+void tNeuron_setL(tNeuron* const nr, float L)
{
+ _tNeuron* n = *nr;
n->gL = L;
n->rate[2] = n->gL/n->C;
}
-void tNeuron_setN(tNeuron* const n, float N)
+void tNeuron_setN(tNeuron* const nr, float N)
{
+ _tNeuron* n = *nr;
n->gN = N;
}
-void tNeuron_setC(tNeuron* const n, float C)
+void tNeuron_setC(tNeuron* const nr, float C)
{
+ _tNeuron* n = *nr;
n->C = C;
n->rate[2] = n->gL/n->C;
}
-float tNeuron_tick(tNeuron* const n)
+float tNeuron_tick(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
+
float output = 0.0f;
float voltage = n->voltage;
@@ -631,12 +840,14 @@
}
-void tNeuron_setMode (tNeuron* const n, NeuronMode mode)
+void tNeuron_setMode (tNeuron* const nr, NeuronMode mode)
{
+ _tNeuron* n = *nr;
n->mode = mode;
}
-void tNeuron_setCurrent (tNeuron* const n, float current)
+void tNeuron_setCurrent (tNeuron* const nr, float current)
{
+ _tNeuron* n = *nr;
n->current = current;
}
--- a/LEAF/Src/leaf-physical.c
+++ b/LEAF/Src/leaf-physical.c
@@ -46,6 +46,37 @@
leaf_free(p);
}
+void tPluck_initToPool (tPluck* const pl, float lowestFrequency, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPluck* p = *pl = (_tPluck*) mpool_alloc(sizeof(_tPluck), m->pool);
+
+ if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
+
+ tNoise_initToPool(&p->noise, WhiteNoise, mp);
+
+ tOnePole_initToPool(&p->pickFilter, 0.0f, mp);
+
+ tOneZero_initToPool(&p->loopFilter, 0.0f, mp);
+
+ tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf.sampleRate * 2, mp);
+
+ tPluck_setFrequency(pl, 220.0f);
+}
+
+void tPluck_freeFromPool (tPluck* const pl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPluck* p = *pl;
+
+ tNoise_freeFromPool(&p->noise, mp);
+ tOnePole_freeFromPool(&p->pickFilter, mp);
+ tOneZero_freeFromPool(&p->loopFilter, mp);
+ tAllpassDelay_freeFromPool(&p->delayLine, mp);
+
+ mpool_free(p, m->pool);
+}
+
float tPluck_getLastOut (tPluck* const pl)
{
_tPluck* p = *pl;
@@ -124,7 +155,7 @@
}
/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
-void tKarplusStrong_init (tKarplusStrong* const pl, float lowestFrequency)
+void tKarplusStrong_init (tKarplusStrong* const pl, float lowestFrequency)
{
_tKarplusStrong* p = *pl = (_tKarplusStrong*) leaf_alloc(sizeof(_tKarplusStrong));
@@ -151,7 +182,6 @@
p->loopGain = 0.999f;
tKarplusStrong_setFrequency( pl, 220.0f );
-
}
void tKarplusStrong_free (tKarplusStrong* const pl)
@@ -171,6 +201,54 @@
leaf_free(p);
}
+void tKarplusStrong_initToPool (tKarplusStrong* const pl, float lowestFrequency, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tKarplusStrong* p = *pl = (_tKarplusStrong*) mpool_alloc(sizeof(_tKarplusStrong), m->pool);
+
+ if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
+
+ tAllpassDelay_initToPool(&p->delayLine, 0.0f, leaf.sampleRate * 2, mp);
+
+ tLinearDelay_initToPool(&p->combDelay, 0.0f, leaf.sampleRate * 2, mp);
+
+ tOneZero_initToPool(&p->filter, 0.0f, mp);
+
+ tNoise_initToPool(&p->noise, WhiteNoise, mp);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tBiQuad_initToPool(&p->biquad[i], mp);
+ }
+
+ p->pluckAmplitude = 0.3f;
+ p->pickupPosition = 0.4f;
+
+ p->stretching = 0.9999f;
+ p->baseLoopGain = 0.995f;
+ p->loopGain = 0.999f;
+
+ tKarplusStrong_setFrequency( pl, 220.0f );
+}
+
+void tKarplusStrong_freeFromPool (tKarplusStrong* const pl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tKarplusStrong* p = *pl;
+
+ tAllpassDelay_freeFromPool(&p->delayLine, mp);
+ tLinearDelay_freeFromPool(&p->combDelay, mp);
+ tOneZero_freeFromPool(&p->filter, mp);
+ tNoise_freeFromPool(&p->noise, mp);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tBiQuad_freeFromPool(&p->biquad[i], mp);
+ }
+
+ mpool_free(p, m->pool);
+}
+
float tKarplusStrong_getLastOut (tKarplusStrong* const pl)
{
_tKarplusStrong* p = *pl;
@@ -328,7 +406,9 @@
/* Simple Living String*/
-void tSimpleLivingString_init(tSimpleLivingString* const pl, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
+void tSimpleLivingString_init(tSimpleLivingString* const pl, float freq, float dampFreq,
+ float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode)
{
_tSimpleLivingString* p = *pl = (_tSimpleLivingString*) leaf_alloc(sizeof(_tSimpleLivingString));
@@ -356,6 +436,38 @@
leaf_free(p);
}
+void tSimpleLivingString_initToPool (tSimpleLivingString* const pl, float freq, float dampFreq,
+ float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSimpleLivingString* p = *pl = (_tSimpleLivingString*) mpool_alloc(sizeof(_tSimpleLivingString), m->pool);
+
+ p->curr=0.0f;
+ tExpSmooth_initToPool(&p->wlSmooth, leaf.sampleRate/freq, 0.01, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+ tSimpleLivingString_setFreq(pl, freq);
+ tLinearDelay_initToPool(&p->delayLine,p->waveLengthInSamples, 2400, mp);
+ tOnePole_initToPool(&p->bridgeFilter, dampFreq, mp);
+ tHighpass_initToPool(&p->DCblocker,13, mp);
+ p->decay=decay;
+ tFeedbackLeveler_initToPool(&p->fbLev, targetLev, levSmoothFactor, levStrength, levMode, mp);
+ p->levMode=levMode;
+}
+
+void tSimpleLivingString_freeFromPool (tSimpleLivingString* const pl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tSimpleLivingString* p = *pl;
+
+ tExpSmooth_freeFromPool(&p->wlSmooth, mp);
+ tLinearDelay_freeFromPool(&p->delayLine, mp);
+ tOnePole_freeFromPool(&p->bridgeFilter, mp);
+ tHighpass_freeFromPool(&p->DCblocker, mp);
+ tFeedbackLeveler_freeFromPool(&p->fbLev, mp);
+
+ mpool_free(p, m->pool);
+}
+
void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
{
_tSimpleLivingString* p = *pl;
@@ -433,7 +545,9 @@
/* Living String*/
-void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
+void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex,
+ float dampFreq, float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode)
{
_tLivingString* p = *pl = (_tLivingString*) leaf_alloc(sizeof(_tLivingString));
@@ -484,6 +598,61 @@
leaf_free(p);
}
+void tLivingString_initToPool (tLivingString* const pl, float freq, float pickPos, float prepIndex,
+ float dampFreq, float decay, float targetLev, float levSmoothFactor,
+ float levStrength, int levMode, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLivingString* p = *pl = (_tLivingString*) mpool_alloc(sizeof(_tLivingString), m->pool);
+
+ p->curr=0.0f;
+ tExpSmooth_initToPool(&p->wlSmooth, leaf.sampleRate/freq, 0.01, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
+ tLivingString_setFreq(pl, freq);
+ p->freq = freq;
+ tExpSmooth_initToPool(&p->ppSmooth, pickPos, 0.01, mp); // smoother for pick position
+ tLivingString_setPickPos(pl, pickPos);
+ p->prepIndex=prepIndex;
+ tLinearDelay_initToPool(&p->delLF,p->waveLengthInSamples, 2400, mp);
+ tLinearDelay_initToPool(&p->delUF,p->waveLengthInSamples, 2400, mp);
+ tLinearDelay_initToPool(&p->delUB,p->waveLengthInSamples, 2400, mp);
+ tLinearDelay_initToPool(&p->delLB,p->waveLengthInSamples, 2400, mp);
+ p->dampFreq = dampFreq;
+ tOnePole_initToPool(&p->bridgeFilter, dampFreq, mp);
+ tOnePole_initToPool(&p->nutFilter, dampFreq, mp);
+ tOnePole_initToPool(&p->prepFilterU, dampFreq, mp);
+ tOnePole_initToPool(&p->prepFilterL, dampFreq, mp);
+ tHighpass_initToPool(&p->DCblockerU,13, mp);
+ tHighpass_initToPool(&p->DCblockerL,13, mp);
+ p->decay=decay;
+ p->prepIndex = prepIndex;
+ tFeedbackLeveler_initToPool(&p->fbLevU, targetLev, levSmoothFactor, levStrength, levMode, mp);
+ tFeedbackLeveler_initToPool(&p->fbLevL, targetLev, levSmoothFactor, levStrength, levMode, mp);
+ p->levMode=levMode;
+}
+
+void tLivingString_freeFromPool (tLivingString* const pl, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tLivingString* p = *pl;
+
+ tExpSmooth_freeFromPool(&p->wlSmooth, mp);
+ tExpSmooth_freeFromPool(&p->ppSmooth, mp);
+ tLinearDelay_freeFromPool(&p->delLF, mp);
+ tLinearDelay_freeFromPool(&p->delUF, mp);
+ tLinearDelay_freeFromPool(&p->delUB, mp);
+ tLinearDelay_freeFromPool(&p->delLB, mp);
+ tOnePole_freeFromPool(&p->bridgeFilter, mp);
+ tOnePole_freeFromPool(&p->nutFilter, mp);
+ tOnePole_freeFromPool(&p->prepFilterU, mp);
+ tOnePole_freeFromPool(&p->prepFilterL, mp);
+ tHighpass_freeFromPool(&p->DCblockerU, mp);
+ tHighpass_freeFromPool(&p->DCblockerL, mp);
+ tFeedbackLeveler_freeFromPool(&p->fbLevU, mp);
+ tFeedbackLeveler_freeFromPool(&p->fbLevL, mp);
+
+ mpool_free(p, m->pool);
+}
+
void tLivingString_setFreq(tLivingString* const pl, float freq)
{ // NOTE: It is faster to set wavelength in samples directly
_tLivingString* p = *pl;
@@ -577,20 +746,20 @@
tLinearDelay_tickIn(&p->delUB, fromNut);
// into lower half of string, from pickpoint, going backwards
float fromLowerPrep=-tOnePole_tick(&p->prepFilterL, fromLF);
- float intoLower=p->prepIndex*fromLowerPrep+(1-p->prepIndex)*fromUB+input;
+ float intoLower=p->prepIndex*fromLowerPrep+(1.0f - p->prepIndex)*fromUB+input;
tLinearDelay_tickIn(&p->delLB, intoLower);
// into lower half of string, from bridge
- float fromBridge=-tFeedbackLeveler_tick(&p->fbLevL, (p->levMode==0?p->decay:1)*tHighpass_tick(&p->DCblockerL, tOnePole_tick(&p->bridgeFilter, fromLB)));
+ float fromBridge=-tFeedbackLeveler_tick(&p->fbLevL, (p->levMode==0?p->decay:1.0f)*tHighpass_tick(&p->DCblockerL, tOnePole_tick(&p->bridgeFilter, fromLB)));
tLinearDelay_tickIn(&p->delLF, fromBridge);
// into upper half of string, from pickpoint, going forwards/upwards
float fromUpperPrep=-tOnePole_tick(&p->prepFilterU, fromUB);
- float intoUpper=p->prepIndex*fromUpperPrep+(1-p->prepIndex)*fromLF+input;
+ float intoUpper=p->prepIndex*fromUpperPrep+(1.0f - p->prepIndex)*fromLF+input;
tLinearDelay_tickIn(&p->delUF, intoUpper);
// update all delay lengths
float pickP=tExpSmooth_tick(&p->ppSmooth);
float wLen=tExpSmooth_tick(&p->wlSmooth);
float lowLen=pickP*wLen;
- float upLen=(1-pickP)*wLen;
+ float upLen=(1.0f-pickP)*wLen;
tLinearDelay_setDelay(&p->delLF, lowLen);
tLinearDelay_setDelay(&p->delLB, lowLen);
tLinearDelay_setDelay(&p->delUF, upLen);
@@ -621,6 +790,23 @@
_tReedTable* p = *pm;
leaf_free(p);
+}
+
+void tReedTable_initToPool (tReedTable* const pm, float offset, float slope, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tReedTable* p = *pm = (_tReedTable*) mpool_alloc(sizeof(_tReedTable), m->pool);
+
+ p->offset = offset;
+ p->slope = slope;
+}
+
+void tReedTable_freeFromPool (tReedTable* const pm, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tReedTable* p = *pm;
+
+ mpool_free(p, m->pool);
}
float tReedTable_tick (tReedTable* const pm, float input)
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -65,6 +65,54 @@
leaf_free(r);
}
+void tPRCReverb_initToPool (tPRCReverb* const rev, float t60, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPRCReverb* r = *rev = (_tPRCReverb*) mpool_alloc(sizeof(_tPRCReverb), m->pool);
+
+ if (t60 <= 0.0f) t60 = 0.001f;
+
+ r->inv_441 = 1.0f/44100.0f;
+
+ int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
+ double scaler = leaf.sampleRate * r->inv_441;
+
+ int delay, i;
+ if (scaler != 1.0f)
+ {
+ for (i=0; i<4; i++)
+ {
+ delay = (int) scaler * lengths[i];
+
+ if ( (delay & 1) == 0) delay++;
+
+ while ( !LEAF_isPrime(delay) ) delay += 2;
+
+ lengths[i] = delay;
+ }
+ }
+
+ tDelay_initToPool(&r->allpassDelays[0], lengths[0], lengths[0] * 2, mp);
+ tDelay_initToPool(&r->allpassDelays[1], lengths[1], lengths[1] * 2, mp);
+ tDelay_initToPool(&r->combDelay, lengths[2], lengths[2] * 2, mp);
+
+ tPRCReverb_setT60(rev, t60);
+
+ r->allpassCoeff = 0.7f;
+ r->mix = 0.5f;
+}
+
+void tPRCReverb_freeFromPool (tPRCReverb* const rev, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tPRCReverb* r = *rev;
+
+ tDelay_freeFromPool(&r->allpassDelays[0], mp);
+ tDelay_freeFromPool(&r->allpassDelays[1], mp);
+ tDelay_freeFromPool(&r->combDelay, mp);
+ mpool_free(r, m->pool);
+}
+
void tPRCReverb_setT60(tPRCReverb* const rev, float t60)
{
_tPRCReverb* r = *rev;
@@ -150,6 +198,7 @@
for ( i=0; i<6; i++ )
{
tLinearDelay_init(&r->combDelays[i], lengths[i], lengths[i] * 2.0f);
+ tLinearDelay_clear(&r->combDelays[i]);
r->combCoeffs[i] = pow(10.0, (-3 * lengths[i] * leaf.invSampleRate / t60));
}
@@ -156,6 +205,7 @@
for ( i=0; i<8; i++ )
{
tLinearDelay_init(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2.0f);
+ tLinearDelay_clear(&r->allpassDelays[i]);
}
@@ -181,6 +231,65 @@
leaf_free(r);
}
+void tNReverb_initToPool (tNReverb* const rev, float t60, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tNReverb* r = *rev = (_tNReverb*) mpool_alloc(sizeof(_tNReverb), m->pool);
+
+ if (t60 <= 0.0f) t60 = 0.001f;
+
+ r->inv_441 = 1.0f/44100.0f;
+
+ 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.
+ double scaler = leaf.sampleRate / 25641.0f;
+
+ int delay, i;
+
+ for (i=0; i < 15; i++)
+ {
+ delay = (int) scaler * lengths[i];
+ if ( (delay & 1) == 0)
+ delay++;
+ while ( !LEAF_isPrime(delay) )
+ delay += 2;
+ lengths[i] = delay;
+ }
+
+ for ( i=0; i<6; i++ )
+ {
+ tLinearDelay_initToPool(&r->combDelays[i], lengths[i], lengths[i] * 2.0f, mp);
+ r->combCoeffs[i] = pow(10.0, (-3 * lengths[i] * leaf.invSampleRate / t60));
+ }
+
+ for ( i=0; i<8; i++ )
+ {
+ tLinearDelay_initToPool(&r->allpassDelays[i], lengths[i+6], lengths[i+6] * 2.0f, mp);
+ }
+
+
+ tNReverb_setT60(rev, t60);
+ r->allpassCoeff = 0.7f;
+ r->mix = 0.3f;
+}
+
+void tNReverb_freeFromPool (tNReverb* const rev, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tNReverb* r = *rev;
+
+ for (int i = 0; i < 6; i++)
+ {
+ tLinearDelay_freeFromPool(&r->combDelays[i], mp);
+ }
+
+ for (int i = 0; i < 8; i++)
+ {
+ tLinearDelay_freeFromPool(&r->allpassDelays[i], mp);
+ }
+
+ mpool_free(r, m->pool);
+}
+
void tNReverb_setT60(tNReverb* const rev, float t60)
{
_tNReverb* r = *rev;
@@ -204,7 +313,7 @@
_tNReverb* r = *rev;
r->lastIn = input;
- float temp, temp0, temp1, temp2, temp3, out;
+ float temp, temp0, temp1, temp2, out;
int i;
temp0 = 0.0;
@@ -381,8 +490,6 @@
tDattorroReverb_setFeedbackFilter(rev, 5000.f);
tDattorroReverb_setFeedbackGain(rev, 0.4f);
-
-
}
void tDattorroReverb_free (tDattorroReverb* const rev)
@@ -425,6 +532,111 @@
tCycle_free(&r->f2_lfo);
leaf_free(r);
+}
+
+void tDattorroReverb_initToPool (tDattorroReverb* const rev, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tDattorroReverb* r = *rev = (_tDattorroReverb*) mpool_alloc(sizeof(_tDattorroReverb), m->pool);
+
+ r->size_max = 2.0f;
+ r->size = 1.f;
+ r->t = r->size * leaf.sampleRate * 0.001f;
+ r->frozen = 0;
+ // INPUT
+ tTapeDelay_initToPool(&r->in_delay, 0.f, SAMP(200.f), mp);
+ tOnePole_initToPool(&r->in_filter, 1.f, mp);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_initToPool(&r->in_allpass[i], SAMP(in_allpass_delays[i]), SAMP(20.f), mp); // * r->size_max
+ tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+ }
+
+ // FEEDBACK 1
+ tAllpass_initToPool(&r->f1_allpass, SAMP(30.51f), SAMP(100.f), mp); // * r->size_max
+ tAllpass_setGain(&r->f1_allpass, 0.7f);
+
+ tTapeDelay_initToPool(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f) * r->size_max + 1, mp);
+ tTapeDelay_initToPool(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f) * r->size_max + 1, mp);
+ tTapeDelay_initToPool(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f) * r->size_max + 1, mp);
+
+ tOnePole_initToPool(&r->f1_filter, 1.f, mp);
+
+ tHighpass_initToPool(&r->f1_hp, 20.f, mp);
+
+ tCycle_initToPool(&r->f1_lfo, mp);
+ tCycle_setFreq(&r->f1_lfo, 0.1f);
+
+ // FEEDBACK 2
+ tAllpass_initToPool(&r->f2_allpass, SAMP(22.58f), SAMP(100.f), mp); // * r->size_max
+ tAllpass_setGain(&r->f2_allpass, 0.7f);
+
+ tTapeDelay_initToPool(&r->f2_delay_1, SAMP(149.62f), SAMP(200.f) * r->size_max + 1, mp);
+ tTapeDelay_initToPool(&r->f2_delay_2, SAMP(60.48f), SAMP(100.f) * r->size_max + 1, mp);
+ tTapeDelay_initToPool(&r->f2_delay_3, SAMP(106.28f), SAMP(200.f) * r->size_max + 1, mp);
+
+ tOnePole_initToPool(&r->f2_filter, 1.f, mp);
+
+ tHighpass_initToPool(&r->f2_hp, 20.f, mp);
+
+ tCycle_initToPool(&r->f2_lfo, mp);
+ tCycle_setFreq(&r->f2_lfo, 0.07f);
+
+
+ // PARAMETERS
+ tDattorroReverb_setMix(rev, 0.5f);
+
+ tDattorroReverb_setInputDelay(rev, 0.f);
+
+ tDattorroReverb_setInputFilter(rev, 10000.f);
+
+ tDattorroReverb_setFeedbackFilter(rev, 5000.f);
+
+ tDattorroReverb_setFeedbackGain(rev, 0.4f);
+}
+
+void tDattorroReverb_freeFromPool (tDattorroReverb* const rev, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tDattorroReverb* r = *rev;
+
+ // INPUT
+ tTapeDelay_freeFromPool(&r->in_delay, mp);
+ tOnePole_freeFromPool(&r->in_filter, mp);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_freeFromPool(&r->in_allpass[i], mp);
+ }
+
+ // FEEDBACK 1
+ tAllpass_freeFromPool(&r->f1_allpass, mp);
+
+ tTapeDelay_freeFromPool(&r->f1_delay_1, mp);
+ tTapeDelay_freeFromPool(&r->f1_delay_2, mp);
+ tTapeDelay_freeFromPool(&r->f1_delay_3, mp);
+
+ tOnePole_freeFromPool(&r->f1_filter, mp);
+
+ tHighpass_freeFromPool(&r->f1_hp, mp);
+
+ tCycle_freeFromPool(&r->f1_lfo, mp);
+
+ // FEEDBACK 2
+ tAllpass_freeFromPool(&r->f2_allpass, mp);
+
+ tTapeDelay_freeFromPool(&r->f2_delay_1, mp);
+ tTapeDelay_freeFromPool(&r->f2_delay_2, mp);
+ tTapeDelay_freeFromPool(&r->f2_delay_3, mp);
+
+ tOnePole_freeFromPool(&r->f2_filter, mp);
+
+ tHighpass_freeFromPool(&r->f2_hp, mp);
+
+ tCycle_freeFromPool(&r->f2_lfo, mp);
+
+ mpool_free(r, m->pool);
}
float tDattorroReverb_tick (tDattorroReverb* const rev, float input)
--- a/LEAF/Src/leaf-sampling.c
+++ b/LEAF/Src/leaf-sampling.c
@@ -35,40 +35,37 @@
s->active = 0;
s->idx = 0;
s->mode = RecordOneShot;
-
- tBuffer_clear(sb);
}
-void tBuffer_init_locate (tBuffer* const sb, uint32_t length, mpool_t* pool)
+void tBuffer_free (tBuffer* const sb)
{
- _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), pool);
+ _tBuffer* s = *sb;
+
+ leaf_free(s->buff);
+ leaf_free(s);
+}
- s->buff = (float*) mpool_alloc( sizeof(float) * length, pool);
-
+void tBuffer_initToPool (tBuffer* const sb, uint32_t length, tMempool* const mp)
+{
+ _tMempool* m = *mp;
+ _tBuffer* s = *sb = (_tBuffer*) mpool_alloc(sizeof(_tBuffer), m->pool);
+
+ s->buff = (float*) mpool_alloc( sizeof(float) * length, m->pool);
+
s->bufferLength = length;
s->recordedLength = 0;
s->idx = 0;
s->mode = RecordOneShot;
-
- tBuffer_clear(sb);
}
-void tBuffer_free (tBuffer* const sb)
+void tBuffer_freeFromPool (tBuffer* const sb, tMempool* const mp)
{
+ _tMempool* m = *mp;
_tBuffer* s = *sb;
-
- leaf_free(s->buff);
- leaf_free(s);
-}
-void tBuffer_free_locate (tBuffer* const sb, mpool_t* pool)
-{
- _tBuffer* s = *sb;
-
- mpool_free(s->buff, pool);
- mpool_free(s, pool);
+ mpool_free(s->buff, m->pool);
+ mpool_free(s, m->pool);
}
-
void tBuffer_tick (tBuffer* const sb, float sample)
{