<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>pitch detection - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/pitch-detection/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Fri, 05 Dec 2025 17:50:26 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>pitch detection - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Quefrequência e Análise Cepstral: Uma Introdução Prática para Sistemas Embarcados (ESP32-P4)</title>
		<link>https://mcu.tec.br/algoritimos/dsp/quefrequencia-e-analise-cepstral-uma-introducao-pratica-para-sistemas-embarcados-esp32-p4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quefrequencia-e-analise-cepstral-uma-introducao-pratica-para-sistemas-embarcados-esp32-p4</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 05 Dec 2025 11:23:39 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[análise cepstral]]></category>
		<category><![CDATA[cepstro]]></category>
		<category><![CDATA[classificação acústica]]></category>
		<category><![CDATA[detecção de eventos sonoros]]></category>
		<category><![CDATA[DSP embarcado]]></category>
		<category><![CDATA[engenharia de áudio]]></category>
		<category><![CDATA[envelope espectral]]></category>
		<category><![CDATA[esp-dsp]]></category>
		<category><![CDATA[ESP32-P4]]></category>
		<category><![CDATA[fft]]></category>
		<category><![CDATA[ifft]]></category>
		<category><![CDATA[log-espectro]]></category>
		<category><![CDATA[MFCC]]></category>
		<category><![CDATA[pitch detection]]></category>
		<category><![CDATA[processamento de áudio embarcado]]></category>
		<category><![CDATA[processamento digital de sinais]]></category>
		<category><![CDATA[quefrequência]]></category>
		<category><![CDATA[sistema fonte-filtro]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=947</guid>

					<description><![CDATA[<p>A análise cepstral e o conceito de quefrequência são técnicas essencialmente poderosas no processamento de sinais de áudio, permitindo separar efeitos de excitação, resposta acústica e periodicidades espectrais que não são claramente visíveis no domínio da frequência tradicional. Neste artigo para o site mcu.tec.br, apresentamos uma explicação didática e rigorosa sobre o que é o cepstro, como surge a quefrequência e por que essa abordagem é tão eficiente para extração de pitch, detecção de envoltória espectral, identificação de ecos e modelagem fonte–filtro. O conteúdo inclui as fórmulas matemáticas necessárias para compreensão do método, além de exemplos práticos de implementação em C utilizando o ESP32-P4 e a biblioteca ESP-DSP, permitindo aplicações em reconhecimento de fala embarcado, classificação acústica, monitoramento industrial e análise de eventos sonoros em tempo real.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/quefrequencia-e-analise-cepstral-uma-introducao-pratica-para-sistemas-embarcados-esp32-p4/">Quefrequência e Análise Cepstral: Uma Introdução Prática para Sistemas Embarcados (ESP32-P4)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h3 class="wp-block-heading">Introdução: por que falar em Quefrequência e Análise Cepstral?</h3>



<p class="wp-block-paragraph">Quando trabalhamos com áudio em sistemas embarcados (como um ESP32-P4), é muito comum pensar apenas em tempo e frequência: sinal no tempo, depois FFT para ver o espectro, aplicar filtros, etc. Porém, há situações em que olhar somente o espectro de magnitude não é suficiente para separar os “componentes” de interesse do sinal:</p>



<ul class="wp-block-list">
<li>Separar o conteúdo de excitação (por exemplo, cordas vocais ou fonte sonora) do “formante” ou ressonâncias do sistema (trato vocal, sala, caixa acústica).</li>



<li>Identificar ecos ou reverberações (reflexões) embutidos no sinal.</li>



<li>Estimar pitch (frequência fundamental da voz) mesmo em ambientes ruidosos ou com filtragem forte.</li>



<li>Detectar características de envoltória espectral (timbre) independentemente da excitação instantânea.</li>
</ul>



<p class="wp-block-paragraph">A análise cepstral foi criada justamente para isso: ela “desfaz” a convolução no domínio da frequência ao transformar multiplicações em somas usando o logaritmo, e depois aplica novamente uma transformada inversa. Isso gera um novo domínio de análise – não mais tempo, nem frequência – mas o domínio da <strong>quefrequência</strong>.</p>



<h4 class="wp-block-heading">Conceito intuitivo de Quefrequência</h4>



<p class="wp-block-paragraph">O termo “quefrequência” é um trocadilho proposital com “frequency” (frequência). A ideia é:</p>



<ul class="wp-block-list">
<li>No domínio da frequência, o eixo horizontal é a frequência ( f ) (Hz).</li>



<li>Na análise cepstral, depois de aplicar log do espectro e uma transformada inversa, o eixo horizontal passa a ter unidade de <strong>tempo</strong>, mas não é o tempo original do sinal; é um “tempo de periodicidade” derivado da estrutura de frequência.</li>



<li>Como essa variável não é exatamente o tempo do domínio original, nem a frequência, foi dado o nome de <strong>quefrequência</strong> e a unidade de <strong>queferência</strong> (em segundos ou amostras, mas interpretada como “período da estrutura espectral”).</li>
</ul>



<p class="wp-block-paragraph">Intuitivamente:</p>



<ul class="wp-block-list">
<li>Picos de periodicidade de <strong>pitch</strong> aparecem como picos em quefrequência correspondendo ao período fundamental do sinal.</li>



<li>A envoltória lenta do espectro (por exemplo, os formantes da voz ou a resposta de uma sala) aparece concentrada em baixas quefrequências.</li>



<li>Componentes mais “rápidos” do espectro (finas linhas espectrais, harmônicos) aparecem em quefrequências mais altas.</li>
</ul>



<p class="wp-block-paragraph">Isso permite “separar no eixo da quefrequência” aquilo que queremos analisar:</p>



<ul class="wp-block-list">
<li>Baixa quefrequência → envoltória espectral (formantes, timbre, resposta de sistema).</li>



<li>Alta quefrequência → detalhes finos da excitação (harmônicos, rugosidade, etc.).</li>
</ul>



<p class="wp-block-paragraph">Em processamento de voz, isso tem aplicações clássicas:</p>



<ul class="wp-block-list">
<li><strong>Modelagem fonte–filtro</strong>: a fala é modelada como excitação (cordas vocais ou ruído glótico) passando por um filtro (trato vocal). A análise cepstral permite separar esses dois componentes.</li>



<li><strong>Reconhecimento de fala</strong>: coeficientes cepstrais (por exemplo, MFCC – Mel Frequency Cepstral Coefficients) são onipresentes em sistemas de ASR.</li>



<li><strong>Equalização e cancelamento de eco</strong>: a estrutura de eco pode ser observada no domínio cepstral e tratada de forma mais clara em alguns cenários.</li>
</ul>



<p class="wp-block-paragraph">No contexto do <strong>ESP32-P4</strong> e de sistemas embarcados em geral, a análise cepstral é interessante porque:</p>



<ul class="wp-block-list">
<li>Pode ser implementada em cima de FFTs já disponíveis (bibliotecas de DSP, ESP-DSP, etc.).</li>



<li>É computacionalmente viável para janelas de áudio de tamanho moderado.</li>



<li>Fornece uma representação compacta do sinal (poucos coeficientes cepstrais podem ser suficientes para muitos algoritmos de decisão, classificação ou detecção).</li>
</ul>



<h4 class="wp-block-heading">Visão global do fluxo de análise cepstral</h4>



<p class="wp-block-paragraph">Sem entrar ainda nos detalhes matemáticos (que virão na próxima seção), o fluxo básico é:</p>



<ol class="wp-block-list">
<li><strong>Janelação do sinal no tempo</strong><br>Pegamos um bloco de amostras \( x[n] \) (por exemplo, 256, 512 ou 1024 amostras) e aplicamos uma janela \( w[n] \) (Hann, Hamming, etc.) para reduzir descontinuidades.</li>



<li><strong>Transformada de Fourier (FFT)</strong><br>Calculamos o espectro complexo:<br>\[<br>X[k] = \text{FFT}{ x[n] \cdot w[n] }<br>\]<br>Obtemos magnitude (|X[k]|) e fase \(\angle X[k]\).</li>



<li><strong>Logaritmo da magnitude</strong><br>Calculamos o logaritmo \(natural ou base 10\) da magnitude:<br>\[<br>Y[k] = \log(|X[k]|)<br>\]<br>Isso transforma produtos (decorrentes da convolução no tempo) em somas no domínio espectral.</li>



<li><strong>Transformada de Fourier inversa (IFFT)</strong><br>Fazemos a IFFT de ( Y[k] ):<br>\[<br>c[n] = \text{IFFT}{ Y[k] }<br>\]<br>O sinal \( c[n] \) é o <strong>cepstro</strong> do quadro de áudio, e o índice ( n ) agora é interpretado como <strong>quefrequência</strong>.</li>



<li><strong>Análise dos coeficientes cepstrais</strong>
<ul class="wp-block-list">
<li>Coeficientes próximos de ( n = 0 ) (baixa quefrequência) descrevem a envoltória lenta do espectro.</li>



<li>Coeficientes em quefrequências maiores podem indicar periodicidade (pitch) e detalhes finos.</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph">Na prática, em um ESP32-P4, esse fluxo pode ser implementado em tempo quase real, usando:</p>



<ul class="wp-block-list">
<li>DMA + I2S para adquirir áudio.</li>



<li>FFT otimizada em ponto fixo ou flutuante (conforme os recursos).</li>



<li>Um pipeline de janelas de áudio para extrair cepstro quadro a quadro (por exemplo, a cada 10–20 ms).</li>
</ul>



<p class="wp-block-paragraph">Nas próximas seções, vamos:</p>



<ol class="wp-block-list">
<li>Escrever as <strong>fórmulas matemáticas</strong> formais da análise cepstral (domínio contínuo e discreto, convolução, FFT, log-espectro, IFFT, quefrequência).</li>



<li>Discutir a <strong>interpretação física e prática</strong> do cepstro e da quefrequência, com exemplos típicos em áudio.</li>



<li>Apresentar <strong>códigos em C para ESP32-P4</strong>, com:
<ul class="wp-block-list">
<li>Aquisição de áudio (mock ou usando I2S).</li>



<li>Cálculo da FFT, log-espectro e IFFT para obter o cepstro.</li>



<li>Extração de coeficientes de baixa quefrequência para uso em algoritmos de decisão (por exemplo, detecção de voz, pitch simplificado, ou caracterização de timbre).</li>
</ul>
</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2 – Fundamentos Matemáticos da Análise Cepstral e da Quefrequência</h3>



<p class="wp-block-paragraph">A análise cepstral nasce da necessidade de separar efeitos de <strong>convolução</strong> entre um sinal de excitação e a resposta de um sistema. Em áudio, isso aparece no modelo clássico <strong>fonte–filtro</strong>, mas o conceito é geral: sempre que um sinal ( x(t) ) resulta da convolução entre dois sinais ( s(t) ) e ( h(t) ), o cepstro ajuda a separar essas contribuições.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2.1 O ponto de partida: convolução no tempo → multiplicação na frequência</h2>



<p class="wp-block-paragraph">Seja um sinal:</p>



<p class="wp-block-paragraph">\[<br>x(t) = s(t) * h(t)<br>\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\( s(t) \): excitação (por exemplo, vibrato das cordas vocais).</li>



<li>\( h(t) \): filtro (por exemplo, trato vocal ou resposta de uma sala).</li>
</ul>



<p class="wp-block-paragraph">Pela transformada de Fourier:</p>



<p class="wp-block-paragraph">\[<br>X(\omega) = S(\omega) \cdot H(\omega)<br>\]



<p class="wp-block-paragraph">A multiplicação complica a interpretação do espectro quando queremos isolar \( S(\omega) \) e \( H(\omega) \).<br>A solução clássica é aplicar logaritmo:</p>



<p class="wp-block-paragraph">\[<br>\log |X(\omega)| = \log |S(\omega)| + \log |H(\omega)|<br>\]



<p class="wp-block-paragraph">Isto é fundamental: o log converte produtos em somas, tornando possível uma &#8220;separação&#8221; térmica entre efeitos rápidos e lentos no domínio espectral.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2.2 Cepstro como IFFT do log-espectro</h2>



<p class="wp-block-paragraph">A definição formal do <strong>cepstro real</strong> é:</p>



<p class="wp-block-paragraph">\[<br>c(t) = \mathcal{F}^{-1}\left{ \log |X(\omega)| \right}<br>\]



<p class="wp-block-paragraph">O sinal \( c(t) \) não está mais no domínio do tempo original. O eixo ( t ) passa a ser interpretado como <strong>quefrequência</strong>, e sua unidade não é frequência, mas sim algo dimensionalmente equivalente ao tempo — porém não o tempo físico.</p>



<p class="wp-block-paragraph">Por isso, usa-se notação humorística criada pelo grupo de Bogert (inventores do cepstro):</p>



<ul class="wp-block-list">
<li>tempo → <strong>quetime</strong></li>



<li>frequência → <strong>quefrequência</strong></li>



<li>espectro → <strong>espectro</strong></li>



<li>cepstro → <strong>cepstrum</strong></li>



<li>convolução → <strong>convolução</strong></li>



<li>filtro → <strong>lifter</strong> (filtro no domínio do cepstro)</li>
</ul>



<p class="wp-block-paragraph">No domínio discreto, para uma janela ( x[n] ), temos:</p>



<p class="wp-block-paragraph">\[<br>X[k] = \text{FFT}{x[n]}<br>\]



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">\[<br>C[n] = \text{IFFT}\left{\log(|X[k]|)\right}<br>\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\( k = 0, 1, &#8230;, N-1 \) é o índice de frequência,</li>



<li>\( n = 0, 1, &#8230;, N-1 \) é o índice de quefrequência.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2.3 Separação entre excitação e envoltória espectral</h2>



<p class="wp-block-paragraph">A interpretação prática decorre da análise de periodicidades:</p>



<ul class="wp-block-list">
<li>A excitação ( s(t) ), quando periódica (como voz sonora), gera um espectro composto por harmônicos espaçados.<br>Esses harmônicos introduzem padrões <strong>rápidos</strong> no espectro → aparecem em <strong>quefrequências altas</strong>.</li>



<li>O filtro ( h(t) ) representa a forma da garganta, microfone, sala, etc., produzindo variações <strong>lentas</strong> na magnitude espectral (formantes, equalização).<br>Essas variações lentas → aparecem em <strong>quefrequências baixas</strong>.</li>
</ul>



<p class="wp-block-paragraph">Portanto:</p>



<p class="wp-block-paragraph">\[<br>C[n] = C_s[n] + C_h[n]<br>\]



<p class="wp-block-paragraph">e como:</p>



<ul class="wp-block-list">
<li>\( C_h[n] \) está concentrado em pequenos valores de ( n ),</li>



<li>\( C_s[n] \) está concentrado em valores mais altos,</li>
</ul>



<p class="wp-block-paragraph">fica simples isolá-los truncando ou filtrando o cepstro.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2.4 Pitch a partir da quefrequência</h2>



<p class="wp-block-paragraph">Se o sinal contém um período dominante \( T_0 \), sua frequência fundamental é:</p>



<p class="wp-block-paragraph">\[<br>f_0 = \frac{1}{T_0}<br>\]



<p class="wp-block-paragraph">No domínio cepstral, surge um pico aproximadamente em:</p>



<p class="wp-block-paragraph">\[<br>n_0 \approx \frac{T_0}{\Delta t}<br>\]



<p class="wp-block-paragraph">onde \( \Delta t = \frac{1}{f_s} \) é o período de amostragem.</p>



<p class="wp-block-paragraph">Por exemplo, em voz humana, com pitch entre 80 e 300 Hz:</p>



<ul class="wp-block-list">
<li>\( T_0 \approx 3,3 \text{ ms a } 12,5 \text{ ms} \)</li>



<li>Em um sistema com 16 kHz de amostragem: \[<br>n_0 \approx [53\text{ a }200] \text{ amostras}<br>\]</li>
</ul>



<p class="wp-block-paragraph">Assim, basta procurar o máximo do cepstro em uma faixa adequada.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2.5 Cepstro em sistemas embarcados: por que é eficiente?</h2>



<p class="wp-block-paragraph">A análise cepstral é muito eficiente computacionalmente porque:</p>



<ul class="wp-block-list">
<li>Reutiliza FFT/IFFT já comuns em DSP.</li>



<li>Usa apenas operações elementares (log, magnitude, FFT inversa).</li>



<li>Pode ser reduzida a poucos coeficientes (por exemplo, primeiros 12 CEPSTRAIS).</li>
</ul>



<p class="wp-block-paragraph">Isso torna o método adequado para o <strong>ESP32-P4</strong>, que conta com:</p>



<ul class="wp-block-list">
<li>Núcleos de processamento de 32 bits com boa capacidade de DSP.</li>



<li>Instruções aceleradas para MACs e operações vetoriais.</li>



<li>Suporte a bibliotecas otimizadas, como <strong>ESP-DSP</strong>.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3 – Interpretação Prática da Quefrequência em Áudio</h3>



<p class="wp-block-paragraph">A análise cepstral não é apenas uma manobra matemática elegante; ela é extremamente prática quando lidamos com sinais acústicos reais. Nesta seção, vamos interpretar o que significa observar um sinal no domínio da <strong>quefrequência</strong> e como isso permite separar componentes que, no domínio da frequência tradicional, aparecem misturados.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3.1 Separação Fonte–Filtro: o coração da análise cepstral</h2>



<p class="wp-block-paragraph">Em áudio — especialmente em voz e instrumentos — um modelo universal é:</p>



<p class="wp-block-paragraph">\[<br>x(t) = s(t) * h(t)<br>\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\( s(t) \) é a excitação (cordas vocais, palheta, ruído, golpe mecânico),</li>



<li>\( h(t) \) é o filtro acústico (trato vocal, corpo do instrumento, caixa acústica, reverberação).</li>
</ul>



<p class="wp-block-paragraph">Esse modelo implica:</p>



<p class="wp-block-paragraph">\[<br>X(\omega) = S(\omega)\cdot H(\omega)<br>\]



<p class="wp-block-paragraph">Quando analisamos o espectro convencional, os efeitos de excitação e filtro aparecem multiplicados. O buraco que a análise cepstral preenche é justamente <strong>desmultiplicar</strong> esses efeitos — o que não é possível diretamente através da FFT, mas se torna possível usando o log-espectro + IFFT.</p>



<h3 class="wp-block-heading">O que acontece no cepstro?</h3>



<p class="wp-block-paragraph">Após o processo:</p>



<p class="wp-block-paragraph">\[<br>C[n] = \text{IFFT}{\log(|X[k]|)},<br>\]



<p class="wp-block-paragraph">a estrutura se reorganiza de forma surpreendente:</p>



<ul class="wp-block-list">
<li>Variações <strong>lentas</strong> do espectro (formantes, equalização, formato do corpo do instrumento) aparecem <strong>próximas de n = 0</strong>.</li>



<li>Variações <strong>rápidas</strong>, como harmônicos resultantes de excitações periódicas, aparecem em <strong>quefrequências maiores</strong>.</li>
</ul>



<p class="wp-block-paragraph">É como se a análise cepstral “esticava” o espectro em um domínio onde cada tipo de efeito possui uma assinatura clara e separável.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3.2 Estimativa de Pitch (Fundamental) no Cepstro</h2>



<p class="wp-block-paragraph">Uma das aplicações mais conhecidas do cepstro é a detecção de pitch.</p>



<p class="wp-block-paragraph">Considere um sinal periódico com período fundamental \( T_0 \). Um espectro composto por harmônicos cria uma estrutura repetitiva. O log-espectro evidencia essas repetições e a IFFT devolve um pico em:</p>



<p class="wp-block-paragraph">\[<br>n_0 \approx \frac{T_0}{\Delta t},<br>\quad \Delta t = \frac{1}{f_s}.<br>\]



<p class="wp-block-paragraph">Interpretando:</p>



<ul class="wp-block-list">
<li>O pico ocorre aproximadamente na quefrequência que representa o período do sinal.</li>



<li>Assim, basta localizar o máximo em uma janela adequada para extrair pitch.</li>
</ul>



<h3 class="wp-block-heading">Exemplo prático:</h3>



<p class="wp-block-paragraph">Para amostragem a 16 kHz e pitch de 200 Hz:</p>



<p class="wp-block-paragraph">\[<br>T_0 = 5 \text{ ms} \quad \Rightarrow \quad n_0 \approx 80.<br>\]



<p class="wp-block-paragraph">Logo, buscar picos entre 50 e 250 amostras é suficiente para detectar a maior parte da voz humana.</p>



<p class="wp-block-paragraph">Essa abordagem funciona bem mesmo quando:</p>



<ul class="wp-block-list">
<li>O espectro está suavizado,</li>



<li>Há ruído moderado,</li>



<li>O sinal sofreu filtragens/acústicas conhecidas ou não lineares.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3.3 Detecção de Envoltória Espectral (Timbre)</h2>



<p class="wp-block-paragraph">Os primeiros coeficientes do cepstro representam a <strong>envelopa espectral</strong>, que define o timbre de instrumentos e da voz.</p>



<p class="wp-block-paragraph">Em reconhecimento de fala, isso inspira técnicas clássicas como:</p>



<ul class="wp-block-list">
<li>LPC (Linear Predictive Coding),</li>



<li>MFCC (Mel-Frequency Cepstral Coefficients).</li>
</ul>



<p class="wp-block-paragraph">A ideia é simples:</p>



<ul class="wp-block-list">
<li>Os coeficientes de baixa quefrequência capturam a forma geral do espectro.</li>



<li>Pequenos conjuntos (12 a 20 coeficientes) representam bem o timbre.</li>
</ul>



<p class="wp-block-paragraph">Isso se torna extremamente útil em sistemas embarcados para:</p>



<ul class="wp-block-list">
<li>Classificação de sons (porta batendo, voz, motor, música).</li>



<li>Detecção de eventos acústicos (EDA).</li>



<li>Reconhecimento de comandos por voz com baixa complexidade.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3.4 Detecção de Eco e Reverberação</h2>



<p class="wp-block-paragraph">Uma propriedade menos conhecida — mas muito poderosa — é a capacidade de observar <strong>ecos</strong> no domínio cepstral.</p>



<p class="wp-block-paragraph">Quando um eco ocorre com atraso \( \tau \), a convolução com uma versão atrasada do sinal adiciona um componente periódico no espectro. No cepstro, isso aparece como um pico em:</p>



<p class="wp-block-paragraph">\[<br>n_\tau \approx \frac{\tau}{\Delta t}.<br>\]



<p class="wp-block-paragraph">Exemplo:</p>



<ul class="wp-block-list">
<li>Um eco com 10 ms de atraso → pico na quefrequência correspondente a 10 ms.</li>



<li>Uma reverberação mais longa produz uma faixa de quefrequências com energia distribuída.</li>
</ul>



<p class="wp-block-paragraph">Isso é útil para:</p>



<ul class="wp-block-list">
<li>Cancelamento de eco,</li>



<li>Algoritmos de de-reverberação,</li>



<li>Diagnóstico acústico (testes de salas, tubulações, painéis mecânicos).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3.5 Resumo interpretativo da quefrequência</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Região da Quefrequência</th><th>Significado</th><th>Fenômenos representados</th></tr></thead><tbody><tr><td>Muito baixa (n ≈ 0–10)</td><td>Envoltória espectral lenta</td><td>Formantes da voz, resposta de caixa, equalização</td></tr><tr><td>Baixa (n ≈ 10–40)</td><td>Estruturas amplas do filtro</td><td>Timbre geral do instrumento</td></tr><tr><td>Média (n ≈ 50–250)</td><td>Períodos da excitação</td><td>Pitch, harmônicos</td></tr><tr><td>Alta (n &gt; 250)</td><td>Detalhes rápidos e ruído</td><td>Textura sonora, fricativas, aspereza</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Este mapeamento orienta como “ler” um cepstro e como projetar algoritmos que exploram o método.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4 – Implementação Prática da Análise Cepstral no ESP32-P4</h3>



<p class="wp-block-paragraph">Nesta seção entramos no nível operacional: como implementar, no ESP32-P4, o pipeline completo da análise cepstral — desde a captura de áudio até a obtenção do vetor de coeficientes no domínio da <strong>quefrequência</strong>.</p>



<p class="wp-block-paragraph">O ESP32-P4 possui um núcleo de desempenho superior às gerações anteriores, com instruções otimizadas para DSP, permitindo executar FFT/IFFT e operações vetoriais com boa eficiência mesmo em janelas de 512 ou 1024 amostras. A biblioteca <strong>ESP-DSP</strong> facilita bastante esse processo, pois contém FFTs altamente otimizadas.</p>



<p class="wp-block-paragraph">A seguir, apresento o pipeline completo e exemplos de código baseados no ESP-IDF + ESP-DSP.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.1 Pipeline de processamento do cepstro</h2>



<p class="wp-block-paragraph">O processo no microcontrolador segue:</p>



<ol class="wp-block-list">
<li>Capturar um quadro de áudio via I2S (1024 amostras, por exemplo).</li>



<li>Aplicar janela Hann ou Hamming.</li>



<li>Fazer FFT real → espectro complexo.</li>



<li>Obter magnitude.</li>



<li>Aplicar logaritmo.</li>



<li>Fazer IFFT para obter o cepstro.</li>



<li>Analisar quefrequências de interesse.</li>
</ol>



<p class="wp-block-paragraph">Representando matematicamente para ( N ) amostras:</p>



<p class="wp-block-paragraph">\[<br>X[k] = \text{FFT}{ x[n] \cdot w[n] }<br>\]



<p class="wp-block-paragraph">\[<br>Y[k] = \log(|X[k]| + \epsilon)<br>\]



<p class="wp-block-paragraph">\[<br>C[n] = \text{IFFT}{ Y[k] }<br>\]



<p class="wp-block-paragraph">O termo \( \epsilon \) evita log(0), tipicamente \( \epsilon = 10^{-12} \).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.2 Estrutura básica do código no ESP32-P4</h2>



<p class="wp-block-paragraph">A seguir um esqueleto funcional em C, com comentários detalhados e adequado ao ESP-IDF.</p>



<p class="wp-block-paragraph">Inclui:</p>



<ul class="wp-block-list">
<li>Janela Hann</li>



<li>FFT real</li>



<li>Cálculo de magnitude + log</li>



<li>IFFT</li>



<li>Extração de pitch via busca de máximo na faixa de quefrequência</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="894" height="613" src="https://mcu.tec.br/wp-content/uploads/2025/12/image-5.png" alt="" class="wp-image-950" srcset="https://mcu.tec.br/wp-content/uploads/2025/12/image-5.png 894w, https://mcu.tec.br/wp-content/uploads/2025/12/image-5-300x206.png 300w, https://mcu.tec.br/wp-content/uploads/2025/12/image-5-768x527.png 768w" sizes="(max-width: 894px) 100vw, 894px" /></figure>
</div>


<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Código: Inicialização do módulo DSP</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>/**
 * @brief Inicializa a biblioteca ESP-DSP para FFTs
 */
static void init_dsp()
{
    // Inicializa tabelas de FFT internas.
    dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Inicializa a biblioteca ESP-DSP para FFTs</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">init_dsp</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Inicializa tabelas de FFT internas.</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">dsps_fft2r_init_fc32</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CONFIG_DSP_MAX_FFT_SIZE</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.3 Aplicação da janela Hann</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>/**
 * @brief Aplica janela Hann ao buffer de entrada
 */
static void apply_hann(float *data, int N)
{
    for (int n = 0; n &lt; N; n++) {
        float w = 0.5f * (1 - cosf((2 * M_PI * n) / (N - 1)));
        data&#91;n&#93; *= w;
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Aplica janela Hann ao buffer de entrada</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">apply_hann</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">w</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">5</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">cosf</span><span style="color: #D8DEE9FF">((</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">*=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">w</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.4 FFT + cálculo da magnitude + log</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void compute_log_spectrum(const float *input, float *log_spec, int N)
{
    // Buffer complexo para FFT (intercalado real/imag)
    static float fft_buf&#91;2048&#93;;

    // Copia entrada para buffer da FFT
    for (int i = 0; i &lt; N; i++) {
        fft_buf&#91;2*i&#93;   = input&#91;i&#93;; // parte real
        fft_buf&#91;2*i+1&#93; = 0.0f;     // parte imaginária
    }

    // FFT real
    dsps_fft2r_fc32(fft_buf, N);
    dsps_bit_rev_fc32(fft_buf, N);

    // Calcula magnitude e log
    for (int k = 0; k &lt; N; k++) {
        float real = fft_buf&#91;2*k&#93;;
        float imag = fft_buf&#91;2*k+1&#93;;
        float mag  = sqrtf(real*real + imag*imag);
        log_spec&#91;k&#93; = logf(mag + 1e-12f);
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">compute_log_spectrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">input</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">log_spec</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Buffer complexo para FFT (intercalado real/imag)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fft_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2048</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Copia entrada para buffer da FFT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">fft_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;   </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">input</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// parte real</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">fft_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">+</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #616E88">// parte imaginária</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// FFT real</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">dsps_fft2r_fc32</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">fft_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">dsps_bit_rev_fc32</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">fft_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Calcula magnitude e log</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">real</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fft_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fft_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">k</span><span style="color: #81A1C1">+</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sqrtf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">real</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">real</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imag</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">imag</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">log_spec</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">logf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">e</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">12</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.5 IFFT para obter o Cepstro</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void compute_cepstrum(const float *log_spec, float *cep, int N)
{
    static float buf&#91;2048&#93;;

    // Copia log-espectro para o buffer complexo
    for (int k = 0; k &lt; N; k++) {
        buf&#91;2*k&#93;   = log_spec&#91;k&#93;;
        buf&#91;2*k+1&#93; = 0.0f;
    }

    // IFFT
    dsps_fft2r_fc32(buf, N);
    dsps_bit_rev_fc32(buf, N);

    // Saída real do cepstro
    for (int n = 0; n &lt; N; n++) {
        cep&#91;n&#93; = buf&#91;2*n&#93; / N; // normalização
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">compute_cepstrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">log_spec</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2048</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Copia log-espectro para o buffer complexo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">&#93;   </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">log_spec</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">k</span><span style="color: #81A1C1">+</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// IFFT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">dsps_fft2r_fc32</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">dsps_bit_rev_fc32</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Saída real do cepstro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// normalização</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.6 Extração de pitch a partir da quefrequência</h2>



<p class="wp-block-paragraph">O pitch aparece como o pico dominante em uma faixa de quefrequências que representa períodos possíveis da excitação.</p>



<p class="wp-block-paragraph">Por exemplo, para voz humana em 16 kHz:</p>



<ul class="wp-block-list">
<li>pitch de 80–300 Hz → períodos entre 3,3 ms e 12,5 ms → 53–200 amostras.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>/**
 * @brief Estima pitch a partir do cepstro
 *
 * @param cep      Vetor de cepstro
 * @param fs       Taxa de amostragem
 * @param N        Tamanho do cepstro
 *
 * @return Frequência fundamental estimada
 */
float estimate_pitch_from_cepstrum(const float *cep, int fs, int N)
{
    int min_q = fs / 300; // ~53
    int max_q = fs / 80;  // ~200

    int max_index = min_q;
    float max_val = cep&#91;min_q&#93;;

    for (int n = min_q; n &lt; max_q; n++) {
        if (cep&#91;n&#93; > max_val) {
            max_val   = cep&#91;n&#93;;
            max_index = n;
        }
    }

    // período estimado
    float T0 = (float)max_index / fs;

    return 1.0f / T0;
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Estima pitch a partir do cepstro</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">cep</span><span style="color: #616E88">      Vetor de cepstro</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">fs</span><span style="color: #616E88">       Taxa de amostragem</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">N</span><span style="color: #616E88">        Tamanho do cepstro</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">return</span><span style="color: #616E88"> Frequência fundamental estimada</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">estimate_pitch_from_cepstrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">min_q</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">300</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// ~53</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max_q</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">80</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// ~200</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max_index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">min_q</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max_val</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">min_q</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">min_q</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max_q</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max_val</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">max_val</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">max_index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// período estimado</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">T0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">max_index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">T0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.7 Extração dos primeiros coeficientes cepstrais (para classificação)</h2>



<p class="wp-block-paragraph">Em muita aplicações (classificação acústica, detecção de eventos), apenas os primeiros coeficientes cepstrais são necessários.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>/**
 * @brief Copia os primeiros M coeficientes do cepstro
 */
void extract_cepstral_coeffs(const float *cep, float *out, int M)
{
    for (int i = 0; i &lt; M; i++) {
        out&#91;i&#93; = cep&#91;i&#93;;
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Copia os primeiros M coeficientes do cepstro</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">extract_cepstral_coeffs</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">out</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">out</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.8 Pipeline completo (função principal)</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void process_audio_frame(float *frame, int N, int fs)
{
    static float log_spec&#91;1024&#93;;
    static float cep&#91;1024&#93;;

    apply_hann(frame, N);
    compute_log_spectrum(frame, log_spec, N);
    compute_cepstrum(log_spec, cep, N);

    float pitch = estimate_pitch_from_cepstrum(cep, fs, N);

    printf("Pitch estimado: %.2f Hz\n", pitch);
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">process_audio_frame</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">frame</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">log_spec</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1024</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cep</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1024</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">apply_hann</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">frame</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">compute_log_spectrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">frame</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">log_spec</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">compute_cepstrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">log_spec</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pitch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">estimate_pitch_from_cepstrum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fs</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Pitch estimado: %.2f Hz</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pitch</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4.9 Observações de implementação no ESP32-P4</h2>



<ol class="wp-block-list">
<li><strong>Memória</strong><br>FFT de 1024 pontos requer buffers complexos de 2048 floats → 8 KB.<br>O ESP32-P4 suporta isso confortavelmente.</li>



<li><strong>Desempenho</strong><br>Com clock adequado, é possível analisar um quadro de 1024 amostras em menos de 5 ms.</li>



<li><strong>Precisão</strong><br>Sugere-se usar <code>float</code> (32 bits). Em sistemas críticos, é possível migrar para ponto fixo.</li>



<li><strong>Aquisição de áudio real</strong><br>Basta integrar esta pipeline à captura I2S + DMA, substituindo o <code>frame[]</code> preenchido por dados do ADC/I2S.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5 – Conclusão e Aplicações Práticas em Sistemas Embarcados</h3>



<p class="wp-block-paragraph">A análise cepstral — e, em particular, a interpretação do sinal no domínio da <strong>quefrequência</strong> — é uma das ferramentas mais poderosas e versáteis no processamento moderno de áudio. Seu ponto forte é justamente possibilitar a separação matemática e prática entre efeitos que, no domínio da frequência convencional, aparecem misturados de forma inseparável.</p>



<p class="wp-block-paragraph">Ao longo deste artigo, vimos que:</p>



<ul class="wp-block-list">
<li>O cepstro transforma convoluções em somas através da operação log-espectral + IFFT.</li>



<li>Esse processo reorganiza o conteúdo espectral, permitindo distinguir <strong>excitação</strong>, <strong>resposta acústica</strong>, <strong>pitch</strong>, <strong>ecos</strong> e <strong>timbre</strong>.</li>



<li>A quefrequência interpreta periodicidades espectrais (não temporais), revelando padrões profundos do sinal.</li>



<li>Em voz, permite separar fonte–filtro e detectar frequência fundamental mesmo sob ruído ou filtragem.</li>



<li>Em instrumentação, auxilia na detecção de defeitos, ecos estruturais, vibrações periódicas e assinaturas mecânicas.</li>



<li>Em classificação de eventos acústicos, os primeiros coeficientes cepstrais são extremamente eficientes — compactos, robustos e amigáveis para algoritmos embarcados.</li>
</ul>



<p class="wp-block-paragraph">Do ponto de vista de implementação embarcada:</p>



<ul class="wp-block-list">
<li>A análise cepstral é inteiramente viável no <strong>ESP32-P4</strong>, graças às instruções DSP nativas e ao suporte da biblioteca <strong>ESP-DSP</strong>.</li>



<li>Um pipeline típico com janelas de 1024 amostras pode ser processado em tempo real com folga, mesmo associado a I2S + DMA.</li>



<li>O código apresentado pode servir como base para:
<ul class="wp-block-list">
<li>Detecção de voz (VAD);</li>



<li>Estimativa de pitch;</li>



<li>Extração de coeficientes cepstrais para classificadores;</li>



<li>Estudo de reverberações e ecos;</li>



<li>Detecção de falhas mecânicas via áudio/vibração.</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">A análise cepstral é especialmente adequada para sistemas embarcados modernos que precisam extrair significado de sinais sonoros complexos, mantendo consumo moderado de memória e CPU. Ela combina rigor matemático, elegância teórica e elevada eficiência prática — por isso permanece um dos pilares do processamento de áudio desde os anos 1960 até hoje.</p><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/quefrequencia-e-analise-cepstral-uma-introducao-pratica-para-sistemas-embarcados-esp32-p4/">Quefrequência e Análise Cepstral: Uma Introdução Prática para Sistemas Embarcados (ESP32-P4)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">947</post-id>	</item>
	</channel>
</rss>
