<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Audio Processing on kenji.blog</title><link>http://kenji.blog/pt/categories/audio-processing/</link><description>Recent content in Audio Processing on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 04:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/categories/audio-processing/index.xml" rel="self" type="application/rss+xml"/><item><title>Como Integrar a IA de Reconhecimento de Voz (Whisper) em Projetos C++</title><link>http://kenji.blog/pt/p/whisper-cpp-integration-guide/</link><pubDate>Fri, 11 Sep 2026 04:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/whisper-cpp-integration-guide/</guid><description>&lt;img src="http://kenji.blog/p/whisper-cpp-integration-guide/img/eyecatch.jpg" alt="Featured image of post Como Integrar a IA de Reconhecimento de Voz (Whisper) em Projetos C++" />&lt;h2 id="1-introdução-por-que-reconhecimento-de-voz-em-c">1. Introdução: Por que reconhecimento de voz em C++?
&lt;/h2>&lt;p>A &amp;ldquo;Whisper&amp;rdquo;, um modelo de reconhecimento de voz de alta precisão desenvolvido pela OpenAI, tem sido utilizada em várias aplicações desde que foi disponibilizada em código aberto. Embora o uso em ambientes Python (baseado em PyTorch) seja comum, quando se trata de integrá-la em &lt;strong>dispositivos edge (smartphones, equipamentos IoT, sistemas embarcados)&lt;/strong> ou em &lt;strong>aplicações C++ nativas que exigem alto desempenho em tempo real&lt;/strong> (motores de jogos, softwares DAW, robótica, etc.), a dependência do interpretador Python torna-se um grande gargalo de desempenho.&lt;/p>
&lt;p>É aí que entra o &lt;strong>&lt;a class="link" href="https://github.com/ggerganov/whisper.cpp" target="_blank" rel="noopener"
>whisper.cpp&lt;/a>&lt;/strong>, desenvolvido por Georgi Gerganov, como o salvador. Esta biblioteca é baseada na &lt;code>ggml&lt;/code>, uma biblioteca de cálculos tensoriais para aprendizado de máquina, e reduz ao máximo as dependências, realizando a inferência do Whisper apenas com C/C++.&lt;/p>
&lt;p>Neste artigo, explicaremos detalhadamente como usar este &lt;code>whisper.cpp&lt;/code> para integrar recursos de reconhecimento de voz de ponta em seu próprio projeto C++, cobrindo desde os fundamentos do processamento de sinais de áudio, como usar a API em detalhes, gerenciamento de memória, otimização de multithreading, até os padrões de implementação para processamento em tempo real.&lt;/p>
&lt;hr>
&lt;h2 id="2-processamento-de-sinais-de-áudio-e-requisitos-de-entrada-do-whisper">2. Processamento de Sinais de Áudio e Requisitos de Entrada do Whisper
&lt;/h2>&lt;p>Para que a IA compreenda a voz, é necessário converter o &amp;ldquo;som&amp;rdquo;, que é um sinal analógico, em dados digitais e formatá-lo de forma que o modelo de IA possa processar (tensores). O formato de áudio exigido pelo Whisper é muito rigoroso.&lt;/p>
&lt;h3 id="21-formato-de-áudio-exigido-pelo-whisper">2.1 Formato de Áudio Exigido pelo Whisper
&lt;/h3>&lt;p>O modelo Whisper aceita dados de áudio com as seguintes especificações como entrada:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Taxa de Amostragem (Sample Rate)&lt;/strong>: 16.000 Hz (16 kHz)&lt;/li>
&lt;li>&lt;strong>Número de Canais (Channels)&lt;/strong>: 1 (Mono)&lt;/li>
&lt;li>&lt;strong>Tipo de Dados (Data Type)&lt;/strong>: Ponto flutuante de 32 bits (&lt;code>float&lt;/code> em C/C++)&lt;/li>
&lt;li>&lt;strong>Normalização (Normalization)&lt;/strong>: Valores escalonados na faixa de $[-1.0, 1.0]$&lt;/li>
&lt;/ul>
&lt;p>Por exemplo, se a entrada for um arquivo de áudio com qualidade de CD (44,1 kHz, estéreo, PCM de 16 bits), será necessário realizar previamente a subamostragem (downsampling), a mixagem dos canais (mixdown) e a conversão de formato.&lt;/p>
&lt;p>A fórmula para calcular a taxa de transferência de dados é a seguinte:&lt;/p>
$$ \text{Data Rate (bytes/sec)} = \text{Sample Rate} \times \text{Channels} \times \frac{\text{Bit Depth}}{8} $$
&lt;p>Para os requisitos do Whisper (16 kHz, 1 ch, Float de 32 bits), o tamanho dos dados para 1 segundo é:&lt;/p>
$$ 16000 \times 1 \times \frac{32}{8} = 64,000 \text{ bytes/sec (64 KB/s)} $$
&lt;p>Por ser extremamente leve, mesmo dispositivos edge com largura de banda de memória limitada têm capacidade suficiente para realizar o buffering.&lt;/p>
&lt;h3 id="22-matemática-da-transformação-em-espectrograma-mel">2.2 Matemática da Transformação em Espectrograma Mel
&lt;/h3>&lt;p>Internamente, o Whisper não processa diretamente os dados de forma de onda de áudio unidimensionais (Raw Waveform). Antes de ser introduzido no modelo Transformer, o áudio é convertido em um &lt;strong>Espectrograma Mel (Mel-Spectrogram)&lt;/strong>, que é uma representação de frequência próxima às características da audição humana. O &lt;code>whisper.cpp&lt;/code> inclui este processo de conversão em sua implementação C++, mas entender como ele funciona é útil para lidar com ruídos e otimizar o pré-processamento.&lt;/p>
&lt;p>A fórmula para converter a frequência normal $f$ (Hz) na escala Mel $m$ é aproximada da seguinte forma:&lt;/p>
$$ m = 2595 \log_{10} \left( 1 + \frac{f}{700} \right) $$
&lt;p>Inversamente, a transformação da escala Mel para a frequência é dada por:&lt;/p>
$$ f = 700 \left( 10^{\frac{m}{2595}} - 1 \right) $$
&lt;p>Além disso, a forma de onda de áudio é convertida para o domínio tempo-frequência por meio da &lt;strong>Transformada de Fourier de Tempo Curto (STFT: Short-Time Fourier Transform)&lt;/strong>. A forma discreta da STFT usando uma função de janela $w(n)$ é expressa como:&lt;/p>
$$ X(m, k) = \sum_{n=0}^{N-1} x(n + mH) w(n) e^{-j \frac{2\pi}{N} k n} $$
&lt;p>
&lt;em>(Onde $N$ é o tamanho da janela FFT, $H$ é o tamanho do salto (hop size), e $w(n)$ é uma função de janela como a janela de Hann)&lt;/em>&lt;/p>
&lt;p>No modelo Whisper, geralmente são usados um tamanho de janela $N = 400$ (25ms), um tamanho de salto $H = 160$ (10ms) e um banco de filtros Mel de 80 dimensões. Esta extração de características é executada automaticamente (e de forma rápida usando instruções SIMD) ao chamar a função &lt;code>whisper_full()&lt;/code> no &lt;code>whisper.cpp&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="3-arquitetura-e-design-do-pipeline">3. Arquitetura e Design do Pipeline
&lt;/h2>&lt;p>Vamos projetar o pipeline de processamento de áudio em uma aplicação C++. O fluxo começa com a entrada a partir de um arquivo ou microfone, passa pelo pré-processamento, pela inferência usando o &lt;code>whisper.cpp&lt;/code> e culmina na saída de texto.&lt;/p>
&lt;div class="mermaid">graph TD
A["Fonte de Áudio (Microfone/Arquivo)"] -->|Bytes Brutos, ex: 48kHz Estéreo| B["Decodificador de Áudio e Reamostrador (FFmpeg/miniaudio)"]
B -->|16kHz Mono 32-bit Float| C["Buffer Circular / Matriz de Memória"]
C -->|Alimentar Dados PCM| D["Núcleo whisper.cpp (ggml)"]
D --> E["Extração do Espectrograma Mel"]
E --> F["Codificador-Decodificador Transformer"]
F --> G["Geração de Tokens de Texto"]
G --> H["Saída de Texto (String UTF-8)"]&lt;/div>
&lt;p>A responsabilidade do lado da aplicação é a seção &lt;strong>de A a C (decodificação e reamostragem do áudio)&lt;/strong> na figura acima. Como o próprio &lt;code>whisper.cpp&lt;/code> não inclui um decodificador de arquivos de áudio, a melhor prática é combiná-lo com bibliotecas como FFmpeg ou &lt;code>miniaudio&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="4-compilação-e-introdução-do-whispercpp">4. Compilação e Introdução do whisper.cpp
&lt;/h2>&lt;p>Estes são os passos para integrar o &lt;code>whisper.cpp&lt;/code> no seu projeto. O uso do CMake é o mais versátil.&lt;/p>
&lt;h3 id="configuração-do-cmakeliststxt">Configuração do CMakeLists.txt
&lt;/h3>&lt;p>O &lt;code>whisper.cpp&lt;/code> pode ser incorporado ao projeto como código-fonte ou adicionado como um submódulo para ser vinculado.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.14&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">WhisperApp&lt;/span> &lt;span class="s">C&lt;/span> &lt;span class="s">CXX&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD_REQUIRED&lt;/span> &lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Habilita instruções de extensão da CPU (AVX, F16C, etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># No MacOS, a estrutura NEON/Accelerate é habilitada automaticamente
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">WHISPER_SUPPORT_SDL2&lt;/span> &lt;span class="s">OFF&lt;/span> &lt;span class="s">CACHE&lt;/span> &lt;span class="s">BOOL&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span> &lt;span class="s">FORCE&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">whisper.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">whisper_app&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">whisper_app&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">whisper&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com esta configuração, o backend &lt;code>ggml&lt;/code> altamente otimizado do &lt;code>whisper.cpp&lt;/code> será compilado e vinculado estaticamente à aplicação.&lt;/p>
&lt;hr>
&lt;h2 id="5-detalhes-da-api-c-e-passos-de-implementação">5. Detalhes da API C++ e Passos de Implementação
&lt;/h2>&lt;p>Agora, vamos explicar como usar a API observando o código C++ real.&lt;/p>
&lt;h3 id="51-inicialização-do-contexto-e-carregamento-do-modelo">5.1 Inicialização do Contexto e Carregamento do Modelo
&lt;/h3>&lt;p>No &lt;code>whisper.cpp&lt;/code>, todos os estados e a alocação de memória são gerenciados pela estrutura &lt;code>whisper_context&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;#34;whisper.h&amp;#34;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Inicialização dos parâmetros
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">struct&lt;/span> &lt;span class="nc">whisper_context_params&lt;/span> &lt;span class="n">cparams&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_context_default_params&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">use_gpu&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Usa aceleração via GPU (CuBLAS/Metal) se disponível
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. Carregamento do modelo (modelo binário no formato ggml)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">model_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;models/ggml-base.bin&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">struct&lt;/span> &lt;span class="nc">whisper_context&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_init_from_file_with_params&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_path&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">cparams&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Erro: Falha ao carregar o modelo - &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">model_path&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Modelo carregado com sucesso.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>O arquivo do modelo está em um formato quantizado &lt;code>.bin&lt;/code> exclusivo. Você pode usar os scripts de conversão no repositório oficial ou baixá-lo diretamente do HuggingFace. Em ambientes com fortes restrições de memória, o uso de um modelo quantizado de 4 bits (ex: &lt;code>ggml-base-q4_0.bin&lt;/code>) pode reduzir o consumo de RAM para cerca de 1/4.&lt;/p>
&lt;h3 id="52-configuração-dos-parâmetros-de-inferência">5.2 Configuração dos Parâmetros de Inferência
&lt;/h3>&lt;p>Em seguida, configure o &lt;code>whisper_full_params&lt;/code> para controlar o comportamento da inferência.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. Configuração dos parâmetros para inferência completa (Usando Greedy Sampling)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">struct&lt;/span> &lt;span class="nc">whisper_full_params&lt;/span> &lt;span class="n">wparams&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_full_default_params&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">WHISPER_SAMPLING_GREEDY&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Configuração do número de threads (O ideal é corresponder ao número de núcleos físicos da CPU)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">wparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_threads&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Configuração de idioma (&amp;#34;auto&amp;#34; para detecção automática, &amp;#34;ja&amp;#34; para japonês)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">wparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">language&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;ja&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Suprime a saída padrão dos resultados intermediários (para controlar na aplicação)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">wparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">print_progress&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">wparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">print_realtime&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Função de tradução (true se for traduzir o áudio para texto em inglês)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">wparams&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">translate&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="53-preparação-dos-dados-de-áudio-e-execução-da-inferência">5.3 Preparação dos Dados de Áudio e Execução da Inferência
&lt;/h3>&lt;p>Aqui, assumimos que os dados de áudio a 16kHz já estão armazenados em um &lt;code>std::vector&amp;lt;float&amp;gt;&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Dados de áudio virtuais (na realidade, dados PCM obtidos de um arquivo ou microfone)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 3 segundos (16000 Hz * 3 seg = 48000 amostras)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">pcmf32&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">48000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0f&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 4. Execução da inferência
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">whisper_full&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">wparams&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">pcmf32&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">pcmf32&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Erro: Falha ao executar whisper_full.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">whisper_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="54-extração-dos-resultados">5.4 Extração dos Resultados
&lt;/h3>&lt;p>Quando o &lt;code>whisper_full&lt;/code> for concluído, os resultados do reconhecimento serão salvos no contexto em segmentos.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 5. Obtenção e exibição dos resultados
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_segments&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_full_n_segments&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">n_segments&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">const&lt;/span> &lt;span class="kt">char&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">text&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_full_get_segment_text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Obtenção do timestamp (Unidade: 10ms)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="kt">int64_t&lt;/span> &lt;span class="n">t0&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_full_get_segment_t0&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">const&lt;/span> &lt;span class="kt">int64_t&lt;/span> &lt;span class="n">t1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">whisper_full_get_segment_t1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">t0&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mf">10.0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; ms -&amp;gt; &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">t1&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mf">10.0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; ms]: &amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">text&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 6. Liberação da memória
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">whisper_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Este bloco de código serve como o modelo mais básico para usar o Whisper em C++.&lt;/p>
&lt;hr>
&lt;h2 id="6-implementação-avançada-de-reconhecimento-de-voz-em-tempo-real">6. Implementação Avançada de Reconhecimento de Voz em Tempo Real
&lt;/h2>&lt;p>Processar arquivos pré-gravados é simples, mas para melhorar a experiência do usuário (UX) da aplicação, o &amp;ldquo;reconhecimento de voz em tempo real (reconhecimento contínuo/streaming)&amp;rdquo; a partir da entrada do microfone é necessário.&lt;/p>
&lt;p>Para implementar isso, o gerenciamento de fluxos de áudio usando uma arquitetura multithread e um buffer circular (Ring Buffer) é essencial.&lt;/p>
&lt;div class="mermaid">graph LR
subgraph "Thread de Áudio (Alta Prioridade)"
A["API de Captura de Áudio (CoreAudio/WASAPI/ALSA)"] -->|Callback| B["Reamostrador (para 16kHz)"]
B --> C["Buffer Circular"]
end
subgraph "Thread Principal / Trabalhadora"
C -->|Extrair bloco de 30ms-1000ms| D["Detecção de Atividade de Voz (VAD)"]
D -->|Se voz detectada| E["Acumular Buffer PCM"]
E -->|Acionar Inferência| F["whisper_full()"]
F --> G["Atualizar UI/Texto"]
end&lt;/div>
&lt;h3 id="61-a-importância-da-detecção-de-atividade-de-voz-vad">6.1 A Importância da Detecção de Atividade de Voz (VAD)
&lt;/h3>&lt;p>No processamento em tempo real, executar constantemente a inferência, mesmo para partes silenciosas, é um desperdício de recursos computacionais. Inserir um algoritmo VAD (como limiares baseados em energia simples ou WebRTC VAD) na etapa anterior permite o seguinte controle: &lt;strong>&amp;ldquo;Iniciar o buffering apenas quando a fala começar e disparar o &lt;code>whisper_full&lt;/code> no momento em que a fala terminar (após um certo período de silêncio)&amp;rdquo;.&lt;/strong>&lt;/p>
&lt;h3 id="62-abordagem-de-janela-deslizante-sliding-window">6.2 Abordagem de Janela Deslizante (Sliding Window)
&lt;/h3>&lt;p>Se a fala continuar por muito tempo, a técnica de &amp;ldquo;janela deslizante&amp;rdquo; é usada, extraindo blocos a cada poucos segundos para inferência. No entanto, se o áudio for simplesmente cortado em pedaços, palavras podem ser cortadas no meio, diminuindo significativamente a precisão do reconhecimento.&lt;/p>
&lt;p>Como solução, utilizamos um método em que &lt;strong>&amp;ldquo;a inferência é sempre realizada incluindo o contexto dos últimos N segundos&amp;rdquo;&lt;/strong> (sobreposição). O &lt;code>whisper.cpp&lt;/code> também tem o recurso &lt;code>wparams.prompt_tokens&lt;/code> que repassa tokens de texto anteriores como um prompt, permitindo um reconhecimento contínuo altamente preciso enquanto mantém o contexto.&lt;/p>
&lt;hr>
&lt;h2 id="7-gerenciamento-de-memória-e-otimização-para-dispositivos-edge">7. Gerenciamento de Memória e Otimização para Dispositivos Edge
&lt;/h2>&lt;p>Aprofundaremos as maiores vantagens do &lt;code>whisper.cpp&lt;/code>: seu desempenho e eficiência de memória.&lt;/p>
&lt;h3 id="71-o-poder-da-biblioteca-tensorial-ggml">7.1 O Poder da Biblioteca Tensorial ggml
&lt;/h3>&lt;p>O backend do &lt;code>whisper.cpp&lt;/code>, &lt;code>ggml&lt;/code>, é uma biblioteca tensorial em C sem dependências externas. Sua maior característica é que ela suporta a &lt;strong>quantização dinâmica (Quantization) dos dados de peso&lt;/strong>.&lt;/p>
&lt;p>Por exemplo, vamos calcular o tamanho da memória do modelo Whisper &lt;code>Small&lt;/code> (cerca de 240 milhões de parâmetros).
No caso normal (16-bit Float = 2 bytes):&lt;/p>
$$ \text{Memory (FP16)} \approx 244,000,000 \times 2 \text{ bytes} \approx 488 \text{ MB} $$
&lt;p>Ao convertê-lo para a quantização de 4 bits (formato Q4_0), ele ocupa em média 0,5 bytes por parâmetro (cerca de 0,56 bytes incluindo o custo de sobrecarga, como os fatores de escala).&lt;/p>
$$ \text{Memory (Q4\_0)} \approx 244,000,000 \times 0.56 \text{ bytes} \approx 137 \text{ MB} $$
&lt;p>Em ambientes com fortes restrições de RAM, como dispositivos iOS e Raspberry Pi, essa redução no uso da memória (memory footprint) se traduz diretamente na estabilidade de toda a aplicação.&lt;/p>
&lt;h3 id="72-utilização-da-aceleração-de-hardware">7.2 Utilização da Aceleração de Hardware
&lt;/h3>&lt;p>Embora a CPU sozinha seja suficientemente rápida por meio das instruções AVX2 e NEON, o &lt;code>whisper.cpp&lt;/code> também suporta aceleração de hardware a partir de várias GPUs e NPUs como backend.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Apple Silicon (Mac/iOS)&lt;/strong>: Suporte à API Metal através do &lt;code>ggml-metal&lt;/code>. Inferência ultrarrápida usando a GPU.&lt;/li>
&lt;li>&lt;strong>NVIDIA GPU (Windows/Linux)&lt;/strong>: Suporte ao &lt;code>cuBLAS&lt;/code>. Especifique &lt;code>-DWHISPER_CUBLAS=ON&lt;/code> durante a compilação no CMake.&lt;/li>
&lt;li>&lt;strong>Intel (Windows/Linux)&lt;/strong>: Suporte ao backend &lt;code>OpenVINO&lt;/code>. É possível utilizar a NPU nos mais recentes processadores Intel Core.&lt;/li>
&lt;/ul>
&lt;p>Ao usar esses aceleradores em um projeto C++, quase não há necessidade de modificar o código-fonte. Desde que &lt;code>cparams.use_gpu = true;&lt;/code> esteja configurado durante a inicialização do contexto, ele será automaticamente descarregado (offloaded) para o hardware de acordo com o backend compilado.&lt;/p>
&lt;h3 id="73-ajuste-fino-de-cache-e-número-de-threads">7.3 Ajuste Fino de Cache e Número de Threads
&lt;/h3>&lt;p>A configuração do &lt;code>wparams.n_threads&lt;/code> é extremamente importante. Aumentar o número de threads indiscriminadamente não melhora o desempenho devido ao gargalo de largura de banda da memória (Memory Bound).&lt;/p>
&lt;p>Como regra prática, é ideal determinar o número de threads com a seguinte fórmula:&lt;/p>
$$ N_{\text{threads}} = \min(\text{Núcleos Físicos da CPU}, 4 \sim 8) $$
&lt;p>A inclusão de núcleos lógicos, como os de Hyper-Threading, frequentemente causa conflitos de cache e resulta em velocidades de inferência mais baixas. Portanto, é uma regra de ouro configurá-lo para o &lt;strong>número de núcleos físicos&lt;/strong>. Ao usar &lt;code>std::thread::hardware_concurrency()&lt;/code> no C++11, ele retorna o número de núcleos lógicos. Sendo assim, recomenda-se hardcodar o valor de acordo com o ambiente ou adquirir o número de núcleos físicos através de APIs em nível de sistema operacional.&lt;/p>
&lt;hr>
&lt;h2 id="8-conclusão">8. Conclusão
&lt;/h2>&lt;p>Neste artigo, explicamos em detalhes como usar o &lt;code>whisper.cpp&lt;/code> para integrar a IA de reconhecimento de voz de ponta em seu projeto C++, desde a teoria até a prática e otimização.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Conformidade com os Requisitos de Entrada&lt;/strong>: Adoção estrita de 16 kHz, 1 ch, Float de 32 bits.&lt;/li>
&lt;li>&lt;strong>Uso Intuitivo da API&lt;/strong>: Design simples em que a inferência é concluída com apenas &lt;code>whisper_init_from_file_with_params&lt;/code> e &lt;code>whisper_full&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Processamento em Tempo Real&lt;/strong>: Controle multithread com VAD e janela deslizante.&lt;/li>
&lt;li>&lt;strong>Otimização Esmagadora&lt;/strong>: Quantização de 4 bits pelo &lt;code>ggml&lt;/code> e benefícios de backends de hardware como Metal e cuBLAS.&lt;/li>
&lt;/ul>
&lt;p>Use o &lt;code>whisper.cpp&lt;/code> para se libertar das dependências de ambientes Python enormes ou APIs de nuvem e desenvolver aplicativos de processamento de voz que funcionam de forma rápida e segura de maneira nativa. A IA local será uma tecnologia fundamental essencial para o desenvolvimento futuro de software, sob o ponto de vista da proteção da privacidade e latência.&lt;/p></description></item></channel></rss>