文档章节

操作 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
8
使用waveOut接口在Windows中播放声音

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

ll124884135
2012/05/29
0
0
AVI 视频容器

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

wwl33695
2014/07/08
0
0
AVI格式分析

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

TINATINA
2016/07/18
64
0

没有更多内容

加载失败,请刷新页面

加载更多

性能优化(JVM概念及配置)

虚拟机组成 一次编写,到处运行 Java虚拟机是对操作系统的模拟,隔离差异 2018编程语言排行榜 一个复杂的构架 虚拟机的内部概念 运行原理 编译器,解释器执行流程 内存分配-线程模型 栈帧模型...

这很耳东先生
6分钟前
0
0
Scala之初步认识与环境准备

1. 了解 Scala 1.1. 什么是 Scala Scala 是 Scalable Language 的简写,是一门多范式的编程语言。 Scala设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚...

飞鱼说编程
27分钟前
3
0
Vue项目分环境打包的实现步骤

在项目开发中,我们的项目一般分为开发版、测试版、Pre版、Prod版。Vue-cli的默认环境一只有dev和prod两个,之前每次要发布测试版或Pre版都是修改了源码中API地址后打包,这样很麻烦。如果能...

peakedness丶
28分钟前
3
0
vue+lowdb+express

搭建流程: 1.安装Node.js; 2.安装npm; 3.安装Express; 搭建流程 npm install -g express 安装 express 生成器 npm install -g express-generator 查看是否安装成功,随便输的一个命令...

Js_Mei
33分钟前
2
0
Qt那些事0.0.15

以下与Q_DECLARE_METATYPE相关内容全部是翻译自Qt文档。参看QVariant Class | Qt Core 5.9以及QMetaType Class | Qt Core 5.9 QVariant QVariant::fromValue(const T& value) 返回一份包含v......

Ev4n
34分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部