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

操作 Wave 文件(4): 獲取 Wave 文件主塊與子塊的信息

編輯:Delphi

有兩個相關的結構體: TMMIOInfo、TMMCKInfo.

  TMMIOInfo 是多媒體文件打開後的狀態信息, mmioOpen 函數的第二個參數就是這個結構的指針;

  以後還可以通過 mmioGetInfo、mmiOSetInfo 使用它; 不過暫時還沒有用到它.

  現在先用到了 TMMCKInfo, 這是文件內部 "塊" 的信息, 構成如下:

TMMCKInfo = record 
 ckid: FOURCC;    {塊標識}  
 cksize: DWord;    {塊大小} 
 fccType: FOURCC;   {格式類型標識} 
 dwDataOffset: DWord; {偏移地址} 
 dwFlags: DWord;   {附加信息} 
end; 

  查找 "塊" 需要通過 mmioDescend、mmioAscend 兩個函數.

  mmioAscend 是從子塊跳出;

  mmioDescend 是進入到子塊; 進入子塊是需要指定子塊的 ckid 和父塊信息;

  mmioDescend 也用來查找主塊(RIFF), 此時需要很少的信息就可以找到主塊.

  測試代碼:

unit Unit1; 
 
interface 
 
uses 
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
 Dialogs, StdCtrls; 
 
type 
 TForm1 = class(TForm) 
  Button1: TButton; 
  Button2: TButton; 
  procedure Button1Click(Sender: TObject); 
  procedure Button2Click(Sender: TObject); 
 end; 
 
var 
 Form1: TForm1; 
 
implementation 
 
{$R *.dfm} 
 
uses MMSystem; 
 
const FilePath = 'C:\WINDOWS\Media\Windows XP 啟動.wav'; 
 
//獲取 RIFF 塊的信息 
procedure TForm1.Button1Click(Sender: TObject); 
var 
 hFile: HMMIO; 
 ckiRIFF: TMMCKInfo; 
begin 
 //清空 ckiRIFF 結構體; 有些函數使用前要求必須清空, 即使不要求也還是清空的好. 
 FillChar(ckiRIFF, SizeOf(TMMCKInfo), 0); {局部變量在清空前有垃圾數據} 
 
 //打開文件, 獲取句柄 
 hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ); 
 
 //獲取 RIFF 塊的信息 
 mmioDescend(hFile,    {文件句柄} 
       @ckiRIFF,   {塊信息結構的指針, 用於獲取塊的信息} 
       nil,     {這父塊的結構信息, RIFF 沒有父塊, 無需指定} 
       MMIO_FINDRIFF {如果是查詢子塊這裡的標志是 MMIO_FINDCHUNK} 
       );       {返回 0 表示查找成功, 這裡忽略了驗證} 
 
 //以下是查證獲取到的信息 
 ShowMessageFmt('%d, %d, %d, %d, %d', [ckiRIFF.ckid, ckiRIFF.cksize, ckiRIFF.fccType, 
 ckiRIFF.dwDataOffset, ckiRIFF.dwFlags ]); {1179011410, 424636, 1163280727, 8, 0} 
 
 if ckiRIFF.ckid = FOURCC_RIFF then ShowMessage('是 RIFF'); 
 if ckiRIFF.fccType = mmiOStringToFOURCC('WAVE',0) then ShowMessage('是 WAVE'); 
 
 //關閉 
 mmioClose(hFile, 0); 
end; 
 
 
//獲取子塊的信息 
procedure TForm1.Button2Click(Sender: TObject); 
var 
 hFile: HMMIO; 
 ckiRIFF,ckiSub: TMMCKInfo; 
 n: Integer; 
begin 
 //清空准備接受信息的結構 
 FillChar(ckiRIFF, SizeOf(TMMCKInfo), 0); 
 FillChar(ckiSub, SizeOf(TMMCKInfo), 0); 
 
 hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ); 
 
 //先獲取主塊(RIFF)信息 
 mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF); 
 
 //獲取 fmt 子塊信息 
 ckiSub.ckid := mmiOStringToFOURCC('fmt', 0); 
 if mmioDescend(hFile, @ckiSub, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR then 
 begin 
  ShowMessageFmt('%d, %d, %d, %d, %d', [ckiSub.ckid, ckiSub.cksize, ckiSub.fccType, 
   ckiSub.dwDataOffset, ckiSub.dwFlags]); 
 end; 
 
 //如果繼續查找需要跳出子塊; 下面將從偏移地址 20 跳到 36 處 
 mmioAscend(hFile, @ckiSub, 0); {其第三個參數一直是 0, 是備用參數} 
 
 //獲取 data 子塊信息 
 ckiSub.ckid := mmiOStringToFOURCC('data', 0); 
 if mmioDescend(hFile, @ckiSub, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR then 
 begin 
  ShowMessageFmt('%d, %d, %d, %d, %d', [ckiSub.ckid, ckiSub.cksize, ckiSub.fccType, 
   ckiSub.dwDataOffset, ckiSub.dwFlags]); 
 end; 
 
 mmioClose(hFile, 0); 
end; 
 
end. 


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