Note
Go to the end to download the full example code.
Timbre and spectral content#
This section introduces common tools for representing the timbral or textural content of audio signals.
What is timbre?#
Earlier sections focused on pitch, harmony, and rhythm. Here we turn to timbre: the aspects of sound that make two instruments playing the same notes sound different. Compared to the earlier topics we’ve examined, timbre is harder to pin down conceptually with a clean definition. As a result, the analysis in this section will be a bit more exploratory and data-driven than purely computational. By the end of this section, you should have a better understanding of how basic signal representations (e.g. the STFT) capture both pitch and timbre, and why disentangling these concepts takes a bit of extra work.
Warning
If you’re not previously familiar with concepts like nearest neighbors and dimensionality reduction, you might want to read up on those topics before continuing with this tutorial section. The scikit-learn documentation is a good place to start:
To study timbre, we want examples where pitch and timing are held roughly constant while the instrument changes. For that, we use an excerpt from the ChoraleBricks dataset, augmented with piano and synthesized strings. Each instrument is stored in a separate channel of the same audio file.
For context, we can listen to each instrument in isolation:
import numpy as np
import matplotlib.pyplot as plt
import librosa
from IPython.display import Audio, HTML
y, sr = librosa.loadx("drese", mono=False)
HTML(librosa.util.example_info("drese", html=True))
instruments = ["Alto Sax", "Clarinet", "Trumpet", "Piano", "Synth string"]
n_instruments = len(instruments)
html_content = ""
for i, instrument in enumerate(instruments):
audio_widget = Audio(y[i], rate=sr)._repr_html_()
html_content += f"<div><strong>{instrument}:</strong><br>{audio_widget}</div><br>"
# Must be the final statement evaluated in this script block
HTML(html_content)