Я пытаюсь создать движок TTS для службы TTS, работающей локально в моей сети.
Я использовал ИИ для создания основ и настройки движка с системой Android. Но я не могу заставить TTS нормально работать при использовании его для чтения текста в программе для чтения книг.
Я использую следующий сервер: https://github.com/travisvn/chatterbox-tts-api
Служба, которую я использую, возвращает файлы WAV, которые работают нормально. Но при их фрагментировании для добавления в TTS я продолжаю получать искажения и искаженный текст (например, отсутствие звука на старых ЭЛТ-телевизорах). Единственное, о чем я могу думать, это разбиение аудио при передаче к системному обработчику.
Вот основной цикл кода:
// This function is called when apps ask to convert TTS
// callback is an injected object to interact with the app asking for the TTS
override fun onSynthesizeText(
request: SynthesisRequest?,
callback: SynthesisCallback
) {
val text = request?.charSequenceText?.toString()
if (text.isNullOrEmpty()) {
callback.error()
return
}
runBlocking(Dispatchers.IO) {
try {
when (val result = repository.generateSpeech(text)) {
is TtsRepository.TtsResult.Success -> {
val audioData = result.audioData
val inputStream = audioData.byteStream()
// reading the WAV header
val headerBytes = ByteArray(44)
inputStream.read(headerBytes)
val wavInfo = parseWavHeader(headerBytes)
// finding the audio format, mostly for debugging
val audioFormat = when (wavInfo.bitsPerSample) {
8 -> AudioFormat.ENCODING_PCM_8BIT
16 -> AudioFormat.ENCODING_PCM_16BIT
24 -> AudioFormat.ENCODING_PCM_24BIT_PACKED
32 -> AudioFormat.ENCODING_PCM_32BIT
else -> AudioFormat.ENCODING_PCM_16BIT
}
val channelConfig = when (wavInfo.channels) {
1 -> 1 // AudioFormat.CHANNEL_OUT_FRONT_LEFT or AudioFormat.CHANNEL_OUT_FRONT_RIGHT
else -> AudioFormat.CHANNEL_CONFIGURATION_INVALID
}
callback.start(wavInfo.sampleRate, audioFormat, channelConfig)
Log.d(TAG, "TTS request started: ${wavInfo.sampleRate}Hz, ${wavInfo.channels}ch, ${wavInfo.bitsPerSample}bit")
val maxBufferSize = callback.maxBufferSize // {
callback.error()
}
}
} catch (e: Exception) {
callback.error()
}
}
}
Известен ли способ обработки фрагментов? Я попробовал проверить в Интернете, но не смог найти четкого объяснения. Эта проблема возникает только с частью TTS, так как воспроизведение файла WAV нормально работает в ExoPlayer.
Редактировать:
Значение «1» — это просто количество каналов, оно принимает либо 2, либо 1, и Я просто жестко запрограммировал его на 1, так как это то, что отправляет моя служба TTS.
Сначала 44 байта считываются из аудиопотока, поэтому они пропускаются здесь:
Я пытаюсь создать движок TTS для службы TTS, работающей локально в моей сети. Я использовал ИИ для создания основ и настройки движка с системой Android. Но я не могу заставить TTS нормально работать при использовании его для чтения текста в программе для чтения книг. Я использую следующий сервер: https://github.com/travisvn/chatterbox-tts-api Служба, которую я использую, возвращает файлы WAV, которые работают нормально. Но при их фрагментировании для добавления в TTS [b]я продолжаю получать искажения и искаженный текст[/b] (например, отсутствие звука на старых ЭЛТ-телевизорах). Единственное, о чем я могу думать, это [b]разбиение аудио[/b] при передаче к системному обработчику. Вот основной цикл кода: [code]// This function is called when apps ask to convert TTS // callback is an injected object to interact with the app asking for the TTS override fun onSynthesizeText( request: SynthesisRequest?, callback: SynthesisCallback ) { val text = request?.charSequenceText?.toString() if (text.isNullOrEmpty()) { callback.error() return }
runBlocking(Dispatchers.IO) { try { when (val result = repository.generateSpeech(text)) { is TtsRepository.TtsResult.Success -> { val audioData = result.audioData val inputStream = audioData.byteStream() // reading the WAV header val headerBytes = ByteArray(44) inputStream.read(headerBytes) val wavInfo = parseWavHeader(headerBytes) // finding the audio format, mostly for debugging val audioFormat = when (wavInfo.bitsPerSample) { 8 -> AudioFormat.ENCODING_PCM_8BIT 16 -> AudioFormat.ENCODING_PCM_16BIT 24 -> AudioFormat.ENCODING_PCM_24BIT_PACKED 32 -> AudioFormat.ENCODING_PCM_32BIT else -> AudioFormat.ENCODING_PCM_16BIT }
val channelConfig = when (wavInfo.channels) { 1 -> 1 // AudioFormat.CHANNEL_OUT_FRONT_LEFT or AudioFormat.CHANNEL_OUT_FRONT_RIGHT else -> AudioFormat.CHANNEL_CONFIGURATION_INVALID }
[/code] Известен ли способ обработки фрагментов? Я попробовал проверить в Интернете, но не смог найти четкого объяснения. Эта проблема возникает только с частью TTS, так как воспроизведение файла WAV нормально работает в ExoPlayer. Редактировать: [list] [*]Пример аудио: https://afilehost.com/EBnkmWYrzR0y.
[*]Значение «1» — это просто количество каналов, оно принимает либо 2, либо 1, и Я просто жестко запрограммировал его на 1, так как это то, что отправляет моя служба TTS.
[*]Сначала 44 байта считываются из аудиопотока, поэтому они пропускаются здесь: [code]val headerBytes = ByteArray(44) inputStream.read(headerBytes) [/code] так что с ними не должно быть проблем.
[*]вот функция parseWavHeader: [code]private fun parseWavHeader(header: ByteArray): WavAudioInfo { val buffer = ByteBuffer.wrap(header).order(ByteOrder.LITTLE_ENDIAN)
val chunkId = String(header, 0, 4) require(chunkId == "RIFF") { "Not a valid WAV file" }
val format = String(header, 8, 4) require(format == "WAVE") { "Not a WAV file" }
val subChunk1Id = String(header, 12, 4) require(subChunk1Id == "fmt ") { "Invalid WAV format chunk" }
val audioFormat = buffer.getShort(20).toInt() require(audioFormat == 1) { "Only PCM format supported, got: $audioFormat" }
val numChannels = buffer.getShort(22).toInt() val sampleRate = buffer.getInt(24) val byteRate = buffer.getInt(28) val blockAlign = buffer.getShort(32).toInt() val bitsPerSample = buffer.getShort(34).toInt()
val subChunk2Id = String(header, 36, 4) Log.d(TAG, "subChunk =$subChunk2Id") //require(subChunk2Id == "data") { "Invalid WAV data chunk" } //