X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=filter.cpp;h=0cb0180d8c4ce4f673112422708f68f5608f9b4d;hp=a5cd76733f3f5325af1c511a3f4c007e6c6cf8e9;hb=703e00da89118df9be0354dda621bed023e6030e;hpb=12f9082b06c037b76dc3a653643bdaeaea89f2d2 diff --git a/filter.cpp b/filter.cpp index a5cd767..0cb0180 100644 --- a/filter.cpp +++ b/filter.cpp @@ -1,9 +1,11 @@ +#include #include #include #include -#include -#include #include +#include + +#include "defs.h" #ifdef __SSE__ #include @@ -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 Filter::evaluate_transfer_function(float omega) +complex Filter::evaluate_transfer_function(float omega) { - std::complex z = exp(std::complex(0.0f, omega)); - std::complex z2 = z * z; - return std::pow((b0 * z2 + b1 * z + b2) / (1.0f * z2 + a1 * z + a2), filter_order); + complex z = exp(complex(0.0f, omega)); + complex z2 = z * z; + return pow((b0 * z2 + b1 * z + b2) / (1.0f * z2 + a1 * z + a2), filter_order); }