程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 操作 Wave 文件(1): 關於 Wave 文件的基礎知識與文件格式

操作 Wave 文件(1): 關於 Wave 文件的基礎知識與文件格式

編輯:Delphi

 最近准備學習 DirectSound、DirectMusic、DirectShow, 但剛一接觸就碰到了關於 Wave 文件的諸多問題, 只好先回頭學學 Wave 文件.


Wave 文件的基礎知識

經常見到這樣的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等.

44100HZ 16bit stereo : 每秒鐘有 44100 次采樣, 采樣數據用 16 位(2字節)記錄, 雙聲道(立體聲);
22050HZ 8bit mono : 每秒鐘有 22050 次采樣, 采樣數據用 8 位(1字節)記錄, 單聲道;

當然也可以有 16bit 的單聲道或 8bit 的立體聲, 等等.


人對頻率的識別范圍是 20HZ - 20000HZ, 如果每秒鐘能對聲音做 20000 個采樣, 回放時就足可以滿足人耳的需求. 所以 22050 的采樣頻率是常用的, 44100 已是 CD 音質, 超過 48000 的采樣對人耳已經沒有意義. 這和電影的每秒 24 幀圖片的道理差不多.

每個采樣數據記錄的是振幅, 采樣精度取決於儲存空間的大小:
1 字節(也就是8bit) 只能記錄 256 個數, 也就是只能對振幅做 256 種識別;
2 字節(也就是16bit) 可以細到 65536 個數, 這已是 CD 標准了;
4 字節(也就是32bit) 能把振幅細化到 4294967296 種可能性, 實在是沒必要了.

如果是雙聲道(stereo), 采樣就是雙份的, 文件也差不多要大一倍.


這樣我們就可以根據一個 wav 文件的大小、采樣頻率和采樣大小估算出一個 wav 文件的長度; 譬如 "Windows XP 啟動.wav" 的文件長度是 424,644 字節, 它是 "22050HZ / 16bit / 立體聲" 格式(這可以從其 "屬性->摘要" 裡看到).
它的每秒的傳輸速率是 22050*16*2 = 705600(bit), 換算成字節是 705600/8 = 88200(字節);
424644(總字節數) / 88200(每秒字節數) ≈ 4.8145578(秒).

這還不夠精確, 在標准的 PCM 格式的 WAVE 文件中至少還有 42 個字節是采樣數據之外的內容, 應該去掉:
(424644-42) / (22050*16*2/8) ≈ 4.8140816(秒). 這比較精確了.


關於聲音文件還有一個概念: "位速", 也有叫做比特率、取樣率, 譬如上面文件的位速是 705.6kbps 或 705600bps, 其中的 b 是 bit, ps 是每秒的意思; 壓縮的音頻文件常常用位速來表示, 譬如達到 CD 音質的 mp3 是: 128kbps / 44100HZ.


Wave 文件的文件格式

微軟的多媒體文件(wav、avi、tif 等)都有一個 RIFF 頭, Wave 文件基本是這個樣子:

RIFF 頭 fmt 子塊 data 子塊

祥表如下:

RIFF 頭 ckid 4 "RIFF" 標識 cksize 4 文件大小; 這個大小不包括 ckid 和 cksize 本身, 下面的子塊大小也是這樣 fccType 4 類型, 這裡是 "WAVE" 標識   22

24 fmt 子塊 ckid 4 "fmt " 標識 cksize 4 塊大小; 一般是 16, 如果是 18 說明後面有附加信息 wFormatTag 2 編碼方式; 1 表示是 PCM 編碼  nChannels 2 聲道數; 1 是單聲道、2 是立體聲 nSamplesPerSec 4 采樣頻率(每秒的樣本數); 譬如 44100 nAvgBytesPerSec 4 傳輸速率 = 采樣頻率 * 每次采樣大小, 單位是字節 nBlockAlign 2 每次采樣的大小 = 采樣精度 * 聲道數 / 8(因單位是字節所以要/8);
這也是字節對齊的最小單位, 譬如 16bit 立體聲在這裡的值是 4 字節 wBitsPerSample 2 采樣精度; 譬如 16bit 在這裡的值就是 16 cbSize 2 附加數據的大小, 如果 fmt 塊的大小是 18 它才存在 ? data 子塊 ckid 4 "data" 標識 cksize 4 塊大小 采樣數據 ? 數據(如果是雙聲道數據排列是: 左右左右...)

上面的表格只是微軟的 PCM 編碼的 Wave 文件的結構, 其他編碼格式的 Wave 文件結構遠比這復雜, 可能會包含更多子塊, 譬如: 事實塊(Fact)、提示塊(Cue)、標簽塊(Label)、注釋塊(Note)、標簽文本塊(Labeled Text)、采樣器塊(Sampler)、樂器塊(Instrument)、列表塊(List)等等, 如果有 List 塊, 它還會包含更多子塊. 

復雜吧? 還好, 我們一般只用 PCM(Pulse Code Modulation) 編碼的 Wave 文件.


接下來要存取、播放、錄制, 說來容易, 操作起來都挺麻煩.


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved