Reputation: 146910
I'm using WaveInEvent
of NAudio
to record microphone data. It works fine for a while, but after a few times, it stops providing input data- the DataAvailable
callback is never called with new data.
I have tried creating a new WaveInEvent
each time, but this did not resolve the problem. I've also tried using the WASAPI input, which always called DataAvailable
- with zero bytes of data.
How can I record audio from the microphone reliably with NAudio
?
Currently, my code looks like this:
StartRecording() {
microphone = new WaveInEvent();
microphone.DeviceNumber = 0;
microphone.WaveFormat = outformat;
microphone.BufferMilliseconds = 50;
microphone.DataAvailable += (_, recArgs) =>
{
session.OnAudioData(recArgs.Buffer, recArgs.BytesRecorded);
};
microphone.StartRecording();
}
StopRecording() {
if (microphone != null)
{
microphone.StopRecording();
microphone.Dispose();
microphone = null;
}
}
There's no other naudio code in the project except using WaveFormat to describe wave formats.
NAudio throws an access violation exception trying to call WaveInBuffer.Reuse() from a threadpool worker. I'm not sure why this doesn't do something more serious than just drop audio data.
For the condition where I did not recreate the WaveInEvent, I get an MmException instead- invalid handle calling waveInPrepareHeader, in the same place.
Frankly, the fact that I get different results heavily implies that NAudio is doing some funky shit it shouldn't to share state between instances, and looking at the source on Codeplex, I'm not really sure WTF is going on.
Upvotes: 2
Views: 1644
Reputation: 41
I had the same problem with you and i use WaveOut event in combination with WaveInEvent to solve the problem. For a mysterious reason, when used with WaveOut, WaveIn keeps recording infinitely:
var waveIn = new WaveInEvent();
waveIn.DeviceNumber = 0;
waveIn.WaveFormat = new WaveFormat(44100, 1);
var sampleProvider = new WaveInProvider(waveIn);
var volumeProvider = new VolumeSampleProvider(sampleProvider.ToSampleProvider());
volumeProvider.Volume = 0f; //Set the volume to 0 to turn off the sound
var waveOut = new WaveOutEvent();
waveOut.Init(volumeProvider);
waveIn.DataAvailable += (sender, e) =>
{
.......
}
waveIn.StartRecording();
waveOut.Play();
Upvotes: 0
Reputation: 146910
It seems that the drivers for the USB microphone do not behave correctly. When the buffer is sent to the user through the WIM_DATA message, it is full. However when waveInUnprepareHeader is called, it's still in the queue, even though it was literally just passed as full. So I think that the drivers for the microphone are ultimately to blame.
I've been looking more closely at the microphone and it seems that this particular unit is actually known to have been damaged.
Upvotes: 1