-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinalproject_util.py
133 lines (114 loc) · 4.47 KB
/
finalproject_util.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
import os
import numpy as np
import librosa
import jiwer
import soundfile as sf
def compress_decompress(filepaths,
codec,
filetypes,
bitrates=[128],
folder_override=""):
"""Compress and then decompress all files in a list of filepaths.
Args:
filepaths (list): list of paths
codec (str): codec to use. must be compatible with ffmpeg
filetypes (tuple): tuple containing:
- filetypes[0] = original filetype, ex: 'wav'
- filetypes[1] = it's being converted to, ex: 'mp3'
options (str, optional): other options for ffmpeg.
Defaults to "".
bitrates (list, optional): list of bitrates to compress at.
Defaults to [256, 192, 160, 128, 96, 64, 32, 16, 8].
"""
filetype_fr, filetype_to = filetypes
for fp in filepaths:
filename = fp.split("/")[-1][:-4]
for bitrate in bitrates:
new_filename = f"{filename}+{bitrate}kbps"
new_path = f"audio/{filetype_to}{folder_override}/{new_filename}"
arg1 = "--yes" if os.path.isfile(
f"{new_path}.{filetype_to}") else ""
arg2 = "--yes" if os.path.isfile(
f"{new_path}.{filetype_fr}") else ""
if arg1 or arg2:
print(f"File {new_path}.{filetype_to} already exists")
continue
try:
os.system(
f'ffmpeg -i {fp} -c:a {codec} -b:a {bitrate}k {new_path}.{filetype_to} {arg1}')
os.system(
f'ffmpeg -i {new_path}.{filetype_to} -vn {new_path}.{filetype_fr} {arg2}')
except BaseException as e:
print("Error with file at", fp)
print("Exception:", e)
continue
def get_noise_multiplier(signal, noise, snr=20.):
"""Function to get a, the multiplier for noise based on a given
signal-noise-ratio
Args:
signal (iterable): signal
noise (iterable): noise
snr (float, optional): signal-to-noise ratio. Defaults to 20..
Returns:
float: multiplier for noise
"""
signal = np.array(signal)
noise = np.array(noise)
MS_sig = (signal ** 2.).sum() / len(signal)
MS_noise = (noise ** 2.).sum() / len(noise)
temp = 10. ** (snr / 10.)
a = MS_sig / (MS_noise * temp)
return a
def add_noise(signal, noise, snr=20, sr=44100, len_sec=None, filepath=None, randomseed=None):
"""Adds noise to signal
Args:
signal (ndarray): signal
noise (ndarray): noise. should be at least as long as signal
snr (int, optional): signal-to-noise-ratio in decibels. Defaults to 20.
sr (int, optional): sample rate in Hz. Defaults to 44100.
len_sec (int, optional): length of the output in seconds. If not
specified, truncated to length of signal.
filepath (str, optional): path to write the output to. If None, the
file is not written to disk and only returned. Defaults to None.
randomseed (int, optional): random seed for reproducability. If None,
no seed is used.
Returns:
ndarray: signal with noise added
"""
if randomseed:
np.random.seed(randomseed)
a = get_noise_multiplier(signal, noise, snr=snr)
num_samples = len_sec * sr if len_sec else len(signal)
noise_start = np.random.randint(0, len(noise) - num_samples)
to_add = noise[noise_start: noise_start + num_samples]
result = signal[:num_samples] + a * to_add
if filepath:
sf.write(filepath, result, samplerate=sr)
return result
def wer(ref, hyp):
""" word error rate function built with code from this article:
https://medium.com/@johnidouglasmarangon/how-to-calculate-the-word-error-rate-in-python-ce0751a46052
Args:
ref (str): reference, ground truth
hyp (str): hypothesis, model output/prediction
Returns:
float: word error rate as a float between 0 and 1
"""
transforms = jiwer.Compose(
[
jiwer.ExpandCommonEnglishContractions(),
jiwer.RemoveEmptyStrings(),
jiwer.ToLowerCase(),
jiwer.RemoveMultipleSpaces(),
jiwer.Strip(),
jiwer.RemovePunctuation(),
jiwer.ReduceToListOfListOfWords(),
]
)
wer = jiwer.wer(
ref,
hyp,
truth_transform=transforms,
hypothesis_transform=transforms,
)
return wer