2013-06-29 187 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文件做同樣的事情? –