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

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: 15.08.98 - 14:20:44 $                                        =}
  24. {========================================================================}
  25. unit MMDelay;
  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.     MMSystem,
  39.     MMRegs,
  40.     MMObj,
  41.     MMDSPObj,
  42.     MMUtils,
  43.     MMWaveIO,
  44.     MMPCMSup,
  45.     MMFX;
  46. type
  47.    EMMDelayError = class(Exception);
  48.    {-- TMMDelay ---------------------------------------------------------}
  49.    TMMDelay = class(TMMDSPComponent)
  50.    private
  51.       FEnabled       : Boolean;
  52.       FOpen          : Boolean;
  53.       FPDelay        : PDelay;
  54.       FMaxDelay      : integer;
  55.       FDelayLeft     : integer;
  56.       FDelayRight    : integer;
  57.       FCleanup       : Longint;
  58.       procedure SetEnabled(aValue: Boolean);
  59.       procedure SetDelays(index: integer; aValue: integer);
  60.    protected
  61.       procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
  62.       procedure Update; virtual;
  63.       procedure Opened; override;
  64.       procedure Closed; override;
  65.       procedure Started; override;
  66.       procedure BufferReady(lpwh: PWaveHdr); override;
  67.       procedure BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean); override;
  68.    public
  69.       constructor Create(aOwner: TComponent); override;
  70.       destructor Destroy; override;
  71.       procedure Open;
  72.       procedure Close;
  73.       procedure Process(Buffer: PChar; Length: integer);
  74.       function  CleanUp(Buffer: PChar; Length: integer): Longint;
  75.    published
  76.       property Input;
  77.       property Output;
  78.       property Enabled: Boolean read FEnabled write SetEnabled default True;
  79.       property MaxDelay: integer index 0 read FMaxDelay write SetDelays default 250;
  80.       property DelayLeft: integer index 1 read FDelayLeft write SetDelays default 1;
  81.       property DelayRight: integer index 2 read FDelayRight write SetDelays default 1;
  82.    end;
  83. implementation
  84. {== TMMDelay ============================================================}
  85. constructor TMMDelay.Create(aOwner: TComponent);
  86. begin
  87.    inherited Create(aOwner);
  88.    FEnabled    := True;
  89.    FOpen       := False;
  90.    FPDelay     := nil;
  91.    FMaxDelay   := 250;
  92.    FDelayLeft  := 1;
  93.    FDelayRight := 1;
  94. end;
  95. {-- TMMDelay ------------------------------------------------------------}
  96. destructor TMMDelay.Destroy;
  97. begin
  98.    Close;
  99.    inherited Destroy;
  100. end;
  101. {-- TMMDelay ------------------------------------------------------------}
  102. procedure TMMDelay.SetEnabled(aValue: Boolean);
  103. begin
  104.    if (aValue <> FEnabled) then
  105.    begin
  106.       FEnabled := aValue;
  107.       if FEnabled then Update;
  108.    end;
  109. end;
  110. {-- TMMDelay ------------------------------------------------------------}
  111. procedure TMMDelay.SetDelays(index: integer; aValue: integer);
  112. begin
  113.    case index of
  114.       0: if (aValue = FMaxDelay) then exit else
  115.          begin
  116.             FMaxDelay := aValue;
  117.          end;
  118.       1: if (aValue = FDelayLeft) then exit else
  119.          begin
  120.             FDelayLeft := MinMax(aValue,1,FMaxDelay);
  121.             Update;
  122.          end;
  123.       2: if (aValue = FDelayRight) then exit else
  124.          begin
  125.             FDelayRight := MinMax(aValue,1,FMaxDelay);
  126.             Update;
  127.          end;
  128.    end;
  129. end;
  130. {-- TMMDelay ------------------------------------------------------------}
  131. procedure TMMDelay.SetPWaveFormat(aValue: PWaveFormatEx);
  132. begin
  133.    if (aValue <> nil) then
  134.    begin
  135.       if not (csDesigning in ComponentState) then
  136.          if not pcmIsValidFormat(aValue) then
  137.             raise EMMDelayError.Create(LoadResStr(IDS_INVALIDFORMAT));
  138.    end;
  139.    inherited SetPWaveFormat(aValue);
  140. end;
  141. {-- TMMDelay ------------------------------------------------------------}
  142. procedure TMMDelay.Open;
  143. begin
  144.    if not FOpen then
  145.    begin
  146.       if pcmIsValidFormat(PWaveFormat) then
  147.       begin
  148.          FPDelay := InitDelay(PWaveFormat, FMaxDelay);
  149.          if (FPDelay = nil) then OutOfMemoryError
  150.          else
  151.          begin
  152.             FOpen := True;
  153.             Update;
  154.          end;
  155.       end;
  156.    end;
  157. end;
  158. {-- TMMDelay ------------------------------------------------------------}
  159. procedure TMMDelay.Close;
  160. begin
  161.    if FOpen then
  162.    begin
  163.       FOpen := False;
  164.       DoneDelay(FPDelay);
  165.    end;
  166. end;
  167. {-- TMMDelay ------------------------------------------------------------}
  168. procedure TMMDelay.Process(Buffer: PChar; Length: integer);
  169. begin
  170.    { process the buffer trough the delay line }
  171.    if (FPDelay <> nil) then DoDelay(FPDelay, Buffer, Length);
  172. end;
  173. {-- TMMDelay ------------------------------------------------------------}
  174. function TMMDelay.CleanUp(Buffer: PChar; Length: integer): Longint;
  175. begin
  176.    { process the remaining delayed bytes in the delay lines }
  177.    if (FPDelay <> nil) and (FCleanup > 0) then
  178.    begin
  179.       FCleanup := Max(FCleanup - Length,0);
  180.       FillChar(Buffer^, Length, 0);
  181.       Process(Buffer, Length);
  182.    end;
  183.    { return the remaining bytes to process }
  184.    Result := FCleanup;
  185. end;
  186. {-- TMMDelay ------------------------------------------------------------}
  187. procedure TMMDelay.Update;
  188. begin
  189.    { setup the delay lines with the params }
  190.    if FOpen then
  191.    begin
  192.       FCleanup := 0;
  193.       if (FDelayLeft > FCleanUp) then FCleanUp := FDelayLeft;
  194.       if (FDelayRight > FCleanUp) then FCleanUp := FDelayRight;
  195.       if (FCleanup > 0) then
  196.       begin
  197.          { convert cleanup time to bytes }
  198.          FCleanup := wioTimeToBytes(PWaveFormat,FCleanup);
  199.       end;
  200.       { now update the delay lines }
  201.       SetDelay(FPDelay, FDelayLeft, FDelayRight);
  202.    end;
  203. end;
  204. {-- TMMDelay ------------------------------------------------------------}
  205. procedure TMMDelay.Opened;
  206. begin
  207.    Open;
  208.    inherited Opened;
  209. end;
  210. {-- TMMDelay ------------------------------------------------------------}
  211. procedure TMMDelay.Closed;
  212. begin
  213.    Close;
  214.    inherited Closed;
  215. end;
  216. {-- TMMDelay ------------------------------------------------------------}
  217. procedure TMMDelay.Started;
  218. begin
  219.    Update;
  220.    inherited Started;
  221. end;
  222. {-- TMMDelay ------------------------------------------------------------}
  223. procedure TMMDelay.BufferReady(lpwh: PWaveHdr);
  224. begin
  225.    if Enabled and FOpen then
  226.    begin
  227.       Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
  228.    end;
  229.    inherited BufferReady(lpwh);
  230. end;
  231. {-- TMMDelay ------------------------------------------------------------}
  232. procedure TMMDelay.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
  233. var
  234.    aLength: Longint;
  235. begin
  236.    inherited BufferLoad(lpwh, MoreBuffers);
  237.    if Enabled and FOpen then
  238.    begin
  239.       if not MoreBuffers then
  240.       begin
  241.          aLength := lpwh^.dwBufferLength;
  242.          if Cleanup(lpwh^.lpData, aLength) > 0 then MoreBuffers := True;
  243.          lpwh^.dwBytesRecorded := aLength;
  244.       end
  245.       else Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
  246.    end;
  247. end;
  248. end.