用Okio创建WAV文件

我的系统需要使用WAV文件数组的字节创建一个WAV文件。 目前它使用Okio在缓冲区中读写数据,然后将数据写入最终文件。

我正在关注这个文件和这个堆栈溢出问题:

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

和…

  • Okio:1.10.0
  • Kotlin: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() } } } 

该文件生成成功,但是当我尝试打开任何媒体播放器上的音频,似乎损坏。

当我试图探索这个音频文件生成的字节,结果是这样的:

字节

我不知道我是否正确地写头,你能帮我解决这个问题吗?

谢谢!

你从哪里得到sampleRate的价值? 您正在编写80 3E 00 00(即16000),但实际上应该是10 00 00 00(即原始PCM格式为16)。

在这个头文件中,你应该写出fmt块的大小。

我希望这能解决你的问题