{"id":612,"date":"2026-08-04T15:24:56","date_gmt":"2026-08-04T18:24:56","guid":{"rendered":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/portfolio-amd-dsp\/"},"modified":"2026-08-05T17:05:43","modified_gmt":"2026-08-05T20:05:43","slug":"portfolio-amd-dsp","status":"publish","type":"page","link":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/portfolio-amd-dsp\/","title":{"rendered":"Detector de Secret\u00e1ria Eletr\u00f4nica por Processamento de Sinais"},"content":{"rendered":"<style>\n.pf-wrap{max-width:1100px;margin:0 auto;font-size:16px;line-height:1.65}\n.pf-chamada{font-size:1.15rem;opacity:.85;margin:0 0 2rem}\n.pf-grade{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1.5rem}\n.pf-card{border:1px solid rgba(128,128,128,.3);border-radius:10px;overflow:hidden;display:flex;flex-direction:column;transition:transform .15s ease,box-shadow .15s ease}\n.pf-card:hover{transform:translateY(-3px);box-shadow:0 8px 24px rgba(0,0,0,.12)}\n.pf-card img{width:100%;height:180px;object-fit:cover;display:block;background:rgba(128,128,128,.12)}\n.pf-card-corpo{padding:1rem 1.1rem 1.2rem;display:flex;flex-direction:column;gap:.6rem;flex:1}\n.pf-card h3{margin:0;font-size:1.05rem;line-height:1.35}\n.pf-card p{margin:0;font-size:.92rem;opacity:.85;flex:1}\n.pf-chips{display:flex;flex-wrap:wrap;gap:.35rem}\n.pf-chip{font-size:.75rem;padding:.18rem .55rem;border-radius:999px;border:1px solid rgba(128,128,128,.35);opacity:.9}\n.pf-meta{font-size:.8rem;opacity:.7}\n.pf-cadeado{font-size:.8rem;opacity:.75}\n.pf-hero{margin:0 0 1.5rem}\n.pf-hero h1{margin:0 0 .4rem;line-height:1.2}\n.pf-secao{margin:2rem 0}\n.pf-secao h2{font-size:1.15rem;margin:0 0 .6rem;text-transform:uppercase;letter-spacing:.06em;opacity:.75}\n.pf-galeria{display:grid;gap:1.2rem;margin:2rem 0}\n.pf-galeria figure{margin:0}\n.pf-galeria img{width:100%;border:1px solid rgba(128,128,128,.3);border-radius:8px;display:block}\n.pf-galeria figcaption{font-size:.85rem;opacity:.75;margin-top:.4rem}\n.pf-repo{border:1px solid rgba(128,128,128,.35);border-left-width:4px;border-radius:8px;padding:1rem 1.2rem;margin:2rem 0}\n.pf-repo h2{margin:0 0 .5rem;font-size:1rem;text-transform:uppercase;letter-spacing:.06em}\n.pf-repo pre{background:rgba(128,128,128,.12);padding:.7rem .9rem;border-radius:6px;overflow-x:auto;margin:.6rem 0;font-size:.85rem}\n.pf-contato{margin:2rem 0;padding-top:1.2rem;border-top:1px solid rgba(128,128,128,.3);font-size:.95rem}\n.pf-voltar{display:inline-block;margin-bottom:1rem;font-size:.9rem}\n@media (max-width:600px){.pf-card img{height:150px}}\n<\/style>\n<div class=\"pf-wrap\">\n  <a class=\"pf-voltar\" href=\"\/index.php\/portfolio-backend\/\">\u2190 voltar ao portf\u00f3lio<\/a><\/p>\n<header class=\"pf-hero\">\n<p class=\"pf-meta\">08\/2026 \u00b7 1 semana<\/p>\n<p>Detecta secret\u00e1ria eletr\u00f4nica por cad\u00eancia de fala, sem IA, sem modelo e sem treino \u2014 com o resultado medido em 80 chamadas reais.<\/p>\n<div class=\"pf-chips\"><span class=\"pf-chip\">Python<\/span><span class=\"pf-chip\">NumPy<\/span><span class=\"pf-chip\">ffmpeg<\/span><span class=\"pf-chip\">Goertzel<\/span><span class=\"pf-chip\">pytest<\/span><span class=\"pf-chip\">Asterisk<\/span><\/div>\n<\/header>\n<section class=\"pf-secao\">\n<h2>O problema<\/h2>\n<p>Discador que n\u00e3o distingue pessoa de caixa postal desperdi\u00e7a o tempo mais caro da opera\u00e7\u00e3o: o do agente. A resposta usual hoje \u00e9 transcrever a chamada e perguntar a um modelo de linguagem, o que custa segundos de GPU por liga\u00e7\u00e3o e n\u00e3o roda offline. O algoritmo cl\u00e1ssico do Asterisk resolve isso em C, dentro do dialplan, mas fica preso l\u00e1: n\u00e3o d\u00e1 para usar sobre grava\u00e7\u00e3o, em lote, ou dentro de um pipeline de an\u00e1lise.<\/p>\n<\/section>\n<section class=\"pf-secao\">\n<h2>A arquitetura<\/h2>\n<p>Porte fiel do app_amd.c para Python\/NumPy, decidindo apenas por cad\u00eancia: quanto tempo houve sil\u00eancio antes da fala, quanto durou o bloco cont\u00ednuo de fala e quantos blocos existiram. A intui\u00e7\u00e3o \u00e9 velha e s\u00f3lida \u2014 quem atende diz al\u00f4 e espera resposta, enquanto a secret\u00e1ria eletr\u00f4nica emenda uma sauda\u00e7\u00e3o longa sem pausa. Os nomes de status e causa s\u00e3o os mesmos do Asterisk (MACHINE\/LONGGREETING, MAXWORDS, INITIALSILENCE, MAXWORDLENGTH; HUMAN; NOTSURE\/TOOLONG), assim como os par\u00e2metros do amd.conf, para que a configura\u00e7\u00e3o j\u00e1 ajustada em produ\u00e7\u00e3o seja reaproveitada sem tradu\u00e7\u00e3o. A detec\u00e7\u00e3o de bipe usa o algoritmo de Goertzel, mais barato que uma FFT completa quando se procura uma frequ\u00eancia conhecida. As depend\u00eancias s\u00e3o NumPy e ffmpeg, e nada mais: sem rede, sem GPU, sem modelo em disco.<\/p>\n<\/section>\n<section class=\"pf-secao\">\n<h2>O resultado<\/h2>\n<p>Em 80 grava\u00e7\u00f5es reais de discador no pior cen\u00e1rio para o m\u00e9todo \u2014 \u00e1udio p\u00f3s-atendimento com as duas pernas misturadas \u2014 obteve 100% de recall em m\u00e1quina (37 de 37) e 78% de acur\u00e1cia global. O erro \u00e9 conservador na dire\u00e7\u00e3o certa: nenhuma m\u00e1quina escapa, mas 37% dos humanos s\u00e3o marcados como m\u00e1quina, e a an\u00e1lise mostra que isso vem de o \u00e1udio conter a URA de oferta, n\u00e3o de falha do algoritmo. Serve como pr\u00e9-filtro: tudo classificado como HUMAN pode ser aceito sem segunda opini\u00e3o, o que corta 34% do trabalho antes de qualquer etapa cara. S\u00e3o 428 linhas de teste para 584 de c\u00f3digo, e a documenta\u00e7\u00e3o registra a armadilha de VAD que quase produziu a conclus\u00e3o falsa de que AMD sem IA n\u00e3o funciona.<\/p>\n<\/section>\n<div class=\"pf-galeria\">\n<figure>\n      <img decoding=\"async\" src=\"https:\/\/carloslopes.programandosolucoes.com.br\/wp-content\/uploads\/portfolio\/amd-dsp-01-cadencia.png\" alt=\"A decis\u00e3o por cad\u00eancia: o que separa um al\u00f4 de uma sauda\u00e7\u00e3o de caixa postal\" loading=\"lazy\"><figcaption>A decis\u00e3o por cad\u00eancia: o que separa um al\u00f4 de uma sauda\u00e7\u00e3o de caixa postal<\/figcaption><\/figure>\n<figure>\n      <img decoding=\"async\" src=\"https:\/\/carloslopes.programandosolucoes.com.br\/wp-content\/uploads\/portfolio\/amd-dsp-02-resultado.png\" alt=\"Resultado medido em 80 chamadas reais, com a leitura de cada n\u00famero\" loading=\"lazy\"><figcaption>Resultado medido em 80 chamadas reais, com a leitura de cada n\u00famero<\/figcaption><\/figure>\n<\/p><\/div>\n<div class=\"pf-repo\">\n<h2>\ud83d\udd12 C\u00f3digo-fonte<\/h2>\n<pre><code>git clone https:\/\/git.programandosolucoes.com.br\/git\/repos\/amd-dsp.git<\/code><\/pre>\n<p>C\u00f3digo-fonte privado. As credenciais de leitura s\u00e3o liberadas sob solicita\u00e7\u00e3o \u2014 me chame para conversar sobre o projeto.<\/p>\n<\/p><\/div>\n<div class=\"pf-contato\">\n    <strong>Carlos Alberto<\/strong> \u2014 carlosalberto4ti@gmail.com \u00b7 +55 11 2615-2880\n  <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u2190 voltar ao portf\u00f3lio 08\/2026 \u00b7 1 semana Detecta secret\u00e1ria eletr\u00f4nica por cad\u00eancia de fala, sem IA, sem modelo e sem treino \u2014 com o resultado medido em 80 chamadas reais. PythonNumPyffmpegGoertzelpytestAsterisk O problema Discador que n\u00e3o distingue pessoa de caixa postal desperdi\u00e7a o tempo mais caro da opera\u00e7\u00e3o: o do agente. A resposta usual [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-612","page","type-page","status-publish","hentry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"it","enabled_languages":["en","br","it"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"br":{"title":false,"content":false,"excerpt":false},"it":{"title":false,"content":false,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/pages\/612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/comments?post=612"}],"version-history":[{"count":1,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/pages\/612\/revisions"}],"predecessor-version":[{"id":624,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/pages\/612\/revisions\/624"}],"wp:attachment":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/it\/index.php\/wp-json\/wp\/v2\/media?parent=612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}