Local Voice (FluidAudio TTS/STT)
by @trondw
Local text-to-speech (TTS) and speech-to-text (STT) using FluidAudio on Apple Silicon. Sub-second voice synthesis and transcription running entirely on-device via the Apple Neural Engine. Use when setting up local voice capabilities, voice assistant integration, or replacing cloud TTS/STT services.
clawhub install local-voiceπ About This Skill
name: local-voice description: Local text-to-speech (TTS) and speech-to-text (STT) using FluidAudio on Apple Silicon. Sub-second voice synthesis and transcription running entirely on-device via the Apple Neural Engine. Use when setting up local voice capabilities, voice assistant integration, or replacing cloud TTS/STT services.
Local Voice (FluidAudio TTS/STT)
Sub-second local voice AI for Apple Silicon Macs using FluidAudio's CoreML models.
Features
Requirements
Quick Setup
1. Install Dependencies
brew install espeak-ng
2. Build the Daemon
cd /path/to/skill/sources
swift build -c release
3. Install Binary and Framework
mkdir -p ~/clawd/bin
cp .build/release/StellaVoice ~/clawd/bin/
cp -R .build/arm64-apple-macosx/release/ESpeakNG.framework ~/clawd/bin/
install_name_tool -add_rpath @executable_path ~/clawd/bin/StellaVoice
4. Create LaunchAgent
cat > ~/Library/LaunchAgents/com.stella.tts.plist << 'EOF'
Label
com.stella.tts
ProgramArguments
$HOME/clawd/bin/StellaVoice
RunAtLoad
KeepAlive
StandardOutPath
$HOME/.clawdbot/logs/stella-tts.log
StandardErrorPath
$HOME/.clawdbot/logs/stella-tts.err.log
EOFlaunchctl load ~/Library/LaunchAgents/com.stella.tts.plist
API Endpoints
The daemon listens on http://127.0.0.1:18790:
TTS - Text to Speech
# Simple text to WAV
curl -X POST http://127.0.0.1:18790/synthesize -d "Hello world" -o output.wavWith speed control (0.5-2.0)
curl -X POST "http://127.0.0.1:18790/synthesize?speed=1.2" -d "Fast!" -o output.wavJSON endpoint
curl -X POST http://127.0.0.1:18790/synthesize/json \
-H "Content-Type: application/json" \
-d '{"text": "Hello", "speed": 1.0, "deEss": true}'
STT - Speech to Text
curl -X POST http://127.0.0.1:18790/transcribe \
--data-binary @audio.wav \
-H "Content-Type: audio/wav"
Returns: {"text": "transcribed text"}
Health Check
curl http://127.0.0.1:18790/health
Returns: ok
Voice Options
Default voice is af_sky. Change by modifying the source code.
Top Kokoro voices (American female):
af_heart (A grade) - warm, naturalaf_bella (A-) - expressiveaf_sky (C-) - clear, lightAll 54 voices: See references/VOICES.md
Expressiveness
Speed Control
speed=0.8 β Calm, relaxedspeed=1.0 β Natural pacespeed=1.2 β Energetic, upbeatPunctuation (automatic)
! β Excited tone? β Rising intonation. β Neutral, falling... β PausesSSML Tags
Kokoro
Dr.
2024-01-15
Helper Script
See scripts/stella-tts.sh for a convenient wrapper:
scripts/stella-tts.sh "Hello world" output.wav
scripts/stella-tts.sh "Hello world" output.mp3 # Auto-converts
Integration Example
For voice assistants, update your voice proxy to use local endpoints:
// STT
const response = await fetch('http://127.0.0.1:18790/transcribe', {
method: 'POST',
headers: { 'Content-Type': 'audio/wav' },
body: audioData
});
const { text } = await response.json();// TTS
const audio = await fetch('http://127.0.0.1:18790/synthesize', {
method: 'POST',
body: textToSpeak
});
Troubleshooting
Library not loaded (ESpeakNG)
install_name_tool -add_rpath @executable_path /path/to/binarySlow first request
x86 vs ARM
uname -m (should show arm64)Source Code
The daemon source is in sources/ directory. It's a Swift package using:
Rebuild after modifying:
cd sources && swift build -c release
π Tips & Best Practices
Library not loaded (ESpeakNG)
install_name_tool -add_rpath @executable_path /path/to/binarySlow first request
x86 vs ARM
uname -m (should show arm64)