Filter chains

The standard way to set up a model based on filterbanks is to start with a sound and then construct a chain of filterbanks that modify it, for example a common model of cochlear filtering is to apply a bank of gammatone filters, and then half wave rectify and compress it (for example, with a 1/3 power law). This can be achieved in Brian hears as follows (for 3000 channels in the human hearing range from 20 Hz to 20 kHz):

cfmin, cfmax, cfN = 20*Hz, 20*kHz, 3000
cf = erbspace(cfmin, cfmax, cfN)
sound = Sound('test.wav')
gfb = GammatoneFilterbank(sound, cf)
ihc = FunctionFilterbank(gfb, lambda x: clip(x, 0, Inf)**(1.0/3.0))

The erbspace() function constructs an array of centre frequencies on the ERB scale. The GammatoneFilterbank(source, cf) class creates a bank of gammatone filters with inputs coming from source and the centre frequencies in the array cf. The FunctionFilterbank(source, func) creates a bank of filters that applies the given function func to the inputs in source.

Filterbanks can be added and multiplied, for example for creating a linear and nonlinear path, e.g.:

sum_path_fb = 0.1*linear_path_fb+0.2*nonlinear_path_fb

A filterbank must have an input with either a single channel or an equal number of channels. In the former case, the single channel is duplicated for each of the output channels. However, you might want to apply gammatone filters to a stereo sound, for example, but in this case it’s not clear how to duplicate the channels and you have to specify it explicitly. You can do this using the Repeat, Tile, Join and Interleave filterbanks. For example, if the input is a stereo sound with channels LR then you can get an output with channels LLLRRR or LRLRLR by writing (respectively):

fb = Repeat(sound, 3)
fb = Tile(sound, 3)

To combine multiple filterbanks into one, you can either join them in series or interleave them, as follows:

fb = Join(source1, source2)
fb = Interleave(source1, source2)

For a more general (but more complicated) approach, see RestructureFilterbank.

Two of the most important generic filterbanks (upon which many of the others are based) are LinearFilterbank and FIRFilterbank. The former is a generic digital filter for FIR and IIR filters. The latter is specifically for FIR filters. These can be implemented with the former, but the implementation is optimised using FFTs with the latter (which can often be hundreds of times faster, particularly for long impulse responses). IIR filter banks can be designed using IIRFilterbank which is based on the syntax of the iirdesign scipy function.

You can change the input source to a Filterbank by modifying its source attribute, e.g. to change the input sound of a filterbank fb you might do:

fb.source = newsound

Note that the new source should have the same number of channels.

You can implement control paths (using the output of one filter chain path to modify the parameters of another filter chain path) using ControlFilterbank (see reference documentation for more details). For examples of this in action, see the following: