delphi 多媒体 操作 wave(1)

摘要:
wave文件的文件格式Microsoft多媒体文件(wave、avi、tif等)都有一个RIFF头。波形文件基本上看起来像这样:RIFF头fmt子块数据子块波形文件有很多编码方法。最常见和最简单的一种是PCM编码。其他代码包含更多“块”,但至少包含上述块,PCM代码仅包含上述块。2.判断文件是否为波形文件。波形文件的前12个字节可以描述如下:TRiff=recordckId:DWORD;

Wave 文件的文件格式

微软的多媒体文件(wav、avi、tif 等)都有一个 RIFF 头, Wave 文件基本是这个样子:

RIFF 头
fmt 子块
data 子块

Wave 文件的编码方式有好多, 最常用最简单的就是 PCM 编码.
其他编码会包含更多的"块", 但至少会包含上面的块, PCM 编码只包含上面的块

2.判断一个文件是否是 Wave 文件

Wave 文件的前 12 个字节可以这样描述:

TRiff = record
ckId : DWORD; {'RIFF'}
ckSize : DWORD; {文件大小, 不包括前 8 个字节}
fccType : DWORD; {'WAVE'}
end;

3.mmio 系列函数用于 Wave 等多媒体文件的 I/O 操作

mmio 系列函数比一般的 I/O 函数更适合操作 RIFF 格式的多媒体文件, 主要是能更方便地操作 RIFF 的文件块, 官方还说它们更优化.
和其他 I/O 函数一样, 它们也是要 Open 获取句柄, 然后读写, 最后关闭; 但它们文件句柄和其他 I/O 函数的句柄并不兼容, 不过部分函数(上面前 7 个)也可以用于一般文件的操作.
uses MMSystem;

procedure TForm1.FormCreate(Sender: TObject);

const

FilePath = 'C:\Temp\mm.txt';

var

hFile: HMMIO; str: RawByteString;

begin

hFile := mmioOpen(PChar(FilePath), {要打开的文件}nil, {接受 TMMIOInfo 结构信息的指针, 暂时没用到}

MMIO_CREATE or MMIO_READWRITE {打开选项; 这是建立并以读写权限打开} );

mmioWrite(hFile, 'Delphi', 6); {写入 6 个字符}

mmioSeek(hFile, 0, SEEK_SET); {把读写指针移动到文件头}

SetLength(str, 6); mmioRead(hFile, PAnsiChar(str), 6); {读出 6 个字符}

ShowMessage(str); {Delphi}

mmioClose(hFile, 0); {关闭文件; 第二个参数还可以是 MMIO_FHOPEN, 另有它用}{最后再删除这个文件, 既然已删除就无需 Close 了}

mmioOpen(PChar(FilePath), nil, MMIO_DELETE);

end;

4.有两个相关的结构体: 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), 此时需要很少的信息就可以找到主块.

5.获取 Wave 文件的波形数据

uses MMSystem;

function GetWaveData(FilePath: string; var stream: TMemoryStream): Boolean;
var
hFile: HMMIO;
ckiRIFF,ckiData: TMMCKInfo;
begin
Result := False;
hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ);
if hFile = 0 then Exit;

ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo));
ZeroMemory(@ckiData, SizeOf(TMMCKInfo));
ckiData.ckid := mmioStringToFOURCC('data', 0);

//先获取主块的信息
mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF);

//再获取 data 块的信息后, 指针将自动指向 data 数据的起点; 然后读出数据
if (ckiRIFF.ckid = FOURCC_RIFF) and
(ckiRIFF.fccType = mmioStringToFOURCC('WAVE',0)) and
(mmioDescend(hFile, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then
begin
stream.Size := ckiData.cksize;
Result := (mmioRead(hFile, stream.Memory, ckiData.cksize) = ckiData.cksize);
end;
mmioClose(hFile, 0);
end;

//调用测试
procedure TForm1.Button1Click(Sender: TObject);
const
FilePath = 'C:\WINDOWS\Media\Windows XP 启动.wav';
var
stream: TMemoryStream;
begin
stream := TMemoryStream.Create;

if GetWaveData(FilePath, stream) then
ShowMessageFmt('读出的数据大小是: %d', [stream.Size]); {424600}

stream.Free;
end;

6.使用 TMediaPlayer 录制 wav 文件

TMediaPlayer 录音是基于一个已存在的 wav 文件, 上次建立空白 wav 的函数可派上用场了.TMediaPlayer 的功能是基于 MCI 的, 都是该淘汰的东西了, 只是简单了解下.
接下来还要学习用 waveIn...系列函数录音、用 DirectSound 录音.

7.多媒体函数库Bass.dll

http://www.cnblogs.com/del/category/150851.html

最近要写个小程序, 用到 mp3 播放; 因为需要非常复杂的控制与功能, 想到了 Bass.dll.
以前我曾以为 Bass.dll 是 Windows 系统自带的库, 后来才知道原来是第三方的:
http://www.un4seen.com/.
Bass.dll 一直在更新, 现在最新版本是 2.411, 下载地址:
http://us2.un4seen.com/files/bass24.zip

在 Delphi 中使用前, 有三步工作要做:
1、复制 Bass.dll 到系统可以识别的文件夹, 譬如: Windows\System32、Windows、Windows\System, 也可以是系统或用户的环境变量 Path 指定的任何目录, 还可以在做程序时放在当前目录, 随便放一个文件夹然后在程序中指定路径也可以.
2、把专为 Delphi 写的头文件 bass.pas 放在某个目录(譬如: C:\Program Files\CodeGear\RAD Studio\6.0\Imports\Bass24).
3、然后从 Delphi 菜单 -> Tools -> Options -> Library-Win32 -> Library path -> 然后 Add 这个目录 (
例子).

免责声明:文章转载自《delphi 多媒体 操作 wave(1)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇make编写教程(一)基于OpenScales的地图网站全程开发(FLEX+GIS等技术结合)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

delphi 中record 的类操作符重载简介

今天简单介绍一下 delphi 中record 的类操作符重载使用,就是如何 实现 record 之间的简单操作。 关于类操作符重载 ,大家可以看 官方的文档。 Delphi allows certain functions, or "operators", to be overloaded within record declarations. The...

DELPHI字符串、数组操作函数(转)

对字符串及数组的操作,是每个程序员必须要掌握的。熟练的使用Delphi的这些函数,在编程时能更加得心应手。   1.Copy   功能说明:该函数用于从字符串中复制指定范围中的字符。该函数有3个参数。第一个参数是数据源(即被复制的字符串),第二个参数是从字符串某一处开始复制,第三个参数是要复制字符串的长度(   即个数)。最后函数返回一个新的字符串(即是我...

delphi 文件的操作

转载至:http://hi.baidu.com/endlesslove137/blog/item/86f1669990a7ed046f068ced.html //判断文件是否存在 FileExists//判断文件夹是否存在 DirectoryExists//删除文件 DeleteFile; Windows.DeleteFile//删除文件夹 Remove...

常用EXE文件反编译工具【转】

http://www.cnblogs.com/happyday56/p/3740108.html PE Explorer V1.99 R5 绿色汉化特别版_强大的可视化汉化集成工具 功能极为强大的可视化汉化集成工具,可直接浏览、修改软件资源,包括菜单、对话框、字符串表等; 另外,还具备有 W32DASM 软件的反编译能力和PEditor 软件的 PE 文件...

Delphi -- 创建 桌面、发送到...、快速启动栏、开始菜单、程序菜单、右键菜 单

{================================================================= 功 能: 创建 桌面、发送到...、快速启动栏、开始菜单、程序菜单、右键菜单 快捷方式 参 数: FileName : 快捷方式执行文件名 Description : 快捷方式描述信息 Arguements...

Delphi使用spcomm实现串口通信 基础知识及(两个实例)

心得 如果你已经会使用SPCOMM且出现10个以上的串口问题 请改一下串口名 COM1.CommName='\\.\com18'; 就这样 加'\\.\'就行了我也不知道什么回事....... 以下为抄录不知道是谁的 Delphi 是新一代可视化开发工具,它具有功能强大、简便易用和代码执行速度快等特点,是全球公认的快速应用开发工具技术的先驱者,它越来越在构...