Activate the pre-amplifier in AudioProcessing.
It's a module for applying a gain to the capture signal. The gain is the first processing step in APM. After this CL, these two features work: * The PreAmplifier can be activated with AudioProcessing::Config::pre_amplifier * The PreApmlifier can be controlled after APM creation by AudioProcessing::SetRuntimeSetting. What's left is a change to AecDumps and to AecDump-replay. NOTRY=True # 1-line change, tests just passed. Bug: webrtc:9138 Change-Id: I85b3af511695b0a9cec2eed6fee7f05080305e1d Reviewed-on: https://webrtc-review.googlesource.com/69811 Commit-Queue: Alex Loiko <aleloi@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22881}
This commit is contained in:
@ -143,6 +143,7 @@ rtc_static_library("audio_processing") {
|
|||||||
"../../system_wrappers:metrics_api",
|
"../../system_wrappers:metrics_api",
|
||||||
"agc2:adaptive_digital",
|
"agc2:adaptive_digital",
|
||||||
"agc2:fixed_digital",
|
"agc2:fixed_digital",
|
||||||
|
"agc2:gain_applier",
|
||||||
"vad",
|
"vad",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "common_audio/signal_processing/include/signal_processing_library.h"
|
#include "common_audio/signal_processing/include/signal_processing_library.h"
|
||||||
#include "modules/audio_processing/aec/aec_core.h"
|
#include "modules/audio_processing/aec/aec_core.h"
|
||||||
#include "modules/audio_processing/agc/agc_manager_direct.h"
|
#include "modules/audio_processing/agc/agc_manager_direct.h"
|
||||||
|
#include "modules/audio_processing/agc2/gain_applier.h"
|
||||||
#include "modules/audio_processing/audio_buffer.h"
|
#include "modules/audio_processing/audio_buffer.h"
|
||||||
#include "modules/audio_processing/beamformer/nonlinear_beamformer.h"
|
#include "modules/audio_processing/beamformer/nonlinear_beamformer.h"
|
||||||
#include "modules/audio_processing/common.h"
|
#include "modules/audio_processing/common.h"
|
||||||
@ -186,6 +187,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
|
|||||||
bool beamformer_enabled,
|
bool beamformer_enabled,
|
||||||
bool adaptive_gain_controller_enabled,
|
bool adaptive_gain_controller_enabled,
|
||||||
bool gain_controller2_enabled,
|
bool gain_controller2_enabled,
|
||||||
|
bool pre_amplifier_enabled,
|
||||||
bool echo_controller_enabled,
|
bool echo_controller_enabled,
|
||||||
bool voice_activity_detector_enabled,
|
bool voice_activity_detector_enabled,
|
||||||
bool level_estimator_enabled,
|
bool level_estimator_enabled,
|
||||||
@ -205,6 +207,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
|
|||||||
(adaptive_gain_controller_enabled != adaptive_gain_controller_enabled_);
|
(adaptive_gain_controller_enabled != adaptive_gain_controller_enabled_);
|
||||||
changed |=
|
changed |=
|
||||||
(gain_controller2_enabled != gain_controller2_enabled_);
|
(gain_controller2_enabled != gain_controller2_enabled_);
|
||||||
|
changed |= (pre_amplifier_enabled_ != pre_amplifier_enabled);
|
||||||
changed |= (echo_controller_enabled != echo_controller_enabled_);
|
changed |= (echo_controller_enabled != echo_controller_enabled_);
|
||||||
changed |= (level_estimator_enabled != level_estimator_enabled_);
|
changed |= (level_estimator_enabled != level_estimator_enabled_);
|
||||||
changed |=
|
changed |=
|
||||||
@ -220,6 +223,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
|
|||||||
beamformer_enabled_ = beamformer_enabled;
|
beamformer_enabled_ = beamformer_enabled;
|
||||||
adaptive_gain_controller_enabled_ = adaptive_gain_controller_enabled;
|
adaptive_gain_controller_enabled_ = adaptive_gain_controller_enabled;
|
||||||
gain_controller2_enabled_ = gain_controller2_enabled;
|
gain_controller2_enabled_ = gain_controller2_enabled;
|
||||||
|
pre_amplifier_enabled_ = pre_amplifier_enabled;
|
||||||
echo_controller_enabled_ = echo_controller_enabled;
|
echo_controller_enabled_ = echo_controller_enabled;
|
||||||
level_estimator_enabled_ = level_estimator_enabled;
|
level_estimator_enabled_ = level_estimator_enabled;
|
||||||
voice_activity_detector_enabled_ = voice_activity_detector_enabled;
|
voice_activity_detector_enabled_ = voice_activity_detector_enabled;
|
||||||
@ -251,7 +255,8 @@ bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive()
|
|||||||
|
|
||||||
bool AudioProcessingImpl::ApmSubmoduleStates::CaptureFullBandProcessingActive()
|
bool AudioProcessingImpl::ApmSubmoduleStates::CaptureFullBandProcessingActive()
|
||||||
const {
|
const {
|
||||||
return gain_controller2_enabled_ || capture_post_processor_enabled_;
|
return gain_controller2_enabled_ || capture_post_processor_enabled_ ||
|
||||||
|
pre_amplifier_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandSubModulesActive()
|
bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandSubModulesActive()
|
||||||
@ -312,6 +317,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules {
|
|||||||
std::unique_ptr<EchoControl> echo_controller;
|
std::unique_ptr<EchoControl> echo_controller;
|
||||||
std::unique_ptr<CustomProcessing> capture_post_processor;
|
std::unique_ptr<CustomProcessing> capture_post_processor;
|
||||||
std::unique_ptr<CustomProcessing> render_pre_processor;
|
std::unique_ptr<CustomProcessing> render_pre_processor;
|
||||||
|
std::unique_ptr<GainApplier> pre_amplifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioProcessingBuilder::AudioProcessingBuilder() = default;
|
AudioProcessingBuilder::AudioProcessingBuilder() = default;
|
||||||
@ -714,6 +720,7 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
|
|||||||
config_.gain_controller2 = AudioProcessing::Config::GainController2();
|
config_.gain_controller2 = AudioProcessing::Config::GainController2();
|
||||||
}
|
}
|
||||||
InitializeGainController2();
|
InitializeGainController2();
|
||||||
|
InitializePreAmplifier();
|
||||||
private_submodules_->gain_controller2->ApplyConfig(config_.gain_controller2);
|
private_submodules_->gain_controller2->ApplyConfig(config_.gain_controller2);
|
||||||
RTC_LOG(LS_INFO) << "Gain Controller 2 activated: "
|
RTC_LOG(LS_INFO) << "Gain Controller 2 activated: "
|
||||||
<< config_.gain_controller2.enabled;
|
<< config_.gain_controller2.enabled;
|
||||||
@ -913,8 +920,12 @@ void AudioProcessingImpl::HandleRuntimeSettings() {
|
|||||||
RTC_DCHECK(setting.type() != RuntimeSetting::Type::kNotSpecified);
|
RTC_DCHECK(setting.type() != RuntimeSetting::Type::kNotSpecified);
|
||||||
switch (setting.type()) {
|
switch (setting.type()) {
|
||||||
case RuntimeSetting::Type::kCapturePreGain:
|
case RuntimeSetting::Type::kCapturePreGain:
|
||||||
// TODO(bugs.chromium.org/9138): Notify
|
if (config_.pre_amplifier.enabled) {
|
||||||
// pre-gain when the sub-module is implemented.
|
float value;
|
||||||
|
setting.GetFloat(&value);
|
||||||
|
private_submodules_->pre_amplifier->SetGainFactor(value);
|
||||||
|
}
|
||||||
|
// TODO(bugs.chromium.org/9138): Log setting handling by Aec Dump.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RTC_NOTREACHED();
|
RTC_NOTREACHED();
|
||||||
@ -1189,6 +1200,12 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
|
|||||||
|
|
||||||
AudioBuffer* capture_buffer = capture_.capture_audio.get(); // For brevity.
|
AudioBuffer* capture_buffer = capture_.capture_audio.get(); // For brevity.
|
||||||
|
|
||||||
|
if (private_submodules_->pre_amplifier) {
|
||||||
|
private_submodules_->pre_amplifier->ApplyGain(AudioFrameView<float>(
|
||||||
|
capture_buffer->channels_f(), capture_buffer->num_channels(),
|
||||||
|
capture_buffer->num_frames()));
|
||||||
|
}
|
||||||
|
|
||||||
capture_input_rms_.Analyze(rtc::ArrayView<const int16_t>(
|
capture_input_rms_.Analyze(rtc::ArrayView<const int16_t>(
|
||||||
capture_buffer->channels_const()[0],
|
capture_buffer->channels_const()[0],
|
||||||
capture_nonlocked_.capture_processing_format.num_frames()));
|
capture_nonlocked_.capture_processing_format.num_frames()));
|
||||||
@ -1771,7 +1788,7 @@ bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
|
|||||||
capture_nonlocked_.intelligibility_enabled,
|
capture_nonlocked_.intelligibility_enabled,
|
||||||
capture_nonlocked_.beamformer_enabled,
|
capture_nonlocked_.beamformer_enabled,
|
||||||
public_submodules_->gain_control->is_enabled(),
|
public_submodules_->gain_control->is_enabled(),
|
||||||
config_.gain_controller2.enabled,
|
config_.gain_controller2.enabled, config_.pre_amplifier.enabled,
|
||||||
capture_nonlocked_.echo_controller_enabled,
|
capture_nonlocked_.echo_controller_enabled,
|
||||||
public_submodules_->voice_detection->is_enabled(),
|
public_submodules_->voice_detection->is_enabled(),
|
||||||
public_submodules_->level_estimator->is_enabled(),
|
public_submodules_->level_estimator->is_enabled(),
|
||||||
@ -1837,6 +1854,15 @@ void AudioProcessingImpl::InitializeGainController2() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioProcessingImpl::InitializePreAmplifier() {
|
||||||
|
if (config_.pre_amplifier.enabled) {
|
||||||
|
private_submodules_->pre_amplifier.reset(
|
||||||
|
new GainApplier(true, config_.pre_amplifier.fixed_gain_factor));
|
||||||
|
} else {
|
||||||
|
private_submodules_->pre_amplifier.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioProcessingImpl::InitializeResidualEchoDetector() {
|
void AudioProcessingImpl::InitializeResidualEchoDetector() {
|
||||||
RTC_DCHECK(private_submodules_->echo_detector);
|
RTC_DCHECK(private_submodules_->echo_detector);
|
||||||
private_submodules_->echo_detector->Initialize(
|
private_submodules_->echo_detector->Initialize(
|
||||||
|
|||||||
@ -186,6 +186,7 @@ class AudioProcessingImpl : public AudioProcessing {
|
|||||||
bool beamformer_enabled,
|
bool beamformer_enabled,
|
||||||
bool adaptive_gain_controller_enabled,
|
bool adaptive_gain_controller_enabled,
|
||||||
bool gain_controller2_enabled,
|
bool gain_controller2_enabled,
|
||||||
|
bool pre_amplifier_enabled,
|
||||||
bool echo_controller_enabled,
|
bool echo_controller_enabled,
|
||||||
bool voice_activity_detector_enabled,
|
bool voice_activity_detector_enabled,
|
||||||
bool level_estimator_enabled,
|
bool level_estimator_enabled,
|
||||||
@ -209,6 +210,7 @@ class AudioProcessingImpl : public AudioProcessing {
|
|||||||
bool beamformer_enabled_ = false;
|
bool beamformer_enabled_ = false;
|
||||||
bool adaptive_gain_controller_enabled_ = false;
|
bool adaptive_gain_controller_enabled_ = false;
|
||||||
bool gain_controller2_enabled_ = false;
|
bool gain_controller2_enabled_ = false;
|
||||||
|
bool pre_amplifier_enabled_ = false;
|
||||||
bool echo_controller_enabled_ = false;
|
bool echo_controller_enabled_ = false;
|
||||||
bool level_estimator_enabled_ = false;
|
bool level_estimator_enabled_ = false;
|
||||||
bool voice_activity_detector_enabled_ = false;
|
bool voice_activity_detector_enabled_ = false;
|
||||||
@ -253,6 +255,7 @@ class AudioProcessingImpl : public AudioProcessing {
|
|||||||
void InitializeLowCutFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
void InitializeLowCutFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||||
void InitializeEchoController() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
void InitializeEchoController() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||||
void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||||
|
void InitializePreAmplifier() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||||
void InitializePostProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
void InitializePostProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
|
||||||
void InitializePreProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_);
|
void InitializePreProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_);
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,24 @@ class MockInitialize : public AudioProcessingImpl {
|
|||||||
MOCK_CONST_METHOD0(Release, rtc::RefCountReleaseStatus());
|
MOCK_CONST_METHOD0(Release, rtc::RefCountReleaseStatus());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GenerateFixedFrame(int16_t audio_level,
|
||||||
|
size_t input_rate,
|
||||||
|
size_t num_channels,
|
||||||
|
AudioFrame* fixed_frame) {
|
||||||
|
const size_t samples_per_input_channel = rtc::CheckedDivExact(
|
||||||
|
input_rate, static_cast<size_t>(rtc::CheckedDivExact(
|
||||||
|
1000, AudioProcessing::kChunkSizeMs)));
|
||||||
|
fixed_frame->samples_per_channel_ = samples_per_input_channel;
|
||||||
|
fixed_frame->sample_rate_hz_ = input_rate;
|
||||||
|
fixed_frame->num_channels_ = num_channels;
|
||||||
|
|
||||||
|
RTC_DCHECK_LE(samples_per_input_channel * num_channels,
|
||||||
|
AudioFrame::kMaxDataSizeSamples);
|
||||||
|
for (size_t i = 0; i < samples_per_input_channel * num_channels; ++i) {
|
||||||
|
fixed_frame->mutable_data()[i] = audio_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
|
TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
|
||||||
@ -75,9 +93,33 @@ TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
|
TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
|
||||||
// TODO(bugs.chromium.org/9138): Implement this test as soon as the pre-gain
|
std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
|
||||||
// sub-module is implemented and it is notified by HandleRuntimeSettings()
|
webrtc::AudioProcessing::Config apm_config;
|
||||||
// when the gain changes.
|
apm_config.pre_amplifier.enabled = true;
|
||||||
|
apm_config.pre_amplifier.fixed_gain_factor = 1.f;
|
||||||
|
apm->ApplyConfig(apm_config);
|
||||||
|
|
||||||
|
AudioFrame frame;
|
||||||
|
constexpr int16_t audio_level = 10000;
|
||||||
|
constexpr size_t input_rate = 48000;
|
||||||
|
constexpr size_t num_channels = 2;
|
||||||
|
|
||||||
|
GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
|
||||||
|
apm->ProcessStream(&frame);
|
||||||
|
EXPECT_EQ(frame.data()[100], audio_level)
|
||||||
|
<< "With factor 1, frame shouldn't be modified.";
|
||||||
|
|
||||||
|
constexpr float gain_factor = 2.f;
|
||||||
|
apm->SetRuntimeSetting(
|
||||||
|
AudioProcessing::RuntimeSetting::CreateCapturePreGain(gain_factor));
|
||||||
|
|
||||||
|
// Process for two frames to have time to ramp up gain.
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
|
||||||
|
apm->ProcessStream(&frame);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(frame.data()[100], gain_factor * audio_level)
|
||||||
|
<< "Frame should be amplified.";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Reference in New Issue
Block a user