/// <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."); } }
private void StartCapture() { if (_subscribed) { throw Log.CreatePossibleBugException("Cannot subscribe encoder to mic: already subscribed", "B1F845C2-3A9F-48F0-B9D2-4E5457CFDCB8"); } Log.Debug("Subscribing encoder to microphone"); if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordEncoderPipelineInputAudio) { var filename = string.Format("Dissonance_Diagnostics/EncoderPipelineInput_{0}", DateTime.UtcNow.ToFileTime()); _microphoneDiagnosticOutput = new AudioFileWriter(filename, _inputFormat); } if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordEncoderPipelineOutputAudio) { var filename = string.Format("Dissonance_Diagnostics/EncoderPipelineOutput_{0}", DateTime.UtcNow.ToFileTime()); _preEncodeDiagnosticOutput = new AudioFileWriter(filename, _output.WaveFormat); } _mic.Subscribe(this); _subscribed = true; }
/// <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 } }