Stream audio chunks as they are synthesized, enabling playback to start before the full synthesis completes.
Streaming Synthesis
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
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
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:
// 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() |
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)
| Text Length | Regular Synthesis | Streaming First Audio |
|---|
| 50 chars | ~100ms | ~100ms |
| 200 chars | ~400ms | ~100ms |
| 500 chars | ~1000ms | ~100ms |
| 1000 chars | ~2000ms | ~100ms |