The following introduces the concept of the pyfar filter classes. See
filter classes for a complete documentation.
There are three types of Filter objects:
FIR Filter: Finite Impulse Response (FIR) filters are non-recursive filters. FIR filters are very flexible and can have arbitrary magnitude and phase responses.
IIR Filter: Infinite Impulse Response (IIR) filters are recursive filters. They can achieve steeper filter slopes than FIR filters of the same order but are less flexible with respect to the phase response.
SOS Filter: Second Order Section (SOS) filters are cascaded 2nd order recursive filters. They are often more robust against numerical errors than IIR filters of the same order.
Initializing a Filter Object¶
A filter object is initialized at least with the coefficients and a sampling rate
import pyfar as pf filter = pf.FilterFIR([[3, -1]], 44100)
Applying a time-invariant Filter¶
To filter an audio signal, pass it to the filters process function
input = pf.Signal([1, 2, 3, 4], 44100) output = filter.process(input)
The output is
output.time = [[3, 5, 7, 9]] and has the same number of
samples as the input.
The output will be the same no matter how often
process is called. This
default behavior is often desired. In some cases, a different functionality can
be useful. For blockwise processing of input signals, the filter object can
track the state of the filter. The initial state can be passed during
initialization or typical states can be set using
The above initializes the state with zeros, and if the filter is called with blocks of the input
block_one = filter.process(input[0, 0:2]) block_two = filter.process(input[0, 2:4])
the blockwise output yields the same as the complete output
block_one.time = [[3, 5]],
block_two.time = [[7, 9]].
This is the case because initializing the state also makes the filter object
track the state across multiple calls of the
Another option for initialization is
which makes sure that the first sample of the output is the same as the first sample of the input.
To disable tracking the state, call
output = filter.process(input, reset=True)
or simply do not initialize the state at all as done by
filter = pf.FilterFIR([[3, -1]], 44100, state=None)
which is the default.
Applying a time-variant Filter¶
In some cases it is necessary to mimic time-variant systems. This can be done by exchanging the filter coefficients
# input signal input = pf.Signal([1, 2, 3, 4], 44100) # initialize filter and state filter = pf.FilterFIR([[2, -2]], 44100) filter.init_state(input.cshape, state='zeros') # process first block output_1 = filter.process(input[..., :2]) # update filter coefficients filter.coefficients = [[2, -1.9]] # process second block output_2 = filter.process(input[..., 2:])
Note that this only works for filters of the same length and after initializing the state. Otherwise, discontinuities will appear between the output blocks.