play method generates speech and streams it to the device speakers frame-by-frame as it is generated.
Basic Usage
Playback Strategies
You can control how much audio is buffered before playback begins:Auto (Default)
Measures the first generation step and pre-buffers just enough to avoid underruns:- Start generation without starting the audio engine
- Measure the time for the first decoding step
- Compute required buffer:
buffer = stepTime * maxNewTokens - audioPerStep - Accumulate audio until buffer threshold is met
- Start playback
The auto strategy is recommended for most use cases. It balances latency and smoothness.
Stream
Start playing as soon as the first frame arrives (lowest latency):Buffered
Pre-buffer a fixed duration before starting playback:Generate First
Generate all audio before playing anything (highest latency, but allows concurrent chunk generation):concurrentWorkerCount > 1, since playback doesn’t start until all chunks are ready.
Voices and Languages
All voice and language options work withplay:
Generation Options
All generation options are supported:For streaming strategies (
.auto, .stream, .buffered), chunking is forced to sequential (concurrentWorkerCount = 1) so frames can be enqueued in order. .generateFirst respects the caller’s concurrency setting.Progress Callbacks
Receive per-step updates during playback:SpeechProgress with the same fields as in generation callbacks.
Playback Control
TheAudioOutput class manages playback:
Audio Format
TTSKit outputs mono PCM Float32 audio at 24 kHz:Crossfading
When generating long text with chunking, audio chunks are automatically crossfaded at boundaries:AudioOutput.crossfade method uses equal-power curves (cos/sin) to preserve energy through the overlap region.
Edge Fading
The audio output applies automatic fade-in/fade-out at discontinuities:- Fade-in: Applied at the start of playback, start of a chunk, or after an underrun
- Fade-out: Applied at the end of playback, end of a chunk, or before an underrun
Underrun Detection
The audio output detects underruns using wall-clock timing:- Track when all scheduled audio should finish playing (
expectedPlaybackEnd) - If current time >
expectedPlaybackEnd, the player has drained - Apply fade-out to the last frame before the gap
- Apply fade-in to the next frame after the gap
iOS Audio Session
On iOS, the audio session is automatically configured for playback:Example: Real-Time Streaming
Here’s a complete example with progress updates and playback control:Platform Support
- macOS: Full support for all playback strategies
- iOS: Full support for all playback strategies
- watchOS: M4A export not available, use WAV format
Next Steps
Generation
Learn about generation options and chunking
Voices & Languages
Explore available voices and language support