2015-10-19 3 views
0

Часть 1
У меня есть NAudio код, связанныйNAudio WasapiLoopbackCapture прерывистый звук

private void InitAudioOut(DateTime dtNow) 
    { 
     _pathOut = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} OUT).wav", dtNow); 

     _waveOut = new WasapiLoopbackCapture(); 
     _waveOut.DataAvailable += WaveOutDataAvailable; 
     _waveOut.RecordingStopped += WaveOutRecordStopped; 

     _waveOutFileStream = new WaveFileWriter(_pathOut, _waveOut.WaveFormat); 

     _waveOut.StartRecording(); 
    } 

С этой инициализации процесса записи звука я имею followind WaveOutDataAvailable метод:

private void WaveOutDataAvailable(object sender, WaveInEventArgs e) 
    { 
     var buf= e.Buffer; 
     _waveOutFileStream.Write(buf, 0, buf.Length); 
     _waveOutFileStream.Flush(); 
    } 

звука в результирующий файл прерывистый и медленный, например, наличие «пустых» разделов между звуковыми фрагментами, любые идеи приветствуются.

Конец части 1

Часть 2
Существует другая версия этого кода, где я пытаюсь преобразовать поток WAV в MP3 поток на лету, а затем записать его в файл, это выглядит следующим образом :

private void InitAudioIn(DateTime dtNow) 
    { 
     _pathIn = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} IN).mp3", dtNow); 
     _waveIn = new WaveInEvent(); 
     _waveIn.WaveFormat = new WaveFormat(44100, 2); 

     _waveIn.DataAvailable += WaveInDataAvailable; 
     _waveIn.RecordingStopped += WaveInRecordStopped; 

     _waveInFileStream = File.Create(_pathIn); 

     _waveIn.StartRecording(); 
    } 

с WaveInDataAvailable метода следующим образом: метод

private void WaveInDataAvailable(object sender, WaveInEventArgs e) 
    { 
     var wavToMp3Buffer = ConvertWavToMp3(e.Buffer, _waveIn.WaveFormat); 
     _waveInFileStream.Write(wavToMp3Buffer, 0, wavToMp3Buffer.Length); 
     _waveInFileStream.Flush(); 
    } 

ConvertWavToMp3:

public byte[] ConvertWavToMp3(byte[] wavContent, WaveFormat waveFormat) 
    { 
     using (var baseMemoryStream = new MemoryStream()) 
     using (var wavToMp3Writer = new LameMP3FileWriter(baseMemoryStream, waveFormat, 64)) 
     { 
      wavToMp3Writer.Write(wavContent, 0, wavContent.Length); 
      wavToMp3Writer.Flush(); 
      return baseMemoryStream.ToArray(); 
     } 
    } 

Если я не пытаюсь конвертировать его в MP3 и просто записать его в файл WAV, что это абсолютно нормально, но если я пытаюсь преобразование MP3 с помощью метода ConvertWavToMp3 то звук становится медленным и прерывистым, что не так с этой реализацией?

ответ

1

В первой части вы делаете недопустимое предположение о том, что длина буфера совпадает с количеством действительных байтов в буфере. Попытайтесь:

private void WaveOutDataAvailable(object sender, WaveInEventArgs e) 
{ 
    _waveOutFileStream.Write(e.Buffer, 0, e.BytesRecorded); 
} 

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

Что касается второй части ...

Вашего кода создает файл, который является конкатенацией серии MP3-файлов, по одному для каждого буфера передается в ваш метод WaveInDataAvailable, и в том числе всего пустого пространства в конец этих буферов. Конечно, это не будет правильно воспроизводиться.

Если вы хотите написать MP3, сделайте это напрямую. Сделайте свой _waveInFileStream экземпляром LameMP3FileWriter и дайте ему обработать саму работу. Мало того, что это будет производить гораздо более полезный результат, но вы сэкономите себя на множестве неэффективных беспорядков с настройкой и разрывом кодировщика для каждого получаемого вами блока данных.

+0

Убрано Flush, изменил метод записи, как вы предлагали, задайте, чтобы писатель файлов был напрямую LameMP3FIleWriter, результат PERFECT, 100% точная запись, спасибо! – HardLuck