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
64 64
65 float tauAttack, tauRelease;65 float tauAttack, tauRelease;
66 float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain66 float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain
67 67 float invR;
68 float inv4W;
68 float x_G[2], y_G[2], x_T[2], y_T[2];69 float x_G[2], y_G[2], x_T[2], y_T[2];
69 70
70 int isActive;71 int isActive;
leaf/Inc/leaf-filters.h+1−0
@@ -1072,6 +1072,7 @@ extern "C" { · 1071 unmodified lines
1072 void tVZFilter_setResonance (tVZFilter* const vf, float res);1072 void tVZFilter_setResonance (tVZFilter* const vf, float res);
1073 void tVZFilter_setFrequencyAndResonance (tVZFilter* const vf, float freq, float res);1073 void tVZFilter_setFrequencyAndResonance (tVZFilter* const vf, float freq, float res);
1074 void tVZFilter_setFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, float res, float gains);1074 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);
1075 void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain);1076 void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain);
1076 void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph);1077 void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph);
1077 void tVZFilter_setMorphOnly (tVZFilter* const vf, float morph);1078 void tVZFilter_setMorphOnly (tVZFilter* const vf, float morph);
leaf/Inc/leaf-math.h+2−0
@@ -217,6 +217,8 @@ extern "C" { · 216 unmodified lines
217 217
218 float atodb(float a);218 float atodb(float a);
219 219
220 float fasteratodb(float a);
221
220 float dbtoa(float db);222 float dbtoa(float db);
221 223
222 float fastdbtoa(float db);224 float fastdbtoa(float db);
leaf/Inc/leaf-physical.h+7−5
@@ -351,26 +351,28 @@ typedef struct _tSimpleLivingString3 · 350 unmodified lines
351 float curr;351 float curr;
352 float Uout;352 float Uout;
353 float Lout;353 float Lout;
354 int maxLength;
354 tLinearDelay delayLineU;355 tLinearDelay delayLineU;
355 tLinearDelay delayLineL;356 tLinearDelay delayLineL;
356 tOnePole bridgeFilter;357 tOnePole bridgeFilter;
357 tHighpass DCblocker;358 tHighpass DCblocker;
358 tFeedbackLeveler fbLev;359 tFeedbackLeveler fbLev;
359 tExpSmooth wlSmooth;360 tExpSmooth wlSmooth;
361 int oversampling;
360 float sampleRate;362 float sampleRate;
361} _tSimpleLivingString3;363} _tSimpleLivingString3;
362 364
363typedef _tSimpleLivingString3* tSimpleLivingString3;365typedef _tSimpleLivingString3* tSimpleLivingString3;
364 366
365void tSimpleLivingString3_init (tSimpleLivingString3* const, float freq, float dampFreq,367void tSimpleLivingString3_init (tSimpleLivingString3* const, int oversampling, float freq, float dampFreq,
366 float decay, float targetLev, float levSmoothFactor,368 float decay, float targetLev, float levSmoothFactor,
367 float levStrength, int levMode, LEAF* const leaf);369 float levStrength, int levMode, LEAF* const leaf);
368void tSimpleLivingString3_initToPool (tSimpleLivingString3* const, float freq, float dampFreq,370void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
369 float decay, float targetLev, float levSmoothFactor,371 float decay, float targetLev, float levSmoothFactor,
370 float levStrength, int levMode, tMempool* const);372 float levStrength, int levMode, tMempool* const mp);
371void tSimpleLivingString3_free (tSimpleLivingString3* const);373void tSimpleLivingString3_free (tSimpleLivingString3* const);
372 374
373float tSimpleLivingString3_pluck (tSimpleLivingString3* const pl, float input, float position);375void tSimpleLivingString3_pluck (tSimpleLivingString3* const pl, float input, float position);
374float tSimpleLivingString3_tick (tSimpleLivingString3* const, float input);376float tSimpleLivingString3_tick (tSimpleLivingString3* const, float input);
375float tSimpleLivingString3_sample (tSimpleLivingString3* const);377float tSimpleLivingString3_sample (tSimpleLivingString3* const);
376void tSimpleLivingString3_setFreq (tSimpleLivingString3* const, float freq);378void 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
64 c->y_T[0] = 0.0f, c->y_T[1] = 0.0f;64 c->y_T[0] = 0.0f, c->y_T[1] = 0.0f;
65 c->T = 0.0f; // Threshold65 c->T = 0.0f; // Threshold
66 c->R = 0.5f; // compression Ratio66 c->R = 0.5f; // compression Ratio
67 c->invR = 2.0f; //inverse of ratio
67 c->M = 3.0f; // decibel Make-up gain68 c->M = 3.0f; // decibel Make-up gain
68 c->W = 1.0f; // decibel Width of knee transition69 c->W = 1.5f; // decibel Width of knee transition
70 c->inv4W = 1.0f / (4.0f * c->W) ;
69 71
70 72
71}73}
@@ -83,34 +85,33 @@ float tCompressor_tick(tCompressor* const comp, float in) · 11 unmodified lines
83 85
84 float slope, overshoot;86 float slope, overshoot;
85 87
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);
87 float out_db = 0.0f;89 float out_db = 0.0f;
88 90
89 c->y_T[1] = c->y_T[0];91 c->y_T[1] = c->y_T[0];
90 92
91 slope = 1.0f - (1.0f/c->R); // feed-forward topology; 93 slope = 1.0f - c->invR; // feed-forward topology;
92 94
93 overshoot = in_db - c->T;95 overshoot = in_db - c->T;
94 96
95 /*97
96 if (overshoot <= -(c->W * 0.5f))98 if (overshoot <= -(c->W))
97 {99 {
98 out_db = in_db;100 out_db = in_db;
99 c->isActive = 0;101 c->isActive = 0;
100 }102 }
101 103 else if ((overshoot > -(c->W)) && (overshoot < (c->W)))
102 else if ((overshoot > -(c->W * 0.5f)) && (overshoot < (c->W * 0.5f)))
103 {104 {
104 float squareit = (overshoot + c->W*0.5f);105 float squareit = (overshoot + c->W);
105 out_db = in_db + slope * ((squareit * squareit) / (2.0f * c->W)); // .^ 2 ???106 out_db = in_db + slope * ((squareit * squareit) * c->inv4W); // .^ 2 ???
106 c->isActive = 1;107 c->isActive = 1;
107 }108 }
108 else if (overshoot >= (c->W * 0.5f))109 else
109 {110 {
110 out_db = in_db + slope * overshoot;111 out_db = in_db + slope * overshoot;
111 c->isActive = 1;112 c->isActive = 1;
112 }113 }
113 */114/* // simpler hard-knee version
114 if (overshoot <= 0.0f)115 if (overshoot <= 0.0f)
115 {116 {
116 out_db = in_db;117 out_db = in_db;
@@ -121,26 +122,13 @@ float tCompressor_tick(tCompressor* const comp, float in) · 4 unmodified lines
121 out_db = in_db + slope * overshoot;122 out_db = in_db + slope * overshoot;
122 c->isActive = 1;123 c->isActive = 1;
123 }124 }
124 125 */
125 c->x_T[0] = out_db - in_db;126 c->x_T[0] = out_db - in_db;
126
127
128
129 if (c->x_T[0] > c->y_T[1])127 if (c->x_T[0] > c->y_T[1])
130 c->y_T[0] = c->tauAttack * c->y_T[1] + (1.0f-c->tauAttack) * c->x_T[0];128 c->y_T[0] = c->tauAttack * c->y_T[1] + (1.0f-c->tauAttack) * c->x_T[0];
131 else129 else
132 c->y_T[0] = c->tauRelease * c->y_T[1] + (1.0f-c->tauRelease) * c->x_T[0];130 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
138 float attenuation = fasterdbtoa(c->M - c->y_T[0]);131 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;
144 return attenuation * in;132 return attenuation * in;
145}133}
146 134
@@ -158,10 +146,12 @@ void tCompressor_setParams(tCompressor* const comp, float thresh, float ratio, f · 11 unmodified lines
158 _tCompressor* c = *comp;146 _tCompressor* c = *comp;
159 c->T = thresh;147 c->T = thresh;
160 c->R = ratio;148 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);
162 c->M = makeup;152 c->M = makeup;
163 c->tauAttack = expf(-1.0f/(0.001f * attack * c->sampleRate));153 c->tauAttack = fasterexpf(-1.0f/(0.001f * attack * c->sampleRate));
164 c->tauRelease = expf(-1.0f/(0.001f * release * c->sampleRate));154 c->tauRelease = fasterexpf(-1.0f/(0.001f * release * c->sampleRate));
165}155}
166 156
167/* Feedback Leveler */157/* Feedback Leveler */
leaf/Src/leaf-filters.c+14−1
@@ -1524,7 +1524,7 @@ void tVZFilter_setFreqFast (tVZFilter* const vf, float cutoff) · 1523 unmodified lines
1524 int intVer = (int)cutoff;1524 int intVer = (int)cutoff;
1525 float floatVer = cutoff - (float)intVer;1525 float floatVer = cutoff - (float)intVer;
1526 f->g = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);1526 f->g = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
1527 1527
1528 switch( f->type )1528 switch( f->type )
1529 {1529 {
1530 case Bypass:1530 case Bypass:
@@ -1697,6 +1697,18 @@ void tVZFilter_setFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, · 166 unmodified lines
1697 f->invG = 1.0f/f->G;1697 f->invG = 1.0f/f->G;
1698 tVZFilter_calcCoeffs(vf);1698 tVZFilter_calcCoeffs(vf);
1699}1699}
1700
1701void 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
1700void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain)1712void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain)
1701{1713{
1702 _tVZFilter* f = *vf;1714 _tVZFilter* f = *vf;
@@ -1708,6 +1720,7 @@ void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, · 5 unmodified lines
1708 tVZFilter_calcCoeffs(vf);1720 tVZFilter_calcCoeffs(vf);
1709}1721}
1710 1722
1723
1711void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph)1724void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph)
1712{1725{
1713 _tVZFilter* f = *vf;1726 _tVZFilter* f = *vf;
leaf/Src/leaf-math.c+4−1
@@ -810,11 +810,14 @@ float atodb(float a) · 809 unmodified lines
810{810{
811 return 20.0f*log10f(a);811 return 20.0f*log10f(a);
812}812}
813float fasteratodb(float a)
814{
815 return 20.0f*log10f_fast(a);
816}
813 817
814float dbtoa(float db)818float dbtoa(float db)
815{819{
816 return powf(10.0f, db * 0.05f);820 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
818}821}
819 822
820 823
leaf/Src/leaf-physical.c+15−16
@@ -501,14 +501,14 @@ void tSimpleLivingString_setSampleRate(tSimpleLivingString* const pl, float sr · 500 unmodified lines
501 501
502/* Simple Living String*/502/* Simple Living String*/
503 503
504void tSimpleLivingString3_init(tSimpleLivingString3* const pl, float freq, float dampFreq,504void tSimpleLivingString3_init(tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
505 float decay, float targetLev, float levSmoothFactor,505 float decay, float targetLev, float levSmoothFactor,
506 float levStrength, int levMode, LEAF* const leaf)506 float levStrength, int levMode, LEAF* const leaf)
507{507{
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);
509}509}
510 510
511void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, float freq, float dampFreq,511void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, int oversampling, float freq, float dampFreq,
512 float decay, float targetLev, float levSmoothFactor,512 float decay, float targetLev, float levSmoothFactor,
513 float levStrength, int levMode, tMempool* const mp)513 float levStrength, int levMode, tMempool* const mp)
514{514{
@@ -516,12 +516,13 @@ void tSimpleLivingString3_initToPool (tSimpleLivingString3* const pl, float · 1 unmodified line
516 _tSimpleLivingString3* p = *pl = (_tSimpleLivingString3*) mpool_alloc(sizeof(_tSimpleLivingString3), m);516 _tSimpleLivingString3* p = *pl = (_tSimpleLivingString3*) mpool_alloc(sizeof(_tSimpleLivingString3), m);
517 p->mempool = m;517 p->mempool = m;
518 LEAF* leaf = p->mempool->leaf;518 LEAF* leaf = p->mempool->leaf;
519 519 p->oversampling = oversampling;
520 p->sampleRate = leaf->sampleRate;520 p->sampleRate = leaf->sampleRate * oversampling;
521 p->curr=0.0f;521 p->curr=0.0f;
522 p->maxLength = 2400 * oversampling;
522 tExpSmooth_initToPool(&p->wlSmooth, p->sampleRate/freq/2.0f, 0.01f, mp); // smoother for string wavelength (not freq, to avoid expensive divisions)523 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->delayLineU,p->waveLengthInSamples, p->maxLength, mp);
524 tLinearDelay_initToPool(&p->delayLineL,p->waveLengthInSamples, 2400, mp);525 tLinearDelay_initToPool(&p->delayLineL,p->waveLengthInSamples, p->maxLength, mp);
525 tSimpleLivingString3_setFreq(pl, freq);526 tSimpleLivingString3_setFreq(pl, freq);
526 tLinearDelay_setDelay(&p->delayLineU, p->waveLengthInSamples);527 tLinearDelay_setDelay(&p->delayLineU, p->waveLengthInSamples);
527 tLinearDelay_setDelay(&p->delayLineL, p->waveLengthInSamples);528 tLinearDelay_setDelay(&p->delayLineL, p->waveLengthInSamples);
@@ -554,10 +555,11 @@ void tSimpleLivingString3_free (tSimpleLivingString3* const pl) · 26 unmodified lines
554void tSimpleLivingString3_setFreq(tSimpleLivingString3* const pl, float freq)555void tSimpleLivingString3_setFreq(tSimpleLivingString3* const pl, float freq)
555{556{
556 _tSimpleLivingString3* p = *pl;557 _tSimpleLivingString3* p = *pl;
557 558 p->freq = freq;
558 if (freq<20) freq=20;559 float waveLength = (p->sampleRate/freq);
559 else if (freq>10000) freq=10000;560 if (waveLength<4.8) waveLength=4.8f;
560 p->waveLengthInSamples = (p->sampleRate/freq) * 0.5f;561 else if (waveLength>p->maxLength*2) waveLength=p->maxLength*2;
562 p->waveLengthInSamples = waveLength * 0.5f;
561 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);563 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
562}564}
563 565
@@ -566,7 +568,7 @@ void tSimpleLivingString3_setWaveLength(tSimpleLivingString3* const pl, floa · 2 unmodified lines
566 _tSimpleLivingString3* p = *pl;568 _tSimpleLivingString3* p = *pl;
567 569
568 if (waveLength<4.8) waveLength=4.8f;570 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;
570 p->waveLengthInSamples = waveLength * 0.5f;572 p->waveLengthInSamples = waveLength * 0.5f;
571 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);573 tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
572}574}
@@ -608,7 +610,7 @@ void tSimpleLivingString3_setLevMode(tSimpleLivingString3* const pl, int lev · 35 unmodified lines
608 p->levMode=levMode;610 p->levMode=levMode;
609}611}
610 612
611float tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, float position)613void tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, float position)
612{614{
613 _tSimpleLivingString3* p = *pl;615 _tSimpleLivingString3* p = *pl;
614 int length = p->waveLengthInSamples;616 int length = p->waveLengthInSamples;
@@ -636,7 +638,6 @@ float tSimpleLivingString3_pluck(tSimpleLivingString3* const pl, float input, · 21 unmodified lines
636 int currentBufReadPointMod = currentBufReadPoint % p->delayLineU->maxDelay;638 int currentBufReadPointMod = currentBufReadPoint % p->delayLineU->maxDelay;
637 p->delayLineL->buff[currentBufWritePoint] = p->delayLineU->buff[currentBufReadPointMod];639 p->delayLineL->buff[currentBufWritePoint] = p->delayLineU->buff[currentBufReadPointMod];
638 }640 }
639
640}641}
641 642
642float tSimpleLivingString3_tick(tSimpleLivingString3* const pl, float input)643float tSimpleLivingString3_tick(tSimpleLivingString3* const pl, float input)
@@ -644,8 +645,6 @@ float tSimpleLivingString3_tick(tSimpleLivingString3* const pl, float input) · 1 unmodified line
644 _tSimpleLivingString3* p = *pl;645 _tSimpleLivingString3* p = *pl;
645 tLinearDelay_setDelay(&p->delayLineU, tExpSmooth_tick(&p->wlSmooth));646 tLinearDelay_setDelay(&p->delayLineU, tExpSmooth_tick(&p->wlSmooth));
646 tLinearDelay_setDelay(&p->delayLineL, tExpSmooth_tick(&p->wlSmooth));647 tLinearDelay_setDelay(&p->delayLineL, tExpSmooth_tick(&p->wlSmooth));
647 //tLinearDelay_setDelay(&p->delayLineU, p->waveLengthInSamples);
648 //tLinearDelay_setDelay(&p->delayLineL, p->waveLengthInSamples);
649 648
650 p->Uout = tOnePole_tick(&p->bridgeFilter,tLinearDelay_tickOut(&p->delayLineU));649 p->Uout = tOnePole_tick(&p->bridgeFilter,tLinearDelay_tickOut(&p->delayLineU));
651 p->Lout = tLinearDelay_tickOut(&p->delayLineL);650 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