Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
        //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;
                }
            }
        }
Exemplo n.º 3
0
        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();
            }
        }
Exemplo n.º 4
0
        protected virtual void ApplyReset()
        {
            Log.Debug("Resetting preprocessing pipeline");

            _resamplerInput.Reset();
            _resampler.Reset();
            _resampledOutput.Reset();

            _arv.Reset();
            _droppedFrames = 0;

            _resetApplied = true;
        }
Exemplo n.º 5
0
        protected virtual void ApplyReset()
        {
            Log.Debug("Resetting preprocessing pipeline");

            _resamplerInput.Reset();
            _resampler.Reset();
            _resampledOutput.Reset();

            _arv.Reset();
            _droppedSamples = 0;

            SendResetToSubscribers();

            _resetApplied = true;
        }
Exemplo n.º 6
0
        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;
                    }
                }
            }
        }