Создание WAV-файла с помощью Okio

Моя система должна создать один WAV-файл, используя байты массива WAV-файлов. В настоящее время он использует Okio для чтения и записи данных о буферах, а затем записывает данные в окончательный файл.

Я следую этому документу, и этот вопрос переполнения стека:

  • http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf
  • https://stackoverflow.com/a/12370312/2430555

а также…

  • Окио: 1.10.0
  • Котлин: 1.0.2-1
  • Java: 1.7

Я создал этот код:

fun mixAudios() { try { //Create the file used to storage the mixed audio file. val file = File(directory, finalFileName) //Open the buffer for this file. val bufferedSink = Okio.buffer(Okio.appendingSink(file)) //Data header of the file. val header = Buffer() //Data of the file. val data = Buffer() //Do a action for every audio. audios.forEach { //Try to read the file, if success, return the file. Okio.buffer(Okio.source(File(it.address)))?.let { file -> //Create a new buffer for every audio address. val buffer = Buffer() //Read every byte on the buffer. file.readAll(buffer) //Remove the first 44 items of the buffer. buffer.readByteArray(44) //Get the buffer and write every byte on the sink. data.writeAll(buffer) //Close the sink. buffer.close() file.close() } } //Count of bytes on the data buffer. val fileSize = data.size().toInt() //The data is ready to be written on the sink. data.close() val totalFileSize = fileSize + 36 val byteRate = (SAMPLE_RATE * CHANNELS * BYTES_PER_SAMPLE) / 8 //Write the header of the final file. header.writeUtf8("RIFF") //Write the total file size (with the header) .writeByte(totalFileSize and 0xff) .writeByte((totalFileSize shr 8) and 0xff) .writeByte((totalFileSize shr 16) and 0xff) .writeByte((totalFileSize shr 24) and 0xff) // .writeIntLe(fileSize) //Inform the size of the chunk, including the header. .writeUtf8("WAVE") //Inform the type of file. .writeUtf8("fmt ") //Add the "fmt" letters .writeIntLe(samplingRate) //fmt chunk .writeByte(AUDIO_FORMAT_PCM) //This byte represents the audio format (PCM). .writeByte(0) .writeByte(CHANNELS) //This byte represents the channels of the audio. .writeByte(0) //Write the sample rate .writeByte(SAMPLE_RATE and 0xff) .writeByte((SAMPLE_RATE shr 8) and 0xff) .writeByte((SAMPLE_RATE shr 16) and 0xff) .writeByte((SAMPLE_RATE shr 24) and 0xff) // .writeIntLe(SAMPLE_RATE) //The sample rate of the audio //Write the byte rate .writeByte(byteRate and 0xff) .writeByte((byteRate shr 8) and 0xff) .writeByte((byteRate shr 16) and 0xff) .writeByte((byteRate shr 24) and 0xff) // .writeIntLe((SAMPLE_RATE * CHANNELS * BYTES_PER_SAMPLE) / 8) //Byte rate .writeByte(CHANNELS * BYTES_PER_SAMPLE / 8) //Block align .writeByte(0) .writeByte(BYTES_PER_SAMPLE) //Bytes per sample .writeByte(0) .writeUtf8("data") //File content size .writeByte(fileSize and 0xff) .writeByte((fileSize shr 8) and 0xff) .writeByte((fileSize shr 16) and 0xff) .writeByte((fileSize shr 24) and 0xff) // .writeIntLe(fileSize) .close() with (bufferedSink) { writeAll(header) writeAll(data) close() //Close and write the file on the memory. } //Do the rest... } catch (e: Exception) { if (debugEnabled) { e.printStackTrace() } } } 

Файл генерируется с успехом, но когда я пытаюсь открыть этот звук на любом медиаплеере, он кажется поврежденным.

Когда я пытаюсь исследовать байты этого аудиофайла, результат выглядит примерно так:

байтов

Я не знаю, правильно ли пишу заголовок, можете ли вы помочь мне решить эту проблему?

Спасибо!

Откуда вы получаете значение для sampleplingRate? Вы пишете 80 3E 00 00 (т.е. 16000), но на самом деле это должно быть 10 00 00 00 (т.е. 16 для формата необработанного формата PCM).

В этот момент в заголовке вы должны записать размер фрагмента fmt.

Я надеюсь, что это решает вашу проблему