Added EchoControlFactory interface.
The factory for EchoControl is changed from an rtc::Callback1 to an interface. This avoids using rtc::Callback1 outside of WebRTC. This also makes the EchoControl factory more similar to other factories in the code base. Bug: webrtc:8345 Change-Id: Ie61b9416ed771f8c756326736d17e339eb768469 Reviewed-on: https://webrtc-review.googlesource.com/8900 Reviewed-by: Per Åhgren <peah@webrtc.org> Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20272}
This commit is contained in:
committed by
Commit Bot
parent
6f09ae20bd
commit
002ef28272
@ -242,7 +242,6 @@ rtc_static_library("audio_processing") {
|
||||
"../../audio/utility:audio_frame_operations",
|
||||
"../../rtc_base:gtest_prod",
|
||||
"../../rtc_base:protobuf_utils",
|
||||
"../../rtc_base:rtc_base",
|
||||
"../audio_coding:isac",
|
||||
]
|
||||
public_deps = [
|
||||
|
||||
@ -309,35 +309,33 @@ struct AudioProcessingImpl::ApmPrivateSubmodules {
|
||||
|
||||
AudioProcessing* AudioProcessing::Create() {
|
||||
webrtc::Config config;
|
||||
return Create(config, nullptr, rtc::Callback1<EchoControl*, int>(), nullptr);
|
||||
return Create(config, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
AudioProcessing* AudioProcessing::Create(const webrtc::Config& config) {
|
||||
return Create(config, nullptr, rtc::Callback1<EchoControl*, int>(), nullptr);
|
||||
return Create(config, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
AudioProcessing* AudioProcessing::Create(const webrtc::Config& config,
|
||||
NonlinearBeamformer* beamformer) {
|
||||
return Create(config, nullptr, rtc::Callback1<EchoControl*, int>(),
|
||||
beamformer);
|
||||
return Create(config, nullptr, nullptr, beamformer);
|
||||
}
|
||||
|
||||
AudioProcessing* AudioProcessing::Create(
|
||||
const webrtc::Config& config,
|
||||
std::unique_ptr<PostProcessing> capture_post_processor,
|
||||
NonlinearBeamformer* beamformer) {
|
||||
return Create(config, std::move(capture_post_processor),
|
||||
rtc::Callback1<EchoControl*, int>(), beamformer);
|
||||
return Create(config, std::move(capture_post_processor), nullptr, beamformer);
|
||||
}
|
||||
|
||||
AudioProcessing* AudioProcessing::Create(
|
||||
const webrtc::Config& config,
|
||||
std::unique_ptr<PostProcessing> capture_post_processor,
|
||||
rtc::Callback1<EchoControl*, int> echo_control_factory,
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory,
|
||||
NonlinearBeamformer* beamformer) {
|
||||
AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
|
||||
config, std::move(capture_post_processor), echo_control_factory,
|
||||
beamformer);
|
||||
config, std::move(capture_post_processor),
|
||||
std::move(echo_control_factory), beamformer);
|
||||
if (apm->Initialize() != kNoError) {
|
||||
delete apm;
|
||||
apm = nullptr;
|
||||
@ -347,18 +345,15 @@ AudioProcessing* AudioProcessing::Create(
|
||||
}
|
||||
|
||||
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
|
||||
: AudioProcessingImpl(config,
|
||||
nullptr,
|
||||
rtc::Callback1<EchoControl*, int>(),
|
||||
nullptr) {}
|
||||
: AudioProcessingImpl(config, nullptr, nullptr, nullptr) {}
|
||||
|
||||
AudioProcessingImpl::AudioProcessingImpl(
|
||||
const webrtc::Config& config,
|
||||
std::unique_ptr<PostProcessing> capture_post_processor,
|
||||
rtc::Callback1<EchoControl*, int> echo_control_factory,
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory,
|
||||
NonlinearBeamformer* beamformer)
|
||||
: high_pass_filter_impl_(new HighPassFilterImpl(this)),
|
||||
echo_control_factory_(echo_control_factory),
|
||||
echo_control_factory_(std::move(echo_control_factory)),
|
||||
submodule_states_(!!capture_post_processor),
|
||||
public_submodules_(new ApmPublicSubmodules()),
|
||||
private_submodules_(
|
||||
@ -1715,9 +1710,9 @@ void AudioProcessingImpl::InitializeLowCutFilter() {
|
||||
}
|
||||
|
||||
void AudioProcessingImpl::InitializeEchoCanceller3() {
|
||||
if (!echo_control_factory_.empty()) {
|
||||
private_submodules_->echo_controller.reset(
|
||||
echo_control_factory_(proc_sample_rate_hz()));
|
||||
if (echo_control_factory_) {
|
||||
private_submodules_->echo_controller =
|
||||
echo_control_factory_->Create(proc_sample_rate_hz());
|
||||
} else if (capture_nonlocked_.echo_canceller3_enabled) {
|
||||
// TODO(gustaf): Remove once injection is used.
|
||||
private_submodules_->echo_controller.reset(new EchoCanceller3(
|
||||
|
||||
@ -43,7 +43,7 @@ class AudioProcessingImpl : public AudioProcessing {
|
||||
// beamformer.
|
||||
AudioProcessingImpl(const webrtc::Config& config,
|
||||
std::unique_ptr<PostProcessing> capture_post_processor,
|
||||
rtc::Callback1<EchoControl*, int> echo_control_factory,
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory,
|
||||
NonlinearBeamformer* beamformer);
|
||||
~AudioProcessingImpl() override;
|
||||
int Initialize() override;
|
||||
@ -142,8 +142,8 @@ class AudioProcessingImpl : public AudioProcessing {
|
||||
// Submodule interface implementations.
|
||||
std::unique_ptr<HighPassFilter> high_pass_filter_impl_;
|
||||
|
||||
// EchoControl factory method.
|
||||
rtc::Callback1<EchoControl*, int> echo_control_factory_;
|
||||
// EchoControl factory.
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory_;
|
||||
|
||||
class ApmSubmoduleStates {
|
||||
public:
|
||||
|
||||
@ -1316,8 +1316,8 @@ TEST_F(ApmTest, AgcOnlyAdaptsWhenTargetSignalIsPresent) {
|
||||
config.Set<Beamforming>(new Beamforming(true, geometry));
|
||||
testing::NiceMock<MockNonlinearBeamformer>* beamformer =
|
||||
new testing::NiceMock<MockNonlinearBeamformer>(geometry, 1u);
|
||||
std::unique_ptr<AudioProcessing> apm(AudioProcessing::Create(
|
||||
config, nullptr, rtc::Callback1<EchoControl*, int>(), beamformer));
|
||||
std::unique_ptr<AudioProcessing> apm(
|
||||
AudioProcessing::Create(config, nullptr, nullptr, beamformer));
|
||||
EXPECT_EQ(kNoErr, apm->gain_control()->Enable(true));
|
||||
ChannelBuffer<float> src_buf(kSamplesPerChannel, kNumInputChannels);
|
||||
ChannelBuffer<float> dest_buf(kSamplesPerChannel, kNumOutputChannels);
|
||||
@ -2915,9 +2915,8 @@ TEST(ApmConfiguration, EnablePostProcessing) {
|
||||
new testing::NiceMock<test::MockPostProcessing>();
|
||||
auto mock_post_processor =
|
||||
std::unique_ptr<PostProcessing>(mock_post_processor_ptr);
|
||||
rtc::scoped_refptr<AudioProcessing> apm =
|
||||
AudioProcessing::Create(webrtc_config, std::move(mock_post_processor),
|
||||
rtc::Callback1<EchoControl*, int>(), nullptr);
|
||||
rtc::scoped_refptr<AudioProcessing> apm = AudioProcessing::Create(
|
||||
webrtc_config, std::move(mock_post_processor), nullptr, nullptr);
|
||||
|
||||
AudioFrame audio;
|
||||
audio.num_channels_ = 1;
|
||||
@ -2927,4 +2926,31 @@ TEST(ApmConfiguration, EnablePostProcessing) {
|
||||
apm->ProcessStream(&audio);
|
||||
}
|
||||
|
||||
class MyEchoControlFactory : public EchoControlFactory {
|
||||
public:
|
||||
std::unique_ptr<EchoControl> Create(int sample_rate_hz) {
|
||||
auto ec = new test::MockEchoControl();
|
||||
EXPECT_CALL(*ec, AnalyzeRender(testing::_)).Times(1);
|
||||
EXPECT_CALL(*ec, AnalyzeCapture(testing::_)).Times(2);
|
||||
EXPECT_CALL(*ec, ProcessCapture(testing::_, testing::_)).Times(2);
|
||||
return std::unique_ptr<EchoControl>(ec);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ApmConfiguration, EchoControlInjection) {
|
||||
// Verify that apm uses an injected echo controller if one is provided.
|
||||
webrtc::Config webrtc_config;
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory(
|
||||
new MyEchoControlFactory());
|
||||
|
||||
rtc::scoped_refptr<AudioProcessing> apm = AudioProcessing::Create(
|
||||
webrtc_config, nullptr, std::move(echo_control_factory), nullptr);
|
||||
|
||||
AudioFrame audio;
|
||||
audio.num_channels_ = 1;
|
||||
SetFrameSampleRate(&audio, AudioProcessing::NativeRate::kSampleRate16kHz);
|
||||
apm->ProcessStream(&audio);
|
||||
apm->ProcessReverseStream(&audio);
|
||||
apm->ProcessStream(&audio);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
#include "modules/audio_processing/beamformer/array_util.h"
|
||||
#include "modules/audio_processing/include/config.h"
|
||||
#include "rtc_base/arraysize.h"
|
||||
#include "rtc_base/callback.h"
|
||||
#include "rtc_base/deprecation.h"
|
||||
#include "rtc_base/platform_file.h"
|
||||
#include "rtc_base/refcount.h"
|
||||
@ -44,7 +43,7 @@ class ProcessingConfig;
|
||||
|
||||
class EchoCancellation;
|
||||
class EchoControlMobile;
|
||||
class EchoControl;
|
||||
class EchoControlFactory;
|
||||
class GainControl;
|
||||
class HighPassFilter;
|
||||
class LevelEstimator;
|
||||
@ -386,7 +385,7 @@ class AudioProcessing : public rtc::RefCountInterface {
|
||||
static AudioProcessing* Create(
|
||||
const webrtc::Config& config,
|
||||
std::unique_ptr<PostProcessing> capture_post_processor,
|
||||
rtc::Callback1<EchoControl*, int> echo_control_factory,
|
||||
std::unique_ptr<EchoControlFactory> echo_control_factory,
|
||||
NonlinearBeamformer* beamformer);
|
||||
~AudioProcessing() override {}
|
||||
|
||||
@ -971,6 +970,13 @@ class EchoControl {
|
||||
virtual ~EchoControl() {}
|
||||
};
|
||||
|
||||
// Interface for a factory that creates EchoControllers.
|
||||
class EchoControlFactory {
|
||||
public:
|
||||
virtual std::unique_ptr<EchoControl> Create(int sample_rate_hz) = 0;
|
||||
virtual ~EchoControlFactory() = default;
|
||||
};
|
||||
|
||||
// The automatic gain control (AGC) component brings the signal to an
|
||||
// appropriate range. This is done by applying a digital gain directly and, in
|
||||
// the analog mode, prescribing an analog gain to be applied at the audio HAL.
|
||||
|
||||
@ -112,6 +112,15 @@ class MockPostProcessing : public PostProcessing {
|
||||
MOCK_CONST_METHOD0(ToString, std::string());
|
||||
};
|
||||
|
||||
class MockEchoControl : public EchoControl {
|
||||
public:
|
||||
virtual ~MockEchoControl() {}
|
||||
MOCK_METHOD1(AnalyzeRender, void(AudioBuffer* render));
|
||||
MOCK_METHOD1(AnalyzeCapture, void(AudioBuffer* capture));
|
||||
MOCK_METHOD2(ProcessCapture,
|
||||
void(AudioBuffer* capture, bool echo_path_change));
|
||||
};
|
||||
|
||||
class MockVoiceDetection : public VoiceDetection {
|
||||
public:
|
||||
virtual ~MockVoiceDetection() {}
|
||||
|
||||
Reference in New Issue
Block a user