Sistema de classificação de áudio em C puro que utiliza FFT (Fast Fourier Transform), MFCCs (Mel-Frequency Cepstral Coefficients) e uma Rede Neural MLP (Multi-Layer Perceptron) para identificar sons de diferentes animais.
O modelo atinge 84.4% de acurácia em dados de teste, classificando 6 classes de áudio:
| Classe | Precisão |
|---|---|
| cachorro | 87% |
| cavalo | 87% |
| gato | 73% |
| macaco | 80% |
| pardal | 93% |
| silêncio | 87% |
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Áudio WAV │ ──► │ Extração de │ ──► │ Treinamento │ ──► │ Classificação │
│ (entrada) │ │ Features (FFT) │ │ da Rede MLP │ │ em Tempo Real │
└─────────────────┘ └──────────────────┘ └─────────────────┘ └──────────────────┘
audio/ extrair_features.c treinar_rede.c prever_audio.c
fft-to-mlp-network/
├── extrair_features.c # Extrai características do áudio usando FFT/MFCC
├── treinar_rede.c # Treina a rede neural MLP
├── prever_audio.c # Classifica novos áudios
├── dataset_downloader.py # Baixa áudios do Freesound (opcional)
├── features_train.csv # Features de treino (70% dos dados)
├── features_test.csv # Features de teste (30% dos dados)
├── mlp_model.bin # Modelo treinado (pesos da rede)
└── audio/
└── train/
├── cachorro/ # Arquivos .wav de cachorros
├── cavalo/ # Arquivos .wav de cavalos
├── gato/ # Arquivos .wav de gatos
├── macaco/ # Arquivos .wav de macacos
├── pardal/ # Arquivos .wav de pardais
└── silencio/ # Arquivos .wav de silêncio
O sistema extrai 30 características de cada arquivo de áudio usando técnicas de processamento de sinais:
O áudio é dividido em janelas sobrepostas para capturar variações temporais:
| Parâmetro | Valor | Descrição |
|---|---|---|
| Tamanho da Janela | 1024 amostras | ~64ms a 16kHz |
| Salto (Hop) | 512 amostras | 50% de sobreposição |
| Janelamento | Hamming | Reduz vazamento espectral |
A FFT transforma o sinal do domínio do tempo para o domínio da frequência:
Sinal no Tempo ──► Janela Hamming ──► FFT ──► Magnitude Espectral
Implementação da FFT (DFT):
for (int k = 0; k < TAMANHO_FFT / 2; k++) {
float soma_real = 0.0f, soma_imag = 0.0f;
for (int n = 0; n < TAMANHO_FFT; n++) {
float angulo = -2.0f * M_PI * k * n / TAMANHO_FFT;
soma_real += janeado[n] * cosf(angulo); // Parte real
soma_imag += janeado[n] * sinf(angulo); // Parte imaginária
}
magnitude[k] = sqrtf(soma_real² + soma_imag²); // Espectro de magnitude
}| # | Feature | Descrição |
|---|---|---|
| 1 | RMS_mean | Média do Root Mean Square (volume geral) |
| 2 | RMS_std | Desvio padrão do RMS (variação de volume) |
| 3 | ZeroCross_mean | Média de cruzamentos por zero (ruído vs tom) |
| 4 | ZeroCross_std | Variação dos cruzamentos por zero |
| 5 | Centroid_mean | Centro de massa espectral (brilho do som) |
| 6 | Centroid_std | Variação do centroide espectral |
| 7 | Energy_mean | Energia espectral média |
| 8 | Energy_std | Variação da energia espectral |
| 9 | Peak_max | Frequência de pico máxima (Hz) |
| 10 | Peak_mean | Média das frequências de pico |
| 11-23 | MFCC_1 a MFCC_13 | Coeficientes cepstrais em escala Mel |
| 24 | Bandwidth_mean | Largura de banda espectral média |
| 25 | Bandwidth_std | Variação da largura de banda |
| 26 | Rolloff_mean | Frequência de rolloff (85% da energia) |
| 27 | Rolloff_std | Variação do rolloff |
| 28 | Flatness_mean | Planicidade espectral (ruído vs tom) |
| 29 | Flatness_std | Variação da planicidade |
| 30 | DeltaEnergy_mean | Variação média de energia entre janelas |
Os MFCCs são as features mais importantes para reconhecimento de áudio, pois simulam a percepção auditiva humana.
┌────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐
│ FFT │ ─► │ Magnitude² │ ─► │ Banco Mel │ ─► │ Log │ ─► │ DCT │
│ (Espectro) │ │ (Potência) │ │ (26 filtros)│ │ (compressão)│ │ (13 coef)│
└────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └──────────┘
A escala Mel aproxima a percepção humana de frequências:
// Conversão Hz → Mel
mel = 2595 * log10(1 + hz / 700)
// Conversão Mel → Hz
hz = 700 * (10^(mel / 2595) - 1)26 filtros triangulares são espaçados uniformemente na escala Mel:
Amplitude
│ /\ /\ /\ /\ /\
│ / \ / \ / \ / \ / \
│ / \ / \ / \ / \ / \
│ / \/ \/ \/ \/ \
└─────────────────────────────────────────► Frequência (Mel)
F1 F2 F3 F4 F5 ...
Transforma as energias Mel em coeficientes cepstrais:
for (int k = 0; k < 13; k++) {
mfcc[k] = 0;
for (int n = 0; n < 26; n++) {
mfcc[k] += log_energia_mel[n] * cos(π * k * (2n + 1) / 52);
}
} Entrada (30)
│
▼
┌───────────────┐
│ Camada 1 │ 64 neurônios + ReLU + Dropout 40%
│ (Oculta) │
└───────┬───────┘
│
▼
┌───────────────┐
│ Camada 2 │ 32 neurônios + ReLU + Dropout 40%
│ (Oculta) │
└───────┬───────┘
│
▼
┌───────────────┐
│ Saída │ 6 neurônios + Softmax (probabilidades)
│ (Classes) │
└───────────────┘
| Componente | Descrição |
|---|---|
| ReLU | f(x) = max(0, x) - Função de ativação não-linear |
| Dropout | Desativa 40% dos neurônios aleatoriamente (regularização) |
| Softmax | Converte saídas em probabilidades (somam 1.0) |
| Xavier Init | Inicialização inteligente dos pesos |
| Parâmetro | Valor | Descrição |
|---|---|---|
| Taxa de Aprendizado | 0.001 | Velocidade de atualização dos pesos |
| Épocas Máximas | 1000 | Iterações sobre todo o dataset |
| Dropout | 40% | Taxa de desativação de neurônios |
| L2 (Weight Decay) | 0.001 | Penalização de pesos grandes |
| Early Stopping | 200 épocas | Para se não melhorar por 200 épocas |
-
Propagação Direta (Forward Pass)
entrada → camada1 → ReLU → dropout → camada2 → ReLU → dropout → saída → softmax -
Cálculo da Perda (Cross-Entropy)
perda = -log(probabilidade_classe_correta)
-
Retropropagação (Backpropagation)
- Calcula gradientes camada por camada
- Atualiza pesos:
peso -= learning_rate * (gradiente + L2 * peso)
Antes do treinamento, as features são normalizadas:
// Calcula média e desvio padrão do TREINO
for cada feature:
feature_normalizada = (feature - média) / desvio_padrão
⚠️ Importante: As estatísticas (média/desvio) são calculadas apenas no conjunto de treino e aplicadas tanto no treino quanto no teste para evitar data leakage.
Organize seus arquivos de áudio em pastas por classe:
audio/train/
├── cachorro/ ← arquivos .wav de cachorros
├── gato/ ← arquivos .wav de gatos
└── ...
# Windows (GCC/MinGW)
gcc -o extrair_features.exe extrair_features.c -lm
gcc -o treinar_rede.exe treinar_rede.c -lm
gcc -o prever_audio.exe prever_audio.c -lm
# Linux/Mac
gcc -o extrair_features extrair_features.c -lm
gcc -o treinar_rede treinar_rede.c -lm
gcc -o prever_audio prever_audio.c -lm./extrair_featuresSaída:
features_train.csv(70% dos dados)features_test.csv(30% dos dados)
./treinar_redeSaída:
mlp_model.bin(modelo treinado ~17KB)
./prever_audio caminho/para/audio.wavExemplo de saída:
>>> CLASSE PREDITA: pardal <<<
>>> CONFIANÇA: 98.13% <<<
Probabilidades por classe:
pardal 98.13% |#######################################
macaco 1.75% |
gato 0.07% |
cavalo 0.06% |
silencio 0.00% |
cachorro 0.00% |
O sistema usa split estratificado 70/30:
| Classe | Treino | Teste |
|---|---|---|
| cachorro | 35 | 15 |
| cavalo | 35 | 15 |
| gato | 35 | 15 |
| macaco | 35 | 15 |
| pardal | 35 | 15 |
| silêncio | 35 | 15 |
| Total | 210 | 90 |
O arquivo mlp_model.bin contém:
| Campo | Tipo | Tamanho |
|---|---|---|
| Pesos camada 1 | float[30][64] | 7,680 bytes |
| Bias camada 1 | float[64] | 256 bytes |
| Pesos camada 2 | float[64][32] | 8,192 bytes |
| Bias camada 2 | float[32] | 128 bytes |
| Pesos camada 3 | float[32][6] | 768 bytes |
| Bias camada 3 | float[6] | 24 bytes |
| Médias normalização | float[30] | 120 bytes |
| Desvios normalização | float[30] | 120 bytes |
| Nomes das classes | char[6][20] | 120 bytes |
| Número de classes | int | 4 bytes |
| Versão | int | 4 bytes |
| Total | ~17 KB |
- Formato: WAV (PCM não comprimido)
- Bits por amostra: 8 ou 16 bits
- Canais: Mono ou Estéreo (convertido para mono)
- Taxa de amostragem: Qualquer (recomendado 16kHz+)
- Áudio máximo: 500.000 amostras (~31s a 16kHz)
- Janelas máximas: 1.000 por arquivo
- Modelo em RAM: ~70KB durante inferência
Consulte o arquivo LICENSE para detalhes.
- Implementação 100% em C sem dependências externas
- Algoritmos baseados em literatura clássica de processamento de áudio
- Dataset de teste: Freesound.org (via API)