kfr

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

commit 6f042bf7133b9289888fe3d4a704e46e2b4ecf8a
parent 14643be8a512afcfb8988e335517868e631e5790
Author: [email protected] <[email protected]>
Date:   Sun, 25 Jun 2023 17:21:47 +0100

Planck-taper window

Diffstat:
Mexamples/window.cpp | 3+++
Minclude/kfr/dsp/window.hpp | 33++++++++++++++++++++++++++++++++-
Mtests/unit/dsp/window.cpp | 9+++++++++
3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/examples/window.cpp b/examples/window.cpp @@ -60,6 +60,9 @@ int main() output = window_kaiser(output.size(), 2.5); plot_save("window_kaiser", output, options + ", title='Kaiser window'"); + output = window_planck_taper(output.size(), 0.1); + plot_save("window_planck_taper", output, options + ", title='Planck-taper window'"); + println("SVG plots have been saved to svg directory"); return 0; diff --git a/include/kfr/dsp/window.hpp b/include/kfr/dsp/window.hpp @@ -52,6 +52,7 @@ enum class window_type gaussian = 13, lanczos = 14, cosine_np = 15, + planck_taper = 16, }; template <window_type type> @@ -380,6 +381,23 @@ struct expression_lanczos : expression_window_with_metrics<T, window_metrics::me } }; +template <typename T> +struct expression_planck_taper : expression_window_with_metrics<T, window_metrics::metrics_m1_1> +{ + expression_planck_taper(size_t size, T epsilon, window_symmetry symmetry = window_symmetry::symmetric) + : expression_window_with_metrics<T, window_metrics::metrics_m1_1>(size, epsilon, symmetry) + { + } + template <size_t N> + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_planck_taper& self, shape<1> index, + axis_params<0, N> sh) + { + vec<T, N> x = (T(1) - abs(get_elements(self.linspace, index, sh))) / (T(2) * self.arg); + vec<T, N> val = T(1) / (T(1) + exp(T(1) / x - T(1) / (T(1) - x))); + return select(x <= T(0), T(0), select(x >= T(1), T(1), val)); + } +}; + template <window_type> struct window_by_type; @@ -405,6 +423,7 @@ KFR_WINDOW_BY_TYPE(flattop) KFR_WINDOW_BY_TYPE(gaussian) KFR_WINDOW_BY_TYPE(lanczos) KFR_WINDOW_BY_TYPE(cosine_np) +KFR_WINDOW_BY_TYPE(planck_taper) #undef KFR_WINDOW_BY_TYPE /** @@ -552,6 +571,17 @@ KFR_FUNCTION expression_lanczos<T> window_lanczos(size_t size, ctype_t<T> = ctyp return expression_lanczos<T>(size); } +/** + * @brief Returns template expression that generates Planck-taper window of length @c size + */ +template <typename T = fbase> +KFR_FUNCTION expression_planck_taper<T> window_planck_taper( + size_t size, identity<T> epsilon, window_symmetry symmetry = window_symmetry::symmetric, + ctype_t<T> = ctype_t<T>()) +{ + return expression_planck_taper<T>(size, epsilon, symmetry); +} + template <typename T = fbase, window_type type, typename window_expr = typename window_by_type<type>::template type<T>> CMT_NOINLINE window_expr window(size_t size, cval_t<window_type, type>, identity<T> win_param = T(), @@ -570,7 +600,8 @@ CMT_NOINLINE expression_handle<T> window(size_t size, window_type type, identity cvals_t<window_type, window_type::rectangular, window_type::triangular, window_type::bartlett, window_type::cosine, window_type::hann, window_type::bartlett_hann, window_type::hamming, window_type::bohman, window_type::blackman, window_type::blackman_harris, window_type::kaiser, - window_type::flattop, window_type::gaussian, window_type::lanczos, window_type::cosine_np>(), + window_type::flattop, window_type::gaussian, window_type::lanczos, window_type::cosine_np, + window_type::planck_taper>(), type, [size, win_param, symmetry](auto win) { diff --git a/tests/unit/dsp/window.cpp b/tests/unit/dsp/window.cpp @@ -36,6 +36,7 @@ const char* wins[] = { "gaussian ", "lanczos ", "cosine_np ", + "planck_taper ", }; template <window_type type, typename T> @@ -53,6 +54,7 @@ TEST(window) using s = window_symmetry; using u = univector<f32>; // clang-format + // 7 ; symmetric win<w::rectangular, f32>(7, 0.0, s::symmetric, u{ 1, 1, 1, 1, 1, 1, 1 }); win<w::triangular, f32>(7, 0.0, s::symmetric, u{ 0.25, 0.5, 0.75, 1., 0.75, 0.5, 0.25 }); win<w::bartlett, f32>(7, 0.0, s::symmetric, @@ -80,7 +82,9 @@ TEST(window) u{ -2.8e-08, 0.413497, 0.826993, 1, 0.826993, 0.413497, -2.8e-08 }); win<w::cosine_np, f32>(7, 0.0, s::symmetric, u{ 0.22252093, 0.6234898, 0.90096887, 1., 0.90096887, 0.6234898, 0.22252093 }); + win<w::planck_taper, f32>(7, 0.25, s::symmetric, u{ 0, 0.817575, 1, 1, 1, 0.817574, 0 }); + // 8 ; symmetric win<w::rectangular, f32>(8, 0.0, s::symmetric, u{ 1, 1, 1, 1, 1, 1, 1, 1 }); win<w::triangular, f32>(8, 0.0, s::symmetric, u{ 0.125, 0.375, 0.625, 0.875, 0.875, 0.625, 0.375, 0.125 }); @@ -119,7 +123,9 @@ TEST(window) win<w::cosine_np, f32>( 8, 0.0, s::symmetric, u{ 0.19509032, 0.55557023, 0.83146961, 0.98078528, 0.98078528, 0.83146961, 0.55557023, 0.19509032 }); + win<w::planck_taper, f32>(8, 0.25, s::symmetric, u{ 0, 0.641834, 1, 1, 1, 1, 0.641833, 0 }); + // 7 ; periodic win<w::rectangular, f32>(7, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1 }); win<w::triangular, f32>(7, 0.0, s::periodic, u{ 0.125, 0.375, 0.625, 0.875, 0.875, 0.625, 0.375 }); win<w::bartlett, f32>(7, 0.0, s::periodic, @@ -154,7 +160,9 @@ TEST(window) win<w::cosine_np, f32>( 7, 0.0, s::periodic, u{ 0.19509032, 0.55557023, 0.83146961, 0.98078528, 0.98078528, 0.83146961, 0.55557023 }); + win<w::planck_taper, f32>(7, 0.25, s::periodic, u{ 0, 0.641834, 1, 1, 1, 1, 0.641833 }); + // 8 ; periodic win<w::rectangular, f32>(8, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1, 1 }); 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 }); win<w::bartlett, f32>(8, 0.0, s::periodic, u{ 0., 0.25, 0.5, 0.75, 1., 0.75, 0.5, 0.25 }); @@ -187,6 +195,7 @@ TEST(window) u{ -2.8e-08, 0.300105, 0.63662, 0.900316, 1, 0.900316, 0.63662, 0.300105 }); win<w::cosine_np, f32>(8, 0.0, s::periodic, u{ 0.17364818, 0.5, 0.76604444, 0.93969262, 1., 0.93969262, 0.76604444, 0.5 }); + win<w::planck_taper, f32>(8, 0.25, s::periodic, u{ 0, 0.5, 1, 1, 1, 1, 1, 0.5 }); // clang-format on } } // namespace CMT_ARCH_NAME