Spei-To-Text API-ошибка разбора кодирования файла PCM AudioRecorder - PullRequest
0 голосов
/ 01 июля 2019

Я использую AudioRecord в своем приложении для записи голоса, затем вызываю API преобразования речи в текст с помощью Firebase, но он всегда возвращает неправильное «кодирование».

 val DEFAULT_AUDIO_SOURCE: Int = MediaRecorder.AudioSource.UNPROCESSED
 val DEFAULT_SAMPLE_RATE_HZ: Int = 16_000
 val DEFAULT_CHANNEL_CONFIG: Int = AudioFormat.CHANNEL_IN_MONO
 val DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
 val BUFFER_SIZE: Int = 2*AudioRecord.getMinBufferSize(DEFAULT_SAMPLE_RATE_HZ, DEFAULT_CHANNEL_CONFIG, DEFAULT_AUDIO_FORMAT)

 mAudioRecord = AudioRecord(
                    DEFAULT_AUDIO_SOURCE,
                    DEFAULT_SAMPLE_RATE_HZ,
                    DEFAULT_CHANNEL_CONFIG,
                    DEFAULT_AUDIO_FORMAT,
                    DEFAULT_BUFFER_SIZE)
 val data = ByteArray(file.length().toInt())
 val input = DataInputStream(FileInputStream(file));
 input.read(data);
 input.close();
 val audioContent: String = Base64.encodeToString(data, Base64.NO_WRAP);
 val resp = 
 mApi.transcribe(FirebaseCloudFunctionsModel.Transcribe("LINEAR16", CloudTranslate.DEFAULT_SAMPLE_RATE_HZ, Locale.getDefault().toString(), audioContent)).execute()

1 Ответ

0 голосов
/ 05 июля 2019

Поскольку вы используете PCM 16 бит, запишите звук в буфер ShortArray (его размер должен быть вдвое меньше размера буфера, так как short равен 16 бит или 2 байта), и конвертируйте буфер в ByteArray, используя эту функцию:

private fun short2byte(sData:ShortArray):ByteArray {
  val shortArrsize = sData.size
  val bytes = ByteArray(shortArrsize * 2)
  for (i in 0 until shortArrsize)
  {
    bytes[i * 2] = (sData[i] and 0x00FF).toByte()
    bytes[(i * 2) + 1] = (sData[i] shr 8).toByte()
    sData[i] = 0
  }
  return bytes
}

Google Cloud API использует безопасную URL-кодировку Base64, поэтому добавьте ее в качестве одного из флагов для функции encodeString.

 val audioContent: String = Base64.encodeToString(data,  Base64.URL_SAFE | Base64.NO_WRAP);

Вместо записи аудио в файл, вы можете напрямую записать его вByteArrayOutputStream в памяти, если аудио имеет небольшой размер.

...