DSPRelated.com
Forums

amplitude change in time variable iir filter

Started by banton May 20, 2006
Hello,

If I change the coefficients of an iir filter with
the intention to change the resonance frequency, this
will also change the amplitude.  How can I modify the
values in the filter taps to compensate for the
amplitude change.

example:

A 2 pole filter with pole on the unit circle:

     C = 2 cos(freq);

     y[k] = C y[k-1] - y[k-2]

I hit this filter with an impulse and I get a sinewave out.
Now if I change C for a new frequency (while the filter is
"running") the amplitude changes.
If I want to modify y[k-1] and y[k-2] (not in the output,
but just for computing the next value) how do I have to
modify them?
or to put it in another way:
what is the proportion of the amplitude change 
to the frequency change?

gr.
Anton
 

banton wrote:
> Hello, > > If I change the coefficients of an iir filter with > the intention to change the resonance frequency, this > will also change the amplitude. How can I modify the > values in the filter taps to compensate for the > amplitude change. >
While it is theoretically possible to change the filter response in a controllable fashion by direct manipulation of the filter coefficients, it isn't usually a recommended method due to the complexities of the math that would be involved. Instead, it is often times much easier to go back to a desired 'analog' filter equation and transform it into a 'digital' filter. Note, this is a topic that has come up before and if you search through the group archives you should be able to find some additional details related to this topic.
banton wrote:
> Hello, > > If I change the coefficients of an iir filter with > the intention to change the resonance frequency, this > will also change the amplitude. How can I modify the > values in the filter taps to compensate for the > amplitude change. > > example: > > A 2 pole filter with pole on the unit circle: > > C = 2 cos(freq); > > y[k] = C y[k-1] - y[k-2] > > I hit this filter with an impulse and I get a sinewave out. > Now if I change C for a new frequency (while the filter is > "running") the amplitude changes. > If I want to modify y[k-1] and y[k-2] (not in the output, > but just for computing the next value) how do I have to > modify them?
If you start the above recursion with y[0] = 1 (and assume y[-1] = 0), then A sin(freq) = 1 (1 is the height of the impulse) and therefore A = 1 / sin(freq) is the amplitude of the resulting sine wave, ie. y[k] = 1 / sin(freq) sin(freq k + freq) (the unit impulse response). So if you want to have the same amplitude A with oscillating frequency equal to freq2 you have to initialize the recursion with y[0] = 0, y[1] = sin(freq) / sin(freq2), and start applying the recursion for y[k], k = 2, 3, ... Does this answer anything? Regards, Andor
banton wrote:
> Hello, > > If I change the coefficients of an iir filter with > the intention to change the resonance frequency, this > will also change the amplitude.
that is to be expected.
> How can I modify the > values in the filter taps to compensate for the > amplitude change.
when you change the value of "C" to change the frequency, you also have to fudge the filter "states" y[k-1] and y[k-2].
> example: > > A 2 pole filter with pole on the unit circle: > > C = 2 cos(freq); > > y[k] = C y[k-1] - y[k-2] > > I hit this filter with an impulse and I get a sinewave out. > Now if I change C for a new frequency (while the filter is > "running") the amplitude changes. > If I want to modify y[k-1] and y[k-2] (not in the output, > but just for computing the next value) how do I have to > modify them?
ah, you have precisely the right idea. the answer is simple, i think. let's say that your amplitude is A (you determined that by your initial settings for the states y[-1] and y[-2]) and that you're changing from freq1 to freq2. so C1 = 2*cos(freq1) and C2 = 2*cos(freq2) also y[k] = A * cos(freq*k + phi) where A and phi are functions of C, y[-1], and y[-2]. i leave it to the reader to determine what those functions are. remember that y[-1] = A * cos(-freq + phi) y[-2] = A * cos(-2*freq + phi) first determine what your new output would be if you "didn't" change the freq (or C) y[k] = C1*y[k-1] - y[k-2] now, if you don't want this to click, you want your next y[k] to be the same value even after changing C1 to C2 and fudging with the states so y[k] = C1*y[k-1] - y[k-2] = C2*y'[k-1] - y'[k-2] that's one equation, two unknowns (y'[k-1] and y'[k-2], your "fudged" states). we need another. y[k] = C1*y[k-1] - y[k-2] = A * cos(freq1*k + phi1) or y[k] = C2*y'[k-1] - y'[k-2] = A * cos(freq2*k + phi2) we want the contents to the cos() function to be the same in both cases i'm just now running late and (being on Google, i can't conveniently save this), so i'll post this now and return to it.