Adaptive Filtering

Module contents

Adaptive Filter Algorithms

This sub-package provides implementations of popular adaptive filter algorithms.

RLS
Recursive Least Squares
LMS
Least Mean Squares and Normalized Least Mean Squares

All these classes derive from the base class pyroomacoustics.adaptive.adaptive_filter.AdaptiveFilter that offer a generic way of running an adaptive filter.

The above classes are applicable for time domain processing. For frequency domain adaptive filtering, there is the SubbandLMS class. After using a DFT or STFT block, the SubbandLMS class can be used to used to apply LMS or NLMS to each frequency band. A shorter adaptive filter can be used on each band as opposed to the filter required in the time domain version. Roughly, a filter of M taps applied to each band (total of B) corresponds to a time domain filter with N = M x B taps.

How to use the adaptive filter module

First, an adaptive filter object is created and all the relevant options can be set (step size, regularization, etc). Then, the update function is repeatedly called to provide new samples to the algorithm.

# initialize the filter
rls = pyroomacoustics.adaptive.RLS(30)

# run the filter on a stream of samples
for i in range(100):
    rls.update(x[i], d[i])

# the reconstructed filter is available
print('Reconstructed filter:', rls.w)

The SubbandLMS class has the same methods as the time domain approaches. However, the signal must be in the frequency domain. This can be done with the STFT block in the transform sub-package of pyroomacoustics.

# initialize STFT and SubbandLMS blocks
block_size = 128
stft_x = pra.transform.STFT(N=block_size,
    hop=block_size//2,
    analysis_window=pra.hann(block_size))
stft_d = pra.transform.STFT(N=block_size,
    hop=block_size//2,
    analysis_window=pra.hann(block_size))
nlms = pra.adaptive.SubbandLMS(num_taps=6,
    num_bands=block_size//2+1, mu=0.5, nlms=True)

# preparing input and reference signals
...

# apply block-by-block
for n in range(num_blocks):

    # obtain block
    ...

    # to frequency domain
    stft_x.analysis(x_block)
    stft_d.analysis(d_block)
    nlms.update(stft_x.X, stft_d.X)

    # estimating input convolved with unknown response
    y_hat = stft_d.synthesis(np.diag(np.dot(nlms.W.conj().T,stft_x.X)))

    # AEC output
    E = stft_d.X - np.diag(np.dot(nlms.W.conj().T,stft_x.X))
    out = stft_d.synthesis(E)

Other Available Subpackages

pyroomacoustics.adaptive.data_structures
this provides abstractions for computing functions on regular or irregular grids defined on circles and spheres with peak finding methods
pyroomacoustics.adaptive.util
a few methods mainly to efficiently manipulate Toeplitz and Hankel matrices

Utilities

pyroomacoustics.adaptive.algorithms
a dictionary containing all the adaptive filter object subclasses availables indexed by keys ['RLS', 'BlockRLS', 'BlockLMS', 'NLMS', 'SubbandLMS']

Tools and Helpers