ACMWaveIn.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:5k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit ACMWaveIn;
  2. interface
  3. uses
  4.   msacm, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, mmsystem;
  5. type
  6.   TOnData = procedure(data: pointer; size: longint) of object;
  7.   TACMWaveIn = class(TWinControl)
  8.   private
  9.     FOnData: TOnData;
  10.     Fbuffersize: Integer;
  11.     FDeviceID: Integer;
  12.     procedure WaveInCallback(var msg: TMessage); message MM_WIM_DATA;
  13.     procedure Setbuffersize(Value: Integer);
  14.     { Private declarations }
  15.   protected
  16.     procedure TWMPaint(var msg: TWMPaint); message WM_PAINT;
  17.    { Protected declarations }
  18.   public
  19.     constructor Create(AOwner: TComponent); override;
  20.     procedure Open(format: PWaveFormatEx; DeviceID: Integer = 0);
  21.     procedure Close;
  22.     function getsample: int64;
  23.     { Public declarations }
  24.   published
  25.     property BufferSize: Integer read Fbuffersize write Setbuffersize default 160;
  26.     property OnData: TOnData read FOnData write FOnData;
  27.     { Published declarations }
  28.   end;
  29. var
  30.   closed: boolean;
  31.   sizebuf: integer;
  32.   HWaveIn1: PHWaveIn;
  33. procedure Register;
  34. implementation
  35. procedure Register;
  36. begin
  37.   RegisterComponents('Milos', [TACMWaveIn]);
  38. end;
  39. procedure TACMWaveIn.TWMPaint(var msg: TWMPaint); //display icon
  40. var
  41.   icon: HIcon;
  42.   dc: HDC;
  43. begin
  44.   if csDesigning in ComponentState then
  45.   begin
  46.     icon := LoadIcon(HInstance, MAKEINTRESOURCE('TACMWAVEIN'));
  47.     dc := GetDC(Handle);
  48.     DrawIcon(dc, 0, 0, icon);
  49.     Width := 32;
  50.     Height := 32;
  51.     ReleaseDC(Handle, dc);
  52.     FreeResource(icon);
  53.   end;
  54.   ValidateRect(Handle, nil);
  55. end;
  56. constructor TACMWaveIn.Create(AOwner: TComponent);
  57. begin
  58.   inherited create(AOwner);
  59.   width := 32;
  60.   height := 32;
  61.   Fbuffersize := 160;
  62.   Visible := false;
  63. end;
  64. procedure TACMWaveIn.WaveInCallback(var msg: TMessage); //this is called when is buffer full
  65. var
  66.   Header: PWaveHdr;
  67.   i, bytesrecorded: integer;
  68.   data: PChar;
  69. begin
  70.      {block has been recorded}
  71.   Header := PWaveHdr(msg.lparam);
  72.   if closed = false then
  73.   begin
  74.     i := waveInUnPrepareHeader(HWaveIn1^, Header, sizeof(TWavehdr));
  75.     if i <> 0 then raise Exception.Create('In Un Prepare error');
  76.     bytesrecorded := header.dwbytesrecorded;
  77.     getmem(data, bytesrecorded); //allocate memory
  78.     move(header.lpdata^, data^, bytesrecorded); //copy data
  79.     if assigned(FOnData) then
  80.     begin
  81.       FOnData(data, bytesrecorded);
  82.     end;
  83.     Freemem(data); //free memory
  84.           {reuse a old memory block}
  85.     header.dwbufferlength := sizebuf;
  86.     header.dwbytesrecorded := 0;
  87.     header.dwUser := 0;
  88.     header.dwflags := 0;
  89.     header.dwloops := 0;
  90.          {prepare the old block}
  91.     i := waveInPrepareHeader(HWaveIn1^, Header, sizeof(TWavehdr));
  92.     if i <> 0 then raise Exception.Create('In Prepare error');
  93.           {add it to the buffer}
  94.     i := waveInAddBuffer(HWaveIn1^, Header, sizeof(TWaveHdr));
  95.     if i <> 0 then raise Exception.Create('Add buffer error');
  96.   end
  97.   else
  98.   begin //free buffers if closed
  99.     dispose(header.lpdata);
  100.     dispose(header);
  101.   end;
  102. end;
  103. procedure TACMWaveIn.Open(format: PWaveFormatEx; DeviceID: Integer = 0);
  104. var
  105.   WaveFormat: PWaveFormatEx;
  106.   Header: PWaveHdr;
  107.   memBlock: PChar;
  108.   i, j, maxsizeformat: integer;
  109. begin
  110.   if (hwavein1 = nil) and (format <> nil) then
  111.   begin
  112.     acmMetrics(0, ACM_METRIC_MAX_SIZE_FORMAT, MaxSizeFormat);
  113.     getmem(WaveFormat, MaxSizeFormat);
  114.     move(format^, waveformat^, maxsizeformat);
  115.     sizebuf := 160; //format.nAvgBytesPerSec;
  116.     HWaveIn1 := new(PHWaveIn);
  117.      // create record handle with waveformatex structure
  118.     i := WaveInOpen(HWaveIn1, DeviceID, waveformat, handle, 0, CALLBACK_WINDOW or WAVE_MAPPED);
  119.     if i <> 0 then
  120.     begin
  121.       raise Exception.Create('Problem creating record handle' + inttostr(i));
  122.       exit;
  123.     end;
  124.     closed := false;
  125.      {need to add some buffers to the recording queue}
  126.      {in case the messages that blocks have been recorded}
  127.      {are delayed}
  128.     for j := 1 to 3 do
  129.     begin
  130.           {make a new block}
  131.       Header := new(PWaveHdr);
  132.       memBlock := new(PChar);
  133.       getmem(memblock, sizebuf); //allocate memory
  134.       Header := new(PwaveHdr);
  135.       header.lpdata := memBlock;
  136.       header.dwbufferlength := sizebuf;
  137.       header.dwbytesrecorded := 0;
  138.       header.dwUser := 0;
  139.       header.dwflags := 0;
  140.       header.dwloops := 0;
  141.           {prepare the new block}
  142.       i := waveInPrepareHeader(HWaveIn1^, Header, sizeof(TWavehdr));
  143.       if i <> 0 then raise Exception.Create('In Prepare error');
  144.           {add it to the buffer}
  145.       i := waveInAddBuffer(HWaveIn1^, Header, sizeof(TWaveHdr));
  146.       if i <> 0 then raise Exception.Create('Add buffer error');
  147.     end; {of loop}
  148.      {finally start recording}
  149.     i := waveInStart(HwaveIn1^);
  150.     if i <> 0 then raise Exception.Create('Start error');
  151.   end;
  152. end;
  153. procedure TACMWaveIn.Close;
  154. begin
  155.   if HWaveIn1 <> nil then
  156.   begin
  157.     closed := true;
  158.     WaveInReset(HWaveIn1^);
  159.     WaveInClose(HWaveIn1^);
  160.     dispose(HWaveIn1);
  161.     HWaveIn1 := nil;
  162.   end;
  163. end;
  164. function TACMWaveIn.getsample: int64;
  165. var
  166.   mt: TMMTime;
  167. begin
  168.   mt.wType := TIME_SAMPLES;
  169.   waveInGetPosition(HWaveIn1^, @mt, sizeof(mt));
  170.   Result := mt.sample;
  171. end;
  172. procedure TACMWaveIn.Setbuffersize(Value: Integer);
  173. begin
  174.   if Value>0 then
  175.     Fbuffersize := Value;
  176. end;
  177. end.