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 : }