def test_interp_harmonics_multi_static(s_multi): S, sr = s_multi freqs = librosa.fft_frequencies(sr=sr) Hall = librosa.interp_harmonics(S, freqs=freqs, harmonics=[0.5, 1, 2]) H0 = librosa.interp_harmonics(S[0], freqs=freqs, harmonics=[0.5, 1, 2]) H1 = librosa.interp_harmonics(S[1], freqs=freqs, harmonics=[0.5, 1, 2]) assert np.allclose(Hall[0], H0) assert np.allclose(Hall[1], H1) assert not np.allclose(H0, H1)
def relacion_fundamental_harmonicos(file): y, sr = librosa.load(file) # y, sr = librosa.load("../audios/clash cymbals/clash-cymbals__long_forte_undamped.mp3") h_range = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] S = np.abs(librosa.stft(y)) fft_freqs = librosa.fft_frequencies(sr=sr) S_harm = librosa.interp_harmonics(S, fft_freqs, h_range, axis=0) return np.sum(S_harm[1]) / np.sum(S_harm[2:])
def interp_hcqt(audio_fpath=None, y=None, fs=None): """Compute the harmonic CQT from a given audio file Parameters ---------- audio_fpath : str path to audio file Returns ------- hcqt : np.ndarray Harmonic cqt time_grid : np.ndarray List of time stamps in seconds freq_grid : np.ndarray List of frequency values in Hz """ if y is None: y, fs = librosa.load(audio_fpath, sr=SR) else: y = librosa.resample(y, fs, SR) fs = SR # How many bins do we need? # n_bins_max = 2**(ceil(log2(max(HARMONICS))) * BPO + n_bins) n_bins_plane = N_OCTAVES * BINS_PER_OCTAVE n_bins_master = int(np.ceil(np.log2(np.max(HARMONICS))) * BINS_PER_OCTAVE) + n_bins_plane cqt_master = np.abs(librosa.cqt(y=y, sr=fs, hop_length=HOP_LENGTH, fmin=FMIN, n_bins=n_bins_master, bins_per_octave=BINS_PER_OCTAVE)) freq_grid = librosa.cqt_frequencies(N_OCTAVES * BINS_PER_OCTAVE, FMIN, bins_per_octave=BINS_PER_OCTAVE) freq_master = librosa.cqt_frequencies(n_bins_master, FMIN, bins_per_octave=BINS_PER_OCTAVE) hcqt = librosa.interp_harmonics(cqt_master, freq_master, HARMONICS)[:, :N_OCTAVES * BINS_PER_OCTAVE] log_hcqt = ((1.0/80.0) * librosa.core.amplitude_to_db(hcqt, ref=np.max)) + 1.0 time_grid = librosa.core.frames_to_time( np.arange(log_hcqt.shape[-1]), sr=SR, hop_length=HOP_LENGTH ) return log_hcqt, freq_grid, time_grid
def test_interp_harmonics_multi_vary(tfr_multi): times, freqs, mags = tfr_multi # Force slinear mode here to deal with non-unique frequencies Hall = librosa.interp_harmonics(mags, freqs=freqs, harmonics=[0.5, 1, 2], kind="slinear") H0 = librosa.interp_harmonics(mags[0], freqs=freqs[0], harmonics=[0.5, 1, 2], kind="slinear") H1 = librosa.interp_harmonics(mags[1], freqs=freqs[1], harmonics=[0.5, 1, 2], kind="slinear") assert np.allclose(Hall[0], H0) assert np.allclose(Hall[1], H1) assert not np.allclose(H0, H1)
def test_harmonics_2d(): x = np.arange(16) y = np.linspace(-8, 8, num=len(x), endpoint=False)**2 y = np.tile(y, (5, 1)).T h = [0.25, 0.5, 1, 2, 4] yh = librosa.interp_harmonics(y, x, h, axis=0) eq_(yh.shape[1:], y.shape) eq_(yh.shape[0], len(h)) for i in range(len(h)): if h[i] <= 1: # Check that subharmonics match step = int(1./h[i]) vals = yh[i, ::step] assert np.allclose(vals, y[:len(vals)]) else: # Else check that harmonics match step = h[i] vals = y[::step] assert np.allclose(vals, yh[i, :len(vals)])
def test_harmonics_badshape_2d(): freqs = np.zeros((5, 5)) obs = np.zeros((5, 10)) librosa.interp_harmonics(obs, freqs, [1])
def harmonic_extract(y, sr): h_range = [1] S = np.abs(librosa.stft(y)) fft_freqs = librosa.fft_frequencies(sr=sr) S_harm = librosa.interp_harmonics(S, fft_freqs, h_range, axis=0)[0] return S_harm
def __getitem__(self, i): """Return a sample from the dataset.""" related_track_idxs = self.related_track_idxs.iat[i] # set random seed for all sampling seed = np.random.randint(0, 10000000) # load STFT of related stems, sample and add for j, track_idx in enumerate(related_track_idxs): # load metadata and temp stft tensor stft_path = self.metadata.at[track_idx, 'stft_path'] instrument = self.metadata.at[track_idx, 'instrument'] volume = self.metadata.at[track_idx, 'trackVolume'] tmp = self._load(stft_path, volume, seed) # initialize tensors if j == 0: X = torch.zeros_like(tmp) y_all_complex = [ torch.zeros_like(tmp) for _ in range(self.n_classes) ] c_all = [0] * self.n_classes # add tensors X.add_(tmp) y_all_complex[instrument].add_(tmp) c_all[instrument] = 1 # take magnitude of combined stems and scale X_complex = torch.zeros_like(X).copy_(X) X = self._stft_mag(X) if self.harmonics: X = X.numpy() if X.shape[1] == 1025: fft_freqs = librosa.fft_frequencies(sr=22050, n_fft=2048) elif X.shape[1] == 2049: fft_freqs = librosa.fft_frequencies(sr=44100, n_fft=4096) X = librosa.interp_harmonics(X, fft_freqs, [1, 2, 3], axis=1) X = torch.from_numpy(X) X = X.view(6, X.size(2), self.n_frames) # stack targets and add metadata for collate function y_all_complex = torch.stack(y_all_complex) if X.dim() == 2: X_complex = X_complex.unsqueeze(0) X = X.unsqueeze(0) y_all_complex = y_all_complex.unsqueeze(1) t = torch.tensor([y_all_complex.size(-2)]) c = torch.tensor(c_all).long() track_idx = torch.tensor(track_idx) return { 'X': X, 'X_complex': X_complex, 'y_complex': y_all_complex, 'c': c, 't': t, 'track_idx': track_idx }
def __getitem__(self, i): """Return a sample from the dataset.""" related_track_idxs = self.related_track_idxs.iat[i] # load STFT of related stems, sample and add for j, track_idx in enumerate(related_track_idxs): # load metadata and temp stft tensor stft_path = self.metadata.at[track_idx, 'stft_path'] instrument = self.metadata.at[track_idx, 'instrument'] volume = self.metadata.at[track_idx, 'trackVolume'] tmp = self._load(stft_path, volume) # initialize tensors if j == 0: X = torch.zeros_like(tmp) y_all_complex = [ torch.zeros_like(tmp) for _ in range(self.n_classes) ] c_all = [0] * self.n_classes # add tensors X.add_(tmp) y_all_complex[instrument].add_(tmp) c_all[instrument] = 1 # take magnitude of combined stems and scale and split into chunks X_complex = torch.zeros_like(X).copy_(X) X = self._stft_mag(X) # stack targets and add metadata for collate function y_all_complex = torch.stack(y_all_complex) if X.dim() == 2: X_complex, _ = self._split_track(X_complex, self.n_frames, 1) X_complex = X_complex.unsqueeze(1) X, ns = self._split_track(X, self.n_frames, 1) X = X.unsqueeze(1) y_all_complex = y_all_complex.unsqueeze(1) else: X_complex0, _ = self._split_track(X_complex[0], self.n_frames, 1) X_complex1, _ = self._split_track(X_complex[1], self.n_frames, 1) X_complex = torch.stack([X_complex0, X_complex1], dim=1) X0, _ = self._split_track(X[0], self.n_frames, 1) X1, ns = self._split_track(X[1], self.n_frames, 1) X = torch.stack([X0, X1], dim=1) if self.harmonics: X = X.numpy() if X.shape[2] == 1025: fft_freqs = librosa.fft_frequencies(sr=22050, n_fft=2048) elif X.shape[2] == 2049: fft_freqs = librosa.fft_frequencies(sr=44100, n_fft=4096) X = librosa.interp_harmonics(X, fft_freqs, [1, 2, 3], axis=2) X = torch.from_numpy(X) X = X.transpose(1, 0).contiguous() X = X.view(X.size(0), 6, X.size(3), self.n_frames) t = torch.tensor([y_all_complex.size(-2)]) c = torch.tensor(c_all).long() track_idx = torch.tensor(track_idx) return { 'X': X, 'X_complex': X_complex, 'y_complex': y_all_complex, 'c': c, 'ns': ns, 't': t, 'track_idx': track_idx }
def __getitem__(self, i): """Return a sample from the dataset.""" # target track metadata related_track_idxs = self.related_track_idxs.iat[i] # sample volume alphas n_related = len(related_track_idxs) volume_alphas = self._sample_volume_alphas(n_related) if self.threshold: volume_alphas = F.threshold(volume_alphas, self.threshold, 0.0) if self.instrument_mask: volume_alphas *= self._sample_instrument_mask(n_related) # set random seed for all sampling seed = np.random.randint(0, 10000000) # load STFT of related stems, sample and add for j, track_idx in enumerate(related_track_idxs): # load metadata and temp stft tensor stft_path = self.metadata.at[track_idx, 'stft_path'] instrument = self.metadata.at[track_idx, 'instrument'] tmp = self._load(stft_path, volume_alphas[j], seed) if self.chan_swap: tmp = self._chan_swap(tmp) if self.gain_slope: tmp = self._gain_modulation(tmp) # initialize input tensor and add if j == 0: X = torch.zeros_like(tmp) X.add_(tmp) # magnitdue and scale target for tensors tmp = self._stft_mag(tmp) # initialize target tensor and add if j == 0: y_all = [torch.zeros_like(tmp) for _ in range(self.n_classes)] y_all[instrument].add_(tmp) # add random interference X = self._add_interfere(X, volume_alphas, seed) # take magnitude of combined stems and scale X = self._stft_mag(X) if self.harmonics: X = X.numpy() if X.shape[1] == 1025: fft_freqs = librosa.fft_frequencies(sr=22050, n_fft=2048) elif X.shape[1] == 2049: fft_freqs = librosa.fft_frequencies(sr=44100, n_fft=4096) X = librosa.interp_harmonics(X, fft_freqs, [1, 2, 3], axis=1) X = torch.from_numpy(X) X = X.view(6, X.size(2), self.n_frames) # stack target tensors y_all = torch.stack(y_all) if X.dim() == 2: X = X.unsqueeze(0) y_all = y_all.unsqueeze(1) return {'X': X, 'y': y_all}