1. 程式人生 > >WAV和PCM的關係和區別

WAV和PCM的關係和區別

**

什麼是WAV和PCM?

**

WAV:wav是一種無損的音訊檔案格式,WAV符合 PIFF(Resource Interchange File Format)規範。所有的WAV都有一個檔案頭,這個檔案頭音訊流的編碼引數。WAV對音訊流的編碼沒有硬性規定,除了PCM之外,還有幾乎所有支援ACM規範的編碼都可以為WAV的音訊流進行編碼。

PCM:PCM(Pulse Code Modulation—-脈碼調製錄音)。所謂PCM錄音就是將聲音等模擬訊號變成符號化的脈衝列,再予以記錄。PCM訊號是由[1]、[0]等符號構成的數字訊號,而未經過任何編碼和壓縮處理。與模擬訊號比,它不易受傳送系統的雜波及失真的影響。動態範圍寬,可得到音質相當好的影響效果。

簡單來說:wav是一種無損的音訊檔案格式,pcm是沒有壓縮的編碼方式。

**

WAV和PCM的關係

**

  WAV可以使用多種音訊編碼來壓縮其音訊流,不過我們常見的都是音訊流被PCM編碼處理的WAV,但這不表示WAV只能使用PCM編碼,MP3編碼同樣也可以運用在WAV中,和AVI一樣,只要安裝好了相應的Decode,就可以欣賞這些WAV了。在Windows平臺下,基於PCM編碼的WAV是被支援得最好的音訊格式,所有音訊軟體都能完美支援,由於本身可以達到較高的音質的要求,因此,WAV也是音樂編輯創作的首選格式,適合儲存音樂素材。因此,基於PCM編碼的WAV被作為了一種中介的格式,常常使用在其他編碼的相互轉換之中,例如MP3轉換成WMA。

簡單來說:pcm是無損wav檔案中音訊資料的一種編碼方式,但wav還可以用其它方式編碼。

將錄音寫成wav格式的檔案

  有時候需要將錄音檔案儲存為wav格式,這需要手動填充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(); } }