123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- using SongVocalSectionAnalyser.Common.Collections;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Linq;
- using System.Windows.Forms;
- namespace SongVocalIsolateAutomation.UI
- {
- internal partial class WaveDubGraphic : UserControl
- {
- private WaveDub _waveDub;
- private bool _updateBitmap;
- private Bitmap _bufferedBitmap;
- private float _zoomRate = 1;
- private int _stageWidth, _stageHeight, _stageWidthSamples, _cursorX;
- public WaveDubGraphic()
- {
- InitializeComponent();
- }
- public void SetData(WaveDub waveDub)
- {
- _waveDub = waveDub;
- if (null != _waveDub)
- {
- BottomScrollBar.Maximum = _waveDub.Length;
- }
- ReDraw();
- }
- //----------------------------- Private method --------------------
- private void ReDraw()
- {
- _updateBitmap = true;
- GraphControl.Invalidate();
- }
- private void UpdateScaleData()
- {
- _stageWidth = GraphControl.Width;
- _stageHeight = GraphControl.Height;
- _stageWidthSamples = (int)(_stageWidth / _zoomRate) + 1;
- BottomScrollBar.LargeChange = _stageWidthSamples;
- }
- //----------------------------- EVT --------------------
- private void GraphControl_Resize(object sender, EventArgs e)
- {
- var old = _bufferedBitmap;
- _bufferedBitmap = new Bitmap(GraphControl.Width, GraphControl.Height, PixelFormat.Format32bppArgb);
- old?.Dispose();
- UpdateScaleData();
- ReDraw();
- }
- private void GraphControl_Paint(object sender, PaintEventArgs e)
- {
- e.Graphics.SetHighQuility();
- if (_updateBitmap)
- {
- try
- {
- Render();
- }
- catch (Exception exception)
- {
- e.Graphics.DrawString(exception.ToString(), Font, Brushes.Red, Point.Empty);
- }
- _updateBitmap = false;
- }
- e.Graphics.DrawImage(_bufferedBitmap, Point.Empty);
- }
- private void BottomScrollBar_Scroll(object sender, ScrollEventArgs e)
- {
- ReDraw();
- }
- private void TopScrollBar_Scroll(object sender, ScrollEventArgs e)
- {
- _waveDub.OffsetI = TopScrollBar.Value;
- ReDraw();
- }
- private void GraphControl_MouseMove(object sender, MouseEventArgs e)
- {
- _cursorX = e.X;
- ReDraw();
- }
- private void ScalePot_ValueChanged(object sender, EventArgs e)
- {
- _zoomRate = ScalePot.Value < 1
- ? (float)ScalePot.Value
- : (float)(1 + (ScalePot.Value - 1) * 20);
- UpdateScaleData();
- ReDraw();
- }
- private void Render()
- {
- var iColor = Color.FromArgb(224, Color.Red);
- var vColor = Color.FromArgb(224, Color.Blue);
- var cColor = Color.FromArgb(224, Color.Green);
- var wColor = Color.FromArgb(224, Color.Yellow);
- using (var vPen = new Pen(vColor))
- using (var iPen = new Pen(iColor))
- using (var cPen = new Pen(cColor, 2))
- using (var vBrush = new SolidBrush(vColor))
- using (var iBrush = new SolidBrush(iColor))
- using (var cBrush = new SolidBrush(cColor))
- using (var wBrush = new SolidBrush(wColor))
- using (var g = Graphics.FromImage(_bufferedBitmap))
- {
- g.SetHighQuility();
- g.Clear(Color.Transparent);
- var halfStageHeight = _stageHeight / 2.0f;
- //middle zero line
- g.FillRectangle(wBrush,
- 0, halfStageHeight - halfStageHeight * 0.2f,
- _stageWidth, halfStageHeight * 0.4f);
- g.DrawLine(Pens.Black,
- 0, halfStageHeight,
- _stageWidth, halfStageHeight);
- g.DrawLine(Pens.Black,
- _cursorX, 0,
- _cursorX, _stageHeight);
- if (null == _waveDub) return;
- var yRate = halfStageHeight;
- if (_zoomRate < 1)
- {
- //compact vertical line
- float iSampleIndex = BottomScrollBar.Value + _waveDub.OffsetI;
- float vSampleIndex = BottomScrollBar.Value;
- var pixelPerSample = 1 / _zoomRate;
- for (var x = 0; x < _stageWidth && vSampleIndex < _waveDub.SamplesV.Count; x++)
- {
- var skip = pixelPerSample * x;
- var vChunk = _waveDub.SamplesV.SkipFast((int)(vSampleIndex + skip)).Take((int)pixelPerSample).ToArray();
- if (0 == vChunk.Length) break;
- var vMin = vChunk.Min();
- var vMax = vChunk.Max();
- var xMidPoint = new PointF(x, halfStageHeight);
- var yPoint = new PointF(x, vMin * yRate + halfStageHeight);
- g.DrawLine(vPen, xMidPoint, yPoint);
- yPoint.Y = vMax * yRate + halfStageHeight;
- g.DrawLine(vPen, xMidPoint, yPoint);
- var iChunk = _waveDub.SamplesI.SkipFast((int)(vSampleIndex + skip)).Take((int)pixelPerSample).ToArray();
- if (0 != iChunk.Length)
- {
- var iMax = iChunk.Max();
- var iMin = iChunk.Min();
- yPoint.Y = iMin * yRate + halfStageHeight;
- g.DrawLine(iPen, xMidPoint, yPoint);
- yPoint.Y = iMax * yRate + halfStageHeight;
- g.DrawLine(iPen, xMidPoint, yPoint);
- var cChunk = vChunk.Zip(iChunk, (v, i) => v - i).ToArray();
- var cMax = cChunk.Max();
- var cMin = cChunk.Min();
- yPoint.Y = cMin * yRate + halfStageHeight;
- g.DrawLine(cPen, xMidPoint, yPoint);
- yPoint.Y = cMax * yRate + halfStageHeight;
- g.DrawLine(cPen, xMidPoint, yPoint);
- }
- vSampleIndex += pixelPerSample;
- iSampleIndex += pixelPerSample;
- }
- }
- else
- {
- var iPoints = new List<PointF>(_stageWidthSamples);
- var vPoints = new List<PointF>(_stageWidthSamples);
- var cPoints = new List<PointF>(_stageWidthSamples);
- var iSampleIndex = BottomScrollBar.Value + _waveDub.OffsetI;
- var vSampleIndex = BottomScrollBar.Value;
- for (var x = 0; x < _stageWidthSamples && vSampleIndex < _waveDub.SamplesV.Count; x++)
- {
- var vValue = _waveDub.SamplesV[vSampleIndex];
- var scaledX = x * _zoomRate;
- vPoints.Add(new PointF(scaledX, vValue * yRate + halfStageHeight));
- if (iSampleIndex >= 0 && iSampleIndex < _waveDub.SamplesI.Count)
- {
- var iValue = _waveDub.SamplesI[iSampleIndex];
- iPoints.Add(new PointF(scaledX, iValue * yRate + halfStageHeight));
- var cValue = vValue - iValue;
- cPoints.Add(new PointF(scaledX, cValue * yRate + halfStageHeight));
- }
- vSampleIndex++;
- iSampleIndex++;
- }
- if (vPoints.Count > 1) g.DrawLines(vPen, vPoints.ToArray());
- if (iPoints.Count > 1) g.DrawLines(iPen, iPoints.ToArray());
- if (cPoints.Count > 1) g.DrawLines(cPen, cPoints.ToArray());
- if (_zoomRate >= 10)
- {
- var dotRc = new RectangleF(0, 0, 6, 6);
- //show point in sample
- foreach (var vPoint in vPoints)
- {
- dotRc.Location = vPoint;
- dotRc.Offset(-3, -3);
- g.FillEllipse(vBrush, dotRc);
- }
- foreach (var iPoint in iPoints)
- {
- dotRc.Location = iPoint;
- dotRc.Offset(-3, -3);
- g.FillEllipse(iBrush, dotRc);
- }
- foreach (var cPoint in cPoints)
- {
- dotRc.Location = cPoint;
- dotRc.Offset(-3, -3);
- g.FillEllipse(cBrush, dotRc);
- }
- }
- }
- }
- }
- }
- }
|