【问题标题】:C# Real time waveform data plot using NAudio使用 NAudio 绘制 C# 实时波形数据
【发布时间】:2013-06-29 08:27:17
【问题描述】:

我是处理 wav 文件和 C# 的新手。我的目标是在 wavfile 的波形中绘制实时数据。我的意思是在录制声音(wav)文件时,我想同时绘制它的图表。我搜索了一些声音库和决定使用 NAudio。(不知道它对我来说是最好的选择。我愿意接受有关选择音频库的任何建议)。但是我不知道使用声音绘制实时数据。有些人建议使用 GDI,但正如我所说,我是新手,我认为有效使用 GDI 需要花费太多时间。如果我必须学习 GDI,请分享任何可以帮助像我这样的初学者的文章。其实我看起来不知道我应该从哪里开始。需要指导 :)) 我有一个问题。

NAudio 的教程之一,他使用字节数组在 Chart 中绘制波形。如果你知道 wav 文件的大小就可以了。但是它的工作速度太慢,并且对于更大的 wav 文件会出现内存不足异常10mb。下面的代码是指我的意思。

    OpenFileDialog open = new OpenFileDialog();
    open.Filter = "Wave File (*.wav)|*.wav;";
    if (open.ShowDialog() != DialogResult.OK) return;
    chart1.Series.Add("wave");
    chart1.Series["wave"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
    chart1.Series["wave"].ChartArea = "ChartArea1";
    NAudio.Wave.WaveChannel32 wave = new NAudio.Wave.WaveChannel32(new NAudio.Wave.WaveFileReader(open.FileName));

    byte[] buffer = new byte[426565];
    int read;
    while (wave.Position < wave.Length)
    {
        read = wave.Read(buffer, 0, 426565);
        for (int i = 0; i < read / 4; i++)
        {
            chart1.Series["wave"].Points.Add(BitConverter.ToSingle(buffer, i * 4));
        }
    }

有没有办法更快地执行这个操作?

【问题讨论】:

  • 作为 Gigasoft 的创始人,请参阅我们的 DirectX /Direct3D Charting wav data demo, example 123 该演示展示了 WinForms、WPF 和 C++/MFC 纯本机中的 exe。通过垂直线注释实时更新播放位置,显示 12M 点在播放和拖动视口等时不断更新,没有延迟。还显示了一个简单的自定义 x 轴分钟:秒。可通过鼠标和鼠标滚轮进行缩放。显示当前缩放区域的缩放框以及通道的完整波形。它的图表类似于 Adob​​e Audition 或 Nero 波形编辑器,只需几行代码。

标签: c# naudio waveform real-time-data


【解决方案1】:

如果您绘制每个样本,您最终会得到一个大得无法控制的波形,因为音频通常每秒包含数千个样本。绘制波形的常用方法是选择一段时间内的最大值,然后画一条垂直线来表示它。例如,如果您有一首三分钟的歌曲,并且想要一个大约 600 像素宽的波形,那么每个像素将代表大约三分之一秒。所以你会在三分之一秒内找到最大的样本值,并用它来绘制你的波形。

此外,在您的示例代码中,您正在读取奇数个字节。但由于这是浮点音频,因此您应该始终以 4 个字节的倍数读取。

【讨论】:

    【解决方案2】:

    这对我有用

                WaveChannel32 wave = new WaveChannel32(new WaveFileReader(txtWave.Text));
                int sampleSize = 1024;
                var bufferSize = 16384 * sampleSize;
                var buffer = new byte[bufferSize];
                int read = 0;
                chart.Series.Add("wave");
                chart.Series["wave"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
                chart.Series["wave"].ChartArea = "ChartArea1";
                while (wave.Position < wave.Length)
                {
                    read = wave.Read(buffer, 0, bufferSize);
                    for (int i = 0; i < read / sampleSize; i++)
                    {
                        var point = BitConverter.ToSingle(buffer, i * sampleSize);
    
                        chart.Series["wave"].Points.Add(point);
                    }
                }
    

    【讨论】:

    • 我们如何对 Webm 文件做同样的事情?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    相关资源
    最近更新 更多