Server/Spectrum/LineSpectrum.cs
changeset 273 e5f85a895a62
child 274 920fea7a6427
     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