Forums

IIR filter - DC offset after swapping coefficients

Started by Unknown July 25, 2003
Hello,

I have an application that has a standard IIR high pass filter with a
long time constant.  During certain conditions, a shorter time
constant is required, so new coefficients .. with a shorter time
contant ... are swapped in.   After a designated period, the original
coefficients are returned.  The problem I'm encountering is during
this last step.  After the original coefficients are returned, there
is a DC offset to the signal ( that takes a long time to work it's way
through, due to the long time constant ).  There must be a way to
modify the states of this IIR during the switch back to the original
coefficients, to avoid this DC offset.  

It's a single pole IIR, with the following equation:

	y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1)

I've tried a bunch of different modifications to the x(n), x(n-1) and
y(n-1) states, but while some modified the level of DC offset after
the coefficient switch, none of them eliminated it, as desired.

Anyone have any ideas or insight on how to be rid of this DC offset
after the coefficient switch?

Robert

www.gldsp.com

( modify address for return email )

www.numbersusa.com
www.americanpatrol.com
r_obert@REMOVE_THIS.hotmail.com wrote:
> > Hello, > > I have an application that has a standard IIR high pass filter with a > long time constant. During certain conditions, a shorter time > constant is required, so new coefficients .. with a shorter time > contant ... are swapped in. After a designated period, the original > coefficients are returned. The problem I'm encountering is during > this last step. After the original coefficients are returned, there > is a DC offset to the signal ( that takes a long time to work it's way > through, due to the long time constant ). There must be a way to > modify the states of this IIR during the switch back to the original > coefficients, to avoid this DC offset. > > It's a single pole IIR, with the following equation: > > y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) > > I've tried a bunch of different modifications to the x(n), x(n-1) and > y(n-1) states, but while some modified the level of DC offset after > the coefficient switch, none of them eliminated it, as desired. > > Anyone have any ideas or insight on how to be rid of this DC offset > after the coefficient switch? > > Robert > > www.gldsp.com > > ( modify address for return email ) > > www.numbersusa.com > www.americanpatrol.com
Filters have startup transients. The best way to avoid transients is to let them fade away and never wake them again: draco dormiens nunquam titilandum, and all that. That filter seems to require few enough cycles and memory so that you could probably run two simultaneously, one with each time constant, and switch between their outputs as needed. If the change is too abrupt for your spec, a little more code could fade between them. We recently had a similar thread. You might want to seek it out for more ideas. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Jerry Avins <jya@ieee.org> wrote:

>r_obert@REMOVE_THIS.hotmail.com wrote: >> >> Hello, >> >> I have an application that has a standard IIR high pass filter with a >> long time constant. During certain conditions, a shorter time >> constant is required, so new coefficients .. with a shorter time >> contant ... are swapped in. After a designated period, the original >> coefficients are returned. The problem I'm encountering is during >> this last step. After the original coefficients are returned, there >> is a DC offset to the signal ( that takes a long time to work it's way >> through, due to the long time constant ). There must be a way to >> modify the states of this IIR during the switch back to the original >> coefficients, to avoid this DC offset. >> >> It's a single pole IIR, with the following equation: >> >> y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) >> >> I've tried a bunch of different modifications to the x(n), x(n-1) and >> y(n-1) states, but while some modified the level of DC offset after >> the coefficient switch, none of them eliminated it, as desired. >> >> Anyone have any ideas or insight on how to be rid of this DC offset >> after the coefficient switch? >> >> Robert >> >> www.gldsp.com >> >> ( modify address for return email ) >> >> www.numbersusa.com >> www.americanpatrol.com > >Filters have startup transients. The best way to avoid transients is to >let them fade away and never wake them again: draco dormiens nunquam >titilandum, and all that. That filter seems to require few enough cycles >and memory so that you could probably run two simultaneously, one with >each time constant, and switch between their outputs as needed. If the >change is too abrupt for your spec, a little more code could fade >between them. We recently had a similar thread. You might want to seek >it out for more ideas.
Running a parallel filter is not an option for several reasons, mainly for overhead reasons. Even though it's a fairly simple filter, it's also being done in 32 bit math, and the processor is already too loaded. I have to believe there is a way to avoid the DC shift after swapping coefficients, via some manipulation of the states of the filter ... but which I've not yet been able to stumble upon. If anyone else has any ideas, they'd be greatly appreciated. Thanks, Robert P.S. I'd be happy to hear the name of the recent thread you refer to, if you remember ... else I'll search ( the thread names are not always obvious when searching, since sometimes a thread about subject A morphs into subject B ). www.gldsp.com ( modify address for return email ) www.numbersusa.com www.americanpatrol.com
r_obert@REMOVE_THIS.hotmail.com wrote in message news:<dlm2ivcqt1g68v3evvjmocgk8o1804ed8n@4ax.com>...
> Hello, > > I have an application that has a standard IIR high pass filter with a > long time constant. During certain conditions, a shorter time > constant is required, so new coefficients .. with a shorter time > contant ... are swapped in. After a designated period, the original > coefficients are returned. The problem I'm encountering is during > this last step. After the original coefficients are returned, there > is a DC offset to the signal ( that takes a long time to work it's way > through, due to the long time constant ). There must be a way to > modify the states of this IIR during the switch back to the original > coefficients, to avoid this DC offset. > > It's a single pole IIR, with the following equation: > > y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) > > I've tried a bunch of different modifications to the x(n), x(n-1) and > y(n-1) states, but while some modified the level of DC offset after > the coefficient switch, none of them eliminated it, as desired. > > Anyone have any ideas or insight on how to be rid of this DC offset > after the coefficient switch?
probably you would have a leftover DC offset even if you weren't switching coefs (although i can see that a non-simultaneous coef update would bring out a DC offset problem). are you using fixed-point arithmetic? (i suspect so.) look up "fraction saving" in Google or Google Groups or maybe look at http://www.dspguru.com/comp.dsp/tricks/alg/dc_block.htm . r b-j
rbj@surfglobal.net (robert bristow-johnson) wrote:

>r_obert@REMOVE_THIS.hotmail.com wrote in message news:<dlm2ivcqt1g68v3evvjmocgk8o1804ed8n@4ax.com>... >> Hello, >> >> I have an application that has a standard IIR high pass filter with a >> long time constant. During certain conditions, a shorter time >> constant is required, so new coefficients .. with a shorter time >> contant ... are swapped in. After a designated period, the original >> coefficients are returned. The problem I'm encountering is during >> this last step. After the original coefficients are returned, there >> is a DC offset to the signal ( that takes a long time to work it's way >> through, due to the long time constant ). There must be a way to >> modify the states of this IIR during the switch back to the original >> coefficients, to avoid this DC offset. >> >> It's a single pole IIR, with the following equation: >> >> y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) >> >> I've tried a bunch of different modifications to the x(n), x(n-1) and >> y(n-1) states, but while some modified the level of DC offset after >> the coefficient switch, none of them eliminated it, as desired. >> >> Anyone have any ideas or insight on how to be rid of this DC offset >> after the coefficient switch? > >probably you would have a leftover DC offset even if you weren't >switching coefs (although i can see that a non-simultaneous coef >update would bring out a DC offset problem). are you using >fixed-point arithmetic? (i suspect so.) look up "fraction saving" in >Google or Google Groups or maybe look at >http://www.dspguru.com/comp.dsp/tricks/alg/dc_block.htm . >
Hey Robert, Hope New Hampshire ( or was it Vermont ) is treating you nice. Can't see how it wouldn't. I am using the "fraction saving" method quite successfully on my other low pass, 16 bit integer implementations, that had a general DC offset from truncation ... thanks to help from yourself, Jerry, Nigel and the rest of the folks. However, this problem is a different animal. You will see it even with a floating point implementation, so fraction saving is probably not going to be the cure. I tried a bunch of other stuff, and angles today, but still without much luck, i.e. DC offset persistent after swapping coefficients. I'm starting to wonder if it's even resolvable using this form of filter. I'd be happy to hear any other ideas from anyone, Regards, Robert www.gldsp.com ( modify address for return email ) www.numbersusa.com www.americanpatrol.com
r_obert@REMOVE_THIS.hotmail.com wrote:

>rbj@surfglobal.net (robert bristow-johnson) wrote: > >rest of the folks. However, this problem is a different animal. You >will see it even with a floating point implementation, so fraction >saving is probably not going to be the cure.
I forgot to add, that in addition to this happening just as distinctly using a pure floating point implementation, the actual DSP implementation is using 32 bit math, so there isn't much fraction to save! Robert www.gldsp.com ( modify address for return email ) www.numbersusa.com www.americanpatrol.com
Robert wrote:
> >> I have an application that has a standard IIR high pass filter with a > >> long time constant. During certain conditions, a shorter time > >> constant is required, so new coefficients .. with a shorter time > >> contant ... are swapped in. After a designated period, the original > >> coefficients are returned. The problem I'm encountering is during > >> this last step. After the original coefficients are returned, there > >> is a DC offset to the signal ( that takes a long time to work it's way > >> through, due to the long time constant ). There must be a way to > >> modify the states of this IIR during the switch back to the original > >> coefficients, to avoid this DC offset.
...
> I am using the "fraction saving" method quite successfully on my other > low pass, 16 bit integer implementations, that had a general DC offset > from truncation ... thanks to help from yourself, Jerry, Nigel and the > rest of the folks. However, this problem is a different animal. You > will see it even with a floating point implementation, so fraction > saving is probably not going to be the cure.
I fear that unless you have the old filter (with the long time constant) running parallel to the new filter, you will always have the same transition time for the DC when switching. You can make the switch inaudible by "crossfading" the filter coefficients (effectively just switch through a whole bunch of high-passes with increasing time constants). But this process must take as long as the original transition to be inaudible. Perhaps audibility isn't a factor. You can also reset the states to 0, but this doesn't change anything, you still have some kind of step response for the DC, and the transition (or rise-to-step) time is only dependent on the long time constant, and not the step size. Perhaps just updating the state variables of the long-time constant filter can be done with less instructions than running the whole filter parallel? It depends on the filter architecture. IIR DC-blocking filters usually mean trouble. You need high-precision math to get decent attenuation (even with 32bit floating-point you have to be careful), and the result is an ugly phase shift at low frequencies. They also have a tendency to overshoot (I assign this to the phase shift - at such low frequencies this is bound to result in amplitude problems). Downsampled linear-phase FIR filters are another approach, they don't have phase problems, but there is a sample-rate conversion in the audio path which just isn't nice (even though one can control the resulting distortion). How's about trying to measure DC by "boxcar" averaging?
> I'd be happy to hear any other ideas from anyone,
FWIW. Andor
an2or@mailcircuit.com (Andor) wrote:

>> I am using the "fraction saving" method quite successfully on my other >> low pass, 16 bit integer implementations, that had a general DC offset >> from truncation ... thanks to help from yourself, Jerry, Nigel and the >> rest of the folks. However, this problem is a different animal. You >> will see it even with a floating point implementation, so fraction >> saving is probably not going to be the cure. > >I fear that unless you have the old filter (with the long time >constant) running parallel to the new filter, you will always have the >same transition time for the DC when switching. You can make the >switch inaudible by "crossfading" the filter coefficients (effectively >just switch through a whole bunch of high-passes with increasing time >constants). But this process must take as long as the original >transition to be inaudible. Perhaps audibility isn't a factor.
Not really, but added complexity and overhead would be. But I'll keep that idea in mind, thanks.
> >You can also reset the states to 0, but this doesn't change anything, >you still have some kind of step response for the DC, and the >transition (or rise-to-step) time is only dependent on the long time >constant, and not the step size.
Right ... have seen that.
> >Perhaps just updating the state variables of the long-time constant >filter can be done with less instructions than running the whole >filter parallel? It depends on the filter architecture.
I've been exploring that a bit.
> >IIR DC-blocking filters usually mean trouble. You need high-precision >math to get decent attenuation (even with 32bit floating-point you >have to be careful), and the result is an ugly phase shift at low >frequencies. They also have a tendency to overshoot (I assign this to >the phase shift - at such low frequencies this is bound to result in >amplitude problems). Downsampled linear-phase FIR filters are another >approach, they don't have phase problems, but there is a sample-rate >conversion in the audio path which just isn't nice (even though one >can control the resulting distortion).
Yep.
> >How's about trying to measure DC by "boxcar" averaging?
I've been considering an idea like that too, although it would be a bit of a departure from my present approach, which I've been hoping to salvage.
>FWIW. > >Andor
Thanks for the ideas, Robert www.gldsp.com ( modify address for return email ) www.numbersusa.com www.americanpatrol.com
Hi Robert,

How did you put this "REMOVE_THIS" thing in your e-mail address? In (outlook
express)-(tools)-(accounts)-(News)-..(Properties), should this change be
made in "e-mail address" field or "Reply To" field or both?

Regards,
Ishtiaq.

<r_obert@REMOVE_THIS.hotmail.com> wrote in message
news:dlm2ivcqt1g68v3evvjmocgk8o1804ed8n@4ax.com...
> Hello, > > I have an application that has a standard IIR high pass filter with a > long time constant. During certain conditions, a shorter time > constant is required, so new coefficients .. with a shorter time > contant ... are swapped in. After a designated period, the original > coefficients are returned. The problem I'm encountering is during > this last step. After the original coefficients are returned, there > is a DC offset to the signal ( that takes a long time to work it's way > through, due to the long time constant ). There must be a way to > modify the states of this IIR during the switch back to the original > coefficients, to avoid this DC offset. > > It's a single pole IIR, with the following equation: > > y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) > > I've tried a bunch of different modifications to the x(n), x(n-1) and > y(n-1) states, but while some modified the level of DC offset after > the coefficient switch, none of them eliminated it, as desired. > > Anyone have any ideas or insight on how to be rid of this DC offset > after the coefficient switch? > > Robert > > www.gldsp.com > > ( modify address for return email ) > > www.numbersusa.com > www.americanpatrol.com
X-No-Archive: yes

"I. R. Khan" <khan01@hibikino.ne.jp> wrote:

>Hi Robert, > >How did you put this "REMOVE_THIS" thing in your e-mail address? In (outlook >express)-(tools)-(accounts)-(News)-..(Properties), should this change be >made in "e-mail address" field or "Reply To" field or both? > >Regards, >Ishtiaq.
Hi, I use Agent ( www.forteinc.com ) for reading and posting to Usenet, which allows you to change the posting address. Regards, Robert www.gldsp.com ( modify address for return email ) www.numbersusa.com www.americanpatrol.com