Some advice of DSP here...

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
zeroone
Posts: 933
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: Some advice of DSP here...

Post by zeroone »

How do you design a filter via cascading other filters?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Some advice of DSP here...

Post by tepples »

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

Re: Some advice of DSP here...

Post by zeroone »

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?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Some advice of DSP here...

Post by tepples »

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

Re: Some advice of DSP here...

Post by zeroone »

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 :/
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Some advice of DSP here...

Post by lidnariq »

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.
User avatar
James
Posts: 429
Joined: Sat Jan 22, 2005 8:51 am
Location: Chicago, IL
Contact:

Re: Some advice of DSP here...

Post by James »

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: Select all

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
User avatar
zeroone
Posts: 933
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: Some advice of DSP here...

Post by zeroone »

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: Select all

%[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: Select all

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.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Some advice of DSP here...

Post by lidnariq »

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

Re: Some advice of DSP here...

Post by zeroone »

How did James get such a steep drop off slope in his graph?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Some advice of DSP here...

Post by tepples »

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

Re: Some advice of DSP here...

Post by zeroone »

Is it possible to decimate in stages? E.g. decimate from 1.79 MHz to 0.919 MHz, and from there, to 48000 Hz.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Some advice of DSP here...

Post by tepples »

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.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Some advice of DSP here...

Post by lidnariq »

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

Re: Some advice of DSP here...

Post by zeroone »

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?
Post Reply