File size: 1,455 Bytes
69261fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | """Light spectral-subtraction post filter for the FastWave output hiss (numpy).
The diffusion model leaves a broadband noise floor (mostly above the input band).
We estimate the noise magnitude per frequency from the quietest frames of the
output itself and apply a smoothed Wiener-like gain.
"""
import numpy as np
from .audio import hann
def denoise(x, sr=48000, n_fft=1024, hop=256, alpha=1.2, floor=0.10, quiet_percentile=20,
smooth=3):
x = np.asarray(x, dtype=np.float32)
if len(x) < n_fft:
return x
win = hann(n_fft)
m = 1 + (len(x) - n_fft) // hop
idx = np.arange(n_fft)[None, :] + hop * np.arange(m)[:, None]
fr = x[idx] * win
X = np.fft.rfft(fr, axis=1)
mag = np.abs(X)
noise = np.percentile(mag, quiet_percentile, axis=0)
gain = 1.0 - alpha * noise[None, :] / np.maximum(mag, 1e-8)
gain = np.clip(gain, floor, 1.0)
if smooth > 1 and m >= smooth:
k = np.ones(smooth) / smooth
gain = np.apply_along_axis(lambda c: np.convolve(c, k, mode="same"), 0, gain)
Y = X * gain
frames = np.fft.irfft(Y, n=n_fft, axis=1) * win
out_len = (m - 1) * hop + n_fft
acc = np.zeros(out_len, dtype=np.float64)
wsum = np.zeros(out_len, dtype=np.float64)
for i in range(m):
acc[i * hop: i * hop + n_fft] += frames[i]
wsum[i * hop: i * hop + n_fft] += win ** 2
acc /= np.maximum(wsum, 1e-8)
return acc[: len(x)].astype(np.float32)
|