diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index dd2ded6945..027e1ed719 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -242,6 +242,7 @@ 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 = [ diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 68a24d27c9..c1010669b0 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -309,24 +309,35 @@ struct AudioProcessingImpl::ApmPrivateSubmodules { AudioProcessing* AudioProcessing::Create() { webrtc::Config config; - return Create(config, nullptr, nullptr); + return Create(config, nullptr, rtc::Callback1(), nullptr); } AudioProcessing* AudioProcessing::Create(const webrtc::Config& config) { - return Create(config, nullptr, nullptr); + return Create(config, nullptr, rtc::Callback1(), nullptr); } AudioProcessing* AudioProcessing::Create(const webrtc::Config& config, NonlinearBeamformer* beamformer) { - return Create(config, nullptr, beamformer); + return Create(config, nullptr, rtc::Callback1(), + beamformer); } AudioProcessing* AudioProcessing::Create( const webrtc::Config& config, std::unique_ptr capture_post_processor, NonlinearBeamformer* beamformer) { + return Create(config, std::move(capture_post_processor), + rtc::Callback1(), beamformer); +} + +AudioProcessing* AudioProcessing::Create( + const webrtc::Config& config, + std::unique_ptr capture_post_processor, + rtc::Callback1 echo_control_factory, + NonlinearBeamformer* beamformer) { AudioProcessingImpl* apm = new rtc::RefCountedObject( - config, std::move(capture_post_processor), beamformer); + config, std::move(capture_post_processor), echo_control_factory, + beamformer); if (apm->Initialize() != kNoError) { delete apm; apm = nullptr; @@ -336,13 +347,18 @@ AudioProcessing* AudioProcessing::Create( } AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config) - : AudioProcessingImpl(config, nullptr, nullptr) {} + : AudioProcessingImpl(config, + nullptr, + rtc::Callback1(), + nullptr) {} AudioProcessingImpl::AudioProcessingImpl( const webrtc::Config& config, std::unique_ptr capture_post_processor, + rtc::Callback1 echo_control_factory, NonlinearBeamformer* beamformer) : high_pass_filter_impl_(new HighPassFilterImpl(this)), + echo_control_factory_(echo_control_factory), submodule_states_(!!capture_post_processor), public_submodules_(new ApmPublicSubmodules()), private_submodules_( @@ -679,6 +695,7 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { LOG(LS_INFO) << "Highpass filter activated: " << config_.high_pass_filter.enabled; + // TODO(gustaf): Do this outside of APM. config_ok = EchoCanceller3::Validate(config_.echo_canceller3); if (!config_ok) { LOG(LS_ERROR) << "AudioProcessing module config error" << std::endl @@ -689,6 +706,7 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { config_.echo_canceller3 = AudioProcessing::Config::EchoCanceller3(); } + // TODO(gustaf): Enable EchoCanceller3 by injection, not configuration. if (config.echo_canceller3.enabled != capture_nonlocked_.echo_canceller3_enabled) { capture_nonlocked_.echo_canceller3_enabled = @@ -1697,7 +1715,11 @@ void AudioProcessingImpl::InitializeLowCutFilter() { } void AudioProcessingImpl::InitializeEchoCanceller3() { - if (capture_nonlocked_.echo_canceller3_enabled) { + if (!echo_control_factory_.empty()) { + private_submodules_->echo_controller.reset( + echo_control_factory_(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( config_.echo_canceller3, proc_sample_rate_hz(), true)); } else { diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index 1e5695ca5a..a5e16cbbf8 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -43,6 +43,7 @@ class AudioProcessingImpl : public AudioProcessing { // beamformer. AudioProcessingImpl(const webrtc::Config& config, std::unique_ptr capture_post_processor, + rtc::Callback1 echo_control_factory, NonlinearBeamformer* beamformer); ~AudioProcessingImpl() override; int Initialize() override; @@ -141,6 +142,9 @@ class AudioProcessingImpl : public AudioProcessing { // Submodule interface implementations. std::unique_ptr high_pass_filter_impl_; + // EchoControl factory method. + rtc::Callback1 echo_control_factory_; + class ApmSubmoduleStates { public: explicit ApmSubmoduleStates(bool capture_post_processor_enabled); diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc index 854d6a552c..4540a6a3a3 100644 --- a/modules/audio_processing/audio_processing_unittest.cc +++ b/modules/audio_processing/audio_processing_unittest.cc @@ -1316,8 +1316,8 @@ TEST_F(ApmTest, AgcOnlyAdaptsWhenTargetSignalIsPresent) { config.Set(new Beamforming(true, geometry)); testing::NiceMock* beamformer = new testing::NiceMock(geometry, 1u); - std::unique_ptr apm( - AudioProcessing::Create(config, nullptr, beamformer)); + std::unique_ptr apm(AudioProcessing::Create( + config, nullptr, rtc::Callback1(), beamformer)); EXPECT_EQ(kNoErr, apm->gain_control()->Enable(true)); ChannelBuffer src_buf(kSamplesPerChannel, kNumInputChannels); ChannelBuffer dest_buf(kSamplesPerChannel, kNumOutputChannels); @@ -2915,15 +2915,16 @@ TEST(ApmConfiguration, EnablePostProcessing) { new testing::NiceMock(); auto mock_post_processor = std::unique_ptr(mock_post_processor_ptr); - rtc::scoped_refptr apm = AudioProcessing::Create( - webrtc_config, std::move(mock_post_processor), nullptr); + rtc::scoped_refptr apm = + AudioProcessing::Create(webrtc_config, std::move(mock_post_processor), + rtc::Callback1(), nullptr); AudioFrame audio; audio.num_channels_ = 1; SetFrameSampleRate(&audio, AudioProcessing::NativeRate::kSampleRate16kHz); EXPECT_CALL(*mock_post_processor_ptr, Process(testing::_)).Times(1); - std::cout << apm->ProcessStream(&audio) << std::endl; + apm->ProcessStream(&audio); } } // namespace webrtc diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index 54aed341b6..2cbea501c6 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -23,6 +23,7 @@ #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" @@ -43,6 +44,7 @@ class ProcessingConfig; class EchoCancellation; class EchoControlMobile; +class EchoControl; class GainControl; class HighPassFilter; class LevelEstimator; @@ -376,10 +378,15 @@ class AudioProcessing : public rtc::RefCountInterface { RTC_DEPRECATED static AudioProcessing* Create(const webrtc::Config& config, NonlinearBeamformer* beamformer); + static AudioProcessing* Create( + const webrtc::Config& config, + std::unique_ptr capture_post_processor, + NonlinearBeamformer* beamformer); // Allows passing in optional user-defined processing modules. static AudioProcessing* Create( const webrtc::Config& config, std::unique_ptr capture_post_processor, + rtc::Callback1 echo_control_factory, NonlinearBeamformer* beamformer); ~AudioProcessing() override {}