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

          Line data    Source code
       1             : /**
       2             :  * \file Chebyshev1Filter.hxx
       3             :  */
       4             : 
       5             : #include "Chebyshev1Filter.h"
       6             : #include <ATK/EQ/helpers.h>
       7             : 
       8             : #include <boost/math/constants/constants.hpp>
       9             : #include <boost/math/special_functions/asinh.hpp>
      10             : 
      11             : namespace Chebyshev1Utilities
      12             : {
      13             :   template<typename DataType>
      14          92 :   void create_chebyshev1_analog_coefficients(int order, DataType ripple, EQUtilities::ZPK<DataType>& zpk)
      15             :   {
      16          92 :     zpk.z.clear(); // no zeros for this filter type
      17          92 :     zpk.p.clear();
      18          92 :     if(ripple == 0)
      19             :     {
      20          66 :       return;
      21             :     }
      22          36 :     if(order == 0)
      23             :     {
      24          10 :       zpk.k = static_cast<DataType>(std::pow(10, (-ripple / 20)));
      25          10 :       return;
      26             :     }
      27             :     
      28          26 :     DataType eps = static_cast<DataType>(std::sqrt(std::pow(10, (0.1 * ripple)) - 1.0));
      29          26 :     DataType mu = static_cast<DataType>(1.0 / order * boost::math::asinh(1 / eps));
      30             :     
      31          84 :     for(gsl::index i = -order+1; i < order; i += 2)
      32             :     {
      33          58 :       DataType theta = boost::math::constants::pi<DataType>() * i / (2*order);
      34          58 :       zpk.p.push_back(-std::sinh(std::complex<DataType>(mu, theta)));
      35             :     }
      36             : 
      37          26 :     std::complex<DataType> f = 1;
      38             :     
      39          84 :     for(gsl::index i = 0; i < zpk.p.size(); ++i)
      40             :     {
      41          58 :       f *= -zpk.p[i];
      42             :     }
      43          26 :     zpk.k = f.real();
      44          26 :     if(order % 2 == 0)
      45             :     {
      46           0 :       zpk.k = zpk.k / std::sqrt(1 + eps * eps);
      47             :     }
      48             :   }
      49             :   
      50             :   template<typename DataType, typename Container>
      51          46 :   void create_default_chebyshev1_coeffs(size_t order, DataType ripple, DataType Wn, Container& coefficients_in, Container& coefficients_out)
      52             :   {
      53          92 :     EQUtilities::ZPK<DataType> zpk;
      54             : 
      55          46 :     int fs = 2;
      56          46 :     create_chebyshev1_analog_coefficients(static_cast<int>(order), ripple, zpk);
      57          46 :     EQUtilities::populate_lp_coeffs(Wn, fs, order, zpk, coefficients_in, coefficients_out);
      58          46 :   }
      59             :   
      60             :   template<typename DataType, typename Container>
      61          23 :   void create_bp_chebyshev1_coeffs(size_t order, DataType ripple, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
      62             :   {
      63          46 :     EQUtilities::ZPK<DataType> zpk;
      64             : 
      65          23 :     int fs = 2;
      66          23 :     create_chebyshev1_analog_coefficients(static_cast<int>(order/2), ripple, zpk);
      67          23 :     EQUtilities::populate_bp_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
      68          23 :   }
      69             :   
      70             :   template<typename DataType, typename Container>
      71          23 :   void create_bs_chebyshev1_coeffs(size_t order, DataType ripple, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
      72             :   {
      73          46 :     EQUtilities::ZPK<DataType> zpk;
      74             : 
      75          23 :     int fs = 2;
      76          23 :     create_chebyshev1_analog_coefficients(static_cast<int>(order/2), ripple, zpk);
      77          23 :     EQUtilities::populate_bs_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
      78          23 :   }
      79             : }
      80             : 
      81             : namespace ATK
      82             : {
      83             :   template <typename DataType>
      84           9 :   Chebyshev1LowPassCoefficients<DataType>::Chebyshev1LowPassCoefficients(gsl::index nb_channels)
      85           9 :   :Parent(nb_channels, nb_channels)
      86             :   {
      87           9 :   }
      88             :   
      89             :   template <typename DataType_>
      90           5 :   void Chebyshev1LowPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
      91             :   {
      92           5 :     this->ripple = ripple;
      93           5 :     setup();
      94           5 :   }
      95             :   
      96             :   template <typename DataType_>
      97           1 :   typename Chebyshev1LowPassCoefficients<DataType_>::CoeffDataType Chebyshev1LowPassCoefficients<DataType_>::get_ripple() const
      98             :   {
      99           1 :     return ripple;
     100             :   }
     101             :   
     102             :   template <typename DataType_>
     103           6 :   void Chebyshev1LowPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
     104             :   {
     105           6 :     if(cut_frequency <= 0)
     106             :     {
     107           1 :       throw std::out_of_range("Frequency can't be negative");
     108             :     }
     109           5 :     this->cut_frequency = cut_frequency;
     110           5 :     setup();
     111           5 :   }
     112             :   
     113             :   template <typename DataType_>
     114           1 :   typename Chebyshev1LowPassCoefficients<DataType_>::CoeffDataType Chebyshev1LowPassCoefficients<DataType_>::get_cut_frequency() const
     115             :   {
     116           1 :     return cut_frequency;
     117             :   }
     118             :   
     119             :   template <typename DataType>
     120           6 :   void Chebyshev1LowPassCoefficients<DataType>::set_order(unsigned int order)
     121             :   {
     122           6 :     if(order == 0)
     123             :     {
     124           1 :       throw std::out_of_range("Order can't be null");
     125             :     }
     126           5 :     in_order = out_order = order;
     127           5 :     setup();
     128           5 :   }
     129             :   
     130             :   template <typename DataType>
     131           1 :   unsigned int Chebyshev1LowPassCoefficients<DataType>::get_order() const
     132             :   {
     133           1 :     return in_order;
     134             :   }
     135             : 
     136             :   template <typename DataType>
     137          23 :   void Chebyshev1LowPassCoefficients<DataType>::setup()
     138             :   {
     139          23 :     Parent::setup();
     140          23 :     coefficients_in.assign(in_order+1, 0);
     141          23 :     coefficients_out.assign(out_order, 0);
     142             :     
     143          23 :     Chebyshev1Utilities::create_default_chebyshev1_coeffs(in_order, ripple, 2 * cut_frequency / input_sampling_rate, coefficients_in, coefficients_out);
     144          23 :   }
     145             :   
     146             :   template <typename DataType>
     147           9 :   Chebyshev1HighPassCoefficients<DataType>::Chebyshev1HighPassCoefficients(gsl::index nb_channels)
     148           9 :   :Parent(nb_channels, nb_channels)
     149             :   {
     150           9 :   }
     151             :   
     152             :   template <typename DataType_>
     153           6 :   void Chebyshev1HighPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
     154             :   {
     155           6 :     if(cut_frequency <= 0)
     156             :     {
     157           1 :       throw std::out_of_range("Frequency can't be negative");
     158             :     }
     159           5 :     this->cut_frequency = cut_frequency;
     160           5 :     setup();
     161           5 :   }
     162             :   
     163             :   template <typename DataType_>
     164           1 :   typename Chebyshev1HighPassCoefficients<DataType_>::CoeffDataType Chebyshev1HighPassCoefficients<DataType_>::get_cut_frequency() const
     165             :   {
     166           1 :     return cut_frequency;
     167             :   }
     168             :   
     169             :   template <typename DataType_>
     170           5 :   void Chebyshev1HighPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
     171             :   {
     172           5 :     this->ripple = ripple;
     173           5 :     setup();
     174           5 :   }
     175             :   
     176             :   template <typename DataType_>
     177           1 :   typename Chebyshev1HighPassCoefficients<DataType_>::CoeffDataType Chebyshev1HighPassCoefficients<DataType_>::get_ripple() const
     178             :   {
     179           1 :     return ripple;
     180             :   }
     181             : 
     182             :   template <typename DataType>
     183           6 :   void Chebyshev1HighPassCoefficients<DataType>::set_order(unsigned int order)
     184             :   {
     185           6 :     if(order == 0)
     186             :     {
     187           1 :       throw std::out_of_range("Order can't be null");
     188             :     }
     189           5 :     in_order = out_order = order;
     190           5 :     setup();
     191           5 :   }
     192             :   
     193             :   template <typename DataType>
     194           1 :   unsigned int Chebyshev1HighPassCoefficients<DataType>::get_order() const
     195             :   {
     196           1 :     return in_order;
     197             :   }
     198             : 
     199             :   template <typename DataType>
     200          23 :   void Chebyshev1HighPassCoefficients<DataType>::setup()
     201             :   {
     202          23 :     Parent::setup();
     203          23 :     coefficients_in.assign(in_order+1, 0);
     204          23 :     coefficients_out.assign(out_order, 0);
     205             :     
     206          23 :     Chebyshev1Utilities::create_default_chebyshev1_coeffs(in_order, ripple, (input_sampling_rate - 2 * cut_frequency) / input_sampling_rate, coefficients_in, coefficients_out);
     207          51 :     for(gsl::index i = in_order - 1; i >= 0; i -= 2)
     208             :     {
     209          28 :       coefficients_in[i] = - coefficients_in[i];
     210          28 :       coefficients_out[i] = - coefficients_out[i];
     211             :     }
     212          23 :   }
     213             :   
     214             :   template <typename DataType>
     215          10 :   Chebyshev1BandPassCoefficients<DataType>::Chebyshev1BandPassCoefficients(gsl::index nb_channels)
     216          10 :   :Parent(nb_channels, nb_channels)
     217             :   {
     218          10 :   }
     219             :   
     220             :   template <typename DataType_>
     221           7 :   void Chebyshev1BandPassCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
     222             :   {
     223           7 :     if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
     224             :     {
     225           2 :       throw std::out_of_range("Frequencies can't be negative");
     226             :     }
     227           5 :     this->cut_frequencies = cut_frequencies;
     228           5 :     setup();
     229           5 :   }
     230             :   
     231             :   template <typename DataType_>
     232           3 :   void Chebyshev1BandPassCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
     233             :   {
     234           3 :     set_cut_frequencies(std::make_pair(f0, f1));
     235           1 :   }
     236             :   
     237             :   template <typename DataType_>
     238           2 :   std::pair<typename Chebyshev1BandPassCoefficients<DataType_>::CoeffDataType, typename Chebyshev1BandPassCoefficients<DataType_>::CoeffDataType> Chebyshev1BandPassCoefficients<DataType_>::get_cut_frequencies() const
     239             :   {
     240           2 :     return cut_frequencies;
     241             :   }
     242             :   
     243             :   template <typename DataType_>
     244           5 :   void Chebyshev1BandPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
     245             :   {
     246           5 :     this->ripple = ripple;
     247           5 :     setup();
     248           5 :   }
     249             :   
     250             :   template <typename DataType_>
     251           1 :   typename Chebyshev1BandPassCoefficients<DataType_>::CoeffDataType Chebyshev1BandPassCoefficients<DataType_>::get_ripple() const
     252             :   {
     253           1 :     return ripple;
     254             :   }
     255             : 
     256             :   template <typename DataType>
     257           6 :   void Chebyshev1BandPassCoefficients<DataType>::set_order(unsigned int order)
     258             :   {
     259           6 :     if(order == 0)
     260             :     {
     261           1 :       throw std::out_of_range("Order can't be null");
     262             :     }
     263           5 :     in_order = out_order = 2 * order;
     264           5 :     setup();
     265           5 :   }
     266             :   
     267             :   template <typename DataType>
     268           1 :   unsigned int Chebyshev1BandPassCoefficients<DataType>::get_order() const
     269             :   {
     270           1 :     return in_order / 2;
     271             :   }
     272             : 
     273             :   template <typename DataType>
     274          23 :   void Chebyshev1BandPassCoefficients<DataType>::setup()
     275             :   {
     276          23 :     Parent::setup();
     277          23 :     coefficients_in.assign(in_order+1, 0);
     278          23 :     coefficients_out.assign(out_order, 0);
     279             :     
     280          23 :     Chebyshev1Utilities::create_bp_chebyshev1_coeffs(in_order, ripple, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
     281          23 :   }
     282             :   
     283             :   template <typename DataType>
     284          10 :   Chebyshev1BandStopCoefficients<DataType>::Chebyshev1BandStopCoefficients(gsl::index nb_channels)
     285          10 :   :Parent(nb_channels, nb_channels)
     286             :   {
     287          10 :   }
     288             :   
     289             :   template <typename DataType_>
     290           7 :   void Chebyshev1BandStopCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
     291             :   {
     292           7 :     if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
     293             :     {
     294           2 :       throw std::out_of_range("Frequencies can't be negative");
     295             :     }
     296           5 :     this->cut_frequencies = cut_frequencies;
     297           5 :     setup();
     298           5 :   }
     299             :   
     300             :   template <typename DataType_>
     301           3 :   void Chebyshev1BandStopCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
     302             :   {
     303           3 :     set_cut_frequencies(std::make_pair(f0, f1));
     304           1 :   }
     305             :   
     306             :   template <typename DataType_>
     307           2 :   std::pair<typename Chebyshev1BandStopCoefficients<DataType_>::CoeffDataType, typename Chebyshev1BandStopCoefficients<DataType_>::CoeffDataType> Chebyshev1BandStopCoefficients<DataType_>::get_cut_frequencies() const
     308             :   {
     309           2 :     return cut_frequencies;
     310             :   }
     311             :   
     312             :   template <typename DataType_>
     313           5 :   void Chebyshev1BandStopCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
     314             :   {
     315           5 :     this->ripple = ripple;
     316           5 :     setup();
     317           5 :   }
     318             :   
     319             :   template <typename DataType_>
     320           1 :   typename Chebyshev1BandStopCoefficients<DataType_>::CoeffDataType Chebyshev1BandStopCoefficients<DataType_>::get_ripple() const
     321             :   {
     322           1 :     return ripple;
     323             :   }
     324             : 
     325             :   template <typename DataType>
     326           6 :   void Chebyshev1BandStopCoefficients<DataType>::set_order(unsigned int order)
     327             :   {
     328           6 :     if(order == 0)
     329             :     {
     330           1 :       throw std::out_of_range("Order can't be null");
     331             :     }
     332           5 :     in_order = out_order = 2 * order;
     333           5 :     setup();
     334           5 :   }
     335             :   
     336             :   template <typename DataType>
     337           1 :   unsigned int Chebyshev1BandStopCoefficients<DataType>::get_order() const
     338             :   {
     339           1 :     return in_order / 2;
     340             :   }
     341             : 
     342             :   template <typename DataType>
     343          23 :   void Chebyshev1BandStopCoefficients<DataType>::setup()
     344             :   {
     345          23 :     Parent::setup();
     346          23 :     coefficients_in.assign(in_order+1, 0);
     347          23 :     coefficients_out.assign(out_order, 0);
     348             :     
     349          23 :     Chebyshev1Utilities::create_bs_chebyshev1_coeffs(in_order, ripple, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
     350          23 :   }
     351             : }

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