Line data Source code
1 : /** 2 : * \file ToneStackFilter.hxx 3 : */ 4 : 5 : #include "ToneStackFilter.h" 6 : 7 : #include <boost/math/tools/polynomial.hpp> 8 : 9 : namespace ATK 10 : { 11 : template<typename DataType> 12 37 : ToneStackCoefficients<DataType>::ToneStackCoefficients(gsl::index nb_channels) 13 37 : :TypedBaseFilter<DataType>(nb_channels, nb_channels) 14 : { 15 37 : } 16 : 17 : template<typename DataType> 18 31 : ToneStackCoefficients<DataType>::ToneStackCoefficients(ToneStackCoefficients&& other) 19 31 : :Parent(std::move(other)), R1(other.R1), R2(other.R2), R3(other.R3), R4(other.R4), C1(other.C1), C2(other.C2), C3(other.C3), low(other.low), middle(other.middle), high(other.high) 20 : { 21 : 22 31 : } 23 : 24 : template<typename DataType> 25 93 : void ToneStackCoefficients<DataType>::setup() 26 : { 27 93 : Parent::setup(); 28 : 29 93 : coefficients_in.assign(in_order+1, 0); 30 93 : coefficients_out.assign(out_order, 0); 31 : 32 93 : CoeffDataType tempm[2] = {static_cast<CoeffDataType>(-2) * input_sampling_rate, static_cast<CoeffDataType>(2) * input_sampling_rate}; 33 93 : CoeffDataType tempp[2] = {static_cast<CoeffDataType>(1), static_cast<CoeffDataType>(1)}; 34 186 : boost::math::tools::polynomial<CoeffDataType> poly1(tempm, 1); 35 186 : boost::math::tools::polynomial<CoeffDataType> poly2(tempp, 1); 36 : 37 186 : boost::math::tools::polynomial<CoeffDataType> b; 38 186 : boost::math::tools::polynomial<CoeffDataType> a; 39 : 40 93 : b = poly2 * poly2 * poly1 * (high*C1*R1 + middle*C3*R3 + low*(C1*R2 + C2*R2) + (C1*R3 + C2*R3)); 41 93 : b += poly2 * poly1 * poly1 * (high*(C1*C2*R1*R4 + C1*C3*R1*R4) - middle*middle*(C1*C3*R3*R3 + C2*C3*R3*R3) + middle*(C1*C3*R1*R3 + C1*C3*R3*R3 + C2*C3*R3*R3) 42 93 : + low*(C1*C2*R1*R2 + C1*C2*R2*R4 + C1*C3*R2*R4) + low*middle*(C1*C3*R2*R3 + C2*C3*R2*R3) 43 93 : + (C1*C2*R1*R3 + C1*C2*R3*R4 + C1*C3*R3*R4)); 44 93 : b += poly1 * poly1 * poly1 * (low*middle*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4) - middle*middle*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4) 45 93 : + middle*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4) + high*C1*C2*C3*R1*R3*R4 - high*middle*C1*C2*C3*R1*R3*R4 46 93 : + high*low*C1*C2*C3*R1*R2*R4); 47 : 48 93 : a = poly2 * poly2 * poly2; 49 93 : a += poly2 * poly2 * poly1 * ((C1*R1 + C1*R3 + C2*R3 + C2*R4 + C3*R4) + middle*C3*R3 + low*(C1*R2 + C2*R2)); 50 93 : a += poly2 * poly1 * poly1 * (middle*(C1*C3*R1*R3 - C2*C3*R3*R4 + C1*C3*R3*R3 + C2*C3*R3*R3) 51 93 : + low*middle*(C1*C3*R2*R3 + C2*C3*R2*R3) - middle*middle*(C1*C3*R3*R3 + C2*C3*R3*R3) + low*(C1*C2*R2*R4 + C1*C2*R1*R2 + C1*C3*R2*R4 + C2*C3*R2*R4) 52 93 : + (C1*C2*R1*R4 + C1*C3*R1*R4 + C1*C2*R3*R4 + C1*C2*R1*R3 + C1*C3*R3*R4 + C2*C3*R3*R4)); 53 93 : a += poly1 * poly1 * poly1 * (low*middle*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4) - middle*middle*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4) 54 93 : + middle*(C1*C2*C3*R3*R3*R4 + C1*C2*C3*R1*R3*R3 - C1*C2*C3*R1*R3*R4) 55 93 : + low*C1*C2*C3*R1*R2*R4 + C1*C2*C3*R1*R3*R4); 56 : 57 465 : for(gsl::index i = 0; i < in_order + 1; ++i) 58 : { 59 372 : coefficients_in[i] = b[i] / a[out_order]; 60 : } 61 372 : for(gsl::index i = 0; i < out_order; ++i) 62 : { 63 279 : coefficients_out[i] = -a[i] / a[out_order]; 64 : } 65 93 : } 66 : 67 : template<typename DataType_> 68 13 : void ToneStackCoefficients<DataType_>::set_low(CoeffDataType low) 69 : { 70 13 : if(low < 0 || low > 1) 71 : { 72 2 : throw std::out_of_range("Low is outside the interval [0,1]"); 73 : } 74 11 : this->low = low; 75 : 76 11 : setup(); 77 11 : } 78 : 79 : template<typename DataType_> 80 1 : typename ToneStackCoefficients<DataType_>::CoeffDataType ToneStackCoefficients<DataType_>::get_low() const 81 : { 82 1 : return low; 83 : } 84 : 85 : template<typename DataType_> 86 12 : void ToneStackCoefficients<DataType_>::set_middle(CoeffDataType middle) 87 : { 88 12 : if(middle < 0 || middle > 1) 89 : { 90 2 : throw std::out_of_range("Middle is outside the interval [0,1]"); 91 : } 92 10 : this->middle = middle; 93 : 94 10 : setup(); 95 10 : } 96 : 97 : template<typename DataType_> 98 1 : typename ToneStackCoefficients<DataType_>::CoeffDataType ToneStackCoefficients<DataType_>::get_middle() const 99 : { 100 1 : return middle; 101 : } 102 : 103 : 104 : template<typename DataType_> 105 12 : void ToneStackCoefficients<DataType_>::set_high(CoeffDataType high) 106 : { 107 12 : if(high < 0 || high > 1) 108 : { 109 2 : throw std::out_of_range("high is outside the interval [0,1]"); 110 : } 111 10 : this->high = high; 112 : 113 10 : setup(); 114 10 : } 115 : 116 : template<typename DataType_> 117 1 : typename ToneStackCoefficients<DataType_>::CoeffDataType ToneStackCoefficients<DataType_>::get_high() const 118 : { 119 1 : return high; 120 : } 121 : 122 : template<typename DataType> 123 30 : IIRFilter<ToneStackCoefficients<DataType> > ToneStackCoefficients<DataType>::buildBassmanStack() 124 : { 125 60 : IIRFilter<ToneStackCoefficients<DataType> > filter; 126 30 : filter.set_coefficients(static_cast<CoeffDataType>(250e3), static_cast<CoeffDataType>(1e6), static_cast<CoeffDataType>(25e3), static_cast<CoeffDataType>(45e3), 127 : static_cast<CoeffDataType>(250e-12), static_cast<CoeffDataType>(20e-9), static_cast<CoeffDataType>(20e-9)); 128 60 : return std::move(filter); 129 : } 130 : 131 : template<typename DataType> 132 1 : IIRFilter<ToneStackCoefficients<DataType> > ToneStackCoefficients<DataType>::buildJCM800Stack() 133 : { 134 2 : IIRFilter<ToneStackCoefficients<DataType> > filter; 135 1 : filter.set_coefficients(static_cast<CoeffDataType>(220e3), static_cast<CoeffDataType>(1e6), static_cast<CoeffDataType>(22e3), static_cast<CoeffDataType>(33e3), 136 : static_cast<CoeffDataType>(470e-12), static_cast<CoeffDataType>(22e-9), static_cast<CoeffDataType>(22e-9)); 137 2 : return std::move(filter); 138 : } 139 : 140 : template<typename DataType_> 141 31 : void ToneStackCoefficients<DataType_>::set_coefficients(CoeffDataType R1, CoeffDataType R2, CoeffDataType R3, CoeffDataType R4, CoeffDataType C1, CoeffDataType C2, CoeffDataType C3) 142 : { 143 31 : this->R1 = R1; 144 31 : this->R2 = R2; 145 31 : this->R3 = R3; 146 31 : this->R4 = R4; 147 31 : this->C1 = C1; 148 31 : this->C2 = C2; 149 31 : this->C3 = C3; 150 31 : } 151 : }