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