📄 mmfade.pas
字号:
{========================================================================}
{= (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 + -