private void drawBitMap()
        {
            if (this.max == 0)
            {
                this.findMax();
            }
            if (this.count == 0)
            {
                throw new Exception();
            }
            this.bitMap = new Bitmap(this.count, 512);
            long position = 0;

            position = this.StartPosition;
            double koef; int x = 0;

            for (int i = 0; i < this.count; i++, x++)
            {
                double[] spectrum = SpectrumViewer.getSpectrum(this.Audio, position);
                position += 1024;
                koef      = 135 / max * 16;
                int color;
                for (int j = 0; j < spectrum.Length; j++)
                {
                    color = 20 + (int)(spectrum[j] * koef);
                    if (color > 255)
                    {
                        color = 255;
                    }
                    this.bitMap.SetPixel(x, 512 - j - 1, Color.FromArgb(0, color, 0));
                }
            }
        }
        private void findMax()
        {
            long position = 0;

            for (int i = 0; i < this.Audio.FloatSamples.Length / 1024; i++)
            {
                double[] spectrum = SpectrumViewer.getSpectrum(this.Audio, position);
                position += 1024;
                for (int j = 0; j < spectrum.Length; j++)
                {
                    if (spectrum[j] > this.max)
                    {
                        this.max = spectrum[j];
                    }
                }
            }
        }
Ejemplo n.º 3
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.Audio != null)
            {
                long position = 0;
                if (audio.Format == Enums.AudioFormats.MP3)
                {
                    MP3File file = audio as MP3File;
                    position = file.Reader.Position / 2;
                }
                else if (audio.Format == Enums.AudioFormats.WAV)
                {
                    WaveFile file = audio as WaveFile;
                    position = file.Reader.Position / 2;
                }

                double[] spectrum = SpectrumViewer.getSpectrum(this.Audio, position);
                if (this.state == ViewState.LOGARITHM)
                {
                    this.logarithmSpectrum(spectrum);
                }

                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                Pen linePen = new Pen(this.PenColor, this.PenWidth);
                linePen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                linePen.EndCap   = System.Drawing.Drawing2D.LineCap.Round;

                float step = (float)(this.Width - 20) / spectrum.Length;

                // Отрисовка шкалы по оси X
                int yLinePos   = (this.state != ViewState.LOGARITHM) ? this.Height - 20 : 20;
                int yStringPos = (this.state != ViewState.LOGARITHM) ? yLinePos + 3 : 3;
                e.Graphics.DrawLine(Pens.White, 0, yLinePos, this.Width, yLinePos);
                e.Graphics.DrawString("kHz", new Font(FontFamily.GenericSansSerif, 7.5f), Brushes.White, 0, yStringPos);
                int[] freqPointsPercents = { 5, 10, 20, 25, 40, 50, 60, 75, 80, 90, 95 };   // Позиции значений частот (в %)
                float freqPoint;
                for (int i = 0; i < freqPointsPercents.Length; i++)
                {
                    freqPoint = 20 + (freqPointsPercents[i] * (this.Width - 20) / 100f);
                    if (this.state == ViewState.COLUMNAR || this.state == ViewState.DEFAULT)
                    {
                        e.Graphics.DrawLine(new Pen(Color.Gray, 1f), freqPoint, 0, freqPoint, this.Height - 20);
                    }
                    else
                    {
                        e.Graphics.DrawLine(new Pen(Color.Gray, 1f), freqPoint, 20, freqPoint, this.Height);
                    }
                    // Получение частоты в текущей точке и ее отображение
                    double sample      = (spectrum.Length * freqPointsPercents[i]) / 100.0;
                    string currentFreq = ((sample * freq) * Math.Pow(10, -3)).ToString("0.000");
                    e.Graphics.DrawString(currentFreq, new Font(FontFamily.GenericSansSerif, 7.5f), Brushes.White, freqPoint - 15, yStringPos);
                }

                // Отрисовка шкалы по оси Y
                e.Graphics.DrawLine(Pens.White, 20, 0, 20, this.Height);
                if (this.state == ViewState.LOGARITHM)
                {
                    e.Graphics.DrawString("dB", new Font(FontFamily.GenericSansSerif, 7.5f), Brushes.White, 2, this.Height - 15);
                }
                int[]  gradePointsPercents = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; // Позиции значений уровня спектра (в %)
                int    gradePoint;
                double currentGrade;
                for (int i = 0; i < gradePointsPercents.Length; i++)
                {
                    if (i == gradePointsPercents.Length - 1 && this.state == ViewState.LOGARITHM)
                    {
                        break;                                                                              // Для dB не выводить последнее значение
                    }
                    gradePoint = gradePointsPercents[i] * (this.Height - 20) / 100;
                    gradePoint = (this.state == ViewState.LOGARITHM) ? gradePoint + 20 : gradePoint;
                    e.Graphics.DrawLine(new Pen(Color.Gray, 1f), 20, gradePoint, this.Width, gradePoint);
                    if (this.state != ViewState.LOGARITHM)
                    {
                        // Нормировка значения уровня спектра
                        currentGrade = (this.Height - 20 - gradePoint) * this.Audio.Avg / (this.Height - 20);
                        if (this.state == ViewState.COLUMNAR)
                        {
                            currentGrade /= 3;
                        }
                        currentGrade *= 10000;
                        currentGrade  = Math.Round(currentGrade);
                    }
                    else
                    {
                        currentGrade = Math.Round(gradePoint / -1.5);
                    }
                    e.Graphics.DrawString(currentGrade.ToString(), new Font(FontFamily.GenericSansSerif, 7f), Brushes.White, -1, gradePoint - 6);
                }

                // Отрисовка спектра
                float koef = (this.state != ViewState.LOGARITHM) ? (this.Height - 20) / this.Audio.Avg : 1.5f;

                float x = e.ClipRectangle.X + 20;
                float y = (float)(this.Height - 20);
                y = (this.state == ViewState.LOGARITHM) ? 20 : y;
                if (this.state != ViewState.COLUMNAR)   // Для грфаического представления
                {
                    float x1, y1;
                    for (int i = 1; i < spectrum.Length; i++)
                    {
                        x1 = x + step;
                        y1 = (this.state != ViewState.LOGARITHM) ? (this.Height - 20) - (float)(spectrum[i] * koef) : 20 - (float)(spectrum[i] * koef);
                        if (float.IsInfinity(y1))
                        {
                            continue;
                        }
                        e.Graphics.DrawLine(linePen, x, y, x1, y1);
                        x = x1; y = y1;
                    }
                }
                else        // Для столбчатого
                {
                    float columnWidth  = (float)(this.Width - 20) / this.columnCount;
                    float columnHeight = 0;
                    float columnHeightCoord;
                    float oldLineYCoord;
                    for (int i = 0; i < this.columnCount; i++, columnHeight = 0)
                    {
                        // Находим среднее значение уровня для текущего столбца
                        for (int j = i * (spectrum.Length / this.columnCount), count = 0; count < (spectrum.Length / this.columnCount); j++, count++)
                        {
                            if (i == 0 && j == 0)
                            {
                                continue;
                            }
                            columnHeight += (float)spectrum[j];
                        }
                        columnHeight      /= (i == 0) ? (spectrum.Length / this.columnCount) - 1 : spectrum.Length / this.columnCount;
                        this.oldValues[i] -= 0.00005f; // Плавное падение полосы-указателя предыдущего уровня
                        oldLineYCoord      = (this.Height - 20) - this.oldValues[i] * koef * 3;
                        if (columnHeight > this.oldValues[i])
                        {
                            this.oldValues[i] = columnHeight;   // Обновление указателя уровня
                        }
                        columnHeightCoord = (this.Height - 20) - columnHeight * koef * 3;
                        e.Graphics.DrawLine(linePen, x, oldLineYCoord, x + columnWidth, oldLineYCoord);
                        e.Graphics.DrawRectangle(Pens.Aqua, x, columnHeightCoord, columnWidth, y - columnHeightCoord);
                        x += columnWidth;
                    }
                }
            }
            base.OnPaint(e);
        }