在 Delphi 下使用 DirectSound (4): 设置音量、相位、播放频率和播放位置
通过 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): 设置音量、相位、播放频率和播放位置相关推荐
- 在 Delphi 下使用 DirectSound (6): 按文件自己的格式(TWaveFormatEx)播放
这必须手动建立主缓冲区. unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Contr ...
- 在 Delphi 下使用 DirectSound (5): 获取或设置缓冲区的格式:
次缓冲区(或叫辅助缓冲区)尽管使用了波形文件自己的 TWaveFormatEx, 但最终播放的却只是 22050HZ 的 8 位立体声. 因为次缓冲区最终要混入主缓冲区才播放, 可主缓冲区的缺省格式是 ...
- 在 Delphi 下使用 DirectSound (9): 效果器初步及 IDirectSoundFXGargle8 效果器
只有使用 IDirectSoundBuffer8 的次缓冲区才能设置"特效", 主缓冲区主要负责的是混音和处理 3D 效果. IDirectSoundBuffer8(非 IDire ...
- 在 Delphi 下使用 DirectSound (12): 测试失真效果器 IDirectSoundFXDistortion8
为什么80%的码农都做不了架构师?>>> {相关结构:} TDSFXDistortion = packed recordfGain: Sinle; //-60 .. 0 : - ...
- 在 Delphi 下使用 DirectSound (14): 测试镶边效果器 IDirectSoundFXFlanger8
{相关结构:} TDSFXFlanger = packed recordfWetDryMix: Single; // 0 .. 100 : 50 (%)fDepth: Single; // 0 .. ...
- 在 Delphi 下使用 DirectSound (2): 查看设备性能
使用 DirectSound 前应先建立 IDirectSound8 对象(之前的版本是 IDirectSound): function DirectSoundCreate8(pcGuidDevice ...
- Delphi下利用WinIo模拟鼠标键盘详解
本文最早在编程论坛上发表,文章地址:http://programbbs.com/bbs/view12-17207-1.htm,相关文件可以在上述地址的页面中下载.转载时请注明出处. 前言 一日发现Se ...
- Delphi下的COM编程
Delphi通过向导可以非常迅速和方便的直接建立实现COM对象的代码,但是整个COM实现的过程被完全的封装,甚至没有VCL那么结构清晰可见. 一个没有C++下COM开发经验甚至没有接触过COM开发的D ...
- DELPHI下的SOCK编程(转)
DELPHI下的SOCK编程 本文是写给公司新来的程序员的,算是一点培训的教材.本文不会涉及太多的编程细节,只是简单讲解在DELPHI下进行Winsock编程最好了解的知识. 题外话:我认 ...
最新文章
- flask html css文件更改后(谷歌)浏览器不及时更新样式文件怎么办?(ctrl+shift+delete清除缓存的图片和文件)
- [MVC]Controller
- VTK修炼之道1_初识VTK
- The 2018 ACM-ICPC上海大都会赛 J Beautiful Numbers (数位DP)
- Thrift实现C#调用Java开发步骤详解
- python request headers获取_Python爬虫实战—— Request对象之header伪装策略
- 单例模式(含多线程处理)
- linxu 获取指定字符的前后多少行
- Gof 设计模式 完结
- html创建站点文件夹,Dreamweaver站点中新建文件夹和修改/删除/移动文件的操作方法...
- Qt(一)消息提示框
- 怎么修复Windows11中的AMD驱动程序崩溃
- 服务器的速度没有虚拟主机快,云服务器没有虚拟主机快
- c语言对随机数进行快速排序,C语言快速排序与二分查找算法示例
- win7电脑怎么录屏?免费的录屏软件分享
- 仿flash滚动播放图片
- python爬取豆瓣网评并写入excel表格中
- 国产数据库岁末大盘点
- 1 - 概率论与数理统计
- CAD-VB多段线、波浪线、射线、构造线