Line data Source code
1 : /** 2 : * \file TimeVaryingSecondOrderFilter.cpp 3 : * @see http://abvolt.com/research/publications2.htm 4 : * @see http://www.music.mcgill.ca/~ich/classes/FiltersChap2.pdf for the allpass filter 5 : */ 6 : 7 : #include "TimeVaryingSecondOrderFilter.h" 8 : #include <ATK/EQ/TimeVaryingIIRFilter.h> 9 : 10 : #include <boost/math/constants/constants.hpp> 11 : 12 : #include <cassert> 13 : #include <cmath> 14 : 15 : namespace ATK 16 : { 17 : /// Time varying coefficient base class. Two input ports, the first is the data, the second one is the central frequency 18 : template <typename DataType> 19 49 : TimeVaryingBaseSecondOrderCoefficients<DataType>::TimeVaryingBaseSecondOrderCoefficients() 20 49 : :Parent(2, 1) 21 : { 22 49 : } 23 : 24 : template <typename DataType> 25 173 : void TimeVaryingBaseSecondOrderCoefficients<DataType>::setup() 26 : { 27 173 : Parent::setup(); 28 : 29 173 : coefficients_in.clear(); 30 173 : coefficients_in.reserve((in_order+1) * number_of_steps); 31 173 : coefficients_out.clear(); 32 173 : coefficients_out.reserve(out_order * number_of_steps); 33 173 : } 34 : 35 : template <typename DataType> 36 30 : void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_min_frequency(double min_frequency) 37 : { 38 30 : if(min_frequency <= 0) 39 : { 40 1 : throw std::out_of_range("Min frequency must be positive"); 41 : } 42 29 : this->min_frequency = min_frequency; 43 29 : setup(); 44 29 : } 45 : 46 : template <typename DataType> 47 1 : double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_min_frequency() const 48 : { 49 1 : return min_frequency; 50 : } 51 : 52 : template <typename DataType> 53 30 : void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_max_frequency(double max_frequency) 54 : { 55 30 : if(max_frequency <= min_frequency) 56 : { 57 1 : throw std::out_of_range("Max frequency must be greater than min frequency"); 58 : } 59 29 : this->max_frequency = max_frequency; 60 29 : setup(); 61 29 : } 62 : 63 : template <typename DataType> 64 1 : double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_max_frequency() const 65 : { 66 1 : return max_frequency; 67 : } 68 : 69 : template <typename DataType> 70 30 : void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_number_of_steps(int number_of_steps) 71 : { 72 30 : if(number_of_steps <= 0) 73 : { 74 1 : throw std::out_of_range("Number of steps must be strictly positive"); 75 : } 76 29 : this->number_of_steps = number_of_steps; 77 29 : setup(); 78 29 : } 79 : 80 : template <typename DataType> 81 1 : int TimeVaryingBaseSecondOrderCoefficients<DataType>::get_number_of_steps() const 82 : { 83 1 : return number_of_steps; 84 : } 85 : 86 : template <typename DataType> 87 3 : void TimeVaryingBaseSecondOrderCoefficients<DataType>::set_memory(double memory) 88 : { 89 3 : if(memory < 0 || memory >= 1) 90 : { 91 2 : throw std::out_of_range("Memory for time varying EQ had to be in the range [0, 1["); 92 : } 93 1 : this->memory = memory; 94 1 : } 95 : 96 : template <typename DataType> 97 1 : double TimeVaryingBaseSecondOrderCoefficients<DataType>::get_memory() const 98 : { 99 1 : return memory; 100 : } 101 : 102 : template<typename DataType> 103 14 : TimeVaryingBandPassCoefficients<DataType>::TimeVaryingBandPassCoefficients() 104 14 : :Parent() 105 : { 106 14 : } 107 : 108 : template <typename DataType> 109 22 : void TimeVaryingBandPassCoefficients<DataType>::setup() 110 : { 111 22 : Parent::setup(); 112 : 113 36005 : for(gsl::index i = 0; i < number_of_steps; ++i) 114 : { 115 35983 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 116 35983 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 117 35983 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c); 118 35983 : DataType Q_inv = 1 / Q; 119 : 120 35983 : coefficients_in.push_back(-Q_inv * c / d); 121 35983 : coefficients_in.push_back(0); 122 35983 : coefficients_in.push_back(Q_inv * c / d); 123 35983 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 124 35983 : coefficients_out.push_back(- 2 * (c * c - 1) / d); 125 : } 126 22 : } 127 : 128 : template <typename DataType_> 129 5 : void TimeVaryingBandPassCoefficients<DataType_>::set_Q(DataType_ Q) 130 : { 131 5 : if(Q <= 0) 132 : { 133 1 : throw std::out_of_range("Q must be strictly positive"); 134 : } 135 4 : this->Q = Q; 136 4 : setup(); 137 4 : } 138 : 139 : template <typename DataType_> 140 1 : DataType_ TimeVaryingBandPassCoefficients<DataType_>::get_Q() const 141 : { 142 1 : return Q; 143 : } 144 : 145 : template<typename DataType> 146 4 : TimeVaryingLowPassCoefficients<DataType>::TimeVaryingLowPassCoefficients() 147 4 : :Parent() 148 : { 149 4 : } 150 : 151 : template <typename DataType> 152 20 : void TimeVaryingLowPassCoefficients<DataType>::setup() 153 : { 154 20 : Parent::setup(); 155 : 156 47784 : for(gsl::index i = 0; i < number_of_steps; ++i) 157 : { 158 47764 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 159 47764 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 160 47764 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c); 161 : 162 47764 : coefficients_in.push_back(c * c / d); 163 47764 : coefficients_in.push_back(2 * c * c / d); 164 47764 : coefficients_in.push_back(c * c / d); 165 47764 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 166 47764 : coefficients_out.push_back(- 2 * (c * c - 1) / d); 167 : } 168 20 : } 169 : 170 : template<typename DataType> 171 3 : TimeVaryingHighPassCoefficients<DataType>::TimeVaryingHighPassCoefficients() 172 3 : :Parent() 173 : { 174 3 : } 175 : 176 : template <typename DataType> 177 15 : void TimeVaryingHighPassCoefficients<DataType>::setup() 178 : { 179 15 : Parent::setup(); 180 : 181 35838 : for(gsl::index i = 0; i < number_of_steps; ++i) 182 : { 183 35823 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 184 35823 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 185 35823 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c); 186 : 187 35823 : coefficients_in.push_back(1); 188 35823 : coefficients_in.push_back(-2); 189 35823 : coefficients_in.push_back(1); 190 35823 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 191 35823 : coefficients_out.push_back(- 2 * (c * c - 1) / d); 192 : } 193 15 : } 194 : 195 : template<typename DataType> 196 7 : TimeVaryingBandPassPeakCoefficients<DataType>::TimeVaryingBandPassPeakCoefficients() 197 7 : :Parent() 198 : { 199 7 : } 200 : 201 : template <typename DataType> 202 23 : void TimeVaryingBandPassPeakCoefficients<DataType>::setup() 203 : { 204 23 : Parent::setup(); 205 : 206 35926 : for(gsl::index i = 0; i < number_of_steps; ++i) 207 : { 208 35903 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 209 35903 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 210 35903 : DataType Q_inv = 1 / Q; 211 35903 : if(gain <= 1) 212 : { 213 110 : DataType V0 = 1 / gain; 214 110 : DataType d = 1 + V0 * Q_inv * c + c * c; 215 : 216 110 : coefficients_in.push_back((1 - Q_inv * c + c * c) / d); 217 110 : coefficients_in.push_back(2 * (c * c - 1) / d); 218 110 : coefficients_in.push_back((1 + Q_inv * c + c * c) / d); 219 110 : coefficients_out.push_back(-(1 - V0 * Q_inv * c + c * c) / d); 220 110 : coefficients_out.push_back(-2 * (c * c - 1) / d); 221 : } 222 : else 223 : { 224 35793 : DataType V0 = gain; 225 35793 : DataType d = 1 + Q_inv * c + c * c; 226 : 227 35793 : coefficients_in.push_back((1 - V0 * Q_inv * c + c * c) / d); 228 35793 : coefficients_in.push_back(2 * (c * c - 1) / d); 229 35793 : coefficients_in.push_back((1 + V0 * Q_inv * c + c * c) / d); 230 35793 : coefficients_out.push_back(-(1 - Q_inv * c + c * c) / d); 231 35793 : coefficients_out.push_back(-2 * (c * c - 1) / d); 232 : } 233 : } 234 23 : } 235 : 236 : template <typename DataType_> 237 5 : void TimeVaryingBandPassPeakCoefficients<DataType_>::set_Q(DataType_ Q) 238 : { 239 5 : if(Q <= 0) 240 : { 241 1 : throw std::out_of_range("Q must be strictly positive"); 242 : } 243 4 : this->Q = Q; 244 4 : setup(); 245 4 : } 246 : 247 : template <typename DataType_> 248 1 : DataType_ TimeVaryingBandPassPeakCoefficients<DataType_>::get_Q() const 249 : { 250 1 : return Q; 251 : } 252 : 253 : template <typename DataType_> 254 5 : void TimeVaryingBandPassPeakCoefficients<DataType_>::set_gain(DataType_ gain) 255 : { 256 5 : if(gain <= 0) 257 : { 258 1 : throw std::out_of_range("Gain must be strictly positive"); 259 : } 260 4 : this->gain = gain; 261 4 : setup(); 262 4 : } 263 : 264 : template <typename DataType_> 265 1 : DataType_ TimeVaryingBandPassPeakCoefficients<DataType_>::get_gain() const 266 : { 267 1 : return gain; 268 : } 269 : 270 : template<typename DataType> 271 5 : TimeVaryingAllPassCoefficients<DataType>::TimeVaryingAllPassCoefficients() 272 5 : :Parent() 273 : { 274 5 : } 275 : 276 : template <typename DataType> 277 19 : void TimeVaryingAllPassCoefficients<DataType>::setup() 278 : { 279 19 : Parent::setup(); 280 : 281 35882 : for(gsl::index i = 0; i < number_of_steps; ++i) 282 : { 283 35863 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 284 35863 : DataType c = std::tan(boost::math::constants::pi<DataType>() * Q); 285 35863 : DataType d = -std::cos(2 * boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 286 : 287 35863 : coefficients_in.push_back(1); 288 35863 : coefficients_in.push_back(d * (1 - c)); 289 35863 : coefficients_in.push_back(-c); 290 35863 : coefficients_out.push_back(c); 291 35863 : coefficients_out.push_back(-d * (1 - c)); 292 : } 293 19 : } 294 : 295 : template <typename DataType_> 296 5 : void TimeVaryingAllPassCoefficients<DataType_>::set_Q(DataType_ Q) 297 : { 298 5 : if(Q <= 0) 299 : { 300 1 : throw std::out_of_range("Q must be strictly positive"); 301 : } 302 4 : this->Q = Q; 303 4 : setup(); 304 4 : } 305 : 306 : template <typename DataType_> 307 1 : DataType_ TimeVaryingAllPassCoefficients<DataType_>::get_Q() const 308 : { 309 1 : return Q; 310 : } 311 : 312 : template<typename DataType> 313 8 : TimeVaryingLowShelvingCoefficients<DataType>::TimeVaryingLowShelvingCoefficients() 314 8 : :Parent() 315 : { 316 8 : } 317 : 318 : template <typename DataType> 319 37 : void TimeVaryingLowShelvingCoefficients<DataType>::setup() 320 : { 321 37 : Parent::setup(); 322 : 323 71753 : for(gsl::index i = 0; i < number_of_steps; ++i) 324 : { 325 71716 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 326 71716 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 327 71716 : if(gain <= 1) 328 : { 329 35923 : DataType V0 = 1 / gain; 330 35923 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.) * V0) * c + V0 * c * c); 331 : 332 35923 : coefficients_in.push_back((1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 333 35923 : coefficients_in.push_back(2 * (c * c - 1) / d); 334 35923 : coefficients_in.push_back((1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 335 35923 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.) * V0) * c + V0 * c * c) / d); 336 35923 : coefficients_out.push_back(- 2 * (V0 * c * c - 1) / d); 337 : } 338 : else 339 : { 340 35793 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c); 341 : 342 35793 : coefficients_in.push_back((1 - std::sqrt(static_cast<DataType>(2.) * gain) * c + gain * c * c) / d); 343 35793 : coefficients_in.push_back(2 * (gain * c * c - 1) / d); 344 35793 : coefficients_in.push_back((1 + std::sqrt(static_cast<DataType>(2.) * gain) * c + gain * c * c) / d); 345 35793 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.)) * c + c * c) / d); 346 35793 : coefficients_out.push_back(- 2 * (c * c - 1) / d); 347 : } 348 : } 349 37 : } 350 : 351 : template <typename DataType_> 352 8 : void TimeVaryingLowShelvingCoefficients<DataType_>::set_gain(DataType_ gain) 353 : { 354 8 : if(gain <= 0) 355 : { 356 1 : throw std::out_of_range("Gain must be strictly positive"); 357 : } 358 7 : this->gain = gain; 359 7 : setup(); 360 7 : } 361 : 362 : template <typename DataType_> 363 1 : DataType_ TimeVaryingLowShelvingCoefficients<DataType_>::get_gain() const 364 : { 365 1 : return gain; 366 : } 367 : 368 : template<typename DataType> 369 8 : TimeVaryingHighShelvingCoefficients<DataType>::TimeVaryingHighShelvingCoefficients() 370 8 : :Parent() 371 : { 372 8 : } 373 : 374 : template <typename DataType> 375 37 : void TimeVaryingHighShelvingCoefficients<DataType>::setup() 376 : { 377 37 : Parent::setup(); 378 : 379 71753 : for(gsl::index i = 0; i < number_of_steps; ++i) 380 : { 381 71716 : DataType cut_frequency = static_cast<DataType>((max_frequency - min_frequency) * i / (number_of_steps - 1) + min_frequency); 382 71716 : DataType c = std::tan(boost::math::constants::pi<DataType>() * cut_frequency / input_sampling_rate); 383 71716 : if(gain <= 1) 384 : { 385 35923 : DataType V0 = 1 / gain; 386 35923 : DataType d = (V0 + std::sqrt(static_cast<DataType>(2.) * V0) * c + c * c); 387 : 388 35923 : coefficients_in.push_back(-(1 - std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d); 389 35923 : coefficients_in.push_back(-2 * (c * c - 1) / d); 390 35923 : coefficients_in.push_back(-(1 + std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d); 391 35923 : coefficients_out.push_back(- (V0 - std::sqrt(static_cast<DataType>(2.0) * V0) * c + c * c) / d); 392 35923 : coefficients_out.push_back(- 2 * (c * c - V0) / d); 393 : } 394 : else 395 : { 396 35793 : DataType d = (1 + std::sqrt(static_cast<DataType>(2.)) * c + c * c); 397 : 398 35793 : coefficients_in.push_back(-(gain - std::sqrt(static_cast<DataType>(2.0) * gain) * c + c * c) / d); 399 35793 : coefficients_in.push_back(-2 * (c * c - gain) / d); 400 35793 : coefficients_in.push_back(-(gain + std::sqrt(static_cast<DataType>(2.0) * gain) * c + c * c) / d); 401 35793 : coefficients_out.push_back(- (1 - std::sqrt(static_cast<DataType>(2.0)) * c + c * c) / d); 402 35793 : coefficients_out.push_back(- 2 * (c * c - 1) / d); 403 : } 404 : } 405 37 : } 406 : 407 : template<typename DataType_> 408 8 : void TimeVaryingHighShelvingCoefficients<DataType_>::set_gain(DataType_ gain) 409 : { 410 8 : if(gain <= 0) 411 : { 412 1 : throw std::out_of_range("Gain must be strictly positive"); 413 : } 414 7 : this->gain = gain; 415 7 : setup(); 416 7 : } 417 : 418 : template <typename DataType_> 419 1 : DataType_ TimeVaryingHighShelvingCoefficients<DataType_>::get_gain() const 420 : { 421 1 : return gain; 422 : } 423 : 424 : #if ATK_ENABLE_INSTANTIATION 425 : template class TimeVaryingBaseSecondOrderCoefficients<float>; 426 : 427 : template class ATK_EQ_EXPORT TimeVaryingBandPassCoefficients<float>; 428 : template class ATK_EQ_EXPORT TimeVaryingLowPassCoefficients<float>; 429 : template class ATK_EQ_EXPORT TimeVaryingHighPassCoefficients<float>; 430 : template class ATK_EQ_EXPORT TimeVaryingBandPassPeakCoefficients<float>; 431 : template class ATK_EQ_EXPORT TimeVaryingAllPassCoefficients<float>; 432 : template class ATK_EQ_EXPORT TimeVaryingLowShelvingCoefficients<float>; 433 : template class ATK_EQ_EXPORT TimeVaryingHighShelvingCoefficients<float>; 434 : #endif 435 : template class TimeVaryingBaseSecondOrderCoefficients<double>; 436 : 437 : template class ATK_EQ_EXPORT TimeVaryingBandPassCoefficients<double>; 438 : template class ATK_EQ_EXPORT TimeVaryingLowPassCoefficients<double>; 439 : template class ATK_EQ_EXPORT TimeVaryingHighPassCoefficients<double>; 440 : template class ATK_EQ_EXPORT TimeVaryingBandPassPeakCoefficients<double>; 441 : template class ATK_EQ_EXPORT TimeVaryingAllPassCoefficients<double>; 442 : template class ATK_EQ_EXPORT TimeVaryingLowShelvingCoefficients<double>; 443 : template class ATK_EQ_EXPORT TimeVaryingHighShelvingCoefficients<double>; 444 : }