kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

window.cpp (11633B)


      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/tensor.hpp>
     10 #include <kfr/dsp/window.hpp>
     11 #include <kfr/io/tostring.hpp>
     12 
     13 CMT_PRAGMA_MSVC(warning(push))
     14 CMT_PRAGMA_MSVC(warning(disable : 4305))
     15 CMT_PRAGMA_MSVC(warning(disable : 4244))
     16 
     17 namespace kfr
     18 {
     19 inline namespace CMT_ARCH_NAME
     20 {
     21 
     22 const char* wins[] = {
     23     "",
     24     "rectangular    ",
     25     "triangular     ",
     26     "bartlett       ",
     27     "cosine         ",
     28     "hann           ",
     29     "bartlett_hann  ",
     30     "hamming        ",
     31     "bohman         ",
     32     "blackman       ",
     33     "blackman_harris",
     34     "kaiser         ",
     35     "flattop        ",
     36     "gaussian       ",
     37     "lanczos        ",
     38     "cosine_np      ",
     39     "planck_taper   ",
     40     "tukey          ",
     41 };
     42 
     43 template <window_type type, typename T>
     44 void win(size_t len, T arg, window_symmetry sym, univector<T> ref)
     45 {
     46     univector<T> calc = render(window(len, cval_t<window_type, type>{}, arg, sym, cometa::ctype<T>));
     47     testo::scope sc(as_string("win=", wins[static_cast<int>(type)], " len=", len, " sym=",
     48                               sym == window_symmetry::symmetric, "\n    calc=", calc, "\n    ref =", ref));
     49     CHECK(rms(calc - ref) < 0.00001f);
     50 }
     51 
     52 TEST(window)
     53 {
     54     using w = window_type;
     55     using s = window_symmetry;
     56     using u = univector<f32>;
     57     // clang-format
     58     // 7 ; symmetric
     59     win<w::rectangular, f32>(7, 0.0, s::symmetric, u{ 1, 1, 1, 1, 1, 1, 1 });
     60     win<w::triangular, f32>(7, 0.0, s::symmetric, u{ 0.25, 0.5, 0.75, 1., 0.75, 0.5, 0.25 });
     61     win<w::bartlett, f32>(7, 0.0, s::symmetric,
     62                           u{ 0., 0.33333333, 0.66666667, 1., 0.66666667, 0.33333333, 0. });
     63     win<w::cosine, f32>(7, 0.0, s::symmetric, u{ 0, 0.5, 0.866025, 1, 0.866025, 0.5, 0 });
     64     win<w::hann, f32>(7, 0.0, s::symmetric, u{ 0., 0.25, 0.75, 1., 0.75, 0.25, 0. });
     65     win<w::bartlett_hann, f32>(7, 0.0, s::symmetric, u{ 0., 0.27, 0.73, 1., 0.73, 0.27, 0. });
     66     win<w::hamming, f32>(7, 0.54, s::symmetric, u{ 0.08, 0.31, 0.77, 1., 0.77, 0.31, 0.08 });
     67     win<w::bohman, f32>(7, 0.0, s::symmetric,
     68                         u{ 0., 0.10899778, 0.60899778, 1., 0.60899778, 0.10899778, 0. });
     69     win<w::blackman, f32>(7, 0.16, s::symmetric,
     70                           u{ -1.38777878e-17, 1.30000000e-01, 6.30000000e-01, 1.00000000e+00, 6.30000000e-01,
     71                              1.30000000e-01, -1.38777878e-17 });
     72     win<w::blackman_harris, f32>(
     73         7, 0.0, s::symmetric,
     74         u{ 6.00000e-05, 5.56450e-02, 5.20575e-01, 1.00000e+00, 5.20575e-01, 5.56450e-02, 6.00000e-05 });
     75     win<w::kaiser, f32>(7, 8.0, s::symmetric,
     76                         u{ 0.00233883, 0.1520107, 0.65247867, 1., 0.65247867, 0.1520107, 0.00233883 });
     77     win<w::flattop, f32>(7, 0.0, s::symmetric,
     78                          u{ -4.2105100e-04, -5.1263156e-02, 1.9821053e-01, 1.0000000e+00, 1.9821053e-01,
     79                             -5.1263156e-02, -4.2105100e-04 });
     80     win<w::gaussian, f32>(7, 2.5, s::symmetric,
     81                           u{ 0.1006689, 0.36044779, 0.77483743, 1., 0.77483743, 0.36044779, 0.1006689 });
     82     win<w::lanczos, f32>(7, 0.0, s::symmetric,
     83                          u{ -2.8e-08, 0.413497, 0.826993, 1, 0.826993, 0.413497, -2.8e-08 });
     84     win<w::cosine_np, f32>(7, 0.0, s::symmetric,
     85                            u{ 0.22252093, 0.6234898, 0.90096887, 1., 0.90096887, 0.6234898, 0.22252093 });
     86     win<w::planck_taper, f32>(7, 0.25, s::symmetric, u{ 0, 0.817575, 1, 1, 1, 0.817574, 0 });
     87     win<w::tukey, f32>(7, 0.5, s::symmetric, u{ 0., 0.75, 1., 1., 1., 0.75, 0. });
     88 
     89     // 8 ; symmetric
     90     win<w::rectangular, f32>(8, 0.0, s::symmetric, u{ 1, 1, 1, 1, 1, 1, 1, 1 });
     91     win<w::triangular, f32>(8, 0.0, s::symmetric,
     92                             u{ 0.125, 0.375, 0.625, 0.875, 0.875, 0.625, 0.375, 0.125 });
     93     win<w::bartlett, f32>(
     94         8, 0.0, s::symmetric,
     95         u{ 0., 0.28571429, 0.57142857, 0.85714286, 0.85714286, 0.57142857, 0.28571429, 0. });
     96     win<w::cosine, f32>(8, 0.0, s::symmetric,
     97                         u{ 0, 0.433884, 0.781832, 0.974928, 0.974928, 0.781831, 0.433883, 0 });
     98     win<w::hann, f32>(8, 0.0, s::symmetric,
     99                       u{ 0., 0.1882551, 0.61126047, 0.95048443, 0.95048443, 0.61126047, 0.1882551, 0. });
    100     win<w::bartlett_hann, f32>(
    101         8, 0.0, s::symmetric,
    102         u{ 0., 0.2116453, 0.60170081, 0.92808246, 0.92808246, 0.60170081, 0.2116453, 0. });
    103     win<w::hamming, f32>(
    104         8, 0.54, s::symmetric,
    105         u{ 0.08, 0.25319469, 0.64235963, 0.95444568, 0.95444568, 0.64235963, 0.25319469, 0.08 });
    106     win<w::bohman, f32>(8, 0.0, s::symmetric,
    107                         u{ 0., 0.07072475, 0.43748401, 0.91036851, 0.91036851, 0.43748401, 0.07072475, 0. });
    108     win<w::blackman, f32>(8, 0.16, s::symmetric,
    109                           u{ -1.38777878e-17, 9.04534244e-02, 4.59182958e-01, 9.20363618e-01, 9.20363618e-01,
    110                              4.59182958e-01, 9.04534244e-02, -1.38777878e-17 });
    111     win<w::blackman_harris, f32>(8, 0.0, s::symmetric,
    112                                  u{ 6.00000000e-05, 3.33917235e-02, 3.32833504e-01, 8.89369772e-01,
    113                                     8.89369772e-01, 3.32833504e-01, 3.33917235e-02, 6.00000000e-05 });
    114     win<w::kaiser, f32>(
    115         8, 8.0, s::symmetric,
    116         u{ 0.00233883, 0.10919581, 0.48711868, 0.92615774, 0.92615774, 0.48711868, 0.10919581, 0.00233883 });
    117     win<w::flattop, f32>(8, 0.0, s::symmetric,
    118                          u{ -4.21051000e-04, -3.68407812e-02, 1.07037167e-02, 7.80873915e-01, 7.80873915e-01,
    119                             1.07037167e-02, -3.68407812e-02, -4.21051000e-04 });
    120     win<w::gaussian, f32>(
    121         8, 2.5, s::symmetric,
    122         u{ 0.09139376, 0.29502266, 0.64438872, 0.9523448, 0.9523448, 0.64438872, 0.29502266, 0.09139376 });
    123     win<w::lanczos, f32>(8, 0.0, s::symmetric,
    124                          u{ -2.8e-08, 0.348411, 0.724101, 0.966766, 0.966766, 0.724101, 0.34841, -2.8e-08 });
    125     win<w::cosine_np, f32>(
    126         8, 0.0, s::symmetric,
    127         u{ 0.19509032, 0.55557023, 0.83146961, 0.98078528, 0.98078528, 0.83146961, 0.55557023, 0.19509032 });
    128     win<w::planck_taper, f32>(8, 0.25, s::symmetric, u{ 0, 0.641834, 1, 1, 1, 1, 0.641833, 0 });
    129     win<w::tukey, f32>(8, 0.5, s::symmetric, u{ 0., 0.61126047, 1., 1., 1., 1., 0.61126047, 0. });
    130 
    131     // 7 ; periodic
    132     win<w::rectangular, f32>(7, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1 });
    133     win<w::triangular, f32>(7, 0.0, s::periodic, u{ 0.125, 0.375, 0.625, 0.875, 0.875, 0.625, 0.375 });
    134     win<w::bartlett, f32>(7, 0.0, s::periodic,
    135                           u{ 0., 0.28571429, 0.57142857, 0.85714286, 0.85714286, 0.57142857, 0.28571429 });
    136     win<w::cosine, f32>(7, 0.0, s::periodic,
    137                         u{ 0, 0.433884, 0.781832, 0.974928, 0.974928, 0.781831, 0.433883 });
    138     win<w::hann, f32>(7, 0.0, s::periodic,
    139                       u{ 0., 0.1882551, 0.61126047, 0.95048443, 0.95048443, 0.61126047, 0.1882551 });
    140     win<w::bartlett_hann, f32>(7, 0.0, s::periodic,
    141                                u{ 0., 0.2116453, 0.60170081, 0.92808246, 0.92808246, 0.60170081, 0.2116453 });
    142     win<w::hamming, f32>(7, 0.54, s::periodic,
    143                          u{ 0.08, 0.25319469, 0.64235963, 0.95444568, 0.95444568, 0.64235963, 0.25319469 });
    144     win<w::bohman, f32>(7, 0.0, s::periodic,
    145                         u{ 0., 0.07072475, 0.43748401, 0.91036851, 0.91036851, 0.43748401, 0.07072475 });
    146     win<w::blackman, f32>(7, 0.16, s::periodic,
    147                           u{ -1.38777878e-17, 9.04534244e-02, 4.59182958e-01, 9.20363618e-01, 9.20363618e-01,
    148                              4.59182958e-01, 9.04534244e-02 });
    149     win<w::blackman_harris, f32>(7, 0.0, s::periodic,
    150                                  u{ 6.00000000e-05, 3.33917235e-02, 3.32833504e-01, 8.89369772e-01,
    151                                     8.89369772e-01, 3.32833504e-01, 3.33917235e-02 });
    152     win<w::kaiser, f32>(
    153         7, 8.0, s::periodic,
    154         u{ 0.00233883, 0.10919581, 0.48711868, 0.92615774, 0.92615774, 0.48711868, 0.10919581 });
    155     win<w::flattop, f32>(7, 0.0, s::periodic,
    156                          u{ -4.21051000e-04, -3.68407812e-02, 1.07037167e-02, 7.80873915e-01, 7.80873915e-01,
    157                             1.07037167e-02, -3.68407812e-02 });
    158     win<w::gaussian, f32>(
    159         7, 2.5, s::periodic,
    160         u{ 0.09139376, 0.29502266, 0.64438872, 0.9523448, 0.9523448, 0.64438872, 0.29502266 });
    161     win<w::lanczos, f32>(7, 0.0, s::periodic,
    162                          u{ -2.8e-08, 0.348411, 0.724101, 0.966766, 0.966766, 0.724101, 0.34841 });
    163     win<w::cosine_np, f32>(
    164         7, 0.0, s::periodic,
    165         u{ 0.19509032, 0.55557023, 0.83146961, 0.98078528, 0.98078528, 0.83146961, 0.55557023 });
    166     win<w::planck_taper, f32>(7, 0.25, s::periodic, u{ 0, 0.641834, 1, 1, 1, 1, 0.641833 });
    167     win<w::tukey, f32>(7, 0.5, s::periodic, u{ 0., 0.61126047, 1., 1., 1., 1., 0.61126047 });
    168 
    169     // 8 ; periodic
    170     win<w::rectangular, f32>(8, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1, 1 });
    171     win<w::triangular, f32>(8, 0.0, s::periodic, u{ 0.2, 0.4, 0.6, 0.8, 1., 0.8, 0.6, 0.4 });
    172     win<w::bartlett, f32>(8, 0.0, s::periodic, u{ 0., 0.25, 0.5, 0.75, 1., 0.75, 0.5, 0.25 });
    173     win<w::cosine, f32>(8, 0.0, s::periodic,
    174                         u{ 0, 0.382683, 0.707107, 0.92388, 1, 0.92388, 0.707107, 0.382683 });
    175     win<w::hann, f32>(8, 0.0, s::periodic,
    176                       u{ 0., 0.14644661, 0.5, 0.85355339, 1., 0.85355339, 0.5, 0.14644661 });
    177     win<w::bartlett_hann, f32>(8, 0.0, s::periodic,
    178                                u{ 0., 0.17129942, 0.5, 0.82870058, 1., 0.82870058, 0.5, 0.17129942 });
    179     win<w::hamming, f32>(8, 0.54, s::periodic,
    180                          u{ 0.08, 0.21473088, 0.54, 0.86526912, 1., 0.86526912, 0.54, 0.21473088 });
    181     win<w::bohman, f32>(8, 0.0, s::periodic,
    182                         u{ 0., 0.04830238, 0.31830989, 0.75540916, 1., 0.75540916, 0.31830989, 0.04830238 });
    183     win<w::blackman, f32>(8, 0.16, s::periodic,
    184                           u{ -1.38777878e-17, 6.64466094e-02, 3.40000000e-01, 7.73553391e-01, 1.00000000e+00,
    185                              7.73553391e-01, 3.40000000e-01, 6.64466094e-02 });
    186     win<w::blackman_harris, f32>(8, 0.0, s::periodic,
    187                                  u{ 6.00000000e-05, 2.17358370e-02, 2.17470000e-01, 6.95764163e-01,
    188                                     1.00000000e+00, 6.95764163e-01, 2.17470000e-01, 2.17358370e-02 });
    189     win<w::kaiser, f32>(
    190         8, 8.0, s::periodic,
    191         u{ 0.00233883, 0.08273982, 0.36897272, 0.78875245, 1., 0.78875245, 0.36897272, 0.08273982 });
    192     win<w::flattop, f32>(8, 0.0, s::periodic,
    193                          u{ -4.21051000e-04, -2.68721933e-02, -5.47368400e-02, 4.44135357e-01, 1.00000000e+00,
    194                             4.44135357e-01, -5.47368400e-02, -2.68721933e-02 });
    195     win<w::gaussian, f32>(
    196         8, 2.5, s::periodic,
    197         u{ 0.08465799, 0.24935221, 0.53940751, 0.85699689, 1., 0.85699689, 0.53940751, 0.24935221 });
    198     win<w::lanczos, f32>(8, 0.0, s::periodic,
    199                          u{ -2.8e-08, 0.300105, 0.63662, 0.900316, 1, 0.900316, 0.63662, 0.300105 });
    200     win<w::cosine_np, f32>(8, 0.0, s::periodic,
    201                            u{ 0.17364818, 0.5, 0.76604444, 0.93969262, 1., 0.93969262, 0.76604444, 0.5 });
    202     win<w::planck_taper, f32>(8, 0.25, s::periodic, u{ 0, 0.5, 1, 1, 1, 1, 1, 0.5 });
    203     win<w::tukey, f32>(8, 0.5, s::periodic, u{ 0., 0.5, 1., 1., 1., 1., 1., 0.5 });
    204     // clang-format on
    205 }
    206 } // namespace CMT_ARCH_NAME
    207 } // namespace kfr
    208 
    209 CMT_PRAGMA_MSVC(warning(pop))