= fS.11x3 \; greater than or equal
fS.11c> \; greater than
ft \2 ... >
ft \2 ... >
ce >ft \4 ... >
ce
{ #m#k#f#i#l#t#e#r is a program which designs an infinite impulse response
digital filter from parameters specified on the command line. Lowpass,
highpass, bandpass and bandstop filters, with Butterworth, Bessel or
Chebyshev characteristics, are designed using the bilinear transform or
matched ^z-transform method. For most applications the bilinear
transform method is recommended. The program can also design resonators
with bandpass, bandstop or allpass characteristics. A companion
program, #m#k#s#h#a#p#e, designs raised-cosine finite-impulse-response
filters and Hilbert trans-formers.
Other programs generate ``C'' code (in a variety of formats)
from the compiled filter specification, and generate various graphs in
``gif'' format. }
{ The source code of the programs (in C++) is at
ft >TABL
and there is a World Wide Web form-based front end at
ft >TABL
The WWW front end is recommended. For most applications, it is the most
convenient way to use the #m#k#f#i#l#t#e#r package. }
>SECT
{ In normal use, the output of #m#k#f#i#l#t#e#r is a set of ^s- and ^z-plane
pole and zero posi-tions, the filter recurrence relation, and some other
information in human-readable form. By specifying the #-#l
parameter, computer-readable output is produced which can be piped into
other programs. In particular, the program #g#e#n#c#o#d#e takes the #-#l
output from #m#k#f#i#l#t#e#r and generates a piece of C or C++ code which
implements the filter, and the program #g#e#n#p#l#o#t takes the #-#l output and
generates a ``gif'' file contain-ing a frequency-domain or time-domain
response graph. }
{ A warning about higher-order Bessel filters: although an analogue
Bessel filter has an excellent approximation to a linear phase
characteristic, the pre-warping inherent in the bilinear transform
design method upsets this, and the corresponding digital filter often
deviates significantly from linear phase. This is particularly evident
in the higher-order Bessel filters (say ^N_>_2). You're advised to study
the graphs produced by #g#e#n#p#l#o#t before you use any Bessel filter
generated by this package, and to consider using the matched ^z-transform
for Bessel filters. }
{ #m#k#f#i#l#t#e#r can also design resonators.
A resonator is a digital equivalent of a tuned circuit. There are three
varieties:
TABL
TABL
TABL }
{ The phase response of the bandpass resonator approximates to +/p/2 at
frequencies below the centre and --/p/2 at frequencies above the
centre, and is exactly zero at the centre. The bandstop and allpass
resonators both have approximately zero phase shift except at the centre
frequency, at which the phase shift is nominally +-/p; however in
the case of the bandstop resonator, since the gain is zero at the
centre frequency, the phase shift at that frequency is not defined. }
{ In both respects (magnitude and phase) the resonator behaves like a
``real'' analogue tuned circuit. }
{ If you want a narrow bandpass or
bandstop filter, a resonator is often more efficient and better
behaved than a traditional (e.g. Butterworth) filter. }
{ All types of resonator are designed directly in the ^z-plane. The
bilinear transform is not used here. A bandpass resonator is
constructed first; if you asked for one of the other types, the
bandpass resonator is transformed accordingly. }
{ The number of poles is fixed at 2, initially at ^z_=_^r_exp_+-j/t, where
^r is close to 1. Two zeros are added at ^z_=_+-1, to ensure zero
response at d.c. and h.f. }
{ The presence of the conjugate poles affects the response slightly: the
``correct'' pole positions are not exactly where you would expect them
to be. Consequently, the initial pole positions are next refined
iteratively, to place the peak as close as possible to where you said
you wanted it. }
{ If you asked for a bandstop or allpass resonator, the zeros at
^z_=_+-1 are then removed. For a bandstop design, new zeros are
added on the unit circle at ^z_=_exp_+-j/t, where /t
is the ^u^n^r^e^f^i^n^e^d initial value of /t. This gives a zero
response at the precise centre frequency. For an allpass design, zeros
are added at (1/^r)_exp_+-j/t, where /t this time is the
^r^e^f^i^n^e^d value, to balance the existing poles. }
{ You may specify a value of #I#n#f as the ^Q (quality factor) of a bandpass
resonator, in which case you will get an oscillator (with poles exactly
on the unit circle in the ^z-plane). }
>SECT
{ ``[_]'' means ``optional''; ``|'' means ``or''._
``^(^N^o^t^ ^R^e^s^)'' means that the parameter is neither required nor allowed
for resonators, i.e. if #-#R#e has been specified. }
{ The following parameters are ^r^e^q^u^i^r^e^d^: }
< \t \t \tf Filter type: Bessel, Butterworth, Chebyshev or Resonator,
respectively. Exactly one of these options must be specified. The
parameter ^r is the passband ripple in dB, meaningful for Chebyshev
designs only. (NB:_ ^r_<_0.)_ ^Q is the Q-factor of the resonator:
the higher the Q, the narrower the peak. Values in the range
10_..._1000 are typical. The special value #I#n#f specifies an
oscillator. >
>TABL
< \t \t \tf Pass type: Lowpass, Highpass, Bandpass, Bandstop or
Allpass, respective-ly. Exactly one of these options must be specified.
For resonators, only --#B#p, --#B#s and --#A#p are allowed. For non-resonators,
all pass types ^e^x^c^e^p^t --#A#p are allowed. >
>TABL
TABL
\need 12
< \t \t \t \t \t (blt) \t (mzt) >
< \t >
< \t Lowpass: \t __^N \t none \t __^N \t ^N at --1 \t none >
< \t >
< \t Highpass \t __^N \t ^N at 0 \t __^N \t ^N at +1 \t ^N at +1 >
< \t >
< \t Bandpass: \t _2^N \t ^N at 0 \t _2^N \t ^N at --1; \t ^N at +1 >
< \t \t \t \t \t ^N at +1 \t >
< \t >
< \t Bandstop: \t _2^N \t ^N at +j'w'\0; \t _2^N \t _2^N \t 2^N >
< \t \t \t ^N at --j'w'\0 \t \t \t >
>tabs
>TABL
TABL
TABL
TABL
>SUBS
{ The following parameters are ^o^p^t^i^o^n^a^l^: }
TABL
TABL
TABL
TABL
TABL
>SUBS
>SECT
If the #-#l option is specified, #m#k#f#i#l#t#e#r writes the following to standard
output:
TABL
< \t \t For a highpass filter: \t ^g _=_ ^H(0.5) >
< \t \t For a bandpass filter: \t ^g _=_ ^H((/a\1 + /a\2) / 2) >
< \t \t For a bandstop filter: \t ^g _=_ [^H(0) ^H(0.5)]/0/./5 >
{ \t The program outputs the magnitude of ^g. }
>TABL
TABL
TABL
{ A trial run,
specifying the same parameters both with and without #-#l, will make this
clear. }
>SECT
{ This program generates a finite impulse response filter with a
raised-cosine magni-tude response, or a Hilbert transformer. It is run
by:
< \t #m#k#s#h#a#p#e #-#i ^n [#-{#l#w#x}] >
< \t #m#k#s#h#a#p#e #-#h ^n [#-{#l#w}] >
>TABL
where /a is the ``corner'' frequency,
/b is the excess bandwidth (roll-off factor), and ^n is the length of the
impulse response, in samples. }
{ Although #-#l is an optional parameter, the program doesn't do anything
useful if #-#l is not specified. With #-#l, the output is in the format
described in section 2.2 above. }
{ Exactly one of --#c, --#r, --#i or --#h must be specified._ --#c specifies
a raised-cosine response._ --#r specifies a square-root response, i.e.
the magnitude of the response at any frequency is proportional to the
square root of the response you would have got if you had specified --#c
instead of --#r. Square-root raised-cosine filters are often used in
digital communication systems. --#i specifies the identity response
(constant ``1'' at all frequencies)._ --#h specifies a Hilbert
transformer. For --#h and --#i, the only parameter required is ^n, the
length of the impulse response. }
{ The optional parameter --#x (not available for Hilbert transformers)
specifies that ^x_/_sin_^x compensation is to be applied in the frequency
domain, to compensate for the sin_^x_/_^x response of real-world DACs
(which output a sequence of square pulses when, ideally, they should be
outputting a sequence of delta functions). }
{ The optional parameter --#w applies a Hamming window to the impulse
response. This can significantly improve (reduce the amplitude of) the
sidelobes, at the cost of some distortion in the passband response shape
for short filters. }
{ The corner frequency is defined for raised-cosine filters as the
frequency at which the response is --6_dB relative to the response at
0_Hz if --#c is specified, or --3_dB if --#r is specified. }
{ For further information on raised-cosine filters, see
rin >ft >TABL }
>SECT
{ The program #g#e#n#c#o#d#e takes the #-#l output from #m#k#f#i#l#t#e#r or #m#k#s#h#a#p#e and
generates a piece of C or C++ code which implements the filter. With
the exception of code generated by #-#f or #-#x#y#c (see below), the code is
meant primarily to be read, not executed; however it is syntactically
correct and complete except for input and output code, which you will
have to supply. }
{ #g#e#n#c#o#d#e and #g#e#n#p#l#o#t do not work with oscillators designed by #m#k#f#i#l#t#e#r
(i.e. band-pass resonators with infinite ^Q), because the ``gain'' of an
oscillator is infinite. }
{ The usage is:
>TABL }
{ The parameters control the format of the output. The default is
#-#a#n#s#i#c, which specifies Ansi ``C''._ #-#x#y#c causes just a single line to
be output, containing the following data separated by tab characters:
the pass-band gain ^g (see section 2.2); the ^Z+1 ^x coefficients; the ^P+1
^y coefficients. }
{ #-#f generates code required
by Fisher's experimental ``Filter-Filter'' program. This option is
intended for internal use only. }
{ The program #g#e#n#p#l#o#t takes the #-#l output from #m#k#f#i#l#t#e#r or #m#k#s#h#a#p#e
and generates a ``gif'' file containing a graph of either the
phase and magnitude (frequency-domain) response, or the impulse
(time-domain) response. The usage is
>TABL
^f^n^.^g^i^f is the name of the output ``gif'' file. #-#i selects an impulse
response graph and #-#s selects a unit-step response graph; ^n is the
number of samples along the time axis. If neither #-#i nor #-#s is given
then a frequency-domain graph is produced, in which case the optional
parameters /a\1 and /a\2 are lower and upper limits on the range of
frequency values to be plotted, expressed as a fraction of the sampling
rate. The default values are /a\1_=_0 and /a\2_=_0.5, i.e. the response
is plotted from zero frequency up to the Nyquist frequency. If the #-#l#o#g
option is specified, the magnitude scale is logarithmic and labelled in
dB from ^m^i^n to zero. (^m^i^n must be negative.) If the #-#l#o#g option is
omitted, the magnitude scale is linear from 0.0 to 1.0. }
{ The #-#d option modifies the phase part of the frequency-response graph.
Normally, the phase decreases monotonically wth frequency, because all
causal filters have a strictly positive overall signal (group) delay. If
#-#d is specified, #g#e#n#p#l#o#t tries to guess the group delay and plots the
phase relative to this figure. This is useful in the case of a
linear-phase finite-impulse-response filter (e.g. raised-cosine or
Hilbert transformer), in which case the delay is half the number of zeros,
and likely to be confusing for other filter types. }
{ #g#e#n#p#l#o#t uses the #g#d ``gif'' manipulation library from
Quest Protein Database Center, #<#h#t#t#p#:#/#/#s#i#v#a#.#c#s#h#l#.#o#r#g#/#g#d#/#g#d#.#h#t#m#l#>. }
>SECT
< \t \t Generate a 4-pole Butterworth lowpass filter with corner
frequency 0.2 ^f`s; >
< \t \t display pole & zero positions and filter recurrence relation >
>TABL
< \t \t Generate C code for the above filter >
>TABL
< \t \t Generate phase & magnitude graphs for the above filter >
>TABL
\need 3
< \t \t Generate a bandpass resonator with Q_=_1000 and centre frequency
0.3_^f`s; >
< \t \t display pole & zero positions and filter recurrence relation >
>TABL
>SECT
< Dept of Computer Science >
< The University of York >
< York YO1 5DD, U.K. >
\2
< #f#i#s#h#e#r#@#m#i#n#s#t#e#r#.#y#o#r#k#.#a#c#.#u#k >
< #h#t#t#p#:#/#/#w#w#w#-#u#s#e#r#s#.#c#s#.#y#o#r#k#.#a#c#.#u#k#/#~#f#i#s#h#e#r >
>in
\3
< \g 13 Dec 1999 >
>SECT
>CHAP