Skip to content
KugelAudioDocs

Generate Speech

One-shot speech generation, generation parameters, word timestamps, models, and audio utilities

Basic generation

Generate complete audio and receive it all at once:

audio = client.tts.generate(
    text="Hello, this is a test of the KugelAudio text-to-speech system.",
    model_id="kugel-3.5",
    voice_id=1071,
    language="en",
)

# Audio properties
print(f"Duration: {audio.duration_seconds:.2f}s")
print(f"Samples: {audio.samples}")
print(f"Sample rate: {audio.sample_rate} Hz")
print(f"Generation time: {audio.generation_ms:.0f}ms")
print(f"RTF: {audio.rtf:.2f}")  # Real-time factor

# Save to WAV file
audio.save("output.wav")

# Get raw PCM bytes
pcm_data = audio.audio

# Get WAV bytes (with header)
wav_bytes = audio.to_wav_bytes()

# Get float32 samples in [-1.0, 1.0]
samples = audio.to_float32()

# Save raw PCM instead of WAV
audio.save("output.pcm", format="raw")

The float, WAV and decoding helpers expect PCM16 output. For ulaw_8000 or alaw_8000, use the audio bytes as raw G.711 data. The Rust, C++ and Dart WAV helpers also write G.711 audio as a G.711 WAV file.

Pass numeric voice IDs. To use a voice handle, resolve it with GET /v1/voices/{handle} and pass its id.

Generation parameters

What each parameter does, with defaults and ranges, is documented once in Generation parameters. The SDKs take the same parameters on generation and on one-shot streaming:

Snake_case keyword arguments on generate(), generate_async(), stream(), and stream_async():

text, model_id, voice_id, cfg_scale, temperature, max_new_tokens, sample_rate, output_format, normalize, language, word_timestamps, speed, dictionary_ids, project_id.

  • voice_id defaults to None in the signature, but synthesis fails with MISSING_VOICE_ID without it.
  • temperature=None leaves the value unset so the server applies its default.
  • Without project_id, a project API key applies its own project's dictionaries; set project_id to use another project's. See Dictionaries at synthesis.

Async generation

import asyncio

async def main():
    audio = await client.tts.generate_async(
        text="Async generation example.",
        model_id="kugel-3.5",
        voice_id=1071,
    )
    audio.save("async_output.wav")

asyncio.run(main())

Playing audio in the browser

Not applicable: the Python SDK runs on your server. Save the audio or forward its bytes to your client.

Word timestamps

Request word-level time alignments alongside audio, for subtitle synchronization, lip-sync, or barge-in handling. For timestamps while streaming, see Word timestamps in streaming.

audio = client.tts.generate(
    text="Hello, how are you today?",
    model_id="kugel-3.5",
    voice_id=1071,
    word_timestamps=True,
)

# Access word timestamps from the response
for ts in audio.word_timestamps:
    print(f"{ts.word}: {ts.start_ms}ms - {ts.end_ms}ms (score: {ts.score:.2f})")

# Example output:
# Hello: 0ms - 320ms (score: 1.00)
# how: 350ms - 480ms (score: 1.00)
# are: 500ms - 580ms (score: 1.00)
# you: 600ms - 720ms (score: 1.00)
# today: 750ms - 1100ms (score: 1.00)

# Word timestamps are also available with async generation
audio = await client.tts.generate_async(
    text="Hello, world!",
    model_id="kugel-3.5",
    voice_id=1071,
    word_timestamps=True,
)
for ts in audio.word_timestamps:
    print(f"{ts.word}: {ts.start_ms}-{ts.end_ms}ms")

Models

List the available models:

models = client.models.list()

for model in models:
    print(f"{model.id}: {model.name}")
    print(f"  Description: {model.description}")
    print(f"  Max Input: {model.max_input_length} characters")
    print(f"  Sample Rate: {model.sample_rate} Hz")

Audio utilities

Helpers for converting and saving audio outside a response object:

The conversions live on the response objects: AudioResponse.save(), to_wav_bytes(), to_float32(), and AudioChunk.to_float32(). See AudioResponse.

Next steps