LCOV - code coverage report
Current view: top level - src/audio/dsp - biquad.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 59 59
Test Date: 2026-06-01 11:15:25 Functions: 100.0 % 8 8

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include "common.h"
       4              : 
       5              : namespace Amplitron {
       6              : 
       7              : /**
       8              :  * Transposed Direct Form II biquad filter.
       9              :  * Used by Equalizer, AmpSimulator, and CabinetSim.
      10              :  */
      11          476 : struct Biquad {
      12          387 :     float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
      13          387 :     float b0 = 1, b1 = 0, b2 = 0, a1 = 0, a2 = 0;
      14              : 
      15      4979784 :     float process(float x) {
      16      4979784 :         float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
      17      4979784 :         x2 = x1; x1 = x;
      18      4979784 :         y2 = y1; y1 = y;
      19      4979784 :         return y;
      20              :     }
      21              : 
      22          552 :     void reset() { x1 = x2 = y1 = y2 = 0; }
      23              : 
      24              :     // --- Coefficient computation (Audio EQ Cookbook formulas) ---
      25              : 
      26          297 :     void set_low_shelf(float freq, float gain_db, float q, int sample_rate) {
      27          297 :         float A = std::pow(10.0f, gain_db / 40.0f);
      28          297 :         float w0 = TWO_PI * freq / sample_rate;
      29          297 :         float cos_w0 = std::cos(w0);
      30          297 :         float sin_w0 = std::sin(w0);
      31          297 :         float alpha = sin_w0 / (2.0f * q);
      32          297 :         float sqA = std::sqrt(A);
      33              : 
      34          297 :         float a0 = (A + 1) + (A - 1) * cos_w0 + 2 * sqA * alpha;
      35          297 :         b0 = (A * ((A + 1) - (A - 1) * cos_w0 + 2 * sqA * alpha)) / a0;
      36          297 :         b1 = (2 * A * ((A - 1) - (A + 1) * cos_w0)) / a0;
      37          297 :         b2 = (A * ((A + 1) - (A - 1) * cos_w0 - 2 * sqA * alpha)) / a0;
      38          297 :         a1 = (-2 * ((A - 1) + (A + 1) * cos_w0)) / a0;
      39          297 :         a2 = ((A + 1) + (A - 1) * cos_w0 - 2 * sqA * alpha) / a0;
      40          297 :     }
      41              : 
      42          297 :     void set_peaking(float freq, float gain_db, float q, int sample_rate) {
      43          297 :         float A = std::pow(10.0f, gain_db / 40.0f);
      44          297 :         float w0 = TWO_PI * freq / sample_rate;
      45          297 :         float cos_w0 = std::cos(w0);
      46          297 :         float sin_w0 = std::sin(w0);
      47          297 :         float alpha = sin_w0 / (2.0f * q);
      48              : 
      49          297 :         float a0 = 1 + alpha / A;
      50          297 :         b0 = (1 + alpha * A) / a0;
      51          297 :         b1 = (-2 * cos_w0) / a0;
      52          297 :         b2 = (1 - alpha * A) / a0;
      53          297 :         a1 = (-2 * cos_w0) / a0;
      54          297 :         a2 = (1 - alpha / A) / a0;
      55          297 :     }
      56              : 
      57          297 :     void set_high_shelf(float freq, float gain_db, float q, int sample_rate) {
      58          297 :         float A = std::pow(10.0f, gain_db / 40.0f);
      59          297 :         float w0 = TWO_PI * freq / sample_rate;
      60          297 :         float cos_w0 = std::cos(w0);
      61          297 :         float sin_w0 = std::sin(w0);
      62          297 :         float alpha = sin_w0 / (2.0f * q);
      63          297 :         float sqA = std::sqrt(A);
      64              : 
      65          297 :         float a0 = (A + 1) - (A - 1) * cos_w0 + 2 * sqA * alpha;
      66          297 :         b0 = (A * ((A + 1) + (A - 1) * cos_w0 + 2 * sqA * alpha)) / a0;
      67          297 :         b1 = (-2 * A * ((A - 1) + (A + 1) * cos_w0)) / a0;
      68          297 :         b2 = (A * ((A + 1) + (A - 1) * cos_w0 - 2 * sqA * alpha)) / a0;
      69          297 :         a1 = (2 * ((A - 1) - (A + 1) * cos_w0)) / a0;
      70          297 :         a2 = ((A + 1) - (A - 1) * cos_w0 - 2 * sqA * alpha) / a0;
      71          297 :     }
      72              : };
      73              : 
      74              : /**
      75              :  * One-pole low-pass filter for tone controls and DC blocking.
      76              :  */
      77          558 : struct OnePole {
      78          341 :     float state = 0.0f;
      79              : 
      80        29208 :     float lp(float input, float coeff) {
      81        29208 :         state += coeff * (input - state);
      82        29208 :         return state;
      83              :     }
      84              : 
      85        26136 :     float hp(float input, float coeff) {
      86        26136 :         state += coeff * (input - state);
      87        26136 :         return input - state;
      88              :     }
      89              : 
      90          842 :     void reset() { state = 0.0f; }
      91              : };
      92              : 
      93              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1