pyroomacoustics.denoise.subspace module

class pyroomacoustics.denoise.subspace.Subspace(frame_len=256, mu=10, lookback=10, skip=2, thresh=0.01, data_type='float32')

Bases: object

A class for performing single channel noise reduction in the time domain via the subspace approach. This implementation is based off of the approach presented in:

Y. Ephraim and H. L. Van Trees, A signal subspace approach for speech enhancement, IEEE Transactions on Speech and Audio Processing, vol. 3, no. 4, pp. 251-266, Jul 1995.

Moreover, an adaptation of the subspace approach is implemented here, as presented in:

Y. Hu and P. C. Loizou, A subspace approach for enhancing speech corrupted by colored noise, IEEE Signal Processing Letters, vol. 9, no. 7, pp. 204-206, Jul 2002.

Namely, an eigendecomposition is performed on the matrix:

\[\Sigma = R_n^{-1} R_y - I,\]

where \(R_n\) is the noise covariance matrix, \(R_y\) is the covariance matrix of the input noisy signal, and \(I\) is the identity matrix. The covariance matrices are estimated from past samples; the number of past samples/frames used for estimation can be set with the parameters lookback and skip. A simple energy threshold (thresh parameter) is used to identify noisy frames.

The eigenvectors corresponding to the positive eigenvalues of \(\Sigma\) are used to create a linear operator \(H_{opt}\) in order to enhance the noisy input signal \(\mathbf{y}\):

\[\mathbf{\hat{x}} = H_{opt} \cdot \mathbf{y}.\]

The length of \(\mathbf{y}\) is specified by the parameter frame_len; \(50\%\) overlap and add with a Hanning window is used to reconstruct the output. A great summary of the approach can be found in the paper by Y. Hu and P. C. Loizou under Section III, B.

Adjusting the factor \(\\mu\) presents a trade-off between noise suppression and distortion.

Below is an example of how to use this class to emulate a streaming/online input. A full example can be found here. Depending on your choice for frame_len, lookback, and skip, the approach may not be suitable for real-time processing.

# initialize Subspace object
scnr = Subspace(frame_len=256, mu=10, lookback=10, skip=2, thresh=0.01)

# apply block-by-block
for n in range(num_blocks):
    denoised_signal = scnr.apply(noisy_input)

There also exists a “one-shot” function.

# import or create `noisy_signal`
denoised_signal = apply_subspace(noisy_signal, frame_len=256, mu=10,
                                 lookback=10, skip=2, thresh=0.01)
Parameters
  • frame_len (int) – Frame length in samples. Note that large values (above 256) will make the eigendecompositions very expensive.

  • mu (float) – Enhancement factor, larger values suppress more noise but could lead to more distortion.

  • lookback (int) – How many frames to look back for covariance matrix estimation.

  • skip (int) – How many samples to skip when estimating the covariance matrices with past samples. skip=1 will use all possible frames in the estimation.

  • thresh (float) – Threshold to distinguish between (signal+noise) and (noise) frames. A high value will classify more frames as noise but might remove desired signal!

  • data_type ('float32' or 'float64') – Data type to use in the enhancement procedure. Default is ‘float32’.

apply(new_samples)
Parameters

new_samples (numpy array) – New array of samples of length self.hop in the time domain.

Returns

Denoised samples.

Return type

numpy array

compute_signal_projection()
update_cov_matrices(new_samples)
pyroomacoustics.denoise.subspace.apply_subspace(noisy_signal, frame_len=256, mu=10, lookback=10, skip=2, thresh=0.01, data_type=<MagicMock id='140583672361936'>)

One-shot function to apply subspace denoising approach.

Parameters
  • noisy_signal (numpy array) – Real signal in time domain.

  • frame_len (int) – Frame length in samples. Note that large values (above 256) will make the eigendecompositions very expensive. 50% overlap is used with hanning window.

  • mu (float) – Enhancement factor, larger values suppress more noise but could lead to more distortion.

  • lookback (int) – How many frames to look back for covariance matrix estimation.

  • skip (int) – How many samples to skip when estimating the covariance matrices with past samples. skip=1 will use all possible frames in the estimation.

  • thresh (float) – Threshold to distinguish between (signal+noise) and (noise) frames. A high value will classify more frames as noise and might even remove desired signal!

  • data_type ('float32' or 'float64') – Data type to use in the enhancement procedure. Default is ‘float32’.

Returns

Enhanced/denoised signal.

Return type

numpy array