LCOV - code coverage report
Current view: top level - Delay - FixedDelayLineFilter.hxx (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 46 46 100.0 %
Date: 2021-02-18 20:07:22 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /**
       2             :  * \file FixedDelayLineFilter.hxx
       3             :  */
       4             : 
       5             : #include "FixedDelayLineFilter.h"
       6             : #include <ATK/Core/Utilities.h>
       7             : 
       8             : #include <cstring>
       9             : #include <stdexcept>
      10             : 
      11             : namespace ATK
      12             : {
      13             :   template<typename DataType>
      14             :   class FixedDelayLineFilter<DataType>::FDLF_Impl
      15             :   {
      16             :   public:
      17             :     typename FixedDelayLineFilter<DataType>::AlignedOutVector delay_line;
      18             :     gsl::index index{0};
      19             : 
      20           6 :     explicit FDLF_Impl(gsl::index max_delay)
      21           6 :       :delay_line(max_delay, TypeTraits<DataType>::Zero())
      22             :     {
      23           6 :     }
      24             :   };
      25             : 
      26             :   template<typename DataType_>
      27           6 :   FixedDelayLineFilter<DataType_>::FixedDelayLineFilter(gsl::index max_delay)
      28           6 :     :Parent(1, 1), impl(std::make_unique<FDLF_Impl>(max_delay))
      29             :   {
      30           6 :   }
      31             :   
      32             :   template<typename DataType_>
      33           6 :   FixedDelayLineFilter<DataType_>::~FixedDelayLineFilter()
      34             :   {
      35             :     
      36           6 :   }
      37             :   
      38             :   template<typename DataType_>
      39           6 :   void FixedDelayLineFilter<DataType_>::set_delay(gsl::index delay)
      40             :   {
      41           6 :     if(delay == 0)
      42             :     {
      43           1 :       throw ATK::RuntimeError("Delay must be strictly positive");
      44             :     }
      45           5 :     if(delay >= impl->delay_line.size())
      46             :     {
      47           1 :       throw ATK::RuntimeError("Delay must be less than delay line size");
      48             :     }
      49             : 
      50           4 :     this->delay = delay;
      51           4 :   }
      52             : 
      53             :   template<typename DataType_>
      54           1 :   gsl::index FixedDelayLineFilter<DataType_>::get_delay() const
      55             :   {
      56           1 :     return delay;
      57             :   }
      58             : 
      59             :   template<typename DataType_>
      60           3 :   void FixedDelayLineFilter<DataType_>::full_setup()
      61             :   {
      62             :     // reset the delay line
      63           3 :     impl->delay_line.assign(impl->delay_line.size(), TypeTraits<DataType>::Zero());
      64           3 :     impl->index = 0;
      65           3 :   }
      66             : 
      67             :   template<typename DataType_>
      68        1055 :   void FixedDelayLineFilter<DataType_>::process_impl(gsl::index size) const
      69             :   {
      70        1055 :     const DataType* ATK_RESTRICT input = converted_inputs[0];
      71        1055 :     DataType* ATK_RESTRICT output = outputs[0];
      72        1055 :     DataType* ATK_RESTRICT delay_line = impl->delay_line.data();
      73        1055 :     auto delay_line_size = static_cast<gsl::index>(impl->delay_line.size());
      74             : 
      75        1055 :     auto max_index1 = size > delay - impl->index ? size - (delay - impl->index) : 0;
      76        1055 :     auto max_index2 = impl->index < delay ? max_index1 : std::min(size, delay);
      77        1055 :     auto size_before_index = std::min(impl->index, max_index2);
      78        1055 :     auto size_after_index = impl->index < delay ? std::min(size, delay - impl->index) : 0;
      79             : 
      80        1055 :     memcpy(reinterpret_cast<void*>(output), reinterpret_cast<const void*>(delay_line + delay_line_size - (delay - impl->index)), static_cast<gsl::index>(size_after_index * sizeof(DataType_)));
      81        1055 :     memcpy(reinterpret_cast<void*>(output + size_after_index), reinterpret_cast<const void*>(delay_line + size_after_index + impl->index - delay), static_cast<gsl::index>(size_before_index * sizeof(DataType_)));
      82             : 
      83        1055 :     if(size > delay)
      84             :     {
      85        1000 :       memcpy(reinterpret_cast<void*>(output + delay), reinterpret_cast<const void*>(input), static_cast<gsl::index>((size - delay) * sizeof(DataType_)));
      86             :     }
      87             : 
      88        1055 :     if(size > delay_line_size)
      89             :     {
      90           1 :       impl->index = 0;
      91           1 :       memcpy(reinterpret_cast<void*>(delay_line), reinterpret_cast<const void*>(input + size - delay_line_size), delay_line_size * sizeof(DataType_));
      92             :     }
      93             :     else
      94             :     {
      95        1054 :       auto new_index = std::min(impl->index + size, delay_line_size);
      96        1054 :       auto first_size = new_index - impl->index;
      97        1054 :       memcpy(reinterpret_cast<void*>(delay_line + impl->index), reinterpret_cast<const void*>(input), first_size * sizeof(DataType_));
      98        1054 :       auto second_size = size - first_size;
      99             :       
     100        1054 :       if(impl->index + size > delay_line_size)
     101             :       {
     102         548 :         impl->index = second_size;
     103         548 :         memcpy(reinterpret_cast<void*>(delay_line), reinterpret_cast<const void*>(input + first_size), second_size * sizeof(DataType_));
     104             :       }
     105             :       else
     106             :       {
     107         506 :         impl->index = new_index;
     108             :       }
     109             :     }
     110        1055 :   }
     111             : }

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