MATLAB Filter Tool

 

Ryan McGee

 

RMM052000@utdallas.edu

 


 

MATLAB files: FD.m
Manual: FD_Manual.doc

ABSTRACT

 

The goal of this project was to create a MATLAB program to automate the design of notch filters, resonators, and oscillators.  Based on user input of desired parameters, MATLAB will generate the appropriate linear constant coefficient difference equation (LCCDE).  The LCCDE of each filter is output to the user along with a graph of the respective frequency response or waveform.

 

PROCEDURE

 

Setting the Sampling Frequency

For each filter the user is able to specify the sampling frequency, FS, and, F0, the frequency to be notched in the case of FIR or IIR notch filters, or resonated in the case of all-pole or pole-zero resonators.  For oscillators, the user can set the sampling and oscillating frequency.  The user will be warned if FS does not exceed twice F0, for this does not satisfy the Nyquist theorem and will result in an inaccurate response. 

 

Setting the Gain

Additionally for the notch filters and resonators, the user is allowed to specify the gain in dB at a particular frequency of the filter (FG).  FG is normalized by the sampling frequency and converted to radians to obtain w0.    The default gain at FG of each filter is computed and then normalized to obtain the user’s desired gain at FG. 

 

Obtaining the Impulse Response

To derive an impulse response for a filter, one must first plot the zeros of the filter on the unit circle (r = 1) in the complex z-plane.  The resulting z-domain equation can be easily converted to the discrete vector and made causal by multiplying by a power of z.  The IIR notch, all-pole, and pole-zero resonator all have poles lying at the same angle as their zeros but at distance of r < 1 from the origin.  Values of r closer to 1 (closer to each zero) will result in a narrower notch or resonator. 

 

The derivations for each filter were done by hand and vectors containing the n-domain values were entered into MATLAB.  Also, the user is prompted to enter a value of r for each filter and given restrictions (0 ≤ r < 1).

 

Generating the LCCDE

I derived by hand the LCCDE from each filter’s impulse response by converting from the z-domain to the discrete domain (n-domain).  I input the standard form of each LCCDE into MATLAB as a string that calls upon my impulse response vectors to obtain the proper coefficients.  The result is a neat printout of each particular filter’s LCCDE based on the user’s specified parameters.

 

The Oscillator

Specifying the gain of the oscillator is irrelevant in this case because the oscillator is a waveform generator rather than a filter.  The user is simply asked for the sampling frequency and oscillating frequency.  My program generates the appropriate waveform from the LCCDE of the oscillator. 

 

EXAMPLES OF RESULTS

 

FIR Notch

Choose one of the following or type 999 to quit.

 1. FIR Notch

 2. IIR Notch

 3. All-Pole Resonator

 4. Pole-Zero Resonator

 5. Oscillator

 1

Sampling Frequency: 400

Notch Frequency: 80

Frequency to Set Gain: 0

Gain (dB) at 0Hz: 0

 

LCCDE =

 

y(n) = 0.7236[1x(n) + -0.618x(n-1) + 1x(n-2)]

 

 

 

IIR Notch

Choose one of the following or type 999 to quit.

 1. FIR Notch

 2. IIR Notch

 3. All-Pole Resonator

 4. Pole-Zero Resonator

 5. Oscillator

 2

Sampling Frequency: 600

Notch Frequency: 60

r: .98

Frequency to Set Gain: 20

Gain (dB) at 20Hz: 10

 

LCCDE =

 

y(n) + -1.618y(n-1) + 0.9604y(n-2) = 2.801[x(n) + 1x(n-1) + x(n-2)]

 

 

 


All-Pole Resonator

Choose one of the following or type 999 to quit.

 1. FIR Notch

 2. IIR Notch

 3. All-Pole Resonator

 4. Pole-Zero Resonator

 5. Oscillator

 3

Sampling Frequency: 250

Resonating Frequency: 100

r: .95

Frequency to Set Gain: 0

Gain (dB) at 0Hz: 10

 

LCCDE =

 

y(n) + 1.537y(n-1) + 0.9025y(n-2) = 10.88x(n)

 

 

 

 

 


Pole-Zero Resonator

Choose one of the following or type 999 to quit.

 1. FIR Notch

 2. IIR Notch

 3. All-Pole Resonator

 4. Pole-Zero Resonator

 5. Oscillator

 4

Sampling Frequency: 900

Resonating Frequency: 70

r: .99

Frequency to Set Gain: 10

Gain (dB) at 10Hz: 5

 

LCCDE =

 

y(n) + -1.748y(n-1) + 0.9801y(n-2) = 2.894[x(n) - x(n-2)]

 

 


Oscillator

Choose one of the following or type 999 to quit.

 1. FIR Notch

 2. IIR Notch

 3. All-Pole Resonator

 4. Pole-Zero Resonator

 5. Oscillator

 5

Sampling Frequency: 500

Oscillating Frequency: 12

 

LCCDE =

 

y(n) + -1.977y(n-1) + y(n-2) = 0.1502x(n-1)

 


CONCLUSION

 

While the theory behind construction of digital filters can take some time to fully understand, it is no more difficult than the theory behind analog filters.  However, the main difference between analog and digital lies in the ease of implementation.  Whereas analog circuits must be physically constructed with parts lacking perfect tolerance, digital filters and oscillators can be more precisely constructed using relatively few lines of code and with no cost for parts (besides a computer). 
MATLAB CODE

 

%Filter Designer (FD.m)

 

choice = input('Choose one of the following or type 999 to quit.\n 1. FIR Notch \n 2. IIR Notch \n 3. All-Pole Resonator \n 4. Pole-Zero Resonator \n 5. Oscillator \n ');

 

if(choice == 1)

 

    %FIR notch filter

 

    FS = input('Sampling Frequency: ');

    F0 = input('Notch Frequency: ');

    if (F0 > FS/2)

        warnstr =['WARNING! The Sampling frequency is less than twice the notch frequency. Response will be inaccurate.']

    end

    FG = input('Frequency to Set Gain: ');

    if (FG == F0)

        warnstr =['WARNING! User should not set the gain of the notch frequency. Response will be inaccurate.']

    end

    fgstr = ['Gain (dB) at ' num2str(FG) 'Hz: '];

    FGAINdB = input(fgstr);

    FGAIN = 10^(FGAINdB/20);

   

    w0 = 2*pi*F0/FS;

    wg = 2*pi*FG/FS;

   

    GH = abs(1 - 2*cos(w0)*exp(-j*wg) + exp(-j*2*wg));

    G = FGAIN/GH;

   

    h = [1 -2*cos(w0) 1];

   

    freqz(G*h,1,[], FS);

   

    titlestr = ['FIR Notch Filter for ' num2str(F0) 'Hz'];

    title(titlestr)

   

    LCCDE = ['y(n) = ' num2str(G, 4) '[' num2str(h(1), 4) 'x(n) + ' num2str(h(2), 4) 'x(n-1) + ' num2str(h(3), 4) 'x(n-2)]']

 

elseif(choice == 2)

 

    %IIR Notch

 

    FS = input('Sampling Frequency: ');

    F0 = input('Notch Frequency: ');

    if (F0 > FS/2)

        warnstr =['WARNING! The Sampling frequency is less than twice the notch frequency. Response will be inaccurate.']

    end

    r = input('r: ');

    if (r >= 1 || r < 0)

        warnstr =['WARNING! r should be a positive value < 1']

    end

    FG = input('Frequency to Set Gain: ');

    if (FG == F0)

        warnstr =['WARNING! User should not set the gain of the notch frequency. Response will be inaccurate.']

    end

    fgstr = ['Gain (dB) at ' num2str(FG) 'Hz: '];

    FGAINdB = input(fgstr);

    FGAIN = 10^(FGAINdB/20);

   

    w0 = 2*pi*F0/FS;

    wg = 2*pi*FG/FS;

   

    bg = abs(1 - 2*cos(w0)*exp(-j*wg) + exp(-j*2*wg));

    ag = abs(1 - 2*cos(w0)*exp(-j*wg) + (r^2)*exp(-j*2*wg));

    GH = bg/ag;

    G = FGAIN/GH;

   

    b = [1 -2*cos(w0) 1];

    a = [1 -2*cos(w0) (r^2)];

   

    freqz(G*b,a,1024, FS);

    titlestr = ['IIR Notch Filter for ' num2str(F0) 'Hz and r = ' num2str(r)];

    title(titlestr)

   

    LCCDE = ['y(n) + ' num2str(b(2), 4) 'y(n-1) + ' num2str((r^2), 4) 'y(n-2) = ' num2str(G, 4) '[x(n) + ' num2str(b(1), 4) 'x(n-1) + x(n-2)]']

 

elseif(choice == 3)

 

    %All-Pole Resonator

 

    FS = input('Sampling Frequency: ');

    F0 = input('Resonating Frequency: ');

    if (F0 > FS/2)

        warnstr =['WARNING! The Sampling frequency is less than twice the resonating frequency. Response will be inaccurate.']

    end

    r = input('r: ');

    if (r >= 1 || r < 0)

        warnstr =['WARNING! r should be a positive value < 1']

    end

    FG = input('Frequency to Set Gain: ');

    fgstr = ['Gain (dB) at ' num2str(FG) 'Hz: '];

    FGAINdB = input(fgstr);

    FGAIN = 10^(FGAINdB/20);

   

    wr = 2*pi*F0/FS;

    if (r >= 0.9)

        w0 = wr;

    else

        w0 = acos((2*r*cos(wr))/(1 + r^2));

    end

   

    wg = 2*pi*FG/FS;

   

    ag = abs(1 - 2*r*cos(w0)*exp(-j*wg) + (r^2)*exp(-j*2*wg));

    GH = 1/ag;

    G = FGAIN/GH;

   

    a = [1 -2*r*cos(w0) (r^2)];

 

    freqz(G,a,[], FS);

    titlestr = ['All-Pole Resonator for ' num2str(F0) 'Hz and r = ' num2str(r)];

    title(titlestr)

 

    LCCDE = ['y(n) + ' num2str(a(2), 4) 'y(n-1) + ' num2str((r^2), 4) 'y(n-2) = ' num2str(G, 4) 'x(n)']

   

elseif(choice == 4)

 

    %Pole-Zero Resonator

 

    FS = input('Sampling Frequency: ');

    F0 = input('Resonating Frequency: ');

    if (F0 > FS/2)

        warnstr =['WARNING! The Sampling frequency is less than twice the resonating frequency. Response will be inaccurate.']

    end

    r = input('r: ');

    if (r >= 1 || r < 0)

        warnstr =['WARNING! r should be a positive value < 1']

    end

    FG = input('Frequency to Set Gain: ');

    if (FG == 0)

        warnstr =['WARNING! User should not set the DC (0Hz) gain. Response will be inaccurate.']

    end

    fgstr = ['Gain (dB) at ' num2str(FG) 'Hz: '];

    FGAINdB = input(fgstr);

    FGAIN = 10^(FGAINdB/20);

   

    wr = 2*pi*F0/FS;

    if (r >= 0.9)

        w0 = wr;

    else

        w0 = acos((2*r*cos(wr))/(1 + r^2));

    end

   

    wg = 2*pi*FG/FS;

   

    bg = abs(1 - exp(-j*2*wg));

    ag = abs(1 - 2*r*cos(w0)*exp(-j*wg) + (r^2)*exp(-j*2*wg));

    GH = bg/ag;

    G = FGAIN/GH;

   

    b = [1 0 -1];

    a = [1 -2*r*cos(w0) (r^2)];

   

    freqz(G*b,a,[], FS);

    titlestr = ['Pole-Zero Resonator for ' num2str(F0) 'Hz and r = ' num2str(r)];

    title(titlestr)

   

    LCCDE = ['y(n) + ' num2str(a(2), 4) 'y(n-1) + ' num2str((r^2), 4) 'y(n-2) = ' num2str(G, 4) '[x(n) - x(n-2)]']

 

elseif (choice == 5)

%Oscillator

 

    FS = input('Sampling Frequency: ');

    F0 = input('Oscillating Frequency: ');

    if (F0 > FS/2)

        warnstr =['WARNING! The Sampling frequency is less than twice the oscillating frequency. Waveform will be inaccurate.']

    end

   

    w0 = 2*pi*F0/FS;

   

    b = [0 sin(w0)];

    a = [1 -2*cos(w0) 1];

  

    LCCDE = ['y(n) + ' num2str(a(2), 4) 'y(n-1) + y(n-2) = ' num2str(b(2), 4) 'x(n-1)']

   

    x(1) = 1;

    x(2) = 0;

    y(1) = 0;

    y(2) = sin(w0)*x(1);

    for n = 3:FS;

        x(n) = 0;

        y(n) = 2*cos(w0)*y(n-1) - y(n-2) + sin(w0)*x(n-1);

    end

 

    t0 = 1:FS;

    t = t0/FS;

    plot(t, y)

    titlestr = [num2str(F0) 'Hz Oscillator'];

    title(titlestr)

    xlabel('Time (sec)')

    ylabel('Amplitude')

 

elseif (choice == 999)

    %do nothing and quit

else

   

    'Invalid Input.  Please enter a valid integer choice, 1-5 or type 999 to quit.'

    FD()

 

end

   

if (choice ~= 999)

    clear all

    FD()

end

 

clear all