High quality graph/waveform display component in C#
Asked Answered
E

6

8

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

Erichericha answered 11/1, 2010 at 13:41 Comment(1)
As Gigasoft founder, see our DirectX /Direct3D C# charting wav data demo, example 123 The demo shows exes in WinForms, WPF, and C++/MFC pure native. Real-time updated with play position of vertical line annotation showing 12M points continuously updated with no lag. Also shows an easy custom x axis of Minutes:Seconds. Zoom-able via mouse and mouse-wheel.Malik
K
5

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

Kal answered 11/1, 2010 at 16:36 Comment(0)
B
2

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

Budgerigar answered 11/1, 2010 at 16:49 Comment(0)
M
2

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
        {
        }
    }
Mignonne answered 16/1, 2014 at 8:49 Comment(1)
can the above code be used to generate wave from from an MP4 file?Microbarograph
F
1

That is a wave flow displayer

http://www.codeproject.com/KB/audio-video/wavecontrol.aspx

Fusee answered 8/4, 2010 at 6:39 Comment(0)
E
1

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.

Eightfold answered 10/3, 2011 at 0:10 Comment(0)
A
1

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;
}

}
Aeroplane answered 25/11, 2013 at 10:20 Comment(2)
There are a lot of superfluous variables, some miscalculations etc in Illaya's code. I'll post my cleaned up, modified version below because it's too much for the comments-box.Evieevil
@Aeroplane Can naudio be used to generate wave form from an MP4 file ?Microbarograph

© 2022 - 2024 — McMap. All rights reserved.