I've been writing an app that records chunks of input audio to multiple files, with gaps between, but I discovered that if I try a call sequence which essentially boils down to this:
WasapiCapture client = new WasapiCapture();
// set up output processor for file 1
client.StartRecording();
// wait for end of content for file 1
client.StopRecording();
// set up output processor for file 2
client.StartRecording();
then the second StartRecording() fails inside InitializeCaptureDevice() at the call to audioClient.Initialize()
I was able to work around this by disposing of my WasapiCapture client and constructing a new one each time, because my system load was low enough that I didn't care about the needless thread destroy/create and whatever the overhead of fetching a new IAudioClient
might be. In other circumstances all that unnecessary work might be a problem though.
I see the MS documentation for IAudioClient states that "the client must successfully call
Initialize once and only once to initialize the audio stream between the client and the device" (italics mine), so I'm thinking some strategy where NAudio remembers the WaveFormat it uses in a call to audioClient.Initialize() and on
subsequent calls to InitializeCaptureDevice(), throws if a recording is active, does nothing if the WaveFormat has not changed, or disposes the old audioClient and initializes a new one if the WaveFormat has changed. Doing something like that would probably
also need some modification to CaptureThread so that it didn't exit until the WasapiCapture object is disposed.
Comments: Just committed on the ReuseableWasapiCapture fork. I did add a simple NUnit test, can't say I'm ready to say it's trustworthy yet, but it's good enough to go home on a Friday night.
WasapiCapture client = new WasapiCapture();
// set up output processor for file 1
client.StartRecording();
// wait for end of content for file 1
client.StopRecording();
// set up output processor for file 2
client.StartRecording();
then the second StartRecording() fails inside InitializeCaptureDevice() at the call to audioClient.Initialize()
I was able to work around this by disposing of my WasapiCapture client and constructing a new one each time, because my system load was low enough that I didn't care about the needless thread destroy/create and whatever the overhead of fetching a new IAudioClient
might be. In other circumstances all that unnecessary work might be a problem though.
I see the MS documentation for IAudioClient states that "the client must successfully call
Initialize once and only once to initialize the audio stream between the client and the device" (italics mine), so I'm thinking some strategy where NAudio remembers the WaveFormat it uses in a call to audioClient.Initialize() and on
subsequent calls to InitializeCaptureDevice(), throws if a recording is active, does nothing if the WaveFormat has not changed, or disposes the old audioClient and initializes a new one if the WaveFormat has changed. Doing something like that would probably
also need some modification to CaptureThread so that it didn't exit until the WasapiCapture object is disposed.
Comments: Just committed on the ReuseableWasapiCapture fork. I did add a simple NUnit test, can't say I'm ready to say it's trustworthy yet, but it's good enough to go home on a Friday night.