文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:38
字数 623
阅读 4
收藏 0
点赞 0
评论 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.

 
 
 
 
 

 

 

  

© 著作权归作者所有

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

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

刘军兴 ⋅ 2015/12/16 ⋅ 0

【wav音频解析】之wavread函数的C++实现

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

刘小米 ⋅ 2014/09/29 ⋅ 7

AVI 视频容器

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

wwl33695 ⋅ 2014/07/08 ⋅ 0

AVI 视频容器

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

wwl33695 ⋅ 2014/07/08 ⋅ 0

使用waveOut接口在Windows中播放声音

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

ll124884135 ⋅ 2012/05/29 ⋅ 0

AVI格式分析

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

TINATINA ⋅ 2016/07/18 ⋅ 0

视音频数据处理入门:PCM音频采样数据处理

===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB、YUV像素数据处理 视音频数据处理入门:PCM音频采样数据处理 视音频数据处理...

leixiaohua1020 ⋅ 2016/01/29 ⋅ 0

PHP实现基于文本的莫斯电码生成器

介绍 我最近遇到一个基于输入文本生成摩斯代码音频文件的需求。几番搜索无果之后,我决定自己编写一个生成器。 下载源代码 – 2.63 KB 因为我希望通过web的方式访问我的摩斯代码音频文件,所...

snowing1990 ⋅ 2016/04/08 ⋅ 0

waveOutOpen 函数说明

waveOutOpen 函数说明 (2008-12-21 13:33:10) 转载▼ 使用心得:首先打开声音输出设备,然后初始化输出内存,并保证不要使用缓存;(调用waveOutPrepareHeader设置内存),然后通过回调函数进...

薛蕊 ⋅ 2014/05/28 ⋅ 0

量子计算开发工具--Qbsolv

加拿大公司 D-Wave 的量子计算机在学术界备受质疑,尽管如此,该公司正试图通过开源的方法推动量子计算程序开发。D-Wave开源了 Qbsolv 工具,该工具是设计帮助没有量子物理背景的开发者为 D-...

匿名 ⋅ 2017/01/13 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

IDEA PermGen space内存溢出

解决方案: File -> Settings -> Build, Execution, Deployment / Build Tools / Maven / Runner下,找到VM Options选项,默认是空的,改为如下内容(或更大值)...

快乐的小火柴 ⋅ 15分钟前 ⋅ 0

前端常见跨域解决方案

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 广义的跨域: 1.) 资源跳转: A链接、重定向、表单提交2.) 资源嵌入: <link>、<script>、<im...

临江仙卜算子 ⋅ 16分钟前 ⋅ 0

系统管理命令service

service命令用来控制系统服务的实用工具,例如启动、停止、重启和关闭系统服务,以及当前状态。当然也可以直接操作,例如/etc/init.d/mysqld restart等。 语法 service (选项)(参数) 选项...

Jpchina ⋅ 21分钟前 ⋅ 0

MySQL 联合索引的命中规则

为什么要用联合索引? 对于查询语句“SELECT T.* FROM T WHERE T.c1=1 AND T.c3=2”涉及到两列,这个时候我们一般采用一个联合索引(c1, c3);而不用两个单列索引,这是因为一条查询语句往往应...

hensemlee ⋅ 28分钟前 ⋅ 0

Spring 自动组件扫描

通常情况下都是在XML配置文件中手动声明Bean和组件的。不过Spring也可以自动扫描组件实例化Bean,这样就可以避免在XML文件中繁琐的Bean声明。 手动声明Bean: 这里不再啰嗦,就是简单地在XML...

霍淇滨 ⋅ 33分钟前 ⋅ 0

MapReduce简单需求分析-共同好友及查找互粉的情况

MapReduce的设计,最重要的是要找准key,然后制定一系列的数据处理流程。MapReduce的Map中,会把key相同的分配到同一个reduce中,对于key的选择,可以找到某个相同的因素。以下面的几个例子说...

Jason_typ ⋅ 35分钟前 ⋅ 0

springboot多数据源自动切换

SpringBoot多数据源切换,先上配置文件: 1.pom: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20......

JackyRiver ⋅ 37分钟前 ⋅ 0

Boost库编译应用

版本:Boost 1.66.0 Windows库编译 官网指南:直接执行bootstrap.bat处理文件即可,可以我却遇到一堆的问题。 环境:Windows 10 + Visual Studio 2017 Boost编译出来库命名 boost库生成文件命...

水海云 ⋅ 41分钟前 ⋅ 0

解决Eclipse发布到Tomcat丢失依赖jar包的问题

如果jar文件是以外部依赖的形式导入的。Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的。 可以通过Eclipse在项目上右击 - Propertics - Deployment Assembly,添加“Java Build ...

ArlenXu ⋅ 41分钟前 ⋅ 0

iview tree组件层级过多时可左右滚动

使用vue+iview的tree组件,iview官网iview的tree树形控件 问题描述:tree层级过多时左右不可滚动 问题解决:修改overflow属性值 .el-tree-node>.el-tree-node_children { overflow: vi...

YXMBetter ⋅ 43分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部