Wave文件头的大小错误,原因不明

时间:2017-10-12 13:23:19

标签: java android binary hex

我试图将原始pcm音频保存为Wav文件(使用Wave标头)。问题是我的标头是一个未知的原因是48字节长。29 00 29 00字节位于标题的末尾。在写入标题(以及之前)写入原始数据之后,我检查写入Log.i("header", String.valueOf(dos.size()))的字节,结果是48,而应该是44。

文件头(十六进制):

52 49 46 46  //"RIFF"
24 90 43 08
57 41 56 45  // "WAVE"
66 6D 74 20  // "fmt "
10 00 00 00
01 00 02 00
44 AC 00 00
10 B1 02 00
04 00 00 00
10 00 00 00
64 61 74 61 // "data"
00 E4 10 02 // raw data size. Decimal 34661376. Looks ok to me.
29 00 29 00 // Where these come from?

代码:

public void writeWav(byte rawAudio[], String filename)   {

    Log.i("data3", String.valueOf(rawAudio.length));

    FileOutputStream fos=null;
    String youFilePath = Environment.getExternalStorageDirectory().toString()+"/Download/"+filename;
    int myDataSize = rawAudio.length;
    int myChunk2Size =  myDataSize * 2 * 16/8;
    int myChunkSize = 36 + myChunk2Size;


    try {
        fos = new FileOutputStream(youFilePath);
    } catch (IOException e) {
        e.printStackTrace();
    }
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    DataOutputStream dos = new DataOutputStream(bos);

    try {

        dos.writeBytes("RIFF");
        dos.write(intToFourByteArray(myChunkSize));
        dos.writeBytes("WAVE");
        dos.writeBytes("fmt ");
        dos.write(intToFourByteArray(16));
        dos.write(intToTwoByteArray(1));
        dos.write(intToTwoByteArray(2));
        dos.write(intToFourByteArray(44100));
        dos.write(intToFourByteArray((44100 * 2 * 16)/8));
        dos.write(intToFourByteArray((2*16)/8));
        dos.write(intToFourByteArray(16));
        dos.writeBytes("data");
        dos.write(intToFourByteArray(myDataSize));
        Log.i("header", String.valueOf(dos.size())); // 48 bytes. Why?
        dos.write(rawAudio);
        Log.i("data output stream", String.valueOf(dos.size()));
        Log.i("myDataSize", String.valueOf(myDataSize));
        dos.flush();
        dos.close();


    } catch (IOException e) {
        e.printStackTrace();
    }

}

private byte[] intToFourByteArray(int i)    {

    byte[] b = new byte[4];
    b[0] = (byte) (i & 0x00FF);
    b[1] = (byte) ((i >> 8) & 0x000000FF);
    b[2] = (byte) ((i >> 16) & 0x000000FF);
    b[3] = (byte) ((i >> 24) & 0x000000FF);

    // little endian
    Log.i("byte", String.valueOf(b[0]+","+b[1]+","+b[2]+","+b[3]));
    return b;
}

private byte[] intToTwoByteArray(int i)    {

    byte[] b = new byte[2];
    b[0] = (byte) (i & 0x00FF);
    b[1] = (byte) ((i >> 8) & 0x00FF);

    // little endian
    Log.i("byte", String.valueOf(b[0]+","+b[1]));
    return b;
}

0 个答案:

没有答案