Skip to main content

Streaming and long text

generate_stream() yields audio after each text chunk instead of waiting for the full input. This lowers time to first audio and lets an application play or store chunks incrementally.

from kittentts import KittenTTS

tts = KittenTTS("KittenML/kitten-tts-mini-0.8")

for chunk in tts.generate_stream(
long_text,
voice="Bruno",
speed=1.0,
clean_text=True,
):
audio = chunk.squeeze()
send_to_player(audio, sample_rate=24_000)

Save the complete stream

import numpy as np
import soundfile as sf

chunks = [
chunk.squeeze()
for chunk in tts.generate_stream(long_text, voice="Bruno")
]

full_audio = np.concatenate(chunks)
sf.write("chapter.wav", full_audio, 24_000)

Chunking behavior

The SDK normalizes the text when clean_text=True, then divides it at sentence boundaries with a target maximum of 400 characters. Each chunk is inferred separately.

For predictable narration:

  • Pass complete sentences with punctuation.
  • Start playback as soon as the first chunk is ready.
  • Serialize playback so later chunks do not interrupt earlier ones.
  • Keep the same voice and speed across a stream.
  • Concatenate arrays on the sample axis after calling squeeze() when saving.

This is generation streaming, not a continuous network stream. The generator performs one local ONNX inference per chunk.