예제 #1
0
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)
예제 #2
0
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:])
예제 #3
0
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
예제 #4
0
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)
예제 #5
0
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)])
예제 #6
0
def test_harmonics_badshape_2d():
    freqs = np.zeros((5, 5))
    obs = np.zeros((5, 10))
    librosa.interp_harmonics(obs, freqs, [1])
예제 #7
0
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
        }
예제 #9
0
    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
        }
예제 #10
0
    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}