在 Delphi 下使用 DirectSound (5): 擷取或設定緩衝區的格式:

來源:互聯網
上載者:User
次緩衝區(或叫輔助緩衝區)儘管使用了波形檔案自己的 TWaveFormatEx, 但最終播放的卻只是 22050HZ 的 8 位立體聲.
因為次緩衝區最終要混入主要緩衝區才播放, 可主要緩衝區的預設格式是 22050HZ 的 8 位立體聲(這利於在不同應用程式之間的平滑切換).

次緩衝區一旦建立, 其格式就無法修改了(無法使用緩衝區對象的 SetFormat() 方法); 好在主要緩衝區可以重設格式.
也就是說, 播放 44100HZ、16 位的 Wave 時, 如果不通過主緩衝修改格式則無法原聲播放.

要修改格式只能手動建立主要緩衝區(我們無法使 DirectSound 自動建立的主要緩衝區, 沒有入口).

手動建立主要緩衝區的注意事項:
1、SetCooperativeLevel(Handle, DSSCL_PRIORITY); 因為主緩衝應該是硬緩衝, 這會影響到其它應用程式.
2、為緩衝區指定 TDSBufferDesc 結構時須 TDSBufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER.
3、同時 TDSBufferDesc.dwBufferBytes = 0; 主緩衝使用的應該是硬緩衝, 其大小是固定的, 不能設定, 指定 0 即可

4、同時 TDSBufferDesc.lpwfxFormat = nil; 因為主要緩衝區的格式已有預設, 重新設定必須使用 SetFormat() 方法.

另外, 主緩衝不支援 IDirectSoundBuffer8 介面(IDirectSoundBuffer8 比 IDirectSoundBuffer 多出一些功能);
在次緩衝中可以使用 IDirectSoundBuffer8,但不存在像 CreateSoundBuffer8 這樣的函數, 可通過 IDirectSoundBuffer.QueryInterface() 方法方便擷取.

測試程式:
unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls;type  TForm1 = class(TForm)    Button1: TButton;    Button2: TButton;    procedure FormCreate(Sender: TObject);    procedure FormDestroy(Sender: TObject);    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);  end;var  Form1: TForm1;implementation{$R *.dfm}uses DirectSound, MMSystem;var  myDSound: IDirectSound8;        //裝置對象  bufPrimary: IDirectSoundBuffer; //主緩衝  buf: IDirectSoundBuffer;        //次緩衝  buf8: IDirectSoundBuffer8;      //次緩衝的 IDirectSoundBuffer8 介面{初始化裝置}procedure TForm1.FormCreate(Sender: TObject);begin  DirectSoundCreate8(nil, myDSound, nil);  {若手動建立主緩衝, 裝置的優先順序至少要指定為 DSSCL_PRIORITY}  myDSound.SetCooperativeLevel(Handle, DSSCL_PRIORITY);end;{建立主緩衝, 並修改其格式}procedure TForm1.Button1Click(Sender: TObject);var  wavFormat,fmt2: TWaveFormatEx;  bufDesc: TDSBufferDesc;begin  ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));  bufDesc.dwSize := SizeOf(TDSBufferDesc);  bufDesc.dwFlags := DSBCAPS_PRIMARYBUFFER; //指明建立的是主緩衝  bufDesc.dwBufferBytes := 0; //主緩衝有固定的大小, 無需指定, 須是 0  bufDesc.lpwfxFormat := nil; //主緩衝有自己的格式, 修改它須通過 SetFormat() 方法  myDSound.CreateSoundBuffer(bufDesc, bufPrimary, nil);  {顯示修改前主緩衝格式}  bufPrimary.GetFormat(@fmt2, SizeOf(TWaveFormatEx), nil);  ShowMessageFmt('主緩衝預設: %dHZ %d 位 %d 聲道', [fmt2.nSamplesPerSec, fmt2.wBitsPerSample, fmt2.nChannels]);  {修改主緩衝的格式}  ZeroMemory(@wavFormat, SizeOf(TWaveFormatEx));  with wavFormat do begin    wFormatTag := WAVE_FORMAT_PCM;    nChannels := 2;    nSamplesPerSec := 44100;    wBitsPerSample := 16;    nBlockAlign := wBitsPerSample * nChannels div 8;    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;  end;  bufPrimary.SetFormat(@wavFormat);  {顯示修改後主緩衝格式}  bufPrimary.GetFormat(@fmt2, SizeOf(TWaveFormatEx), nil);  ShowMessageFmt('主緩衝改後: %dHZ %d 位 %d 聲道', [fmt2.nSamplesPerSec, fmt2.wBitsPerSample, fmt2.nChannels]);end;{建立次緩衝, 同時擷取個 IDirectSoundBuffer8 介面}procedure TForm1.Button2Click(Sender: TObject);var  wavFormat,fmt2: TWaveFormatEx;  bufDesc: TDSBufferDesc;begin  {為建立次緩衝準備格式}  ZeroMemory(@wavFormat, SizeOf(TWaveFormatEx));  with wavFormat do begin    wFormatTag := WAVE_FORMAT_PCM;    nChannels := 2;    nSamplesPerSec := 44100;    wBitsPerSample := 16;    nBlockAlign := wBitsPerSample * nChannels div 8;    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;  end;  ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));  bufDesc.dwSize := SizeOf(TDSBufferDesc);  bufDesc.dwFlags := DSBCAPS_STATIC;  bufDesc.dwBufferBytes := 3 * wavFormat.nAvgBytesPerSec; //指定容納 3 秒鐘的波形資料  bufDesc.lpwfxFormat := @wavFormat;  {建立 IDirectSoundBuffer, 並查看其格式}  myDSound.CreateSoundBuffer(bufDesc, buf, nil);  buf.GetFormat(@fmt2, SizeOf(TWaveFormatEx), nil);  ShowMessageFmt('buf: %dHZ %d 位 %d 聲道', [fmt2.nSamplesPerSec, fmt2.wBitsPerSample, fmt2.nChannels]);  {從 IDirectSoundBuffer 擷取 IDirectSoundBuffer8, 並查看其格式}  buf.QueryInterface(IID_IDirectSoundBuffer8, buf8); //  ZeroMemory(@fmt2, SizeOf(TWaveFormatEx));  buf.GetFormat(@fmt2, SizeOf(TWaveFormatEx), nil);  ShowMessageFmt('buf8: %dHZ %d 位 %d 聲道', [fmt2.nSamplesPerSec, fmt2.wBitsPerSample, fmt2.nChannels]);end;procedure TForm1.FormDestroy(Sender: TObject);begin  bufPrimary := nil;  buf := nil;  buf8 := nil;  myDSound := nil;end;end.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.