2012-05-24 94 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; 
});