ref: 11207b528439d1b404e50dee7a9f29537670008b
parent: 5ab7e4d4e6f42964225fc142e9419f721e948a8a
author: Jeffrey Snyder <jeffsnyder@Jeffreys-MacBook-Pro.local>
date: Wed Aug 17 15:04:49 EDT 2022
added setFreqFast functions to filters
--- a/leaf/Inc/leaf-filters.h
+++ b/leaf/Inc/leaf-filters.h
@@ -663,6 +663,7 @@
float tSVF_tick (tSVF* const, float v0);
void tSVF_setFreq (tSVF* const, float freq);
+ void tSVF_setFreqFast (tSVF* const vf, float cutoff);
void tSVF_setQ (tSVF* const, float Q);
void tSVF_setFreqAndQ (tSVF* const svff, float freq, float Q);
void tSVF_setSampleRate (tSVF* const svff, float sr);
@@ -1064,6 +1065,7 @@
void tVZFilter_calcCoeffsEfficientBP (tVZFilter* const);
void tVZFilter_setBandwidth (tVZFilter* const, float bandWidth);
void tVZFilter_setFreq (tVZFilter* const, float freq);
+ void tVZFilter_setFreqFast (tVZFilter* const vf, float cutoff);
void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw);
void tVZFilter_setFreqAndBandwidthEfficientBP (tVZFilter* const vf, float freq, float bw);
void tVZFilter_setGain (tVZFilter* const, float gain);
@@ -1138,6 +1140,7 @@
float tDiodeFilter_tick (tDiodeFilter* const, float input);
void tDiodeFilter_setFreq (tDiodeFilter* const vf, float cutoff);
+ void tDiodeFilter_setFreqFast (tDiodeFilter* const vf, float cutoff);
void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance);
void tDiodeFilter_setSampleRate(tDiodeFilter* const vf, float sr);
@@ -1167,6 +1170,7 @@
float tLadderFilter_tick (tLadderFilter* const, float input);
void tLadderFilter_setFreq (tLadderFilter* const vf, float cutoff);
+ void tLadderFilter_setFreqFast (tLadderFilter* const vf, float cutoff);
void tLadderFilter_setQ (tLadderFilter* const vf, float resonance);
void tLadderFilter_setSampleRate(tLadderFilter* const vf, float sr);
--- a/leaf/Inc/leaf-sampling.h
+++ b/leaf/Inc/leaf-sampling.h
@@ -453,7 +453,7 @@
@} */
#define FILLEN 256
-
+
typedef struct _tMBSampler
{
--- a/leaf/Src/leaf-filters.c
+++ b/leaf/Src/leaf-filters.c
@@ -894,6 +894,18 @@
svf->a3 = svf->g * svf->a2;
}
+void tSVF_setFreqFast (tSVF* const vf, float cutoff)
+{
+ _tSVF* svf = *vf;
+ int intVer = (int)cutoff;
+ float floatVer = cutoff - (float)intVer;
+
+ svf->g = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
+ 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 tSVF_setQ(tSVF* const svff, float Q)
{
_tSVF* svf = *svff;
@@ -1506,6 +1518,131 @@
f->fc = LEAF_clip(0.0f, freq, 0.5f * f->sampleRate);
tVZFilter_calcCoeffs(vf);
}
+
+void tVZFilter_setFreqFast (tVZFilter* const vf, float cutoff)
+{
+ _tVZFilter* f = *vf;
+ int intVer = (int)cutoff;
+ float floatVer = cutoff - (float)intVer;
+ f->g = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
+
+ switch( f->type )
+ {
+ case Bypass:
+ {
+ f->R2 = f->invG;
+ f->cL = 1.0f;
+ f->cB = f->R2;
+ f->cH = 1.0f;
+
+ }
+ break;
+ case Lowpass:
+ {
+ //f->R2 = f->invG;
+ //f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
+ f->cL = 1.0f; f->cB = 0.0f; f->cH = 0.0f;
+
+ }
+ break;
+ case Highpass:
+ {
+ //f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
+ //f->R2 = f->invG;
+ f->cL = 0.0f; f->cB = 0.0f; f->cH = 1.0f;
+ }
+ break;
+ case BandpassSkirt:
+ {
+ //f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
+ //f->R2 = f->invG;
+ f->cL = 0.0f; f->cB = 1.0f; f->cH = 0.0f;
+ }
+ break;
+ case BandpassPeak:
+ {
+ //f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
+ //f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
+ f->cL = 0.0f; f->cB = f->G * f->R2; f->cH = 0.0f;
+ //f->cL = 0.0f; f->cB = f->R2; f->cH = 0.0f;
+ }
+ break;
+ case BandReject:
+ {
+ //f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B);
+ //f->g = tanf(PI * f->fc * f->invSampleRate); // embedded integrator gain (Fig 3.11)
+ f->cL = 1.0f; f->cB = 0.0f; f->cH = 1.0f;
+ }
+ break;
+ case Bell:
+ {
+ float fl = f->fc*fastPowf(2.0f, (-f->B)*0.5f); // lower bandedge frequency (in Hz)
+ float wl = fastertanf(PI*fl*f->invSampleRate); // warped radian lower bandedge frequency /(2*fs)
+ float r = f->g/wl;
+ r *= r; // warped frequency ratio wu/wl == (wc/wl)^2 where wu is the
+ // warped upper bandedge, wc the center
+ f->R2 = 2.0f*fastsqrtf(((r*r+1.0f)/r-2.0f)/(4.0f*f->G));
+ f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = 1.0f;
+ }
+ break;
+ case Lowshelf:
+ {
+ float A = fastsqrtf(f->G);
+ f->g /= fastsqrtf(A); // scale SVF-cutoff frequency for shelvers
+ //f->R2 = 2*sinhf(f->B*logf(2.0f)*0.5f); if using bandwidth instead of Q
+ //f->R2 = f->invQ;
+ f->cL = f->G; f->cB = f->R2*f->G; f->cH = 1.0f;
+
+ }
+ break;
+ case Highshelf:
+ {
+ float A = fastsqrtf(f->G);
+ f->g *= fastsqrtf(A); // scale SVF-cutoff frequency for shelvers
+ //f->R2 = 2.0f*sinhf(f->B*logf(2.0f)*0.5f); if using bandwidth instead of Q
+ f->cL = 1.0f; f->cB = f->R2*f->G; f->cH = f->G;
+ }
+ break;
+ case Allpass:
+ {
+ //f->R2 = 2.0f*tVZFilter_BandwidthToR(vf, f->B); if using bandwidth instead of Q
+ f->cL = 1.0f; f->cB = -f->R2; f->cH = 1.0f;
+ }
+ break;
+
+ // experimental - maybe we must find better curves for cL, cB, cH:
+ case Morph:
+ {
+ //f->R2 = 2.0f*tVZFilter_BandwidthToREfficientBP(vf, f->B);
+
+ //f->R2 = f->invG;
+ //float x = f->m-1.0f;
+
+ float x = (2.0f*f->m-1.0f);
+ //f->cL = maximum(0.0f,(1.0f - (f->m * 2.0f)));
+ //f->cH = maximum(0.0f,(f->m * 2.0f) - 1.0f);
+ //f->cB = maximum(0.0f, 1.0f - f->cH - f->cL);
+ //f->cL = minimum(0.0f,(1.0f - (f->m * 2.0f))) ;
+ f->cL = maximum(-x, 0.0f); /*cL *= cL;*/
+ f->cH = minimum( x, 0.0f); /*cH *= cH;*/
+ f->cB = 1.0f-x*x;
+
+ // bottom line: we need to test different versions for how they feel when tweaking the
+ // morph parameter
+
+ // this scaling ensures constant magnitude at the cutoff point (we divide the coefficients by
+ // the magnitude response value at the cutoff frequency and scale back by the gain):
+ float s = f->G * fastsqrtf((f->R2*f->R2) / (f->cL*f->cL + f->cB*f->cB + f->cH*f->cH - 2.0f*f->cL*f->cH)) * 2.0f;
+ f->cL *= s; f->cB *= s; f->cH *= s;
+ }
+ break;
+
+ }
+ f->R2Plusg = f->R2+f->g;
+ f->h = 1.0f / (1.0f + (f->R2*f->g) + (f->g*f->g)); // factor for feedback precomputation
+}
+
+
void tVZFilter_setFreqAndBandwidth (tVZFilter* const vf, float freq, float bw)
{
_tVZFilter* f = *vf;
@@ -1774,6 +1911,14 @@
f->f = tanf(PI * f->cutoff * f->invSampleRate);
}
+void tDiodeFilter_setFreqFast (tDiodeFilter* const vf, float cutoff)
+{
+ _tDiodeFilter* f = *vf;
+ int intVer = (int)cutoff;
+ float floatVer = cutoff - (float)intVer;
+ f->f = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
+}
+
void tDiodeFilter_setQ (tDiodeFilter* const vf, float resonance)
{
_tDiodeFilter* f = *vf;
@@ -1917,6 +2062,16 @@
f->cutoff = LEAF_clip(40.0f, cutoff, 18000.0f);
f->c = tanf(PI * (f->cutoff / (float)f->oversampling) * f->invSampleRate);
+ f->c2 = 2.0f * f->c;
+}
+
+void tLadderFilter_setFreqFast (tLadderFilter* const vf, float cutoff)
+{
+ _tLadderFilter* f = *vf;
+ int intVer = (int)cutoff;
+ float floatVer = cutoff - (float)intVer;
+
+ f->c = (__leaf_table_filtertan[intVer] * (1.0f - floatVer)) + (__leaf_table_filtertan[intVer+1] * floatVer);
f->c2 = 2.0f * f->c;
}
--- a/leaf/Src/leaf-tables.c
+++ b/leaf/Src/leaf-tables.c
@@ -10045,7 +10045,7 @@
664f, 3.976216f, 3.97477f, 3.973324f, 3.971879f, 3.970435f, 3.968992f, 3.967551f, 3.96611f, 3.96467f, 3.963232f, 3.961794f, 3.960358f, 3.958922f,
3.957488f, 3.956055f, 3.954622f, 3.953191f, 3.951761f, 3.950332f, 3.948903f, 3.947476f, 3.94605f, 3.944625f, 3.943201f, 3.941778f, 3.940356f, 3.938935f, 3.937515f, 3.936096f, 3.934678f, 3.933261f, 3.931845f, 3.930431f,
3.929017f, 3.927604f, 3.926192f, 3.924781f, 3.923372f, 3.921963f, 3.920555f, 3.919148f, 3.917743f, 3.916338f, 3.914934f, 3.913532f, 3.91213f, 3.910729f, 3.90933f, 3.907931f, 3.906533f, 3.905136f, 3.903741f, 3.902346f,
-948903f, 3.947476f, 3.94605f, 3.944625f, 3.943201f, 3.941778f, 3.940356f, 3.938935f, 3.937515f, 3.936096f, 3.934678f, 3.933261f, 3.931845f, 3.930431f,
+948903f, 3.947476f, 3.94605f, 3.944625f, 3.943201f, 3.941778f, 3.940356f, 3.938935f, 3.937515f, 3.936096f, 3.934678f, 3.933261f, 3.931845f, 3.930431f,
8903f, 3.947476f, 3.94605f, 3.944625f, 3.943201f, 3.941778f, 3.940356f, 3.938935f, 3.937515f, 3.936096f, 3.934678f, 3.933261f, 3.931845f, 3.930431f,
3.929017f, 3.927604f, 3.926192f, 3.924781f, 3.923372f, 3.921963f, 3.920555f, 3.919148f, 3.917743f, 3.916338f, 3.914934f, 3.913532f, 3.91213f, 3.910729f, 3.90933f, 3.907931f, 3.906533f, 3.905136f, 3.903741f, 3.902346f,
3.900952f, 3.89956f, 3.898168f, 3.896777f, 3.895388f, 3.893999f, 3.892611f, 3.891224f, 3.889839f, 3.888454f, 3.88707f, 3.885687f, 3.884305f, 3.882925f, 3.881545f, 3.880166f, 3.878788f, 3.877411f, 3.876035f, 3.87466f,