]> git.sesse.net Git - nageru/commitdiff
Add support for EQ filters to the Filter class.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 28 Aug 2016 22:29:25 +0000 (00:29 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 19 Oct 2016 22:55:44 +0000 (00:55 +0200)
filter.cpp
filter.h

index 3974ebca0f09e09ee431d67ce4b8a36bfc834736..c6f9997b9b7387853d41115d72ee02aa36d1ccce 100644 (file)
@@ -36,6 +36,7 @@ Filter::Filter()
 {
        omega = M_PI;
        resonance = 0.01f;
+       A = 1.0f;
 
        init(FILTER_NONE, 1);
        update();
@@ -131,6 +132,33 @@ void Filter::update()
                // a2 = 1 - alpha;
                break;
 
+       case FILTER_PEAKING_EQ:
+               b0 = 1 + alpha * A;
+               b1 = -2*cs;
+               b2 = 1 - alpha * A;
+               a0 = 1 + alpha / A;
+               // a1 = -2*cs;
+               a2 = 1 - alpha / A;
+               break;
+
+       case FILTER_LOW_SHELF:
+               b0 =      A * ((A + 1) - (A - 1)*cs + 2 * sqrt(A) * alpha);
+               b1 =  2 * A * ((A - 1) - (A + 1)*cs                      );
+               b2 =      A * ((A + 1) - (A - 1)*cs - 2 * sqrt(A) * alpha);
+               a0 =           (A + 1) + (A - 1)*cs + 2 * sqrt(A) * alpha ;
+               a1 =     -2 * ((A - 1) + (A + 1)*cs                      );
+               a2 =           (A + 1) + (A - 1)*cs - 2 * sqrt(A) * alpha ;
+               break;
+
+       case FILTER_HIGH_SHELF:
+               b0 =      A * ((A + 1) + (A - 1)*cs + 2 * sqrt(A) * alpha);
+               b1 = -2 * A * ((A - 1) + (A + 1)*cs                      );
+               b2 =      A * ((A + 1) + (A - 1)*cs - 2 * sqrt(A) * alpha);
+               a0 =           (A + 1) - (A - 1)*cs + 2 * sqrt(A) * alpha ;
+               a1 =      2 * ((A - 1) - (A + 1)*cs                      );
+               a2 =           (A + 1) - (A - 1)*cs - 2 * sqrt(A) * alpha ;
+               break;
+
        default:
                //unknown filter type
                assert(false);
@@ -266,7 +294,7 @@ void StereoFilter::init(FilterType type, int new_order)
 #endif
 }
 
-void StereoFilter::render(float *inout_left_ptr, unsigned n_samples, float cutoff, float resonance)
+void StereoFilter::render(float *inout_left_ptr, unsigned n_samples, float cutoff, float resonance, float dbgain_normalized)
 {
 #ifdef __SSE__
        if (parm_filter.filtertype == FILTER_NONE || parm_filter.filter_order == 0)
@@ -277,6 +305,7 @@ void StereoFilter::render(float *inout_left_ptr, unsigned n_samples, float cutof
 
        parm_filter.set_linear_cutoff(cutoff);
        parm_filter.set_resonance(resonance);
+       parm_filter.set_dbgain_normalized(dbgain_normalized);
        parm_filter.update();
 
        __m128 b0 = _mm_set1_ps(parm_filter.b0);
index 5e455d2fff840704a7ab3ae44cca24105f89a8d7..a4a3a1349e035b97c592b7d6b5b2e265c0908772 100644 (file)
--- a/filter.h
+++ b/filter.h
@@ -32,6 +32,11 @@ enum FilterType
        FILTER_BPF,
        FILTER_NOTCH,
        FILTER_APF,
+
+       // EQ filters.
+       FILTER_PEAKING_EQ,
+       FILTER_LOW_SHELF,
+       FILTER_HIGH_SHELF,
 };
 
 #define FILTER_MAX_ORDER 4
@@ -69,6 +74,12 @@ public:
                resonance = new_resonance;
        }
 
+       // For EQ filters only.
+       void set_dbgain_normalized(float db_gain_div_40)
+       {
+               A = pow(10.0f, db_gain_div_40);
+       }
+
 #ifdef __SSE__
        // We don't need the stride argument for SSE, as StereoFilter
        // has its own SSE implementations.
@@ -81,6 +92,7 @@ public:
 private:
        float omega; //which is 2*Pi*frequency /SAMPLE_RATE
        float resonance;
+       float A;  // which is 10^(db_gain / 40)
 
 public:
        unsigned filter_order;
@@ -104,7 +116,7 @@ class StereoFilter
 public:
        void init(FilterType type, int new_order);
        
-       void render(float *inout_left_ptr, unsigned n_samples, float cutoff, float resonance);
+       void render(float *inout_left_ptr, unsigned n_samples, float cutoff, float resonance, float dbgain_normalized = 0.0f);
 #ifndef NDEBUG
 #ifdef __SSE__
        void debug() { parm_filter.debug(); }