Phase 06 - Lesson 01

Fundamentos de Áudio — Formas de Onda, Amostragem, Transformada de Fourier

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Formas de onda são o sinal bruto. Espectrogramas são a representação. Os atributos mel são a forma amigável para ML. Todo pipeline moderno de ASR e TTS sobe essa escada, e o primeiro degrau é entender amostragem e Fourier.

Tipo: Aprender Linguagens: Python Pré-requisitos: Fase 1 · 06 (Vetores e Matrizes), Fase 1 · 14 (Distribuições de Probabilidade) Tempo: ~45 minutos

O Problema

Um microfone produz um sinal de pressão-versus-tempo. Sua rede neural consome tensores. Entre eles há uma pilha de convenções que, quando violadas, produzem bugs silenciosos: o modelo treina bem mas o WER dobra, ou o TTS entrega um chiado, ou um sistema de clonagem de voz memoriza o microfone em vez do locutor.

Todo bug em sistemas de fala remonta a uma de três perguntas:

  1. Em qual taxa de amostragem os dados foram gravados, e o que o modelo espera?
  2. O sinal está com aliasing?
  3. Você está operando sobre amostras brutas ou sobre uma representação em frequência?

Acerte isso e o resto da Fase 6 fica tratável. Erre isso e até o Whisper-Large-v4 produz lixo.

O Conceito

Forma de onda, amostragem, DFT e bins de frequência visualizados

Forma de onda. Um array unidimensional de floats em [-1.0, 1.0]. Indexado por número de amostra. Para converter para segundos, divida pela taxa de amostragem: t = n / sr. Um clipe de 10 segundos a 16 kHz é um array de 160.000 floats.

Taxa de amostragem (sr). Quantas amostras por segundo. Taxas comuns em 2026:

Taxa Uso
8 kHz Telefonia, VOIP legado. Nyquist em 4 kHz mata as consoantes. Evite para ASR.
16 kHz Padrão de ASR. Whisper, Parakeet e SeamlessM4T v2 consomem 16 kHz.
22,05 kHz Treinamento de vocoder TTS para modelos mais antigos.
24 kHz TTS moderno (Kokoro, F5-TTS, xTTS v2).
44,1 kHz Áudio de CD, música.
48 kHz Cinema, áudio profissional, TTS de alta fidelidade (VALL-E 2, NaturalSpeech 3).

Nyquist-Shannon. Uma taxa de amostragem sr pode representar de forma inequívoca frequências até sr/2. O limite sr/2 é a frequência de Nyquist. Energia acima de Nyquist sofre aliasing — é dobrada para frequências mais baixas — e corrompe o sinal. Sempre aplique um filtro passa-baixas antes de reduzir a taxa de amostragem.

Profundidade de bits. PCM de 16 bits (int16 com sinal, faixa ±32.767) é o formato universal de troca. 24 bits para música, float de 32 bits para DSP interno. Bibliotecas como soundfile leem int16 mas expõem arrays float32 em [-1, 1].

Transformada de Fourier. Qualquer sinal finito é uma soma de senoides em frequências diferentes. A Transformada Discreta de Fourier (DFT) calcula, para N amostras, N coeficientes complexos — um por bin de frequência. O bin k mapeia para a frequência k · sr / N Hz. A magnitude é a amplitude naquela frequência, o ângulo é a fase.

FFT. Fast Fourier Transform: um algoritmo O(N log N) para a DFT quando N é uma potência de 2. Toda biblioteca de áudio usa FFT por baixo dos panos. Uma FFT de 1024 amostras a 16 kHz fornece 512 bins de frequência úteis abrangendo de 0 a 8 kHz com resolução de 15,6 Hz.

Janelamento + janela. Não aplicamos FFT a um clipe inteiro. Nós o cortamos em frames sobrepostos (tipicamente 25 ms com salto de 10 ms), multiplicamos cada frame por uma função de janela (Hann, Hamming) para eliminar descontinuidades de borda, e então aplicamos FFT a cada frame. Isto é a Transformada de Fourier de Curto Tempo (STFT). A Lição 02 continua a partir daqui.

Construa

Passo 1: leia um clipe e plote a forma de onda

code/main.py usa apenas o módulo wave da stdlib para manter a demonstração livre de dependências. Em produção você usará soundfile ou torchaudio.load (ambos retornam tuplas (waveform, sr)):

import soundfile as sf
waveform, sr = sf.read("clip.wav", dtype="float32")  # shape (T,), sr=int

Passo 2: sintetize uma onda senoidal a partir de princípios fundamentais

import math

def sine(freq_hz, sr, seconds, amp=0.5):
    n = int(sr * seconds)
    return [amp * math.sin(2 * math.pi * freq_hz * i / sr) for i in range(n)]

Uma senoide de 440 Hz (lá de concerto) a 16 kHz por 1 segundo são 16.000 floats. Escreva com wave.open(..., "wb") usando codificação PCM de 16 bits.

Passo 3: calcule a DFT à mão

def dft(x):
    N = len(x)
    out = []
    for k in range(N):
        re = sum(x[n] * math.cos(-2 * math.pi * k * n / N) for n in range(N))
        im = sum(x[n] * math.sin(-2 * math.pi * k * n / N) for n in range(N))
        out.append((re, im))
    return out

O(N²) — adequado para N=256 para confirmar a correção, inútil para áudio real. O código real chama numpy.fft.rfft ou torch.fft.rfft.

Passo 4: encontre a frequência dominante

O índice de pico de magnitude k_star mapeia para a frequência k_star * sr / N. Executar isso na senoide de 440 Hz deve retornar um pico no bin 440 * N / sr.

Passo 5: demonstre o aliasing

Amostre uma senoide de 7 kHz a 10 kHz (Nyquist = 5 kHz). O tom de 7 kHz está acima de Nyquist e dobra para 10 − 7 = 3 kHz. O pico da FFT aparece em 3 kHz. Esta é a demonstração clássica de aliasing e a razão pela qual todo DAC/ADC vem com um filtro passa-baixas de parede de tijolos.

Use

A pilha que você de fato vai colocar em produção em 2026:

Tarefa Biblioteca Por quê
Ler/escrever WAV/FLAC/OGG soundfile (wrapper de libsndfile) Mais rápida, estável, retorna float32.
Reamostrar torchaudio.transforms.Resample ou librosa.resample Anti-aliasing correto embutido.
STFT / Mel torchaudio ou librosa Amigável a GPU; ecossistema PyTorch.
Streaming em tempo real sounddevice ou pyaudio Bindings PortAudio multiplataforma.
Inspecionar um arquivo ffprobe ou soxi CLI, rápida, reporta sr/canais/codec.

Regra de decisão: case a taxa de amostragem antes de casar qualquer outra coisa. O Whisper espera 16 kHz mono float32. Passe a ele 44,1 kHz estéreo e você obterá lixo que parece um bug do modelo.

Entregue

Salve como outputs/skill-audio-loader.md. A skill ajuda você a verificar se a entrada de áudio corresponde às expectativas do modelo a jusante e a reamostrar corretamente quando não corresponde.

Exercícios

  1. Fácil. Sintetize uma mistura de 1 segundo de 220 Hz + 440 Hz + 880 Hz a 16 kHz. Execute a DFT. Confirme três picos nos bins esperados.
  2. Médio. Grave um WAV de 3 segundos da sua voz a 48 kHz. Reduza a amostragem para 16 kHz usando torchaudio.transforms.Resample (com anti-aliasing), depois para 16 kHz usando decimação ingênua (uma amostra a cada três). Aplique FFT em ambos. Onde aparece o aliasing?
  3. Difícil. Construa a STFT do zero usando apenas math e a DFT do Passo 3. Tamanho de frame 400, salto 160, janela de Hann. Plote as magnitudes com matplotlib.pyplot.imshow. Este é o espectrograma da Lição 02.

Termos-Chave

Termo O que as pessoas dizem O que de fato significa
Taxa de amostragem Quantas amostras por segundo Frequência em Hz na qual o ADC mede o sinal.
Nyquist A frequência máxima que você pode representar sr/2; energia acima dela sofre aliasing para baixo.
Profundidade de bits Resolução de cada amostra int16 = 65.536 níveis; float32 = precisão de 24 bits em [-1, 1].
DFT A transformada de Fourier para sequências N amostras → N coeficientes de frequência complexos.
FFT A DFT rápida Algoritmo O(N log N) que requer N = potência de 2.
Bin Coluna de frequência k · sr / N Hz; resolução = sr / N.
STFT Espectrograma por baixo dos panos FFT janelada em frames ao longo do tempo.
Aliasing Fantasmas estranhos de frequência Energia acima de Nyquist espelhando-se para bins mais baixos.

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).