/// <summary> /// (Re)Start the transmission pipeline, getting to a state where we *can* send voice (but aren't yet) /// </summary> private void RestartTransmissionPipeline(string reason) { Log.Debug("Restarting transmission pipeline: '{0}'", reason); StopTransmissionPipeline(); //Clear the flag for requesting an explicit reset. //We're about to apply a reset so the request will be satisfied. _pendingResetRequest = false; //No point starting a transmission pipeline if the network is not a client if (_network == null || !_network.Mode.IsClientEnabled()) { return; } //Create new mic capture system var format = _microphone.StartCapture(_micName); //If we created a mic (can be null if e.g. there is no mic) if (format != null) { //Close and re-open all channels, propogating this restart to the receiving end _roomChannels.Refresh(); _playerChannels.Refresh(); //Create preprocessor and subscribe it to microphone (webrtc preprocessor always wants audio to drive VAD+AEC) _preprocessor = CreatePreprocessor(format); _preprocessor.UpstreamLatency = _microphone.Latency; _preprocessor.Start(); _microphone.Subscribe(_preprocessor); //Sub VAD listeners to preprocessor for (var i = 0; i < _activationListeners.Count; i++) { _preprocessor.Subscribe(_activationListeners[i]); } //Sub audio listeners to the preprocessor output for (var i = 0; i < _audioListeners.Count; i++) { var al = _audioListeners[i]; al.Reset(); _preprocessor.Subscribe(al); } //Create encoder (not yet subscribed to receive audio data, we'll do that later) Log.AssertAndThrowPossibleBug(_network != null, "5F33336B-15B5-4A85-9B54-54352C74768E", "Network object is unexpectedly null"); _encoder = new EncoderPipeline(_preprocessor.OutputFormat, _codecSettingsLoader.CreateEncoder(), _network); } else { Log.Warn("Failed to start microphone capture; local voice transmission will be disabled."); } }
/// <param name="micName"></param> /// <param name="source">Source to read frames from</param> private MicrophoneCapture([CanBeNull] string micName, AudioClip source) { if (source == null) { throw new ArgumentNullException("source", Log.PossibleBugMessage("capture source clip is null", "333E11A6-8026-41EB-9B34-EF9ADC54B651")); } _micName = micName; _clip = source; var captureFormat = new WaveFormat(1, source.frequency); _maxReadBufferPower = (byte)Math.Ceiling(Math.Log(0.1f * source.frequency, 2)); _preprocessing = new WebRtcPreprocessingPipeline(captureFormat); _preprocessing.Start(); //Ensure we have enough buffer size to contain several input frames to the preprocessor _rawMicSamples = new BufferedSampleProvider(captureFormat, _preprocessing.InputFrameSize * 4); _rawMicFrames = new SampleToFrameProvider(_rawMicSamples, (uint)_preprocessing.InputFrameSize); Log.Info("Began mic capture (SampleRate:{0} FrameSize:{1}, Buffer Limit:2^{2})", captureFormat.SampleRate, _preprocessing.InputFrameSize, _maxReadBufferPower); }
/// <summary> /// (Re)Start the transmission pipeline, getting to a state where we *can* send voice (but aren't yet) /// </summary> private void RestartTransmissionPipeline(string reason) { Log.Debug("Restarting transmission pipeline: '{0}'", reason); StopTransmissionPipeline(); //If capture has been specifically disabled, exit out of starting it if (_encounteredFatalException) { return; } #if !NCRUNCH Profiler.BeginSample("CapturePipelineManager: RestartTransmissionPipeline"); #endif try { //Clear the flag for requesting an explicit reset. //We're about to apply a reset so the request will be satisfied. _pendingResetRequest = false; //No point starting a transmission pipeline if the network is not a client if (_network == null || !_network.Mode.IsClientEnabled()) { return; } //Create new mic capture system var format = _microphone.StartCapture(_micName); //If we created a mic (can be null if e.g. there is no mic) if (format != null) { //Close and re-open all channels, propogating this restart to the receiving end _roomChannels.Refresh(); _playerChannels.Refresh(); //Create preprocessor and subscribe it to microphone (webrtc preprocessor always wants audio to drive VAD+AEC) _preprocessor = CreatePreprocessor(format); _preprocessor.UpstreamLatency = _microphone.Latency; _preprocessor.Start(); _microphone.Subscribe(_preprocessor); //Sub VAD listeners to preprocessor for (var i = 0; i < _activationListeners.Count; i++) { _preprocessor.Subscribe(_activationListeners[i]); } //Sub audio listeners to the preprocessor output for (var i = 0; i < _audioListeners.Count; i++) { var al = _audioListeners[i]; al.Reset(); _preprocessor.Subscribe(al); } //Create encoder (not yet subscribed to receive audio data, we'll do that later) Log.AssertAndThrowPossibleBug(_network != null, "5F33336B-15B5-4A85-9B54-54352C74768E", "Network object is unexpectedly null"); _encoder = new EncoderPipeline(_preprocessor.OutputFormat, _codecSettingsLoader.CreateEncoder(), _network); } else { Log.Warn("Failed to start microphone capture; local voice transmission will be disabled."); _cannotStartMic = true; } } catch (Exception ex) { //We don't know what happened, but something went wrong. As a precaution kill the transmission pipeline (it will be restarted if necessary) StopTransmissionPipeline(); Log.Error("Unexpected exception encountered starting microphone capture; local voice transmission will be disabled: {0}", ex); _encounteredFatalException = true; } finally { #if !NCRUNCH Profiler.EndSample(); #endif } }