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 6cda7d9087c74d7793b8d5f39c6866cef7ce94f5
parent 7a43865db8c766d8ca32e503b92a7bb8de03c422
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue, 27 Jun 2023 20:29:31 +0100

Tukey window

Diffstat:
Minclude/kfr/dsp/window.hpp | 32+++++++++++++++++++++++++++++++-
Mtests/unit/dsp/window.cpp | 5+++++
2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/kfr/dsp/window.hpp b/include/kfr/dsp/window.hpp @@ -53,6 +53,7 @@ enum class window_type lanczos = 14, cosine_np = 15, planck_taper = 16, + tukey = 17, }; template <window_type type> @@ -398,6 +399,23 @@ struct expression_planck_taper : expression_window_with_metrics<T, window_metric } }; +template <typename T> +struct expression_tukey : expression_window_with_metrics<T, window_metrics::metrics_m1_1> +{ + expression_tukey(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_tukey& self, shape<1> index, + axis_params<0, N> sh) + { + vec<T, N> x = (T(1) - abs(get_elements(self.linspace, index, sh))) / self.arg; + vec<T, N> val = T(0.5) * (T(1) - cos(c_pi<T> * x)); + return select(x <= T(0), T(0), select(x >= T(1), T(1), val)); + } +}; + template <window_type> struct window_by_type; @@ -424,6 +442,7 @@ KFR_WINDOW_BY_TYPE(gaussian) KFR_WINDOW_BY_TYPE(lanczos) KFR_WINDOW_BY_TYPE(cosine_np) KFR_WINDOW_BY_TYPE(planck_taper) +KFR_WINDOW_BY_TYPE(tukey) #undef KFR_WINDOW_BY_TYPE /** @@ -582,6 +601,17 @@ KFR_FUNCTION expression_planck_taper<T> window_planck_taper( return expression_planck_taper<T>(size, epsilon, symmetry); } +/** + * @brief Returns template expression that generates Tukey window of length @c size (numpy compatible) + */ +template <typename T = fbase> +KFR_FUNCTION expression_tukey<T> window_tukey(size_t size, identity<T> alpha, + window_symmetry symmetry = window_symmetry::symmetric, + ctype_t<T> = ctype_t<T>()) +{ + return expression_tukey<T>(size, alpha, 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(), @@ -601,7 +631,7 @@ CMT_NOINLINE expression_handle<T> window(size_t size, window_type type, identity 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::planck_taper>(), + window_type::planck_taper, window_type::tukey>(), type, [size, win_param, symmetry](auto win) { diff --git a/tests/unit/dsp/window.cpp b/tests/unit/dsp/window.cpp @@ -37,6 +37,7 @@ const char* wins[] = { "lanczos ", "cosine_np ", "planck_taper ", + "tukey ", }; template <window_type type, typename T> @@ -83,6 +84,7 @@ TEST(window) 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 }); + win<w::tukey, f32>(7, 0.5, s::symmetric, u{ 0., 0.75, 1., 1., 1., 0.75, 0. }); // 8 ; symmetric win<w::rectangular, f32>(8, 0.0, s::symmetric, u{ 1, 1, 1, 1, 1, 1, 1, 1 }); @@ -124,6 +126,7 @@ TEST(window) 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 }); + win<w::tukey, f32>(8, 0.5, s::symmetric, u{ 0., 0.61126047, 1., 1., 1., 1., 0.61126047, 0. }); // 7 ; periodic win<w::rectangular, f32>(7, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1 }); @@ -161,6 +164,7 @@ TEST(window) 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 }); + win<w::tukey, f32>(7, 0.5, s::periodic, u{ 0., 0.61126047, 1., 1., 1., 1., 0.61126047 }); // 8 ; periodic win<w::rectangular, f32>(8, 0.0, s::periodic, u{ 1, 1, 1, 1, 1, 1, 1, 1 }); @@ -196,6 +200,7 @@ TEST(window) 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 }); + win<w::tukey, f32>(8, 0.5, s::periodic, u{ 0., 0.5, 1., 1., 1., 1., 1., 0.5 }); // clang-format on } } // namespace CMT_ARCH_NAME