braidio.tts#
ElevenLabs narration synthesis.
Thin wrapper over mixing.text_to_speech() (the ElevenLabs entry point,
with on-disk caching) applying a voice preset: the eleven_multilingual_v2
quality model and a locked voice + settings so a whole production sounds like
one narrator.
Voice defaults to “George — Warm, Captivating Storyteller”; override with the
BRAIDIO_TTS_VOICE env var (VOICE_ENV_VAR) or the voice_id arg.
Module Attributes
The narration model. |
Functions
|
Synthesize |
|
Voice id from arg → |
|
Synthesize a multi-speaker exchange in ONE pass (ElevenLabs Text-to-Dialogue). |
- braidio.tts.DEFAULT_MODEL_ID = 'eleven_v3'#
The narration model. eleven_v3 rather than eleven_multilingual_v2 because v2 cannot render inline [audio tags] AT ALL, and tag density is the main lever on whether a read sounds alive (braidio.style.audio_tag_rate). A v2 default caps every production at the flat end before an author writes a word. Override per-render with
delivery=, or persist your own in ~/.config/braidio/config.json — see braidio.defaults.
- braidio.tts.narrate(text, out_path, *, api_key=None, voice_id=None, model_id='eleven_v3', voice_settings=None, output_format='mp3_44100_128', refresh=False, return_cache_status=False)[source]#
Synthesize
texttoout_path(mp3). Returns the path.Caching is handled by
mixing.text_to_speech(keyed on text+voice+model); passrefresh=Trueto regenerate.api_keyis an optional per-request ElevenLabs key: when given it wins over the environment; whenNone(default) resolution falls back to$ELEVENLABS_API_KEY(unchanged behavior). This is what lets a caller thread a per-user BYO key without touching the process environment.return_cache_status: whenTrue, return(path, was_cached)wherewas_cachedisTrueiff mixing served the audio from its on-disk cache (no ElevenLabs call = $0 real spend). Lets the caller attribute real cost (braidio#8). DefaultFalsekeeps thePathreturn.
- braidio.tts.resolve_voice_id(voice_id=None)[source]#
Voice id from arg →
VOICE_ENV_VARenv → default.- Return type:
- braidio.tts.text_to_dialogue(turns, *, model_id='eleven_v3', output_format='mp3_44100_128', settings=None, seed=None, api_key=None, cache=True, refresh=False, return_cache_status=False)[source]#
Synthesize a multi-speaker exchange in ONE pass (ElevenLabs Text-to-Dialogue).
Unlike per-line
narrate(), this renders the whole conversation together so prosody is conditioned across turns — the key to sounding like people talking to each other rather than alternating monologues (see braidio#1 /docs/research/conversational-vs-narration-tts.md).eleven_v3only.Cached (like
narrate()/mixing.text_to_speech): the result is keyed on the SHA-256 of every parameter that affects the audio (turns, voices, model, settings, seed, format). A cache hit returns the same bytes instantly — no API call, deterministic master, and the basis for partial re-render (change one exchange → only its key changes).cache=True(default) usesDIALOGUE_CACHE_ENV_KEY/ the default cache dir;cache=Falsedisables it; a path uses that dir.refresh=Trueforces a re-render (to re-roll a v3 take). Because v3 is nondeterministic, caching a seedless call freezes one random take — pass aseedfor reproducibility.- Parameters:
turns – ordered
(voice_id, text)pairs (or{"voice_id", "text"}). Keep each request under ~2000 chars total (API limit).settings (
dict|None) – optional model settings dict (e.g.{"stability": 0.45}).return_cache_status (
bool) – whenTrue, return(audio, was_cached)wherewas_cachedisTrueiff the bytes came from the on-disk cache (no ElevenLabs call = $0 real spend) — the same attributionnarrate()offers (braidio#8). DefaultFalsekeeps thebytesreturn.
- Return type:
- Returns:
raw audio bytes in
output_format.