mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-18 08:07:56 +01:00

The FixedGainController (FGC) applies a fixed gain. It will also control the limiter. The limiter will be landed over the next several CLs. The GainController2 is a 'private submodule' of APM. It will control the new automatic gain controller (AGC). It controls the AGC through Initialize() and ApplyConfig(). This CL contains * build changes to make modules/audio_processing/agc2 an independent target * a new MutableFloatAudioFrame which is the audio interface between AGC2 and APM * move of the fixed gain application from GainController2 to FixedGainController. If you are a googler, there is more information in this doc: https://docs.google.com/document/d/1RV2Doet3MZtUPAHVva61Vjo20iyd1bmmm3aR8znWpzo/edit# Bug: webrtc:7949 Change-Id: Ief95cbbce83c3aafe54638fd2ab881c9fb8bdc3a Reviewed-on: https://webrtc-review.googlesource.com/50440 Commit-Queue: Alex Loiko <aleloi@webrtc.org> Reviewed-by: Oskar Sundbom <ossu@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22046}
109 lines
4 KiB
C++
109 lines
4 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/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
|