0

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

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

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

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

4

2 回答 2

5

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

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

于 2013-07-01T06:50:20.663 回答
1

这对我有用

            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);
                }
            }
于 2015-10-24T19:12:51.247 回答