blob: 7c12a07ed9c3ac2ad1c61e1fa8db373dd7a65f2a [file] [log] [blame]
andrew@webrtc.org60730cf2014-01-07 17:45:09 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/audio_processing_impl.h"
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000012
Alessio Bazzica3b51cd32022-12-14 16:36:10 +010013#include <algorithm>
Per Åhgren2507f8c2020-03-19 12:33:29 +010014#include <array>
Alessio Bazzicae4498052018-12-17 09:44:06 +010015#include <memory>
Hanna Silenc69188d2022-09-16 11:38:56 +020016#include <tuple>
Alessio Bazzicae4498052018-12-17 09:44:06 +010017
Hanna Silenc69188d2022-09-16 11:38:56 +020018#include "absl/types/optional.h"
Niels Möller105711e2022-06-14 15:48:26 +020019#include "api/make_ref_counted.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010020#include "api/scoped_refptr.h"
Alessio Bazzicad2b97402018-08-09 14:23:11 +020021#include "modules/audio_processing/include/audio_processing.h"
Sam Zackrissonb37e59d2020-04-27 08:39:33 +020022#include "modules/audio_processing/optionally_built_submodule_creators.h"
Per Åhgrencc73ed32020-04-26 23:56:17 +020023#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
Sam Zackrissonb37e59d2020-04-27 08:39:33 +020024#include "modules/audio_processing/test/echo_canceller_test_tools.h"
Alessio Bazzicae4498052018-12-17 09:44:06 +010025#include "modules/audio_processing/test/echo_control_mock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_processing/test/test_utils.h"
Alessio Bazzicae4498052018-12-17 09:44:06 +010027#include "rtc_base/checks.h"
Sam Zackrissonb37e59d2020-04-27 08:39:33 +020028#include "rtc_base/random.h"
Hanna Silenc69188d2022-09-16 11:38:56 +020029#include "rtc_base/strings/string_builder.h"
Hanna Silen0c1ad292022-06-16 16:35:45 +020030#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "test/gmock.h"
32#include "test/gtest.h"
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000033
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000034namespace webrtc {
peaha9cc40b2017-06-29 08:32:09 -070035namespace {
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000036
Alessio Bazzicae4498052018-12-17 09:44:06 +010037using ::testing::Invoke;
38using ::testing::NotNull;
39
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000040class MockInitialize : public AudioProcessingImpl {
41 public:
Alessio Bazzicabe1b8982021-09-17 08:26:10 +020042 MockInitialize() : AudioProcessingImpl() {}
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000043
Per Åhgren0ade9832020-09-01 23:57:20 +020044 MOCK_METHOD(void, InitializeLocked, (), (override));
Niels Möller5b747232021-07-26 17:16:25 +020045 void RealInitializeLocked() {
46 AssertLockedForTest();
Per Åhgren0ade9832020-09-01 23:57:20 +020047 AudioProcessingImpl::InitializeLocked();
pbos@webrtc.org788acd12014-12-15 09:41:24 +000048 }
peaha9cc40b2017-06-29 08:32:09 -070049
Danil Chapovalov704fb552020-05-18 15:10:15 +020050 MOCK_METHOD(void, AddRef, (), (const, override));
51 MOCK_METHOD(rtc::RefCountReleaseStatus, Release, (), (const, override));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000052};
53
Alessio Bazzicae4498052018-12-17 09:44:06 +010054// Creates MockEchoControl instances and provides a raw pointer access to
55// the next created one. The raw pointer is meant to be used with gmock.
56// Returning a pointer of the next created MockEchoControl instance is necessary
57// for the following reasons: (i) gmock expectations must be set before any call
58// occurs, (ii) APM is initialized the first time that
59// AudioProcessingImpl::ProcessStream() is called and the initialization leads
60// to the creation of a new EchoControl object.
61class MockEchoControlFactory : public EchoControlFactory {
62 public:
Mirko Bonadei317a1f02019-09-17 17:06:18 +020063 MockEchoControlFactory() : next_mock_(std::make_unique<MockEchoControl>()) {}
Alessio Bazzicae4498052018-12-17 09:44:06 +010064 // Returns a pointer to the next MockEchoControl that this factory creates.
65 MockEchoControl* GetNext() const { return next_mock_.get(); }
Per Åhgren4e5c7092019-11-01 20:44:11 +010066 std::unique_ptr<EchoControl> Create(int sample_rate_hz,
67 int num_render_channels,
68 int num_capture_channels) override {
Alessio Bazzicae4498052018-12-17 09:44:06 +010069 std::unique_ptr<EchoControl> mock = std::move(next_mock_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +020070 next_mock_ = std::make_unique<MockEchoControl>();
Alessio Bazzicae4498052018-12-17 09:44:06 +010071 return mock;
72 }
73
74 private:
75 std::unique_ptr<MockEchoControl> next_mock_;
76};
77
Alessio Bazzicad2b97402018-08-09 14:23:11 +020078// Mocks EchoDetector and records the first samples of the last analyzed render
79// stream frame. Used to check what data is read by an EchoDetector
80// implementation injected into an APM.
81class TestEchoDetector : public EchoDetector {
82 public:
83 TestEchoDetector()
84 : analyze_render_audio_called_(false),
85 last_render_audio_first_sample_(0.f) {}
86 ~TestEchoDetector() override = default;
87 void AnalyzeRenderAudio(rtc::ArrayView<const float> render_audio) override {
88 last_render_audio_first_sample_ = render_audio[0];
89 analyze_render_audio_called_ = true;
90 }
91 void AnalyzeCaptureAudio(rtc::ArrayView<const float> capture_audio) override {
92 }
93 void Initialize(int capture_sample_rate_hz,
94 int num_capture_channels,
95 int render_sample_rate_hz,
96 int num_render_channels) override {}
97 EchoDetector::Metrics GetMetrics() const override { return {}; }
98 // Returns true if AnalyzeRenderAudio() has been called at least once.
99 bool analyze_render_audio_called() const {
100 return analyze_render_audio_called_;
101 }
102 // Returns the first sample of the last analyzed render frame.
103 float last_render_audio_first_sample() const {
104 return last_render_audio_first_sample_;
105 }
106
107 private:
108 bool analyze_render_audio_called_;
109 float last_render_audio_first_sample_;
110};
111
112// Mocks CustomProcessing and applies ProcessSample() to all the samples.
113// Meant to be injected into an APM to modify samples in a known and detectable
114// way.
115class TestRenderPreProcessor : public CustomProcessing {
116 public:
117 TestRenderPreProcessor() = default;
118 ~TestRenderPreProcessor() = default;
119 void Initialize(int sample_rate_hz, int num_channels) override {}
120 void Process(AudioBuffer* audio) override {
121 for (size_t k = 0; k < audio->num_channels(); ++k) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200122 rtc::ArrayView<float> channel_view(audio->channels()[k],
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200123 audio->num_frames());
124 std::transform(channel_view.begin(), channel_view.end(),
125 channel_view.begin(), ProcessSample);
126 }
Mirko Bonadeic4dd7302019-02-25 09:12:02 +0100127 }
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200128 std::string ToString() const override { return "TestRenderPreProcessor"; }
129 void SetRuntimeSetting(AudioProcessing::RuntimeSetting setting) override {}
130 // Modifies a sample. This member is used in Process() to modify a frame and
131 // it is publicly visible to enable tests.
132 static constexpr float ProcessSample(float x) { return 2.f * x; }
133};
134
Hanna Silenc69188d2022-09-16 11:38:56 +0200135// Runs `apm` input processing for volume adjustments for `num_frames` random
136// frames starting from the volume `initial_volume`. This includes three steps:
137// 1) Set the input volume 2) Process the stream 3) Set the new recommended
138// input volume. Returns the new recommended input volume.
139int ProcessInputVolume(AudioProcessing& apm,
140 int num_frames,
141 int initial_volume) {
142 constexpr int kSampleRateHz = 48000;
143 constexpr int kNumChannels = 1;
144 std::array<float, kSampleRateHz / 100> buffer;
145 float* channel_pointers[] = {buffer.data()};
146 StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
147 /*num_channels=*/kNumChannels);
148 int recommended_input_volume = initial_volume;
149 for (int i = 0; i < num_frames; ++i) {
150 Random random_generator(2341U);
151 RandomizeSampleVector(&random_generator, buffer);
152
153 apm.set_stream_analog_level(recommended_input_volume);
154 apm.ProcessStream(channel_pointers, stream_config, stream_config,
155 channel_pointers);
156 recommended_input_volume = apm.recommended_stream_analog_level();
157 }
158 return recommended_input_volume;
159}
160
peaha9cc40b2017-06-29 08:32:09 -0700161} // namespace
162
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000163TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200164 MockInitialize mock;
165 ON_CALL(mock, InitializeLocked)
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000166 .WillByDefault(Invoke(&mock, &MockInitialize::RealInitializeLocked));
167
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200168 EXPECT_CALL(mock, InitializeLocked).Times(1);
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000169 mock.Initialize();
170
Per Åhgren2507f8c2020-03-19 12:33:29 +0100171 constexpr size_t kMaxSampleRateHz = 32000;
172 constexpr size_t kMaxNumChannels = 2;
173 std::array<int16_t, kMaxNumChannels * kMaxSampleRateHz / 100> frame;
174 frame.fill(0);
Henrik Lundin64253a92022-02-04 09:02:48 +0000175 StreamConfig config(16000, 1);
peah2ace3f92016-09-10 04:42:27 -0700176 // Call with the default parameters; there should be an init.
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200177 EXPECT_CALL(mock, InitializeLocked).Times(0);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100178 EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
Per Åhgren2507f8c2020-03-19 12:33:29 +0100179 EXPECT_NOERR(
180 mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000181
182 // New sample rate. (Only impacts ProcessStream).
Henrik Lundin64253a92022-02-04 09:02:48 +0000183 config = StreamConfig(32000, 1);
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200184 EXPECT_CALL(mock, InitializeLocked).Times(1);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100185 EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000186
187 // New number of channels.
Henrik Lundin64253a92022-02-04 09:02:48 +0000188 config = StreamConfig(32000, 2);
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200189 EXPECT_CALL(mock, InitializeLocked).Times(2);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100190 EXPECT_NOERR(mock.ProcessStream(frame.data(), config, config, frame.data()));
Per Åhgren2507f8c2020-03-19 12:33:29 +0100191 EXPECT_NOERR(
192 mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000193
aluebsb0319552016-03-17 20:39:53 -0700194 // A new sample rate passed to ProcessReverseStream should cause an init.
Henrik Lundin64253a92022-02-04 09:02:48 +0000195 config = StreamConfig(16000, 2);
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200196 EXPECT_CALL(mock, InitializeLocked).Times(1);
Per Åhgren2507f8c2020-03-19 12:33:29 +0100197 EXPECT_NOERR(
198 mock.ProcessReverseStream(frame.data(), config, config, frame.data()));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000199}
200
Alessio Bazzicac054e782018-04-16 12:10:09 +0200201TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
Niels Möller4f776ac2021-07-02 11:30:54 +0200202 rtc::scoped_refptr<AudioProcessing> apm =
203 AudioProcessingBuilderForTesting().Create();
Alex Loikob5c9a792018-04-16 16:31:22 +0200204 webrtc::AudioProcessing::Config apm_config;
205 apm_config.pre_amplifier.enabled = true;
206 apm_config.pre_amplifier.fixed_gain_factor = 1.f;
207 apm->ApplyConfig(apm_config);
208
Per Åhgren2507f8c2020-03-19 12:33:29 +0100209 constexpr int kSampleRateHz = 48000;
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200210 constexpr int16_t kAudioLevel = 10000;
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200211 constexpr size_t kNumChannels = 2;
Alex Loikob5c9a792018-04-16 16:31:22 +0200212
Per Åhgren2507f8c2020-03-19 12:33:29 +0100213 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000214 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgren2507f8c2020-03-19 12:33:29 +0100215 frame.fill(kAudioLevel);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100216 apm->ProcessStream(frame.data(), config, config, frame.data());
Per Åhgren2507f8c2020-03-19 12:33:29 +0100217 EXPECT_EQ(frame[100], kAudioLevel)
Alex Loikob5c9a792018-04-16 16:31:22 +0200218 << "With factor 1, frame shouldn't be modified.";
219
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200220 constexpr float kGainFactor = 2.f;
Alex Loikob5c9a792018-04-16 16:31:22 +0200221 apm->SetRuntimeSetting(
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200222 AudioProcessing::RuntimeSetting::CreateCapturePreGain(kGainFactor));
Alex Loikob5c9a792018-04-16 16:31:22 +0200223
224 // Process for two frames to have time to ramp up gain.
225 for (int i = 0; i < 2; ++i) {
Per Åhgren2507f8c2020-03-19 12:33:29 +0100226 frame.fill(kAudioLevel);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100227 apm->ProcessStream(frame.data(), config, config, frame.data());
Alex Loikob5c9a792018-04-16 16:31:22 +0200228 }
Per Åhgren2507f8c2020-03-19 12:33:29 +0100229 EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
Alex Loikob5c9a792018-04-16 16:31:22 +0200230 << "Frame should be amplified.";
Alessio Bazzicac054e782018-04-16 12:10:09 +0200231}
232
Per Åhgrendb5d7282021-03-15 16:31:04 +0000233TEST(AudioProcessingImplTest,
234 LevelAdjustmentUpdateCapturePreGainRuntimeSetting) {
Niels Möller4f776ac2021-07-02 11:30:54 +0200235 rtc::scoped_refptr<AudioProcessing> apm =
236 AudioProcessingBuilderForTesting().Create();
Per Åhgrendb5d7282021-03-15 16:31:04 +0000237 webrtc::AudioProcessing::Config apm_config;
238 apm_config.capture_level_adjustment.enabled = true;
239 apm_config.capture_level_adjustment.pre_gain_factor = 1.f;
240 apm->ApplyConfig(apm_config);
241
242 constexpr int kSampleRateHz = 48000;
243 constexpr int16_t kAudioLevel = 10000;
244 constexpr size_t kNumChannels = 2;
245
246 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000247 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgrendb5d7282021-03-15 16:31:04 +0000248 frame.fill(kAudioLevel);
249 apm->ProcessStream(frame.data(), config, config, frame.data());
250 EXPECT_EQ(frame[100], kAudioLevel)
251 << "With factor 1, frame shouldn't be modified.";
252
253 constexpr float kGainFactor = 2.f;
254 apm->SetRuntimeSetting(
255 AudioProcessing::RuntimeSetting::CreateCapturePreGain(kGainFactor));
256
257 // Process for two frames to have time to ramp up gain.
258 for (int i = 0; i < 2; ++i) {
259 frame.fill(kAudioLevel);
260 apm->ProcessStream(frame.data(), config, config, frame.data());
261 }
262 EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
263 << "Frame should be amplified.";
264}
265
266TEST(AudioProcessingImplTest,
267 LevelAdjustmentUpdateCapturePostGainRuntimeSetting) {
Niels Möller4f776ac2021-07-02 11:30:54 +0200268 rtc::scoped_refptr<AudioProcessing> apm =
269 AudioProcessingBuilderForTesting().Create();
Per Åhgrendb5d7282021-03-15 16:31:04 +0000270 webrtc::AudioProcessing::Config apm_config;
271 apm_config.capture_level_adjustment.enabled = true;
272 apm_config.capture_level_adjustment.post_gain_factor = 1.f;
273 apm->ApplyConfig(apm_config);
274
275 constexpr int kSampleRateHz = 48000;
276 constexpr int16_t kAudioLevel = 10000;
277 constexpr size_t kNumChannels = 2;
278
279 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000280 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgrendb5d7282021-03-15 16:31:04 +0000281 frame.fill(kAudioLevel);
282 apm->ProcessStream(frame.data(), config, config, frame.data());
283 EXPECT_EQ(frame[100], kAudioLevel)
284 << "With factor 1, frame shouldn't be modified.";
285
286 constexpr float kGainFactor = 2.f;
287 apm->SetRuntimeSetting(
288 AudioProcessing::RuntimeSetting::CreateCapturePostGain(kGainFactor));
289
290 // Process for two frames to have time to ramp up gain.
291 for (int i = 0; i < 2; ++i) {
292 frame.fill(kAudioLevel);
293 apm->ProcessStream(frame.data(), config, config, frame.data());
294 }
295 EXPECT_EQ(frame[100], kGainFactor * kAudioLevel)
296 << "Frame should be amplified.";
297}
298
Per Åhgren652ada52021-03-03 10:52:44 +0000299TEST(AudioProcessingImplTest, EchoControllerObservesSetCaptureUsageChange) {
300 // Tests that the echo controller observes that the capture usage has been
301 // updated.
302 auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
303 const MockEchoControlFactory* echo_control_factory_ptr =
304 echo_control_factory.get();
305
Niels Möller4f776ac2021-07-02 11:30:54 +0200306 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgren652ada52021-03-03 10:52:44 +0000307 AudioProcessingBuilderForTesting()
308 .SetEchoControlFactory(std::move(echo_control_factory))
Niels Möller4f776ac2021-07-02 11:30:54 +0200309 .Create();
Per Åhgren652ada52021-03-03 10:52:44 +0000310
311 constexpr int16_t kAudioLevel = 10000;
312 constexpr int kSampleRateHz = 48000;
313 constexpr int kNumChannels = 2;
314 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000315 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgren652ada52021-03-03 10:52:44 +0000316 frame.fill(kAudioLevel);
317
318 MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
319
320 // Ensure that SetCaptureOutputUsage is not called when no runtime settings
321 // are passed.
322 EXPECT_CALL(*echo_control_mock, SetCaptureOutputUsage(testing::_)).Times(0);
323 apm->ProcessStream(frame.data(), config, config, frame.data());
324
325 // Ensure that SetCaptureOutputUsage is called with the right information when
326 // a runtime setting is passed.
327 EXPECT_CALL(*echo_control_mock,
328 SetCaptureOutputUsage(/*capture_output_used=*/false))
329 .Times(1);
330 EXPECT_TRUE(apm->PostRuntimeSetting(
331 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
332 /*capture_output_used=*/false)));
333 apm->ProcessStream(frame.data(), config, config, frame.data());
334
335 EXPECT_CALL(*echo_control_mock,
336 SetCaptureOutputUsage(/*capture_output_used=*/true))
337 .Times(1);
338 EXPECT_TRUE(apm->PostRuntimeSetting(
339 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
340 /*capture_output_used=*/true)));
341 apm->ProcessStream(frame.data(), config, config, frame.data());
342
343 // The number of positions to place items in the queue is equal to the queue
344 // size minus 1.
345 constexpr int kNumSlotsInQueue = RuntimeSettingQueueSize();
346
347 // Ensure that SetCaptureOutputUsage is called with the right information when
348 // many runtime settings are passed.
349 for (int k = 0; k < kNumSlotsInQueue - 1; ++k) {
350 EXPECT_TRUE(apm->PostRuntimeSetting(
351 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
352 /*capture_output_used=*/false)));
353 }
354 EXPECT_CALL(*echo_control_mock,
355 SetCaptureOutputUsage(/*capture_output_used=*/false))
356 .Times(kNumSlotsInQueue - 1);
357 apm->ProcessStream(frame.data(), config, config, frame.data());
358
359 // Ensure that SetCaptureOutputUsage is properly called with the fallback
360 // value when the runtime settings queue becomes full.
361 for (int k = 0; k < kNumSlotsInQueue; ++k) {
362 EXPECT_TRUE(apm->PostRuntimeSetting(
363 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
364 /*capture_output_used=*/false)));
365 }
366 EXPECT_FALSE(apm->PostRuntimeSetting(
367 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
368 /*capture_output_used=*/false)));
369 EXPECT_FALSE(apm->PostRuntimeSetting(
370 AudioProcessing::RuntimeSetting::CreateCaptureOutputUsedSetting(
371 /*capture_output_used=*/false)));
372 EXPECT_CALL(*echo_control_mock,
373 SetCaptureOutputUsage(/*capture_output_used=*/false))
374 .Times(kNumSlotsInQueue);
375 EXPECT_CALL(*echo_control_mock,
376 SetCaptureOutputUsage(/*capture_output_used=*/true))
377 .Times(1);
378 apm->ProcessStream(frame.data(), config, config, frame.data());
379}
380
Alessio Bazzicae4498052018-12-17 09:44:06 +0100381TEST(AudioProcessingImplTest,
382 EchoControllerObservesPreAmplifierEchoPathGainChange) {
383 // Tests that the echo controller observes an echo path gain change when the
384 // pre-amplifier submodule changes the gain.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200385 auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
Alessio Bazzicae4498052018-12-17 09:44:06 +0100386 const auto* echo_control_factory_ptr = echo_control_factory.get();
387
Niels Möller4f776ac2021-07-02 11:30:54 +0200388 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgrencc73ed32020-04-26 23:56:17 +0200389 AudioProcessingBuilderForTesting()
Alessio Bazzicae4498052018-12-17 09:44:06 +0100390 .SetEchoControlFactory(std::move(echo_control_factory))
Niels Möller4f776ac2021-07-02 11:30:54 +0200391 .Create();
Sam Zackrisson41478c72019-10-15 10:10:26 +0200392 // Disable AGC.
Alessio Bazzicae4498052018-12-17 09:44:06 +0100393 webrtc::AudioProcessing::Config apm_config;
Sam Zackrisson41478c72019-10-15 10:10:26 +0200394 apm_config.gain_controller1.enabled = false;
Alessio Bazzicae4498052018-12-17 09:44:06 +0100395 apm_config.gain_controller2.enabled = false;
396 apm_config.pre_amplifier.enabled = true;
397 apm_config.pre_amplifier.fixed_gain_factor = 1.f;
398 apm->ApplyConfig(apm_config);
399
Alessio Bazzicae4498052018-12-17 09:44:06 +0100400 constexpr int16_t kAudioLevel = 10000;
401 constexpr size_t kSampleRateHz = 48000;
402 constexpr size_t kNumChannels = 2;
Per Åhgren2507f8c2020-03-19 12:33:29 +0100403 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000404 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgren2507f8c2020-03-19 12:33:29 +0100405 frame.fill(kAudioLevel);
Alessio Bazzicae4498052018-12-17 09:44:06 +0100406
407 MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
408
Per Åhgren0aefbf02019-08-23 21:29:17 +0200409 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistbf47f342019-05-09 10:50:31 +0200410 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100411 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
Fredrik Hernqvistbf47f342019-05-09 10:50:31 +0200412 .Times(1);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100413 apm->ProcessStream(frame.data(), config, config, frame.data());
Alessio Bazzicae4498052018-12-17 09:44:06 +0100414
Per Åhgren0aefbf02019-08-23 21:29:17 +0200415 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistbf47f342019-05-09 10:50:31 +0200416 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100417 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
Fredrik Hernqvistbf47f342019-05-09 10:50:31 +0200418 .Times(1);
Alessio Bazzicae4498052018-12-17 09:44:06 +0100419 apm->SetRuntimeSetting(
420 AudioProcessing::RuntimeSetting::CreateCapturePreGain(2.f));
Per Åhgrendc5522b2020-03-19 14:55:58 +0100421 apm->ProcessStream(frame.data(), config, config, frame.data());
Alessio Bazzicae4498052018-12-17 09:44:06 +0100422}
423
424TEST(AudioProcessingImplTest,
Per Åhgrendb5d7282021-03-15 16:31:04 +0000425 EchoControllerObservesLevelAdjustmentPreGainEchoPathGainChange) {
426 // Tests that the echo controller observes an echo path gain change when the
427 // pre-amplifier submodule changes the gain.
428 auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
429 const auto* echo_control_factory_ptr = echo_control_factory.get();
430
Niels Möller4f776ac2021-07-02 11:30:54 +0200431 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgrendb5d7282021-03-15 16:31:04 +0000432 AudioProcessingBuilderForTesting()
433 .SetEchoControlFactory(std::move(echo_control_factory))
Niels Möller4f776ac2021-07-02 11:30:54 +0200434 .Create();
Per Åhgrendb5d7282021-03-15 16:31:04 +0000435 // Disable AGC.
436 webrtc::AudioProcessing::Config apm_config;
437 apm_config.gain_controller1.enabled = false;
438 apm_config.gain_controller2.enabled = false;
439 apm_config.capture_level_adjustment.enabled = true;
440 apm_config.capture_level_adjustment.pre_gain_factor = 1.f;
441 apm->ApplyConfig(apm_config);
442
443 constexpr int16_t kAudioLevel = 10000;
444 constexpr size_t kSampleRateHz = 48000;
445 constexpr size_t kNumChannels = 2;
446 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000447 StreamConfig config(kSampleRateHz, kNumChannels);
Per Åhgrendb5d7282021-03-15 16:31:04 +0000448 frame.fill(kAudioLevel);
449
450 MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
451
452 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
453 EXPECT_CALL(*echo_control_mock,
454 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
455 .Times(1);
456 apm->ProcessStream(frame.data(), config, config, frame.data());
457
458 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
459 EXPECT_CALL(*echo_control_mock,
460 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
461 .Times(1);
462 apm->SetRuntimeSetting(
463 AudioProcessing::RuntimeSetting::CreateCapturePreGain(2.f));
464 apm->ProcessStream(frame.data(), config, config, frame.data());
465}
466
467TEST(AudioProcessingImplTest,
Alessio Bazzicae4498052018-12-17 09:44:06 +0100468 EchoControllerObservesAnalogAgc1EchoPathGainChange) {
469 // Tests that the echo controller observes an echo path gain change when the
470 // AGC1 analog adaptive submodule changes the analog gain.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200471 auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
Alessio Bazzicae4498052018-12-17 09:44:06 +0100472 const auto* echo_control_factory_ptr = echo_control_factory.get();
473
Niels Möller4f776ac2021-07-02 11:30:54 +0200474 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgrencc73ed32020-04-26 23:56:17 +0200475 AudioProcessingBuilderForTesting()
Alessio Bazzicae4498052018-12-17 09:44:06 +0100476 .SetEchoControlFactory(std::move(echo_control_factory))
Niels Möller4f776ac2021-07-02 11:30:54 +0200477 .Create();
Alessio Bazzicae4498052018-12-17 09:44:06 +0100478 webrtc::AudioProcessing::Config apm_config;
Sam Zackrisson41478c72019-10-15 10:10:26 +0200479 // Enable AGC1.
480 apm_config.gain_controller1.enabled = true;
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200481 apm_config.gain_controller1.analog_gain_controller.enabled = true;
Alessio Bazzicae4498052018-12-17 09:44:06 +0100482 apm_config.gain_controller2.enabled = false;
483 apm_config.pre_amplifier.enabled = false;
484 apm->ApplyConfig(apm_config);
485
Alessio Bazzicae4498052018-12-17 09:44:06 +0100486 constexpr int16_t kAudioLevel = 1000;
487 constexpr size_t kSampleRateHz = 48000;
488 constexpr size_t kNumChannels = 2;
Per Åhgren2507f8c2020-03-19 12:33:29 +0100489 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000490 StreamConfig stream_config(kSampleRateHz, kNumChannels);
Per Åhgren2507f8c2020-03-19 12:33:29 +0100491 frame.fill(kAudioLevel);
Alessio Bazzicae4498052018-12-17 09:44:06 +0100492
493 MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
494
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200495 constexpr int kInitialStreamAnalogLevel = 123;
496 apm->set_stream_analog_level(kInitialStreamAnalogLevel);
497
498 // When the first fame is processed, no echo path gain change must be
499 // detected.
Per Åhgren0aefbf02019-08-23 21:29:17 +0200500 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200501 EXPECT_CALL(*echo_control_mock,
502 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100503 .Times(1);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100504 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Alessio Bazzicae4498052018-12-17 09:44:06 +0100505
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200506 // Simulate the application of the recommended analog level.
507 int recommended_analog_level = apm->recommended_stream_analog_level();
508 if (recommended_analog_level == kInitialStreamAnalogLevel) {
509 // Force an analog gain change if it did not happen.
510 recommended_analog_level++;
Alessio Bazzicae4498052018-12-17 09:44:06 +0100511 }
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200512 apm->set_stream_analog_level(recommended_analog_level);
Alessio Bazzicae4498052018-12-17 09:44:06 +0100513
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200514 // After the first fame and with a stream analog level change, the echo path
515 // gain change must be detected.
Per Åhgren0aefbf02019-08-23 21:29:17 +0200516 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200517 EXPECT_CALL(*echo_control_mock,
518 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100519 .Times(1);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100520 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Alessio Bazzicae4498052018-12-17 09:44:06 +0100521}
522
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200523// Tests that a stream is successfully processed when AGC2 adaptive digital is
524// used and when the field trial
525// `WebRTC-Audio-TransientSuppressorVadMode/Enabled-Default/` is set.
Hanna Silen0c1ad292022-06-16 16:35:45 +0200526TEST(AudioProcessingImplTest,
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200527 ProcessWithAgc2AndTransientSuppressorVadModeDefault) {
528 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100529 "WebRTC-Audio-GainController2/Disabled/");
530 auto apm = AudioProcessingBuilder()
531 .SetConfig({.gain_controller1{.enabled = false}})
532 .Create();
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200533 ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
Hanna Silen0c1ad292022-06-16 16:35:45 +0200534 webrtc::AudioProcessing::Config apm_config;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200535 apm_config.gain_controller1.enabled = false;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200536 apm_config.gain_controller2.enabled = true;
537 apm_config.gain_controller2.adaptive_digital.enabled = true;
Alessio Bazzica17e14fd2022-12-07 17:08:45 +0100538 apm_config.transient_suppression.enabled = true;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200539 apm->ApplyConfig(apm_config);
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200540 constexpr int kSampleRateHz = 48000;
541 constexpr int kNumChannels = 1;
542 std::array<float, kSampleRateHz / 100> buffer;
543 float* channel_pointers[] = {buffer.data()};
544 StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
545 /*num_channels=*/kNumChannels);
546 Random random_generator(2341U);
547 constexpr int kFramesToProcess = 10;
548 for (int i = 0; i < kFramesToProcess; ++i) {
549 RandomizeSampleVector(&random_generator, buffer);
550 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
551 channel_pointers),
552 kNoErr);
553 }
Hanna Silen0c1ad292022-06-16 16:35:45 +0200554}
555
Alessio Bazzicaa5aaedb2022-09-06 16:39:07 +0200556// Tests that a stream is successfully processed when AGC2 adaptive digital is
557// used and when the field trial
558// `WebRTC-Audio-TransientSuppressorVadMode/Enabled-RnnVad/` is set.
559TEST(AudioProcessingImplTest,
560 ProcessWithAgc2AndTransientSuppressorVadModeRnnVad) {
Hanna Silen0c1ad292022-06-16 16:35:45 +0200561 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100562 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true/");
Hanna Silen0c1ad292022-06-16 16:35:45 +0200563 rtc::scoped_refptr<AudioProcessing> apm = AudioProcessingBuilder().Create();
564 ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
565 webrtc::AudioProcessing::Config apm_config;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200566 apm_config.gain_controller1.enabled = false;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200567 apm_config.gain_controller2.enabled = true;
568 apm_config.gain_controller2.adaptive_digital.enabled = true;
Alessio Bazzica17e14fd2022-12-07 17:08:45 +0100569 apm_config.transient_suppression.enabled = true;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200570 apm->ApplyConfig(apm_config);
571 constexpr int kSampleRateHz = 48000;
572 constexpr int kNumChannels = 1;
573 std::array<float, kSampleRateHz / 100> buffer;
574 float* channel_pointers[] = {buffer.data()};
575 StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
576 /*num_channels=*/kNumChannels);
577 Random random_generator(2341U);
578 constexpr int kFramesToProcess = 10;
579 for (int i = 0; i < kFramesToProcess; ++i) {
580 RandomizeSampleVector(&random_generator, buffer);
581 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
582 channel_pointers),
583 kNoErr);
584 }
585}
586
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200587TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) {
588 // Tests that the echo controller observes an echo path gain change when a
589 // playout volume change is reported.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200590 auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200591 const auto* echo_control_factory_ptr = echo_control_factory.get();
592
Niels Möller4f776ac2021-07-02 11:30:54 +0200593 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgrencc73ed32020-04-26 23:56:17 +0200594 AudioProcessingBuilderForTesting()
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200595 .SetEchoControlFactory(std::move(echo_control_factory))
Niels Möller4f776ac2021-07-02 11:30:54 +0200596 .Create();
Sam Zackrisson41478c72019-10-15 10:10:26 +0200597 // Disable AGC.
598 webrtc::AudioProcessing::Config apm_config;
599 apm_config.gain_controller1.enabled = false;
600 apm_config.gain_controller2.enabled = false;
601 apm->ApplyConfig(apm_config);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200602
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200603 constexpr int16_t kAudioLevel = 10000;
604 constexpr size_t kSampleRateHz = 48000;
605 constexpr size_t kNumChannels = 2;
Per Åhgren2507f8c2020-03-19 12:33:29 +0100606 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000607 StreamConfig stream_config(kSampleRateHz, kNumChannels);
Per Åhgren2507f8c2020-03-19 12:33:29 +0100608 frame.fill(kAudioLevel);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200609
610 MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
611
Per Åhgren0aefbf02019-08-23 21:29:17 +0200612 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200613 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100614 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200615 .Times(1);
Per Åhgrendc5522b2020-03-19 14:55:58 +0100616 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200617
Per Åhgren0aefbf02019-08-23 21:29:17 +0200618 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200619 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100620 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200621 .Times(1);
622 apm->SetRuntimeSetting(
623 AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
Per Åhgrendc5522b2020-03-19 14:55:58 +0100624 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200625
Per Åhgren0aefbf02019-08-23 21:29:17 +0200626 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200627 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100628 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/false))
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200629 .Times(1);
630 apm->SetRuntimeSetting(
631 AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50));
Per Åhgrendc5522b2020-03-19 14:55:58 +0100632 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200633
Per Åhgren0aefbf02019-08-23 21:29:17 +0200634 EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200635 EXPECT_CALL(*echo_control_mock,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100636 ProcessCapture(NotNull(), testing::_, /*echo_path_change=*/true))
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200637 .Times(1);
638 apm->SetRuntimeSetting(
639 AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(100));
Per Åhgrendc5522b2020-03-19 14:55:58 +0100640 apm->ProcessStream(frame.data(), stream_config, stream_config, frame.data());
Fredrik Hernqvistca362852019-05-10 15:50:02 +0200641}
642
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200643TEST(AudioProcessingImplTest, RenderPreProcessorBeforeEchoDetector) {
644 // Make sure that signal changes caused by a render pre-processing sub-module
645 // take place before any echo detector analysis.
Tommi87f70902021-04-27 14:43:08 +0200646 auto test_echo_detector = rtc::make_ref_counted<TestEchoDetector>();
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200647 std::unique_ptr<CustomProcessing> test_render_pre_processor(
648 new TestRenderPreProcessor());
649 // Create APM injecting the test echo detector and render pre-processor.
Niels Möller4f776ac2021-07-02 11:30:54 +0200650 rtc::scoped_refptr<AudioProcessing> apm =
Per Åhgrencc73ed32020-04-26 23:56:17 +0200651 AudioProcessingBuilderForTesting()
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200652 .SetEchoDetector(test_echo_detector)
653 .SetRenderPreProcessing(std::move(test_render_pre_processor))
Niels Möller4f776ac2021-07-02 11:30:54 +0200654 .Create();
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200655 webrtc::AudioProcessing::Config apm_config;
656 apm_config.pre_amplifier.enabled = true;
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200657 apm->ApplyConfig(apm_config);
658
659 constexpr int16_t kAudioLevel = 1000;
660 constexpr int kSampleRateHz = 16000;
661 constexpr size_t kNumChannels = 1;
Sam Zackrisson12e319a2020-01-03 14:54:20 +0100662 // Explicitly initialize APM to ensure no render frames are discarded.
663 const ProcessingConfig processing_config = {{
Henrik Lundin64253a92022-02-04 09:02:48 +0000664 {kSampleRateHz, kNumChannels},
665 {kSampleRateHz, kNumChannels},
666 {kSampleRateHz, kNumChannels},
667 {kSampleRateHz, kNumChannels},
Sam Zackrisson12e319a2020-01-03 14:54:20 +0100668 }};
669 apm->Initialize(processing_config);
670
Per Åhgren2507f8c2020-03-19 12:33:29 +0100671 std::array<int16_t, kNumChannels * kSampleRateHz / 100> frame;
Henrik Lundin64253a92022-02-04 09:02:48 +0000672 StreamConfig stream_config(kSampleRateHz, kNumChannels);
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200673
674 constexpr float kAudioLevelFloat = static_cast<float>(kAudioLevel);
675 constexpr float kExpectedPreprocessedAudioLevel =
676 TestRenderPreProcessor::ProcessSample(kAudioLevelFloat);
677 ASSERT_NE(kAudioLevelFloat, kExpectedPreprocessedAudioLevel);
678
679 // Analyze a render stream frame.
Per Åhgren2507f8c2020-03-19 12:33:29 +0100680 frame.fill(kAudioLevel);
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200681 ASSERT_EQ(AudioProcessing::Error::kNoError,
Per Åhgren2507f8c2020-03-19 12:33:29 +0100682 apm->ProcessReverseStream(frame.data(), stream_config,
683 stream_config, frame.data()));
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200684 // Trigger a call to in EchoDetector::AnalyzeRenderAudio() via
685 // ProcessStream().
Per Åhgren2507f8c2020-03-19 12:33:29 +0100686 frame.fill(kAudioLevel);
687 ASSERT_EQ(AudioProcessing::Error::kNoError,
688 apm->ProcessStream(frame.data(), stream_config, stream_config,
Per Åhgrendc5522b2020-03-19 14:55:58 +0100689 frame.data()));
Alessio Bazzicad2b97402018-08-09 14:23:11 +0200690 // Regardless of how the call to in EchoDetector::AnalyzeRenderAudio() is
691 // triggered, the line below checks that the call has occurred. If not, the
692 // APM implementation may have changed and this test might need to be adapted.
693 ASSERT_TRUE(test_echo_detector->analyze_render_audio_called());
694 // Check that the data read in EchoDetector::AnalyzeRenderAudio() is that
695 // produced by the render pre-processor.
696 EXPECT_EQ(kExpectedPreprocessedAudioLevel,
697 test_echo_detector->last_render_audio_first_sample());
698}
699
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200700// Disabling build-optional submodules and trying to enable them via the APM
701// config should be bit-exact with running APM with said submodules disabled.
702// This mainly tests that SetCreateOptionalSubmodulesForTesting has an effect.
703TEST(ApmWithSubmodulesExcludedTest, BitexactWithDisabledModules) {
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200704 auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200705 ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
706
707 ApmSubmoduleCreationOverrides overrides;
708 overrides.transient_suppression = true;
709 apm->OverrideSubmoduleCreationForTesting(overrides);
710
711 AudioProcessing::Config apm_config = apm->GetConfig();
712 apm_config.transient_suppression.enabled = true;
713 apm->ApplyConfig(apm_config);
714
715 rtc::scoped_refptr<AudioProcessing> apm_reference =
716 AudioProcessingBuilder().Create();
717 apm_config = apm_reference->GetConfig();
718 apm_config.transient_suppression.enabled = false;
719 apm_reference->ApplyConfig(apm_config);
720
721 constexpr int kSampleRateHz = 16000;
722 constexpr int kNumChannels = 1;
723 std::array<float, kSampleRateHz / 100> buffer;
724 std::array<float, kSampleRateHz / 100> buffer_reference;
725 float* channel_pointers[] = {buffer.data()};
726 float* channel_pointers_reference[] = {buffer_reference.data()};
727 StreamConfig stream_config(/*sample_rate_hz=*/kSampleRateHz,
Henrik Lundin64253a92022-02-04 09:02:48 +0000728 /*num_channels=*/kNumChannels);
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200729 Random random_generator(2341U);
730 constexpr int kFramesToProcessPerConfiguration = 10;
731
732 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
733 RandomizeSampleVector(&random_generator, buffer);
734 std::copy(buffer.begin(), buffer.end(), buffer_reference.begin());
735 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
736 channel_pointers),
737 kNoErr);
738 ASSERT_EQ(
739 apm_reference->ProcessStream(channel_pointers_reference, stream_config,
740 stream_config, channel_pointers_reference),
741 kNoErr);
742 for (int j = 0; j < kSampleRateHz / 100; ++j) {
743 EXPECT_EQ(buffer[j], buffer_reference[j]);
744 }
745 }
746}
747
748// Disable transient suppressor creation and run APM in ways that should trigger
749// calls to the transient suppressor API.
750TEST(ApmWithSubmodulesExcludedTest, ReinitializeTransientSuppressor) {
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200751 auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200752 ASSERT_EQ(apm->Initialize(), kNoErr);
753
754 ApmSubmoduleCreationOverrides overrides;
755 overrides.transient_suppression = true;
756 apm->OverrideSubmoduleCreationForTesting(overrides);
757
758 AudioProcessing::Config config = apm->GetConfig();
759 config.transient_suppression.enabled = true;
760 apm->ApplyConfig(config);
761 // 960 samples per frame: 10 ms of <= 48 kHz audio with <= 2 channels.
762 float buffer[960];
763 float* channel_pointers[] = {&buffer[0], &buffer[480]};
764 Random random_generator(2341U);
765 constexpr int kFramesToProcessPerConfiguration = 3;
766
767 StreamConfig initial_stream_config(/*sample_rate_hz=*/16000,
Henrik Lundin64253a92022-02-04 09:02:48 +0000768 /*num_channels=*/1);
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200769 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
770 RandomizeSampleVector(&random_generator, buffer);
771 EXPECT_EQ(apm->ProcessStream(channel_pointers, initial_stream_config,
772 initial_stream_config, channel_pointers),
773 kNoErr);
774 }
775
776 StreamConfig stereo_stream_config(/*sample_rate_hz=*/16000,
Henrik Lundin64253a92022-02-04 09:02:48 +0000777 /*num_channels=*/2);
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200778 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
779 RandomizeSampleVector(&random_generator, buffer);
780 EXPECT_EQ(apm->ProcessStream(channel_pointers, stereo_stream_config,
781 stereo_stream_config, channel_pointers),
782 kNoErr);
783 }
784
785 StreamConfig high_sample_rate_stream_config(/*sample_rate_hz=*/48000,
Henrik Lundin64253a92022-02-04 09:02:48 +0000786 /*num_channels=*/2);
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200787 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
788 RandomizeSampleVector(&random_generator, buffer);
789 EXPECT_EQ(
790 apm->ProcessStream(channel_pointers, high_sample_rate_stream_config,
791 high_sample_rate_stream_config, channel_pointers),
792 kNoErr);
793 }
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200794}
795
796// Disable transient suppressor creation and run APM in ways that should trigger
797// calls to the transient suppressor API.
798TEST(ApmWithSubmodulesExcludedTest, ToggleTransientSuppressor) {
Alessio Bazzicabe1b8982021-09-17 08:26:10 +0200799 auto apm = rtc::make_ref_counted<AudioProcessingImpl>();
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200800 ASSERT_EQ(apm->Initialize(), AudioProcessing::kNoError);
801
802 ApmSubmoduleCreationOverrides overrides;
803 overrides.transient_suppression = true;
804 apm->OverrideSubmoduleCreationForTesting(overrides);
805
806 // 960 samples per frame: 10 ms of <= 48 kHz audio with <= 2 channels.
807 float buffer[960];
808 float* channel_pointers[] = {&buffer[0], &buffer[480]};
809 Random random_generator(2341U);
810 constexpr int kFramesToProcessPerConfiguration = 3;
811 StreamConfig stream_config(/*sample_rate_hz=*/16000,
Henrik Lundin64253a92022-02-04 09:02:48 +0000812 /*num_channels=*/1);
Sam Zackrissonb37e59d2020-04-27 08:39:33 +0200813
814 AudioProcessing::Config config = apm->GetConfig();
815 config.transient_suppression.enabled = true;
816 apm->ApplyConfig(config);
817 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
818 RandomizeSampleVector(&random_generator, buffer);
819 EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
820 channel_pointers),
821 kNoErr);
822 }
823
824 config = apm->GetConfig();
825 config.transient_suppression.enabled = false;
826 apm->ApplyConfig(config);
827 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
828 RandomizeSampleVector(&random_generator, buffer);
829 EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
830 channel_pointers),
831 kNoErr);
832 }
833
834 config = apm->GetConfig();
835 config.transient_suppression.enabled = true;
836 apm->ApplyConfig(config);
837 for (int i = 0; i < kFramesToProcessPerConfiguration; ++i) {
838 RandomizeSampleVector(&random_generator, buffer);
839 EXPECT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
840 channel_pointers),
841 kNoErr);
842 }
843}
Hanna Silenc69188d2022-09-16 11:38:56 +0200844
Alessio Bazzica4f26c252022-12-20 13:46:01 +0100845class StartupInputVolumeParameterizedTest
846 : public ::testing::TestWithParam<int> {};
847
848// Tests that, when no input volume controller is used, the startup input volume
849// is never modified.
850TEST_P(StartupInputVolumeParameterizedTest,
851 WithNoInputVolumeControllerStartupVolumeNotModified) {
852 webrtc::AudioProcessing::Config config;
853 config.gain_controller1.enabled = false;
854 config.gain_controller2.enabled = false;
855 auto apm = AudioProcessingBuilder().SetConfig(config).Create();
856
857 int startup_volume = GetParam();
858 int recommended_volume = ProcessInputVolume(
859 *apm, /*num_frames=*/1, /*initial_volume=*/startup_volume);
860 EXPECT_EQ(recommended_volume, startup_volume);
861}
862
863INSTANTIATE_TEST_SUITE_P(AudioProcessingImplTest,
864 StartupInputVolumeParameterizedTest,
865 ::testing::Values(0, 5, 15, 50, 100));
866
867// Tests that, when no input volume controller is used, the recommended input
868// volume always matches the applied one.
869TEST(AudioProcessingImplTest,
870 WithNoInputVolumeControllerAppliedAndRecommendedVolumesMatch) {
871 webrtc::AudioProcessing::Config config;
872 config.gain_controller1.enabled = false;
873 config.gain_controller2.enabled = false;
874 auto apm = AudioProcessingBuilder().SetConfig(config).Create();
875
876 Random rand_gen(42);
877 for (int i = 0; i < 32; ++i) {
878 SCOPED_TRACE(i);
879 int32_t applied_volume = rand_gen.Rand(/*low=*/0, /*high=*/255);
880 int recommended_volume =
881 ProcessInputVolume(*apm, /*num_frames=*/1, applied_volume);
882 EXPECT_EQ(recommended_volume, applied_volume);
883 }
884}
885
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100886class ApmInputVolumeControllerParametrizedTest
887 : public ::testing::TestWithParam<
888 std::tuple<int, int, AudioProcessing::Config>> {
889 protected:
890 ApmInputVolumeControllerParametrizedTest()
891 : sample_rate_hz_(std::get<0>(GetParam())),
892 num_channels_(std::get<1>(GetParam())),
893 channels_(num_channels_),
894 channel_pointers_(num_channels_) {
895 const int frame_size = sample_rate_hz_ / 100;
896 for (int c = 0; c < num_channels_; ++c) {
897 channels_[c].resize(frame_size);
898 channel_pointers_[c] = channels_[c].data();
899 std::fill(channels_[c].begin(), channels_[c].end(), 0.0f);
Hanna Silend4dbe452022-11-30 15:16:21 +0100900 }
Hanna Silenc69188d2022-09-16 11:38:56 +0200901 }
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100902
903 int sample_rate_hz() const { return sample_rate_hz_; }
904 int num_channels() const { return num_channels_; }
905 AudioProcessing::Config GetConfig() const { return std::get<2>(GetParam()); }
906
907 float* const* channel_pointers() { return channel_pointers_.data(); }
908
909 private:
910 const int sample_rate_hz_;
911 const int num_channels_;
912 std::vector<std::vector<float>> channels_;
913 std::vector<float*> channel_pointers_;
914};
915
916TEST_P(ApmInputVolumeControllerParametrizedTest,
917 EnforceMinInputVolumeAtStartupWithZeroVolume) {
918 const StreamConfig stream_config(sample_rate_hz(), num_channels());
919 auto apm = AudioProcessingBuilder().SetConfig(GetConfig()).Create();
920
921 apm->set_stream_analog_level(0);
922 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
923 channel_pointers());
924 EXPECT_GT(apm->recommended_stream_analog_level(), 0);
Hanna Silenc69188d2022-09-16 11:38:56 +0200925}
926
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100927TEST_P(ApmInputVolumeControllerParametrizedTest,
928 EnforceMinInputVolumeAtStartupWithNonZeroVolume) {
929 const StreamConfig stream_config(sample_rate_hz(), num_channels());
930 auto apm = AudioProcessingBuilder().SetConfig(GetConfig()).Create();
Hanna Silenc69188d2022-09-16 11:38:56 +0200931
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100932 constexpr int kStartupVolume = 3;
933 apm->set_stream_analog_level(kStartupVolume);
934 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
935 channel_pointers());
936 EXPECT_GT(apm->recommended_stream_analog_level(), kStartupVolume);
937}
Hanna Silenc69188d2022-09-16 11:38:56 +0200938
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100939TEST_P(ApmInputVolumeControllerParametrizedTest,
940 EnforceMinInputVolumeAfterManualVolumeAdjustment) {
941 const auto config = GetConfig();
942 if (config.gain_controller1.enabled) {
943 // After a downward manual adjustment, AGC1 slowly converges to the minimum
944 // input volume.
945 GTEST_SKIP() << "Does not apply to AGC1";
Hanna Silend4dbe452022-11-30 15:16:21 +0100946 }
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100947 const StreamConfig stream_config(sample_rate_hz(), num_channels());
948 auto apm = AudioProcessingBuilder().SetConfig(GetConfig()).Create();
949
950 apm->set_stream_analog_level(20);
951 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
952 channel_pointers());
953 constexpr int kManuallyAdjustedVolume = 3;
954 apm->set_stream_analog_level(kManuallyAdjustedVolume);
955 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
956 channel_pointers());
957 EXPECT_GT(apm->recommended_stream_analog_level(), kManuallyAdjustedVolume);
Hanna Silenc69188d2022-09-16 11:38:56 +0200958}
959
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100960TEST_P(ApmInputVolumeControllerParametrizedTest,
Alessio Bazzica4f26c252022-12-20 13:46:01 +0100961 DoNotEnforceMinInputVolumeAtStartupWithHighVolume) {
962 const StreamConfig stream_config(sample_rate_hz(), num_channels());
963 auto apm = AudioProcessingBuilder().SetConfig(GetConfig()).Create();
964
965 constexpr int kStartupVolume = 200;
966 apm->set_stream_analog_level(kStartupVolume);
967 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
968 channel_pointers());
969 EXPECT_EQ(apm->recommended_stream_analog_level(), kStartupVolume);
970}
971
972TEST_P(ApmInputVolumeControllerParametrizedTest,
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100973 DoNotEnforceMinInputVolumeAfterManualVolumeAdjustmentToZero) {
974 const StreamConfig stream_config(sample_rate_hz(), num_channels());
975 auto apm = AudioProcessingBuilder().SetConfig(GetConfig()).Create();
Hanna Silenc69188d2022-09-16 11:38:56 +0200976
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100977 apm->set_stream_analog_level(100);
978 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
979 channel_pointers());
980 apm->set_stream_analog_level(0);
981 apm->ProcessStream(channel_pointers(), stream_config, stream_config,
982 channel_pointers());
983 EXPECT_EQ(apm->recommended_stream_analog_level(), 0);
Hanna Silenc69188d2022-09-16 11:38:56 +0200984}
985
Alessio Bazzica3b51cd32022-12-14 16:36:10 +0100986INSTANTIATE_TEST_SUITE_P(
987 AudioProcessingImplTest,
988 ApmInputVolumeControllerParametrizedTest,
989 ::testing::Combine(
990 ::testing::Values(8000, 16000, 32000, 48000), // Sample rates.
991 ::testing::Values(1, 2), // Number of channels.
992 ::testing::Values(
993 // Full AGC1.
994 AudioProcessing::Config{
995 .gain_controller1 = {.enabled = true,
996 .analog_gain_controller =
997 {.enabled = true,
998 .enable_digital_adaptive = true}},
999 .gain_controller2 = {.enabled = false}},
1000 // Hybrid AGC.
1001 AudioProcessing::Config{
1002 .gain_controller1 = {.enabled = true,
1003 .analog_gain_controller =
1004 {.enabled = true,
1005 .enable_digital_adaptive = false}},
1006 .gain_controller2 = {.enabled = true,
1007 .adaptive_digital = {.enabled = true}}})));
Hanna Silenc69188d2022-09-16 11:38:56 +02001008
Alessio Bazzica79beaa72022-10-31 16:42:34 +01001009// When the input volume is not emulated and no input volume controller is
1010// active, the recommended volume must always be the applied volume.
1011TEST(AudioProcessingImplTest,
1012 RecommendAppliedInputVolumeWithNoAgcWithNoEmulation) {
1013 auto apm = AudioProcessingBuilder()
1014 .SetConfig({.capture_level_adjustment = {.enabled = false},
1015 .gain_controller1 = {.enabled = false}})
1016 .Create();
1017
1018 constexpr int kOneFrame = 1;
1019 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1020 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1021 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1022}
1023
1024// When the input volume is emulated, the recommended volume must always be the
1025// applied volume and at any time it must not be that set in the input volume
1026// emulator.
1027// TODO(bugs.webrtc.org/14581): Enable when APM fixed to let this test pass.
1028TEST(AudioProcessingImplTest,
1029 DISABLED_RecommendAppliedInputVolumeWithNoAgcWithEmulation) {
1030 auto apm =
1031 AudioProcessingBuilder()
1032 .SetConfig({.capture_level_adjustment = {.enabled = true,
1033 .analog_mic_gain_emulation{
1034 .enabled = true,
1035 .initial_level = 255}},
1036 .gain_controller1 = {.enabled = false}})
1037 .Create();
1038
1039 constexpr int kOneFrame = 1;
1040 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1041 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1042 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1043}
1044
1045// Even if there is an enabled input volume controller, when the input volume is
1046// emulated, the recommended volume is always the applied volume because the
1047// active controller must only adjust the internally emulated volume and leave
1048// the externally applied volume unchanged.
1049// TODO(bugs.webrtc.org/14581): Enable when APM fixed to let this test pass.
1050TEST(AudioProcessingImplTest,
1051 DISABLED_RecommendAppliedInputVolumeWithAgcWithEmulation) {
1052 auto apm =
1053 AudioProcessingBuilder()
1054 .SetConfig({.capture_level_adjustment = {.enabled = true,
1055 .analog_mic_gain_emulation{
1056 .enabled = true}},
1057 .gain_controller1 = {.enabled = true,
1058 .analog_gain_controller{
1059 .enabled = true,
1060 }}})
1061 .Create();
1062
1063 constexpr int kOneFrame = 1;
1064 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/123), 123);
1065 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/59), 59);
1066 EXPECT_EQ(ProcessInputVolume(*apm, kOneFrame, /*initial_volume=*/135), 135);
1067}
1068
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001069TEST(AudioProcessingImplTest,
1070 Agc2FieldTrialDoNotSwitchToFullAgc2WhenNoAgcIsActive) {
1071 constexpr AudioProcessing::Config kOriginal{
1072 .gain_controller1{.enabled = false},
1073 .gain_controller2{.enabled = false},
1074 };
1075 webrtc::test::ScopedFieldTrials field_trials(
1076 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true/");
1077
1078 // Test config application via `AudioProcessing` ctor.
1079 auto adjusted =
1080 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1081 EXPECT_EQ(adjusted.gain_controller1, kOriginal.gain_controller1);
1082 EXPECT_EQ(adjusted.gain_controller2, kOriginal.gain_controller2);
1083
1084 // Test config application via `AudioProcessing::ApplyConfig()`.
1085 auto apm = AudioProcessingBuilder().Create();
1086 apm->ApplyConfig(kOriginal);
1087 adjusted = apm->GetConfig();
1088 EXPECT_EQ(adjusted.gain_controller1, kOriginal.gain_controller1);
1089 EXPECT_EQ(adjusted.gain_controller2, kOriginal.gain_controller2);
1090}
1091
1092TEST(AudioProcessingImplTest,
1093 Agc2FieldTrialDoNotSwitchToFullAgc2WithAgc1Agc2InputVolumeControllers) {
1094 constexpr AudioProcessing::Config kOriginal{
1095 .gain_controller1{.enabled = true,
1096 .analog_gain_controller{.enabled = true}},
1097 .gain_controller2{.enabled = true,
1098 .input_volume_controller{.enabled = true}},
1099 };
1100 webrtc::test::ScopedFieldTrials field_trials(
1101 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true/");
1102
1103 // Test config application via `AudioProcessing` ctor.
1104 auto adjusted =
1105 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1106 EXPECT_EQ(adjusted.gain_controller1, kOriginal.gain_controller1);
1107 EXPECT_EQ(adjusted.gain_controller2, kOriginal.gain_controller2);
1108
1109 // Test config application via `AudioProcessing::ApplyConfig()`.
1110 auto apm = AudioProcessingBuilder().Create();
1111 apm->ApplyConfig(kOriginal);
1112 adjusted = apm->GetConfig();
1113 EXPECT_EQ(adjusted.gain_controller1, kOriginal.gain_controller1);
1114 EXPECT_EQ(adjusted.gain_controller2, kOriginal.gain_controller2);
1115}
1116
1117class Agc2FieldTrialParametrizedTest
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001118 : public ::testing::TestWithParam<AudioProcessing::Config> {};
1119
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001120TEST_P(Agc2FieldTrialParametrizedTest, DoNotChangeConfigIfDisabled) {
1121 const AudioProcessing::Config original = GetParam();
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001122 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001123 "WebRTC-Audio-GainController2/Disabled/");
1124
1125 // Test config application via `AudioProcessing` ctor.
1126 auto adjusted =
1127 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1128 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1129 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1130
1131 // Test config application via `AudioProcessing::ApplyConfig()`.
1132 auto apm = AudioProcessingBuilder().Create();
1133 apm->ApplyConfig(original);
1134 adjusted = apm->GetConfig();
1135 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1136 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1137}
1138
1139TEST_P(Agc2FieldTrialParametrizedTest, DoNotChangeConfigIfNoOverride) {
1140 const AudioProcessing::Config original = GetParam();
1141 webrtc::test::ScopedFieldTrials field_trials(
1142 "WebRTC-Audio-GainController2/Enabled,"
1143 "switch_to_agc2:false,"
1144 "disallow_transient_suppressor_usage:false/");
1145
1146 // Test config application via `AudioProcessing` ctor.
1147 auto adjusted =
1148 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1149 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1150 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1151
1152 // Test config application via `AudioProcessing::ApplyConfig()`.
1153 auto apm = AudioProcessingBuilder().Create();
1154 apm->ApplyConfig(original);
1155 adjusted = apm->GetConfig();
1156 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1157 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1158}
1159
1160TEST_P(Agc2FieldTrialParametrizedTest, DoNotSwitchToFullAgc2) {
1161 const AudioProcessing::Config original = GetParam();
1162 webrtc::test::ScopedFieldTrials field_trials(
1163 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:false/");
1164
1165 // Test config application via `AudioProcessing` ctor.
1166 auto adjusted =
1167 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1168 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1169 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1170
1171 // Test config application via `AudioProcessing::ApplyConfig()`.
1172 auto apm = AudioProcessingBuilder().Create();
1173 apm->ApplyConfig(original);
1174 adjusted = apm->GetConfig();
1175 EXPECT_EQ(adjusted.gain_controller1, original.gain_controller1);
1176 EXPECT_EQ(adjusted.gain_controller2, original.gain_controller2);
1177}
1178
1179TEST_P(Agc2FieldTrialParametrizedTest, SwitchToFullAgc2) {
1180 const AudioProcessing::Config original = GetParam();
1181 webrtc::test::ScopedFieldTrials field_trials(
1182 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true/");
1183
1184 // Test config application via `AudioProcessing` ctor.
1185 auto adjusted =
1186 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1187 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1188 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1189 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1190 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1191
1192 // Test config application via `AudioProcessing::ApplyConfig()`.
1193 auto apm = AudioProcessingBuilder().Create();
1194 apm->ApplyConfig(original);
1195 adjusted = apm->GetConfig();
1196 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1197 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1198 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1199 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1200}
1201
1202TEST_P(Agc2FieldTrialParametrizedTest,
1203 SwitchToFullAgc2AndOverrideInputVolumeControllerParameters) {
1204 const AudioProcessing::Config original = GetParam();
1205 webrtc::test::ScopedFieldTrials field_trials(
1206 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true,"
1207 "min_input_volume:123,"
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001208 "clipped_level_min:20,"
1209 "clipped_level_step:30,"
1210 "clipped_ratio_threshold:0.4,"
1211 "clipped_wait_frames:50,"
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001212 "enable_clipping_predictor:true,"
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001213 "target_range_max_dbfs:-6,"
1214 "target_range_min_dbfs:-70,"
1215 "update_input_volume_wait_frames:80,"
1216 "speech_probability_threshold:0.9,"
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001217 "speech_ratio_threshold:1.0/");
1218
1219 // Test config application via `AudioProcessing` ctor.
1220 auto adjusted =
1221 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1222 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1223 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1224 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1225 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1226
1227 // Test config application via `AudioProcessing::ApplyConfig()`.
1228 auto apm = AudioProcessingBuilder().Create();
1229 apm->ApplyConfig(original);
1230 adjusted = apm->GetConfig();
1231 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1232 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1233 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1234 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1235}
1236
1237TEST_P(Agc2FieldTrialParametrizedTest,
1238 SwitchToFullAgc2AndOverrideAdaptiveDigitalControllerParameters) {
1239 const AudioProcessing::Config original = GetParam();
1240 webrtc::test::ScopedFieldTrials field_trials(
1241 "WebRTC-Audio-GainController2/Enabled,switch_to_agc2:true,"
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001242 "headroom_db:10,"
1243 "max_gain_db:20,"
1244 "initial_gain_db:7,"
1245 "max_gain_change_db_per_second:5,"
1246 "max_output_noise_level_dbfs:-40/");
1247
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001248 // Test config application via `AudioProcessing` ctor.
1249 auto adjusted =
1250 AudioProcessingBuilder().SetConfig(original).Create()->GetConfig();
1251 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1252 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1253 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1254 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1255 ASSERT_NE(adjusted.gain_controller2.adaptive_digital,
1256 original.gain_controller2.adaptive_digital);
1257 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.headroom_db, 10);
1258 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.max_gain_db, 20);
1259 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.initial_gain_db, 7);
1260 EXPECT_EQ(
1261 adjusted.gain_controller2.adaptive_digital.max_gain_change_db_per_second,
1262 5);
1263 EXPECT_EQ(
1264 adjusted.gain_controller2.adaptive_digital.max_output_noise_level_dbfs,
1265 -40);
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001266
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001267 // Test config application via `AudioProcessing::ApplyConfig()`.
1268 auto apm = AudioProcessingBuilder().Create();
1269 apm->ApplyConfig(original);
1270 adjusted = apm->GetConfig();
1271 EXPECT_FALSE(adjusted.gain_controller1.enabled);
1272 EXPECT_TRUE(adjusted.gain_controller2.enabled);
1273 EXPECT_TRUE(adjusted.gain_controller2.input_volume_controller.enabled);
1274 EXPECT_TRUE(adjusted.gain_controller2.adaptive_digital.enabled);
1275 ASSERT_NE(adjusted.gain_controller2.adaptive_digital,
1276 original.gain_controller2.adaptive_digital);
1277 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.headroom_db, 10);
1278 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.max_gain_db, 20);
1279 EXPECT_EQ(adjusted.gain_controller2.adaptive_digital.initial_gain_db, 7);
1280 EXPECT_EQ(
1281 adjusted.gain_controller2.adaptive_digital.max_gain_change_db_per_second,
1282 5);
1283 EXPECT_EQ(
1284 adjusted.gain_controller2.adaptive_digital.max_output_noise_level_dbfs,
1285 -40);
1286}
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001287
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001288TEST_P(Agc2FieldTrialParametrizedTest, ProcessSucceedsWithTs) {
1289 AudioProcessing::Config config = GetParam();
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001290 if (!config.transient_suppression.enabled) {
1291 GTEST_SKIP() << "TS is disabled, skip.";
1292 }
1293
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001294 webrtc::test::ScopedFieldTrials field_trials(
1295 "WebRTC-Audio-GainController2/Disabled/");
1296 auto apm = AudioProcessingBuilder().SetConfig(config).Create();
1297
1298 constexpr int kSampleRateHz = 48000;
1299 constexpr int kNumChannels = 1;
1300 std::array<float, kSampleRateHz / 100> buffer;
1301 float* channel_pointers[] = {buffer.data()};
1302 StreamConfig stream_config(kSampleRateHz, kNumChannels);
1303 Random random_generator(2341U);
1304 constexpr int kFramesToProcess = 10;
1305 int volume = 100;
1306 for (int i = 0; i < kFramesToProcess; ++i) {
1307 SCOPED_TRACE(i);
1308 RandomizeSampleVector(&random_generator, buffer);
1309 apm->set_stream_analog_level(volume);
1310 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
1311 channel_pointers),
1312 kNoErr);
1313 volume = apm->recommended_stream_analog_level();
1314 }
1315}
1316
1317TEST_P(Agc2FieldTrialParametrizedTest, ProcessSucceedsWithoutTs) {
1318 webrtc::test::ScopedFieldTrials field_trials(
1319 "WebRTC-Audio-GainController2/Enabled,"
1320 "switch_to_agc2:false,"
1321 "disallow_transient_suppressor_usage:true/");
1322 auto apm = AudioProcessingBuilder().SetConfig(GetParam()).Create();
1323
1324 constexpr int kSampleRateHz = 48000;
1325 constexpr int kNumChannels = 1;
1326 std::array<float, kSampleRateHz / 100> buffer;
1327 float* channel_pointers[] = {buffer.data()};
1328 StreamConfig stream_config(kSampleRateHz, kNumChannels);
1329 Random random_generator(2341U);
1330 constexpr int kFramesToProcess = 10;
1331 int volume = 100;
1332 for (int i = 0; i < kFramesToProcess; ++i) {
1333 SCOPED_TRACE(i);
1334 RandomizeSampleVector(&random_generator, buffer);
1335 apm->set_stream_analog_level(volume);
1336 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
1337 channel_pointers),
1338 kNoErr);
1339 volume = apm->recommended_stream_analog_level();
1340 }
1341}
1342
1343TEST_P(Agc2FieldTrialParametrizedTest,
1344 ProcessSucceedsWhenSwitchToFullAgc2WithTs) {
1345 AudioProcessing::Config config = GetParam();
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001346 if (!config.transient_suppression.enabled) {
1347 GTEST_SKIP() << "TS is disabled, skip.";
1348 }
1349
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001350 webrtc::test::ScopedFieldTrials field_trials(
1351 "WebRTC-Audio-GainController2/Enabled,"
1352 "switch_to_agc2:true,"
1353 "disallow_transient_suppressor_usage:false/");
1354 auto apm = AudioProcessingBuilder().SetConfig(config).Create();
1355
1356 constexpr int kSampleRateHz = 48000;
1357 constexpr int kNumChannels = 1;
1358 std::array<float, kSampleRateHz / 100> buffer;
1359 float* channel_pointers[] = {buffer.data()};
1360 StreamConfig stream_config(kSampleRateHz, kNumChannels);
1361 Random random_generator(2341U);
1362 constexpr int kFramesToProcess = 10;
1363 int volume = 100;
1364 for (int i = 0; i < kFramesToProcess; ++i) {
1365 SCOPED_TRACE(i);
1366 RandomizeSampleVector(&random_generator, buffer);
1367 apm->set_stream_analog_level(volume);
1368 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
1369 channel_pointers),
1370 kNoErr);
1371 volume = apm->recommended_stream_analog_level();
1372 }
1373}
1374
1375TEST_P(Agc2FieldTrialParametrizedTest,
1376 ProcessSucceedsWhenSwitchToFullAgc2WithoutTs) {
1377 webrtc::test::ScopedFieldTrials field_trials(
1378 "WebRTC-Audio-GainController2/Enabled,"
1379 "switch_to_agc2:true,"
1380 "disallow_transient_suppressor_usage:true/");
1381 auto apm = AudioProcessingBuilder().SetConfig(GetParam()).Create();
1382
1383 constexpr int kSampleRateHz = 48000;
1384 constexpr int kNumChannels = 1;
1385 std::array<float, kSampleRateHz / 100> buffer;
1386 float* channel_pointers[] = {buffer.data()};
1387 StreamConfig stream_config(kSampleRateHz, kNumChannels);
1388 Random random_generator(2341U);
1389 constexpr int kFramesToProcess = 10;
1390 int volume = 100;
1391 for (int i = 0; i < kFramesToProcess; ++i) {
1392 SCOPED_TRACE(i);
1393 RandomizeSampleVector(&random_generator, buffer);
1394 apm->set_stream_analog_level(volume);
1395 ASSERT_EQ(apm->ProcessStream(channel_pointers, stream_config, stream_config,
1396 channel_pointers),
1397 kNoErr);
1398 volume = apm->recommended_stream_analog_level();
1399 }
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001400}
1401
1402INSTANTIATE_TEST_SUITE_P(
1403 AudioProcessingImplTest,
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001404 Agc2FieldTrialParametrizedTest,
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001405 ::testing::Values(
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001406 // Full AGC1, TS disabled.
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001407 AudioProcessing::Config{
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001408 .transient_suppression = {.enabled = false},
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001409 .gain_controller1 =
1410 {.enabled = true,
1411 .analog_gain_controller = {.enabled = true,
1412 .enable_digital_adaptive = true}},
1413 .gain_controller2 = {.enabled = false}},
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001414 // Full AGC1, TS enabled.
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001415 AudioProcessing::Config{
Alessio Bazzica40b5bd72023-01-16 20:19:48 +01001416 .transient_suppression = {.enabled = true},
1417 .gain_controller1 =
1418 {.enabled = true,
1419 .analog_gain_controller = {.enabled = true,
1420 .enable_digital_adaptive = true}},
1421 .gain_controller2 = {.enabled = false}},
1422 // Hybrid AGC, TS disabled.
1423 AudioProcessing::Config{
1424 .transient_suppression = {.enabled = false},
1425 .gain_controller1 =
1426 {.enabled = true,
1427 .analog_gain_controller = {.enabled = true,
1428 .enable_digital_adaptive = false}},
1429 .gain_controller2 = {.enabled = true,
1430 .adaptive_digital = {.enabled = true}}},
1431 // Hybrid AGC, TS enabled.
1432 AudioProcessing::Config{
1433 .transient_suppression = {.enabled = true},
Alessio Bazzicadfba28e2022-12-09 10:02:41 +01001434 .gain_controller1 =
1435 {.enabled = true,
1436 .analog_gain_controller = {.enabled = true,
1437 .enable_digital_adaptive = false}},
1438 .gain_controller2 = {.enabled = true,
1439 .adaptive_digital = {.enabled = true}}}));
1440
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001441TEST(AudioProcessingImplTest, CanDisableTransientSuppressor) {
1442 constexpr AudioProcessing::Config kOriginal = {
1443 .transient_suppression = {.enabled = false}};
1444
1445 // Test config application via `AudioProcessing` ctor.
1446 auto adjusted =
1447 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1448 EXPECT_FALSE(adjusted.transient_suppression.enabled);
1449
1450 // Test config application via `AudioProcessing::ApplyConfig()`.
1451 auto apm = AudioProcessingBuilder().Create();
1452 apm->ApplyConfig(kOriginal);
1453 adjusted = apm->GetConfig();
1454 EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
1455}
1456
1457TEST(AudioProcessingImplTest, CanEnableTs) {
1458 constexpr AudioProcessing::Config kOriginal = {
1459 .transient_suppression = {.enabled = true}};
1460
1461 // Test config application via `AudioProcessing` ctor.
1462 auto adjusted =
1463 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1464 EXPECT_TRUE(adjusted.transient_suppression.enabled);
1465
1466 // Test config application via `AudioProcessing::ApplyConfig()`.
1467 auto apm = AudioProcessingBuilder().Create();
1468 apm->ApplyConfig(kOriginal);
1469 adjusted = apm->GetConfig();
1470 EXPECT_TRUE(adjusted.transient_suppression.enabled);
1471}
1472
1473TEST(AudioProcessingImplTest, CanDisableTsWithAgc2FieldTrialDisabled) {
1474 constexpr AudioProcessing::Config kOriginal = {
1475 .transient_suppression = {.enabled = false}};
Hanna Silena6574902022-11-30 16:59:05 +01001476 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001477 "WebRTC-Audio-GainController2/Disabled/");
Hanna Silena6574902022-11-30 16:59:05 +01001478
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001479 // Test config application via `AudioProcessing` ctor.
1480 auto adjusted =
1481 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1482 EXPECT_FALSE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001483
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001484 // Test config application via `AudioProcessing::ApplyConfig()`.
1485 auto apm = AudioProcessingBuilder().Create();
1486 apm->ApplyConfig(kOriginal);
1487 adjusted = apm->GetConfig();
1488 EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001489}
1490
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001491TEST(AudioProcessingImplTest, CanEnableTsWithAgc2FieldTrialDisabled) {
1492 constexpr AudioProcessing::Config kOriginal = {
1493 .transient_suppression = {.enabled = true}};
Hanna Silena6574902022-11-30 16:59:05 +01001494 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001495 "WebRTC-Audio-GainController2/Disabled/");
Hanna Silena6574902022-11-30 16:59:05 +01001496
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001497 // Test config application via `AudioProcessing` ctor.
1498 auto adjusted =
1499 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1500 EXPECT_TRUE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001501
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001502 // Test config application via `AudioProcessing::ApplyConfig()`.
1503 auto apm = AudioProcessingBuilder().Create();
1504 apm->ApplyConfig(kOriginal);
1505 adjusted = apm->GetConfig();
1506 EXPECT_TRUE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001507}
1508
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001509TEST(AudioProcessingImplTest,
1510 CanDisableTsWithAgc2FieldTrialEnabledAndUsageAllowed) {
1511 constexpr AudioProcessing::Config kOriginal = {
1512 .transient_suppression = {.enabled = false}};
Hanna Silena6574902022-11-30 16:59:05 +01001513 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001514 "WebRTC-Audio-GainController2/Enabled,"
1515 "disallow_transient_suppressor_usage:false/");
Hanna Silena6574902022-11-30 16:59:05 +01001516
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001517 // Test config application via `AudioProcessing` ctor.
1518 auto adjusted =
1519 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1520 EXPECT_FALSE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001521
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001522 // Test config application via `AudioProcessing::ApplyConfig()`.
1523 auto apm = AudioProcessingBuilder().Create();
1524 apm->ApplyConfig(kOriginal);
1525 adjusted = apm->GetConfig();
1526 EXPECT_FALSE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001527}
1528
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001529TEST(AudioProcessingImplTest,
1530 CanEnableTsWithAgc2FieldTrialEnabledAndUsageAllowed) {
1531 constexpr AudioProcessing::Config kOriginal = {
1532 .transient_suppression = {.enabled = true}};
Hanna Silena6574902022-11-30 16:59:05 +01001533 webrtc::test::ScopedFieldTrials field_trials(
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001534 "WebRTC-Audio-GainController2/Enabled,"
1535 "disallow_transient_suppressor_usage:false/");
Hanna Silena6574902022-11-30 16:59:05 +01001536
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001537 // Test config application via `AudioProcessing` ctor.
1538 auto adjusted =
1539 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1540 EXPECT_TRUE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001541
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001542 // Test config application via `AudioProcessing::ApplyConfig()`.
1543 auto apm = AudioProcessingBuilder().Create();
1544 apm->ApplyConfig(kOriginal);
1545 adjusted = apm->GetConfig();
1546 EXPECT_TRUE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001547}
1548
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001549TEST(AudioProcessingImplTest,
1550 CannotEnableTsWithAgc2FieldTrialEnabledAndUsageDisallowed) {
1551 constexpr AudioProcessing::Config kOriginal = {
1552 .transient_suppression = {.enabled = true}};
1553 webrtc::test::ScopedFieldTrials field_trials(
1554 "WebRTC-Audio-GainController2/Enabled,"
1555 "disallow_transient_suppressor_usage:true/");
Hanna Silena6574902022-11-30 16:59:05 +01001556
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001557 // Test config application via `AudioProcessing` ctor.
1558 auto adjusted =
1559 AudioProcessingBuilder().SetConfig(kOriginal).Create()->GetConfig();
1560 EXPECT_FALSE(adjusted.transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001561
Alessio Bazzica3b51cd32022-12-14 16:36:10 +01001562 // Test config application via `AudioProcessing::ApplyConfig()`.
1563 auto apm = AudioProcessingBuilder().Create();
1564 apm->ApplyConfig(kOriginal);
1565 adjusted = apm->GetConfig();
1566 EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
Hanna Silena6574902022-11-30 16:59:05 +01001567}
1568
andrew@webrtc.org60730cf2014-01-07 17:45:09 +00001569} // namespace webrtc