NAudio WasapiLoopbackCapture间歇性声音

时间:2015-10-19 01:36:04

标签: c# mp3 wav naudio

第1部分 我有一些与NAudio相关的代码

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

通过声音录制过程的初始化,我有以下的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文件,它绝对没问题,但如果我通过ConvertWavToMp3方法尝试MP3转换,那么声音会变慢间歇性的,这个实现有什么问题?

1 个答案:

答案 0 :(得分:1)

第一部分,您假设缓冲区长度与缓冲区中的有效字节数相同。尝试:

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

让输出流自动处理冲洗。尝试强制数据到磁盘将无法工作或在某些情况下可能导致意外结果,如部分块写入可能会干扰您的数据。在录制结束时冲洗,而不是在录制期间。

至于第二部分......

您的代码正在创建一个文件,该文件是一系列MP3文件的串联,一个用于传递给WaveInDataAvailable方法的每个缓冲区,并包含这些缓冲区末尾的所有空白区域。当然,它不会正常播放。

如果您想要编写MP3,请直接进行。让_waveInFileStream成为LameMP3FileWriter的实例,让它自己处理工作。这不仅可以产生更有用的输出,而且可以为您收到的每个数据块设置和拆除编码器,从而节省大量的低效率。