LCOV - code coverage report
Current view: top level - Delay - MultipleUniversalFixedDelayLineFilter.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 63 63 100.0 %
Date: 2021-02-18 20:07:22 Functions: 13 42 31.0 %

          Line data    Source code
       1             : /**
       2             :  * \file MultipleUniversalFixedDelayLineFilter.cpp
       3             :  */
       4             : 
       5             : #include "MultipleUniversalFixedDelayLineFilter.h"
       6             : #include <ATK/Core/TypeTraits.h>
       7             : #include <ATK/Core/Utilities.h>
       8             : 
       9             : #include <cmath>
      10             : #include <cstring>
      11             : #include <complex>
      12             : #include <stdexcept>
      13             : 
      14             : namespace ATK
      15             : {
      16             :   template<class DataType, int nb_channels>
      17             :   class MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::SUFDLF_Impl
      18             :   {
      19             :   public:
      20             :     std::array<std::vector<DataType>, nb_channels> processed_input;
      21             :     int64_t index{0};
      22             : 
      23          19 :     explicit SUFDLF_Impl(gsl::index max_delay)
      24          19 :     {
      25             :       // reset the delay line
      26          57 :       for (unsigned int channel = 0; channel < nb_channels; ++channel)
      27             :       {
      28          38 :         processed_input[channel].assign(max_delay, 0);
      29             :       }
      30          19 :     }
      31             :   };
      32             : 
      33             :   template<class DataType, int nb_channels>
      34          19 :   MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::MultipleUniversalFixedDelayLineFilter(gsl::index max_delay)
      35          19 :     :Parent(nb_channels, 2 * nb_channels), impl(std::make_unique<SUFDLF_Impl>(max_delay)), max_delay(max_delay)
      36             :   {
      37          19 :     delay.fill(max_delay - 1);
      38          19 :     blend.fill(0);
      39          19 :     feedback.fill(0);
      40          19 :     feedforward.fill(0);
      41          19 :   }
      42             : 
      43             :   template<class DataType, int nb_channels>
      44          19 :   MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::~MultipleUniversalFixedDelayLineFilter()
      45             :   {
      46          19 :   }
      47             : 
      48             :   template<class DataType, int nb_channels>
      49          15 :   void MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::set_delay(unsigned int channel, gsl::index delay)
      50             :   {
      51          15 :     if (delay == 0)
      52             :     {
      53           1 :       throw ATK::RuntimeError("Delay must be strictly positive");
      54             :     }
      55          14 :     if (delay >= max_delay)
      56             :     {
      57           1 :       throw ATK::RuntimeError("Delay must be less than delay line size");
      58             :     }
      59             : 
      60          13 :     this->delay[channel] = delay;
      61          13 :   }
      62             : 
      63             :   template<class DataType, int nb_channels>
      64           1 :   gsl::index MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::get_delay(unsigned int channel) const
      65             :   {
      66           1 :     return delay[channel];
      67             :   }
      68             : 
      69             :   template<class DataType_, int nb_channels>
      70           7 :   void MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::set_blend(unsigned int channel, DataType_ blend)
      71             :   {
      72           7 :     this->blend[channel] = blend;
      73           7 :   }
      74             : 
      75             :   template<class DataType_, int nb_channels>
      76           1 :   DataType_ MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::get_blend(unsigned int channel) const
      77             :   {
      78           1 :     return blend[channel];
      79             :   }
      80             : 
      81             :   template<class DataType_, int nb_channels>
      82          11 :   void MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::set_feedback(unsigned int from_channel, unsigned int to_channel, DataType_ feedback)
      83             :   {
      84          11 :     if (std::abs(feedback) >= 1)
      85             :     {
      86           2 :       throw ATK::RuntimeError("Feedback must be between -1 and 1 to avoid divergence");
      87             :     }
      88           9 :     this->feedback[from_channel * nb_channels + to_channel] = feedback;
      89           9 :   }
      90             : 
      91             :   template<class DataType_, int nb_channels>
      92           1 :   DataType_ MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::get_feedback(unsigned int from_channel, unsigned int to_channel) const
      93             :   {
      94           1 :     return feedback[from_channel * nb_channels + to_channel];
      95             :   }
      96             : 
      97             :   template<class DataType_, int nb_channels>
      98          15 :   void MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::set_feedforward(unsigned int from_channel, unsigned int to_channel, DataType_ feedforward)
      99             :   {
     100          15 :     this->feedforward[from_channel * nb_channels + to_channel] = feedforward;
     101          15 :   }
     102             : 
     103             :   template<class DataType_, int nb_channels>
     104           1 :   DataType_ MultipleUniversalFixedDelayLineFilter<DataType_, nb_channels>::get_feedforward(unsigned int from_channel, unsigned int to_channel) const
     105             :   {
     106           1 :     return feedforward[from_channel * nb_channels + to_channel];
     107             :   }
     108             : 
     109             :   template<class DataType, int nb_channels>
     110          11 :   void MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::full_setup()
     111             :   {
     112             :     // reset the delay line
     113          33 :     for (int channel = 0; channel < nb_channels; ++channel)
     114             :     {
     115          22 :       impl->processed_input[channel].assign(max_delay, 0);
     116             :     }
     117          11 :   }
     118             : 
     119             :   template<class DataType, int nb_channels>
     120        2127 :   void MultipleUniversalFixedDelayLineFilter<DataType, nb_channels>::process_impl(gsl::index size) const
     121             :   {
     122     1411590 :     for (gsl::index i = 0; i < size; ++i)
     123             :     {
     124     4228400 :       ATK_VECTORIZE for (gsl::index channel = 0; channel < nb_channels; ++channel)
     125             :       {
     126     2818930 :         auto j = impl->index - static_cast<int64_t>(delay[channel]);
     127     2818930 :         if (j < 0)
     128             :         {
     129     1767510 :           j += max_delay;
     130             :         }
     131     2818930 :         outputs[nb_channels + channel][i] = impl->processed_input[channel][j];
     132             :       }
     133     4228400 :       ATK_VECTORIZE for (gsl::index to_channel = 0; to_channel < nb_channels; ++to_channel)
     134             :       {
     135     2818930 :         impl->processed_input[to_channel][impl->index] = converted_inputs[to_channel][i];
     136     8456800 :         ATK_VECTORIZE for (gsl::index from_channel = 0; from_channel < nb_channels; ++from_channel)
     137             :         {
     138     5637860 :           impl->processed_input[to_channel][impl->index] += feedback[from_channel * nb_channels + to_channel] * outputs[nb_channels + from_channel][i];
     139             :         }
     140             :       }
     141     4228400 :       ATK_VECTORIZE for (gsl::index to_channel = 0; to_channel < nb_channels; ++to_channel)
     142             :       {
     143     2818930 :         outputs[to_channel][i] = blend[to_channel] * impl->processed_input[to_channel][impl->index];
     144     8456800 :         ATK_VECTORIZE for (gsl::index from_channel = 0; from_channel < nb_channels; ++from_channel)
     145             :         {
     146     5637860 :           outputs[to_channel][i] += feedforward[from_channel * nb_channels + to_channel] * outputs[nb_channels + from_channel][i];
     147             :         }
     148             :       }
     149     1409470 :       ++impl->index;
     150     1409470 :       if (impl->index == max_delay)
     151             :       {
     152       12890 :         impl->index = 0;
     153             :       }
     154             :     }
     155        2127 :   }
     156             : 
     157             :   template class MultipleUniversalFixedDelayLineFilter<double, 2>;
     158             :   template class MultipleUniversalFixedDelayLineFilter<double, 4>;
     159             :   template class MultipleUniversalFixedDelayLineFilter<double, 8>;
     160             : 
     161             : #if ATK_ENABLE_INSTANTIATION
     162             :   template class MultipleUniversalFixedDelayLineFilter<float, 2>;
     163             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<float>, 2>;
     164             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<double>, 2>;
     165             : 
     166             :   template class MultipleUniversalFixedDelayLineFilter<float, 4>;
     167             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<float>, 4>;
     168             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<double>, 4>;
     169             : 
     170             :   template class MultipleUniversalFixedDelayLineFilter<float, 8>;
     171             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<float>, 8>;
     172             :   template class MultipleUniversalFixedDelayLineFilter<std::complex<double>, 8>;
     173             : #endif
     174             : }

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