DIGITAL FILTER DESIGN
Window Method of FIR Filter Design
The basic idea behind the Window method of filter design is that the ideal frequency response of the desired filter is equal to 1 for all the pass band frequencies, and equal to 0 for all the stop band frequencies, then the filter impulse response is obtained by taking the Discrete Fourier Transform (DFT) of the ideal frequency response. Unfortunately, the filter response would be infinitely long since it has to reproduce the infinitely steep discontinuities in the ideal frequency response at the band edges. To create a Finite Impulse Response (FIR) filter, the time domain filter coefficients must be restricted in number by multiplying by a window function of a finite width. The simplest window function is the rectangular window which corresponds to truncating the sequence after a certain number of terms.
The effect of time domain windows on the resulting frequency spectrum is discussed in the Spectrum Analyser page. Rectangular windowing the time domain will result in a frequency spectrum pass band width close to the desired value but with side lobes appearing at the pass band edges. To suppress the side lobes and make the filter frequency response approximate more closely to the ideal, the width of the window must be increased and the window function tapered down to zero at the ends. This will increase the width of the transition region, between the pass and stop bands, but will lower the side lobe levels outside the pass band.
Kaiser-Bessel Window
The Kaiser-Bessel window provides a simple to calculate set of window coefficients, whose parameters can be adjusted to produce the desired maximum side lobe levels for the near minimal filter length. To demonstrate the power and simplicity of this technique the Kaiser filter generator is shown below. Simply set the sample rate and the type of filter desired, low pass, band pass or high pass, then set the frequency values of the edges of the filter and the minimum attenuation that is required in the stop band. Then press the "CALC FILTER" button, the filter coefficients are calculated, and their graph drawn along with the frequency response of the filter. The actually algorithms and the JavaScript code to implement them are presented at the bottom of the page.
|
|
Kaiser FIR Design
|
|
|
FIR Listing
|
Kaiser-Bessel Filter Design Source Code
The formulae used in this FIR generator are taken from the paper by J. F. Kaiser, “Nonrecursive digital filter design using I0-sinh window function”. In this paper Kaiser presented empirical formulae for calculating the shape parameter of the Kaiser-Bessel window required to achieve the required stop band side lode attenuation.
The values of window shape parameter
needed to achieve the required attenuation Att may be calculated from:
The relation between the transition bandwidth dw, and the filter length M, is given by:
The formula to actually generate the Kaiser -Bessel window coefficients is as follows:
where:
is the number of points in the filter
![]()
is the Kaiser-Bessel window shape factor
is the
order Bessel function of the first kind.
The two cut off frequencies entered in the filter design determine shape of the impulse response of the ideal filter. This sinc function may be calculated analytically and then sampled. The formulae for this impulse response is:
Hence the required filter coefficients are given by windowing the ideal impulse response A[], by the Kaiser-Bessel window w[]:
The JavaScript code fragments to implement these formulae are shown below. The symmetry of the window function about the center point (j=Np) means that the window coefficients need only be calculated for 0<j<=Np.
JavaScript code to calculate the impulse response of the ideal filter.
A[0] = 2*(Fb-Fa)/Fs;
for(j=1; j<=Np; j++)
A[j] = (Math.sin(2*pi*j*Fb/Fs)-Math.sin(2*pi*j*Fa/Fs))/(pi*j);
The JavaScript code to calculate the desired shape Kaiser-Bessel window.
if (Att<21)
Alpha = 0;
else if (Att>50)
Alpha = 0.1102*(Att-8.7);
else
Alpha = 0.5842*Math.pow((Att-21), 0.4)+0.07886*(Att-21);
// Window the ideal response with the Kaiser-Bessel window
Inoalpha = Ino(Alpha);
for(j=0; j<=Np; j++)
w[j] = Ino(Alpha*Math.sqrt(1-(j*j/(Np*Np))))/Inoalpha;
The code to generate the zeroth order Bessel function used in the code above is:
function Ino(x)
{
// This function calculates the zero<sup>th</sup> order Bessel function
var d = 0;
var ds = 1;
var s = 1;
do
{
d += 2;
ds *= x*x/(d*d);
s += ds;
}
while (ds > s*1e-6);
return s;
}
These algorithms are all that is needed to generate the filter coefficients for "low pass", "high pass" and "band pass" filters. The "band stop" filter type requires one additional manipulation. The coefficients start out the same as the equivalent "band pass" filter but then the center coefficient H[Np], is replaced with 1-H[Np], and all the other coefficients are inverted H[j] = -H[j].
The complete JavaScript source code of the functions is all in the file dspUtils-04.js
