Birdsong spectrograms¶
In this notebook we do some signal processing with recordings of birdsong (downloaded from https://xeno-canto.org).
In [ ]:
import numpy as np
import scipy
import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
import pandas as pd
from pathlib import Path
from IPython.display import Audio
We start by reading all the files and saving the results in a dict.
In [5]:
data_dir = '../data/audio/birds/'
files = list(Path(data_dir).glob('*.wav'))
birds = {}
for file in files:
n = file.stem
print(n)
b = {'name' : n, 'file' : file}
x = wav.read(file)
b['rate'] = x[0]
y = x[1]
if y.ndim == 2:
y = y.mean(axis=1)
y = (y - y.mean()) / y.std()
y = y.astype(np.float32)
b['data'] = y
b['time'] = np.arange(len(y)) / b['rate']
birds[n] = b
blackbird chaffinch robin woodpigeon wren
The following function will display a widget with a button that you can click to play the recording of the specified bird.
In [6]:
def play_sound(n):
display(Audio(filename=birds[n]['file']))
In [7]:
play_sound('robin')
In [8]:
def show_spectrogram(n):
b = birds[n]
t = b['time']
r = b['rate']
y = b['data']
w = scipy.signal.get_window('tukey', 1024)
spf, spt, spp = scipy.signal.spectrogram(y, r)
b['spectrogram_f'] = spf
b['spectrogram_t'] = spt
b['spectrogram_p'] = spp
fig,ax = plt.subplots(2,1, figsize=(10,5))
ax[0].set_title(n)
ax[0].set_xlim(t[0], t[-1])
ax[0].plot(t, y)
ax[1].pcolormesh(spt, spf, np.maximum(np.log(spp)+15,0), cmap='Reds')
In [14]:
play_sound('blackbird')
show_spectrogram('blackbird')
In [15]:
play_sound('chaffinch')
show_spectrogram('chaffinch')
In [18]:
play_sound('robin')
show_spectrogram('robin')