2
$\begingroup$

I am working on a 2-pole IIR high-pass filter. The filter is fixed point and it is causing me some issues. I believe I'm just misunderstanding something. I am implementing everything in Octave for now, but eventually it will be implemented in a 32-bit processor. The corner frequency is very low, $2.7\textrm{ Hz}$.

When I test the filter by passing in an impulse and then doing an fft on the output, I get different results based on the magnitude of the impulse.

First, I made the filter using signed 64-bit integers just for testing. So the impulse I feed into the filter looks like this:

Fs = 51200; %sample frequency
impulse = int64( [2^31, zeros(1,Fs*10-1)] ); %multiply by 10 to get 0.1 Hz resolution

Here is the fixed-point impulse response compared against the floating-point impulse response.

small amplitude

If I rerun the code but with a larger impulse I get the desired frequency response.

Fs = 51200; %sample frequency
impulse = int64( [2^63, zeros(1,Fs*10-1)] ); %multiply by 10 to get 0.1 Hz resolution

Large amplitude impulse response

They match so closely you can barely see the red, floating-point response.

  • Why is there this difference just from changing the amplitude of the input?

  • I need to implement this in 32 bits, but when I do, the amplitude of the input is restricted to $2^{31}$ so I end up with the distorted impulse response. How can I fix this or work around this?

$\endgroup$
  • $\begingroup$ For the fixed point low impulse response you are probably close numerical accuracy of the fixed point numbers at low frequencies where the gain is very low. By increasing the impulse amplitude the numerical accuracy relative to the impulse amplitude becomes smaller. If you would calculate the response for longer you will still see this difference at a lower frequency. $\endgroup$ – fibonatic Jul 26 '16 at 18:07
  • $\begingroup$ You say that you used 64 integers for the filter coefficients, but afterwards you say that you're using fixed-point numbers. Can you give more information on what exactly you're doing? $\endgroup$ – MBaz Jul 26 '16 at 18:08
  • $\begingroup$ @MBaz, your question confused me. The processor I am using does not support floating point operations. All operations are done using 32-bit integers. So, they are fixed point. I implemented the filter and tested it in Octave using floating point numbers and it worked great. Then I switched to 32-bit and the response became distorted. So I switched to 64-bit integers to see if the increased resolution would help. It did help as long as the impulse was sufficiently large. When the impulse is dropped to an amplitude of 2^31 (the max amplitude for 32-bit integers), the response distorts. $\endgroup$ – Joey M. Jul 26 '16 at 19:45
  • $\begingroup$ Could you actually add the values of these taps? $\endgroup$ – Marcus Müller Jul 26 '16 at 21:12
  • $\begingroup$ @JoeyM. Sorry for causing confusion. In fixed point arithmetic, an N-bit integer is interpreted as having Q bits for the integer part, and N-Q bits for the fractional (decimal) part. You seem to be using N=Q, which seem to me to be less than ideal (but I'm not an expert). Many processors have support for fixed-point libraries where you can specify N and Q, maybe it's worth a shot for you to look into it. $\endgroup$ – MBaz Jul 26 '16 at 22:10
1
$\begingroup$

The lower amplitude the input signal has compared to the resolution of the filter coefficients the weaker is its ability to shape the frequency of the input signal. It also depends on the span of the filter coefficients.

You get the same result if you feed the filter with 32-bit coefficients with a signal having an amplitude covering only the lower 16-bits. If you want to work around this effect you need to amplify the input signal.

$\endgroup$
  • $\begingroup$ The signal is amplified as much as possible. The amplitude is the largest integer representable with 32-bit signed integers. Does this mean I'm just out of luck with this low-pass filter and only 32-bit resolution? $\endgroup$ – Joey M. Jul 26 '16 at 20:37
  • $\begingroup$ in essence: yes. numerical stability and accuracy are among the things you need to consider when designing a filter, and recursive (=IIR) filters are prone to making their problem worse. I'd simply go ahead and use a longer FIR instead – it's not rare that CPU implementations of FIRs of the same order are faster than equivalently long IIRs for reasons of being able to optimize better for real CPU architectures. $\endgroup$ – Marcus Müller Jul 26 '16 at 21:06
  • $\begingroup$ also, sampling rate seems to be 52.1 kHz; assuming your 32 bit CPU is not running at single-digit Megahertzes, having a couple of taps more might make them less numerically problematic. Another word of advice: Many 32bitters come in variants with floating point units. Use these if possible. It makes so much stuff so much easier, and often even faster (less scaling taking places, FPUs sometimes have FMAC instructions, that kind of arguments). $\endgroup$ – Marcus Müller Jul 26 '16 at 21:09
  • $\begingroup$ also note that the problem might not only happen with low amplitudes, but also with amplitudes exceeding the numerical range. Aim for something where every intermediate result stays correctly representable! $\endgroup$ – Marcus Müller Jul 26 '16 at 21:12
  • $\begingroup$ We are building off of a previous platform, that's why we're using fixed-point. From our tests, the new FPUs are indeed faster and thus consume less power as well. We are going in that direction from now on. $\endgroup$ – Joey M. Jul 26 '16 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.