完整调用单元如下:
unit Echo1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, mmsystem;
const
{The larger the size of the block the fewer blocks recorded}
{per second and therefore the longer the delay between}
{recording and playback}
memBlockLength = 500;
{500 bytes at 11k/sec = delay of 500/11000 of a second}
{roughly a 20th}
type
Tmemblock = array[0..memblocklength] of byte;
PmemBlock = ^TmemBlock;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
private
{ Private declarations }
HwaveIn
HWaveIn;
HWaveOut
HWaveOut;
close_invoked,close_complete:boolean;
in_count,out_count:integer;
procedure MMOutDone(var msg:Tmessage);message MM_WOM_DONE;
procedure MMInDone(var msg:Tmessage);message MM_WIM_DATA;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
WaveFormat
PCMWaveFormat;
Header
WaveHdr;
memBlock
memBlock;
i,j:integer;
begin
WaveFormat:=new(PPCMwaveFormat);
with WaveFormat^.wfdo
begin
WFormatTag := WAVE_FORMAT_PCM;
{PCM format - the only option!}
NChannels:=1;
{mono}
NSamplesPerSec:=11000;
{11kHz sampling}
NAvgBytesPerSec:=11000;
{we aim to use 8 bit sound so only 11k per second}
NBlockAlign:=1;
{only one byte in each sample}
waveformat^.wBitsPerSample:=8;
{8 bits in each sample}
end;
i:=waveOutOpen(nil,0,PWaveFormat(WaveFormat),0,0,WAVE_FORMAT_QUERY);
if i<&gt0 then
application.messagebox('Error', 'Play format not supported', mb_OK);
i:=waveInOpen(nil,0,PWaveFormat(WaveFormat),0,0,WAVE_FORMAT_QUERY);
if i<&gt0 then
application.messagebox('Error', 'Record format not supported', mb_OK);
HwaveOut:=new(PHwaveOut);
i:=waveOutOpen(HWaveOut,0,Pwaveformat(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
if i<&gt0 then
application.messagebox('Error', 'Problem creating play handle', mb_OK);
HwaveIn:=new(PHwaveIn);
i:=waveInOpen(HWaveIn,0,Pwaveformat(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
if i<&gt0 then
application.messagebox('Error', 'Problem creating record handle', mb_OK);
{these are the count of the number of blocks sent to}
{the audio device}
in_count:=0;
out_count:=0;
{need to add some buffers to the recording queue}
{in case the messages that blocks have been recorded}
{are delayed}
for j:= 1 to 3do
begin
{make a new block}
Header:=new(PWaveHdr);
memBlock:=new(PmemBlock);
Header:=new(PwaveHdr);
with header^do
begin
lpdata:=pointer(memBlock);
dwbufferlength:=memblocklength;
dwbytesrecorded:=0;
dwUser:=0;
dwflags:=0;
dwloops:=0;
end;
{prepare the new block}
i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
if i<&gt0 then
application.messagebox('In Prepare error','error',mb_ok);
{add it to the buffer}
i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
if i<&gt0 then
application.messagebox('Add buffer error','error',mb_ok);
inc(in_count);
end;
{of loop}
{finally start recording}
i:=waveInStart(HwaveIn^);
if i<&gt0 then
application.messagebox('Start error','error',mb_ok);
close_invoked:=false;
close_complete:=false;
end;
procedure TForm1.MMOutDone(var msg:Tmessage);
var
Header
WaveHdr;
i:integer;
begin
dec(out_count);
{get the returned header}
Header:=PWaveHdr(msg.lparam);
i:=waveOutUnPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr));
if i<&gt0 then
application.messagebox('Out Un Prepare error','error',mb_ok);
{free the memory}
dispose(Header^.lpdata);
dispose(Header);
{if there's no more blocks being recorded}
if (out_count=0) then
begin
WaveOutClose(HWaveOut^);
HwaveOut:=nil;
end;
{if there's nothing more todo
then
close}
if (in_count=0) and (out_count=0) then
begin
close_complete:=true;
close;
end;
end;
procedure TForm1.MMInDone(var msg:Tmessage);
var
Header
WaveHdr;
memBlock
memBlock;
i:integer;
begin
dec(in_count);
{block has been recorded}
Header:=PWaveHdr(msg.lparam);
i:=waveInUnPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
if i<&gt0 then
application.messagebox('In Un Prepare error','error',mb_ok);
if not(close_invoked) then
begin
{prepare it for play back}
i:=waveOutPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr));
if i<&gt0 then
application.messagebox('Out Prepare error','error',mb_ok);
{add it to the playback queue}
i:=waveOutWrite(HWaveOut^,Header,sizeof(TWaveHdr));
if i<&gt0 then
application.messagebox('Wave out error','error',mb_ok);
inc(out_count);
{make a new block}
Header:=new(PWaveHdr);
memBlock:=new(PmemBlock);
Header:=new(PwaveHdr);
with header^do
begin
lpdata:=pointer(memBlock);
dwbufferlength:=memblocklength;
dwbytesrecorded:=0;
dwUser:=0;
dwflags:=0;
dwloops:=0;
end;
{prepare the new block}
i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
if i<&gt0 then
application.messagebox('In Prepare error','error',mb_ok);
{add it to the buffer}
i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
if i<&gt0 then
application.messagebox('Add buffer error','error',mb_ok);
inc(in_count);
end;
{if there's no more blocks being recorded}
if (in_count=0) then
begin
WaveInClose(HWaveIn);
HwaveIn:=nil;
end;
{if there's nothing more todo
then
close}
if (in_count=0) and (out_count=0) then
begin
close_complete:=true;
close;
end;
end;
procedure TForm1.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
{reset the output channel}
if HWaveOut<&gtnil then
WaveOutReset(HWaveOut^);
{reset the input channel}
if HwaveIn<&gtnil then
WaveInReset(HWaveIn^);
close_invoked:=true;
canclose:=close_complete;
end;
end.