]> git.sesse.net Git - nageru/blobdiff - filter.cpp
Release Nageru 1.7.2.
[nageru] / filter.cpp
index a5cd76733f3f5325af1c511a3f4c007e6c6cf8e9..0cb0180d8c4ce4f673112422708f68f5608f9b4d 100644 (file)
@@ -1,9 +1,11 @@
+#include <assert.h>
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
-#include <complex>
 #include <algorithm>
+#include <complex>
+
+#include "defs.h"
 
 #ifdef __SSE__
 #include <mmintrin.h>
@@ -11,6 +13,8 @@
 
 #include "filter.h"
 
+using namespace std;
+
 #ifdef __SSE__
 
 // For SSE, we set the denormals-as-zero flag instead.
@@ -34,6 +38,7 @@ Filter::Filter()
 {
        omega = M_PI;
        resonance = 0.01f;
+       A = 1.0f;
 
        init(FILTER_NONE, 1);
        update();
@@ -49,8 +54,8 @@ void Filter::update()
 
        float sn, cs;
        float cutoff_freq = omega;
-       cutoff_freq = std::min(cutoff_freq, (float)M_PI);
-       cutoff_freq = std::max(cutoff_freq, 0.001f);
+       cutoff_freq = min(cutoff_freq, (float)M_PI);
+       cutoff_freq = max(cutoff_freq, 0.001f);
        calcSinCos(cutoff_freq, &sn, &cs);
        if (resonance <= 0) resonance = 0.001f;
 
@@ -129,6 +134,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);
@@ -259,12 +291,12 @@ void StereoFilter::init(FilterType type, int new_order)
        memset(feedback, 0, sizeof(feedback));
 #else
        for (unsigned i = 0; i < 2; ++i) {
-               filters[i].init(type, 0, new_order, 0);
+               filters[i].init(type, 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)
@@ -275,6 +307,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);
@@ -352,9 +385,9 @@ void StereoFilter::render(float *inout_left_ptr, unsigned n_samples, float cutof
   we need to raise the answer to the Nth power.
 
 */
-std::complex<double> Filter::evaluate_transfer_function(float omega)
+complex<double> Filter::evaluate_transfer_function(float omega)
 {
-       std::complex<float> z = exp(std::complex<float>(0.0f, omega));
-       std::complex<float> z2 = z * z;
-       return std::pow((b0 * z2 + b1 * z + b2) / (1.0f * z2 + a1 * z + a2), filter_order);
+       complex<float> z = exp(complex<float>(0.0f, omega));
+       complex<float> z2 = z * z;
+       return pow((b0 * z2 + b1 * z + b2) / (1.0f * z2 + a1 * z + a2), filter_order);
 }