Introduction
Filters are one of the most important components in our toolbox as engineers, especially in audio. This article aims to be a beginner level explanation for how digital audio filters work.
Most discussion about filtering involves university-level math, making it inaccessible to most learners. I will explain everything from first principles and also include lots of good links for further reading. If all goes well, this should be accessible to anyone with some high school Algebra knowledge.
Here is a roadmap of the article. The first section talks about how we can make a low-pass filter by taking a simple rolling average of our input sound and provides an interactive demo. In the second section, I show that we can make a high-pass filter using a low-pass filter. Then, I talk about how we can cascade these filters together to achieve a more selective filtering effect. To conclude, I provide some useful resources for you to learn more.
How Does a Low-Pass Filter Work
When we talk about low-frequencies vs high frequencies, we are talking about how quickly the sound waves go up and down. Low frequencies go up and down relatively slowly. The lowest frequency humans can usually hear is 20 Hertz (Hz), meaning the wave goes up and down 20x every second. The lowest human voices start at around 80Hz and top out at around 1000Hz (1kHz) for a crying baby.
Let’s pretend we made a recording using our beautiful low 80Hz voice but there’s a loud baby crying at 1kHz in the background and we want to get rid of that sound (while preserving our 80Hz voice). We can use a filter!
Let’s take a look at the signals in time. Overlapping sound waves are additive in nature, so we can simulate the combined audio by just summing the individual frequency tones.
One thing we notice in the combined graph is that the 1kHz tone seems to wobble around the 80Hz tone but on average, the graph looks like the 80Hz tone. This is an important thing to note, because it turns out we can make a very simple filter by taking a rolling average! However, we will not be using a traditional average. We will be using a technique called the exponential moving average. Outside signal filtering, this type of average is great for data smoothing, general science/engineering, and finance applications!
Let’s write the exponential moving average recurrance relation:
I will go through each term to make sure we understand fully. is the th input sample. is the th lowpass output sample. is the th lowpass output sample. Lastly is the filter parameter that determines how smooth the output will be.
When reading these recurrance relations, you can think of the th sample as the current sample, the th sample as the previous sample, and the th sample as the next sample. So for example the filter calculates the th output sample as the following:
There are a few implicit assumptions here that I want to touch on. Firstly, we assume the algorithm has already calculated . We also assume that is known because it is an audio input. is a parameter of the function and is also known. So we are left with only one unkonwn: , which we can solve for with the recurrance relation! One final piece of information we need is a starting value . I always set it to but you can set it to whatever you want 🙂
And that’s it! We have made our very first filter. I have gone ahead and implemented this filter in a little interactive demo! Feel free to reverse-engineer the source code 🙂
Click “Set to Lowpass” to see the low-pass filter in action!
See the Pen Low-Pass Filter by davisynth (@davisynth) on CodePen.
How Does a High-Pass Filter Work
For this second example, let’s pretend we want to isolate just the 1kHz baby sound. How do we filter out the low frequencies while preserving the high frequencies?
The low-pass filter we made acted like a subtraction. It took our total sound (80Hz + 1kHz) and subtracted the high pitch 1kHz, leaving just the 80Hz remaining. Let’s do some back-of-the-napkin calculations and see if there’s a chance we can get just the high frequencies given this information.
By rearranging we get the following:
So to get just the high frequencies, all we need to do is take our total sound and subtract the low-pass filtered version from it!
Before implementing this in code, we need to make it into a recurrance relation. Here are the steps:
We begin with a recurrence relation for our high-pass sample as a function of input sample and low-passed sample :
We substitute in the low-pass recurrence relation for .
This still involves which is a problem for us. Luckily there’s a neat trick here! Let’s start by re-arranging our starting high-pass recurrance relation to be the following:
The trick we use is the fact that is relative. We can replace with and write it equivalently as this:
Now we have a value for ! Let’s substitute that in and keep chugging along:
Notice that now we have a nice recurrance relation where is a function of only itself and the input signal.
Simplifying yields the following:
Let’s see how well this algorithm does in the interactive demo!
Click “Set to Highpass” to see the high-pass filter in action!
See the Pen Filter-Alpha-Only-Lowpass-Default by davisynth (@davisynth) on CodePen.
Higher Order Filters
If you played around with the demo, you might notice that the filter does not completely remove unwanted frequencies (the stopband). It just removes them at a faster rate than it removes the frequencies we want to keep (the passband). The next demo has a second parameter called “Order”. By dragging the “Order” slider to anything higher than 1, you should see that the filter becomes more selective.
Here’s what’s going on behind the scenes: I have applied the same filter many times over to the data series. The more times I apply it, the better the filter becomes at removing stopband frequencies while keeping the passband intact.
The number of times I have applied the filter is equal to the filter order in this case. However please be careful to not take this to be the definition of “filter order” in a more general context. This only applies to situations where we chain these simple low-pass and high-pass filters together.
This topology with daisy-chained filters is usually referred to as a Ladder Filter. It is one of the most common filters you will find in the wild, especially in electronics!
See the Pen Filter-Alpha-Only-Lowpass-Default by davisynth (@davisynth) on CodePen.
More Resources to Learn About Filters
Before you delve deeper into filters and filter design, I strongly enourage you to read about the related fields of study: Linear Systems, and Digital Signal Processing (DSP).
For linear systems, I loved the textbook my college class used: Oppenheim and Willsky Signals and Systems ISBN: 9780138097318. MIT OpenCourseWare has the full Signals and Systems course available for free online with a series of video lectures taught by Alan Oppenheim himself! I cannot stress enough how much of a gift to the world this wonderful online course is. This book is also great because it has tables of solved Fourier and Z transforms that I like to use as a reference whenever I design audio algorithms.
My go-to book for DSP is Schaum’s Outlines of Digital Signal Processing ISBN: 978-0071635097. The Schaum’s Outlines book series is my favorite way to learn because it provides solutions to every problem so you get constant feedback to make sure you understand the material.
A great online reference is Stanford’s Center for Computer Research in Music and Acoustics (CCRMA). Specifically the amazing course materials provided by Julius Orion Smith III. His course Introduction to Digital Filters is an absolute gem!
Thank you for reading this article! If you want to see more of my work related to audio, check out my FREE audio software: Ripple Delay Multi-Tap Delay Plugin, Spiral Delay, Dimension Plus 🙂