librosa.core.interp_harmonics

librosa.core.interp_harmonics(x, freqs, h_range, kind=’linear’, fill_value=0, axis=0)[source]

Compute the energy at harmonics of time-frequency representation.

Given a frequency-based energy representation such as a spectrogram or tempogram, this function computes the energy at the chosen harmonics of the frequency axis. (See examples below.) The resulting harmonic array can then be used as input to a salience computation.

Parameters:
x : np.ndarray

The input energy

freqs : np.ndarray, shape=(X.shape[axis])

The frequency values corresponding to X’s elements along the chosen axis.

h_range : list-like, non-negative

Harmonics to compute. The first harmonic (1) corresponds to x itself. Values less than one (e.g., 1/2) correspond to sub-harmonics.

kind : str

Interpolation type. See scipy.interpolate.interp1d.

fill_value : float

The value to fill when extrapolating beyond the observed frequency range.

axis : int

The axis along which to compute harmonics

Returns:
x_harm : np.ndarray, shape=(len(h_range), [x.shape])

x_harm[i] will have the same shape as x, and measure the energy at the h_range[i] harmonic of each frequency.

Examples

Estimate the harmonics of a time-averaged tempogram

>>> y, sr = librosa.load(librosa.util.example_audio_file(),
...                      duration=15, offset=30)
>>> # Compute the time-varying tempogram and average over time
>>> tempi = np.mean(librosa.feature.tempogram(y=y, sr=sr), axis=1)
>>> # We'll measure the first five harmonics
>>> h_range = [1, 2, 3, 4, 5]
>>> f_tempo = librosa.tempo_frequencies(len(tempi), sr=sr)
>>> # Build the harmonic tensor
>>> t_harmonics = librosa.interp_harmonics(tempi, f_tempo, h_range)
>>> print(t_harmonics.shape)
(5, 384)
>>> # And plot the results
>>> import matplotlib.pyplot as plt
>>> plt.figure()
>>> librosa.display.specshow(t_harmonics, x_axis='tempo', sr=sr)
>>> plt.yticks(0.5 + np.arange(len(h_range)),
...            ['{:.3g}'.format(_) for _ in h_range])
>>> plt.ylabel('Harmonic')
>>> plt.xlabel('Tempo (BPM)')
>>> plt.tight_layout()

We can also compute frequency harmonics for spectrograms. To calculate sub-harmonic energy, use values < 1.

>>> h_range = [1./3, 1./2, 1, 2, 3, 4]
>>> 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)
>>> print(S_harm.shape)
(6, 1025, 646)
>>> plt.figure()
>>> for i, _sh in enumerate(S_harm, 1):
...     plt.subplot(3, 2, i)
...     librosa.display.specshow(librosa.amplitude_to_db(_sh,
...                                                      ref=S.max()),
...                              sr=sr, y_axis='log')
...     plt.title('h={:.3g}'.format(h_range[i-1]))
...     plt.yticks([])
>>> plt.tight_layout()

(Source code)

../_images/librosa-core-interp_harmonics-1_00.png
../_images/librosa-core-interp_harmonics-1_01.png