2016-08-30 70 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