private Bitmap DrawSpectrum(int smapleOffset, int sampleLength, Rectangle clip) { if (_waveFile == null) { return null; } if (clip.Width == 0 || clip.Height == 0) { return null; } Bitmap spectrum = new Bitmap(clip.Width, clip.Height); using (UnsafeBitmap unsafeMap = new UnsafeBitmap(spectrum)) { Graphics graphics = Graphics.FromImage(unsafeMap.Bitmap); graphics.FillRectangle(Brushes.WhiteSmoke, graphics.VisibleClipBounds); int windowCount = (sampleLength - Fft.WindowSize) / Fft.WindowIncrement; int windowOffset = smapleOffset / Fft.WindowIncrement; int windowEndIndex = windowOffset + windowCount; unsafeMap.LockBitmap(); float stepX = (float)clip.Width / windowCount; float stepY = (float)clip.Height / Fft.FftWidth; float offsetX = stepX / 2; for (int windowIndex = windowOffset; windowIndex < windowEndIndex; windowIndex++) { float[] data = _waveFile.Spectrum[windowIndex]; if (data == null) { System.Diagnostics.Debug.Assert(false); continue; } int length = data.Length; float x = (windowIndex - windowOffset) * stepX; for (int j = 0; j < length; ++j) { float value = data[j]; float y = ((length - j) * stepY) - 1; int i = (int)(value / 18); i = (i > 256) ? 255 : i; byte color = (byte)(128 - (i / 2)); for (float rx = -stepX / 2; rx < stepX / 2; rx++) { for (float ry = -stepY / 2; ry < stepY / 2; ry++) { int px = (int)(x + rx + offsetX); int py = (int)(y + ry); double distance = Math.Sqrt((rx * rx) + (ry * ry)); byte alpha = (distance > 256) ? (byte)255 : (byte)distance; if (px >= 0 && px < clip.Width && py >= 0 && py < clip.Height) { unsafeMap.SetAt((int)px, (int)py, (byte)i, color, 0, alpha); } } } unsafeMap.SetAt((int)(x + offsetX), (int)y, (byte)i, (byte)(128 - (i / 2)), 0, 0); } } unsafeMap.UnlockBitmap(); spectrum = unsafeMap.Detach(); } return spectrum; }
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; }