DSPRelated.com
Forums

Implementing cascade IIR filters

Started by kmap June 7, 2006
Dear comp.dsp,

I am just beginning my foray into practical DSP after learning the
bookish stuff in class. To try out various things, I manipulating wave
files in C,  and in parallel, trying to make XMMS (http://www.xmms.org)
effect plugins to get the effect in real time.

My query is about IIR filtering. What is the best way to implement an
IIR filter, assuming that I get data in blocks of, say 1024 samples? To
filter, I need to maintain state information, and I have several
filters in cascade. Right now, what I am doing is:

1. Use pen and paper to get the difference equation to implement the
filter. Is pretty clumsy when I have several filters in cascade, but I
manage to get it right in a few attempts :-)

2. Maintain a buffer just large enough to hold the "most backward"
input and output samples I need, and find the current output. I make
sure that the buffer behaves like a FIFO queue.

Now, to code this is quite cumbersome, but the idea is straightforward,
and I get what I want. What I would like to know is, whether there is a
less clumsy and/or more efficient way of doing this. Efficient, I guess
this would be as efficient as any other method, but can it be made less
clumsy?

Thanks.

Kumar

kmap wrote:
> Dear comp.dsp, > > I am just beginning my foray into practical DSP after learning the > bookish stuff in class. To try out various things, I manipulating wave > files in C, and in parallel, trying to make XMMS (http://www.xmms.org) > effect plugins to get the effect in real time. > > My query is about IIR filtering. What is the best way to implement an > IIR filter, assuming that I get data in blocks of, say 1024 samples? To > filter, I need to maintain state information, and I have several > filters in cascade. Right now, what I am doing is: > > 1. Use pen and paper to get the difference equation to implement the > filter. Is pretty clumsy when I have several filters in cascade, but I > manage to get it right in a few attempts :-) > > 2. Maintain a buffer just large enough to hold the "most backward" > input and output samples I need, and find the current output. I make > sure that the buffer behaves like a FIFO queue. > > Now, to code this is quite cumbersome, but the idea is straightforward, > and I get what I want. What I would like to know is, whether there is a > less clumsy and/or more efficient way of doing this. Efficient, I guess > this would be as efficient as any other method, but can it be made less > clumsy? > > Thanks. > > Kumar >
For elegance write code that puts all the IIR filter stuff in a structure with matching functions (or do it in C++ with a class). Have one such structure for each filter in your cascade, and call: FilterStruct filter1, filter2, filter3, ... filterN; ... intermediate = updateFilter(input, &filter1); intermediate = updateFilter(intermediate, &filter2); intermediate = updateFilter(intermediate, &filter3); ... output= updateFilter(intermediate, &filterN); (note that I'm leaving out how to _load_ these filters). Listing 2 of http://www.wescottdesign.com/articles/zTransform/z-transforms.html has a direct form something-or-other filter implementation that shows how to do this. For efficiency you have to look at what your processor does. On a conventional machine that doesn't support vector processing the above code pays in function calls and indirect references. You could hard code the thing for a bit more speed. On a DSP you can play various tricks to do this in assembly, but it'd take an article-length posting. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Posting from Google? See http://cfaj.freeshell.org/google/ "Applied Control Theory for Embedded Systems" came out in April. See details at http://www.wescottdesign.com/actfes/actfes.html
Tim Wescott wrote:
> For elegance write code that puts all the IIR filter stuff in a > structure with matching functions (or do it in C++ with a class). Have > one such structure for each filter in your cascade, and call: > > FilterStruct filter1, filter2, filter3, ... filterN; > > ... > > intermediate = updateFilter(input, &filter1); > intermediate = updateFilter(intermediate, &filter2); > intermediate = updateFilter(intermediate, &filter3); > > ... > > output= updateFilter(intermediate, &filterN);
That is something I had considered, and even tried earlier. Each instance of the filter can hold its "state" separately when we need buffers. This is nice because one can abstract out some elements of the filtering process. Will the memory required for this implementation be roughly the same as the monolithic implementation I suggest in my earlier post? It should be so, as the sum total delays in this cascade is what I have as the maximum delay in my previous implementation, but just want to confirm. Thanks a lot! Kumar