jamie@141
|
1 /*
|
jamie@141
|
2 * Copyright (C) 2012 Jamie Bullock
|
jamie@140
|
3 *
|
jamie@141
|
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
|
jamie@141
|
5 * of this software and associated documentation files (the "Software"), to
|
jamie@141
|
6 * deal in the Software without restriction, including without limitation the
|
jamie@141
|
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
jamie@141
|
8 * sell copies of the Software, and to permit persons to whom the Software is
|
jamie@141
|
9 * furnished to do so, subject to the following conditions:
|
jamie@107
|
10 *
|
jamie@141
|
11 * The above copyright notice and this permission notice shall be included in
|
jamie@141
|
12 * all copies or substantial portions of the Software.
|
jamie@107
|
13 *
|
jamie@141
|
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
jamie@141
|
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
jamie@141
|
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
jamie@141
|
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
jamie@141
|
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
jamie@141
|
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
jamie@141
|
20 * IN THE SOFTWARE.
|
jamie@107
|
21 *
|
jamie@107
|
22 */
|
jamie@107
|
23
|
jamie@107
|
24 /* window.c: defines window generation functions (formulae courtesy of Wikipedia (http://en.wikipedia.org/wiki/Window_function) */
|
jamie@107
|
25
|
jamie@107
|
26 #include <math.h>
|
jamie@107
|
27
|
jamie@107
|
28 #include "xtract_window_private.h"
|
jamie@107
|
29
|
jamie@140
|
30 void gauss(float *window, const int N, const float sd)
|
jamie@140
|
31 {
|
jamie@107
|
32
|
jamie@107
|
33 int n;
|
jamie@107
|
34 const float M = N - 1;
|
jamie@107
|
35 float num,
|
jamie@107
|
36 den,
|
jamie@107
|
37 exponent;
|
jamie@107
|
38
|
jamie@140
|
39 for (n = 0; n < N; n++)
|
jamie@140
|
40 {
|
jamie@107
|
41
|
jamie@107
|
42 num = n - M / 2.f;
|
jamie@107
|
43 den = sd * M / 2.f;
|
jamie@140
|
44
|
jamie@107
|
45 exponent = -0.5 * powf(num / den, 2);
|
jamie@107
|
46
|
jamie@107
|
47 window[n] = exp(exponent);
|
jamie@107
|
48
|
jamie@107
|
49 }
|
jamie@107
|
50 }
|
jamie@107
|
51
|
jamie@140
|
52 void hamming(float *window, const int N)
|
jamie@140
|
53 {
|
jamie@107
|
54
|
jamie@107
|
55 int n;
|
jamie@107
|
56 const float M = N - 1;
|
jamie@107
|
57
|
jamie@107
|
58 for (n = 0; n < N; n++)
|
jamie@107
|
59 window[n] = 0.53836 - (0.46164 * cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
60
|
jamie@107
|
61 }
|
jamie@107
|
62
|
jamie@140
|
63 void hann(float *window, const int N)
|
jamie@140
|
64 {
|
jamie@107
|
65
|
jamie@107
|
66 int n;
|
jamie@107
|
67 const float M = N - 1;
|
jamie@107
|
68
|
jamie@107
|
69 for (n = 0; n < N; n++)
|
jamie@107
|
70 window[n] = 0.5 * (1.0 - cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
71
|
jamie@107
|
72 }
|
jamie@107
|
73
|
jamie@140
|
74 void bartlett(float *window, const int N)
|
jamie@140
|
75 {
|
jamie@107
|
76
|
jamie@107
|
77 int n;
|
jamie@107
|
78 const float M = N - 1;
|
jamie@107
|
79
|
jamie@107
|
80 for (n = 0; n < N; n++)
|
jamie@107
|
81 window[n] = 2.f / M * (M / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
82
|
jamie@107
|
83 }
|
jamie@107
|
84
|
jamie@140
|
85 void triangular(float *window, const int N)
|
jamie@140
|
86 {
|
jamie@107
|
87
|
jamie@107
|
88 int n;
|
jamie@107
|
89 const float M = N - 1;
|
jamie@107
|
90
|
jamie@107
|
91 for (n = 0; n < N; n++)
|
jamie@107
|
92 window[n] = 2.f / N * (N / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
93 }
|
jamie@107
|
94
|
jamie@140
|
95 void bartlett_hann(float *window, const int N)
|
jamie@140
|
96 {
|
jamie@107
|
97
|
jamie@107
|
98 int n;
|
jamie@107
|
99 const float M = N - 1,
|
jamie@140
|
100 a0 = 0.62,
|
jamie@140
|
101 a1 = 0.5,
|
jamie@140
|
102 a2 = 0.38;
|
jamie@107
|
103 float term1 = 0.f,
|
jamie@107
|
104 term2 = 0.f;
|
jamie@107
|
105
|
jamie@140
|
106 for (n = 0; n < N; n++)
|
jamie@140
|
107 {
|
jamie@107
|
108
|
jamie@107
|
109 term1 = a1 * fabsf(n / M - 0.5);
|
jamie@107
|
110 term2 = a2 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
111
|
jamie@107
|
112 window[n] = a0 - term1 - term2;
|
jamie@107
|
113 }
|
jamie@107
|
114 }
|
jamie@107
|
115
|
jamie@140
|
116 void blackman(float *window, const int N)
|
jamie@140
|
117 {
|
jamie@107
|
118
|
jamie@107
|
119 int n;
|
jamie@107
|
120 const float M = N - 1,
|
jamie@140
|
121 a0 = 0.42,
|
jamie@140
|
122 a1 = 0.5,
|
jamie@140
|
123 a2 = 0.08;
|
jamie@107
|
124 float term1 = 0.f,
|
jamie@107
|
125 term2 = 0.f;
|
jamie@107
|
126
|
jamie@140
|
127 for (n = 0; n < N; n++)
|
jamie@140
|
128 {
|
jamie@140
|
129
|
jamie@107
|
130 term1 = a1 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
131 term2 = a2 * cosf(4.0 * PI * (float)n / M);
|
jamie@107
|
132
|
jamie@107
|
133 window[n] = a0 - term1 + term2;
|
jamie@107
|
134 }
|
jamie@107
|
135 }
|
jamie@107
|
136
|
jamie@107
|
137 #define BIZ_EPSILON 1E-21 // Max error acceptable
|
jamie@107
|
138
|
jamie@107
|
139 /* Based on code from mplayer window.c, and somewhat beyond me */
|
jamie@140
|
140 float besselI0(float x)
|
jamie@140
|
141 {
|
jamie@107
|
142
|
jamie@140
|
143 float temp;
|
jamie@140
|
144 float sum = 1.0;
|
jamie@140
|
145 float u = 1.0;
|
jamie@140
|
146 float halfx = x/2.0;
|
jamie@140
|
147 int n = 1;
|
jamie@107
|
148
|
jamie@140
|
149 do
|
jamie@140
|
150 {
|
jamie@107
|
151
|
jamie@140
|
152 temp = halfx/(float)n;
|
jamie@140
|
153 u *=temp * temp;
|
jamie@140
|
154 sum += u;
|
jamie@140
|
155 n++;
|
jamie@107
|
156
|
jamie@140
|
157 }
|
jamie@140
|
158 while (u >= BIZ_EPSILON * sum);
|
jamie@107
|
159
|
jamie@140
|
160 return(sum);
|
jamie@107
|
161
|
jamie@107
|
162 }
|
jamie@107
|
163
|
jamie@140
|
164 void kaiser(float *window, const int N, const float alpha)
|
jamie@140
|
165 {
|
jamie@107
|
166
|
jamie@107
|
167 int n;
|
jamie@107
|
168 const float M = N - 1;
|
jamie@107
|
169 float num;
|
jamie@107
|
170
|
jamie@140
|
171 for (n = 0; n < N; n++)
|
jamie@140
|
172 {
|
jamie@107
|
173
|
jamie@107
|
174 num = besselI0(alpha * sqrtf(1.0 - powf((2.0 * n / M - 1), 2)));
|
jamie@107
|
175 window[n] = num / besselI0(alpha);
|
jamie@140
|
176
|
jamie@107
|
177 }
|
jamie@107
|
178 }
|
jamie@107
|
179
|
jamie@140
|
180 void blackman_harris(float *window, const int N)
|
jamie@140
|
181 {
|
jamie@107
|
182
|
jamie@107
|
183 int n;
|
jamie@107
|
184 const float M = N - 1,
|
jamie@140
|
185 a0 = 0.35875,
|
jamie@140
|
186 a1 = 0.48829,
|
jamie@140
|
187 a2 = 0.14128,
|
jamie@140
|
188 a3 = 0.01168;
|
jamie@107
|
189 float term1 = 0.f,
|
jamie@107
|
190 term2 = 0.f,
|
jamie@107
|
191 term3 = 0.f;
|
jamie@107
|
192
|
jamie@140
|
193 for (n = 0; n < N; n++)
|
jamie@140
|
194 {
|
jamie@107
|
195
|
jamie@107
|
196 term1 = a1 * cosf(2.0 * PI * n / M);
|
jamie@107
|
197 term2 = a2 * cosf(4.0 * PI * n / M);
|
jamie@107
|
198 term3 = a3 * cosf(6.0 * PI * n / M);
|
jamie@107
|
199
|
jamie@107
|
200 window[n] = a0 - term1 + term2 - term3;
|
jamie@107
|
201 }
|
jamie@107
|
202 }
|