У меня есть сырые файлы PCM, сгенерированные из строки base64. Вот ссылка на ответ API, который возвращается. .
Затем я создаю файл PCM из этой строки, после чего преобразую его в MP3, используя библиотеку LAME.
Вот код, который относится к конвертации:
companion object {
init {
System.loadLibrary("mp3lame")
}
}
private external fun initEncoder(numChannels: Int, sampleRate: Int, bitRate: Int, mode: Int, quality: Int)
private external fun destroyEncoder()
private external fun encodeFile(sourcePath: String, targetPath: String): Int
val NUM_CHANNELS = 1
val SAMPLE_RATE = 16000
val BITRATE = 128
val MODE = 3
val QUALITY = 0
fun createAudioFromBase64AndGetPath(inputBase64: String, outputFileName: String) {
initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY)
val path: String = "newFile.wav"
try {
val decoded = Base64.decode(inputBase64, Base64.NO_WRAP)
try {
val fileRaw = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.pcm")
val fileEncoded = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.mp3")
val os = FileOutputStream(fileRaw, true)
os.write(decoded)
os.close()
val result = encodeFile(fileRaw!!.absolutePath, fileEncoded!!.absolutePath)
if (result == 0) {
Log.d ("encoded to ", fileEncoded!!.name)
}
destroyEncoder()
} catch (e: Exception) {
Log.e ("decode ", "first catch", e)
e.printStackTrace()
}
} catch (e: Exception) {
e.printStackTrace()
Log.d ("decode ", "2nd catch", e)
}
}
Звук звучит как this.
Я пробовал перемещаться по файлам библиотеки C, которые объясняют, что означают различные параметры переменных для initEncoder , и я возился, но ничего не изменилось.
Чтобы попытаться устранить эту проблему без задержки компиляции приложения каждый раз, я взял строку base64 и преобразовал ее в файл PCM с помощью онлайн-конвертера (Motobit). Затем я использовал очень изящный (и бесплатный) конвертер для Mac под названием XLD, чтобы протестировать эти преобразования без необходимости каждый раз компилировать приложение, чтобы посмотреть, смогу ли я выяснить, что происходит, и, возможно, я просто использовал неправильную комбинацию переменные для initEncoder.
Первое, что я заметил, было то, что мне пришлось выбрать опцию «Open raw PCM (bin + cue) ...», чтобы открыть файл pcm, загруженный с motobit.
Вот окно выбора.
Следующая часть головоломки, которая, кажется, является решающей, заключалась в том, что мне удалось только правильно преобразовать звук (без шума) при выборе «Little» в поле «Endian». Проблема в том, что в моем приложении я не могу узнать, как или даже могу ли я получить доступ и изменить это свойство в библиотеке LAME.
Для ясности я использую обертку отсюда: https://developer.samsung.com/technical-doc/view.do?v=T000000090