Comment Créer une Forme d'Onde depuis Audio: Python, Bibliothèques & Méthodes Visualisation
Générer une visualisation forme d'onde depuis fichier audio est tâche DSP fondamentale. Que vous construisiez lecteur podcast, éditeur audio, ou visualisation données, voici trois approches — du one-liner bibliothèques au traitement signal brut.
Méthode 1: Bibliothèques Haut Niveau (Recommandée — 5 Lignes)
Python + Librosa + Matplotlib — gère décodage, rééchantillonnage, stéréo-vers-mono, normalisation automatiquement.
import librosa
import librosa.display
import matplotlib.pyplot as plt
# Charger audio (auto-rééchantillonne 22050 Hz mono par défaut)
y, sr = librosa.load("votre_audio.wav") # ou .mp3, .flac, .ogg
# Tracer forme d'onde
plt.figure(figsize=(14, 5))
librosa.display.waveshow(y, sr=sr, alpha=0.8)
plt.title("Forme d'onde (Amplitude vs Temps)")
plt.xlabel("Temps (secondes)")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.savefig("waveform.png", dpi=150)
plt.show()
Install : pip install librosa matplotlib numpy
Options Personnalisation
librosa.load(..., sr=None)— garder fréquence échantillonnage native.librosa.display.waveshow(..., max_points=50000)— sous-échantillonner gros fichiers.offset=30, duration=10— tracer segment 10s commençant 30s.- Style:
color='cyan',linewidth=0.5, fond sombreplt.style.use('dark_background').
Méthode 2: Traitement Manuel (Comprendre Signal)
Python + wave + NumPy — pas bibliothèque DSP, lib standard pur + NumPy. Bon pour apprendre.
import wave
import numpy as np
import matplotlib.pyplot as plt
# Ouvrir fichier WAV
with wave.open("votre_audio.wav", "rb") as wf:
n_channels = wf.getnchannels()
sampwidth = wf.getsampwidth() # octets par échantillon (1, 2, 3, 4)
framerate = wf.getframerate()
n_frames = wf.getnframes()
raw = wf.readframes(n_frames)
# Convertir octets en array NumPy
dtype = {1: np.int8, 2: np.int16, 3: np.int32, 4: np.int32}[sampwidth]
audio = np.frombuffer(raw, dtype=dtype)
# Gérer stéréo: moyenniser canaux vers mono
if n_channels == 2:
audio = audio.reshape(-1, 2).mean(axis=1)
# Normaliser à [-1, 1]
audio = audio.astype(np.float32) / np.iinfo(dtype).max
# Axe temps
time = np.arange(len(audio)) / framerate
# Tracer
plt.figure(figsize=(14, 5))
plt.plot(time, audio, linewidth=0.5, color='#00d4aa')
plt.title("Forme d'onde (Décodage Manuel)")
plt.xlabel("Temps (s)")
plt.ylabel("Amplitude (normalisée)")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Étapes Clés Expliquées
wave.openlit en-têtes RIFF/WAV.getsampwidthdétermine profondeur bits → dtype correct.frombufferinterprète octets bruts comme entiers.- Stéréo → mono via moyenne (préserve énergie mieux que canal unique).
- Normaliser par valeur max entier pour dtype (ex: 32767 pour int16).
- Vecteur temps: index échantillon / fréquence échantillonnage.
Méthode 3: Avancé — Spectrogramme (Fréquence vs Temps)
Forme d'onde montre amplitude. Spectrogramme montre contenu fréquentiel dans temps — essentiel analyse.
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
y, sr = librosa.load("votre_audio.wav", sr=None)
# Calculer spectrogramme Mel (fréquences espacées perceptuellement)
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000)
S_dB = librosa.power_to_db(S, ref=np.max)
# Tracer
plt.figure(figsize=(14, 6))
librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel', fmax=8000, cmap='magma')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogramme Mel')
plt.tight_layout()
plt.show()
Autres Types Spectrogramme
- STFT (Linéaire) :
librosa.stft→librosa.amplitude_to_db— espacement fréquence linéaire. - CQT (Constant-Q) :
librosa.cqt— fréquence logarithmique, meilleur musique. - Chromagramme :
librosa.feature.chroma_stft— 12 classes hauteur (analyse harmonie).
Alternative Web / JavaScript
Pour forme d'onde navigateur (pas backend) :
<canvas id="waveform" width="800" height="200"></canvas>
<script>
const audioCtx = new AudioContext();
fetch('audio.mp3').then(r => r.arrayBuffer())
.then(buf => audioCtx.decodeAudioData(buf))
.then(buffer => {
const data = buffer.getChannelData(0); // Float32Array [-1,1]
const canvas = document.getElementById('waveform');
const ctx = canvas.getContext('2d');
const step = Math.ceil(data.length / canvas.width);
ctx.fillStyle = '#00d4aa';
for (let x = 0; x < canvas.width; x++) {
const start = x * step;
const end = Math.min(start + step, data.length);
let min = 1, max = -1;
for (let i = start; i < end; i++) {
min = Math.min(min, data[i]);
max = Math.max(max, data[i]);
}
const yMin = (1 + min) * canvas.height / 2;
const yMax = (1 + max) * canvas.height / 2;
ctx.fillRect(x, yMin, 1, yMax - yMin);
}
});
</script>
Utilise Web Audio API decodeAudioData — fonctionne hors-ligne, pas serveur nécessaire.
Choisir Votre Approche
| Besoin | Utiliser |
|---|---|
| Script rapide, analyse, recherche | Librosa (Méthode 1) |
| Apprendre DSP, pas dépendances, WAV seulement | Manuel (Méthode 2) |
| Analyse fréquence, musique, parole | Spectrogramme (Méthode 3) |
| Visualiseur web temps réel | Web Audio API + Canvas |
| Production C++/Rust/Go | libsndfile + FFTW / kissfft / rustfft |
Pour la plupart tâches Python: Librosa. Il gère cas limites (rééchantillonnage, stéréo, formats, normalisation) qui mordent code manuel.
