blob: 88a93b0cdbf1ad9c03e1eb41d469c7ec4e9f10da [file] [log] [blame]
alessiob3ec96df2017-05-22 06:57:06 -07001/*
2 * Copyright (c) 2017 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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/audio_processing/gain_controller2.h"
12
Alessio Bazzica270f7b52017-10-13 11:05:17 +020013#include <algorithm>
Alessio Bazzica980c4602021-04-14 19:09:17 +020014#include <cmath>
Mirko Bonadei317a1f02019-09-17 17:06:18 +020015#include <memory>
Alessio Bazzica6ee97342021-09-27 17:06:40 +020016#include <numeric>
Alessio Bazzica38901042021-10-14 12:14:21 +020017#include <tuple>
alessiob3ec96df2017-05-22 06:57:06 -070018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/array_view.h"
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010020#include "modules/audio_processing/agc2/agc2_testing_common.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/audio_processing/audio_buffer.h"
Alex Loiko5e784612018-11-01 14:51:56 +010022#include "modules/audio_processing/test/audio_buffer_tools.h"
23#include "modules/audio_processing/test/bitexactness_tools.h"
Alessio Bazzica270f7b52017-10-13 11:05:17 +020024#include "rtc_base/checks.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "test/gtest.h"
alessiob3ec96df2017-05-22 06:57:06 -070026
27namespace webrtc {
28namespace test {
alessiob3ec96df2017-05-22 06:57:06 -070029namespace {
30
Alessio Bazzica38901042021-10-14 12:14:21 +020031using Agc2Config = AudioProcessing::Config::GainController2;
32
Alessio Bazzica6ee97342021-09-27 17:06:40 +020033// Sets all the samples in `ab` to `value`.
34void SetAudioBufferSamples(float value, AudioBuffer& ab) {
35 for (size_t k = 0; k < ab.num_channels(); ++k) {
36 std::fill(ab.channels()[k], ab.channels()[k] + ab.num_frames(), value);
alessiob3ec96df2017-05-22 06:57:06 -070037 }
38}
39
Alessio Bazzica6ee97342021-09-27 17:06:40 +020040float RunAgc2WithConstantInput(GainController2& agc2,
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010041 float input_level,
Alessio Bazzica6ee97342021-09-27 17:06:40 +020042 int num_frames,
43 int sample_rate_hz) {
44 const int num_samples = rtc::CheckedDivExact(sample_rate_hz, 100);
45 AudioBuffer ab(sample_rate_hz, 1, sample_rate_hz, 1, sample_rate_hz, 1);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010046
47 // Give time to the level estimator to converge.
Alessio Bazzica6ee97342021-09-27 17:06:40 +020048 for (int i = 0; i < num_frames + 1; ++i) {
49 SetAudioBufferSamples(input_level, ab);
Hanna Silen0c1ad292022-06-16 16:35:45 +020050 agc2.Process(/*speech_probability=*/absl::nullopt, &ab);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010051 }
52
53 // Return the last sample from the last processed frame.
Per Ã…hgrend47941e2019-08-22 11:51:13 +020054 return ab.channels()[0][num_samples - 1];
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010055}
56
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010057std::unique_ptr<GainController2> CreateAgc2FixedDigitalMode(
58 float fixed_gain_db,
Alessio Bazzica6ee97342021-09-27 17:06:40 +020059 int sample_rate_hz) {
Alessio Bazzica38901042021-10-14 12:14:21 +020060 Agc2Config config;
61 config.adaptive_digital.enabled = false;
62 config.fixed_digital.gain_db = fixed_gain_db;
63 EXPECT_TRUE(GainController2::Validate(config));
64 return std::make_unique<GainController2>(config, sample_rate_hz,
Hanna Silen0c1ad292022-06-16 16:35:45 +020065 /*num_channels=*/1,
66 /*use_internal_vad=*/true);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +010067}
68
alessiob3ec96df2017-05-22 06:57:06 -070069} // namespace
70
Alessio Bazzica0c83e152020-10-14 12:49:54 +020071TEST(GainController2, CheckDefaultConfig) {
Alessio Bazzica38901042021-10-14 12:14:21 +020072 Agc2Config config;
Alessio Bazzica270f7b52017-10-13 11:05:17 +020073 EXPECT_TRUE(GainController2::Validate(config));
alessiob3ec96df2017-05-22 06:57:06 -070074}
75
Alessio Bazzica0c83e152020-10-14 12:49:54 +020076TEST(GainController2, CheckFixedDigitalConfig) {
Alessio Bazzica38901042021-10-14 12:14:21 +020077 Agc2Config config;
Alessio Bazzica0c83e152020-10-14 12:49:54 +020078 // Attenuation is not allowed.
Alessio Bazzica6ee97342021-09-27 17:06:40 +020079 config.fixed_digital.gain_db = -5.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +020080 EXPECT_FALSE(GainController2::Validate(config));
81 // No gain is allowed.
Alessio Bazzica6ee97342021-09-27 17:06:40 +020082 config.fixed_digital.gain_db = 0.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +020083 EXPECT_TRUE(GainController2::Validate(config));
84 // Positive gain is allowed.
Alessio Bazzica6ee97342021-09-27 17:06:40 +020085 config.fixed_digital.gain_db = 15.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +020086 EXPECT_TRUE(GainController2::Validate(config));
87}
alessiob3ec96df2017-05-22 06:57:06 -070088
Alessio Bazzicaa850e6c2021-10-04 13:35:55 +020089TEST(GainController2, CheckHeadroomDb) {
Alessio Bazzica38901042021-10-14 12:14:21 +020090 Agc2Config config;
Alessio Bazzicaa850e6c2021-10-04 13:35:55 +020091 config.adaptive_digital.headroom_db = -1.0f;
92 EXPECT_FALSE(GainController2::Validate(config));
93 config.adaptive_digital.headroom_db = 0.0f;
94 EXPECT_TRUE(GainController2::Validate(config));
95 config.adaptive_digital.headroom_db = 5.0f;
96 EXPECT_TRUE(GainController2::Validate(config));
97}
98
99TEST(GainController2, CheckMaxGainDb) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200100 Agc2Config config;
Alessio Bazzicaa850e6c2021-10-04 13:35:55 +0200101 config.adaptive_digital.max_gain_db = -1.0f;
102 EXPECT_FALSE(GainController2::Validate(config));
103 config.adaptive_digital.max_gain_db = 0.0f;
104 EXPECT_FALSE(GainController2::Validate(config));
105 config.adaptive_digital.max_gain_db = 5.0f;
106 EXPECT_TRUE(GainController2::Validate(config));
107}
108
109TEST(GainController2, CheckInitialGainDb) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200110 Agc2Config config;
Alessio Bazzicaa850e6c2021-10-04 13:35:55 +0200111 config.adaptive_digital.initial_gain_db = -1.0f;
112 EXPECT_FALSE(GainController2::Validate(config));
113 config.adaptive_digital.initial_gain_db = 0.0f;
114 EXPECT_TRUE(GainController2::Validate(config));
115 config.adaptive_digital.initial_gain_db = 5.0f;
116 EXPECT_TRUE(GainController2::Validate(config));
117}
118
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200119TEST(GainController2, CheckAdaptiveDigitalMaxGainChangeSpeedConfig) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200120 Agc2Config config;
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200121 config.adaptive_digital.max_gain_change_db_per_second = -1.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200122 EXPECT_FALSE(GainController2::Validate(config));
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200123 config.adaptive_digital.max_gain_change_db_per_second = 0.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200124 EXPECT_FALSE(GainController2::Validate(config));
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200125 config.adaptive_digital.max_gain_change_db_per_second = 5.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200126 EXPECT_TRUE(GainController2::Validate(config));
127}
128
129TEST(GainController2, CheckAdaptiveDigitalMaxOutputNoiseLevelConfig) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200130 Agc2Config config;
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200131 config.adaptive_digital.max_output_noise_level_dbfs = 5.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200132 EXPECT_FALSE(GainController2::Validate(config));
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200133 config.adaptive_digital.max_output_noise_level_dbfs = 0.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200134 EXPECT_TRUE(GainController2::Validate(config));
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200135 config.adaptive_digital.max_output_noise_level_dbfs = -5.0f;
Alessio Bazzica0c83e152020-10-14 12:49:54 +0200136 EXPECT_TRUE(GainController2::Validate(config));
137}
138
139// Checks that the default config is applied.
140TEST(GainController2, ApplyDefaultConfig) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200141 auto gain_controller2 = std::make_unique<GainController2>(
Hanna Silen0c1ad292022-06-16 16:35:45 +0200142 Agc2Config{}, /*sample_rate_hz=*/16000, /*num_channels=*/2,
143 /*use_internal_vad=*/true);
Alessio Bazzica38901042021-10-14 12:14:21 +0200144 EXPECT_TRUE(gain_controller2.get());
alessiob3ec96df2017-05-22 06:57:06 -0700145}
146
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100147TEST(GainController2FixedDigital, GainShouldChangeOnSetGain) {
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200148 constexpr float kInputLevel = 1000.0f;
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100149 constexpr size_t kNumFrames = 5;
150 constexpr size_t kSampleRateHz = 8000;
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200151 constexpr float kGain0Db = 0.0f;
152 constexpr float kGain20Db = 20.0f;
Alessio Bazzica270f7b52017-10-13 11:05:17 +0200153
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100154 auto agc2_fixed = CreateAgc2FixedDigitalMode(kGain0Db, kSampleRateHz);
155
156 // Signal level is unchanged with 0 db gain.
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200157 EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel, kNumFrames,
158 kSampleRateHz),
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100159 kInputLevel);
160
161 // +20 db should increase signal by a factor of 10.
Alessio Bazzica38901042021-10-14 12:14:21 +0200162 agc2_fixed->SetFixedGainDb(kGain20Db);
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200163 EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel, kNumFrames,
164 kSampleRateHz),
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100165 kInputLevel * 10);
alessiob3ec96df2017-05-22 06:57:06 -0700166}
167
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100168TEST(GainController2FixedDigital, ChangeFixedGainShouldBeFastAndTimeInvariant) {
169 // Number of frames required for the fixed gain controller to adapt on the
170 // input signal when the gain changes.
171 constexpr size_t kNumFrames = 5;
Alex Loiko5e784612018-11-01 14:51:56 +0100172
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200173 constexpr float kInputLevel = 1000.0f;
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100174 constexpr size_t kSampleRateHz = 8000;
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200175 constexpr float kGainDbLow = 0.0f;
176 constexpr float kGainDbHigh = 25.0f;
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100177 static_assert(kGainDbLow < kGainDbHigh, "");
Alex Loiko5e784612018-11-01 14:51:56 +0100178
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100179 auto agc2_fixed = CreateAgc2FixedDigitalMode(kGainDbLow, kSampleRateHz);
180
181 // Start with a lower gain.
182 const float output_level_pre = RunAgc2WithConstantInput(
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200183 *agc2_fixed, kInputLevel, kNumFrames, kSampleRateHz);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100184
185 // Increase gain.
Alessio Bazzica38901042021-10-14 12:14:21 +0200186 agc2_fixed->SetFixedGainDb(kGainDbHigh);
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200187 static_cast<void>(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel,
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100188 kNumFrames, kSampleRateHz));
189
190 // Back to the lower gain.
Alessio Bazzica38901042021-10-14 12:14:21 +0200191 agc2_fixed->SetFixedGainDb(kGainDbLow);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100192 const float output_level_post = RunAgc2WithConstantInput(
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200193 *agc2_fixed, kInputLevel, kNumFrames, kSampleRateHz);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100194
195 EXPECT_EQ(output_level_pre, output_level_post);
196}
197
Alessio Bazzica38901042021-10-14 12:14:21 +0200198class FixedDigitalTest
199 : public ::testing::TestWithParam<std::tuple<float, float, int, bool>> {
200 protected:
201 float gain_db_min() const { return std::get<0>(GetParam()); }
202 float gain_db_max() const { return std::get<1>(GetParam()); }
203 int sample_rate_hz() const { return std::get<2>(GetParam()); }
204 bool saturation_expected() const { return std::get<3>(GetParam()); }
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100205};
206
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100207TEST_P(FixedDigitalTest, CheckSaturationBehaviorWithLimiter) {
Alessio Bazzica38901042021-10-14 12:14:21 +0200208 for (const float gain_db : test::LinSpace(gain_db_min(), gain_db_max(), 10)) {
209 SCOPED_TRACE(gain_db);
210 auto agc2_fixed = CreateAgc2FixedDigitalMode(gain_db, sample_rate_hz());
211 const float processed_sample =
212 RunAgc2WithConstantInput(*agc2_fixed, /*input_level=*/32767.0f,
213 /*num_frames=*/5, sample_rate_hz());
214 if (saturation_expected()) {
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200215 EXPECT_FLOAT_EQ(processed_sample, 32767.0f);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100216 } else {
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200217 EXPECT_LT(processed_sample, 32767.0f);
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100218 }
Alex Loiko5e784612018-11-01 14:51:56 +0100219 }
Alex Loiko5e784612018-11-01 14:51:56 +0100220}
221
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100222static_assert(test::kLimiterMaxInputLevelDbFs < 10, "");
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100223INSTANTIATE_TEST_SUITE_P(
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100224 GainController2,
225 FixedDigitalTest,
226 ::testing::Values(
Artem Titovcfea2182021-08-10 01:22:31 +0200227 // When gain < `test::kLimiterMaxInputLevelDbFs`, the limiter will not
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100228 // saturate the signal (at any sample rate).
Alessio Bazzica38901042021-10-14 12:14:21 +0200229 std::make_tuple(0.1f,
230 test::kLimiterMaxInputLevelDbFs - 0.01f,
231 8000,
232 false),
233 std::make_tuple(0.1,
234 test::kLimiterMaxInputLevelDbFs - 0.01f,
235 48000,
236 false),
Artem Titovcfea2182021-08-10 01:22:31 +0200237 // When gain > `test::kLimiterMaxInputLevelDbFs`, the limiter will
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100238 // saturate the signal (at any sample rate).
Alessio Bazzica38901042021-10-14 12:14:21 +0200239 std::make_tuple(test::kLimiterMaxInputLevelDbFs + 0.01f,
240 10.0f,
241 8000,
242 true),
243 std::make_tuple(test::kLimiterMaxInputLevelDbFs + 0.01f,
244 10.0f,
245 48000,
246 true)));
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100247
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200248// Processes a test audio file and checks that the gain applied at the end of
249// the recording is close to the expected value.
250TEST(GainController2, CheckFinalGainWithAdaptiveDigitalController) {
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200251 constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
252 constexpr int kStereo = 2;
Alessio Bazzica38901042021-10-14 12:14:21 +0200253
254 // Create AGC2 enabling only the adaptive digital controller.
255 Agc2Config config;
256 config.fixed_digital.gain_db = 0.0f;
257 config.adaptive_digital.enabled = true;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200258 GainController2 agc2(config, kSampleRateHz, kStereo,
259 /*use_internal_vad=*/true);
Alessio Bazzica38901042021-10-14 12:14:21 +0200260
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200261 test::InputAudioFile input_file(
262 test::GetApmCaptureTestVectorFileName(kSampleRateHz),
263 /*loop_at_end=*/true);
Henrik Lundin64253a92022-02-04 09:02:48 +0000264 const StreamConfig stream_config(kSampleRateHz, kStereo);
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200265
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200266 // Init buffers.
267 constexpr int kFrameDurationMs = 10;
268 std::vector<float> frame(kStereo * stream_config.num_frames());
269 AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
270 kSampleRateHz, kStereo);
271
272 // Simulate.
273 constexpr float kGainDb = -6.0f;
274 const float gain = std::pow(10.0f, kGainDb / 20.0f);
275 constexpr int kDurationMs = 10000;
276 constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
277 for (int i = 0; i < kNumFramesToProcess; ++i) {
278 ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
279 stream_config.num_channels(), &input_file,
280 frame);
281 // Apply a fixed gain to the input audio.
Hanna Silen0c1ad292022-06-16 16:35:45 +0200282 for (float& x : frame) {
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200283 x *= gain;
Hanna Silen0c1ad292022-06-16 16:35:45 +0200284 }
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200285 test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
Hanna Silen0c1ad292022-06-16 16:35:45 +0200286 agc2.Process(/*speech_probability=*/absl::nullopt, &audio_buffer);
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200287 }
288
289 // Estimate the applied gain by processing a probing frame.
290 SetAudioBufferSamples(/*value=*/1.0f, audio_buffer);
Hanna Silen0c1ad292022-06-16 16:35:45 +0200291 agc2.Process(/*speech_probability=*/absl::nullopt, &audio_buffer);
Alessio Bazzica6ee97342021-09-27 17:06:40 +0200292 const float applied_gain_db =
293 20.0f * std::log10(audio_buffer.channels_const()[0][0]);
294
295 constexpr float kExpectedGainDb = 5.6f;
296 constexpr float kToleranceDb = 0.3f;
297 EXPECT_NEAR(applied_gain_db, kExpectedGainDb, kToleranceDb);
Alex Loiko5e784612018-11-01 14:51:56 +0100298}
Alessio Bazzica3e4c77f2018-11-01 21:31:38 +0100299
Hanna Silen0c1ad292022-06-16 16:35:45 +0200300// Processes a test audio file and checks that the injected speech probability
301// is ignored when the internal VAD is used.
302TEST(GainController2,
303 CheckInjectedVadProbabilityNotUsedWithAdaptiveDigitalController) {
304 constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
305 constexpr int kStereo = 2;
306
307 // Create AGC2 enabling only the adaptive digital controller.
308 Agc2Config config;
309 config.fixed_digital.gain_db = 0.0f;
310 config.adaptive_digital.enabled = true;
311 GainController2 agc2(config, kSampleRateHz, kStereo,
312 /*use_internal_vad=*/true);
313 GainController2 agc2_reference(config, kSampleRateHz, kStereo,
314 /*use_internal_vad=*/true);
315
316 test::InputAudioFile input_file(
317 test::GetApmCaptureTestVectorFileName(kSampleRateHz),
318 /*loop_at_end=*/true);
319 const StreamConfig stream_config(kSampleRateHz, kStereo);
320
321 // Init buffers.
322 constexpr int kFrameDurationMs = 10;
323 std::vector<float> frame(kStereo * stream_config.num_frames());
324 AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
325 kSampleRateHz, kStereo);
326 AudioBuffer audio_buffer_reference(kSampleRateHz, kStereo, kSampleRateHz,
327 kStereo, kSampleRateHz, kStereo);
328
329 // Simulate.
330 constexpr float kGainDb = -6.0f;
331 const float gain = std::pow(10.0f, kGainDb / 20.0f);
332 constexpr int kDurationMs = 10000;
333 constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
334 constexpr float kSpeechProbabilities[] = {1.0f, 0.3f};
335 constexpr float kEpsilon = 0.0001f;
336 bool all_samples_zero = true;
337 for (int i = 0, j = 0; i < kNumFramesToProcess; ++i, j = 1 - j) {
338 ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
339 stream_config.num_channels(), &input_file,
340 frame);
341 // Apply a fixed gain to the input audio.
342 for (float& x : frame) {
343 x *= gain;
344 }
345 test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
346 agc2.Process(kSpeechProbabilities[j], &audio_buffer);
347 test::CopyVectorToAudioBuffer(stream_config, frame,
348 &audio_buffer_reference);
349 agc2_reference.Process(absl::nullopt, &audio_buffer_reference);
350
351 // Check the output buffers.
352 for (int i = 0; i < kStereo; ++i) {
353 for (int j = 0; j < static_cast<int>(audio_buffer.num_frames()); ++j) {
354 all_samples_zero &=
355 fabs(audio_buffer.channels_const()[i][j]) < kEpsilon;
356 EXPECT_FLOAT_EQ(audio_buffer.channels_const()[i][j],
357 audio_buffer_reference.channels_const()[i][j]);
358 }
359 }
360 }
361 EXPECT_FALSE(all_samples_zero);
362}
363
364// Processes a test audio file and checks that the injected speech probability
365// is not ignored when the internal VAD is not used.
366TEST(GainController2,
367 CheckInjectedVadProbabilityUsedWithAdaptiveDigitalController) {
368 constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
369 constexpr int kStereo = 2;
370
371 // Create AGC2 enabling only the adaptive digital controller.
372 Agc2Config config;
373 config.fixed_digital.gain_db = 0.0f;
374 config.adaptive_digital.enabled = true;
375 GainController2 agc2(config, kSampleRateHz, kStereo,
376 /*use_internal_vad=*/false);
377 GainController2 agc2_reference(config, kSampleRateHz, kStereo,
378 /*use_internal_vad=*/true);
379
380 test::InputAudioFile input_file(
381 test::GetApmCaptureTestVectorFileName(kSampleRateHz),
382 /*loop_at_end=*/true);
383 const StreamConfig stream_config(kSampleRateHz, kStereo);
384
385 // Init buffers.
386 constexpr int kFrameDurationMs = 10;
387 std::vector<float> frame(kStereo * stream_config.num_frames());
388 AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
389 kSampleRateHz, kStereo);
390 AudioBuffer audio_buffer_reference(kSampleRateHz, kStereo, kSampleRateHz,
391 kStereo, kSampleRateHz, kStereo);
392 // Simulate.
393 constexpr float kGainDb = -6.0f;
394 const float gain = std::pow(10.0f, kGainDb / 20.0f);
395 constexpr int kDurationMs = 10000;
396 constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
397 constexpr float kSpeechProbabilities[] = {1.0f, 0.3f};
398 constexpr float kEpsilon = 0.0001f;
399 bool all_samples_zero = true;
400 bool all_samples_equal = true;
401 for (int i = 0, j = 0; i < kNumFramesToProcess; ++i, j = 1 - j) {
402 ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
403 stream_config.num_channels(), &input_file,
404 frame);
405 // Apply a fixed gain to the input audio.
406 for (float& x : frame) {
407 x *= gain;
408 }
409 test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
410 agc2.Process(kSpeechProbabilities[j], &audio_buffer);
411 test::CopyVectorToAudioBuffer(stream_config, frame,
412 &audio_buffer_reference);
413 agc2_reference.Process(absl::nullopt, &audio_buffer_reference);
414 // Check the output buffers.
415 for (int i = 0; i < kStereo; ++i) {
416 for (int j = 0; j < static_cast<int>(audio_buffer.num_frames()); ++j) {
417 all_samples_zero &=
418 fabs(audio_buffer.channels_const()[i][j]) < kEpsilon;
419 all_samples_equal &=
420 fabs(audio_buffer.channels_const()[i][j] -
421 audio_buffer_reference.channels_const()[i][j]) < kEpsilon;
422 }
423 }
424 }
425 EXPECT_FALSE(all_samples_zero);
426 EXPECT_FALSE(all_samples_equal);
427}
428
429// Processes a test audio file and checks that the output is equal when
430// an injected speech probability from `VoiceActivityDetectorWrapper` and
431// the speech probability computed by the internal VAD are the same.
432TEST(GainController2,
433 CheckEqualResultFromInjectedVadProbabilityWithAdaptiveDigitalController) {
434 constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
435 constexpr int kStereo = 2;
436
437 // Create AGC2 enabling only the adaptive digital controller.
438 Agc2Config config;
439 config.fixed_digital.gain_db = 0.0f;
440 config.adaptive_digital.enabled = true;
441 GainController2 agc2(config, kSampleRateHz, kStereo,
442 /*use_internal_vad=*/false);
443 GainController2 agc2_reference(config, kSampleRateHz, kStereo,
444 /*use_internal_vad=*/true);
445 VoiceActivityDetectorWrapper vad(config.adaptive_digital.vad_reset_period_ms,
446 GetAvailableCpuFeatures(), kSampleRateHz);
447 test::InputAudioFile input_file(
448 test::GetApmCaptureTestVectorFileName(kSampleRateHz),
449 /*loop_at_end=*/true);
450 const StreamConfig stream_config(kSampleRateHz, kStereo);
451
452 // Init buffers.
453 constexpr int kFrameDurationMs = 10;
454 std::vector<float> frame(kStereo * stream_config.num_frames());
455 AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
456 kSampleRateHz, kStereo);
457 AudioBuffer audio_buffer_reference(kSampleRateHz, kStereo, kSampleRateHz,
458 kStereo, kSampleRateHz, kStereo);
459
460 // Simulate.
461 constexpr float kGainDb = -6.0f;
462 const float gain = std::pow(10.0f, kGainDb / 20.0f);
463 constexpr int kDurationMs = 10000;
464 constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
465 for (int i = 0; i < kNumFramesToProcess; ++i) {
466 ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
467 stream_config.num_channels(), &input_file,
468 frame);
469 // Apply a fixed gain to the input audio.
470 for (float& x : frame) {
471 x *= gain;
472 }
473 test::CopyVectorToAudioBuffer(stream_config, frame,
474 &audio_buffer_reference);
475 agc2_reference.Process(absl::nullopt, &audio_buffer_reference);
476 test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
477 agc2.Process(vad.Analyze(AudioFrameView<const float>(
478 audio_buffer.channels(), audio_buffer.num_channels(),
479 audio_buffer.num_frames())),
480 &audio_buffer);
481 // Check the output buffer.
482 for (int i = 0; i < kStereo; ++i) {
483 for (int j = 0; j < static_cast<int>(audio_buffer.num_frames()); ++j) {
484 EXPECT_FLOAT_EQ(audio_buffer.channels_const()[i][j],
485 audio_buffer_reference.channels_const()[i][j]);
486 }
487 }
488 }
489}
490
alessiob3ec96df2017-05-22 06:57:06 -0700491} // namespace test
492} // namespace webrtc