1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Server/Spectrum/LineSpectrum.cs Mon Jan 02 18:43:45 2017 +0100
1.3 @@ -0,0 +1,166 @@
1.4 +using System;
1.5 +using System.ComponentModel;
1.6 +using System.Drawing;
1.7 +using System.Drawing.Drawing2D;
1.8 +using System.Drawing.Text;
1.9 +using CSCore.DSP;
1.10 +
1.11 +namespace Visualization
1.12 +{
1.13 + public class LineSpectrum : SpectrumBase
1.14 + {
1.15 + private int _barCount;
1.16 + private double _barSpacing;
1.17 + private double _barWidth;
1.18 + private Size _currentSize;
1.19 +
1.20 + public LineSpectrum(FftSize fftSize)
1.21 + {
1.22 + FftSize = fftSize;
1.23 + }
1.24 +
1.25 + [Browsable(false)]
1.26 + public double BarWidth
1.27 + {
1.28 + get { return _barWidth; }
1.29 + }
1.30 +
1.31 + public double BarSpacing
1.32 + {
1.33 + get { return _barSpacing; }
1.34 + set
1.35 + {
1.36 + if (value < 0)
1.37 + throw new ArgumentOutOfRangeException("value");
1.38 + _barSpacing = value;
1.39 + UpdateFrequencyMapping();
1.40 +
1.41 + RaisePropertyChanged("BarSpacing");
1.42 + RaisePropertyChanged("BarWidth");
1.43 + }
1.44 + }
1.45 +
1.46 + public int BarCount
1.47 + {
1.48 + get { return _barCount; }
1.49 + set
1.50 + {
1.51 + if (value <= 0)
1.52 + throw new ArgumentOutOfRangeException("value");
1.53 + _barCount = value;
1.54 + SpectrumResolution = value;
1.55 + UpdateFrequencyMapping();
1.56 +
1.57 + RaisePropertyChanged("BarCount");
1.58 + RaisePropertyChanged("BarWidth");
1.59 + }
1.60 + }
1.61 +
1.62 + [BrowsableAttribute(false)]
1.63 + public Size CurrentSize
1.64 + {
1.65 + get { return _currentSize; }
1.66 + protected set
1.67 + {
1.68 + _currentSize = value;
1.69 + RaisePropertyChanged("CurrentSize");
1.70 + }
1.71 + }
1.72 +
1.73 + public Bitmap CreateSpectrumLine(Size size, Brush brush, Color background, bool highQuality)
1.74 + {
1.75 + if (!UpdateFrequencyMappingIfNessesary(size))
1.76 + return null;
1.77 +
1.78 + var fftBuffer = new float[(int)FftSize];
1.79 +
1.80 + //get the fft result from the spectrum provider
1.81 + if (SpectrumProvider.GetFftData(fftBuffer, this))
1.82 + {
1.83 + using (var pen = new Pen(brush, (float)_barWidth))
1.84 + {
1.85 + var bitmap = new Bitmap(size.Width, size.Height);
1.86 +
1.87 + using (Graphics graphics = Graphics.FromImage(bitmap))
1.88 + {
1.89 + PrepareGraphics(graphics, highQuality);
1.90 + graphics.Clear(background);
1.91 +
1.92 + CreateSpectrumLineInternal(graphics, pen, fftBuffer, size);
1.93 + }
1.94 +
1.95 + return bitmap;
1.96 + }
1.97 + }
1.98 + return null;
1.99 + }
1.100 +
1.101 + public Bitmap CreateSpectrumLine(Size size, Color color1, Color color2, Color background, bool highQuality)
1.102 + {
1.103 + if (!UpdateFrequencyMappingIfNessesary(size))
1.104 + return null;
1.105 +
1.106 + using (
1.107 + Brush brush = new LinearGradientBrush(new RectangleF(0, 0, (float)_barWidth, size.Height), color2,
1.108 + color1, LinearGradientMode.Vertical))
1.109 + {
1.110 + return CreateSpectrumLine(size, brush, background, highQuality);
1.111 + }
1.112 + }
1.113 +
1.114 + private void CreateSpectrumLineInternal(Graphics graphics, Pen pen, float[] fftBuffer, Size size)
1.115 + {
1.116 + int height = size.Height;
1.117 + //prepare the fft result for rendering
1.118 + SpectrumPointData[] spectrumPoints = CalculateSpectrumPoints(height, fftBuffer);
1.119 +
1.120 + //connect the calculated points with lines
1.121 + for (int i = 0; i < spectrumPoints.Length; i++)
1.122 + {
1.123 + SpectrumPointData p = spectrumPoints[i];
1.124 + int barIndex = p.SpectrumPointIndex;
1.125 + double xCoord = BarSpacing * (barIndex + 1) + (_barWidth * barIndex) + _barWidth / 2;
1.126 +
1.127 + var p1 = new PointF((float)xCoord, height);
1.128 + var p2 = new PointF((float)xCoord, height - (float)p.Value - 1);
1.129 +
1.130 + graphics.DrawLine(pen, p1, p2);
1.131 + }
1.132 + }
1.133 +
1.134 + protected override void UpdateFrequencyMapping()
1.135 + {
1.136 + _barWidth = Math.Max(((_currentSize.Width - (BarSpacing * (BarCount + 1))) / BarCount), 0.00001);
1.137 + base.UpdateFrequencyMapping();
1.138 + }
1.139 +
1.140 + private bool UpdateFrequencyMappingIfNessesary(Size newSize)
1.141 + {
1.142 + if (newSize != CurrentSize)
1.143 + {
1.144 + CurrentSize = newSize;
1.145 + UpdateFrequencyMapping();
1.146 + }
1.147 +
1.148 + return newSize.Width > 0 && newSize.Height > 0;
1.149 + }
1.150 +
1.151 + private void PrepareGraphics(Graphics graphics, bool highQuality)
1.152 + {
1.153 + if (highQuality)
1.154 + {
1.155 + graphics.SmoothingMode = SmoothingMode.AntiAlias;
1.156 + graphics.CompositingQuality = CompositingQuality.AssumeLinear;
1.157 + graphics.PixelOffsetMode = PixelOffsetMode.Default;
1.158 + graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
1.159 + }
1.160 + else
1.161 + {
1.162 + graphics.SmoothingMode = SmoothingMode.HighSpeed;
1.163 + graphics.CompositingQuality = CompositingQuality.HighSpeed;
1.164 + graphics.PixelOffsetMode = PixelOffsetMode.None;
1.165 + graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
1.166 + }
1.167 + }
1.168 + }
1.169 +}
1.170 \ No newline at end of file