Delphi에서 DirectSound 사용(4): 음량, 위상, 재생 주파수 및 재생 위치 설정
6570 단어 Delphi
이 동시에 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.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Delphi] TStringBuilder그리고 꼭 사용해야만 할까? 그림처럼 Heap 영역에 "Hello" 공간을 생성하고 포인팅을 한다. "Hello World" 공간을 새로 생성한 후 포인팅을 하게 된다. 결국 "Hello" 라는 String 객체가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.