From 564ec85f6792497bb6c697f7efdf39e6ef9b45cb Mon Sep 17 00:00:00 2001 From: Dario Lencina Date: Thu, 9 Jul 2026 21:58:41 -0700 Subject: [PATCH] =?UTF-8?q?feat(voice):=20local=20speech=20stack=20by=20de?= =?UTF-8?q?fault=20=E2=80=94=20whisper.cpp=20STT=20+=20piper=20TTS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Speech no longer needs an API key. videoeditor-voice grows a second backend for each direction, local and default: - STT: whisper.cpp (`whisper-cli` over pinned ggml-base.en weights), word-level timestamps normalized to the same transcript shape Scribe returns, so analyze and the recorder coach work unchanged. `VIDEOEDITOR_STT=elevenlabs` opts back into Scribe. - TTS: a piper voice (en_US-lessac-medium) rendered by sherpa-onnx-offline-tts, encoded to the pipeline's mp3 via ffmpeg. `tts: elevenlabs` frontmatter (or `VIDEOEDITOR_TTS`) opts back into ElevenLabs; voice_id is now only required on that path. nixpkgs' piper-tts is broken on aarch64-darwin, hence sherpa-onnx as the engine. The nix closure pins the whole stack: whisper-cpp, sherpa-onnx, and both models, with WHISPER_MODEL / PIPER_VOICE baked into the wrapper and exported by the dev shell. hello-bench now renders keyless end to end. The recorder e2e also unsets WHISPER_MODEL: whisper hallucinates words on the fake mic's tone, which would make coaching assertions flaky. New: `cargo run -p videoeditor-voice --example transcribe --