5. Wiener denoise audio filter

Let try the online demo app!

[1]:
import matplotlib.pyplot as plt
import torch

import cutcutcodec

5.1. Read, Denoise and Write

In a Wiener filter, the noise profile has to be ergodic.

There is two important arguments:

  1. level: The denoising ratio in \([0, 1]\). 0 doese nothing while 1 is the maximum denoising level.

  2. band: The spectral band width in Hz, bigger it is, less it is noisy but less it is accurate.

[2]:
FILE = cutcutcodec.utils.get_project_root() / "media" / "audio" / "wiener.wav"
RATE = 44100

# read the signal
with cutcutcodec.read(FILE) as noisy_container:

    # extract the noise
    start = 22.0  # start time
    noise_container = noisy_container.apply_audio_subclip(start, torch.inf).apply_audio_delay(-start)

    # denoised with wiener (band=20 is nice for white noise, band=1.0 for cloc)
    denoised_container = (noise_container | noisy_container).apply_audio_wiener(level=0.98, band=20.0)

    # plot signals
    noisy_stream = noisy_container.out_streams[0]
    denoised_stream = denoised_container.out_streams[0]
    noisy_signal = noisy_stream.snapshot(0, RATE, int(RATE*noisy_stream.duration))
    denoised_signal = denoised_stream.snapshot(0, RATE, int(RATE*denoised_stream.duration))

    # save signal
    output = (noisy_stream | denoised_stream).apply_audio_cat()
    cutcutcodec.write(output.out_streams, "/tmp/denoised_wiener.flac", streams_settings=[{"encodec": "flac", "rate": RATE}])
Encoding denoised_wiener.flac: 100%|███████████████████████████████████████████████████| 102.31s/102.31s [00:01<00:00]

5.2. Plot spectrograms

[3]:
# display noisy frame
plt.title("Spectogram of the noisy signal")
plt.xlabel("time (s)")
plt.ylabel("frequency (Hz)")
plt.specgram(noisy_signal[0], Fs=RATE, NFFT=2048)
plt.show()

# display denoised frame
plt.title("Spectogram of the denoised signal")
plt.xlabel("time (s)")
plt.ylabel("frequency (Hz)")
plt.specgram(denoised_signal[0], Fs=RATE, NFFT=2048)
plt.show()
../../../_images/build_examples_advanced_wiener_5_0.png
../../../_images/build_examples_advanced_wiener_5_1.png

5.3. Plot temporal signals

[4]:
# signal in temporal domains
plt.title("Wiener filtering in temporal domain.")
plt.plot(torch.arange(noisy_signal.shape[1]) / RATE, noisy_signal[0], label="noisy signal")
plt.plot(torch.arange(denoised_signal.shape[1]) / RATE, denoised_signal[0], label="denoised signal")
plt.xlabel("time (s)")
plt.legend()
plt.show()
../../../_images/build_examples_advanced_wiener_7_0.png