2012-05-24 5 views
2

Я занимаюсь звуковым программированием с использованием naudio (используя учебник). Im моя программа (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

Каково качество звука, например, если вы используете приложение NAudioDemo, которое поставляется с источником NAudio? Кроме того, какую версию NAudio вы используете? –

ответ

1

Я не смог точно воспроизвести то, что вы нашли, но я заметил, что событие DataAvailable не оставляет много места для блокировки других операций. Простой Thread.Sleep(100); останавливает приложение.

Предполагая, что ваша непрерывная запись (и промывка) может повлиять на проблему, я внедрил наивный Queue, который хранит байты для записи и использует поток из threadpool для фактической записи.

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