WaveDubGraphic.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using SongVocalSectionAnalyser.Common.Collections;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.Linq;
  7. using System.Windows.Forms;
  8. namespace SongVocalIsolateAutomation.UI
  9. {
  10. internal partial class WaveDubGraphic : UserControl
  11. {
  12. private WaveDub _waveDub;
  13. private bool _updateBitmap;
  14. private Bitmap _bufferedBitmap;
  15. private float _zoomRate = 1;
  16. private int _stageWidth, _stageHeight, _stageWidthSamples, _cursorX;
  17. public WaveDubGraphic()
  18. {
  19. InitializeComponent();
  20. }
  21. public void SetData(WaveDub waveDub)
  22. {
  23. _waveDub = waveDub;
  24. if (null != _waveDub)
  25. {
  26. BottomScrollBar.Maximum = _waveDub.Length;
  27. }
  28. ReDraw();
  29. }
  30. //----------------------------- Private method --------------------
  31. private void ReDraw()
  32. {
  33. _updateBitmap = true;
  34. GraphControl.Invalidate();
  35. }
  36. private void UpdateScaleData()
  37. {
  38. _stageWidth = GraphControl.Width;
  39. _stageHeight = GraphControl.Height;
  40. _stageWidthSamples = (int)(_stageWidth / _zoomRate) + 1;
  41. BottomScrollBar.LargeChange = _stageWidthSamples;
  42. }
  43. //----------------------------- EVT --------------------
  44. private void GraphControl_Resize(object sender, EventArgs e)
  45. {
  46. var old = _bufferedBitmap;
  47. _bufferedBitmap = new Bitmap(GraphControl.Width, GraphControl.Height, PixelFormat.Format32bppArgb);
  48. old?.Dispose();
  49. UpdateScaleData();
  50. ReDraw();
  51. }
  52. private void GraphControl_Paint(object sender, PaintEventArgs e)
  53. {
  54. e.Graphics.SetHighQuility();
  55. if (_updateBitmap)
  56. {
  57. try
  58. {
  59. Render();
  60. }
  61. catch (Exception exception)
  62. {
  63. e.Graphics.DrawString(exception.ToString(), Font, Brushes.Red, Point.Empty);
  64. }
  65. _updateBitmap = false;
  66. }
  67. e.Graphics.DrawImage(_bufferedBitmap, Point.Empty);
  68. }
  69. private void BottomScrollBar_Scroll(object sender, ScrollEventArgs e)
  70. {
  71. ReDraw();
  72. }
  73. private void TopScrollBar_Scroll(object sender, ScrollEventArgs e)
  74. {
  75. _waveDub.OffsetI = TopScrollBar.Value;
  76. ReDraw();
  77. }
  78. private void GraphControl_MouseMove(object sender, MouseEventArgs e)
  79. {
  80. _cursorX = e.X;
  81. ReDraw();
  82. }
  83. private void ScalePot_ValueChanged(object sender, EventArgs e)
  84. {
  85. _zoomRate = ScalePot.Value < 1
  86. ? (float)ScalePot.Value
  87. : (float)(1 + (ScalePot.Value - 1) * 20);
  88. UpdateScaleData();
  89. ReDraw();
  90. }
  91. private void Render()
  92. {
  93. var iColor = Color.FromArgb(224, Color.Red);
  94. var vColor = Color.FromArgb(224, Color.Blue);
  95. var cColor = Color.FromArgb(224, Color.Green);
  96. var wColor = Color.FromArgb(224, Color.Yellow);
  97. using (var vPen = new Pen(vColor))
  98. using (var iPen = new Pen(iColor))
  99. using (var cPen = new Pen(cColor, 2))
  100. using (var vBrush = new SolidBrush(vColor))
  101. using (var iBrush = new SolidBrush(iColor))
  102. using (var cBrush = new SolidBrush(cColor))
  103. using (var wBrush = new SolidBrush(wColor))
  104. using (var g = Graphics.FromImage(_bufferedBitmap))
  105. {
  106. g.SetHighQuility();
  107. g.Clear(Color.Transparent);
  108. var halfStageHeight = _stageHeight / 2.0f;
  109. //middle zero line
  110. g.FillRectangle(wBrush,
  111. 0, halfStageHeight - halfStageHeight * 0.2f,
  112. _stageWidth, halfStageHeight * 0.4f);
  113. g.DrawLine(Pens.Black,
  114. 0, halfStageHeight,
  115. _stageWidth, halfStageHeight);
  116. g.DrawLine(Pens.Black,
  117. _cursorX, 0,
  118. _cursorX, _stageHeight);
  119. if (null == _waveDub) return;
  120. var yRate = halfStageHeight;
  121. if (_zoomRate < 1)
  122. {
  123. //compact vertical line
  124. float iSampleIndex = BottomScrollBar.Value + _waveDub.OffsetI;
  125. float vSampleIndex = BottomScrollBar.Value;
  126. var pixelPerSample = 1 / _zoomRate;
  127. for (var x = 0; x < _stageWidth && vSampleIndex < _waveDub.SamplesV.Count; x++)
  128. {
  129. var skip = pixelPerSample * x;
  130. var vChunk = _waveDub.SamplesV.SkipFast((int)(vSampleIndex + skip)).Take((int)pixelPerSample).ToArray();
  131. if (0 == vChunk.Length) break;
  132. var vMin = vChunk.Min();
  133. var vMax = vChunk.Max();
  134. var xMidPoint = new PointF(x, halfStageHeight);
  135. var yPoint = new PointF(x, vMin * yRate + halfStageHeight);
  136. g.DrawLine(vPen, xMidPoint, yPoint);
  137. yPoint.Y = vMax * yRate + halfStageHeight;
  138. g.DrawLine(vPen, xMidPoint, yPoint);
  139. var iChunk = _waveDub.SamplesI.SkipFast((int)(vSampleIndex + skip)).Take((int)pixelPerSample).ToArray();
  140. if (0 != iChunk.Length)
  141. {
  142. var iMax = iChunk.Max();
  143. var iMin = iChunk.Min();
  144. yPoint.Y = iMin * yRate + halfStageHeight;
  145. g.DrawLine(iPen, xMidPoint, yPoint);
  146. yPoint.Y = iMax * yRate + halfStageHeight;
  147. g.DrawLine(iPen, xMidPoint, yPoint);
  148. var cChunk = vChunk.Zip(iChunk, (v, i) => v - i).ToArray();
  149. var cMax = cChunk.Max();
  150. var cMin = cChunk.Min();
  151. yPoint.Y = cMin * yRate + halfStageHeight;
  152. g.DrawLine(cPen, xMidPoint, yPoint);
  153. yPoint.Y = cMax * yRate + halfStageHeight;
  154. g.DrawLine(cPen, xMidPoint, yPoint);
  155. }
  156. vSampleIndex += pixelPerSample;
  157. iSampleIndex += pixelPerSample;
  158. }
  159. }
  160. else
  161. {
  162. var iPoints = new List<PointF>(_stageWidthSamples);
  163. var vPoints = new List<PointF>(_stageWidthSamples);
  164. var cPoints = new List<PointF>(_stageWidthSamples);
  165. var iSampleIndex = BottomScrollBar.Value + _waveDub.OffsetI;
  166. var vSampleIndex = BottomScrollBar.Value;
  167. for (var x = 0; x < _stageWidthSamples && vSampleIndex < _waveDub.SamplesV.Count; x++)
  168. {
  169. var vValue = _waveDub.SamplesV[vSampleIndex];
  170. var scaledX = x * _zoomRate;
  171. vPoints.Add(new PointF(scaledX, vValue * yRate + halfStageHeight));
  172. if (iSampleIndex >= 0 && iSampleIndex < _waveDub.SamplesI.Count)
  173. {
  174. var iValue = _waveDub.SamplesI[iSampleIndex];
  175. iPoints.Add(new PointF(scaledX, iValue * yRate + halfStageHeight));
  176. var cValue = vValue - iValue;
  177. cPoints.Add(new PointF(scaledX, cValue * yRate + halfStageHeight));
  178. }
  179. vSampleIndex++;
  180. iSampleIndex++;
  181. }
  182. if (vPoints.Count > 1) g.DrawLines(vPen, vPoints.ToArray());
  183. if (iPoints.Count > 1) g.DrawLines(iPen, iPoints.ToArray());
  184. if (cPoints.Count > 1) g.DrawLines(cPen, cPoints.ToArray());
  185. if (_zoomRate >= 10)
  186. {
  187. var dotRc = new RectangleF(0, 0, 6, 6);
  188. //show point in sample
  189. foreach (var vPoint in vPoints)
  190. {
  191. dotRc.Location = vPoint;
  192. dotRc.Offset(-3, -3);
  193. g.FillEllipse(vBrush, dotRc);
  194. }
  195. foreach (var iPoint in iPoints)
  196. {
  197. dotRc.Location = iPoint;
  198. dotRc.Offset(-3, -3);
  199. g.FillEllipse(iBrush, dotRc);
  200. }
  201. foreach (var cPoint in cPoints)
  202. {
  203. dotRc.Location = cPoint;
  204. dotRc.Offset(-3, -3);
  205. g.FillEllipse(cBrush, dotRc);
  206. }
  207. }
  208. }
  209. }
  210. }
  211. }
  212. }