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

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

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