2012-05-24 67 views
2

我使用naudio(使用教程)lerning音頻編程。我的程序(C#.net winForms)我有記錄和停止按鈕。代碼如下:錄音波naudio liblary - 低質量的聲音

NAudio.Wave.WaveIn sourceStream = null; 
    NAudio.Wave.WaveFileWriter waveWriter = null; 

    private void RecordButton_Click(object sender, EventArgs e) 
    { 
     int deviceNumber = 0; 
     sourceStream = new NAudio.Wave.WaveIn(); 
     sourceStream.DeviceNumber = deviceNumber; 
     sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels); 

     sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable); 
     waveWriter = new NAudio.Wave.WaveFileWriter("d:\\a.wav", sourceStream.WaveFormat); 

     sourceStream.StartRecording(); 
    } 

    private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e) 
    { 
     if (waveWriter == null) return; 

     waveWriter.WriteData(e.Buffer, 0, e.BytesRecorded); 
     waveWriter.Flush(); 
    } 

    private void StopButton_Click(object sender, EventArgs e) 
    { 
      waveWriter.Dispose(); 
      waveWriter = null;  
    } 

它可以工作,但波形文件質量並不好 - 我錄製的聲音有很小的差距。我想要採樣率44100赫茲和採樣格式16位。

+0

難道是因爲麥克風不好? – banging

+0

不,我只有一個錄音設備(它與另一個商業程序一起使用) – Juss

+0

音頻質量如果您使用的是NAudio音源附帶的NAudioDemo應用程序,音質如何?另外,你使用的是哪種版本的NAudio? –

回答

1

我無法準確地複製您發現的內容,但我注意到DataAvailable事件沒有留下太多空間以阻止其他操作。一個簡單的Thread.Sleep(100);阻止應用程序。

假設你的連續寫入(和刷新)可能導致了這個問題,我實現了一個天真的Queue,它保持要寫入的字節並使用線程池中的一個線程完成實際的寫入。

DataAvailable事件現在看起來是這樣的:

Queue<byte[]> writebuffer = new Queue<byte[]>(); 

    private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e) 
    { 
     if (waveWriter == null) return; 

     byte[] realbytes = new byte[e.BytesRecorded]; 
     Array.Copy(e.Buffer, realbytes, e.BytesRecorded); 
     writebuffer.Enqueue(realbytes); 
    } 

StartRecording電話後我就排隊讀隊列和數據寫入數據流任務。如果我在該處添加延遲,應用程序不再停滯。

ThreadPool.QueueUserWorkItem((s) => 
{ 
    var keeprunning = true; 
    sourceStream.RecordingStopped += (rss, rse) => { keeprunning = false; }; 
    while(keeprunning) 
    { 
     if (writebuffer.Count==0) 
     { 
       Thread.Sleep(0); 
     } 
     else 
     { 
      var buf = writebuffer.Dequeue(); 
      waveWriter.Write(buf,0,buf.Length); 
      // Thread.Sleep(100); // for testing 
     } 
    } 
    waveWriter.Dispose(); 
    waveWriter = null; 
});