Spaces:
Sleeping
Sleeping
# %% | |
import os | |
import torch | |
import librosa | |
import numpy as np | |
import torch.nn.functional as F | |
from tqdm import tqdm | |
from utils.audio import MelSpectrogram | |
from utils import write_lines_to_file | |
# %% CONFIG | |
wavs_path = 'G:/data/arabic-speech-corpus/wav_new' | |
waves = [f.path for f in os.scandir(wavs_path) if f.path.endswith('.wav')] | |
print(f"{len(waves)} wave files found at {wavs_path}") | |
mel_trf = MelSpectrogram() | |
# %% extract pitch (f0) values | |
pitch_dict = {} | |
for i, wav_path in tqdm(enumerate(waves), total=len(waves)): | |
wav, sr = librosa.load(wav_path, sr=mel_trf.sample_rate) | |
wav_name = os.path.basename(wav_path) | |
if wav_name in pitch_dict: | |
continue | |
mel_spec = mel_trf(torch.tensor(wav)[None])[0] # [mel_bands, T] | |
# estimate pitch | |
pitch_mel, voiced_flag, voiced_probs = librosa.pyin( | |
wav, sr=mel_trf.sample_rate, | |
fmin=librosa.note_to_hz('C2'), | |
fmax=librosa.note_to_hz('C7'), | |
frame_length=mel_trf.win_length, | |
hop_length=mel_trf.hop_length) | |
pitch_mel = np.where(np.isnan(pitch_mel), 0., pitch_mel) # set nan to zero | |
pitch_mel = torch.from_numpy(pitch_mel) | |
pitch_mel = F.pad(pitch_mel, (0, mel_spec.size(1) - pitch_mel.size(0))) # pad to mel length | |
pitch_dict[wav_name] = pitch_mel | |
if i % 10 == 0: # save intermediate dict | |
torch.save(pitch_dict, './data/pitch_dict.pt') | |
torch.save(pitch_dict, './data/pitch_dict.pt') | |
# %% calculate pitch mean and std | |
pitch_dict = torch.load('./data/pitch_dict.pt') | |
rmean = 0 | |
rvar = 0 | |
ndata = 0 | |
for pitch_mel in pitch_dict.values(): | |
pitch_mel = np.where(np.isnan(pitch_mel), 0.0, pitch_mel) | |
pitch_mel_ = pitch_mel[pitch_mel > 1] | |
p_mean = np.mean(pitch_mel_) | |
p_var = np.var(pitch_mel_) | |
p_len = len(pitch_mel_) | |
rvar = ((ndata-1)*rvar + (p_len-1)*p_var) / (ndata + p_len - 1) + \ | |
ndata*p_len*(p_mean - rmean)**2 / ((ndata + p_len)*(ndata + p_len - 1)) | |
rmean = (p_len*p_mean + ndata*rmean) / (p_len + ndata) | |
ndata += p_len | |
mean, std = rmean, np.sqrt(rvar) | |
print('mean ', mean) | |
print('std ', std) | |
write_lines_to_file(path='./data/mean_std.txt', | |
lines=[f"mean: {mean}", | |
f"std: {std}"]) | |