private void RaiseDataAvailable(WaveInBuffer buffer) { EventHandler <DataAvailableEventArgs> handler = this.DataAvailable; if (handler != null && buffer.WaveHeader.bytesRecorded > 0) { handler(this, new DataAvailableEventArgs(buffer.Buffer, 0, buffer.WaveHeader.bytesRecorded, WaveFormat)); } }
private void InitializeInternal() { var supportedFormats = new Queue <WaveFormat>(Device.SupportedFormats .OrderBy(x => Math.Abs(x.SampleRate - WaveFormat.SampleRate)) .ThenBy(x => Math.Abs(x.BitsPerSample - WaveFormat.BitsPerSample)) .ThenBy(x => Math.Abs(x.Channels - WaveFormat.Channels))); var finalFormat = WaveFormat; do { try { _waveInHandle = CreateWaveInHandle(finalFormat); } catch (MmException exception) { if (exception.Result == MmResult.BadFormat && supportedFormats.Count > 0) { finalFormat = supportedFormats.Dequeue(); } else if (exception.Result == MmResult.BadFormat && supportedFormats.Count == 0) { throw new Exception("No valid format could be found.", exception); } else { throw; } } } while (_waveInHandle == IntPtr.Zero); _failedBuffers.Clear(); var bufferSize = (int)WaveFormat.MillisecondsToBytes(_latency); _buffers = new WaveInBuffer[BufferCount]; for (int i = 0; i < _buffers.Length; i++) { _buffers[i] = new WaveInBuffer(_waveInHandle, bufferSize, (IntPtr)i); } }
private void FireUpBuffer(WaveInBuffer buffer) { buffer.AddBufferToQueue(); Interlocked.Increment(ref _activeBuffers); }
private void Callback(IntPtr handle, WaveMsg msg, IntPtr user, WaveHeader header, IntPtr reserved) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId + "|" + msg); if (_waveInHandle != handle) { return; } if (msg == WaveMsg.WIM_DATA) { if (_callbackThread == null) { _callbackThread = Thread.CurrentThread; } //Debug.Assert(_callbackThread == Thread.CurrentThread, "Strange thread?"); if (_callbackThread != Thread.CurrentThread) { Debugger.Break(); } var index = (int)header.userData; WaveInBuffer buffer = _buffers[index]; Interlocked.Decrement(ref _activeBuffers); if (Monitor.TryEnter(_lockObj, 10)) { try { callback0: //only add buffer to queue again, if we are still recording if (buffer != null && RecordingState != RecordingState.Stopped) { try { //todo: should we care about recordingstate when firing dataavailable? RaiseDataAvailable(buffer); FireUpBuffer(buffer); } catch (Exception exception) { StopFromCallback(exception); } } if (_failedBuffers.Count > 0) { while (_failedBuffers.Count > 0 && (buffer = _buffers[(index = _failedBuffers.Dequeue())]).IsInQueue == false) { Debug.WriteLine("Already queued."); } if (buffer != null && !buffer.IsInQueue) { Debug.WriteLine("Failed buffer: " + index); goto callback0; } } } finally { Monitor.Exit(_lockObj); } } else { _failedBuffers.Enqueue(index); } if (_activeBuffers <= 0) { StopFromCallback(null); } _callbackThread = null; } else if (msg == WaveMsg.WIM_CLOSE) { if (RecordingState != RecordingState.Stopped) { StopFromCallback(null); } } }