将主动录制的 Wav 文件的内容复制并更新到新文件

Posted

技术标签:

【中文标题】将主动录制的 Wav 文件的内容复制并更新到新文件【英文标题】:Copy and update content of actively recording Wav file to a new file 【发布时间】:2016-01-22 15:54:54 【问题描述】:

我正在使用NAudio Library 以 WAV 格式进行音频录制。

    private void RecordStart() 
        try 
            _sourceStream = new WaveIn 
                DeviceNumber = _recordingInstance.InputDeviceIndex,
                WaveFormat =
                    new WaveFormat(
                    44100,
                    WaveIn.GetCapabilities(_recordingInstance.InputDeviceIndex).Channels)
            ;

            _sourceStream.DataAvailable += SourceStreamDataAvailable;
            if (!Directory.Exists(_recordingInstance.AudioFilePath)) 
                Directory.CreateDirectory(_recordingInstance.AudioFilePath);
            

            WaveFileWriter _waveWriter = new WaveFileWriter(
                _recordingInstance.AudioFilePath + _recordingInstance.AudioFileName,
                _sourceStream.WaveFormat);
            _sourceStream.StartRecording();
         
        catch (Exception exception) 
            Log.Error("Recording failes", exception);
        
    

    private void SourceStreamDataAvailable(object sender, WaveInEventArgs e) 
        if (_waveWriter == null) return;
        _waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
        _waveWriter.Flush();
    

我想将最新的可用内容复制到另一个位置。复制的文件应该是 WAV 格式,并且应该能够播放可用的持续时间。只要有更多内容可用,就更新目标文件。

我已经使用静态 WAV 文件尝试了以下示例代码(使用 NAudio),但解决方案不起作用。

    生成的 WAV 文件已损坏 - 格式不正确。

    using (WaveFileReader reader = new WaveFileReader(remoteWavFile))
    
      byte[] buffer = new byte[reader.Length];
      int read = reader.Read(buffer, 0, buffer.Length);           
    
    

    录制过程中,代码抛出异常“文件正在被另一个应用程序使用”。

【问题讨论】:

“解决方案不起作用”是什么意思?它编译吗?它会抛出异常吗?它打你的狗吗?请更详细地描述问题。 我试图将内容读取到缓冲区,然后使用字节数组创建一个新文件。它复制了内容并创建了一个 WAV 文件。但无法播放文件。 所以您的第二个代码块显示您从波形文件中读取数据,但它对这些数据没有任何作用。写部分在哪里? 【参考方案1】:

我已经在 NAudio 库本身的帮助下解决了这个问题。

    当我们只使用 NAudio 的 WaveFileReader 类时。它会抛出异常 - “文件正在被另一个应用程序使用”。 所以我必须创建一个文件流,它使用File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) 打开源文件 - 实时录制文件,然后将此流作为 WaveFileReader 的输入传递。

    然后创建一个 NAudio 的 WaveFileWritter 类,与 reader 的 WavFormat 相同。

下面是我用过的代码。

   public static void CopyWavFile(string inPath, string outPath)
        using (var fs = File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (var reader = new WaveFileReader(fs))
                using (var writer = new WaveFileWriter(outPath, reader.WaveFormat))
                    reader.Position = 0;
                    var endPos = (int)reader.Length;                        
                    var buffer = new byte[1024];
                    while (reader.Position < endPos)
                        var bytesRequired = (int)(endPos - reader.Position);
                        if (bytesRequired <= 0) continue;
                        var bytesToRead = Math.Min(bytesRequired, buffer.Length);
                        var bytesRead = reader.Read(buffer, 0, bytesToRead);
                        if (bytesRead > 0)
                            writer.Write(buffer, 0, bytesRead);
                        
                    
                
                     
                   
    

【讨论】:

以上是关于将主动录制的 Wav 文件的内容复制并更新到新文件的主要内容,如果未能解决你的问题,请参考以下文章

通过 openAL 将录制的音频保存为 .wav

绘制录制声音时的奇怪频率

将 PCM 录制的数据写入 .wav 文件(java android)

将录制的音频从浏览器保存到 Python API 作为 WAV 文件

文件未正确复制到新位置

用 AVAudioRecorder 录制 WAV 格式文件?