-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnoise_reducer.py
More file actions
64 lines (55 loc) · 1.84 KB
/
Copy pathnoise_reducer.py
File metadata and controls
64 lines (55 loc) · 1.84 KB
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import numpy as np
import soundfile as sf
import noisereduce as nr
from scipy.signal import butter, filtfilt
def butter_bandpass(lowcut=80, highcut=8000, fs=16000, order=5):
"""Keep only human voice frequencies (80Hz–8kHz)."""
nyq = fs / 2
low = lowcut / nyq
high = min(highcut / nyq, 0.99)
b, a = butter(order, [low, high], btype='band')
return b, a
def reduce_noise(
input_wav: str,
output_wav: str = "cleaned_audio.wav",
prop_decrease: float = 0.75,
use_bandpass: bool = True,
normalize: bool = True
) -> str:
"""
Apply configurable audio preprocessing pipeline.
Args:
input_wav: Input WAV file path
output_wav: Output WAV file path
prop_decrease: Noise reduction aggressiveness (0.0–1.0). 0.0 = skip noise reduction.
use_bandpass: Apply bandpass filter (80Hz–8kHz voice range)
normalize: Normalize audio volume
"""
data, rate = sf.read(input_wav)
# Step 1: Bandpass filter — keep human voice frequencies only
if use_bandpass:
try:
b, a = butter_bandpass(fs=rate)
data = filtfilt(b, a, data)
except Exception:
pass # skip if filter fails on short audio
# Step 2: Noise reduction
if prop_decrease > 0.0:
noise_sample_duration = int(0.5 * rate)
noise_clip = data[:max(noise_sample_duration, 1)]
data = nr.reduce_noise(
y=data,
sr=rate,
y_noise=noise_clip,
prop_decrease=prop_decrease,
stationary=False,
n_fft=2048,
n_std_thresh_stationary=1.5
)
# Step 3: Normalize volume
if normalize:
max_val = np.max(np.abs(data))
if max_val > 0:
data = data / max_val * 0.95
sf.write(output_wav, data, rate)
return output_wav