shithub: leaf

Download patch

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,