blob: 9336fd768f6a04bb64b4b07c65c0b1b2ff71e699 [file] [log] [blame]
/*
* 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/fixed_gain_controller.h"
#include "api/array_view.h"
#include "modules/audio_processing/agc2/vector_float_frame.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/gunit.h"
namespace webrtc {
namespace {
constexpr float kInputLevelLinear = 15000.f;
constexpr float kGainToApplyDb = 15.f;
float RunFixedGainControllerWithConstantInput(FixedGainController* fixed_gc,
const float input_level,
const size_t num_frames,
const int sample_rate) {
// Give time to the level etimator to converge.
for (size_t i = 0; i < num_frames; ++i) {
VectorFloatFrame vectors_with_float_frame(
1, rtc::CheckedDivExact(sample_rate, 100), input_level);
fixed_gc->Process(vectors_with_float_frame.float_frame_view());
}
// Process the last frame with constant input level.
VectorFloatFrame vectors_with_float_frame_last(
1, rtc::CheckedDivExact(sample_rate, 100), input_level);
fixed_gc->Process(vectors_with_float_frame_last.float_frame_view());
// Return the last sample from the last processed frame.
const auto channel =
vectors_with_float_frame_last.float_frame_view().channel(0);
return channel[channel.size() - 1];
}
ApmDataDumper test_data_dumper(0);
FixedGainController CreateFixedGainController(float gain_to_apply,
size_t rate,
bool enable_limiter) {
FixedGainController fgc(&test_data_dumper);
fgc.SetGain(gain_to_apply);
fgc.SetSampleRate(gain_to_apply);
fgc.EnableLimiter(enable_limiter);
return fgc;
}
} // namespace
TEST(AutomaticGainController2FixedDigital, CreateUseWithoutLimiter) {
const int kSampleRate = 48000;
FixedGainController fixed_gc =
CreateFixedGainController(kGainToApplyDb, kSampleRate, false);
VectorFloatFrame vectors_with_float_frame(
1, rtc::CheckedDivExact(kSampleRate, 100), kInputLevelLinear);
auto float_frame = vectors_with_float_frame.float_frame_view();
fixed_gc.Process(float_frame);
const auto channel = float_frame.channel(0);
EXPECT_LT(kInputLevelLinear, channel[0]);
}
TEST(AutomaticGainController2FixedDigital, CreateUseWithLimiter) {
const int kSampleRate = 44000;
FixedGainController fixed_gc =
CreateFixedGainController(kGainToApplyDb, kSampleRate, true);
VectorFloatFrame vectors_with_float_frame(
1, rtc::CheckedDivExact(kSampleRate, 100), kInputLevelLinear);
auto float_frame = vectors_with_float_frame.float_frame_view();
fixed_gc.Process(float_frame);
const auto channel = float_frame.channel(0);
EXPECT_LT(kInputLevelLinear, channel[0]);
}
TEST(AutomaticGainController2FixedDigital, GainShouldChangeOnSetGain) {
constexpr float input_level = 1000.f;
constexpr size_t num_frames = 5;
constexpr size_t kSampleRate = 8000;
constexpr float gain_db_no_change = 0.f;
constexpr float gain_db_factor_10 = 20.f;
FixedGainController fixed_gc_no_saturation =
CreateFixedGainController(gain_db_no_change, kSampleRate, false);
// Signal level is unchanged with 0 db gain.
EXPECT_FLOAT_EQ(
RunFixedGainControllerWithConstantInput(
&fixed_gc_no_saturation, input_level, num_frames, kSampleRate),
input_level);
fixed_gc_no_saturation.SetGain(gain_db_factor_10);
// +20db should increase signal by a factor of 10.
EXPECT_FLOAT_EQ(
RunFixedGainControllerWithConstantInput(
&fixed_gc_no_saturation, input_level, num_frames, kSampleRate),
input_level * 10);
}
} // namespace webrtc