Spaces:
Runtime error
Runtime error
| import torch | |
| import numpy as np | |
| import librosa.util as librosa_util | |
| from scipy.signal import get_window | |
| from src.tools.torch_utils import random_uniform | |
| from scipy.io.wavfile import write | |
| def window_sumsquare( | |
| window, | |
| n_frames, | |
| hop_length, | |
| win_length, | |
| n_fft, | |
| dtype=np.float32, | |
| norm=None, | |
| ): | |
| """ | |
| # from librosa 0.6 | |
| Compute the sum-square envelope of a window function at a given hop length. | |
| This is used to estimate modulation effects induced by windowing | |
| observations in short-time fourier transforms. | |
| Parameters | |
| ---------- | |
| window : string, tuple, number, callable, or list-like | |
| Window specification, as in `get_window` | |
| n_frames : int > 0 | |
| The number of analysis frames | |
| hop_length : int > 0 | |
| The number of samples to advance between frames | |
| win_length : [optional] | |
| The length of the window function. By default, this matches `n_fft`. | |
| n_fft : int > 0 | |
| The length of each analysis frame. | |
| dtype : np.dtype | |
| The data type of the output | |
| Returns | |
| ------- | |
| wss : np.ndarray, shape=`(n_fft + hop_length * (n_frames - 1))` | |
| The sum-squared envelope of the window function | |
| """ | |
| if win_length is None: | |
| win_length = n_fft | |
| n = n_fft + hop_length * (n_frames - 1) | |
| x = np.zeros(n, dtype=dtype) | |
| # Compute the squared window at the desired length | |
| win_sq = get_window(window, win_length, fftbins=True) | |
| win_sq = librosa_util.normalize(win_sq, norm=norm) ** 2 | |
| win_sq = librosa_util.pad_center(win_sq, n_fft) | |
| # Fill the envelope | |
| for i in range(n_frames): | |
| sample = i * hop_length | |
| x[sample : min(n, sample + n_fft)] += win_sq[: max(0, min(n_fft, n - sample))] | |
| return x | |
| def griffin_lim(magnitudes, stft_fn, n_iters=30): | |
| """ | |
| PARAMS | |
| ------ | |
| magnitudes: spectrogram magnitudes | |
| stft_fn: STFT class with transform (STFT) and inverse (ISTFT) methods | |
| """ | |
| angles = np.angle(np.exp(2j * np.pi * np.random.rand(*magnitudes.size()))) | |
| angles = angles.astype(np.float32) | |
| angles = torch.autograd.Variable(torch.from_numpy(angles)) | |
| signal = stft_fn.inverse(magnitudes, angles).squeeze(1) | |
| for i in range(n_iters): | |
| _, angles = stft_fn.transform(signal) | |
| signal = stft_fn.inverse(magnitudes, angles).squeeze(1) | |
| return signal | |
| def dynamic_range_compression(x, normalize_fun=torch.log, C=1, clip_val=1e-5): | |
| """ | |
| PARAMS | |
| ------ | |
| C: compression factor | |
| """ | |
| return normalize_fun(torch.clamp(x, min=clip_val) * C) | |
| def dynamic_range_decompression(x, C=1): | |
| """ | |
| PARAMS | |
| ------ | |
| C: compression factor used to compress | |
| """ | |
| return torch.exp(x) / C | |
| def frequency_masking(self, log_mel_spec, freqm): | |
| bs, freq, tsteps = log_mel_spec.size() | |
| mask_len = int(random_uniform(freqm // 8, freqm)) | |
| mask_start = int(random_uniform(start=0, end=freq - mask_len)) | |
| log_mel_spec[:, mask_start : mask_start + mask_len, :] *= 0.0 | |
| return log_mel_spec | |
| def time_masking(self, log_mel_spec, timem): | |
| bs, freq, tsteps = log_mel_spec.size() | |
| mask_len = int(random_uniform(timem // 8, timem)) | |
| mask_start = int(random_uniform(start=0, end=tsteps - mask_len)) | |
| log_mel_spec[:, :, mask_start : mask_start + mask_len] *= 0.0 | |
| return log_mel_spec | |
| def get_mel_from_wav(audio, _stft): | |
| audio = torch.clip(torch.FloatTensor(audio).unsqueeze(0), -1, 1) | |
| audio = torch.autograd.Variable(audio, requires_grad=False) | |
| melspec, magnitudes, phases, energy = _stft.mel_spectrogram(audio) | |
| melspec = torch.squeeze(melspec, 0).numpy().astype(np.float32) | |
| magnitudes = torch.squeeze(magnitudes, 0).numpy().astype(np.float32) | |
| energy = torch.squeeze(energy, 0).numpy().astype(np.float32) | |
| return melspec, magnitudes, energy | |
| def inv_mel_spec(mel, out_filename, _stft, griffin_iters=60): | |
| mel = torch.stack([mel]) | |
| mel_decompress = _stft.spectral_de_normalize(mel) | |
| mel_decompress = mel_decompress.transpose(1, 2).data.cpu() | |
| spec_from_mel_scaling = 1000 | |
| spec_from_mel = torch.mm(mel_decompress[0], _stft.mel_basis) | |
| spec_from_mel = spec_from_mel.transpose(0, 1).unsqueeze(0) | |
| spec_from_mel = spec_from_mel * spec_from_mel_scaling | |
| audio = griffin_lim( | |
| torch.autograd.Variable(spec_from_mel[:, :, :-1]), _stft._stft_fn, griffin_iters | |
| ) | |
| audio = audio.squeeze() | |
| audio = audio.cpu().numpy() | |
| audio_path = out_filename | |
| write(audio_path, _stft.sampling_rate, audio) | |