wav格式文件是常見的錄音文件,是聲音波形文件格式之一,wav 文件由文件頭和數據體兩部分組成。
文件頭是我們在做錄音保存到文件的時候,要存儲的文件的說明信息,播放器要通過文件頭的相關信息去讀取數據播放文件,下面是wav文件頭的格式說明。
端模式 |
field name |
Size |
說明 |
big | ChunkID | 4 | 文件頭標識,一般就是"RIFF" 四個字母 |
little | ChunkSize | 4 | 整個數據文件的大小,不包括上面ID和Size本身 |
big | Format | 4 | 一般就是"WAVE" 四個字母 |
big | SubChunk1ID | 4 | 格式說明塊,本字段一般就是"fmt " |
little | SubChunk1Size | 4 | 本數據塊的大小,不包括ID和Size字段本身,這里是pcm 16 |
little | AudioFormat | 2 | 音頻的格式說明,對於pcm 這里是1 |
little | NumChannels | 2 | 聲道數 |
little | SampleRate | 4 | 采樣率 |
little | ByteRate | 4 | 比特率,每秒所需要的字節數 |
little | BlockAlign | 2 | 數據塊對齊單元 |
little | BitsPerSample | 2 | 采樣時模數轉換的分辨率,采樣位數 |
big | SubChunk2ID | 4 | 真正的聲音數據塊,本字段一般是"data" |
little | SubChunk2Size | 4 | 本數據塊的大小,不包括ID和Size字段本身 |
little | Data | N | 音頻的采樣數據 |
下面貼上一段代碼可對應着看
private static byte[] getWaveFileHeader(int totalDataLen, int sampleRate, int channelCount, int bits) { byte[] header = new byte[44]; // RIFF/WAVE header header[0] = 'R'; header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; int fileLength = totalDataLen + 36; header[4] = (byte) (fileLength & 0xff); header[5] = (byte) (fileLength >> 8 & 0xff); header[6] = (byte) (fileLength >> 16 & 0xff); header[7] = (byte) (fileLength >> 24 & 0xff); //WAVE header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; // 'fmt ' chunk header[12] = 'f'; header[13] = 'm'; header[14] = 't'; header[15] = ' '; // 4 bytes: size of 'fmt ' chunk header[16] = 16; header[17] = 0; header[18] = 0; header[19] = 0; // pcm format = 1 header[20] = 1; header[21] = 0; header[22] = (byte) channelCount; header[23] = 0; header[24] = (byte) (sampleRate & 0xff); header[25] = (byte) (sampleRate >> 8 & 0xff); header[26] = (byte) (sampleRate >> 16 & 0xff); header[27] = (byte) (sampleRate >> 24 & 0xff); int byteRate = sampleRate * bits * channelCount / 8; header[28] = (byte) (byteRate & 0xff); header[29] = (byte) (byteRate >> 8 & 0xff); header[30] = (byte) (byteRate >> 16 & 0xff); header[31] = (byte) (byteRate >> 24 & 0xff); // block align header[32] = (byte) (channelCount * bits / 8); header[33] = 0; // bits per sample header[34] = (byte) bits; header[35] = 0; //data header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (totalDataLen & 0xff); header[41] = (byte) (totalDataLen >> 8 & 0xff); header[42] = (byte) (totalDataLen >> 16 & 0xff); header[43] = (byte) (totalDataLen >> 24 & 0xff); return header; }
有了頭信息,下面就是pcm數據了,
pcm數據也有一定的格式
1、8位單通道
數據塊1 | 數據塊2 | ... |
數據1 | 數據2 | ... |
2、8位雙通道
數據塊1 | 數據塊2 | ... | ||
聲道1數據1 | 聲道2數據1 | 聲道1數據2 | 聲道2數據2 | ... |
3、16位單通道
數據塊1 | 數據塊2 | ... | ||
數據1低字節 | 數據1高字節 | 數據2低字節 | 數據2高字節 | ... |
4、16位雙通道
數據塊1 | 數據塊2 | ... | ||||||
聲道1低字節 | 聲道1高字節 | 聲道2低字節 | 聲道2高字節 | 聲道1低字節 | 聲道1高字節 | 聲道2低字節 | 聲道2高字節 | ... |
pcm數據按照上面格式讀取即可。
參考:
https://www.cnblogs.com/liyiwen/archive/2010/04/19/1715715.html