[轉載]delphi實現音頻捕捉與播放

delphi實現音頻捕捉與播放

unit unit1;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, mmsystem, StdCtrls;

const memBlockLength = 500; 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 : PHWaveIn ; HWaveOut: PHWaveOut ; 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:PPCMWaveFormat; Header:PWaveHdr; memBlock:PmemBlock; i,j:integer; begin WaveFormat:=new(PPCMwaveFormat); with WaveFormat^.wf do 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,PWAVEFORMATEX(WaveFormat),0,0,WAVE_FORMAT_QUERY);
 if i <> 0 then application.messagebox('Error', 'Play format not supported', mb_OK);

 i:=waveInOpen(nil,0,PWAVEFORMATEX(WaveFormat),0,0,WAVE_FORMAT_QUERY);
 if i <> 0 then application.messagebox('Error', 'Record format not supported', mb_OK);

 HwaveOut:=new(PHwaveOut);
 i:=waveOutOpen(HWaveOut,0,PWAVEFORMATEX(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
 if i <> 0 then application.messagebox('Error', 'Problem creating play handle', mb_OK);

 HwaveIn:=new(PHwaveIn);
 i:=waveInOpen(HWaveIn,0,PWAVEFORMATEX(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
 if i <> 0 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 3 do
 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;


      i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
      if i <> 0 then application.messagebox('In Prepare error','error',mb_ok);


      i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
      if i <> 0 then application.messagebox('Add buffer error','error',mb_ok);

      inc(in_count);

 end; {of loop}

 {開始記錄}
 i:=waveInStart(HwaveIn^);
 if i <> 0 then application.messagebox('Start error','error',mb_ok);

 close_invoked:=false;
 close_complete:=false;

end;

procedure TForm1.MMOutDone(var msg:Tmessage); var Header:PWaveHdr; i:integer; begin dec(out_count); {得到返回的數據} Header:=PWaveHdr(msg.lparam); i:=waveOutUnPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr)); if i<> 0 then application.messagebox('Out Un Prepare error','error',mb_ok);

 {釋放}
 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 (in_count=0) and (out_count=0) then
 begin
      close_complete:=true;
      close;
 end;

end;

procedure TForm1.MMInDone(var msg:Tmessage); var Header:PWaveHdr; memBlock:PmemBlock; i:integer; begin dec(in_count); {得到已經接收的數據塊} Header:=PWaveHdr(msg.lparam); i:=waveInUnPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr)); if i<>0 then application.messagebox('In Un Prepare error','error',mb_ok);

 if not(close_invoked) then
 begin
      {裝入輸出緩存}
      i:=waveOutPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr));
      if i<>0 then application.messagebox('Out Prepare error','error',mb_ok);

      {添加到輸出隊列中}
      i:=waveOutWrite(HWaveOut^,Header,sizeof(TWaveHdr));
      if i<>0 then application.messagebox('Wave out error','error',mb_ok);
      inc(out_count);

      {定義一個新的緩存塊}
      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;

      {準備波形裝入塊}
      i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
      if i<>0 then application.messagebox('In Prepare error','error',mb_ok);

      {將緩存區發送給波形輸入設備}
      i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
      if i<>0 then application.messagebox('Add buffer error','error',mb_ok);

      inc(in_count);
 end;

 {隊列已經爲空}
 if (in_count=0) then
 begin
      WaveInClose(HWaveIn^);
      HwaveIn:=nil;
 end;

 {判斷是否已經處理完輸入和輸出隊列}
 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 <> nil then WaveOutReset(HWaveOut^);

 {reset the input channel}
 if HwaveIn<>nil then WaveInReset(HWaveIn^);
 close_invoked:=true;
 canclose:=close_complete;

end;

end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章