Pregunta

When I am trying to generate wave form image by passing mp3 stream to the following function it is throwing overflow exception at g.DrawLine call. Please correct me where I am going wrong.Any help is greatly appreciated.

public static void DrawNormalizedAudio(ref float[] data, Color color)
{
   Bitmap bmp= new Bitmap(1800,200);            

   int BORDER_WIDTH = 5;
   int width = bmp.Width - (2 * BORDER_WIDTH);
   int height = bmp.Height - (2 * BORDER_WIDTH);

   using (Graphics g = Graphics.FromImage(bmp))
   {
      g.Clear(Color.Black);
      Pen pen = new Pen(color);
      int size = data.Length;
      for (int iPixel = 0; iPixel < width; iPixel++)
      {
        // determine start and end points within WAV
           int start = (int)((float)iPixel * ((float)size / (float)width));
           int end = (int)((float)(iPixel + 1) * ((float)size / (float)width));
           float min = float.MaxValue;
           float max = float.MinValue;
           for (int i = start; i < end; i++)
           {
              float val = data[i];
              min = val < min ? val : min;
              max = val > max ? val : max;
           }
           int yMax = BORDER_WIDTH + height - (int)((max + 1) * .5 * height);
           int yMin = BORDER_WIDTH + height - (int)((min + 1) * .5 * height);
           g.DrawLine(pen, iPixel + BORDER_WIDTH, yMax,
           iPixel + BORDER_WIDTH, yMin);
          }
        }

        bmp.Save("D:\\waveimage.png"); 
    }

    public float[] FloatArrayFromStream(System.IO.MemoryStream stream)
    {
        return FloatArrayFromByteArray(stream.GetBuffer());
    }

    public float[] FloatArrayFromByteArray(byte[] input)
    {
        float[] output = new float[input.Length / 4];
        for (int i = 0; i < output.Length; i++)
        {
            output[i] = BitConverter.ToSingle(input, i * 4);
        }
        return output;
    }      
¿Fue útil?

Solución

My first thought is that you are drawing an image that has more output columns than input, which would give you values for min and max (and therefore yMin and yMax) that are out of range. I would expect that the yMin calculation would throw the exception in that case.

You should be clamping the yMin and yMax values to the size of the drawing area on the canvas, then adding the BORDER_WIDTH offset before (or during) the call to g.DrawLine.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top