LCOV - code coverage report
Current view: top level - Delay - FeedbackDelayNetworkFilter.hxx (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 54 54 100.0 %
Date: 2021-02-18 20:07:22 Functions: 42 84 50.0 %

          Line data    Source code
       1             : /**
       2             :  * \file FeedbackDelayNetworkFilter.hxx
       3             :  */
       4             : 
       5             : #ifndef ATK_DELAY_FEEDBACKDELAYNETWORKFILTER_HXX
       6             : #define ATK_DELAY_FEEDBACKDELAYNETWORKFILTER_HXX
       7             : 
       8             : #include <ATK/Delay/FeedbackDelayNetworkFilter.h>
       9             : #include <ATK/Core/Utilities.h>
      10             : 
      11             : #include <Eigen/Dense>
      12             : 
      13             : #include <complex>
      14             : 
      15             : namespace ATK
      16             : {
      17             :   template<typename Mixture>
      18             :   class FeedbackDelayNetworkFilter<Mixture>::HFDN_Impl: public Mixture::MixtureImpl
      19             :   {
      20             :   public:
      21             :     using Vector =  typename Mixture::MixtureImpl::Vector;
      22             :     using Matrix =  typename Mixture::MixtureImpl::Matrix;
      23             : 
      24             :     std::vector<Vector, boost::alignment::aligned_allocator<Vector, 32>> delay_line;
      25             :     std::vector<Vector, boost::alignment::aligned_allocator<Vector, 32>> processed_input;
      26             :     int64_t index{0};
      27             :     Vector ingain = Vector::Zero();
      28             :     Vector outgain = Vector::Zero();
      29             :     Vector feedback = Vector::Zero();
      30             : 
      31          30 :     explicit HFDN_Impl(gsl::index max_delay)
      32          30 :       :processed_input(max_delay, Vector::Zero())
      33             :     {
      34          30 :     }
      35             :   };
      36             : 
      37             :   template<typename Mixture>
      38          30 :   FeedbackDelayNetworkFilter<Mixture>::FeedbackDelayNetworkFilter(gsl::index max_delay)
      39          30 :     :Parent(1, 2), impl(std::make_unique<HFDN_Impl>(max_delay)), max_delay(max_delay)
      40             :   {
      41          30 :     delay.fill(max_delay - 1);
      42          30 :   }
      43             : 
      44             :   template<typename Mixture>
      45          30 :   FeedbackDelayNetworkFilter<Mixture>::~FeedbackDelayNetworkFilter()
      46             :   {
      47          30 :   }
      48             : 
      49             :   template<typename Mixture>
      50          26 :   void FeedbackDelayNetworkFilter<Mixture>::set_delay(unsigned int channel, gsl::index delay)
      51             :   {
      52          26 :     if (delay == 0)
      53             :     {
      54           2 :       throw ATK::RuntimeError("Delay must be strictly positive");
      55             :     }
      56          24 :     if (delay >= max_delay)
      57             :     {
      58           2 :       throw ATK::RuntimeError("Delay must be less than delay line size");
      59             :     }
      60             : 
      61          22 :     this->delay[channel] = delay;
      62          22 :   }
      63             : 
      64             :   template<typename Mixture>
      65           2 :   gsl::index FeedbackDelayNetworkFilter<Mixture>::get_delay(unsigned int channel) const
      66             :   {
      67           2 :     return delay[channel];
      68             :   }
      69             : 
      70             :   template<typename Mixture>
      71          22 :   void FeedbackDelayNetworkFilter<Mixture>::set_ingain(unsigned int channel, DataType ingain)
      72             :   {
      73          22 :     impl->ingain(channel) = ingain;
      74          22 :   }
      75             : 
      76             :   template<typename Mixture>
      77           2 :   typename FeedbackDelayNetworkFilter<Mixture>::DataType FeedbackDelayNetworkFilter<Mixture>::get_ingain(unsigned int channel) const
      78             :   {
      79           2 :     return impl->ingain(channel);
      80             :   }
      81             : 
      82             :   template<typename Mixture>
      83          14 :   void FeedbackDelayNetworkFilter<Mixture>::set_feedback(unsigned int channel, DataType feedback)
      84             :   {
      85          14 :     if (std::abs(feedback * static_cast<DataType>(Mixture::gain_factor)) >= 1)
      86             :     {
      87           4 :       throw ATK::RuntimeError("Feedback must be between " + std::to_string(-Mixture::gain_factor) + " and " + std::to_string(Mixture::gain_factor) + " to avoid divergence");
      88             :     }
      89          10 :     impl->feedback(channel) = feedback * static_cast<DataType>(Mixture::gain_factor);
      90          10 :   }
      91             : 
      92             :   template<typename Mixture>
      93           2 :   typename FeedbackDelayNetworkFilter<Mixture>::DataType FeedbackDelayNetworkFilter<Mixture>::get_feedback(unsigned int channel) const
      94             :   {
      95           2 :     return impl->feedback(channel) / static_cast<DataType>(Mixture::gain_factor);
      96             :   }
      97             : 
      98             :   template<typename Mixture>
      99          22 :   void FeedbackDelayNetworkFilter<Mixture>::set_outgain(unsigned int channel, DataType outgain)
     100             :   {
     101          22 :     impl->outgain(channel) = outgain;
     102          22 :   }
     103             : 
     104             :   template<typename Mixture>
     105           2 :   typename FeedbackDelayNetworkFilter<Mixture>::DataType FeedbackDelayNetworkFilter<Mixture>::get_outgain(unsigned int channel) const
     106             :   {
     107           2 :     return impl->outgain(channel);
     108             :   }
     109             : 
     110             :   template<typename Mixture>
     111          14 :   void FeedbackDelayNetworkFilter<Mixture>::full_setup()
     112             :   {
     113             :     // reset the delay line
     114          14 :     impl->processed_input.assign(max_delay, HFDN_Impl::Vector::Zero());
     115          14 :   }
     116             : 
     117             :   template<typename Mixture>
     118        4222 :   void FeedbackDelayNetworkFilter<Mixture>::process_impl(gsl::index size) const
     119             :   {
     120        4222 :     const DataType* ATK_RESTRICT input = converted_inputs[0];
     121        4222 :     DataType* ATK_RESTRICT output = outputs[0];
     122             : 
     123        4222 :     impl->delay_line.resize(size);
     124             : 
     125     2298861 :     for (gsl::index i = 0; i < size; ++i)
     126             :     {
     127     9197780 :       for (gsl::index channel = 0; channel < nb_channels; ++channel)
     128             :       {
     129     6903130 :         auto j = impl->index - static_cast<int64_t>(delay[channel]);
     130     6903130 :         if (j < 0)
     131             :         {
     132     4806210 :           j += max_delay;
     133             :         }
     134             : 
     135     6903130 :         impl->delay_line[i](channel) = impl->processed_input[j](channel);
     136             :       }
     137     2294640 :       impl->processed_input[impl->index] = (impl->ingain * input[i]).array() + impl->mix(impl->delay_line[i]).array() * impl->feedback.array();
     138             : 
     139     2294640 :       output[i] = impl->outgain.dot(impl->delay_line[i]);
     140             : 
     141     2294640 :       ++impl->index;
     142     2294640 :       if(impl->index == max_delay)
     143             :       {
     144        4812 :         impl->index = 0;
     145             :       }
     146             :     }
     147        4222 :   }
     148             : }
     149             : 
     150             : #endif

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