public virtual void StopCapture() { Log.AssertAndThrowPossibleBug(_clip != null, "CDDAE69D-44DC-487F-9B69-4703B779400E", "Attempted to stop microphone capture, but it is already stopped"); //Stop diagnostic output if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } //Stop capture Microphone.End(_micName); _format = null; _clip = null; _readHead = 0; _started = false; _micName = null; //Clean the buffers _rawMicSamples.Reset(); _rawMicFrames.Reset(); //Stop watching for device changes AudioSettings.OnAudioConfigurationChanged -= OnAudioDeviceChanged; _audioDeviceChanged = false; }
public void Handle(ArraySegment <float> inputSamples, WaveFormat format) { if (_resetRequired) { Log.Trace("Resetting encoder pipeline"); _resampler.Reset(); _input.Reset(); _output.Reset(); _resetRequired = false; } if (!format.Equals(_inputFormat)) { throw new ArgumentException(string.Format("Samples expected in format {0}, but supplied with format {1}", _inputFormat, format), "format"); } if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.WriteSamples(inputSamples); } //Write samples to the pipeline (keep a running total of how many we have sent) //Keep sending until we've sent all of these samples var offset = 0; while (offset != inputSamples.Count) { offset += _input.Write(inputSamples.Array, offset + inputSamples.Offset, inputSamples.Count - offset); //Drain some of those samples just written, encode them and send them off EncodeFrames(); } }
//These methods run on the main thread, they drain audio from the mic and send it across to the other thread for proper processing // // Update - Either discard mic samples (if no one is subscribed to mic data) or call DrainMicSamples // DrainMicSamples - Read as many samples as possible from the mic (using a set of pow2 sized buffers to get as // much as possible), passes samples to ConsumeMicSamples // ConsumeMicSamples - Take some number of samples from produced by DrainMicSamples and buffer them up, call SendFrame // every time some samples are added to the buffer // SendFrame - Read as many frames as possible from the buffer and send them to the other thread. Also poke the other thread // to tell it that it has work to do public void Update() { if (!_started) { _readHead = Microphone.GetPosition(_micName); _started = _readHead > 0; if (!_started) { return; } } if (_preprocessing.RequiresInput) { //Read samples from clip into mic sample buffer DrainMicSamples(); } else { //We're not interested in the audio from the mic, so skip the read head to the current mic position and drop all the audio _readHead = Microphone.GetPosition(_micName); _rawMicSamples.Reset(); _rawMicFrames.Reset(); _preprocessing.Reset(); if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } } }
public void Reset() { if (_disposed) { return; } using (_encoder.Lock()) { Log.Debug("Applying encoder reset"); _resampler.Reset(); _input.Reset(); _output.Reset(); _stopping = false; _stopped = false; } }
public void ReceiveMicrophoneData(ArraySegment <float> inputSamples, [NotNull] WaveFormat format) { if (format == null) { throw new ArgumentNullException("format"); } if (!format.Equals(_inputFormat)) { throw new ArgumentException(string.Format("Samples expected in format {0}, but supplied with format {1}", _inputFormat, format), "format"); } using (var encoderLock = _encoder.Lock()) { var encoder = encoderLock.Value; //Early exit if we have been disposed on the main thread if (_disposed) { return; } //Apply a reset if one is pending if (_resetRequired) { Log.Trace("Resetting encoder pipeline"); _resampler.Reset(); _input.Reset(); _output.Reset(); _resetRequired = false; Stopping = false; Stopped = false; } //Early exit if we've sent the last frame of this stream if (Stopped) { return; } //Propogate the loss value on to the encoder encoder.PacketLoss = TransmissionPacketLoss; //Write samples to the pipeline (keep a running total of how many we have sent) //Keep sending until we've sent all of these samples var offset = 0; var stopping = Stopping; while (offset != inputSamples.Count) { // ReSharper disable once AssignNullToNotNullAttribute (Justification: Array segment cannot be null) offset += _input.Write(new ArraySegment <float>(inputSamples.Array, inputSamples.Offset + offset, inputSamples.Count - offset)); //Drain some of those samples just written, encode them and send them off //If we're shutting down send a maximum of 1 packet var encodedFrames = EncodeFrames(encoder, stopping ? 1 : int.MaxValue); //Don't encode any more frames if we've sent the one final frame if (encodedFrames > 0 && stopping) { Stopped = true; break; } } } }