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

Peak Picking¶

Peak picking is the act of locating peaks in a signal. For example, in onset detection, we may want to find peaks in a novelty function. These peaks would correspond to the musical onsets.

Let's load an example audio file.

In [56]:
filename = librosa.util.example_audio_file()
T = 7
x, sr = librosa.load(filename, duration=T)
In [57]:
print x.shape, sr
(154350,) 22050

Listen to the audio file:

In [58]:
ipd.Audio(x, rate=sr)
Out[58]:

Plot the signal:

In [59]:
librosa.display.waveplot(x, sr=sr)
Out[59]:
<matplotlib.collections.PolyCollection at 0x11b635e10>

Compute an onset envelope:

In [63]:
onset_envelope = librosa.onset.onset_strength(x, sr=sr, hop_length=256)
In [64]:
onset_envelope.shape
Out[64]:
(603,)
In [65]:
t = numpy.linspace(0, T, len(onset_envelope), endpoint=False)
In [66]:
plt.plot(t, onset_envelope)
plt.xlabel('Time (sec)')
plt.xlim(0, T)
plt.ylim(0)
Out[66]:
(0, 7.0296167607626998)

In this onset strength envelope, we clearly see many peaks. Some correspond to onsets, and others don't. How do

librosa.util has a peak_pick method which does this for us. Let's see how it works:

def peak_pick(x, pre_max, post_max, pre_avg, post_avg, delta, wait):
    '''Uses a flexible heuristic to pick peaks in a signal.

    A sample n is selected as a peak if the corresponding x[n]
    fulfills the following three conditions:

    1. `x[n] == max(x[n - pre_max:n + post_max])`
    2. `x[n] >= mean(x[n - pre_avg:n + post_avg]) + delta`
    3. `n - previous_n > wait`

    where `previous_n` is the last sample picked as a peak (greedily).
In [67]:
onset_frames = librosa.util.peak_pick(onset_envelope, 3, 3, 3, 5, 0.5, 10)
In [73]:
onset_frames = librosa.util.peak_pick(onset_envelope, 1, 1, 1, 1, 0.01, 10)
In [74]:
onset_frames
Out[74]:
array([  5,  19,  33,  44,  58,  70,  84, 100, 111, 122, 133, 144, 158,
       171, 183, 197, 209, 220, 232, 243, 257, 272, 283, 296, 310, 321,
       332, 343, 358, 370, 382, 397, 411, 429, 443, 455, 470, 482, 497,
       509, 520, 531, 542, 556, 570, 581, 596])
In [75]:
plt.plot(t, onset_envelope)
plt.vlines(t[onset_frames], 0, onset_envelope.max(), color='r', alpha=0.7)
plt.xlabel('Time (sec)')
plt.xlim(0, T)
plt.ylim(0)
Out[75]:
(0, 7.0296167607626998)
In [ ]:
 
In [ ]:
 
In [ ]:
 

Questions¶

Adjust the hop length from 512 to 256 or 1024. How does that affect the onset envelope, and consequently, the peak picking?

Adjust the peak_pick parameters, pre_max, post_max, pre_avg, post_avg, delta, and wait. How do the detected peaks change?

In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: