Search code examples
c#audioaudio-recordingnaudionaudio-framework

Copy and update content of actively recording Wav file to a new file


I have an active audio recording happening in WAV format with NAudio Library.

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

I want to copy the latest available content to another location. The copied file should be in WAV format, and should be able to play the available duration. Update the destination file, whenever more content is available.

I have Tried the following sample code (using NAudio) with a static WAV file, but the solution is not working.

  1. The resulting WAV file created is corrupted - not in the correct format.

    using (WaveFileReader reader = new WaveFileReader(remoteWavFile))
    {
      byte[] buffer = new byte[reader.Length];
      int read = reader.Read(buffer, 0, buffer.Length);           
    }
    
  2. When the recording is in progress, the code throws an exception "File is in use by another application".


Solution

  • I have solved the problem with help of NAudio Library itself.

    1. When we only use the WaveFileReader class of NAudio. It will throw the exception - "file is in use by another application". So I had to create a file stream, which opens the source file - live recording file, with File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) then pass this stream as an input of WaveFileReader.

    2. Then create a WaveFileWritter class of NAudio, with the same WavFormat of the reader.

    copied below is the code, i have used.

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