📄 acmwaveout.pas
字号:
unit ACMWaveOut;
interface
uses
msacm, mmsystem, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TACMWaveOut = class(TWinControl)
private
FOnDone: TNotifyEvent;
procedure WaveOutCallback(var msg: TMessage); message MM_WOM_DONE;
{ Private declarations }
protected
procedure TWMPaint(var msg: TWMPaint); message WM_PAINT;
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
//destructor Destroy;
procedure Open(format: PWaveFormatEx; DeviceID: Integer = 0);
procedure PlayBack(data: pointer; size: longint);
procedure Close;
procedure Reset;
function getsample: cardinal;
published
{ Published declarations }
property OnDone: TNotifyEvent read FOnDone write FOnDone;
end;
var
HWaveOut1: PHWaveOut;
closed: boolean;
procedure Register;
implementation
constructor TACMWaveOut.create(AOwner: TComponent);
begin
inherited Create(AOWner);
width := 32;
height := 32;
Visible := false;
end;
procedure TACMWaveOut.TWMPaint(var msg: TWMPaint); //draw icon
var
icon: HIcon;
dc: HDC;
begin
if csDesigning in ComponentState then
begin
icon := LoadIcon(HInstance, MAKEINTRESOURCE('TACMWAVEOUT'));
dc := GetDC(Handle);
DrawIcon(dc, 0, 0, icon);
Width := 32;
Height := 32;
ReleaseDC(Handle, dc);
FreeResource(icon);
end;
ValidateRect(Handle, nil);
end;
procedure TACMWaveOut.Open(format: PWaveFormatEx; DeviceID: Integer = 0);
var
waveformat: PWaveFormatEx;
maxsizeformat, i: integer;
begin
if (format <> nil) and (HWaveOut1 = nil) then
begin
acmMetrics(0, ACM_METRIC_MAX_SIZE_FORMAT, MaxSizeFormat);
getmem(WaveFormat, MaxSizeFormat);
move(format^, waveformat^, maxsizeformat);
HWaveOut1 := new(PHWaveOut);
//create playing handle with waveformatex structure
i := WaveOutOpen(HWaveOut1, DeviceID, waveformat, handle, 0, CALLBACK_WINDOW or WAVE_MAPPED);
if i <> 0 then
begin
raise Exception.Create('Problem creating playing handle' + inttostr(i));
//showmessage('Problem creating playing handle' + inttostr(i));
exit;
end;
closed := false;
end;
end;
procedure TACMWaveOut.PlayBack(data: pointer; size: longint);
var
Header: PWaveHdr;
memblock: pointer;
i: integer;
begin
if HWaveOut1 <> nil then
begin
header := new(PWaveHdr);
memblock := new(pointer);
getmem(memblock, size);
move(data^, memBlock^, size);
header.lpdata := memBlock;
header.dwbufferlength := size;
header.dwbytesrecorded := size;
header.dwUser := 0;
header.dwflags := 0;
header.dwloops := 0;
i := WaveOutPrepareHeader(HWaveOut1^, header, sizeof(TWaveHdr));
if i <> 0 then raise Exception.Create('WaveOutPrepareHeader error');
i := WaveOutWrite(HWaveOut1^, header, sizeof(TWaveHdr));
if i <> 0 then raise Exception.Create('WaveOutWrite error');
end;
end;
procedure TACMWaveOut.WaveOutCallback(var msg: TMessage);
var header: PWaveHdr;
i: integer;
begin
header := PWaveHdr(msg.LParam);
if closed = false then
begin
i := WaveOutUnPrepareHeader(HWaveOut1^, header, sizeof(TWaveHdr));
if i <> 0 then raise Exception.Create('WaveOutPrepareHeader error');
end;
if assigned(FOnDone) then
begin
FOnDone(self);
end;
dispose(Header^.lpData);
dispose(Header);
end;
procedure TACMWaveOut.Close;
begin
if HWaveOut1 <> nil then
begin
closed := TRUE;
WaveOutReset(HWaveOut1^);
WaveOutClose(HWaveOut1^);
HWaveOut1 := nil;
end;
end;
procedure TACMWaveOut.Reset;
begin
if HWaveOut1 <> nil then
begin
WaveOutReset(HWaveOut1^);
end;
end;
procedure Register;
begin
RegisterComponents('Milos', [TACMWaveOut]);
end;
function TACMWaveOut.getsample: cardinal;
var
mt: TMMTime;
begin
mt.wType := TIME_SAMPLES;
if Closed then exit;
waveOutGetPosition(HWaveout1^, @mt, sizeof(mt));
Result := mt.sample;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -