diff options
author | Arne Elster <arne@elster.li> | 2022-01-06 23:52:00 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-14 22:45:05 +0100 |
commit | 8185e7e932cf55eddd95f2b88605694bb352ca2f (patch) | |
tree | fc5e4f04c3ac95bc8a6293c3c80185d08a3c4c1a /Userland/Libraries/LibDSP/Window.h | |
parent | 00dd8f8fbef2952aa4db166b8a2ebf965f094775 (diff) | |
download | serenity-8185e7e932cf55eddd95f2b88605694bb352ca2f.zip |
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.
Diffstat (limited to 'Userland/Libraries/LibDSP/Window.h')
-rw-r--r-- | Userland/Libraries/LibDSP/Window.h | 70 |
1 files changed, 70 insertions, 0 deletions
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 <AK/FixedArray.h> +#include <AK/Math.h> + +namespace LibDSP { + +template<typename T> +class Window final { +public: + template<size_t size> + constexpr static Array<T, size> hamming() { return make_window<size>(calculate_hamming); } + constexpr static FixedArray<T> hamming(size_t size) { return make_window(size, calculate_hamming); } + + template<size_t size> + constexpr static Array<T, size> hann() { return make_window<size>(calculate_hann); } + constexpr static FixedArray<T> hann(size_t size) { return make_window(size, calculate_hann); } + + template<size_t size> + constexpr static Array<T, size> blackman_harris() { return make_window<size>(calculate_blackman_harris); } + constexpr static FixedArray<T> 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<T> * index) / (size - 1))); + } + + constexpr static double calculate_hamming(size_t index, size_t size) + { + return 0.54 - 0.46 * AK::cos((2 * AK::Pi<T> * 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<T> * index / size) + a2 * AK::cos(4 * AK::Pi<T> * index / size) - a3 * AK::cos(6 * AK::Pi<T> * index / size); + } + + template<size_t size> + constexpr static Array<T, size> make_window(auto window_function) + { + Array<T, size> result; + for (size_t i = 0; i < size; i++) { + result[i] = window_function(i, size); + } + return result; + } + + constexpr static FixedArray<T> make_window(size_t size, auto window_function) + { + FixedArray<T> result; + result.resize(size); + for (size_t i = 0; i < size; i++) { + result[i] = window_function(i, size); + } + return result; + } +}; + +} |