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


使用 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.


你可能感兴趣的:(Delphi)