Hi all, I've run across a 'problem' that seems like it would be relatively commonplace....but I am unsure how to address it. Can anyone point me to appropriate literature (or even offer suggestions)? Given: 16-bit fixed point processor 42-tap FIR filter (coefficients on [-32767, 32768]) Input values on [-32767, 32768] The accumulator is 40-bit, so it can handle the 42-taps without overflow, regardless of the input values. Step response (value of '1' on input) after 42 passes results in a value of about 32000 (I believe this is considered to be the filter gain, but please correct me if I'm wrong). I see a problem if my input values hover around zero...the potential for the output to swing rapidly from positive to negative. Can I shift my input range to [0, 65535]? Does this have any detrimental/unexpected effect? The other problem I see is related to scaling. My output should be 16-bit, same as the input. My initial thought is to divide the accumulated result by the filter gain, and then by the number of taps. Does this sound reasonable? On the other hand, if I allow negative inputs, is there a recommended method to scale the result to a 16-bit value? I can't seem to get my brain around this one. Cheers, Dave
FIR: Dealing with negative values and scaling
Started by ●September 11, 2006
Reply by ●September 11, 20062006-09-11
[-32768, 32767] dave_bonnell@hotmail.com wrote:> Hi all, > > I've run across a 'problem' that seems like it would be relatively > commonplace....but I am unsure how to address it. Can anyone point me > to appropriate literature (or even offer suggestions)? > > Given: > 16-bit fixed point processor > 42-tap FIR filter (coefficients on [-32767, 32768]) > Input values on [-32767, 32768] > > The accumulator is 40-bit, so it can handle the 42-taps without > overflow, regardless of the input values. Step response (value of '1' > on input) after 42 passes results in a value of about 32000 (I believe > this is considered to be the filter gain, but please correct me if I'm > wrong). > > I see a problem if my input values hover around zero...the potential > for the output to swing rapidly from positive to negative. Can I shift > my input range to [0, 65535]? Does this have any > detrimental/unexpected effect? > > The other problem I see is related to scaling. My output should be > 16-bit, same as the input. My initial thought is to divide the > accumulated result by the filter gain, and then by the number of taps. > Does this sound reasonable? > > On the other hand, if I allow negative inputs, is there a recommended > method to scale the result to a 16-bit value? I can't seem to get my > brain around this one. > > Cheers, > Dave
Reply by ●September 11, 20062006-09-11
dave_bonnell@hotmail.com wrote:> Hi all, > > I've run across a 'problem' that seems like it would be relatively > commonplace....but I am unsure how to address it. Can anyone point me > to appropriate literature (or even offer suggestions)? > > Given: > 16-bit fixed point processor > 42-tap FIR filter (coefficients on [-32767, 32768]) > Input values on [-32767, 32768]Interesting ranges. Normal 2's complement numbers range from -32768 to 32767.> > The accumulator is 40-bit, so it can handle the 42-taps without > overflow, regardless of the input values. Step response (value of '1' > on input) after 42 passes results in a value of about 32000 (I believe > this is considered to be the filter gain, but please correct me if I'm > wrong).Well, the DC gain of the filter.> > I see a problem if my input values hover around zero...the potential > for the output to swing rapidly from positive to negative. Can I shift > my input range to [0, 65535]? Does this have any > detrimental/unexpected effect?Why is this a problem? If your input can hover around 0, a bit plus or a bit minus, you'd _expect_ the output to do the same. Is there some reason that you don't want your output to range negative? What about just setting the output to zero if it goes down there?> > The other problem I see is related to scaling. My output should be > 16-bit, same as the input. My initial thought is to divide the > accumulated result by the filter gain, and then by the number of taps. > Does this sound reasonable?That depends. If you're implementing a low-pass filter then chances are you want an overall DC gain of 1, so you should divide by the filter gain as your final step. If you're implementing some other kind of filter that has any significant peaks at other frequencies, and you absolutely positively can't allow overflow then you should divide by the worst-case (i.e. highest) gain. If you're implementing a peaky filter and _some_ clipping is acceptable, then you can just clip on saturation.> > On the other hand, if I allow negative inputs, is there a recommended > method to scale the result to a 16-bit value? I can't seem to get my > brain around this one. >Either there's something about your application that you haven't mentioned, or you're getting wrapped around the axle about negative numbers. If you feed in a negative step (i.e. -1) then you would expect an output of -32000, which is just fine and dandy. What's the problem? -- 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
Reply by ●September 11, 20062006-09-11
> Interesting ranges. Normal 2's complement numbers range from -32768 to > 32767.ARRggh. Closing brace was meant to be a ")", not "]".> Why is this a problem? If your input can hover around 0, a bit plus or > a bit minus, you'd _expect_ the output to do the same. Is there some > reason that you don't want your output to range negative? What about > just setting the output to zero if it goes down there? > >The input is simply the output of an analog voltage conversion, and negative values don't make much sense conceptually (with the application in mind). I am concerned that using negative inputs may cause me to lose some information....see the remainder of this post for clarification.> If you're implementing a low-pass filter then chances are you want an > overall DC gain of 1, so you should divide by the filter gain as your > final step. >Yup, this is a low pass filter, intended for anti-aliasing.> If you're implementing some other kind of filter that has any > significant peaks at other frequencies, and you absolutely positively > can't allow overflow then you should divide by the worst-case (i.e. > highest) gain. If you're implementing a peaky filter and _some_ > clipping is acceptable, then you can just clip on saturation.Gotcha. This isn't the case, so I shouldn't have to worry about worst-case gain.> Either there's something about your application that you haven't > mentioned, or you're getting wrapped around the axle about negative > numbers. If you feed in a negative step (i.e. -1) then you would expect > an output of -32000, which is just fine and dandy. What's the problem?On second (third? fourth?) thought, I think you've hit the target here. If my input changes from a step to a negative step (i.e. output swings from 32000 to -32000), and I perform a division to account for gain, I'll end up with basically a 1, -1 on output. I could then shift this value to [0, 65535] for use by higher-level programs (as I said, a negative value doesn't conceptually agree with the application). Part of my confusion was that I thought I needed to divide by the number of taps in addition to the filter's DC gain. Maybe I'm still a little confused, but I'll work through the numbers and see if I can convince myself. Cheers, Dave
Reply by ●September 11, 20062006-09-11
Why does having the values switch rapidly between positive and negative values cause a problem? In article <1157997617.903590.73830@i3g2000cwc.googlegroups.com>, "dave_bonnell@hotmail.com" <dave_bonnell@hotmail.com> wrote:>Hi all, > >I've run across a 'problem' that seems like it would be relatively >commonplace....but I am unsure how to address it. Can anyone point me >to appropriate literature (or even offer suggestions)? > >Given: >16-bit fixed point processor >42-tap FIR filter (coefficients on [-32767, 32768]) >Input values on [-32767, 32768] > >The accumulator is 40-bit, so it can handle the 42-taps without >overflow, regardless of the input values. Step response (value of '1' >on input) after 42 passes results in a value of about 32000 (I believe >this is considered to be the filter gain, but please correct me if I'm >wrong). > >I see a problem if my input values hover around zero...the potential >for the output to swing rapidly from positive to negative. Can I shift >my input range to [0, 65535]? Does this have any >detrimental/unexpected effect? > >The other problem I see is related to scaling. My output should be >16-bit, same as the input. My initial thought is to divide the >accumulated result by the filter gain, and then by the number of taps. >Does this sound reasonable? > >On the other hand, if I allow negative inputs, is there a recommended >method to scale the result to a 16-bit value? I can't seem to get my >brain around this one. > >Cheers, >Dave >
Reply by ●September 11, 20062006-09-11
In article <1158002423.442254.265560@d34g2000cwd.googlegroups.com>, "dave_bonnell@hotmail.com" <dave_bonnell@hotmail.com> wrote:> >Yup, this is a low pass filter, intended for anti-aliasing. >Anti-aliasing is normally done before sampling. The only reason that I'm aware of for anti-aliasing after sampling is prior to decimation.
Reply by ●September 11, 20062006-09-11
"dave_bonnell@hotmail.com" <dave_bonnell@hotmail.com> wrote in news:1158002423.442254.265560@d34g2000cwd.googlegroups.com:> Yup, this is a low pass filter, intended for anti-aliasing.Anti-aliasing MUST be done before the sampling is done-- as an analog pre- filter. If the signal is already aliased in the sampling process, it isn't possible to recover it -- Scott Reverse name to reply
Reply by ●September 11, 20062006-09-11
dave_bonnell@hotmail.com wrote: ...> value to [0, 65535] for use by higher-level programs (as I said, a > negative value doesn't conceptually agree with the application).... I'm lost here. All signals that can be capacitor- or transformer coupled -- that is, almost all audio and RF -- are bipolar. How can you not have negative values? Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●September 11, 20062006-09-11
A unity gain lowpass filter is not immune to overflow. Dirk Bell DSP Consultant Tim Wescott wrote:> dave_bonnell@hotmail.com wrote: > > > Hi all, > > > > I've run across a 'problem' that seems like it would be relatively > > commonplace....but I am unsure how to address it. Can anyone point me > > to appropriate literature (or even offer suggestions)? > > > > Given: > > 16-bit fixed point processor > > 42-tap FIR filter (coefficients on [-32767, 32768]) > > Input values on [-32767, 32768] > > Interesting ranges. Normal 2's complement numbers range from -32768 to > 32767. > > > > The accumulator is 40-bit, so it can handle the 42-taps without > > overflow, regardless of the input values. Step response (value of '1' > > on input) after 42 passes results in a value of about 32000 (I believe > > this is considered to be the filter gain, but please correct me if I'm > > wrong). > > Well, the DC gain of the filter. > > > > I see a problem if my input values hover around zero...the potential > > for the output to swing rapidly from positive to negative. Can I shift > > my input range to [0, 65535]? Does this have any > > detrimental/unexpected effect? > > Why is this a problem? If your input can hover around 0, a bit plus or > a bit minus, you'd _expect_ the output to do the same. Is there some > reason that you don't want your output to range negative? What about > just setting the output to zero if it goes down there? > > > > The other problem I see is related to scaling. My output should be > > 16-bit, same as the input. My initial thought is to divide the > > accumulated result by the filter gain, and then by the number of taps. > > Does this sound reasonable? > > That depends. > > If you're implementing a low-pass filter then chances are you want an > overall DC gain of 1, so you should divide by the filter gain as your > final step. > > If you're implementing some other kind of filter that has any > significant peaks at other frequencies, and you absolutely positively > can't allow overflow then you should divide by the worst-case (i.e. > highest) gain. If you're implementing a peaky filter and _some_ > clipping is acceptable, then you can just clip on saturation. > > > > On the other hand, if I allow negative inputs, is there a recommended > > method to scale the result to a 16-bit value? I can't seem to get my > > brain around this one. > > > Either there's something about your application that you haven't > mentioned, or you're getting wrapped around the axle about negative > numbers. If you feed in a negative step (i.e. -1) then you would expect > an output of -32000, which is just fine and dandy. What's the problem? > > -- > > 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
Reply by ●September 12, 20062006-09-12
Jerry Avins wrote: (snip)> I'm lost here. All signals that can be capacitor- or transformer coupled > -- that is, almost all audio and RF -- are bipolar. How can you not have > negative values?I agree. There are different ways to look at the output of an A/D converter. One is a signed value, say between -32768 and 32767, the other is an unsigned value between 0 and 65535. With an AC coupled input, one would bias the input somewhere in the middle, but it might not be exactly in the middle. Zero volts might not be 0 or 32768 as signed or unsigned values. One system I worked with would average some number of A/D outputs before the signal arrived, and then subtract that from the actual signal. (With FPGA hardware to do the calculation.) -- glen






