Manual: IIRFilter

[ javadoc | examples ]

An Infinite Impulse Response, or IIR, filter is a filter that uses a set of coefficients and previous filtered values to filter a stream of audio. It is an efficient way to do digital filtering. IIRFilter is an abstract class that contains all the code required to apply the filter described by its filter coefficients to the signal it is given to process. You can’t instantiate an IIRFilter, you have to use a subclass, such as LowPassSP or HighPassSP. You can also write your own subclasses, which is briefly described at the end of this page. The methods that IIRFilter provides are:

// Returns the cutoff (or center) frequency (in Hz).
float frequency()
// Sets the cutoff/center frequency of the filter.  
void setFreq(float f)
// Returns true if the frequency is valid for this filter.
boolean  validFreq(float f)
// Returns the sample rate of audio that this filter will process.
float sampleRate()
// Prints the current values of the coefficients to the console.
void printCoeff()
// applies the filter to signal
void process(float[] signal)
// applies the filter to sigLeft and sigRight         
void process(float[] sigLeft, float[] sigRight)

A filter usually has a center frequency, this is sometimes called a cutoff frequency if you are talking about a hi or low pass filter. This value is set in Hertz (cycles per second). For reference, 440 Hz is the A above middle C on the piano. If you double the frequency, the sound will go up an octave.

Code Sample (online example)

/**
  * This sketch demonstrates how to use one of the low pass filters that comes with Minim. <br />
  * Move the mouse right to increase the cutoff frequency, move it to the left to descrease it.
  */
 
import ddf.minim.*;
import ddf.minim.effects.*;
 
Minim minim;
AudioPlayer groove;
LowPassSP lpf;
 
void setup()
{
  size(512, 200, P3D);
  minim = new Minim(this);
  groove = minim.loadFile("groove.mp3");
  groove.loop();
  // make a low pass filter with a cutoff frequency of 100 Hz
  // the second argument is the sample rate of the audio that will be filtered
  // it is required to correctly compute values used by the filter
  lpf = new LowPassSP(100, groove.sampleRate());
  groove.addEffect(lpf);
}
 
void draw()
{
  background(0);
  stroke(255);
  // we multiply the values returned by get by 50 so we can see the waveform
  for ( int i = 0; i < groove.bufferSize() - 1; i++ )
  {
    float x1 = map(i, 0, groove.bufferSize(), 0, width);
    float x2 = map(i+1, 0, groove.bufferSize(), 0, width);
    line(x1, height/4 - groove.left.get(i)*50, x2, height/4 - groove.left.get(i+1)*50);
    line(x1, 3*height/4 - groove.right.get(i)*50, x2, 3*height/4 - groove.right.get(i+1)*50);
  }
}
 
void mouseMoved()
{
  // map the mouse position to the range [20, 1000], an arbitrary range of cutoff frequencies
  float cutoff = map(mouseX, 0, width, 20, 1000);
  lpf.setFreq(cutoff);
}
 
void stop()
{
  // always close Minim audio classes when you finish with them
  groove.close();
  // always stop Minim before exiting
  minim.stop();
 
  super.stop();
}

Low Pass Filters

A low pass filter is a filter that attenuates frequencies in a signal above a certain cutoff frequency. This can make the audio sound “muffled” if the cutoff frequency is low enough and silence the signal entirely if it contains no frequencies below the cutoff. Minim includes two low pass filters: LowPassSP and LowPassFS. LowPassSP is a single pole low pass filter, which means it only has two coefficients and is pretty cheap to calculate. It also means that it is not the greatest low pass filter in the world. LowPassFS is a four stage low pass filter. It has more coefficients and is generally a better low pass filter than LowPassSP. However, it becomes unstable if the cutoff frequency is set below 60 Hz, so it will report an error and set the cutoff to 60 Hz if you try to set it lower. The constructors for both filters take an initial cutoff frequency and a sample rate:

LowPassSP(float freq, float sampleRate)
LowPassFS(float freq, float sampleRate)

High Pass Filters

A high pass filter is the opposite of a low pass filter. It attenuates frequencies below a certain cutoff, allowing frequencies above to pass unchanged. Minim includes one high pass filter: HighPassSP. This is a single pole high pass filter, meaning it has a small number of coefficients and is cheap to use. However, it is not the greatest quality high pass filter. You can construct one with an initial cutoff frequency and a sample rate:

HighPassSP(float freq, float sampleRate)

Band Pass Filters

A band pass filter is a filter that filters out all frequencies except for those in a band centered on the current frequency of the filter. Minim includes one band pass filter: BandPass.

// Constructs a band pass filter with the requested center frequency, 
// bandwidth and sample rate.
BandPass(float freq, float bandWidth, float sampleRate)
// Returns the band width of this filter.
float getBandWidth()
// Sets the band width of the filter.          
void setBandWidth(float bandWidth)

Here, the frequency that you pass to the constructor is the center frequency of the band of frequencies you want to pass and the band width is how large the band is. If you specified 440 and 100 for freq and bandWidth, you would be passing frequencies in the range [390, 490].

Notch Filters

A notch filter removes a narrow band of frequencies from an audio signal. It is the opposite of a band pass filter, which allows only a narrow band of frequencies to pass through the filter. Minim includes one notch filter: NotchFilter.

// Constructs a notch filter with the requested center frequency, 
// bandwidth and sample rate.
NotchFilter(float freq, float bandWidth, float sampleRate)
// Returns the band width of this filter.
float getBandWidth()
// Sets the band width of the filter.
void setBandWidth(float b)

Chebyshev Filter

A Chebyshev filter is an IIR filter that uses a particular method to calculate the coefficients of the filter. It is defined by whether it is a low pass filter or a high pass filter and the number of poles it has. You needn’t worry about what a pole is, exactly, just know that more poles usually makes for a better filter. An additional limitation is that the number of poles must be even. Another characteristic of Chebyshev filters is how much “ripple” they allow in the pass band. The pass band is the range of frequencies that the filter lets through. The “ripple” in the pass band can be seen as a wavy line in the frequency response of the filter. Lots of ripple is bad, but more ripple gives a faster rolloff from the pass band to the stop band (the range of frequencies blocked by the filter). Faster rolloff is good because it means the cutoff is sharper. Ripple is expressed as a percentage, such as 0.5% ripple. Minim provides a Chebyshev filter with the class ChebFilter:

// A constant used to indicate a high pass filter.
static int HP
// A constant used to indicate a low pass filter.
static int LP
// Constructs a Chebyshev filter with a cutoff of the given frequency, 
// of the given type (ChebFilter.HP or ChebFilter.LP), 
// with the give amount of ripple in the pass band, 
// and with the given number of poles,
// for filtering audio with the given sample rate.
ChebFilter(float frequency, int type, float ripple, int poles, float sampleRate)
// Returns the number of poles in the filter.          
int getPoles()
// Sets the number of poles used in the filter. 
void setPoles(int p)
// Gets the ripple percentage of the filter.
float getRipple()
// Sets the ripple percentage of the filter.  
void setRipple(float r)
// Returns the type of the filter (ChebFilter.HP or ChebFilter.LP).  
int getType()
// Sets the type of the filter.  
void setType(int t)

The number of poles must be even and between 2 and 20. This function will report an error if either of those conditions are not met. However, it should also be mentioned that depending on the current cutoff frequency of the filter, the number of
poles that will result in a stable filter, can be a few as 4. ChebFilter does not report an error in the case of the number of requested poles resulting in an unstable filter. For reference, here is a table of the maximum number of poles possible according to cutoff frequency:

Cutoff Frequency
(expressed as a fraction of the sampling rate)
0.02 0.05 0.10 0.25 0.40 0.45 0.48
Maximum poles 4 6 10 20 10 6 4

Examples using all of these filters can be viewed online at http://code.compartmental.net/minim/examples/AudioEffect/, and are also included in the full Minim distribution.

Extending IIRFilter

If you want to make your own IIR filter, you can write a class that extends IIRFilter. You must the define the calcCoeff method, which will be called whenever the properties of the filter change.

// The a coefficients.
protected  float[] a
// The b coefficients.
protected  float[] b
// Calculates the coefficients of the filter 
// using the current frequency and possibly other information
abstract void calcCoeff()

IIRFilter expects that you will assign new values to a and b when it calls calcCoeff. When filling the coefficient arrays, be aware that b[0] corresponds to b1. A subclass might also want to override the validFreq method to provide information about whether or not a frequency is a stable one for the filter. Here’s the implementation of LowPassFS:

public class LowPassFS extends IIRFilter
{
  public LowPassFS(float freq, float sampleRate)
  {
    super(freq, sampleRate);
  }
 
  public boolean validFreq(float f)
  {
    if (f < 60)
    {
      return false;
    }
    return true;
  }
 
  protected void calcCoeff()
  {
    float freqFrac = frequency()/sampleRate();
    float x = (float) Math.exp(-14.445 * freqFrac);
    a = new float[] { (float) Math.pow(1 - x, 4) };
    b = new float[] { 4 * x, -6 * x * x, 4 * x * x * x, -x * x * x * x };
  }
}
  1. Giles Whitaker’s avatar

    This is an excellent manual – very well put together and easy to follow. Makes a big difference, thanks.