什么是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的文件頭信息,整段代碼非常簡單,大致如下:
1 private RandomAccessFile fopen(String path) throws IOException { 2 File f = new File(path); 3 4 if (f.exists()) { 5 f.delete(); 6 } else { 7 File parentDir = f.getParentFile(); 8 if (!parentDir.exists()) { 9 parentDir.mkdirs(); 10 } 11 } 12 13 RandomAccessFile file = new RandomAccessFile(f, "rw"); 14 // 16K、16bit、單聲道 15 /* RIFF header */ 16 file.writeBytes("RIFF"); // riff id 17 file.writeInt(0); // riff chunk size *PLACEHOLDER* 18 file.writeBytes("WAVE"); // wave type 19 20 /* fmt chunk */ 21 file.writeBytes("fmt "); // fmt id 22 file.writeInt(Integer.reverseBytes(16)); // fmt chunk size 23 file.writeShort(Short.reverseBytes((short) 1)); // format: 1(PCM) 24 file.writeShort(Short.reverseBytes((short) 1)); // channels: 1 25 file.writeInt(Integer.reverseBytes(16000)); // samples per second 26 file.writeInt(Integer.reverseBytes((int) (1 * 16000 * 16 / 8))); // BPSecond 27 file.writeShort(Short.reverseBytes((short) (1 * 16 / 8))); // BPSample 28 file.writeShort(Short.reverseBytes((short) (1 * 16))); // bPSample 29 30 /* data chunk */ 31 file.writeBytes("data"); // data id 32 file.writeInt(0); // data chunk size *PLACEHOLDER* 33 34 Log.d(TAG, "wav path: " + path); 35 return file; 36 } 37 38 private void fwrite(RandomAccessFile file, byte[] data, int offset, int size) throws IOException { 39 file.write(data, offset, size); 40 Log.d(TAG, "fwrite: " + size); 41 } 42 43 private void fclose(RandomAccessFile file) throws IOException { 44 try { 45 file.seek(4); // riff chunk size 46 file.writeInt(Integer.reverseBytes((int) (file.length() - 8))); 47 48 file.seek(40); // data chunk size 49 file.writeInt(Integer.reverseBytes((int) (file.length() - 44))); 50 51 Log.d(TAG, "wav size: " + file.length()); 52 53 } finally { 54 file.close(); 55 } 56 }
參考資料
作者:張明雲
鏈接:https://www.jianshu.com/p/1d1f893e53e9
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。