2
$\begingroup$

I have the following code, which I am told is a low-pass Butterworth filter. How do I derive the frequency response and phase for this? I only have experience in analog electronics and so cannot relate this to a real filter response. I'm not sure why everything is scaled up by 2^ 16 - it must be to do with maintaining adequate resolution during the calculations?

#define FILTER_TC(FC, FS) ((411775 * FC) / FS)'

where TC = (2^16) * 2pi * Fc * Fs, with Fc the cut-off frequency in Hz, and Fs the sample frequency in Hz.

#define FILTER_LP(FILTER_OUT, FILTER_IN, FC, FS) \
    (FILTER_OUT += ((signed long)FILTER_TC(FC, FS) * \
    ((signed long)FILTER_IN - (signed long)(FILTER_OUT)) >> 16)'

Thank you for any help with this.

jmv

$\endgroup$
6
$\begingroup$

You can figure out the filter's transfer function by rewriting the body of the preprocessor macro a bit. Let FILTER_TC(FC, FS) (which really just defines the cutoff frequency of the filter) be equal to k in the below expression.

#define FILTER_LP(FILTER_OUT, FILTER_IN, FC, FS) \
    FILTER_OUT = FILTER_OUT + ((signed long) k * ((signed long) FILTER_IN - (signed long) FILTER_OUT)) >> 16)

In the above, I just expanded the += operator to be a bit less terse. By inspection, we can write the discrete-time difference equation:

$$ y[n] = y[n-1] + k(x[n] - y[n-1]) \\ y[n] = (1-k)y[n-1] + k x[n] $$

where $y[n]$ and $x[n]$ are equal to FILTER_OUT and FILTER_IN at time index $n$, respectively. This maps to a $z$-domain transfer function of:

$$ H(z) = \frac{Y(z)}{X(z)} = \frac{k}{1 - (1-k)z^{-1}} $$

This is a lowpass filter, although it is not a Butterworth filter. Its frequency response is plotted below for k = 0.25.

enter image description here

In the above frequency response plot, the blue trace shows the magnitude response and the green trace corresponds to the phase response. It shows that the example you gave isn't a particularly good lowpass filter, even for a first-order filter. You could do better with respect to high-frequency attenuation by using a correct Butterworth structure, for example.

The bit manipulations and explicit casts to signed long types are used because the filter is implemented using fixed-point arithmetic. This is a scheme by which you use integers to represent real numbers using a fixed quantization level. Fixed-point implementations of DSP algorithms were almost ubiquitous in the past, but floating-point processing is becoming more and more common. I would expect to find fixed-point implementations primarily in low-power or embedded contexts today.

$\endgroup$

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.