xref: /aosp_15_r20/external/webrtc/modules/audio_processing/agc2/noise_level_estimator_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/agc2/noise_level_estimator.h"
12 
13 #include <array>
14 #include <cmath>
15 #include <functional>
16 #include <limits>
17 
18 #include "api/function_view.h"
19 #include "modules/audio_processing/agc2/agc2_testing_common.h"
20 #include "modules/audio_processing/agc2/vector_float_frame.h"
21 #include "modules/audio_processing/logging/apm_data_dumper.h"
22 #include "rtc_base/gunit.h"
23 
24 namespace webrtc {
25 namespace {
26 
27 constexpr int kNumIterations = 200;
28 constexpr int kFramesPerSecond = 100;
29 
30 // Runs the noise estimator on audio generated by 'sample_generator'
31 // for kNumIterations. Returns the last noise level estimate.
RunEstimator(rtc::FunctionView<float ()> sample_generator,NoiseLevelEstimator & estimator,int sample_rate_hz)32 float RunEstimator(rtc::FunctionView<float()> sample_generator,
33                    NoiseLevelEstimator& estimator,
34                    int sample_rate_hz) {
35   const int samples_per_channel =
36       rtc::CheckedDivExact(sample_rate_hz, kFramesPerSecond);
37   VectorFloatFrame signal(1, samples_per_channel, 0.0f);
38   for (int i = 0; i < kNumIterations; ++i) {
39     AudioFrameView<float> frame_view = signal.float_frame_view();
40     for (int j = 0; j < samples_per_channel; ++j) {
41       frame_view.channel(0)[j] = sample_generator();
42     }
43     estimator.Analyze(frame_view);
44   }
45   return estimator.Analyze(signal.float_frame_view());
46 }
47 
48 class NoiseEstimatorParametrization : public ::testing::TestWithParam<int> {
49  protected:
sample_rate_hz() const50   int sample_rate_hz() const { return GetParam(); }
51 };
52 
53 // Checks that full scale white noise maps to about -5.5 dBFS.
TEST_P(NoiseEstimatorParametrization,NoiseFloorEstimatorWithRandomNoise)54 TEST_P(NoiseEstimatorParametrization, NoiseFloorEstimatorWithRandomNoise) {
55   ApmDataDumper data_dumper(0);
56   auto estimator = CreateNoiseFloorEstimator(&data_dumper);
57 
58   test::WhiteNoiseGenerator gen(/*min_amplitude=*/test::kMinS16,
59                                 /*max_amplitude=*/test::kMaxS16);
60   const float noise_level_dbfs =
61       RunEstimator(gen, *estimator, sample_rate_hz());
62   EXPECT_NEAR(noise_level_dbfs, -5.5f, 0.5f);
63 }
64 
65 // Checks that a full scale sine wave maps to about -3 dBFS.
TEST_P(NoiseEstimatorParametrization,NoiseFloorEstimatorWithSineTone)66 TEST_P(NoiseEstimatorParametrization, NoiseFloorEstimatorWithSineTone) {
67   ApmDataDumper data_dumper(0);
68   auto estimator = CreateNoiseFloorEstimator(&data_dumper);
69 
70   test::SineGenerator gen(/*amplitude=*/test::kMaxS16, /*frequency_hz=*/600.0f,
71                           sample_rate_hz());
72   const float noise_level_dbfs =
73       RunEstimator(gen, *estimator, sample_rate_hz());
74   EXPECT_NEAR(noise_level_dbfs, -3.0f, 0.1f);
75 }
76 
77 // Check that sufficiently spaced periodic pulses do not raise the estimated
78 // noise floor, which is determined by the amplitude of the non-pulse samples.
TEST_P(NoiseEstimatorParametrization,NoiseFloorEstimatorWithPulseTone)79 TEST_P(NoiseEstimatorParametrization, NoiseFloorEstimatorWithPulseTone) {
80   ApmDataDumper data_dumper(0);
81   auto estimator = CreateNoiseFloorEstimator(&data_dumper);
82 
83   constexpr float kNoPulseAmplitude = 10.0f;
84   test::PulseGenerator gen(/*pulse_amplitude=*/test::kMaxS16, kNoPulseAmplitude,
85                            /*frequency_hz=*/20.0f, sample_rate_hz());
86   const float noise_level_dbfs =
87       RunEstimator(gen, *estimator, sample_rate_hz());
88   const float expected_noise_floor_dbfs =
89       20.0f * std::log10f(kNoPulseAmplitude / test::kMaxS16);
90   EXPECT_NEAR(noise_level_dbfs, expected_noise_floor_dbfs, 0.5f);
91 }
92 
93 INSTANTIATE_TEST_SUITE_P(GainController2NoiseEstimator,
94                          NoiseEstimatorParametrization,
95                          ::testing::Values(8000, 16000, 32000, 48000));
96 
97 }  // namespace
98 }  // namespace webrtc
99