Search code examples
c#xnadirectxaudio-recordingnaudio

Record live audio from mic input and save simultanously


I was trying to develop a Voice recorder in C#. I have tried many ways, like NAudio, DirectX, Microsoft.Xna.Framework.Audio, etc.

Everything gives the same result. After we stop the recording, the output file mp3/wav get saved.

The mp3/wav file get created at the beginning itself (without and content - 0 bytes)

I am trying to create an application which can save audio live/simultaneously.

    private void StartRecording() {
        this.WaveSource = new WaveInEvent { WaveFormat = new WaveFormat(44100, 1) };

        this.WaveSource.DataAvailable += this.WaveSourceDataAvailable;
        this.WaveSource.RecordingStopped += this.WaveSourceRecordingStopped;

        this.WaveFile = new WaveFileWriter(@"C:\Sample.wav", this.WaveSource.WaveFormat);

        this.WaveSource.StartRecording();
    }

    private void StopRecording() {
        this.WaveSource.StopRecording();
    }

    void WaveSourceDataAvailable(object sender, WaveInEventArgs e) {
        if (this.WaveFile != null) {
            this.WaveFile.Write(e.Buffer, 0, e.BytesRecorded);
            this.WaveFile.Flush();
        }
    }

    void WaveSourceRecordingStopped(object sender, StoppedEventArgs e) {
        if (this.WaveSource != null) {
            this.WaveSource.Dispose();
            this.WaveSource = null;
        }

        if (this.WaveFile != null) {
            this.WaveFile.Dispose();
            this.WaveFile = null;
        }
    }

Solution

  • I have solved the problem with NAudio library itself. Few modification to the existing code.

    public class Recorder {
    
        WaveIn sourceStream;
        WaveFileWriter waveWriter;
        readonly String FilePath;
        readonly String FileName;
        readonly int InputDeviceIndex;
    
        public Recorder(int inputDeviceIndex, String filePath, String fileName) {
            InitializeComponent();
            this.InputDeviceIndex = inputDeviceIndex;
            this.FileName = fileName;
            this.FilePath = filePath;
        }
    
        public void StartRecording(object sender, EventArgs e) {
            sourceStream = new WaveIn {
                DeviceNumber = this.InputDeviceIndex,
                WaveFormat =
                    new WaveFormat(44100, WaveIn.GetCapabilities(this.InputDeviceIndex).Channels)
            };
    
            sourceStream.DataAvailable += this.SourceStreamDataAvailable;
    
            if (!Directory.Exists(FilePath)) {
                Directory.CreateDirectory(FilePath);
            }
    
            waveWriter = new WaveFileWriter(FilePath + FileName, sourceStream.WaveFormat);
            sourceStream.StartRecording();
        }
    
        public void SourceStreamDataAvailable(object sender, WaveInEventArgs e) {
            if (waveWriter == null) return;
            waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
            waveWriter.Flush();
        }
    
        private void RecordEnd(object sender, EventArgs e) {
            if (sourceStream != null) {
                sourceStream.StopRecording();
                sourceStream.Dispose();
                sourceStream = null;
            }
            if (this.waveWriter == null) {
                return;
            }
            this.waveWriter.Dispose();
            this.waveWriter = null;
            recordEndButton.Enabled = false;
            Application.Exit();
            Environment.Exit(0);
        }
    }