SpeechSynthesizer

class SpeechSynthesizer : Closeable


Performs on-device text-to-speech audio synthesis.

One client serves every language. SpeechSynthesizerOptions only supplies a default locale; pass a locale to getSupportedVoices to list another language's voices, and the rest of the API follows the VoiceInfo you hand it. There is no reason to close and rebuild the client, or to keep one instance per language — both pay for a Binder reconnect and buy nothing.

Typical usage:

// 1. Create a SpeechSynthesizer with desired options.
val options: SpeechSynthesizerOptions =
speechSynthesizerOptions(Locale.US) {
// Optionally configure a background executor
// setExecutor(myExecutor)
// Optionally fail instead of substituting a voice that is not installed
// setVoiceFallbackEnabled(false)
}
val speechSynthesizer: SpeechSynthesizer = SpeechSynthesis.getClient(options)

// 2. Find a supported voice and check its status.
lifecycleScope.launch {
try {
// Defaults to the options locale. Pass one to switch language:
// speechSynthesizer.getSupportedVoices(Locale.FRANCE)
val supportedVoices: List<VoiceInfo> = speechSynthesizer.getSupportedVoices()
val voiceToUse: VoiceInfo? =
supportedVoices.firstOrNull { it.gender == VoiceInfo.Gender.FEMALE }

if (voiceToUse != null) {
val status: Int = speechSynthesizer.checkStatus(voiceToUse)
if (status == FeatureStatus.DOWNLOADABLE) {
// 3. If needed, download the voice model.
speechSynthesizer.download(voiceToUse).collect { downloadStatus ->
when (downloadStatus) {
is DownloadStatus.DownloadCompleted -> {
// Model is ready, start synthesis.
startMySynthesis(speechSynthesizer, voiceToUse)
}
is DownloadStatus.DownloadFailed -> {
// Handle download failure.
}
is DownloadStatus.DownloadProgress -> {
// Handle download progress.
}
else -> {}
}
}
} else if (status == FeatureStatus.AVAILABLE) {
// Model is ready, start synthesis.
startMySynthesis(speechSynthesizer, voiceToUse)
} else {
// Handle other statuses like DOWNLOADING or UNAVAILABLE.
}
}
} finally {
// 5. Release resources. Closing outside the coroutine would tear down the client
// while the work above is still in flight.
speechSynthesizer.close()
}
}

// 4. Define your synthesis logic.
suspend fun startMySynthesis(synthesizer: SpeechSynthesizer, voice: VoiceInfo) {
// Create a request and collect the responses.
val request = SpeechSynthesizerRequest(
input = SpeechSynthesizerRequest.Input.Text("Hello, world!", voice),
audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
synthesizer.synthesize(request).collect { response ->
// Process the responses.
when (response) {
is SpeechSynthesizerResponse.StatusUpdate -> {
when (response.status) {
SpeechSynthesizerResponse.Status.START -> { /* Started playing */}
SpeechSynthesizerResponse.Status.DONE -> { /* Playback finished */}
else -> {}
}
}
is SpeechSynthesizerResponse.AudioAvailable -> {
// Handle a chunk of synthesized audio
}
is SpeechSynthesizerResponse.Error -> {
// Handle synthesis error. With setVoiceFallbackEnabled(false), a voice that
// is not installed arrives here as ERROR_NOT_INSTALLED_YET.
}
}
}
}

Summary

Public functions

suspend @FeatureStatus Int
checkStatus(voiceInfo: VoiceInfo)

Checks the availability status of a specific VoiceInfo.

open Unit

Releases resources used by this SpeechSynthesizer.

Flow<DownloadStatus>
download(voiceInfo: VoiceInfo)

Downloads the model assets required for speech synthesis with the specified VoiceInfo.

suspend List<VoiceInfo>

Returns the voices supported for locale, defaulting to the locale configured in SpeechSynthesizerOptions.

Unit

Stops any active or pending speech synthesis.

Flow<SpeechSynthesizerResponse>

Synthesizes the input text from SpeechSynthesizerRequest into spoken audio.

Public functions

checkStatus

suspend fun checkStatus(voiceInfo: VoiceInfo): @FeatureStatus Int

Checks the availability status of a specific VoiceInfo.

Returns
@FeatureStatus Int

A FeatureStatus indicator representing the status of the voice.

close

open fun close(): Unit

Releases resources used by this SpeechSynthesizer.

Subsequent calls are no-ops.

download

fun download(voiceInfo: VoiceInfo): Flow<DownloadStatus>

Downloads the model assets required for speech synthesis with the specified VoiceInfo.

Returns
Flow<DownloadStatus>

A Flow of DownloadStatus emitting progress updates and the download outcome.

getSupportedVoices

suspend fun getSupportedVoices(locale: Locale = options.locale): List<VoiceInfo>

Returns the voices supported for locale, defaulting to the locale configured in SpeechSynthesizerOptions.

Passing a locale here is cheaper than building a second SpeechSynthesizer: the platform engine and the service connection are locale-independent, so a single instance can serve every language an app needs. Results are cached per locale for the lifetime of the instance.

Parameters
locale: Locale = options.locale

the locale to list voices for. A locale without a country (for example Locale.FRENCH) matches every region of that language.

stop

fun stop(): Unit

Stops any active or pending speech synthesis.

synthesize

fun synthesize(request: SpeechSynthesizerRequest): Flow<SpeechSynthesizerResponse>

Synthesizes the input text from SpeechSynthesizerRequest into spoken audio.

Parameters
request: SpeechSynthesizerRequest

The SpeechSynthesizerRequest containing the text input and synthesis configurations.

Returns
Flow<SpeechSynthesizerResponse>

A Flow of SpeechSynthesizerResponse emitting audio data chunks and playback lifecycle updates.