1 /*=============================================================================
3 // This software has been released under the terms of the GNU General Public
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
8 //=============================================================================
11 /* Calculates a number of window functions. The following window
12 functions are currently implemented: Boxcar, Triang, Hanning,
13 Hamming, Blackman, Flattop and Kaiser. In the function call n is
14 the number of filter taps and w the buffer in which the filter
15 coefficients will be stored.
25 // w buffer for the window parameters
27 void af_window_boxcar(int n
, FLOAT_TYPE
* w
)
30 // Calculate window coefficients
37 // Triang a.k.a Bartlett
42 // w = 1.0 - ---------------
45 // w buffer for the window parameters
47 void af_window_triang(int n
, FLOAT_TYPE
* w
)
49 FLOAT_TYPE k1
= (FLOAT_TYPE
)(n
& 1);
50 FLOAT_TYPE k2
= 1/((FLOAT_TYPE
)n
+ k1
);
51 int end
= (n
+ 1) >> 1;
54 // Calculate window coefficients
55 for (i
=0 ; i
<end
; i
++)
56 w
[i
] = w
[n
-i
-1] = (2.0*((FLOAT_TYPE
)(i
+1))-(1.0-k1
))*k2
;
63 // w = 0.5 - 0.5*cos(------), where 0 < k <= N
66 // w buffer for the window parameters
68 void af_window_hanning(int n
, FLOAT_TYPE
* w
)
71 FLOAT_TYPE k
= 2*M_PI
/((FLOAT_TYPE
)(n
+1)); // 2*pi/(N+1)
73 // Calculate window coefficients
75 *w
++ = 0.5*(1.0 - cos(k
*(FLOAT_TYPE
)(i
+1)));
81 // w(k) = 0.54 - 0.46*cos(------), where 0 <= k < N
85 // w buffer for the window parameters
87 void af_window_hamming(int n
,FLOAT_TYPE
* w
)
90 FLOAT_TYPE k
= 2*M_PI
/((FLOAT_TYPE
)(n
-1)); // 2*pi/(N-1)
92 // Calculate window coefficients
94 *w
++ = 0.54 - 0.46*cos(k
*(FLOAT_TYPE
)i
);
100 // w(k) = 0.42 - 0.5*cos(------) + 0.08*cos(------), where 0 <= k < N
104 // w buffer for the window parameters
106 void af_window_blackman(int n
,FLOAT_TYPE
* w
)
109 FLOAT_TYPE k1
= 2*M_PI
/((FLOAT_TYPE
)(n
-1)); // 2*pi/(N-1)
110 FLOAT_TYPE k2
= 2*k1
; // 4*pi/(N-1)
112 // Calculate window coefficients
114 *w
++ = 0.42 - 0.50*cos(k1
*(FLOAT_TYPE
)i
) + 0.08*cos(k2
*(FLOAT_TYPE
)i
);
120 // w(k) = 0.2810638602 - 0.5208971735*cos(------) + 0.1980389663*cos(------), where 0 <= k < N
124 // w buffer for the window parameters
126 void af_window_flattop(int n
,FLOAT_TYPE
* w
)
129 FLOAT_TYPE k1
= 2*M_PI
/((FLOAT_TYPE
)(n
-1)); // 2*pi/(N-1)
130 FLOAT_TYPE k2
= 2*k1
; // 4*pi/(N-1)
132 // Calculate window coefficients
134 *w
++ = 0.2810638602 - 0.5208971735*cos(k1
*(FLOAT_TYPE
)i
)
135 + 0.1980389663*cos(k2
*(FLOAT_TYPE
)i
);
138 /* Computes the 0th order modified Bessel function of the first kind.
139 // (Needed to compute Kaiser window)
141 // y = sum( (x/(2*n))^2 )
144 #define BIZ_EPSILON 1E-21 // Max error acceptable
146 static FLOAT_TYPE
besselizero(FLOAT_TYPE x
)
149 FLOAT_TYPE sum
= 1.0;
151 FLOAT_TYPE halfx
= x
/2.0;
155 temp
= halfx
/(FLOAT_TYPE
)n
;
159 } while (u
>= BIZ_EPSILON
* sum
);
167 // w buffer for the window parameters
168 // b beta parameter of Kaiser window, Beta >= 1
170 // Beta trades the rejection of the low pass filter against the
171 // transition width from passband to stop band. Larger Beta means a
172 // slower transition and greater stop band rejection. See Rabiner and
173 // Gold (Theory and Application of DSP) under Kaiser windows for more
174 // about Beta. The following table from Rabiner and Gold gives some
175 // feel for the effect of Beta:
177 // All ripples in dB, width of transition band = D*N where N = window
180 // BETA D PB RIP SB RIP
181 // 2.120 1.50 +-0.27 -30
182 // 3.384 2.23 0.0864 -40
183 // 4.538 2.93 0.0274 -50
184 // 5.658 3.62 0.00868 -60
185 // 6.764 4.32 0.00275 -70
186 // 7.865 5.0 0.000868 -80
187 // 8.960 5.7 0.000275 -90
188 // 10.056 6.4 0.000087 -100
190 void af_window_kaiser(int n
, FLOAT_TYPE
* w
, FLOAT_TYPE b
)
193 FLOAT_TYPE k1
= 1.0/besselizero(b
);
194 int k2
= 1 - (n
& 1);
195 int end
= (n
+ 1) >> 1;
198 // Calculate window coefficients
199 for (i
=0 ; i
<end
; i
++){
200 tmp
= (FLOAT_TYPE
)(2*i
+ k2
) / ((FLOAT_TYPE
)n
- 1.0);
201 w
[end
-(1&(!k2
))+i
] = w
[end
-1-i
] = k1
* besselizero(b
*sqrt(1.0 - tmp
*tmp
));