Hi all,
I just wanted to make a quick check,does any of you know of an open source c# code to present wave form (graphically) from a byte array?
Thank you!
Hi all,
I just wanted to make a quick check,does any of you know of an open source c# code to present wave form (graphically) from a byte array?
Thank you!
This is as open source as it gets:
public static void DrawNormalizedAudio(ref float[] data, PictureBox pb,
Color color)
{
Bitmap bmp;
if (pb.Image == null)
{
bmp = new Bitmap(pb.Width, pb.Height);
}
else
{
bmp = (Bitmap)pb.Image;
}
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);
}
}
pb.Image = bmp;
}
This takes an array of samples in floating-point format (where all sample values range from -1 to +1). If your original data is actually in the form of a byte[] array, you'll have to do a little bit of work to convert it to float[]. Let me know if you need that, too.
Update: since the question technically asked for something to render a byte array, here are a couple of helper methods:
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;
}
Update 2: I forgot there's a better way to do this:
public float[] FloatArrayFromByteArray(byte[] input)
{
float[] output = new float[input.Length / 4];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
return output;
}
I'm just so in love with for
loops, I guess.
I've been a fan of ZedGraph for many years and have used it to display all kinds of data in quite a few projects.
The following sample will create a graph that displays an array of doubles that vary between -1 and 1.
void DisplayWaveGraph(ZedGraphControl graphControl, double[] waveData)
{
var pane = graphControl.GraphPane;
pane.Title.IsVisible = false;
var xAxis = pane.XAxis;
xAxis.Title.IsVisible = false;
xAxis.Scale.Min = 0;
xAxis.Scale.Max = waveData.Length - 1;
var yAxis = pane.YAxis;
yAxis.Title.IsVisible = false;
yAxis.Scale.Min = -1;
yAxis.Scale.Max = 1;
var timeData = Enumerable.Range(0, waveData.Length)
.Select(i => (double) i)
.ToArray();
pane.AddCurve(null, timeData, waveData, Color.Red, SymbolType.None);
graphControl.AxisChange();
}
In NAudio, there is code to draw audio waveforms in both WinForms and WPF. Have a look at the demo projects for examples of how to use it.
Can someone post code to convert from MemoryStream or Byte[] to float array to create the waveform?
Thanks!
public float[] FloatArrayFromStream(System.IO.MemoryStream stream)
{
return FloatFromByte(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;
}