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

          Line data    Source code
       1             : /**
       2             :  * \file BesselFilter.hxx
       3             :  */
       4             : 
       5             : #include "BesselFilter.h"
       6             : #include <ATK/EQ/helpers.h>
       7             : 
       8             : #include <boost/math/constants/constants.hpp>
       9             : 
      10             : namespace BesselUtilities
      11             : {
      12             :   template<typename DataType>
      13          90 :   void create_bessel_analog_coefficients(int order, EQUtilities::ZPK<DataType>& zpk)
      14             :   {
      15          90 :     zpk.k = 1;
      16          90 :     auto& z = zpk.z;
      17          90 :     auto& p = zpk.p;
      18          90 :     z.clear(); // no zeros for this filter type
      19          90 :     p.clear();
      20          90 :     switch (order)
      21             :     {
      22          26 :       case 0:
      23          26 :         break;
      24          30 :       case 1:
      25          30 :         p.push_back(1);
      26          30 :         break;
      27           1 :       case 2:
      28           1 :         p.push_back(std::complex<DataType>(-.8660254037844386467637229, .4999999999999999999999996));
      29           1 :         p.push_back(std::complex<DataType>(-.8660254037844386467637229, -.4999999999999999999999996));
      30           1 :         break;
      31          22 :       case 3:
      32          22 :         p.push_back(std::complex<DataType>(-.9416000265332067855971980, 0));
      33          22 :         p.push_back(std::complex<DataType>(-.7456403858480766441810907, .7113666249728352680992154));
      34          22 :         p.push_back(std::complex<DataType>(-.7456403858480766441810907, -.7113666249728352680992154));
      35          22 :         break;
      36           1 :       case 4:
      37           1 :         p.push_back(std::complex<DataType>(-.6572111716718829545787781, .8301614350048733772399715));
      38           1 :         p.push_back(std::complex<DataType>(-.6572111716718829545787781, -.8301614350048733772399715));
      39           1 :         p.push_back(std::complex<DataType>(-.9047587967882449459642637, .2709187330038746636700923));
      40           1 :         p.push_back(std::complex<DataType>(-.9047587967882449459642637, -.2709187330038746636700923));
      41           1 :         break;
      42           1 :       case 5:
      43           1 :         p.push_back(std::complex<DataType>(-.9264420773877602247196260, 0));
      44           1 :         p.push_back(std::complex<DataType>(-.8515536193688395541722677, .4427174639443327209850002));
      45           1 :         p.push_back(std::complex<DataType>(-.8515536193688395541722677, -.4427174639443327209850002));
      46           1 :         p.push_back(std::complex<DataType>(-.5905759446119191779319432, .9072067564574549539291747));
      47           1 :         p.push_back(std::complex<DataType>(-.5905759446119191779319432, -.9072067564574549539291747));
      48           1 :         break;
      49           1 :       case 6:
      50           1 :         p.push_back(std::complex<DataType>(-.9093906830472271808050953, .1856964396793046769246397));
      51           1 :         p.push_back(std::complex<DataType>(-.9093906830472271808050953, -.1856964396793046769246397));
      52           1 :         p.push_back(std::complex<DataType>(-.7996541858328288520243325, .5621717346937317988594118));
      53           1 :         p.push_back(std::complex<DataType>(-.7996541858328288520243325, -.5621717346937317988594118));
      54           1 :         p.push_back(std::complex<DataType>(-.5385526816693109683073792, .9616876881954277199245657));
      55           1 :         p.push_back(std::complex<DataType>(-.5385526816693109683073792, -.9616876881954277199245657));
      56           1 :         break;
      57           1 :       case 7:
      58           1 :         p.push_back(std::complex<DataType>(-.9194871556490290014311619, 0));
      59           1 :         p.push_back(std::complex<DataType>(-.8800029341523374639772340, .3216652762307739398381830));
      60           1 :         p.push_back(std::complex<DataType>(-.8800029341523374639772340, -.3216652762307739398381830));
      61           1 :         p.push_back(std::complex<DataType>(-.7527355434093214462291616, .6504696305522550699212995));
      62           1 :         p.push_back(std::complex<DataType>(-.7527355434093214462291616, -.6504696305522550699212995));
      63           1 :         p.push_back(std::complex<DataType>(-.4966917256672316755024763, 1.002508508454420401230220));
      64           1 :         p.push_back(std::complex<DataType>(-.4966917256672316755024763, -1.002508508454420401230220));
      65           1 :         break;
      66           1 :       case 8:
      67           1 :         p.push_back(std::complex<DataType>(-.9096831546652910216327629, .1412437976671422927888150));
      68           1 :         p.push_back(std::complex<DataType>(-.9096831546652910216327629, -.1412437976671422927888150));
      69           1 :         p.push_back(std::complex<DataType>(-.8473250802359334320103023, .4259017538272934994996429));
      70           1 :         p.push_back(std::complex<DataType>(-.8473250802359334320103023, -.4259017538272934994996429));
      71           1 :         p.push_back(std::complex<DataType>(-.7111381808485399250796172, .7186517314108401705762571));
      72           1 :         p.push_back(std::complex<DataType>(-.7111381808485399250796172, -.7186517314108401705762571));
      73           1 :         p.push_back(std::complex<DataType>(-.4621740412532122027072175, 1.034388681126901058116589));
      74           1 :         p.push_back(std::complex<DataType>(-.4621740412532122027072175, -1.034388681126901058116589));
      75           1 :         break;
      76           1 :       case 9:
      77           1 :         p.push_back(std::complex<DataType>(-.9154957797499037686769223, 0));
      78           1 :         p.push_back(std::complex<DataType>(-.8911217017079759323183848, .2526580934582164192308115));
      79           1 :         p.push_back(std::complex<DataType>(-.8911217017079759323183848, -.2526580934582164192308115));
      80           1 :         p.push_back(std::complex<DataType>(-.8148021112269012975514135, .5085815689631499483745341));
      81           1 :         p.push_back(std::complex<DataType>(-.8148021112269012975514135, -.5085815689631499483745341));
      82           1 :         p.push_back(std::complex<DataType>(-.6743622686854761980403401, .7730546212691183706919682));
      83           1 :         p.push_back(std::complex<DataType>(-.6743622686854761980403401, -.7730546212691183706919682));
      84           1 :         p.push_back(std::complex<DataType>(-.4331415561553618854685942, 1.060073670135929666774323));
      85           1 :         p.push_back(std::complex<DataType>(-.4331415561553618854685942, -1.060073670135929666774323));
      86           1 :         break;
      87           1 :       case 10:
      88           1 :         p.push_back(std::complex<DataType>(-.9091347320900502436826431, .1139583137335511169927714));
      89           1 :         p.push_back(std::complex<DataType>(-.9091347320900502436826431, -.1139583137335511169927714));
      90           1 :         p.push_back(std::complex<DataType>(-.8688459641284764527921864, .3430008233766309973110589));
      91           1 :         p.push_back(std::complex<DataType>(-.8688459641284764527921864, -.3430008233766309973110589));
      92           1 :         p.push_back(std::complex<DataType>(-.7837694413101441082655890, .5759147538499947070009852));
      93           1 :         p.push_back(std::complex<DataType>(-.7837694413101441082655890, -.5759147538499947070009852));
      94           1 :         p.push_back(std::complex<DataType>(-.6417513866988316136190854, .8175836167191017226233947));
      95           1 :         p.push_back(std::complex<DataType>(-.6417513866988316136190854, -.8175836167191017226233947));
      96           1 :         p.push_back(std::complex<DataType>(-.4083220732868861566219785, 1.081274842819124562037210));
      97           1 :         p.push_back(std::complex<DataType>(-.4083220732868861566219785, -1.081274842819124562037210));
      98           1 :         break;
      99           1 :       case 11:
     100           1 :         p.push_back(std::complex<DataType>(-.9129067244518981934637318, 0));
     101           1 :         p.push_back(std::complex<DataType>(-.8963656705721166099815744, .2080480375071031919692341));
     102           1 :         p.push_back(std::complex<DataType>(-.8963656705721166099815744, -.2080480375071031919692341));
     103           1 :         p.push_back(std::complex<DataType>(-.8453044014712962954184557, .4178696917801248292797448));
     104           1 :         p.push_back(std::complex<DataType>(-.8453044014712962954184557, -.4178696917801248292797448));
     105           1 :         p.push_back(std::complex<DataType>(-.7546938934722303128102142, .6319150050721846494520941));
     106           1 :         p.push_back(std::complex<DataType>(-.7546938934722303128102142, -.6319150050721846494520941));
     107           1 :         p.push_back(std::complex<DataType>(-.6126871554915194054182909, .8547813893314764631518509));
     108           1 :         p.push_back(std::complex<DataType>(-.6126871554915194054182909, -.8547813893314764631518509));
     109           1 :         p.push_back(std::complex<DataType>(-.3868149510055090879155425, 1.099117466763120928733632));
     110           1 :         p.push_back(std::complex<DataType>(-.3868149510055090879155425, -1.099117466763120928733632));
     111           1 :         break;
     112           1 :       case 12:
     113           1 :         p.push_back(std::complex<DataType>(-.9084478234140682638817772, 95506365213450398415258360.0e-27));
     114           1 :         p.push_back(std::complex<DataType>(-.9084478234140682638817772, -95506365213450398415258360.0e-27));
     115           1 :         p.push_back(std::complex<DataType>(-.8802534342016826507901575, .2871779503524226723615457));
     116           1 :         p.push_back(std::complex<DataType>(-.8802534342016826507901575, -.2871779503524226723615457));
     117           1 :         p.push_back(std::complex<DataType>(-.8217296939939077285792834, .4810212115100676440620548));
     118           1 :         p.push_back(std::complex<DataType>(-.8217296939939077285792834, -.4810212115100676440620548));
     119           1 :         p.push_back(std::complex<DataType>(-.7276681615395159454547013, .6792961178764694160048987));
     120           1 :         p.push_back(std::complex<DataType>(-.7276681615395159454547013, -.6792961178764694160048987));
     121           1 :         p.push_back(std::complex<DataType>(-.5866369321861477207528215, .8863772751320727026622149));
     122           1 :         p.push_back(std::complex<DataType>(-.5866369321861477207528215, -.8863772751320727026622149));
     123           1 :         p.push_back(std::complex<DataType>(-.3679640085526312839425808, 1.114373575641546257595657));
     124           1 :         p.push_back(std::complex<DataType>(-.3679640085526312839425808, -1.114373575641546257595657));
     125           1 :         break;
     126           1 :       case 13:
     127           1 :         p.push_back(std::complex<DataType>(-.9110914665984182781070663, 0));
     128           1 :         p.push_back(std::complex<DataType>(-.8991314665475196220910718, .1768342956161043620980863));
     129           1 :         p.push_back(std::complex<DataType>(-.8991314665475196220910718, -.1768342956161043620980863));
     130           1 :         p.push_back(std::complex<DataType>(-.8625094198260548711573628, .3547413731172988997754038));
     131           1 :         p.push_back(std::complex<DataType>(-.8625094198260548711573628, -.3547413731172988997754038));
     132           1 :         p.push_back(std::complex<DataType>(-.7987460692470972510394686, .5350752120696801938272504));
     133           1 :         p.push_back(std::complex<DataType>(-.7987460692470972510394686, -.5350752120696801938272504));
     134           1 :         p.push_back(std::complex<DataType>(-.7026234675721275653944062, .7199611890171304131266374));
     135           1 :         p.push_back(std::complex<DataType>(-.7026234675721275653944062, -.7199611890171304131266374));
     136           1 :         p.push_back(std::complex<DataType>(-.5631559842430199266325818, .9135900338325109684927731));
     137           1 :         p.push_back(std::complex<DataType>(-.5631559842430199266325818, -.9135900338325109684927731));
     138           1 :         p.push_back(std::complex<DataType>(-.3512792323389821669401925, 1.127591548317705678613239));
     139           1 :         p.push_back(std::complex<DataType>(-.3512792323389821669401925, -1.127591548317705678613239));
     140           1 :         break;
     141           1 :       default:
     142           1 :         throw std::out_of_range("Can't create a Bessel filter with this order");
     143             :     }
     144          89 :   }
     145             :   
     146             :   template<typename DataType, typename Container>
     147          54 :   void create_default_bessel_coeffs(size_t order, DataType Wn, Container& coefficients_in, Container& coefficients_out)
     148             :   {
     149         108 :     EQUtilities::ZPK<DataType> zpk;
     150             :     
     151          54 :     int fs = 2;
     152          54 :     create_bessel_analog_coefficients(static_cast<int>(order), zpk);
     153          53 :     EQUtilities::populate_lp_coeffs(Wn, fs, order, zpk, coefficients_in, coefficients_out);
     154          53 :   }
     155             :   
     156             :   template<typename DataType, typename Container>
     157          18 :   void create_bp_bessel_coeffs(size_t order, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
     158             :   {
     159          36 :     EQUtilities::ZPK<DataType> zpk;
     160             : 
     161          18 :     int fs = 2;
     162          18 :     create_bessel_analog_coefficients(static_cast<int>(order/2), zpk);
     163          18 :     EQUtilities::populate_bp_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
     164          18 :   }
     165             :   
     166             :   template<typename DataType, typename Container>
     167          18 :   void create_bs_bessel_coeffs(size_t order, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
     168             :   {
     169          36 :     EQUtilities::ZPK<DataType> zpk;
     170             : 
     171          18 :     int fs = 2;
     172          18 :     create_bessel_analog_coefficients(static_cast<int>(order/2), zpk);
     173          18 :     EQUtilities::populate_bs_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
     174          18 :   }
     175             : }
     176             : 
     177             : namespace ATK
     178             : {
     179             :   template <typename DataType>
     180           9 :   BesselLowPassCoefficients<DataType>::BesselLowPassCoefficients(gsl::index nb_channels)
     181           9 :   :Parent(nb_channels, nb_channels)
     182             :   {
     183           9 :   }
     184             :   
     185             :   template <typename DataType_>
     186           7 :   void BesselLowPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
     187             :   {
     188           7 :     if(cut_frequency <= 0)
     189             :     {
     190           1 :       throw std::out_of_range("Frequency can't be negative");
     191             :     }
     192           6 :     this->cut_frequency = cut_frequency;
     193           6 :     setup();
     194           6 :   }
     195             :   
     196             :   template <typename DataType_>
     197           1 :   typename BesselLowPassCoefficients<DataType_>::CoeffDataType BesselLowPassCoefficients<DataType_>::get_cut_frequency() const
     198             :   {
     199           1 :     return cut_frequency;
     200             :   }
     201             :   
     202             :   template <typename DataType>
     203          21 :   void BesselLowPassCoefficients<DataType>::set_order(unsigned int order)
     204             :   {
     205          21 :     if(order == 0)
     206             :     {
     207           1 :       throw std::out_of_range("Order can't be null");
     208             :     }
     209          20 :     in_order = out_order = order;
     210          20 :     setup();
     211          19 :   }
     212             : 
     213             :   template <typename DataType>
     214           1 :   unsigned int BesselLowPassCoefficients<DataType>::get_order() const
     215             :   {
     216           1 :     return in_order;
     217             :   }
     218             : 
     219             :   template <typename DataType>
     220          36 :   void BesselLowPassCoefficients<DataType>::setup()
     221             :   {
     222          36 :     Parent::setup();
     223          36 :     coefficients_in.assign(in_order+1, 0);
     224          36 :     coefficients_out.assign(out_order, 0);
     225             :     
     226          36 :     BesselUtilities::create_default_bessel_coeffs(in_order, 2 * cut_frequency / input_sampling_rate, coefficients_in, coefficients_out);
     227          35 :   }
     228             :   
     229             :   template <typename DataType>
     230           8 :   BesselHighPassCoefficients<DataType>::BesselHighPassCoefficients(gsl::index nb_channels)
     231           8 :   :Parent(nb_channels, nb_channels)
     232             :   {
     233           8 :   }
     234             :   
     235             :   template <typename DataType_>
     236           6 :   void BesselHighPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
     237             :   {
     238           6 :     if(cut_frequency <= 0)
     239             :     {
     240           1 :       throw std::out_of_range("Frequency can't be negative");
     241             :     }
     242           5 :     this->cut_frequency = cut_frequency;
     243           5 :     setup();
     244           5 :   }
     245             :   
     246             :   template <typename DataType_>
     247           1 :   typename BesselHighPassCoefficients<DataType_>::CoeffDataType BesselHighPassCoefficients<DataType_>::get_cut_frequency() const
     248             :   {
     249           1 :     return cut_frequency;
     250             :   }
     251             :   
     252             :   template <typename DataType>
     253           6 :   void BesselHighPassCoefficients<DataType>::set_order(unsigned int order)
     254             :   {
     255           6 :     if(order == 0)
     256             :     {
     257           1 :       throw std::out_of_range("Order can't be null");
     258             :     }
     259           5 :     in_order = out_order = order;
     260           5 :     setup();
     261           5 :   }
     262             :   
     263             :   template <typename DataType>
     264           1 :   unsigned int BesselHighPassCoefficients<DataType>::get_order() const
     265             :   {
     266           1 :     return in_order;
     267             :   }
     268             : 
     269             :   template <typename DataType>
     270          18 :   void BesselHighPassCoefficients<DataType>::setup()
     271             :   {
     272          18 :     Parent::setup();
     273          18 :     coefficients_in.assign(in_order+1, 0);
     274          18 :     coefficients_out.assign(out_order, 0);
     275             :     
     276          18 :     BesselUtilities::create_default_bessel_coeffs(in_order, (input_sampling_rate - 2 * cut_frequency) / input_sampling_rate, coefficients_in, coefficients_out);
     277          41 :     for(gsl::index i = in_order - 1; i >= 0; i -= 2)
     278             :     {
     279          23 :       coefficients_in[i] = - coefficients_in[i];
     280          23 :       coefficients_out[i] = - coefficients_out[i];
     281             :     }
     282          18 :   }
     283             :   
     284             :   template <typename DataType>
     285           9 :   BesselBandPassCoefficients<DataType>::BesselBandPassCoefficients(gsl::index nb_channels)
     286           9 :   :Parent(nb_channels, nb_channels)
     287             :   {
     288           9 :   }
     289             :   
     290             :   template <typename DataType_>
     291           7 :   void BesselBandPassCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
     292             :   {
     293           7 :     if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
     294             :     {
     295           2 :       throw std::out_of_range("Frequencies can't be negative");
     296             :     }
     297           5 :     this->cut_frequencies = cut_frequencies;
     298           5 :     setup();
     299           5 :   }
     300             :   
     301             :   template <typename DataType_>
     302           3 :   void BesselBandPassCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
     303             :   {
     304           3 :     set_cut_frequencies(std::make_pair(f0, f1));
     305           1 :   }
     306             :   
     307             :   template <typename DataType_>
     308           2 :   std::pair<typename BesselBandPassCoefficients<DataType_>::CoeffDataType, typename BesselBandPassCoefficients<DataType_>::CoeffDataType> BesselBandPassCoefficients<DataType_>::get_cut_frequencies() const
     309             :   {
     310           2 :     return cut_frequencies;
     311             :   }
     312             :   
     313             :   template <typename DataType>
     314           6 :   void BesselBandPassCoefficients<DataType>::set_order(unsigned int order)
     315             :   {
     316           6 :     if(order == 0)
     317             :     {
     318           1 :       throw std::out_of_range("Order can't be null");
     319             :     }
     320           5 :     in_order = out_order = 2 * order;
     321           5 :     setup();
     322           5 :   }
     323             :   
     324             :   template <typename DataType>
     325           1 :   unsigned int BesselBandPassCoefficients<DataType>::get_order() const
     326             :   {
     327           1 :     return in_order / 2;
     328             :   }
     329             :   
     330             :   template <typename DataType>
     331          18 :   void BesselBandPassCoefficients<DataType>::setup()
     332             :   {
     333          18 :     Parent::setup();
     334          18 :     coefficients_in.assign(in_order+1, 0);
     335          18 :     coefficients_out.assign(out_order, 0);
     336             :     
     337          18 :     BesselUtilities::create_bp_bessel_coeffs(in_order, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
     338          18 :   }
     339             :   
     340             :   template <typename DataType>
     341           9 :   BesselBandStopCoefficients<DataType>::BesselBandStopCoefficients(gsl::index nb_channels)
     342           9 :   :Parent(nb_channels, nb_channels)
     343             :   {
     344           9 :   }
     345             :   
     346             :   template <typename DataType_>
     347           7 :   void BesselBandStopCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
     348             :   {
     349           7 :     if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
     350             :     {
     351           2 :       throw std::out_of_range("Frequencies can't be negative");
     352             :     }
     353           5 :     this->cut_frequencies = cut_frequencies;
     354           5 :     setup();
     355           5 :   }
     356             :   
     357             :   template <typename DataType_>
     358           3 :   void BesselBandStopCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
     359             :   {
     360           3 :     set_cut_frequencies(std::make_pair(f0, f1));
     361           1 :   }
     362             :   
     363             :   template <typename DataType_>
     364           2 :   std::pair<typename BesselBandStopCoefficients<DataType_>::CoeffDataType, typename BesselBandStopCoefficients<DataType_>::CoeffDataType> BesselBandStopCoefficients<DataType_>::get_cut_frequencies() const
     365             :   {
     366           2 :     return cut_frequencies;
     367             :   }
     368             :   
     369             :   template <typename DataType>
     370           6 :   void BesselBandStopCoefficients<DataType>::set_order(unsigned int order)
     371             :   {
     372           6 :     if(order == 0)
     373             :     {
     374           1 :       throw std::out_of_range("Order can't be null");
     375             :     }
     376           5 :     in_order = out_order = 2 * order;
     377           5 :     setup();
     378           5 :   }
     379             :   
     380             :   template <typename DataType>
     381           1 :   unsigned int BesselBandStopCoefficients<DataType>::get_order() const
     382             :   {
     383           1 :     return in_order / 2;
     384             :   }
     385             : 
     386             :   template <typename DataType>
     387          18 :   void BesselBandStopCoefficients<DataType>::setup()
     388             :   {
     389          18 :     Parent::setup();
     390          18 :     coefficients_in.assign(in_order+1, 0);
     391          18 :     coefficients_out.assign(out_order, 0);
     392             :     
     393          18 :     BesselUtilities::create_bs_bessel_coeffs(in_order, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
     394          18 :   }
     395             : }

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