文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:38
字数 623
阅读 5
收藏 0

有两个相关的结构体: TMMIOInfo、TMMCKInfo.

TMMIOInfo 是多媒体文件打开后的状态信息, mmioOpen 函数的第二个参数就是这个结构的指针.
现在先用到了 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.

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2009/11/06/1597596.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
Windows 音频知识学习汇总

使用低级音频函数 WaveX : http://blog.csdn.net/kvw3000/article/details/68468 控制着不同的音频设备, 包括 wave, midi 和辅助音频设备. 低级服务包括: (1) 查询音频设备. (2) 打开和关闭设...

刘军兴
2015/12/16
19
0
【wav音频解析】之wavread函数的C++实现

本文由三部分组成,第一部分背景介绍 —— 音频类型及本文动机,第二部分类比matlab下wavread()函数的作用,第三部分则给出该函数的C++实现。 一 背景介绍 1.1 本文动机 1)所有wav音频处理的...

刘小米
2014/09/29
0
7
AVI 视频容器

AVI格式是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,...

wwl33695
2014/07/08
0
0
使用waveOut接口在Windows中播放声音

使用waveOut接口在Windows中播放声音 转贴地址:http://wmnmtm.blog.163.com/blog/static/382457142011101314135546/ ####################### //声明: 1 本帖作者是:加菲 ,至此感谢! 2 ...

ll124884135
2012/05/29
0
0
AVI格式分析

AVI文件采用的是RIFF文件结构方式,RIFF(Resource Interchange File Format,资源互换文件格式)是微软公司定义的一种用于管理windows环境中多媒体数据的文件格式,波形音频wave,MIDI和数字...

TINATINA
2016/07/18
64
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

qduoj~前端~二次开发~打包docker镜像并上传到阿里云容器镜像仓库

上一篇文章https://my.oschina.net/finchxu/blog/1930017记录了怎么在本地修改前端,现在我要把我的修改添加到部署到本地的前端的docker容器中,然后打包这个容器成为一个本地镜像,然后把这...

虚拟世界的懒猫
今天
1
0
UML中 的各种符号含义

Class Notation A class notation consists of three parts: Class Name The name of the class appears in the first partition. Class Attributes Attributes are shown in the second par......

hutaishi
今天
1
0
20180818 上课截图

小丑鱼00
今天
1
0
Springsecurity之SecurityContextHolderStrategy

注:下面分析的版本是spring-security-4.2.x,源码的github地址是: https://github.com/spring-projects/spring-security/tree/4.2.x 先上一张图: 图1 SecurityContextHolderStrategy的三个......

汉斯-冯-拉特
今天
1
0
LNMP架构(Nginx负载均衡、ssl原理、生成ssl密钥对、Nginx配置ssl)

Nginx负载均衡 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。有时...

蛋黄_Yolks
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部