In [1]:
%matplotlib inline
import seaborn
import numpy, scipy, matplotlib.pyplot as plt, IPython.display as ipd
import librosa, librosa.display
plt.rcParams['figure.figsize'] = (13, 5)

Constant-Q Transform and Chroma¶

Let's load a file:

In [2]:
x, sr = librosa.load('audio/simple_piano.wav')
ipd.Audio(x, rate=sr)
Out[2]:

Constant-Q Transform¶

Unlike the Fourier transform, but similar to the mel scale, the constant-Q transform (Wikipedia) uses a logarithmically spaced frequency axis. For more information, read the original paper:

To compute a constant-Q spectrogram, will use librosa.cqt:

In [3]:
fmin = librosa.midi_to_hz(36)
hop_length = 512
C = librosa.cqt(x, sr=sr, fmin=fmin, n_bins=72, hop_length=hop_length)

Display:

In [4]:
logC = librosa.logamplitude(C)
librosa.display.specshow(logC, sr=sr, x_axis='time', y_axis='cqt_note', fmin=fmin, cmap='coolwarm')
Out[4]:
<matplotlib.axes._subplots.AxesSubplot at 0x11cac5550>

Note how each frequency bin corresponds to one MIDI pitch number.

Chroma¶

A chroma vector (Wikipedia) (FMP, p. 123) is a typically a 12-element feature vector indicating how much energy of each pitch class, {C, C#, D, D#, E, ..., B}, is present in the signal.

In [5]:
chromagram = librosa.feature.chroma_stft(x, sr=sr, hop_length=hop_length)
librosa.display.specshow(chromagram, x_axis='time', y_axis='chroma', hop_length=hop_length)
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x11ce0ec50>
In [6]:
chromagram = librosa.feature.chroma_cqt(x, sr=sr, hop_length=hop_length)
librosa.display.specshow(chromagram, x_axis='time', y_axis='chroma', hop_length=hop_length)
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x11f51a7d0>

Chroma energy normalized statistics (CENS) (FMP, p. 375). The main idea of CENS features is that taking statistics over large windows smooths local deviations in tempo, articulation, and musical ornaments such as trills and arpeggiated chords. CENS are best used for tasks such as audio matching and similarity.

In [7]:
chromagram = librosa.feature.chroma_cens(x, sr=sr, hop_length=hop_length)
librosa.display.specshow(chromagram, x_axis='time', y_axis='chroma', hop_length=hop_length)
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x11f708890>