通过 IDirectSoundBuffer 的 SetVolume、SetPan、SetFrequency、SetCurrentPosition 方法可以简单进行这些设置.
同时 IDirectSoundBuffer 也有对应的 GetVolume、GetPan、GetFrequency、GetCurrentPosition 方法.

关键的一点是如果能让缓冲区接受音量、相位和频率的设置, 必须在建立缓冲区时指定相应的标志.

下面的常量说明了它们的取值范围:


DSBVOLUME_MAX = 0;      //音量最大值, 保持在控制面板设置的音量
DSBVOLUME_MIN = -10000; //音量最小值DSBPAN_LEFT   = -10000; //左声道
DSBPAN_CENTER = 0;      //均衡
DSBPAN_RIGHT  = 10000;  //右声道DSBFREQUENCY_ORIGINAL = 0;      //使用默认
DSBFREQUENCY_MIN      = 100;    //频率最小值
DSBFREQUENCY_MAX      = 200000; //频率最大值, 在 DirectSound 9.0 之下的版本, 此值是 100000


在上一个例子中, 最占篇幅的就是那两个函数; 为了更方便使用, 把它们做在了一个 TReadWaveFile 类里:


{实现 TReadWaveFile 类的单元}
unit ReadWaveFile;interfaceuses Windows, Classes, SysUtils, MMSystem;type
TReadWaveFile = class
privateFFileHandle: HMMIO;FFormat: TWaveFormatEx;FSize: DWORD;
publicconstructor Create;destructor Destroy; override;function Open(FileName: string): Boolean;            //打开文件并读取信息function Read(pDest: Pointer; Size: DWORD): Boolean; //读出波形数据property Format: TWaveFormatEx read FFormat;         //读出格式数据property Size: DWORD read FSize;                     //读出波形数据的大小
end;implementation{ TReadWaveFile }constructor TReadWaveFile.Create;
begininherited;end;destructor TReadWaveFile.Destroy;
beginif FFileHandle > 0 then mmioClose(FFileHandle, 0);inherited;
end;function TReadWaveFile.Open(FileName: string): Boolean;
varckiRIFF,ckiFmt,ckiData: TMMCKInfo;
beginResult := False;if not FileExists(FileName) then Exit;FFileHandle := mmioOpen(PChar(FileName), nil, MMIO_READ);if FFileHandle = 0 then Exit;ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo));mmioDescend(FFileHandle, @ckiRIFF, nil, MMIO_FINDRIFF);if (ckiRIFF.ckid <> FOURCC_RIFF) or (ckiRIFF.fccType <> mmioStringToFOURCC('WAVE',0)) then Exit;ZeroMemory(@FFormat, SizeOf(TWaveFormatEx));ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo));ckiFmt.ckid := mmioStringToFOURCC('fmt', 0);ZeroMemory(@ckiData, SizeOf(TMMCKInfo));ckiData.ckid := mmioStringToFOURCC('data', 0);if (mmioDescend(FFileHandle, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) thenmmioRead(FFileHandle, @FFormat, SizeOf(TWaveFormatEx));mmioAscend(FFileHandle, @ckiFmt, 0);if (mmioDescend(FFileHandle, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) thenFSize := ckiData.cksize;Result := FFormat.wFormatTag = WAVE_FORMAT_PCM;
end;function TReadWaveFile.Read(pDest: Pointer; Size: DWORD): Boolean;
beginResult := mmioRead(FFileHandle, pDest, Size) = Size;
end;end.


测试程序用到了四个 Button 和三个 TrackBar 还有它们的默认事件:


unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;typeTForm1 = class(TForm)Button1: TButton;     //打开并播放Button2: TButton;     //反复播放Button3: TButton;     //暂停Button4: TButton;     //从头播放TrackBar1: TTrackBar; //用于音量调节TrackBar2: TTrackBar; //用于相位调节TrackBar3: TTrackBar; //用于频率调节procedure FormCreate(Sender: TObject);procedure FormDestroy(Sender: TObject);procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button3Click(Sender: TObject);procedure Button4Click(Sender: TObject);procedure TrackBar1Change(Sender: TObject);procedure TrackBar2Change(Sender: TObject);procedure TrackBar3Change(Sender: TObject);end;varForm1: TForm1;implementation{$R *.dfm}uses DirectSound, ReadWaveFile; // ReadWaveFile 是 TReadWaveFile 类所在的单元varmyDSound: IDirectSound8;buf: IDirectSoundBuffer;procedure TForm1.FormCreate(Sender: TObject);
beginTrackBar1.Min := DSBVOLUME_MIN;TrackBar1.Max := DSBVOLUME_MAX;TrackBar2.Min := DSBPAN_LEFT;TrackBar2.Max := DSBPAN_RIGHT;TrackBar3.Min := 100;TrackBar3.Max := 100000;Button1.Caption := '打开并播放';Button2.Caption := '反复播放';Button3.Caption := '暂停';Button4.Caption := '从头播放';System.ReportMemoryLeaksOnShutdown := true;
end;procedure TForm1.Button1Click(Sender: TObject);
varbufDesc: TDSBufferDesc;p1: Pointer;n1: DWORD;wavPath: string;wav: TReadWaveFile; //
beginbuf := nil;myDSound := nil;with TOpenDialog.Create(nil) do beginFilter := 'Wave File(*.wav)|*.wav';if Execute then wavPath := FileName;Free;end;wav := TReadWaveFile.Create;if not wav.Open(wavPath) thenbeginShowMessage('只能是 PCM 格式的 WAVE 文件');wav.Free;Exit;end;DirectSoundCreate8(nil, myDSound, nil);myDSound.SetCooperativeLevel(Self.Handle, DSSCL_NORMAL);ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));bufDesc.dwSize := SizeOf(TDSBufferDesc);{指定缓冲区允许音量、相位和频率调节}bufDesc.dwFlags := DSBCAPS_STATIC or DSBCAPS_CTRLVOLUME or DSBCAPS_CTRLPAN or DSBCAPS_CTRLFREQUENCY;bufDesc.dwBufferBytes := wav.Size;bufDesc.lpwfxFormat := @wav.Format;myDSound.CreateSoundBuffer(bufDesc, buf, nil);buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER);wav.Read(p1, n1);buf.Unlock(p1, n1, nil, 0);buf.Play(0, 0, 0);TrackBar1.Position := 0;TrackBar2.Position := 0;TrackBar3.Position := wav.Format.nSamplesPerSec;wav.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
beginif buf <> nil then buf.Play(0, 0, DSBPLAY_LOOPING);
end;procedure TForm1.Button3Click(Sender: TObject);
beginif buf <> nil then buf.Stop;
end;{从头播放}
procedure TForm1.Button4Click(Sender: TObject);
beginif buf = nil then Exit;buf.Stop;buf.SetCurrentPosition(0);buf.Play(0, 0, 0);
end;{音量调节}
procedure TForm1.TrackBar1Change(Sender: TObject);
beginif buf <> nil then buf.SetVolume(TTrackBar(Sender).Position);
end;{相位调节}
procedure TForm1.TrackBar2Change(Sender: TObject);
beginif buf <> nil then buf.SetPan(TTrackBar(Sender).Position);
end;{频率调节}
procedure TForm1.TrackBar3Change(Sender: TObject);
beginif buf <> nil then buf.SetFrequency(TTrackBar(Sender).Position);
end;procedure TForm1.FormDestroy(Sender: TObject);
beginbuf := nil;myDSound := nil;
end;end.

转载于:https://www.cnblogs.com/del/archive/2011/01/16/1936942.html

在 Delphi 下使用 DirectSound (4): 设置音量、相位、播放频率和播放位置相关推荐

  1. 在 Delphi 下使用 DirectSound (6): 按文件自己的格式(TWaveFormatEx)播放

    这必须手动建立主缓冲区. unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Contr ...

  2. 在 Delphi 下使用 DirectSound (5): 获取或设置缓冲区的格式:

    次缓冲区(或叫辅助缓冲区)尽管使用了波形文件自己的 TWaveFormatEx, 但最终播放的却只是 22050HZ 的 8 位立体声. 因为次缓冲区最终要混入主缓冲区才播放, 可主缓冲区的缺省格式是 ...

  3. 在 Delphi 下使用 DirectSound (9): 效果器初步及 IDirectSoundFXGargle8 效果器

    只有使用 IDirectSoundBuffer8 的次缓冲区才能设置"特效", 主缓冲区主要负责的是混音和处理 3D 效果. IDirectSoundBuffer8(非 IDire ...

  4. 在 Delphi 下使用 DirectSound (12): 测试失真效果器 IDirectSoundFXDistortion8

    为什么80%的码农都做不了架构师?>>>    {相关结构:} TDSFXDistortion = packed recordfGain: Sinle; //-60 .. 0 : - ...

  5. 在 Delphi 下使用 DirectSound (14): 测试镶边效果器 IDirectSoundFXFlanger8

    {相关结构:} TDSFXFlanger = packed recordfWetDryMix: Single; // 0 .. 100 : 50 (%)fDepth: Single; // 0 .. ...

  6. 在 Delphi 下使用 DirectSound (2): 查看设备性能

    使用 DirectSound 前应先建立 IDirectSound8 对象(之前的版本是 IDirectSound): function DirectSoundCreate8(pcGuidDevice ...

  7. Delphi下利用WinIo模拟鼠标键盘详解

    本文最早在编程论坛上发表,文章地址:http://programbbs.com/bbs/view12-17207-1.htm,相关文件可以在上述地址的页面中下载.转载时请注明出处. 前言 一日发现Se ...

  8. Delphi下的COM编程

    Delphi通过向导可以非常迅速和方便的直接建立实现COM对象的代码,但是整个COM实现的过程被完全的封装,甚至没有VCL那么结构清晰可见. 一个没有C++下COM开发经验甚至没有接触过COM开发的D ...

  9. DELPHI下的SOCK编程(转)

    DELPHI下的SOCK编程       本文是写给公司新来的程序员的,算是一点培训的教材.本文不会涉及太多的编程细节,只是简单讲解在DELPHI下进行Winsock编程最好了解的知识. 题外话:我认 ...

最新文章

  1. flask html css文件更改后(谷歌)浏览器不及时更新样式文件怎么办?(ctrl+shift+delete清除缓存的图片和文件)
  2. [MVC]Controller
  3. VTK修炼之道1_初识VTK
  4. The 2018 ACM-ICPC上海大都会赛 J Beautiful Numbers (数位DP)
  5. Thrift实现C#调用Java开发步骤详解
  6. python request headers获取_Python爬虫实战—— Request对象之header伪装策略
  7. 单例模式(含多线程处理)
  8. linxu 获取指定字符的前后多少行
  9. Gof 设计模式 完结
  10. html创建站点文件夹,Dreamweaver站点中新建文件夹和修改/删除/移动文件的操作方法...
  11. Qt(一)消息提示框
  12. 怎么修复Windows11中的AMD驱动程序崩溃
  13. 服务器的速度没有虚拟主机快,云服务器没有虚拟主机快
  14. c语言对随机数进行快速排序,C语言快速排序与二分查找算法示例
  15. win7电脑怎么录屏?免费的录屏软件分享
  16. 仿flash滚动播放图片
  17. python爬取豆瓣网评并写入excel表格中
  18. 国产数据库岁末大盘点
  19. 1 - 概率论与数理统计
  20. CAD-VB多段线、波浪线、射线、构造线

热门文章

  1. 图的基本算法实现(邻接矩阵与邻接表两种方法)
  2. OpenCV环境下Laplace(拉普拉斯)和Roberts基本边缘检测算子的实现代码
  3. 计算机索引无法使用情况,电脑上出现索引,电脑卡的什么都打不开
  4. redis 永不过期 java_死磕 Java
  5. leetcode算法题--Triangle
  6. OVS DPDK--介绍(一)
  7. CTF web题总结--任意文件下载
  8. PHP 8 确认支持 JIT
  9. Picasso-源码解析(三)
  10. python笔记22-literal_eval函数处理返回json中的单双引号