MMLevel.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:64k
- {========================================================================}
- {= (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: 10.01.99 - 15:45:43 $ =}
- {========================================================================}
- Unit MMLevel;
- {$C FIXED PRELOAD PERMANENT}
- {$I COMPILER.INC}
- Interface
- Uses
- {$IFDEF WIN32}
- Windows,
- {$ELSE}
- WinTypes,
- WinProcs,
- {$ENDIF}
- SysUtils,
- Messages,
- Classes,
- Graphics,
- Controls,
- Forms,
- Dialogs,
- Menus,
- MMSystem,
- MMUtils,
- MMString,
- MMObj,
- MMTimer,
- MMMulDiv,
- MMMath,
- MMRegs,
- MMPCMSup,
- MMWaveIO,
- MMDIBCv,
- MMScale;
- const
- {$IFDEF CBUILDER3} {$EXTERNALSYM MAXDECAYCOUNT} {$ENDIF}
- MAXDECAYCOUNT = 32; { Maximum amount of temporal averaging allowed }
- {$IFDEF CBUILDER3} {$EXTERNALSYM VALUERANGE} {$ENDIF}
- VALUERANGE = 100; { Range for SetValue/GetValue, here 0..100% }
- SYNCBARS : integer = 2;
- type
- EMMLevelError = class(Exception);
- TMMLevelKind = (lkHorizontal, lkVertical);
- TMMLevelDirection = (dirNormal, dirReversed,dirSymetric);
- TMMLevelDrawBar = procedure(Sender: TObject; DIB: TMMDIBCanvas;
- Rect: TRect; nSpots, Peak: integer) of object;
- { array for uniform decay mode values }
- TDataBuf = array[0..MAXDECAYCOUNT-1] of Long;
- {-- TMMCustomLevel ---------------------------------------------------------}
- TMMCustomLevel = class(TMMDIBGraphicControl)
- private
- FTimerID : Longint; { timer for peak handling }
- FBarDIB : TMMDIBCanvas; { bitmap for inactive spots }
- FEnabled : Boolean; { Enable or disable Level }
- FKind : TMMLevelKind; { draw horizontal / vertikal bars }
- FBar1Color : TColor; { Farbe f黵 die Punkte im 1. Abschnitt }
- FBar2Color : TColor; { Farbe f黵 die Punkte im 2. Abschnitt }
- FBar3Color : TColor; { Farbe f黵 die Punkte im 3. Abschnitt }
- FInact1Color : TColor; { foreColor for inactive spots 1 }
- FInact2Color : TColor; { foreColor for inactive spots 2 }
- FInact3Color : TColor; { foreColor for inactive spots 3 }
- FInactiveDoted: Boolean; { draw the inactive spots doted }
- FActiveDoted : Boolean; { draw the active spots doted }
- FPoint1 : integer; { Schwelle von 1. zu 2. Abschnitt % }
- FPoint2 : integer; { Schwelle von 2. zu 3. Abschnitt % }
- FPoint1Spot : integer; { on which spot begins next color }
- FPoint2Spot : integer; { on which spot begins next color }
- FSpotSpace : integer; { Horizontal space between spots }
- FSpotWidth : integer; { the spot width in pixel }
- FFirstSpace : integer; { the space before the first spot }
- FNumSpots : integer; { number of Spots }
- FDirection : TMMLevelDirection;{ draw direction, forward/backward }
- FBits : TMMBits; { bit8 or bit16 }
- FChannel : TMMChannel; { chBoth, chLeft or chRigth }
- FMode : TMMMode; { mMono or mStereo }
- FBytes : Longint; { calculated data bytes per level }
- FGain : Integer; { the linear gain for the pcm data }
- FSamples : integer; { number of samples for calculation }
- FSensitivy : integer; { here starts the display (db) scaling }
- FLogAmp : Boolean; { set to True for log-based amp. scale }
- FData : integer; { the current data for the level }
- FDataBuf : TDataBuf; { Memory for averaging mode }
- FDecay : integer; { the current Decay value }
- FDecayMode : TMMDecayMode; { indicating decay mode on/off }
- FDecayFactor : Float; { Geometric decay factor }
- FDecayCount : integer; { Temporal averaging parameter }
- FDecayCntAct : integer; { Total num of bins averaged so far }
- FDecayPtr : integer; { Index for averaging buffer location }
- FLastVal_F : Float; { Lastvalue for exp decay mode }
- FLastVal : Longint; { Lastvalue for uniform averaging }
- FNumPeaks : integer; { number of spots displayed as peak }
- FDrawScale : Boolean; { draw the scale or not }
- FCurPeak : integer; { the actual sample Peak Value }
- FPeak : integer; { the actual Peak Value for the display}
- FPeakDelay : integer; { the delay for the peak spot }
- FPeakSpeed : integer; { the decrease speed for the peak spot }
- FPeakCounter : integer; { internal Peak delay counter }
- FWidth : integer; { calculated width without border }
- FHeight : integer; { calculated height without border }
- FClientRect : TRect; { calculated beveled Rect }
- FRange : Longint; { pcm input dynamic range }
- FRefresh : Boolean; { needs the peak a refresh ? }
- FDCOffsetL : integer;
- FDCOffsetR : integer;
- FDrawReversed : Boolean;
- { Events }
- FOnPaint : TNotifyEvent;
- FOnGainOverflow: TNotifyEvent;
- FOnPcmOverflow : TNotifyEvent;
- FOnDrawBar : TMMLevelDrawBar;
- procedure ResetDecayBuffers;
- procedure CalcNumSpots;
- procedure SetBytesPerLevel;
- procedure DrawInactiveSpots;
- procedure DrawLevelHorizontal(DIB: TMMDIBCanvas; nSpots, Peak: integer; DrawAll: Boolean);
- procedure DrawLevelVertical(DIB: TMMDIBCanvas; nSpots, Peak: integer; DrawAll: Boolean);
- procedure DrawLevel(Dummy: Boolean);
- procedure SetOnDrawBar(aValue: TMMLevelDrawBar);
- procedure SetEnabled(aValue: Boolean);
- procedure SetKind(aValue: TMMLevelKind);
- Procedure SetColors(Index: Integer; aValue: TColor);
- procedure SetPoints(Index, aValue: integer);
- procedure SetSpotSpace(aValue: integer);
- procedure SetSpotWidth(aValue: integer);
- procedure SetDirection(aValue: TMMLevelDirection);
- procedure SetPCMWaveFormat(wf: TPCMWaveFormat);
- function GetPCMWaveFormat: TPCMWaveFormat;
- procedure SetBits(aValue: TMMBits);
- procedure SetChannel(aValue: TMMChannel);
- procedure SetMode(aValue: TMMMode);
- procedure SetGain(aValue: Integer);
- function GetGain: integer;
- procedure SetSamples(aValue: integer);
- procedure SetDecayMode(aValue: TMMDecayMode);
- procedure SetDecay(aValue: integer);
- procedure SetNumPeaks(aValue: integer);
- procedure SetPeakDelay(aValue: integer);
- procedure SetPeakSpeed(aValue: integer);
- procedure SetInactiveDoted(aValue: Boolean);
- procedure SetActiveDoted(aValue: Boolean);
- procedure SetSensitivy(aValue: integer);
- procedure SetLogAmp(aValue: Boolean);
- procedure SetValue(aValue: integer);
- function GetValue: integer;
- function GetPeak: integer;
- function GetPeakValue: integer;
- procedure SetDCOffset(Index, aValue: integer);
- function GetDCOffset(Index: integer): integer;
- procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
- protected
- procedure SetBPP(aValue: integer); override;
- procedure Paint; override;
- procedure Loaded; override;
- procedure GainOverflow; dynamic;
- procedure PcmOverflow; dynamic;
- procedure Changed; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure ChangeDesigning(aValue: Boolean); override;
- procedure SetBounds(aLeft, aTop, aWidth, aHeight: integer); override;
- property DrawReversed: Boolean read FDrawReversed write FDrawReversed;
- procedure RefreshPCMData(PCMData: Pointer);
- procedure SetData(SampleValue: integer);
- procedure ResetData;
- property BytesPerLevel: Longint read FBytes;
- property PCMWaveFormat: TPCMWaveFormat read GetPCMWaveFormat write SetPCMWaveFormat;
- property NumSpots: integer read FNumSpots;
- property Point1Spot: integer read FPoint1Spot;
- property Point2Spot: integer read FPoint2Spot;
- property Peak: integer read FCurPeak;
- property PeakDisplay: integer read GetPeak;
- property PeakValue: integer read GetPeakValue;
- protected
- { Events }
- property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
- property OnDrawBar: TMMLevelDrawBar read FOnDrawBar write SetOnDrawBar;
- property OnGainOverflow: TNotifyEvent read FOnGainOverflow write FOnGainOverflow;
- property OnPcmOverflow: TNotifyEvent read FOnPcmOverflow write FOnPcmOverflow;
- property ParentColor default False;
- property Color default clBlack;
- property Height default 17;
- property Width default 200;
- property Enabled: Boolean read FEnabled write SetEnabled default True;
- property Kind: TMMLevelKind read FKind write SetKind default lkHorizontal;
- property SpotSpace: integer read FSpotSpace write SetSpotSpace default 1;
- property SpotWidth: integer read FSpotWidth write SetSpotWidth default 1;
- property Bar1Color: TColor index 0 read FBar1Color write SetColors default clAqua;
- property Bar2Color: TColor index 1 read FBar2Color write SetColors default clAqua;
- property Bar3Color: TColor index 2 read FBar3Color write SetColors default clRed;
- property Inactive1Color: TColor index 3 read FInact1Color write SetColors default clTeal;
- property Inactive2Color: TColor index 4 read FInact2Color write SetColors default clTeal;
- property Inactive3Color: TColor index 5 read FInact3Color write SetColors default clMaroon;
- property InactiveDoted: Boolean read FInactiveDoted write SetInactiveDoted default False;
- property ActiveDoted: Boolean read FActiveDoted write SetActiveDoted default False;
- property Point1: integer index 0 Read FPoint1 write SetPoints default 50;
- property Point2: integer index 1 Read FPoint2 write SetPoints default 85;
- property Direction: TMMLevelDirection read FDirection write SetDirection default dirNormal;
- property BitLength: TMMBits read FBits write setBits default b8bit;
- property Channel: TMMChannel read FChannel write setChannel default chBoth;
- property Mode: TMMMode read FMode write SetMode default mMono;
- property Gain: Integer read getGain write setGain default 0;
- property Samples: integer read FSamples write SetSamples default 50;
- property Sensitivy: integer read FSensitivy write SetSensitivy default -35;
- property LogAmp: Boolean read FLogAmp write SetLogAmp default True;
- property NumPeaks: integer read FNumPeaks write SetNumPeaks default 1;
- property PeakDelay: integer read FPeakDelay write SetPeakDelay default 20;
- property PeakSpeed: integer read FPeakSpeed write SetPeakSpeed default 0;
- property DecayMode: TMMDecayMode read FDecayMode write SetDecayMode default dmNone;
- property Decay: integer read FDecay write SetDecay default 1;
- property Value: integer read GetValue write SetValue stored False default 0;
- property DCOffsetL: integer index 0 read GetDCOffset write SetDCOffset default 0;
- property DCOffsetR: integer index 1 read GetDCOffset write SetDCOffset default 0;
- end;
- {-- TMMLevel --------------------------------------------------------}
- TMMLevel = class(TMMCustomLevel)
- published
- property OnClick;
- property OnDblClick;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnDrawBar;
- property OnGainOverflow;
- property OnPcmOverflow;
- property OnPaint;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnStartDrag;
- property Align;
- property Bevel;
- property PopupMenu;
- property ParentShowHint;
- property ParentColor;
- property ShowHint;
- property Visible;
- property Color;
- property DragCursor;
- property Enabled;
- property Kind;
- property Height;
- property Width;
- property SpotSpace;
- property SpotWidth;
- property Bar1Color;
- property Bar2Color;
- property Bar3Color;
- property Inactive1Color;
- property Inactive2Color;
- property Inactive3Color;
- property InactiveDoted;
- property ActiveDoted;
- property Point1;
- property Point2;
- property Direction;
- property BitLength;
- property Channel;
- property Mode;
- property Gain;
- property Samples;
- property Sensitivy;
- property LogAmp;
- property NumPeaks;
- property PeakDelay;
- property PeakSpeed;
- property DecayMode;
- property Decay;
- property Value;
- property DCOffsetL;
- property DCOffsetR;
- end;
- {-- TMMLevScale -----------------------------------------------------}
- TMMLevScale = class(TMMCustomScale)
- published
- property Visible default False;
- property TickCount;
- property EnlargeEvery;
- property Size;
- property Origin;
- property Connect;
- end;
- TMMScalePos = (spAboveOrLeft, spBelowOrRight, spBoth);
- {-- TMMLevelScale ---------------------------------------------------}
- TMMLevelScale = class(TMMGraphicControl)
- private
- FScaleTicks : integer; { draw every FScaleTicks a volume string }
- FPoint1 : integer; { Schwelle von 1. zu 2. Abschnitt % }
- FPoint2 : integer; { Schwelle von 2. zu 3. Abschnitt % }
- FScale1Color: TColor; { Farbe f黵 die Punkte im 1. Abschnitt }
- FScale2Color: TColor; { Farbe f黵 die Punkte im 2. Abschnitt }
- FScale3Color: TColor; { Farbe f黵 die Punkte im 3. Abschnitt }
- FKind : TMMLevelKind;
- FDirection : TMMLevelDirection;
- FSensitivy : integer;
- FLogAmp : Boolean;
- FScale : TMMLevScale;
- FScalePos : TMMScalePos;
- procedure SetScale(Value: TMMLevScale);
- procedure SetScalePos(Value: TMMScalePos);
- procedure ScaleChanged(Sender: TObject);
- procedure SetSensitivy(aValue: integer);
- procedure SetLogAmp(aValue: Boolean);
- procedure SetScaleTicks(aValue: integer);
- procedure SetPoints(Index, aValue: integer);
- procedure SetColors(Index: Integer; aValue: TColor);
- procedure SetKind(aValue: TMMLevelKind);
- procedure SetDirection(aValue: TMMLevelDirection);
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Paint; override;
- published
- { Events }
- property OnClick;
- property OnDblClick;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property Align;
- property Width default 200;
- property Height default 7;
- property Visible;
- property Enabled;
- property PopupMenu;
- property ParentShowHint;
- property ParentFont default False;
- property Font;
- property Color default clBlack;
- property ScaleTicks: integer read FScaleTicks write SetScaleTicks default 8;
- property Point1: integer index 0 Read FPoint1 write SetPoints default 50;
- property Point2: integer index 1 Read FPoint2 write SetPoints default 85;
- property Scale1Color: TColor index 0 read FScale1Color write SetColors default clWhite;
- property Scale2Color: TColor index 1 read FScale2Color write SetColors default clWhite;
- property Scale3Color: TColor index 2 read FScale3Color write SetColors default clRed;
- property Sensitivy: integer read FSensitivy write SetSensitivy default -35;
- property LogAmp: Boolean read FLogAmp write SetLogAmp default True;
- property Kind: TMMLevelKind read FKind write SetKind default lkHorizontal;
- property Direction: TMMLevelDirection read FDirection write SetDirection default dirNormal;
- property Scale: TMMLevScale read FScale write SetScale;
- property ScalePos: TMMScalePos read FScalePos write SetScalePos default spBoth;
- end;
- implementation
- {------------------------------------------------------------------------}
- procedure TimeCallBack(uTimerID, dwUser: Longint); export;
- begin
- if (dwUser <> 0) then
- with TMMCustomLevel(dwUser) do
- begin
- if (FPeak > 0) then
- begin
- dec(FPeakCounter);
- if FPeakCounter <= 0 then
- begin
- if (FPeakSpeed = 0) then
- begin
- FPeak := 0; { reset the peak }
- FPeakCounter := 0;
- end
- else
- begin
- dec(FPeak); { dec the peak spot }
- FPeakCounter := FPeakSpeed;
- end;
- FRefresh := True;
- end;
- end;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- constructor TMMCustomLevel.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FBarDIB := TMMDIBCanvas.Create(Self);
- FTimerID := 0;
- FRange := $7FFF; { 32768 - 16 bit (abs) }
- FEnabled := True;
- FKind := lkHorizontal;
- FDirection := dirNormal;
- FBar1Color := clAqua;
- FBar2Color := clAqua;
- FBar3Color := clRed;
- FInact1Color := clTeal;
- FInact2Color := clTeal;
- FInact3Color := clMaroon;
- FInactiveDoted := False;
- FActiveDoted := False;
- FSpotSpace := 1;
- FSpotWidth := 1;
- FBits := b8Bit;
- FChannel := chBoth;
- FMode := mMono;
- FDrawScale := False;
- FNumPeaks := 1;
- FPeakDelay := 20;
- FPeakSpeed := 0;
- FPeakCounter := 0;
- FData := 0;
- FDecay := 1;
- FDecayMode := dmNone;
- FDecayFactor := 0.0001;
- FDecayCount := 1;
- FDecayCntAct := 0;
- FDecayPtr := 0;
- FCurPeak := 0;
- FPeak := 0;
- FGain := 8; { no Gain = 8 div 8 = 1 }
- FSamples := 50;
- FPoint1 := 50;
- FPoint2 := 85;
- FRefresh := False;
- FSensitivy := -35;
- FLogAmp := True;
- FDCOffsetL := 0;
- FDCOffsetR := 0;
- FDrawReversed := False;
- SetBounds(0,0,200,17);
- Color := clBlack;
- ParentFont := False;
- Font.Name := 'Small Fonts';
- Font.Size := 7;
- SetBytesPerLevel;
- if not (csDesigning in ComponentState) then
- begin
- { create the peak timer }
- FTimerID := MMTimeSetEvent(25, False, TimeCallBack, Longint(Self));
- end;
- ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
- if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- Destructor TMMCustomLevel.Destroy;
- begin
- if (FTimerID <> 0) then
- begin
- { destroy the peak timer }
- MMTimeKillEvent(FTimerID);
- end;
- FBarDIB.Free;
- inherited Destroy;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.ChangeDesigning(aValue: Boolean);
- begin
- inherited ChangeDesigning(aValue);
- if not (csDesigning in ComponentState) then
- begin
- { create the peak timer }
- if (FTimerID = 0) then
- FTimerID := MMTimeSetEvent(25, False, TimeCallBack, Longint(Self));
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetBPP(aValue: integer);
- begin
- if (aValue <> BitsPerPixel) then
- begin
- if (aValue <> 8) and (aValue <> 24) then
- raise EMMDIBError.Create('Bitlength not supported yet');
- FBarDIB.BitsPerPixel := aValue;
- DIBCanvas.BitsPerPixel := aValue;
- DrawInactiveSpots;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.GainOverflow;
- begin
- if Assigned(FOnGainOverflow) then FOnGainOverflow(Self);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.PcmOverflow;
- begin
- if Assigned(FOnPcmOverflow) then FOnPcmOverflow(Self);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.ResetDecayBuffers;
- var
- i: integer;
- begin
- FDecayPtr := 0;
- FDecayCntAct := 0; { Restart the count of number of samples taken }
- FLastVal := 0;
- FLastVal_F := 0;
- for i := 0 to MAXDECAYCOUNT-1 do FDataBuf[i] := 0;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.ResetData;
- begin
- FPeak := 0;
- FPeakCounter := 0;
- FData := 0;
- FCurPeak := 0;
- ResetDecayBuffers;
- Refresh;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetDecayMode(aValue: TMMDecayMode);
- begin
- { Select averaging mode }
- if (aValue <> FDecayMode) then
- begin
- FDecayMode := aValue;
- { Re-initialize the buffers }
- ResetDecayBuffers;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetDecay(aValue: integer);
- var
- i: integer;
- begin
- aValue := MinMax(aValue,1,16);
- if (aValue <> FDecay) then
- begin
- FDecay := aValue;
- { factor for stepUp and exponential averaging }
- FDecayFactor := 0.0001;
- for i := 0 to FDecay-1 do
- FDecayFactor := sqrt(FDecayFactor);
- { counter for uniform averaging }
- FDecayCount := MinMax(2*(aValue-1),1,MaxDecayCount);
- { Re-initialize the buffers for uniform averaging }
- if (FDecayMode = dmUniform) then ResetDecayBuffers;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK1}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetPeakDelay(aValue: integer);
- begin
- aValue := MinMax(aValue, 0, 50);
- if (aValue <> FPeakDelay) then
- begin
- FPeakDelay := aValue;
- FPeakCounter := 0;
- Invalidate;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK2}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetPeakSpeed(aValue: integer);
- begin
- aValue := MinMax(aValue, 0, 50);
- if (aValue <> FPeakSpeed) then
- begin
- FPeakSpeed := aValue;
- FPeakCounter := 0;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetNumPeaks(aValue: integer);
- begin
- aValue := MinMax(aValue, 0, 5);
- if (aValue <> FNumPeaks) then
- begin
- FNumPeaks := aValue;
- FPeakCounter := 0;
- if (FNumPeaks = 0) then
- MMTimeSuspendEvent(FTimerID)
- else if FEnabled then
- MMTimeResumeEvent(FTimerID);
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetEnabled(aValue: Boolean);
- begin
- if (aValue <> FEnabled) then
- begin
- FEnabled := aValue;
- { inherited Enabled := Value }
- if (not FEnabled) then
- begin
- ResetData;
- MMTimeSuspendEvent(FTimerID);
- end
- else
- begin
- CalcNumSpots; { init FData when in designing }
- MMTimeResumeEvent(FTimerID);
- end;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetKind(aValue: TMMLevelKind);
- var
- Temp: integer;
- begin
- if (aValue <> FKind) then
- begin
- FKind := aValue;
- if ((FKind = lkHorizontal) and (Height > Width)) or
- ((FKind = lkVertical) and (Height < Width)) then
- begin
- Temp := Width;
- Width := Height; { swap Width and Height }
- Height := Temp;
- end;
- Changed; { recalc the dimension }
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetDirection(aValue: TMMLevelDirection);
- Begin
- if (aValue <> FDirection) then
- begin
- FDirection := aValue;
- DrawInactiveSpots;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetSpotSpace(aValue: integer);
- begin
- aValue := MinMax(aValue, 0, 10);
- if (aValue <> FSpotSpace) then
- begin
- FSpotSpace := aValue;
- CalcNumSpots;
- Invalidate;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK3}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetSpotWidth(aValue: integer);
- Var
- Temp: integer;
- begin
- Temp := 0;
- case FKind of
- lkHorizontal: Temp := FWidth div 3;
- lkVertical : Temp := FHeight div 3;
- end;
- aValue := MinMax(aValue, 1, Temp);
- if (aValue <> FSpotWidth) then
- begin
- FSpotWidth := aValue;
- CalcNumSpots;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetSensitivy(aValue: integer);
- begin
- aValue := MinMax(aValue, -90, -9);
- if (aValue <> FSensitivy) then
- begin
- FSensitivy := aValue;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetLogAmp(aValue: Boolean);
- begin
- if (aValue <> FLogAmp) then
- begin
- FLogAmp := aValue;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.CalcNumSpots;
- begin
- FSpotWidth := Max(FSpotWidth,1);
- if (FKind = lkHorizontal) then
- begin
- FNumSpots := (FWidth+FSpotSpace) div (FSpotWidth+FSpotSpace);
- FNumSpots := Max(FNumSpots,1); { fix div by zerro !!! }
- FFirstSpace := (FWidth-(FNumSpots*(FSpotWidth+FSpotSpace)-FSpotSpace)) div 2;
- end
- else
- begin
- FNumSpots := (FHeight+FSpotSpace)div(FSpotWidth+FSpotSpace);
- FNumSpots := Max(FNumSpots,1); { fix div by zerro !!! }
- FFirstSpace := (FHeight-(FNumSpots*(FSpotWidth+FSpotSpace)-FSpotSpace)) div 2;
- end;
- { calc the spot on which the next color starts }
- FPoint1Spot := (FPoint1 * FNumSpots) div 100;
- FPoint2Spot := (FPoint2 * FNumSpots) div 100;
- { redraw background }
- DrawInactiveSpots;
- { we will see anything in designer }
- if (csDesigning in ComponentState) and FEnabled then
- begin
- if (FPoint2Spot < FNumSpots) then
- FData := FPoint2Spot + ((FNumSpots-FPoint2Spot) div 2)
- else if (FPoint1Spot < FNumSpots) then
- FData := FPoint1Spot + ((FNumSpots-FPoint1Spot) div 2)
- else
- FData := FNumSpots - (FNumSpots div 4);
- end
- else
- begin
- FPeak := 0;
- FData := 0;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetBounds(aLeft, aTop, aWidth, aHeight: integer);
- begin
- inherited SetBounds(aLeft, aTop, aWidth, aHeight);
- Changed;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.Loaded;
- begin
- inherited Loaded;
- DrawInactiveSpots;
- Invalidate;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.Changed;
- begin
- FClientRect := BeveledRect;
- FWidth := Max(FClientRect.Right - FClientRect.Left,1);
- FHeight := Max(FClientRect.Bottom - FClientRect.Top,1);
- DIBCanvas.SetBounds(0,0,FWidth,FHeight);
- FBarDIB.SetBounds(0,0,FWidth,FHeight);
- { recalculate the number of spots }
- CalcNumSpots;
- inherited Changed;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetBytesPerLevel;
- begin
- FBytes := (Ord(FBits)+1) * (Ord(FMode)+1) * FSamples;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetSamples(aValue: integer);
- begin
- aValue := Max(aValue, 1);
- if (aValue <> FSamples) then
- begin
- FSamples := aValue;
- SetBytesPerLevel;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetPCMWaveFormat(wf: TPCMWaveFormat);
- var
- pwfx: PWaveFormatEx;
- begin
- pwfx := @wf;
- if not pcmIsValidFormat(pwfx) then
- raise EMMLevelError.Create(LoadResStr(IDS_INVALIDFORMAT));
- BitLength := TMMBits(pwfx^.wBitsPerSample div 8 - 1);
- Mode := TMMMode(pwfx^.nChannels-1);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetPCMWaveFormat: TPCMWaveFormat;
- var
- wfx: TWaveFormatEx;
- begin
- pcmBuildWaveHeader(@wfx, (Ord(FBits)+1)*8, Ord(FMode)+1, 11025);
- Result := PPCMWaveFormat(@wfx)^;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetBits(aValue: TMMBits);
- begin
- if (aValue <> FBits) then
- begin
- FBits := aValue;
- SetBytesPerLevel;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetChannel(aValue: TMMChannel);
- begin
- if (aValue <> FChannel) then
- begin
- FChannel := aValue;
- SetBytesPerLevel;
- Invalidate;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK2}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetMode(aValue: TMMMode);
- begin
- if (aValue <> FMode) then
- begin
- FMode := aValue;
- SetBytesPerLevel;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetGain(aValue: Integer);
- begin
- if (aValue <> FGain-8) AND (aValue >= -8) AND (aValue <= 32) then
- begin
- FGain := aValue + 8;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetGain: Integer;
- begin
- Result := FGain - 8;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetPoints(Index, aValue: integer);
- begin
- aValue := MinMax(aValue, 1, 100);
- case Index of
- 0: if FPoint1 = aValue then exit else FPoint1 := aValue;
- 1: if FPoint2 = aValue then exit else FPoint2 := aValue;
- end;
- CalcNumSpots;
- Invalidate;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetColors(Index:Integer; aValue: TColor);
- begin
- case Index of
- 0: if FBar1Color = aValue then exit else FBar1Color := aValue;
- 1: if FBar2Color = aValue then exit else FBar2Color := aValue;
- 2: if FBar3Color = aValue then exit else FBar3Color := aValue;
- 3: if FInact1Color = aValue then exit else FInact1Color := aValue;
- 4: if FInact2Color = aValue then exit else FInact2Color := aValue;
- 5: if FInact3Color = aValue then exit else FInact3Color := aValue;
- end;
- DrawInactiveSpots;
- Invalidate;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetDCOffset(Index,aValue: Integer);
- begin
- case Index of
- 0: if FDCOffsetL = aValue then exit else FDCOffsetL := -aValue;
- 1: if FDCOffsetR = aValue then exit else FDCOffsetR := -aValue;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetDCOffset(Index: Integer): integer;
- begin
- case Index of
- 0: Result := -FDCOffsetL;
- 1: Result := -FDCOffsetR;
- else Result := 0;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetInactiveDoted(aValue: Boolean);
- begin
- if (aValue <> FInactiveDoted) then
- begin
- FInactiveDoted := aValue;
- DrawInactiveSpots;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetActiveDoted(aValue: Boolean);
- begin
- if (aValue <> FActiveDoted) then
- begin
- FActiveDoted := aValue;
- DrawInactiveSpots;
- Invalidate;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.CMColorChanged(var Message: TMessage);
- begin
- DrawInactiveSpots;
- inherited;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- Procedure TMMCustomLevel.RefreshPCMData(PCMData: Pointer);
- Var
- i: integer;
- ReIndex: integer;
- BestValue,Value,DCOffs: integer;
- begin
- if FEnabled and Visible then
- begin
- BestValue := 0;
- ReIndex := Ord(FChannel)-1;
- if (FBits = b8bit) then
- if (FMode = mMono) then
- for i := 0 to FSamples-1 do
- begin
- Value := ABS((PByteArray(PCMData)^[i]+FDCOffsetL-128) shl 8);
- if (Value > BestValue) then BestValue := Value;
- end
- else if (FChannel = chBoth) then
- for i := 0 to FSamples-1 do
- begin
- Value := ABS(((Word(PByteArray(PCMData)^[i+i]+FDCOffsetL)+PByteArray(PCMData)^[i+i+1]+FDCOffsetR)div 2-128) shl 8);
- if (Value > BestValue) then BestValue := Value;
- end
- else
- begin
- if (FChannel = chLeft) then
- DCOffs := FDCOffsetL
- else
- DCOffs := FDCOffsetR;
- for i := 0 to FSamples-1 do
- begin
- Value := ABS((PByteArray(PCMData)^[i+i+ReIndex]+DCOffs-128) shl 8);
- if (Value > BestValue) then BestValue := Value;
- end;
- end
- else
- if (FMode = mMono) then
- for i := 0 to FSamples-1 do
- begin
- Value := ABS(PSmallArray(PCMData)^[i]+FDCOffsetL);
- if (Value > BestValue) then BestValue := Value;
- end
- else if (FChannel = chBoth) then
- for i := 0 to FSamples-1 do
- begin
- Value := ABS((Long(PSmallArray(PCMData)^[i+i]+FDCOffsetL)+PSmallArray(PCMData)^[i+i+1]+FDCOffsetR)div 2);
- if (Value > BestValue) then BestValue := Value;
- end
- else
- begin
- if (FChannel = chLeft) then
- DCOffs := FDCOffsetL
- else
- DCOffs := FDCOffsetR;
- for i := 0 to FSamples-1 do
- begin
- Value := ABS(PSmallArray(PCMData)^[i+i+ReIndex]+DCOffs);
- if (Value > BestValue) then BestValue := Value;
- end;
- end;
- if (BestValue >= FRange) then PcmOverflow;
- SetData(BestValue);
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetData(SampleValue: integer);
- var
- dbValue: Float;
- begin
- SampleValue := abs(SampleValue);
- FCurPeak := SampleValue;
- if (SampleValue = 0) and (FData = 0) and not FRefresh then exit;
- if (FDecayMode <> dmNone) then
- begin
- inc(FDecayPtr);
- inc(FDecayCntAct);
- if (FDecayPtr >= FDecayCount) then FDecayPtr := 0;
- if (FDecayCntAct > FDecayCount) then FDecayCntAct := FDecayCount;
- { In decay mode, need to average the value }
- case Ord(FDecayMode) of
- 1: begin
- FLastVal_F := FLastVal_F*FDecayFactor;
- if (SampleValue > FLastVal_F) then FLastVal_F := SampleValue
- else SampleValue := Trunc(FLastVal_F);
- end;
- 2: begin
- FLastVal_F := FLastVal_F*FDecayFactor+(1-FDecayFactor)*SampleValue;
- SampleValue := Floor(FLastVal_F);
- end;
- 3: begin
- FLastVal := FLastVal+(SampleValue-FDataBuf[FDecayPtr]);
- FDataBuf[FDecayPtr] := SampleValue;
- SampleValue := FLastVal div FDecayCntAct;
- end;
- end;
- end;
- if FLogAmp then
- begin
- { add the gain and calc the actual db value }
- dbValue := Log10(MaxR(MulDiv32(SampleValue,FGain,8)/FRange,0.000001))*20;
- { now the scaling }
- SampleValue := Max(Round((dbValue-FSensitivy)*FNumSpots/-FSensitivy),0);
- end
- else
- begin
- { calc the low limit (Sensivity(db) to sample value }
- dbValue := FRange/pow(10,-FSensitivy/20);
- { now the scaling }
- SampleValue := Max(Round((MulDiv32(SampleValue,FGain,8)-dbValue)*FNumSpots/(FRange-dbValue)),0);
- end;
- if (Direction = dirSymetric) then
- SampleValue := SampleValue div 2;
- if FDrawReversed then
- SampleValue := FNumSpots-SampleValue;
- if (SampleValue > FNumSpots) then
- begin
- GainOverflow;
- SampleValue := FNumSpots;
- end;
- if (SampleValue >= FPeak) and (SampleValue > 0) and (FNumPeaks > 0) then
- begin
- FRefresh := True;
- FPeak := SampleValue; {start a new peak timer }
- FPeakCounter := (FPeakDelay*2)+1;
- end;
- if (SampleValue <> FData) or FRefresh then
- begin
- FRefresh := False;
- FData := SampleValue;
- if FEnabled and Visible then
- FastDraw(DrawLevel,False);
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetValue(aValue: integer);
- begin
- SetData(Round(MinMax(aValue,0,VALUERANGE)*FRange/VALUERANGE));
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetValue: integer;
- begin
- if FData = 0 then
- Result := 0
- else if not FLogAmp then
- Result := Round(FData * VALUERANGE / FNumSpots)
- else
- Result := Round(pow(10,(FSensitivy-FSensitivy*FData/FNumspots)/20)
- * 8 / FGain * VALUERANGE);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetPeak: integer;
- begin
- if FPeak = 0 then
- Result := 0
- else if not FLogAmp then
- Result := Round(FPeak * VALUERANGE / FNumSpots)
- else
- Result := Round(pow(10,(FSensitivy-FSensitivy*FPeak/FNumspots)/20)
- * 8 / FGain * VALUERANGE);
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- function TMMCustomLevel.GetPeakValue: integer;
- begin
- Result := (GetPeak * FRange) div VALUERANGE;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.SetOnDrawBar(aValue: TMMLevelDrawBar);
- begin
- FOnDrawBar := aValue;
- if not assigned(FOnDrawBar) then DrawInactiveSpots;
- Invalidate;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.DrawLevelHorizontal(DIB: TMMDIBCanvas; nSpots, Peak: integer; DrawAll: Boolean);
- Var
- i: integer;
- SpotRect: TRect; { Spot draw rectangle }
- SpotInc: integer; { increase value for next spot }
- begin
- SpotInc := FSpotWidth + FSpotSpace;
- SpotRect.Top := 0;
- SpotRect.Bottom := FHeight;
- if (FDirection = dirNormal) then
- begin
- SpotRect.Left := FFirstSpace;
- SpotRect.Right := SpotRect.Left + FSpotWidth; {Leerraum }
- end
- else
- begin
- SpotRect.Right := FWidth - FFirstSpace;
- SpotRect.Left := SpotRect.Right - FSpotWidth;
- SpotInc := -SpotInc;
- end;
- with DIB do
- begin
- if not DrawAll and (Direction = dirSymetric) then
- begin
- if (nSpots > FNumSpots) then nSpots := FNumSpots
- else if (nSpots < 1) then nSpots := 1;
- OffsetRect(SpotRect, (nSpots-1-SYNCBARS)*SpotInc, 0);
- for i := 0 to 2*SYNCBARS do { draw the highlited spots }
- begin
- if (nSpots > FPoint2Spot) then DIB_SetTColor(FBar3Color)
- else if (nSpots > FPoint1Spot) then DIB_SetTColor(FBar2Color)
- else DIB_SetTColor(FBar1Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, SpotInc, 0);
- end;
- end
- else
- begin
- DIB_SetTColor(FBar1Color);
- for i := 1 to nSpots do { draw the highlited spots }
- begin
- if i > FPoint2Spot then DIB_SetTColor(FBar3Color)
- else if i > FPoint1Spot then DIB_SetTColor(FBar2Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, SpotInc, 0);
- end;
- end;
- if (FNumPeaks > 0) and (Peak > nSpots) then
- begin
- OffsetRect(SpotRect, ((Peak-1)-nSpots)*SpotInc, 0);
- for i := 0 to FNumPeaks-1 do { draw the peak spots }
- begin
- if Peak-i > FPoint2Spot then DIB_SetTColor(FBar3Color)
- else if Peak-i > FPoint1Spot then DIB_SetTColor(FBar2Color)
- else DIB_SetTColor(FBar1Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, -SpotInc, 0);
- end;
- end;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.DrawLevelVertical(DIB: TMMDIBCanvas; nSpots, Peak: integer; DrawAll: Boolean);
- Var
- i: integer;
- SpotRect: TRect; { Spot draw rectangle }
- SpotInc: integer; { increase value for next spot }
- begin
- SpotInc := FSpotWidth + FSpotSpace;
- SpotRect.Left := 0;
- SpotRect.Right := FWidth;
- with DIB do
- begin
- if (FDirection = dirNormal) then
- begin
- SpotRect.Bottom := FHeight - FFirstSpace;
- SpotRect.Top := SpotRect.Bottom - FSpotWidth;
- SpotInc := -SpotInc;
- end
- else
- begin
- SpotRect.Top := FFirstSpace;
- SpotRect.Bottom := SpotRect.Top + FSpotWidth;
- end;
- if not DrawAll and (Direction = dirSymetric) then
- begin
- if (nSpots > FNumSpots) then nSpots := FNumSpots
- else if (nSpots < 1) then nSpots := 1;
- OffsetRect(SpotRect, 0, (nSpots-1-SYNCBARS)*SpotInc);
- for i := 0 to 2*SYNCBARS do { draw the highlited spots }
- begin
- if (nSpots > FPoint2Spot) then DIB_SetTColor(FBar3Color)
- else if (nSpots > FPoint1Spot) then DIB_SetTColor(FBar2Color)
- else DIB_SetTColor(FBar1Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, 0, SpotInc);
- end;
- end
- else
- begin
- DIB_SetTColor(FBar1Color);
- for i := 1 to nSpots do { draw the highlited spots }
- begin
- if i > FPoint2Spot then DIB_SetTColor(FBar3Color)
- else if i > FPoint1Spot then DIB_SetTColor(FBar2Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, 0, SpotInc);
- end;
- end;
- if (FNumPeaks > 0) and (Peak > nSpots) then
- begin
- OffsetRect(SpotRect, 0, ((Peak-1)-nSpots) * SpotInc);
- for i := 0 to FNumPeaks-1 do { draw the peak spots }
- begin
- if Peak-i > FPoint2Spot then DIB_SetTColor(FBar3Color)
- else if Peak-i > FPoint1Spot then DIB_SetTColor(FBar2Color)
- else DIB_SetTColor(FBar1Color);
- DIB_FillRectDoted(SpotRect,FActiveDoted);
- OffsetRect(SpotRect, 0, -SpotInc);
- end;
- end;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.DrawInactiveSpots;
- var
- _Bar1,_Bar2,_Bar3: TColor;
- _Active: Boolean;
- begin
- if not (csLoading in ComponentState) and (FBarDIB <> nil) and not assigned(FOnDrawBar) then
- with FBarDIB do
- begin
- DIB_InitDrawing;
- DIB_SetTColor(Color);
- DIB_Clear;
- _Bar1 := FBar1Color;
- _Bar2 := FBar2Color;
- _Bar3 := FBar3Color;
- _Active := FActiveDoted;
- FBar1Color := FInact1Color;
- FBar2Color := FInact2Color;
- FBar3Color := FInact3Color;
- FActiveDoted := FInactiveDoted;
- case FKind of
- lkHorizontal: DrawLevelHorizontal(FBarDIB,FNumSpots,0,True);
- lkVertical : DrawLevelVertical(FBarDIB,FNumSpots,0,True);
- end;
- FBar1Color := _Bar1;
- FBar2Color := _Bar2;
- FBar3Color := _Bar3;
- FActiveDoted := _Active;
- DIB_DoneDrawing;
- end;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- procedure TMMCustomLevel.DrawLevel(Dummy: Boolean);
- begin
- if assigned(FOnPaint) then FOnPaint(Self);
- DIBCanvas.DIB_InitDrawing;
- { draw the background }
- if assigned(FOnDrawBar) then
- begin
- FOnDrawBar(Self,DIBCanvas,Rect(0,0,FWidth,FHeight),FData,FPeak);
- end
- else
- begin
- DIBCanvas.DIB_CopyDIBBits(FBarDIB.Surface,0,0,FWidth,FHeight,0,0);
- if FEnabled then
- begin
- case FKind of { draw the level to bitmap }
- lkHorizontal: DrawLevelHorizontal(DIBCanvas,FData,FPeak,False);
- lkVertical : DrawLevelVertical(DIBCanvas,FData,FPeak,False);
- end;
- end;
- end;
- DIBCanvas.DIB_BitBlt(Canvas.Handle,FClientRect,0,0); { copy to screen }
- DIBCanvas.DIB_DoneDrawing;
- end;
- {-- TMMCustomLevel ------------------------------------------------------}
- Procedure TMMCustomLevel.Paint;
- begin
- { draw the bevel }
- inherited Paint;
- DrawLevel(True);
- {$IFDEF BUILD_ACTIVEX}
- if Selected then
- begin
- Canvas.Brush.Style := bsClear;
- Canvas.Pen.Color := clRed;
- Canvas.Rectangle(0,0,Width,Height);
- Canvas.Brush.Style := bsSolid;
- end;
- {$ENDIF}
- end;
- {== TMMLevelScale =======================================================}
- constructor TMMLevelScale.Create(aOwner: TComponent);
- begin
- inherited create(aOwner);
- FSensitivy := -35;
- FLogAmp := True;
- FScaleTicks := 8;
- FPoint1 := 50;
- FPoint2 := 85;
- FScale1Color := clWhite;
- FScale2Color := clWhite;
- FScale3Color := clRed;
- ParentFont := False;
- Font.Name := 'Small Fonts';
- Font.Size := 6;
- Color := clBlack;
- Width := 200;
- Height := 7;
- FScalePos := spBoth;
- FScale := TMMLevScale.Create;
- FScale.Visible := False;
- FScale.OnChange := ScaleChanged;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- destructor TMMLevelScale.Destroy;
- begin
- FScale.Free;
- inherited Destroy;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetScalePos(Value: TMMScalePos);
- begin
- if Value <> FScalePos then
- begin
- FScalePos := Value;
- Invalidate;
- end;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetScale(Value: TMMLevScale);
- begin
- FScale.Assign(Value);
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.ScaleChanged(Sender: TObject);
- begin
- Invalidate;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetSensitivy(aValue: integer);
- begin
- aValue := MinMax(aValue, -90, -9);
- if (aValue <> FSensitivy) then
- begin
- FSensitivy := aValue;
- Invalidate;
- end;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetLogAmp(aValue: Boolean);
- begin
- if (aValue <> FLogAmp) then
- begin
- FLogAmp := aValue;
- Invalidate;
- end;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetScaleTicks(aValue: integer);
- begin
- if (aValue <> FScaleTicks) then
- begin
- FScaleTicks := Max(aValue,2);
- Invalidate;
- end;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetPoints(Index, aValue: integer);
- begin
- aValue := MinMax(aValue, 1, 100);
- case Index of
- 0: if FPoint1 = aValue then exit else FPoint1 := aValue;
- 1: if FPoint2 = aValue then exit else FPoint2 := aValue;
- end;
- Invalidate;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetColors(Index:Integer; aValue: TColor);
- begin
- case Index of
- 0: if FScale1Color = aValue then exit else FScale1Color := aValue;
- 1: if FScale2Color = aValue then exit else FScale2Color := aValue;
- 2: if FScale3Color = aValue then exit else FScale3Color := aValue;
- end;
- Invalidate;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.SetKind(aValue: TMMLevelKind);
- var
- Temp: integer;
- begin
- if (aValue <> FKind) then
- begin
- FKind := aValue;
- if ((FKind = lkHorizontal) and (Height > Width)) or
- ((FKind = lkVertical) and (Height < Width)) then
- begin
- Temp := Width;
- Width := Height; { swap Width and Height }
- Height := Temp;
- end;
- Invalidate;
- end;
- end;
- {-- TMMLevelScale -------------------------------------------------------}
- Procedure TMMLevelScale.SetDirection(aValue: TMMLevelDirection);
- Begin
- if (aValue <> FDirection) then
- begin
- FDirection := aValue;
- Invalidate;
- end;
- end;
- (*
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.Paint;
- const
- FRange = $7FFF;
- var
- i, Count,CurValue,Volume: Longint;
- dbValue: Float;
- R : TRect;
- Rev : Boolean;
- P1, P2 : Integer;
- begin
- with Canvas do
- begin
- Brush.Color := Color;
- FillRect(ClientRect);
- Font := Self.Font;
- R := ClientRect;
- if Scale.Visible then
- begin
- InflateRect(R,-1,-2);
- Scale.Canvas := Canvas ;
- Rev := (Kind = lkVertical) xor (Direction = dirReversed);
- if Rev then
- begin
- Scale.Color := Scale3Color;
- Scale.Color2 := Scale2Color;
- Scale.Color3 := Scale1Color;
- P1 := 100 - Point2;
- P2 := 100 - Point1;
- end
- else
- begin
- Scale.Color := Scale1Color;
- Scale.Color2 := Scale2Color;
- Scale.Color3 := Scale3Color;
- P1 := Point1;
- P2 := Point2;
- end;
- Scale.Point1 := MulDiv(P1-1,Scale.TickCount,100);
- Scale.Point2 := MulDiv(P2-1,Scale.TickCount,100);
- if (ScalePos = spAboveOrLeft) or (ScalePos = spBoth) then
- begin
- if Kind = lkHorizontal then
- begin
- Scale.DrawRect(Canvas,Rect(R.Left,R.Top,R.Right-1,R.Top+Scale.ScaleHeight),True);
- Inc(R.Top,Scale.ScaleHeight);
- end
- else
- begin
- Scale.DrawRect(Canvas,Rect(R.Left,R.Top,R.Left+Scale.ScaleHeight,R.Bottom-1),True);
- Inc(R.Left,Scale.ScaleHeight);
- end;
- end;
- if (ScalePos = spBelowOrRight) or (ScalePos = spBoth) then
- begin
- if Kind = lkHorizontal then
- begin
- Scale.DrawRect(Canvas,Rect(R.Left,R.Bottom-Scale.ScaleHeight,R.Right-1,R.Bottom),False);
- Dec(R.Bottom,Scale.ScaleHeight)
- end
- else
- begin
- Scale.DrawRect(Canvas,Rect(R.Right-Scale.ScaleHeight,R.Top,R.Right,R.Bottom-1),False);
- Dec(R.Right,Scale.ScaleHeight);
- end;
- end;
- end;
- if (R.Top > R.Bottom) or (R.Left > R.Right) then Exit;
- { Draw the scale }
- if FScaleTicks > 1 then
- for i := 0 to FScaleTicks-1 do
- begin
- CurValue := MulDiv(FRange,i,FScaleTicks-1);
- if ((FKind = lkHorizontal) and (FDirection = dirReversed)) or
- ((FKind = lkVertical) and (FDirection = dirNormal)) then
- CurValue := FRange - CurValue;
- if (CurValue > Long(FPoint2)*FRange/100) then Font.Color := FScale3Color
- else if (CurValue > Long(FPoint1)*FRange/100) then Font.Color := FScale2Color
- else Font.Color := FScale1Color;
- if FLogAmp then
- begin
- Count := i;
- if ((FKind = lkHorizontal) and (FDirection = dirNormal)) or
- ((FKind = lkVertical) and (FDirection = dirReversed)) then
- Count := FScaleTicks-1-Count;
- Volume := Muldiv(Count,FSensitivy,FScaleTicks-1)
- end
- else
- begin
- Count := i;
- if ((FKind = lkHorizontal) and (FDirection = dirReversed)) or
- ((FKind = lkVertical) and (FDirection = dirNormal)) then
- Count := FScaleTicks-1-Count;
- dbValue := FRange/pow(10,-FSensitivy/20);
- Volume := Round(Log10(((Long(Count)*(FRange-dbValue)/(FScaleTicks-1))+dbValue)/FRange)*20)
- end;
- if (FDirection = dirNormal) then
- Count := 0
- else
- Count := FSensitivy;
- if (FKind = lkHorizontal) then
- TextOut(MulDiv32(i,R.Right-R.Left-TextWidth(IntToStr(Count))-1,FScaleTicks-1),
- R.Top + (R.Bottom-R.Top-TextHeight(IntToStr(Volume))) div 2,IntToStr(Volume))
- else
- TextOut(R.Left + (R.Right-R.Left-TextWidth(IntToStr(Volume))) div 2,
- MulDiv32(i,R.Bottom-R.Top-TextHeight(IntToStr(Count))-1,FScaleTicks-1),
- IntToStr(Volume));
- end;
- end;
- end;
- *)
- { TODO: Not perfect yet ! }
- {-- TMMLevelScale -------------------------------------------------------}
- procedure TMMLevelScale.Paint;
- Label NextLoop;
- const
- FRange = $7FFF;
- var
- i, j, Pos, H2, W2, th, tw, tw2, Count, CurValue, Volume: Longint;
- dbValue : Float;
- R : TRect;
- Rev : Boolean;
- P1, P2 : Integer;
- Skip : Integer;
- incValue : Integer;
- Offset : Integer;
- s : string;
- begin
- with Canvas do
- begin
- Brush.Color := Color;
- FillRect(ClientRect);
- Font := Self.Font;
- R := ClientRect;
- if (Kind = lkHorizontal) then
- Offset := TextWidth('0') div 2
- else
- Offset := TextHeight('0') div 2;
- if Scale.Visible then
- begin
- Scale.Canvas := Canvas;
- Rev := (Kind = lkVertical) xor (Direction = dirReversed);
- if Rev then
- begin
- Scale.Color := Scale3Color;
- Scale.Color2 := Scale2Color;
- Scale.Color3 := Scale1Color;
- P1 := 100 - Point2;
- P2 := 100 - Point1;
- end
- else
- begin
- Scale.Color := Scale1Color;
- Scale.Color2 := Scale2Color;
- Scale.Color3 := Scale3Color;
- P1 := Point1;
- P2 := Point2;
- end;
- Scale.Point1 := MulDiv(P1-1,Scale.TickCount,100);
- Scale.Point2 := MulDiv(P2-1,Scale.TickCount,100);
- if (ScalePos = spAboveOrLeft) or (ScalePos = spBoth) then
- begin
- if Kind = lkHorizontal then
- begin
- if Direction <> dirReversed then
- Scale.DrawRect(Canvas,Rect(R.Left-Offset-1,R.Top,R.Right-Offset-1,R.Top+Scale.ScaleHeight),True)
- else
- Scale.DrawRect(Canvas,Rect(R.Left+Offset,R.Top,R.Right+Offset-1,R.Top+Scale.ScaleHeight),True);
- Inc(R.Top,Scale.ScaleHeight);
- end
- else
- begin
- if Direction <> dirReversed then
- Scale.DrawRect(Canvas,Rect(R.Left,R.Top+Offset,R.Left+Scale.ScaleHeight,R.Bottom+Offset-1),True)
- else
- Scale.DrawRect(Canvas,Rect(R.Left,R.Top-Offset,R.Left+Scale.ScaleHeight,R.Bottom-Offset-1),True);
- Inc(R.Left,Scale.ScaleHeight);
- end;
- end;
- if (ScalePos = spBelowOrRight) or (ScalePos = spBoth) then
- begin
- if Kind = lkHorizontal then
- begin
- if Direction <> dirReversed then
- Scale.DrawRect(Canvas,Rect(R.Left-Offset-1,R.Bottom-Scale.ScaleHeight,R.Right-Offset-1,R.Bottom),False)
- else
- Scale.DrawRect(Canvas,Rect(R.Left+Offset,R.Bottom-Scale.ScaleHeight,R.Right+Offset-1,R.Bottom),False);
- Dec(R.Bottom,Scale.ScaleHeight)
- end
- else
- begin
- if Direction <> dirReversed then
- Scale.DrawRect(Canvas,Rect(R.Right-Scale.ScaleHeight,R.Top+Offset,R.Right,R.Bottom+Offset-1),False)
- else
- Scale.DrawRect(Canvas,Rect(R.Right-Scale.ScaleHeight,R.Top-Offset,R.Right,R.Bottom-Offset-1),False);
- Dec(R.Right,Scale.ScaleHeight);
- end;
- end;
- end;
- if (R.Top > R.Bottom) or (R.Left > R.Right) then Exit;
- th := TextHeight('W');
- tw := TextWidth(IntToStr(FSensitivy));
- tw2:= tw;
- { maybe we must skip some ticks ? }
- Skip := 1;
- if (FKind = lkHorizontal) then
- begin
- if (Direction = dirSymetric) then
- while (Width div 2) div (((FScaleTicks-1) div skip)*tw) < 1 do inc(Skip)
- else
- while Width div (((FScaleTicks-1) div skip)*tw) < 1 do inc(Skip);
- if (Direction <> dirReversed) then
- incValue := -1
- else
- incValue := 1;
- end
- else
- begin
- if (Direction = dirSymetric) then
- while (Height div 2) div (((FScaleTicks-1) div skip)*th) < 1 do inc(Skip)
- else
- while Height div (((FScaleTicks-1) div skip)*th) < 1 do inc(Skip);
- if (Direction <> dirReversed) then
- incValue := 1
- else
- incValue := -1;
- end;
- if (incValue = 1) then
- i := 0
- else
- i := FScaleTicks-1;
- H2 := (R.Bottom-R.Top) div 2;
- W2 := (R.Right-R.Left) div 2;
- { draw the scale }
- for j := 0 to FScaleTicks-1 do
- begin
- if ((j) mod Skip <> 0) then goto NextLoop;
- CurValue := MulDiv(FRange,i,FScaleTicks-1);
- if ((FKind = lkHorizontal) and (FDirection = dirReversed)) or
- ((FKind = lkVertical) and (FDirection <> dirReversed)) then
- CurValue := FRange - CurValue;
- if (CurValue > Long(FPoint2)*FRange/100) then Font.Color := FScale3Color
- else if (CurValue > Long(FPoint1)*FRange/100) then Font.Color := FScale2Color
- else Font.Color := FScale1Color;
- if FLogAmp then
- begin
- Count := i;
- if ((FKind = lkHorizontal) and (FDirection <> dirReversed)) or
- ((FKind = lkVertical) and (FDirection = dirReversed)) then
- Count := FScaleTicks-1-Count;
- Volume := Muldiv(Count,FSensitivy,FScaleTicks-1)
- end
- else
- begin
- Count := i;
- if ((FKind = lkHorizontal) and (FDirection = dirReversed)) or
- ((FKind = lkVertical) and (FDirection <> dirReversed)) then
- Count := FScaleTicks-1-Count;
- dbValue := FRange/pow(10,-FSensitivy/20);
- Volume := Round(Log10(((Long(Count)*(FRange-dbValue)/(FScaleTicks-1))+dbValue)/FRange)*20)
- end;
- if (FKind = lkHorizontal) then
- begin
- s := IntToStr(Volume);
- tw := TextWidth(s);
- if (FDirection = dirSymetric) then
- begin
- Pos := MulDivRN(i,(R.Right-R.Left-1)div 2,FScaleTicks-1);
- if (Pos >= 0) and (W2-Pos+tw <= W2) then
- begin
- TextOut(R.Left+Pos-(tw div 2),R.Top+(R.Bottom-R.Top-th)div 2,s);
- if (i < FScaleTicks-1) then
- begin
- s := '+'+IntToStr(abs(Volume));
- TextOut(R.Left+2*W2-Pos-1-(tw div 2),R.Top+(R.Bottom-R.Top-th)div 2,s);
- end;
- end;
- end
- else
- begin
- Pos := MulDivRN(i,R.Right-R.Left-1,FScaleTicks-1);
- if incValue = -1 then dec(Pos,tw);
- if (Pos >= 0) and (Pos+tw <= Width) then
- TextOut(R.Left+Pos,R.Top+(R.Bottom-R.Top-th)div 2,s);
- end;
- end
- else
- begin
- s := IntToStr(Volume);
- tw := TextWidth(s);
- if (FDirection = dirSymetric) then
- begin
- Pos := MulDivRN(i,(R.Bottom-R.Top-1)div 2,FScaleTicks-1);
- if (Pos >= 0) and (Pos+th <= H2) then
- begin
- TextOut(R.Right-(R.Right-R.Left)div 2 -(tw2 div 2)+(tw2-tw)-1,R.Top+H2+1+Pos-(th div 2),s);
- if (i > 0) then
- begin
- s := '+'+IntToStr(abs(Volume));
- TextOut(R.Right-(R.Right-R.Left)div 2 -(tw2 div 2)+(tw2-tw)-1,R.Top+H2+1-Pos-(th div 2),s);
- end;
- end;
- end
- else
- begin
- Pos := MulDivRN(i,R.Bottom-R.Top-1,FScaleTicks-1);
- if incValue = -1 then dec(Pos,th);
- if (Pos >= 0) and (Pos+th <= Height) then
- TextOut(R.Right-(R.Right-R.Left)div 2 -(tw2 div 2)+(tw2-tw)-1,R.Top+Pos,s);
- end;
- end;
- NextLoop:
- i := i + incValue;
- end;
- end;
- end;
- end.