⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmreverb.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{========================================================================}
{=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
{========================================================================}
{=                          All Rights Reserved                         =}
{========================================================================}
{=  D 01099 Dresden             = Tel.: +0351-8012255                   =}
{=  Loewenstr.7a                = info@swiftsoft.de                     =}
{========================================================================}
{=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
{========================================================================}
{=  This code is for reference purposes only and may not be copied or   =}
{=  distributed in any format electronic or otherwise except one copy   =}
{=  for backup purposes.                                                =}
{=                                                                      =}
{=  No Delphi Component Kit or Component individually or in a collection=}
{=  subclassed or otherwise from the code in this unit, or associated   =}
{=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
{=  without express permission from SwiftSoft.                          =}
{=                                                                      =}
{=  For more licence informations please refer to the associated        =}
{=  HelpFile.                                                           =}
{========================================================================}
{=  $Date: 1/29/98 - 5:37:12 PM $                                      =}
{========================================================================}
unit MMReverb;

{$I COMPILER.INC}

interface

uses
{$IFDEF WIN32}
    Windows,
{$ELSE}
    WinTypes,
    WinProcs,
{$ENDIF}
    SysUtils,
    Classes,
    Controls,
    MMSystem,
    MMRegs,
    MMObj,
    MMDSPObj,
    MMObjLst,
    MMUtils,
    MMWaveIO,
    MMPCMSup,
    MMFX;

type
   TMMEchoIndex = 0..MaxEchos-1;

   EMMReverbError = class(Exception);
   TMMReverb = class;

   {-- TMMEcho ----------------------------------------------------------}
   TMMEcho = class(TObject)
   private
      FDelay   : Longint;          { delay (ms) for this echo line       }
      FGain    : Longint;          { mix volume (%) for this echo        }
      FOnChange: TNotifyEvent;

      procedure SetDelay(aValue: Longint);
      procedure SetGain(aValue: Longint);

      procedure Store(S: TStream); virtual;
      procedure Load(S: TStream); virtual;

   protected
      procedure Changed; virtual;

   public
      constructor Create;
      procedure Assign(Source: TObject);

      procedure SetParams(aDelay, aGain: Longint);

      property OnChange: TNotifyEvent read FOnChange write FOnChange;
      property Delay: Longint read FDelay write SetDelay default 0;
      property Gain: Longint read FGain write SetGain default 0;
   end;

   {-- TMMEchoList ------------------------------------------------------}
   TMMEchoList = class(TObjectList)
   private
      FReverb: TMMReverb;

      procedure SetEcho(Index: TMMEchoIndex; Echo: TMMEcho);
      function  GetEcho(Index: TMMEchoIndex): TMMEcho;

   protected
      procedure ReadData(S: TStream); override;
      procedure WriteData(S: TStream); override;

   public
      function  AddObject(Item: TObject): TOLSize; override;
      procedure Assign(Source: TPersistent); override;
      property Items[Index: TMMEchoIndex]: TMMEcho read GetEcho write SetEcho; default;
   end;

   {-- TMMReverb --------------------------------------------------------}
   TMMReverb = class(TMMDSPComponent)
   private
      FEnabled       : Boolean;
      FOpen          : Boolean;
      FPReverb       : PReverb;
      FDescription   : String;
      FMaxDelay      : integer;
      FInputGain     : TMMEffectVolume;
      FInputPan      : TMMEffectVolume;
      FOutputGain    : TMMEffectVolume;
      FFeedBack      : TMMFeedBack;
      FFilter        : Boolean;
      FEchos         : TMMEchoList;
      FUpdating      : Boolean;
      FCleanup       : Longint;

      FOnChange      : TNotifyEvent;
      FOnPcmOverflow : TNotifyEvent;

      procedure SetEnabled(aValue: Boolean);
      procedure SetDescription(aValue: String);
      procedure SetMaxDelay(aValue: integer);
      procedure SetGains(index: integer; aValue: TMMEffectVolume);
      procedure SetFeedBack(aValue: TMMFeedBack);
      procedure SetFilter(aValue: Boolean);
      procedure SetEchos(aValue: TMMEchoList);
      procedure EchosChanged(Sender: TObject);

   protected
      procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
      procedure Assign(Source: TPersistent); override;
      procedure Change; dynamic;
      procedure Update; virtual;
      procedure Opened; override;
      procedure Closed; override;
      procedure Started; override;
      procedure PcmOverflow; dynamic;
      procedure BufferReady(lpwh: PWaveHdr); override;
      procedure BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean); override;

   public
      constructor Create(aOwner: TComponent); override;
      destructor Destroy; override;

      procedure Open;
      procedure Close;
      procedure Process(Buffer: PChar; Length: integer);
      function  CleanUp(Buffer: PChar; Length: integer): Longint;

      procedure SaveToIniFile(IniFile: TFileName; Section: string);
      procedure ReadFromIniFile(IniFile: TFileName; Section: string);
      procedure ReadIniSections(IniFile: TFileName; Strings: TStrings);
      procedure DeleteSection(IniFile: TFileName; Section: string);

   published
      property OnChange: TNotifyEvent read FOnChange write FOnChange;
      property OnPcmOverflow: TNotifyEvent read FOnPcmOverflow write FOnPcmOverflow;

      property Input;
      property Output;
      property Enabled: Boolean read FEnabled write SetEnabled default True;
      property Description: String read FDescription write SetDescription stored False;
      property MaxDelay: integer read FMaxDelay write SetMaxDelay stored False;
      property InputGain: TMMEffectVolume index 0 read FInputGain write SetGains stored False;
      property InputPan: TMMEffectVolume index 1 read FInputPan write SetGains stored False;
      property OutputGain: TMMEffectVolume index 2 read FOutputGain write SetGains stored False;
      property FeedBack: TMMFeedBack read FFeedback write SetFeedBack stored False;
      property Filter: Boolean read FFilter write SetFilter stored False;
      property Echos: TMMEchoList read FEchos write SetEchos;
   end;

implementation

uses IniFiles;

const
   STREAMKENNUNG : Longint = $00425652; { 'RVB ' }

{== TMMEcho =============================================================}
constructor TMMEcho.Create;
begin
   inherited Create;

   FDelay := 0;
   FGain  := 0;
   FOnChange := nil;
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.Changed;
begin
   if assigned(FOnChange) then FOnChange(Self);
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.SetParams(aDelay, aGain: Longint);
begin
   if (aDelay <> FDelay) or (aGain <> FGain) then
   begin
      FDelay := aDelay;
      FGain := aGain;
      Changed;
   end;
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.SetDelay(aValue: Longint);
begin
   SetParams(aValue, FGain);
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.SetGain(aValue: Longint);
begin
   SetParams(FDelay, aValue);
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.Store(S: TStream);
begin
   S.WriteBuffer(FDelay,SizeOf(FDelay));
   S.WriteBuffer(FGain,SizeOf(FGain));
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.Load(S: TStream);
var
   aDelay,aGain: Longint;

begin
   S.ReadBuffer(aDelay,SizeOf(aDelay));
   S.ReadBuffer(aGain,SizeOf(aGain));
   SetParams(aDelay,aGain);
end;

{-- TMMEcho -------------------------------------------------------------}
procedure TMMEcho.Assign(Source: TObject);
begin
   if Source is TMMEcho then
   begin
      SetParams(TMMEcho(Source).Delay,TMMEcho(Source).Gain);
   end;
end;

{== TMMEchoList =========================================================}
procedure TMMEchoList.SetEcho(Index: TMMEchoIndex; Echo: TMMEcho);
begin
   Put(Index, Echo);
end;

{-- TMMEchoList ---------------------------------------------------------}
function TMMEchoList.GetEcho(Index: TMMEchoIndex): TMMEcho;
begin
   Result := TMMEcho(Get(Index));
end;

{-- TMMEchoList ---------------------------------------------------------}
function TMMEchoList.AddObject(Item: TObject): TOLSize;
begin
   Result := inherited AddObject(Item);
   (Item as TMMEcho).OnChange := OnChange;
end;

{-- TMMEchoList ---------------------------------------------------------}
procedure TMMEchoList.Assign(Source: TPersistent);
var
   i: integer;
   Echo: TMMEcho;

begin
   if (Source is TMMEchoList) or (Source = nil) then
   begin
      BeginUpdate;
      try
         FReverb.FUpdating := True;
         FreeAll;
         if (Source <> nil) then
         for i := 0 to TMMEchoList(Source).Count-1 do
         begin
            Echo := TMMEcho.Create;
            Echo.Assign(TMMEchoList(Source)[i]);
            AddObject(Echo);
         end;

      finally
         FReverb.FUpdating := False;
         EndUpdate;
      end;
      exit;
   end;

   inherited assign(Source);
end;

{-- TMMEchoList ---------------------------------------------------------}
procedure TMMEchoList.ReadData(S: TStream);
Var
   pBuf: PChar;
   Kennung: Longint;
   ObjCount,
   Index: TOLSize;
   Destroy: Boolean;
   Value: Longint;

begin
   BeginUpdate;
   try
      FReverb.FUpdating := True;
      S.ReadBuffer(Kennung,sizeOf(STREAMKENNUNG));
      if (Kennung <> STREAMKENNUNG) then
         raise EStreamError.Create('Invalid Object stream');
      FreeAll;
      { load stream items }
      S.ReadBuffer(Destroy,SizeOf(Destroy));
      DestroyObjects := Destroy;

      { read string length }
      S.ReadBuffer(Value,SizeOf(Value));
      if Value > 0 then
      begin
         pBuf := StrAlloc(Value+1);
         try
            FillChar(pBuf^, Value+1, 0);
            S.ReadBuffer(pBuf^, Value);
            FReverb.Description := StrPas(pBuf);
         finally
            StrDispose(pBuf);
         end;
      end;

      S.ReadBuffer(Value,SizeOf(Value));
      FReverb.FMaxDelay := Value;
      S.ReadBuffer(Value,SizeOf(Value));
      FReverb.FInputGain := Value;
      S.ReadBuffer(Value,SizeOf(Value));
      FReverb.FInputPan := Value;
      S.ReadBuffer(Value,SizeOf(Value));
      FReverb.FOutputGain := Value;
      S.ReadBuffer(Value,SizeOf(Value));
      FReverb.FFeedBack := Value;

      S.ReadBuffer(ObjCount,SizeOf(Objcount));  { Read in Object count }
      ObjCount := Min(ObjCount,MAXECHOS);
      if Capacity-Count < ObjCount then Capacity := Count+ObjCount;

      { Read in Object Count }
      for Index := 0 to ObjCount-1 do
          AddObject(ReadObjectFromStream(S));

   finally
      FReverb.FUpdating := False;
      EndUpdate;
   end;
end;

{-- TMMEchoList ---------------------------------------------------------}
procedure TMMEchoList.WriteData(S: TStream);
var
   Index,ObjCount: TOlSize;
   Destroy: Boolean;
   Value: Longint;

begin
   { Write list to Stream }
   S.WriteBuffer(STREAMKENNUNG,SizeOf(STREAMKENNUNG));
   Destroy := DestroyObjects;
   S.WriteBuffer(Destroy,SizeOf(Destroy));

   { write string length }
   Value := Length(FReverb.FDescription);
   S.WriteBuffer(Value, SizeOf(Value));
{$IFDEF WIN32}
   S.WriteBuffer(PChar(FReverb.FDescription)^, Length(FReverb.FDescription));
{$ELSE}
   S.WriteBuffer(FReverb.FDescription[1], Length(FReverb.FDescription));
{$ENDIF}

   Value := FReverb.FMaxDelay;
   S.WriteBuffer(Value, SizeOf(Value));
   Value := FReverb.FInputGain;
   S.WriteBuffer(Value, SizeOf(Value));
   Value := FReverb.FInputPan;
   S.WriteBuffer(Value, SizeOf(Value));
   Value := FReverb.FOutputGain;
   S.WriteBuffer(Value, SizeOf(Value));
   Value := FReverb.FFeedBack;
   S.WriteBuffer(Value, SizeOf(Value));

   ObjCount := Count;
   S.WriteBuffer(ObjCount,SizeOf(ObjCount));
   for Index := 0 to Count-1 do
       WriteObjectToStream(Items[Index],S);
end;

{== TMMReverb ===========================================================}
constructor TMMReverb.Create(aOwner: TComponent);
var
   i: integer;

begin
   inherited Create(aOwner);

   FEchos := TMMEchoList.Create;
   FEchos.OnChange := EchosChanged;
   FEchos.FReverb  := Self;

   for i := 0 to MAXECHOS-1 do FEchos.AddObject(TMMEcho.Create);

   FPReverb    := nil;
   FDescription:= 'Untitled';
   FEnabled    := True;
   FOpen       := False;
   FUpdating   := False;

   FMaxDelay   := 250;
   FInputGain  := 80;
   FInputPan   := 0;
   FOutputGain := 100;
   FFeedBack   := 0;
   FFilter     := False;
end;

{-- TMMReverb -----------------------------------------------------------}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -