jamie@107
|
1 /* libxtract feature extraction library
|
jamie@140
|
2 *
|
jamie@107
|
3 * Copyright (C) 2006 Jamie Bullock
|
jamie@107
|
4 *
|
jamie@107
|
5 * This program is free software; you can redistribute it and/or modify
|
jamie@107
|
6 * it under the terms of the GNU General Public License as published by
|
jamie@107
|
7 * the Free Software Foundation; either version 2 of the License, or
|
jamie@107
|
8 * (at your option) any later version.
|
jamie@107
|
9 *
|
jamie@107
|
10 * This program is distributed in the hope that it will be useful,
|
jamie@107
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
jamie@107
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
jamie@107
|
13 * GNU General Public License for more details.
|
jamie@107
|
14 *
|
jamie@107
|
15 * You should have received a copy of the GNU General Public License
|
jamie@107
|
16 * along with this program; if not, write to the Free Software
|
jamie@140
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
jamie@107
|
18 * USA.
|
jamie@107
|
19 */
|
jamie@107
|
20
|
jamie@107
|
21 /* window.c: defines window generation functions (formulae courtesy of Wikipedia (http://en.wikipedia.org/wiki/Window_function) */
|
jamie@107
|
22
|
jamie@107
|
23 #include <math.h>
|
jamie@107
|
24
|
jamie@107
|
25 #include "xtract_window_private.h"
|
jamie@107
|
26
|
jamie@140
|
27 void gauss(float *window, const int N, const float sd)
|
jamie@140
|
28 {
|
jamie@107
|
29
|
jamie@107
|
30 int n;
|
jamie@107
|
31 const float M = N - 1;
|
jamie@107
|
32 float num,
|
jamie@107
|
33 den,
|
jamie@107
|
34 exponent;
|
jamie@107
|
35
|
jamie@140
|
36 for (n = 0; n < N; n++)
|
jamie@140
|
37 {
|
jamie@107
|
38
|
jamie@107
|
39 num = n - M / 2.f;
|
jamie@107
|
40 den = sd * M / 2.f;
|
jamie@140
|
41
|
jamie@107
|
42 exponent = -0.5 * powf(num / den, 2);
|
jamie@107
|
43
|
jamie@107
|
44 window[n] = exp(exponent);
|
jamie@107
|
45
|
jamie@107
|
46 }
|
jamie@107
|
47 }
|
jamie@107
|
48
|
jamie@140
|
49 void hamming(float *window, const int N)
|
jamie@140
|
50 {
|
jamie@107
|
51
|
jamie@107
|
52 int n;
|
jamie@107
|
53 const float M = N - 1;
|
jamie@107
|
54
|
jamie@107
|
55 for (n = 0; n < N; n++)
|
jamie@107
|
56 window[n] = 0.53836 - (0.46164 * cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
57
|
jamie@107
|
58 }
|
jamie@107
|
59
|
jamie@140
|
60 void hann(float *window, const int N)
|
jamie@140
|
61 {
|
jamie@107
|
62
|
jamie@107
|
63 int n;
|
jamie@107
|
64 const float M = N - 1;
|
jamie@107
|
65
|
jamie@107
|
66 for (n = 0; n < N; n++)
|
jamie@107
|
67 window[n] = 0.5 * (1.0 - cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
68
|
jamie@107
|
69 }
|
jamie@107
|
70
|
jamie@140
|
71 void bartlett(float *window, const int N)
|
jamie@140
|
72 {
|
jamie@107
|
73
|
jamie@107
|
74 int n;
|
jamie@107
|
75 const float M = N - 1;
|
jamie@107
|
76
|
jamie@107
|
77 for (n = 0; n < N; n++)
|
jamie@107
|
78 window[n] = 2.f / M * (M / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
79
|
jamie@107
|
80 }
|
jamie@107
|
81
|
jamie@140
|
82 void triangular(float *window, const int N)
|
jamie@140
|
83 {
|
jamie@107
|
84
|
jamie@107
|
85 int n;
|
jamie@107
|
86 const float M = N - 1;
|
jamie@107
|
87
|
jamie@107
|
88 for (n = 0; n < N; n++)
|
jamie@107
|
89 window[n] = 2.f / N * (N / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
90 }
|
jamie@107
|
91
|
jamie@140
|
92 void bartlett_hann(float *window, const int N)
|
jamie@140
|
93 {
|
jamie@107
|
94
|
jamie@107
|
95 int n;
|
jamie@107
|
96 const float M = N - 1,
|
jamie@140
|
97 a0 = 0.62,
|
jamie@140
|
98 a1 = 0.5,
|
jamie@140
|
99 a2 = 0.38;
|
jamie@107
|
100 float term1 = 0.f,
|
jamie@107
|
101 term2 = 0.f;
|
jamie@107
|
102
|
jamie@140
|
103 for (n = 0; n < N; n++)
|
jamie@140
|
104 {
|
jamie@107
|
105
|
jamie@107
|
106 term1 = a1 * fabsf(n / M - 0.5);
|
jamie@107
|
107 term2 = a2 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
108
|
jamie@107
|
109 window[n] = a0 - term1 - term2;
|
jamie@107
|
110 }
|
jamie@107
|
111 }
|
jamie@107
|
112
|
jamie@140
|
113 void blackman(float *window, const int N)
|
jamie@140
|
114 {
|
jamie@107
|
115
|
jamie@107
|
116 int n;
|
jamie@107
|
117 const float M = N - 1,
|
jamie@140
|
118 a0 = 0.42,
|
jamie@140
|
119 a1 = 0.5,
|
jamie@140
|
120 a2 = 0.08;
|
jamie@107
|
121 float term1 = 0.f,
|
jamie@107
|
122 term2 = 0.f;
|
jamie@107
|
123
|
jamie@140
|
124 for (n = 0; n < N; n++)
|
jamie@140
|
125 {
|
jamie@140
|
126
|
jamie@107
|
127 term1 = a1 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
128 term2 = a2 * cosf(4.0 * PI * (float)n / M);
|
jamie@107
|
129
|
jamie@107
|
130 window[n] = a0 - term1 + term2;
|
jamie@107
|
131 }
|
jamie@107
|
132 }
|
jamie@107
|
133
|
jamie@107
|
134 #define BIZ_EPSILON 1E-21 // Max error acceptable
|
jamie@107
|
135
|
jamie@107
|
136 /* Based on code from mplayer window.c, and somewhat beyond me */
|
jamie@140
|
137 float besselI0(float x)
|
jamie@140
|
138 {
|
jamie@107
|
139
|
jamie@140
|
140 float temp;
|
jamie@140
|
141 float sum = 1.0;
|
jamie@140
|
142 float u = 1.0;
|
jamie@140
|
143 float halfx = x/2.0;
|
jamie@140
|
144 int n = 1;
|
jamie@107
|
145
|
jamie@140
|
146 do
|
jamie@140
|
147 {
|
jamie@107
|
148
|
jamie@140
|
149 temp = halfx/(float)n;
|
jamie@140
|
150 u *=temp * temp;
|
jamie@140
|
151 sum += u;
|
jamie@140
|
152 n++;
|
jamie@107
|
153
|
jamie@140
|
154 }
|
jamie@140
|
155 while (u >= BIZ_EPSILON * sum);
|
jamie@107
|
156
|
jamie@140
|
157 return(sum);
|
jamie@107
|
158
|
jamie@107
|
159 }
|
jamie@107
|
160
|
jamie@140
|
161 void kaiser(float *window, const int N, const float alpha)
|
jamie@140
|
162 {
|
jamie@107
|
163
|
jamie@107
|
164 int n;
|
jamie@107
|
165 const float M = N - 1;
|
jamie@107
|
166 float num;
|
jamie@107
|
167
|
jamie@140
|
168 for (n = 0; n < N; n++)
|
jamie@140
|
169 {
|
jamie@107
|
170
|
jamie@107
|
171 num = besselI0(alpha * sqrtf(1.0 - powf((2.0 * n / M - 1), 2)));
|
jamie@107
|
172 window[n] = num / besselI0(alpha);
|
jamie@140
|
173
|
jamie@107
|
174 }
|
jamie@107
|
175 }
|
jamie@107
|
176
|
jamie@140
|
177 void blackman_harris(float *window, const int N)
|
jamie@140
|
178 {
|
jamie@107
|
179
|
jamie@107
|
180 int n;
|
jamie@107
|
181 const float M = N - 1,
|
jamie@140
|
182 a0 = 0.35875,
|
jamie@140
|
183 a1 = 0.48829,
|
jamie@140
|
184 a2 = 0.14128,
|
jamie@140
|
185 a3 = 0.01168;
|
jamie@107
|
186 float term1 = 0.f,
|
jamie@107
|
187 term2 = 0.f,
|
jamie@107
|
188 term3 = 0.f;
|
jamie@107
|
189
|
jamie@140
|
190 for (n = 0; n < N; n++)
|
jamie@140
|
191 {
|
jamie@107
|
192
|
jamie@107
|
193 term1 = a1 * cosf(2.0 * PI * n / M);
|
jamie@107
|
194 term2 = a2 * cosf(4.0 * PI * n / M);
|
jamie@107
|
195 term3 = a3 * cosf(6.0 * PI * n / M);
|
jamie@107
|
196
|
jamie@107
|
197 window[n] = a0 - term1 + term2 - term3;
|
jamie@107
|
198 }
|
jamie@107
|
199 }
|