A Somewhat Misguided Filter Tutorial by Louis Gorenfeld Updated on August 10, 2013, about 5 years after I first wrote it (man, time sure flies!). Please send critiques to [email protected]. Why This Tutorial? I'm writing this tutorial because when I was trying to learn how basic digital filters worked, I could never find all the information I wanted in one place. I looked though dozens of websites and a few different DSP books before feeling that I understood the material. Partly, this is because most explanations of the subject are aimed at engineering students and supplement the lecture rather than replace it. In this crazy world, j is the complex number. And, the concise explanations don't give much basic Algebra advice for solving problems. Steps are often completely skipped, and important points go unexplained. Lastly, when examining filters, these articles often only examine a very simple filter in detail. Hopefully this document will give people who are not math aces a good starting point for exploring digital filters. I do this by including the math review in the walkthrough, for those people who have simply forgotten a lot of mathematics. When finished, you will have a usable sweepable lowpass filter. Another motivation was that I felt the world needed another tutorial more than it needed yet another virtual analog synth. So, I sat down to write this instead, and I hope it helps someone out! But, before we start, I have to add a disclaimer. Shockingly, I am not an electrical engineering major. I graduated in computer science, which does involve quite a bit of math. But, while it's highly mathematical, it never touches upon linear systems. So, all the information presented here is what I've been able to piece together from multiple sources. Before digging in, I recommend that the reader has: ● ● ...had in the past the following math: ○ Algebra (with a little complex number experience) ○ Trigonometry (but no heavy Trig is used here, just the concept of sines and cosines) ○ Be comfy using symbols usually discussed in Calculus (no actual Calculus used) ...should know the following about digital signals: ○ What the Nyquist frequency is and what it means in practical terms ○ The Fourier Theorem (the basic concept, not why/how the transform works) ○ I'd suggest using this tutorial as a supplemental guide to existing books and papers. Other books and papers have nicer diagrams. Important Warning Filters can be extremely unstable, especially if they're miscalculated. So, when playing with them, you should do the following: • Don't use headphones unless the volume is turned far down, and turn the volume down when using speakers too unless you have a pair you don't mind losing. • If this is being done in code, put in a limiting function where if the waveform exceeds a certain value, the audio is muted for a given time. Or, alternatively, place a limiter on the signal that doesn't let it exceed a comfortable amount. This Looks Like a Lot of Work. Why Don't I Just Use a Ready-Made Filter? Because there is no knowledge that is not power. I was going to credit this quote to Mortal Kombat 3, but it turns out to be Ralph Waldo Emerson. But seriously, don't you want to know how these things work? The Scope of This Tutorial This tutorial is intended to walk the reader through designing a biquad filter. The focus is going to be on how to use the math to design a filter rather than why the math works. The reason for this is that, although the mathematical proofs are brilliant and compelling, they'd be a complete book all by themselves. For that, I'd refer you to one of the books I mention throughout the tutorial. They all do a better job than I possibly could. Quick Rundown of Common Sweepable Digital Filters Biquads and other Z-Plane filters These are very common, and basically what we'll be discussing here. They aren't great for sweepable lowpasses (though they can be serviceable), but are good for bandpass, peaking and shelving (good for EQ and tone control), smoothing filters, resonators (dampened sine), and notch filters, spread it on your toast, put it in your coffee... A biquad is a kind of filter that has two poles and two zeros. Poles emphasize frequencies and zeroes cancel them out, and the different filter types I mentioned are created by positioning the poles and zeroes into various configurations. Moog Ladder Filter This filter is the sweepable lowpass. If you chain 4 1-pole lowpasses together, you get this 24dB/oct filter. Adding an inverted loopback gives you resonance. One enormous advantage this has is that, unlike a biquad lowpass, the resonance amount and cutoff point are completely independent from each other. And since you have 4 separate filter stages, you can place non-linearities between each phase for a nice rounded distortion sound! This really gives the filter a lot of punch. In other words, for subtractive synthesis, you don't necessarily want a clean filter like a biquad. You really want a distorted, messy filter. The downside is that there is a tuning issue to be solved, which turns out to be non-trivial. I won't cover any of this here, though, but I will say that it is a potentially very rich sounding filter that should be looked into. The feedback tuning problem can be solved properly through mathematics, or it can be fixed to a somewhat satisfactory degree using guesswork and oversampling. An excellent explanation is available at http://rhordijk.home.xs4all.nl/G2Pages/ResFilters.htm. State-Variable Filter First appearing in Hal Chamberlain's wonderful book Musical Applications of Microprocessors, this 12 dB/oct filter gives you lowpass, highpass and bandpass from the same structure. This is not a filter I've used much, so I cannot really comment on it, but it is worth looking into and is a popular filter structure. What Is a Filter? We all know what filters do from a human-hearing (frequency domain) standpoint: They boost or chop out frequencies in a sound. But like everything else in audio processing, we need to figure out what to do on a per-sample level to achieve this effect. Let's look at a very simple filter that averages neighboring samples together. Think of it as an audio blur. You could describe it like this: y(n) = 0.5 x(n) + 0.5 x(n – 1) This is saying that to get the output at sample position n, you add half of the current input sample at position n to the previous input sample at position n-1. Some filters, like this one, multiply the input by some coefficients (.5 and .5 in this case) and add them together. Others do the same thing, but with past outputs. And both can be combined. Where filters use past inputs you get zeroes, and where they use past outputs you get poles. In general, a filter with N zeroes and M poles can be described as: N M r=0 r=0 a 0 y[ n]= ∑ b r x [n−r ]− ∑ ar y [n−r ] We will discuss poles and zeroes in greater detail. I Keep Hearing “Linear Time-Invariant System”. What Is That? Filters are an example of a linear, time-invariant system. This isn't as complicated as it sounds. Here's why: Linear A system is called linear if you can take two systems, arrange them in any order, and get the same result. For example, if you run a signal through a lowpass after a highpass, you'd expect them to combine into a bandpass. The lows are cut out, then the highs are cut out. If you reverse the order (highs are cut out first, then the lows), it's the same thing. Now, if you drop a distortion effect between the two filters, this is no longer the case. The system is now not linear anymore. This is because, in general, a distortion effect depends on the amplitude of the signal. Running it through a lowpass or a highpass first unmistakably changes how the distortion behaves, and you will get very different sounds reversing the order. Time-Invariant The operation of the filter does not depend on time. For example, if you wait a second and play a noise through a filter, it will filter just the same as if you started the noise immediately (minus the blank space at the beginning, of course). So, as long as your filter isn't sweeping, it's time-invariant. Sinusoids in Complex Form We're used to frequencies being described as a single number. For example, the value 440hz. But, this is unsuitable for filter design because while this information tells us about the pitch, it does not say anything about the phase. And, what are filters but phase shifting and adding? Which isn't to say that you can't have purely real filters, but there are some limitations such as not being capable of resonance. So, we turn to the complex domain. If you want to know why it works, keep reading. If not, just skip to the next section! We know that a complex number can be used to represent two independent values as one number. For example, if I say 3 + 5i, that's X=3 and Y=5 when graphed on a pair of axes. For our purposes, we will encode phase and frequency in a single complex number. We can do this by letting the real portion be a cosine, and the imaginary portion be a sine (a cosine phased ahead by 90 degrees). Here's an example: cos(w) + i sin(w) This is equivalent to writing (cos(w), sin(w)). If we add together sines and cosines of varying phases but the same frequency, we get sinusoids of all different phases back. This is where it really becomes convenient for sound. Yehar's tutorial Digital Sound Processing Tutorial for the Braindead and Musimathics vol.2 both discuss this in greater detail. So why am I going off on this tangent? See, Euler discovered that e^iw = cos(w) + i sin(w). That means we can just use e^iw whenever we want to represent a sinusoid of any phase! Due to how complex numbers work, it shakes out like this: cos(w) = (e^iw + e^-iw) / 2 = cos(w) + isin(w) + cos(w) – isin(w) = 2cos(w) / 2 = cos(w) sin(w) = (e^iw – e^-iw) / 2i = cos(w) + isin(w) – cos(w) + isin(w) = 2isin(w) / 2i = sin(w) And any in-between phase can be represented, too, as long as the magnitude adds up to 1. We can also use it any time we want to talk about a point on a unit circle, like we will with the z-plane. However, keep in mind that although we're looking at sound on a 2d plane here, this isn't the same as the Z-Plane, which is the subject of the next section. I only discussed complex sinusoids because it's a compact way of representing a sinusoid of any given phase and it is going to be used a lot. Though it might look intimidating, it is actually a lot easier to manage in an equation! When we start working through the filter equations, you'll see why. The Z-Plane As mentioned in the introduction, a variety of filters can be made from pole-zero design techniques. We start with a 2d plane with the unit circle drawn onto it as a guide. Going along the unit circle, 0 degrees corresponds to 0hz, while pi corresponds to Nyquist (half the sampling rate). Frequencies from pi to 2pi are mirrored frequencies. If we want to make a filter that cancels a frequency, we put a zero down on this plane at that frequency. Similarly, if we want to emphasize a frequency, we put a pole down. The amount of effect that a pole or zero has on a frequency is inversely proportional to the distance from that pole to the point on the unit circle. In other words, a zero lying on the unit circle has a greater effect than one away from the circle. Note that if a pole is placed outside of the unit circle, the filter is unstable, it will produce unpleasant feedback, and will possibly blow out a speaker or two. As an example of pole-zero filter design, let's say we want to cancel frequencies at pi/2 (at 44100hz sampling rate, this is 11025hz). We would place a zero at some radius at angle pi/2. Now, as we trace along the unit circle, the closer the frequency gets to that zero, the more the frequency is diminished. Note that poles can also result in a lowpass or highpass, and this will be steeper than doing it with zeroes. For example, while in a one-zero filter you'd create a lowpass by cutting the highs, in a onepole you'd create a lowpass by emphasizing the lows and then turning everything down. Now, there's something missing from this example. We talk about complex numbers on a 2d plane, but what we really want is to input a real signal and get a real signal back. How can this happen if the complex numbers don't cancel? The answer is that if you have a complex zero or a complex pole (a zero or pole away from the x-axis), that pole should have a complex conjugate. If you don't remember how to cancel the complex component with a conjugate, here's an example: Say we have a complex number (1 + 2i). The 2i can be canceled out by multiplying by another complex number which has a negated complex component. Observe: (1 + 2i)(1 – 2i) = (1 – 2i + 2i – 2i^2) = (1 – 2i^2) = (1 + 2) This implies that if you have a filter with a complex pole or zero, you should add another complex pole or zero, but with the Y (complex) component flipped. If you have a zero at (0, 1), you should add another at (0, -1). If a pole is at (.6, .95), there should be another at (.6, -.95). Designing with the Z-Plane Let's design a filter starting with a Z-Plane graph. We'll do a sweepable lowpass with adjustable resonance, which is everyone's favorite. Now, a basic lowpass can be made by putting down a zero at nyquist. The effect this has is that as the frequency approaches Nyquist, it is diminished. But what about the resonance? Remember that poles are where frequencies are emphasized. What we want to do is emphasize the frequency at the filter's cutoff. By placing a pole at that location, the amplitude of the frequency is increased as it approaches the pole. Then, it drops off as it gets closer to the zeros. As mentioned above, that pole needs a conjugate. What we end up with is a 2-pole 2-zero lowpass. If you decide you want a highpass instead, the zeros can be moved from Nyquist to DC (angle=0). Or, a bandpass may be created by placing one zero at DC and one at Nyquist. The Z-Transform (A Short Detour) We're about to start throwing around a complex variable, “z”. What is it and how does it relate to the Z -Plane? When we talk about x(n) or y(n), we're talking about input and output samples in the time domain, at time equal to n. But, when we talk about X(z) or Y(z), we're talking about input and output in the frequency domain. So then what's the Z-Transform? In a mathematical sense, it's a juggling of the Discrete Fourier Transform. Shown below is the Discrete Fourier Transform (remember that each e^-iwn is a sinusoid at a specific frequency and phase): X (e i wT N )= ∑ x[n ]e −i w n T n=0 And here's the z-transform (because you can't have something called a z-transform without any z's, right?): N X ( z)= ∑ x [n] z n =0 −n What have we done? Well, e^iw is a point on the unit circle (look up Euler's Identity). But z is more powerful than that-- it's any complex number that we want it to be! We've taken the Discrete Fourier Transform and have unrestricted our choices. If e^iw is a train that can only drive on the unit circle railroad, z is an off-road vehicle that can go anywhere it damn well pleases! In math terms, it's a generalization of the Discrete Fourier Transform. Don't worry about this too much. In this case, z is the complex frequency e^iw and n is the sample delay. When you see z^-N, just think “this coefficient x[n] is associated with a sample n-samples back in our signal”. If you want to explore this in more detail, I heavily recommend Musimathics Vol.2. It's got proofs for days that show exactly how you get from here to there, and it is explained far better than I could ever manage. Transfer Functions – What Are They? A transfer function describes a filter in terms of a ratio between its input and its output. For example: Y(n) = H(n) X(n) This equation says that some spectrum, Y (the output), is gotten by multiplying the input, X, by some function, H. By the way, this is all in the frequency domain. In the time domain we'd be convolving x and y. To find the transfer function, we need to figure out what H is. Jugging the equation gets us: H(n) = X(n) / Y(n) Now, X and Y are frequency-domain representations. Let's swap in the time-domain representation of the generalized filter equation's inputs and outputs (see the previous section). N ∑ x[ n] z−n H (n)= n=0 M ∑ y [n] z−n n =0 This is a transfer function for a filter that has N zeroes and M poles. In a practical sense, what we get out of this is a mathematical tool for understanding how a given filter affects its input. For example, you can use it to find how different frequencies are affected (which is covered later in this tutorial). You can also use it to find how the filter shifts the phases of various frequencies. It also makes it easier to work out the Algebra needed to find the coefficients. A transfer function not only presents H as a ratio of its input to output, but it is a nice demonstration of what poles and zeroes are: The zeroes of any function are where that function equals zero. And the poles in a filter are where the H function is undefined. In other words, they are asymptotes. This will be explored in more detail in the next section. Solving the Transfer Function for the Filter Coefficients If you remember from algebra, if you have a function factored into a form such as: f(x) = (6-x)(2-x) ...then the zeros of the function will be at x=6 and x=2. This is essentially what we wish to find in this filter. Additionally, we want to find where the asymptotes (poles) are, too. Those are when the equation divides by zero and zooms off towards infinity. To accomplish this, we use what's called the transfer function. The transfer function takes a frequency in complex notation. What you get out of it is a number which describes the response of the filter at that frequency. We'll start with the transfer function in the form used in the book Elements of Computer Music by F. Richard Moore: N ∏ (1−Z i z−1 ) H ( z)= i=0 M ∏ (1−P i z−1) i=0 Looking at this form, you can see that the frequency z divides the pole or zero locations. When that pole or zero location equals the z location, they cancel leaving 1, which of course makes the sum zero and voila: you've found your root. This will become clearer as we go. Below, we have the generic biquad transfer function in all of its glory. You can clearly see the two zeros on top, and the two poles below. For example, R_z*e^iw_z is the location of one zero at frequency w and radius R. Notice that since the poles and zeros have complex conjugates, the exponent for e on the second root is negative. 1−R z e i w z −1 1−R z e−i w z−1 H z = iw −i w −1 1−R p e z −1 1−R p e z You may be tempted to replace all unfamiliar exponential frequency notation with sines and cosines. I found this to be a mistake. If you're like me, remembering a couple algebraic exponent rules is easier than remembering a whole mess of trigonometry identities. Another perk of keeping the poles and zeroes in exponential form is that the equation is shorter. z p z p And another thing to note: We could have let Z or P be any complex number anywhere on this plane. For example, we could have arbitrarily chosen something like P = .3 + 9i. But we chose R*e^iw because the angle corresponds to a frequency that's affected, and the radius R corresponds to the strength of that pole or zero on that frequency. Not only that, but it also helps terms factor and cancel (especially when we start solving for gain), so it's convenient in an Algebraic sense too. Ok, back to the problem at hand. What we really want is a zero fixed at half the sampling rate. That is, even though we want frequencies at w_p emphasized, we want them to diminish as they get towards Nyquist. So, we set w_z to pi and get this: 1−R z e i z −1 1−R z e−i z−1 H z = 1−R p e i w z −1 1−R p e−i w z −1 p p Now, we can substitute in Euler's identity for the zeros: e i =cos i sin −10 −1 And remember that R=1 since it lies on the unit circle. This gives us: −1 −1 (1+z )(1+z ) H ( z)= i w −1 −i w −1 (1−R p e z )(1−R p e z ) Now we really only have the bottom to worry about. Not only that, but now this equation really says something: We have a biquad filter with the zeros at half the sampling rate, and two poles at R radius and angle w_p. Also note that the top is now strictly real because the zero lies on the x-axis. We'll finish off the top later, but now let's concentrate on the poles. p p To reduce the equation further, we multiply the bottom out, giving: −1 −1 (1+ z )(1+z ) H ( z)= i w −1 −i w −1 2 i w −i w −2 1−R e z − R e z +R e e z p p p p Ok, this looks scary, but there are a lot of combinable terms in here. First, the e's next to the R^2 term on the end can be multiplied together. After the exponents are added, you'll be left with e^0, which is just 1 (just like anything to the 0 th power). −1 −1 (1+z )(1+ z ) H ( z)= i w −1 −i w −1 2 −2 1−R e z − R e z +R z But what about the -Re's? We've taken them as far as they can go in exponential form, so let's use Euler's identity again. We know that since they are complex conjugates that we should be left with a real result. To make it visually simpler, let's only focus on these terms: −R ei w −R e−i w =−R cos w p −i R sin w p− R cos w pi Rsin w p −2 R cos w p Look at how much can cancel! Let's put this into the equation, shall we? −1 −1 (1+z )(1+ z ) H ( z)= −1 2 −2 1−2 R cos w p z +R z p p p p −1 2 (1+z ) −1 2 −2 1−2 R cos w p z +R z That's one done transfer function. Since the z^-1 represents a one-sample delay and z^-2 represents a two-sample delay, we can take the filter coefficients right from this: H ( z)= a1 = 2 a2 = 1 b1 = -2Rcos(w) b2 = R^2 From the Transfer Function to the Filter Equation Let's look at the general form of a filter: y n=∑ ai x n−i−∑ bi y n−i This equation takes in a sample of input at time n. There are i poles and i zeros. The input sample goes through a series multiplies and adds. The function x(t) is the input at time t, and the function y(t) is the output at time t. For example, if we have a filter described like so: y(n) = x(n) + 0.5 x(n-1) Looking at it from right to left, this would take the previous input sample (x(n-1)), multiply that by half, and then add it to the current input sample (x(n)). This would give us a very simple one-zero filter. Ok, so we can see it's got one pole or zero because i is 1. But how do we know that's a zero and not a pole? There was something I didn't mention in the Poles and Zeros section. Zeros deal with past filter inputs. So what do poles do? Poles deal with past filter outputs. Poles can be thought of as feedback. That's why they can produce resonance. If we had a filter like this: y(n) = x(n) – 0.5 y(n-1) This would be a one-pole filter instead (but would have no resonance-- you can't have resonance with only one real pole). Ok, so back to our lowpass filter. We have two poles and two zeros, so the equation would be something like this: y n= x na0 x n−1a1 x n−2−[b0 y n−1b 1 y n−2] The a's and b's are called the filter coefficients, which are what we found in the previous section. We can now substitute them in and finish our filter equation: y n= x n2 x n−1 x n−2−[−2 Rcos y n−1 R2 y n−2] y n= x n2 x n−1x n−22 R cos y n−1−R2 y n−2 Solving For Gain Unfortunately, we're not done yet. Now, the filter as presented here works, but the amplitude of its output varies wildly from inaudible to blowing-headphones-off loud. You might never even hear it filtering because it can clip so badly. One approach to fix this is to find the filter's gain at the resonance (pole) frequency. To do this, you would solve the equation | H(e^iw) | where w is the frequency of the poles. Why do we solve it for this point? It's because this frequency is where the filter will be loudest. If we were doing, say, a nonresonant lowpass, it might be loudest at angle=0 (0 Hz) instead. A non-resonant highpass might be loudest at angle=PI (one half the sampling rate). So, what really is | H(e^iw) |? It's the magnitude of a complex function. If you think back to Algebra, you might remember that if you have a complex number, you can find the magnitude (length) of it by doing this: Let's say you've got 3 + 2i: | 3 + 2i | = sqrt( (3 + 2i) (3 – 2i) ) = sqrt( 9 - 4i^2 ) = sqrt(9 + 4) = sqrt(5) Hmm, this is suspiciously close to the Pythagorean Theorem. If you've got a point at (0, 0) and another at (3, 2), is it the same? Remember that 3 + 2i is another way of describing a point at (3, 2): Sqrt( 3^2 + 2^2 ) = sqrt(9 + 4) = sqrt(13) Yes, they are equivalent! This gives us our pick. Some books explain gain by saying that the gain at a given frequency is found by taking the distance from the poles to the point on the unit circle of the frequency in question, and multiplying them together. Instead, we will just find the magnitude of the complex transfer function at that frequency. Why? It keeps the math tidier. Resist the urge to get away from complex exponents and flee back to concepts you're more comfortable with! It'll make the equations easier to work with. Now, let's begin. Call gain the at a certain frequency the function G(w). Basically, here's what we need to find: G (w)=∣H (e )∣= √ H (e ) H (e iw −iw iw ) OK, so let's see how this all works. Let's take a peek first at the original transfer function, before we started mucking with it: −1 2 H ( z)= (1−R p e i wp (1+z ) −1 −i w −1 z )(1−R p e z ) p Taking the magnitude of this and plugging in e^iw for z gets us this: ∣H (e iwp )∣= √ H (ei w ) H (e−iw )= p p √ (1+e−iw )2 (1+ei w )2 p √ (1−R iw p p iw p e e )(1− R p e −iw p iw p p iw p e )(1−R p e e −iw p −iw p )(1− R p e e −iw p ) First, notice all the w's are labeled w_p for 'pole', even in the numerator where the function's zeroes are. That's not a typo: We really are just concerned with what the gain is at the point the pole is closest to, because in this particular filter that will always be the loudest frequency. For now, let's ditch the subscript 'p' so I don't have to type it anymore. Now, before we multiply by the complex conjugate, let's simplify things as much as possible: First, let's tackle the bottom: √ (1− R iw p iw e e )(1−R p e −iw iw iw −iw e )(1−R p e e )(1−R p e −iw −iw e ) To get the (1-R)'s, the e's in those positions cancel out to 1 (adding exponents): √ (1− R p e −iw iw iw −iw e )(1−R p )(1−R p )(1− R p e e ) … and there are two (1-R)'s, so we can immediately take them out of the square root: (1−R p) √(1−R p e −iw −iw e iw iw )(1−R p e e ) Now combine the other terms (adding exponents): (1−R p) √(1−R p e −2iw )(1− R p e 2iw ) And finally, multiply out what's inside of the square root, expand e^iw to its trigonometric definition so that the i*sin(w)'s cancel, and we're left with a fairly concise expression of the two pole's effects on the sound's gain at the pole's frequency! (1−R p) √ 1−2R p cos(2w)+ R p 2 But, we still have to find the effect that the zeroes have on the sound. For that, we need to solve the top. I won't go through all the rules again because they're very similar to what has already been solved, and this is much simpler than tackling the denominator: √ (1+e− jw )2 (1+e jw)2 − jw (1+e jw jw )(1+e ) 2+e +e − jw 2+2cos (w) Reuniting the numerator and denominator, this gives us a gain of: G (w)= 2−2 cos(w) (1−R p) √(1−2R p cos(2w)+R2p ) What does this mean? It means that to keep gain constant, you should multiply the original signal by the reciprocal of this before feeding it into the filter. This Isn't Filtering Enough! OK, so you worked out all the equations, put the filter together, and you have it rigged up like this: The radius of the pole controls the amount of resonance, and the angle the cutoff frequency. But, somehow it only filters well at low cutoff settings when resonance is really high! What gives? One important thing to note is this: If you have a pole at angle=0 or angle=pi, this is basically a real two-pole filter. A real two-pole filter works by sliding the pole along the real X axis. It's just like having two one-pole filters in series: two poles directly on top of each other. When the pole is closest to (1, 0), it filters the most. As it slides along the x-axis towards (0, 0), it filters less and less. In this two-pole filter, you're sweeping the poles from a certain angle towards angle=0. Once you get to 0, it's still too leaky because it's too far from the edge of the unit circle! In other words, the pole just isn't having enough effect. One possible fix is to morph the resonance setting as it travels so that you wind up just to the left of (1, 0) at the lowest filter cutoff setting, no matter what filter resonance was initially set to. For example, you could make the radius go from .95 to .995 as the pole's frequency sweeps from 4000hz to 10hz. This will ensure that it ends up filtering out enough once it hits 10hz. The resonance won't be completely constant, but it also will be hard to tell as a listener. Improving the Filter Making a 24db Filter A two-pole filter gives us 12db per octave of attenuation (the frequencies drop off slowly). This is okay, but for some sounds it's not great. A lot of synthesizers have a 24db filter (the frequencies drop off more sharply). We have two options for making one of these: Option 1: Design a 4-pole filter by adding two more roots to the transfer function. This isn't horribly messy, but it is more work. Option 2: String together two 2-pole filters in series. This will also create a 24db filter. Adding Saturation The warm analog sound that is sought is a product of more than a pristine filter. The signal actually is saturated between the filter stages, enhancing the resonance and making the sound meatier. If we've gone for option #2 in making a 24db filter, we can stick a something like a hard clipper between the stages. Some Useful Identities Derivations from Euler's Identity: i e =cos i sin Or, more generally: iw e =cos w+i sin w This is a common cancelation (remember that sin is an odd function while cos is even): iw −i w e +e =cos(w)+i sin (w)+cos(w)−i sin (w)=2 cos(w) Great DSP Links Much of the information in this guide is compiled from knowledge from the following sites (and, yes, this is because I am too lazy to do proper footnotes): DSP Guide : http://www.dspguide.com Yehar's DSP Tutorial for the Braindead : http://www.student.oulu.fi/~oniemita/dsp/dspstuff.txt Julias O. Smith III's online DSP guide : http://www-ccrma.stanford.edu/~jos/filters/ DIY Moog-style Filter : http://rhordijk.home.xs4all.nl/G2Pages/ResFilters.htm And the following books: Musimathics vol.2 by Gareth Loy Elements of Computer Music by F. Richard Moore The Scientist and Engineer's Guide to Digital Signal Processing by Steven W. Smith These three books are highly recommended. Moore's book goes into some depth about the Z plane and pole-zero design, but also goes over many other synthesis and music concepts. Smith's book focuses on practical filter usage, with the more advanced theory tucked away in the back. Musimathics is excellent at breaking down these equations and explaining why it is that they work.
© Copyright 2026 Paperzz