shithub: leaf

Download patch

ref: 3eaa22b1fa6fafffdb6961c7dda791f3df59d885
parent: 8b254651676c1c577ecc1bacf05470e61258476a
author: Matthew Wang <mjw7@princeton.edu>
date: Mon Mar 1 11:08:36 EST 2021

factor sample rate into tick based env factors and neuron timestep

--- a/leaf/Inc/leaf-envelopes.h
+++ b/leaf/Inc/leaf-envelopes.h
@@ -164,8 +164,9 @@
     {
         
         tMempool mempool;
-        float factor, oneminusfactor;
+        float baseFactor, factor, oneminusfactor;
         float curr,dest;
+        float invSampleRate;
     } _tExpSmooth;
     
     typedef _tExpSmooth* tExpSmooth;
@@ -179,7 +180,8 @@
     void    tExpSmooth_setFactor    (tExpSmooth* const, float factor);
     void    tExpSmooth_setDest      (tExpSmooth* const, float dest);
     void    tExpSmooth_setVal       (tExpSmooth* const, float val);
-    void    tExpSmooth_setValAndDest(tExpSmooth* const expsmooth, float val);
+    void    tExpSmooth_setValAndDest(tExpSmooth* const, float val);
+    void    tExpSmooth_setSampleRate(tExpSmooth* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
@@ -252,6 +254,8 @@
         
         float next;
         
+        float attack, decay, release;
+        
         float attackInc, decayInc, releaseInc, rampInc;
         
         int inAttack, inDecay, inSustain, inRelease, inRamp;
@@ -260,7 +264,9 @@
         
         float attackPhase, decayPhase, releasePhase, rampPhase;
         
-        float leakFactor;
+        float baseLeakFactor, leakFactor;
+        
+        float invSampleRate;
     } _tADSR;
     
     typedef _tADSR* tADSR;
@@ -277,6 +283,7 @@
     void    tADSR_setLeakFactor (tADSR* const, float leakFactor);
     void    tADSR_on            (tADSR* const, float velocity);
     void    tADSR_off           (tADSR* const);
+    void    tADSR_setSampleRate (tADSR* const, float sr);
     
     // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
     
@@ -358,7 +365,9 @@
         
         float attackPhase, decayPhase, releasePhase, rampPhase;
         
-        float leakFactor;
+        float baseLeakFactor, leakFactor;
+        
+        float invSampleRate;
     } _tADSRT;
     
     typedef _tADSRT* tADSRT;
@@ -466,12 +475,12 @@
         float attackBase;
         float decayBase;
         float releaseBase;
-        float leakFactor;
+        float baseLeakFactor, leakFactor;
         float targetGainSquared;
         float factor;
         float oneMinusFactor;
         float gain;
-        
+        float invSampleRate;
     } _tADSRS;
     
     typedef _tADSRS* tADSRS;
--- a/leaf/Inc/leaf-math.h
+++ b/leaf/Inc/leaf-math.h
@@ -58,6 +58,9 @@
 #define INV_10240      0.00009765625f
 #define INV_20480      0.000048828125f
     
+#define INV_44100      0.00002267573f
+#define INV_48000      0.00002083333f
+    
     
 #define INV_TWELVE                 0.0833333333f
 #define INV_440                     0.0022727273f
--- a/leaf/Inc/leaf-oscillators.h
+++ b/leaf/Inc/leaf-oscillators.h
@@ -630,7 +630,7 @@
         
         float voltage, current;
         float timeStep;
-        
+        float invSampleRate;
         float alpha[3];
         float beta[3];
         float rate[3];
@@ -657,6 +657,7 @@
     void    tNeuron_setV2       (tNeuron* const neuron, float V2);
     void    tNeuron_setV3       (tNeuron* const neuron, float V3);
     void    tNeuron_setTimeStep (tNeuron* const neuron, float timestep);
+    void    tNeuron_setSampleRate(tNeuron* const neuron, float sr);
 
     //==============================================================================
     
--- a/leaf/Inc/leaf-reverb.h
+++ b/leaf/Inc/leaf-reverb.h
@@ -77,7 +77,6 @@
         
         float mix, t60;
         
-        float inv_441;
         float sampleRate;
         float invSampleRate;
         
@@ -152,7 +151,6 @@
         
         float mix, t60;
         
-        float inv_441;
         float sampleRate;
         float invSampleRate;
         
--- a/leaf/Src/leaf-envelopes.c
+++ b/leaf/Src/leaf-envelopes.c
@@ -234,11 +234,13 @@
         attack = 8192.0f;
     if (attack < 0.0f)
         attack = 0.0f;
+    adsr->attack = attack;
 
     if (decay > 8192.0f)
         decay = 8192.0f;
     if (decay < 0.0f)
         decay = 0.0f;
+    adsr->decay = decay;
 
     if (sustain > 1.0f)
         sustain = 1.0f;
@@ -249,6 +251,7 @@
         release = 8192.0f;
     if (release < 0.0f)
         release = 0.0f;
+    adsr->release = release;
 
     int16_t attackIndex = ((int16_t)(attack * 8.0f))-1;
     int16_t decayIndex = ((int16_t)(decay * 8.0f))-1;
@@ -279,7 +282,9 @@
     adsr->releaseInc = adsr->inc_buff[releaseIndex];
     adsr->rampInc = adsr->inc_buff[rampIndex];
 
+    adsr->baseLeakFactor = 1.0f;
     adsr->leakFactor = 1.0f;
+    adsr->invSampleRate = adsr->mempool->leaf->invSampleRate;
 }
 
 void    tADSR_free (tADSR* const adsrenv)
@@ -293,6 +298,8 @@
     _tADSR* adsr = *adsrenv;
 
     int32_t attackIndex;
+    
+    adsr->attack = attack;
 
     if (attack < 0.0f) {
         attackIndex = 0.0f;
@@ -302,7 +309,7 @@
         attackIndex = ((int32_t)(8192.0f * 8.0f))-1;
     }
 
-    adsr->attackInc = adsr->inc_buff[attackIndex];
+    adsr->attackInc = adsr->inc_buff[attackIndex] * (44100.f * adsr->invSampleRate);
 }
 
 void     tADSR_setDecay(tADSR* const adsrenv, float decay)
@@ -310,6 +317,8 @@
     _tADSR* adsr = *adsrenv;
 
     int32_t decayIndex;
+    
+    adsr->decay = decay;
 
     if (decay < 0.0f) {
         decayIndex = 0.0f;
@@ -319,7 +328,7 @@
         decayIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
     }
 
-    adsr->decayInc = adsr->inc_buff[decayIndex];
+    adsr->decayInc = adsr->inc_buff[decayIndex] * (44100.f * adsr->invSampleRate);
 }
 
 void     tADSR_setSustain(tADSR* const adsrenv, float sustain)
@@ -336,6 +345,8 @@
     _tADSR* adsr = *adsrenv;
 
     int32_t releaseIndex;
+    
+    adsr->release = release;
 
     if (release < 0.0f) {
         releaseIndex = 0.0f;
@@ -345,7 +356,7 @@
         releaseIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
     }
 
-    adsr->releaseInc = adsr->inc_buff[releaseIndex];
+    adsr->releaseInc = adsr->inc_buff[releaseIndex] * (44100.f * adsr->invSampleRate);
 }
 
 // 0.999999 is slow leak, 0.9 is fast leak
@@ -352,9 +363,8 @@
 void     tADSR_setLeakFactor(tADSR* const adsrenv, float leakFactor)
 {
     _tADSR* adsr = *adsrenv;
-
-
-    adsr->leakFactor = leakFactor;
+    adsr->baseLeakFactor = leakFactor;
+    adsr->leakFactor = powf(leakFactor, 44100.0f * adsr->invSampleRate);
 }
 
 void tADSR_on(tADSR* const adsrenv, float velocity)
@@ -482,6 +492,19 @@
 
     return adsr->next;
 }
+
+void tADSR_setSampleRate(tADSR* const adsrenv, float sr)
+{
+    _tADSR* adsr = *adsrenv;
+    
+    adsr->invSampleRate = 1.0f/sr;
+    
+    tADSR_setAttack(adsrenv, adsr->attack);
+    tADSR_setDecay(adsrenv, adsr->decay);
+    tADSR_setRelease(adsrenv, adsr->release);
+    tADSR_setLeakFactor(adsrenv, adsr->baseLeakFactor);
+}
+
 #endif // LEAF_INCLUDE_ADSR_TABLES
 
 
@@ -535,7 +558,11 @@
     adsr->factor = 0.01f;
     adsr->oneMinusFactor = 0.99f;
     adsr->output = 0.0f;
+    
+    adsr->baseLeakFactor = 1.0f;
     adsr->leakFactor = 1.0f;
+    
+    adsr->invSampleRate = leaf->invSampleRate;
 }
 
 void    tADSRS_free  (tADSRS* const adsrenv)
@@ -586,7 +613,8 @@
 void     tADSRS_setLeakFactor(tADSRS* const adsrenv, float leakFactor)
 {
     _tADSRS* adsr = *adsrenv;
-    adsr->leakFactor = leakFactor;
+    adsr->baseLeakFactor = leakFactor;
+    adsr->leakFactor = powf(leakFactor, 44100.0f * adsr->invSampleRate);
 }
 
 void tADSRS_on(tADSRS* const adsrenv, float velocity)
@@ -650,10 +678,12 @@
     
     adsr->sampleRate = sr;
     adsr->sampleRateInMs =  adsr->sampleRate * 0.001f;
+    adsr->invSampleRate = 1.0f/sr;
     
     tADSRS_setAttack(adsrenv, adsr->attack);
     tADSRS_setDecay(adsrenv, adsr->decay);
     tADSRS_setRelease(adsrenv, adsr->release);
+    tADSRS_setLeakFactor(adsrenv, adsr->baseLeakFactor);
 }
 
 //================================================================================
@@ -710,7 +740,9 @@
     adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / release;
     adsr->rampInc = adsr->bufferSizeDividedBySampleRateInMs / 8.0f;
 
+    adsr->baseLeakFactor = 1.0f;
     adsr->leakFactor = 1.0f;
+    adsr->invSampleRate = leaf->invSampleRate;
 }
 
 void    tADSRT_free  (tADSRT* const adsrenv)
@@ -768,7 +800,8 @@
 void     tADSRT_setLeakFactor(tADSRT* const adsrenv, float leakFactor)
 {
     _tADSRT* adsr = *adsrenv;
-    adsr->leakFactor = leakFactor;
+    adsr->baseLeakFactor = leakFactor;
+    adsr->leakFactor = powf(leakFactor, 44100.0f * adsr->invSampleRate);;
 }
 
 void tADSRT_on(tADSRT* const adsrenv, float velocity)
@@ -1010,16 +1043,18 @@
     return adsr->next;
 }
 
-void    tADSRT_setSampleRate (tADSRT* const adsrenv, float sr)
+void    tADSRT_setSampleRate(tADSRT* const adsrenv, float sr)
 {
     _tADSRT* adsr = *adsrenv;
     
     adsr->sampleRate = sr;
+    adsr->invSampleRate = 1.0f/sr;
     adsr->bufferSizeDividedBySampleRateInMs = adsr->buff_size / (adsr->sampleRate * 0.001f);
     adsr->attackInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->attack;
     adsr->decayInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->decay;
     adsr->releaseInc = adsr->bufferSizeDividedBySampleRateInMs / adsr->release;
     adsr->rampInc = adsr->bufferSizeDividedBySampleRateInMs / 8.0f;
+    adsr->leakFactor = powf(adsr->baseLeakFactor, 44100.0f * adsr->invSampleRate);
 }
 
 /////-----------------
@@ -1279,12 +1314,13 @@
     _tExpSmooth* smooth = *expsmooth = (_tExpSmooth*) mpool_alloc(sizeof(_tExpSmooth), m);
     smooth->mempool = m;
     
-    smooth->curr=val;
-    smooth->dest=val;
-    if (factor<0) factor=0;
-    if (factor>1) factor=1;
-    smooth->factor=factor;
-    smooth->oneminusfactor=1.0f-factor;
+    smooth->curr = val;
+    smooth->dest = val;
+    if (factor < 0) factor = 0;
+    if (factor > 1) factor = 1;
+    smooth->factor = factor;
+    smooth->oneminusfactor = 1.0f - factor;
+    smooth->invSampleRate = smooth->mempool->leaf->invSampleRate;
 }
 
 void    tExpSmooth_free (tExpSmooth* const expsmooth)
@@ -1297,12 +1333,12 @@
 {   // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
     _tExpSmooth* smooth = *expsmooth;
     
-    if (factor<0)
-        factor=0;
-    else
-        if (factor>1) factor=1;
-    smooth->factor=factor;
-    smooth->oneminusfactor=1.0f-factor;
+    if (factor < 0)
+        factor = 0;
+    else if (factor > 1) factor = 1;
+    smooth->baseFactor = factor;
+    smooth->factor = powf(factor, 44100.f * smooth->invSampleRate);
+    smooth->oneminusfactor = 1.0f - factor;
 }
 
 void     tExpSmooth_setDest(tExpSmooth* const expsmooth, float dest)
@@ -1335,6 +1371,14 @@
 {
     _tExpSmooth* smooth = *expsmooth;
     return smooth->curr;
+}
+
+void    tExpSmooth_setSampleRate(tExpSmooth* const expsmooth, float sr)
+{
+    _tExpSmooth* smooth = *expsmooth;
+    smooth->invSampleRate = 1.0f/sr;
+    smooth->factor = powf(smooth->baseFactor, 44100.f * smooth->invSampleRate);
+    smooth->oneminusfactor = 1.0f - smooth->factor;
 }
 
 //tSlide is based on the max/msp slide~ object
--- a/leaf/Src/leaf-oscillators.c
+++ b/leaf/Src/leaf-oscillators.c
@@ -700,12 +700,14 @@
     _tMempool* m = *mp;
     _tNeuron* n = *nr = (_tNeuron*) mpool_alloc(sizeof(_tNeuron), m);
     n->mempool = m;
+    LEAF* leaf = n->mempool->leaf;
 
     tPoleZero_initToPool(&n->f, mp);
     
     tPoleZero_setBlockZero(&n->f, 0.99f);
     
-    n->timeStep = 1.0f / 50.0f;
+    n->invSampleRate = leaf->invSampleRate;
+    n->timeStep = (44100.0f * n->invSampleRate) / 50.0f;
     
     n->current = 0.0f; // 100.0f for sound
     n->voltage = 0.0f;
@@ -742,7 +744,7 @@
     
     tPoleZero_setBlockZero(&n->f, 0.99f);
     
-    n->timeStep = 1.0f / 50.0f;
+    n->timeStep = (44100.0f * n->invSampleRate) / 50.0f;
     
     n->current = 0.0f; // 100.0f for sound
     n->voltage = 0.0f;
@@ -786,7 +788,7 @@
 void tNeuron_setTimeStep(tNeuron* const nr, float timeStep)
 {
     _tNeuron* n = *nr;
-    n->timeStep = timeStep;
+    n->timeStep = (44100.0f * n->invSampleRate) * timeStep;
 }
 
 void tNeuron_setK(tNeuron* const nr, float K)
@@ -901,6 +903,13 @@
 {
     _tNeuron* n = *nr;
     n->current = current;
+}
+
+void tNeuron_setSampleRate (tNeuron* const nr, float sr)
+{
+    _tNeuron* n = *nr;
+    n->invSampleRate = 1.0f/sr;
+    n->timeStep = (44100.0f * n->invSampleRate) / 50.0f;
 }
 
 //----------------------------------------------------------------------------------------------------------
--- a/leaf/Src/leaf-reverb.c
+++ b/leaf/Src/leaf-reverb.c
@@ -33,13 +33,11 @@
     
     if (t60 <= 0.0f) t60 = 0.001f;
     
-    r->inv_441 = 1.0f/44100.0f;
-    
     r->sampleRate = leaf->sampleRate;
     r->invSampleRate = leaf->invSampleRate;
     
     int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
-    double scaler = r->sampleRate * r->inv_441;
+    double scaler = r->sampleRate * INV_44100;
     
     int delay, i;
     if (scaler != 1.0f)
@@ -144,7 +142,7 @@
     r->invSampleRate = 1.0f/r->sampleRate;
     
     int lengths[4] = { 341, 613, 1557, 2137 }; // Delay lengths for 44100 Hz sample rate.
-    double scaler = r->sampleRate * r->inv_441;
+    double scaler = r->sampleRate * INV_44100;
     
     int delay, i;
     if (scaler != 1.0f)
@@ -187,12 +185,11 @@
     
     if (t60 <= 0.0f) t60 = 0.001f;
     
-    r->inv_441 = 1.0f/44100.0f;
     r->sampleRate = leaf->sampleRate;
     r->invSampleRate = leaf->invSampleRate;
     
     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 = r->sampleRate * r->inv_441;// / 25641.0f;
+    double scaler = r->sampleRate * INV_44100;// / 25641.0f;
     
     int delay, i;
     
@@ -389,7 +386,7 @@
     r->invSampleRate = 1.0f/r->sampleRate;
     
     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 = r->sampleRate * r->inv_441;// / 25641.0f;
+    double scaler = r->sampleRate * INV_44100;// / 25641.0f;
     
     int delay, i;