Fale portuguΓͺs β seus amigos ouvem em inglΓͺs.
Eles falam em inglΓͺs β vocΓͺ ouve em portuguΓͺs.
Sem nuvem. Sem API key. Sem latΓͺncia de internet. Sua voz nunca sai da sua mΓ‘quina.
p50 ~450ms Β· p95 ~550ms (GPU small, fala β traduΓ§Γ£o sintetizada)
π Site Β· π§π· PortuguΓͺs Β· πΊπΈ English
|
Γndice β Β O que Γ© Β· Em aΓ§Γ£o Β· Arquitetura Β· Os dois painΓ©is Β· Destaques Β· Comparativo Β· Performance Β· Stack Β· Quick start Β· Discord Β· Estrutura Β· UI Β· Problemas Β· FAQ Β· Roadmap Β· Notas tΓ©cnicas Β· Contribuindo Β· LicenΓ§a |
Laguna Γ© um tradutor de voz em tempo real pensado pra chamadas no Discord (mas serve pra qualquer coisa). VocΓͺ fala no microfone, o Laguna transcreve, traduz e ressintetiza β tudo na sua mΓ‘quina, em menos de meio segundo β e entrega o Γ‘udio traduzido num microfone virtual que o Discord enxerga como se fosse seu.
O caminho contrΓ‘rio tambΓ©m funciona: captura o Γ‘udio do Discord, transcreve e traduz pra vocΓͺ ouvir no fone.
NΓ£o-metas: isto nΓ£o Γ© um produto SaaS, nΓ£o Γ© um competidor de Google Translate, e nΓ£o tenta ser. Γ uma ferramenta pra quem joga/conversa com gente que fala outro idioma e quer uma ponte sem depender de cloud.
π Tem um site de apresentaΓ§Γ£o: lagunatranslate.vercel.app β bilΓngue, com o pipeline animado e a UI em destaque.
sequenceDiagram
autonumber
participant π as Microfone
participant VAD as WebRTC VAD<br/>(30ms frames)
participant STT as faster-whisper<br/>(CUDA fp16)
participant MT as Argos Translate
participant TTS as Piper TTS
participant π as Cabo Virtual<br/>(Laguna Mic)
participant π§ as Discord
π->>VAD: PCM 16kHz mono
Note over VAD: detecta fala,<br/>buffer 300ms prΓ©-fala
VAD->>STT: segmento de voz<br/>(~2-10s)
STT-->>MT: "olΓ‘ pessoal, teste de traduΓ§Γ£o"<br/>(~450ms)
MT-->>TTS: "hello everyone, translation test"<br/>(~30ms)
TTS-->>π: PCM sintetizado<br/>(~40ms)
π->>π§: entra como microfone
flowchart LR
subgraph UI["π₯οΈ Web UI (navegador)"]
HTML[index.html<br/>JS + CSS]
end
subgraph SRV["βοΈ Servidor FastAPI (127.0.0.1:7531)"]
REST[REST /api/*]
WS[WebSocket /ws]
end
subgraph CORE["π§ Laguna Core"]
W1[DirectionWorker<br/>FALAR ποΈ]
W2[DirectionWorker<br/>ESCUTAR π]
end
subgraph PIPE["π Pipeline por worker"]
direction TB
CAP[sounddevice<br/>InputStream]
VAD[WebRTC VAD]
STT[faster-whisper]
MT[Argos Translate]
TTS[Piper TTS]
OUT[sounddevice<br/>OutputStream]
CAP --> VAD --> STT --> MT --> TTS --> OUT
end
subgraph HW["ποΈ Γudio / Windows"]
MIC[π Mic real]
LOOP[WASAPI Loopback]
VCBL[VB-CABLE<br/>π Laguna Mic / Output]
FONE[π§ Fone]
end
HTML <-->|REST start/stop/gain| REST
HTML <-.->|live events| WS
REST --> W1 & W2
W1 -.eventos.-> WS
W2 -.eventos.-> WS
W1 --> PIPE
W2 --> PIPE
MIC --> CAP
LOOP --> CAP
OUT --> VCBL
OUT --> FONE
classDef dim fill:#eef,stroke:#99f,color:#223
class UI,SRV,CORE,PIPE,HW dim
Dois workers rodam simultΓ’neos e independentes β cada um com seus modelos, configs, devices e mΓ©tricas. O servidor FastAPI sΓ³ orquestra: REST pra controle, WebSocket pra live updates (STT parcial, traduΓ§Γ£o, latΓͺncia rolling, medidores de nΓvel).
flowchart TB
subgraph VOCE["π€ VocΓͺ"]
VMIC[π Mic real]
VFONE[π§ Fone real]
end
subgraph LAGUNA["π Laguna Translator"]
FALAR[Painel FALAR<br/>PT β EN]
ESCUTAR[Painel ESCUTAR<br/>EN β PT]
end
subgraph VBCABLE["π VB-CABLE (renomeado)"]
LAGMIC[Laguna Mic<br/>virtual input]
LAGOUT[Laguna Output<br/>virtual output]
end
subgraph DISCORD["π¬ Discord"]
DIN[Input: Laguna Mic]
DOUT[Output: seu fone real]
end
VMIC -->|sua voz PT| FALAR
FALAR -->|voz sintetizada EN| LAGMIC
LAGMIC --> DIN
DOUT -->|Γ‘udio dos amigos EN<br/>via loopback| ESCUTAR
ESCUTAR -->|voz sintetizada PT| VFONE
style LAGUNA fill:#e6f7ff,stroke:#1890ff,color:#003a8c
style VBCABLE fill:#fff7e6,stroke:#fa8c16,color:#612500
| π 100% local | Nenhum dado sai da mΓ‘quina. Sem API key, sem cloud, sem telemetria. |
| β‘ p50 ~450ms | Small + CUDA fp16 Γ© o sweet spot β rΓ‘pido e preciso. |
| π Bidirecional simultΓ’neo | Dois pipelines independentes: FALAR e ESCUTAR rodam ao mesmo tempo. |
| π DetecΓ§Γ£o de idioma | Se vocΓͺ jΓ‘ falou no idioma alvo, pula a traduΓ§Γ£o (~130ms overhead, zero latΓͺncia extra de MT/TTS). |
| ποΈ Passthrough opcional | Mandar tambΓ©m sua voz original junto com a traduΓ§Γ£o (ΓΊtil pra mixar canal bilΓngue). |
| ποΈ UI web reativa | WebSocket + medidores de nΓvel + latΓͺncia p50/p95 em tempo real. |
| π Temas claro/escuro | Shift+T pra alternar. |
| π i18n PT/EN | Toggle π no topo. |
| π§ WASAPI loopback | Captura saΓda do PC direto (sem "Stereo Mix"). |
| πͺΆ Lean | Sem torch. DependΓͺncias bem definidas em requirements.txt. |
| π Laguna | βοΈ Bots / SaaS de cloud | π± Google Translate (app) | π€ Bots de traduΓ§Γ£o do Discord | |
|---|---|---|---|---|
| Roda 100% local | β | β | β | β |
| Entra como microfone no Discord | β | β | β (precisa de bot no servidor) | |
| LatΓͺncia tΓpica | ~450ms | 2β5s | β (Γ© uma tela) | 1β3s+ |
| Privacidade da voz | total | β | β | β |
| Bidirecional simultΓ’neo | β | β | ||
| Sem API key / sem conta | β | β | β | |
| Custo | grΓ‘tis Β· MIT | $/mΓͺs | grΓ‘tis | grΓ‘tis/$ |
Honestidade: serviΓ§os de cloud podem ter traduΓ§Γ£o de qualidade superior em frases longas. A Laguna troca um pouco disso por latΓͺncia baixa, privacidade total e zero dependΓͺncia de internet β que Γ© o que faz uma conversa fluir.
Frase teste: "Hello everyone, this is a real-time translator test for Discord." (sintetizada via Piper pt_BR, ~4s de Γ‘udio).
| Stack | STT | MT | TTS | Total | Qualidade |
|---|---|---|---|---|---|
| tiny CPU int8 | 410 ms | 317 ms | 272 ms | 999 ms | β baixa (muitos erros) |
| small CPU int8 | 2179 ms | 292 ms | 296 ms | 2767 ms | β perfeita |
| small CUDA fp16 β | 568 ms | 269 ms | 276 ms | 1113 ms | β perfeita |
| medium CUDA fp16 | 775 ms | 317 ms | 246 ms | 1338 ms | β leve hallucination |
| DireΓ§Γ£o | p50 | p95 | p99 |
|---|---|---|---|
| PT β EN (pbβen) | 458 ms | 562 ms | 600 ms |
| EN β PT (enβpb) | 424 ms | 496 ms | 534 ms |
"Medium ficou com
'tradutora'e traduziu'Discord'β'discΓ³rdia'; small acertou tudo." Small Γ© o ponto Γ³timo: mais rΓ‘pido e mais preciso pro caso de uso.
flowchart LR
subgraph ML["π§ Machine Learning"]
FW[faster-whisper 1.2<br/>+ CTranslate2 4.6]
AR[Argos Translate 1.10<br/>pb β en]
PI[Piper TTS 1.4<br/>en_US-lessac Β· pt_BR-faber]
end
subgraph AUDIO["ποΈ Γudio"]
SD[sounddevice]
WV[webrtcvad-wheels]
NP[numpy Β· scipy]
end
subgraph WEB["π Web"]
FA[FastAPI]
UV[uvicorn]
WS[WebSocket]
end
subgraph GPU["β‘ GPU (opcional)"]
CB[nvidia-cublas-cu12 12.9]
CD[nvidia-cudnn-cu12 9.19]
end
subgraph OPT["π¦ Opcionais"]
PW[pywebview<br/>janela nativa]
VB[VB-CABLE<br/>mic virtual]
end
- Windows 10/11 (o launcher
.vbs/.bate WASAPI loopback sΓ£o Windows-especΓficos) - Python 3.13 em
C:\Python313\(ou ajuste os caminhos nos scripts) - GPU NVIDIA com CUDA 12 (opcional, mas fortemente recomendado β roda em CPU tambΓ©m)
- VB-CABLE pra integrar com Discord: https://vb-audio.com/Cable/
git clone https://github.com/caioross/Laguna_Translate.git
cd Laguna_Translate
C:/Python313/python.exe -m pip install -r requirements.txt
# Para GPU (opcional β skip se sΓ³ for rodar em CPU)
C:/Python313/python.exe -m pip install nvidia-cublas-cu12 nvidia-cudnn-cu12
# Para janela nativa em vez do navegador (opcional β sem ele, laguna_app.py cai no navegador padrΓ£o)
C:/Python313/python.exe -m pip install pywebviewPara uma instalaΓ§Γ£o reproduzΓvel com as versΓ΅es exatas comprovadas, use o
requirements.lockno lugar dorequirements.txt:C:/Python313/python.exe -m pip install -r requirements.lock.
Modelos baixam sozinhos no primeiro run (~800MB total): Whisper small, vozes Piper, pacotes Argos pbβen.
C:/Python313/python.exe laguna_server.pyAbre http://127.0.0.1:7531 automaticamente. Dois painΓ©is β FALAR e ESCUTAR β com tudo configurΓ‘vel e mΓ©tricas ao vivo.
C:/Python313/python.exe laguna_app.pypowershell -ExecutionPolicy Bypass -File .\install_shortcuts.ps1Cria Laguna Translator.lnk no Desktop e Menu Iniciar. Usa Laguna.vbs (launcher silencioso, sem console). Pra remover: uninstall_shortcuts.ps1.
Modos CLI, offline e stress tests (clique pra expandir)
# Listar devices
C:/Python313/python.exe fase0_poc.py --list-devices
# PT β EN
C:/Python313/python.exe fase0_poc.py --direction pt2en --model small --device cuda
# EN β PT
C:/Python313/python.exe fase0_poc.py --direction en2pt --model small --device cuda
# Debug (salva WAVs dos segmentos)
C:/Python313/python.exe fase0_poc.py --direction pt2en --debugCtrl+C encerra e imprime estatΓsticas p50/p95/p99 por estΓ‘gio.
C:/Python313/python.exe test_offline.py dry_en2pt.wav --direction pt2en --model small --device cuda -o out.wavC:/Python313/python.exe stress_fase0.py --rounds 20 --model small --device cuda # PT β EN
C:/Python313/python.exe stress_en2pt.py --rounds 20 --model small --device cuda # EN β PTsequenceDiagram
participant U as π€ UsuΓ‘rio
participant W as πͺ Windows Sound
participant L as π Laguna
participant D as π¬ Discord
U->>W: instala VB-CABLE
U->>W: renomeia "CABLE Output" β "Laguna Translator Mic"
U->>W: renomeia "CABLE Input" β "Laguna Translator Output"
U->>L: abre UI, badge mostra "π Laguna OK"
U->>D: Input = Laguna Translator Mic
U->>D: Output = seu fone real
L->>D: voz traduzida entra como mic
D->>L: Γ‘udio dos amigos (via loopback) β traduz β fone
Passo a passo
- Baixe e instale VB-CABLE: https://vb-audio.com/Cable/ (grΓ‘tis, reinicie depois)
- ConfiguraΓ§Γ΅es de som do Windows β Mais opΓ§Γ΅es de som
- Aba GravaΓ§Γ£o β direito em
CABLE Outputβ Propriedades β Geral β renomeia praLaguna Translator Mic - Aba ReproduΓ§Γ£o β direito em
CABLE Inputβ Propriedades β Geral β renomeia praLaguna Translator Output - No Laguna a badge do topo vira "π Laguna: dispositivos renomeados OK"
- No Discord β Voz e VΓdeo:
- Entrada:
Laguna Translator Mic - SaΓda: seu fone real (nΓ£o o virtual)
- Entrada:
- No painel do Laguna:
- FALAR β "SaΓda virtual" =
Laguna Translator Output - ESCUTAR β "Captura" =
Laguna Translator Mic(ou marque loopback e selecione o device que o Discord usa)
- FALAR β "SaΓda virtual" =
Sem VB-CABLE o app ainda funciona β sΓ³ nΓ£o aparece "invisΓvel" como mic no Discord.
Γrvore de arquivos
Laguna_Translate/
βββ laguna_core.py # DirectionWorker: pipeline bidirecional, VAD/STT/MT/TTS
βββ laguna_server.py # FastAPI + WebSocket (UI web em http://127.0.0.1:7531)
βββ laguna_app.py # Launcher com janela nativa (pywebview + WebView2)
βββ laguna_pipeline.py # Engines e constantes: STT, ArgosMT, PiperTTS, VAD, detect_device
βββ fase0_poc.py # CLI de POC (--list-devices); reexporta laguna_pipeline por compat
βββ fase1_app.py # Painel PySide6 (legado, substituΓdo pela UI web)
β
βββ static/ # UI web
β βββ index.html
β βββ app.js # controla REST/WS, 2 painΓ©is, medidores, temas
β βββ i18n.js # PT/EN
β βββ style.css
β
βββ Laguna.vbs # launcher silencioso (pythonw, sem console)
βββ Laguna.bat # launcher com console (debug)
βββ install_shortcuts.ps1 # cria atalhos Desktop + Start Menu
βββ uninstall_shortcuts.ps1
β
βββ bench_fase0.py # benchmark single-frase comparando stacks
βββ stress_fase0.py # stress PT β EN (200+ segmentos)
βββ stress_en2pt.py # stress EN β PT
βββ test_offline.py # pipeline num WAV (sem mic)
βββ test_lang_detect.py # testa skip-same-lang
β
βββ docs/ # plano tΓ©cnico
βββ requirements.txt
βββ LICENSE # MIT
βββ README.md # vocΓͺ tΓ‘ aqui
O site de apresentaΓ§Γ£o (lagunatranslate.vercel.app) mora num repositΓ³rio separado (LagunaTranslate-site) β Next.js + Tailwind.
FALAR β vocΓͺ fala no mic real, Laguna traduz, Γ‘udio sintetizado sai no microfone virtual que o Discord usa como entrada.
ESCUTAR β Laguna captura o Γ‘udio que chega ao seu fone (via loopback WASAPI ou um mic virtual pareado), traduz e toca no seu fone.
Cada painel tem:
- seleΓ§Γ£o de idiomas (origem β alvo)
- seleΓ§Γ£o de devices (mic/loopback, saΓda virtual, fone opcional)
- toggle passthrough (enviar tambΓ©m o Γ‘udio original)
- controles de volume (saΓda da traduΓ§Γ£o, passthrough) em dB
- avanΓ§ado: modelo STT, device (auto/cuda/cpu), skip same lang
- bloco ao vivo: transcriΓ§Γ£o + traduΓ§Γ£o + mΓ©tricas p50/p95 + medidores de nΓvel
- tooltips em tudo (passe o mouse)
CUDA nΓ£o Γ© detectada / cai pra CPU mesmo com GPU NVIDIA
Instale os pacotes CUDA via pip e confirme que estΓ£o no mesmo Python:
C:/Python313/python.exe -m pip install nvidia-cublas-cu12 nvidia-cudnn-cu12No Windows, laguna_pipeline.py::_register_cuda_dlls() registra os diretΓ³rios bin/ do nvidia.cublas e nvidia.cudnn antes do import faster_whisper. Sem isso, o ctranslate2 nΓ£o acha as DLLs. Force a GPU no painel avanΓ§ado (Device β cuda) pra ver o erro real, se houver.
O Discord nΓ£o escuta a traduΓ§Γ£o / nΓ£o aparece o mic virtual
- Confirme que o VB-CABLE estΓ‘ instalado e que vocΓͺ reiniciou.
- No painel FALAR, a "SaΓda virtual" precisa ser o
CABLE Input(renomeado praLaguna Translator Output). - No Discord β Voz e VΓdeo, a Entrada tem que ser o
CABLE Output(renomeado praLaguna Translator Mic). - Recarregue a pΓ‘gina da UI depois de renomear β os devices sΓ³ aparecem marcados com π apΓ³s o reload.
"loopback indisponΓvel" no painel ESCUTAR
O loopback WASAPI exige um device de saΓda (nΓ£o de entrada). Marque a opΓ§Γ£o "Captura loopback (WASAPI)" e selecione o dispositivo de reproduΓ§Γ£o que o Discord estΓ‘ usando. Se ainda falhar, use o caminho via VB-CABLE: aponte a saΓda do Discord pro Laguna Translator Output e capture pelo Laguna Translator Mic.
Os primeiros fonemas sΓ£o cortados / frases curtas somem
O VAD usa buffer prΓ©-fala de 300ms e segmento mΓnimo de 400ms. Falas muito curtas ("oi", "ok") podem cair abaixo do mΓnimo. Fale com um leve "respiro" antes β ou ajuste as constantes em laguna_pipeline.py (PRE_SPEECH_BUFFER_MS, MIN_SPEECH_MS).
O download dos modelos trava ou estΓ‘ muito lento
Os modelos vΓͺm do Hugging Face Hub no primeiro run e ficam em models_cache/. Em picos, o Hub aplica rate-limit. Tente de novo (o download Γ© retomΓ‘vel) ou rode uma direΓ§Γ£o de cada vez pra baixar menos coisa em paralelo.
Eco / loop de feedback (o app escuta a prΓ³pria traduΓ§Γ£o)
Garanta que a saΓda da traduΓ§Γ£o vai pro device virtual (Discord), nΓ£o pro mesmo device que vocΓͺ estΓ‘ capturando. No FALAR, capture do mic real e mande a traduΓ§Γ£o pro Laguna Translator Output. No ESCUTAR, capture do loopback/Discord e toque no seu fone real β nunca no mesmo canal.
Meu Γ‘udio vai pra nuvem? NΓ£o. Captura, transcriΓ§Γ£o, traduΓ§Γ£o e sΓntese rodam na sua mΓ‘quina. Sem API key, sem servidor externo, sem telemetria.
Preciso de GPU NVIDIA? NΓ£o Γ© obrigatΓ³rio. Com GPU (CUDA fp16) vocΓͺ fica no sweet spot de ~450ms. Sem GPU, o app cai pro caminho de CPU automaticamente β funciona, sΓ³ com mais latΓͺncia.
Funciona sΓ³ no Discord? Foi pensado pro Discord, mas como entrega a traduΓ§Γ£o por um microfone virtual, funciona em qualquer app que deixe escolher o device de entrada: Meet, Zoom, OBS, etc.
Quais idiomas? PortuguΓͺs β InglΓͺs, nas duas direΓ§Γ΅es e simultaneamente. Outros pares estΓ£o no roadmap.
Preciso do VB-CABLE? SΓ³ pra entrar "invisΓvel" como mic no Discord. Sem ele o app continua funcionando pra testar e ouvir traduΓ§Γ΅es.
Γ de graΓ§a? Posso fazer fork? Sim. LicenΓ§a MIT: comercial, pessoal, fork, remix, rebrand. SΓ³ mantenha o copyright.
- Empacotar como
.exestandalone (PyInstaller--onedircom hooks prafaster_whisper,piper,ctranslate2,nvidia.cublas,nvidia.cudnn,argostranslateβ Inno Setup wrapper). Instalador ~1.5GB full, ~300MB com first-run bootstrap. - Backend alternativo de MT (NLLB, M2M100) pra melhorar gΓria de jogo ("sick flick", "carry").
- Mais pares de idiomas (ES, FR, JP...).
- Modelo Whisper
distil-large-v3como opΓ§Γ£o premium. - Push-to-talk opcional.
- Build Linux (loopback via PulseAudio/PipeWire em vez de WASAPI).
Argos: pt vs pb
Argos tem dois pacotes portugueses:
ptβ Europeu ("estΓ‘s", "equipa", "juntar-se")pbβ Brasileiro ("estΓ‘", "time", "se juntar")
O cΓ³digo mapeia pt β pb automaticamente via ARGOS_CODE_MAP em laguna_pipeline.py. Whisper STT continua usando pt (o modelo nΓ£o distingue variantes).
DLLs CUDA no Windows
laguna_pipeline.py::_register_cuda_dlls() procura nvidia.cublas e nvidia.cudnn instalados via pip e registra os diretΓ³rios bin/ antes do import faster_whisper. Sem isso, ctranslate2 nΓ£o encontra as DLLs no Windows.
Pipeline de VAD β segmentaΓ§Γ£o
WebRTC VAD com agressividade 2, frames de 30ms. Buffer prΓ©-fala de 300ms, hangover de silΓͺncio de 600ms, segmento mΓnimo 400ms, mΓ‘ximo 12s (force flush). ImplementaΓ§Γ£o em laguna_core.py e laguna_pipeline.py.
Este projeto Γ© open-source de verdade β no sentido "faz fork e se divirta". NΓ£o tem roadmap oficial, nΓ£o tem SLA, nΓ£o tem processo. Se vocΓͺ acha que falta algo:
- DΓ‘ fork.
- Mexe Γ vontade.
- Se achar que vale compartilhar, manda um PR descrevendo o que mudou e por quΓͺ.
- Se quiser seguir um caminho totalmente diferente, siga β o fork Γ© seu.
Issues com bugs/ideias tambΓ©m sΓ£o bem-vindas. Sem PR template, sem CLA, sem burocracia. Respeito mΓΊtuo e sΓ³.
MIT β ver LICENSE. Faz o que quiser: comercial, pessoal, fork, remix, rebrand. SΓ³ nΓ£o tire o copyright e nΓ£o me processe se quebrar. π€
|
Contents β Β What it is Β· In action Β· Architecture Β· The two panels Β· Highlights Β· Comparison Β· Performance Β· Stack Β· Quick start Β· Discord Β· Structure Β· UI Β· Troubleshooting Β· FAQ Β· Roadmap Β· Technical notes Β· Contributing Β· License |
Laguna is a real-time voice translator built for Discord calls (but works anywhere). You speak into your mic; Laguna transcribes, translates and re-synthesizes it β all on your machine, in under half a second β and feeds the translated audio into a virtual microphone that Discord sees as if it were you. The reverse direction works too: it captures Discord's audio, transcribes and translates it back for you to hear.
Non-goals: this is not a SaaS product, not a Google Translate competitor, and doesn't try to be. It's a tool for people who game/chat with someone speaking another language and want a bridge that doesn't depend on the cloud.
π There's a landing page: lagunatranslate.vercel.app β bilingual, with the animated pipeline and the UI front and center.
sequenceDiagram
autonumber
participant π as Microphone
participant VAD as WebRTC VAD<br/>(30ms frames)
participant STT as faster-whisper<br/>(CUDA fp16)
participant MT as Argos Translate
participant TTS as Piper TTS
participant π as Virtual Cable<br/>(Laguna Mic)
participant π§ as Discord
π->>VAD: PCM 16kHz mono
Note over VAD: detects speech,<br/>300ms pre-speech buffer
VAD->>STT: voice segment<br/>(~2-10s)
STT-->>MT: "olΓ‘ pessoal, teste de traduΓ§Γ£o"<br/>(~450ms)
MT-->>TTS: "hello everyone, translation test"<br/>(~30ms)
TTS-->>π: synthesized PCM<br/>(~40ms)
π->>π§: comes in as a microphone
flowchart LR
subgraph UI["π₯οΈ Web UI (browser)"]
HTML[index.html<br/>JS + CSS]
end
subgraph SRV["βοΈ FastAPI server (127.0.0.1:7531)"]
REST[REST /api/*]
WS[WebSocket /ws]
end
subgraph CORE["π§ Laguna Core"]
W1[DirectionWorker<br/>SPEAK ποΈ]
W2[DirectionWorker<br/>LISTEN π]
end
subgraph PIPE["π Per-worker pipeline"]
direction TB
CAP[sounddevice<br/>InputStream]
VAD[WebRTC VAD]
STT[faster-whisper]
MT[Argos Translate]
TTS[Piper TTS]
OUT[sounddevice<br/>OutputStream]
CAP --> VAD --> STT --> MT --> TTS --> OUT
end
subgraph HW["ποΈ Audio / Windows"]
MIC[π Real mic]
LOOP[WASAPI Loopback]
VCBL[VB-CABLE<br/>π Laguna Mic / Output]
FONE[π§ Headset]
end
HTML <-->|REST start/stop/gain| REST
HTML <-.->|live events| WS
REST --> W1 & W2
W1 -.events.-> WS
W2 -.events.-> WS
W1 --> PIPE
W2 --> PIPE
MIC --> CAP
LOOP --> CAP
OUT --> VCBL
OUT --> FONE
classDef dim fill:#eef,stroke:#99f,color:#223
class UI,SRV,CORE,PIPE,HW dim
Two workers run simultaneously and independently β each with its own models, config, devices and metrics. The FastAPI server only orchestrates: REST for control, WebSocket for live updates (partial STT, translation, rolling latency, level meters).
flowchart TB
subgraph VOCE["π€ You"]
VMIC[π Real mic]
VFONE[π§ Real headset]
end
subgraph LAGUNA["π Laguna Translator"]
FALAR[SPEAK panel<br/>PT β EN]
ESCUTAR[LISTEN panel<br/>EN β PT]
end
subgraph VBCABLE["π VB-CABLE (renamed)"]
LAGMIC[Laguna Mic<br/>virtual input]
LAGOUT[Laguna Output<br/>virtual output]
end
subgraph DISCORD["π¬ Discord"]
DIN[Input: Laguna Mic]
DOUT[Output: your real headset]
end
VMIC -->|your PT voice| FALAR
FALAR -->|synthesized EN voice| LAGMIC
LAGMIC --> DIN
DOUT -->|friends' EN audio<br/>via loopback| ESCUTAR
ESCUTAR -->|synthesized PT voice| VFONE
style LAGUNA fill:#e6f7ff,stroke:#1890ff,color:#003a8c
style VBCABLE fill:#fff7e6,stroke:#fa8c16,color:#612500
| π 100% local | Nothing leaves your machine. No API key, no cloud, no telemetry. |
| β‘ p50 ~450ms | Small + CUDA fp16 is the sweet spot β fast and accurate. |
| π Simultaneous bidirectional | Two independent pipelines: SPEAK and LISTEN run at the same time. |
| π Language detection | If you already spoke the target language, it skips translation (~130ms overhead, zero extra MT/TTS latency). |
| ποΈ Optional passthrough | Send your original voice alongside the translation (handy for a bilingual channel). |
| ποΈ Reactive web UI | WebSocket + level meters + p50/p95 latency in real time. |
| π Light/dark themes | Shift+T to toggle. |
| π PT/EN i18n | π toggle at the top. |
| π§ WASAPI loopback | Captures the PC's output directly (no "Stereo Mix"). |
| πͺΆ Lean | No torch. Well-defined deps in requirements.txt. |
| π Laguna | βοΈ Cloud bots / SaaS | π± Google Translate (app) | π€ Discord translation bots | |
|---|---|---|---|---|
| Runs 100% local | β | β | β | β |
| Comes in as a Discord mic | β | β | β (needs a server bot) | |
| Typical latency | ~450ms | 2β5s | β (it's a screen) | 1β3s+ |
| Voice privacy | total | β | β | β |
| Simultaneous bidirectional | β | β | ||
| No API key / no account | β | β | β | |
| Cost | free Β· MIT | $/mo | free | free/$ |
Honesty: cloud services may produce higher-quality translation on long sentences. Laguna trades a bit of that for low latency, total privacy and zero internet dependency β which is what actually keeps a conversation flowing.
Test phrase: "Hello everyone, this is a real-time translator test for Discord." (synthesized via Piper pt_BR, ~4s of audio).
| Stack | STT | MT | TTS | Total | Quality |
|---|---|---|---|---|---|
| tiny CPU int8 | 410 ms | 317 ms | 272 ms | 999 ms | β low (many errors) |
| small CPU int8 | 2179 ms | 292 ms | 296 ms | 2767 ms | β perfect |
| small CUDA fp16 β | 568 ms | 269 ms | 276 ms | 1113 ms | β perfect |
| medium CUDA fp16 | 775 ms | 317 ms | 246 ms | 1338 ms | β slight hallucination |
| Direction | p50 | p95 | p99 |
|---|---|---|---|
| PT β EN (pbβen) | 458 ms | 562 ms | 600 ms |
| EN β PT (enβpb) | 424 ms | 496 ms | 534 ms |
"Medium rendered
'tradutora'and translated'Discord'β'discΓ³rdia'; small got everything right." Small is the sweet spot: faster and more accurate for the use case.
faster-whisper 1.2 (+ CTranslate2) Β· Argos Translate (pb β en) Β· Piper TTS (en_US-lessac Β· pt_BR-faber) Β· sounddevice + WebRTC VAD + numpy/scipy Β· FastAPI + uvicorn + WebSocket Β· optional NVIDIA CUDA 12 + pywebview + VB-CABLE.
- Windows 10/11 (the
.vbs/.batlauncher and WASAPI loopback are Windows-specific) - Python 3.13 in
C:\Python313\(or adjust the paths in the scripts) - NVIDIA GPU with CUDA 12 (optional, but strongly recommended β runs on CPU too)
- VB-CABLE to integrate with Discord: https://vb-audio.com/Cable/
git clone https://github.com/caioross/Laguna_Translate.git
cd Laguna_Translate
C:/Python313/python.exe -m pip install -r requirements.txt
# For GPU (optional β skip if running on CPU only)
C:/Python313/python.exe -m pip install nvidia-cublas-cu12 nvidia-cudnn-cu12
# For a native window instead of the browser (optional β without it, laguna_app.py falls back to the default browser)
C:/Python313/python.exe -m pip install pywebviewFor a reproducible install with the exact proven versions, use
requirements.lockinstead ofrequirements.txt:C:/Python313/python.exe -m pip install -r requirements.lock.
Models auto-download on first run (~800 MB total): Whisper small, Piper voices, Argos pbβen packages.
C:/Python313/python.exe laguna_server.py # opens http://127.0.0.1:7531Two panels β SPEAK (PTβEN) and LISTEN (ENβPT) β with everything configurable and live metrics. For a native window (WebView2): python laguna_app.py. CLI/offline/stress modes are available (fase0_poc.py, test_offline.py, stress_*.py).
- Download and install VB-CABLE: https://vb-audio.com/Cable/ (free, reboot afterwards)
- Windows Sound settings β More sound settings
- Recording tab β right-click
CABLE Outputβ Properties β General β rename toLaguna Translator Mic - Playback tab β right-click
CABLE Inputβ Properties β General β rename toLaguna Translator Output - In Laguna, the top badge turns into "π Laguna: devices renamed OK"
- In Discord β Voice & Video:
- Input:
Laguna Translator Mic - Output: your real headset (not the virtual one)
- Input:
- In the Laguna panel:
- SPEAK β "Virtual output" =
Laguna Translator Output - LISTEN β "Capture" =
Laguna Translator Mic(or check loopback and pick the device Discord uses)
- SPEAK β "Virtual output" =
Without VB-CABLE the app still works β it just won't appear "invisible" as a mic in Discord.
The Python program lives in this repo (laguna_core.py, laguna_server.py, laguna_app.py, fase0_poc.py, static/ web UI, benchmark/stress scripts). The landing page (lagunatranslate.vercel.app) lives in a separate repo (LagunaTranslate-site, Next.js + Tailwind). See the Portuguese section for the full file tree.
SPEAK β you talk into the real mic, Laguna translates, and synthesized audio goes out through the virtual microphone Discord uses as input.
LISTEN β Laguna captures the audio reaching your headset (via WASAPI loopback or a paired virtual mic), translates it and plays it back in your headset.
Each panel has language selection, device selection (mic/loopback, virtual output, optional headset), a passthrough toggle, dB volume controls, an advanced block (STT model, device auto/cuda/cpu, skip same lang), and a live block with transcription + translation + p50/p95 metrics + level meters. Tooltips on everything.
CUDA not detected / falls back to CPU even with an NVIDIA GPU
Install the CUDA packages via pip into the same Python: pip install nvidia-cublas-cu12 nvidia-cudnn-cu12. On Windows, _register_cuda_dlls() registers the bin/ dirs of nvidia.cublas / nvidia.cudnn before importing faster_whisper β without it, ctranslate2 can't find the DLLs. Force Device β cuda in the advanced block to surface the real error.
Discord doesn't hear the translation / the virtual mic is missing
Confirm VB-CABLE is installed and you rebooted. In SPEAK, "Virtual output" must be CABLE Input (renamed Laguna Translator Output). In Discord β Voice & Video, Input must be CABLE Output (renamed Laguna Translator Mic). Reload the UI after renaming β devices only show the π mark after a refresh.
"loopback unavailable" in the LISTEN panel
WASAPI loopback needs an output device (not an input). Check "Loopback capture (WASAPI)" and pick the playback device Discord uses. If it still fails, route via VB-CABLE instead.
First phonemes cut off / short phrases vanish
The VAD uses a 300ms pre-speech buffer and a 400ms minimum segment. Very short utterances ("hi", "ok") can fall below the minimum. Tune the constants in laguna_pipeline.py (PRE_SPEECH_BUFFER_MS, MIN_SPEECH_MS).
Does my audio go to the cloud? No β capture, transcription, translation and synthesis all run on your machine. No API key, no external server, no telemetry.
Do I need an NVIDIA GPU? Not required. With a GPU (CUDA fp16) you stay in the ~450ms sweet spot; without one, the app falls back to CPU automatically.
Does it only work on Discord? It was built for Discord, but since it delivers translation through a virtual mic it works in any app that lets you pick the input device: Meet, Zoom, OBS, etc.
Which languages? Portuguese β English, both directions and simultaneously. More pairs are on the roadmap.
Do I need VB-CABLE? Only to come in "invisible" as a mic in Discord. Without it, the app still works to test and hear translations.
Is it free? Can I fork it? Yes. MIT license: commercial, personal, fork, remix, rebrand. Just keep the copyright.
- Package as a standalone
.exe(PyInstaller--onedirwith hooks forfaster_whisper,piper,ctranslate2,nvidia.cublas,nvidia.cudnn,argostranslateβ Inno Setup wrapper). - Alternative MT backend (NLLB, M2M100) for gaming slang.
- More language pairs (ES, FR, JPβ¦).
- Whisper
distil-large-v3as a premium option. - Optional push-to-talk.
- Linux build (loopback via PulseAudio/PipeWire instead of WASAPI).
- Argos
ptvspb: Argos has two Portuguese packages βpt(European) andpb(Brazilian). The code mapspt β pbviaARGOS_CODE_MAPin laguna_pipeline.py. Whisper STT keeps usingpt(the model doesn't distinguish variants). - CUDA DLLs on Windows:
_register_cuda_dlls()finds pip-installednvidia.cublas/nvidia.cudnnand registers theirbin/dirs before importingfaster_whisper. - VAD β segmentation: WebRTC VAD at aggressiveness 2, 30ms frames. 300ms pre-speech buffer, 600ms silence hangover, 400ms min segment, 12s max (force flush). See laguna_core.py and laguna_pipeline.py.
This project is genuinely open-source β "fork it and have fun." No official roadmap, no SLA, no process. Fork, hack freely, and open a PR describing what changed and why if you think it's worth sharing. Issues with bugs/ideas welcome. No PR template, no CLA, no bureaucracy. Mutual respect, that's all.
MIT β see LICENSE. Do whatever you want: commercial, personal, fork, remix, rebrand. Just keep the copyright and don't sue me if it breaks. π€
ConstruΓdo com β e muita fΓ© no faster-whisper.
Parte do ecossistema de projetos de Caio.