-
-
Notifications
You must be signed in to change notification settings - Fork 20
Text to Speech
Ava supports two TTS playback modes for voice assistant replies: Standard TTS (URL-based) and Streaming TTS (PCM-based). The mode is selected in Settings → Voice → Voice Replies.
0.5.9–0.6.1 steadily hardened streaming TTS across different Home Assistant and TTS combinations, so silent or broken replies are far less common. 0.6.3 comprehensively rebuilt TTS playback across both classic and streaming modes. 0.7.3 added TTS volume as a HA-controllable number entity and preserve-original-URL for HTTPS setups.
Standard TTS waits until Home Assistant generates the full voice reply, then downloads and plays it from a URL.
Flow:
- HA sends
TTS_STARTwith the reply text (displayed as subtitle) - HA sends
TTS_ENDwith the TTS audio URL - Ava downloads the audio file and plays it via ExoPlayer
- On playback completion, Ava sends
announce_finishedto HA
Characteristics:
- Better compatibility — works with any HA TTS provider
- Supports floating subtitle overlay (word-by-word or full text)
- Supports wake sound and stop sound
- Higher latency — first audio is heard only after the full reply is generated and downloaded
- HTTP streaming playback with configurable connect/read timeout (30s)
Early TTS URL: HA may include the TTS URL in RUN_START before the conversation even begins. Ava caches this URL and uses it when TTS_END arrives, reducing latency.
Streaming TTS starts playing audio while the reply is still being generated on the HA side. HA sends PCM audio chunks in real time.
Flow:
- HA sends
TTS_START— Ava enters Responding state - HA sends
TTS_STREAM_START— Ava opens anAudioTrack(16 kHz, 16-bit, mono PCM) - HA sends PCM audio chunks via
VoiceAssistantAudiomessages — Ava writes them toAudioTrackin real time - HA sends
TTS_STREAM_END— Ava drains remaining audio, then completes
Characteristics:
- Faster first response — audio starts playing as soon as the first PCM chunk arrives
- No floating subtitle overlay (subtitles are suppressed in streaming mode because text arrives in fragments)
- Requires HA server with streaming TTS output support (HA
SPEAKERfeature flag) - PCM audio is played via raw
AudioTrack, not ExoPlayer - Volume scaling is applied per-sample on PCM data before writing to the track
- Buffered chunk handling: if PCM chunks arrive before
TTS_STREAM_START, they are buffered and flushed when the stream opens (max 256 frames)
Streaming TTS is great for low-latency replies, but not every Home Assistant TTS setup produces valid PCM audio in every situation. Ava now handles the common failure cases without leaving you with silence:
- Empty stream fallback (0.5.9): If a server announces a stream but no usable audio arrives, Ava falls back to the standard URL path. It only switches if real PCM data starts arriving, and avoids duplicate playback if late stream data appears.
-
No-audio stream protection (0.6.0): Some servers send
TTS_STREAM_STARTandTTS_STREAM_ENDevents without actually transmitting any PCM. Ava now waits for enough real audio data before the PCM path takes over, so an empty stream can no longer interrupt a URL voice reply that has already started. A watchdog also stops the assistant from getting stuck in Responding when the end event never arrives. -
Relative media paths and out-of-order events (0.6.1): Some Home Assistant speak responses provide a relative media path instead of a full URL; Ava resolves it through the authenticated base address used for cover and media requests. The streaming state machine also recovers if a PCM stream opens but never becomes audible, or if
TTS_STREAM_ENDarrives before any real audio.
In other words: if streaming works, you get the faster PCM reply. If the server advertises a stream but cannot deliver audio, you still get the URL reply — not silence.
TTS playback has been comprehensively rebuilt across both classic and streaming modes:
- Long responses are no longer terminated by a fixed 20-second timeout. Ava now follows actual playback progress, uses duration information when available, and distinguishes active playback, rebuffering, network failure, and a genuinely stalled stream.
- If streaming PCM provides no usable audio, stops unexpectedly, or misses an upstream completion event, Ava can recover through URL playback without playing both sources.
- A stale playback callback could previously terminate the next voice session immediately after a progressive TTS response. Playback state is now fully detached between sessions, fixing intermittent first-wake and follow-up wake failures.
- Failed starts, prolonged buffering, audio-focus loss, and missing stream-end events are handled independently, allowing voice sessions to finish cleanly and media playback to resume normally.
Home Assistant installations serving TTS directly over HTTPS can now enable Use original TTS URL. Ava plays the address returned by Home Assistant instead of rewriting it to LAN HTTP, preventing the silent address timeout reported in #152.
This option is disabled by default, leaving existing LAN configurations unchanged.
Path: Ava Settings → Voice Replies → Maintenance → Use original TTS URL
Feature flag negotiation: When streaming TTS is enabled in settings, Ava sets the SPEAKER feature flag in the VoiceAssistantConfigurationRequest. HA uses this to decide whether to send PCM streams.
| Feature | Standard TTS | Streaming TTS |
|---|---|---|
| First audio latency | Higher (wait for full reply) | Lower (play while generating) |
| Floating subtitles | Yes | No |
| Wake sound | Yes | Yes |
| Stop sound | Yes | Yes |
| Server requirement | Any HA TTS provider | HA with streaming output support |
| Playback engine | ExoPlayer (HTTP) | AudioTrack (raw PCM) |
| Audio format | Any (URL-based) | 16 kHz 16-bit mono PCM |
| Whisper response | Yes | Yes |
Ava supports HA's VoiceAssistantAnnounceRequest for proactive announcements (e.g., timer finished, ask_question). This is separate from the conversation TTS flow.
Flow:
- HA sends
AnnounceRequestwithmedia_id(and optionalpreannounce_media_id) - Ava ducks media playback, plays the announcement audio
- On completion, Ava sends
announce_finishedto HA - If
start_conversation=true, Ava starts a new voice pipeline to listen for the user's response (10s timeout)
Preannounce: If a preannounce_media_id is provided, Ava plays it first (e.g., "Attention:"), then plays the main media. A 3-second load timeout skips the preannounce if it fails to start.
Settings → Voice → Voice replies.
Wake sounds and spoken replies use a TTS volume separate from music. While speaking, Ava sets media volume to the TTS level, then restores it. Changing TTS volume during a reply takes effect immediately.
| Setting | Description | Default |
|---|---|---|
| Media volume | Current device media volume (reference) | — |
| TTS volume | Level written to media volume during those replies (15%–100%) | 30% |
| Show in Home Assistant | Show a live TTS volume number entity under Configuration in Home Assistant for automations | Off |
Volume-key changes during a reply are applied after speech ends. This does not change Volume Follow on the media-player settings page.
Ava displays localized toast messages for voice pipeline errors. Error messages are determined by the error code from HA and displayed in the user's locale.
Supported languages: English (default), Chinese (zh), German (de), Russian (ru), Portuguese (pt), Vietnamese (vi).
Locale detection: Ava uses LocaleUtils to detect the system locale at runtime. If the locale is not one of the supported languages, English is used as fallback.
| Error Code Pattern | String Key | English Message |
|---|---|---|
stt-no-text |
pipeline_error_no_speech |
Speech detected, no text |
timeout / timed-out
|
pipeline_error_no_response |
Response timed out, possibly network delay or busy service |
stt-* / intent-* / tts*
|
pipeline_error_config |
Voice processing paused, config may need a look |
cloud-auth |
pipeline_error_cloud_auth |
Cloud auth issue, re-login |
wake / duplicate
|
pipeline_error_wake |
Wake signal anomaly, retry |
| (other) | pipeline_error_unknown |
Temporary issue, will retry shortly |
| (HA disconnected) | pipeline_error_ha_disconnected |
Server offline, check network |
| (HA start failed) | pipeline_error_ha_start_failed |
Pipeline init issue, check config |
| (TTS playback) | pipeline_error_tts_playback |
Voice reply playback failed: TTS address timed out, check the address |
| Language | pipeline_error_no_speech |
pipeline_error_tts_playback |
|---|---|---|
| English | Speech detected, no text | Voice reply playback failed: TTS address timed out, check the address |
| Chinese | 检测到语音,但无文本 | 语音回复播放失败:TTS 地址超时请检查地址 |
| German | Sprache erkannt, kein Text | Sprachantwort-Wiedergabe fehlgeschlagen: TTS-Adresse timed out, Adresse prüfen |
| Russian | Речь есть, текста нет | Ошибка воспроизведения голосового ответа: тайм-аут адреса TTS, проверьте адрес |
| Portuguese | Voz detectada, sem texto | Falha na reprodução da resposta por voz: endereço TTS expirou, verifique o endereço |
| Vietnamese | Có giọng nói, không có văn bản | Phát phản hồi giọng nói thất bại: địa chỉ TTS hết thời gian, kiểm tra địa chỉ |
- TTS playback uses
USAGE_MEDIAwithAUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK - When TTS starts, Ava requests audio focus, which may duck other media players
- On TTS completion, audio focus is released, allowing other media to resume
- Non-root Android cannot give TTS a separate volume path, so Ava temporarily writes system media volume (
STREAM_MUSIC) to the TTS level during a reply, then restores the remembered system volume when speech ends - Changing TTS volume (settings or HA entity) during a reply takes effect immediately; the system volume bar shows the live device level, including that temporary write
All TTS-related settings are in Settings → Voice → Voice Replies.
| Setting | Description | Default |
|---|---|---|
| TTS mode | Standard or Streaming | Standard |
| Floating subtitle overlay | Show subtitles in floating window during conversations | Off |
| System volume | Live device media volume; adjustable for comparison; remember-and-restore around TTS | — |
| TTS volume | Level used while speaking; temporarily written to system media volume | 30% |
| Show in Home Assistant | Show a live TTS volume number entity under Configuration in Home Assistant for automations | Off |
| Usage guide | Explains Android limits, comparison, restore, and HA automation examples | — |
AI Hub TTS is a Home Assistant add-on based on the Kokoro model. It is the recommended TTS engine for Ava.
Features:
- Fully offline — no internet required after model download
- 26 high-quality voices
- CPU inference, generation < 1 second
- Wyoming protocol with auto-discovery — HA picks it up automatically
- Memory usage < 500 MB
Installation:
- In Home Assistant: Settings → Add-ons → Add-on Store
- Click ⋮ → Repositories → Add
https://github.com/truemanshum/ai-hub-tts - Refresh and install AI Hub TTS
- First start auto-downloads the model (~500 MB)
- Settings → Voice Assistants → select AI Hub TTS as the TTS engine
Configuration:
voice: af_heart # Voice selection
sample_rate: 24000 # Sample rate
debug: false # Debug modeWith Ava: Works in both Standard and Streaming TTS modes. For Streaming TTS, ensure the HA voice assistant pipeline has streaming output enabled.
By default, Ava rewrites TTS URLs to use the LAN address for faster local playback. In HTTPS setups or reverse-proxy configurations, this rewriting can break playback — the rewritten URL may not be reachable or may fail certificate validation.
Preserve original TTS URL disables the rewriting. Ava plays from the URL exactly as Home Assistant returns it.
Path: Settings → Voice Config → Voice Replies → Use original TTS URL
Ava's TTS volume can be exposed as a number entity in Home Assistant, allowing automations to adjust how loud Ava speaks without touching the device.
| Setting | Description |
|---|---|
| Show in Home Assistant | Expose TTS volume as a number.* entity |
| TTS volume | Level used while speaking; temporarily written to system media volume during TTS, then restored |
Automation example:
# Speak louder at night
service: number.set_value
target:
entity_id: number.your_device_name_tts_volume
data:
value: 60Back to Voice Control
- Quick-Start
- System-Requirements
- Voice-Control
- Chorus-Wake
- ESPHome-Encryption
- HA-Direct-Connection
- Browser
- Screensaver
- Floating-Windows
- Home-Launcher
- Home-Screen-Widgets
- Notification-Scenes
- Quick-Entity
- Sensors
- Backup
- Sendspin
- Bluetooth
- Voice-Messages-Calls
- Music-Playback
- Camera
- Screen-Control
- Intent-Launcher
- ADB-Commands
- Mod-Store
- Ava-Fleet