(4): 获取 Wave 文件主块与子块的信息

有两个相关的结构体: 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. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值