SDRSharper/SDRSharper.PanView/SDRSharp.PanView/Scope.cs

1318 lines
32 KiB
C#
Raw Normal View History

using SDRSharp.Radio;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace SDRSharp.PanView
{
public class Scope : UserControl
{
public delegate void delPositionChanged(object sender, PositionEventArgs e);
private const int GradientAlpha = 180;
private const int AxisMargin = 5;
private const int LabelMargin = 16;
private const int TicksMargin = 5;
private const int BarSize = 10;
private const float TimeConst = 0.001f;
private const float Amplification = 100f;
private int _carrierAvg = 2000;
private float _audioRel = 5E-07f;
private bool _showLines;
private int _audioAvg = 25;
private int _peakDelay = 20;
private float _peakRel = 0.01f;
private int _scopeHeight;
private int _barsHeight;
private bool _showBars;
private int _yNeg;
private int _yPos;
private Bitmap _bkgBuffer;
private Bitmap _buffer;
private Graphics _graphics;
private Point[] _points;
private Point[] _upper;
private Point[] _lower;
private int _uppIdx;
private int _lowIdx;
private bool _performNeeded;
private bool _drawBackgroundNeeded;
private int _oldX;
private int _oldY;
private float _oldHshift;
private float _oldVshift;
private DcRemover _dcRemover1 = new DcRemover(0.001f);
private DcRemover _dcRemover2 = new DcRemover(0.001f);
private float[] _vBuf;
private float[] _hBuf;
private DemodType _vChannel;
private DemodType _hChannel;
private float _hShift;
private float _vShift;
private float _vDiv;
private float _hDiv;
private float _tDiv;
private bool _hInvert;
private bool _vInvert;
private bool _hBlockDC;
private bool _vBlockDC;
private bool _xyMode;
private float _trigLevel;
private bool _trigChange;
private float _average;
private float _neg;
private float _pos;
private float[] _avgBuf;
private float[] _negBuf;
private float[] _posBuf;
private int _posTmo;
private int _negTmo;
private float _posPeak;
private float _negPeak;
private float _posAver;
private float _negAver;
private int _timeOut;
private string _statusText;
private static Pen _gridPen = new Pen(Color.FromArgb(100, 100, 100));
private static Pen _axisPen = new Pen(Color.FromArgb(100, 100, 250));
private static Pen _carrierPen = new Pen(Color.Red);
private static Pen _audioPen = new Pen(Color.Yellow);
private static Brush _audioBrush = new SolidBrush(Color.FromArgb(225, Color.LightGreen));
private static Brush _clippingBrush = new SolidBrush(Color.FromArgb(205, Color.Red));
private static Brush _overmodBrush = new SolidBrush(Color.FromArgb(190, Color.Yellow));
private static Pen _PeakPen = new Pen(Color.Red, 3f);
private static Pen _AverPen = new Pen(Color.Yellow, 3f);
private static Pen _tracePen = new Pen(Color.White);
private static Font _font = new Font("Arial", 7f);
private static Font _statusFont = new Font("Lucida Console", 9f);
private static ColorBlend _gradientColorBlend;
private static int[] _gradientPixels = new int[255];
private Rectangle _clipRectangle;
private LinearGradientBrush _gradientBrush;
private static int _spectrumFill;
private static Color _traceColor;
private static Color _backgroundColor;
private PathGradientBrush _backgroundBrush;
public int CarrierAvg
{
get
{
return this.log((float)this._carrierAvg / 2000f);
}
set
{
this._carrierAvg = (int)(this.pow(value) * 2000f);
}
}
public int AudioRel
{
get
{
return this.log(this._audioRel / 5E-07f);
}
set
{
this._audioRel = this.pow(value) * 5E-07f;
}
}
public int AudioAvg
{
get
{
return this.log((float)this._audioAvg / 25f);
}
set
{
this._audioAvg = (int)(this.pow(value) * 25f);
}
}
public int PeakDelay
{
get
{
return this.log((float)this._peakDelay / 20f);
}
set
{
this._peakDelay = (int)(this.pow(value) * 20f);
}
}
public int PeakRel
{
get
{
return this.log(this._peakRel / 0.01f);
}
set
{
this._peakRel = this.pow(value) * 0.01f;
}
}
public float Vdiv
{
get
{
return this._vDiv;
}
set
{
this._vDiv = value;
}
}
public float Hdiv
{
get
{
return this._hDiv;
}
set
{
this._hDiv = value;
}
}
public float Tdiv
{
get
{
return this._tDiv;
}
set
{
this._tDiv = value;
}
}
public float Vshift
{
get
{
return this._vShift;
}
set
{
this._vShift = value;
this._drawBackgroundNeeded = true;
}
}
public float Hshift
{
get
{
return this._hShift;
}
set
{
this._hShift = value;
}
}
public bool Vinvert
{
get
{
return this._vInvert;
}
set
{
this._vInvert = value;
}
}
public bool Hinvert
{
get
{
return this._hInvert;
}
set
{
this._hInvert = value;
}
}
public bool HblockDC
{
get
{
return this._hBlockDC;
}
set
{
this._hBlockDC = value;
}
}
public bool VblockDC
{
get
{
return this._vBlockDC;
}
set
{
this._vBlockDC = value;
}
}
public bool XYmode
{
get
{
return this._xyMode;
}
set
{
this._xyMode = value;
this._drawBackgroundNeeded = true;
}
}
public DemodType Vchannel
{
get
{
return this._vChannel;
}
set
{
this._vChannel = value;
this._drawBackgroundNeeded = true;
}
}
public DemodType Hchannel
{
get
{
return this._hChannel;
}
set
{
this._hChannel = value;
}
}
public float TrigLevel
{
get
{
return this._trigLevel;
}
set
{
this._trigLevel = value;
this._drawBackgroundNeeded = true;
}
}
public bool ShowLines
{
get
{
return this._showLines;
}
set
{
this._showLines = value;
}
}
public bool ShowBars
{
get
{
return this._showBars;
}
set
{
this._showBars = value;
}
}
public int SpectrumFill
{
get
{
return Scope._spectrumFill;
}
set
{
Scope._spectrumFill = value;
}
}
public Color BackgoundColor
{
get
{
return Scope._backgroundColor;
}
set
{
this.newBackgroundBrush(value);
}
}
public string StatusText
{
get
{
return this._statusText;
}
set
{
this._statusText = value;
this._performNeeded = true;
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ColorBlend GradientColorBlend
{
get
{
return Scope._gradientColorBlend;
}
set
{
this.newGradientBrush(value);
}
}
public Color TraceColor
{
get
{
return Scope._traceColor;
}
set
{
if (!(Scope._traceColor == value))
{
Scope._traceColor = value;
Scope._tracePen.Dispose();
Scope._tracePen = new Pen(Scope._traceColor);
}
}
}
public event delPositionChanged XYPositionChanged;
public Scope()
{
this._bkgBuffer = new Bitmap(base.ClientRectangle.Width, base.ClientRectangle.Height, PixelFormat.Format32bppPArgb);
this._buffer = new Bitmap(base.ClientRectangle.Width, base.ClientRectangle.Height, PixelFormat.Format32bppPArgb);
this._graphics = Graphics.FromImage(this._buffer);
base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
base.SetStyle(ControlStyles.DoubleBuffer, true);
base.SetStyle(ControlStyles.UserPaint, true);
base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
base.UpdateStyles();
Scope._audioPen.DashStyle = DashStyle.Dot;
Scope._carrierPen.DashStyle = DashStyle.Dot;
Scope._audioPen.DashStyle = DashStyle.Dot;
Scope._gridPen.DashStyle = DashStyle.Dot;
Scope._axisPen.DashStyle = DashStyle.Dash;
}
~Scope()
{
this._buffer.Dispose();
this._graphics.Dispose();
this._gradientBrush.Dispose();
this._backgroundBrush.Dispose();
}
public void Reset()
{
this._neg = 0f;
this._pos = 0f;
}
private void fillGradientVector(ColorBlend blend, int size)
{
if (blend != null)
{
int num = 4;
Bitmap bitmap = new Bitmap(num, size, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, size), Color.Black, Color.White);
linearGradientBrush.InterpolationColors = blend;
graphics.FillRectangle(linearGradientBrush, new Rectangle(0, 0, num, size));
int num2 = 255;
for (int i = 0; i < size; i++)
{
if (i < size / 20)
{
Scope._gradientPixels[i] = Color.White.ToArgb();
}
else
{
num2 = 255 - i * 60 / size;
Color color = Color.FromArgb(num2, bitmap.GetPixel(num / 2, i));
Scope._gradientPixels[i] = color.ToArgb();
}
}
graphics.Dispose();
bitmap.Dispose();
}
}
public void Perform(bool hideTrace = false)
{
if (this._drawBackgroundNeeded)
{
this.DrawBackground();
}
if (this._performNeeded || this._drawBackgroundNeeded)
{
this.DrawForeground(hideTrace);
this.DrawStatusText();
base.Invalidate();
}
this._performNeeded = false;
this._drawBackgroundNeeded = false;
}
public unsafe void Render(float* xBuf, float* yBuf, int length, int latency, int timeOut)
{
this._timeOut = Math.Min(this._timeOut, timeOut);
if (--this._timeOut <= 0 && yBuf != null)
{
this._timeOut = timeOut;
float num = (float)latency / 1000f;
num = this._tDiv * 10f / num;
int num2 = Math.Min(length, (int)(num * (float)length));
int num3 = Math.Min(length, base.ClientRectangle.Width - 10);
float factor = (float)num2 / (float)num3;
int num4 = 0;
float[] vBuf = this._vBuf;
fixed (float* ptr = vBuf)
{
bool flag = (double)this._trigLevel < 0.45 && (double)this._trigLevel > -0.45;
if (flag)
{
if (this._vBlockDC)
{
this._dcRemover1.Process(yBuf, length);
}
num4 = this.TriggerPoint(yBuf, num2);
}
Fourier.SubCopy(yBuf + num4, ptr, length - num4, num3, factor);
if (!flag && this._vBlockDC)
{
this._dcRemover1.Process(ptr, num3);
}
}
if (this._xyMode)
{
float[] hBuf = this._hBuf;
fixed (float* ptr2 = hBuf)
{
Fourier.SubCopy(xBuf + num4, ptr2, length - num4, num3, factor);
if (this._hBlockDC)
{
this._dcRemover2.Process(ptr2, num3);
}
}
}
this._performNeeded = true;
}
}
private unsafe int TriggerPoint(float* buf, int len)
{
float num = (this._trigLevel - this._vShift) * 0.8f * this._vDiv / 100f;
for (int i = 1; i < len - 1; i++)
{
if (buf[i] >= num && buf[i - 1] < num)
{
return i;
}
}
return 0;
}
private void DrawBackground()
{
if (Scope._gradientColorBlend != null)
{
float num10 = this._average * 100f / (this._vDiv * 0.8f);
using (Graphics graphics = Graphics.FromImage(this._bkgBuffer))
{
Scope.ConfigureGraphics(graphics);
graphics.Clear(Color.FromArgb(40, 40, 40));
graphics.FillRectangle(this._backgroundBrush, 0, 0, base.ClientRectangle.Width, this._scopeHeight);
int num = this._scopeHeight - 10;
float num2 = (float)num / 8f;
float num3 = (float)(base.ClientRectangle.Width - 10) / 10f;
float num4 = (!this._vBlockDC) ? (this._vShift * (float)num) : 0f;
for (int i = -8; i < 17; i++)
{
float num5 = 5f + (float)i * num2 - num4;
if (num5 < (float)this._scopeHeight)
{
graphics.DrawLine(Scope._gridPen, 5f, num5, (float)(base.ClientRectangle.Width - 5), num5);
}
}
for (int j = 0; j < 11; j++)
{
float num6 = 5f + (float)j * num3;
graphics.DrawLine(Scope._gridPen, num6, 5f, num6, (float)(this._scopeHeight - 5));
}
graphics.DrawLine(Scope._axisPen, base.ClientRectangle.Width / 2, 5, base.ClientRectangle.Width / 2, this._scopeHeight - 5);
float num7 = (float)(this._scopeHeight / 2) - num4;
if (num7 < (float)this._scopeHeight)
{
graphics.DrawLine(Scope._axisPen, 5f, num7, (float)(base.ClientRectangle.Width - 5), num7);
}
num7 = (float)(this._scopeHeight / 2) - this._trigLevel * (float)num;
if (!this.XYmode)
{
graphics.DrawLine(Pens.Yellow, 0f, num7 + 2f, 2f, num7);
graphics.DrawLine(Pens.Yellow, 0f, num7 - 2f, 2f, num7);
}
if (this._showBars)
{
using (Pen pen = new Pen(this.BackColor, 3f))
{
graphics.DrawLine(pen, 0, this._scopeHeight, base.ClientRectangle.Width, this._scopeHeight);
}
int num8 = base.ClientRectangle.Width - 10;
num = this._scopeHeight - 10;
num3 = (float)num8 / 15f;
this._yNeg = base.ClientRectangle.Height - 16;
this._yPos = this._yNeg - 16 - 5 - 10;
graphics.DrawLine(Scope._axisPen, 5f, (float)this._yPos, 5f + num3 * 15f, (float)this._yPos);
graphics.DrawLine(Scope._axisPen, 5f, (float)this._yNeg, 5f + num3 * 10f, (float)this._yNeg);
for (int k = 0; k < 15; k++)
{
int num9 = (int)(5f + num3 * (float)k);
graphics.DrawLine(Scope._axisPen, num9, this._yPos, num9, this._yPos - 3);
if (k == 0)
{
graphics.DrawString("0", Scope._font, Brushes.LightGray, (float)num9, (float)(this._yPos + 1));
}
else if (k % 2 == 0)
{
graphics.DrawString((k * 10).ToString(), Scope._font, Brushes.LightGray, (float)((k < 10) ? (num9 - 6) : (num9 - 9)), (float)(this._yPos + 1));
}
if (k < 11)
{
graphics.DrawLine(Scope._axisPen, num9, this._yNeg, num9, this._yNeg - 3);
if (k == 0)
{
graphics.DrawString("0", Scope._font, Brushes.LightGray, (float)num9, (float)(this._yNeg + 1));
}
else if (k % 2 == 0)
{
graphics.DrawString((k * 10).ToString(), Scope._font, Brushes.LightGray, (float)((k < 10) ? (num9 - 6) : (num9 - 9)), (float)(this._yNeg + 1));
}
}
}
}
}
}
}
private void DrawTrace()
{
int num;
int num2;
float num4;
bool flag;
int num13;
int num14;
Point[] array;
Point[] array2;
if (this._vBuf != null && this._vBuf.Length != 0)
{
if (this._hDiv == 0f)
{
this._hDiv = 1f;
}
if (this._vDiv == 0f)
{
this._vDiv = 1f;
}
num = base.ClientRectangle.Width - 10;
num2 = this._scopeHeight - 10;
float num3 = this.XYmode ? ((float)num / this._hDiv * 100f) : ((float)(num / this._vBuf.Length));
num4 = (float)num2 / this._vDiv * 100f * 1.25f;
int num5 = 0;
int num6 = 0;
float num7 = 0f;
float num8 = 0f;
for (int i = 0; i < this._hBuf.Length; i++)
{
if (!this._xyMode)
{
num8 = (float)(-num / 2) + (float)i * num3;
num7 = this._vBuf[i];
}
else if (this.Vchannel == DemodType.AM && this.Hchannel == DemodType.PM)
{
float num9 = this._vBuf[i];
float num10 = this._hBuf[i] * 500000f;
num8 = (float)((double)num9 * Math.Sin((double)num10));
num7 = (float)((double)num9 * Math.Cos((double)num10));
}
else
{
num8 = this._hBuf[i];
num7 = this._vBuf[i];
}
if (this._hInvert)
{
num8 = 0f - num8;
}
if (this._vInvert)
{
num7 = 0f - num7;
}
num5 = (int)((float)(5 + num / 2) + num8 * num3);
num6 = (int)((float)(this._scopeHeight - 5 - num2 / 2) - num7 * num4);
this._points[i + 1].X = num5 + (int)((float)num * this.Hshift);
this._points[i + 1].Y = num6 - (int)((float)num2 * this.Vshift);
}
this._points[0] = this._points[1];
this._points[this._points.Length - 1] = this._points[this._points.Length - 2];
this._graphics.SetClip(this._clipRectangle);
flag = false;
flag = (this._vChannel == DemodType.Envelope && !this._xyMode);
if (flag)
{
int num11 = 0;
int num12 = this._scopeHeight - (int)((float)(2 * num2) * this.Vshift);
num13 = this._scopeHeight / 2 - (int)((float)num2 * this.Vshift);
this._lowIdx = (this._uppIdx = 0);
this.addUpper(0, num13);
this.addLower(0, num13);
num14 = 10;
for (int j = 0; j < this._points.Length - 1; j++)
{
if (this._points[j + 1].Y > this._points[j].Y)
{
if (num11 <= 0)
{
num11 = 1;
if (this._points[j].Y <= num13)
{
this.addUpper(this._points[j].X, this._points[j].Y);
this.addLower(this._points[j].X, num12 - this._points[j].Y);
if (Math.Abs(this._points[j].Y - num13) > num14)
{
num14 = Math.Abs(this._points[j].Y - num13);
}
}
}
}
else if (this._points[j + 1].Y < this._points[j].Y && num11 >= 0)
{
num11 = -1;
if (this._points[j].Y >= num13)
{
this.addLower(this._points[j].X, this._points[j].Y);
this.addUpper(this._points[j].X, num12 - this._points[j].Y);
if (Math.Abs(this._points[j].Y - num13) > num14)
{
num14 = Math.Abs(this._points[j].Y - num13);
}
}
}
}
num14 = (int)((float)num14 * 1.1f);
if (this._uppIdx > 1 && this._lowIdx > 1)
{
this._upper[0].X = this._upper[1].X;
this._upper[0].Y = num13;
this._lower[0].X = this._lower[1].X;
this._lower[0].Y = num13;
this.addUpper(this._upper[this._uppIdx - 1].X, num13);
this.addLower(this._lower[this._lowIdx - 1].X, num13);
array = new Point[this._uppIdx];
array2 = new Point[this._lowIdx];
Array.Copy(this._upper, array, this._uppIdx);
Array.Copy(this._lower, array2, this._lowIdx);
if (Scope._spectrumFill == 1)
{
this._graphics.FillPolygon(this._gradientBrush, array);
this._graphics.FillPolygon(this._gradientBrush, array2);
goto IL_0700;
}
if (Scope._gradientColorBlend != null)
{
num14 = Math.Min(num14 * 2, base.ClientRectangle.Height);
for (int k = 2; k < this._uppIdx - 1; k++)
{
int x = this._upper[k - 1].X;
int y = this._upper[k - 1].Y;
int x2 = this._upper[k].X;
int y2 = this._upper[k].Y;
for (int l = x; l < x2; l++)
{
int num15 = (int)((float)y + (float)(l - x) / (float)(x2 - x) * (float)(y2 - y));
int num16 = 2 * Math.Abs(num15 - num13);
int val = (int)((float)num16 / (float)num14 * 255f);
Color color = Color.FromArgb(Scope._gradientPixels[Math.Min(val, 255)]);
if (num16 > num14 / 40)
{
this._graphics.DrawLine(new Pen(color), l, num13 + num16 / 2, l, num13 - num16 / 2);
}
}
}
goto IL_0700;
}
return;
}
}
goto IL_086e;
}
return;
IL_0700:
array[0].Y = array[1].Y;
array[this._uppIdx - 1] = array[this._uppIdx - 2];
array2[0].Y = array2[1].Y;
array2[this._lowIdx - 1] = array2[this._lowIdx - 2];
this._graphics.DrawLines(new Pen(this.TraceColor), array);
this._graphics.DrawLines(new Pen(this.TraceColor), array2);
for (int m = 2; m < this._uppIdx - 1; m++)
{
if (num13 - this._upper[m].Y < num14 / 40)
{
this._graphics.FillEllipse(Brushes.Red, this._upper[m].X - 3, num13 - 3, 6, 6);
}
}
for (int n = 2; n < this._lowIdx - 2; n++)
{
if (this._lower[n].Y - num13 < num14 / 40)
{
this._graphics.FillEllipse(Brushes.Red, this._lower[n].X - 3, num13 - 3, 6, 6);
}
}
goto IL_086e;
IL_086e:
if (!flag)
{
this._graphics.DrawLines(Scope._tracePen, this._points);
}
if (this._vChannel != DemodType.AM && this._vChannel != DemodType.Envelope)
{
return;
}
this.getAudioLevels();
if (this._showLines)
{
int num5 = (int)(5f + (float)num * this.Hshift);
int num6 = (int)((float)(this._scopeHeight - 5 - num2 / 2) + (this._vInvert ? this._average : (0f - this._average)) * num4 - (float)num2 * this._vShift);
if (this._vChannel != DemodType.Envelope)
{
this._graphics.DrawLine(Scope._carrierPen, num5, num6, num5 + num, num6);
}
num6 = (int)((float)(this._scopeHeight - 5 - num2 / 2) + (this._vInvert ? this._pos : (0f - this._pos)) * num4 - (float)num2 * this._vShift);
this._graphics.DrawLine(Scope._audioPen, num5, num6, num5 + num, num6);
num6 = (int)((float)(this._scopeHeight - 5 - num2 / 2) + (this._vInvert ? this._neg : (0f - this._neg)) * num4 - (float)num2 * this._vShift);
this._graphics.DrawLine(Scope._audioPen, num5, num6, num5 + num, num6);
if (this._showBars && !this.VblockDC)
{
this.drawBars();
}
}
}
private void addLower(int x, int y)
{
this._lower[this._lowIdx].X = x;
this._lower[this._lowIdx++].Y = y;
}
private void addUpper(int x, int y)
{
this._upper[this._uppIdx].X = x;
this._upper[this._uppIdx++].Y = y;
}
private void getAudioLevels()
{
if (this._vChannel == DemodType.AM)
{
int num = this._carrierAvg - 1;
for (int i = 0; i < this._vBuf.Length; i++)
{
this._average = ((float)num * this._average + this._vBuf[i]) / (float)this._carrierAvg;
this._avgBuf[i] = this._average;
if (this._vBuf[i] > this._pos)
{
if (this.VblockDC || (double)this._vBuf[i] < (double)this._average + 1.5 * (double)(this._average - this._neg))
{
this._pos = this._vBuf[i];
}
}
else if (!this.VblockDC && this._pos > 4f * this._average)
{
this._pos = 3.9f * this._average;
}
else if (this._pos > this._average)
{
this._pos -= this._audioRel * this._vDiv;
}
if (this._vBuf[i] < this._neg)
{
if (this.VblockDC || this._vBuf[i] > 0f)
{
this._neg = this._vBuf[i];
}
}
else if (this._neg < this._average)
{
this._neg += this._audioRel * this._vDiv;
}
}
}
else if (this._vChannel == DemodType.Envelope)
{
float num2 = this._audioRel * 1000f / (float)this._vBuf.Length;
for (int j = 2; j < this._vBuf.Length - 2; j++)
{
if (this._vBuf[j] > this._pos)
{
this._pos = this._vBuf[j];
}
else
{
this._pos -= num2 / 30f * this._vDiv;
}
if (this._vBuf[j] < this._neg)
{
this._neg = this._vBuf[j];
}
else
{
this._neg += num2 / 30f * this._vDiv;
}
}
}
}
private void drawBars()
{
if (this._vChannel == DemodType.AM && this._average != 0f)
{
int num = this._audioAvg - 1;
this._graphics.SetClip(new Rectangle(0, this._scopeHeight, base.ClientRectangle.Width, this._barsHeight));
float num2 = (float)(base.ClientRectangle.Width - 10) / 15f;
int num3 = 0;
int num4 = this._yPos - 5 - 10;
int num5 = this._yNeg - 5 - 10;
float num6 = Math.Min(1.45f, (this._pos - this._average) / this._average);
if ((double)num6 < 1.0)
{
this._graphics.FillRectangle(Scope._audioBrush, 5f, (float)num4, num6 * num2 * 10f, 10f);
}
else
{
this._graphics.FillRectangle(Scope._overmodBrush, 5f, (float)num4, num6 * num2 * 10f, 10f);
}
this._posAver = Math.Max(0f, ((float)num * this._posAver + num6) / (float)this._audioAvg);
if (num6 > this._posPeak)
{
this._posPeak = num6;
this._posTmo = this._peakDelay;
}
else if (this._posTmo > 0)
{
this._posTmo--;
}
else if (this._posPeak > this._posAver)
{
this._posPeak -= this._peakRel;
}
num3 = (int)(5f + this._posAver * num2 * 10f);
this._graphics.DrawLine(Scope._AverPen, num3, num4, num3, num4 + 10);
num3 = (int)(5f + this._posPeak * num2 * 10f);
this._graphics.DrawLine(Scope._PeakPen, num3, num4, num3, num4 + 10);
float num7 = Math.Min(1.01f, (this._average - this._neg) / this._average);
if ((double)num7 < 0.97)
{
this._graphics.FillRectangle(Scope._audioBrush, 5f, (float)num5, num7 * num2 * 10f, 10f);
}
else
{
this._graphics.FillRectangle(Scope._clippingBrush, 5f, (float)num5, num7 * num2 * 10f, 10f);
}
this._negAver = Math.Max(0f, ((float)num * this._negAver + num7) / (float)this._audioAvg);
if (num7 > this._negPeak)
{
this._negPeak = num7;
this._negTmo = this._peakDelay;
}
else if (this._negTmo > 0)
{
this._negTmo--;
}
else if (this._negPeak > this._negAver)
{
this._negPeak -= this._peakRel;
}
num3 = (int)(5f + this._negAver * num2 * 10f);
this._graphics.DrawLine(Scope._AverPen, num3, num5, num3, num5 + 10);
num3 = (int)(5f + this._negPeak * num2 * 10f);
this._graphics.DrawLine(Scope._PeakPen, num3, num5, num3, num5 + 10);
}
}
private void DrawStatusText()
{
if (!string.IsNullOrEmpty(this._statusText))
{
this._graphics.DrawString(this._statusText, Scope._statusFont, Brushes.Silver, 7f, 7f);
}
}
private static void ConfigureGraphics(Graphics graphics)
{
graphics.CompositingMode = CompositingMode.SourceOver;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.SmoothingMode = SmoothingMode.None;
graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
graphics.InterpolationMode = InterpolationMode.High;
}
private void DrawForeground(bool hideTrace)
{
if (base.ClientRectangle.Width > 5 && base.ClientRectangle.Height > 5)
{
this.CopyBackground();
this.DrawTrace();
}
}
private unsafe void CopyBackground()
{
BitmapData bitmapData = this._buffer.LockBits(base.ClientRectangle, ImageLockMode.WriteOnly, this._buffer.PixelFormat);
BitmapData bitmapData2 = this._bkgBuffer.LockBits(base.ClientRectangle, ImageLockMode.ReadOnly, this._bkgBuffer.PixelFormat);
Utils.Memcpy((void*)bitmapData.Scan0, (void*)bitmapData2.Scan0, Math.Abs(bitmapData.Stride) * bitmapData.Height);
this._buffer.UnlockBits(bitmapData);
this._bkgBuffer.UnlockBits(bitmapData2);
}
protected override void OnPaint(PaintEventArgs e)
{
Scope.ConfigureGraphics(e.Graphics);
e.Graphics.DrawImageUnscaled(this._buffer, 0, 0);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (base.ClientRectangle.Width > 0 && base.ClientRectangle.Height > 0)
{
this._buffer.Dispose();
this._graphics.Dispose();
this._bkgBuffer.Dispose();
this._bkgBuffer = new Bitmap(base.ClientRectangle.Width, base.ClientRectangle.Height, PixelFormat.Format32bppPArgb);
this._buffer = new Bitmap(base.ClientRectangle.Width, base.ClientRectangle.Height, PixelFormat.Format32bppPArgb);
this._graphics = Graphics.FromImage(this._buffer);
Scope.ConfigureGraphics(this._graphics);
if (!this._showBars)
{
this._barsHeight = 0;
}
else
{
this._barsHeight = 62;
}
if (!this._showBars)
{
this._scopeHeight = base.ClientRectangle.Height;
}
else
{
this._scopeHeight = base.ClientRectangle.Height - this._barsHeight - 5 - 3;
}
int num = base.ClientRectangle.Width - 10;
this._hBuf = new float[num];
this._points = new Point[num + 2];
this._upper = new Point[num + 2];
this._lower = new Point[num + 2];
this._vBuf = new float[num];
this._avgBuf = new float[num];
this._negBuf = new float[num];
this._posBuf = new float[num];
if (this._gradientBrush != null)
{
this._gradientBrush.Dispose();
}
this.newGradientBrush(null);
this._clipRectangle = new Rectangle(0, 0, base.ClientRectangle.Width, this._scopeHeight);
this.newBackgroundBrush(null);
this._drawBackgroundNeeded = true;
this.Perform(false);
if (Scope._gradientPixels != null && Scope._gradientPixels.Length >= base.ClientRectangle.Height)
{
return;
}
Scope._gradientPixels = null;
Scope._gradientPixels = new int[base.ClientRectangle.Height];
}
}
private void newGradientBrush(ColorBlend blend = null)
{
int y = (int)((float)(this._scopeHeight / 2) - this._vShift * (float)this._scopeHeight);
this._gradientBrush = new LinearGradientBrush(new Rectangle(0, y, base.ClientRectangle.Width, this._scopeHeight / 2), Color.White, Color.Black, LinearGradientMode.Vertical);
if (blend != null)
{
if (Scope._gradientColorBlend == null)
{
Scope._gradientColorBlend = new ColorBlend(2);
}
Scope._gradientColorBlend.Positions[0] = 0f;
Scope._gradientColorBlend.Positions[1] = 1f;
int num = blend.Colors.Length - 1;
if (Scope._spectrumFill == 1)
{
Scope._gradientColorBlend.Colors[0] = Color.FromArgb(180, blend.Colors[num]);
Scope._gradientColorBlend.Colors[1] = Color.FromArgb(180, blend.Colors[0]);
}
else if (Scope._spectrumFill == 2)
{
Scope._gradientColorBlend.Colors[0] = blend.Colors[0];
Math.Max(blend.Colors[num].R, Math.Max(blend.Colors[num].G, blend.Colors[num].B));
Scope._gradientColorBlend.Colors[1] = blend.Colors[num];
}
else
{
Scope._gradientColorBlend.Colors[0] = Scope._traceColor;
Scope._gradientColorBlend.Colors[1] = Scope._backgroundColor;
}
}
else if (Scope._gradientColorBlend == null)
{
return;
}
this._gradientBrush.InterpolationColors = Scope._gradientColorBlend;
this._gradientBrush.WrapMode = WrapMode.TileFlipX;
if (Scope._spectrumFill > 1)
{
this.fillGradientVector(Scope._gradientColorBlend, 255);
}
}
private void newBackgroundBrush(Color? color = default(Color?))
{
if (color.HasValue)
{
Scope._backgroundColor = color.Value;
}
if (this._backgroundBrush != null)
{
this._backgroundBrush.Dispose();
}
this._backgroundBrush = Utils.BackgroundBrush(base.Name, Scope._backgroundColor, base.ClientRectangle.Width, this._scopeHeight, false, false);
this._drawBackgroundNeeded = true;
}
protected override void OnPaintBackground(PaintEventArgs e)
{
}
private void InitializeComponent()
{
base.SuspendLayout();
this.BackColor = SystemColors.Control;
base.Name = "Scope";
base.ResumeLayout(false);
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.Cursor = Cursors.Hand;
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.Cursor = Cursors.Default;
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this._oldHshift = this._hShift;
this._oldVshift = this._vShift;
this._oldX = e.X;
this._oldY = e.Y;
if (this.Cursor == Cursors.SizeNS)
{
this._trigChange = true;
}
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (this._trigChange)
{
this._trigChange = false;
this.Cursor = Cursors.Hand;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
float num = -1f;
if (this._trigChange || (e.X < 10 && !this._xyMode))
{
num = -1f * (float)(e.Y - 5) / (float)(this._scopeHeight - 10) + 0.5f;
}
this.Cursor = (((double)Math.Abs(num - this._trigLevel) < 0.1) ? Cursors.SizeNS : Cursors.Hand);
if (e.Button == MouseButtons.Left)
{
if (this._trigChange)
{
PositionEventArgs positionEventArgs = new PositionEventArgs(0f, -1f * (float)(e.Y - 5) / (float)(this._scopeHeight - 10) + 0.5f, true);
this._trigLevel = positionEventArgs.Ypos;
this._drawBackgroundNeeded = true;
if (this.XYPositionChanged != null)
{
this.XYPositionChanged(this, positionEventArgs);
}
}
else
{
this._vShift = this._oldVshift + (float)(this._oldY - e.Y) / (float)(this._scopeHeight - 10);
this._hShift = this._oldHshift - (float)(this._oldX - e.X) / (float)(base.ClientRectangle.Width - 10);
if ((double)this._vShift > 1.0)
{
this._vShift = 1f;
}
if ((double)this._vShift < -1.0)
{
this._vShift = -1f;
}
if ((double)this._hShift > 1.0)
{
this._hShift = 1f;
}
if ((double)this._hShift < -1.0)
{
this._hShift = -1f;
}
this.newGradientBrush(null);
this._drawBackgroundNeeded = true;
}
}
}
private float pow(int factor)
{
return (float)Math.Pow(10.0, (double)factor / 10.0);
}
private int log(float value)
{
return (int)(Math.Log10((double)value) * 10.0);
}
}
}