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

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 10.09.98 - 15:54:27 $                                        =}
  24. {========================================================================}
  25. unit MMWRec;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.   Windows,
  31. {$ELSE}
  32.   WinTypes,
  33.   WinProcs,
  34. {$ENDIF}
  35.   SysUtils,
  36.   Classes,
  37.   Controls,
  38.   Dialogs,
  39.   MMSystem,
  40.   MMRegs,
  41.   MMObj,
  42.   MMDSPobj,
  43.   MMUtils,
  44.   MMWave,
  45.   MMWavIn,
  46.   MMWaveIO,
  47.   MMPCMSup,
  48.   MMACMDlg;
  49. type
  50.     EMMWaveRecorderError = class(Exception);
  51.     {-- TMMWaveRecorer --------------------------------------------------------}
  52.     TMMWaveRecorder = class(TMMDSPComponent)
  53.     private
  54.        FChanging   : Boolean;
  55.        FStartPos   : Longint;
  56.        FOnStart    : TNotifyEvent;
  57.        FOnStop     : TNotifyEvent;
  58.        FOnPause    : TNotifyEvent;
  59.        FOnRestart  : TNotifyEvent;
  60.        FOnChange   : TNotifyEvent;
  61.        FOnData     : TMMBufferEvent;
  62.        procedure SetWave(aValue: TMMWave);
  63.        function  GetWave: TMMWave;
  64.        procedure SetNumBuffers(aValue: integer);
  65.        function  GetNumBuffers: integer;
  66.        procedure SetDeviceID(aValue: TMMDeviceID);
  67.        function  GetDeviceID: TMMDeviceID;
  68.        procedure SetDummyString(aValue: string);
  69.        function  GetProductName: string;
  70.        function  GetInputFormat: string;
  71.        procedure SetInputFormat(aValue: string);
  72.        procedure SetTimeFormat(aValue: TMMTimeFormats);
  73.        function  GetTimeFormat: TMMTimeFormats;
  74.        procedure SetCallBackMode(aValue: TMMCBMode);
  75.        function  GetCallBackMode: TMMCBMode;
  76.        procedure SetPosition(aValue: Longint);
  77.        function  GetPosition: Longint;
  78.        procedure SetMaxRecTime(aValue: Longint);
  79.        function  GetMaxRecTime: Longint;
  80.        procedure SetMode(aValue: TMMMode);
  81.        function  GetMode: TMMMode;
  82.        procedure SetBits(aValue: TMMBits);
  83.        function  GetBits: TMMBits;
  84.        procedure SetRate(aValue: Longint);
  85.        function  GetRate: Longint;
  86.        procedure SetFileName(aValue: TFileName);
  87.        function  GetFileName: TFileName;
  88.        procedure SetOverwrite(aValue: Boolean);
  89.        function  GetOverwrite: Boolean;
  90.        function  GetState: TMMWaveInState;
  91.        procedure DoChange(Sender: TObject);
  92.        procedure DoChanged(Sender: TObject);
  93.        procedure DoClose(Sender: TObject);
  94.        procedure DoStart(Sender: TObject);
  95.        procedure DoStop(Sender: TObject);
  96.        procedure DoPause(Sender: TObject);
  97.        procedure DoRestart(Sender: TObject);
  98.        procedure DoData(Sender: TObject; lpwh: PWaveHdr);
  99.     protected
  100.        FWaveIn   : TMMWaveIn;
  101.        FWaveFile : TMMWaveFile;
  102.        procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
  103.        function  GetBufferSize: Longint; override;
  104.        procedure SetBufferSize(aValue: Longint); override;
  105.        procedure DefineProperties(Filer: TFiler); override;
  106.        procedure ReadData(Stream: TStream); virtual;
  107.        procedure WriteData(Stream: TStream); virtual;
  108.     public
  109.        constructor Create(aOwner: TComponent); override;
  110.        destructor  Destroy; override;
  111.        procedure Recording;
  112.        procedure Stop;
  113.        procedure Pause;
  114.        procedure Restart;
  115.        function  SelectFile: Boolean;
  116.        function  SelectFormat: Boolean;
  117.        procedure SetPCMFormat(Mode: TMMMode; Bits: TMMBits; SampleRate: Longint);
  118.        procedure SaveFormatInRegistry(RootKey: HKEY; Localkey, Field: string);
  119.        procedure LoadFormatFromRegistry(RootKey: HKEY; Localkey, Field: string);
  120.        property  FileName: TFileName read GetFileName write SetFileName stored False;
  121.        property  PWaveFormat;
  122.        property  State: TMMWaveInState read GetState;
  123.        property  Position: Longint read GetPosition write SetPosition;
  124.     published
  125.        property OnStart: TNotifyEvent read FOnStart write FOnStart;
  126.        property OnStop: TNotifyEvent read FOnStop write FOnStop;
  127.        property OnPause: TNotifyEvent read FOnPause write FOnPause;
  128.        property OnRestart: TNotifyEvent read FOnRestart write FOnRestart;
  129.        property OnChange: TNotifyEvent read FOnChange write FOnChange;
  130.        property OnData: TMMBufferEvent read FOnData write FOnData;
  131.        property Output;
  132.        property Wave: TMMWave read GetWave write SetWave;
  133.        property BufferSize: Longint read GetBufferSize write SetBufferSize;
  134.        property NumBuffers: integer read GetNumBuffers write SetNumBuffers;
  135.        property DeviceID: TMMDeviceID read GetDeviceID write SetDeviceID;
  136.        property ProductName: string read GetProductName write SetDummyString stored False;
  137.        property TimeFormat: TMMTimeFormats read GetTimeFormat write SetTimeFormat;
  138.        property CallBackMode: TMMCBMode read GetCallBackMode write SetCallBackMode;
  139.        property MaxRecordTime: Longint read GetMaxRecTime write SetMaxRecTime;
  140.        property Mode: TMMMode read GetMode write SetMode;
  141.        property BitLength: TMMBits read GetBits write SetBits;
  142.        property SampleRate: Longint read GetRate write SetRate;
  143.        property InputFormat: string read GetInputFormat write SetInputFormat stored False;
  144.        property OverwriteExisting: Boolean read GetOverwrite write SetOverwrite;
  145.     end;
  146. implementation
  147. {== MMWaveRecorder ============================================================}
  148. constructor TMMWaveRecorder.Create(aOwner: TComponent);
  149. begin
  150.    inherited Create(aOwner);
  151.    FWaveFile             := TMMWaveFile.Create(Self);
  152.    FWaveFile.Wave.FileMustExist := False;
  153.    FWaveFile.OnChange    := DoChange;
  154.    FWaveFile.OnChanged   := DoChanged;
  155.    FWaveFile.OnClose     := DoClose;
  156.    FWaveIn               := TMMWaveIn.Create(Self);
  157.    FWaveIn.Output        := FWaveFile;
  158.    FWaveIn.OnOpen        := DoStart;
  159.    FWaveIn.OnStop        := DoStop;
  160.    FWaveIn.OnPause       := DoPause;
  161.    FWaveIn.OnRestart     := DoRestart;
  162.    FWaveIn.OnBufferReady := DoData;
  163.    FStartPos             := 0;
  164.    FInputValid           := True;
  165.    FWaveFile.Output      := Self;
  166.    FInputValid           := False;
  167.    FChanging             := False;
  168.    ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  169.    if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  170. end;
  171. {-- TMMWaveRecorder -----------------------------------------------------------}
  172. destructor TMMWaveRecorder.Destroy;
  173. begin
  174.    Stop;
  175.    FWaveFile.Free;
  176.    FWaveIn.Free;
  177.    inherited Destroy;
  178. end;
  179. {-- TMMWaveRecorder -----------------------------------------------------------}
  180. procedure TMMWaveRecorder.ReadData(Stream: TStream);
  181. var
  182.    Buf: PChar;
  183. begin
  184.    Buf := GlobalAllocMem(Stream.Size);
  185.    try
  186.       Stream.ReadBuffer(Buf^,Stream.Size);
  187.       FWaveIn.PWaveFormat := Pointer(Buf);
  188.    finally
  189.       GlobalFreeMem(Pointer(Buf));
  190.    end;
  191. end;
  192. {-- TMMWaveRecorder -----------------------------------------------------------}
  193. procedure TMMWaveRecorder.WriteData(Stream: TStream);
  194. begin
  195.    Stream.WriteBuffer(FWaveIn.PWaveFormat^,wioSizeOfWaveFormat(FWaveIn.PWaveFormat));
  196. end;
  197. {-- TMMWaveRecorder -----------------------------------------------------------}
  198. procedure TMMWaveRecorder.DefineProperties(Filer: TFiler);
  199. begin
  200.    inherited DefineProperties(Filer);
  201.    Filer.DefineBinaryProperty('WaveFormatEx', ReadData, WriteData, (PWaveFormat <> nil) and (PWaveFormat.wFormatTag <> WAVE_FORMAT_PCM));
  202. end;
  203. {-- TMMWaveRecorder -----------------------------------------------------------}
  204. procedure TMMWaveRecorder.SetPWaveFormat(aValue: PWaveFormatEx);
  205. var
  206.    Size,Size2: integer;
  207. begin
  208.    if not FChanging then
  209.    begin
  210.       if (aValue <> nil) then
  211.       begin
  212.          if (FWaveIn.PWaveFormat <> nil) then
  213.          begin
  214.             size := wioSizeOfWaveFormat(aValue);
  215.             size2:= wioSizeOfWaveFormat(FWaveIn.PWaveFormat);
  216.             if (Size <> Size2) or not GlobalCmpMem(aValue^,FWaveIn.PWaveFormat^,Size) then
  217.             begin
  218.                FWaveIn.PWaveFormat := aValue;
  219.                exit;
  220.             end;
  221.          end
  222.          else
  223.          begin
  224.             FWaveIn.PWaveFormat := aValue;
  225.             exit;
  226.          end;
  227.       end;
  228.       inherited SetPWaveFormat(aValue);
  229.    end;
  230. end;
  231. {-- TMMWaveRecorder -----------------------------------------------------------}
  232. procedure TMMWaveRecorder.SetMode(aValue: TMMMode);
  233. begin
  234.    FWaveIn.Mode := aValue;
  235. end;
  236. {-- TMMWaveRecorder -----------------------------------------------------------}
  237. function TMMWaveRecorder.GetMode: TMMMode;
  238. begin
  239.    Result := FWaveIn.Mode;
  240. end;
  241. {-- TMMWaveRecorder -----------------------------------------------------------}
  242. procedure TMMWaveRecorder.SetBits(aValue: TMMBits);
  243. begin
  244.    FWaveIn.BitLength := aValue;
  245. end;
  246. {-- TMMWaveRecorder -----------------------------------------------------------}
  247. function TMMWaveRecorder.GetBits: TMMBits;
  248. begin
  249.    Result := FWaveIn.BitLength;
  250. end;
  251. {-- TMMWaveRecorder -----------------------------------------------------------}
  252. procedure TMMWaveRecorder.SetRate(aValue: Longint);
  253. begin
  254.    FWaveIn.SampleRate:= aValue;
  255. end;
  256. {-- TMMWaveRecorder -----------------------------------------------------------}
  257. function TMMWaveRecorder.GetRate: Longint;
  258. begin
  259.    Result := FWaveIn.SampleRate;
  260. end;
  261. {-- TMMWaveRecorder -----------------------------------------------------------}
  262. procedure TMMWaveRecorder.SetWave(aValue: TMMWave);
  263. begin
  264.    FWaveFile.Wave := aValue;
  265. end;
  266. {-- TMMWaveRecorder -----------------------------------------------------------}
  267. function TMMWaveRecorder.GetWave: TMMWave;
  268. begin
  269.    Result := FWaveFile.Wave;
  270. end;
  271. {-- TMMWaveRecorder -----------------------------------------------------------}
  272. function TMMWaveRecorder.SelectFormat: Boolean;
  273. var
  274.    ACM: TMMACM;
  275. begin
  276.    ACM := TMMACM.Create(nil);
  277.    try
  278.       ACM.EnumFormats := efInput;
  279.       Result := ACM.ChooseFormat(PWaveFormat,'Select Format');
  280.       if Result then
  281.          PWaveFormat := ACM.PWaveFormat;
  282.    finally
  283.       ACM.Free;
  284.    end;
  285. end;
  286. {-- TMMWaveRecorder -----------------------------------------------------------}
  287. procedure TMMWaveRecorder.SetPCMFormat(Mode: TMMMode; Bits: TMMBits; SampleRate: Longint);
  288. var
  289.    wfx: TWaveFormatEx;
  290. begin
  291.    pcmBuildWaveHeader(@wfx, (Ord(Bits)+1)*8, Ord(Mode)+1, SampleRate);
  292.    PWaveFormat := @wfx;
  293. end;
  294. {-- TMMWaveRecorder -----------------------------------------------------------}
  295. function TMMWaveRecorder.SelectFile: Boolean;
  296. begin
  297.    with TSaveDialog.Create(nil) do
  298.    try
  299.       Filter   := 'Wave Files (*.wav)|*.wav|';
  300.       FileName := Self.FileName;
  301.       Options  := Options + [ofPathMustExist, ofFileMustExist, ofHideReadOnly];
  302.       Title    := LoadResStr(IDS_SELECTFILE);
  303.       Result   := Execute;
  304.       if Result then
  305.          Self.FileName := FileName;
  306.    finally
  307.       Free;
  308.    end;
  309. end;
  310. {-- TMMWaveRecorder -----------------------------------------------------------}
  311. procedure TMMWaveRecorder.SaveFormatInRegistry(RootKey: HKEY; Localkey, Field: string);
  312. begin
  313.    SaveInRegistryBinary(RootKey,LocalKey,Field,PWaveFormat^,wioSizeOfWaveFormat(PWaveFormat));
  314. end;
  315. {-- TMMWaveRecorder -----------------------------------------------------------}
  316. procedure TMMWaveRecorder.LoadFormatFromRegistry(RootKey: HKEY; Localkey, Field: string);
  317. var
  318.    wfx: array[0..1024] of Char;
  319. begin
  320.    if GetFromRegistryBinary(RootKey,LocalKey,Field,wfx,sizeOf(wfx)) > 0 then
  321.       PWaveFormat := @wfx;
  322. end;
  323. {-- TMMWaveRecorder -----------------------------------------------------------}
  324. procedure TMMWaveRecorder.SetFileName(aValue: TFileName);
  325. begin
  326.    FWaveFile.Wave.FileName := aValue;
  327. end;
  328. {-- TMMWaveRecorder -----------------------------------------------------------}
  329. function TMMWaveRecorder.GetFileName: TFileName;
  330. begin
  331.    Result := FWaveFile.Wave.FileName;
  332. end;
  333. {-- TMMWaveRecorder -----------------------------------------------------------}
  334. procedure TMMWaveRecorder.SetBufferSize(aValue: Longint);
  335. begin
  336.    FWaveIn.BufferSize := aValue;
  337. end;
  338. {-- TMMWaveRecorder -----------------------------------------------------------}
  339. function TMMWaveRecorder.GetBufferSize: Longint;
  340. begin
  341.    Result := FWaveIn.BufferSize;
  342. end;
  343. {-- TMMWaveRecorder -----------------------------------------------------------}
  344. procedure TMMWaveRecorder.SetNumBuffers(aValue: integer);
  345. begin
  346.    FWaveIn.NumBuffers := aValue;
  347. end;
  348. {-- TMMWaveRecorder -----------------------------------------------------------}
  349. function TMMWaveRecorder.GetNumBuffers: integer;
  350. begin
  351.    Result := FWaveIn.NumBuffers;
  352. end;
  353. {-- TMMWaveRecorder -----------------------------------------------------------}
  354. procedure TMMWaveRecorder.SetDeviceID(aValue: TMMDeviceID);
  355. begin
  356.    FWaveIn.DeviceID := aValue;
  357. end;
  358. {-- TMMWaveRecorder -----------------------------------------------------------}
  359. function TMMWaveRecorder.GetDeviceID: TMMDeviceID;
  360. begin
  361.    Result := FWaveIn.DeviceID;
  362. end;
  363. {-- TMMWaveRecorder -----------------------------------------------------------}
  364. procedure TMMWaveRecorder.SetDummyString(aValue: string);
  365. begin
  366.    ;
  367. end;
  368. {-- TMMWaveRecorder -----------------------------------------------------------}
  369. function TMMWaveRecorder.GetProductName: string;
  370. begin
  371.    Result := FWaveIn.ProductName;
  372. end;
  373. {-- TMMWaveRecorder -----------------------------------------------------------}
  374. function TMMWaveRecorder.GetInputFormat: string;
  375. var
  376.    FormatTag, Format: string;
  377. begin
  378.    Result := 'Unknown';
  379.    if acmGetFormatDescription(FWaveIn.PWaveFormat, FormatTag, Format) then
  380.       Result := FormatTag+' '+Format;
  381. end;
  382. {-- TMMWaveRecorder -----------------------------------------------------------}
  383. procedure TMMWaveRecorder.SetInputFormat(aValue: string);
  384. begin
  385.    MessageDlg('This is a read-only property, please use SelectFormat.',
  386.               mtInformation,[mbOK],0);
  387. end;
  388. {-- TMMWaveRecorder -----------------------------------------------------------}
  389. procedure TMMWaveRecorder.SetTimeFormat(aValue: TMMTimeFormats);
  390. begin
  391.    FWaveIn.TimeFormat  := aValue;
  392.    FWaveFile.Wave.TimeFormat := aValue;
  393. end;
  394. {-- TMMWaveRecorder -----------------------------------------------------------}
  395. function TMMWaveRecorder.GetTimeFormat: TMMTimeFormats;
  396. begin
  397.    Result := FWaveIn.TimeFormat;
  398. end;
  399. {-- TMMWaveRecorder -----------------------------------------------------------}
  400. procedure TMMWaveRecorder.SetCallBackMode(aValue: TMMCBMode);
  401. begin
  402.    FWaveIn.CallBackMode := aValue;
  403. end;
  404. {-- TMMWaveRecorder -----------------------------------------------------------}
  405. function TMMWaveRecorder.GetCallBackMode: TMMCBMode;
  406. begin
  407.    Result := FWaveIn.CallBackMode;
  408. end;
  409. {-- TMMWaveRecorder -----------------------------------------------------------}
  410. procedure TMMWaveRecorder.SetMaxRecTime(aValue: Longint);
  411. begin
  412.    FWaveIn.MaxRecordTime := aValue;
  413. end;
  414. {-- TMMWaveRecorder -----------------------------------------------------------}
  415. function TMMWaveRecorder.GetMaxRecTime: Longint;
  416. begin
  417.    Result := FWaveIn.MaxRecordTime;
  418. end;
  419. {-- TMMWaveRecorder -----------------------------------------------------------}
  420. procedure TMMWaveRecorder.SetOverwrite(aValue: Boolean);
  421. begin
  422.    FWaveFile.OverwriteExisting := aValue;
  423. end;
  424. {-- TMMWaveRecorder -----------------------------------------------------------}
  425. function TMMWaveRecorder.GetOverwrite: Boolean;
  426. begin
  427.    Result := FWaveFile.OverwriteExisting;
  428. end;
  429. {-- TMMWaveRecorder -----------------------------------------------------------}
  430. function TMMWaveRecorder.GetState: TMMWaveInState;
  431. begin
  432.    Result := FWaveIn.State;
  433. end;
  434. {-- TMMWaveRecorder -----------------------------------------------------------}
  435. procedure TMMWaveRecorder.SetPosition(aValue: Longint);
  436. begin
  437.    if (wisOpen in State) then
  438.        raise EMMWaveRecorderError.Create(LoadResStr(IDS_PROPERTYOPEN));
  439.    if not OverwriteExisting then
  440.       FWaveFile.Wave.Position := aValue;
  441. end;
  442. {-- TMMWaveRecorder -----------------------------------------------------------}
  443. function TMMWaveRecorder.GetPosition: Longint;
  444. begin
  445.    if (wisOpen in State) then
  446.    begin
  447.       Result := FWaveIn.Position;
  448.       if not OverwriteExisting then
  449.          inc(Result,FStartPos);
  450.    end
  451.    else if not OverwriteExisting then
  452.       Result := FWaveFile.Wave.Position
  453.    else
  454.       Result := 0;
  455. end;
  456. {-- TMMWaveRecorder -----------------------------------------------------------}
  457. procedure TMMWaveRecorder.DoChange(Sender: TObject);
  458. begin
  459.    FChanging := True;
  460.    Stop;
  461.    if assigned(FOnChange) then FOnChange(Self);
  462. end;
  463. {-- TMMWaveRecorder -----------------------------------------------------------}
  464. procedure TMMWaveRecorder.DoChanged(Sender: TObject);
  465. begin
  466.    FChanging := False;
  467. end;
  468. {-- TMMWaveRecorder -----------------------------------------------------------}
  469. procedure TMMWaveRecorder.DoClose(Sender: TObject);
  470. begin
  471.    Stop;
  472. end;
  473. {-- TMMWaveRecorder -----------------------------------------------------------}
  474. procedure TMMWaveRecorder.DoStart(Sender: TObject);
  475. begin
  476.    if assigned(FOnStart) then FOnStart(Self);
  477. end;
  478. {-- TMMWaveRecorder -----------------------------------------------------------}
  479. procedure TMMWaveRecorder.DoStop(Sender: TObject);
  480. begin
  481.    FWaveIn.Close;
  482.    if assigned(FOnStop) then FOnStop(Self);
  483. end;
  484. {-- TMMWaveRecorder -----------------------------------------------------------}
  485. procedure TMMWaveRecorder.DoPause(Sender: TObject);
  486. begin
  487.    if assigned(FOnPause) then FOnPause(Self);
  488. end;
  489. {-- TMMWaveRecorder -----------------------------------------------------------}
  490. procedure TMMWaveRecorder.DoRestart(Sender: Tobject);
  491. begin
  492.    if assigned(FOnRestart) then FOnRestart(Self);
  493. end;
  494. {-- TMMWaveRecorder -----------------------------------------------------------}
  495. procedure TMMWaveRecorder.DoData(Sender: TObject; lpwh: PWaveHdr);
  496. begin
  497.    if assigned(FOnData) then FOnData(Self,lpwh);
  498. end;
  499. {-- TMMWaveRecorder -----------------------------------------------------------}
  500. procedure TMMWaveRecorder.Recording;
  501. begin
  502.    if not (wisRecord in State) and (FWaveFile.Wave.FileName <> '') then
  503.    begin
  504.       FStartPos := FWaveFile.Wave.Position;
  505.       FWaveIn.Start;
  506.    end;
  507. end;
  508. {-- TMMWaveRecorder -----------------------------------------------------------}
  509. procedure TMMWaveRecorder.Stop;
  510. begin
  511.    FWaveIn.Stop;
  512.    FWaveIn.Close;
  513. end;
  514. {-- TMMWaveRecorder -----------------------------------------------------------}
  515. procedure TMMWaveRecorder.Pause;
  516. begin
  517.    if not (wisPause in State) and (FWaveFile.Wave.FileName <> '') then FWaveIn.Pause;
  518. end;
  519. {-- TMMWaveRecorder -----------------------------------------------------------}
  520. procedure TMMWaveRecorder.Restart;
  521. begin
  522.    FWaveIn.Restart;
  523. end;
  524. end.