mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 14:50:39 +01:00

This CL was generated by running git ls-files | grep -P "(\.h|\.cc)$" | grep -v 'sdk/' | grep -v 'rtc_base/ssl_' | \ grep -v 'fake_rtc_certificate_generator.h' | grep -v 'modules/audio_device/win/' | \ grep -v 'system_wrappers/source/clock.cc' | grep -v 'rtc_base/trace_event.h' | \ grep -v 'modules/audio_coding/codecs/ilbc/' | grep -v 'screen_capturer_mac.h' | \ grep -v 'spl_inl_mips.h' | grep -v 'data_size_unittest.cc' | grep -v 'timestamp_unittest.cc' \ | xargs clang-format -i ; git cl format Most of these changes are clang-format grouping and reordering includes differently. Bug: webrtc:9340 Change-Id: Ic83ddbc169bfacd21883e381b5181c3dd4fe8a63 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144051 Commit-Queue: Jonas Olsson <jonasolsson@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28505}
205 lines
7.3 KiB
C++
205 lines
7.3 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "modules/audio_processing/agc2/interpolated_gain_curve.h"
|
|
|
|
#include <array>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#include "api/array_view.h"
|
|
#include "common_audio/include/audio_util.h"
|
|
#include "modules/audio_processing/agc2/agc2_common.h"
|
|
#include "modules/audio_processing/agc2/compute_interpolated_gain_curve.h"
|
|
#include "modules/audio_processing/agc2/limiter_db_gain_curve.h"
|
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/gunit.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
constexpr double kLevelEpsilon = 1e-2 * kMaxAbsFloatS16Value;
|
|
constexpr float kInterpolatedGainCurveTolerance = 1.f / 32768.f;
|
|
ApmDataDumper apm_data_dumper(0);
|
|
static_assert(std::is_trivially_destructible<LimiterDbGainCurve>::value, "");
|
|
const LimiterDbGainCurve limiter;
|
|
|
|
} // namespace
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CreateUse) {
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
kLevelEpsilon, DbfsToFloatS16(limiter.max_input_level_db() + 1), 500);
|
|
for (const auto level : levels) {
|
|
EXPECT_GE(igc.LookUpGainToApply(level), 0.0f);
|
|
}
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckValidOutput) {
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
kLevelEpsilon, limiter.max_input_level_linear() * 2.0, 500);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
const float gain = igc.LookUpGainToApply(level);
|
|
EXPECT_LE(0.0f, gain);
|
|
EXPECT_LE(gain, 1.0f);
|
|
}
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckMonotonicity) {
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
kLevelEpsilon, limiter.max_input_level_linear() + kLevelEpsilon + 0.5,
|
|
500);
|
|
float prev_gain = igc.LookUpGainToApply(0.0f);
|
|
for (const auto level : levels) {
|
|
const float gain = igc.LookUpGainToApply(level);
|
|
EXPECT_GE(prev_gain, gain);
|
|
prev_gain = gain;
|
|
}
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckApproximation) {
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
kLevelEpsilon, limiter.max_input_level_linear() - kLevelEpsilon, 500);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
EXPECT_LT(
|
|
std::fabs(limiter.GetGainLinear(level) - igc.LookUpGainToApply(level)),
|
|
kInterpolatedGainCurveTolerance);
|
|
}
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckRegionBoundaries) {
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const std::vector<double> levels{
|
|
{kLevelEpsilon, limiter.knee_start_linear() + kLevelEpsilon,
|
|
limiter.limiter_start_linear() + kLevelEpsilon,
|
|
limiter.max_input_level_linear() + kLevelEpsilon}};
|
|
for (const auto level : levels) {
|
|
igc.LookUpGainToApply(level);
|
|
}
|
|
|
|
const auto stats = igc.get_stats();
|
|
EXPECT_EQ(1ul, stats.look_ups_identity_region);
|
|
EXPECT_EQ(1ul, stats.look_ups_knee_region);
|
|
EXPECT_EQ(1ul, stats.look_ups_limiter_region);
|
|
EXPECT_EQ(1ul, stats.look_ups_saturation_region);
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckIdentityRegion) {
|
|
constexpr size_t kNumSteps = 10;
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels =
|
|
test::LinSpace(kLevelEpsilon, limiter.knee_start_linear(), kNumSteps);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
EXPECT_EQ(1.0f, igc.LookUpGainToApply(level));
|
|
}
|
|
|
|
const auto stats = igc.get_stats();
|
|
EXPECT_EQ(kNumSteps - 1, stats.look_ups_identity_region);
|
|
EXPECT_EQ(1ul, stats.look_ups_knee_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_limiter_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_saturation_region);
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve,
|
|
CheckNoOverApproximationKnee) {
|
|
constexpr size_t kNumSteps = 10;
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels =
|
|
test::LinSpace(limiter.knee_start_linear() + kLevelEpsilon,
|
|
limiter.limiter_start_linear(), kNumSteps);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
// Small tolerance added (needed because comparing a float with a double).
|
|
EXPECT_LE(igc.LookUpGainToApply(level),
|
|
limiter.GetGainLinear(level) + 1e-7);
|
|
}
|
|
|
|
const auto stats = igc.get_stats();
|
|
EXPECT_EQ(0ul, stats.look_ups_identity_region);
|
|
EXPECT_EQ(kNumSteps - 1, stats.look_ups_knee_region);
|
|
EXPECT_EQ(1ul, stats.look_ups_limiter_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_saturation_region);
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve,
|
|
CheckNoOverApproximationBeyondKnee) {
|
|
constexpr size_t kNumSteps = 10;
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
limiter.limiter_start_linear() + kLevelEpsilon,
|
|
limiter.max_input_level_linear() - kLevelEpsilon, kNumSteps);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
// Small tolerance added (needed because comparing a float with a double).
|
|
EXPECT_LE(igc.LookUpGainToApply(level),
|
|
limiter.GetGainLinear(level) + 1e-7);
|
|
}
|
|
|
|
const auto stats = igc.get_stats();
|
|
EXPECT_EQ(0ul, stats.look_ups_identity_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_knee_region);
|
|
EXPECT_EQ(kNumSteps, stats.look_ups_limiter_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_saturation_region);
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve,
|
|
CheckNoOverApproximationWithSaturation) {
|
|
constexpr size_t kNumSteps = 3;
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
const auto levels = test::LinSpace(
|
|
limiter.max_input_level_linear() + kLevelEpsilon,
|
|
limiter.max_input_level_linear() + kLevelEpsilon + 0.5, kNumSteps);
|
|
for (const auto level : levels) {
|
|
SCOPED_TRACE(std::to_string(level));
|
|
EXPECT_LE(igc.LookUpGainToApply(level), limiter.GetGainLinear(level));
|
|
}
|
|
|
|
const auto stats = igc.get_stats();
|
|
EXPECT_EQ(0ul, stats.look_ups_identity_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_knee_region);
|
|
EXPECT_EQ(0ul, stats.look_ups_limiter_region);
|
|
EXPECT_EQ(kNumSteps, stats.look_ups_saturation_region);
|
|
}
|
|
|
|
TEST(AutomaticGainController2InterpolatedGainCurve, CheckApproximationParams) {
|
|
test::InterpolatedParameters parameters =
|
|
test::ComputeInterpolatedGainCurveApproximationParams();
|
|
|
|
InterpolatedGainCurve igc(&apm_data_dumper, "");
|
|
|
|
for (size_t i = 0; i < kInterpolatedGainCurveTotalPoints; ++i) {
|
|
// The tolerance levels are chosen to account for deviations due
|
|
// to computing with single precision floating point numbers.
|
|
EXPECT_NEAR(igc.approximation_params_x_[i],
|
|
parameters.computed_approximation_params_x[i], 0.9f);
|
|
EXPECT_NEAR(igc.approximation_params_m_[i],
|
|
parameters.computed_approximation_params_m[i], 0.00001f);
|
|
EXPECT_NEAR(igc.approximation_params_q_[i],
|
|
parameters.computed_approximation_params_q[i], 0.001f);
|
|
}
|
|
}
|
|
|
|
} // namespace webrtc
|