uploaded all materials

This commit is contained in:
2025-03-24 00:43:09 -04:00
commit f2fb36f646
78 changed files with 15606 additions and 0 deletions

View File

@ -0,0 +1,35 @@
function Hd = bandstop2500
%BANDSTOP2500 Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 9.9 and Signal Processing Toolbox 8.5.
% Generated on: 24-Mar-2021 17:32:55
% Elliptic Bandstop filter designed using FDESIGN.BANDSTOP.
% All frequency values are in Hz.
Fs = 8192; % Sampling Frequency
Fpass1 = 2000; % First Passband Frequency
Fstop1 = 2300; % First Stopband Frequency
Fstop2 = 2700; % Second Stopband Frequency
Fpass2 = 3000; % Second Passband Frequency
Apass1 = 0.5; % First Passband Ripple (dB)
Astop = 60; % Stopband Attenuation (dB)
Apass2 = 1; % Second Passband Ripple (dB)
match = 'both'; % Band to match exactly
% Construct an FDESIGN object and call its ELLIP method.
h = fdesign.bandstop(Fpass1, Fstop1, Fstop2, Fpass2, Apass1, Astop, ...
Apass2, Fs);
Hd = design(h, 'ellip', 'MatchExactly', match);
% Get the transfer function values.
[b, a] = tf(Hd);
% Convert to a singleton filter.
Hd = dfilt.df2(b, a);
% [EOF]

View File

@ -0,0 +1,131 @@
%% Lesson 7a. Designing filters the modern way
% * Learn how to use `filterDesigner`
% * Learn how to use `fdesign`
close all; clear; clc;
%% Filter Overview
% Remember order = # of delay elements, want to minimize to meet
% some spec.
%
% There are 4 main types of filters:
% * Lowpass - passes low frequencies through
% * Highpass - passes high frequencies through
% * Bandpass - passes a specific band
% * Bandstop - stops a specific band from going through
%
% There are four primary implementations of filters that optimize
% different properties:
% * Butterworth - maxflat passband, monotonic passband & stopband
% * Chebychev I - equiripple passband, monotonic stopband
% * Chebychev II - monotonic passband, equiripple stopband
% * Elliptic - minimum order, equiripple passband & stopband
%
% In this lesson, you will be able to very clearly see these
% properties and filter types!
%% Filter design (GUI)
% Note: Ask Prof. Keene about `filterDesigner`, it'll make him
% very happy.
filterDesigner; % then export to workspace as numerator and
% denominator (not SOS for now)
%% Applying a GUI-designed filter
% Note that if a filter is generated using a `filterDesigner` function,
% it will be a filter object. You can apply a filter object using the
% `filter()` function. If your filter is given as an impulse response, you
% can either use the `filter()` function or convolve the impulse response
% and the input signal.
% Load handel again
load handel;
% Get a generated filter (this should decimate a narrow frequency band
% centered at 2.5kHz, assuming a 8192Hz sampling frequency).
flt = bandstop2500;
% Perform the filter
y1 = filter(flt, y);
%% Filter design via `fdesign`
% Filter specifications
Fsample = 44100;
Apass = 1;
Astop = 80;
Fpass = 1e3;
Fstop = 1e4;
% Use the appropriate `fdesign.*` object to create the filter; in this case,
% we're designing a lowpass filter.
specs = fdesign.lowpass(Fpass, Fstop, Apass, Astop, Fsample);
% Note: the arguments to `fdesign.*` can be altered by passing in a SPEC option
% -- the following call to `fdesign.lowpass` will produce the same filter. If
% you want to do more complex stuff (like setting the 3 dB point directly or
% setting the filter order), you can change this argument. See `doc
% fdesign.lowpass` for more info.
equivalent_specs = fdesign.lowpass('Fp,Fst,Ap,Ast', ...
Fpass, Fstop, Apass, Astop, Fsample);
% For a given filter type, there are a myriad of different ways to design it
% depending on what properties you want out of the filter (equiripple
% passband/stopband, monotonic passband/stopband, minimum-order, max-flat,
% etc.), which our lowpass filter object supports.
%
% Note: `'SystemObject'` should be set to `true` by Mathworks' recommendation
% for these calls, even though they will often work without it.
designmethods(specs, 'SystemObject', true);
% There are also various options we can set when designing the filter. In this
% example, we'll tell it to match the passband amplitude exactly.
designoptions(specs, 'butter', SystemObject=true);
% Finally, let's make this thing!
butter_filter = design(specs, 'butter', ...
MatchExactly='passband', SystemObject=true);
%% Examining a filter
% Filters can be visualized with `fvtool`, drawing a nice box around the
% transition zone and lines at the edge frequencies & important amplitudes:
h = fvtool(butter_filter); % note no call to `figure`!
% `measure` is another way to check:
measurements = measure(butter_filter);
% `h` is a handle to the graphics object we've created with `fvtool`, and we
% can change its properties (listed with `get(h)`) if we wish:
h.FrequencyScale = 'Log';
ax = h.Children(15); % the axes object, found by looking at `h.Children`
ax.YLim = [-60 10]; % in dB
%% Using a filter
% Filter objects have a lot of methods to them (things like `freqz`, `impz`,
% `islinphase`, `isallpass`, etc -- check `methods(butter_filter)` if you want
% the list) that are rather useful. One method they *don't* have is `filter`,
% so if you want to apply a filter to a signal, you do it like this:
load handel; % of course; loads `y` and `Fs` into the workspace
y1 = butter_filter(y); % use like a function!
sound(y, Fs);
sound(y1, Fs);
%% Plotting the result
% Obtain the FFT of the original and the filtered signal.
shifted_fft_mag = @(sig, len) fftshift(abs(fft(sig, len))) / len;
N = 2^15;
S1 = shifted_fft_mag(y, N);
S2 = shifted_fft_mag(y1, N);
F = linspace(-Fsample/2, Fsample/2, N); % not quite accurate but close
% Plot the FFTs.
figure;
subplot(2, 1, 1);
plot(F, S1);
title 'Fourier Transform of Original Audio';
xlabel 'Frequency (Hz)';
ylabel 'Magnitude';
subplot(2, 1, 2);
plot(F, S2);
title 'Fourier Transform of Filtered Audio';
xlabel 'Frequency (Hz)';
ylabel 'Magnitude';

View File

@ -0,0 +1,103 @@
%% Lesson 7c. Designing filters the old fashioned way
% (notes kept for historical reasons; the new notes are in `filter_design.m`.
%
% * Learn how to use the `filterDesigner` GUI.
% * Learn how to manually design a filter.
clc; clear; close all;
%% Filter Overview
% Remember order = # of delay elements, want to minimize to meet
% some spec.
%
% There are 4 main types of filters:
% * Lowpass - passes low frequencies through
% * Highpass - passes high frequencies through
% * Bandpass - passes a specific band
% * Bandstop - stops a specific band from going through
%
% There are four primary implementations of filters that optimize
% different properties:
% * Butterworth - maxflat passband, monotonic passband & stopband
% * Chebychev I - equiripple passband, monotonic stopband
% * Chebychev II - monotonic passband, equiripple stopband
% * Elliptic - minimum order, equiripple passband & stopband
%
% In this lesson, you will be able to very clearly see these
% properties and filter types!
%% Filter Design (GUI)
% Note: Ask Prof. Keene about `filterDesigner`, it'll make him
% very happy.
filterDesigner; % then export to workspace as numerator and
% denominator (not SOS for now)
%% Filter Design (Code)
% Manually specify specifications
Fs = 44100;
Apass = 1;
Astop = 80;
Fpass = 1e3;
Fstop = 1e4;
wpass = Fpass / (Fs/2); % normalized to nyquist freq.
wstop = Fstop / (Fs/2); % normalized to nyquist freq.
% Compute the minimum order for Butterworth filter
% that meets the specifications.
% Alternatively, see `butter1ord`, `cheby1ord`,
% `cheby2ord`, `ellipord`.
n = buttord(wpass, wstop, Apass, Astop);
% Generate Butterworth filter with order `n` (which is
% designed to meet the specification).
% Alternatively, see `cheby1`, `cheby2`, `ellip`.
[b, a] = butter(n, wpass);
[H, W] = freqz(b, a);
% Plot the frequency response. (At this point, recall that
% the frequency response is the FFT of the impulse response.
% Can you generate the frequency response without using
% the `freqz` function (instead using the `impz` and `fft`
% functions)?
f = W .* Fs/(2*pi);
figure;
semilogx(f, 20*log10(abs(H)));
xlim([1e2 1e5]);
ylim([-100 5]);
grid on;
title 'Butterworth Lowpass Filter';
xlabel 'Frequency (Hz)';
ylabel 'Magnitude (dB)';
%% Applying a filter
% Note that if a filter is generated using a `filterDesigner` function,
% it will be a filter object. You can apply a filter object using the
% `filter()` function. If your filter is given as an impulse response, you
% can either use the `filter()` function or convolve the impulse response
% and the input signal.
% Load handel again
load handel;
% Get a generated filter (this should decimate a narrow frequency band
% centered at 2.5kHz, assuming a 8192Hz sampling frequency).
flt = bandstop2500;
% Perform the filter
y1 = filter(flt, y);
%% How does it sound now?
sound(y1, Fs);
%% Plotting the result
% Obtain the FFT of the filtered signal.
N = 2^15;
S = fft(y1, N);
S = fftshift(abs(S)) / N;
F = linspace(-Fs/2, Fs/2, N);
% Plot the FFT.
figure;
plot(F, S);
title 'Fourier Transform of Audio';
xlabel 'Frequency (Hz)';
ylabel 'Magnitude';

View File

@ -0,0 +1,93 @@
%% Lesson 7c. Transfer function objects
close all; clear; clc;
%% Transfer function overview
% Transfer functions are abstract representations of LTI systems in terms of
% rational functions (numerator and denominator). We used to work with transfer
% functions in terms of MATLAB-style polynomials, but Mathworks has come up
% with a new, supposedly improved way: transfer function objects! These are
% created via `tf` in a variety of ways. For more info, see Mathworks'
% documentation -- these models are most helpful when working with cascades of
% systems, such as for controls modeling.
%% Digital transfer function objects
% To create a digital tf. object, specify a numerator, denominator, and
% sampling time (which may be set to -1 if you want to leave it undefined). The
% numerator and denominator are specified in decreasing power order, with s^0
% or z^0 on the right.
dig_num = [1]; % 1z = 1
dig_den = [2 -1]; % 2z¹ - 1z = 2z - 1
timestep = 0.1; % 0.1 s
dig_sys = tf(dig_num, dig_den, timestep);
%% Analog transfer function objects
% Analog transfer functions are created the same way as digital ones, just
% without the timestep.
an_num = [1 -1]; % 1s¹ - 1s = 1s - 1
an_den = [1 2 1]; % s² + 2s + 1
an_sys = tf(an_num, an_den);
%% Alternate ways of specifying
% MATLAB provides a syntax for creating transfer functions out of coded
% rational expressions, as this can be clearer:
s = tf('s'); % create an s variable that may then be used mathematically
an_sys_2 = (s - 1)/(s + 1)^2; % same as above
%% Investigating the transfer function
% One property of interest is the step response, which we can view thus:
figure;
stepplot(an_sys);
% MATLAB has a built-in function to get a Bode plot, too (though you should
% modify this in post if you want to highlight specific details in the plot).
figure;
bodeplot(an_sys);
%% One application
% This example is stolen from Mathworks' doc page "Control System Modeling with
% Model Objects," as it's an interesting perspective on what you can do with
% these. In it, we model the following system:
%
% x ---> F(s) ---> +( ) ---> C(s) ---> G(s) ---+---> y
% - |
% ^ |
% \---------- S(s) ---------/
% specify the components of a system
G = zpk([], [-1, -1], 1); % no zeroes, double pole at -1, analog
C = pid(2, 1.3, 0.3, 0.5); % PID controller object
S = tf(5, [1 4]);
F = tf(1, [1 1]);
% find the open-loop transfer function (by breaking the loop at the subtract)
open_loop = F*S*G*C; % multiplication in the "frequency" domain
% check out where the poles & zeroes are
figure;
pzplot(open_loop);
title('Open loop pole/zero plot');
xlim([-6 1]);
ylim([-2 2]);
% see what this thing does with a step input
figure;
stepplot(open_loop);
title('Open-loop system step response');
% note that this is *not* stable with a step input, as the PID controller loses
% its shit!
% find the closed-loop, whole_system response using `feedback` to specify a
% feedback connection
full_system = F*feedback(G*C, S);
% see what this thing looks like now in the s-plane
figure;
pzplot(full_system);
title('Full system pole/zero plot');
xlim([-6 1]);
ylim([-2 2]);
% now stable with a step input, as we have feedback
figure;
stepplot(full_system);
title('Full system step response');