這必須手動建立主緩沖區.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses DirectSound, MMSystem, ReadWaveFile; //ReadWaveFile 是在前面(4)自定義的單元
var
myDSound: IDirectSound8; //設備對象
bufPrimary: IDirectSoundBuffer; //主緩沖
buf: IDirectSoundBuffer; //次緩沖
{初始化設備並建立主緩沖區}
procedure TForm1.FormCreate(Sender: TObject);
var
wavFormat: TWaveFormatEx;
bufDesc: TDSBufferDesc;
begin
DirectSoundCreate8(nil, myDSound, nil);
myDSound.SetCoOperativeLevel(Handle, DSSCL_PRIORITY);
ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));
bufDesc.dwSize := SizeOf(TDSBufferDesc);
bufDesc.dwFlags := DSBCAPS_PRIMARYBUFFER;
bufDesc.dwBufferBytes := 0;
bufDesc.lpwfxFormat := nil;
myDSound.CreateSoundBuffer(bufDesc, bufPrimary, nil);
end;
{建立次緩沖區, 並從 Wave 文件填充數據}
procedure TForm1.Button1Click(Sender: TObject);
var
wavFormat: TWaveFormatEx;
bufDesc: TDSBufferDesc;
wavPath: string;
wav: TReadWaveFile;
p1: Pointer;
n1: DWord;
begin
buf := nil;
with TOpenDialog.Create(nil) do begin
Filter := 'Wave File(*.wav)|*.wav';
if Execute then wavPath := FileName;
Free;
end;
wav := TReadWaveFile.Create;
if not wav.Open(wavPath) then
begin
ShowMessage('只能是 PCM 格式的 WAVE 文件');
wav.Free;
Exit;
end;
ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));
bufDesc.dwSize := SizeOf(TDSBufferDesc);
bufDesc.dwFlags := DSBCAPS_STATIC;
bufDesc.dwBufferBytes := wav.Size;
bufDesc.lpwfxFormat := @wav.Format;
{建立次緩沖, 並把主緩沖的格式修改為當前文件的格式}
myDSound.CreateSoundBuffer(bufDesc, buf, nil);
bufPrimary.SetFormat(@wavFormat); //!
buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER);
wav.Read(p1, n1);
wav.Free;
buf.Unlock(p1, n1, nil, 0);
buf.Play(0, 0, 0);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
bufPrimary := nil;
buf := nil;
myDSound := nil;
end;
end.