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

          Line data    Source code
       1             : /**
       2             :  * \file TimeVaryingSecondOrderFilter.cpp
       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 "TimeVaryingSecondOrderFilter.h"
       8             : #include <ATK/EQ/TimeVaryingIIRFilter.h>
       9             : 
      10             : #include <boost/math/constants/constants.hpp>
      11             : 
      12             : #include <cassert>
      13             : #include <cmath>
      14             : 
      15             : namespace ATK
      16             : {
      17             :   /// Time varying coefficient base class. Two input ports, the first is the data, the second one is the central frequency
      18             :   template <typename DataType>
      19          49 :   TimeVaryingBaseSecondOrderCoefficients<DataType>::TimeVaryingBaseSecondOrderCoefficients()
      20          49 :     :Parent(2, 1)
      21             :   {
      22          49 :   }
      23             : 
      24             :   template <typename DataType>
      25         173 :   void TimeVaryingBaseSecondOrderCoefficients<DataType>::setup()
      26             :   {
      27         173 :     Parent::setup();
      28             : 
      29         173 :     coefficients_in.clear();
      30         173 :     coefficients_in.reserve((in_order+1) * number_of_steps);
      31         173 :     coefficients_out.clear();
      32         173 :     coefficients_out.reserve(out_order * number_of_steps);
      33         173 :   }
      34             : 
      35             :   template <typename DataType>
      36          30 :   void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_min_frequency(double min_frequency)
      37             :   {
      38          30 :     if(min_frequency <= 0)
      39             :     {
      40           1 :       throw std::out_of_range("Min frequency must be positive");
      41             :     }
      42          29 :     this->min_frequency = min_frequency;
      43          29 :     setup();
      44          29 :   }
      45             : 
      46             :   template <typename DataType>
      47           1 :   double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_min_frequency() const
      48             :   {
      49           1 :     return min_frequency;
      50             :   }
      51             : 
      52             :   template <typename DataType>
      53          30 :   void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_max_frequency(double max_frequency)
      54             :   {
      55          30 :     if(max_frequency <= min_frequency)
      56             :     {
      57           1 :       throw std::out_of_range("Max frequency must be greater than min frequency");
      58             :     }
      59          29 :     this->max_frequency = max_frequency;
      60          29 :     setup();
      61          29 :   }
      62             : 
      63             :   template <typename DataType>
      64           1 :   double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_max_frequency() const
      65             :   {
      66           1 :     return max_frequency;
      67             :   }
      68             : 
      69             :   template <typename DataType>
      70          30 :   void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_number_of_steps(int number_of_steps)
      71             :   {
      72          30 :     if(number_of_steps <= 0)
      73             :     {
      74           1 :       throw std::out_of_range("Number of steps must be strictly positive");
      75             :     }
      76          29 :     this->number_of_steps = number_of_steps;
      77          29 :     setup();
      78          29 :   }
      79             : 
      80             :   template <typename DataType>
      81           1 :   int TimeVaryingBaseSecondOrderCoefficients<DataType>::get_number_of_steps() const
      82             :   {
      83           1 :     return number_of_steps;
      84             :   }
      85             : 
      86             :   template <typename DataType>
      87           3 :   void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_memory(double memory)
      88             :   {
      89           3 :     if(memory < 0 || memory >= 1)
      90             :     {
      91           2 :       throw std::out_of_range("Memory for time varying EQ had to be in the range [0, 1[");
      92             :     }
      93           1 :     this->memory = memory;
      94           1 :   }
      95             : 
      96             :   template <typename DataType>
      97           1 :   double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_memory() const
      98             :   {
      99           1 :     return memory;
     100             :   }
     101             : 
     102             :   template<typename DataType>
     103          14 :   TimeVaryingBandPassCoefficients<DataType>::TimeVaryingBandPassCoefficients()
     104          14 :     :Parent()
     105             :   {
     106          14 :   }
     107             : 
     108             :   template <typename DataType>
     109          22 :   void TimeVaryingBandPassCoefficients<DataType>::setup()
     110             :   {
     111          22 :     Parent::setup();
     112             :     
     113       36005 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     114             :     {
     115       35983 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     116       35983 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     117       35983 :       DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c);
     118       35983 :       DataType Q_inv = 1 / Q;
     119             : 
     120       35983 :       coefficients_in.push_back(-Q_inv * c / d);
     121       35983 :       coefficients_in.push_back(0);
     122       35983 :       coefficients_in.push_back(Q_inv * c / d);
     123       35983 :       coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     124       35983 :       coefficients_out.push_back(- 2 * (c * c - 1) / d);
     125             :     }
     126          22 :   }
     127             :   
     128             :   template <typename DataType_>
     129           5 :   void TimeVaryingBandPassCoefficients<DataType_>::set_Q(DataType_ Q)
     130             :   {
     131           5 :     if(Q <= 0)
     132             :     {
     133           1 :       throw std::out_of_range("Q must be strictly positive");
     134             :     }
     135           4 :     this->Q = Q;
     136           4 :     setup();
     137           4 :   }
     138             : 
     139             :   template <typename DataType_>
     140           1 :   DataType_ TimeVaryingBandPassCoefficients<DataType_>::get_Q() const
     141             :   {
     142           1 :     return Q;
     143             :   }
     144             : 
     145             :   template<typename DataType>
     146           4 :   TimeVaryingLowPassCoefficients<DataType>::TimeVaryingLowPassCoefficients()
     147           4 :     :Parent()
     148             :   {
     149           4 :   }
     150             : 
     151             :   template <typename DataType>
     152          20 :   void TimeVaryingLowPassCoefficients<DataType>::setup()
     153             :   {
     154          20 :     Parent::setup();
     155             : 
     156       47784 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     157             :     {
     158       47764 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     159       47764 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     160       47764 :       DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c);
     161             :     
     162       47764 :       coefficients_in.push_back(c * c / d);
     163       47764 :       coefficients_in.push_back(2 * c * c / d);
     164       47764 :       coefficients_in.push_back(c * c / d);
     165       47764 :       coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     166       47764 :       coefficients_out.push_back(- 2 * (c * c - 1) / d);
     167             :     }
     168          20 :   }
     169             : 
     170             :   template<typename DataType>
     171           3 :   TimeVaryingHighPassCoefficients<DataType>::TimeVaryingHighPassCoefficients()
     172           3 :     :Parent()
     173             :   {
     174           3 :   }
     175             : 
     176             :   template <typename DataType>
     177          15 :   void TimeVaryingHighPassCoefficients<DataType>::setup()
     178             :   {
     179          15 :     Parent::setup();
     180             : 
     181       35838 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     182             :     {
     183       35823 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     184       35823 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     185       35823 :       DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c);
     186             : 
     187       35823 :       coefficients_in.push_back(1);
     188       35823 :       coefficients_in.push_back(-2);
     189       35823 :       coefficients_in.push_back(1);
     190       35823 :       coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     191       35823 :       coefficients_out.push_back(- 2 * (c * c - 1) / d);
     192             :     }
     193          15 :   }
     194             : 
     195             :   template<typename DataType>
     196           7 :   TimeVaryingBandPassPeakCoefficients<DataType>::TimeVaryingBandPassPeakCoefficients()
     197           7 :     :Parent()
     198             :   {
     199           7 :   }
     200             : 
     201             :   template <typename DataType>
     202          23 :   void TimeVaryingBandPassPeakCoefficients<DataType>::setup()
     203             :   {
     204          23 :     Parent::setup();
     205             : 
     206       35926 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     207             :     {
     208       35903 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     209       35903 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     210       35903 :       DataType Q_inv = 1 / Q;
     211       35903 :       if(gain <= 1)
     212             :       {
     213         110 :         DataType V0 = 1 / gain;
     214         110 :         DataType d = 1 + V0 * Q_inv * c + c * c;
     215             : 
     216         110 :         coefficients_in.push_back((1 - Q_inv * c + c * c) / d);
     217         110 :         coefficients_in.push_back(2 * (c * c - 1) / d);
     218         110 :         coefficients_in.push_back((1 + Q_inv * c + c * c) / d);
     219         110 :         coefficients_out.push_back(-(1 - V0 * Q_inv * c + c * c) / d);
     220         110 :         coefficients_out.push_back(-2 * (c * c - 1) / d);
     221             :       }
     222             :       else
     223             :       {
     224       35793 :         DataType V0 = gain;
     225       35793 :         DataType d = 1 + Q_inv * c + c * c;
     226             : 
     227       35793 :         coefficients_in.push_back((1 - V0 * Q_inv * c + c * c) / d);
     228       35793 :         coefficients_in.push_back(2 * (c * c - 1) / d);
     229       35793 :         coefficients_in.push_back((1 + V0 * Q_inv * c + c * c) / d);
     230       35793 :         coefficients_out.push_back(-(1 - Q_inv * c + c * c) / d);
     231       35793 :         coefficients_out.push_back(-2 * (c * c - 1) / d);
     232             :       }
     233             :     }
     234          23 :   }
     235             : 
     236             :   template <typename DataType_>
     237           5 :   void TimeVaryingBandPassPeakCoefficients<DataType_>::set_Q(DataType_ Q)
     238             :   {
     239           5 :     if(Q <= 0)
     240             :     {
     241           1 :       throw std::out_of_range("Q must be strictly positive");
     242             :     }
     243           4 :     this->Q = Q;
     244           4 :     setup();
     245           4 :   }
     246             : 
     247             :   template <typename DataType_>
     248           1 :   DataType_ TimeVaryingBandPassPeakCoefficients<DataType_>::get_Q() const
     249             :   {
     250           1 :     return Q;
     251             :   }
     252             : 
     253             :   template <typename DataType_>
     254           5 :   void TimeVaryingBandPassPeakCoefficients<DataType_>::set_gain(DataType_ gain)
     255             :   {
     256           5 :     if(gain <= 0)
     257             :     {
     258           1 :       throw std::out_of_range("Gain must be strictly positive");
     259             :     }
     260           4 :     this->gain = gain;
     261           4 :     setup();
     262           4 :   }
     263             : 
     264             :   template <typename DataType_>
     265           1 :   DataType_ TimeVaryingBandPassPeakCoefficients<DataType_>::get_gain() const
     266             :   {
     267           1 :     return gain;
     268             :   }
     269             : 
     270             :   template<typename DataType>
     271           5 :   TimeVaryingAllPassCoefficients<DataType>::TimeVaryingAllPassCoefficients()
     272           5 :     :Parent()
     273             :   {
     274           5 :   }
     275             : 
     276             :   template <typename DataType>
     277          19 :   void TimeVaryingAllPassCoefficients<DataType>::setup()
     278             :   {
     279          19 :     Parent::setup();
     280             : 
     281       35882 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     282             :     {
     283       35863 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     284       35863 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * Q);
     285       35863 :       DataType d = -std::cos(2 * boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     286             : 
     287       35863 :       coefficients_in.push_back(1);
     288       35863 :       coefficients_in.push_back(d * (1 - c));
     289       35863 :       coefficients_in.push_back(-c);
     290       35863 :       coefficients_out.push_back(c);
     291       35863 :       coefficients_out.push_back(-d * (1 - c));
     292             :     }
     293          19 :   }
     294             : 
     295             :   template <typename DataType_>
     296           5 :   void TimeVaryingAllPassCoefficients<DataType_>::set_Q(DataType_ Q)
     297             :   {
     298           5 :     if(Q <= 0)
     299             :     {
     300           1 :       throw std::out_of_range("Q must be strictly positive");
     301             :     }
     302           4 :     this->Q = Q;
     303           4 :     setup();
     304           4 :   }
     305             : 
     306             :   template <typename DataType_>
     307           1 :   DataType_ TimeVaryingAllPassCoefficients<DataType_>::get_Q() const
     308             :   {
     309           1 :     return Q;
     310             :   }
     311             : 
     312             :   template<typename DataType>
     313           8 :   TimeVaryingLowShelvingCoefficients<DataType>::TimeVaryingLowShelvingCoefficients()
     314           8 :     :Parent()
     315             :   {
     316           8 :   }
     317             : 
     318             :   template <typename DataType>
     319          37 :   void TimeVaryingLowShelvingCoefficients<DataType>::setup()
     320             :   {
     321          37 :     Parent::setup();
     322             : 
     323       71753 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     324             :     {
     325       71716 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     326       71716 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     327       71716 :       if(gain <= 1)
     328             :       {
     329       35923 :         DataType V0 = 1 / gain;
     330       35923 :         DataType d = (1 + std::sqrt(static_cast<DataType>(2.) * V0) * c + V0 * c * c);
     331             : 
     332       35923 :         coefficients_in.push_back((1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     333       35923 :         coefficients_in.push_back(2 * (c * c - 1) / d);
     334       35923 :         coefficients_in.push_back((1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     335       35923 :         coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.) * V0) * c + V0 * c * c) / d);
     336       35923 :         coefficients_out.push_back(- 2 * (V0 * c * c - 1) / d);
     337             :       }
     338             :       else
     339             :       {
     340       35793 :         DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c);
     341             : 
     342       35793 :         coefficients_in.push_back((1 - std::sqrt(static_cast<DataType>(2.) * gain) * c + gain * c * c) / d);
     343       35793 :         coefficients_in.push_back(2 * (gain * c * c - 1) / d);
     344       35793 :         coefficients_in.push_back((1 + std::sqrt(static_cast<DataType>(2.) * gain) * c + gain * c * c) / d);
     345       35793 :         coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d);
     346       35793 :         coefficients_out.push_back(- 2 * (c * c - 1) / d);
     347             :       }
     348             :     }
     349          37 :   }
     350             : 
     351             :   template <typename DataType_>
     352           8 :   void TimeVaryingLowShelvingCoefficients<DataType_>::set_gain(DataType_ gain)
     353             :   {
     354           8 :     if(gain <= 0)
     355             :     {
     356           1 :       throw std::out_of_range("Gain must be strictly positive");
     357             :     }
     358           7 :     this->gain = gain;
     359           7 :     setup();
     360           7 :   }
     361             : 
     362             :   template <typename DataType_>
     363           1 :   DataType_ TimeVaryingLowShelvingCoefficients<DataType_>::get_gain() const
     364             :   {
     365           1 :     return gain;
     366             :   }
     367             : 
     368             :   template<typename DataType>
     369           8 :   TimeVaryingHighShelvingCoefficients<DataType>::TimeVaryingHighShelvingCoefficients()
     370           8 :     :Parent()
     371             :   {
     372           8 :   }
     373             : 
     374             :   template <typename DataType>
     375          37 :   void TimeVaryingHighShelvingCoefficients<DataType>::setup()
     376             :   {
     377          37 :     Parent::setup();
     378             : 
     379       71753 :     for(gsl::index i = 0; i < number_of_steps; ++i)
     380             :     {
     381       71716 :       DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency);
     382       71716 :       DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate);
     383       71716 :       if(gain <= 1)
     384             :       {
     385       35923 :         DataType V0 = 1 / gain;
     386       35923 :         DataType d = (V0 + std::sqrt(static_cast<DataType>(2.) * V0) * c + c * c);
     387             : 
     388       35923 :         coefficients_in.push_back(-(1 - std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d);
     389       35923 :         coefficients_in.push_back(-2 * (c * c - 1) / d);
     390       35923 :         coefficients_in.push_back(-(1 + std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d);
     391       35923 :         coefficients_out.push_back(- (V0 - std::sqrt(static_cast<DataType>(2.0) * V0) * c + c * c) / d);
     392       35923 :         coefficients_out.push_back(- 2 * (c * c - V0) / d);
     393             :       }
     394             :       else
     395             :       {
     396       35793 :         DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c);
     397             : 
     398       35793 :         coefficients_in.push_back(-(gain - std::sqrt(static_cast<DataType>(2.0) * gain) * c + c * c) / d);
     399       35793 :         coefficients_in.push_back(-2 * (c * c - gain) / d);
     400       35793 :         coefficients_in.push_back(-(gain + std::sqrt(static_cast<DataType>(2.0) * gain) * c + c * c) / d);
     401       35793 :         coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d);
     402       35793 :         coefficients_out.push_back(- 2 * (c * c - 1) / d);
     403             :       }
     404             :     }
     405          37 :   }
     406             :   
     407             :   template<typename DataType_>
     408           8 :   void TimeVaryingHighShelvingCoefficients<DataType_>::set_gain(DataType_ gain)
     409             :   {
     410           8 :     if(gain <= 0)
     411             :     {
     412           1 :       throw std::out_of_range("Gain must be strictly positive");
     413             :     }
     414           7 :     this->gain = gain;
     415           7 :     setup();
     416           7 :   }
     417             : 
     418             :   template <typename DataType_>
     419           1 :   DataType_ TimeVaryingHighShelvingCoefficients<DataType_>::get_gain() const
     420             :   {
     421           1 :     return gain;
     422             :   }
     423             : 
     424             : #if ATK_ENABLE_INSTANTIATION
     425             :   template class TimeVaryingBaseSecondOrderCoefficients<float>;
     426             :   
     427             :   template class ATK_EQ_EXPORT TimeVaryingBandPassCoefficients<float>;
     428             :   template class ATK_EQ_EXPORT TimeVaryingLowPassCoefficients<float>;
     429             :   template class ATK_EQ_EXPORT TimeVaryingHighPassCoefficients<float>;
     430             :   template class ATK_EQ_EXPORT TimeVaryingBandPassPeakCoefficients<float>;
     431             :   template class ATK_EQ_EXPORT TimeVaryingAllPassCoefficients<float>;
     432             :   template class ATK_EQ_EXPORT TimeVaryingLowShelvingCoefficients<float>;
     433             :   template class ATK_EQ_EXPORT TimeVaryingHighShelvingCoefficients<float>;
     434             : #endif
     435             :   template class TimeVaryingBaseSecondOrderCoefficients<double>;
     436             : 
     437             :   template class ATK_EQ_EXPORT TimeVaryingBandPassCoefficients<double>;
     438             :   template class ATK_EQ_EXPORT TimeVaryingLowPassCoefficients<double>;
     439             :   template class ATK_EQ_EXPORT TimeVaryingHighPassCoefficients<double>;
     440             :   template class ATK_EQ_EXPORT TimeVaryingBandPassPeakCoefficients<double>;
     441             :   template class ATK_EQ_EXPORT TimeVaryingAllPassCoefficients<double>;
     442             :   template class ATK_EQ_EXPORT TimeVaryingLowShelvingCoefficients<double>;
     443             :   template class ATK_EQ_EXPORT TimeVaryingHighShelvingCoefficients<double>;
     444             : }

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