unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses MMSystem; //chan: 1 单声道、2 立体声; //freq: 频率, 取值: 11025, 22050, 44100 //bit : 每个样本的大小, 取值 8、16 function CreateWav1(chan, freq, bit: Word; const FilePath: string): Boolean; var h: HMMIO; ckiRiff, ckiFmt, ckiData: TMMCKInfo; fmt: TPCMWaveFormat; begin //此函数是使用 mmioCreateChunk 函数来分别建立 Wave 文件的每个块. {初识化相关结构} ZeroMemory(@ckiRiff, SizeOf(TMMCKInfo)); ckiRiff.cksize := 36; {mmioCreateChunk 函数会自动写上 ckid, 但其 cksize 需要手动给} ckiRiff.fccType := mmioStringToFOURCC('WAVE', 0); ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo)); ckiFmt.ckid := mmioStringToFOURCC('fmt', 0); ZeroMemory(@ckiData, SizeOf(TMMCKInfo)); ckiData.ckid := mmioStringToFOURCC('data', 0); {指定 Wave 格式} fmt.wf.wFormatTag := WAVE_FORMAT_PCM; fmt.wf.nChannels := chan; fmt.wf.nSamplesPerSec := freq; fmt.wf.nAvgBytesPerSec := freq * chan * bit div 8; fmt.wf.nBlockAlign := chan * bit div 8; fmt.wBitsPerSample := bit; h := mmioOpen(PChar(FilePath), nil, MMIO_CREATE or MMIO_WRITE); if h = 0 then Exit(False); {分别建立 RIFF、fmt、data 块} if (mmioCreateChunk(h, @ckiRiff, MMIO_CREATERIFF) = MMSYSERR_NOERROR) and (mmioCreateChunk(h, @ckiFmt, 0) = MMSYSERR_NOERROR) and (mmioWrite(h, PAnsiChar(@fmt), SizeOf(TPCMWaveFormat)) = SizeOf(TPCMWaveFormat)) and (mmioAscend(h, @ckiFmt, 0) = MMSYSERR_NOERROR) and (mmioCreateChunk(h, @ckiData, 0) = MMSYSERR_NOERROR) then Result := True; mmioClose(h, 0); end; //把 PCM 编码的 WAVE 文件的前 44 个字节看成一个结构来操作: function CreateWav2(chan, freq, bit: Word; const FilePath: string): Boolean; type TWaveHeader = record Riff_ckid : DWORD; Riff_cksize : DWORD; Riff_fccType : DWORD; fmt_ckid : DWORD; fmt_cksize : DWORD; wFormatTag : Word; nChannels : Word; nSamplesPerSec : DWORD; nAvgBytesPerSec: DWORD; nBlockAlign : Word; wBitsPerSample : Word; data_ckid : DWORD; data_cksize : DWORD; end; var wh: TWaveHeader; hFile: Integer; begin wh.Riff_ckid := FOURCC_RIFF; wh.Riff_cksize := 36; wh.Riff_fccType := mmioStringToFOURCC('WAVE', 0); wh.fmt_ckid := mmioStringToFOURCC('fmt', 0); wh.fmt_cksize := 16; wh.wFormatTag := WAVE_FORMAT_PCM; wh.nChannels := chan; wh.nSamplesPerSec := freq; wh.nAvgBytesPerSec := freq * chan * bit div 8; wh.nBlockAlign := chan * bit div 8; wh.wBitsPerSample := bit; wh.data_ckid := mmioStringToFOURCC('data', 0); wh.data_cksize := 0; hFile := FileCreate(FilePath); Result := (FileWrite(hFile, wh, SizeOf(TWaveHeader)) <> -1); FileClose(hFile); end; //同上, 只是改用流来写文件 function CreateWav3(chan, freq, bit: Word; const FilePath: string): Boolean; type TWaveHeader = record Riff_ckid : DWORD; Riff_cksize : DWORD; Riff_fccType : DWORD; fmt_ckid : DWORD; fmt_cksize : DWORD; wFormatTag : Word; nChannels : Word; nSamplesPerSec : DWORD; nAvgBytesPerSec: DWORD; nBlockAlign : Word; wBitsPerSample : Word; data_ckid : DWORD; data_cksize : DWORD; end; var wh: TWaveHeader; begin wh.Riff_ckid := FOURCC_RIFF; wh.Riff_cksize := 36; wh.Riff_fccType := mmioStringToFOURCC('WAVE', 0); wh.fmt_ckid := mmioStringToFOURCC('fmt', 0); wh.fmt_cksize := 16; wh.wFormatTag := WAVE_FORMAT_PCM; wh.nChannels := chan; wh.nSamplesPerSec := freq; wh.nAvgBytesPerSec := freq * chan * bit div 8; wh.nBlockAlign := chan * bit div 8; wh.wBitsPerSample := bit; wh.data_ckid := mmioStringToFOURCC('data', 0); wh.data_cksize := 0; with TFileStream.Create(FilePath, fmCreate) do begin Result := (Write(wh, SizeOf(TWaveHeader)) = SizeOf(TWaveHeader)); Free; end; end; procedure TForm1.FormCreate(Sender: TObject); begin CreateWav1(1, 11025, 8, 'C:\Temp\X1.wav'); CreateWav2(2, 22050, 16, 'C:\Temp\X2.wav'); CreateWav3(2, 44100, 16, 'C:\Temp\X3.wav'); end; end.
分类:
API WAVE 专栏
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2008-11-10 Delphi 的内存操作函数(3): 给结构体指针分配内存
2008-11-10 Delphi 的内存操作函数(2): 给数组指针分配内存