speaker_helper.backends.chatterbox module
Chatterbox: a voice library, an emotion dial, and cloning from a sample.
Module summary
Where kokoro reads with one of 54 fixed
voices, Chatterbox renders from a reference recording and takes an
exaggeration dial that maps well onto what a document means by “say this
cheerfully”. It is the backend to reach for when the request is “sound like
this person” or “sound like you mean it”, and the wrong one for “read me this
article” — it pulls torch, and a reader who wants a page read aloud should not
have to install a deep-learning stack to get it.
Two dials, and what they are for
exaggeration (0–2, neutral at 0.5) carries emotion. cfg_weight carries
stability: higher is more predictable, lower lets the model vary. They are
driven from the segment’s emotion/intensity and pace respectively,
because those are the words a document uses — a float in a config file says
nothing about why it is that value.
- class speaker_helper.backends.chatterbox.ChatterboxEngine(settings)[source]
Bases:
objectThe Chatterbox backend: cloning, and an emotion dial.
- Parameters:
settings (Settings) –
voice_samplenames a reference recording to clone; without one the model’s default speaker reads.
- async clone_voice(name, samples, *, language=None)[source]
Adopt the first sample as the reference this engine renders from.
There is no enrolment step and nothing to store on a server: the model conditions on the recording at generation time. So “cloning” here is remembering which file to pass, and the honest return value is the path rather than an invented voice id.
- Parameters:
name (str)
samples (list[VoiceSample])
language (str | None)
- Return type:
- async health()[source]
Whether this engine could synthesise, without loading the model.
- Return type:
- async list_voices(engine=None)[source]
One entry, and it is honest about what it is.
This engine has no catalogue: it renders from a reference recording or from its default speaker. Returning an empty list would read as “not loaded yet”; returning a fake catalogue would be worse.
- async synthesize(text, *, language=None, voice=None, speed=1.0, emotion='neutral', intensity='')[source]
Synthesise one piece of text.
speedis read as a pace and turned intocfg_weight: this model has no speed multiplier, and pretending otherwise by resampling the output would change the pitch along with the rate.
- speaker_helper.backends.chatterbox.EMOTION_EXAGGERATION_BASE: dict[str, float] = {'angry': 1.2, 'calm': 0.4, 'cautious': 0.45, 'cheerful': 0.8, 'contemplative': 0.4, 'enthusiastic': 1.0, 'friendly': 0.7, 'neutral': 0.5, 'sad': 0.35, 'terrified': 1.1, 'warm': 0.65, 'whispering': 0.2}
emotion→ the neutral-relative base of the exaggeration dial. 0.5 is ordinary conversational delivery; the intensity scales the distance from it.
- speaker_helper.backends.chatterbox.PACE_CFG_WEIGHT: dict[str, float] = {'fast': 0.3, 'normal': 0.5, 'slow': 0.7}
pace→cfg_weight. Higher is more stable and predictable, lower more expressive. Slow reading wants stability; fast reading can afford variation without sounding careless.
- speaker_helper.backends.chatterbox.SAMPLE_RATE_HZ: int = 24000
ChatterboxTTS’s native sample rate (24 kHz mono) — the same as Kokoro’s, which is why a narration can mix engines without resampling.
- speaker_helper.backends.chatterbox.check_install()[source]
Return 0 when
chatterboxis importable, 1 otherwise.Two module names are tried because the distribution has shipped under both; which one a given install exposes is not something a caller should have to know.
- Return type:
- speaker_helper.backends.chatterbox.emotion_to_exaggeration(emotion, intensity)[source]
Map an
emotionand anintensityonto the engine’s dial.Clamped to
[0, 2]so a hallucinated intensity from a model never blows the dial — the kind of input that arrives as2.7and comes back as a scream.- Parameters:
emotion (str) – A key of
EMOTION_EXAGGERATION_BASE; anything else is neutral.intensity (float) –
0.0flat …1.0full effect.0.5means “use the base”, below pulls towards neutral, above pushes past it.
- Return type: