2013-06-29 158 views
0

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

一个n音讯的教程,他以字节数组的作品绘制在Chart.It波形是好的,如果你知道WAV大小file.However它的工作速度太慢,给了内存溢出异常更大的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)); 
     } 
    } 

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

+0

作为Gigasoft创始人,看到我们的[的DirectX/Direct3D的图表WAV数据演示,例如123(http://www.gigasoft.com)该演示展示了在WinForms的EXE文件, WPF和C++/MFC纯原生。通过垂直线条注释实时更新播放位置,显示12M点连续更新,播放和拖动视口时无延迟。还显示简单的定制x分钟:秒。可通过鼠标和鼠标滚轮进行缩放。显示当前缩放区域的缩放框以及全部通道波形。它的图表与Adobe Audition或Nero波形编辑器类似,只需几行代码。 – Robert

回答

4

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

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

+0

谢谢你的回复。我会牢记这些.. – Blast

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

我们如何对Webm文件做同样的事情? –