-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWavToDb.py
More file actions
94 lines (71 loc) · 2.57 KB
/
WavToDb.py
File metadata and controls
94 lines (71 loc) · 2.57 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import numpy as np
import pandas as pd
import os
import re
from scipy.io import wavfile
from scipy.signal import lfilter
# ================= USER SETTINGS =================
cal_wav = r"D:\Project\IITDelhi\onosokki\till\REC\CAL_94dB_1kHz_TEST1.wav" # calibration tone WAV file
test_wav_folder = r"D:\Project\IITDelhi\onosokki\till\REC\input2"
output_folder = r"D:\Project\IITDelhi\onosokki\till\REC\output1"
dt = 0.01 # 10 ms
p_ref = 20e-6 # reference pressure (Pa)
p_cal = 1.0 # 94 dB = 1 Pa
cal_duration = 5 # seconds of calibration tone
# =================================================
os.makedirs(output_folder, exist_ok=True)
# ---------- A-WEIGHTING FILTER ----------
def A_weighting(fs):
f1, f2, f3, f4 = 20.598997, 107.65265, 737.86223, 12194.217
A1000 = 1.9997
nums = [(2*np.pi*f4)**2 * (10**(A1000/20)), 0, 0, 0, 0]
dens = np.polymul(
[1, 4*np.pi*f4, (2*np.pi*f4)**2],
np.polymul(
[1, 4*np.pi*f1, (2*np.pi*f1)**2],
np.polymul([1, 2*np.pi*f3], [1, 2*np.pi*f2])
)
)
return nums, dens
# ---------- READ CALIBRATION WAV ----------
fs_cal, cal_sig = wavfile.read(cal_wav)
if cal_sig.ndim > 1:
cal_sig = cal_sig[:, 0]
cal_sig = cal_sig.astype(np.float64)
N_cal = int(fs_cal * cal_duration)
rms_cal = np.sqrt(np.mean(cal_sig[:N_cal]**2))
cal_gain = p_cal / rms_cal
print(f"Calibration gain applied: {cal_gain:.6e} Pa/unit")
# ---------- PROCESS TEST WAV FILES ----------
for fname in os.listdir(test_wav_folder):
if not fname.lower().endswith(".wav"):
continue
wav_path = os.path.join(test_wav_folder, fname)
fs, sig = wavfile.read(wav_path)
if sig.ndim > 1:
sig = sig[:, 0]
sig = sig.astype(np.float64) * cal_gain # convert to Pa
# A-weighting
b, a = A_weighting(fs)
sig_A = lfilter(b, a, sig)
samples_per_block = int(fs * dt)
n_blocks = len(sig_A) // samples_per_block
time = []
dBA = []
for i in range(n_blocks):
block = sig_A[i*samples_per_block:(i+1)*samples_per_block]
rms = np.sqrt(np.mean(block**2))
spl = 20 * np.log10(rms / p_ref + 1e-12)
time.append(i * dt)
dBA.append(spl)
# Extract run ID (A025 etc.)
m = re.search(r"(A\d+)", fname)
run_id = m.group(1) if m else "UNK"
df = pd.DataFrame({
f"dB_{run_id}": dBA,
"Time": time
})
out_csv = fname.replace(".wav", "_dBA_10ms.csv")
df.to_csv(os.path.join(output_folder, out_csv), index=False)
print(f"Processed: {fname}")
print("✅ All Pass-by and Coast-by WAV files converted successfully.")