private void firstWriteHeaders() { // Create data header header.Header = new char[] { 'd', 'a', 't', 'a' }; header.Length = this.bytes; byte[] dataHeader = header.GetBytes(); // Create Wave format header format.FmtHeader = new char[] { 'f', 'm', 't', ' ' }; format.Length = 16; format.Channels = (short)this.channels; format.FormatTag = (short)sampleFormat.ToWaveFormat(); format.SamplesPerSecond = sampleRate; format.BitsPerSample = (short)this.bitsPerSample; format.BlockAlignment = (short)this.blockAlign; format.AverageBytesPerSecond = this.averageBitsPerSecond / 8; waveFormat = format.GetBytes(); // Create RIFF header riff.RiffHeader = new char[] { 'R', 'I', 'F', 'F' }; riff.WaveHeader = new char[] { 'W', 'A', 'V', 'E' }; riff.Length = this.bytes + dataHeader.Length + waveFormat.Length; byte[] riffHeader = riff.GetBytes(); // Write headers to allocate space waveStream.Write(riffHeader, 0, riffHeader.Length); waveStream.Write(waveFormat, 0, waveFormat.Length); waveStream.Write(dataHeader, 0, dataHeader.Length); }
/// <summary> /// Worker thread. /// </summary> /// private void WorkerThread() { // Get the selected capture device DirectSoundCapture captureDevice = new DirectSoundCapture(device); // Set the capture format WaveFormat format = new WaveFormat(); format.Channels = 1; format.SamplesPerSecond = sampleRate; format.FormatTag = sampleFormat.ToWaveFormat(); format.BitsPerSample = (short)Signal.GetSampleSize(sampleFormat); format.BlockAlignment = (short)(format.BitsPerSample / 8); format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment; // Setup the capture buffer CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription(); captureBufferDescription.Format = format; captureBufferDescription.BufferBytes = 2 * desiredCaptureSize * format.BlockAlignment; captureBufferDescription.WaveMapped = true; captureBufferDescription.ControlEffects = false; CaptureBuffer captureBuffer = null; NotificationPosition[] notifications = new NotificationPosition[2]; try { captureBuffer = new CaptureBuffer(captureDevice, captureBufferDescription); // Setup the notification positions int bufferPortionSize = captureBuffer.SizeInBytes / 2; notifications[0] = new NotificationPosition(); notifications[0].Offset = bufferPortionSize - 1; notifications[0].Event = new AutoResetEvent(false); notifications[1] = new NotificationPosition(); notifications[1].Offset = bufferPortionSize - 1 + bufferPortionSize; notifications[1].Event = 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].Event; } // 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); 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); 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].Event != null) { notifications[i].Event.Close(); } } } }
/// <summary> /// Worker thread. /// </summary> /// private void WorkerThread() { needToStop = false; // 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]; Signal signal = Signal.FromArray(currentSample, sampleRate, sampleFormat); while (!needToStop) { int bufferPortionIndex = WaitHandle.WaitAny(waitHandles); captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None); OnNewFrame(signal); } } else if (sampleFormat == SampleFormat.Format16Bit) { short[] currentSample = new short[desiredCaptureSize]; Signal signal = Signal.FromArray(currentSample, sampleRate, sampleFormat); while (!needToStop) { int bufferPortionIndex = WaitHandle.WaitAny(waitHandles); captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None); OnNewFrame(signal); } } } catch (Exception ex) { if (AudioSourceError == null) { throw; } AudioSourceError(this, new AudioSourceErrorEventArgs(ex)); } finally { if (captureBuffer != null) { captureBuffer.Stop(); captureBuffer.Dispose(); } if (captureDevice != null) { captureDevice.Dispose(); } #if !NETSTANDARD1_4 for (int i = 0; i < notifications.Length; i++) { if (notifications[i].WaitHandle != null) { notifications[i].WaitHandle.Close(); } } #endif } }