Designing & Implementing a Finite Impulse Response (FIR) Low Pass Filter (LPF)

By Tony Josi

Often in different applications, noisy signals are to be filtered using software filters to enhance the signal quality and remove the noise content. This article aims at designing and implementing a finite impulse response low pass filter using the simple moving average approach by deriving an approximation relation between the filter's cut-off frequency and the window size of the moving average.

Finite Impulse Response (FIR) filters are those filters that have a fixed number of non zero output values when given an impulse signal as input. Compared to the Infinite impulse response filters, FIRs are phase linear and uses convolution instead of recursion. Using Convolution the output signal is obtained as the convolution of the input signal and the impulse response [more]. impulse response of a filter is the response or output of the filter when it's fed with an impulse signal.

Filter Design Approach

The relation between cutoff frequency and the window size (block size) of the MA Filter can be obtained by analysing the response produced by the filter (of any window size, say N) when an impulsesignal is passed through it. Since the impulse function contains all frequencies, the impulse response defines the response of a linear time-invariant system for all frequencies [more]. The impulse response of MA Filter will look like a "box" as the average (window size N) of impulse amplitude is taken as the amplitude of the output until the number of samples reaches from 0 to N, if the impulse occurs at the sample zero in the input signal. The Discrete Time Fourier Transform (DTFT) of the output signal of the filter reveals the frequency characteristics of the filter (Frequency response).

To find the cut off frequency of a filter of Window size N, equate the frequency response function of the filter at cut-off frequency to 1/sqrt(2) (ie, -3 dB); as the cut-off frequency is regarded as the frequency at which the filter reduces the amplitude of the input signal by 1/sqrt(2) [-3 dB]. That means if a signal of frequency equal to cut-off frequency enters the filter, then the filter reduces the amplitude of the signal by 1/sqrt(2).

Deriving the Frequency Response of a Moving Average Filter

Impulse Response

Impulse Signal Impulse Response
Impulse Signal Impulse Response

The above image (right) shows the response of an impulse signal at 40, through an FIR LPF filter of window size 9.

If N is the window size of the LPF filter, then the impulse response of the filter can be defined as:

1

OR:

2

Discrete Time Fourier Transform of Impulse Signal

The frequency response of the filter should be taken to analyse the filter characteristics. The discrete time fourier transform of the output signal of the filter reveals the frequency characteristics of the filter. Discrete time fourier transform can be obtained using the following equation,

1

Replacing the input signal with the impulse response signal,

1

The summation (sigma term) in the above equation can be considered as the sum of a geometric series.

The sum of a geometric series 1 can be defined as, 1 [refer]

So the summation can be expressed as,

1

Then the frequency response becomes,

1

Eulers Formula: From Eulers Formula, 1, [refer]

Replacing with Eulers Formula,

1

As we are only interested in the magnitude of the filter response and not it's phase, we can leave out the exponents from the above equation and use the remaining part for the analysis of frequency response (the exponent part is the eigenvector and its phase of the LTI system),

1

So the above function defines the response amplitude of a signal of frequency ω, when passed through the filter. The cut-off frequency is defined as the frequency at which the energy of the signal reduces by −3 dB. Hence the amplitude at the cut-off frequency will be -3 dB * amplitude of input signal. -3 dB = 1/sqrt(2);

1

The above equation havent got any simple analytical solution. One method to approximate solutions for the above equation is to use Taylor Series representation of F(ωc).

If we approximate the F(ωc) to the first 3 orders/terms of the Taylor Series,

1

[Refer] for the detailed steps of Taylor Series approximation of F(ω).

Taking the first two terms of the above Taylor Series Approximation gives us,

1

Solving the above equation,

1

Even though above equation connects the window size and cut-off frequency the equation is biased, meaning that the approximation error doesnt converge at large values of window size, N. To avoid that, one method is to generalise the above equation by replacing the constant with a variable a;

1

and substituting it in the frequency response and equating it to 1/sqrt(2) when limit N tends to infinity,

1

the above limit leads to,

1

[Refer 1] for the detailed steps of Limit Calculation.

[Refer 2] for the detailed steps of Limit Calculation.

Solving the above equation gives,

1

Replacing the above new constant in the cut-off frequency - window size equation gives,

1

Converting continuous time frequency ω to the discrete time frequency f, where fs is the sampling frequency,

1

Substituting the above equation becomes,

1

Finally, for a particular cut-off frequency f, window size N can be expressed as,

1

where fs is the sampling frequency.

FIR LPF Filter Implemented in Software

The below C++ code snippet implements an FIR LPF filter using the simple moving average approach:

 1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
class fir_lpf_MA_Filter {
      
          private:
              int         moving_Avg_Length;
              double      lpf_Sum;
              double     *data_Buffer;
              int         buffer_NotFilled;
              int         data_Buffer_Cur_Length;
      
          public:
              fir_lpf_MA_Filter(double cut_Off_Freq, double sampling_Freq);
              double fir_lpf_MA_Filter_Process(double data);
              void fir_lpf_MA_Filter_Reset();
              ~fir_lpf_MA_Filter();
      
              fir_lpf_MA_Filter(const fir_lpf_MA_Filter &copy) = delete;
              fir_lpf_MA_Filter operator=(const fir_lpf_MA_Filter &copy) = delete;
              fir_lpf_MA_Filter(fir_lpf_MA_Filter &&copy) = delete;
              fir_lpf_MA_Filter operator=(fir_lpf_MA_Filter &&copy) = delete;
      
      };
   
   fir_lpf_MA_Filter::fir_lpf_MA_Filter(double cut_Off_Freq, double sampling_Freq) {
       
       auto fCut_Off = cut_Off_Freq / sampling_Freq;
       auto temp_bs = fCut_Off * fCut_Off;
       int calc_window_size = sqrt(0.196202 + temp_bs) / fCut_Off;
   
       std::cout<<"Calc. win size: "<<calc_window_size<<"\n";
   
       moving_Avg_Length = calc_window_size + 1;
       data_Buffer = new double[moving_Avg_Length]();
       data_Buffer_Cur_Length = 0;
       lpf_Sum = 0;
       buffer_NotFilled = 1;
   
   }
   
   fir_lpf_MA_Filter::~fir_lpf_MA_Filter() {
   
       delete[] data_Buffer;
   
   }
   
   double fir_lpf_MA_Filter::fir_lpf_MA_Filter_Process(double data) {
   
       lpf_Sum += data;
       data_Buffer[data_Buffer_Cur_Length] = data;
       if(++data_Buffer_Cur_Length == moving_Avg_Length) {
           data_Buffer_Cur_Length = 0;
           buffer_NotFilled = 0;
       } 
       lpf_Sum -= data_Buffer[data_Buffer_Cur_Length];
       return buffer_NotFilled ? lpf_Sum / data_Buffer_Cur_Length : lpf_Sum / (moving_Avg_Length - 1);
   
   }
   
   void fir_lpf_MA_Filter::fir_lpf_MA_Filter_Reset() {
   
       std::fill_n(data_Buffer, moving_Avg_Length, 0.0);
       buffer_NotFilled = 0;
       data_Buffer_Cur_Length = 0;
   
   }
   

Examples

The following example shows an unfiltered input signal (left) having 2 frequencies: 1 error signal at 1.2 Hz and 1 data signal of 0.01 Hz, when passed to the LPF filter with a cut-off frequency of 0.025 Hz produces the filtered signal (right) with only the data signal of 0.01 Hz frequency.

Unfiltered Input Signal Filtered Output Signal
Unfiltered Input Signal Filtered Output Signal