>> Technologie Électronique >  >> Audio personnel >> Enregistreurs vocaux numériques

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 sombre plt.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

  1. wave.open lit en-têtes RIFF/WAV.
  2. getsampwidth détermine profondeur bits → dtype correct.
  3. frombuffer interprète octets bruts comme entiers.
  4. Stéréo → mono via moyenne (préserve énergie mieux que canal unique).
  5. Normaliser par valeur max entier pour dtype (ex: 32767 pour int16).
  6. 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

BesoinUtiliser
Script rapide, analyse, rechercheLibrosa (Méthode 1)
Apprendre DSP, pas dépendances, WAV seulementManuel (Méthode 2)
Analyse fréquence, musique, paroleSpectrogramme (Méthode 3)
Visualiseur web temps réelWeb Audio API + Canvas
Production C++/Rust/Golibsndfile + 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.

Enregistreurs vocaux numériques