encryptio.com

This sentence is very meta.

mkfilter

mkfilter is a UNIX–y FIR filter creation program. Currently, it creates constant group-delay filters (that is, linear phase filters). Currently, the supported filter types are bandpass, highpass, lowpass, bandstop (i.e. notch), and custom frequency response filters. There is also a "deepnotch" type, which tries to get a bandstop filter with the smallest rolloff for the given length and the specified attentuation factor.

I created it because all the FIR filter design programs I found were crappy, nonfree, or not usable in a UNIX-like environment. This satisfies the last two objectively, and I leave it to you to decide on the first.

Source code is avaliable at github.

Usage

mkfilter {-o outfile | --analyze} -t type [-f freq[,freq]]
         [-c frequencycurve] [-C file] [-d depth] [-w window]
         [-r samplerate] [-l len] [-R selfconvolutions]
         [--analyzefactor=factor]
mkfilter --analyze [--analyzefactor=factor] file.wav
mkfilter -h

Command Line Options

-o file

Sets the output sound file. Can be combined with --analyze, and retains its meaning - analysis is still printed on stdout and the sound file is written.

--analyze

Turns on analysis mode. In this mode, mkfilter will print the frequency and phase response data to stdout. This can be useful for graphing. There is an alternative use that allows analysis of an existing file, without creating one inside mkfilter - mkfilter --analyze file.wav.

--analyzefactor=INTEGER

Sets the extra space used for analysis. The higher this number, the more memory and CPU time it will take to analyze the filter, but the frequency bands will be more tightly spaced (and thus, more of them.) Note that increasing this number by 1 will double the amount of memory and increase the time taken on the order of O(n log n).

-t TYPE

Sets the filter type. May be set to:

  • lowpass, or its alias lp
  • highpass, or its alias hp
  • bandpass, or its alias bp
  • bandpass2, or its alias bp2
  • bandstop, or its aliases bs or notch
  • bandstop2, or its aliases bs2 or notch2
  • deepnotch, or its alias dn
  • custom, or its alias fit

The details of each of these types are listed in the section Filter Types, below.

-f frequency[,frequency]

Sets the cutoff frequency or frequencies. Some filter types can be parameterized with multiple frequencies, see Filter Types, below.

-r rate

Sets the sample rate of the output. Defaults to 44100.

-l length

Sets the length of the output filter in samples. Zero-phase filters require that this be an odd number, and it will be automatically rounded accordingly.

-R repeat

If used, the filter is convolved with itself repeat times. This can increase the stop-band attenuation at the cost of a slower rolloff for the given filter length. Note that the filter length will also be multiplied by repeat times. If you require a particular length filter, you must adjust the length down by an appropriate factor.

-d depth

Sets the attenuation level used in the deepnotch filter. Defaults to 0.01. Ignored for all other filter types.

-w window

Sets the windowing function used. Allowed window types are blackman, hamming, barlett, hanning (or equivalently cosine), and rectangular (equivalently none). Also see the section Window Types, below.

-c freq=value[,freq=value,...]

Sets the frequency curve used in custom filters. See the section in Filter Types, below.

-C file

Sets the file used to read the custom filter frequency points. The file format is simply "frequency amplitude". Note that the output of --analyze is compatible with this option's input format. See the section in Filter Types, below.

-h

Prints a short help message and exits.

Filter Types

lowpass

Passes all frequencies below the given frequency and attenuates the ones above.

mkfilter -t lp -f 1000 -l 500

highpass

Passes all frequencies above the given frequency and attenuates the ones above.

mkfilter -t hp -f 1000 -l 500

bandpass

Passes all frequencies between the two given frequencies. If only one frequency is given, mkfilter switches to bandpass2.

mkfilter -t bp -f 1000,2000 -l 500

bandpass2

Passes all frequencies between the two given frequencies. This is an alternative algorithm to bandpass, implemented by convoluting a highpass filter with a lowpass filter. This gives better performance when the frequencies are very close, due to floating point roundoff errors. However, when the frequencies are far apart, bandpass will give a faster rolloff for a given filter length.

mkfilter -t bp2 -f 1000,2000 -l 500

bandstop

Attenuates all frequency bands between the two given frequencies. If only one frequency is given, mkfilter switches to bandstop2. This algorithm is not recommended for use with a single frequency. The deepnotch filter type was built to attenuate a single frequency.

mkfilter -t bs -f 1000,2000 -l 500

bandstop2

Uses the same trick as bandpass2 for a band-stop filter. It is recommended to use deepnotch or bandstop instead of this filter type, but it is included here for completeness.

mkfilter -t bs2 -f 1000,2000 -l 500

deepnotch

Iteratively runs bandstop with frequencies slightly lower and higher than the given frequency, trying to find the closest value that gives the requested attenuation (-d option.) This is not always possible (especially with frequencies close to the bottom or top of the frequency range), so deepnotch will take the best attenuation it can get while remaining centered on the given frequency.

mkfilter -t dn -f 1000 -d 0.02 -l 500

custom

Creates a filter with the response given by the -c or -C options. The values are linearly interpolated (this may look odd on a logarithmic plot.) Values indicating frequencies below the lowest one given are given the value of the lowest frequency (thus stretching it out horizontally on the plot), and frequencies above the highest frequency are treated similarly.

mkfilter -t custom -c 500=1,800=0.1,1600=0.1,2000=0.01,3000=0.01,5000=1 -l 500

Window Functions

The only two recommended window functions are blackman and hamming. However, for some special purposes, other windows may be useful. When in doubt, use analyzefilter from this distribution to view the filter response, and test the filter in real use, if possible. analyzefilter's multiple inputs prove useful here.

mkfilter -t lp -f 1000 -l 500 -w blackman
mkfilter -t lp -f 1000 -l 500 -w hamming
mkfilter -t lp -f 1000 -l 500 -w rectangular

blackman

This is the default window type. It gives the best stopband attenuation of any of the window functions implemented, but also the slowest rolloff.

hamming

This window has less stopband attenuation than the blackman window, but still second best. Its rolloff is much faster than the blackman window.

rectangular

This "window" is equivalent to doing nothing. It has the fastest rolloff of all the windows implemented, and also the worst stopband attenuation. It also has significant ripple in the passband.

others

The barlett and hanning windows are implemented, but not recommended.

Notes

Faster rolloff (or equivalently for a custom filter, closer fit) can be achieved by increasing the filter length. Note that longer filters have worse behavior in the time domain.

mkunfilter is included in the source distribution as a shell script to invert the frequency response of a given filter (not necessarily linear-phase). It uses the analysis of an input filter to shape a custom filter. Exploring its method would be a good expositional exercise.