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

📄 mmfade.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{========================================================================}
{=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
{========================================================================}
{=                          All Rights Reserved                         =}
{========================================================================}
{=  D 01099 Dresden             = Fax.: +49(0)351-8037944               =}
{=  Loewenstr.7a                = info@swiftsoft.de                     =}
{========================================================================}
{=  Actual versions on http://www.swiftsoft.de/index.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: 01.11.98 - 03:53:31 $                                        =}
{========================================================================}
unit MMFade;

{$I COMPILER.INC}

interface

uses
{$IFDEF WIN32}
  Windows,
{$ELSE}
  WinProcs,
  WinTypes,
{$ENDIF}
  SysUtils,
  Messages,
  Classes,
  Controls,
  MMSystem,
  MMObj,
  MMutils,
  MMMulDiv,
  MMRegs,
  MMPCMSup;

const
    Overflow  : Boolean = False;
type
    PMMFadePoint = ^TMMFadePoint;
    TMMFadePoint = record
       Offset    : Longint;
       Volume    : Longint;
       VolumeL   : Longint;
       VolumeR   : Longint;
       Selected  : LongBool;
    end;

    PMMFadeSeg   = ^TMMFadeSeg;
    TMMFadeSeg   = record
       ptStart   : TMMFadePoint;
       ptEnd     : TMMFadePoint;
    end;

const
    { Maximum List size }
    MaxFadeListSize   = Maxint div (sizeOf(TMMFadePoint)*sizeOf(TMMFadePoint));

type
    PMMFadeArray = ^TMMFadeArray;
    TMMFadeArray = array[0..MaxFadeListSize-1] of TMMFadePoint;

    {-- TMMFadeList -----------------------------------------------------}
    TMMFadeList = class(TMMObject)
    private
       FList        : PMMFadeArray;
       FCount       : Integer;
       FCapacity    : Integer;

       FCurIndex    : Longint;
       FStartOffset : Longint;
       FStartVolume : Longint;
       FStartVolumeL: Longint;
       FStartVolumeR: Longint;

    protected
       procedure Error; virtual;
       procedure Grow; virtual;
       function  Get(Index: Integer): PMMFadePoint;
       procedure Put(Index: Integer; Point: PMMFadePoint);
       procedure SetCapacity(NewCapacity: Integer);
       procedure SetCount(NewCount: Integer);

    public
        destructor  Destroy; override;

        procedure Clear;
        procedure Sort;

        function  Add(Point: TMMFadePoint): Integer;
        procedure Insert(Index: Integer; Point: TMMFadePoint);
        procedure Delete(Index: Integer);
        function  Selected(Index: Integer): Boolean;

        function  QueryFadePoint(Point: TMMFadePoint): Boolean;
        function  AddFadePoint(Point: TMMFadePoint; Align: Boolean): Boolean;
        function  LocateFadePoint(Offset: Longint): integer;
        function  FindFadePoint(Offset: Longint): integer;
        function  CalcFadeVolume(Offset: Longint): Longint;

        procedure Assign(Source: TPersistent); override;
        procedure AssignEnvelope(Source: TPersistent); virtual;
        procedure AssignToEnvelope(Dest: TPersistent); virtual;

        function  First: PMMFadePoint;
        function  Last: PMMFadePoint;
        function  Expand: TMMFadeList;
        property  Capacity: Integer read FCapacity write SetCapacity;
        property  Count: Integer read FCount write SetCount;
        property  Points[Index: Integer]: PMMFadePoint read Get write Put; default;
        property  List: PMMFadeArray read FList;

        property  CurIndex: Longint read FCurIndex write FCurIndex;
        property  StartOffset: Longint read FStartOffset write FStartOffset;
        property  StartVolumeL: Longint read FStartVolumeL write FStartVolumeL;
        property  StartVolumeR: Longint read FStartVolumeR write FStartVolumeR;
    end;

function pcmVolumeFade(pwfx: PWaveFormatEx; lpData: PChar;
                       dwSrcLen: TDataSize; FadeList: TMMFadeList): Boolean;

function pcmVolumeFade8(pwfx: PWaveFormatEx; lpData: PChar;
                        dwSrcLen: TDataSize; FadeList: TMMFadeList): Boolean;

function pcmVolumeFade16(pwfx: PWaveFormatEx; lpData: PChar;
                         dwSrcLen: TDataSize; FadeList: TMMFadeList): Boolean;

implementation

uses
    Consts,
    {$IFDEF DELPHI6}
    RTLConsts,
    {$ENDIF}
    MMEnvelp;

{------------------------------------------------------------------------}
{$IFDEF DELPHI3}
procedure ListError(const Ident: string);
begin
   raise EListError.Create(Ident);
end;
{$ELSE}
procedure ListError(Ident: Word);
begin
   raise EListError.CreateRes(Ident);
end;
{$ENDIF}

{------------------------------------------------------------------------}
procedure ListIndexError;
begin
   ListError(SListIndexError);
end;

{== TMMFadeList =========================================================}
destructor TMMFadeList.Destroy;
begin
   FStartVolume := 0;

   Clear;
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Error;
begin
   ListIndexError;
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Clear;
begin
   SetCount(0);
   SetCapacity(0);
end;

{-- TMMFadeList ---------------------------------------------------------}
{ QueryPoint sagt, ob dieser punkt eingefuegt werden kann.                    }
function TMMFadeList.QueryFadePoint(Point: TMMFadePoint): Boolean;
var
   i: integer;

begin
   Result := True;
   for i := 0 to Count-1 do
   begin
      if ((i = 0) and (Point.Offset <= Points[i]^.Offset)) or
         ((i = Count-1) and (Point.Offset >= Points[i]^.Offset)) or
         (Points[i]^.Offset = Point.Offset) then
      begin
         Result := False;
         exit;
      end;
   end;
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.AddFadePoint(Point: TMMFadePoint; Align: Boolean): Boolean;
var
  i: integer;

begin
   Result := False;
   if QueryFadePoint(Point) then     { passt hier Punkt ueberhaupt hin ? }
   begin
      i := LocateFadePoint(Point.Offset);
      if (i < 1) or (i >= Count) then Add(Point)
      else
      begin
         { neuen Punkt genau auf Linie zwischen zwei Punken einf黦en }
         if Align then
         with Point do
         begin
            Volume := CalcFadeVolume(Offset);
         end;
         Insert(i, Point);
      end;
      Result := True;
   end;
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.Add(Point: TMMFadePoint): Integer;
begin
   Result := FCount;
   if Result = FCapacity then Grow;
   FList^[Result] := Point;
   inc(FCount);
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Insert(Index: Integer; Point: TMMFadePoint);
begin
   if (Index < 0) or (Index > FCount) then Error;
   if FCount = FCapacity then Grow;
   if Index < FCount then
      System.Move(FList^[Index], FList^[Index + 1],
                 (FCount - Index) * SizeOf(TMMFadePoint));
   FList^[Index] := Point;
   Inc(FCount);
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Delete(Index: Integer);
begin
   if (Index < 0) or (Index >= FCount) then Error;
   Dec(FCount);
   if Index < FCount then
      System.Move(FList^[Index + 1], FList^[Index],
                 (FCount - Index) * SizeOf(TMMFadePoint));
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.Selected(Index: Integer): Boolean;
begin
   if (Index < 0) or (Index >= FCount) then Error;
   Result := FList^[Index].Selected;
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.First: PMMFadePoint;
begin
   Result := Get(0);
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.Last: PMMFadePoint;
begin
   Result := Get(FCount-1);
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.Get(Index: Integer): PMMFadePoint;
begin
   if (Index < 0) or (Index >= FCount) then Error;
   Result := @FList^[Index];
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Put(Index: Integer; Point: PMMFadePoint);
begin
   if (Index < 0) or (Index >= FCount) then Error;
   FList^[Index] := Point^;
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Grow;
var
  Delta: Integer;
begin
   if FCapacity > 8 then
      Delta := 16
   else if FCapacity > 4 then
      Delta := 8
   else
      Delta := 4;
  SetCapacity(FCapacity + Delta);
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.SetCapacity(NewCapacity: Integer);
begin
   if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then Error;

   if NewCapacity <> FCapacity then
   begin
     {$IFDEF WIN32}
     ReallocMem(FList, NewCapacity * SizeOf(TMMFadePoint));
     {$ELSE}
     if NewCapacity = 0 then
     begin
        GlobalFreePtr(FList);
        FList := nil;
     end
     else
     begin
        if FCapacity = 0 then
           FList := GlobalAllocPtr(HeapAllocFlags, NewCapacity*sizeOf(TMMFadePoint))
        else
           FList := GlobalReallocPtr(FList, NewCapacity*sizeOf(TMMFadePoint), HeapAllocFlags);
        if FList = nil then
           raise EStreamError.Create(LoadStr(SMemoryStreamError));
     end;
     {$ENDIF}
     FCapacity := NewCapacity;
   end;
end;

{-- TMMFadeList ---------------------------------------------------------}
function TMMFadeList.Expand: TMMFadeList;
begin
   if FCount = FCapacity then Grow;
   Result := Self;
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.SetCount(NewCount: Integer);
begin
   if (NewCount < 0) or (NewCount > MaxListSize) then Error;
   if NewCount > FCapacity then SetCapacity(NewCount);
   if NewCount > FCount then
      FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(TMMFadePoint), 0);
   FCount := NewCount;
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.Assign(Source: TPersistent);
var
   i: integer;
   p: TMMFadePoint;

begin
   if (Source is TMMFadeList) or (Source = nil) then
   begin
      if (Source <> Self) then
      begin
         Clear;
         if (Source <> nil) then
         begin
            Capacity := TMMFadeList(Source).Count;
            for i := 0 to TMMFadeList(Source).Count-1 do
            begin
               p := TMMFadeList(Source).Points[i]^;
               p.Selected := False;
               Add(p);
            end;
         end;
      end;
   end
   else inherited assign(Source);
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.AssignEnvelope(Source: TPersistent);
var
   i: integer;
   p: TMMFadePoint;

begin
   if (Source is TMMEnvelope) or (Source = nil) then
   begin
      Clear;
      if (Source <> nil) then
      begin
         Capacity := TMMEnvelope(Source).Count;
         for i := 0 to TMMEnvelope(Source).Count-1 do
         begin
            p.Offset   := TMMEnvelope(Source).Points[i].X_Value;
            p.Volume   := TMMEnvelope(Source).Points[i].Y_Value;
            p.Selected := False;
            Add(p);
         end;
      end;
   end
   else inherited assign(Source);
end;

{-- TMMFadeList ---------------------------------------------------------}
procedure TMMFadeList.AssignToEnvelope(Dest: TPersistent);
var
   i: integer;
   aPoint: TMMEnvelopePoint;

begin
   if (Dest <> nil) and (Dest is TMMEnvelope) then
   begin
      TMMEnvelope(Dest).Clear;
      aPoint := TMMEnvelopePoint.Create;
      try
         for i := 0 to Count-1 do
         begin
            aPoint.X_Value  := Points[i]^.Offset;
            aPoint.Y_Value  := Points[i]^.Volume;
            aPoint.Selected := False;
            TMMEnvelope(Dest).AddPoint(aPoint,False);
         end;
      finally
        aPoint.Free;
      end;
   end;
end;

{-- TMMFadeList --------------------------------------------------------}
function TMMFadeList.LocateFadePoint(Offset: Longint): integer;
{ LocatePoint returns the Index of the first point, which lies right   }
{ from Offset. Is the list empty -1, is there no other element Count(!)     }
var
   L, H : integer;

begin
   if (Count = 0) then
   begin
      Result := -1;
   end
   else
   begin
      if Points[Count-1]^.Offset <= Offset then
      begin
         Result := Count;
      end
      else
      begin
         L := 0;
         H := Count-1;
         Result := H shr 1;
         while L < H do
         begin
            if Points[Result]^.Offset <= Offset then
               L := Result+1

⌨️ 快捷键说明

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