History

optimized some things, such as compressor.

Jeffrey Snyder committed 3 years ago

Commit c4f8a191 parent 96b6a598 files · +63 −52Browse files

Unified · Split

8 files
  1. leaf/Inc/leaf-dynamics.h +2 −1
  2. leaf/Inc/leaf-filters.h +1 −0
  3. leaf/Inc/leaf-math.h +2 −0
  4. leaf/Inc/leaf-physical.h +7 −5
  5. leaf/Src/leaf-dynamics.c +18 −28
  6. leaf/Src/leaf-filters.c +14 −1
  7. leaf/Src/leaf-math.c +4 −1
  8. leaf/Src/leaf-physical.c +15 −16
leaf/Inc/leaf-dynamics.h+2−1
@@ -64,7 +64,8 @@ extern "C" { · 63 unmodified lines
6464
6565 float tauAttack, tauRelease;
6666 float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain
67−
67+ float invR;
68+ float inv4W;
6869 float x_G[2], y_G[2], x_T[2], y_T[2];
6970
7071 int isActive;
leaf/Inc/leaf-filters.h+1−0
@@ -1072,6 +1072,7 @@ extern "C" { · 1071 unmodified lines
10721072 void tVZFilter_setResonance (tVZFilter* const vf, float res);
10731073 void tVZFilter_setFrequencyAndResonance (tVZFilter* const vf, float freq, float res);
10741074 void tVZFilter_setFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, float res, float gains);
1075+ void tVZFilter_setFastFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, float res, float gain);
10751076 void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain);
10761077 void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph);
10771078 void tVZFilter_setMorphOnly (tVZFilter* const vf, float morph);
leaf/Inc/leaf-math.h+2−0
@@ -217,6 +217,8 @@ extern "C" { · 216 unmodified lines
217217
218218 float atodb(float a);
219219
220+ float fasteratodb(float a);
221+
220222 float dbtoa(float db);
221223
222224 float fastdbtoa(float db);
leaf/Inc/leaf-physical.h+7−5
@@ -351,26 +351,28 @@ typedef struct _tSimpleLivingString3 · 350 unmodified lines
351351 float curr;
352352 float Uout;
353353 float Lout;
354+ int maxLength;
354355 tLinearDelay delayLineU;
355356 tLinearDelay delayLineL;
356357 tOnePole bridgeFilter;
357358 tHighpass DCblocker;
358359 tFeedbackLeveler fbLev;
359360 tExpSmooth wlSmooth;
361+ int oversampling;
360362 float sampleRate;
361363 } _tSimpleLivingString3;
362364
363365 typedef _tSimpleLivingString3* tSimpleLivingString3;
364366
365−void tSimpleLivingString3_init (tSimpleLivingString3* const, float freq, float dampFreq,
367+void tSimpleLivingString3_init (tSimpleLivingString3* const, int oversampling, float freq, float dampFreq,
366368 float decay, float targetLev, float levSmoothFactor,
367369 float levStrength, int levMode, LEAF* const leaf);
368−void tSimpleLivingString3_initToPool (tSimpleLivingString3* const, float freq, float dampFreq,
369− float decay, float targetLev, float levSmoothFactor,
370− float levStrength, int levMode, tMempool* const);
370+void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
371+ float decay, float targetLev, float levSmoothFactor,
372+ float levStrength, int levMode, tMempool* const mp);
371373 void tSimpleLivingString3_free (tSimpleLivingString3* const);
372374
373−float tSimpleLivingString3_pluck (tSimpleLivingString3* const pl, float input, float position);
375+void tSimpleLivingString3_pluck (tSimpleLivingString3* const pl, float input, float position);
374376 float tSimpleLivingString3_tick (tSimpleLivingString3* const, float input);
375377 float tSimpleLivingString3_sample (tSimpleLivingString3* const);
376378 void tSimpleLivingString3_setFreq (tSimpleLivingString3* const, float freq);
leaf/Src/leaf-dynamics.c+18−28
@@ -64,8 +64,10 @@ void tCompressor_initToPool (tCompressor* const comp, tMempool* const mp) · 63 unmodified lines
6464 c->y_T[0] = 0.0f, c->y_T[1] = 0.0f;
6565 c->T = 0.0f; // Threshold
6666 c->R = 0.5f; // compression Ratio
67+ c->invR = 2.0f; //inverse of ratio
6768 c->M = 3.0f; // decibel Make-up gain
68− c->W = 1.0f; // decibel Width of knee transition
69+ c->W = 1.5f; // decibel Width of knee transition
70+ c->inv4W = 1.0f / (4.0f * c->W) ;
6971
7072
7173 }
@@ -83,34 +85,33 @@ float tCompressor_tick(tCompressor* const comp, float in) · 11 unmodified lines
8385
8486 float slope, overshoot;
8587
86− float in_db = LEAF_clip(-90.0f, atodb(fabsf(in)), 0.0f);
88+ float in_db = LEAF_clip(-90.0f, fasteratodb(fastabsf(in)), 0.0f);
8789 float out_db = 0.0f;
8890
8991 c->y_T[1] = c->y_T[0];
9092
91− slope = 1.0f - (1.0f/c->R); // feed-forward topology;
93+ slope = 1.0f - c->invR; // feed-forward topology;
9294
9395 overshoot = in_db - c->T;
9496
95− /*
96− if (overshoot <= -(c->W * 0.5f))
97+
98+ if (overshoot <= -(c->W))
9799 {
98100 out_db = in_db;
99101 c->isActive = 0;
100102 }
101−
102− else if ((overshoot > -(c->W * 0.5f)) && (overshoot < (c->W * 0.5f)))
103+ else if ((overshoot > -(c->W)) && (overshoot < (c->W)))
103104 {
104− float squareit = (overshoot + c->W*0.5f);
105− out_db = in_db + slope * ((squareit * squareit) / (2.0f * c->W)); // .^ 2 ???
105+ float squareit = (overshoot + c->W);
106+ out_db = in_db + slope * ((squareit * squareit) * c->inv4W); // .^ 2 ???
106107 c->isActive = 1;
107108 }
108− else if (overshoot >= (c->W * 0.5f))
109+ else
109110 {
110111 out_db = in_db + slope * overshoot;
111112 c->isActive = 1;
112113 }
113− */
114+/* // simpler hard-knee version
114115 if (overshoot <= 0.0f)
115116 {
116117 out_db = in_db;
@@ -121,26 +122,13 @@ float tCompressor_tick(tCompressor* const comp, float in) · 4 unmodified lines
121122 out_db = in_db + slope * overshoot;
122123 c->isActive = 1;
123124 }
124−
125+ */
125126 c->x_T[0] = out_db - in_db;
126−
127−
128−
129127 if (c->x_T[0] > c->y_T[1])
130128 c->y_T[0] = c->tauAttack * c->y_T[1] + (1.0f-c->tauAttack) * c->x_T[0];
131129 else
132130 c->y_T[0] = c->tauRelease * c->y_T[1] + (1.0f-c->tauRelease) * c->x_T[0];
133− if (isnan(c->y_T[0]))
134− {
135− out_db = 1.0f;
136− }
137−
138131 float attenuation = fasterdbtoa(c->M - c->y_T[0]);
139− if (isnan(attenuation))
140− {
141− out_db = 1.0f;
142− }
143− //float attenuation = 1.0f;
144132 return attenuation * in;
145133 }
146134
@@ -158,10 +146,12 @@ void tCompressor_setParams(tCompressor* const comp, float thresh, float ratio, f · 11 unmodified lines
158146 _tCompressor* c = *comp;
159147 c->T = thresh;
160148 c->R = ratio;
161− c->W = knee;
149+ c->invR = 1.0f / ratio;
150+ c->W = knee * 0.5f;
151+ c->inv4W = 1.0f / (2.0f * knee);
162152 c->M = makeup;
163− c->tauAttack = expf(-1.0f/(0.001f * attack * c->sampleRate));
164− c->tauRelease = expf(-1.0f/(0.001f * release * c->sampleRate));
153+ c->tauAttack = fasterexpf(-1.0f/(0.001f * attack * c->sampleRate));
154+ c->tauRelease = fasterexpf(-1.0f/(0.001f * release * c->sampleRate));
165155 }
166156
167157 /* Feedback Leveler */
leaf/Src/leaf-filters.c+14−1
@@ -1524,7 +1524,7 @@ void tVZFilter_setFreqFast (tVZFilter* const vf, float cutoff) · 1523 unmodified lines
15241524 int intVer = (int)cutoff;
15251525 float floatVer = cutoff - (float)intVer;
15261526 f->g = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
1527−
1527+
15281528 switch( f->type )
15291529 {
15301530 case Bypass:
@@ -1697,6 +1697,18 @@ void tVZFilter_setFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, · 166 unmodified lines
16971697 f->invG = 1.0f/f->G;
16981698 tVZFilter_calcCoeffs(vf);
16991699 }
1700+
1701+void tVZFilter_setFastFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, float res, float gain)
1702+{
1703+ _tVZFilter* f = *vf;
1704+ //f->fc = LEAF_clip(0.1f, freq, 0.4f * f->sampleRate);
1705+ f->Q = LEAF_clip(0.01f, res, 100.0f);
1706+ f->R2 = 1.0f / f->Q;
1707+ f->G = LEAF_clip(0.000001f, gain, 4000.0f);
1708+ f->invG = 1.0f/f->G;
1709+ tVZFilter_setFreqFast(vf, freq);
1710+}
1711+
17001712 void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain)
17011713 {
17021714 _tVZFilter* f = *vf;
@@ -1708,6 +1720,7 @@ void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, · 5 unmodified lines
17081720 tVZFilter_calcCoeffs(vf);
17091721 }
17101722
1723+
17111724 void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph)
17121725 {
17131726 _tVZFilter* f = *vf;
leaf/Src/leaf-math.c+4−1
@@ -810,11 +810,14 @@ float atodb(float a) · 809 unmodified lines
810810 {
811811 return 20.0f*log10f(a);
812812 }
813+float fasteratodb(float a)
814+{
815+ return 20.0f*log10f_fast(a);
816+}
813817
814818 float dbtoa(float db)
815819 {
816820 return powf(10.0f, db * 0.05f);
817− //return expf(0.115129254649702f * db); //faster version from http://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html
818821 }
819822
820823
leaf/Src/leaf-physical.c+15−16
@@ -501,14 +501,14 @@ void tSimpleLivingString_setSampleRate(tSimpleLivingString* const pl, float sr · 500 unmodified lines
501501
502502 /* Simple Living String*/
503503
504−void tSimpleLivingString3_init(tSimpleLivingString3* const pl, float freq, float dampFreq,
504+void tSimpleLivingString3_init(tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
505505 float decay, float targetLev, float levSmoothFactor,
506506 float levStrength, int levMode, LEAF* const leaf)
507507 {
508− tSimpleLivingString3_initToPool(pl, freq, dampFreq, decay, targetLev, levSmoothFactor, levStrength, levMode, &leaf->mempool);
508+ tSimpleLivingString3_initToPool(pl, oversampling, freq, dampFreq, decay, targetLev, levSmoothFactor, levStrength, levMode, &leaf->mempool);
509509 }
510510
511−void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, float freq, float dampFreq,
511+void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
512512 float decay, float targetLev, float levSmoothFactor,
513513 float levStrength, int levMode, tMempool* const mp)
514514 {
@@ -516,12 +516,13 @@ void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, float · 1 unmodified line
516516 _tSimpleLivingString3* p = *pl = (_tSimpleLivingString3*) mpool_alloc(sizeof(_tSimpleLivingString3), m);
517517 p->mempool = m;
518518 LEAF* leaf = p->mempool->leaf;
519−
520− p->sampleRate = leaf->sampleRate;
519+ p->oversampling = oversampling;
520+ p->sampleRate = leaf->sampleRate * oversampling;
521521 p->curr=0.0f;
522+ p->maxLength = 2400 * oversampling;
522523 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq/2.0f, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)
523− tLinearDelay_initToPool(&p->delayLineU,p->waveLengthInSamples, 2400, mp);
524− tLinearDelay_initToPool(&p->delayLineL,p->waveLengthInSamples, 2400, mp);
524+ tLinearDelay_initToPool(&p->delayLineU,p->waveLengthInSamples, p->maxLength, mp);
525+ tLinearDelay_initToPool(&p->delayLineL,p->waveLengthInSamples, p->maxLength, mp);
525526 tSimpleLivingString3_setFreq(pl, freq);
526527 tLinearDelay_setDelay(&p->delayLineU, p->waveLengthInSamples);
527528 tLinearDelay_setDelay(&p->delayLineL, p->waveLengthInSamples);
@@ -554,10 +555,11 @@ void tSimpleLivingString3_free (tSimpleLivingString3* const pl) · 26 unmodified lines
554555 void tSimpleLivingString3_setFreq(tSimpleLivingString3* const pl, float freq)
555556 {
556557 _tSimpleLivingString3* p = *pl;
557−
558− if (freq<20) freq=20;
559− else if (freq>10000) freq=10000;
560− p->waveLengthInSamples = (p->sampleRate/freq) * 0.5f;
558+ p->freq = freq;
559+ float waveLength = (p->sampleRate/freq);
560+ if (waveLength<4.8) waveLength=4.8f;
561+ else if (waveLength>p->maxLength*2) waveLength=p->maxLength*2;
562+ p->waveLengthInSamples = waveLength * 0.5f;
561563 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
562564 }
563565
@@ -566,7 +568,7 @@ void tSimpleLivingString3_setWaveLength(tSimpleLivingString3* const pl, floa · 2 unmodified lines
566568 _tSimpleLivingString3* p = *pl;
567569
568570 if (waveLength<4.8) waveLength=4.8f;
569− else if (waveLength>4800) waveLength=4800;
571+ else if (waveLength>p->maxLength*2) waveLength=p->maxLength*2;
570572 p->waveLengthInSamples = waveLength * 0.5f;
571573 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
572574 }
@@ -608,7 +610,7 @@ void tSimpleLivingString3_setLevMode(tSimpleLivingString3* const pl, int lev · 35 unmodified lines
608610 p->levMode=levMode;
609611 }
610612
611−float tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, float position)
613+void tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, float position)
612614 {
613615 _tSimpleLivingString3* p = *pl;
614616 int length = p->waveLengthInSamples;
@@ -636,7 +638,6 @@ float tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, · 21 unmodified lines
636638 int currentBufReadPointMod = currentBufReadPoint % p->delayLineU->maxDelay;
637639 p->delayLineL->buff[currentBufWritePoint] = p->delayLineU->buff[currentBufReadPointMod];
638640 }
639−
640641 }
641642
642643 float tSimpleLivingString3_tick(tSimpleLivingString3* const pl, float input)
@@ -644,8 +645,6 @@ float tSimpleLivingString3_tick(tSimpleLivingString3* const pl, float input) · 1 unmodified line
644645 _tSimpleLivingString3* p = *pl;
645646 tLinearDelay_setDelay(&p->delayLineU, tExpSmooth_tick(&p->wlSmooth));
646647 tLinearDelay_setDelay(&p->delayLineL, tExpSmooth_tick(&p->wlSmooth));
647− //tLinearDelay_setDelay(&p->delayLineU, p->waveLengthInSamples);
648− //tLinearDelay_setDelay(&p->delayLineL, p->waveLengthInSamples);
649648
650649 p->Uout = tOnePole_tick(&p->bridgeFilter,tLinearDelay_tickOut(&p->delayLineU));
651650 p->Lout = tLinearDelay_tickOut(&p->delayLineL);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t