OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... | |
33 #include "webrtc/media/base/mediaconstants.h" | 33 #include "webrtc/media/base/mediaconstants.h" |
34 #include "webrtc/media/base/streamparams.h" | 34 #include "webrtc/media/base/streamparams.h" |
35 #include "webrtc/media/engine/payload_type_mapper.h" | 35 #include "webrtc/media/engine/payload_type_mapper.h" |
36 #include "webrtc/media/engine/webrtcmediaengine.h" | 36 #include "webrtc/media/engine/webrtcmediaengine.h" |
37 #include "webrtc/media/engine/webrtcvoe.h" | 37 #include "webrtc/media/engine/webrtcvoe.h" |
38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" | 38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" |
39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
40 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 40 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
41 #include "webrtc/system_wrappers/include/field_trial.h" | 41 #include "webrtc/system_wrappers/include/field_trial.h" |
42 #include "webrtc/system_wrappers/include/trace.h" | 42 #include "webrtc/system_wrappers/include/trace.h" |
43 #include "webrtc/voice_engine/transmit_mixer.h" | |
43 | 44 |
44 namespace cricket { | 45 namespace cricket { |
45 namespace { | 46 namespace { |
46 | 47 |
47 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | | 48 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
48 webrtc::kTraceWarning | webrtc::kTraceError | | 49 webrtc::kTraceWarning | webrtc::kTraceError | |
49 webrtc::kTraceCritical; | 50 webrtc::kTraceCritical; |
50 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | | 51 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | |
51 webrtc::kTraceInfo; | 52 webrtc::kTraceInfo; |
52 | 53 |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed | 553 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed |
553 // bitrate then ignore. | 554 // bitrate then ignore. |
554 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname | 555 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname |
555 << " to bitrate " << bps << " bps" | 556 << " to bitrate " << bps << " bps" |
556 << ", requires at least " << codec_inst.rate << " bps."; | 557 << ", requires at least " << codec_inst.rate << " bps."; |
557 return rtc::Optional<int>(); | 558 return rtc::Optional<int>(); |
558 } | 559 } |
559 return rtc::Optional<int>(codec_rate); | 560 return rtc::Optional<int>(codec_rate); |
560 } | 561 } |
561 | 562 |
562 } // namespace { | 563 } // namespace { |
hlundin-webrtc
2017/02/13 21:03:57
Why the extra '{'?
I think it fooled the automatic
the sun
2017/02/13 23:34:47
Done.
| |
564 | |
565 namespace apm_helpers { | |
566 | |
567 webrtc::AgcConfig GetAgcConfig(webrtc::AudioProcessing* apm) { | |
568 RTC_DCHECK(apm); | |
569 webrtc::AgcConfig result; | |
570 result.targetLeveldBOv = apm->gain_control()->target_level_dbfs(); | |
571 result.digitalCompressionGaindB = apm->gain_control()->compression_gain_db(); | |
572 result.limiterEnable = apm->gain_control()->is_limiter_enabled(); | |
573 return result; | |
574 } | |
575 | |
576 void SetAgcConfig(webrtc::AudioProcessing* apm, | |
hlundin-webrtc
2017/02/13 21:03:57
Swap order of parameters; input before input/outpu
the sun
2017/02/13 23:34:47
<bikeshed>
Hm. https://google.github.io/styleguide
hlundin-webrtc
2017/02/14 07:50:43
I accept that. But this bikeshedding increased my
| |
577 const webrtc::AgcConfig& config) { | |
578 RTC_DCHECK(apm); | |
579 webrtc::GainControl* gc = apm->gain_control(); | |
580 if (gc->set_target_level_dbfs(config.targetLeveldBOv) != 0) { | |
581 LOG(LS_ERROR) << "Failed to set target level: " << config.targetLeveldBOv; | |
582 } | |
583 if (gc->set_compression_gain_db(config.digitalCompressionGaindB) != 0) { | |
584 LOG(LS_ERROR) << "Failed to set compression gain: " | |
585 << config.digitalCompressionGaindB; | |
586 } | |
587 if (gc->enable_limiter(config.limiterEnable) != 0) { | |
588 LOG(LS_ERROR) << "Failed to set limiter on/off: " << config.limiterEnable; | |
589 } | |
590 } | |
591 | |
592 void SetEcStatus(webrtc::AudioProcessing* apm, | |
hlundin-webrtc
2017/02/13 21:03:57
apm last
the sun
2017/02/13 23:34:46
Acknowledged.
| |
593 bool enable, | |
594 webrtc::EcModes mode) { | |
595 RTC_DCHECK(apm); | |
596 RTC_DCHECK(mode == webrtc::kEcConference || mode == webrtc::kEcAecm); | |
597 webrtc::EchoCancellation* ec = apm->echo_cancellation(); | |
598 webrtc::EchoControlMobile* ecm = apm->echo_control_mobile(); | |
599 if (mode == webrtc::kEcConference) { | |
600 // Disable the AECM before enable the AEC | |
hlundin-webrtc
2017/02/13 21:03:57
enable -> enabling
the sun
2017/02/13 23:34:47
Done.
| |
601 if (enable && ecm->is_enabled() && ecm->Enable(false) != 0) { | |
hlundin-webrtc
2017/02/13 21:03:57
If we set mode=webrtc::kEcConference and enable=fa
the sun
2017/02/13 23:34:47
I've tried to faithfully replicate how this method
| |
602 LOG(LS_ERROR) << "Failed to disable AECM."; | |
603 return; | |
604 } | |
605 if (ec->Enable(enable) != 0) { | |
606 LOG(LS_ERROR) << "Failed to enable/disable AEC: " << enable; | |
607 return; | |
608 } | |
609 if (ec->set_suppression_level(webrtc::EchoCancellation::kHighSuppression) | |
610 != 0) { | |
611 LOG(LS_ERROR) << "Failed to set high AEC aggressiveness."; | |
612 return; | |
613 } | |
614 } else { | |
615 // Disable the AEC before enable the AECM | |
hlundin-webrtc
2017/02/13 21:03:57
enable -> enabling
the sun
2017/02/13 23:34:47
Done.
| |
616 if (enable && ec->is_enabled() && ec->Enable(false) != 0) { | |
hlundin-webrtc
2017/02/13 21:03:57
Similar snag here as above.
the sun
2017/02/13 23:34:47
Acknowledged.
| |
617 LOG(LS_ERROR) << "Failed to disable AEC."; | |
618 return; | |
619 } | |
620 if (ecm->Enable(enable) != 0) { | |
621 LOG(LS_ERROR) << "Failed to enable/disable AECM: " << enable; | |
622 return; | |
623 } | |
624 } | |
625 LOG(LS_INFO) << "Echo control set to " << enable << " with mode " << mode; | |
626 } | |
627 | |
628 void SetEcMetricsStatus(webrtc::AudioProcessing* apm, bool enable) { | |
hlundin-webrtc
2017/02/13 21:03:57
Swap parameter order.
the sun
2017/02/13 23:34:47
Acknowledged.
| |
629 RTC_DCHECK(apm); | |
630 if ((apm->echo_cancellation()->enable_metrics(enable) != 0) || | |
631 (apm->echo_cancellation()->enable_delay_logging(enable) != 0)) { | |
632 LOG(LS_ERROR) << "Failed to enable/disable EC metrics: " << enable; | |
633 } | |
634 } | |
635 | |
636 void SetAecmMode(webrtc::AudioProcessing* apm, bool enable_cng) { | |
hlundin-webrtc
2017/02/13 21:03:57
Swap parameter order.
the sun
2017/02/13 23:34:47
Acknowledged.
| |
637 RTC_DCHECK(apm); | |
638 webrtc::EchoControlMobile* ecm = apm->echo_control_mobile(); | |
639 if (ecm->set_routing_mode(webrtc::EchoControlMobile::kSpeakerphone) != 0) { | |
640 LOG(LS_ERROR) << "Failed to set AECM mode kSpeakerphone."; | |
641 return; | |
642 } | |
643 if (ecm->enable_comfort_noise(enable_cng) != 0) { | |
644 LOG(LS_ERROR) << "Failed to enable/disable CNG: " << enable_cng; | |
645 return; | |
646 } | |
647 } | |
648 | |
649 void SetAgcStatus(webrtc::AudioProcessing* apm, | |
hlundin-webrtc
2017/02/13 21:03:57
Input before output.
the sun
2017/02/13 23:34:47
Acknowledged.
| |
650 webrtc::AudioDeviceModule* adm, | |
651 bool enable, | |
652 webrtc::AgcModes mode) { | |
653 RTC_DCHECK(apm); | |
654 RTC_DCHECK(adm); | |
655 RTC_DCHECK(mode == webrtc::kAgcFixedDigital || | |
656 mode == webrtc::kAgcAdaptiveAnalog); | |
657 #if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID) | |
hlundin-webrtc
2017/02/13 21:03:57
Are these defined to either 1 or 0? If so, skip th
the sun
2017/02/13 23:34:46
defined(nn) is used in other parts of the code.
D
| |
658 RTC_DCHECK(mode == webrtc::kAgcFixedDigital); | |
hlundin-webrtc
2017/02/13 21:03:57
RTC_DCHECK_EQ
the sun
2017/02/13 23:34:47
Done.
| |
659 webrtc::GainControl::Mode agc_mode = webrtc::GainControl::kFixedDigital; | |
660 #else | |
661 RTC_DCHECK(mode == webrtc::kAgcAdaptiveAnalog); | |
hlundin-webrtc
2017/02/13 21:03:57
RTC_DCHECK_EQ
the sun
2017/02/13 23:34:47
Done.
| |
662 webrtc::GainControl::Mode agc_mode = webrtc::GainControl::kAdaptiveAnalog; | |
663 #endif | |
664 webrtc::GainControl* gc = apm->gain_control(); | |
665 if (gc->set_mode(agc_mode) != 0) { | |
666 LOG(LS_ERROR) << "Failed to set AGC mode: " << agc_mode; | |
667 return; | |
668 } | |
669 if (gc->Enable(enable) != 0) { | |
670 LOG(LS_ERROR) << "Failed to enable/disable AGC: " << enable; | |
671 return; | |
672 } | |
673 if (agc_mode != webrtc::GainControl::kFixedDigital) { | |
674 // Set Agc state in the ADM when adaptive Agc mode has been selected. | |
675 // Note that we also enable the ADM Agc when Adaptive Digital mode is | |
676 // used since we want to be able to provide the APM with updated mic | |
677 // levels when the user modifies the mic level manually. | |
678 if (adm->SetAGC(enable) != 0) { | |
679 LOG(LS_ERROR) << "Failed to set AGC mode in ADM: " << enable; | |
680 return; | |
681 } | |
682 } | |
683 LOG(LS_INFO) << "AGC set to " << enable << " with mode " << mode; | |
684 } | |
685 | |
686 void SetNsStatus(webrtc::AudioProcessing* apm, bool enable) { | |
hlundin-webrtc
2017/02/13 21:03:57
Swap.
the sun
2017/02/13 23:34:46
Acknowledged.
| |
687 RTC_DCHECK(apm); | |
688 webrtc::NoiseSuppression* ns = apm->noise_suppression(); | |
689 if (ns->set_level(webrtc::NoiseSuppression::kHigh) != 0) { | |
690 LOG(LS_ERROR) << "Failed to set high NS level."; | |
691 return; | |
692 } | |
693 if (ns->Enable(enable) != 0) { | |
694 LOG(LS_ERROR) << "Failed to enable/disable NS: " << enable; | |
695 return; | |
696 } | |
697 LOG(LS_INFO) << "NS set to " << enable; | |
698 } | |
699 | |
700 void SetTypingDetectionStatus(webrtc::AudioProcessing* apm, bool enable) { | |
hlundin-webrtc
2017/02/13 21:03:57
Swap.
hlundin-webrtc
2017/02/13 21:03:57
This is confusing. The method name speaks of typin
the sun
2017/02/13 23:34:47
Acknowledged.
the sun
2017/02/13 23:34:47
Yeah. See: https://chromium.googlesource.com/exter
hlundin-webrtc
2017/02/14 07:50:43
I see. Could you snatch a few of the comments in t
the sun
2017/02/14 19:25:57
Not much commentary to copy, so I wrote my own ess
hlundin-webrtc
2017/02/15 13:29:04
Good.
| |
701 RTC_DCHECK(apm); | |
702 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION | |
703 webrtc::VoiceDetection* vd = apm->voice_detection(); | |
704 if (vd->Enable(enable)) { | |
705 LOG(LS_ERROR) << "Failed to enable/disable VAD: " << enable; | |
706 return; | |
707 } | |
708 if (vd->set_likelihood(webrtc::VoiceDetection::kVeryLowLikelihood)) { | |
709 LOG(LS_ERROR) << "Failed to set low VAD likelihood."; | |
710 return; | |
711 } | |
712 LOG(LS_INFO) << "VAD set to " << enable; | |
713 #endif | |
714 } | |
715 } // apm_helpers | |
563 | 716 |
564 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 717 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
565 webrtc::CodecInst* out) { | 718 webrtc::CodecInst* out) { |
566 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 719 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
567 } | 720 } |
568 | 721 |
569 WebRtcVoiceEngine::WebRtcVoiceEngine( | 722 WebRtcVoiceEngine::WebRtcVoiceEngine( |
570 webrtc::AudioDeviceModule* adm, | 723 webrtc::AudioDeviceModule* adm, |
571 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 724 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
572 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) | 725 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 | 766 |
614 // No ADM supplied? Get the default one from VoE. | 767 // No ADM supplied? Get the default one from VoE. |
615 if (!adm_) { | 768 if (!adm_) { |
616 adm_ = voe_wrapper_->base()->audio_device_module(); | 769 adm_ = voe_wrapper_->base()->audio_device_module(); |
617 } | 770 } |
618 RTC_DCHECK(adm_); | 771 RTC_DCHECK(adm_); |
619 | 772 |
620 apm_ = voe_wrapper_->base()->audio_processing(); | 773 apm_ = voe_wrapper_->base()->audio_processing(); |
621 RTC_DCHECK(apm_); | 774 RTC_DCHECK(apm_); |
622 | 775 |
776 transmit_mixer_ = voe_wrapper_->base()->transmit_mixer(); | |
777 RTC_DCHECK(transmit_mixer_); | |
778 | |
623 // Save the default AGC configuration settings. This must happen before | 779 // Save the default AGC configuration settings. This must happen before |
624 // calling ApplyOptions or the default will be overwritten. | 780 // calling ApplyOptions or the default will be overwritten. |
625 int error = voe_wrapper_->processing()->GetAgcConfig(default_agc_config_); | 781 default_agc_config_ = apm_helpers::GetAgcConfig(apm_); |
626 RTC_DCHECK_EQ(0, error); | |
627 | 782 |
628 // Set default engine options. | 783 // Set default engine options. |
629 { | 784 { |
630 AudioOptions options; | 785 AudioOptions options; |
631 options.echo_cancellation = rtc::Optional<bool>(true); | 786 options.echo_cancellation = rtc::Optional<bool>(true); |
632 options.auto_gain_control = rtc::Optional<bool>(true); | 787 options.auto_gain_control = rtc::Optional<bool>(true); |
633 options.noise_suppression = rtc::Optional<bool>(true); | 788 options.noise_suppression = rtc::Optional<bool>(true); |
634 options.highpass_filter = rtc::Optional<bool>(true); | 789 options.highpass_filter = rtc::Optional<bool>(true); |
635 options.stereo_swapping = rtc::Optional<bool>(false); | 790 options.stereo_swapping = rtc::Optional<bool>(false); |
636 options.audio_jitter_buffer_max_packets = rtc::Optional<int>(50); | 791 options.audio_jitter_buffer_max_packets = rtc::Optional<int>(50); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 return new WebRtcVoiceMediaChannel(this, config, options, call); | 828 return new WebRtcVoiceMediaChannel(this, config, options, call); |
674 } | 829 } |
675 | 830 |
676 bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { | 831 bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { |
677 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 832 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
678 LOG(LS_INFO) << "WebRtcVoiceEngine::ApplyOptions: " << options_in.ToString(); | 833 LOG(LS_INFO) << "WebRtcVoiceEngine::ApplyOptions: " << options_in.ToString(); |
679 AudioOptions options = options_in; // The options are modified below. | 834 AudioOptions options = options_in; // The options are modified below. |
680 | 835 |
681 // kEcConference is AEC with high suppression. | 836 // kEcConference is AEC with high suppression. |
682 webrtc::EcModes ec_mode = webrtc::kEcConference; | 837 webrtc::EcModes ec_mode = webrtc::kEcConference; |
683 webrtc::AecmModes aecm_mode = webrtc::kAecmSpeakerphone; | |
684 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog; | 838 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog; |
685 webrtc::NsModes ns_mode = webrtc::kNsHighSuppression; | |
686 if (options.aecm_generate_comfort_noise) { | 839 if (options.aecm_generate_comfort_noise) { |
687 LOG(LS_VERBOSE) << "Comfort noise explicitly set to " | 840 LOG(LS_VERBOSE) << "Comfort noise explicitly set to " |
688 << *options.aecm_generate_comfort_noise | 841 << *options.aecm_generate_comfort_noise |
689 << " (default is false)."; | 842 << " (default is false)."; |
690 } | 843 } |
691 | 844 |
692 #if defined(WEBRTC_IOS) | 845 #if defined(WEBRTC_IOS) |
693 // On iOS, VPIO provides built-in EC, NS and AGC. | 846 // On iOS, VPIO provides built-in EC, NS and AGC. |
694 options.echo_cancellation = rtc::Optional<bool>(false); | 847 options.echo_cancellation = rtc::Optional<bool>(false); |
695 options.auto_gain_control = rtc::Optional<bool>(false); | 848 options.auto_gain_control = rtc::Optional<bool>(false); |
(...skipping 26 matching lines...) Expand all Loading... | |
722 ec_mode = webrtc::kEcConference; | 875 ec_mode = webrtc::kEcConference; |
723 } | 876 } |
724 } | 877 } |
725 #endif | 878 #endif |
726 | 879 |
727 #if (WEBRTC_INTELLIGIBILITY_ENHANCER == 0) | 880 #if (WEBRTC_INTELLIGIBILITY_ENHANCER == 0) |
728 // Hardcode the intelligibility enhancer to be off. | 881 // Hardcode the intelligibility enhancer to be off. |
729 options.intelligibility_enhancer = rtc::Optional<bool>(false); | 882 options.intelligibility_enhancer = rtc::Optional<bool>(false); |
730 #endif | 883 #endif |
731 | 884 |
732 webrtc::VoEAudioProcessing* voep = voe_wrapper_->processing(); | |
733 | |
734 if (options.echo_cancellation) { | 885 if (options.echo_cancellation) { |
735 // Check if platform supports built-in EC. Currently only supported on | 886 // Check if platform supports built-in EC. Currently only supported on |
736 // Android and in combination with Java based audio layer. | 887 // Android and in combination with Java based audio layer. |
737 // TODO(henrika): investigate possibility to support built-in EC also | 888 // TODO(henrika): investigate possibility to support built-in EC also |
738 // in combination with Open SL ES audio. | 889 // in combination with Open SL ES audio. |
739 const bool built_in_aec = adm()->BuiltInAECIsAvailable(); | 890 const bool built_in_aec = adm()->BuiltInAECIsAvailable(); |
740 if (built_in_aec) { | 891 if (built_in_aec) { |
741 // Built-in EC exists on this device and use_delay_agnostic_aec is not | 892 // Built-in EC exists on this device and use_delay_agnostic_aec is not |
742 // overriding it. Enable/Disable it according to the echo_cancellation | 893 // overriding it. Enable/Disable it according to the echo_cancellation |
743 // audio option. | 894 // audio option. |
744 const bool enable_built_in_aec = | 895 const bool enable_built_in_aec = |
745 *options.echo_cancellation && !use_delay_agnostic_aec; | 896 *options.echo_cancellation && !use_delay_agnostic_aec; |
746 if (adm()->EnableBuiltInAEC(enable_built_in_aec) == 0 && | 897 if (adm()->EnableBuiltInAEC(enable_built_in_aec) == 0 && |
747 enable_built_in_aec) { | 898 enable_built_in_aec) { |
748 // Disable internal software EC if built-in EC is enabled, | 899 // Disable internal software EC if built-in EC is enabled, |
749 // i.e., replace the software EC with the built-in EC. | 900 // i.e., replace the software EC with the built-in EC. |
750 options.echo_cancellation = rtc::Optional<bool>(false); | 901 options.echo_cancellation = rtc::Optional<bool>(false); |
751 LOG(LS_INFO) << "Disabling EC since built-in EC will be used instead"; | 902 LOG(LS_INFO) << "Disabling EC since built-in EC will be used instead"; |
752 } | 903 } |
753 } | 904 } |
754 if (voep->SetEcStatus(*options.echo_cancellation, ec_mode) == -1) { | 905 apm_helpers::SetEcStatus(apm(), *options.echo_cancellation, ec_mode); |
the sun
2017/02/14 19:25:57
In case you didn't notice, I feel I should point o
hlundin-webrtc
2017/02/15 13:29:04
I'm not at all sure how this code is supposed to b
the sun
2017/02/15 15:13:30
Acknowledged.
| |
755 LOG_RTCERR2(SetEcStatus, *options.echo_cancellation, ec_mode); | |
756 return false; | |
757 } else { | |
758 LOG(LS_INFO) << "Echo control set to " << *options.echo_cancellation | |
759 << " with mode " << ec_mode; | |
760 } | |
761 #if !defined(ANDROID) | 906 #if !defined(ANDROID) |
762 // TODO(ajm): Remove the error return on Android from webrtc. | 907 apm_helpers::SetEcMetricsStatus(apm(), *options.echo_cancellation); |
763 if (voep->SetEcMetricsStatus(*options.echo_cancellation) == -1) { | |
764 LOG_RTCERR1(SetEcMetricsStatus, *options.echo_cancellation); | |
765 return false; | |
766 } | |
767 #endif | 908 #endif |
768 if (ec_mode == webrtc::kEcAecm) { | 909 if (ec_mode == webrtc::kEcAecm) { |
769 bool cn = options.aecm_generate_comfort_noise.value_or(false); | 910 bool cn = options.aecm_generate_comfort_noise.value_or(false); |
770 if (voep->SetAecmMode(aecm_mode, cn) != 0) { | 911 apm_helpers::SetAecmMode(apm(), cn); |
771 LOG_RTCERR2(SetAecmMode, aecm_mode, cn); | |
772 return false; | |
773 } | |
774 } | 912 } |
775 } | 913 } |
776 | 914 |
777 if (options.auto_gain_control) { | 915 if (options.auto_gain_control) { |
778 bool built_in_agc_avaliable = adm()->BuiltInAGCIsAvailable(); | 916 bool built_in_agc_avaliable = adm()->BuiltInAGCIsAvailable(); |
779 if (built_in_agc_avaliable) { | 917 if (built_in_agc_avaliable) { |
780 if (adm()->EnableBuiltInAGC(*options.auto_gain_control) == 0 && | 918 if (adm()->EnableBuiltInAGC(*options.auto_gain_control) == 0 && |
781 *options.auto_gain_control) { | 919 *options.auto_gain_control) { |
782 // Disable internal software AGC if built-in AGC is enabled, | 920 // Disable internal software AGC if built-in AGC is enabled, |
783 // i.e., replace the software AGC with the built-in AGC. | 921 // i.e., replace the software AGC with the built-in AGC. |
784 options.auto_gain_control = rtc::Optional<bool>(false); | 922 options.auto_gain_control = rtc::Optional<bool>(false); |
785 LOG(LS_INFO) << "Disabling AGC since built-in AGC will be used instead"; | 923 LOG(LS_INFO) << "Disabling AGC since built-in AGC will be used instead"; |
786 } | 924 } |
787 } | 925 } |
788 if (voep->SetAgcStatus(*options.auto_gain_control, agc_mode) == -1) { | 926 apm_helpers::SetAgcStatus( |
789 LOG_RTCERR2(SetAgcStatus, *options.auto_gain_control, agc_mode); | 927 apm(), adm(), *options.auto_gain_control, agc_mode); |
790 return false; | |
791 } else { | |
792 LOG(LS_INFO) << "Auto gain set to " << *options.auto_gain_control | |
793 << " with mode " << agc_mode; | |
794 } | |
795 } | 928 } |
796 | 929 |
797 if (options.tx_agc_target_dbov || options.tx_agc_digital_compression_gain || | 930 if (options.tx_agc_target_dbov || options.tx_agc_digital_compression_gain || |
798 options.tx_agc_limiter) { | 931 options.tx_agc_limiter || options.adjust_agc_delta) { |
799 // Override default_agc_config_. Generally, an unset option means "leave | 932 // Override default_agc_config_. Generally, an unset option means "leave |
800 // the VoE bits alone" in this function, so we want whatever is set to be | 933 // the VoE bits alone" in this function, so we want whatever is set to be |
801 // stored as the new "default". If we didn't, then setting e.g. | 934 // stored as the new "default". If we didn't, then setting e.g. |
802 // tx_agc_target_dbov would reset digital compression gain and limiter | 935 // tx_agc_target_dbov would reset digital compression gain and limiter |
803 // settings. | 936 // settings. |
804 // Also, if we don't update default_agc_config_, then adjust_agc_delta | 937 // Also, if we don't update default_agc_config_, then adjust_agc_delta |
805 // would be an offset from the original values, and not whatever was set | 938 // would be an offset from the original values, and not whatever was set |
806 // explicitly. | 939 // explicitly. |
807 default_agc_config_.targetLeveldBOv = options.tx_agc_target_dbov.value_or( | 940 default_agc_config_.targetLeveldBOv = options.tx_agc_target_dbov.value_or( |
808 default_agc_config_.targetLeveldBOv); | 941 default_agc_config_.targetLeveldBOv); |
809 default_agc_config_.digitalCompressionGaindB = | 942 default_agc_config_.digitalCompressionGaindB = |
810 options.tx_agc_digital_compression_gain.value_or( | 943 options.tx_agc_digital_compression_gain.value_or( |
811 default_agc_config_.digitalCompressionGaindB); | 944 default_agc_config_.digitalCompressionGaindB); |
812 default_agc_config_.limiterEnable = | 945 default_agc_config_.limiterEnable = |
813 options.tx_agc_limiter.value_or(default_agc_config_.limiterEnable); | 946 options.tx_agc_limiter.value_or(default_agc_config_.limiterEnable); |
814 if (voe_wrapper_->processing()->SetAgcConfig(default_agc_config_) == -1) { | 947 |
815 LOG_RTCERR3(SetAgcConfig, | 948 webrtc::AgcConfig config = default_agc_config_; |
816 default_agc_config_.targetLeveldBOv, | 949 if (options.adjust_agc_delta) { |
817 default_agc_config_.digitalCompressionGaindB, | 950 config.targetLeveldBOv -= *options.adjust_agc_delta; |
818 default_agc_config_.limiterEnable); | 951 LOG(LS_INFO) << "Adjusting AGC level from default -" |
819 return false; | 952 << default_agc_config_.targetLeveldBOv << "dB to -" |
953 << config.targetLeveldBOv << "dB"; | |
820 } | 954 } |
955 apm_helpers::SetAgcConfig(apm_, config); | |
821 } | 956 } |
822 | 957 |
823 if (options.intelligibility_enhancer) { | 958 if (options.intelligibility_enhancer) { |
824 intelligibility_enhancer_ = options.intelligibility_enhancer; | 959 intelligibility_enhancer_ = options.intelligibility_enhancer; |
825 } | 960 } |
826 if (intelligibility_enhancer_ && *intelligibility_enhancer_) { | 961 if (intelligibility_enhancer_ && *intelligibility_enhancer_) { |
827 LOG(LS_INFO) << "Enabling NS when Intelligibility Enhancer is active."; | 962 LOG(LS_INFO) << "Enabling NS when Intelligibility Enhancer is active."; |
828 options.noise_suppression = intelligibility_enhancer_; | 963 options.noise_suppression = intelligibility_enhancer_; |
829 } | 964 } |
830 | 965 |
831 if (options.noise_suppression) { | 966 if (options.noise_suppression) { |
832 if (adm()->BuiltInNSIsAvailable()) { | 967 if (adm()->BuiltInNSIsAvailable()) { |
833 bool builtin_ns = | 968 bool builtin_ns = |
834 *options.noise_suppression && | 969 *options.noise_suppression && |
835 !(intelligibility_enhancer_ && *intelligibility_enhancer_); | 970 !(intelligibility_enhancer_ && *intelligibility_enhancer_); |
836 if (adm()->EnableBuiltInNS(builtin_ns) == 0 && builtin_ns) { | 971 if (adm()->EnableBuiltInNS(builtin_ns) == 0 && builtin_ns) { |
837 // Disable internal software NS if built-in NS is enabled, | 972 // Disable internal software NS if built-in NS is enabled, |
838 // i.e., replace the software NS with the built-in NS. | 973 // i.e., replace the software NS with the built-in NS. |
839 options.noise_suppression = rtc::Optional<bool>(false); | 974 options.noise_suppression = rtc::Optional<bool>(false); |
840 LOG(LS_INFO) << "Disabling NS since built-in NS will be used instead"; | 975 LOG(LS_INFO) << "Disabling NS since built-in NS will be used instead"; |
841 } | 976 } |
842 } | 977 } |
843 if (voep->SetNsStatus(*options.noise_suppression, ns_mode) == -1) { | 978 apm_helpers::SetNsStatus(apm(), *options.noise_suppression); |
844 LOG_RTCERR2(SetNsStatus, *options.noise_suppression, ns_mode); | |
845 return false; | |
846 } else { | |
847 LOG(LS_INFO) << "Noise suppression set to " << *options.noise_suppression | |
848 << " with mode " << ns_mode; | |
849 } | |
850 } | 979 } |
851 | 980 |
852 if (options.stereo_swapping) { | 981 if (options.stereo_swapping) { |
hlundin-webrtc
2017/02/13 21:03:57
Hmmm. When is this used? Just curious...
the sun
2017/02/13 23:34:46
It can be set from a constraint: https://chromium.
hlundin-webrtc
2017/02/14 07:50:43
Acknowledged.
| |
853 LOG(LS_INFO) << "Stereo swapping enabled? " << *options.stereo_swapping; | 982 LOG(LS_INFO) << "Stereo swapping enabled? " << *options.stereo_swapping; |
854 voep->EnableStereoChannelSwapping(*options.stereo_swapping); | 983 transmit_mixer()->EnableStereoChannelSwapping(*options.stereo_swapping); |
855 if (voep->IsStereoChannelSwappingEnabled() != *options.stereo_swapping) { | |
856 LOG_RTCERR1(EnableStereoChannelSwapping, *options.stereo_swapping); | |
857 return false; | |
858 } | |
859 } | 984 } |
860 | 985 |
861 if (options.audio_jitter_buffer_max_packets) { | 986 if (options.audio_jitter_buffer_max_packets) { |
862 LOG(LS_INFO) << "NetEq capacity is " | 987 LOG(LS_INFO) << "NetEq capacity is " |
863 << *options.audio_jitter_buffer_max_packets; | 988 << *options.audio_jitter_buffer_max_packets; |
864 channel_config_.acm_config.neteq_config.max_packets_in_buffer = | 989 channel_config_.acm_config.neteq_config.max_packets_in_buffer = |
865 std::max(20, *options.audio_jitter_buffer_max_packets); | 990 std::max(20, *options.audio_jitter_buffer_max_packets); |
866 } | 991 } |
867 if (options.audio_jitter_buffer_fast_accelerate) { | 992 if (options.audio_jitter_buffer_fast_accelerate) { |
868 LOG(LS_INFO) << "NetEq fast mode? " | 993 LOG(LS_INFO) << "NetEq fast mode? " |
869 << *options.audio_jitter_buffer_fast_accelerate; | 994 << *options.audio_jitter_buffer_fast_accelerate; |
870 channel_config_.acm_config.neteq_config.enable_fast_accelerate = | 995 channel_config_.acm_config.neteq_config.enable_fast_accelerate = |
871 *options.audio_jitter_buffer_fast_accelerate; | 996 *options.audio_jitter_buffer_fast_accelerate; |
872 } | 997 } |
873 | 998 |
874 if (options.typing_detection) { | 999 if (options.typing_detection) { |
875 LOG(LS_INFO) << "Typing detection is enabled? " | 1000 LOG(LS_INFO) << "Typing detection is enabled? " |
876 << *options.typing_detection; | 1001 << *options.typing_detection; |
877 if (voep->SetTypingDetectionStatus(*options.typing_detection) == -1) { | 1002 apm_helpers::SetTypingDetectionStatus(apm(), *options.typing_detection); |
878 // In case of error, log the info and continue | |
879 LOG_RTCERR1(SetTypingDetectionStatus, *options.typing_detection); | |
880 } | |
881 } | |
882 | |
883 if (options.adjust_agc_delta) { | |
884 LOG(LS_INFO) << "Adjust agc delta is " << *options.adjust_agc_delta; | |
885 if (!AdjustAgcLevel(*options.adjust_agc_delta)) { | |
886 return false; | |
887 } | |
888 } | 1003 } |
889 | 1004 |
890 webrtc::Config config; | 1005 webrtc::Config config; |
891 | 1006 |
892 if (options.delay_agnostic_aec) | 1007 if (options.delay_agnostic_aec) |
893 delay_agnostic_aec_ = options.delay_agnostic_aec; | 1008 delay_agnostic_aec_ = options.delay_agnostic_aec; |
894 if (delay_agnostic_aec_) { | 1009 if (delay_agnostic_aec_) { |
895 LOG(LS_INFO) << "Delay agnostic aec is enabled? " << *delay_agnostic_aec_; | 1010 LOG(LS_INFO) << "Delay agnostic aec is enabled? " << *delay_agnostic_aec_; |
896 config.Set<webrtc::DelayAgnostic>( | 1011 config.Set<webrtc::DelayAgnostic>( |
897 new webrtc::DelayAgnostic(*delay_agnostic_aec_)); | 1012 new webrtc::DelayAgnostic(*delay_agnostic_aec_)); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1060 channels_.push_back(channel); | 1175 channels_.push_back(channel); |
1061 } | 1176 } |
1062 | 1177 |
1063 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { | 1178 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { |
1064 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1179 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1065 auto it = std::find(channels_.begin(), channels_.end(), channel); | 1180 auto it = std::find(channels_.begin(), channels_.end(), channel); |
1066 RTC_DCHECK(it != channels_.end()); | 1181 RTC_DCHECK(it != channels_.end()); |
1067 channels_.erase(it); | 1182 channels_.erase(it); |
1068 } | 1183 } |
1069 | 1184 |
1070 // Adjusts the default AGC target level by the specified delta. | |
1071 // NB: If we start messing with other config fields, we'll want | |
1072 // to save the current webrtc::AgcConfig as well. | |
1073 bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { | |
1074 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1075 webrtc::AgcConfig config = default_agc_config_; | |
1076 config.targetLeveldBOv -= delta; | |
1077 | |
1078 LOG(LS_INFO) << "Adjusting AGC level from default -" | |
1079 << default_agc_config_.targetLeveldBOv << "dB to -" | |
1080 << config.targetLeveldBOv << "dB"; | |
1081 | |
1082 if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) { | |
1083 LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv); | |
1084 return false; | |
1085 } | |
1086 return true; | |
1087 } | |
1088 | |
1089 bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file, | 1185 bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file, |
1090 int64_t max_size_bytes) { | 1186 int64_t max_size_bytes) { |
1091 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1187 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1092 FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); | 1188 FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); |
1093 if (!aec_dump_file_stream) { | 1189 if (!aec_dump_file_stream) { |
1094 LOG(LS_ERROR) << "Could not open AEC dump file stream."; | 1190 LOG(LS_ERROR) << "Could not open AEC dump file stream."; |
1095 if (!rtc::ClosePlatformFile(file)) | 1191 if (!rtc::ClosePlatformFile(file)) |
1096 LOG(LS_WARNING) << "Could not close file."; | 1192 LOG(LS_WARNING) << "Could not close file."; |
1097 return false; | 1193 return false; |
1098 } | 1194 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1141 RTC_DCHECK(adm_); | 1237 RTC_DCHECK(adm_); |
1142 return adm_; | 1238 return adm_; |
1143 } | 1239 } |
1144 | 1240 |
1145 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() { | 1241 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() { |
1146 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1242 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1147 RTC_DCHECK(apm_); | 1243 RTC_DCHECK(apm_); |
1148 return apm_; | 1244 return apm_; |
1149 } | 1245 } |
1150 | 1246 |
1247 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { | |
1248 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1249 RTC_DCHECK(transmit_mixer_); | |
1250 return transmit_mixer_; | |
1251 } | |
1252 | |
1151 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { | 1253 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { |
1152 PayloadTypeMapper mapper; | 1254 PayloadTypeMapper mapper; |
1153 AudioCodecs out; | 1255 AudioCodecs out; |
1154 const std::vector<webrtc::AudioCodecSpec>& specs = | 1256 const std::vector<webrtc::AudioCodecSpec>& specs = |
1155 decoder_factory_->GetSupportedDecoders(); | 1257 decoder_factory_->GetSupportedDecoders(); |
1156 | 1258 |
1157 // Only generate CN payload types for these clockrates: | 1259 // Only generate CN payload types for these clockrates: |
1158 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, | 1260 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
1159 { 16000, false }, | 1261 { 16000, false }, |
1160 { 32000, false }}; | 1262 { 32000, false }}; |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1869 "Failed to apply engine options during channel SetOptions."; | 1971 "Failed to apply engine options during channel SetOptions."; |
1870 return false; | 1972 return false; |
1871 } | 1973 } |
1872 | 1974 |
1873 rtc::Optional<std::string> audio_network_adatptor_config = | 1975 rtc::Optional<std::string> audio_network_adatptor_config = |
1874 GetAudioNetworkAdaptorConfig(options_); | 1976 GetAudioNetworkAdaptorConfig(options_); |
1875 for (auto& it : send_streams_) { | 1977 for (auto& it : send_streams_) { |
1876 it.second->RecreateAudioSendStream(audio_network_adatptor_config); | 1978 it.second->RecreateAudioSendStream(audio_network_adatptor_config); |
1877 } | 1979 } |
1878 | 1980 |
1879 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1981 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1880 << options_.ToString(); | 1982 << options_.ToString(); |
1881 return true; | 1983 return true; |
1882 } | 1984 } |
1883 | 1985 |
1884 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1986 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1885 const std::vector<AudioCodec>& codecs) { | 1987 const std::vector<AudioCodec>& codecs) { |
1886 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1988 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1887 | 1989 |
1888 // Set the payload types to be used for incoming media. | 1990 // Set the payload types to be used for incoming media. |
1889 LOG(LS_INFO) << "Setting receive voice codecs."; | 1991 LOG(LS_INFO) << "Setting receive voice codecs."; |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2698 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2800 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2699 const auto it = send_streams_.find(ssrc); | 2801 const auto it = send_streams_.find(ssrc); |
2700 if (it != send_streams_.end()) { | 2802 if (it != send_streams_.end()) { |
2701 return it->second->channel(); | 2803 return it->second->channel(); |
2702 } | 2804 } |
2703 return -1; | 2805 return -1; |
2704 } | 2806 } |
2705 } // namespace cricket | 2807 } // namespace cricket |
2706 | 2808 |
2707 #endif // HAVE_WEBRTC_VOICE | 2809 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |