这必须手动建立主缓冲区.
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses DirectSound, MMSystem, ReadWaveFile; //ReadWaveFile 是在前面(4)自定义的单元 var myDSound: IDirectSound8; //设备对象 bufPrimary: IDirectSoundBuffer; //主缓冲 buf: IDirectSoundBuffer; //次缓冲 {初始化设备并建立主缓冲区} procedure TForm1.FormCreate(Sender: TObject); var wavFormat: TWaveFormatEx; bufDesc: TDSBufferDesc; begin DirectSoundCreate8(nil, myDSound, nil); myDSound.SetCooperativeLevel(Handle, DSSCL_PRIORITY); ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc)); bufDesc.dwSize := SizeOf(TDSBufferDesc); bufDesc.dwFlags := DSBCAPS_PRIMARYBUFFER; bufDesc.dwBufferBytes := 0; bufDesc.lpwfxFormat := nil; myDSound.CreateSoundBuffer(bufDesc, bufPrimary, nil); end; {建立次缓冲区, 并从 Wave 文件填充数据} procedure TForm1.Button1Click(Sender: TObject); var wavFormat: TWaveFormatEx; bufDesc: TDSBufferDesc; wavPath: string; wav: TReadWaveFile; p1: Pointer; n1: DWORD; begin buf := nil; with TOpenDialog.Create(nil) do begin Filter := 'Wave File(*.wav)|*.wav'; if Execute then wavPath := FileName; Free; end; wav := TReadWaveFile.Create; if not wav.Open(wavPath) then begin ShowMessage('只能是 PCM 格式的 WAVE 文件'); wav.Free; Exit; end; ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc)); bufDesc.dwSize := SizeOf(TDSBufferDesc); bufDesc.dwFlags := DSBCAPS_STATIC; bufDesc.dwBufferBytes := wav.Size; bufDesc.lpwfxFormat := @wav.Format; {建立次缓冲, 并把主缓冲的格式修改为当前文件的格式} myDSound.CreateSoundBuffer(bufDesc, buf, nil); bufPrimary.SetFormat(@wavFormat); //! buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER); wav.Read(p1, n1); wav.Free; buf.Unlock(p1, n1, nil, 0); buf.Play(0, 0, 0); end; procedure TForm1.FormDestroy(Sender: TObject); begin bufPrimary := nil; buf := nil; myDSound := nil; end; end.
分类:
Delphi 与 DirectX
【推荐】国内首个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吧
2010-01-19 从哪查找当前程序所有可用的环境变量?
2010-01-19 使用多窗体时, 关于节约内存和加快启动速度的思考与尝试
2009-01-19 Delphi 与 DirectX 之 DelphiX(82): TDIB.DrawMandelbrot();
2009-01-19 Delphi 与 DirectX 之 DelphiX(81): TDIB.ColoredLine();
2009-01-19 Delphi 与 DirectX 之 DelphiX(80): TDIB.BlendPixel();
2009-01-19 Delphi 与 DirectX 之 DelphiX(79): TDIB.LinePolar();
2009-01-19 Delphi 与 DirectX 之 DelphiX(78): TDIB.AntialiasedLine();