LCOV - code coverage report
Current view: top level - EQ - SecondOrderFilter.hxx (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 179 179 100.0 %
Date: 2021-02-18 20:07:22 Functions: 31 31 100.0 %

          Line data    Source code
       1             : /**
       2             :  * \file SecondOrderFilter.hxx
       3             :  * @see http://abvolt.com/research/publications2.htm
       4             :  * @see http://www.music.mcgill.ca/~ich/classes/FiltersChap2.pdf for the allpass filter
       5             :  */
       6             : 
       7             : #include "SecondOrderFilter.h"
       8             : 
       9             : #include <boost/math/constants/constants.hpp>
      10             : 
      11             : #include <cassert>
      12             : #include <cmath>
      13             : 
      14             : namespace ATK
      15             : {
      16             :   template <typename DataType_>
      17         105 :   SecondOrderCoreCoefficients<DataType_>::SecondOrderCoreCoefficients(gsl::index nb_channels)
      18         105 :     :Parent(nb_channels, nb_channels)
      19             :   {
      20         105 :   }
      21             : 
      22             :   template <typename DataType_>
      23          95 :   SecondOrderBaseCoefficients<DataType_>::SecondOrderBaseCoefficients(gsl::index nb_channels)
      24          95 :     : Parent(nb_channels)
      25             :   {
      26          95 :   }
      27             : 
      28             :   template <typename DataType_>
      29         239 :   void SecondOrderBaseCoefficients<DataType_>::setup()
      30             :   {
      31         239 :     Parent::setup();
      32             : 
      33         239 :     coefficients_in.assign(in_order+1, 0);
      34         239 :     coefficients_out.assign(out_order, 0);
      35         239 :   }
      36             : 
      37             :   template <typename DataType_>
      38          62 :   void SecondOrderBaseCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
      39             :   {
      40          62 :     if(cut_frequency <= 0)
      41             :     {
      42           1 :       throw std::out_of_range("Frequency can't be negative");
      43             :     }
      44          61 :     this->cut_frequency = cut_frequency;
      45          61 :     setup();
      46          61 :   }
      47             :   
      48             :   template <typename DataType_>
      49           2 :   typename SecondOrderBaseCoefficients<DataType_>::CoeffDataType  SecondOrderBaseCoefficients<DataType_>::get_cut_frequency() const
      50             :   {
      51           2 :     return cut_frequency;
      52             :   }
      53             : 
      54             :   template<typename DataType_>
      55           5 :   SecondOrderBandPassCoefficients<DataType_>::SecondOrderBandPassCoefficients(gsl::index nb_channels)
      56           5 :     :Parent(nb_channels)
      57             :   {
      58           5 :   }
      59             : 
      60             :   template <typename DataType_>
      61          13 :   void SecondOrderBandPassCoefficients<DataType_>::setup()
      62             :   {
      63          13 :     Parent::setup();
      64             :     
      65          13 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
      66          13 :     CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c);
      67          13 :     CoeffDataType Q_inv = 1 / Q;
      68             :     
      69          13 :     coefficients_in[2] = Q_inv * c / d;
      70          13 :     coefficients_in[1] = 0;
      71          13 :     coefficients_in[0] = -Q_inv * c / d;
      72          13 :     coefficients_out[1] = - 2 * (c * c - 1) / d;
      73          13 :     coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
      74          13 :   }
      75             :   
      76             :   template <typename DataType_>
      77           5 :   void SecondOrderBandPassCoefficients<DataType_>::set_Q(CoeffDataType Q)
      78             :   {
      79           5 :     if(Q <= 0)
      80             :     {
      81           1 :       throw std::out_of_range("Q can't be negative");
      82             :     }
      83           4 :     this->Q = Q;
      84           4 :     setup();
      85           4 :   }
      86             : 
      87             :   template <typename DataType_>
      88           1 :   typename SecondOrderBandPassCoefficients<DataType_>::CoeffDataType SecondOrderBandPassCoefficients<DataType_>::get_Q() const
      89             :   {
      90           1 :     return Q;
      91             :   }
      92             : 
      93             :   template<typename DataType_>
      94           6 :   SecondOrderLowPassCoefficients<DataType_>::SecondOrderLowPassCoefficients(gsl::index nb_channels)
      95           6 :     :Parent(nb_channels)
      96             :   {
      97           6 :   }
      98             : 
      99             :   template <typename DataType_>
     100          13 :   void SecondOrderLowPassCoefficients<DataType_>::setup()
     101             :   {
     102          13 :     Parent::setup();
     103             : 
     104          13 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     105          13 :     CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c);
     106             :     
     107          13 :     coefficients_in[2] = c * c / d;
     108          13 :     coefficients_in[1] = 2 * c * c / d;
     109          13 :     coefficients_in[0] = c * c / d;
     110          13 :     coefficients_out[1] = - 2 * (c * c - 1) / d;
     111          13 :     coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
     112          13 :   }
     113             : 
     114             :   template<typename DataType_>
     115           3 :   SecondOrderHighPassCoefficients<DataType_>::SecondOrderHighPassCoefficients(gsl::index nb_channels)
     116           3 :     :Parent(nb_channels)
     117             :   {
     118           3 :   }
     119             : 
     120             :   template <typename DataType_>
     121           9 :   void SecondOrderHighPassCoefficients<DataType_>::setup()
     122             :   {
     123           9 :     Parent::setup();
     124             : 
     125           9 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     126           9 :     CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c);
     127             :     
     128           9 :     coefficients_in[2] = 1;
     129           9 :     coefficients_in[1] = -2;
     130           9 :     coefficients_in[0] = 1;
     131           9 :     coefficients_out[1] = - 2 * (c * c - 1) / d;
     132           9 :     coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
     133           9 :   }
     134             : 
     135             :   template<typename DataType_>
     136           6 :   SecondOrderBandPassPeakCoefficients<DataType_>::SecondOrderBandPassPeakCoefficients(gsl::index nb_channels)
     137           6 :     :Parent(nb_channels)
     138             :   {
     139           6 :   }
     140             : 
     141             :   template <typename DataType_>
     142          17 :   void SecondOrderBandPassPeakCoefficients<DataType_>::setup()
     143             :   {
     144          17 :     Parent::setup();
     145             : 
     146          17 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     147          17 :     CoeffDataType Q_inv = 1 / Q;
     148          17 :     if(gain <= 1)
     149             :     {
     150          13 :       CoeffDataType V0 = 1 / gain;
     151          13 :       CoeffDataType d = 1 + V0 * Q_inv * c + c * c;
     152             :       
     153          13 :       coefficients_in[2] = (1 + Q_inv * c + c * c) / d;
     154          13 :       coefficients_in[1] = 2 * (c * c - 1) / d;
     155          13 :       coefficients_in[0] = (1 - Q_inv * c + c * c) / d;
     156          13 :       coefficients_out[1] = -2 * (c * c - 1) / d;
     157          13 :       coefficients_out[0] = -(1 - V0 * Q_inv * c + c * c) / d;
     158             :     }
     159             :     else
     160             :     {
     161           4 :       CoeffDataType V0 = gain;
     162           4 :       CoeffDataType d = 1 + Q_inv * c + c * c;
     163             :       
     164           4 :       coefficients_in[2] = (1 + V0 * Q_inv * c + c * c) / d;
     165           4 :       coefficients_in[1] = 2 * (c * c - 1) / d;
     166           4 :       coefficients_in[0] = (1 - V0 * Q_inv * c + c * c) / d;
     167           4 :       coefficients_out[1] = -2 * (c * c - 1) / d;
     168           4 :       coefficients_out[0] = -(1 - Q_inv * c + c * c) / d;
     169             :     }
     170          17 :   }
     171             : 
     172             :   template <typename DataType_>
     173           5 :   void SecondOrderBandPassPeakCoefficients<DataType_>::set_Q(CoeffDataType Q)
     174             :   {
     175           5 :     if(Q <= 0)
     176             :     {
     177           1 :       throw std::out_of_range("Q can't be negative");
     178             :     }
     179           4 :     this->Q = Q;
     180           4 :     setup();
     181           4 :   }
     182             : 
     183             :   template <typename DataType_>
     184           1 :   typename SecondOrderBandPassPeakCoefficients<DataType_>::CoeffDataType SecondOrderBandPassPeakCoefficients<DataType_>::get_Q() const
     185             :   {
     186           1 :     return Q;
     187             :   }
     188             : 
     189             :   template <typename DataType_>
     190           4 :   void SecondOrderBandPassPeakCoefficients<DataType_>::set_gain(CoeffDataType gain)
     191             :   {
     192           4 :     this->gain = gain;
     193           4 :     setup();
     194           4 :   }
     195             : 
     196             :   template <typename DataType_>
     197           1 :   typename SecondOrderBandPassPeakCoefficients<DataType_>::CoeffDataType SecondOrderBandPassPeakCoefficients<DataType_>::get_gain() const
     198             :   {
     199           1 :     return gain;
     200             :   }
     201             : 
     202             :   template<typename DataType_>
     203           5 :   SecondOrderAllPassCoefficients<DataType_>::SecondOrderAllPassCoefficients(gsl::index nb_channels)
     204           5 :     :Parent(nb_channels)
     205             :   {
     206           5 :   }
     207             : 
     208             :   template <typename DataType_>
     209          13 :   void SecondOrderAllPassCoefficients<DataType_>::setup()
     210             :   {
     211          13 :     Parent::setup();
     212             : 
     213          13 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * Q);
     214          13 :     CoeffDataType d = -std::cos(2 * boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     215             : 
     216          13 :     coefficients_in[2] = -c;
     217          13 :     coefficients_in[1] = d * (1 - c);
     218          13 :     coefficients_in[0] = 1;
     219          13 :     coefficients_out[1] = -d * (1 - c);
     220          13 :     coefficients_out[0] = c;
     221          13 :   }
     222             : 
     223             :   template <typename DataType_>
     224           5 :   void SecondOrderAllPassCoefficients<DataType_>::set_Q(CoeffDataType Q)
     225             :   {
     226           5 :     if(Q <= 0)
     227             :     {
     228           1 :       throw std::out_of_range("Q can't be negative");
     229             :     }
     230           4 :     this->Q = Q;
     231           4 :     setup();
     232           4 :   }
     233             : 
     234             :   template <typename DataType_>
     235           1 :   typename SecondOrderAllPassCoefficients<DataType_>::CoeffDataType SecondOrderAllPassCoefficients<DataType_>::get_Q() const
     236             :   {
     237           1 :     return Q;
     238             :   }
     239             : 
     240             :   template<typename DataType_>
     241           4 :   SecondOrderLowShelvingCoefficients<DataType_>::SecondOrderLowShelvingCoefficients(gsl::index nb_channels)
     242           4 :     :Parent(nb_channels)
     243             :   {
     244           4 :   }
     245             : 
     246             :   template <typename DataType_>
     247          13 :   void SecondOrderLowShelvingCoefficients<DataType_>::setup()
     248             :   {
     249          13 :     Parent::setup();
     250             : 
     251          13 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     252          13 :     if(gain <= 1)
     253             :     {
     254          12 :       CoeffDataType V0 = 1 / gain;
     255          12 :       CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.) * V0) * c + V0 * c * c);
     256             :       
     257          12 :       coefficients_in[2] = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
     258          12 :       coefficients_in[1] = 2 * (c * c - 1) / d;
     259          12 :       coefficients_in[0] = (1 - std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
     260          12 :       coefficients_out[1] = - 2 * (V0 * c * c - 1) / d;
     261          12 :       coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.) * V0) * c + V0 * c * c) / d;
     262             :     }
     263             :     else
     264             :     {
     265           1 :       CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c);
     266             :       
     267           1 :       coefficients_in[2] = (1 + std::sqrt(static_cast<CoeffDataType>(2.) * gain) * c + gain * c * c) / d;
     268           1 :       coefficients_in[1] = 2 * (gain * c * c - 1) / d;
     269           1 :       coefficients_in[0] = (1 - std::sqrt(static_cast<CoeffDataType>(2.) * gain) * c + gain * c * c) / d;
     270           1 :       coefficients_out[1] = - 2 * (c * c - 1) / d;
     271           1 :       coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c) / d;
     272             :     }
     273          13 :   }
     274             : 
     275             :   template <typename DataType_>
     276           4 :   void SecondOrderLowShelvingCoefficients<DataType_>::set_gain(CoeffDataType gain)
     277             :   {
     278           4 :     this->gain = gain;
     279           4 :     setup();
     280           4 :   }
     281             : 
     282             :   template <typename DataType_>
     283           1 :   typename SecondOrderLowShelvingCoefficients<DataType_>::CoeffDataType SecondOrderLowShelvingCoefficients<DataType_>::get_gain() const
     284             :   {
     285           1 :     return gain;
     286             :   }
     287             : 
     288             :   template<typename DataType_>
     289           4 :   SecondOrderHighShelvingCoefficients<DataType_>::SecondOrderHighShelvingCoefficients(gsl::index nb_channels)
     290           4 :     :Parent(nb_channels)
     291             :   {
     292           4 :   }
     293             : 
     294             :   template <typename DataType>
     295          13 :   void SecondOrderHighShelvingCoefficients<DataType>::setup()
     296             :   {
     297          13 :     Parent::setup();
     298             : 
     299          13 :     CoeffDataType c = std::tan(boost::math::constants::pi<CoeffDataType>() * cut_frequency / input_sampling_rate);
     300          13 :     if(gain <= 1)
     301             :     {
     302          12 :       CoeffDataType V0 = 1 / gain;
     303          12 :       CoeffDataType d = (V0 + std::sqrt(static_cast<CoeffDataType>(2.) * V0) * c + c * c);
     304             :       
     305          12 :       coefficients_in[2] = -(1 + std::sqrt(static_cast<CoeffDataType>(2.0)) * c + c * c) / d;
     306          12 :       coefficients_in[1] = -2 * (c * c - 1) / d;
     307          12 :       coefficients_in[0] = -(1 - std::sqrt(static_cast<CoeffDataType>(2.0)) * c + c * c) / d;
     308          12 :       coefficients_out[1] = - 2 * (c * c - V0) / d;
     309          12 :       coefficients_out[0] = - (V0 - std::sqrt(static_cast<CoeffDataType>(2.0) * V0) * c + c * c) / d;
     310             :     }
     311             :     else
     312             :     {
     313           1 :       CoeffDataType d = (1 + std::sqrt(static_cast<CoeffDataType>(2.)) * c + c * c);
     314             :       
     315           1 :       coefficients_in[2] = -(gain + std::sqrt(static_cast<CoeffDataType>(2.0) * gain) * c + c * c) / d;
     316           1 :       coefficients_in[1] = -2 * (c * c - gain) / d;
     317           1 :       coefficients_in[0] = -(gain - std::sqrt(static_cast<CoeffDataType>(2.0) * gain) * c + c * c) / d;
     318           1 :       coefficients_out[1] = - 2 * (c * c - 1) / d;
     319           1 :       coefficients_out[0] = - (1 - std::sqrt(static_cast<CoeffDataType>(2.0)) * c + c * c) / d;
     320             :     }
     321          13 :   }
     322             :   
     323             :   template<typename DataType_>
     324           4 :   void SecondOrderHighShelvingCoefficients<DataType_>::set_gain(CoeffDataType gain)
     325             :   {
     326           4 :     this->gain = gain;
     327           4 :     setup();
     328           4 :   }
     329             : 
     330             :   template <typename DataType_>
     331           1 :   typename SecondOrderHighShelvingCoefficients<DataType_>::CoeffDataType SecondOrderHighShelvingCoefficients<DataType_>::get_gain() const
     332             :   {
     333           1 :     return gain;
     334             :   }
     335             : }

Generated by: LCOV version TK-3.3.0-4-gdba42eea