Multiple Bandpass Filter Creation

34 views (last 30 days)
S
S on 21 Jan 2024
Commented: S on 24 Jan 2024
I am trying to make a cascade of bandpass filters. I want there to be 32 total filters covering the range of 50 to 8000. I am trying to do this efficiently by creating a variable for the upper and lower cutoff frequencies. How would I fix this so that the bpfilt cycles through all my CF1/CF2s in order? The goal would be to then put an input signal in and have it run through all the 32 filters in cascade. Thank you for your time!
close all
fs = 16e3;
range = [50 8000];
CF1=linspace(50, 8000, 32) -50;
CF2=linspace(50, 8000, 32) +50;
bpfilt = designfilt('bandpassfir', ...
'FilterOrder',20,'CutoffFrequency1',CF1, ...
'CutoffFrequency2',CF2,'SampleRate',fs);
freqz(bpfilt.Coefficients,1,[],fs)

Accepted Answer

Paul
Paul on 21 Jan 2024
Edited: Paul on 22 Jan 2024
fs = 16e3;
%range = [50 8000];
CF1=linspace(50, 8000, 32) -50;
CF2=linspace(50, 8000, 32) +50;
Can't use the first and last elements of CF1 and CF2 respectively. CF1(1) = 0, which is not a valid input for CutOffFrequency1. This issue could be dealt with by making the first filter a low pass. CF2(end) is greater than the Nyquist frequecy.
for ii = 1:numel(CF1)-2
bpfilt{ii} = designfilt( ...
'bandpassfir', ...
'FilterOrder',20, ...
'CutoffFrequency1',CF1(ii+1), ...
'CutoffFrequency2',CF2(ii+1), ...
'SampleRate',fs);
[h{ii},f] = freqz(bpfilt{ii}.Coefficients,1,4*8192,fs);
end
Frequency responsee of each filter
figure
subplot(211)
plot(f,db(abs([h{:}])));
subplot(212);
plot(f,180/pi*(angle([h{:}])));
Frequency response of cascaded filters in series; this doesn't look like very useful.
Edit: In fact, the values on the magnitude plot on are so small that they are probably rounding error and are effectively zero (in absolute value). Are you sure you want the filters cascaded?
figure
subplot(211)
plot(f,db(abs(prod([h{:}],2))));
subplot(212);
plot(f,180/pi*(angle(prod([h{:}],2))));
Unfortunately, digitalFilter objects can't be mulitplied.
In theory, the coefficients of each filter can be combined as follows into a single filter
b = 1;
for ii = 1:numel(bpfilt)
b = conv(b,bpfilt{ii}.Coefficients);
end
Compare the frequency response of the cascade to the cascade of the frequency responses
hcascade = freqz(b,1,f,fs);
figure
subplot(211)
hold on
plot(f,db(abs(prod([h{:}],2))));
plot(f,db(abs(hcascade)));
subplot(212);
hold on
plot(f,180/pi*(angle(prod([h{:}],2))));
plot(f,180/pi*angle(hcascade))
In practice, that doesn't look like such a good idea.
If going to pursue this path, it's probabably best to use a loop and filter the input in stages. That will work, in theory, for forward filtering. Not sure if that's appropriate for forward/backward filtering.
  13 Comments
Paul
Paul on 24 Jan 2024
The convention used by the documentation for that underbar is sometimes hard to understand (I get confused myself sometimes). In this case, that underbar means that you can replace the underbar with any of the arguments to freqz that precede n in any of the syntax cases above it. So I was using the syntax
[h,f] = freqz(b,a,n,fs)
In this problem, each bpfilt is a FIR filter. For the bpfilt FIR filter, the denominator is 1, hence the entry of 1 in the second argument in the call to freqz.
S
S on 24 Jan 2024
OH! That makes sense! Thank you for explaining!

Sign in to comment.

More Answers (0)

Categories

Find more on Digital and Analog Filters in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!