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.

Author

Warith HARCHAOUI — https://linkedin.com/in/warith-harchaoui

class speaker_helper.backends.chatterbox.ChatterboxEngine(settings)[source]

Bases: object

The Chatterbox backend: cloning, and an emotion dial.

Parameters:

settings (Settings) – voice_sample names a reference recording to clone; without one the model’s default speaker reads.

async aclose()[source]

Drop the model so torch can free it.

Return type:

None

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:
Return type:

str

async health()[source]

Whether this engine could synthesise, without loading the model.

Return type:

dict

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.

Parameters:

engine (str | None)

Return type:

VoiceList

async synthesize(text, *, language=None, voice=None, speed=1.0, emotion='neutral', intensity='')[source]

Synthesise one piece of text.

speed is read as a pace and turned into cfg_weight: this model has no speed multiplier, and pretending otherwise by resampling the output would change the pitch along with the rate.

Parameters:
Return type:

AudioResult

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 chatterbox is 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:

int

speaker_helper.backends.chatterbox.emotion_to_exaggeration(emotion, intensity)[source]

Map an emotion and an intensity onto 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 as 2.7 and comes back as a scream.

Parameters:
  • emotion (str) – A key of EMOTION_EXAGGERATION_BASE; anything else is neutral.

  • intensity (float) – 0.0 flat … 1.0 full effect. 0.5 means “use the base”, below pulls towards neutral, above pushes past it.

Return type:

float