Text-to-voice on select + hotkey OR /speak api for automation
Rust
0
8 commits
updated May 29, 2026
DevVoice is a desktop app and local HTTP API for speaking selected text with several local TTS models, including VibeVoice Realtime 0.5B and the higher-quality VibeVoice 1.5B model.
The new 1.5B flow keeps the model practical by using a persistent MLX worker on macOS when:
VibeVoiceauto~/Library/Application Support/com.isa.devvoice/vibevoice-mlx-venvIf the MLX environment is missing, DevVoice now provisions it automatically on first 1.5B use. The old non-accelerated Rust 1.5B fallback is no longer treated as a supported path.
No, not for normal use.
When the app opens, DevVoice already starts a background warmup for the currently selected model. For VibeVoice 1.5B with MLX available, that startup warmup loads the MLX model and runs a tiny inference pass automatically.
The manual warmup API is still useful, but now it is optional and mainly for reducing the first request time for a specific voice.
VibeVoice as the voice model.auto.GET /status and wait for "model_ready": true./speak with reference_preset_name or reference_preset_id./vibevoice/warmup once with that preset before the first real /speak.You can confirm the active backend with:
curl http://127.0.0.1:9876/status
When the MLX path is active for 1.5B, tts_runtime_label should show:
{
"model_ready": true,
"tts_runtime_label": "python:mlx-int8:no-semantic"
}
DevVoice now auto-provisions the MLX runtime on first 1.5B use. If you want to install it yourself ahead of time, you can still create the virtual environment manually:
DATA_DIR="$HOME/Library/Application Support/com.isa.devvoice"
python3 -m venv "$DATA_DIR/vibevoice-mlx-venv"
source "$DATA_DIR/vibevoice-mlx-venv/bin/activate"
pip install --upgrade pip
pip install 'git+https://github.com/gafiatulin/vibevoice-mlx.git@f513aa7877e77fefa1aebe87432855c407da3b87' scipy
After that, relaunch DevVoice and keep precision on auto for the MLX worker to be used.
curl -X POST "http://127.0.0.1:9876/vibevoice/presets" \
-H "Content-Type: application/json" \
-d '{"name":"my-demo-voice","referenceAudioPath":"/Users/you/Desktop/reference-voice.wav"}'
Names are unique, so reference_preset_name is safe to use later. New presets now copy the reference clip into DevVoice-managed storage so they do not depend on the original temporary source path.
curl http://127.0.0.1:9876/vibevoice/presets
curl -X POST "http://127.0.0.1:9876/vibevoice/warmup" \
-H "Content-Type: application/json" \
-d '{"referencePresetName":"my-demo-voice"}'
Use this when you want the first real synthesis for that voice to avoid paying the model-load and voice-encode cost right before playback.
curl -X POST "http://127.0.0.1:9876/speak?reference_preset_name=my-demo-voice&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
curl -X POST "http://127.0.0.1:9876/speak?reference_preset_id=my-demo-voice-1716420000&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
curl -X POST "http://127.0.0.1:9876/speak?reference_audio_path=/Users/you/Desktop/reference-voice.wav&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
New presets now keep a DevVoice-managed copy of the reference clip, so they no longer depend on the original source path remaining available. Older presets created before this change may still point at external files.
With the persistent MLX path working, the rough behavior on the tested machine was:
That is still slower than VibeVoice Realtime 0.5B, but it is dramatically faster than the previous tens-of-minutes Rust path for VibeVoice 1.5B.
See architecture.md for the current 1.5B request lifecycle, component layout, fallback behavior, and known limitations.
8 commits
Rust
81.9%
JavaScript
6.8%
HTML
3.9%
Shell
3.0%
Python
2.4%
CSS
2.0%
Text-to-voice on select + hotkey OR /speak api for automation
Rust
0
8 commits
updated May 29, 2026
DevVoice is a desktop app and local HTTP API for speaking selected text with several local TTS models, including VibeVoice Realtime 0.5B and the higher-quality VibeVoice 1.5B model.
The new 1.5B flow keeps the model practical by using a persistent MLX worker on macOS when:
VibeVoiceauto~/Library/Application Support/com.isa.devvoice/vibevoice-mlx-venvIf the MLX environment is missing, DevVoice now provisions it automatically on first 1.5B use. The old non-accelerated Rust 1.5B fallback is no longer treated as a supported path.
No, not for normal use.
When the app opens, DevVoice already starts a background warmup for the currently selected model. For VibeVoice 1.5B with MLX available, that startup warmup loads the MLX model and runs a tiny inference pass automatically.
The manual warmup API is still useful, but now it is optional and mainly for reducing the first request time for a specific voice.
VibeVoice as the voice model.auto.GET /status and wait for "model_ready": true./speak with reference_preset_name or reference_preset_id./vibevoice/warmup once with that preset before the first real /speak.You can confirm the active backend with:
curl http://127.0.0.1:9876/status
When the MLX path is active for 1.5B, tts_runtime_label should show:
{
"model_ready": true,
"tts_runtime_label": "python:mlx-int8:no-semantic"
}
DevVoice now auto-provisions the MLX runtime on first 1.5B use. If you want to install it yourself ahead of time, you can still create the virtual environment manually:
DATA_DIR="$HOME/Library/Application Support/com.isa.devvoice"
python3 -m venv "$DATA_DIR/vibevoice-mlx-venv"
source "$DATA_DIR/vibevoice-mlx-venv/bin/activate"
pip install --upgrade pip
pip install 'git+https://github.com/gafiatulin/vibevoice-mlx.git@f513aa7877e77fefa1aebe87432855c407da3b87' scipy
After that, relaunch DevVoice and keep precision on auto for the MLX worker to be used.
curl -X POST "http://127.0.0.1:9876/vibevoice/presets" \
-H "Content-Type: application/json" \
-d '{"name":"my-demo-voice","referenceAudioPath":"/Users/you/Desktop/reference-voice.wav"}'
Names are unique, so reference_preset_name is safe to use later. New presets now copy the reference clip into DevVoice-managed storage so they do not depend on the original temporary source path.
curl http://127.0.0.1:9876/vibevoice/presets
curl -X POST "http://127.0.0.1:9876/vibevoice/warmup" \
-H "Content-Type: application/json" \
-d '{"referencePresetName":"my-demo-voice"}'
Use this when you want the first real synthesis for that voice to avoid paying the model-load and voice-encode cost right before playback.
curl -X POST "http://127.0.0.1:9876/speak?reference_preset_name=my-demo-voice&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
curl -X POST "http://127.0.0.1:9876/speak?reference_preset_id=my-demo-voice-1716420000&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
curl -X POST "http://127.0.0.1:9876/speak?reference_audio_path=/Users/you/Desktop/reference-voice.wav&cfg_scale=1.3&temperature=0.0&max_tokens=96&save_audio=true" \
-d "I'm your worst nightmare."
New presets now keep a DevVoice-managed copy of the reference clip, so they no longer depend on the original source path remaining available. Older presets created before this change may still point at external files.
With the persistent MLX path working, the rough behavior on the tested machine was:
That is still slower than VibeVoice Realtime 0.5B, but it is dramatically faster than the previous tens-of-minutes Rust path for VibeVoice 1.5B.
See architecture.md for the current 1.5B request lifecycle, component layout, fallback behavior, and known limitations.
8 commits
Rust
81.9%
JavaScript
6.8%
HTML
3.9%
Shell
3.0%
Python
2.4%
CSS
2.0%