From a3333bfafb9eca157b5d1bb59365b720ca9d7c38 Mon Sep 17 00:00:00 2001 From: peah Date: Thu, 30 Jun 2016 00:02:34 -0700 Subject: [PATCH] This CL adds activation logic of the new APM level control functionality and exposes the functionality using the MediaConstraints. The exposing of the feature through the MediaConstraints was done similarly to what was done for the intelligibility enhancer in the CL https://codereview.webrtc.org/1952123003 This CL is dependent on the CL https://codereview.webrtc.org/2090583002/ which contains the level control functionality. NOTRY=true BUG=webrtc:5920 Review-Url: https://codereview.webrtc.org/2095563002 Cr-Commit-Position: refs/heads/master@{#13336} --- webrtc/api/localaudiosource.cc | 1 + webrtc/api/mediaconstraintsinterface.cc | 1 + webrtc/api/mediaconstraintsinterface.h | 1 + webrtc/media/base/mediachannel.h | 48 +++++++++++++----------- webrtc/media/engine/webrtcvoiceengine.cc | 35 ++++++++++++++++- webrtc/media/engine/webrtcvoiceengine.h | 10 +++-- 6 files changed, 69 insertions(+), 27 deletions(-) diff --git a/webrtc/api/localaudiosource.cc b/webrtc/api/localaudiosource.cc index 9da9fd2612..53c426e011 100644 --- a/webrtc/api/localaudiosource.cc +++ b/webrtc/api/localaudiosource.cc @@ -49,6 +49,7 @@ void FromConstraints(const MediaConstraintsInterface::Constraints& constraints, options->experimental_ns}, {MediaConstraintsInterface::kIntelligibilityEnhancer, options->intelligibility_enhancer}, + {MediaConstraintsInterface::kLevelControl, options->level_control}, {MediaConstraintsInterface::kHighpassFilter, options->highpass_filter}, {MediaConstraintsInterface::kTypingNoiseDetection, options->typing_detection}, diff --git a/webrtc/api/mediaconstraintsinterface.cc b/webrtc/api/mediaconstraintsinterface.cc index 6a014a2b03..7ac7417669 100644 --- a/webrtc/api/mediaconstraintsinterface.cc +++ b/webrtc/api/mediaconstraintsinterface.cc @@ -48,6 +48,7 @@ const char MediaConstraintsInterface::kExperimentalNoiseSuppression[] = "googNoiseSuppression2"; const char MediaConstraintsInterface::kIntelligibilityEnhancer[] = "intelligibilityEnhancer"; +const char MediaConstraintsInterface::kLevelControl[] = "levelControl"; const char MediaConstraintsInterface::kHighpassFilter[] = "googHighpassFilter"; const char MediaConstraintsInterface::kTypingNoiseDetection[] = diff --git a/webrtc/api/mediaconstraintsinterface.h b/webrtc/api/mediaconstraintsinterface.h index 13560dd35b..d6fd6beb95 100644 --- a/webrtc/api/mediaconstraintsinterface.h +++ b/webrtc/api/mediaconstraintsinterface.h @@ -74,6 +74,7 @@ class MediaConstraintsInterface { static const char kNoiseSuppression[]; // googNoiseSuppression static const char kExperimentalNoiseSuppression[]; // googNoiseSuppression2 static const char kIntelligibilityEnhancer[]; // intelligibilityEnhancer + static const char kLevelControl[]; // levelControl static const char kHighpassFilter[]; // googHighpassFilter static const char kTypingNoiseDetection[]; // googTypingNoiseDetection static const char kAudioMirroring[]; // googAudioMirroring diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index bb30798249..5a4124ac11 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -158,6 +158,7 @@ struct AudioOptions { SetFrom(&delay_agnostic_aec, change.delay_agnostic_aec); SetFrom(&experimental_ns, change.experimental_ns); SetFrom(&intelligibility_enhancer, change.intelligibility_enhancer); + SetFrom(&level_control, change.level_control); SetFrom(&tx_agc_target_dbov, change.tx_agc_target_dbov); SetFrom(&tx_agc_digital_compression_gain, change.tx_agc_digital_compression_gain); @@ -169,27 +170,30 @@ struct AudioOptions { bool operator==(const AudioOptions& o) const { return echo_cancellation == o.echo_cancellation && - auto_gain_control == o.auto_gain_control && - noise_suppression == o.noise_suppression && - highpass_filter == o.highpass_filter && - stereo_swapping == o.stereo_swapping && - audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets && - audio_jitter_buffer_fast_accelerate == - o.audio_jitter_buffer_fast_accelerate && - typing_detection == o.typing_detection && - aecm_generate_comfort_noise == o.aecm_generate_comfort_noise && - experimental_agc == o.experimental_agc && - extended_filter_aec == o.extended_filter_aec && - delay_agnostic_aec == o.delay_agnostic_aec && - experimental_ns == o.experimental_ns && - intelligibility_enhancer == o.intelligibility_enhancer && - adjust_agc_delta == o.adjust_agc_delta && - tx_agc_target_dbov == o.tx_agc_target_dbov && - tx_agc_digital_compression_gain == o.tx_agc_digital_compression_gain && - tx_agc_limiter == o.tx_agc_limiter && - recording_sample_rate == o.recording_sample_rate && - playout_sample_rate == o.playout_sample_rate && - combined_audio_video_bwe == o.combined_audio_video_bwe; + auto_gain_control == o.auto_gain_control && + noise_suppression == o.noise_suppression && + highpass_filter == o.highpass_filter && + stereo_swapping == o.stereo_swapping && + audio_jitter_buffer_max_packets == + o.audio_jitter_buffer_max_packets && + audio_jitter_buffer_fast_accelerate == + o.audio_jitter_buffer_fast_accelerate && + typing_detection == o.typing_detection && + aecm_generate_comfort_noise == o.aecm_generate_comfort_noise && + experimental_agc == o.experimental_agc && + extended_filter_aec == o.extended_filter_aec && + delay_agnostic_aec == o.delay_agnostic_aec && + experimental_ns == o.experimental_ns && + intelligibility_enhancer == o.intelligibility_enhancer && + level_control == o.level_control && + adjust_agc_delta == o.adjust_agc_delta && + tx_agc_target_dbov == o.tx_agc_target_dbov && + tx_agc_digital_compression_gain == + o.tx_agc_digital_compression_gain && + tx_agc_limiter == o.tx_agc_limiter && + recording_sample_rate == o.recording_sample_rate && + playout_sample_rate == o.playout_sample_rate && + combined_audio_video_bwe == o.combined_audio_video_bwe; } bool operator!=(const AudioOptions& o) const { return !(*this == o); } @@ -213,6 +217,7 @@ struct AudioOptions { ost << ToStringIfSet("delay_agnostic_aec", delay_agnostic_aec); ost << ToStringIfSet("experimental_ns", experimental_ns); ost << ToStringIfSet("intelligibility_enhancer", intelligibility_enhancer); + ost << ToStringIfSet("level_control", level_control); ost << ToStringIfSet("tx_agc_target_dbov", tx_agc_target_dbov); ost << ToStringIfSet("tx_agc_digital_compression_gain", tx_agc_digital_compression_gain); @@ -248,6 +253,7 @@ struct AudioOptions { rtc::Optional delay_agnostic_aec; rtc::Optional experimental_ns; rtc::Optional intelligibility_enhancer; + rtc::Optional level_control; // Note that tx_agc_* only applies to non-experimental AGC. rtc::Optional tx_agc_target_dbov; rtc::Optional tx_agc_digital_compression_gain; diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index d329270ce5..469098a322 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -559,6 +559,7 @@ WebRtcVoiceEngine::WebRtcVoiceEngine( options.delay_agnostic_aec = rtc::Optional(false); options.experimental_ns = rtc::Optional(false); options.intelligibility_enhancer = rtc::Optional(false); + options.level_control = rtc::Optional(false); bool error = ApplyOptions(options); RTC_DCHECK(error); } @@ -682,9 +683,29 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { } } + // Use optional to avoid uneccessary calls to BuiltInAGCIsAvailable while + // complying with the unittest requirements of only 1 call per test. + rtc::Optional built_in_agc_avaliable; + if (options.level_control) { + if (!built_in_agc_avaliable) { + built_in_agc_avaliable = + rtc::Optional(adm()->BuiltInAGCIsAvailable()); + } + RTC_DCHECK(built_in_agc_avaliable); + if (*built_in_agc_avaliable) { + // Disable internal software level control if built-in AGC is enabled, + // i.e., replace the software AGC with the built-in AGC. + options.level_control = rtc::Optional(false); + } + } + if (options.auto_gain_control) { - const bool built_in_agc = adm()->BuiltInAGCIsAvailable(); - if (built_in_agc) { + if (!built_in_agc_avaliable) { + built_in_agc_avaliable = + rtc::Optional(adm()->BuiltInAGCIsAvailable()); + } + RTC_DCHECK(built_in_agc_avaliable); + if (*built_in_agc_avaliable) { if (adm()->EnableBuiltInAGC(*options.auto_gain_control) == 0 && *options.auto_gain_control) { // Disable internal software AGC if built-in AGC is enabled, @@ -841,6 +862,16 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { new webrtc::Intelligibility(*intelligibility_enhancer_)); } + if (options.level_control) { + level_control_ = options.level_control; + } + + LOG(LS_INFO) << "Level control: " + << (!!level_control_ ? *level_control_ : -1); + if (level_control_) { + config.Set(new webrtc::LevelControl(*level_control_)); + } + // We check audioproc for the benefit of tests, since FakeWebRtcVoiceEngine // returns NULL on audio_processing(). webrtc::AudioProcessing* audioproc = voe_wrapper_->base()->audio_processing(); diff --git a/webrtc/media/engine/webrtcvoiceengine.h b/webrtc/media/engine/webrtcvoiceengine.h index 16da9ef29e..64e0f5b185 100644 --- a/webrtc/media/engine/webrtcvoiceengine.h +++ b/webrtc/media/engine/webrtcvoiceengine.h @@ -138,14 +138,16 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback { bool is_dumping_aec_ = false; webrtc::AgcConfig default_agc_config_; - // Cache received extended_filter_aec, delay_agnostic_aec, experimental_ns and - // intelligibility_enhancer values, and apply them in case they are missing - // in the audio options. We need to do this because SetExtraOptions() will - // revert to defaults for options which are not provided. + // Cache received extended_filter_aec, delay_agnostic_aec, experimental_ns + // level controller, and intelligibility_enhancer values, and apply them + // in case they are missing in the audio options. We need to do this because + // SetExtraOptions() will revert to defaults for options which are not + // provided. rtc::Optional extended_filter_aec_; rtc::Optional delay_agnostic_aec_; rtc::Optional experimental_ns_; rtc::Optional intelligibility_enhancer_; + rtc::Optional level_control_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceEngine); };