> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runanywhere.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming TTS

> Stream audio synthesis for long text with lower latency

Stream audio chunks as they are synthesized, enabling playback to start before the full synthesis completes.

## Streaming Synthesis

```kotlin theme={null}
val longText = """
    This is a very long text that will be synthesized in chunks.
    Each chunk will be delivered as soon as it's ready,
    allowing playback to start immediately without waiting
    for the entire synthesis to complete.
""".trimIndent()

RunAnywhere.synthesizeStream(
    text = longText,
    options = TTSOptions(rate = 1.0f),
    onAudioChunk = { chunk ->
        // Play each chunk as it arrives
        audioPlayer.enqueue(chunk)
    }
)
```

## Example: Streaming Audio Player

```kotlin theme={null}
class StreamingAudioPlayer {
    private val audioQueue = ConcurrentLinkedQueue<ByteArray>()
    private var isPlaying = false

    fun enqueue(audioChunk: ByteArray) {
        audioQueue.add(audioChunk)
        if (!isPlaying) {
            startPlayback()
        }
    }

    private fun startPlayback() {
        isPlaying = true
        CoroutineScope(Dispatchers.IO).launch {
            while (audioQueue.isNotEmpty() || isPlaying) {
                val chunk = audioQueue.poll()
                if (chunk != null) {
                    playChunk(chunk)
                } else {
                    delay(10) // Wait for more chunks
                }
            }
        }
    }

    private fun playChunk(chunk: ByteArray) {
        // Play audio chunk using AudioTrack
    }

    fun stop() {
        isPlaying = false
        audioQueue.clear()
    }
}
```

## Example: Chat Response with Streaming TTS

```kotlin theme={null}
class ChatViewModel : ViewModel() {
    private val audioPlayer = StreamingAudioPlayer()

    fun sendMessageAndSpeak(prompt: String) {
        viewModelScope.launch {
            // Generate text with streaming
            val streamResult = RunAnywhere.generateStreamWithMetrics(prompt)

            // Collect full response for TTS
            val fullResponse = StringBuilder()
            streamResult.stream.collect { token ->
                fullResponse.append(token)
                _displayText.value += token
            }

            // Stream synthesize the full response
            RunAnywhere.synthesizeStream(
                text = fullResponse.toString(),
                options = TTSOptions(),
                onAudioChunk = { chunk ->
                    audioPlayer.enqueue(chunk)
                }
            )
        }
    }
}
```

## Stop Synthesis

Cancel ongoing synthesis:

```kotlin theme={null}
// Stop synthesis mid-stream
RunAnywhere.stopSynthesis()
```

## When to Use Streaming

| Scenario                     | Recommended          |
| ---------------------------- | -------------------- |
| Short text (under 100 chars) | `synthesize()`       |
| Long text (over 200 chars)   | `synthesizeStream()` |
| Real-time chat responses     | `synthesizeStream()` |
| Pre-cached audio             | `synthesize()`       |

<Tip>
  Streaming synthesis reduces time-to-first-audio for long text: - **Regular synthesis**: Wait for
  full synthesis, then play - **Streaming synthesis**: Start playing after first chunk (\~100ms)
</Tip>

## Performance Characteristics

| Text Length | Regular Synthesis | Streaming First Audio |
| ----------- | ----------------- | --------------------- |
| 50 chars    | \~100ms           | \~100ms               |
| 200 chars   | \~400ms           | \~100ms               |
| 500 chars   | \~1000ms          | \~100ms               |
| 1000 chars  | \~2000ms          | \~100ms               |
