forked from microsoft/DNS-Challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unit_tests_synthesizer.py
182 lines (152 loc) · 8.47 KB
/
unit_tests_synthesizer.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import numpy as np
import soundfile as sf
import glob
import argparse
import os
import utils
import configparser as CP
LOW_ENERGY_THRESH = -60
def test_snr(clean, noise, expected_snr, snrtolerance=2):
'''Test for SNR
Note: It is not applicable for Segmental SNR'''
rmsclean = (clean**2).mean()**0.5
rmsnoise = (noise**2).mean()**0.5
actual_snr = 20*np.log10(rmsclean/rmsnoise)
return actual_snr > (expected_snr-snrtolerance) and actual_snr < (expected_snr+snrtolerance)
def test_normalization(audio, expected_rms=-25, normtolerance=2):
'''Test for Normalization
Note: Set it to False if different target levels are used'''
rmsaudio = (audio**2).mean()**0.5
rmsaudiodb = 20*np.log10(rmsaudio)
return rmsaudiodb > (expected_rms-normtolerance) and rmsaudiodb < (expected_rms+normtolerance)
def test_samplingrate(sr, expected_sr=16000):
'''Test to ensure all clips have same sampling rate'''
return expected_sr == sr
def test_clipping(audio, num_consecutive_samples=3, clipping_threshold=0.01):
'''Test to detect clipping'''
clipping = False
for i in range(0, len(audio)-num_consecutive_samples-1):
audioseg = audio[i:i+num_consecutive_samples]
if abs(max(audioseg)-min(audioseg)) < clipping_threshold or abs(max(audioseg)) >= 1:
clipping = True
break
return clipping
def test_zeros_beg_end(audio, num_zeros=16000, low_energy_thresh=LOW_ENERGY_THRESH):
'''Test if there are zeros in the beginning and the end of the signal'''
beg_segment_energy = 20*np.log10(audio[:num_zeros]**2).mean()**0.5
end_segment_energy = 20*np.log10(audio[-num_zeros:]**2).mean()**0.5
return beg_segment_energy < low_energy_thresh or end_segment_energy < low_energy_thresh
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--cfg', default='noisyspeech_synthesizer.cfg')
parser.add_argument('--cfg_str', type=str, default='noisy_speech')
args = parser.parse_args()
cfgpath = os.path.join(os.path.dirname(__file__), args.cfg)
assert os.path.exists(cfgpath), f'No configuration file as [{cfgpath}]'
cfg = CP.ConfigParser()
cfg._interpolation = CP.ExtendedInterpolation()
cfg.read(cfgpath)
cfg = cfg._sections[args.cfg_str]
noisydir = cfg['noisy_train']
cleandir = cfg['clean_train']
noisedir = cfg['noise_train']
audioformat = cfg['audioformat']
# List of noisy speech files
noisy_speech_filenames_big = glob.glob(os.path.join(noisydir, audioformat))
noisy_speech_filenames = noisy_speech_filenames_big[0:10]
# Initialize the lists
noisy_filenames_list = []
clean_filenames_list = []
noise_filenames_list = []
snr_results_list =[]
clean_norm_results_list = []
noise_norm_results_list = []
noisy_norm_results_list = []
clean_sr_results_list = []
noise_sr_results_list = []
noisy_sr_results_list = []
clean_clipping_results_list = []
noise_clipping_results_list = []
noisy_clipping_results_list = []
skipped_string = 'Skipped'
# Initialize the counters for stats
total_clips = len(noisy_speech_filenames)
for noisypath in noisy_speech_filenames:
# To do: add right paths to clean filename and noise filename
noisy_filename = os.path.basename(noisypath)
clean_filename = 'clean_fileid_'+os.path.splitext(noisy_filename)[0].split('fileid_')[1]+'.wav'
cleanpath = os.path.join(cleandir, clean_filename)
noise_filename = 'noise_fileid_'+os.path.splitext(noisy_filename)[0].split('fileid_')[1]+'.wav'
noisepath = os.path.join(noisedir, noise_filename)
noisy_filenames_list.append(noisy_filename)
clean_filenames_list.append(clean_filename)
noise_filenames_list.append(noise_filename)
# Read clean, noise and noisy signals
clean_signal, fs_clean = sf.read(cleanpath)
noise_signal, fs_noise = sf.read(noisepath)
noisy_signal, fs_noisy = sf.read(noisypath)
# SNR Test
# To do: add right path split to extract SNR
if utils.str2bool(cfg['snr_test']):
snr = int(noisy_filename.split('_snr')[1].split('_')[0])
snr_results_list.append(str(test_snr(clean=clean_signal, \
noise=noise_signal, expected_snr=snr)))
else:
snr_results_list.append(skipped_string)
# Normalization test
if utils.str2bool(cfg['norm_test']):
tl = int(noisy_filename.split('_tl')[1].split('_')[0])
clean_norm_results_list.append(str(test_normalization(clean_signal)))
noise_norm_results_list.append(str(test_normalization(noise_signal)))
noisy_norm_results_list.append(str(test_normalization(noisy_signal, expected_rms=tl)))
else:
clean_norm_results_list.append(skipped_string)
noise_norm_results_list.append(skipped_string)
noisy_norm_results_list.append(skipped_string)
# Sampling rate test
if utils.str2bool(cfg['sampling_rate_test']):
clean_sr_results_list.append(str(test_samplingrate(sr=fs_clean)))
noise_sr_results_list.append(str(test_samplingrate(sr=fs_noise)))
noisy_sr_results_list.append(str(test_samplingrate(sr=fs_noisy)))
else:
clean_sr_results_list.append(skipped_string)
noise_sr_results_list.append(skipped_string)
noisy_sr_results_list.append(skipped_string)
# Clipping test
if utils.str2bool(cfg['clipping_test']):
clean_clipping_results_list.append(str(test_clipping(audio=clean_signal)))
noise_clipping_results_list.append(str(test_clipping(audio=noise_signal)))
noisy_clipping_results_list.append(str(test_clipping(audio=noisy_signal)))
else:
clean_clipping_results_list.append(skipped_string)
noise_clipping_results_list.append(skipped_string)
noisy_clipping_results_list.append(skipped_string)
# Stats
pc_snr_passed = round(snr_results_list.count('True')/total_clips*100, 1)
pc_clean_norm_passed = round(clean_norm_results_list.count('True')/total_clips*100, 1)
pc_noise_norm_passed = round(noise_norm_results_list.count('True')/total_clips*100, 1)
pc_noisy_norm_passed = round(noisy_norm_results_list.count('True')/total_clips*100, 1)
pc_clean_sr_passed = round(clean_sr_results_list.count('True')/total_clips*100, 1)
pc_noise_sr_passed = round(noise_sr_results_list.count('True')/total_clips*100, 1)
pc_noisy_sr_passed = round(noisy_sr_results_list.count('True')/total_clips*100, 1)
pc_clean_clipping_passed = round(clean_clipping_results_list.count('True')/total_clips*100, 1)
pc_noise_clipping_passed = round(noise_clipping_results_list.count('True')/total_clips*100, 1)
pc_noisy_clipping_passed = round(noisy_clipping_results_list.count('True')/total_clips*100, 1)
print('% clips that passed SNR test:', pc_snr_passed)
print('% clean clips that passed Normalization tests:', pc_clean_norm_passed)
print('% noise clips that passed Normalization tests:', pc_noise_norm_passed)
print('% noisy clips that passed Normalization tests:', pc_noisy_norm_passed)
print('% clean clips that passed Sampling Rate tests:', pc_clean_sr_passed)
print('% noise clips that passed Sampling Rate tests:', pc_noise_sr_passed)
print('% noisy clips that passed Sampling Rate tests:', pc_noisy_sr_passed)
print('% clean clips that passed Clipping tests:', pc_clean_clipping_passed)
print('% noise clips that passed Clipping tests:', pc_noise_clipping_passed)
print('% noisy clips that passed Clipping tests:', pc_noisy_clipping_passed)
log_dir = utils.get_dir(cfg, 'unit_tests_log_dir', 'Unit_tests_logs')
if not os.path.exists(log_dir):
log_dir = os.path.join(os.path.dirname(__file__), 'Unit_tests_logs')
os.makedirs(log_dir)
utils.write_log_file(log_dir, 'unit_test_results.csv', [noisy_filenames_list, clean_filenames_list, \
noise_filenames_list, snr_results_list, clean_norm_results_list, noise_norm_results_list, \
noisy_norm_results_list, clean_sr_results_list, noise_sr_results_list, noisy_sr_results_list, \
clean_clipping_results_list, noise_clipping_results_list, noisy_clipping_results_list])