MMOscope.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:93k
- {========================================================================}
- {= (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/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: 12.04.98 - 23:06:25 $ =}
- {========================================================================}
- Unit MMOscope;
- {$I COMPILER.INC}
- interface
- uses
- {$IFDEF WIN32}
- Windows,
- {$ELSE}
- WinTypes,
- WinProcs,
- {$ENDIF}
- SysUtils,
- Messages,
- Classes,
- Graphics,
- Controls,
- Forms,
- Dialogs,
- ExtCtrls,
- Menus,
- MMUtils,
- MMString,
- MMObj,
- MMSystem,
- MMRegs,
- MMPCMSup,
- MMWaveIO,
- MMDIBCv;
- const
- {$IFDEF CBUILDER3} {$EXTERNALSYM SCALEHEIGHT} {$ENDIF}
- SCALEHEIGHT = 40;
- {$IFDEF CBUILDER3} {$EXTERNALSYM SCALEWIDTH} {$ENDIF}
- SCALEWIDTH = 32;
- {$IFDEF CBUILDER3} {$EXTERNALSYM SCALEFONT} {$ENDIF}
- SCALEFONT = 'ARIAL';
- SCALEFONTSIZE : integer = 10;
- INFOCOLOR : TCOLOR = clWhite;
- EFFECTLIMIT : integer = 3;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MAX_FFTLEN} {$ENDIF}
- MAX_FFTLEN = 4096; { Define the maximum FFT buffer length. }
- type
- EMMOscopeError = class(Exception);
- TMMOscopeKind = (okDots,okConLines,okVertLines,okMirLines,okSpikes);
- TMMOscopeEffect = (efNone,efPeak,efSplit);
- TMMOscopeDrawLine= procedure(Sender: TObject; DIB: TMMDIBCanvas; Rect: TRect; Data: PSmallArray)of object;
- TMMOscopeSelect = procedure(Sender: TObject; Min, Max: Longint) of object;
- {-- TMMOscope --------------------------------------------------------}
- TMMOscope = class(TMMDIBGraphicControl)
- private
- FEnabled : Boolean; { Enable or disable Scope }
- FForeColor : TColor; { foreground color }
- FInactColor : TColor; { color for unmarked regions }
- FOffColor : TColor; { foreColor if disabled }
- FEffectColor : TColor; { color for the effects }
- FScaleTextColor: TColor; { the text color for the scale }
- FScaleLineColor: TColor; { the line color for the scale }
- FGridColor : TColor; { the grid color }
- FScaleBackColor: TColor; { background color for scale }
- FSelectColor : TColor; { color for selected range }
- FSelectDotColor: TColor; { border color for selected range }
- FLocatorColor : TColor; { locator color }
- FEffect : TMMOscopeEffect;{ differrent color effects }
- FSampleRate : Longint; { A/D sampling rate }
- FBits : TMMBits; { bit8 or bit16 }
- FChannel : TMMChannel; { chBoth, chLeft or chRigth }
- FMode : TMMMode; { mMono, mStereo }
- FBytes : Longint; { calculated data bytes per scope }
- FKind : TMMOscopeKind; { scope drawing modes }
- FSteps : Integer; { plot every 'steps' samples }
- FZoom : Integer; { the actual zoom factor }
- FGain : Integer; { the linear gain for the pcm data}
- FData : PSmallArray; { sample data buffer }
- FWidth : integer; { calculated width without border }
- FHeight : integer; { calculated height without border}
- FMiddle : integer; { calculated middleline }
- FClientRect : TRect; { calculated beveled Rect }
- FOldShowHint : Boolean; { saved ShowHint propertie }
- FShowInfo : Boolean; { show the amp/time info or not }
- FShowInfoHint : Boolean; { mouse is down, show the info }
- FDrawMidLine : Boolean; { draw a midline with inactive clr}
- FDrawAmpScale : Boolean; { draw the amp scale or not }
- FDrawTimeScale : Boolean; { draw the time scale or not }
- FDrawGrid : Boolean; { draw the grid or not }
- FMarkBegin : integer; { start pos for marked region }
- FMarkEnd : integer; { end pos for marked region }
- FSelectStart : Longint; { start pos for selected region }
- FSelectEnd : Longint; { end pos for selected region }
- FLocator : Longint; { current locator position }
- FFTLen : integer; { Number of points for FFT (dummy)}
- Fx1 : integer; { horiz. pos. counter for display }
- Fx2 : integer; { horiz. pos. counter for bar }
- FNumScaleSteps : integer; { pre-calc. number of scale steps }
- FBarWidth : integer; { width for the moving bar }
- FBarColor : TColor; { the color for the moving bar }
- FBarTickColor : TColor; { the color for the ticks on bar }
- FNeedReset : Boolean; { the oscope needs a reset }
- FAccelerate : Boolean; { accelerate the display refresh }
- FScroll : Boolean; { scroll the display or not }
- FRange : Longint;
- FCenter : Longint;
- FEffectTop : integer;
- FEffectBottom : integer;
- FLowPass : Boolean;
- FDrawing : Boolean;
- FLocked : Boolean;
- FUseSelection : Boolean;
-
- { Events }
- FOnGainOverflow: TNotifyEvent;
- FOnPcmOverflow : TNotifyEvent;
- FOnPostPaint : TNotifyEvent;
- FOnDrawLine : TMMOscopeDrawLine;
- FOnSelecting : TMMOscopeSelect;
- FOnSelectEnd : TMMOscopeSelect;
- procedure CreateDataBuffers(Length: Cardinal);
- procedure FreeDataBuffers;
- procedure SetBytesPerScope;
- procedure InitializeData;
- procedure CalcScaleSteps;
- procedure DrawAmplitudeScale;
- procedure DrawTimeScales;
- procedure DrawGrids;
- procedure DrawBar;
- procedure DrawInfo(Pos: TPoint);
- procedure DrawInactive;
- procedure DrawAsDots;
- procedure DrawAsSpikes;
- procedure DrawAsConLines;
- procedure DrawAsVertLines;
- procedure DrawAsMirLines;
- procedure DrawSelection(aCanvas: TMMDIBCanvas; sStart, sEnd: Longint;
- sColor: TColor; Solid: Boolean);
- procedure DrawLocator(aCanvas: TMMDIBCanvas; aPos: Longint; aColor: TColor);
- procedure DrawOscope(ClearBackGround: Boolean);
- procedure AdjustSize(var W, H: Integer);
- procedure AdjustBounds;
- procedure SetEnabled(Value: Boolean);
- procedure SetColors(Index: Integer; aValue: TColor);
- procedure SetPCMWaveFormat(wf: TPCMWaveFormat);
- function GetPCMWaveFormat: TPCMWaveFormat;
- procedure SetBits(aValue: TMMBits);
- procedure SetChannel(aValue: TMMChannel);
- procedure SetMode(aValue: TMMMode);
- procedure SetSampleRate(aValue: Longint);
- procedure SetSteps(aValue: Integer);
- procedure SetZoom(aValue: Integer);
- procedure SetGain(aValue: Integer);
- function GetGain: integer;
- procedure SetEffect(aValue: TMMOscopeEffect);
- procedure SetEffectLimits;
- procedure SetKind(aValue: TMMOscopeKind);
- procedure SetDrawMidLine(aValue: Boolean);
- procedure SetDrawAmpScale(aValue: Boolean);
- procedure SetDrawTimeScale(aValue: Boolean);
- procedure SetDrawGrid(aValue: Boolean);
- procedure SetBarWidth(aValue: integer);
- procedure SetFFTLen(aLength: integer);
- procedure SetAccelerate(aValue: Boolean);
- procedure SetScroll(aValue: Boolean);
- function GetScaleBackColor: TColor;
- procedure SetLocator(aValue: Longint);
- protected
- procedure ChangeDesigning(aValue: Boolean); override;
- procedure Paint; override;
- procedure GainOverflow; dynamic;
- procedure PcmOverflow; dynamic;
- procedure SetBounds(aLeft, aTop, aWidth, aHeight: integer); override;
- procedure Changed; override;
- procedure Selecting(Min, Max: Longint); dynamic;
- procedure SelectEnd(Min, Max: Longint); dynamic;
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
- procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure RefreshPCMData(PCMData: Pointer);
- procedure SetData(lpData: PSmallArray);
- procedure ResetData;
- function GetAmplitude(Pos: TPoint): Float;
- function GetTime(Pos: TPoint): Float;
- property BytesPerScope: Longint read FBytes;
- property PCMWaveFormat: TPCMWaveFormat read GetPCMWaveFormat write SetPCMWaveFormat;
- procedure Marked(mkBegin, mkEnd: integer; Redraw: Boolean);
- procedure Select(sStart, sEnd: Longint; Redraw: Boolean);
- property SelectionStart: Longint read FSelectStart;
- property SelectionEnd: Longint read FSelectEnd;
- property Locator: Longint read Flocator write SetLocator default -1;
- function IsLocator(X: integer): Boolean;
- function IsSelectStart(X: integer): Boolean;
- function IsSelectEnd(X: integer): Boolean;
- function IsInSelection(X: integer): Boolean;
- published
- { Events }
- property OnClick;
- property OnDblClick;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnStartDrag;
- property OnGainOverflow: TNotifyEvent read FOnGainOverflow write FOnGainOverflow;
- property OnPcmOverflow: TNotifyEvent read FOnPcmOverflow write FOnPcmOverflow;
- property OnDrawLine: TMMOscopeDrawLine read FOnDrawLine write FOnDrawLine;
- property OnPostPaint: TNotifyEvent read FOnPostPaint write FOnPostPaint;
- property OnSelecting: TMMOscopeSelect read FOnSelecting write FOnSelecting;
- property OnSelectEnd: TMMOscopeSelect read FOnSelectEnd write FOnSelectEnd;
- property Align;
- property Bevel;
- property PopupMenu;
- property BackGroundDIB;
- property UseBackGroundDIB;
- property PaletteRealize;
- property PaletteMapped;
- property Color default clBlack;
- property Cursor default crCross;
- property ParentShowHint;
- property ParentColor default False;
- property Visible;
- property ShowHint;
- property ShowInfo: Boolean read FShowInfo write FShowInfo default True;
- property Enabled: Boolean read FEnabled write SetEnabled default True;
- property Height default 90;
- property Width default 194;
- property Accelerate: Boolean read FAccelerate write SetAccelerate default True;
- property Scroll: Boolean read FScroll write SetScroll default False;
- property DrawMidLine: Boolean read FDrawMidLine write SetDrawMidLine default False;
- property Kind: TMMOscopeKind read FKind write SetKind default okDots;
- property ForegroundColor: TColor index 0 read FForeColor write SetColors default clAqua;
- property InactiveColor: TColor index 1 read FInactColor write SetColors default clTeal;
- property EffectColor: TColor index 2 read FEffectColor write SetColors default clRed;
- property DisabledColor: TColor index 3 read FOffColor write SetColors default clGray;
- Property ScaleTextColor: TColor index 4 read FScaleTextColor write SetColors default clBlack;
- Property ScaleLineColor: TColor index 5 read FScaleLineColor write SetColors default clBlack;
- Property GridColor: TColor index 6 read FGridColor write SetColors default clGray;
- property BarColor: TColor index 7 read FBarColor write SetColors default clGray;
- property BarTickColor: TColor index 8 read FBarTickColor write SetColors default clWhite;
- {$IFDEF BUILD_ACTIVEX}
- property ScaleBackColor: TColor index 9 read FScaleBackColor write SetColors default clBtnFace;
- {$ENDIF}
- property SelectionColor: TColor index 10 read FSelectColor write SetColors default clRed;
- property SelectionDotColor: TColor index 11 read FSelectDotColor write SetColors default clRed;
- property LocatorColor: TColor index 12 read FLocatorColor write SetColors default clYellow;
- property BarWidth: integer read FBarWidth write SetBarWidth default 5;
- property BitLength: TMMBits read FBits write SetBits default b8bit;
- property Channel: TMMChannel read FChannel write SetChannel default chBoth;
- property SampleRate: Longint read FSampleRate write SetSampleRate default 11025;
- property Mode: TMMMode read FMode write SetMode default mMono;
- property Steps: Integer read FSteps write SetSteps default 1;
- property Zoom: Integer read FZoom write SetZoom default 1;
- property Gain: Integer read GetGain write SetGain default 0;
- property Effect: TMMOscopeEffect read FEffect write SetEffect default efNone;
- property DrawAmpScale: Boolean read FDrawAmpScale write SetDrawAmpScale default False;
- property DrawTimeScale: Boolean read FDrawTimeScale write SetDrawTimeScale default False;
- property DrawGrid: Boolean read FDrawGrid write SetDrawGrid default False;
- property FFTLength: integer read FFTLen write SetFFTLen default 128;
- property LowPass: Boolean read FLowPass write FLowPass default False;
- property Locked: Boolean read FLocked write FLocked default False;
- property UseSelection: Boolean read FUseSelection write FUseSelection default False;
- end;
- implementation
- const
- CreateCount : Longint = 0;
- ControlList : TList = nil;
- SaveDC : HDC = 0;
- SaveBitmap : HBitmap = 0;
- SaveWidth : integer = 0;
- SaveHeight : integer = 0;
- SaveInfoPos : TPoint = (X:0;Y:0);
- OldBitmap : HBitmap = 0;
- OldDrawPos : TPoint = (X:0;Y:0);
- {------------------------------------------------------------------------}
- procedure AddOscope(Oscope: TMMOscope);
- begin
- inc(CreateCount);
- if (CreateCount = 1) then
- begin
- ControlList := TList.Create;
- end;
- if ControlList.IndexOf(Oscope) = -1 then
- ControlList.Add(Oscope);
- end;
- {------------------------------------------------------------------------}
- procedure RemoveOscope(Oscope: TMMOscope);
- begin
- ControlList.Remove(Oscope);
- ControlList.Pack;
- dec(CreateCount);
- if (CreateCount = 0) then
- begin
- ControlList.Free;
- ControlList := nil;
- end;
- end;
- {------------------------------------------------------------------------}
- procedure ResetOscope(Oscope: TMMOscope);
- var
- i: integer;
- begin
- if (ControlList <> nil) and (ControlList.Count > 0) then
- begin
- if Oscope.FScroll then
- for i := 0 to ControlList.Count-1 do
- if (ControlList.Items[i] <> Oscope) then
- TMMOscope(ControlList.Items[i]).FNeedReset := True;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- constructor TMMOscope.Create(AOwner: TComponent);
- begin
- ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
- if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
- inherited Create(AOwner);
- FData := Nil;
- FRange := $FFFF;
- FCenter := $7FFF;
- FMarkBegin := 0;
- FMarkEnd := Width;
- FSelectStart := -1;
- FSelectEnd := -1;
- FLocator := -1;
- FEnabled := True;
- Color := clBlack;
- FForeColor := clAqua;
- FInactColor := clTeal;
- FOffColor := clGray;
- FEffectColor := clRed;
- FScaleTextColor := clBlack;
- FScaleLineColor:= clBlack;
- FGridColor := clGray;
- FScaleBackColor:= clBtnFace;
- FSelectColor := clRed;
- FSelectDotColor := clRed;
- FLocatorColor := clYellow;
- FBits := b8Bit;
- FChannel := chBoth;
- FMode := mMono;
- FSampleRate := 11025;
- FSteps := 1;
- FZoom := 1;
- FGain := 8; { no Gain = 8 div 8 = 1 }
- FEffect := efNone;
- FKind := okDots;
- FDrawMidLine := False;
- FDrawAmpScale := False;
- FDrawTimeScale := False;
- FDrawGrid := False;
- FBarWidth := 5;
- FBarColor := clGray;
- FBarTickColor := clWhite;
- Fx1 := -FBarWidth;
- Fx2 := 0;
- FNeedReset := False;
- FAccelerate := True;
- FShowInfoHint := False;
- FShowInfo := True;
- FScroll := False;
- FFTLen := 8;
- FLowPass := False;
- FDrawing := False;
- FLocked := False;
- FUseSelection := False;
- Height := 90;
- Width := 194;
- Cursor := crCross;
- FFTLength := 128;
- if not (csDesigning in ComponentState) then
- begin
- { update the oscope list }
- AddOscope(Self);
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Destructor TMMOscope.Destroy;
- begin
- if not (csDesigning in ComponentState) then
- begin
- { update the oscope list }
- RemoveOscope(Self);
- end;
- FreeDataBuffers;
- inherited Destroy;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.ChangeDesigning(aValue: Boolean);
- begin
- inherited ChangeDesigning(aValue);
- if not (csDesigning in ComponentState) then
- begin
- { update the oscope list }
- AddOscope(Self);
- InitializeData;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.CreateDataBuffers(Length: Cardinal);
- begin
- if (Length > 0) then
- begin
- { allocate memory for sample buffer and lock }
- GlobalReAllocMem(Pointer(FData), (Length+4*10) * sizeOf(SmallInt));
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.FreeDataBuffers;
- begin
- GlobalFreeMem(Pointer(FData));
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.GainOverflow;
- begin
- if Assigned(FOnGainOverflow) then FOnGainOverflow(Self);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.PcmOverflow;
- begin
- if Assigned(FOnPcmOverflow) then FOnPcmOverflow(Self);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.InitializeData;
- Var
- i: integer;
- scale: real;
- begin
- scale := 1.0;
- if (csDesigning in ComponentState) then
- for i := 0 to FWidth-1 do { create sine data }
- begin
- FData^[i] := Round(sin(i*2*PI/((FWidth-1)/8))*scale*$77FF);
- scale := scale - (1.0/FWidth);
- end
- else { create zero data }
- for i := 0 to FWidth-1 do FData^[i] := 0;
- FMarkBegin := 0; { reset the marker positions }
- FMarkEnd := FWidth;
- FSelectStart := -1;
- FSelectEnd := -1;
- FLocator := -1;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.ResetData;
- var
- P: TPoint;
- begin
- if FShowInfoHint then
- begin
- GetCursorPos(P);
- P := ScreenToClient(P);
- Perform(WM_LBUTTONUP, 0, Longint(PointToSmallPoint(P)));
- end;
- { TODO: f黵 Scroll display }
- InitializeData;
- Refresh;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetEnabled(Value: Boolean);
- begin
- if (Value <> FEnabled) then
- begin
- FEnabled := Value;
- {inherited Enabled := Value;}
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetBarWidth(aValue: integer);
- begin
- if (aValue <> FBarWidth) then
- begin
- FBarWidth := Max(aValue,1);
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetFFTLen(aLength: integer);
- var
- i: integer;
- begin
- { FFTLen is here only a dummy to sync. the scrolling with other controls }
- aLength := MinMax(aLength,1,MAX_FFTLEN);
- { Convert FFTLen to a power of 2 }
- i := 0;
- while aLength > 1 do
- begin
- aLength := aLength shr 1;
- inc(i);
- end;
- if (i > 0) then aLength := aLength shl i;
- if (aLength <> FFTLen) then
- begin
- FFTLen := aLength;
- if FScroll then
- begin
- SetBytesPerScope;
- Invalidate;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetKind(aValue: TMMOscopeKind);
- begin
- if (aValue <> FKind) then
- begin
- FKind := aValue;
- if (FKind = okSpikes) then
- begin
- FRange := $7FFF;
- FCenter := 0;
- end
- else
- begin
- FRange := $FFFF;
- FCenter := $7FFF;
- end;
- Invalidate;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK1}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetEffectLimits;
- begin
- case FEffect of
- efPeak : begin
- FEffectTop := FHeight div EFFECTLIMIT;
- FEffectBottom := FHeight - FEffectTop;
- end;
- efSplit: begin
- FEffectTop := 0;
- FEffectBottom := FMiddle;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetEffect(aValue: TMMOscopeEffect);
- begin
- FEffect := aValue;
- SetEffectLimits;
- Invalidate;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK2}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.AdjustSize(var W, H: Integer);
- begin
- W := Max(W,2*BevelExtend+2);
- H := Max(H,2*BevelExtend+2) ;{and $FFFE;}
- if FDrawAmpScale then
- W := Max(W,2*SCALEWIDTH+2*BevelExtend+2);
- if FDrawTimeScale then
- H := Max(H,SCALEHEIGHT+2*BevelExtend+2); {and $FFFE};
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.AdjustBounds;
- var
- W, H: Integer;
- begin
- W := Width;
- H := Height;
- AdjustSize(W, H);
- if (W <> Width) or (H <> Height) then SetBounds(Left, Top, W, H)
- else Changed;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetBounds(aLeft, aTop, aWidth, aHeight: integer);
- var
- W, H: Integer;
- begin
- W := aWidth;
- H := aHeight;
- AdjustSize (W, H);
- inherited SetBounds(aLeft, aTop, W, H);
- Changed;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.Changed;
- begin
- FClientRect := Rect(0,0,Width,Height);
- { make place for amp the scale }
- if FDrawAmpScale then
- InflateRect(FClientRect, -SCALEWIDTH,0);
- { make place for amp the scale }
- if FDrawTimeScale then
- dec(FClientRect.Bottom, SCALEHEIGHT);
- { and now for the bevel }
- InflateRect(FClientRect, -Bevel.BevelExtend, -Bevel.BevelExtend);
- FWidth := Max(FClientRect.Right - FClientRect.Left,4);
- FHeight := Max(FClientRect.Bottom - FClientRect.Top,4);
- FMiddle := FHeight div 2;
- { adjust the data buffer size }
- CreateDataBuffers(FWidth);
- InitializeData; { init the data buffer }
- DIBCanvas.SetBounds(0,0,FWidth,FHeight);
- SetEffectLimits;
- SetBytesPerScope; { calc the new bytes per Scope }
- FMarkBegin := 0; { reset the marker positions }
- FMarkEnd := FWidth;
- FSelectStart := -1;
- FSelectEnd := -1;
- FLocator := -1;
- CalcScaleSteps;
- inherited Changed;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetBytesPerScope;
- begin
- FBytes := (Ord(FBits)+1) * (Ord(FMode)+1);
- if FScroll then FBytes := FBytes * FFTLen
- else
- begin
- FBytes := FBytes * FWidth;
- if (FZoom > 0) then FBytes := FBytes * FZoom
- else if (FZoom < 0) then FBytes := ((FBytes div (abs(FZoom)+1)+5)div 4)*4;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetPCMWaveFormat(wf: TPCMWaveFormat);
- var
- pwfx: PWaveFormatEx;
- begin
- pwfx := @wf;
- if not pcmIsValidFormat(pwfx) then
- raise EMMOscopeError.Create(LoadResStr(IDS_INVALIDFORMAT));
- SampleRate := pwfx^.nSamplesPerSec;
- BitLength := TMMBits(pwfx^.wBitsPerSample div 8 - 1);
- Mode := TMMMode(pwfx^.nChannels-1);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.GetPCMWaveFormat: TPCMWaveFormat;
- var
- wfx: TWaveFormatEx;
- begin
- pcmBuildWaveHeader(@wfx, (Ord(FBits)+1)*8, Ord(FMode)+1, SampleRate);
- Result := PPCMWaveFormat(@wfx)^;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetBits(aValue: TMMBits);
- begin
- if (aValue <> FBits) then
- begin
- FBits := aValue;
- SetBytesPerScope;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetChannel(aValue: TMMChannel);
- begin
- if (aValue <> FChannel) then
- begin
- FChannel := aValue;
- SetBytesPerScope;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetMode(aValue: TMMMode);
- begin
- if (aValue <> FMode) then
- begin
- FMode := aValue;
- SetBytesPerScope;
- Invalidate;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK3}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetSampleRate(aValue: Longint);
- begin
- if (aValue <> FSampleRate) then
- begin
- FSampleRate := MinMax(aValue, 8000, 88200);
- { Re-initialize the display }
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetGain(aValue: Integer);
- begin
- if (aValue <> FGain-8) and (aValue >= -8) and (aValue <= 32) then
- begin
- FGain := aValue + 8;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Function TMMOscope.GetGain: Integer;
- begin
- Result := FGain - 8;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetSteps(aValue: Integer);
- begin
- aValue := MinMax(1, aValue, 9);
- if (aValue <> FSteps) then
- begin
- FSteps := aValue;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetZoom(aValue: Integer);
- begin
- if (aValue <> FZoom) and (aValue <> 0) then
- begin
- FZoom := MinMax(aValue,-9,9);
- SetBytesPerScope;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetDrawAmpScale(aValue: Boolean);
- begin
- if (aValue <> FDrawAmpScale) then
- begin
- FDrawAmpScale := aValue;
- AdjustBounds;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetDrawTimeScale(aValue: Boolean);
- begin
- if (aValue <> FDrawTimeScale) then
- begin
- FDrawTimeScale := aValue;
- AdjustBounds;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetDrawGrid(aValue: Boolean);
- begin
- if (aValue <> FDrawGrid) then
- begin
- FDrawGrid := aValue;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetAccelerate(aValue: Boolean);
- begin
- if (aValue <> FAccelerate) then
- begin
- FAccelerate := aValue;
- if not FAccelerate and FScroll then Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetScroll(aValue: Boolean);
- begin
- if (aValue <> FScroll) then
- begin
- FScroll := aValue;
- Changed;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetColors(Index: Integer; aValue: TColor);
- begin
- case Index of
- 0: if FForeColor = aValue then exit else FForeColor := aValue;
- 1: if FInactColor = aValue then exit else FInactColor := aValue;
- 2: if FEffectColor = aValue then exit else FEffectColor := aValue;
- 3: if FOffColor = aValue then exit else FOffColor := aValue;
- 4: if FScaleTextColor = aValue then exit else FScaleTextColor := aValue;
- 5: if FScaleLineColor = aValue then exit else FScaleLineColor := aValue;
- 6: if FGridColor = aValue then exit else FGridColor := aValue;
- 7: if FBarColor = aValue then exit else FBarColor := aValue;
- 8: if FBarTickColor = aValue then exit else FBarTickColor := aValue;
- 9: if FScaleBackColor = aValue then exit else FScaleBackColor := aValue;
- 10: if FSelectColor = aValue then exit else FSelectColor := aValue;
- 11: if FSelectDotColor = aValue then exit else FSelectDotColor := aValue;
- 12: if FLocatorColor = aValue then exit else FLocatorColor := aValue;
- end;
- Invalidate;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.Marked(mkBegin, mkEnd: Integer; Redraw: Boolean);
- begin
- if (mkBegin <> FMarkBegin) then
- begin
- if (mkBegin < 0) then mkBegin := -1;
- if (mkBegin > FWidth) then mkBegin := FWidth;
- FMarkBegin := mkBegin;
- end;
- if (mkEnd <> FMarkEnd) then
- begin
- if (mkEnd < 0) then mkEnd := -1;
- if (mkEnd > FWidth) then mkEnd := FWidth;
- FMarkEnd := mkEnd;
- end;
- if Redraw then Refresh;
- end;
- {-- TMMOscope -----------------------------------------------------------------}
- procedure TMMOscope.Select(sStart, sEnd: Longint; Redraw: Boolean);
- var
- oldStart,oldEnd: Longint;
- begin
- oldStart:= FSelectStart;
- oldEnd := FSElectEnd;
- if (sStart <> FSelectStart) then
- begin
- if (sStart < 0) then sStart := -1;
- if (sStart > FWidth) then sStart := FWidth;
- FSelectStart := sStart;
- end;
- if (sEnd <> FSelectEnd) then
- begin
- if (sEnd < 0) then sEnd := -1;
- if (sEnd > FWidth) then sEnd := FWidth;
- FSelectEnd := sEnd;
- end;
- if (FSelectStart > FSelectEnd) then
- begin
- SwapLong(FSelectStart,FSelectEnd);
- end;
- if (FSelectEnd - FSelectStart <= 0) then
- begin
- FSelectStart := -1;
- FSelectEnd := -1;
- end;
- if Redraw and ((oldStart <> FSelectStart) or (oldEnd <> FSelectEnd)) then
- Refresh;
- end;
- {-- TMMOscope -----------------------------------------------------------------}
- procedure TMMOscope.SetLocator(aValue: Longint);
- var
- oldLoc: Longint;
- begin
- oldLoc := FLocator;
- if (aValue <> FLocator) then
- begin
- if (aValue < 0) then aValue := -1;
- if (aValue > FWidth) then aValue := FWidth;
- FLocator := aValue;
- end;
- if (oldLoc <> FLocator) then
- Refresh;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SetDrawMidLine(aValue: Boolean);
- begin
- if (aValue <> FDrawMidLine) then
- begin
- FDrawMidLine := aValue;
- Invalidate;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.RefreshPCMData(PCMData: Pointer);
- Var
- i,j: integer;
- ReIndex: integer;
- rZoom: integer;
- wf: TPCMWaveFormat;
- MinL,MaxL,MinR,MaxR: SmallInt;
- begin
- if FEnabled and Visible and not FShowInfoHint then
- begin
- if FScroll then
- begin
- i := 0;
- wf := GetPCMWaveFormat;
- pcmFindMinMax(@wf, PCMData, FBytes,
- MinL,MaxL,MinR,MaxR);
- if (FBits = b8bit) then
- begin
- if (FMode = mMono) or (FChannel = chLeft) then
- begin
- FData^[i] := (MinL-128) shl 8;
- FData^[i+1] := (MaxL-128) shl 8;
- end
- else if (FChannel = chRight) then
- begin
- FData^[i] := (MinR-128) shl 8;
- FData^[i+1] := (MaxR-128) shl 8;
- end
- else
- begin
- FData^[i] := ((MinL + MinR) div 2 - 128) shl 8;
- FData^[i+1] := ((MaxL + MaxR) div 2 - 128) shl 8;
- end;
- end
- else
- begin
- if (FMode = mMono) or (FChannel = chLeft) then
- begin
- FData^[i] := MinL;
- FData^[i+1] := MaxL;
- end
- else if (FChannel = chRight) then
- begin
- FData^[i] := MinR;
- FData^[i+1] := MaxR;
- end
- else
- begin
- FData^[i] := (Longint(MinL)+MinR) div 2;
- FData^[i+1] := (Longint(MaxL)+MaxR) div 2;
- end;
- end;
- end
- else
- begin
- ReIndex := Ord(FChannel)-1;
- j := 0;
- rZoom := abs(FZoom);
- if FZoom > 0 then
- begin
- { copy the sample Data from PCMData to FData }
- if (FBits = b8bit) then
- begin
- if (FMode = mMono) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (PByteArray(PCMData)^[j]-128) shl 8;
- inc(j,rZoom);
- end
- else if (FChannel = chBoth) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := ((Word(PByteArray(PCMData)^[j+j])+PByteArray(PCMData)^[j+j+1])div 2 -128) shl 8;
- inc(j,rZoom);
- end
- else
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (PByteArray(PCMData)^[j+j+ReIndex]-128) shl 8;
- inc(j,rZoom);
- end;
- end
- else
- begin
- if (FMode = mMono) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := PSmallArray(PCMData)^[j];
- inc(j,rZoom);
- end
- else if (FChannel = chBoth) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (Long(PSmallArray(PCMData)^[j+j])+PSmallArray(PCMData)^[j+j+1])div 2;
- inc(j,rZoom);
- end
- else
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := PSmallArray(PCMData)^[j+j+ReIndex];
- inc(j,rZoom);
- end;
- end;
- end
- else
- begin
- inc(rZoom);
- { copy the sample Data from PCMData to FData }
- if (FBits = b8bit) then
- begin
- if (FMode = mMono) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (PByteArray(PCMData)^[j]-128) shl 8;
- if ((i+1) mod rZoom = 0) then inc(j);
- end
- else if (FChannel = chBoth) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := ((Word(PByteArray(PCMData)^[j+j])+PByteArray(PCMData)^[j+j+1])div 2 -128) shl 8;
- if ((i+1) mod rZoom = 0) then inc(j);
- end
- else
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (PByteArray(PCMData)^[j+j+ReIndex]-128) shl 8;
- if ((i+1) mod rZoom = 0) then inc(j);
- end;
- end
- else
- begin
- if (FMode = mMono) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := PSmallArray(PCMData)^[j];
- if ((i+1) mod rZoom = 0) then inc(j);
- end
- else if (FChannel = chBoth) then
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := (Long(PSmallArray(PCMData)^[j+j])+PSmallArray(PCMData)^[j+j+1])div 2;
- if ((i+1) mod rZoom = 0) then inc(j);
- end
- else
- for i := 0 to FWidth-1 do
- begin
- FData^[i] := PSmallArray(PCMData)^[j+j+ReIndex];
- if ((i+1) mod rZoom = 0) then inc(j);
- end;
- end;
- end;
- end;
- SetData(FData);
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.SetData(lpData: PSmallArray);
- var
- i,Last,Value: integer;
- begin
- if (lpData <> FData) then
- GlobalMoveMem(lpData^,FData^,FWidth*sizeOf(Smallint));
- if FLowPass then
- begin
- Last := 0;
- for i := 0 to FWidth-1 do
- begin
- Value := FData^[i];
- FData^[i] := (Last+Longint(Value)*3) div 4; { Soft LowPass }
- Last := Value;
- end;
- end;
- FastDraw(DrawOscope,False);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.DrawAsDots;
- Var
- i: integer;
- Y1: integer;
- aColor: Long;
- rForeClr: Long;
- rInactClr: Long;
- rEffectClr: Long;
- Value: Longint;
- begin
- with DIBCanvas do
- begin
- rForeClr := DIB_ColorToIndex(FForeColor);
- rInactClr := DIB_ColorToIndex(FInactColor);
- if FScroll then
- begin
- DIB_SetTColor(Color);
- DIB_VLine(Fx1,0,FHeight);
- DIB_SetColor(rForeClr);
- if (FEffect = efNone) then
- begin
- for i := 0 to 1 do
- begin { display points by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- DIB_SetPixel(Fx1, FHeight-Y1-1, rForeClr);
- end;
- end
- else
- begin
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- for i := 0 to 1 do
- begin
- Value := FData^[i];
- if (Value >= 32767) then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if (Y1 < FEffectTop) or (Y1 > FEffectBottom) then
- DIB_SetPixel(Fx1, FHeight-Y1-1, rEffectClr)
- else
- DIB_SetPixel(Fx1, FHeight-Y1-1, rForeClr);
- end;
- end;
- end
- else
- begin
- if (FEffect = efNone) then
- begin
- aColor := rInactClr;
- i := 0;
- while i < FWidth do
- begin { display points by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- DIB_SetPixel(i, FHeight-Y1-1, aColor);
- inc(i,FSteps);
- end;
- end
- else
- begin
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- aColor := rInactClr;
- i := 0;
- while i < FWidth do
- begin { display points by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- if (aColor = rForeClr) and ((Y1 < FEffectTop) or (Y1 > FEffectBottom)) then
- DIB_SetPixel(i, FHeight-Y1-1, rEffectClr)
- else
- DIB_SetPixel(i, FHeight-Y1-1, aColor);
- inc(i,FSteps);
- end;
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.DrawAsConLines;
- Var
- i: integer;
- Y1: integer;
- aColor: Long;
- rForeClr: Long;
- rInactClr: Long;
- rEffectClr: Long;
- Value: Longint;
- begin
- with DIBCanvas do
- begin
- rForeClr := DIB_ColorToIndex(FForeColor);
- rInactClr := DIB_ColorToIndex(FInactColor);
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- if FScroll then
- begin
- DIB_SetTColor(Color);
- DIB_VLine(Fx1,0,FHeight);
- DIB_SetColor(rForeClr);
- DIB_MoveTo(OldDrawPos.X,OldDrawPos.Y);
- if (FEffect = efNone) then
- begin
- for i := 0 to 1 do
- begin
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- DIB_LineTo(Fx1, FHeight-Y1-1);
- end;
- end
- else
- begin
- for i := 0 to 1 do
- begin
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if (Y1 < FEffectTop) or (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_LineTo(Fx1, FHeight-Y1-1);
- end
- else
- begin
- DIB_SetColor(rForeClr);
- DIB_LineTo(Fx1, FHeight-Y1-1);
- end;
- end;
- end;
- OldDrawPos := Point(Fx1, FHeight-Y1-1);
- end
- else
- begin
- DIB_SetColor(rInactClr);
- if (FEffect = efNone) then
- begin
- i := FSteps;
- Y1 := Long(FData^[0] * Long(FGain) div 8 + FCenter)* FHeight div FRange;
- DIB_MoveTo(0,FHeight-Y1-1);
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then DIB_SetColor(rInactClr)
- else if i > FMarkBegin then DIB_SetColor(rForeClr);
- DIB_LineTo(i, FHeight-Y1-1);
- inc(i, FSteps);
- end;
- DIB_LineTo(i, FHeight-Y1-1);
- end
- else
- begin
- aColor := rInactClr;
- i := FSteps;
- Y1 := Long(FData^[0] * Long(FGain) div 8 + FCenter)* FHeight div FRange;
- DIB_MoveTo(0, FHeight-Y1-1);
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i > FMarkBegin then aColor := rForeClr;
- if (aColor = rForeClr) and ((Y1 < FEffectTop) or (Y1 > FEffectBottom)) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_LineTo(i, FHeight-Y1-1);
- end
- else
- begin
- DIB_SetColor(aColor);
- DIB_LineTo(i, FHeight-Y1-1);
- end;
- inc(i, FSteps);
- end;
- DIB_LineTo(i, FHeight-Y1-1);
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.DrawAsVertLines;
- Var
- i: integer;
- Y1: integer;
- aColor: Long;
- rForeClr: Long;
- rInactClr: Long;
- rEffectClr: Long;
- Value: Longint;
- begin
- with DIBCanvas do
- begin
- rForeClr := DIB_ColorToIndex(FForeColor);
- rInactClr := DIB_ColorToIndex(FInactColor);
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- i := 0;
- if FScroll then
- begin
- DIB_SetTColor(Color);
- DIB_VLine(Fx1,0,FHeight);
- DIB_SetColor(rForeClr);
- if (FEffect = efNone) then
- begin
- Value := FData^[i];
- if abs(FData^[i+1]) > abs(Value) then Value := FData^[i+1];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- DIB_VLine(Fx1, FMiddle, Y1);
- end
- else if (FEffect = efPeak) then
- begin
- Value := FData^[i];
- if abs(FData^[i+1]) > abs(Value) then Value := FData^[i+1];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- DIB_VLine(Fx1, FMiddle, Y1);
- if (Y1 < FEffectTop) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, Y1, Y1+5);
- end
- else if (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, Y1, Y1-5);
- end;
- end
- else if (FEffect = efSplit) then
- begin
- for i := 0 to 1 do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if (Y1 < FEffectBottom) then
- DIB_SetColor(rEffectClr)
- else
- DIB_SetColor(rForeClr);
- DIB_VLine(Fx1, FMiddle, Y1);
- end;
- end;
- end
- else
- begin
- DIB_SetColor(rInactClr);
- if (FEffect = efNone) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- while i < FWidth do
- begin { display lines by plntting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if i > FMarkEnd then DIB_SetColor(rInactClr)
- else if i >= FMarkBegin then DIB_SetColor(rForeClr);
- DIB_VLine(i, FMiddle, Y1);
- inc(i,FSteps);
- end;
- end
- else if (FEffect = efPeak) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- DIB_SetColor(aColor);
- DIB_VLine(i, FMiddle, Y1);
- if (aColor = rForeClr) then
- begin
- if (Y1 < FEffectTop) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, Y1, Y1+5);
- end
- else if (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, Y1, Y1-5);
- end;
- end;
- inc(i,FSteps);
- end;
- end
- else if (FEffect = efSplit) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_SetColor(rEffectClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Value * FGain div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- if (aColor = rForeClr) and (Y1 < FEffectBottom) then
- DIB_SetColor(rEffectClr)
- else
- DIB_SetColor(aColor);
- DIB_VLine(i, FMiddle, Y1);
- inc(i,FSteps);
- end;
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.DrawAsMirLines;
- Var
- i: integer;
- Y1,Y2: integer;
- aColor: Long;
- rForeClr: Long;
- rInactClr: Long;
- rEffectClr: Long;
- Value: Longint;
- begin
- with DIBCanvas do
- begin
- rForeClr := DIB_ColorToIndex(FForeColor);
- rInactClr := DIB_ColorToIndex(FInactColor);
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- i := 0;
- if FScroll then
- begin
- DIB_SetTColor(Color);
- DIB_VLine(Fx1,0,FHeight);
- DIB_SetColor(rForeClr);
- if (FEffect = efNone) then
- begin
- Value := FData^[i];
- if abs(FData^[i+1]) > abs(Value) then Value := FData^[i+1];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- DIB_VLine(Fx1, FHeight-Y1-1, Y1);
- end
- else if (FEffect = efPeak) then
- begin
- Value := FData^[i];
- if abs(FData^[i+1]) > abs(Value) then Value := FData^[i+1];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- Y2 := FHeight-Y1-1;
- DIB_VLine(Fx1, Y2, Y1);
- if (Y1 < FEffectTop) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1,Y1,Y1+5);
- DIB_VLine(Fx1,Y2,Y2-5);
- end
- else if (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1,Y1,Y1-5);
- DIB_VLine(Fx1,Y2,Y2+5);
- end;
- end
- else if (FEffect = efSplit) then
- begin
- Value := FData^[i];
- if abs(FData^[i+1]) > abs(Value) then Value := FData^[i+1];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if (Y1 < FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, FMiddle, Y1);
- DIB_SetColor(rForeClr);
- DIB_VLine(Fx1, FMiddle, FHeight-Y1-1);
- end
- else
- begin
- DIB_SetColor(rForeClr);
- DIB_VLine(Fx1, FMiddle, Y1);
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, FMiddle, FHeight-Y1-1);
- end;
- end;
- end
- else
- begin
- DIB_SetColor(rInactClr);
- if (FEffect = efNone) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then DIB_SetColor(rInactClr)
- else if i >= FMarkBegin then DIB_SetColor(rForeClr);
- DIB_VLine(i, FHeight-Y1-1, Y1);
- inc(i,FSteps);
- end;
- end
- else if (FEffect = efPeak) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- Y2 := FHeight-Y1-1;
- DIB_SetColor(aColor);
- DIB_VLine(i, Y2, Y1);
- if (aColor = rForeClr) then
- begin
- if (Y1 < FEffectTop) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i,Y1,Y1+5);
- DIB_VLine(i,Y2,Y2-5);
- end
- else if (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i,Y1,Y1-5);
- DIB_VLine(i,Y2,Y2+5);
- end;
- end;
- inc(i,FSteps);
- end;
- end
- else if (FEffect = efSplit) then
- begin
- DIB_HLine(0, FMarkBegin, FMiddle);
- DIB_HLine(0, FMarkBegin, FMiddle-1);
- DIB_SetColor(rForeClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle);
- DIB_SetColor(rEffectClr);
- DIB_HLine(FMarkBegin, FMarkEnd+1, FMiddle-1);
- DIB_SetColor(rInactClr);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle);
- DIB_HLine(FMarkEnd+1, FWidth, FMiddle-1);
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Value * FGain div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- if (aColor = rForeClr) then
- begin
- if (Y1 < FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, FMiddle, Y1);
- DIB_SetColor(aColor);
- DIB_VLine(i, FMiddle, FHeight-Y1-1);
- end
- else
- begin
- DIB_SetColor(aColor);
- DIB_VLine(i, FMiddle, Y1);
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, FMiddle, FHeight-Y1-1);
- end;
- end
- else
- begin
- DIB_SetColor(aColor);
- DIB_VLine(i, FMiddle, Y1);
- DIB_VLine(i, FMiddle, FHeight-Y1-1);
- end;
- inc(i,FSteps);
- end;
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.DrawAsSpikes;
- Var
- i,Y1: integer;
- aColor: Long;
- rForeClr: Long;
- rInactClr: Long;
- rEffectClr: Long;
- Value: Longint;
- begin
- with DIBCanvas do
- begin
- rForeClr := DIB_ColorToIndex(FForeColor);
- rInactClr := DIB_ColorToIndex(FInactColor);
- rEffectClr := DIB_ColorToIndex(FEffectColor);
- i := 0;
- if FScroll then
- begin
- DIB_SetTColor(Color);
- DIB_VLine(Fx1,0,FHeight);
- DIB_SetColor(rForeClr);
- if (FEffect = efNone) then
- begin
- Value := abs(FData^[i]);
- if abs(FData^[i+1]) > Value then Value := abs(FData^[i+1]);
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Word(Value)* Long(FGain) div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- DIB_VLine(Fx1, FHeight, Y1);
- end
- else if(FEffect = efPeak) then
- begin
- Value := abs(FData^[i]);
- if abs(FData^[i+1]) > Value then Value := abs(FData^[i+1]);
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Word(Value)* Long(FGain) div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- DIB_VLine(Fx1, FHeight, Y1);
- if (Y1 < FEffectTop shl 1) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, Y1, Y1+5);
- end;
- end
- else
- begin
- for i := 0 to 1 do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Word(ABS(Value))* Long(FGain) div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(Fx1, FMiddle, FHeight-Y1-1);
- DIB_SetColor(rForeClr);
- DIB_VLine(Fx1, FHeight, FMiddle);
- end
- else DIB_VLine(Fx1, FHeight, FHeight-Y1-1);
- end;
- end;
- end
- else
- begin
- DIB_SetColor(rInactClr);
- if (FEffect = efNone) then
- begin
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Word(ABS(Value))* Long(FGain) div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if i > FMarkEnd then DIB_SetColor(rInactClr)
- else if i >= FMarkBegin then DIB_SetColor(rForeClr);
- DIB_VLine(i, FHeight, Y1);
- inc(i,FSteps);
- end;
- end
- else if(FEffect = efPeak) then
- begin
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := FHeight-(Long(Word(ABS(Value))* Long(FGain) div 8 + FCenter)* FHeight div FRange)-1;
- if (Y1 < -1) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- DIB_SetColor(aColor);
- DIB_VLine(i, FHeight, Y1);
- if (aColor = rForeClr) and (Y1 < FEffectTop shl 1) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, Y1, Y1+5);
- end;
- inc(i,FSteps);
- end;
- end
- else
- begin
- aColor := rInactClr;
- while i < FWidth do
- begin { display lines by plotting samples in FData.}
- Value := FData^[i];
- if Value >= 32767 then PcmOverflow;
- Y1 := Long(Word(ABS(Value))* Long(FGain) div 8 + FCenter)* FHeight div FRange;
- if (Y1 > FHeight) then GainOverflow;
- if i > FMarkEnd then aColor := rInactClr
- else if i >= FMarkBegin then aColor := rForeClr;
- if (aColor = rForeClr) and (Y1 > FEffectBottom) then
- begin
- DIB_SetColor(rEffectClr);
- DIB_VLine(i, FMiddle, FHeight-Y1-1);
- DIB_SetColor(rForeClr);
- DIB_VLine(i, FHeight, FMiddle);
- end
- else
- begin
- DIB_SetColor(aColor);
- DIB_VLine(i, FHeight, FHeight-Y1-1);
- end;
- inc(i,FSteps);
- end;
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.GetAmplitude(Pos: TPoint): Float;
- begin
- Result := 0;
- if PtInRect(FClientRect,Pos) then
- begin
- dec(Pos.Y,FClientRect.Top);
- if (FKind = okSpikes) then
- Result := (FHeight-Pos.Y-1)*(10/(FHeight-1))*0.1
- else
- begin
- Result := (FHeight/2-Pos.Y);
- if Result < 0 then Result := Result -1;
- Result := Result*(10/FHeight)*0.2;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.GetTime(Pos: TPoint): Float;
- var
- wf: TPCMWaveFormat;
- begin
- Result := 0;
- if PtInRect(FClientRect,Pos) then
- begin
- dec(Pos.X,FClientRect.Left-1);
- wf := PCMWaveFormat;
- Result := Pos.X * wioBytesToTime(@wf,FBytes)/FWidth;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.CalcScaleSteps;
- begin
- { calc the number of steps required }
- FNumScaleSteps := 10;
- while (FHeight div FNumScaleSteps < SCALEFONTSIZE) do
- begin
- dec(FNumScaleSteps, 2);
- if FNumScaleSteps <= 2 then break;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.GetScaleBackColor: TColor;
- begin
- {$IFNDEF BUILD_ACTIVEX}
- Result := TForm(Parent).Color;
- {$ELSE}
- Result := FScaleBackColor;
- {$ENDIF}
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawAmplitudeScale;
- var
- aBitmap: TBitmap;
- i, X, Y,H: integer;
- Text,Text1: String;
- Scale: Float;
- YScale: integer;
- begin
- { Put up the amplitude scale }
- if FDrawAmpScale then
- begin
- YScale := 1;
- aBitmap := TBitmap.Create;
- try
- if FDrawTimeScale then
- H := Height-SCALEHEIGHT
- else
- H := Height;
- aBitmap.Width := SCALEWIDTH;
- aBitmap.Height := H;
- aBitmap.Canvas.Font.Color := FScaleTextColor;
- aBitmap.Canvas.Pen.Color := FScaleLineColor;
- aBitmap.Canvas.Brush.Color := GetScaleBackColor;
- with aBitmap.Canvas do
- begin
- { calc the number of steps required }
- Scale := (YScale*32768.0)/FHeight;
- { draw the left side }
- FillRect(Rect(0,0,aBitmap.Width,aBitmap.Height));
- X := SCALEWIDTH-1;
- MoveTo(X, H-BevelExtend-1);
- for i := 0 to FNumScaleSteps do
- begin
- Y := H-BevelExtend-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- LineTo(X, Y);
- LineTo(X-3, Y);
- MoveTo(X, Y);
- if (FKind = okSpikes) then
- begin
- Text := Format('%4.2f',[i*(10/FNumScaleSteps)*0.1]);
- Y := H-BevelExtend-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- TextOutAligned(aBitmap.Canvas, X-5, Y, Text,SCALEFONT,SCALEFONTSIZE,1);{ right text }
- end;
- end;
- if (FKind <> okSpikes) then
- begin
- for i := 0 to FNumScaleSteps div 2 do
- begin
- Text := Format('%4.2f',[i*(10/FNumScaleSteps*2)*0.1]);
- Text1 := Text;
- if (i > 0) then
- begin
- Text := '+'+Text;
- Text1 := '-'+Text1;
- end;
- Y := H-BevelExtend-FMiddle-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- TextOutAligned(aBitmap.Canvas, X-5, Y, Text,SCALEFONT,SCALEFONTSIZE,1);{ right text }
- Y := BevelExtend+FMiddle+Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)+1;
- TextOutAligned(aBitmap.Canvas, X-5, Y, Text1,SCALEFONT,SCALEFONTSIZE,1);{ right text }
- end;
- end;
- Canvas.Draw(-3, 0, aBitmap);
- { draw the right side }
- FillRect(Rect(0,0,aBitmap.Width,aBitmap.Height));
- X := 0;
- MoveTo(X, H-BevelExtend-1);
- for i := 0 to FNumScaleSteps do
- begin
- Y := H-BevelExtend-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- LineTo(X, Y);
- LineTo(X+3, Y);
- MoveTo(X, Y);
- if (FKind = okSpikes) then
- begin
- Text := Format('%4.2f',[i*(10/FNumScaleSteps)*0.1]);
- Y := H-BevelExtend-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- TextOutAligned(aBitmap.Canvas, X+29, Y, Text, SCALEFONT,SCALEFONTSIZE,1);{ right text }
- end;
- end;
- if (FKind <> okSpikes) then
- begin
- for i := 0 to FNumScaleSteps div 2 do
- begin
- Text := Format('%4.2f',[i*(10/FNumScaleSteps*2)*0.1]);
- Text1 := Text;
- if (i > 0) then
- begin
- Text := '+'+Text;
- Text1 := '-'+Text1;
- end;
- Y := H-BevelExtend-FMiddle-Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)-1;
- TextOutAligned(aBitmap.Canvas, X+29, Y, Text, SCALEFONT,SCALEFONTSIZE,1);{ right text }
- Y := BevelExtend+FMiddle+Trunc(i*YScale*32768.0/FNumScaleSteps/Scale)+1;
- TextOutAligned(aBitmap.Canvas, X+29, Y, Text1, SCALEFONT,SCALEFONTSIZE,1);{ right text }
- end;
- end;
- Canvas.Draw((Width - SCALEWIDTH)+3, 0, aBitmap);
- end;
- finally
- aBitmap.Free;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawTimeScales;
- var
- aBitmap: TBitmap;
- i, X: integer;
- Text: String;
- Time: Longint;
- Step: Float;
- NumSteps: integer;
- wf: TPCMWaveFormat;
- begin
- if FDrawTimeScale then
- begin
- aBitmap := TBitmap.Create;
- try
- aBitmap.Width := FWidth + 2*BevelExtend;
- aBitmap.Height := SCALEHEIGHT;
- aBitmap.Canvas.Font.Color := FScaleTextColor;
- aBitmap.Canvas.Pen.Color := FScaleLineColor;
- aBitmap.Canvas.Brush.Color := GetScaleBackColor;
- with aBitmap.Canvas do
- begin
- FillRect(Rect(0,0,aBitmap.Width,aBitmap.Height));
- { calc the number of steps required }
- NumSteps := 32;
- while (FWidth div NumSteps < SCALEFONTSIZE) do
- begin
- NumSteps := NumSteps div 2;
- if NumSteps = 1 then break;
- end;
- { Put up the time scale. }
- wf := PCMWaveFormat;
- Time := wioBytesToTime(@wf,FBytes);
- Step := Time/NumSteps;
- MoveTo(BevelExtend,0);
- for i := 0 to NumSteps do
- begin
- X := i * (FWidth-1) div NumSteps + BevelExtend;
- LineTo(X, 0);
- LineTo(X, 3);
- MoveTo(X, 0);
- Text := Format('%4.1f',[i*Step]);
- TextOutAligned(aBitmap.Canvas,X,6,Text,SCALEFONT,SCALEFONTSIZE,2);{ vertical text }
- end;
- end;
- Canvas.Draw(FClientRect.Left-BevelExtend,
- FClientRect.Bottom+BevelExtend+3, aBitmap);
- finally
- aBitmap.Free;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawGrids;
- var
- i,X,Y,NumSteps: integer;
- YScale: integer;
- Scale: Float;
- begin
- if FDrawGrid then
- with DIBCanvas do
- begin
- DIB_SetTColor(FGridColor);
- { the horizontal lines }
- YScale := 1;
- { calc the scale steps required }
- Scale := (YScale*32768.0)/FHeight;
- for i := 0 to FNumScaleSteps do
- begin
- Y := FHeight-Trunc(i*YScale*32760.0/FNumScaleSteps/Scale)-1;
- DIB_HLineDoted(0, FWidth, Y, 1);
- end;
- { the vertical lines }
- { calc the number of steps required }
- NumSteps := 32;
- while (FWidth div NumSteps < SCALEFONTSIZE) do
- begin
- NumSteps := NumSteps div 2;
- if NumSteps = 1 then break;
- end;
- for i := 0 to NumSteps do
- begin
- X := i * (FWidth-1) div NumSteps;
- DIB_VLineDoted(X, 0, FHeight, 1);
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawBar;
- var
- i,Y: integer;
- aRect: TRect;
- begin
- if FAccelerate then
- with Canvas do
- begin
- Pen.Mode := pmCopy;
- Pen.Color := FBarColor;
- Pen.Width := 1;
- aRect := Rect(FClientRect.Left+Fx2,FClientRect.Top,
- FClientRect.Left+Fx2,FClientRect.Bottom);
- MoveTo(aRect.Left, aRect.Top);
- LineTo(aRect.Left, aRect.Bottom);
- for i := 0 to FNumScaleSteps do
- begin
- Y := (BevelExtend+FHeight)-Trunc(i * (FHeight-1)/FNumScaleSteps)-1;
- SetPixel(Handle,aRect.Left, Y, FBarTickColor);
- end;
- end
- else
- with DIBCanvas do
- begin
- Pen.Mode := pmCopy;
- Brush.Color := FBarColor;
- if Fx2 > Fx1 then
- begin
- aRect := Rect(Fx1+1,0,Fx2+1,FHeight);
- FillRect(aRect);
- end
- else
- begin
- aRect := Rect(0,0,Fx2+1,FHeight);
- FillRect(aRect);
- end;
- Pen.Color := FBarTickColor;
- for i := 0 to FNumScaleSteps do
- begin
- Y := FHeight - Trunc(i * (FHeight-1)/FNumScaleSteps)-1;
- MoveTo(aRect.Left,Y);
- LineTo(aRect.Right,Y);
- end;
- end;
- end;
- {$IFDEF WIN32}
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawInfo(Pos: TPoint);
- var
- Text: String;
- aRect: TRect;
- Buf: array[0..255] of char;
- DC: HDC;
- WindowHandle: HWND;
- begin
- if FShowInfoHint then
- with DIBCanvas do
- begin
- if PtInRect(FClientRect,Pos) then
- begin
- Text := Format('%4.1f ms',[GetTime(Pos)])+
- Format(' %4.2f V',[GetAmplitude(Pos)]);
- Font.Name := 'MS Sans Serif';
- Font.Size := 8;
- Font.Style := [];
- {$IFDEF WIN32}
- Font.Color := clInfoText;
- {$ELSE}
- Font.Color := clBlack;
- {$ENDIF}
- aRect.Left := Pos.X-BevelExtend;
- if FDrawAmpScale then dec(aRect.Left, SCALEWIDTH);
- aRect.Top := Pos.Y-BevelExtend+15;
- aRect.Right := aRect.Left + TextWidth(Text)+4;
- aRect.Bottom := aRect.Top + TextHeight(Text)+2;
- if (aRect.Bottom > FHeight) then OffsetRect(aRect,0,-40);
- if (aRect.Right > FWidth) then OffsetRect(aRect,FWidth-aRect.Right,0);
- if (aRect.Top < 0) then
- begin
- aRect.Top := 0;
- aRect.Bottom := TextHeight(Text)+2;
- end;
- if (SaveDC = 0) then
- begin
- { create memory DC for save bitmap }
- SaveDC := CreateCompatibleDC(DIBCanvas.Handle);
- { create bitmap to store background }
- SaveWidth := 10*TextWidth('W')+4;
- SaveHeight := TextHeight('W')+2;
- SaveBitmap := CreateCompatibleBitmap(DIBCanvas.Handle,SaveWidth,SaveHeight);
- OldBitmap := SelectObject(SaveDC, SaveBitmap);
- end
- else
- { restore background }
- BitBlt(DIBCanvas.Handle,SaveInfoPos.X,
- SaveInfoPos.Y,SaveWidth,SaveHeight,
- SaveDC,0,0,SRCCOPY);
- { save background }
- BitBlt(SaveDC,0,0,SaveWidth,SaveHeight,
- DIBCanvas.Handle,aRect.Left,aRect.Top,SRCCOPY);
- SaveInfoPos := aRect.TopLeft;
- Brush.Color := INFOCOLOR;
- Brush.Style := bsSolid;
- Pen.Color := clBlack;
- Rectangle(aRect.Left,aRect.Top,aRect.Right,aRect.Bottom);
- Brush.Style := bsClear;
- DrawText(Handle, StrPCopy(Buf, Text), -1, aRect,
- DT_SINGLELINE or DT_VCENTER or DT_CENTER or DT_NOPREFIX);
- Brush.Style := bsSolid;
- end
- else if (SaveBitmap <> 0) then
- begin
- { restore background }
- BitBlt(DIBCanvas.Handle,SaveInfoPos.X,
- SaveInfoPos.Y,SaveWidth,SaveHeight,
- SaveDC,0,0,SRCCOPY);
- end;
- DIB_InitDrawing; { copy to screen }
- DC := GetDeviceContext(WindowHandle);
- DIBCanvas.DIB_BitBlt(DC, FClientRect,0,0);
- ReleaseDC(WindowHandle, DC);
- DIB_DoneDrawing;
- end;
- end;
- {$ELSE}
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawInfo(Pos: TPoint);
- var
- Text: String;
- aRect: TRect;
- Buf: array[0..255] of char;
- Border: integer;
- begin
- if FShowInfoHint then
- with Canvas do
- begin
- if PtInRect(FClientRect,Pos) then
- begin
- Text := Format('%4.1f ms',[GetTime(Pos)])+
- Format(' %4.2f V',[GetAmplitude(Pos)]);
- Font.Name := 'MS Sans Serif';
- Font.Size := 8;
- Font.Style := [];
- {$IFDEF WIN32}
- Font.Color := clInfoText;
- {$ELSE}
- Font.Color := clBlack;
- {$ENDIF}
- aRect.Left := Pos.X;
- aRect.Top := Pos.Y+15;
- aRect.Right := aRect.Left + TextWidth(Text)+4;
- aRect.Bottom := aRect.Top + TextHeight(Text)+2;
- Border := BevelExtend;
- if FDrawAmpScale then inc(Border,SCALEHEIGHT);
- if (aRect.Bottom > Height-Border) then OffsetRect(aRect,0,-40);
- Border := BevelExtend;
- if FDrawAmpScale then inc(Border,SCALEWIDTH);
- if (aRect.Right > Width-Border) then OffsetRect(aRect,Width-Border-aRect.Right,0);
- if (aRect.Top < 0) then
- begin
- aRect.Top := 0;
- aRect.Bottom := TextHeight(Text)+2;
- end;
- if (SaveDC = 0) then
- begin
- { create memory DC for save bitmap }
- SaveDC := CreateCompatibleDC(Canvas.Handle);
- { create bitmap to store background }
- SaveWidth := 10*TextWidth('W')+4;
- SaveHeight := TextHeight('W')+2;
- SaveBitmap := CreateCompatibleBitmap(Canvas.Handle,SaveWidth,SaveHeight);
- OldBitmap := SelectObject(SaveDC, SaveBitmap);
- end
- else
- { restore background }
- BitBlt(Canvas.Handle,SaveInfoPos.X,
- SaveInfoPos.Y,SaveWidth,SaveHeight,
- SaveDC,0,0,SRCCOPY);
- { save background }
- BitBlt(SaveDC,0,0,SaveWidth,SaveHeight,
- Canvas.Handle,aRect.Left,aRect.Top,SRCCOPY);
- SaveInfoPos := aRect.TopLeft;
- Brush.Color := INFOCOLOR;
- Brush.Style := bsSolid;
- Pen.Color := clBlack;
- Rectangle(aRect.Left,aRect.Top,aRect.Right,aRect.Bottom);
- Brush.Style := bsClear;
- DrawText(Handle, StrPCopy(Buf, Text), -1, aRect,
- DT_SINGLELINE or DT_VCENTER or DT_CENTER or DT_NOPREFIX);
- Brush.Style := bsSolid;
- end
- else if (SaveBitmap <> 0) then
- begin
- { restore background }
- BitBlt(Canvas.Handle,SaveInfoPos.X,
- SaveInfoPos.Y,SaveWidth,SaveHeight,
- SaveDC,0,0,SRCCOPY);
- end;
- end;
- end;
- {$ENDIF}
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawSelection(aCanvas: TMMDIBCanvas; sStart, sEnd: Longint;
- sColor: TColor; Solid: Boolean);
- begin
- if (sStart >= 0) and (sEnd >= 0) then
- begin
- with aCanvas do
- begin
- DIB_SetTColor(sColor);
- if Solid then
- begin
- DIB_FillRect(Rect(sStart,0,sEnd+1,Height));
- end
- else
- begin
- DIB_HLineDashed(sStart,sEnd+1,0);
- DIB_HLineDashed(sStart,sEnd+1,Height-1);
- DIB_VLineDashed(sStart,0,Height-1);
- DIB_VLineDashed(sEnd,0,Height-1);
- end;
- end;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawLocator(aCanvas: TMMDIBCanvas; aPos: Longint; aColor: TColor);
- begin
- with aCanvas do
- begin
- DIB_SetTColor(aColor);
- DIB_MoveTo(aPos,0);
- DIB_LineTo(aPos,FHeight);
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawInactive;
- begin
- with DIBCanvas do
- begin
- DIB_SetTColor(FOffColor);
- DIB_HLine(5, FWidth-5, FMiddle); { only Draw a horiz. line }
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.DrawOscope(ClearBackGround: Boolean);
- var
- aRect: TRect;
- begin
- DIBCanvas.DIB_InitDrawing;
- if assigned(FOnDrawLine) then
- begin
- FOnDrawLine(Self,DIBCanvas,Rect(0,0,FWidth,FHeight),FData);
- DIBCanvas.DIB_BitBlt(Canvas.Handle, FClientRect,0,0);
- end
- else
- begin
- if not FScroll or (ClearBackGround or FNeedReset) then
- begin
- DrawBackGround; { Clear background or draw DIB }
- Fx1 := -FBarWidth;
- Fx2 := 0;
- OldDrawPos := Point(0,FMiddle);
- if not FNeedReset and FScroll then ResetOscope(Self);
- end;
- if not FEnabled then DrawInactive
- else
- begin
- if not FScroll then
- begin
- { draw solid Selection }
- DrawSelection(DIBCanvas,FSelectStart,FSelectEnd,FSelectColor,True);
- if FDrawMidLine then
- begin
- DIBCanvas.DIB_SetTColor(FOffColor);
- DIBCanvas.DIB_HLineDashed(0,FWidth,FMiddle);
- end;
- DrawGrids; { draw the grid }
- end;
- case FKind of { draw the scope to bitmap }
- okDots : DrawAsDots;
- okConLines : DrawAsConLines;
- okVertLines : DrawAsVertLines;
- okMirLines : DrawAsMirLines;
- okSpikes : DrawAsSpikes;
- end;
- end;
- if FScroll then
- begin
- if ClearBackGround or FNeedReset or not FAccelerate then
- begin
- if (Fx2 < FWidth) then DrawBar;
- DIBCanvas.DIB_BitBlt(Canvas.Handle, FClientRect,0,0);
- FNeedReset := False;
- end
- else
- begin
- aRect := FClientRect;
- aRect.Left := FClientRect.Left + Fx1;
- aRect.Right := 1;
- DIBCanvas.DIB_BitBlt(Canvas.Handle,aRect,Fx1,0);
- end;
- { move the bar }
- if (Fx2 < FWidth) then
- begin
- if Accelerate then DrawBar;
- inc(Fx1);
- inc(Fx2);
- end
- else
- begin
- if Accelerate then
- begin
- {$IFNDEF BUILD_ACTIVEX}
- aRect:= BoundsRect;
- {$ELSE}
- aRect:= ClientRect;
- {$ENDIf}
- InflateRect(aRect, -BevelExtend, -BevelExtend);
- if FDrawAmpScale then
- InflateRect(aRect, -SCALEWIDTH, 0);
- if FDrawTimeScale then
- dec(aRect.Bottom, SCALEHEIGHT);
- dec(aRect.Right,FBarWidth-1);
- {$IFNDEF BUILD_ACTIVEX}
- ScrollWindowEx(Parent.Handle,-1,0,@aRect,@aRect,0,nil,0);
- {$ELSE}
- ScrollWindowEx(Handle,-1,0,@aRect,@aRect,0,nil,0);
- {$ENDIF}
- end
- else DIBCanvas.DIB_CopyDIBBits(biSurface,0,0,FWidth-1,FHeight,1,0);
- end;
- end
- else { copy to screen }
- begin
- { draw doted Selection }
- DrawSelection(DIBCanvas,FSelectStart,FSelectEnd,FSelectDotColor,False);
- { draw the locator }
- DrawLocator(DIBCanvas,FLocator,FLocatorColor);
- DIBCanvas.DIB_BitBlt(Canvas.Handle, FClientRect,0,0);
- end;
- end;
- DIBCanvas.DIB_DoneDrawing;
- if assigned(FOnPostPaint) then FOnPostPaint(Self);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- Procedure TMMOscope.Paint;
- var
- H: integer;
- aRect: TRect;
- begin
- with Canvas do
- begin
- if FDrawAmpScale or FDrawTimeScale then
- begin
- { clear the space between the scales only, to eliminate flicker }
- Brush.Color := GetScaleBackColor;
- Brush.Style := bsSolid;
- if FDrawAmpScale then
- begin
- H := Height;
- if FDrawTimeScale then H := Height-SCALEHEIGHT;
- aRect := Rect(SCALEWIDTH-3,0,SCALEWIDTH,H);
- FillRect(aRect);
- aRect:= Rect(Width-SCALEWIDTH,0,Width-SCALEWIDTH+3,H);
- FillRect(aRect);
- end;
- if FDrawTimeScale then
- begin
- aRect:= Rect(0,Height-SCALEHEIGHT,Width,Height-SCALEHEIGHT+3);
- FillRect(aRect);
- if FDrawAmpScale then
- begin
- aRect:= Rect(0,Height-SCALEHEIGHT,SCALEWIDTH,Height);
- FillRect(aRect);
- aRect:= Rect(WIDTH-SCALEWIDTH,Height-SCALEHEIGHT,Width,Height);
- FillRect(aRect);
- end;
- end;
- if FDrawAmpScale and FDrawTimeScale then
- begin
- { write text }
- Canvas.Font.Color := FScaleTextColor;
- TextOutAligned(Canvas, SCALEWIDTH-16, Height-SCALEHEIGHT+6,
- 'V', SCALEFONT,SCALEFONTSIZE, 1);
- TextOutAligned(Canvas, Width-SCALEWIDTH+18, Height-SCALEHEIGHT+6,
- 'V', SCALEFONT,SCALEFONTSIZE,0);
- TextOutAligned(Canvas, Width-SCALEWIDTH+2, Height-SCALEHEIGHT+20,
- 'mS', SCALEFONT,SCALEFONTSIZE,0);
- end;
- { make place for the scale }
- aRect := GetClientRect;
- if FDrawAmpScale then
- InflateRect(aRect,-SCALEWIDTH,0);
- if FDrawTimeScale then
- dec(aRect.Bottom, SCALEHEIGHT);
- end
- else aRect := GetClientRect;
- { draw the Bevel and fill the real area }
- aRect := Bevel.PaintBevel(Canvas, aRect, True);
- end;
- { now draw the scales and the oscope }
- DrawAmplitudeScale;
- DrawTimeScales;
- if (csDesigning in ComponentState) {$IFDEF WIN32}or (csPaintCopy in ControlState){$ENDIF} then
- DrawOscope(True)
- else
- FastDraw(DrawOscope,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;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.Selecting(Min, Max: Longint);
- begin
- Select(Min,Max,True);
- if assigned(FOnSelecting) then FOnSelecting(Self,Min,Max);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.SelectEnd(Min, Max: Longint);
- begin
- Select(Min,Max,False);
- if assigned(FOnSelectEnd)then FOnSelectEnd(Self,Min,Max);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.IsLocator(X: integer): Boolean;
- begin
- Result := (FLocator >= 0) and
- (X >= (FLocator+BevelExtend)-3) and
- (X <= (FLocator+BevelExtend)+3) and
- (X >= 0) and (X <= Width);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.IsSelectStart(X: integer): Boolean;
- begin
- Result := (FSelectStart >= 0) and
- (X >= (FSelectStart+BevelExtend)-3) and
- (X <= (FSelectStart+BevelExtend)+2) and
- (X >= 0) and (X <= Width);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.IsSelectEnd(X: integer): Boolean;
- begin
- Result := (FSelectEnd >= 0) and
- (X >= (FSelectEnd+BevelExtend)-2) and
- (X <= (FSelectEnd+BevelExtend)+3) and
- (X >= 0) and (X <= Width);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- function TMMOscope.IsInSelection(X: integer): Boolean;
- begin
- Result := (FSelectStart >= 0) and (FSelectEnd >= 0) and
- (X >= (FSelectStart+BevelExtend)) and
- (X <= (FSelectEnd+BevelExtend)) and
- (X >= 0) and (X <= Width);
- end;
- var
- StartOrigin,Origin,
- MinShift,
- MaxShift: Longint;
- Moving : Boolean;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- var
- aRect: TRect;
- begin
- if not (csDesigning in ComponentState) and Enabled then
- begin
- if (Button = mbLeft) and FShowInfo then
- begin
- aRect.TopLeft := ClientToScreen(FClientRect.TopLeft);
- aRect.BottomRight := ClientToScreen(FClientRect.BottomRight);
- ClipCursor(@aRect);
- FShowInfoHint := True;
- { maybe there is a hint, hide it }
- if ShowHint then
- begin
- FOldShowHint := ShowHint;
- ShowHint := False;
- Application.CancelHint;
- Update;
- end
- else FOldShowHint := False;
- {$IFDEF WIN32}
- { we must save the screen in our bitmap }
- DIBCanvas.CopyRect(Rect(0,0,FWidth,FHeight),Canvas,FClientRect);
- {$ENDIF}
- DrawInfo(Point(X,Y));
- end
- else if (Button = mbRight) and FUseSelection and not FLocked and not FDrawing then
- begin
- aRect := BeveledRect;
- if PtInRect(aRect,Point(X,Y)) then
- begin
- FDrawing := True;
- Moving := False;
- MouseCapture := True;
- if IsSelectStart(X) then
- begin
- Origin := FSelectEnd;
- end
- else if IsSelectEnd(X) then
- begin
- Origin := FSelectStart;
- end
- else if IsInSelection(X) then
- begin
- Windows.SetCursor(Screen.Cursors[crsHand4]);
- Moving := True;
- Origin := X-BevelExtend;
- MinShift := -(FSelectStart);
- MaxShift := (FWidth-1)-FSelectEnd;
- end
- else
- begin
- Windows.SetCursor(Screen.Cursors[crSizeWE]);
- Origin := X-BevelExtend;
- { clear old selection }
- Selecting(-1,-1);
- Selecting(Origin,Origin+1);
- end;
- StartOrigin := Origin;
- end;
- end;
- end;
- inherited MouseDown(Button, Shift, X, Y);
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.MouseMove(Shift: TShiftState; X, Y: Integer);
- var
- NewPos,Diff: Longint;
- begin
- if FShowInfo and FShowInfoHint then
- begin
- inherited MouseMove(Shift, X, Y);
- DrawInfo(Point(X,Y));
- end
- else if FUseSelection and not FLocked and FDrawing then
- begin
- X := Limit(X,BevelExtend,(Width-BevelExtend)-1);
- if Moving then
- begin
- Diff := Limit((X-BevelExtend)-Origin,MinShift,MaxShift);
- Selecting(FSelectStart+Diff,FSelectEnd+Diff);
- Origin := Origin + Diff;
- MinShift := MinShift - Diff;
- MaxShift := MaxShift - Diff;
- end
- else
- begin
- NewPos := Limit(X-BevelExtend,0,Width-2*BevelExtend);
- Selecting(Origin,NewPos);
- end;
- inherited MouseMove(Shift, X, Y);
- end
- else if FUseSelection and not FLocked then
- begin
- inherited MouseMove(Shift, X, Y);
- if IsSelectStart(X) or IsSelectEnd(X) then
- Cursor := crSizeWE
- else if IsInSelection(X) then
- Cursor := crsHand3
- else if (Cursor=crSizeWE)or(Cursor=crsHand3)or(Cursor=crsZoom1) then
- Cursor := crDefault;
- end
- else
- begin
- inherited MouseMove(Shift, X, Y);
- if (Cursor <> crCross) and (Cursor <> crHourGlass) then
- Cursor := crDefault;
- end;
- end;
- {-- TMMOscope ------------------------------------------------------------}
- procedure TMMOscope.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if (Button = mbLeft) and FShowInfoHint then
- begin
- { restore background }
- if FEnabled then DrawInfo(Point(-1,-1));
- if (SaveDC <> 0) then
- begin
- SelectObject(SaveDC, OldBitmap);
- DeleteObject(SaveBitmap);
- SaveBitmap := 0;
- DeleteDC(SaveDC);
- SaveDC := 0;
- end;
- FShowInfoHint := False;
- ClipCursor(nil);
- ShowHint := FOldShowHint;
- end
- else if (Button = mbRight) and FDrawing then
- begin
- FDrawing := False;
- MouseCapture := False;
- if (FSelectEnd = FSelectStart+1) or (FSelectEnd = FSelectStart-1) then
- begin
- Selecting(-1,-1);
- end;
- SelectEnd(FSelectStart,FSelectEnd);
- end;
- inherited MouseUp(Button, Shift, X, Y);
- end;
- end.