public void drawSpectrogram3(String prefix, String filename, float[][] data)
        {
            float minDb = -65.0f;
            float maxDb = 0.0f;

            double numberOfSamplesX = data.Length;
            double numberOfSamplesY = data[0].Length;

            // set width and height
            int width  = (int)numberOfSamplesX;
            int height = (int)numberOfSamplesY;

            String filenameToSave = String.Format("C:\\{0}-{1}x{2}-{3}.png", prefix, width, height, System.IO.Path.GetFileNameWithoutExtension(filename));

            System.Console.Out.WriteLine("Writing " + filenameToSave);

            double horizontalScaleFactor = (double)width / numberOfSamplesX;
            double verticalScaleFactor   = (double)height / numberOfSamplesY;

            int maxYIndex = height - 1;

            // Now, you need to figure out the incremental jump between samples to adjust for the scale factor. This works out to be:
            int incrementX = (int)(numberOfSamplesX / (numberOfSamplesX * horizontalScaleFactor));

            if (incrementX == 0)
            {
                incrementX = 1;
            }

            int incrementY = (int)(numberOfSamplesY / (numberOfSamplesY * verticalScaleFactor));

            if (incrementY == 0)
            {
                incrementY = 1;
            }

            // prepare the data
            // retrieve the highest and lowest value
            double maxVal = double.MinValue;
            double minVal = double.MaxValue;

            for (int x = 0; x < data.Length; x++)
            {
                for (int y = 0; y < data[x].Length; y++)
                {
                    if (data[x][y] > maxVal)
                    {
                        maxVal = data[x][y];
                    }

                    if (data[x][y] < minVal)
                    {
                        minVal = data[x][y];
                    }
                }
            }

            float maxValdB = MathUtils.AmplitudeToDecibel((float)maxVal, minDb, maxDb);
            float minValdB = MathUtils.AmplitudeToDecibel((float)minVal, minDb, maxDb);

            double minIntensity = Math.Abs(minVal);
            double maxIntensity = maxVal + minIntensity;

            System.Console.Out.WriteLine("min value: {0}", minVal);
            System.Console.Out.WriteLine("max value: {0}", maxVal);
            System.Console.Out.WriteLine("min value: {0} dB", minValdB);
            System.Console.Out.WriteLine("max value: {0} dB", maxValdB);
            System.Console.Out.WriteLine("min intensity: {0}", minIntensity);
            System.Console.Out.WriteLine("max intensity: {0}", maxIntensity);

            // Create the image for displaying the data.
            Bitmap   png = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            Graphics g   = Graphics.FromImage(png);

            Rectangle rect = new Rectangle(0, 0, width, height);

            g.FillRectangle(Brushes.White, rect);

            for (int i = 0; i < numberOfSamplesX; i += incrementX)
            {
                for (int j = 0; j < numberOfSamplesY; j += incrementY)
                {
                    int x = (int)MathUtils.RoundDown(i * horizontalScaleFactor, 0);
                    int y = (int)MathUtils.RoundDown(j * verticalScaleFactor, 0);

                    float amplitude = data[i][j];
                    float dB        = MathUtils.AmplitudeToDecibel(amplitude, minDb, maxDb);

                    int color = (int)MathUtils.ConvertAndMainainRatio(dB, minValdB, maxValdB, 0, 256);
                    //Color c = VB6Spectrogram.PaletteValueColor(color, 256);
                    Color c = VB6Spectrogram.GreyPaletteValueColor(color, 256);
                    png.SetPixel(x, maxYIndex - y, c);
                }
            }

            png = ColorUtils.Colorize(png, 255, ColorUtils.ColorPaletteType.SOX);
            png.Save(filenameToSave);
            g.Dispose();
        }
        public void drawSpectrogram2(String prefix, String filename, float[][] data, double sampleRate, int numberOfSamples, double fftWindowsSize)
        {
            float minDb = -100.0f;
            float maxDb = 0.0f;

            float numberOfSamplesX = data.Length;
            float numberOfSamplesY = data[0].Length;

            // set width and height
            int width  = (int)numberOfSamplesX;
            int height = (int)numberOfSamplesY;

            String filenameToSave = String.Format("C:\\{0}-{1}x{2}-{3}.png", prefix, width, height, System.IO.Path.GetFileNameWithoutExtension(filename));

            System.Console.Out.WriteLine("Writing " + filenameToSave);

            Bitmap   png = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            Graphics g   = Graphics.FromImage(png);
            Pen      pen = new Pen(Color.Black, 1);

            // prepare the data
            // retrieve the highest and lowest value
            double maxVal = double.MinValue;
            double minVal = double.MaxValue;

            for (int x = 0; x < data.Length; x++)
            {
                for (int y = 0; y < data[x].Length; y++)
                {
                    if (data[x][y] > maxVal)
                    {
                        maxVal = data[x][y];
                    }

                    if (data[x][y] < minVal)
                    {
                        minVal = data[x][y];
                    }
                }
            }

            float maxValdB = MathUtils.AmplitudeToDecibel((float)maxVal, minDb, maxDb);
            float minValdB = MathUtils.AmplitudeToDecibel((float)minVal, minDb, maxDb);

            Axis.drawAxis(Axis.X_AXIS, 10, 10, 0, (float)MathUtils.ConvertToTime(sampleRate, numberOfSamples), 50, width - 50, 50, false, height, g);
            Axis.drawAxis(Axis.Y_AXIS, 100, 10, 20, (float)(sampleRate / 2), 50, height - 50, 50, true, height, g);

            int xCoord = 1;
            int oldX   = 1;

            for (int x = 0; x < numberOfSamplesX; x++)
            {
                int oldY = 1;
                for (int y = 0; y < numberOfSamplesY; y++)
                {
                    int x1 = Axis.plotValue(x + 1, 1, numberOfSamplesX + 1, 50, width - 50, false, height);
                    int y1 = Axis.plotValue(y + 1, 1, numberOfSamplesY + 1, 50, height - 50, true, height);

                    /*
                     * float amplitude = data[x][y];
                     * float dB = MathUtils.ConvertAmplitudeToDB(amplitude, minDb, maxDb);
                     * int color = (int) MathUtils.ConvertAndMainainRatio(dB, minValdB, maxValdB, 0, 256);
                     * Color c = VB6Spectrogram.PaletteValueColor(color, 256);
                     */
                    float amplitude = data[x][y];
                    Color colorbw   = Color.Black;
                    if (amplitude > 0)
                    {
                        float dB       = MathUtils.AmplitudeToDecibel(amplitude, minDb, maxDb);
                        int   colorval = (int)MathUtils.ConvertAndMainainRatio(dB, minDb, maxDb, 0, 255);                        // 255 is full brightness, and good for REW colors (for SOX 220 is good)
                        colorbw = Color.FromArgb(colorval, colorval, colorval);
                    }


                    if (x1 > 0 && x1 < width && y1 > 0 && y1 < height)
                    {
                        pen.Color = colorbw;
                        xCoord    = x1 + 50;
                        g.DrawLine(pen, xCoord, height - oldY - 50, xCoord, height - y1 - 50);
                        oldX = x1;
                        oldY = y1;
                    }
                }
            }

            png = ColorUtils.Colorize(png, 255, ColorUtils.ColorPaletteType.REW);
            png.Save(filenameToSave);
            g.Dispose();
        }