diff -r 10de0c7c2fed -r e5f85a895a62 Server/Spectrum/LineSpectrum.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Server/Spectrum/LineSpectrum.cs Mon Jan 02 18:43:45 2017 +0100 @@ -0,0 +1,166 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using CSCore.DSP; + +namespace Visualization +{ + public class LineSpectrum : SpectrumBase + { + private int _barCount; + private double _barSpacing; + private double _barWidth; + private Size _currentSize; + + public LineSpectrum(FftSize fftSize) + { + FftSize = fftSize; + } + + [Browsable(false)] + public double BarWidth + { + get { return _barWidth; } + } + + public double BarSpacing + { + get { return _barSpacing; } + set + { + if (value < 0) + throw new ArgumentOutOfRangeException("value"); + _barSpacing = value; + UpdateFrequencyMapping(); + + RaisePropertyChanged("BarSpacing"); + RaisePropertyChanged("BarWidth"); + } + } + + public int BarCount + { + get { return _barCount; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException("value"); + _barCount = value; + SpectrumResolution = value; + UpdateFrequencyMapping(); + + RaisePropertyChanged("BarCount"); + RaisePropertyChanged("BarWidth"); + } + } + + [BrowsableAttribute(false)] + public Size CurrentSize + { + get { return _currentSize; } + protected set + { + _currentSize = value; + RaisePropertyChanged("CurrentSize"); + } + } + + public Bitmap CreateSpectrumLine(Size size, Brush brush, Color background, bool highQuality) + { + if (!UpdateFrequencyMappingIfNessesary(size)) + return null; + + var fftBuffer = new float[(int)FftSize]; + + //get the fft result from the spectrum provider + if (SpectrumProvider.GetFftData(fftBuffer, this)) + { + using (var pen = new Pen(brush, (float)_barWidth)) + { + var bitmap = new Bitmap(size.Width, size.Height); + + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + PrepareGraphics(graphics, highQuality); + graphics.Clear(background); + + CreateSpectrumLineInternal(graphics, pen, fftBuffer, size); + } + + return bitmap; + } + } + return null; + } + + public Bitmap CreateSpectrumLine(Size size, Color color1, Color color2, Color background, bool highQuality) + { + if (!UpdateFrequencyMappingIfNessesary(size)) + return null; + + using ( + Brush brush = new LinearGradientBrush(new RectangleF(0, 0, (float)_barWidth, size.Height), color2, + color1, LinearGradientMode.Vertical)) + { + return CreateSpectrumLine(size, brush, background, highQuality); + } + } + + private void CreateSpectrumLineInternal(Graphics graphics, Pen pen, float[] fftBuffer, Size size) + { + int height = size.Height; + //prepare the fft result for rendering + SpectrumPointData[] spectrumPoints = CalculateSpectrumPoints(height, fftBuffer); + + //connect the calculated points with lines + for (int i = 0; i < spectrumPoints.Length; i++) + { + SpectrumPointData p = spectrumPoints[i]; + int barIndex = p.SpectrumPointIndex; + double xCoord = BarSpacing * (barIndex + 1) + (_barWidth * barIndex) + _barWidth / 2; + + var p1 = new PointF((float)xCoord, height); + var p2 = new PointF((float)xCoord, height - (float)p.Value - 1); + + graphics.DrawLine(pen, p1, p2); + } + } + + protected override void UpdateFrequencyMapping() + { + _barWidth = Math.Max(((_currentSize.Width - (BarSpacing * (BarCount + 1))) / BarCount), 0.00001); + base.UpdateFrequencyMapping(); + } + + private bool UpdateFrequencyMappingIfNessesary(Size newSize) + { + if (newSize != CurrentSize) + { + CurrentSize = newSize; + UpdateFrequencyMapping(); + } + + return newSize.Width > 0 && newSize.Height > 0; + } + + private void PrepareGraphics(Graphics graphics, bool highQuality) + { + if (highQuality) + { + graphics.SmoothingMode = SmoothingMode.AntiAlias; + graphics.CompositingQuality = CompositingQuality.AssumeLinear; + graphics.PixelOffsetMode = PixelOffsetMode.Default; + graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; + } + else + { + graphics.SmoothingMode = SmoothingMode.HighSpeed; + graphics.CompositingQuality = CompositingQuality.HighSpeed; + graphics.PixelOffsetMode = PixelOffsetMode.None; + graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + } + } + } +} \ No newline at end of file