Line data Source code
1 : /** 2 : * \file TimeVaryingIIRFilter.h 3 : */ 4 : 5 : #ifndef ATK_EQ_TIMEVARYINGIIRFILTER_H 6 : #define ATK_EQ_TIMEVARYINGIIRFILTER_H 7 : 8 : #include <ATK/config.h> 9 : #include <ATK/EQ/config.h> 10 : 11 : #include <cassert> 12 : #include <cmath> 13 : #include <vector> 14 : 15 : namespace ATK 16 : { 17 : /// IIR filter template class for time varying frequencies. Transposed Direct Form II 18 : template<class Coefficients > 19 : class ATK_EQ_EXPORT TimeVaryingIIRFilter final : public Coefficients 20 : { 21 : public: 22 : /// Simplify parent calls 23 : using Parent = Coefficients; 24 : using typename Parent::DataType; 25 : using Parent::converted_inputs; 26 : using Parent::outputs; 27 : using Parent::coefficients_in; 28 : using Parent::coefficients_out; 29 : using Parent::input_sampling_rate; 30 : using Parent::output_sampling_rate; 31 : using Parent::nb_input_ports; 32 : using Parent::nb_output_ports; 33 : 34 : using Parent::in_order; 35 : using Parent::out_order; 36 : using Parent::input_delay; 37 : using Parent::output_delay; 38 : using Parent::setup; 39 : 40 : using Parent::min_frequency; 41 : using Parent::max_frequency; 42 : using Parent::memory; 43 : using Parent::number_of_steps; 44 : protected: 45 : mutable std::vector<DataType> current_coeffs_in; 46 : mutable std::vector<DataType> current_coeffs_out; 47 : mutable std::vector<DataType> state; 48 : public: 49 49 : TimeVaryingIIRFilter() 50 49 : :Parent() 51 : { 52 49 : } 53 : 54 173 : void setup() final 55 : { 56 173 : Parent::setup(); 57 173 : input_delay = in_order; 58 173 : output_delay = out_order; 59 173 : state.resize(std::max(input_delay, output_delay), 0); 60 173 : } 61 : 62 56 : void process_impl(gsl::index size) const final 63 : { 64 56 : assert(input_sampling_rate == output_sampling_rate); 65 : 66 56 : current_coeffs_in.resize(in_order+1, 0); 67 56 : current_coeffs_out.resize(out_order, 0); 68 : 69 56 : DataType scale = static_cast<DataType>((number_of_steps - 1) / (max_frequency - min_frequency)); 70 : 71 56 : const DataType* ATK_RESTRICT input = converted_inputs[0]; 72 56 : const DataType* ATK_RESTRICT cut_frequencies = converted_inputs[1]; 73 56 : DataType* ATK_RESTRICT output = outputs[0]; 74 3670072 : for(gsl::index i = 0; i < size; ++i) 75 : { 76 3670016 : int frequency_index = static_cast<int>((cut_frequencies[i] - min_frequency) * scale); 77 3670016 : if(frequency_index < 0) 78 : { 79 0 : frequency_index = 0; 80 : } 81 3670016 : if(frequency_index >= number_of_steps) 82 : { 83 0 : frequency_index = number_of_steps - 1; 84 : } 85 14680050 : for(gsl::index j = 0; j < in_order+1; ++j) 86 : { 87 11010060 : current_coeffs_in[j] = static_cast<DataType>(current_coeffs_in[j] * memory + coefficients_in[frequency_index * (in_order+1) + j] * (1 - memory)); 88 : } 89 11010060 : for(gsl::index j = 0; j < out_order; ++j) 90 : { 91 7340028 : current_coeffs_out[j] = static_cast<DataType>(current_coeffs_out[j] * memory + coefficients_out[frequency_index * (out_order) + j] * (1 - memory)); 92 : } 93 : 94 3670016 : output[i] = current_coeffs_in[in_order] * input[i] + state[0]; 95 7340028 : for(gsl::index j = 0; j < state.size() - 1; ++j) 96 : { 97 3670016 : state[j] = state[j + 1]; 98 : } 99 3670016 : state[state.size() - 1] = 0; 100 : 101 11010060 : for(gsl::index j = 0; j < in_order; ++j) 102 : { 103 7340028 : state[j] += input[i] * current_coeffs_in[in_order - static_cast<int64_t>(j) - 1]; 104 : } 105 11010060 : for(gsl::index j = 0; j < out_order; ++j) 106 : { 107 7340028 : state[j] += output[i] * current_coeffs_out[out_order - static_cast<int64_t>(j) - 1]; 108 : } 109 : } 110 56 : } 111 : }; 112 : 113 : } 114 : 115 : #endif