Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NAudio InvalidOperationException when constructing WaveIn

I am very new to NAudio and am trying to write a small program that records some audio from a microphone and writes it to a Wave file. When I call the recordStuff() function in the Main function of my program, the program doesn't get past the construction on the WaveIn object and the program dies with an InvalidOperationException that has the message "Use WaveInEvent to record on a background thread". Could someone with knowledge of NAudio maybe tell me what this means? I have tried calling the recordStuff() function in it's own thread, but I end up with the same result.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NAudio.Wave;

namespace SimpleWave
{
    class Recorder
    {
        public Recorder()
        {
            writer = new WaveFileWriter("C:\\Users\\Paul\\Desktop\\yeah.wav", new NAudio.Wave.WaveFormat(44100, 1));
        }

        public static List<byte> buff = new List<byte>();
        public static WaveFileWriter writer;

        public void recordStuff()
        {
            // WaveIn Streams for recording
            WaveIn waveInStream;

            waveInStream = new WaveIn();
            waveInStream.DeviceNumber = 0;
            waveInStream.WaveFormat = new WaveFormat(44100, 2);
            writer = new WaveFileWriter(@"C:\Users\Paul\Desktop\this.wav", waveInStream.WaveFormat);

            waveInStream.DataAvailable += new EventHandler<WaveInEventArgs>(waveInStream_DataAvailable);
            waveInStream.StartRecording();
        }

        public void waveInStream_DataAvailable(object sender, WaveInEventArgs e)
        {
            writer.Write(e.Buffer, 0, e.BytesRecorded);
        }
    }
}
like image 213
Matt Vaughan Avatar asked Jan 14 '13 04:01

Matt Vaughan


1 Answers

The default WaveIn constructor uses Windows messages for callbacks. However, if you are running a console app, or from a background thread, those Windows messages will not get processed. The easiest solution is to use the WaveInEvent class instead.

waveInStream = new WaveInEvent();

Another problem with your code is that you need to keep waveInStream alive until you've finished recording (i.e. you'll need to be able to call StopRecording at some point), so you should make waveInStream a field of the Recorder class.

like image 92
Mark Heath Avatar answered Nov 19 '22 10:11

Mark Heath