From 8185e7e932cf55eddd95f2b88605694bb352ca2f Mon Sep 17 00:00:00 2001 From: Arne Elster Date: Thu, 6 Jan 2022 23:52:00 +0100 Subject: [PATCH] LibDSP: Add windowing functions Windows are used in many DSP related applications. A prominent use case is spectral analysis, where windowing the signal before doing spectral analysis mitigates spectral leakage. --- Userland/Libraries/LibDSP/Window.h | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Userland/Libraries/LibDSP/Window.h diff --git a/Userland/Libraries/LibDSP/Window.h b/Userland/Libraries/LibDSP/Window.h new file mode 100644 index 0000000000..ef014514f3 --- /dev/null +++ b/Userland/Libraries/LibDSP/Window.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, Arne Elster (arne@elster.li) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace LibDSP { + +template +class Window final { +public: + template + constexpr static Array hamming() { return make_window(calculate_hamming); } + constexpr static FixedArray hamming(size_t size) { return make_window(size, calculate_hamming); } + + template + constexpr static Array hann() { return make_window(calculate_hann); } + constexpr static FixedArray hann(size_t size) { return make_window(size, calculate_hann); } + + template + constexpr static Array blackman_harris() { return make_window(calculate_blackman_harris); } + constexpr static FixedArray blackman_harris(size_t size) { return make_window(size, calculate_blackman_harris); } + +private: + constexpr static double calculate_hann(size_t index, size_t size) + { + return 0.5 * (1 - AK::cos((2 * AK::Pi * index) / (size - 1))); + } + + constexpr static double calculate_hamming(size_t index, size_t size) + { + return 0.54 - 0.46 * AK::cos((2 * AK::Pi * index) / (size - 1)); + } + + constexpr static double calculate_blackman_harris(size_t index, size_t size) + { + T const a0 = 0.35875; + T const a1 = 0.48829; + T const a2 = 0.14128; + T const a3 = 0.01168; + return a0 - a1 * AK::cos(2 * AK::Pi * index / size) + a2 * AK::cos(4 * AK::Pi * index / size) - a3 * AK::cos(6 * AK::Pi * index / size); + } + + template + constexpr static Array make_window(auto window_function) + { + Array result; + for (size_t i = 0; i < size; i++) { + result[i] = window_function(i, size); + } + return result; + } + + constexpr static FixedArray make_window(size_t size, auto window_function) + { + FixedArray result; + result.resize(size); + for (size_t i = 0; i < size; i++) { + result[i] = window_function(i, size); + } + return result; + } +}; + +}