jamie@107
|
1 /* libxtract feature extraction library
|
jamie@107
|
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@107
|
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@107
|
27 void gauss(float *window, const int N, const float sd){
|
jamie@107
|
28
|
jamie@107
|
29 int n;
|
jamie@107
|
30 const float M = N - 1;
|
jamie@107
|
31 float num,
|
jamie@107
|
32 den,
|
jamie@107
|
33 exponent;
|
jamie@107
|
34
|
jamie@107
|
35 for (n = 0; n < N; n++) {
|
jamie@107
|
36
|
jamie@107
|
37 num = n - M / 2.f;
|
jamie@107
|
38 den = sd * M / 2.f;
|
jamie@107
|
39
|
jamie@107
|
40 exponent = -0.5 * powf(num / den, 2);
|
jamie@107
|
41
|
jamie@107
|
42 window[n] = exp(exponent);
|
jamie@107
|
43
|
jamie@107
|
44 }
|
jamie@107
|
45 }
|
jamie@107
|
46
|
jamie@107
|
47 void hamming(float *window, const int N){
|
jamie@107
|
48
|
jamie@107
|
49 int n;
|
jamie@107
|
50 const float M = N - 1;
|
jamie@107
|
51
|
jamie@107
|
52 for (n = 0; n < N; n++)
|
jamie@107
|
53 window[n] = 0.53836 - (0.46164 * cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
54
|
jamie@107
|
55 }
|
jamie@107
|
56
|
jamie@107
|
57 void hann(float *window, const int N){
|
jamie@107
|
58
|
jamie@107
|
59 int n;
|
jamie@107
|
60 const float M = N - 1;
|
jamie@107
|
61
|
jamie@107
|
62 for (n = 0; n < N; n++)
|
jamie@107
|
63 window[n] = 0.5 * (1.0 - cosf(2.0 * PI * (float)n / M));
|
jamie@107
|
64
|
jamie@107
|
65 }
|
jamie@107
|
66
|
jamie@107
|
67 void bartlett(float *window, const int N){
|
jamie@107
|
68
|
jamie@107
|
69 int n;
|
jamie@107
|
70 const float M = N - 1;
|
jamie@107
|
71
|
jamie@107
|
72 for (n = 0; n < N; n++)
|
jamie@107
|
73 window[n] = 2.f / M * (M / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
74
|
jamie@107
|
75 }
|
jamie@107
|
76
|
jamie@107
|
77 void triangular(float *window, const int N){
|
jamie@107
|
78
|
jamie@107
|
79 int n;
|
jamie@107
|
80 const float M = N - 1;
|
jamie@107
|
81
|
jamie@107
|
82 for (n = 0; n < N; n++)
|
jamie@107
|
83 window[n] = 2.f / N * (N / 2.f - fabsf(n - M / 2.f));
|
jamie@107
|
84 }
|
jamie@107
|
85
|
jamie@107
|
86 void bartlett_hann(float *window, const int N){
|
jamie@107
|
87
|
jamie@107
|
88 int n;
|
jamie@107
|
89 const float M = N - 1,
|
jamie@107
|
90 a0 = 0.62,
|
jamie@107
|
91 a1 = 0.5,
|
jamie@107
|
92 a2 = 0.38;
|
jamie@107
|
93 float term1 = 0.f,
|
jamie@107
|
94 term2 = 0.f;
|
jamie@107
|
95
|
jamie@107
|
96 for (n = 0; n < N; n++){
|
jamie@107
|
97
|
jamie@107
|
98 term1 = a1 * fabsf(n / M - 0.5);
|
jamie@107
|
99 term2 = a2 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
100
|
jamie@107
|
101 window[n] = a0 - term1 - term2;
|
jamie@107
|
102 }
|
jamie@107
|
103 }
|
jamie@107
|
104
|
jamie@107
|
105 void blackman(float *window, const int N){
|
jamie@107
|
106
|
jamie@107
|
107 int n;
|
jamie@107
|
108 const float M = N - 1,
|
jamie@107
|
109 a0 = 0.42,
|
jamie@107
|
110 a1 = 0.5,
|
jamie@107
|
111 a2 = 0.08;
|
jamie@107
|
112 float term1 = 0.f,
|
jamie@107
|
113 term2 = 0.f;
|
jamie@107
|
114
|
jamie@107
|
115 for (n = 0; n < N; n++) {
|
jamie@107
|
116
|
jamie@107
|
117 term1 = a1 * cosf(2.0 * PI * (float)n / M);
|
jamie@107
|
118 term2 = a2 * cosf(4.0 * PI * (float)n / M);
|
jamie@107
|
119
|
jamie@107
|
120 window[n] = a0 - term1 + term2;
|
jamie@107
|
121 }
|
jamie@107
|
122 }
|
jamie@107
|
123
|
jamie@107
|
124 #define BIZ_EPSILON 1E-21 // Max error acceptable
|
jamie@107
|
125
|
jamie@107
|
126 /* Based on code from mplayer window.c, and somewhat beyond me */
|
jamie@107
|
127 float besselI0(float x){
|
jamie@107
|
128
|
jamie@107
|
129 float temp;
|
jamie@107
|
130 float sum = 1.0;
|
jamie@107
|
131 float u = 1.0;
|
jamie@107
|
132 float halfx = x/2.0;
|
jamie@107
|
133 int n = 1;
|
jamie@107
|
134
|
jamie@107
|
135 do {
|
jamie@107
|
136
|
jamie@107
|
137 temp = halfx/(float)n;
|
jamie@107
|
138 u *=temp * temp;
|
jamie@107
|
139 sum += u;
|
jamie@107
|
140 n++;
|
jamie@107
|
141
|
jamie@107
|
142 } while (u >= BIZ_EPSILON * sum);
|
jamie@107
|
143
|
jamie@107
|
144 return(sum);
|
jamie@107
|
145
|
jamie@107
|
146 }
|
jamie@107
|
147
|
jamie@107
|
148 void kaiser(float *window, const int N, const float alpha){
|
jamie@107
|
149
|
jamie@107
|
150 int n;
|
jamie@107
|
151 const float M = N - 1;
|
jamie@107
|
152 float num;
|
jamie@107
|
153
|
jamie@107
|
154 for (n = 0; n < N; n++) {
|
jamie@107
|
155
|
jamie@107
|
156 num = besselI0(alpha * sqrtf(1.0 - powf((2.0 * n / M - 1), 2)));
|
jamie@107
|
157 window[n] = num / besselI0(alpha);
|
jamie@107
|
158
|
jamie@107
|
159 }
|
jamie@107
|
160 }
|
jamie@107
|
161
|
jamie@107
|
162 void blackman_harris(float *window, const int N){
|
jamie@107
|
163
|
jamie@107
|
164 int n;
|
jamie@107
|
165 const float M = N - 1,
|
jamie@107
|
166 a0 = 0.35875,
|
jamie@107
|
167 a1 = 0.48829,
|
jamie@107
|
168 a2 = 0.14128,
|
jamie@107
|
169 a3 = 0.01168;
|
jamie@107
|
170 float term1 = 0.f,
|
jamie@107
|
171 term2 = 0.f,
|
jamie@107
|
172 term3 = 0.f;
|
jamie@107
|
173
|
jamie@107
|
174 for (n = 0; n < N; n++) {
|
jamie@107
|
175
|
jamie@107
|
176 term1 = a1 * cosf(2.0 * PI * n / M);
|
jamie@107
|
177 term2 = a2 * cosf(4.0 * PI * n / M);
|
jamie@107
|
178 term3 = a3 * cosf(6.0 * PI * n / M);
|
jamie@107
|
179
|
jamie@107
|
180 window[n] = a0 - term1 + term2 - term3;
|
jamie@107
|
181 }
|
jamie@107
|
182 }
|