Spaces:
Running
Running
Update denoiser.py
Browse files- denoiser.py +43 -22
denoiser.py
CHANGED
|
@@ -202,37 +202,58 @@ class Denoiser:
|
|
| 202 |
except Exception as e:
|
| 203 |
logger.warning(f"[Denoiser] DeepFilterNet unavailable ({e})")
|
| 204 |
|
| 205 |
-
|
| 206 |
-
#
|
| 207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
try:
|
| 209 |
import noisereduce as nr
|
| 210 |
|
| 211 |
-
#
|
| 212 |
-
|
| 213 |
y=audio, sr=sr,
|
| 214 |
-
stationary=
|
| 215 |
-
prop_decrease=0.
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
).astype(np.float32)
|
| 220 |
-
|
| 221 |
-
# Pass 2: Remove non-stationary noise (movement, traffic, intermittent)
|
| 222 |
-
pass2 = nr.reduce_noise(
|
| 223 |
-
y=pass1, sr=sr,
|
| 224 |
-
stationary=False,
|
| 225 |
-
prop_decrease=0.85, # 85% on non-stationary
|
| 226 |
-
freq_mask_smooth_hz=500,
|
| 227 |
-
time_mask_smooth_ms=50,
|
| 228 |
).astype(np.float32)
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
return pass2, "noisereduce (2-pass)"
|
| 232 |
except Exception as e:
|
| 233 |
logger.warning(f"noisereduce failed: {e}")
|
| 234 |
return audio, "none"
|
| 235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
def _deepfilter(self, audio, sr):
|
| 237 |
if not self._df_loaded:
|
| 238 |
from df.enhance import enhance, init_df
|
|
|
|
| 202 |
except Exception as e:
|
| 203 |
logger.warning(f"[Denoiser] DeepFilterNet unavailable ({e})")
|
| 204 |
|
| 205 |
+
def _remove_background_noise(self, audio, sr):
|
| 206 |
+
# ββ Try DeepFilterNet (SOTA) first ββββββββββββββββββββββββββ
|
| 207 |
+
try:
|
| 208 |
+
result = self._deepfilter(audio, sr)
|
| 209 |
+
print("[Denoiser] β
DeepFilterNet noise removal done")
|
| 210 |
+
return result, "DeepFilterNet"
|
| 211 |
+
except Exception as e:
|
| 212 |
+
logger.warning(f"[Denoiser] DeepFilterNet unavailable ({e})")
|
| 213 |
+
|
| 214 |
+
# ββ Try RNNoise (best for voice, no musical artifacts) βββββββ
|
| 215 |
+
try:
|
| 216 |
+
result = self._rnnoise(audio, sr)
|
| 217 |
+
print("[Denoiser] β
RNNoise removal done")
|
| 218 |
+
return result, "RNNoise"
|
| 219 |
+
except Exception as e:
|
| 220 |
+
logger.warning(f"[Denoiser] RNNoise unavailable ({e})")
|
| 221 |
+
|
| 222 |
+
# ββ Fallback: noisereduce with mild settings ββββββββββββββββββ
|
| 223 |
+
# IMPORTANT: Keep prop_decrease LOW (0.50-0.60) to avoid musical
|
| 224 |
+
# noise artifacts. Two aggressive passes make musical noise WORSE.
|
| 225 |
try:
|
| 226 |
import noisereduce as nr
|
| 227 |
|
| 228 |
+
# Single gentle pass β avoids musical noise artifacts
|
| 229 |
+
cleaned = nr.reduce_noise(
|
| 230 |
y=audio, sr=sr,
|
| 231 |
+
stationary=False, # non-stationary handles both types
|
| 232 |
+
prop_decrease=0.55, # gentle β avoids buzzing artifacts
|
| 233 |
+
freq_mask_smooth_hz=1000, # heavy smoothing = less musical noise
|
| 234 |
+
time_mask_smooth_ms=100, # heavy smoothing = less musical noise
|
| 235 |
+
n_std_thresh_stationary=2.0, # higher = less aggressive
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
).astype(np.float32)
|
| 237 |
+
print("[Denoiser] β
noisereduce (gentle, artifact-free) done")
|
| 238 |
+
return cleaned, "noisereduce"
|
|
|
|
| 239 |
except Exception as e:
|
| 240 |
logger.warning(f"noisereduce failed: {e}")
|
| 241 |
return audio, "none"
|
| 242 |
|
| 243 |
+
def _rnnoise(self, audio, sr):
|
| 244 |
+
"""
|
| 245 |
+
RNNoise β Mozilla's RNN-based noise suppressor.
|
| 246 |
+
Specifically trained on voice, produces zero musical artifacts.
|
| 247 |
+
Requires: pip install rnnoise-python
|
| 248 |
+
"""
|
| 249 |
+
import rnnoise
|
| 250 |
+
# RNNoise requires 48kHz mono float32
|
| 251 |
+
audio_48k = self._resample(audio, sr, 48000) if sr != 48000 else audio
|
| 252 |
+
denoised = rnnoise.reduce_noise(audio_48k, 48000)
|
| 253 |
+
# Resample back to original SR
|
| 254 |
+
result = self._resample(denoised, 48000, sr) if sr != 48000 else denoised
|
| 255 |
+
return result.astype(np.float32)
|
| 256 |
+
|
| 257 |
def _deepfilter(self, audio, sr):
|
| 258 |
if not self._df_loaded:
|
| 259 |
from df.enhance import enhance, init_df
|