我试图将原始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;
}