4.2 Real-time implementation
Last updated
Was this helpful?
Last updated
Was this helpful?
As we saw , the single pole IIR yields a HPF with desirable performance. We will therefore replace the simple HPF we implemented for the alien voice effect with such a filter. Moreover, we will implement a , which is a second order (two pole and two zeros) IIR filter; the biquad is one of the most-used filters.
The above Wikipedia article provides a great overview of the different ways a biquad filter can be implemented, without code however. We will guide you through the Python implementation of two approaches: Direct Form 1 and Direct Form 2. With these implementations in hand, it should be straightforward to port the code to C. As we did with the alien voice effect, we will implement the HPF in Python as close as possible as would be done in C.
This is considered the more straightforward implementation, as it follows the standard formulation of the difference equation:
The corresponding block diagram is shown below.
Note the variable HALF_MAX_VAL
in order to use the full range of the signal's data type.
The line:
computes the contribution of the top branch (in the above block diagram) towards the output .
Note that we write a for
in order to accommodate filters with more than two poles/zeros. However, due to stability issues it may be better to cascade multiple biquads instead of creating a filter with more than two poles/zeros.
Running the incomplete script will yield the following plot, in which only a gain (less than one) is applied to the input signal.
If you successfully complete the process
function, you should obtain the following plot.
The difference equation for Direct Form 2 is given by:
where:
The corresponding block diagram is shown below.
The first step is to compute:
Then we can compute the output:
Finally, we need to update the state variables for computing the next sample.
Running the incomplete script will yield the following plot, where the output is all-zeros.
If you successfully complete the process
function, you should obtain the following plot.
With the above implementation(s) working in the simulated environments with a fixed WAV file, you can now try your implementation in a real-time scenario.
Figure: Block diagram of biquad, Direct Form 1. .
From the block diagram, we can essentially "read-off" the operations that need to be performed in our code. Below, we show the incomplete process
function, which is provided to you in in the repo. The complete init
function, which sets the filter coefficients and allocates memory for the state variables, is provided to you.
The second implementation we will consider is known as Direct Form 2. It uses less memory for state variables by placing the feedback portion first. provides a nice visual of how to get from Direct Form 1 to Direct Form 2.
Figure: Block diagram of biquad, Direct Form 2. .
As before, we provide an incomplete process
function, which can be found in in the repo. The complete init
function, which sets the filter coefficients and allocates memory for the state variables, is provided to you.
TASK 7: Try your biquad filter implementation with the and then implement it in C on the microcontroller!
Congrats on implementing the biquad filter! This is a fundamental tool in the arsenal of a DSP engineer. In the , we will build a more sophisticated voice effect that can alter the pitch so that you sound like a chipmunk or Darth Vader.