裝載格式信息的結構有:
TWaveFormat = packed record
wFormatTag: Word;
nChannels: Word;
nSamplesPerSec: DWord;
nAvgBytesPerSec: DWord;
nBlockAlign: Word;
end;
TPCMWaveFormat = record
wf: TWaveFormat;
wBitsPerSample: Word;
end;
TWaveFormatEx = packed record
wFormatTag: Word; {格式類型; 主要使用的是 WAVE_FORMAT_PCM}
nChannels: Word; {聲道數; 1 是單聲道、2 是立體聲}
nSamplesPerSec: DWord; {采樣頻率}
nAvgBytesPerSec: DWord; {傳輸速率}
nBlockAlign: Word; {每次采樣的大小}
wBitsPerSample: Word; {采樣精度}
cbSize: Word; {附加數據的大小}
end;
能看出它們是依次遞增一個字段, 並且也是 Wave 文件的一個構成部分; 現在要做的就是從 Wave 文件中把它們取出來.
獲取函數及測試代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses MMSystem;
function GetWaveFmt(FilePath: string; var fmt: TWaveFormatEx): Boolean;
var
hFile: HMMIO;
ckiRIFF,ckifmt: TMMCKInfo;
begin
Result := False;
hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ);
if hFile = 0 then Exit;
ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo));
ZeroMemory(@ckifmt, SizeOf(TMMCKInfo));
ckifmt.ckid := mmiOStringToFOURCC('fmt', 0); {給查找格式塊准備}
//先獲取主塊的信息
mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF);
//再獲取 fmt 塊的信息後, 指針將自動指向格式數據起點; 然後讀出格式數據
if (ckiRIFF.ckid = FOURCC_RIFF) and (ckiRIFF.fccType = mmiOStringToFOURCC('WAVE',0)) then
if mmioDescend(hFile, @ckifmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR then
if mmioRead(hFile, @fmt, SizeOf(TWaveFormatEx)) = SizeOf(TWaveFormatEx) then
Result := True;
//如果格式塊大小是 16 的 PCM 編碼的文件, 它不包含 cbSize 信息; 如果是給清空
if (ckifmt.cksize = 16) and (fmt.wFormatTag = WAVE_FORMAT_PCM) then fmt.cbSize := 0;
mmioClose(hFile, 0);
end;
//調用測試
procedure TForm1.Button1Click(Sender: TObject);
const
FilePath = 'C:\WINDOWS\Media\Windows XP 啟動.wav';
var
WaveFormat: TWaveFormatEx;
begin
if GetWaveFmt(FilePath, WaveFormat) then with Memo1.Lines do
begin
Clear;
Add(Format('wFormatTag: %d', [WaveFormat.wFormatTag]));
Add(Format('nChannels: %d', [WaveFormat.nChannels]));
Add(Format('nSamplesPerSec: %d', [WaveFormat.nSamplesPerSec]));
Add(Format('nAvgBytesPerSec: %d', [WaveFormat.nAvgBytesPerSec]));
Add(Format('nBlockAlign: %d', [WaveFormat.nBlockAlign]));
Add(Format('wBitsPerSample: %d', [WaveFormat.wBitsPerSample]));
Add(Format('cbSize: %d', [WaveFormat.cbSize]));
end;
{ 顯示結果:
wFormatTag: 1
nChannels: 2
nSamplesPerSec: 22050
nAvgBytesPerSec: 88200
nBlockAlign: 4
wBitsPerSample: 16
cbSize: 0
}
end;
end.