MostlyHarmless 0.0.1
 
Loading...
Searching...
No Matches
marvin_Windows.h
Go to the documentation of this file.
1// ========================================================================================================
2// _______ _______ ______ ___ ___ _______ _______
3// | | | _ | __ \ | |_ _| | |
4// | | | < | |_| |_| |
5// |__|_|__|___|___|___|__|\_____/|_______|__|____|
6//
7// This file is part of the Marvin open source library and is licensed under the terms of the MIT License.
8//
9// ========================================================================================================
10
11#ifndef MARVIN_MATHWINDOWS_H
12#define MARVIN_MATHWINDOWS_H
15#include <numbers>
16#include <cmath>
18
30
34 template <marvin::FloatType SampleType, size_t NumPoints>
35 class PrecomputedWindow final {
36 public:
41 explicit PrecomputedWindow(std::array<SampleType, NumPoints>&& lut) : m_lut(std::move(lut)) {
42 }
43
49 [[nodiscard]] SampleType operator()(SampleType proportion) const {
50 using namespace marvin::literals;
51 const auto rescaled = proportion * (NumPoints - 1_sz);
52 const auto truncated = std::trunc(rescaled);
53 const auto delta = rescaled - truncated;
54 const auto index0{ static_cast<size_t>(truncated) };
55 const auto index1 = index0 + 1;
56 const auto pointA = m_lut[index0];
57 const auto pointB = m_lut[index1];
58 const auto interpolated = marvin::math::lerp(pointA, pointB, delta);
59 return interpolated;
60 }
61
62 private:
63 std::array<SampleType, NumPoints> m_lut;
64 };
65
72 template <FloatType SampleType>
73 [[nodiscard]] SampleType sine(SampleType n, SampleType N) {
74 static constexpr auto pi = std::numbers::pi_v<SampleType>;
75 const auto window = std::sin((pi * n) / (N - 1));
76 return window;
77 }
78
87 template <FloatType SampleType>
88 [[nodiscard]] SampleType tukey(SampleType n, SampleType NumPoints, SampleType alpha) {
89 // 0.5 * (1 - cos(2pin/alphaN)), 0 <= n <= aN / 2
90 // 1, aN/2 <= n <= N / 2
91 // w[N - n] = w[n], 0 <= n <= N / 2
92 const auto N{ NumPoints - 1 };
93 const auto alphaN = alpha * N;
94 const auto NOverTwo = N / static_cast<SampleType>(2.0);
95 const auto aNOverTwo = alphaN / static_cast<SampleType>(2.0);
96 if (n >= 0 && n <= aNOverTwo) {
97 // 0.5 * (1 - cos(2pin / alphaN))
98 constexpr static auto twoPi = static_cast<SampleType>(2.0) * std::numbers::pi_v<SampleType>;
99 const auto cosine = std::cos((twoPi * n) / alphaN);
100 const auto res = static_cast<SampleType>(0.5) * (static_cast<SampleType>(1.0 - cosine));
101 return res;
102 } else if (n > aNOverTwo && n <= NOverTwo) {
103 return static_cast<SampleType>(1.0);
104 } else {
105 const auto reverseIndex = N - n;
106 return tukey(reverseIndex, N, alpha);
107 }
108 }
109
116 template <FloatType SampleType>
117 [[nodiscard]] SampleType blackmanHarris(SampleType n, SampleType N) {
118 constexpr static auto a0{ 0.35875 };
119 constexpr static auto a1{ 0.48829 };
120 constexpr static auto a2{ 0.14128 };
121 constexpr static auto a3{ 0.01168 };
122 constexpr static auto pi{ std::numbers::pi_v<double> };
123 constexpr static auto twoPi{ pi * 2.0 };
124 constexpr static auto fourPi{ pi * 4.0 };
125 constexpr static auto sixPi{ pi * 6.0 };
126 const auto position = static_cast<double>(n) / static_cast<double>(N - 1);
127 const auto a1Term = a1 * std::cos(position * twoPi);
128 const auto a2Term = a2 * std::cos(position * fourPi);
129 const auto a3Term = a3 * std::cos(position * sixPi);
130 const auto result = a0 - a1Term + a2Term - a3Term;
131 return static_cast<SampleType>(result);
132 }
133
144 template <FloatType SampleType>
145 [[nodiscard]] SampleType cosineSum(SampleType n, SampleType N, SampleType alpha) {
146 // w[n] = a0 - (1 - a0) * cos(2pi * n/N)
147 const auto a0 = alpha;
148 const auto a1 = static_cast<SampleType>(1.0) - alpha;
149 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
150 const auto ratio = n / (N - 1);
151 const auto cosine = std::cos(twoPi * ratio);
152 const auto a1Scaled = a1 * cosine;
153 const auto res = a0 - a1Scaled;
154 return res;
155 }
156
163 template <FloatType SampleType>
164 [[nodiscard]] SampleType hann(SampleType n, SampleType N) {
165 return cosineSum(n, N, static_cast<SampleType>(0.5));
166 }
167
174 template <FloatType SampleType>
175 [[nodiscard]] SampleType hamming(SampleType n, SampleType N) {
176 constexpr static auto alpha = static_cast<SampleType>(25.0 / 46.0);
177 return cosineSum(n, N, alpha);
178 }
179} // namespace marvin::math::windows
180#endif
SampleType operator()(SampleType proportion) const
Definition marvin_Windows.h:49
PrecomputedWindow(std::array< SampleType, NumPoints > &&lut)
Definition marvin_Windows.h:41
Various windowing functions. An interactive graph with more intuition than the textual documentation ...
Definition marvin_Windows.h:17
SampleType cosineSum(SampleType n, SampleType N, SampleType alpha)
Definition marvin_Windows.h:145
SampleType blackmanHarris(SampleType n, SampleType N)
Definition marvin_Windows.h:117
SampleType sine(SampleType n, SampleType N)
Definition marvin_Windows.h:73
SampleType hamming(SampleType n, SampleType N)
Definition marvin_Windows.h:175
SampleType hann(SampleType n, SampleType N)
Definition marvin_Windows.h:164
SampleType tukey(SampleType n, SampleType NumPoints, SampleType alpha)
Definition marvin_Windows.h:88
WindowType
Definition marvin_Windows.h:22
@ Hann
Definition marvin_Windows.h:27
@ Sine
Definition marvin_Windows.h:23
@ Hamming
Definition marvin_Windows.h:28
@ BlackmanHarris
Definition marvin_Windows.h:25
@ Tukey
Definition marvin_Windows.h:24
@ CosineSum
Definition marvin_Windows.h:26
T lerp(T start, T end, T ratio) noexcept
Definition marvin_Math.h:32