music.iir

music.iir(sonic_vector, a, b)[source]

Apply an IIR filter to a signal.

Parameters:
sonic_vectorarray_like

An one-dimensional array representing the signal (potentially a sound) for the filter to by applied to.

aiterable of scalars

The feedforward coefficients.

biterable of scalars

The feedback filter coefficients.

Returns:
ndarray

The filtered signal, the same length as the input.

Raises:
ValueError

If sonic_vector is not one-dimensional, or if b is empty or begins with zero. A stereo array used to come back as a two-element result – len() of it counts channels, not samples – and a zero divisor produced an array of infinities behind a warning. Filter one channel at a time.

Notes

The recurrence implemented is

\[b_0 y[n] = \sum_k a_k x[n-k] + \sum_{j \geq 1} b_j y[n-j]\]

Note the plus sign on the feedback sum: this is not the convention scipy.signal.lfilter uses, which subtracts it, and the names of the two coefficient arrays are also the other way round there.

Cost is linear in the length of the signal. It reads only the last len(a) inputs and len(b) - 1 outputs at each step, which is all the recurrence refers to; taking a longer slice and discarding the remainder – as this did – made a second of audio at 44.1 kHz take about three seconds, and ten seconds of audio take five minutes.

Check [1] to know more about this function.

Cite the following article whenever you use this function.

References

[1]

Fabbri, Renato, et al. “Musical elements in the discrete-time representation of sound.” arXiv preprint arXiv:abs/1412.6853 (2017)

Examples

>>> impulse = np.array([1., 0., 0., 0.])
>>> np.allclose(iir(impulse, [1.], [1., .5]), [1., .5, .25, .125])
True