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;