使用
procedure TForm1.FormCreate(Sender: TObject);
begin
Wave1.Play;
end;
var
Faza: Real=0;
procedure TForm1.Wave1Wave(Sender: TWave; var Buffer: TWaveArray);
var
I: Integer;
begin
for I:=$000 to $FFF do begin
Buffer[I].R:=Round($7FFF*Cos(Faza));
Buffer[I].L:=Round($7FFF*Sin(Faza));
Faza:=Faza+2*PI/44100*261.6; // nota C
end;
end;
type
TWaveArray=array[0..$FFF] of packed record
R, L: SmallInt;
end;
TWave=class;
TWaveEvent=procedure(Sender: TWave; var Buffer: TWaveArray) of object;
TWave=class(TComponent)
private
FWindow: HWND;
FHandle: HWAVEOUT;
FIsPlaying: Boolean;
FWave: array[0..1] of record
IsFree: Boolean;
Hdr: TWaveHdr;
Buffer: TWaveArray;
end;
FOnWave: TWaveEvent;
procedure PlayWave(Index: Integer);
procedure FreeWave(Index: Integer);
procedure WndProc(var Msg: TMessage);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Play;
procedure Stop;
property Handle: HWAVEOUT read FHandle;
property IsPlaying: Boolean read FIsPlaying;
published
property OnWave: TWaveEvent read FOnWave write FOnWave;
end;
procedure Register;
implementation
// TWave - public:
constructor TWave.Create(AOwner: TComponent);
var
WF: TPCMWaveformat;
I: Integer;
begin
inherited;
FWindow:=AllocateHWnd(WndProc);
for I:=0 to 1 do FWave[I].IsFree:=True;
WF.wf.wFormatTag:=WAVE_FORMAT_PCM;
WF.wf.nChannels:=2;
WF.wf.nSamplesPerSec:=44100;
WF.wf.nAvgBytesPerSec:=176400;
WF.wf.nBlockAlign:=4;
WF.wBitsPerSample:=16;
if waveOutOpen(@FHandle, WAVE_MAPPER, @WF, FWindow, 0, CALLBACK_WINDOW)<>
MMSYSERR_NOERROR then FHandle:=0;
end;
destructor TWave.Destroy;
var
I: Integer;
begin
if Handle<>0 then begin
if IsPlaying then waveOutReset(Handle);
for I:=0 to 1 do FreeWave(I);
waveOutClose(Handle);
FHandle:=0;
end;
if FWindow<>0 then DeallocateHWnd(FWindow);
inherited;
end;
procedure TWave.Play;
var
I: Integer;
begin
if FIsPlaying then Exit;
for I:=0 to 1 do PlayWave(I);
end;
procedure TWave.Stop;
var
I: Integer;
begin
if not IsPlaying then Exit;
if IsPlaying then waveOutReset(Handle);
FIsPlaying:=False;
for I:=0 to 1 do FreeWave(I);
end;
// TWave - private:
procedure TWave.PlayWave(Index: Integer);
begin
if not FWave[Index].IsFree or not Assigned(OnWave) then Exit;
OnWave(Self, FWave[Index].Buffer);
FWave[Index].Hdr.lpData:=@FWave[Index].Buffer;
FWave[Index].Hdr.dwBufferLength:=SizeOf(TWaveArray);
FWave[Index].Hdr.dwUser:=0;
FWave[Index].Hdr.dwFlags:=0;
FWave[Index].Hdr.dwLoops:=0;
if waveOutPrepareHeader(FHandle, @FWave[Index].Hdr, SizeOf(TWAVEHDR))=MMSYSERR_NOERROR
then
if waveOutWrite(FHandle, @FWave[Index].Hdr, SizeOf(TWAVEHDR))<>MMSYSERR_NOERROR
then
waveOutUnprepareHeader(FHandle, @FWave[Index].Hdr, SizeOf(TWaveHdr))
else begin
FWave[Index].IsFree:=False;
FIsPlaying:=True;
end;
end;
procedure TWave.FreeWave(Index: Integer);
begin
if FWave[Index].IsFree then Exit;
if waveOutUnprepareHeader(FHandle, @FWave[Index].Hdr, SizeOf(TWaveHdr))=
MMSYSERR_NOERROR then FWave[Index].IsFree:=True;
end;
procedure TWave.WndProc(var Msg: TMessage);
var
I: Integer;
begin
if Msg.Msg<>MM_WOM_DONE then begin
Msg.Result:=DefWindowProc(FWindow, Msg.Msg, Msg.wParam, Msg.lParam);
Exit;
end;
if not IsPlaying then Exit;
for I:=0 to 1 do
if Integer(@FWave[I].Hdr)=Msg.LParam then begin
FreeWave(I);
PlayWave(I);
end;
end;
procedure Register;
begin
RegisterComponents('Test', [TWave]);
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
var
t,v:Longint;
begin
// if a=0 then Exit;
t:=TrackBar1.Position;
v:=(t shl 8)or(t shl 24);
waveOutSetVolume(ID,v);
end;
procedure TForm1.TrackBar2Change(Sender: TObject);
var
t,v:Longint;
begin
t:=TrackBar2.Position;
waveOutGetVolume(ID,@v);
v:=v and $ffff0000 or (t shl 8);
waveOutSetVolume(ID,v);
end;
procedure TForm1.TrackBar3Change(Sender: TObject);
var
t,v:Longint;
begin
t:=TrackBar3.Position;
waveOutGetVolume(ID,@v);
v:=v and $0000ffff or (t shl 24);
waveOutSetVolume(ID,v);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
v:longint;
begin
waveOutGetVolume(ID,@v);
TrackBar2.Position:=hi(v);
TrackBar3.Position:=hi(v shr 16);
if hi(v)>hi(v shr 16) then
TrackBar1.Position:=hi(v)
else
TrackBar1.Position:=hi(v shr 16);
auxGetVolume(ID,@v);
if hi(v)>hi(v shr 16) then
TrackBar4.Position:=hi(v)
else
TrackBar4.Position:=hi(v shr 16);
end;
procedure TForm1.TrackBar4Change(Sender: TObject);
var
t,v:Longint;
begin
// if a=0 then Exit;
t:=TrackBar1.Position;
v:=(t shl 8)or(t shl 24);
auxSetVolume(0,v);
//auxSetVolume
end;
procedure TForm1.ButtonClick(Sender: TObject);
begin
if OpenDialog.Execute then
begin
MediaPlayer.FileName:=OpenDialog.FileName;
MediaPlayer.Open;
ID:=MediaPlayer.DeviceID;
end;