Delphi에서 DirectSound 사용(4): 음량, 위상, 재생 주파수 및 재생 위치 설정

6570 단어 Delphi
IDirect Sound Buffer의 Set Volume, Set Pan, Set Frequency, Set Current Position 방법을 통해 이런 설정을 간단하게 할 수 있다.
이 동시에 IDirect Sound Buffer에도 대응하는GetVolume,GetPan,GetFrequency,GetCurrent Position 방법이 있다.
관건적인 것은 버퍼가 음량, 위상, 주파수 설정을 받아들일 수 있다면 버퍼를 만들 때 해당하는 로고를 지정해야 한다는 것이다.
다음 상수는 해당 범위에 대해 설명합니다.


DSBVOLUME_MAX = 0;      //     ,             

DSBVOLUME_MIN = -10000; //     



DSBPAN_LEFT   = -10000; //   

DSBPAN_CENTER = 0;      //  

DSBPAN_RIGHT  = 10000;  //   



DSBFREQUENCY_ORIGINAL = 0;      //    

DSBFREQUENCY_MIN      = 100;    //     

DSBFREQUENCY_MAX      = 200000; //     ,   DirectSound 9.0      ,     100000 


지난번 예에서 가장 편폭을 차지하는 것은 바로 그 두 함수이다.사용하기 편리하도록 TreadWaveFile 클래스에 다음과 같이 구성했습니다.


{   TReadWaveFile     }

unit ReadWaveFile;



interface



uses Windows, Classes, SysUtils, MMSystem;



type

TReadWaveFile = class

private

  FFileHandle: HMMIO;

  FFormat: TWaveFormatEx;

  FSize: DWORD;

public

  constructor Create;

  destructor Destroy; override;

  function Open(FileName: string): Boolean;            //         

  function Read(pDest: Pointer; Size: DWORD): Boolean; //      

  property Format: TWaveFormatEx read FFormat;         //      

  property Size: DWORD read FSize;                     //         

end;



implementation



{ TReadWaveFile }



constructor TReadWaveFile.Create;

begin

  inherited;



end;



destructor TReadWaveFile.Destroy;

begin

  if FFileHandle > 0 then mmioClose(FFileHandle, 0);

  inherited;

end;



function TReadWaveFile.Open(FileName: string): Boolean;

var

  ckiRIFF,ckiFmt,ckiData: TMMCKInfo;

begin

  Result := False;

  if not FileExists(FileName) then Exit;



  FFileHandle := mmioOpen(PChar(FileName), nil, MMIO_READ);

  if FFileHandle = 0 then Exit;

  ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo));

  mmioDescend(FFileHandle, @ckiRIFF, nil, MMIO_FINDRIFF);

  if (ckiRIFF.ckid <> FOURCC_RIFF) or (ckiRIFF.fccType <> mmioStringToFOURCC('WAVE',0)) then Exit;



  ZeroMemory(@FFormat, SizeOf(TWaveFormatEx));

  ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo));

  ckiFmt.ckid := mmioStringToFOURCC('fmt', 0);



  ZeroMemory(@ckiData, SizeOf(TMMCKInfo));

  ckiData.ckid := mmioStringToFOURCC('data', 0);



  if (mmioDescend(FFileHandle, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then

    mmioRead(FFileHandle, @FFormat, SizeOf(TWaveFormatEx));



  mmioAscend(FFileHandle, @ckiFmt, 0);



  if (mmioDescend(FFileHandle, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then

    FSize := ckiData.cksize;



  Result := FFormat.wFormatTag = WAVE_FORMAT_PCM;

end;



function TReadWaveFile.Read(pDest: Pointer; Size: DWORD): Boolean;

begin

  Result := mmioRead(FFileHandle, pDest, Size) = Size;

end;



end.


테스트 프로그램은 4개의 Button과 3개의 TrackBar 및 기본 이벤트를 사용합니다.


unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ComCtrls;



type

  TForm1 = class(TForm)

    Button1: TButton;     //     

    Button2: TButton;     //    

    Button3: TButton;     //  

    Button4: TButton;     //    

    TrackBar1: TTrackBar; //      

    TrackBar2: TTrackBar; //      

    TrackBar3: TTrackBar; //      

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

    procedure Button4Click(Sender: TObject);

    procedure TrackBar1Change(Sender: TObject);

    procedure TrackBar2Change(Sender: TObject);

    procedure TrackBar3Change(Sender: TObject);

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



uses DirectSound, ReadWaveFile; // ReadWaveFile   TReadWaveFile       



var

  myDSound: IDirectSound8;

  buf: IDirectSoundBuffer;



procedure TForm1.FormCreate(Sender: TObject);

begin

  TrackBar1.Min := DSBVOLUME_MIN;

  TrackBar1.Max := DSBVOLUME_MAX;



  TrackBar2.Min := DSBPAN_LEFT;

  TrackBar2.Max := DSBPAN_RIGHT;



  TrackBar3.Min := 100;

  TrackBar3.Max := 100000;



  Button1.Caption := '     ';

  Button2.Caption := '    ';

  Button3.Caption := '  ';

  Button4.Caption := '    ';

  System.ReportMemoryLeaksOnShutdown := true;

end;



procedure TForm1.Button1Click(Sender: TObject);

var

  bufDesc: TDSBufferDesc;

  p1: Pointer;

  n1: DWORD;

  wavPath: string;

  wav: TReadWaveFile; //

begin

  buf := nil;

  myDSound := 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;



  DirectSoundCreate8(nil, myDSound, nil);

  myDSound.SetCooperativeLevel(Self.Handle, DSSCL_NORMAL);



  ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));

  bufDesc.dwSize := SizeOf(TDSBufferDesc);

  {         、       }

  bufDesc.dwFlags := DSBCAPS_STATIC or DSBCAPS_CTRLVOLUME or DSBCAPS_CTRLPAN or DSBCAPS_CTRLFREQUENCY;

  bufDesc.dwBufferBytes := wav.Size;

  bufDesc.lpwfxFormat := @wav.Format;



  myDSound.CreateSoundBuffer(bufDesc, buf, nil);

  buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER);

  wav.Read(p1, n1);



  buf.Unlock(p1, n1, nil, 0);

  buf.Play(0, 0, 0);



  TrackBar1.Position := 0;

  TrackBar2.Position := 0;

  TrackBar3.Position := wav.Format.nSamplesPerSec;

  wav.Free;

end;



procedure TForm1.Button2Click(Sender: TObject);

begin

  if buf <> nil then buf.Play(0, 0, DSBPLAY_LOOPING);

end;



procedure TForm1.Button3Click(Sender: TObject);

begin

  if buf <> nil then buf.Stop;

end;



{    }

procedure TForm1.Button4Click(Sender: TObject);

begin

  if buf = nil then Exit;

  buf.Stop;

  buf.SetCurrentPosition(0);

  buf.Play(0, 0, 0);

end;



{    }

procedure TForm1.TrackBar1Change(Sender: TObject);

begin

  if buf <> nil then buf.SetVolume(TTrackBar(Sender).Position);

end;



{    }

procedure TForm1.TrackBar2Change(Sender: TObject);

begin

  if buf <> nil then buf.SetPan(TTrackBar(Sender).Position);

end;



{    }

procedure TForm1.TrackBar3Change(Sender: TObject);

begin

  if buf <> nil then buf.SetFrequency(TTrackBar(Sender).Position);

end;



procedure TForm1.FormDestroy(Sender: TObject);

begin

  buf := nil;

  myDSound := nil;

end;



end.

좋은 웹페이지 즐겨찾기