什么是WAV和PCM屎媳?
WAV:wav是一種無損的音頻文件格式夺溢,WAV符合 PIFF(Resource Interchange File Format)規(guī)范。所有的WAV都有一個(gè)文件頭剿牺,這個(gè)文件頭音頻流的編碼參數(shù)企垦。WAV對音頻流的編碼沒有硬性規(guī)定,除了PCM之外晒来,還有幾乎所有支持ACM規(guī)范的編碼都可以為WAV的音頻流進(jìn)行編碼钞诡。
PCM:PCM(Pulse Code Modulation----脈碼調(diào)制錄音)。所謂PCM錄音就是將聲音等模擬信號(hào)變成符號(hào)化的脈沖列湃崩,再予以記錄荧降。PCM信號(hào)是由[1]、[0]等符號(hào)構(gòu)成的數(shù)字信號(hào)攒读,而未經(jīng)過任何編碼和壓縮處理朵诫。與模擬信號(hào)比,它不易受傳送系統(tǒng)的雜波及失真的影響薄扁。動(dòng)態(tài)范圍寬剪返,可得到音質(zhì)相當(dāng)好的影響效果。
簡單來說:wav是一種無損的音頻文件格式邓梅,pcm是沒有壓縮的編碼方式脱盲。
WAV和PCM的關(guān)系
WAV可以使用多種音頻編碼來壓縮其音頻流,不過我們常見的都是音頻流被PCM編碼處理的WAV日缨,但這不表示W(wǎng)AV只能使用PCM編碼钱反,MP3編碼同樣也可以運(yùn)用在WAV中,和AVI一樣,只要安裝好了相應(yīng)的Decode面哥,就可以欣賞這些WAV了哎壳。在Windows平臺(tái)下,基于PCM編碼的WAV是被支持得最好的音頻格式尚卫,所有音頻軟件都能完美支持归榕,由于本身可以達(dá)到較高的音質(zhì)的要求,因此焕毫,WAV也是音樂編輯創(chuàng)作的首選格式蹲坷,適合保存音樂素材驶乾。因此邑飒,基于PCM編碼的WAV被作為了一種中介的格式,常常使用在其他編碼的相互轉(zhuǎn)換之中级乐,例如MP3轉(zhuǎn)換成WMA疙咸。
簡單來說:pcm是無損wav文件中音頻數(shù)據(jù)的一種編碼方式,但wav還可以用其它方式編碼风科。
將錄音寫成wav格式的文件
有時(shí)候需要將錄音文件保存為wav格式撒轮,這需要手動(dòng)填充wav的文件頭信息,整段代碼非常簡單贼穆,大致如下:
private RandomAccessFile fopen(String path) throws IOException {
File f = new File(path);
if (f.exists()) {
f.delete();
} else {
File parentDir = f.getParentFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}
}
RandomAccessFile file = new RandomAccessFile(f, "rw");
// 16K题山、16bit、單聲道
/* RIFF header */
file.writeBytes("RIFF"); // riff id
file.writeInt(0); // riff chunk size *PLACEHOLDER*
file.writeBytes("WAVE"); // wave type
/* fmt chunk */
file.writeBytes("fmt "); // fmt id
file.writeInt(Integer.reverseBytes(16)); // fmt chunk size
file.writeShort(Short.reverseBytes((short) 1)); // format: 1(PCM)
file.writeShort(Short.reverseBytes((short) 1)); // channels: 1
file.writeInt(Integer.reverseBytes(16000)); // samples per second
file.writeInt(Integer.reverseBytes((int) (1 * 16000 * 16 / 8))); // BPSecond
file.writeShort(Short.reverseBytes((short) (1 * 16 / 8))); // BPSample
file.writeShort(Short.reverseBytes((short) (1 * 16))); // bPSample
/* data chunk */
file.writeBytes("data"); // data id
file.writeInt(0); // data chunk size *PLACEHOLDER*
Log.d(TAG, "wav path: " + path);
return file;
}
private void fwrite(RandomAccessFile file, byte[] data, int offset, int size) throws IOException {
file.write(data, offset, size);
Log.d(TAG, "fwrite: " + size);
}
private void fclose(RandomAccessFile file) throws IOException {
try {
file.seek(4); // riff chunk size
file.writeInt(Integer.reverseBytes((int) (file.length() - 8)));
file.seek(40); // data chunk size
file.writeInt(Integer.reverseBytes((int) (file.length() - 44)));
Log.d(TAG, "wav size: " + file.length());
} finally {
file.close();
}
}