xref: /aosp_15_r20/external/webrtc/modules/audio_processing/audio_processing_impl_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/audio_processing_impl.h"
12 
13 #include <array>
14 #include <memory>
15 #include <tuple>
16 
17 #include "absl/types/optional.h"
18 #include "api/make_ref_counted.h"
19 #include "api/scoped_refptr.h"
20 #include "modules/audio_processing/include/audio_processing.h"
21 #include "modules/audio_processing/optionally_built_submodule_creators.h"
22 #include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
23 #include "modules/audio_processing/test/echo_canceller_test_tools.h"
24 #include "modules/audio_processing/test/echo_control_mock.h"
25 #include "modules/audio_processing/test/test_utils.h"
26 #include "rtc_base/checks.h"
27 #include "rtc_base/random.h"
28 #include "rtc_base/strings/string_builder.h"
29 #include "test/field_trial.h"
30 #include "test/gmock.h"
31 #include "test/gtest.h"
32 
33 namespace webrtc {
34 namespace {
35 
36 using ::testing::Invoke;
37 using ::testing::NotNull;
38 
39 class MockInitialize : public AudioProcessingImpl {
40  public:
MockInitialize()41   MockInitialize() : AudioProcessingImpl() {}
42 
43   MOCK_METHOD(void, InitializeLocked, (), (override));
RealInitializeLocked()44   void RealInitializeLocked() {
45     AssertLockedForTest();
46     AudioProcessingImpl::InitializeLocked();
47   }
48 
49   MOCK_METHOD(void, AddRef, (), (const, override));
50   MOCK_METHOD(rtc::RefCountReleaseStatus, Release, (), (const, override));
51 };
52 
53 // Creates MockEchoControl instances and provides a raw pointer access to
54 // the next created one. The raw pointer is meant to be used with gmock.
55 // Returning a pointer of the next created MockEchoControl instance is necessary
56 // for the following reasons: (i) gmock expectations must be set before any call
57 // occurs, (ii) APM is initialized the first time that
58 // AudioProcessingImpl::ProcessStream() is called and the initialization leads
59 // to the creation of a new EchoControl object.
60 class MockEchoControlFactory : public EchoControlFactory {
61  public:
MockEchoControlFactory()62   MockEchoControlFactory() : next_mock_(std::make_unique<MockEchoControl>()) {}
63   // Returns a pointer to the next MockEchoControl that this factory creates.
GetNext() const64   MockEchoControl* GetNext() const { return next_mock_.get(); }
Create(int sample_rate_hz,int num_render_channels,int num_capture_channels)65   std::unique_ptr<EchoControl> Create(int sample_rate_hz,
66                                       int num_render_channels,
67                                       int num_capture_channels) override {
68     std::unique_ptr<EchoControl> mock = std::move(next_mock_);
69     next_mock_ = std::make_unique<MockEchoControl>();
70     return mock;
71   }
72 
73  private:
74   std::unique_ptr<MockEchoControl> next_mock_;
75 };
76 
77 // Mocks EchoDetector and records the first samples of the last analyzed render
78 // stream frame. Used to check what data is read by an EchoDetector
79 // implementation injected into an APM.
80 class TestEchoDetector : public EchoDetector {
81  public:
TestEchoDetector()82   TestEchoDetector()
83       : analyze_render_audio_called_(false),
84         last_render_audio_first_sample_(0.f) {}
85   ~TestEchoDetector() override = default;
AnalyzeRenderAudio(rtc::ArrayView<const float> render_audio)86   void AnalyzeRenderAudio(rtc::ArrayView<const float> render_audio) override {
87     last_render_audio_first_sample_ = render_audio[0];
88     analyze_render_audio_called_ = true;
89   }
AnalyzeCaptureAudio(rtc::ArrayView<const float> capture_audio)90   void AnalyzeCaptureAudio(rtc::ArrayView<const float> capture_audio) override {
91   }
Initialize(int capture_sample_rate_hz,int num_capture_channels,int render_sample_rate_hz,int num_render_channels)92   void Initialize(int capture_sample_rate_hz,
93                   int num_capture_channels,
94                   int render_sample_rate_hz,
95                   int num_render_channels) override {}
GetMetrics() const96   EchoDetector::Metrics GetMetrics() const override { return {}; }
97   // Returns true if AnalyzeRenderAudio() has been called at least once.
analyze_render_audio_called() const98   bool analyze_render_audio_called() const {
99     return analyze_render_audio_called_;
100   }
101   // Returns the first sample of the last analyzed render frame.
last_render_audio_first_sample() const102   float last_render_audio_first_sample() const {
103     return last_render_audio_first_sample_;
104   }
105 
106  private:
107   bool analyze_render_audio_called_;
108   float last_render_audio_first_sample_;
109 };
110 
111 // Mocks CustomProcessing and applies ProcessSample() to all the samples.
112 // Meant to be injected into an APM to modify samples in a known and detectable
113 // way.
114 class TestRenderPreProcessor : public CustomProcessing {
115  public:
116   TestRenderPreProcessor() = default;
117   ~TestRenderPreProcessor() = default;
Initialize(int sample_rate_hz,int num_channels)118   void Initialize(int sample_rate_hz, int num_channels) override {}
Process(AudioBuffer * audio)119   void Process(AudioBuffer* audio) override {
120     for (size_t k = 0; k < audio->num_channels(); ++k) {
121       rtc::ArrayView<float> channel_view(audio->channels()[k],
122                                          audio->num_frames());
123       std::transform(channel_view.begin(), channel_view.end(),
124                      channel_view.begin(), ProcessSample);
125     }
126   }
ToString() const127   std::string ToString() const override { return "TestRenderPreProcessor"; }
SetRuntimeSetting(AudioProcessing::RuntimeSetting setting)128   void SetRuntimeSetting(AudioProcessing::RuntimeSetting setting) override {}
129   // Modifies a sample. This member is used in Process() to modify a frame and
130   // it is publicly visible to enable tests.
ProcessSample(float x)131   static constexpr float ProcessSample(float x) { return 2.f * x; }
132 };
133 
134 // Creates a simple `AudioProcessing` instance for APM input volume testing
135 // with AGC1 analog and/or AGC2 input volume controller enabled and AGC2
136 // digital controller enabled.
CreateApmForInputVolumeTest(bool agc1_analog_gain_controller_enabled,bool agc2_input_volume_controller_enabled)137 rtc::scoped_refptr<AudioProcessing> CreateApmForInputVolumeTest(
138     bool agc1_analog_gain_controller_enabled,
139     bool agc2_input_volume_controller_enabled) {
140   webrtc::AudioProcessing::Config config;
141   // Enable AGC1 analog controller.
142   config.gain_controller1.enabled = agc1_analog_gain_controller_enabled;
143   config.gain_controller1.analog_gain_controller.enabled =
144       agc1_analog_gain_controller_enabled;
145   // Enable AG2 input volume controller
146   config.gain_controller2.input_volume_controller.enabled =
147       agc2_input_volume_controller_enabled;
148   // Enable AGC2 adaptive digital controller.
149   config.gain_controller1.analog_gain_controller.enable_digital_adaptive =
150       false;
151   config.gain_controller2.enabled = true;
152   config.gain_controller2.adaptive_digital.enabled = true;
153 
154   auto apm(AudioProcessingBuilder().Create());
155   apm->ApplyConfig(config);
156 
157   return apm;
158 }
159 
160 // Runs `apm` input processing for volume adjustments for `num_frames` random
161 // frames starting from the volume `initial_volume`. This includes three steps:
162 // 1) Set the input volume 2) Process the stream 3) Set the new recommended
163 // input volume. Returns the new recommended input volume.
ProcessInputVolume(AudioProcessing & apm,int num_frames,int initial_volume)164 int ProcessInputVolume(AudioProcessing& apm,
165                        int num_frames,
166                        int initial_volume) {
167   constexpr int kSampleRateHz = 48000;
168   constexpr int kNumChannels = 1;
169   std::array<float, kSampleRateHz / 100> buffer;
170   float* channel_pointers[] = {buffer.data()};
171   StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
172                              /*num_channels=*/kNumChannels);
173   int recommended_input_volume = initial_volume;
174   for (int i = 0; i < num_frames; ++i) {
175     Random random_generator(2341U);
176     RandomizeSampleVector(&random_generator, buffer);
177 
178     apm.set_stream_analog_level(recommended_input_volume);
179     apm.ProcessStream(channel_pointers, stream_config, stream_config,
180                       channel_pointers);
181     recommended_input_volume = apm.recommended_stream_analog_level();
182   }
183   return recommended_input_volume;
184 }
185 
186 constexpr char kMinMicLevelFieldTrial[] =
187     "WebRTC-Audio-2ndAgcMinMicLevelExperiment";
188 constexpr char kMinInputVolumeFieldTrial[] = "WebRTC-Audio-Agc2-MinInputVolume";
189 constexpr int kMinInputVolume = 12;
190 
GetMinMicLevelExperimentFieldTrial(absl::optional<int> value)191 std::string GetMinMicLevelExperimentFieldTrial(absl::optional<int> value) {
192   char field_trial_buffer[128];
193   rtc::SimpleStringBuilder builder(field_trial_buffer);
194   if (value.has_value()) {
195     RTC_DCHECK_GE(*value, 0);
196     RTC_DCHECK_LE(*value, 255);
197     builder << kMinMicLevelFieldTrial << "/Enabled-" << *value << "/";
198     builder << kMinInputVolumeFieldTrial << "/Enabled-" << *value << "/";
199   } else {
200     builder << kMinMicLevelFieldTrial << "/Disabled/";
201     builder << kMinInputVolumeFieldTrial << "/Disabled/";
202   }
203   return builder.str();
204 }
205 
206 // TODO(webrtc:7494): Remove the fieldtrial from the input volume tests when
207 // "WebRTC-Audio-2ndAgcMinMicLevelExperiment" and
208 // "WebRTC-Audio-Agc2-MinInputVolume" are removed.
209 class InputVolumeStartupParameterizedTest
210     : public ::testing::TestWithParam<
211           std::tuple<int, absl::optional<int>, bool, bool>> {
212  protected:
InputVolumeStartupParameterizedTest()213   InputVolumeStartupParameterizedTest()
214       : field_trials_(
215             GetMinMicLevelExperimentFieldTrial(std::get<1>(GetParam()))) {}
GetStartupVolume() const216   int GetStartupVolume() const { return std::get<0>(GetParam()); }
GetMinVolume() const217   int GetMinVolume() const {
218     return std::get<1>(GetParam()).value_or(kMinInputVolume);
219   }
GetAgc1AnalogControllerEnabled() const220   bool GetAgc1AnalogControllerEnabled() const {
221     return std::get<2>(GetParam());
222   }
GetAgc2InputVolumeControllerEnabled() const223   bool GetAgc2InputVolumeControllerEnabled() const {
224     return std::get<3>(GetParam());
225   }
226 
227  private:
228   test::ScopedFieldTrials field_trials_;
229 };
230 
231 class InputVolumeNotZeroParameterizedTest
232     : public ::testing::TestWithParam<
233           std::tuple<int, int, absl::optional<int>, bool, bool>> {
234  protected:
InputVolumeNotZeroParameterizedTest()235   InputVolumeNotZeroParameterizedTest()
236       : field_trials_(
237             GetMinMicLevelExperimentFieldTrial(std::get<2>(GetParam()))) {}
GetStartupVolume() const238   int GetStartupVolume() const { return std::get<0>(GetParam()); }
GetVolume() const239   int GetVolume() const { return std::get<1>(GetParam()); }
GetMinVolume() const240   int GetMinVolume() const {
241     return std::get<2>(GetParam()).value_or(kMinInputVolume);
242   }
GetMinMicLevelExperimentEnabled()243   bool GetMinMicLevelExperimentEnabled() {
244     return std::get<2>(GetParam()).has_value();
245   }
GetAgc1AnalogControllerEnabled() const246   bool GetAgc1AnalogControllerEnabled() const {
247     return std::get<3>(GetParam());
248   }
GetAgc2InputVolumeControllerEnabled() const249   bool GetAgc2InputVolumeControllerEnabled() const {
250     return std::get<4>(GetParam());
251   }
252 
253  private:
254   test::ScopedFieldTrials field_trials_;
255 };
256 
257 class InputVolumeZeroParameterizedTest
258     : public ::testing::TestWithParam<
259           std::tuple<int, absl::optional<int>, bool, bool>> {
260  protected:
InputVolumeZeroParameterizedTest()261   InputVolumeZeroParameterizedTest()
262       : field_trials_(
263             GetMinMicLevelExperimentFieldTrial(std::get<1>(GetParam()))) {}
GetStartupVolume() const264   int GetStartupVolume() const { return std::get<0>(GetParam()); }
GetMinVolume() const265   int GetMinVolume() const {
266     return std::get<1>(GetParam()).value_or(kMinInputVolume);
267   }
GetAgc1AnalogControllerEnabled() const268   bool GetAgc1AnalogControllerEnabled() const {
269     return std::get<2>(GetParam());
270   }
GetAgc2InputVolumeControllerEnabled() const271   bool GetAgc2InputVolumeControllerEnabled() const {
272     return std::get<3>(GetParam());
273   }
274 
275  private:
276   test::ScopedFieldTrials field_trials_;
277 };
278 
279 }  // namespace
280 
TEST(AudioProcessingImplTest,AudioParameterChangeTriggersInit)281 TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
282   MockInitialize mock;
283   ON_CALL(mock, InitializeLocked)
284       .WillByDefault(Invoke(&mock, &MockInitialize::RealInitializeLocked));
285 
286   EXPECT_CALL(mock, InitializeLocked).Times(1);
287   mock.Initialize();
288 
289   constexpr size_t kMaxSampleRateHz = 32000;
290   constexpr size_t kMaxNumChannels = 2;
291   std::array<int16_t, kMaxNumChannels * kMaxSampleRateHz / 100> frame;
292   frame.fill(0);
293   StreamConfig config(16000, 1);
294   // Call with the default parameters; there should be an init.
295   EXPECT_CALL(mock, InitializeLocked).Times(0);
296   EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
297   EXPECT_NOERR(
298       mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
299 
300   // New sample rate. (Only impacts ProcessStream).
301   config = StreamConfig(32000, 1);
302   EXPECT_CALL(mock, InitializeLocked).Times(1);
303   EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
304 
305   // New number of channels.
306   config = StreamConfig(32000, 2);
307   EXPECT_CALL(mock, InitializeLocked).Times(2);
308   EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
309   EXPECT_NOERR(
310       mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
311 
312   // A new sample rate passed to ProcessReverseStream should cause an init.
313   config = StreamConfig(16000, 2);
314   EXPECT_CALL(mock, InitializeLocked).Times(1);
315   EXPECT_NOERR(
316       mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
317 }
318 
TEST(AudioProcessingImplTest,UpdateCapturePreGainRuntimeSetting)319 TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
320   rtc::scoped_refptr<AudioProcessing> apm =
321       AudioProcessingBuilderForTesting().Create();
322   webrtc::AudioProcessing::Config apm_config;
323   apm_config.pre_amplifier.enabled = true;
324   apm_config.pre_amplifier.fixed_gain_factor = 1.f;
325   apm->ApplyConfig(apm_config);
326 
327   constexpr int kSampleRateHz = 48000;
328   constexpr int16_t kAudioLevel = 10000;
329   constexpr size_t kNumChannels = 2;
330 
331   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
332   StreamConfig config(kSampleRateHz, kNumChannels);
333   frame.fill(kAudioLevel);
334   apm->ProcessStream(frame.data(), config, config, frame.data());
335   EXPECT_EQ(frame[100], kAudioLevel)
336       << "With factor 1, frame shouldn't be modified.";
337 
338   constexpr float kGainFactor = 2.f;
339   apm->SetRuntimeSetting(
340       AudioProcessing::RuntimeSetting::CreateCapturePreGain(kGainFactor));
341 
342   // Process for two frames to have time to ramp up gain.
343   for (int i = 0; i < 2; ++i) {
344     frame.fill(kAudioLevel);
345     apm->ProcessStream(frame.data(), config, config, frame.data());
346   }
347   EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
348       << "Frame should be amplified.";
349 }
350 
TEST(AudioProcessingImplTest,LevelAdjustmentUpdateCapturePreGainRuntimeSetting)351 TEST(AudioProcessingImplTest,
352      LevelAdjustmentUpdateCapturePreGainRuntimeSetting) {
353   rtc::scoped_refptr<AudioProcessing> apm =
354       AudioProcessingBuilderForTesting().Create();
355   webrtc::AudioProcessing::Config apm_config;
356   apm_config.capture_level_adjustment.enabled = true;
357   apm_config.capture_level_adjustment.pre_gain_factor = 1.f;
358   apm->ApplyConfig(apm_config);
359 
360   constexpr int kSampleRateHz = 48000;
361   constexpr int16_t kAudioLevel = 10000;
362   constexpr size_t kNumChannels = 2;
363 
364   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
365   StreamConfig config(kSampleRateHz, kNumChannels);
366   frame.fill(kAudioLevel);
367   apm->ProcessStream(frame.data(), config, config, frame.data());
368   EXPECT_EQ(frame[100], kAudioLevel)
369       << "With factor 1, frame shouldn't be modified.";
370 
371   constexpr float kGainFactor = 2.f;
372   apm->SetRuntimeSetting(
373       AudioProcessing::RuntimeSetting::CreateCapturePreGain(kGainFactor));
374 
375   // Process for two frames to have time to ramp up gain.
376   for (int i = 0; i < 2; ++i) {
377     frame.fill(kAudioLevel);
378     apm->ProcessStream(frame.data(), config, config, frame.data());
379   }
380   EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
381       << "Frame should be amplified.";
382 }
383 
TEST(AudioProcessingImplTest,LevelAdjustmentUpdateCapturePostGainRuntimeSetting)384 TEST(AudioProcessingImplTest,
385      LevelAdjustmentUpdateCapturePostGainRuntimeSetting) {
386   rtc::scoped_refptr<AudioProcessing> apm =
387       AudioProcessingBuilderForTesting().Create();
388   webrtc::AudioProcessing::Config apm_config;
389   apm_config.capture_level_adjustment.enabled = true;
390   apm_config.capture_level_adjustment.post_gain_factor = 1.f;
391   apm->ApplyConfig(apm_config);
392 
393   constexpr int kSampleRateHz = 48000;
394   constexpr int16_t kAudioLevel = 10000;
395   constexpr size_t kNumChannels = 2;
396 
397   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
398   StreamConfig config(kSampleRateHz, kNumChannels);
399   frame.fill(kAudioLevel);
400   apm->ProcessStream(frame.data(), config, config, frame.data());
401   EXPECT_EQ(frame[100], kAudioLevel)
402       << "With factor 1, frame shouldn't be modified.";
403 
404   constexpr float kGainFactor = 2.f;
405   apm->SetRuntimeSetting(
406       AudioProcessing::RuntimeSetting::CreateCapturePostGain(kGainFactor));
407 
408   // Process for two frames to have time to ramp up gain.
409   for (int i = 0; i < 2; ++i) {
410     frame.fill(kAudioLevel);
411     apm->ProcessStream(frame.data(), config, config, frame.data());
412   }
413   EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
414       << "Frame should be amplified.";
415 }
416 
TEST(AudioProcessingImplTest,EchoControllerObservesSetCaptureUsageChange)417 TEST(AudioProcessingImplTest, EchoControllerObservesSetCaptureUsageChange) {
418   // Tests that the echo controller observes that the capture usage has been
419   // updated.
420   auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
421   const MockEchoControlFactory* echo_control_factory_ptr =
422       echo_control_factory.get();
423 
424   rtc::scoped_refptr<AudioProcessing> apm =
425       AudioProcessingBuilderForTesting()
426           .SetEchoControlFactory(std::move(echo_control_factory))
427           .Create();
428 
429   constexpr int16_t kAudioLevel = 10000;
430   constexpr int kSampleRateHz = 48000;
431   constexpr int kNumChannels = 2;
432   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
433   StreamConfig config(kSampleRateHz, kNumChannels);
434   frame.fill(kAudioLevel);
435 
436   MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
437 
438   // Ensure that SetCaptureOutputUsage is not called when no runtime settings
439   // are passed.
440   EXPECT_CALL(*echo_control_mock, SetCaptureOutputUsage(testing::_)).Times(0);
441   apm->ProcessStream(frame.data(), config, config, frame.data());
442 
443   // Ensure that SetCaptureOutputUsage is called with the right information when
444   // a runtime setting is passed.
445   EXPECT_CALL(*echo_control_mock,
446               SetCaptureOutputUsage(/*capture_output_used=*/false))
447       .Times(1);
448   EXPECT_TRUE(apm->PostRuntimeSetting(
449       AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
450           /*capture_output_used=*/false)));
451   apm->ProcessStream(frame.data(), config, config, frame.data());
452 
453   EXPECT_CALL(*echo_control_mock,
454               SetCaptureOutputUsage(/*capture_output_used=*/true))
455       .Times(1);
456   EXPECT_TRUE(apm->PostRuntimeSetting(
457       AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
458           /*capture_output_used=*/true)));
459   apm->ProcessStream(frame.data(), config, config, frame.data());
460 
461   // The number of positions to place items in the queue is equal to the queue
462   // size minus 1.
463   constexpr int kNumSlotsInQueue = RuntimeSettingQueueSize();
464 
465   // Ensure that SetCaptureOutputUsage is called with the right information when
466   // many runtime settings are passed.
467   for (int k = 0; k < kNumSlotsInQueue - 1; ++k) {
468     EXPECT_TRUE(apm->PostRuntimeSetting(
469         AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
470             /*capture_output_used=*/false)));
471   }
472   EXPECT_CALL(*echo_control_mock,
473               SetCaptureOutputUsage(/*capture_output_used=*/false))
474       .Times(kNumSlotsInQueue - 1);
475   apm->ProcessStream(frame.data(), config, config, frame.data());
476 
477   // Ensure that SetCaptureOutputUsage is properly called with the fallback
478   // value when the runtime settings queue becomes full.
479   for (int k = 0; k < kNumSlotsInQueue; ++k) {
480     EXPECT_TRUE(apm->PostRuntimeSetting(
481         AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
482             /*capture_output_used=*/false)));
483   }
484   EXPECT_FALSE(apm->PostRuntimeSetting(
485       AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
486           /*capture_output_used=*/false)));
487   EXPECT_FALSE(apm->PostRuntimeSetting(
488       AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
489           /*capture_output_used=*/false)));
490   EXPECT_CALL(*echo_control_mock,
491               SetCaptureOutputUsage(/*capture_output_used=*/false))
492       .Times(kNumSlotsInQueue);
493   EXPECT_CALL(*echo_control_mock,
494               SetCaptureOutputUsage(/*capture_output_used=*/true))
495       .Times(1);
496   apm->ProcessStream(frame.data(), config, config, frame.data());
497 }
498 
TEST(AudioProcessingImplTest,EchoControllerObservesPreAmplifierEchoPathGainChange)499 TEST(AudioProcessingImplTest,
500      EchoControllerObservesPreAmplifierEchoPathGainChange) {
501   // Tests that the echo controller observes an echo path gain change when the
502   // pre-amplifier submodule changes the gain.
503   auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
504   const auto* echo_control_factory_ptr = echo_control_factory.get();
505 
506   rtc::scoped_refptr<AudioProcessing> apm =
507       AudioProcessingBuilderForTesting()
508           .SetEchoControlFactory(std::move(echo_control_factory))
509           .Create();
510   // Disable AGC.
511   webrtc::AudioProcessing::Config apm_config;
512   apm_config.gain_controller1.enabled = false;
513   apm_config.gain_controller2.enabled = false;
514   apm_config.pre_amplifier.enabled = true;
515   apm_config.pre_amplifier.fixed_gain_factor = 1.f;
516   apm->ApplyConfig(apm_config);
517 
518   constexpr int16_t kAudioLevel = 10000;
519   constexpr size_t kSampleRateHz = 48000;
520   constexpr size_t kNumChannels = 2;
521   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
522   StreamConfig config(kSampleRateHz, kNumChannels);
523   frame.fill(kAudioLevel);
524 
525   MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
526 
527   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
528   EXPECT_CALL(*echo_control_mock,
529               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
530       .Times(1);
531   apm->ProcessStream(frame.data(), config, config, frame.data());
532 
533   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
534   EXPECT_CALL(*echo_control_mock,
535               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
536       .Times(1);
537   apm->SetRuntimeSetting(
538       AudioProcessing::RuntimeSetting::CreateCapturePreGain(2.f));
539   apm->ProcessStream(frame.data(), config, config, frame.data());
540 }
541 
TEST(AudioProcessingImplTest,EchoControllerObservesLevelAdjustmentPreGainEchoPathGainChange)542 TEST(AudioProcessingImplTest,
543      EchoControllerObservesLevelAdjustmentPreGainEchoPathGainChange) {
544   // Tests that the echo controller observes an echo path gain change when the
545   // pre-amplifier submodule changes the gain.
546   auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
547   const auto* echo_control_factory_ptr = echo_control_factory.get();
548 
549   rtc::scoped_refptr<AudioProcessing> apm =
550       AudioProcessingBuilderForTesting()
551           .SetEchoControlFactory(std::move(echo_control_factory))
552           .Create();
553   // Disable AGC.
554   webrtc::AudioProcessing::Config apm_config;
555   apm_config.gain_controller1.enabled = false;
556   apm_config.gain_controller2.enabled = false;
557   apm_config.capture_level_adjustment.enabled = true;
558   apm_config.capture_level_adjustment.pre_gain_factor = 1.f;
559   apm->ApplyConfig(apm_config);
560 
561   constexpr int16_t kAudioLevel = 10000;
562   constexpr size_t kSampleRateHz = 48000;
563   constexpr size_t kNumChannels = 2;
564   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
565   StreamConfig config(kSampleRateHz, kNumChannels);
566   frame.fill(kAudioLevel);
567 
568   MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
569 
570   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
571   EXPECT_CALL(*echo_control_mock,
572               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
573       .Times(1);
574   apm->ProcessStream(frame.data(), config, config, frame.data());
575 
576   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
577   EXPECT_CALL(*echo_control_mock,
578               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
579       .Times(1);
580   apm->SetRuntimeSetting(
581       AudioProcessing::RuntimeSetting::CreateCapturePreGain(2.f));
582   apm->ProcessStream(frame.data(), config, config, frame.data());
583 }
584 
TEST(AudioProcessingImplTest,EchoControllerObservesAnalogAgc1EchoPathGainChange)585 TEST(AudioProcessingImplTest,
586      EchoControllerObservesAnalogAgc1EchoPathGainChange) {
587   // Tests that the echo controller observes an echo path gain change when the
588   // AGC1 analog adaptive submodule changes the analog gain.
589   auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
590   const auto* echo_control_factory_ptr = echo_control_factory.get();
591 
592   rtc::scoped_refptr<AudioProcessing> apm =
593       AudioProcessingBuilderForTesting()
594           .SetEchoControlFactory(std::move(echo_control_factory))
595           .Create();
596   webrtc::AudioProcessing::Config apm_config;
597   // Enable AGC1.
598   apm_config.gain_controller1.enabled = true;
599   apm_config.gain_controller1.analog_gain_controller.enabled = true;
600   apm_config.gain_controller2.enabled = false;
601   apm_config.pre_amplifier.enabled = false;
602   apm->ApplyConfig(apm_config);
603 
604   constexpr int16_t kAudioLevel = 1000;
605   constexpr size_t kSampleRateHz = 48000;
606   constexpr size_t kNumChannels = 2;
607   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
608   StreamConfig stream_config(kSampleRateHz, kNumChannels);
609   frame.fill(kAudioLevel);
610 
611   MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
612 
613   constexpr int kInitialStreamAnalogLevel = 123;
614   apm->set_stream_analog_level(kInitialStreamAnalogLevel);
615 
616   // When the first fame is processed, no echo path gain change must be
617   // detected.
618   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
619   EXPECT_CALL(*echo_control_mock,
620               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
621       .Times(1);
622   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
623 
624   // Simulate the application of the recommended analog level.
625   int recommended_analog_level = apm->recommended_stream_analog_level();
626   if (recommended_analog_level == kInitialStreamAnalogLevel) {
627     // Force an analog gain change if it did not happen.
628     recommended_analog_level++;
629   }
630   apm->set_stream_analog_level(recommended_analog_level);
631 
632   // After the first fame and with a stream analog level change, the echo path
633   // gain change must be detected.
634   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
635   EXPECT_CALL(*echo_control_mock,
636               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
637       .Times(1);
638   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
639 }
640 
641 // Tests that a stream is successfully processed when AGC2 adaptive digital is
642 // used and when the field trial
643 // `WebRTC-Audio-TransientSuppressorVadMode/Enabled-Default/` is set.
TEST(AudioProcessingImplTest,ProcessWithAgc2AndTransientSuppressorVadModeDefault)644 TEST(AudioProcessingImplTest,
645      ProcessWithAgc2AndTransientSuppressorVadModeDefault) {
646   webrtc::test::ScopedFieldTrials field_trials(
647       "WebRTC-Audio-TransientSuppressorVadMode/Enabled-Default/");
648   rtc::scoped_refptr<AudioProcessing> apm = AudioProcessingBuilder().Create();
649   ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
650   webrtc::AudioProcessing::Config apm_config;
651   // Disable AGC1 analog.
652   apm_config.gain_controller1.enabled = false;
653   // Enable AGC2 digital.
654   apm_config.gain_controller2.enabled = true;
655   apm_config.gain_controller2.adaptive_digital.enabled = true;
656   apm->ApplyConfig(apm_config);
657   constexpr int kSampleRateHz = 48000;
658   constexpr int kNumChannels = 1;
659   std::array<float, kSampleRateHz / 100> buffer;
660   float* channel_pointers[] = {buffer.data()};
661   StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
662                              /*num_channels=*/kNumChannels);
663   Random random_generator(2341U);
664   constexpr int kFramesToProcess = 10;
665   for (int i = 0; i < kFramesToProcess; ++i) {
666     RandomizeSampleVector(&random_generator, buffer);
667     ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
668                                  channel_pointers),
669               kNoErr);
670   }
671 }
672 
673 // Tests that a stream is successfully processed when AGC2 adaptive digital is
674 // used and when the field trial
675 // `WebRTC-Audio-TransientSuppressorVadMode/Enabled-RnnVad/` is set.
TEST(AudioProcessingImplTest,ProcessWithAgc2AndTransientSuppressorVadModeRnnVad)676 TEST(AudioProcessingImplTest,
677      ProcessWithAgc2AndTransientSuppressorVadModeRnnVad) {
678   webrtc::test::ScopedFieldTrials field_trials(
679       "WebRTC-Audio-TransientSuppressorVadMode/Enabled-RnnVad/");
680   rtc::scoped_refptr<AudioProcessing> apm = AudioProcessingBuilder().Create();
681   ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
682   webrtc::AudioProcessing::Config apm_config;
683   // Disable AGC1 analog.
684   apm_config.gain_controller1.enabled = false;
685   // Enable AGC2 digital.
686   apm_config.gain_controller2.enabled = true;
687   apm_config.gain_controller2.adaptive_digital.enabled = true;
688   apm->ApplyConfig(apm_config);
689   constexpr int kSampleRateHz = 48000;
690   constexpr int kNumChannels = 1;
691   std::array<float, kSampleRateHz / 100> buffer;
692   float* channel_pointers[] = {buffer.data()};
693   StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
694                              /*num_channels=*/kNumChannels);
695   Random random_generator(2341U);
696   constexpr int kFramesToProcess = 10;
697   for (int i = 0; i < kFramesToProcess; ++i) {
698     RandomizeSampleVector(&random_generator, buffer);
699     ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
700                                  channel_pointers),
701               kNoErr);
702   }
703 }
704 
TEST(AudioProcessingImplTest,EchoControllerObservesPlayoutVolumeChange)705 TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) {
706   // Tests that the echo controller observes an echo path gain change when a
707   // playout volume change is reported.
708   auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
709   const auto* echo_control_factory_ptr = echo_control_factory.get();
710 
711   rtc::scoped_refptr<AudioProcessing> apm =
712       AudioProcessingBuilderForTesting()
713           .SetEchoControlFactory(std::move(echo_control_factory))
714           .Create();
715   // Disable AGC.
716   webrtc::AudioProcessing::Config apm_config;
717   apm_config.gain_controller1.enabled = false;
718   apm_config.gain_controller2.enabled = false;
719   apm->ApplyConfig(apm_config);
720 
721   constexpr int16_t kAudioLevel = 10000;
722   constexpr size_t kSampleRateHz = 48000;
723   constexpr size_t kNumChannels = 2;
724   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
725   StreamConfig stream_config(kSampleRateHz, kNumChannels);
726   frame.fill(kAudioLevel);
727 
728   MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
729 
730   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
731   EXPECT_CALL(*echo_control_mock,
732               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
733       .Times(1);
734   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
735 
736   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
737   EXPECT_CALL(*echo_control_mock,
738               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
739       .Times(1);
740   apm->SetRuntimeSetting(
741       AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
742   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
743 
744   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
745   EXPECT_CALL(*echo_control_mock,
746               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
747       .Times(1);
748   apm->SetRuntimeSetting(
749       AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
750   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
751 
752   EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
753   EXPECT_CALL(*echo_control_mock,
754               ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
755       .Times(1);
756   apm->SetRuntimeSetting(
757       AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(100));
758   apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
759 }
760 
TEST(AudioProcessingImplTest,RenderPreProcessorBeforeEchoDetector)761 TEST(AudioProcessingImplTest, RenderPreProcessorBeforeEchoDetector) {
762   // Make sure that signal changes caused by a render pre-processing sub-module
763   // take place before any echo detector analysis.
764   auto test_echo_detector = rtc::make_ref_counted<TestEchoDetector>();
765   std::unique_ptr<CustomProcessing> test_render_pre_processor(
766       new TestRenderPreProcessor());
767   // Create APM injecting the test echo detector and render pre-processor.
768   rtc::scoped_refptr<AudioProcessing> apm =
769       AudioProcessingBuilderForTesting()
770           .SetEchoDetector(test_echo_detector)
771           .SetRenderPreProcessing(std::move(test_render_pre_processor))
772           .Create();
773   webrtc::AudioProcessing::Config apm_config;
774   apm_config.pre_amplifier.enabled = true;
775   apm->ApplyConfig(apm_config);
776 
777   constexpr int16_t kAudioLevel = 1000;
778   constexpr int kSampleRateHz = 16000;
779   constexpr size_t kNumChannels = 1;
780   // Explicitly initialize APM to ensure no render frames are discarded.
781   const ProcessingConfig processing_config = {{
782       {kSampleRateHz, kNumChannels},
783       {kSampleRateHz, kNumChannels},
784       {kSampleRateHz, kNumChannels},
785       {kSampleRateHz, kNumChannels},
786   }};
787   apm->Initialize(processing_config);
788 
789   std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
790   StreamConfig stream_config(kSampleRateHz, kNumChannels);
791 
792   constexpr float kAudioLevelFloat = static_cast<float>(kAudioLevel);
793   constexpr float kExpectedPreprocessedAudioLevel =
794       TestRenderPreProcessor::ProcessSample(kAudioLevelFloat);
795   ASSERT_NE(kAudioLevelFloat, kExpectedPreprocessedAudioLevel);
796 
797   // Analyze a render stream frame.
798   frame.fill(kAudioLevel);
799   ASSERT_EQ(AudioProcessing::Error::kNoError,
800             apm->ProcessReverseStream(frame.data(), stream_config,
801                                       stream_config, frame.data()));
802   // Trigger a call to in EchoDetector::AnalyzeRenderAudio() via
803   // ProcessStream().
804   frame.fill(kAudioLevel);
805   ASSERT_EQ(AudioProcessing::Error::kNoError,
806             apm->ProcessStream(frame.data(), stream_config, stream_config,
807                                frame.data()));
808   // Regardless of how the call to in EchoDetector::AnalyzeRenderAudio() is
809   // triggered, the line below checks that the call has occurred. If not, the
810   // APM implementation may have changed and this test might need to be adapted.
811   ASSERT_TRUE(test_echo_detector->analyze_render_audio_called());
812   // Check that the data read in EchoDetector::AnalyzeRenderAudio() is that
813   // produced by the render pre-processor.
814   EXPECT_EQ(kExpectedPreprocessedAudioLevel,
815             test_echo_detector->last_render_audio_first_sample());
816 }
817 
818 // Disabling build-optional submodules and trying to enable them via the APM
819 // config should be bit-exact with running APM with said submodules disabled.
820 // This mainly tests that SetCreateOptionalSubmodulesForTesting has an effect.
TEST(ApmWithSubmodulesExcludedTest,BitexactWithDisabledModules)821 TEST(ApmWithSubmodulesExcludedTest, BitexactWithDisabledModules) {
822   auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
823   ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
824 
825   ApmSubmoduleCreationOverrides overrides;
826   overrides.transient_suppression = true;
827   apm->OverrideSubmoduleCreationForTesting(overrides);
828 
829   AudioProcessing::Config apm_config = apm->GetConfig();
830   apm_config.transient_suppression.enabled = true;
831   apm->ApplyConfig(apm_config);
832 
833   rtc::scoped_refptr<AudioProcessing> apm_reference =
834       AudioProcessingBuilder().Create();
835   apm_config = apm_reference->GetConfig();
836   apm_config.transient_suppression.enabled = false;
837   apm_reference->ApplyConfig(apm_config);
838 
839   constexpr int kSampleRateHz = 16000;
840   constexpr int kNumChannels = 1;
841   std::array<float, kSampleRateHz / 100> buffer;
842   std::array<float, kSampleRateHz / 100> buffer_reference;
843   float* channel_pointers[] = {buffer.data()};
844   float* channel_pointers_reference[] = {buffer_reference.data()};
845   StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
846                              /*num_channels=*/kNumChannels);
847   Random random_generator(2341U);
848   constexpr int kFramesToProcessPerConfiguration = 10;
849 
850   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
851     RandomizeSampleVector(&random_generator, buffer);
852     std::copy(buffer.begin(), buffer.end(), buffer_reference.begin());
853     ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
854                                  channel_pointers),
855               kNoErr);
856     ASSERT_EQ(
857         apm_reference->ProcessStream(channel_pointers_reference, stream_config,
858                                      stream_config, channel_pointers_reference),
859         kNoErr);
860     for (int j = 0; j < kSampleRateHz / 100; ++j) {
861       EXPECT_EQ(buffer[j], buffer_reference[j]);
862     }
863   }
864 }
865 
866 // Disable transient suppressor creation and run APM in ways that should trigger
867 // calls to the transient suppressor API.
TEST(ApmWithSubmodulesExcludedTest,ReinitializeTransientSuppressor)868 TEST(ApmWithSubmodulesExcludedTest, ReinitializeTransientSuppressor) {
869   auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
870   ASSERT_EQ(apm->Initialize(), kNoErr);
871 
872   ApmSubmoduleCreationOverrides overrides;
873   overrides.transient_suppression = true;
874   apm->OverrideSubmoduleCreationForTesting(overrides);
875 
876   AudioProcessing::Config config = apm->GetConfig();
877   config.transient_suppression.enabled = true;
878   apm->ApplyConfig(config);
879   // 960 samples per frame: 10 ms of <= 48 kHz audio with <= 2 channels.
880   float buffer[960];
881   float* channel_pointers[] = {&buffer[0], &buffer[480]};
882   Random random_generator(2341U);
883   constexpr int kFramesToProcessPerConfiguration = 3;
884 
885   StreamConfig initial_stream_config(/*sample_rate_hz=*/16000,
886                                      /*num_channels=*/1);
887   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
888     RandomizeSampleVector(&random_generator, buffer);
889     EXPECT_EQ(apm->ProcessStream(channel_pointers, initial_stream_config,
890                                  initial_stream_config, channel_pointers),
891               kNoErr);
892   }
893 
894   StreamConfig stereo_stream_config(/*sample_rate_hz=*/16000,
895                                     /*num_channels=*/2);
896   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
897     RandomizeSampleVector(&random_generator, buffer);
898     EXPECT_EQ(apm->ProcessStream(channel_pointers, stereo_stream_config,
899                                  stereo_stream_config, channel_pointers),
900               kNoErr);
901   }
902 
903   StreamConfig high_sample_rate_stream_config(/*sample_rate_hz=*/48000,
904                                               /*num_channels=*/2);
905   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
906     RandomizeSampleVector(&random_generator, buffer);
907     EXPECT_EQ(
908         apm->ProcessStream(channel_pointers, high_sample_rate_stream_config,
909                            high_sample_rate_stream_config, channel_pointers),
910         kNoErr);
911   }
912 }
913 
914 // Disable transient suppressor creation and run APM in ways that should trigger
915 // calls to the transient suppressor API.
TEST(ApmWithSubmodulesExcludedTest,ToggleTransientSuppressor)916 TEST(ApmWithSubmodulesExcludedTest, ToggleTransientSuppressor) {
917   auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
918   ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
919 
920   ApmSubmoduleCreationOverrides overrides;
921   overrides.transient_suppression = true;
922   apm->OverrideSubmoduleCreationForTesting(overrides);
923 
924   //  960 samples per frame: 10 ms of <= 48 kHz audio with <= 2 channels.
925   float buffer[960];
926   float* channel_pointers[] = {&buffer[0], &buffer[480]};
927   Random random_generator(2341U);
928   constexpr int kFramesToProcessPerConfiguration = 3;
929   StreamConfig stream_config(/*sample_rate_hz=*/16000,
930                              /*num_channels=*/1);
931 
932   AudioProcessing::Config config = apm->GetConfig();
933   config.transient_suppression.enabled = true;
934   apm->ApplyConfig(config);
935   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
936     RandomizeSampleVector(&random_generator, buffer);
937     EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
938                                  channel_pointers),
939               kNoErr);
940   }
941 
942   config = apm->GetConfig();
943   config.transient_suppression.enabled = false;
944   apm->ApplyConfig(config);
945   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
946     RandomizeSampleVector(&random_generator, buffer);
947     EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
948                                  channel_pointers),
949               kNoErr);
950   }
951 
952   config = apm->GetConfig();
953   config.transient_suppression.enabled = true;
954   apm->ApplyConfig(config);
955   for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
956     RandomizeSampleVector(&random_generator, buffer);
957     EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
958                                  channel_pointers),
959               kNoErr);
960   }
961 }
962 
963 // Tests that the minimum startup volume is applied at the startup.
TEST_P(InputVolumeStartupParameterizedTest,VerifyStartupMinVolumeAppliedAtStartup)964 TEST_P(InputVolumeStartupParameterizedTest,
965        VerifyStartupMinVolumeAppliedAtStartup) {
966   const int applied_startup_input_volume = GetStartupVolume();
967   const int expected_volume =
968       std::max(applied_startup_input_volume, GetMinVolume());
969   const bool agc1_analog_controller_enabled = GetAgc1AnalogControllerEnabled();
970   const bool agc2_input_volume_controller_enabled =
971       GetAgc2InputVolumeControllerEnabled();
972   auto apm = CreateApmForInputVolumeTest(agc1_analog_controller_enabled,
973                                          agc2_input_volume_controller_enabled);
974 
975   const int recommended_input_volume =
976       ProcessInputVolume(*apm, /*num_frames=*/1, applied_startup_input_volume);
977 
978   if (!agc1_analog_controller_enabled &&
979       !agc2_input_volume_controller_enabled) {
980     // No input volume changes if none of the analog controllers is enabled.
981     ASSERT_EQ(recommended_input_volume, applied_startup_input_volume);
982   } else {
983     ASSERT_EQ(recommended_input_volume, expected_volume);
984   }
985 }
986 
987 // Tests that the minimum input volume is applied if the volume is manually
988 // adjusted to a non-zero value 1) always for AGC2 input volume controller and
989 // 2) only if "WebRTC-Audio-2ndAgcMinMicLevelExperiment" is enabled for AGC1
990 // analog controller.
TEST_P(InputVolumeNotZeroParameterizedTest,VerifyMinVolumeMaybeAppliedAfterManualVolumeAdjustments)991 TEST_P(InputVolumeNotZeroParameterizedTest,
992        VerifyMinVolumeMaybeAppliedAfterManualVolumeAdjustments) {
993   const int applied_startup_input_volume = GetStartupVolume();
994   const int applied_input_volume = GetVolume();
995   const int expected_volume = std::max(applied_input_volume, GetMinVolume());
996   const bool agc1_analog_controller_enabled = GetAgc1AnalogControllerEnabled();
997   const bool agc2_input_volume_controller_enabled =
998       GetAgc2InputVolumeControllerEnabled();
999   auto apm = CreateApmForInputVolumeTest(agc1_analog_controller_enabled,
1000                                          agc2_input_volume_controller_enabled);
1001 
1002   ProcessInputVolume(*apm, /*num_frames=*/1, applied_startup_input_volume);
1003   const int recommended_input_volume =
1004       ProcessInputVolume(*apm, /*num_frames=*/1, applied_input_volume);
1005 
1006   ASSERT_NE(applied_input_volume, 0);
1007 
1008   if (!agc1_analog_controller_enabled &&
1009       !agc2_input_volume_controller_enabled) {
1010     // No input volume changes if none of the analog controllers is enabled.
1011     ASSERT_EQ(recommended_input_volume, applied_input_volume);
1012   } else {
1013     if (GetMinMicLevelExperimentEnabled() ||
1014         (!agc1_analog_controller_enabled &&
1015          agc2_input_volume_controller_enabled)) {
1016       ASSERT_EQ(recommended_input_volume, expected_volume);
1017     } else {
1018       ASSERT_EQ(recommended_input_volume, applied_input_volume);
1019     }
1020   }
1021 }
1022 
1023 // Tests that the minimum input volume is not applied if the volume is manually
1024 // adjusted to zero.
TEST_P(InputVolumeZeroParameterizedTest,VerifyMinVolumeNotAppliedAfterManualVolumeAdjustments)1025 TEST_P(InputVolumeZeroParameterizedTest,
1026        VerifyMinVolumeNotAppliedAfterManualVolumeAdjustments) {
1027   constexpr int kZeroVolume = 0;
1028   const int applied_startup_input_volume = GetStartupVolume();
1029   const bool agc1_analog_controller_enabled = GetAgc1AnalogControllerEnabled();
1030   const bool agc2_input_volume_controller_enabled =
1031       GetAgc2InputVolumeControllerEnabled();
1032   auto apm = CreateApmForInputVolumeTest(agc1_analog_controller_enabled,
1033                                          agc2_input_volume_controller_enabled);
1034 
1035   const int recommended_input_volume_after_startup =
1036       ProcessInputVolume(*apm, /*num_frames=*/1, applied_startup_input_volume);
1037   const int recommended_input_volume =
1038       ProcessInputVolume(*apm, /*num_frames=*/1, kZeroVolume);
1039 
1040   if (!agc1_analog_controller_enabled &&
1041       !agc2_input_volume_controller_enabled) {
1042     // No input volume changes if none of the analog controllers is enabled.
1043     ASSERT_EQ(recommended_input_volume, kZeroVolume);
1044   } else {
1045     ASSERT_NE(recommended_input_volume, recommended_input_volume_after_startup);
1046     ASSERT_EQ(recommended_input_volume, kZeroVolume);
1047   }
1048 }
1049 
1050 // Tests that the minimum input volume is applied if the volume is not zero
1051 // before it is automatically adjusted.
TEST_P(InputVolumeNotZeroParameterizedTest,VerifyMinVolumeAppliedAfterAutomaticVolumeAdjustments)1052 TEST_P(InputVolumeNotZeroParameterizedTest,
1053        VerifyMinVolumeAppliedAfterAutomaticVolumeAdjustments) {
1054   const int applied_startup_input_volume = GetStartupVolume();
1055   const int applied_input_volume = GetVolume();
1056   const bool agc1_analog_controller_enabled = GetAgc1AnalogControllerEnabled();
1057   const bool agc2_input_volume_controller_enabled =
1058       GetAgc2InputVolumeControllerEnabled();
1059   auto apm = CreateApmForInputVolumeTest(agc1_analog_controller_enabled,
1060                                          agc2_input_volume_controller_enabled);
1061 
1062   ProcessInputVolume(*apm, /*num_frames=*/1, applied_startup_input_volume);
1063   const int recommended_input_volume =
1064       ProcessInputVolume(*apm, /*num_frames=*/400, applied_input_volume);
1065 
1066   ASSERT_NE(applied_input_volume, 0);
1067 
1068   if (!agc1_analog_controller_enabled &&
1069       !agc2_input_volume_controller_enabled) {
1070     // No input volume changes if none of the analog controllers is enabled.
1071     ASSERT_EQ(recommended_input_volume, applied_input_volume);
1072   } else {
1073     if (recommended_input_volume != applied_input_volume) {
1074       ASSERT_GE(recommended_input_volume, GetMinVolume());
1075     }
1076   }
1077 }
1078 
1079 // Tests that the minimum input volume is not applied if the volume is zero
1080 // before it is automatically adjusted.
TEST_P(InputVolumeZeroParameterizedTest,VerifyMinVolumeNotAppliedAfterAutomaticVolumeAdjustments)1081 TEST_P(InputVolumeZeroParameterizedTest,
1082        VerifyMinVolumeNotAppliedAfterAutomaticVolumeAdjustments) {
1083   constexpr int kZeroVolume = 0;
1084   const int applied_startup_input_volume = GetStartupVolume();
1085   const bool agc1_analog_controller_enabled = GetAgc1AnalogControllerEnabled();
1086   const bool agc2_input_volume_controller_enabled =
1087       GetAgc2InputVolumeControllerEnabled();
1088   auto apm = CreateApmForInputVolumeTest(agc1_analog_controller_enabled,
1089                                          agc2_input_volume_controller_enabled);
1090 
1091   const int recommended_input_volume_after_startup =
1092       ProcessInputVolume(*apm, /*num_frames=*/1, applied_startup_input_volume);
1093   const int recommended_input_volume =
1094       ProcessInputVolume(*apm, /*num_frames=*/400, kZeroVolume);
1095 
1096   if (!agc1_analog_controller_enabled &&
1097       !agc2_input_volume_controller_enabled) {
1098     // No input volume changes if none of the analog controllers is enabled.
1099     ASSERT_EQ(recommended_input_volume, kZeroVolume);
1100   } else {
1101     ASSERT_NE(recommended_input_volume, recommended_input_volume_after_startup);
1102     ASSERT_EQ(recommended_input_volume, kZeroVolume);
1103   }
1104 }
1105 
1106 INSTANTIATE_TEST_SUITE_P(AudioProcessingImplTest,
1107                          InputVolumeStartupParameterizedTest,
1108                          ::testing::Combine(::testing::Values(0, 5, 30),
1109                                             ::testing::Values(absl::nullopt,
1110                                                               20),
1111                                             ::testing::Bool(),
1112                                             ::testing::Bool()));
1113 
1114 INSTANTIATE_TEST_SUITE_P(AudioProcessingImplTest,
1115                          InputVolumeNotZeroParameterizedTest,
1116                          ::testing::Combine(::testing::Values(0, 5, 15),
1117                                             ::testing::Values(1, 5, 30),
1118                                             ::testing::Values(absl::nullopt,
1119                                                               20),
1120                                             ::testing::Bool(),
1121                                             ::testing::Bool()));
1122 
1123 INSTANTIATE_TEST_SUITE_P(AudioProcessingImplTest,
1124                          InputVolumeZeroParameterizedTest,
1125                          ::testing::Combine(::testing::Values(0, 5, 15),
1126                                             ::testing::Values(absl::nullopt,
1127                                                               20),
1128                                             ::testing::Bool(),
1129                                             ::testing::Bool()));
1130 
1131 // When the input volume is not emulated and no input volume controller is
1132 // active, the recommended volume must always be the applied volume.
TEST(AudioProcessingImplTest,RecommendAppliedInputVolumeWithNoAgcWithNoEmulation)1133 TEST(AudioProcessingImplTest,
1134      RecommendAppliedInputVolumeWithNoAgcWithNoEmulation) {
1135   auto apm = AudioProcessingBuilder()
1136                  .SetConfig({.capture_level_adjustment = {.enabled = false},
1137                              .gain_controller1 = {.enabled = false}})
1138                  .Create();
1139 
1140   constexpr int kOneFrame = 1;
1141   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1142   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1143   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1144 }
1145 
1146 // When the input volume is emulated, the recommended volume must always be the
1147 // applied volume and at any time it must not be that set in the input volume
1148 // emulator.
1149 // TODO(bugs.webrtc.org/14581): Enable when APM fixed to let this test pass.
TEST(AudioProcessingImplTest,DISABLED_RecommendAppliedInputVolumeWithNoAgcWithEmulation)1150 TEST(AudioProcessingImplTest,
1151      DISABLED_RecommendAppliedInputVolumeWithNoAgcWithEmulation) {
1152   auto apm =
1153       AudioProcessingBuilder()
1154           .SetConfig({.capture_level_adjustment = {.enabled = true,
1155                                                    .analog_mic_gain_emulation{
1156                                                        .enabled = true,
1157                                                        .initial_level = 255}},
1158                       .gain_controller1 = {.enabled = false}})
1159           .Create();
1160 
1161   constexpr int kOneFrame = 1;
1162   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1163   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1164   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1165 }
1166 
1167 // Even if there is an enabled input volume controller, when the input volume is
1168 // emulated, the recommended volume is always the applied volume because the
1169 // active controller must only adjust the internally emulated volume and leave
1170 // the externally applied volume unchanged.
1171 // TODO(bugs.webrtc.org/14581): Enable when APM fixed to let this test pass.
TEST(AudioProcessingImplTest,DISABLED_RecommendAppliedInputVolumeWithAgcWithEmulation)1172 TEST(AudioProcessingImplTest,
1173      DISABLED_RecommendAppliedInputVolumeWithAgcWithEmulation) {
1174   auto apm =
1175       AudioProcessingBuilder()
1176           .SetConfig({.capture_level_adjustment = {.enabled = true,
1177                                                    .analog_mic_gain_emulation{
1178                                                        .enabled = true}},
1179                       .gain_controller1 = {.enabled = true,
1180                                            .analog_gain_controller{
1181                                                .enabled = true,
1182                                            }}})
1183           .Create();
1184 
1185   constexpr int kOneFrame = 1;
1186   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1187   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1188   EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1189 }
1190 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigAdjustedWhenExperimentEnabledAndAgc1AnalogEnabled)1191 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1192      ConfigAdjustedWhenExperimentEnabledAndAgc1AnalogEnabled) {
1193   webrtc::test::ScopedFieldTrials field_trials(
1194       "WebRTC-Audio-InputVolumeControllerExperiment/"
1195       "Enabled,"
1196       "enable_clipping_predictor:true,"
1197       "clipped_level_min:20,"
1198       "clipped_level_step:30,"
1199       "clipped_ratio_threshold:0.4,"
1200       "clipped_wait_frames:50,"
1201       "target_range_max_dbfs:-6,"
1202       "target_range_min_dbfs:-70,"
1203       "update_input_volume_wait_frames:80,"
1204       "speech_probability_threshold:0.9,"
1205       "speech_ratio_threshold:1.0/");
1206 
1207   AudioProcessingBuilderForTesting apm_builder;
1208 
1209   // Set a config with analog AGC1 enabled.
1210   AudioProcessing::Config config;
1211   config.gain_controller1.enabled = true;
1212   config.gain_controller1.analog_gain_controller.enabled = true;
1213   config.gain_controller1.analog_gain_controller.enable_digital_adaptive = true;
1214   config.gain_controller2.enabled = false;
1215   config.gain_controller1.mode =
1216       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1217 
1218   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1219 
1220   apm_builder.SetConfig(config);
1221 
1222   auto apm = apm_builder.Create();
1223   auto adjusted_config = apm->GetConfig();
1224 
1225   // Expect the config to be adjusted.
1226   EXPECT_FALSE(adjusted_config.gain_controller1.enabled);
1227   EXPECT_FALSE(adjusted_config.gain_controller1.analog_gain_controller.enabled);
1228   EXPECT_TRUE(adjusted_config.gain_controller2.enabled);
1229   EXPECT_TRUE(adjusted_config.gain_controller2.adaptive_digital.enabled);
1230   EXPECT_TRUE(adjusted_config.gain_controller2.input_volume_controller.enabled);
1231 
1232   // Change config back and compare.
1233   adjusted_config.gain_controller1.enabled = config.gain_controller1.enabled;
1234   adjusted_config.gain_controller1.analog_gain_controller.enabled =
1235       config.gain_controller1.analog_gain_controller.enabled;
1236   adjusted_config.gain_controller2.enabled = config.gain_controller2.enabled;
1237   adjusted_config.gain_controller2.adaptive_digital.enabled =
1238       config.gain_controller2.adaptive_digital.enabled;
1239   adjusted_config.gain_controller2.input_volume_controller.enabled =
1240       config.gain_controller2.input_volume_controller.enabled;
1241 
1242   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1243 }
1244 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigAdjustedWhenExperimentEnabledAndHybridAgcEnabled)1245 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1246      ConfigAdjustedWhenExperimentEnabledAndHybridAgcEnabled) {
1247   webrtc::test::ScopedFieldTrials field_trials(
1248       "WebRTC-Audio-InputVolumeControllerExperiment/"
1249       "Enabled,"
1250       "enable_clipping_predictor:true,"
1251       "clipped_level_min:20,"
1252       "clipped_level_step:30,"
1253       "clipped_ratio_threshold:0.4,"
1254       "clipped_wait_frames:50,"
1255       "target_range_max_dbfs:-6,"
1256       "target_range_min_dbfs:-70,"
1257       "update_input_volume_wait_frames:80,"
1258       "speech_probability_threshold:0.9,"
1259       "speech_ratio_threshold:1.0/");
1260 
1261   AudioProcessingBuilderForTesting apm_builder;
1262 
1263   // Set a config with hybrid AGC enabled.
1264   AudioProcessing::Config config;
1265   config.gain_controller1.enabled = true;
1266   config.gain_controller1.analog_gain_controller.enabled = true;
1267   config.gain_controller1.analog_gain_controller.enable_digital_adaptive =
1268       false;
1269   config.gain_controller2.enabled = true;
1270   config.gain_controller2.adaptive_digital.enabled = true;
1271   config.gain_controller1.mode =
1272       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1273 
1274   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1275 
1276   apm_builder.SetConfig(config);
1277 
1278   auto apm = apm_builder.Create();
1279   auto adjusted_config = apm->GetConfig();
1280 
1281   // Expect the config to be adjusted.
1282   EXPECT_FALSE(adjusted_config.gain_controller1.enabled);
1283   EXPECT_FALSE(adjusted_config.gain_controller1.analog_gain_controller.enabled);
1284   EXPECT_TRUE(adjusted_config.gain_controller2.enabled);
1285   EXPECT_TRUE(adjusted_config.gain_controller2.adaptive_digital.enabled);
1286   EXPECT_TRUE(adjusted_config.gain_controller2.input_volume_controller.enabled);
1287 
1288   // Change config back and compare.
1289   adjusted_config.gain_controller1.enabled = config.gain_controller1.enabled;
1290   adjusted_config.gain_controller1.analog_gain_controller.enabled =
1291       config.gain_controller1.analog_gain_controller.enabled;
1292   adjusted_config.gain_controller2.enabled = config.gain_controller2.enabled;
1293   adjusted_config.gain_controller2.adaptive_digital.enabled =
1294       config.gain_controller2.adaptive_digital.enabled;
1295   adjusted_config.gain_controller2.input_volume_controller.enabled =
1296       config.gain_controller2.input_volume_controller.enabled;
1297 
1298   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1299 }
1300 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigNotAdjustedWhenExperimentEnabledAndAgc1AnalogNotEnabled)1301 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1302      ConfigNotAdjustedWhenExperimentEnabledAndAgc1AnalogNotEnabled) {
1303   webrtc::test::ScopedFieldTrials field_trials(
1304       "WebRTC-Audio-InputVolumeControllerExperiment/"
1305       "Enabled,"
1306       "enable_clipping_predictor:true,"
1307       "clipped_level_min:20,"
1308       "clipped_level_step:30,"
1309       "clipped_ratio_threshold:0.4,"
1310       "clipped_wait_frames:50,"
1311       "target_range_max_dbfs:-6,"
1312       "target_range_min_dbfs:-70,"
1313       "update_input_volume_wait_frames:80,"
1314       "speech_probability_threshold:0.9,"
1315       "speech_ratio_threshold:1.0/");
1316 
1317   AudioProcessingBuilderForTesting apm_builder;
1318 
1319   // Set a config with analog AGC1 not enabled.
1320   AudioProcessing::Config config;
1321   config.gain_controller1.enabled = false;
1322   config.gain_controller1.analog_gain_controller.enabled = true;
1323   config.gain_controller1.analog_gain_controller.enable_digital_adaptive = true;
1324   config.gain_controller2.enabled = false;
1325   config.gain_controller1.mode =
1326       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1327 
1328   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1329 
1330   apm_builder.SetConfig(config);
1331 
1332   auto apm = apm_builder.Create();
1333   auto adjusted_config = apm->GetConfig();
1334 
1335   EXPECT_EQ(config.gain_controller1.enabled,
1336             adjusted_config.gain_controller1.enabled);
1337   EXPECT_EQ(config.gain_controller1.analog_gain_controller.enabled,
1338             adjusted_config.gain_controller1.analog_gain_controller.enabled);
1339   EXPECT_EQ(config.gain_controller2.enabled,
1340             adjusted_config.gain_controller2.enabled);
1341   EXPECT_EQ(config.gain_controller2.adaptive_digital.enabled,
1342             adjusted_config.gain_controller2.adaptive_digital.enabled);
1343   EXPECT_FALSE(
1344       adjusted_config.gain_controller2.input_volume_controller.enabled);
1345 
1346   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1347 }
1348 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigNotAdjustedWhenExperimentEnabledAndHybridAgcNotEnabled)1349 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1350      ConfigNotAdjustedWhenExperimentEnabledAndHybridAgcNotEnabled) {
1351   webrtc::test::ScopedFieldTrials field_trials(
1352       "WebRTC-Audio-InputVolumeControllerExperiment/"
1353       "Enabled,"
1354       "enable_clipping_predictor:true,"
1355       "clipped_level_min:20,"
1356       "clipped_level_step:30,"
1357       "clipped_ratio_threshold:0.4,"
1358       "clipped_wait_frames:50,"
1359       "target_range_max_dbfs:-6,"
1360       "target_range_min_dbfs:-70,"
1361       "update_input_volume_wait_frames:80,"
1362       "speech_probability_threshold:0.9,"
1363       "speech_ratio_threshold:1.0/");
1364 
1365   AudioProcessingBuilderForTesting apm_builder;
1366 
1367   // Set a config with hybrid AGC analog not enabled.
1368   AudioProcessing::Config config;
1369   config.gain_controller1.enabled = false;
1370   config.gain_controller1.analog_gain_controller.enabled = true;
1371   config.gain_controller1.analog_gain_controller.enable_digital_adaptive =
1372       false;
1373   config.gain_controller2.enabled = true;
1374   config.gain_controller2.adaptive_digital.enabled = true;
1375   config.gain_controller1.mode =
1376       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1377 
1378   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1379 
1380   apm_builder.SetConfig(config);
1381 
1382   auto apm = apm_builder.Create();
1383   auto adjusted_config = apm->GetConfig();
1384 
1385   EXPECT_EQ(config.gain_controller1.enabled,
1386             adjusted_config.gain_controller1.enabled);
1387   EXPECT_EQ(config.gain_controller1.analog_gain_controller.enabled,
1388             adjusted_config.gain_controller1.analog_gain_controller.enabled);
1389   EXPECT_EQ(config.gain_controller2.enabled,
1390             adjusted_config.gain_controller2.enabled);
1391   EXPECT_EQ(config.gain_controller2.adaptive_digital.enabled,
1392             adjusted_config.gain_controller2.adaptive_digital.enabled);
1393   EXPECT_FALSE(
1394       adjusted_config.gain_controller2.input_volume_controller.enabled);
1395 
1396   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1397 }
1398 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigNotAdjustedWhenExperimentNotEnabledAndAgc1AnalogEnabled)1399 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1400      ConfigNotAdjustedWhenExperimentNotEnabledAndAgc1AnalogEnabled) {
1401   AudioProcessingBuilderForTesting apm_builder;
1402 
1403   // Set a config with analog AGC1 analog enabled.
1404   AudioProcessing::Config config;
1405   config.gain_controller1.enabled = true;
1406   config.gain_controller1.analog_gain_controller.enabled = true;
1407   config.gain_controller1.analog_gain_controller.enable_digital_adaptive = true;
1408   config.gain_controller2.enabled = false;
1409   config.gain_controller1.mode =
1410       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1411 
1412   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1413 
1414   apm_builder.SetConfig(config);
1415 
1416   auto apm = apm_builder.Create();
1417   auto adjusted_config = apm->GetConfig();
1418 
1419   EXPECT_EQ(config.gain_controller1.enabled,
1420             adjusted_config.gain_controller1.enabled);
1421   EXPECT_EQ(config.gain_controller1.analog_gain_controller.enabled,
1422             adjusted_config.gain_controller1.analog_gain_controller.enabled);
1423   EXPECT_EQ(config.gain_controller2.enabled,
1424             adjusted_config.gain_controller2.enabled);
1425   EXPECT_EQ(config.gain_controller2.adaptive_digital.enabled,
1426             adjusted_config.gain_controller2.adaptive_digital.enabled);
1427   EXPECT_FALSE(
1428       adjusted_config.gain_controller2.input_volume_controller.enabled);
1429 
1430   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1431 }
1432 
TEST(AudioProcessingImplInputVolumeControllerExperimentTest,ConfigNotAdjustedWhenExperimentNotEnabledAndHybridAgcEnabled)1433 TEST(AudioProcessingImplInputVolumeControllerExperimentTest,
1434      ConfigNotAdjustedWhenExperimentNotEnabledAndHybridAgcEnabled) {
1435   AudioProcessingBuilderForTesting apm_builder;
1436 
1437   // Set a config with hybrid AGC enabled.
1438   AudioProcessing::Config config;
1439   config.gain_controller1.enabled = true;
1440   config.gain_controller1.analog_gain_controller.enabled = true;
1441   config.gain_controller1.analog_gain_controller.enable_digital_adaptive =
1442       false;
1443   config.gain_controller2.enabled = true;
1444   config.gain_controller2.adaptive_digital.enabled = true;
1445   config.gain_controller1.mode =
1446       AudioProcessing::Config::GainController1::kAdaptiveAnalog;
1447 
1448   EXPECT_FALSE(config.gain_controller2.input_volume_controller.enabled);
1449 
1450   apm_builder.SetConfig(config);
1451 
1452   auto apm = apm_builder.Create();
1453   auto adjusted_config = apm->GetConfig();
1454 
1455   EXPECT_EQ(config.gain_controller1.enabled,
1456             adjusted_config.gain_controller1.enabled);
1457   EXPECT_EQ(config.gain_controller1.analog_gain_controller.enabled,
1458             adjusted_config.gain_controller1.analog_gain_controller.enabled);
1459   EXPECT_EQ(config.gain_controller2.enabled,
1460             adjusted_config.gain_controller2.enabled);
1461   EXPECT_EQ(config.gain_controller2.adaptive_digital.enabled,
1462             adjusted_config.gain_controller2.adaptive_digital.enabled);
1463   EXPECT_FALSE(
1464       adjusted_config.gain_controller2.input_volume_controller.enabled);
1465 
1466   EXPECT_THAT(adjusted_config.ToString(), ::testing::StrEq(config.ToString()));
1467 }
1468 
1469 }  // namespace webrtc
1470