Spaces:
Sleeping
Sleeping
Update time_domain.py
Browse files- time_domain.py +45 -0
time_domain.py
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# time_domain.py
|
| 2 |
+
# ============================
|
| 3 |
+
# Time-domain statistical analysis for Audio Forensic Analyzer
|
| 4 |
+
# Logic preserved exactly from original app.py
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
import librosa
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def compute_time_domain_stats(y):
|
| 11 |
+
"""Calculate time-domain statistics exactly as in original analyzer."""
|
| 12 |
+
|
| 13 |
+
# Peak amplitude
|
| 14 |
+
peak = float(np.max(np.abs(y)))
|
| 15 |
+
|
| 16 |
+
# RMS amplitude
|
| 17 |
+
rms = float(np.sqrt(np.mean(y ** 2)))
|
| 18 |
+
|
| 19 |
+
# dB conversions (protecting against log(0))
|
| 20 |
+
peak_db = 20 * np.log10(max(peak, 1e-12))
|
| 21 |
+
rms_db = 20 * np.log10(max(rms, 1e-12))
|
| 22 |
+
|
| 23 |
+
# Crest factor (indicator of compression)
|
| 24 |
+
crest_factor = peak_db - rms_db
|
| 25 |
+
|
| 26 |
+
# Noise floor estimate (10th percentile absolute amplitude)
|
| 27 |
+
abs_y = np.abs(y)
|
| 28 |
+
noise_floor = float(np.percentile(abs_y, 10))
|
| 29 |
+
|
| 30 |
+
# Estimated SNR
|
| 31 |
+
snr_est = 20 * np.log10(max(rms, 1e-12) / max(noise_floor, 1e-12))
|
| 32 |
+
|
| 33 |
+
# Zero-crossing rate (speech/noise indicator)
|
| 34 |
+
zcr = float(np.mean(librosa.feature.zero_crossing_rate(y)))
|
| 35 |
+
|
| 36 |
+
return {
|
| 37 |
+
"peak": peak,
|
| 38 |
+
"rms": rms,
|
| 39 |
+
"peak_db": peak_db,
|
| 40 |
+
"rms_db": rms_db,
|
| 41 |
+
"crest_factor_db": crest_factor,
|
| 42 |
+
"noise_floor": noise_floor,
|
| 43 |
+
"snr_db": snr_est,
|
| 44 |
+
"zero_crossing_rate": zcr
|
| 45 |
+
}
|