2016-08-30 81 views
0

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

我下面的这个文件,这个堆栈溢出问题:

和...

  • 奥基奥: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() 
     } 
     } 
    } 

文件被成功生成,但是当我尝试打开任何媒体播放这段音频,似乎已损坏。

当我尝试探索产生此音频文件的字节数,结果是这样的:

bytes

我不知道如果我正确书写标题,你可以帮助我解决这个问题?

谢谢!

回答

1

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

在标题的这一点,你应该写出fmt块的大小。

我希望这能解决你的问题

+0

我从另一个变量中得到这个类与父类没有任何关系。但价值是16000. –

+0

要求信息更喜欢评论问题,而不是仅在您确定时才发布答案和答案! – Dopedev