Line data Source code
1 : /** 2 : * \file PanFilter.cpp 3 : */ 4 : 5 : #include "PanFilter.h" 6 : #include <ATK/Core/TypeTraits.h> 7 : 8 : #include <boost/math/constants/constants.hpp> 9 : 10 : #include <cmath> 11 : #include <complex> 12 : #include <cstdint> 13 : 14 : namespace ATK 15 : { 16 : template<typename DataType_> 17 40 : PanFilter<DataType_>::PanFilter(gsl::index nb_channels) 18 40 : :Parent(nb_channels, 2 * nb_channels) 19 : { 20 40 : } 21 : 22 : template<typename DataType_> 23 31 : void PanFilter<DataType_>::set_pan_law(PAN_LAWS law) 24 : { 25 31 : this->law = law; 26 31 : } 27 : 28 : template<typename DataType_> 29 1 : typename PanFilter<DataType_>::PAN_LAWS PanFilter<DataType_>::get_pan_law() const 30 : { 31 1 : return law; 32 : } 33 : 34 : template<typename DataType_> 35 27 : void PanFilter<DataType_>::set_pan(double pan) 36 : { 37 27 : if(pan < -1 || pan > 1) 38 : { 39 2 : throw std::out_of_range("Pan must be a value between -1 and 1"); 40 : } 41 25 : this->pan = pan; 42 25 : } 43 : 44 : template<typename DataType_> 45 1 : double PanFilter<DataType_>::get_pan() const 46 : { 47 1 : return pan; 48 : } 49 : 50 : template<typename DataType_> 51 36 : void PanFilter<DataType_>::process_impl(gsl::index size) const 52 : { 53 36 : double left_coeff{1}; 54 36 : double right_coeff{1}; 55 : 56 36 : switch(law) 57 : { 58 6 : case PAN_LAWS::SINCOS_0_CENTER: 59 6 : left_coeff = std::sqrt(2) * std::cos((pan + 1) / 4 * boost::math::constants::pi<double>()); 60 6 : right_coeff = std::sqrt(2) * std::sin((pan + 1) / 4 * boost::math::constants::pi<double>()); 61 6 : break; 62 6 : case PAN_LAWS::SINCOS_3_CENTER: 63 6 : left_coeff = std::cos((pan + 1) / 4 * boost::math::constants::pi<double>()); 64 6 : right_coeff = std::sin((pan + 1) / 4 * boost::math::constants::pi<double>()); 65 6 : break; 66 6 : case PAN_LAWS::SQUARE_0_CENTER: 67 6 : left_coeff = std::sqrt(2) * std::sqrt((1 - pan) / 2); 68 6 : right_coeff = std::sqrt(2) * std::sqrt((1 + pan) / 2); 69 6 : break; 70 6 : case PAN_LAWS::SQUARE_3_CENTER: 71 6 : left_coeff = std::sqrt((1 - pan) / 2); 72 6 : right_coeff = std::sqrt((1 + pan) / 2); 73 6 : break; 74 6 : case PAN_LAWS::LINEAR_TAPER: 75 6 : left_coeff = (1 - pan) / 2; 76 6 : right_coeff = (1 + pan) / 2; 77 6 : break; 78 6 : case PAN_LAWS::BALANCE: 79 6 : left_coeff = pan < 0 ? 1 : 1 - pan; 80 6 : right_coeff = pan > 0 ? 1 : 1 + pan; 81 6 : break; 82 : } 83 : 84 36 : assert(2 * nb_input_ports == nb_output_ports); 85 : 86 72 : for (gsl::index channel = 0; channel < nb_input_ports; ++channel) 87 : { 88 36 : const DataType* ATK_RESTRICT input = converted_inputs[channel]; 89 36 : DataType* ATK_RESTRICT output0 = outputs[2 * channel]; 90 36 : DataType* ATK_RESTRICT output1 = outputs[2 * channel + 1]; 91 36900 : for(gsl::index i = 0; i < size; ++i) 92 : { 93 36864 : output0[i] = static_cast<DataType>(static_cast<typename TypeTraits<DataType>::Scalar>(left_coeff) * input[i]); 94 36864 : output1[i] = static_cast<DataType>(static_cast<typename TypeTraits<DataType>::Scalar>(right_coeff) * input[i]); 95 : } 96 : } 97 36 : } 98 : 99 : #if ATK_ENABLE_INSTANTIATION 100 : template class PanFilter<std::int16_t>; 101 : template class PanFilter<std::int32_t>; 102 : template class PanFilter<std::int64_t>; 103 : template class PanFilter<float>; 104 : template class PanFilter<std::complex<float>>; 105 : template class PanFilter<std::complex<double>>; 106 : #endif 107 : template class PanFilter<double>; 108 : }