文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:37
字数 1101
阅读 16
收藏 0

使用 DirectSound 前应先建立 IDirectSound8 对象(之前的版本是 IDirectSound):
function DirectSoundCreate8(
  pcGuidDevice: PGUID;      //设备的 GUID; 指定 nil 表示使用默认声卡
  out ppDS8: IDirectSound8; //要返回的 IDirectSound8 对象
  pUnkOuter: IUnknown       //未使用, 应为 nil
): HResult; stdcall; //返回错误码

//也可使用 GUID 常数指定设备:
DSDEVID_DefaultPlayback      //默认设备
DSDEVID_DefaultVoicePlayback //二级默认设备


然后通过 IDirectSound8 对象(它代表着一个播放设备)创建缓冲区, 以写入声音信息.

这里的缓冲区分 "主缓冲区" 和 "次缓冲区". 主缓冲区只有一个; 次缓冲区可以有多个, 以实现多个声音的同时播放.

DirectSound 会尽量使用硬件(声卡)提供的缓冲区; 如果硬件不支持则只好使用系统内存做缓冲区, 但这样效率不及前者.

通过 IDirectSound8.GetCaps() 方法可以获取指定设备的详细性能:
function GetCaps(
  out pDSCaps: TDSCaps //获取到的信息将放在 TDSCaps 结构体中
): HResult; stdcall;

//TDSCaps 结构:
TDSCaps = packed record
  dwSize                         : DWORD; //结构大小(字节)
  dwFlags                        : DWORD; //性能标志
  dwMinSecondarySampleRate       : DWORD; //次缓冲区的最小取样率
  dwMaxSecondarySampleRate       : DWORD; //次缓冲区的最大取样率
  dwPrimaryBuffers               : DWORD; //主缓冲区个数
  dwMaxHwMixingAllBuffers        : DWORD; //硬件缓冲区的最大数目
  dwMaxHwMixingStaticBuffers     : DWORD; //静态硬件缓冲区的最大数目
  dwMaxHwMixingStreamingBuffers  : DWORD; //流式硬件缓冲区的最大数目
  dwFreeHwMixingAllBuffers       : DWORD; //空闲的硬件缓冲区个数
  dwFreeHwMixingStaticBuffers    : DWORD; //空闲的静态硬件缓冲区个数
  dwFreeHwMixingStreamingBuffers : DWORD; //空闲的流式硬件缓冲区个数
  dwMaxHw3DAllBuffers            : DWORD; //3D 硬件缓冲区的最大数目
  dwMaxHw3DStaticBuffers         : DWORD; //3D 静态硬件缓冲区的最大数目
  dwMaxHw3DStreamingBuffers      : DWORD; //3D 流式硬件缓冲区的最大数目
  dwFreeHw3DAllBuffers           : DWORD; //空闲的 3D 硬件缓冲区的最大数目
  dwFreeHw3DStaticBuffers        : DWORD; //空闲的 3D 静态硬件缓冲区的最大数目
  dwFreeHw3DStreamingBuffers     : DWORD; //空闲的 3D 流式硬件缓冲区的最大数目
  dwTotalHwMemBytes              : DWORD; //硬件内存总量(字节)
  dwFreeHwMemBytes               : DWORD; //空闲的硬件内存总量(字节)
  dwMaxContigFreeHwMemBytes      : DWORD; //空闲的硬件内存最大连续块大小(字节)
  dwUnlockTransferRateHwBuffers  : DWORD; //硬件缓冲区的数据传输速率(千字节/秒)
  dwPlayCpuOverheadSwBuffers     : DWORD; //混合软件缓冲区占用的 CPU 周期的百分比
  dwReserved1                    : DWORD; //未使用
  dwReserved2                    : DWORD; //未使用
end;


查看默认设备性能的测试程序:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo; //用于显示信息
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses DirectSound;

procedure TForm1.FormCreate(Sender: TObject);
var
  myDSound: IDirectSound8;
  capInfo: TDSCaps;
  p: PDSCaps;
begin
  Memo1.ScrollBars := ssBoth;
  Memo1.Align := alLeft;
  Memo1.Clear;

  FillChar(capInfo, SizeOf(TDSCaps), 0);
  capInfo.dwSize := SizeOf(TDSCaps);

  DirectSoundCreate8(nil, myDSound, nil);
  myDSound.GetCaps(capInfo);

  with Memo1.Lines do begin
    Add(Format('%d'#9'dwSize',                         [capInfo.dwSize                        ]));
    Add(Format('%d'#9'dwFlags',                        [capInfo.dwFlags                       ]));
    Add(Format('%d'#9'dwMinSecondarySampleRate',       [capInfo.dwMinSecondarySampleRate      ]));
    Add(Format('%d'#9'dwMaxSecondarySampleRate',       [capInfo.dwMaxSecondarySampleRate      ]));
    Add(Format('%d'#9'dwPrimaryBuffers',               [capInfo.dwPrimaryBuffers              ]));
    Add(Format('%d'#9'dwMaxHwMixingAllBuffers',        [capInfo.dwMaxHwMixingAllBuffers       ]));
    Add(Format('%d'#9'dwMaxHwMixingStaticBuffers',     [capInfo.dwMaxHwMixingStaticBuffers    ]));
    Add(Format('%d'#9'dwMaxHwMixingStreamingBuffers',  [capInfo.dwMaxHwMixingStreamingBuffers ]));
    Add(Format('%d'#9'dwFreeHwMixingAllBuffers',       [capInfo.dwFreeHwMixingAllBuffers      ]));
    Add(Format('%d'#9'dwFreeHwMixingStaticBuffers',    [capInfo.dwFreeHwMixingStaticBuffers   ]));
    Add(Format('%d'#9'dwFreeHwMixingStreamingBuffers', [capInfo.dwFreeHwMixingStreamingBuffers]));
    Add(Format('%d'#9'dwMaxHw3DAllBuffers',            [capInfo.dwMaxHw3DAllBuffers           ]));
    Add(Format('%d'#9'dwMaxHw3DStaticBuffers',         [capInfo.dwMaxHw3DStaticBuffers        ]));
    Add(Format('%d'#9'dwMaxHw3DStreamingBuffers',      [capInfo.dwMaxHw3DStreamingBuffers     ]));
    Add(Format('%d'#9'dwFreeHw3DAllBuffers',           [capInfo.dwFreeHw3DAllBuffers          ]));
    Add(Format('%d'#9'dwFreeHw3DStaticBuffers',        [capInfo.dwFreeHw3DStaticBuffers       ]));
    Add(Format('%d'#9'dwFreeHw3DStreamingBuffers',     [capInfo.dwFreeHw3DStreamingBuffers    ]));
    Add(Format('%d'#9'dwTotalHwMemBytes',              [capInfo.dwTotalHwMemBytes             ]));
    Add(Format('%d'#9'dwFreeHwMemBytes',               [capInfo.dwFreeHwMemBytes              ]));
    Add(Format('%d'#9'dwMaxContigFreeHwMemBytes',      [capInfo.dwMaxContigFreeHwMemBytes     ]));
    Add(Format('%d'#9'dwUnlockTransferRateHwBuffers',  [capInfo.dwUnlockTransferRateHwBuffers ]));
    Add(Format('%d'#9'dwPlayCpuOverheadSwBuffers',     [capInfo.dwPlayCpuOverheadSwBuffers    ]));
  end;
end;

end.


查看所有设备性能的测试程序:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    ComboBox1: TComboBox; //用于设备列表
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses DirectSound;

var
  guidArr: array of TGUID;

function EnumCallback(lpGuid: PGUID; lpcstrDescription, lpcstrModule: PChar;
    lpContext: Pointer): BOOL; stdcall;
begin
  if lpGuid <> nil then
  begin
    TStrings(lpContext).Add(lpcstrDescription);
    SetLength(guidArr, Length(guidArr) + 1);
    guidArr[Length(guidArr) - 1] := lpGuid^;
  end;
  Result := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Align := alTop;
  Memo1.ScrollBars := ssBoth;
  Memo1.Align := alClient;
  Memo1.Clear;
  DirectSoundEnumerate(EnumCallback, ComboBox1.Items);
  ComboBox1.ItemIndex := 0;
  ComboBox1.OnChange(nil);
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
var
  myDSound: IDirectSound8;
  capInfo: TDSCaps;
  p: PDSCaps;
begin
  Memo1.Clear;
  ZeroMemory(@capInfo, SizeOf(TDSCaps));
  capInfo.dwSize := SizeOf(TDSCaps);

  DirectSoundCreate8(@guidArr[ComboBox1.ItemIndex], myDSound, nil);
  Caption := GUIDToString(guidArr[ComboBox1.ItemIndex]);
  myDSound.GetCaps(capInfo);

  with Memo1.Lines do begin
    Add(Format('%d'#9'dwSize',                         [capInfo.dwSize                        ]));
    Add(Format('%d'#9'dwFlags',                        [capInfo.dwFlags                       ]));
    Add(Format('%d'#9'dwMinSecondarySampleRate',       [capInfo.dwMinSecondarySampleRate      ]));
    Add(Format('%d'#9'dwMaxSecondarySampleRate',       [capInfo.dwMaxSecondarySampleRate      ]));
    Add(Format('%d'#9'dwPrimaryBuffers',               [capInfo.dwPrimaryBuffers              ]));
    Add(Format('%d'#9'dwMaxHwMixingAllBuffers',        [capInfo.dwMaxHwMixingAllBuffers       ]));
    Add(Format('%d'#9'dwMaxHwMixingStaticBuffers',     [capInfo.dwMaxHwMixingStaticBuffers    ]));
    Add(Format('%d'#9'dwMaxHwMixingStreamingBuffers',  [capInfo.dwMaxHwMixingStreamingBuffers ]));
    Add(Format('%d'#9'dwFreeHwMixingAllBuffers',       [capInfo.dwFreeHwMixingAllBuffers      ]));
    Add(Format('%d'#9'dwFreeHwMixingStaticBuffers',    [capInfo.dwFreeHwMixingStaticBuffers   ]));
    Add(Format('%d'#9'dwFreeHwMixingStreamingBuffers', [capInfo.dwFreeHwMixingStreamingBuffers]));
    Add(Format('%d'#9'dwMaxHw3DAllBuffers',            [capInfo.dwMaxHw3DAllBuffers           ]));
    Add(Format('%d'#9'dwMaxHw3DStaticBuffers',         [capInfo.dwMaxHw3DStaticBuffers        ]));
    Add(Format('%d'#9'dwMaxHw3DStreamingBuffers',      [capInfo.dwMaxHw3DStreamingBuffers     ]));
    Add(Format('%d'#9'dwFreeHw3DAllBuffers',           [capInfo.dwFreeHw3DAllBuffers          ]));
    Add(Format('%d'#9'dwFreeHw3DStaticBuffers',        [capInfo.dwFreeHw3DStaticBuffers       ]));
    Add(Format('%d'#9'dwFreeHw3DStreamingBuffers',     [capInfo.dwFreeHw3DStreamingBuffers    ]));
    Add(Format('%d'#9'dwTotalHwMemBytes',              [capInfo.dwTotalHwMemBytes             ]));
    Add(Format('%d'#9'dwFreeHwMemBytes',               [capInfo.dwFreeHwMemBytes              ]));
    Add(Format('%d'#9'dwMaxContigFreeHwMemBytes',      [capInfo.dwMaxContigFreeHwMemBytes     ]));
    Add(Format('%d'#9'dwUnlockTransferRateHwBuffers',  [capInfo.dwUnlockTransferRateHwBuffers ]));
    Add(Format('%d'#9'dwPlayCpuOverheadSwBuffers',     [capInfo.dwPlayCpuOverheadSwBuffers    ]));
  end;
end;

end.

本文转载自:http://www.cnblogs.com/del/archive/2011/01/13/1934863.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
DirectSound入门

文档内容: (费话篇) 关于DirectSound DirectSound是DirectX API的音频(waveaudio)组件之一,它可以提供快速的混音、硬件加速功能,并且可以直接访问相关设备,当然,最主要的是它提供的...

长平狐
2012/08/13
901
0
Windows上的音频采集技术(转)

转自:http://shanewfx.github.io/blog/2013/08/14/caprure-audio-on-windows/前一段时间接到一个任务,需要采集到声卡的输出信号,以便与麦克风的输入信号进行混音。 之前一直没有研究过音频...

元谷
2013/12/05
0
0
使用UniDAC在Delphi XE4中开发iOS应用

使用UniDAC在Delphi XE4中开发iOS应用   核心提示:Delphi XE4的发布让很多Delphi开发者欣喜若狂,毫无疑问它使得Delphi开发更简单且更容易被理解,而且让开发无论是iPhone、iPad还是iPod的...

vga
2014/06/01
0
0
DirectSound学习(二)--流式缓冲区

使用流式缓冲方式播放波形音频文件比较复杂,主要原因是在只有一个缓冲区提供给用户的前提下,这个缓冲区在提供给声卡播放数据的同是还需要用户不断的定时向其中写入数据。要注意从缓冲区这时...

imxiangzi
02/11
0
0
钢琴曲演奏软件--FreePiano

FreePiano是一款使用电脑键盘演奏钢琴音曲的开源软件。 FreePiano的特点: 完全免费的,您不需要购买就可以使用全部的功能。 直接调用VSTi音源,不需要安装虚拟MIDI设备。 支持多种音频输出方...

匿名
2013/05/27
2.4K
1

没有更多内容

加载失败,请刷新页面

加载更多

RestClientUtil和ConfigRestClientUtil区别说明

RestClientUtil directly executes the DSL defined in the code. ConfigRestClientUtil gets the DSL defined in the configuration file by the DSL name and executes it. RestClientUtil......

bboss
35分钟前
6
0

中国龙-扬科
昨天
1
0
Linux系统设置全局的默认网络代理

更改全局配置文件/etc/profile all_proxy="all_proxy=socks://rahowviahva.ml:80/"ftp_proxy="ftp_proxy=http://rahowviahva.ml:80/"http_proxy="http_proxy=http://rahowviahva.ml:80/"......

临江仙卜算子
昨天
5
0
java框架学习日志-6(bean作用域和自动装配)

本章补充bean的作用域和自动装配 bean作用域 之前提到可以用scope来设置单例模式 <bean id="type" class="cn.dota2.tpye.Type" scope="singleton"></bean> 除此之外还有几种用法 singleton:......

白话
昨天
8
0
在PC上测试移动端网站和模拟手机浏览器的5大方法

总结很全面,保存下来以备不时之需。原文地址:https://www.cnblogs.com/coolfeng/p/4708942.html

kitty1116
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部