#pragma once #define _USE_MATH_DEFINES #include #include namespace trnr { class chebyshev { public: chebyshev() {} chebyshev(double _samplerate, double _frequency) { set_samplerate(_samplerate); set_frequency(_frequency); } void set_samplerate(double _samplerate) { samplerate = _samplerate; } void set_frequency(double _frequency) { // First calculate the prewarped digital frequency : auto K = tanf(M_PI * _frequency / samplerate); // Now we calc some Coefficients : auto sg = sinh(passband_ripple); auto cg = cosh(passband_ripple); cg *= cg; std::array coeff; coeff[0] = 1 / (cg - 0.85355339059327376220042218105097); coeff[1] = K * coeff[0] * sg * 1.847759065022573512256366378792; coeff[2] = 1 / (cg - 0.14644660940672623779957781894758); coeff[3] = K * coeff[2] * sg * 0.76536686473017954345691996806; K *= K; // (just to optimize it a little bit) // Calculate the first biquad: a0 = 1 / (coeff[1] + K + coeff[0]); a1 = 2 * (coeff[0] - K) * a0; a2 = (coeff[1] - K - coeff[0]) * a0; b0 = a0 * K; b1 = 2 * b0; b2 = b0; // Calculate the second biquad: a3 = 1 / (coeff[3] + K + coeff[2]); a4 = 2 * (coeff[2] - K) * a3; a5 = (coeff[3] - K - coeff[2]) * a3; b3 = a3 * K; b4 = 2 * b3; b5 = b3; } void reset(double _samplerate, double _frequency) { set_samplerate(_samplerate); set_frequency(_frequency); } template void process_sample(t_sample& input) { auto Stage1 = b0 * input + state0; state0 = b1 * input + a1 * Stage1 + state1; state1 = b2 * input + a2 * Stage1; input = b3 * Stage1 + state2; state2 = b4 * Stage1 + a4 * input + state3; state3 = b5 * Stage1 + a5 * input; } template void process_sample(t_sample& input, double frequency) { set_frequency(frequency); process_sample(input); } template void process_block(t_sample* input, int blockSize) { t_sample output = 0; for (int i = 0; i < blockSize; i++) { output = input[i]; process_sample(output); input[i] = output; } } private: double samplerate = 20000; double a0 = 0; double a1 = 0; double a2 = 0; double a3 = 0; double a4 = 0; double a5 = 0; double b0 = 0; double b1 = 0; double b2 = 0; double b3 = 0; double b4 = 0; double b5 = 0; double state0 = 0; double state1 = 0; double state2 = 0; double state3 = 0; double passband_ripple = 1; }; } // namespace trnr