%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 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.
filename = librosa.util.example_audio_file()
T = 7
x, sr = librosa.load(filename, duration=T)
print x.shape, sr
Listen to the audio file:
ipd.Audio(x, rate=sr)
Plot the signal:
librosa.display.waveplot(x, sr=sr)
Compute an onset envelope:
onset_envelope = librosa.onset.onset_strength(x, sr=sr, hop_length=256)
onset_envelope.shape
t = numpy.linspace(0, T, len(onset_envelope), endpoint=False)
plt.plot(t, onset_envelope)
plt.xlabel('Time (sec)')
plt.xlim(0, T)
plt.ylim(0)
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).
onset_frames = librosa.util.peak_pick(onset_envelope, 3, 3, 3, 5, 0.5, 10)
onset_frames = librosa.util.peak_pick(onset_envelope, 1, 1, 1, 1, 0.01, 10)
onset_frames
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)
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?