ChatTTS Sampler
The node that turns text into actual sound
- model
- speaker_params
- AUDIO
- DICT
This is the node where the pack actually earns its keep. Everything before it - the loader, the speaker nodes, the text prep - is setup. The Sampler is where a sentence becomes a waveform you can listen to. It takes your MODEL from the loader, a string of text, and (optionally) a speaker's DICT, and emits AUDIO you can preview or save.
The workflow shape you'll end up with: ChatTTSLoader → ChatTTS_SeedBasedSpeaker → ChatTTS_Sampler → PreviewAudio. If you want the same voice to talk, you feed the Sampler the same speaker dict and the same seed. If you want variety, leave the speaker dict unplugged and let it roll a random voice.
The inputs that matter
Three of them actually deserve your attention, and the defaults are decent for all three:
text- the only required input, multiline. This is where you paste what the model reads. Control tags work inline here:[speed_1]–[speed_9]for pace,[laugh]and[laugh_0..2]for laughter,[break_0..7]and[uv_break]/[lbreak]for pauses. Sloppy but effective - you can dial in a bit of character without touching the sampling parameters.seed(default 2) - the reproducibility knob. Same seed plus the same speaker params gives you the same audio, roughly.temperature(0.3),top_P(0.7),top_K(20) - the sampling controls. Keep temperature low-ish; above ~1.0 ChatTTS starts sounding like a radio caught between stations. The defaults are a good starting point and you'll mostly leave them alone.split_batch(0–32, default 0) - set this above 0 for long text and the sampler splits on newlines and processes chunks in batches. If you have a Text Splitter node upstream, its job is precisely to arrange your text into newline-separated chunks for this.
The optional speaker_params DICT is where the voice comes from. It's the output of Seed-Based Speaker, Voice Extractor, or a loaded speaker profile. Skip it and the sampler invents a random speaker for that run.
How it works
Internally it's a thin but careful wrapper. The sampler locks the torch RNG to your seed, generates a speaker embedding if you didn't supply one, then calls ChatTTS's infer() with one notable shortcut: skip_refine_text=True. Stock ChatTTS runs a two-stage pass - a "refine" step that rewrites your text for prosody, then the actual audio inference. This pack skips refine and goes straight to inference, which is faster and still sounds good, but if you're chasing the absolute best prosody you might notice the difference on tricky sentences. Long audio is trimmed of silence where needed, and everything comes back as a standard ComfyUI audio dict at 24 kHz.
Outputs
AUDIO- feed it to ComfyUI's built-inPreviewAudioorSaveAudionodes and you're done.DICT- the run's metadata: the seed used and the speaker embedding. This is what you'd feed into Save Speaker Profile if you hear a voice you want to keep.
What to watch for
The node would rather hand you silence than crash: on a failed run it returns empty audio with the error text inside the metadata dict, so a silent preview isn't necessarily a broken workflow - peek at the DICT. And because this pack pins numpy<2.0.0, a numpy 2.x environment elsewhere can cause import failures; fix those in the environment ComfyUI actually runs on.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| text | STRING | — | |
| speaker_paramsopt | DICT | — | |
| seedopt | INT | 21–4294967295 | — |
| temperatureopt | FLOAT | 0.300–2 | — |
| top_Popt | FLOAT | 0.700–1 | — |
| top_Kopt | INT | 201–100 | — |
| split_batchopt | INT | 00–32 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| AUDIO | AUDIO | — |
| DICT | DICT | — |