diff --git a/app/src/main/java/io/bartek/tts/TTS.kt b/app/src/main/java/io/bartek/tts/TTS.kt index d30ade4..f21fb3b 100644 --- a/app/src/main/java/io/bartek/tts/TTS.kt +++ b/app/src/main/java/io/bartek/tts/TTS.kt @@ -15,7 +15,7 @@ data class SpeechData(val stream: InputStream, val size: Long) class TTS(context: Context, initListener: TextToSpeech.OnInitListener) { private val tts = TextToSpeech(context, initListener) - fun performTTS(text: String, language: Locale): SpeechData { + fun fetchTTSStream(text: String, language: Locale): SpeechData { val file = createTempFile("tmp_tts_server", ".wav") val uuid = UUID.randomUUID().toString() @@ -39,6 +39,22 @@ class TTS(context: Context, initListener: TextToSpeech.OnInitListener) { return SpeechData(stream, length) } + + fun performTTS(text: String, language: Locale) { + val uuid = UUID.randomUUID().toString() + val lock = Lock() + tts.setOnUtteranceProgressListener(TTSProcessListener(uuid, lock)) + + synchronized(lock) { + tts.language = language + tts.speak(text, TextToSpeech.QUEUE_ADD, null, uuid) + lock.wait() + } + + if(!lock.success) { + throw TTSException() + } + } } private data class Lock(var success: Boolean = false) : Object() diff --git a/app/src/main/java/io/bartek/web/WebServer.kt b/app/src/main/java/io/bartek/web/WebServer.kt index 51f1e94..40f520b 100644 --- a/app/src/main/java/io/bartek/web/WebServer.kt +++ b/app/src/main/java/io/bartek/web/WebServer.kt @@ -25,6 +25,7 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port), session?.let { return when(it.uri) { "/wave" -> wave(it) + "/say" -> say(it) else -> throw ResponseException(NOT_FOUND, "") } } @@ -51,10 +52,28 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port), } val (text, language) = getRequestData(session) - val (stream, size) = tts.performTTS(text, language) + val (stream, size) = tts.fetchTTSStream(text, language) return newFixedLengthResponse(OK, "audio/x-wav", stream, size) } + private fun say(session: IHTTPSession): Response { + if(!preferences.getBoolean("preference_enable_say_endpoint", true)) { + throw ResponseException(NOT_FOUND, "") + } + + if (session.method != Method.POST) { + throw ResponseException(METHOD_NOT_ALLOWED, "") + } + + if (session.headers["content-type"]?.let { it != "application/json" } != false) { + throw ResponseException(BAD_REQUEST, "") + } + + val (text, language) = getRequestData(session) + tts.performTTS(text, language) + return newFixedLengthResponse(OK, MIME_PLAINTEXT, "") + } + private fun getRequestData(session: IHTTPSession): TTSRequestData { val map = mutableMapOf() session.parseBody(map)