And now, an htm page for a second order lopass. Again, generalizing to other filter types is trivial, assuming the transfer function in s is known.
JJ
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0053)
www.earlevel.com/Digital%20Audio/Bilinear.html -->
<HTML>
<HEAD>
<TITLE>The Bilinear Transform</TITLE>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2963" name=GENERATOR>
</HEAD>
<BODY text=#333333 vLink=#66099 aLink=#ff0000 link=#990000 bgColor=#ffffff
leftMargin=8 topMargin=8>
<H3>The bilinear z transform</H3>
<P>The bilinear transform is the most popular method of converting analog filter
prototypes in the s domain to the z domain so we can implement them as digital
filters. The reason we are interested in these s domain filters is that analog
filter theory has been around longer than digital filter theory, so we have
available to us a number of popular and useful filters in the s domain. The
standard biquads used heavily in audio processing are direct implementations
from the s domain using the bilinear transform.
<P>The theory of the bilinear transform is well documented in DSP texts and on
the web, so rather than spend time going into the theory, we'll cut to the chase
and show how to do the transform, using a second order lowpass filter as an
example.
<P>The s domain transfer function of a second order lowpass filter is:
<BLOCKQUOTE><P><PRE>
H(s) = 1 / (s^2 + A*s + 1)
</PRE>
</BLOCKQUOTE>
<P>where (A) is the damping coefficient, i.e. the inverse of the filter's Q.
<P>To move to the z domain, we need to substitute for s in terms of z. At the
same time, we "pre-warp" the response using the TAN function in order to wrap
the infinite s plane onto the circular z plane. The combined substitution is:
<BLOCKQUOTE><P><PRE>
s = (1 - z^-1) / (K*(1 + z^-1)) </PRE>where:
<P><Font face="Courier New" size=-1>
K = TAN (</FONT><Font face=Symbol>p</FONT><Font face="Courier New" size=-1> * Fc / Fs)</FONT>
<P>Fc is the desired corner frequency, and Fs is the sampling frequency.
</BLOCKQUOTE>
<P>Here's our z domain transfer function after substituting for s:
<BLOCKQUOTE><P><PRE>
H(z) = 1 /[(1 - z^-1)^2 / K^2*(1 +z^-1)^2) + A*(1 - z^-1) / K*(1 + z^-1) + 1]
</PRE>
</BLOCKQUOTE>
<P>In order to solve for our filter coefficients, we need to get the equation
into the form of a second order polynomial in the numerator (the zeroes) and
another second order polynomial in the denominator (the poles). That is, we need
it to look something like this:
<P><BLOCKQUOTE>
<PRE>
b0 + b1*z^-1 + b2*z^-2
H(z) =
a0 + a1*z^-1 + a2*z^-2
</PRE>
</BLOCKQUOTE>
<P> We multiply the nominator and the denominator of the substituted transfer function by:
<P><BLOCKQUOTE>
<PRE>
K^2*(1 + z^-1)^2
</PRE>
</BLOCKQUOTE>
<P> We obtain the following expression:
<P><BLOCKQUOTE>
<PRE>
K^2*(1 + z^-1)^2
H(z) =
(1 - z^-1)^2 + A*K*(1 - z^-1)*(1 + z^-1) + K^2*(1 + z^-1)^2
</PRE>
</BLOCKQUOTE>
<P> We expand the numerator and the denominator, and rearrange them in descending powers of z to obtain:
<P><BLOCKQUOTE>
<PRE>
K^2 + 2*K^2*z^-1 + K^2*z^-2
H(z) =
(K^2 + A*K + 1) + 2*(K^2 - 1)*z^-1 + (K^2 -A*K + 1)*z^-2
</PRE>
</BLOCKQUOTE>
<P>Our coefficients are now evident:
<P><BLOCKQUOTE>
<PRE>
b0 = K^2 b1 = 2*K^2 b2 = K^2
a0 = K^2 + A*K + 1 a1 = 2*(K^2 - 1) a2 = K^2 - A*K + 1
</PRE>
</BLOCKQUOTE>
<P>Because the (a0) coefficient is associated with y[n], the filter output, we
divide everything by (a0) to normalize the filter. Here we also note the
relationships between the (b) coefficients:
<P><BLOCKQUOTE>
<PRE>
K^2
b0 =
b1 = 2*b0 b2 = b0
K^2 + A*K + 1
2*(K^2 - 1) K^2 - A*K + 1
a0 = 1 a1 =
a2 =
K^2 + A*K + 1 K^2 + A*K + 1
</PRE>
</BLOCKQUOTE>
<P>Original article: <A href="
www.earlevel.com/Digital%20Audio/Bilinear.html" target=_blank>
www.earlevel.com/Digital%20audio/Bilinear.html</A>
</BODY>
</HTML>