/// <summary> /// Set ArbgPixel at given point. /// </summary> /// <param name="x">X.</param> /// <param name="y">Y.</param> /// <param name="waveColor">Color.</param> internal void SetAt(int x, int y, ArbgPixel waveColor) { System.Diagnostics.Debug.Assert(_base != null); System.Diagnostics.Debug.Assert(_width > 0); ArbgPixel* pixel = (ArbgPixel*)(_base + (y * _width) + (x * sizeof(ArbgPixel))); *pixel = waveColor; }
private Bitmap DrawWaveform(int sampleOffset, int sampleLength, Rectangle clip) { ArbgPixel waveColor = new ArbgPixel(255, 0, 255, 0); if (_waveFile == null) { return null; } if (clip.Width == 0 || clip.Height == 0) { return null; } Bitmap waveform = new Bitmap(clip.Width, clip.Height); using (UnsafeBitmap unsafeMap = new UnsafeBitmap(waveform)) { Graphics graphics = Graphics.FromImage(unsafeMap.Bitmap); graphics.FillRectangle(Brushes.WhiteSmoke, graphics.VisibleClipBounds); unsafeMap.LockBitmap(); float stepY = (float)clip.Height / 2 / short.MaxValue; float stepX = (float)clip.Width / sampleLength; //// #region Draw middle line int middleY = (int)clip.Height / 2; for (int x = 0; x < clip.Width; x++) { unsafeMap.SetAt(x, middleY, 0, 255, 0, 0); } //// #endregion short[] data = _waveFile.DataIn16Bits; int sampleEndIndex = sampleOffset + sampleLength; Point prevPoint = new Point(0, middleY); Point currPoint = new Point(0, middleY); int prevY = int.MinValue; for (int sampleIndex = sampleOffset; sampleIndex < sampleEndIndex; sampleIndex++) { currPoint.X = (int)(((sampleIndex - sampleOffset) * stepX) + 0.5); currPoint.Y = middleY - (int)((data[sampleIndex] * stepY) + 0.5); unsafeMap.SetAt((int)currPoint.X, (int)currPoint.Y, waveColor); if (currPoint.X != prevPoint.X) { // connect two points in line float tag = (float)(currPoint.Y - prevPoint.Y) / (currPoint.X - prevPoint.X); for (int interX = prevPoint.X; interX < currPoint.X; interX++) { int interY = (int)(((interX - prevPoint.X) * tag) + 0.5) + prevPoint.Y; if (prevY != interY && prevY != int.MinValue) { int insertDirect = Math.Sign(interY - prevY); int insertLength = Math.Abs(interY - prevY); for (int insertY = 1; insertY < insertLength; insertY++) { unsafeMap.SetAt(interX, prevY + (insertY * insertDirect), waveColor); } } unsafeMap.SetAt(interX, interY, waveColor); prevY = interY; } } else { if (prevPoint.Y != currPoint.Y) { int insertDirect = Math.Sign(currPoint.Y - prevPoint.Y); int insertLength = Math.Abs(currPoint.Y - prevPoint.Y); for (int insertY = 1; insertY < insertLength; insertY++) { unsafeMap.SetAt(prevPoint.X, prevPoint.Y + (insertY * insertDirect), waveColor); } } } prevPoint = currPoint; } unsafeMap.UnlockBitmap(); waveform = unsafeMap.Detach(); } return waveform; }