在 Delphi 下使用 DirectSound (6): 按文件自己的格式(TWaveFormatEx)播放


这必须手动建立主缓冲区.


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.


你可能感兴趣的:(Delphi)