biquad.cpp (6081B)
1 /** 2 * KFR (https://www.kfrlib.com) 3 * Copyright (C) 2016-2023 Dan Cazarin 4 * See LICENSE.txt for details 5 */ 6 7 #include <kfr/base/reduce.hpp> 8 #include <kfr/base/simd_expressions.hpp> 9 #include <kfr/base/univector.hpp> 10 #include <kfr/dsp/biquad.hpp> 11 #include <kfr/dsp/biquad_design.hpp> 12 #include <kfr/dsp/special.hpp> 13 14 CMT_PRAGMA_MSVC(warning(push)) 15 CMT_PRAGMA_MSVC(warning(disable : 4305)) 16 17 namespace kfr 18 { 19 inline namespace CMT_ARCH_NAME 20 { 21 22 template <typename T, typename... Ts, univector_tag Tag> 23 inline const univector<T, Tag>& choose_array(const univector<T, Tag>& array, const univector<Ts, Tag>&...) 24 { 25 return array; 26 } 27 28 template <typename T, typename T2, typename... Ts, univector_tag Tag, KFR_ENABLE_IF(!std::is_same_v<T, T2>)> 29 inline const univector<T, Tag>& choose_array(const univector<T2, Tag>&, const univector<Ts, Tag>&... arrays) 30 { 31 return choose_array<T>(arrays...); 32 } 33 34 TEST(biquad_lowpass1) 35 { 36 testo::matrix(named("type") = ctypes_t<float, double>{}, 37 [](auto type) 38 { 39 using T = typename decltype(type)::type; 40 41 const biquad_section<T> bq = biquad_lowpass<T>(0.1, 0.7); 42 43 constexpr size_t size = 32; 44 45 const univector<float, size> test_vector_f32{ 46 +0x8.9bce2p-7, +0xd.8383ep-6, +0x8.f908dp-5, +0xe.edc21p-6, +0x9.ae104p-6, 47 +0x9.dcc24p-7, +0xd.50584p-9, -0xf.2668p-13, -0xd.09ca1p-10, -0xe.15995p-10, 48 -0xa.b90d2p-10, -0xc.edea4p-11, -0xb.f14eap-12, -0xc.2cb44p-14, +0xb.4a4dep-15, 49 +0xb.685dap-14, +0xa.b181fp-14, +0xf.0cb2bp-15, +0x8.695d6p-15, +0xd.bedd4p-17, 50 +0xf.5474p-20, -0xd.bb266p-19, -0x9.63ca1p-18, -0xf.ca567p-19, -0xa.5231p-19, 51 -0xa.9e934p-20, -0xe.ab52p-22, +0xa.3c4cp-26, +0xd.721ffp-23, +0xe.ccc1ap-23, 52 +0xb.5f248p-23, +0xd.d2c9ap-24, 53 }; 54 55 const univector<double, size> test_vector_f64{ 56 +0x8.9bce2bf3663e8p-7, +0xd.8384010fdf1dp-6, +0x8.f908e7a36df6p-5, 57 +0xe.edc2332a6d0bp-6, +0x9.ae104af1da9ap-6, +0x9.dcc235ef68e7p-7, 58 +0xd.5057ee425e05p-9, -0xf.266e42a99aep-13, -0xd.09cad73642208p-10, 59 -0xe.1599f32a83dp-10, -0xa.b90d8910a117p-10, -0xc.edeaabb890948p-11, 60 -0xb.f14edbb55383p-12, -0xc.2cb39b86f2dap-14, +0xb.4a506ecff055p-15, 61 +0xb.685edfdb55358p-14, +0xa.b182e32f8e298p-14, +0xf.0cb3dfd894b2p-15, 62 +0x8.695df725b4438p-15, +0xd.beddc3606b9p-17, +0xf.547004d20874p-20, 63 -0xd.bb29b25b49b6p-19, -0x9.63cb9187da1dp-18, -0xf.ca588634fc618p-19, 64 -0xa.52322d320da78p-19, -0xa.9e9420154e4p-20, -0xe.ab51f7b0335ap-22, 65 +0xa.3c6479980e1p-26, +0xd.7223836599fp-23, +0xe.ccc47ddd18678p-23, 66 +0xb.5f265b1be1728p-23, +0xd.d2cb83f8483f8p-24, 67 }; 68 69 const univector<T, size> ir = iir(unitimpulse<T>(), iir_params{ bq }); 70 71 CHECK(absmaxof(choose_array<T>(test_vector_f32, test_vector_f64) - ir) == 0); 72 }); 73 } 74 75 TEST(biquad_lowpass2) 76 { 77 testo::matrix(named("type") = ctypes_t<float, double>{}, 78 [](auto type) 79 { 80 using T = typename decltype(type)::type; 81 82 const biquad_section<T> bq = biquad_lowpass<T>(0.45, 0.2); 83 84 constexpr size_t size = 32; 85 86 const univector<float, size> test_vector_f32{ 87 +0x8.ce416p-4, +0x8.2979p-4, -0x8.a9d04p-7, +0xe.aeb3p-11, +0x8.204f8p-13, 88 -0x8.20d78p-12, +0x8.3379p-12, -0xf.83d81p-13, +0xe.8b5c4p-13, -0xd.9ddadp-13, 89 +0xc.bedfcp-13, -0xb.ee123p-13, +0xb.2a9e5p-13, -0xa.73ac4p-13, +0x9.c86f6p-13, 90 -0x9.2828p-13, +0x8.92229p-13, -0x8.05b7p-13, +0xf.048ffp-14, -0xe.0e849p-14, 91 +0xd.28384p-14, -0xc.50a9p-14, +0xb.86e56p-14, -0xa.ca0b6p-14, +0xa.19476p-14, 92 -0x9.73d38p-14, +0x8.d8f64p-14, -0x8.48024p-14, +0xf.80aa2p-15, -0xe.82ad8p-15, 93 +0xd.94f22p-15, -0xc.b66d9p-15, 94 }; 95 96 const univector<double, size> test_vector_f64{ 97 +0x8.ce416c0d31e88p-4, +0x8.2978efe51dafp-4, -0x8.a9d088b81da6p-7, 98 +0xe.aeb56c029358p-11, +0x8.20492639873ap-13, -0x8.20d4e21aab538p-12, 99 +0x8.3376b2d53b4a8p-12, -0xf.83d3d1c17343p-13, +0xe.8b584f0dd5ac8p-13, 100 -0xd.9dd740ceaacf8p-13, +0xc.bedc85e7a621p-13, -0xb.ee0f472bf8968p-13, 101 +0xb.2a9baed1fe6cp-13, -0xa.73a9d1670f4ep-13, +0x9.c86d29d297798p-13, 102 -0x9.2825f4d894088p-13, +0x8.9220a956d651p-13, -0x8.05b539fdd79e8p-13, 103 +0xf.048cb5194cfa8p-14, -0xe.0e819fa128938p-14, +0xd.2835957d684cp-14, 104 -0xc.50a69c2a8dc18p-14, +0xb.86e33bbaf3cbp-14, -0xa.ca097058af2cp-14, 105 +0xa.1945ad1703dcp-14, -0x9.73d1eef7d8b68p-14, +0x8.d8f4df1bb3efp-14, 106 -0x8.48010323c6f7p-14, +0xf.80a7f5baeeb2p-15, -0xe.82ab94bb68a8p-15, 107 +0xd.94f05f80af008p-15, -0xc.b66c0799b21a8p-15, 108 }; 109 110 const univector<T, size> ir = iir(unitimpulse<T>(), iir_params{ bq }); 111 112 CHECK(absmaxof(choose_array<T>(test_vector_f32, test_vector_f64) - ir) == 0); 113 }); 114 } 115 116 TEST(iir_filter) 117 { 118 biquad_section<float> params[16]; 119 auto f = iir_filter<float>(iir_params{ params }); 120 float buf[256]; 121 f.apply(buf); 122 } 123 } // namespace CMT_ARCH_NAME 124 } // namespace kfr 125 126 CMT_PRAGMA_MSVC(warning(pop))