【问题标题】:High quality graph/waveform display component in C#C#中的高质量图形/波形显示组件
【发布时间】:2011-01-03 18:29:58
【问题描述】:

我正在寻找一个快速、专业且可自定义的 C# 波形显示组件。

我想在时域和频域中主要显示实时音频波形(快!)。我希望能够缩放、更改轴设置、显示多个通道、自定义感觉和颜色等...

任何人都知道任何事情,无论是否商业?

谢谢!

迭戈

【问题讨论】:

  • 作为 Gigasoft 的创始人,请参阅我们的 DirectX /Direct3D C# charting wav data demo, example 123 该演示展示了 WinForms、WPF 和 C++/MFC 纯本机中的 exe。实时更新垂直线标注播放位置,显示12M点连续更新无延迟。还显示了一个简单的自定义 x 轴分钟:秒。可通过鼠标和鼠标滚轮进行缩放。

标签: c# waveform


【解决方案1】:

基于 Illaya 的代码:

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

【讨论】:

  • 上面的代码可以用来从 MP4 文件生成波形吗?
【解决方案2】:

这将使用 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;
}

}

【讨论】:

  • Illaya 的代码中有很多多余的变量,一些误算等。我将在下面发布我清理后的修改版本,因为它对于 cmets-box 来说太多了。
  • @Illaya naudio 可以用来从 MP4 文件生成波形吗?
【解决方案3】:

查看 Zedgraph。这是一个免费的图形库,效果很好。他们的网站上有很多代码示例,可让您按照您的要求进行操作。 Zedgraph Downloads 他们的网站现在似乎有问题,但下载会话可以正常工作并包含他们所有的示例文件。

【讨论】:

    【解决方案4】:

    【讨论】:

      【解决方案5】:

      据我所知,民族乐器有一些很酷的控制,但它不是免费的。

      http://sine.ni.com/psp/app/doc/p/id/psp-317

      免费的:

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

      【讨论】:

        【解决方案6】:

        不久前我遇到了一个正在执行此操作的代码项目。

        查看http://www.codeproject.com/KB/miscctrl/GraphComponents.aspx,这可能是您正在寻找的在 .net 中进行实时绘图的工具

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-05
          • 2011-07-21
          • 2016-09-29
          • 1970-01-01
          • 2011-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多