I'm looking for a fast, professionally looking and customizable waveform display component in C#.
I'm wanting to display mainly real-time audio waveforms (fast!) in both time and frequency domain. I would like the ability to zoom, change axis settings, display multiple channels, customize the feel and colors etc...
Anybody knows of anything, whether commercial or not?
Thank you!
Diego
I bumped into a code project awhile ago that was doing this.
Check out http://www.codeproject.com/KB/miscctrl/GraphComponents.aspx it may be what you are looking for to do real-time graphing in .net
as far as i know, national instrument has some cool control, but it's not free.
http://sine.ni.com/psp/app/doc/p/id/psp-317
free ones:
http://www.codeproject.com/KB/audio-video/wavecontrol.aspx
That is a wave flow displayer
http://www.codeproject.com/KB/audio-video/wavecontrol.aspx
Check out Zedgraph. It's a free graphing library that works great. There are lots of code samples on their website that allow you to do what you're asking. Zedgraph Downloads Their website seems to be having issues right now, but the download session works and contains all of their sample files.
This will generate waveform from audio file using nAudio...
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string strPath = Server.MapPath("audio/060.mp3");
string SongID = "2";
byte[] bytes = File.ReadAllBytes(strPath);
WriteToFile(SongID,strPath, bytes);
Response.Redirect("Main.aspx");
}
private void WriteToFile(string SongID, string strPath, byte[] Buffer)
{
try
{
int samplesPerPixel = 128;
long startPosition = 0;
//FileStream newFile = new FileStream(GeneralUtils.Get_SongFilePath() + "/" + strPath, FileMode.Create);
float[] data = FloatArrayFromByteArray(Buffer);
Bitmap bmp = new Bitmap(1170, 200);
int BORDER_WIDTH = 5;
int width = bmp.Width - (2 * BORDER_WIDTH);
int height = bmp.Height - (2 * BORDER_WIDTH);
NAudio.Wave.Mp3FileReader reader = new NAudio.Wave.Mp3FileReader(strPath, wf => new NAudio.FileFormats.Mp3.DmoMp3FrameDecompressor(wf));
NAudio.Wave.WaveChannel32 channelStream = new NAudio.Wave.WaveChannel32(reader);
int bytesPerSample = (reader.WaveFormat.BitsPerSample / 8) * channelStream.WaveFormat.Channels;
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
Pen pen1 = new Pen(Color.Gray);
int size = data.Length;
string hexValue1 = "#009adf";
Color colour1 = System.Drawing.ColorTranslator.FromHtml(hexValue1);
pen1.Color = colour1;
Stream wavestream = new NAudio.Wave.Mp3FileReader(strPath, wf => new NAudio.FileFormats.Mp3.DmoMp3FrameDecompressor(wf));
wavestream.Position = 0;
int bytesRead1;
byte[] waveData1 = new byte[samplesPerPixel * bytesPerSample];
wavestream.Position = startPosition + (width * bytesPerSample * samplesPerPixel);
for (float x = 0; x < width; x++)
{
short low = 0;
short high = 0;
bytesRead1 = wavestream.Read(waveData1, 0, samplesPerPixel * bytesPerSample);
if (bytesRead1 == 0)
break;
for (int n = 0; n < bytesRead1; n += 2)
{
short sample = BitConverter.ToInt16(waveData1, n);
if (sample < low) low = sample;
if (sample > high) high = sample;
}
float lowPercent = ((((float)low) - short.MinValue) / ushort.MaxValue);
float highPercent = ((((float)high) - short.MinValue) / ushort.MaxValue);
float lowValue = height * lowPercent;
float highValue = height * highPercent;
g.DrawLine(pen1, x, lowValue, x, highValue);
}
}
string filename = Server.MapPath("image/060.png");
bmp.Save(filename);
bmp.Dispose();
}
catch (Exception e)
{
}
}
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;
}
}
Based on Illaya's code:
public void CreateWaveForm(string audioFilePath, string audioWaveFormFilePath)
{
try
{
int bytesPerSample = 0;
using (NAudio.Wave.Mp3FileReader reader = new NAudio.Wave.Mp3FileReader(audioFilePath, wf => new NAudio.FileFormats.Mp3.DmoMp3FrameDecompressor(wf)))
{
using (NAudio.Wave.WaveChannel32 channelStream = new NAudio.Wave.WaveChannel32(reader))
{
bytesPerSample = (reader.WaveFormat.BitsPerSample / 8) * channelStream.WaveFormat.Channels;
//Give a size to the bitmap; either a fixed size, or something based on the length of the audio
using (Bitmap bitmap = new Bitmap((int)Math.Round(reader.TotalTime.TotalSeconds * 40), 200))
{
int width = bitmap.Width;
int height = bitmap.Height;
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.Clear(Color.White);
Pen bluePen = new Pen(Color.Blue);
int samplesPerPixel = (int)(reader.Length / (double)(width * bytesPerSample));
int bytesPerPixel = bytesPerSample * samplesPerPixel;
int bytesRead;
byte[] waveData = new byte[bytesPerPixel];
for (float x = 0; x < width; x++)
{
bytesRead = reader.Read(waveData, 0, bytesPerPixel);
if (bytesRead == 0)
break;
short low = 0;
short high = 0;
for (int n = 0; n < bytesRead; n += 2)
{
short sample = BitConverter.ToInt16(waveData, n);
if (sample < low) low = sample;
if (sample > high) high = sample;
}
float lowPercent = ((((float)low) - short.MinValue) / ushort.MaxValue);
float highPercent = ((((float)high) - short.MinValue) / ushort.MaxValue);
float lowValue = height * lowPercent;
float highValue = height * highPercent;
graphics.DrawLine(bluePen, x, lowValue, x, highValue);
}
}
bitmap.Save(audioWaveFormFilePath);
}
}
}
}
catch
{
}
}