It is currently Sat Dec 16, 2017 7:41 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 98 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next
Author Message
PostPosted: Sat Jul 04, 2015 7:51 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
How do you design a filter via cascading other filters?


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 8:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19353
Location: NE Indiana, USA (NTSC)
The common IIR filter families are broken into second-order "biquad" sections, each of which has two poles and two zeroes. The output of each biquad is fed to the next biquad. It's like factoring a number into smaller primes for easier calculation.

As for cascading an elliptic with a Butterworth, this means you take the samples, pass them through the elliptic, and then pass the output of the elliptic through the Butterworth. This is called a "filter chain". And because biquads are linear, they commute, and I'm under the impression they can be processed in whatever order results in the least noise. This means you can decompose the elliptic and Butterworth filter into chains of biquad sections and then stick the biquads that form the Butterworth filter between the elliptic ones if you feel like it.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 8:26 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
I follow. But, what's the approach of designing each filter, knowing that they will be cascaded?

Also, is an 8th-order Butterworth equivalent to 4 biquad sections? Could 2 cascaded Butterworth filters do the job of the 8 biquad sections? And, if that is the case, what target parameters would I need?


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 9:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19353
Location: NE Indiana, USA (NTSC)
zeroone wrote:
I follow. But, what's the approach of designing each filter, knowing that they will be cascaded?

You get to design the gain and phase response appropriate to each section. For example, in a brick-wall low-pass filter, you want gain in the stopband to reduce a full-scale signal below one ulp (unit in the last place). For example, one ulp in a 16-bit LPCM signal is -90 dBFS (decibels below full scale), so you want about -90 dB of overall gain in the frequencies that would fold down to the audible range after decimation. But for a roll-off in the audible range, you don't want to mess with the phase too much, and Butterworth is fairly mild to phase.

Quote:
Also, is an 8th-order Butterworth equivalent to 4 biquad sections?

An 8th order Butterworth filter can be decomposed into four biquads. But two 4th order Butterworth filters will produce biquads with different parameters compared to one 8th order.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 10:25 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
tepples wrote:
For example, one ulp in a 16-bit LPCM signal is -90 dBFS (decibels below full scale), so you want about -90 dB of overall gain in the frequencies that would fold down to the audible range after decimation.


That is an incredible amount of frequency suppression, far better than the 8-th order Butterworth filter. I do not know how to put these filters together. From what I can find, all the mathematical packages that do this automatically use iterative approaches to working out the filter constants. Unfortunately, I don't have access to them and I probably wouldn't know what to do if I did :/


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 12:10 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6535
Location: Seattle
TI has a tool for designing/proofing digital filters as a series of biquads: http://www.ti.com/tool/coefficient-calc Unfortunately, it only goes up to 192kHz, but the convenient thing about digital filters is that all filter coefficients are relative to the sample rate, so you can just tell it to work at 179kHz and also divide all other frequencies by 10...

Converting an even-order filter to a series of biquads is just a matter of factoring out the transfer function into a series of (two poles and two zeroes). You should be able to coax maxima into doing that.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 12:56 pm 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
zeroone wrote:
all the mathematical packages that do this automatically use iterative approaches to working out the filter constants. Unfortunately, I don't have access to them

Sure you do. Check out GNU Octave.

Here's some code for designing a filter and converting it to second order sections. Use the coefficients (Bs and As) to implement each section as a transposed direct form II filter.

Code:
Fs = 1786840;
cutoff = 20000;
%[z, p, k] = ellip(16, .1, 90, cutoff/(Fs/2));
[z, p, k] = butter(16, cutoff/(Fs/2));
[sos, g] = zp2sos(z, p, k);

Bs = sos(:,1:3);
As = sos(:,4:6);
[nsec,temp]=size(sos);
nsamps = 16384;
x = g*[1,zeros(1,nsamps-1)];
for i=1:nsec
 x = filter(Bs(i,:),As(i,:),x);
end
X = fft(x);
f=[0:nsamps-1]*Fs/nsamps;
figure(1);
grid('on');
axis([0 Fs/2 -100 5]);
legend('off');
plot(f(1:nsamps/2),20*log10(X(1:nsamps/2)));

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 1:30 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
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.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 4:03 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6535
Location: Seattle
zeroone wrote:
fc = 24000; % Cut-off frequency (Hz)
fs = 19687500/11; % Sampling rate (Hz)
James was using a sample rate of 1786830 intentionally instead of the NTSC 1789772⁸/₁₁: the NTSC NES produces video at 60.1 Hz, not 60 Hz as the end-user's monitor does. If one wants to avoid visible tearing, you need to slow down the emulated NES by 1646ppm:

39375000÷11 Hz × 1½ ÷ (341×262-0.5) = 60.0988…
39375000÷11 Hz ÷ 2 × 60 ÷ 60.0988… = 1786830 Hz exactly

Similarly, setting the cut-off frequency at the Nyquist rate both 1- allows more aliasing and 2- in this case, is basically inaudible to anyone. (In practice, no-one above 20 can hear sounds above ~19kHz anyway). Using a lower cutoff with a more gradual slope reduces group delay—which, depending, may be audible.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 4:08 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
How did James get such a steep drop off slope in his graph?


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 5:58 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19353
Location: NE Indiana, USA (NTSC)
The steep slope is something you get with a high-order elliptic filter. It has ripple in the passband, ripple in the stop band, and general havoc with phase around the transition. That's why the transition is placed above the upper limit of adult human hearing, and why a gentler Butterworth rolloff is put in place to mask the ripple.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 7:12 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
Is it possible to decimate in stages? E.g. decimate from 1.79 MHz to 0.919 MHz, and from there, to 48000 Hz.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 7:20 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19353
Location: NE Indiana, USA (NTSC)
Yes, you can filter, decimate, filter, and decimate again, so long as frequencies above half the new frequency have been filtered out before each decimation. So you could generate samples from the APU at 894.9 kHz (every other CPU cycle), run a brick wall, downsample the result to 96 kHz, do further filtering, and decimate again to 48 kHz. Non-integer downsampling does require some interpolation, usually either linear or cubic.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 7:37 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6535
Location: Seattle
tepples wrote:
so long as frequencies above half the new frequency have been filtered out before each decimation.
It's even better than that: as long as any aliased content won't be in the band you ultimately want to keep.

For example, if decimating from 895kHz to 447kHz, it's fine as long as your stop band rejection is good enough in the range from 427kHz to the nyquist rate, because when you decimate by two the aliasing won't make an audible image. Similarly, if decimating directly from 895kHz to 224kHz, your stop band only really matters from 204kHz to 244kHz, and from 427kHz to nyquist.


Top
 Profile  
 
PostPosted: Sat Jul 04, 2015 7:51 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 753
Location: New York, NY
Quote:
It's even better than that: as long as any aliased content won't be in the band you ultimately want to keep.

For example, if decimating from 895kHz to 447kHz, it's fine as long as your stop band rejection is good enough in the range from 427kHz to the nyquist rate, because when you decimate by two the aliasing won't make an audible image. Similarly, if decimating directly from 895kHz to 224kHz, your stop band only really matters from 204kHz to 244kHz, and from 427kHz to nyquist.


If decimation were done in stages like that, with the goal of ultimately bringing it down to 48000 Hz, would it make any sense to not set the cutoff frequency at every stage to 20000 Hz, as opposed to just the final stage?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 98 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group