操作 Wave 文件(5): 获取 Wave 文件的格式信息


装载格式信息的结构有:

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;           {附加数据的大小; PCM 编码的文件没这个字段}

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;



//获取 Wave 中格式数据的函数; 常用的是 TWaveFormatEx, 但 PCM 缺它一个字段

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));

  ZeroMemory(@fmt, SizeOf(TWaveFormatEx));     {也先清空准备接受数据的结构体}

  ckiFmt.ckid := mmioStringToFOURCC('fmt', 0); {给查找格式块准备}



  //先获取主块的信息

  mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF);



  //再获取 fmt 块的信息后, 指针将自动指向格式数据起点; 然后读出格式数据

  if (ckiRIFF.ckid = FOURCC_RIFF) and

     (ckiRIFF.fccType = mmioStringToFOURCC('WAVE',0)) and

     (mmioDescend(hFile, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then

     Result := (mmioRead(hFile, @fmt, ckiFmt.cksize) = ckiFmt.cksize);

  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.


 
   

你可能感兴趣的:(文件)