= 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