speaker_helper.speaker module
High-level speaker-helper API: text in, speech out.
Module summary
Speaker is the façade most applications use. It wraps a
TTSEngine backend and offers two modes:
offline —
Speaker.say()synthesises the whole text into oneAudioResult, optimising throughput/quality.streaming —
Speaker.stream()splits the text into sentence-sized chunks and yields audio as soon as each is ready, minimising time to first audio (TTFA). Synthesis is pipelined (bounded concurrency) while emission stays strictly in order.
Blocking convenience wrappers (Speaker.say_sync(),
Speaker.save()) are provided for scripts and CLIs that are not already
inside an event loop.
Usage example
>>> from speaker_helper import Speaker
>>> # sync, offline — the simplest possible call:
>>> # Speaker().save("Bonjour le monde.", "hello.wav") # requires Voicebox
- class speaker_helper.speaker.Speaker(settings=None, *, engine=None, stream_concurrency=1)[source]
Bases:
objectTurn text into speech via a pluggable TTS engine, offline or streaming.
The concrete engine (Voicebox, mock, …) is selected by
settings.backendand reached only through theTTSEngineprotocol, soSpeakernever depends on a specific backend.- Parameters:
settings (Settings or None) – Configuration; when
None,Settings.load()is used (reads./settings.yamlif present, thenSPEAKER_HELPER_*env vars).engine (TTSEngine or None) – Inject a ready backend instance (e.g. a mock in tests). When
None(default), one is built fromsettingsviacreate_engine().stream_concurrency (int) – Maximum number of chunks synthesised in parallel in streaming mode. The default of
1(a strict pipeline) gives the lowest time to first audio: the first chunk gets the whole engine to itself, and because kokoro synthesises faster than real time (RTF < 1) each later chunk is ready before playback of the previous one finishes. Raise it only to favour total throughput over first-audio latency.
Examples
>>> from speaker_helper import Speaker, Settings >>> spk = Speaker(Settings.from_mapping({"engine": "kokoro", "language": "fr"})) >>> spk.settings.engine 'kokoro'
- property client: TTSEngine
Backward-compatible alias for
engine.Earlier releases exposed the backend as
speaker.client(it was always a Voicebox client). It is now anyTTSEngine; this alias keeps old call sites working.
- async clone_voice(name=None, samples=None, *, language=None)[source]
Clone a voice and make this speaker synthesise with it.
- Parameters:
name (str or None) – Profile name for the clone (idempotency key). Defaults to the configured clone name, or
"ref-malo".samples (list of VoiceSample or None) – Reference recordings. When
None, they are resolved fromsettings.clone— falling back to the bundled ref-malo reference. A sample without a transcript is transcribed withvocal-helper.language (str or None) – Language of the cloned voice (defaults to the configured language).
- Returns:
The cloned voice/profile id.
- Return type:
Examples
>>> from speaker_helper import Speaker, Settings, VoiceSample >>> spk = Speaker(Settings.from_mapping({"backend": "mock"})) >>> # give only the audio; the transcript is derived automatically: >>> # await spk.clone_voice("malo", [VoiceSample("ref.wav", "")])
- classmethod from_profile(profile, settings=None, *, engine=None)[source]
Build a
Speakerfrom a per-language operating profile.Applies the profile’s language/engine/voice/producer settings and its
stream_concurrency(a consumer-parallelism argument, not aSettingsfield).- Parameters:
profile (LanguageProfile) – The profile to apply (see
speaker_helper.profiles).settings (Settings or None) – Base configuration to derive from;
Noneuses defaults.engine (TTSEngine or None) – Optional injected backend (e.g. a mock in tests).
- Returns:
A speaker configured for the profile’s language.
- Return type:
- classmethod from_route(condition, *, language='fr', settings=None, engine=None, **route_kwargs)[source]
Build a
Speakerfrom a routed operating point.Asks
speaker_helper.router.route()to choose an engine + mode from measured quality↔speed evidence for the given condition ("online_realtime"or"offline"), applies that choice, and forwards the decision’sstream_concurrency.- Parameters:
condition (str) –
"online_realtime"(delay-bounded streaming) or"offline".language (str) – Target language driving the candidate catalogue.
settings (Settings or None) – Base configuration to reconfigure;
Noneuses defaults.engine (TTSEngine or None) – Optional injected backend (e.g. a mock in tests); when given, the routing choice still sets language/mode but this engine is used.
**route_kwargs – Extra
RouteRequestfields (rtf_ceiling,rtf_budget,quality_floor,require_measured_rtf).
- Returns:
A speaker configured for the routed operating point. The chosen
RouteDecisionis attached asspeaker.routefor inspection / logging.- Return type:
- save(text, path, *, language=None)[source]
Synthesise
textand write the WAV topath(blocking).- Parameters:
- Returns:
The synthesised audio (also written to
path).- Return type:
- async say(text, *, language=None)[source]
Synthesise
textinto oneAudioResult(offline mode).- Parameters:
- Returns:
The synthesised audio and its metadata.
- Return type:
- say_sync(text, *, language=None)[source]
Blocking wrapper around
say()for non-async callers.- Parameters:
- Returns:
The synthesised audio.
- Return type:
- Raises:
RuntimeError – If called from within a running event loop (use
await say).
- async stream(text, *, language=None)[source]
Yield audio chunks as they are synthesised (streaming mode).
- Parameters:
- Yields:
StreamChunk – Chunks in order. The first carries
ttfa_s(time to first audio); the last hasis_final=True.- Return type:
Notes
Synthesis is pipelined up to
stream_concurrencychunks at a time so later chunks are produced while earlier ones are being consumed, but emission order matches the text.
- async voices(engine=None)[source]
List preset voices for an engine (defaults to the configured one).
- async warmup()[source]
Prime the engine so the first real request is not the slow one.
Synthesises a tiny throwaway utterance, which forces backend-specific one-time costs (profile bootstrap, model download / load) to happen now rather than on a user’s first call. Failures are logged and swallowed — warm-up is best-effort and must never break startup.
- Return type:
None