Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
windowing.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <cmath>
5
6namespace pulp::signal {
7
8namespace detail {
9
10template <typename SampleType>
11inline SampleType four_term_cosine_window(SampleType phase,
12 SampleType a0,
13 SampleType a1,
14 SampleType a2,
15 SampleType a3) {
16 return a0 - a1 * std::cos(phase) +
17 a2 * std::cos(SampleType{2.0f} * phase) -
18 a3 * std::cos(SampleType{3.0f} * phase);
19}
20
21template <typename SampleType>
22inline SampleType blackman_harris_window(SampleType phase) {
24 phase, SampleType{0.35875f}, SampleType{0.48829f},
25 SampleType{0.14128f}, SampleType{0.01168f});
26}
27
28template <typename SampleType>
29inline SampleType blackman_nuttall_window(SampleType phase) {
31 phase, SampleType{0.3635819f}, SampleType{0.4891775f},
32 SampleType{0.1365995f}, SampleType{0.0106411f});
33}
34
35} // namespace detail
36
37// Window functions for FFT, spectral analysis, FIR filter design.
38//
39// RT contract: generate() allocates and is prepare/design-time only. apply()
40// is allocation-free when callers pass a valid buffer and a precomputed window.
42public:
53
54 // Generate a window of the given size and type. Not real-time safe.
55 template <typename SampleType = float>
56 static std::vector<SampleType> generate(int size,
57 Type type,
58 SampleType param = SampleType{0.0f}) {
59 if (size <= 0) return {};
60 if (size == 1) return {SampleType{1.0f}};
61
62 std::vector<SampleType> w(size);
63 for (int i = 0; i < size; ++i) {
64 SampleType n = static_cast<SampleType>(i);
65 SampleType N = static_cast<SampleType>(size - 1);
66
67 switch (type) {
69 w[i] = SampleType{1.0f};
70 break;
71
72 case Type::hann:
73 w[i] = SampleType{0.5f} *
74 (SampleType{1.0f} - std::cos(SampleType{2.0f} *
75 pi<SampleType> * n / N));
76 break;
77
78 case Type::hamming:
79 w[i] = SampleType{0.54f} -
80 SampleType{0.46f} *
81 std::cos(SampleType{2.0f} * pi<SampleType> * n / N);
82 break;
83
84 case Type::blackman:
85 w[i] = SampleType{0.42f} -
86 SampleType{0.5f} *
87 std::cos(SampleType{2.0f} * pi<SampleType> * n / N)
88 + SampleType{0.08f} *
89 std::cos(SampleType{4.0f} * pi<SampleType> * n / N);
90 break;
91
94 SampleType{2.0f} * pi<SampleType> * n / N);
95 break;
96
99 SampleType{2.0f} * pi<SampleType> * n / N);
100 break;
101
102 case Type::flat_top:
103 w[i] = SampleType{0.21557895f}
104 - SampleType{0.41663158f} *
105 std::cos(SampleType{2.0f} * pi<SampleType> * n / N)
106 + SampleType{0.277263158f} *
107 std::cos(SampleType{4.0f} * pi<SampleType> * n / N)
108 - SampleType{0.083578947f} *
109 std::cos(SampleType{6.0f} * pi<SampleType> * n / N)
110 + SampleType{0.006947368f} *
111 std::cos(SampleType{8.0f} * pi<SampleType> * n / N);
112 break;
113
114 case Type::kaiser: {
115 SampleType alpha = param > SampleType{0.0f}
116 ? param
117 : SampleType{3.0f};
118 SampleType x = SampleType{2.0f} * n / N - SampleType{1.0f};
119 w[i] = bessel_i0(alpha * std::sqrt(SampleType{1.0f} - x * x)) /
120 bessel_i0(alpha);
121 break;
122 }
123 }
124 }
125 return w;
126 }
127
128 // Apply a precomputed window to a buffer in-place. Allocation-free.
129 template <typename SampleType>
130 static void apply(SampleType* buffer, const std::vector<SampleType>& window) {
131 for (size_t i = 0; i < window.size(); ++i)
132 buffer[i] *= window[i];
133 }
134
135private:
136 template <typename SampleType>
137 static constexpr SampleType pi =
138 static_cast<SampleType>(3.141592653589793238462643383279502884L);
139
140 // Modified Bessel function of the first kind, order 0 (for Kaiser window)
141 template <typename SampleType>
142 static SampleType bessel_i0(SampleType x) {
143 SampleType sum = SampleType{1.0f};
144 SampleType term = SampleType{1.0f};
145 SampleType x2 = x * x * SampleType{0.25f};
146 for (int k = 1; k < 20; ++k) {
147 term *= x2 / (static_cast<SampleType>(k) * static_cast<SampleType>(k));
148 sum += term;
149 }
150 return sum;
151 }
152};
153
154} // namespace pulp::signal
Definition windowing.hpp:41
static std::vector< SampleType > generate(int size, Type type, SampleType param=SampleType{0.0f})
Definition windowing.hpp:56
static void apply(SampleType *buffer, const std::vector< SampleType > &window)
Definition windowing.hpp:130
Type
Definition windowing.hpp:43
@ blackman_harris
Definition windowing.hpp:50
@ hamming
Definition windowing.hpp:46
@ blackman
Definition windowing.hpp:47
@ flat_top
Definition windowing.hpp:48
@ kaiser
Definition windowing.hpp:49
@ hann
Definition windowing.hpp:45
@ blackman_nuttall
Definition windowing.hpp:51
@ rectangular
Definition windowing.hpp:44
@ x2
Definition forge_distortion_catalog.hpp:48
@ alpha
Straight alpha: src * a + dst * (1 - a).
Definition gpu_pass.hpp:268
Round-2 effect-wave vocabulary.
Definition analysis_frontends.hpp:50
SampleType four_term_cosine_window(SampleType phase, SampleType a0, SampleType a1, SampleType a2, SampleType a3)
Definition windowing.hpp:11
SampleType blackman_nuttall_window(SampleType phase)
Definition windowing.hpp:29
SampleType blackman_harris_window(SampleType phase)
Definition windowing.hpp:22
@ size
Definition config.hpp:216
Definition additive_bank.hpp:218
@ buffer
A borrowed static buffer with a traversable playhead.
Definition granular.hpp:110
float bessel_i0(float x)
Modified Bessel function of the first kind, order 0 Used in Kaiser window design.
Definition special_functions.hpp:25
@ i
Definition formant_filter_bank.hpp:20
float sum(const float *data, std::size_t count) noexcept
@ n
Definition input_events.hpp:40
@ k
Definition input_events.hpp:40
@ x
Definition input_events.hpp:41
@ w
Definition input_events.hpp:41