3 — Construção do Filtro Digital usando Séries de Taylor (Teoria + Primeira Implementação)

3.1 Ideia central: Taylor como operador espectral
Vamos agora sair da intuição e entrar no mecanismo matemático.
Em DSP clássico, filtros passa-faixa normalmente são obtidos por:
- Convolução FIR
- Estruturas IIR
- Transformadas no domínio da frequência
Aqui adotamos um caminho diferente: usar expansões de Taylor para aproximar operadores diferenciais, que por sua natureza realçam ou atenuam componentes espectrais específicas.
A Série de Taylor de um sinal x(t) em torno de t é:
\[
x(t + \Delta t) =
x(t) – \Delta t \frac{dx}{dt} – \frac{\Delta t^2}{2!} \frac{d^2x}{dt^2} – \frac{\Delta t^3}{3!} \frac{d^3x} {dt^3} – \dots
\]
Se reorganizarmos os termos, percebemos que combinações lineares de derivadas constroem operadores seletivos em frequência.
3.2 Derivadas discretas (diferenças finitas)
No domínio discreto:
- Primeira derivada:
\[
x'(n) \approx x[n] – x[n-1]
\] - Segunda derivada:
\[
x”(n) \approx x[n] – 2x[n-1] + x[n-2]
\]
Esses operadores têm respostas conhecidas:
- 1ª derivada → passa-altas
- 2ª derivada → realce de médias frequências
Ao combinar esses termos com pesos adequados, obtemos um passa-faixa simples, centrado na região do assobio.
3.3 Filtro passa-faixa baseado em Taylor (modelo)
Definimos o filtro como:
\[
y[n] = x[n] – a_1 (x[n] – x[n-1]) – a_2 (x[n] – 2x[n-1] + x[n-2])
\]
Onde:
- \( a_1 \) controla a atenuação de baixas frequências
- \( a_2 \) controla o reforço/atenuação das médias
- Altas frequências acabam naturalmente limitadas pela discretização
Valores típicos iniciais (empíricos, estáveis):
a1 = 0.5
a2 = 0.25
Este filtro:
- Atenua DC e variações lentas
- Preserva sinais periódicos estáveis
- É extremamente barato computacionalmente
3.4 Estrutura do código (incremental)
Antes do código completo, vamos estruturar o estado do filtro, algo essencial em firmware real.
3.4.1 Estrutura de estado do filtro
typedef struct {
float x1;
float x2;
} taylor_filter_t;
x1→ amostra anteriorx2→ amostra retrasada
3.5 Implementação do filtro em C (primeira versão)
float taylor_bandpass_step(taylor_filter_t *f, float x)
{
const float a1 = 0.5f;
const float a2 = 0.25f;
float dx1 = x - f->x1;
float dx2 = x - 2.0f * f->x1 + f->x2;
float y = x - a1 * dx1 - a2 * dx2;
f->x2 = f->x1;
f->x1 = x;
return y;
}
Esse código:
- Não usa FFT
- Não usa buffers grandes
- Não depende de bibliotecas externas
- Executa em poucos ciclos de CPU
Perfeito para o RP2040.
3.6 Integração inicial com o ADC (BitDogLab)
Agora vamos conectar esse filtro ao mundo real.
3.6.1 Leitura básica do ADC
float read_adc_normalized(void)
{
uint16_t raw = adc_read(); // 0–4095
return ((float)raw - 2048.0f) / 2048.0f;
}
Isso nos fornece um sinal:
- Centrado em zero
- Normalizado entre aproximadamente −1 e +1
3.7 Primeiro loop funcional (sem cepstrum ainda)
taylor_filter_t filter = {0};
while (true) {
float x = read_adc_normalized();
float y = taylor_bandpass_step(&filter, x);
// aqui ainda não fazemos nada com y
sleep_us(125); // ~8 kHz
}
Neste ponto:
- O sistema já está filtrando o sinal
- Podemos observar
yno debugger ou via UART - Assobios já aparecem com amplitude bem maior que ruído
3.8 Validação prática (o que observar)
Ao assobiar próximo ao microfone:
y[n]apresenta uma oscilação limpa- Ruídos aleatórios ficam muito atenuados
- Voz falada perde energia rapidamente
Isso confirma:
O filtro baseado em Séries de Taylor está funcionando como passa-faixa.