Tever
FR

Tutoriel · Labo DIY

Comment calculer un spectrogramme avec librosa

Tutoriel pas à pas, avec notebook téléchargeable, pour passer d'un audio réel à son spectrogramme avec librosa : STFT, décibels et bandes harmoniques.

Infographie sur fond bleu foncé avec un spectrogramme en tons magma et orange, axe de fréquence en échelle logarithmique et bandes horizontales d'harmoniques, à côté d'un extrait de code Python avec les lignes librosa.load, librosa.stft et librosa.display.specshow

librosa est la bibliothèque Python de référence pour travailler avec de l’audio : elle calcule des spectrogrammes, extrait des caractéristiques et donne un accès direct à la transformée de Fourier sans avoir à l’implémenter soi-même. Ce tutoriel passe de la théorie à la pratique : nous chargeons un audio réel, calculons son spectrogramme et apprenons à le lire. À la fin, vous disposerez d’un notebook Jupyter téléchargeable avec tout le code, prêt à exécuter sur votre propre audio.

Ce que nous allons construire

Nous partons d’un extrait audio réel —un fragment de Fayendo (2021), morceau de l’EP Suañu de Gaita, enregistrement personnel de cornemuse asturienne— et parcourons le chemin complet jusqu’à son spectrogramme :

  1. Charger l’audio avec librosa.load.
  2. Calculer sa transformée de Fourier à court terme (STFT).
  3. Convertir cette transformée en un spectrogramme lisible, en décibels.
  4. Le tracer et apprendre à le lire.

Tout le code de ce tutoriel se trouve aussi dans un notebook Jupyter que vous pouvez télécharger et exécuter avec votre propre audio.

Installation

pip install librosa numpy matplotlib

librosa embarque numpy comme dépendance, mais matplotlib doit être installé à part pour le tracé. Avec ces trois bibliothèques installées, vous pouvez reproduire tout ce qui suit.

1. Charger l’audio

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt

y, sr = librosa.load("tever-extracto.mp3")

print(f"Fréquence d'échantillonnage : {sr} Hz")
print(f"Durée : {librosa.get_duration(y=y, sr=sr):.1f} s")

librosa.load décode le fichier et renvoie deux éléments : y, un tableau numpy avec la forme d’onde, et sr (sample rate), la fréquence d’échantillonnage. Par défaut, librosa rééchantillonne à 22050 Hz —suffisant pour la plage qui nous intéresse en analyse musicale, et plus léger à traiter que les 44100 Hz d’un CD.

2. La transformée de Fourier à court terme (STFT)

La forme d’onde ne dit pas facilement quelles notes sonnent : c’est la représentation temporelle, une valeur de pression d’air par instant. Pour voir quelles fréquences elle contient, il faut passer au domaine fréquentiel, et non d’un coup sur tout l’audio, mais par fenêtres courtes qui se déplacent dans le temps. C’est la STFT (Short-Time Fourier Transform) : de nombreuses petites transformées de Fourier, une par fenêtre, empilées les unes après les autres.

D = librosa.stft(y, n_fft=2048, hop_length=512)

Deux paramètres déterminent la résolution de l’analyse :

ParamètreCe qu’il contrôle
n_fftLa taille de chaque fenêtre d’analyse, en échantillons. 2048 est une valeur courante : résolution fréquentielle suffisante sans trop perdre en résolution temporelle.
hop_lengthLe déplacement de la fenêtre entre deux calculs successifs. Avec chevauchement (hop_length inférieur à n_fft), le résultat est plus lisse.

D est une matrice de nombres complexes : chaque colonne est une fenêtre temporelle, chaque ligne une fréquence, et la valeur combine magnitude (la quantité d’énergie) et phase.

3. De la magnitude aux décibels

Pour le spectrogramme, seule la magnitude est nécessaire, pas la phase. Et comme l’oreille humaine perçoit l’intensité de façon logarithmique, on la convertit en décibels :

S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

Ainsi, les petites différences dans les zones de faible énergie se distinguent aussi bien que les grandes dans les zones de forte énergie —sur une échelle linéaire, elles seraient écrasées.

4. Tracer le spectrogramme

fig, ax = plt.subplots(figsize=(12, 5))
img = librosa.display.specshow(
    S_db, sr=sr, hop_length=512,
    x_axis="time", y_axis="log", ax=ax, cmap="magma",
)
ax.set(title="Spectrogramme (STFT, échelle logarithmique)")
fig.colorbar(img, ax=ax, format="%+2.0f dB")
plt.show()

specshow interprète les axes de temps et de fréquence directement à partir de sr et hop_length, sans que vous ayez à les calculer à la main. L’axe Y en échelle logarithmique (y_axis="log") est celui d’usage en musique : il reflète mieux la répartition des notes dans la plage audible qu’une échelle linéaire.

Spectrogramme réel généré avec librosa à partir d'un extrait de Fayendo : axe de fréquence en échelle logarithmique, axe de temps en secondes, énergie en décibels représentée en tons magma et orange. On y voit des bandes horizontales d'harmoniques et des silences verticaux entre les phrases.

Spectrogramme d’un extrait de Fayendo, calculé avec le code de ce tutoriel. Les bandes horizontales sont les harmoniques de chaque note ; les vides verticaux, des silences entre les phrases.

Comment lire le résultat

Sur le spectrogramme ci-dessus, on voit des bandes horizontales qui montent et descendent ensemble : ce sont la fréquence fondamentale de chaque note et ses harmoniques —des multiples entiers de cette fréquence—. Ce motif de bandes parallèles, et la façon dont l’énergie se répartit entre elles, est l’un des signaux qu’un système de transcription musicale automatique utilise pour décider quelle note est jouée. Les vides verticaux de silence entre les bandes correspondent aux respirations entre les phrases —une caractéristique du phrasé propre aux instruments à vent continu, comme la cornemuse.

Prochaines étapes

Ce tutoriel s’arrête au spectrogramme comme image. Le notebook téléchargeable indique trois directions pour continuer :

  • Chromagramme (librosa.feature.chroma_stft) : regroupe l’énergie dans les 12 classes de hauteur (do, do#, ré…), utile pour détecter des accords ou une tonalité.
  • MFCC (librosa.feature.mfcc) : une représentation compacte du timbre, très utilisée en classification d’instruments et de genres.
  • Détection d’onsets (librosa.onset.onset_detect) : trouver l’instant exact où commence chaque note, premier pas vers une transcription automatique réelle.

Le notebook

Tout le code de ce tutoriel —charger, transformer, tracer et les prochaines étapes commentées— se trouve dans un notebook Jupyter téléchargeable, avec le fragment de Fayendo utilisé comme exemple. Ouvrez-le avec jupyter notebook ou jupyter lab, ou déposez-le sur Google Colab si vous ne voulez rien installer en local. Si vous n’avez jamais utilisé de notebook, Qu’est-ce qu’un notebook Jupyter explique par où commencer.

Bibliographie

Les références sur lesquelles s’appuie cet article, et par où poursuivre la lecture :