Line data Source code
1 : /** 2 : * \file VariableDelayLineFilter.cpp 3 : */ 4 : 5 : #include "VariableDelayLineFilter.h" 6 : 7 : #include <cstdint> 8 : #include <cstring> 9 : #include <stdexcept> 10 : 11 : namespace ATK 12 : { 13 : template<typename DataType> 14 : class VariableDelayLineFilter<DataType>::VDLF_Impl 15 : { 16 : public: 17 : /// Delay line contains the last size elements + max_delay of the last delay line 18 : std::vector<DataType> delay_line; 19 : 20 : /// Integer portion of the delay for the last processed chunk 21 : std::vector<gsl::index> integer_delay; 22 : /// Fractional portion of the delay for the last processed chunk, used for the interpolation 23 : std::vector<DataType> fractional_delay; 24 : 25 1 : explicit VDLF_Impl(gsl::index max_delay) 26 1 : :delay_line(max_delay, 0) 27 : { 28 1 : } 29 : 30 4 : void update_delay_line(gsl::index max_delay, gsl::index size) 31 : { 32 4 : auto array_size = delay_line.size(); 33 : // Update delay line 34 80004 : ATK_VECTORIZE for (gsl::index i = 0; i < max_delay; ++i) 35 : { 36 80000 : delay_line[i] = delay_line[array_size + i - max_delay]; 37 : } 38 4 : delay_line.resize(size + max_delay); 39 : 40 4 : integer_delay.resize(size); 41 4 : fractional_delay.resize(size); 42 4 : } 43 : }; 44 : 45 : 46 : template<typename DataType_> 47 1 : VariableDelayLineFilter<DataType_>::VariableDelayLineFilter(gsl::index max_delay) 48 1 : :Parent(2, 1), impl(std::make_unique<VDLF_Impl>(max_delay)), max_delay(max_delay) 49 : { 50 1 : } 51 : 52 : template<typename DataType_> 53 1 : VariableDelayLineFilter<DataType_>::~VariableDelayLineFilter() 54 : { 55 1 : } 56 : 57 : template<typename DataType_> 58 1 : void VariableDelayLineFilter<DataType_>::full_setup() 59 : { 60 : // reset the delay line 61 1 : impl->delay_line.assign(max_delay, 0); 62 1 : } 63 : 64 : template<typename DataType_> 65 4 : void VariableDelayLineFilter<DataType_>::process_impl(gsl::index size) const 66 : { 67 4 : impl->update_delay_line(max_delay, size); 68 : 69 4 : const DataType* ATK_RESTRICT input1 = converted_inputs[0]; // samples 70 4 : const DataType* ATK_RESTRICT input2 = converted_inputs[1]; // delay 71 4 : DataType* ATK_RESTRICT output = outputs[0]; 72 : 73 4 : gsl::index* ATK_RESTRICT integer_delay = impl->integer_delay.data(); 74 4 : DataType* ATK_RESTRICT fractional_delay = impl->fractional_delay.data(); 75 4 : DataType* ATK_RESTRICT delay_line = impl->delay_line.data(); 76 : 77 4 : memcpy(reinterpret_cast<void*>(delay_line + max_delay), reinterpret_cast<const void*>(input1), size * sizeof(DataType)); 78 : 79 65540 : ATK_VECTORIZE for(gsl::index i = 0; i < size; ++i) 80 : { 81 65536 : auto rounded = static_cast<gsl::index>(input2[i]); 82 65536 : integer_delay[i] = rounded >= max_delay ? 0 : rounded; 83 65536 : fractional_delay[i] = input2[i] - integer_delay[i]; 84 : } 85 : 86 65540 : ATK_VECTORIZE for(gsl::index i = 0; i < size; ++i) 87 : { 88 65536 : output[i] = delay_line[i + max_delay - integer_delay[i]] * (1 - fractional_delay[i]) + delay_line[i + max_delay - integer_delay[i] - 1] * fractional_delay[i]; 89 : } 90 4 : } 91 : 92 : template class VariableDelayLineFilter<double>; 93 : #if ATK_ENABLE_INSTANTIATION 94 : template class VariableDelayLineFilter<float>; 95 : #endif 96 : }