In [1]:
%matplotlib inline
import numpy, scipy, matplotlib.pyplot as plt, IPython.display as ipd
import librosa, librosa.display
import stanford_mir; stanford_mir.init()
The zero crossing rate indicates the number of times that a signal crosses the horizontal axis.
Let's load a signal:
In [2]:
x, sr = librosa.load('audio/simple_loop.wav')
Listen to the signal:
In [3]:
ipd.Audio(x, rate=sr)
Out[3]:
Plot the signal:
In [4]:
plt.figure(figsize=(14, 5))
librosa.display.waveplot(x, sr=sr)
Out[4]:
Let's zoom in:
In [5]:
n0 = 6500
n1 = 7500
plt.figure(figsize=(14, 5))
plt.plot(x[n0:n1])
Out[5]:
I count five zero crossings. Let's compute the zero crossings using librosa.
In [6]:
zero_crossings = librosa.zero_crossings(x[n0:n1], pad=False)
In [7]:
zero_crossings.shape
Out[7]:
That computed a binary mask where True
indicates the presence of a zero crossing. To find the total number of zero crossings, use sum
:
In [8]:
print(sum(zero_crossings))
To find the zero-crossing rate over time, use zero_crossing_rate
:
In [9]:
zcrs = librosa.feature.zero_crossing_rate(x)
print(zcrs.shape)
Plot the zero-crossing rate:
In [10]:
plt.figure(figsize=(14, 5))
plt.plot(zcrs[0])
Out[10]:
Note how the high zero-crossing rate corresponds to the presence of the snare drum.
The reason for the high rate near the beginning is because the silence oscillates quietly around zero:
In [11]:
plt.figure(figsize=(14, 5))
plt.plot(x[:1000])
plt.ylim(-0.0001, 0.0001)
Out[11]:
A simple hack around this is to add a small constant before computing the zero crossing rate:
In [12]:
zcrs = librosa.feature.zero_crossing_rate(x + 0.0001)
plt.figure(figsize=(14, 5))
plt.plot(zcrs[0])
Out[12]:
Try for other audio files. Does the zero-crossing rate still return something useful in polyphonic mixtures?
In [13]:
ls audio