private void WorkerThread()
{
// Get the selected capture device
DirectSoundCapture captureDevice = new DirectSoundCapture(device);
// Set the capture format
var bitsPerSample = Signal.GetSampleSize(sampleFormat);
WaveFormat format = WaveFormat.CreateCustomFormat(sampleFormat.ToWaveFormat(), sampleRate, 1,
sampleRate * bitsPerSample / 8, bitsPerSample / 8, bitsPerSample);
// Setup the capture buffer
CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription();
captureBufferDescription.Format = format;
captureBufferDescription.BufferBytes = 2 * desiredCaptureSize * format.BlockAlign;
captureBufferDescription.Flags |= CaptureBufferCapabilitiesFlags.WaveMapped;
captureBufferDescription.Flags &= ~CaptureBufferCapabilitiesFlags.ControlEffects;
CaptureBuffer captureBuffer = null;
NotificationPosition[] notifications = new NotificationPosition[2];
try
{
captureBuffer = new CaptureBuffer(captureDevice, captureBufferDescription);
// Setup the notification positions
int bufferPortionSize = captureBuffer.Capabilities.BufferBytes / 2;
notifications[0] = new NotificationPosition();
notifications[0].Offset = bufferPortionSize - 1;
notifications[0].WaitHandle = new AutoResetEvent(false);
notifications[1] = new NotificationPosition();
notifications[1].Offset = bufferPortionSize - 1 + bufferPortionSize;
notifications[1].WaitHandle = new AutoResetEvent(false);
captureBuffer.SetNotificationPositions(notifications);
// Make a copy of the wait handles
WaitHandle[] waitHandles = new WaitHandle[notifications.Length];
for (int i = 0; i < notifications.Length; i++)
waitHandles[i] = notifications[i].WaitHandle;
// Start capturing
captureBuffer.Start(true);
if (sampleFormat == SampleFormat.Format32BitIeeeFloat)
{
float[] currentSample = new float[desiredCaptureSize];
while (!stopEvent.WaitOne(0, true))
{
int bufferPortionIndex = WaitHandle.WaitAny(waitHandles);
captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None);
OnNewFrame(currentSample);
}
}
else if (sampleFormat == SampleFormat.Format16Bit)
{
short[] currentSample = new short[desiredCaptureSize];
while (!stopEvent.WaitOne(0, true))
{
int bufferPortionIndex = WaitHandle.WaitAny(waitHandles);
captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None);
OnNewFrame(currentSample);
}
}
}
catch (Exception ex)
{
if (AudioSourceError != null)
AudioSourceError(this, new AudioSourceErrorEventArgs(ex.Message));
else throw;
}
finally
{
if (captureBuffer != null)
{
captureBuffer.Stop();
captureBuffer.Dispose();
}
if (captureDevice != null)
captureDevice.Dispose();
for (int i = 0; i < notifications.Length; i++)
if (notifications[i].WaitHandle != null)
notifications[i].WaitHandle.Close();
}
}