>> Tecnologia Eletrônica >  >> Áudio Pessoal >> Gravadores de Voz Digitais

Como Criar Waveform a partir de Áudio: Python, Bibliotecas e Métodos de Visualização

Gerar visualização de waveform a partir de arquivo de áudio é tarefa fundamental de DSP. Seja construindo player de podcast, editor de áudio, ou data visualization, aqui estão três abordagens — de one-liner libraries a processamento raw de sinal.

Método 1: Bibliotecas High-Level (Recomendado — 5 Linhas)

Python + Librosa + Matplotlib — lida com decoding, resampling, stereo-para-mono, normalização automaticamente.

import librosa import librosa.display import matplotlib.pyplot as plt # Load audio (auto-resamples to 22050 Hz mono by default) y, sr = librosa.load("your_audio.wav") # or .mp3, .flac, .ogg # Plot waveform plt.figure(figsize=(14, 5)) librosa.display.waveshow(y, sr=sr, alpha=0.8) plt.title("Waveform (Amplitude vs Time)") plt.xlabel("Time (seconds)") plt.ylabel("Amplitude") plt.tight_layout() plt.savefig("waveform.png", dpi=150) plt.show() 

Install: pip install librosa matplotlib numpy

Opções de Customização

  • librosa.load(..., sr=None) — mantém sample rate nativo.
  • librosa.display.waveshow(..., max_points=50000) — downsample para arquivos grandes.
  • offset=30, duration=10 — plota segmento 10s começando em 30s.
  • Estilo: color='cyan', linewidth=0.5, dark background plt.style.use('dark_background').

Método 2: Processamento Manual (Entendendo o Sinal)

Python + wave + NumPy — sem lib DSP, pure standard lib + NumPy. Bom para aprendizado.

import wave import numpy as np import matplotlib.pyplot as plt # Open WAV file with wave.open("your_audio.wav", "rb") as wf: n_channels = wf.getnchannels() sampwidth = wf.getsampwidth() # bytes per sample (1, 2, 3, 4) framerate = wf.getframerate() n_frames = wf.getnframes() raw = wf.readframes(n_frames) # Convert bytes to NumPy array dtype = {1: np.int8, 2: np.int16, 3: np.int32, 4: np.int32}[sampwidth] audio = np.frombuffer(raw, dtype=dtype) # Handle stereo: average channels to mono if n_channels == 2: audio = audio.reshape(-1, 2).mean(axis=1) # Normalize to [-1, 1] audio = audio.astype(np.float32) / np.iinfo(dtype).max # Time axis time = np.arange(len(audio)) / framerate # Plot plt.figure(figsize=(14, 5)) plt.plot(time, audio, linewidth=0.5, color='#00d4aa') plt.title("Waveform (Manual Decode)") plt.xlabel("Time (s)") plt.ylabel("Amplitude (normalized)") plt.grid(True, alpha=0.3) plt.tight_layout() plt.show() 

Passos-Chave Explicados

  1. wave.open lê headers RIFF/WAV.
  2. getsampwidth determina bit depth → dtype correto.
  3. frombuffer interpreta bytes raw como integers.
  4. Stereo → mono via mean (preserva energia melhor que canal único).
  5. Normalize por valor max integer do dtype (ex.: 32767 para int16).
  6. Vetor tempo: sample index / sample rate.

Método 3: Avançado — Spectrogram (Frequência vs Tempo)

Waveform mostra amplitude. Spectrogram mostra conteúdo de frequência ao longo do tempo — essencial para análise.

import librosa import librosa.display import matplotlib.pyplot as plt import numpy as np y, sr = librosa.load("your_audio.wav", sr=None) # Compute Mel spectrogram (frequências perceptualmente espaçadas) S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000) S_dB = librosa.power_to_db(S, ref=np.max) # Plot 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('Mel Spectrogram') plt.tight_layout() plt.show() 

Outros Tipos de Spectrogram

  • STFT (Linear): librosa.stft → librosa.amplitude_to_db — espaçamento linear de frequência.
  • CQT (Constant-Q): librosa.cqt — frequência logarítmica, melhor para música.
  • Chromagram: librosa.feature.chroma_stft — 12 pitch classes (análise harmonia).

Alternativa Web / JavaScript

Para waveform no browser (sem 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> 

Usa Web Audio API decodeAudioData — funciona offline, sem servidor necessário.

Escolhendo Sua Abordagem

NecessidadeUse
Script rápido, análise, pesquisaLibrosa (Método 1)
Aprender DSP, sem dependências, só WAVManual (Método 2)
Análise de frequência, música, falaSpectrogram (Método 3)
Visualizador web real-timeWeb Audio API + Canvas
Produção C++/Rust/Golibsndfile + FFTW / kissfft / rustfft

Para a maioria das tarefas Python: Librosa. Lida com edge cases (resampling, stereo, formatos, normalização) que mordem no código manual.