[sdiy] Digital interpolation filtering

Eric Brombaugh ebrombaugh1 at cox.net
Sun May 31 16:56:32 CEST 2009

On May 31, 2009, at 2:42 AM, Tom Wiltshire wrote:

> I don't have any good tools for simulation, and mostly use PHP  
> scripts (yeah, really!) to do stuff that Matlab probably does better.

:) - well, we all use what we're most familiar with. Nothing wrong  
with using any language you've got handy for doing research, but some  
tools fit the job better than others. The main advantage of using  
something like Matlab/Scilab/Mathcad, etc is that a lot of the low- 
level operations are already there in the language. Stuff like  
plotting, convolution, even basic filter design are simple function  
calls. This means you'll spend less time trying to get the tedious  
stuff working and make faster progress toward the main goal.

For example, suppose you wanted to generate a set of FIR filter  
coefficients and plot the frequency response. In Octave, I'd do it  
like this:

  b = remez(35, [0 .14 .22 1], [1 1 0 0]);
  freqz(b, 1);

The first line uses the Parks-McClellan / Remez Exchange algorithm to  
optimize a set of FIR coefficients. The parameters of the function are  
(n, f, a), where n is the number of filter taps minus one, f is a  
vector (array) of corner frequencies and a is a vector of weights. In  
this case I've asked it to set the passband (a = 1) from DC to  
0.14*Nyquist and the stopband (a = 0) from 0.22*Nyquist to Nyquist.  
This gives me a filter with roughly 1/6 passband.

The second line tells Octave to plot the discrete-time frequency  
response of the linear system with numerator equal to the coefficients  
I just generated and denominator of 1 (an FIR filter has no feedback,  
so the denominator is always 1). The result is a graphical plot   
showing the passband ripple, stopband rejection and phase vs frequency.

Just a bit quicker than coding all that up at a lower level.

> The code I use to generate the impulse response has a variable for  
> the number of taps, and then stretches a raised cosine window to  
> that size. There's then also a variable for the relative frequency  
> of the sinc function (eg 1=same frequency as the raised cosine, from  
> -pi to pi, 4=4 times the freq -4pi to +4pi, etc).
> I've found that altering these two parameters seems to change the  
> cutoff frequency and response, but I've got no handle on how  
> exactly. I've simply plugged some numbers in and then had a look to  
> see what the output looks like. With certain sets of values I can  
> get good looking bandlimited square waves out, so I figure it's  
> working. But I have no idea when I've got the "right" coefficients,  
> or what exactly the response of the filter is. It's all done by eye  
> currently!

It's hard for me to tell, but it seems that there are a few concepts  
being confused here. While you mention a raised cosine window, you  
also talk about a sinc function. It sounds like you're trying to use a  
filter design technique called windowing, where a frequency response  
is constructed (often using a raised cosine or other window type) and  
processed through an inverse FFT to derive the corresponding impulse  
response. In this approach one usually has only indirect control over  
the period of the resulting sinc pulse because the input to the IFFT  
entirely determines the characteristics of the output.

Alternatively, it may be that you're working entirely in the time  
domain but just windowing a sinc function with a raised cosine in  
order to chop it down to fit into the available taps. This is an  
approach to filter design that I'm not familiar with - it may work,  
but it seems to me that the interrelation of the window length, the  
interval of the raised cosine and the sinc characteristics would be  
extremely non-intuitive. Add to that the fact that you don't yet have  
a way to directly inspect the frequency response of the result and I  
can see how this could be pretty confusing.

I'd recommend that you code up some method of viewing the frequency  
response - use an FFT to process the coefficients you've created, plot  
the magnitude and see how changing the variables to your coefficient  
generation code affects the result. Building up some intuition about  
how they interact is critical to making progress.


More information about the Synth-diy mailing list