Can you walk me through what some of this code does? Does the code below cascade an Elliptic filter and a Butterworth filter each of order 16? Why are you dividing the input sampling frequency by 2?
Code:
%[z, p, k] = ellip(16, .1, 90, cutoff/(Fs/2));
[z, p, k] = butter(16, cutoff/(Fs/2));
Edit: I downloaded it and I am starting to suspect that % means comment. Is a 16th-order Butterworth filter sufficient for this? Did you use Fs/2 because you are sampling at every 2 CPU cycles?
Edit 2:
Here's the result. That doesn't look quite right to me.
Edit 3: Starting to understand this
Edit 4: I modified your code slightly:
Code:
fc = 24000; % Cut-off frequency (Hz)
fs = 19687500/11; % Sampling rate (Hz)
order = 8; % Filter order
[B,A] = butter(order,2*fc/fs); % [0:pi] maps to [0:1] here
[sos,g] = tf2sos(B,A)
Bs = sos(:,1:3); % Section numerator polynomials
As = sos(:,4:6); % Section denominator polynomials
[nsec,temp] = size(sos);
nsamps = 4096;
x = g*[1,zeros(1,nsamps-1)];
for i=1:nsec
x = filter(Bs(i,:),As(i,:),x);
end
figure(2);
X=fft(x);
f = [0:nsamps-1]*fs/nsamps; grid('on');
axis([0 50000 -100 5], "manual"); legend('off');
plot(f(1:nsamps/2),20*log10(X(1:nsamps/2)));
This assumes sampling at the NTSC CPU frequency and a cutoff of 24000 Hz using an 8th-order Butterworth filter.
Here are the results. They are consistent with
my implementation. However, when I set the order higher than 12, Octave seems to produce erroneous results likely due to numerical precision similar to the problems with my implementation. I have yet to figure out how to increase the precision or how to display more decimal places.
In any case, you can see that it drops 10 dB roughly every 10 KHz. Is that slope steep enough to do the job? I though it has to be much, much steeper.