diff --git a/modules/audio_processing/agc2/BUILD.gn b/modules/audio_processing/agc2/BUILD.gn index 5ec3ce1df1..e12252806b 100644 --- a/modules/audio_processing/agc2/BUILD.gn +++ b/modules/audio_processing/agc2/BUILD.gn @@ -17,10 +17,10 @@ group("agc2") { rtc_library("adaptive_digital") { sources = [ - "adaptive_agc.cc", - "adaptive_agc.h", "adaptive_digital_gain_applier.cc", "adaptive_digital_gain_applier.h", + "adaptive_digital_gain_controller.cc", + "adaptive_digital_gain_controller.h", "adaptive_mode_level_estimator.cc", "adaptive_mode_level_estimator.h", "saturation_protector.cc", diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc index deb03b074a..a34f598874 100644 --- a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc +++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc @@ -118,7 +118,9 @@ void CopyAudio(AudioFrameView src, AdaptiveDigitalGainApplier::AdaptiveDigitalGainApplier( ApmDataDumper* apm_data_dumper, - const AudioProcessing::Config::GainController2::AdaptiveDigital& config) + const AudioProcessing::Config::GainController2::AdaptiveDigital& config, + int sample_rate_hz, + int num_channels) : apm_data_dumper_(apm_data_dumper), gain_applier_( /*hard_clip_samples=*/false, @@ -134,7 +136,7 @@ AdaptiveDigitalGainApplier::AdaptiveDigitalGainApplier( RTC_DCHECK_GE(frames_to_gain_increase_allowed_, 1); RTC_DCHECK_GE(config_.max_output_noise_level_dbfs, -90.0f); RTC_DCHECK_LE(config_.max_output_noise_level_dbfs, 0.0f); - Initialize(/*sample_rate_hz=*/48000, /*num_channels=*/1); + Initialize(sample_rate_hz, num_channels); } void AdaptiveDigitalGainApplier::Initialize(int sample_rate_hz, diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier.h b/modules/audio_processing/agc2/adaptive_digital_gain_applier.h index e254b516e4..dc84c1e238 100644 --- a/modules/audio_processing/agc2/adaptive_digital_gain_applier.h +++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier.h @@ -38,7 +38,9 @@ class AdaptiveDigitalGainApplier { AdaptiveDigitalGainApplier( ApmDataDumper* apm_data_dumper, - const AudioProcessing::Config::GainController2::AdaptiveDigital& config); + const AudioProcessing::Config::GainController2::AdaptiveDigital& config, + int sample_rate_hz, + int num_channels); AdaptiveDigitalGainApplier(const AdaptiveDigitalGainApplier&) = delete; AdaptiveDigitalGainApplier& operator=(const AdaptiveDigitalGainApplier&) = delete; diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier_unittest.cc b/modules/audio_processing/agc2/adaptive_digital_gain_applier_unittest.cc index efbc1e1799..ea7485f512 100644 --- a/modules/audio_processing/agc2/adaptive_digital_gain_applier_unittest.cc +++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier_unittest.cc @@ -50,11 +50,15 @@ constexpr AdaptiveDigitalConfig kDefaultConfig{}; // Helper to create initialized `AdaptiveDigitalGainApplier` objects. struct GainApplierHelper { - explicit GainApplierHelper(const AdaptiveDigitalConfig& config) + GainApplierHelper(const AdaptiveDigitalConfig& config, + int sample_rate_hz, + int num_channels) : apm_data_dumper(0), gain_applier( std::make_unique(&apm_data_dumper, - config)) {} + config, + sample_rate_hz, + num_channels)) {} ApmDataDumper apm_data_dumper; std::unique_ptr gain_applier; }; @@ -76,8 +80,7 @@ AdaptiveDigitalGainApplier::FrameInfo GetFrameInfoToNotAdapt( } TEST(GainController2AdaptiveGainApplier, GainApplierShouldNotCrash) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kStereo); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/48000, kStereo); // Make one call with reasonable audio level values and settings. VectorFloatFrame fake_audio(kStereo, kFrameLen10ms48kHz, 10000.0f); helper.gain_applier->Process(GetFrameInfoToNotAdapt(kDefaultConfig), @@ -92,8 +95,7 @@ TEST(GainController2AdaptiveGainApplier, MaxGainApplied) { kDefaultConfig.max_gain_change_db_per_second)) + kNumExtraFrames; - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/8000, kMono); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/8000, kMono); AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(kDefaultConfig); info.speech_level_dbfs = -60.0f; @@ -108,8 +110,7 @@ TEST(GainController2AdaptiveGainApplier, MaxGainApplied) { } TEST(GainController2AdaptiveGainApplier, GainDoesNotChangeFast) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/8000, kMono); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/8000, kMono); constexpr float initial_level_dbfs = -25.0f; constexpr float kMaxGainChangeDbPerFrame = @@ -150,8 +151,7 @@ TEST(GainController2AdaptiveGainApplier, GainDoesNotChangeFast) { } TEST(GainController2AdaptiveGainApplier, GainIsRampedInAFrame) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/48000, kMono); constexpr float initial_level_dbfs = -25.0f; @@ -177,8 +177,7 @@ TEST(GainController2AdaptiveGainApplier, GainIsRampedInAFrame) { } TEST(GainController2AdaptiveGainApplier, NoiseLimitsGain) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/48000, kMono); constexpr float initial_level_dbfs = -25.0f; constexpr int num_initial_frames = @@ -209,8 +208,7 @@ TEST(GainController2AdaptiveGainApplier, NoiseLimitsGain) { } TEST(GainController2GainApplier, CanHandlePositiveSpeechLevels) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kStereo); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/48000, kStereo); // Make one call with positive audio level values and settings. VectorFloatFrame fake_audio(kStereo, kFrameLen10ms48kHz, 10000.0f); @@ -221,8 +219,7 @@ TEST(GainController2GainApplier, CanHandlePositiveSpeechLevels) { } TEST(GainController2GainApplier, AudioLevelLimitsGain) { - GainApplierHelper helper(kDefaultConfig); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); + GainApplierHelper helper(kDefaultConfig, /*sample_rate_hz=*/48000, kMono); constexpr float initial_level_dbfs = -25.0f; constexpr int num_initial_frames = @@ -262,8 +259,7 @@ TEST_P(AdaptiveDigitalGainApplierTest, DoNotIncreaseGainWithTooFewSpeechFrames) { AdaptiveDigitalConfig config; config.adjacent_speech_frames_threshold = adjacent_speech_frames_threshold(); - GainApplierHelper helper(config); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); + GainApplierHelper helper(config, /*sample_rate_hz=*/48000, kMono); // Lower the speech level so that the target gain will be increased. AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(config); @@ -285,8 +281,7 @@ TEST_P(AdaptiveDigitalGainApplierTest, TEST_P(AdaptiveDigitalGainApplierTest, IncreaseGainWithEnoughSpeechFrames) { AdaptiveDigitalConfig config; config.adjacent_speech_frames_threshold = adjacent_speech_frames_threshold(); - GainApplierHelper helper(config); - helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); + GainApplierHelper helper(config, /*sample_rate_hz=*/48000, kMono); // Lower the speech level so that the target gain will be increased. AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(config); @@ -316,7 +311,7 @@ INSTANTIATE_TEST_SUITE_P(GainController2, TEST(GainController2GainApplier, DryRunDoesNotChangeInput) { AdaptiveDigitalConfig config; config.dry_run = true; - GainApplierHelper helper(config); + GainApplierHelper helper(config, /*sample_rate_hz=*/8000, kMono); // Simulate an input signal with log speech level. AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(config); @@ -328,7 +323,6 @@ TEST(GainController2GainApplier, DryRunDoesNotChangeInput) { kNumExtraFrames; constexpr float kPcmSamples = 123.456f; // Run the gain applier and check that the PCM samples are not modified. - helper.gain_applier->Initialize(/*sample_rate_hz=*/8000, kMono); for (int i = 0; i < num_frames_to_adapt; ++i) { SCOPED_TRACE(i); VectorFloatFrame fake_audio(kMono, kFrameLen10ms8kHz, kPcmSamples); @@ -341,13 +335,12 @@ TEST(GainController2GainApplier, DryRunDoesNotChangeInput) { TEST(GainController2GainApplier, DryRunHandlesSampleRateChange) { AdaptiveDigitalConfig config; config.dry_run = true; - GainApplierHelper helper(config); + GainApplierHelper helper(config, /*sample_rate_hz=*/8000, kMono); AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(config); info.speech_level_dbfs = -60.0f; constexpr float kPcmSamples = 123.456f; VectorFloatFrame fake_audio_8k(kMono, kFrameLen10ms8kHz, kPcmSamples); - helper.gain_applier->Initialize(/*sample_rate_hz=*/8000, kMono); helper.gain_applier->Process(info, fake_audio_8k.float_frame_view()); EXPECT_FLOAT_EQ(fake_audio_8k.float_frame_view().channel(0)[0], kPcmSamples); helper.gain_applier->Initialize(/*sample_rate_hz=*/48000, kMono); @@ -361,13 +354,12 @@ TEST(GainController2GainApplier, DryRunHandlesSampleRateChange) { TEST(GainController2GainApplier, DryRunHandlesNumChannelsChange) { AdaptiveDigitalConfig config; config.dry_run = true; - GainApplierHelper helper(config); + GainApplierHelper helper(config, /*sample_rate_hz=*/8000, kMono); AdaptiveDigitalGainApplier::FrameInfo info = GetFrameInfoToNotAdapt(config); info.speech_level_dbfs = -60.0f; constexpr float kPcmSamples = 123.456f; VectorFloatFrame fake_audio_8k(kMono, kFrameLen10ms8kHz, kPcmSamples); - helper.gain_applier->Initialize(/*sample_rate_hz=*/8000, kMono); helper.gain_applier->Process(info, fake_audio_8k.float_frame_view()); EXPECT_FLOAT_EQ(fake_audio_8k.float_frame_view().channel(0)[0], kPcmSamples); VectorFloatFrame fake_audio_48k(kStereo, kFrameLen10ms8kHz, kPcmSamples); diff --git a/modules/audio_processing/agc2/adaptive_agc.cc b/modules/audio_processing/agc2/adaptive_digital_gain_controller.cc similarity index 80% rename from modules/audio_processing/agc2/adaptive_agc.cc rename to modules/audio_processing/agc2/adaptive_digital_gain_controller.cc index 295a33f895..381e454868 100644 --- a/modules/audio_processing/agc2/adaptive_agc.cc +++ b/modules/audio_processing/agc2/adaptive_digital_gain_controller.cc @@ -8,7 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/agc2/adaptive_agc.h" +#include "modules/audio_processing/agc2/adaptive_digital_gain_controller.h" + +#include #include "common_audio/include/audio_util.h" #include "modules/audio_processing/agc2/vad_wrapper.h" @@ -39,11 +41,13 @@ AudioLevels ComputeAudioLevels(AudioFrameView frame) { } // namespace -AdaptiveAgc::AdaptiveAgc( +AdaptiveDigitalGainController::AdaptiveDigitalGainController( ApmDataDumper* apm_data_dumper, - const AudioProcessing::Config::GainController2::AdaptiveDigital& config) + const AudioProcessing::Config::GainController2::AdaptiveDigital& config, + int sample_rate_hz, + int num_channels) : speech_level_estimator_(apm_data_dumper, config), - gain_controller_(apm_data_dumper, config), + gain_controller_(apm_data_dumper, config, sample_rate_hz, num_channels), apm_data_dumper_(apm_data_dumper), noise_level_estimator_(CreateNoiseFloorEstimator(apm_data_dumper)), saturation_protector_( @@ -55,15 +59,16 @@ AdaptiveAgc::AdaptiveAgc( RTC_DCHECK(saturation_protector_); } -AdaptiveAgc::~AdaptiveAgc() = default; +AdaptiveDigitalGainController::~AdaptiveDigitalGainController() = default; -void AdaptiveAgc::Initialize(int sample_rate_hz, int num_channels) { +void AdaptiveDigitalGainController::Initialize(int sample_rate_hz, + int num_channels) { gain_controller_.Initialize(sample_rate_hz, num_channels); } -void AdaptiveAgc::Process(AudioFrameView frame, - float speech_probability, - float limiter_envelope) { +void AdaptiveDigitalGainController::Process(AudioFrameView frame, + float speech_probability, + float limiter_envelope) { AudioLevels levels = ComputeAudioLevels(frame); apm_data_dumper_->DumpRaw("agc2_input_rms_dbfs", levels.rms_dbfs); apm_data_dumper_->DumpRaw("agc2_input_peak_dbfs", levels.peak_dbfs); @@ -95,7 +100,7 @@ void AdaptiveAgc::Process(AudioFrameView frame, gain_controller_.Process(info, frame); } -void AdaptiveAgc::HandleInputGainChange() { +void AdaptiveDigitalGainController::HandleInputGainChange() { speech_level_estimator_.Reset(); saturation_protector_->Reset(); } diff --git a/modules/audio_processing/agc2/adaptive_agc.h b/modules/audio_processing/agc2/adaptive_digital_gain_controller.h similarity index 62% rename from modules/audio_processing/agc2/adaptive_agc.h rename to modules/audio_processing/agc2/adaptive_digital_gain_controller.h index a9a6985f08..75ea44591e 100644 --- a/modules/audio_processing/agc2/adaptive_agc.h +++ b/modules/audio_processing/agc2/adaptive_digital_gain_controller.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_AGC_H_ -#define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_AGC_H_ +#ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_CONTROLLER_H_ +#define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_CONTROLLER_H_ #include @@ -23,22 +23,26 @@ namespace webrtc { class ApmDataDumper; -// Adaptive digital gain controller. -// TODO(crbug.com/webrtc/7494): Rename to `AdaptiveDigitalGainController`. -class AdaptiveAgc { +// Gain controller that adapts and applies a variable digital gain to meet the +// target level, which is determined by the given configuration. +class AdaptiveDigitalGainController { public: - AdaptiveAgc( + AdaptiveDigitalGainController( ApmDataDumper* apm_data_dumper, - const AudioProcessing::Config::GainController2::AdaptiveDigital& config); - ~AdaptiveAgc(); + const AudioProcessing::Config::GainController2::AdaptiveDigital& config, + int sample_rate_hz, + int num_channels); + AdaptiveDigitalGainController(const AdaptiveDigitalGainController&) = delete; + AdaptiveDigitalGainController& operator=( + const AdaptiveDigitalGainController&) = delete; + ~AdaptiveDigitalGainController(); + // Detects and handles changes of sample rate and or number of channels. void Initialize(int sample_rate_hz, int num_channels); - // TODO(crbug.com/webrtc/7494): Add `SetLimiterEnvelope()`. - - // Analyzes `frame` and applies a digital adaptive gain to it. Takes into - // account the speech probability and the envelope measured by the limiter. - // TODO(crbug.com/webrtc/7494): Remove `limiter_envelope`. + // Analyzes `frame`, adapts the current digital gain and applies it to + // `frame`. + // TODO(bugs.webrtc.org/7494): Remove `limiter_envelope`. void Process(AudioFrameView frame, float speech_probability, float limiter_envelope); @@ -56,4 +60,4 @@ class AdaptiveAgc { } // namespace webrtc -#endif // MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_AGC_H_ +#endif // MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_CONTROLLER_H_ diff --git a/modules/audio_processing/gain_controller2.cc b/modules/audio_processing/gain_controller2.cc index 8ca87c7ca1..466e4b0eb4 100644 --- a/modules/audio_processing/gain_controller2.cc +++ b/modules/audio_processing/gain_controller2.cc @@ -51,18 +51,14 @@ AvailableCpuFeatures GetAllowedCpuFeatures() { } // Creates an adaptive digital gain controller if enabled. -std::unique_ptr CreateAdaptiveDigitalController( +std::unique_ptr CreateAdaptiveDigitalController( const Agc2Config::AdaptiveDigital& config, int sample_rate_hz, int num_channels, ApmDataDumper* data_dumper) { if (config.enabled) { - // TODO(bugs.webrtc.org/7494): Also init with sample rate and num - // channels. - auto controller = std::make_unique(data_dumper, config); - // TODO(bugs.webrtc.org/7494): Remove once passed to the ctor. - controller->Initialize(sample_rate_hz, num_channels); - return controller; + return std::make_unique( + data_dumper, config, sample_rate_hz, num_channels); } return nullptr; } diff --git a/modules/audio_processing/gain_controller2.h b/modules/audio_processing/gain_controller2.h index 7e28ee20ba..8c82d745b5 100644 --- a/modules/audio_processing/gain_controller2.h +++ b/modules/audio_processing/gain_controller2.h @@ -14,7 +14,7 @@ #include #include -#include "modules/audio_processing/agc2/adaptive_agc.h" +#include "modules/audio_processing/agc2/adaptive_digital_gain_controller.h" #include "modules/audio_processing/agc2/cpu_features.h" #include "modules/audio_processing/agc2/gain_applier.h" #include "modules/audio_processing/agc2/limiter.h" @@ -57,7 +57,7 @@ class GainController2 { ApmDataDumper data_dumper_; GainApplier fixed_gain_applier_; std::unique_ptr vad_; - std::unique_ptr adaptive_digital_controller_; + std::unique_ptr adaptive_digital_controller_; Limiter limiter_; int calls_since_last_limiter_log_; int analog_level_;