[Android] 013. 合成音声(TextToSpeech)

合成音声をサクッと試します
詳細は以下
https://developer.android.com/reference/android/speech/tts/TextToSpeech

val context = LocalContext.current
var tts by remember { mutableStateOf<TextToSpeech?>(null) }
var text by remember { mutableStateOf("こんにちわ") }

LaunchedEffect(Unit) {
    tts = TextToSpeech(context) {
        if (it == TextToSpeech.SUCCESS) {
            tts?.apply {
                language = Locale.JAPANESE
                setSpeechRate(1.0f)
                setPitch(1.0f)
            }
        }
    }
}
DisposableEffect(Unit) {
    onDispose {
        tts?.shutdown()
    }
}

Column {
    TextField(value = text, onValueChange = { text = it })
    Button(onClick = {
        tts?.speak(text, TextToSpeech.QUEUE_FLUSH, null, null)
    }) {
        Text("speak")
    }
}

合成再生完了などイベントをハンドリングしたい場合(同期再生などをしたい場合など)はOnUtteranceProgressListenerを設定します

if (it == TextToSpeech.SUCCESS) { tts?.apply { の後に追加してください

// speakのutteranceIdを設定した場合のみイベントが発生します
val result = setOnUtteranceProgressListener(object: UtteranceProgressListener() {
    override fun onStart(utteranceId: String?) {
        Log.d("App", "onDone: $utteranceId")
    }

    override fun onStop(utteranceId: String?, interrupted: Boolean) {
        super.onStop(utteranceId, interrupted)
        Log.d("App", "onStop: $utteranceId $interrupted")
    }

    override fun onDone(utteranceId: String) {
        Log.d("App", "onDone: $utteranceId")
    }

    // deprecatedだがabstract...
    override fun onError(utteranceId: String?) {}

    override fun onError(utteranceId: String?, errorCode: Int) {
        super.onError(utteranceId, errorCode)
        Log.d("App", "onError: $utteranceId $errorCode")
    }

    override fun onAudioAvailable(utteranceId: String?, audio: ByteArray?) {
        super.onAudioAvailable(utteranceId, audio)
        Log.d("App", "onAudioAvailable: $utteranceId")
    }

    override fun onBeginSynthesis(utteranceId: String?, sampleRateInHz: Int, audioFormat: Int, channelCount: Int) {
        super.onBeginSynthesis(utteranceId, sampleRateInHz, audioFormat, channelCount)
        Log.d("App", "onBeginSynthesis: $utteranceId")
    }

    override fun onRangeStart(utteranceId: String?, start: Int, end: Int, frame: Int) {
        super.onRangeStart(utteranceId, start, end, frame)
        Log.d("App", "onRangeStart: $utteranceId")
    }
})
Log.d("App", "setOnUtteranceProgressListener = $result")

Android Studio Giraffe 2022.3.1 built on June 29, 2023