diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index 052bb47860..3f048732f4 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -419,6 +419,7 @@ if (rtc_include_tests) { ":audioproc_protobuf_utils", ":audioproc_test_utils", ":audioproc_unittest_proto", + ":runtime_settings_protobuf_utils", "../../api/audio:audio_frame_api", "../../rtc_base:rtc_base_tests_utils", "../../rtc_base:rtc_task_queue", @@ -531,6 +532,7 @@ if (rtc_include_tests) { ":audioproc_debug_proto", ":audioproc_protobuf_utils", ":audioproc_test_utils", + ":runtime_settings_protobuf_utils", "../../api/audio:aec3_factory", "../../common_audio:common_audio", "../../rtc_base:checks", @@ -651,10 +653,26 @@ if (rtc_include_tests) { deps = [ ":audioproc_debug_proto", "../..:webrtc_common", + "../../rtc_base:checks", "../../rtc_base:protobuf_utils", "../../rtc_base:rtc_base_approved", "../../rtc_base/system:arch", ] } + + rtc_static_library("runtime_settings_protobuf_utils") { + testonly = true + sources = [ + "test/runtime_setting_util.cc", + "test/runtime_setting_util.h", + ] + + deps = [ + ":audio_processing", + ":audioproc_debug_proto", + ":audioproc_protobuf_utils", + "../../rtc_base:checks", + ] + } } } diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.cc b/modules/audio_processing/aec_dump/aec_dump_impl.cc index 9e07367c8d..2732934140 100644 --- a/modules/audio_processing/aec_dump/aec_dump_impl.cc +++ b/modules/audio_processing/aec_dump/aec_dump_impl.cc @@ -167,6 +167,34 @@ void AecDumpImpl::WriteConfig(const InternalAPMConfig& config) { worker_queue_->PostTask(std::unique_ptr(std::move(task))); } +void AecDumpImpl::WriteRuntimeSetting( + const AudioProcessing::RuntimeSetting& runtime_setting) { + RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); + auto task = CreateWriteToFileTask(); + auto* event = task->GetEvent(); + event->set_type(audioproc::Event::RUNTIME_SETTING); + audioproc::RuntimeSetting* setting = event->mutable_runtime_setting(); + switch (runtime_setting.type()) { + case AudioProcessing::RuntimeSetting::Type::kCapturePreGain: { + float x; + runtime_setting.GetFloat(&x); + setting->set_capture_pre_gain(x); + break; + } + case AudioProcessing::RuntimeSetting::Type:: + kCustomRenderProcessingRuntimeSetting: { + float x; + runtime_setting.GetFloat(&x); + setting->set_custom_render_processing_setting(x); + break; + } + case AudioProcessing::RuntimeSetting::Type::kNotSpecified: + RTC_NOTREACHED(); + break; + } + worker_queue_->PostTask(std::unique_ptr(std::move(task))); +} + std::unique_ptr AecDumpImpl::CreateWriteToFileTask() { return absl::make_unique(debug_file_.get(), &num_bytes_left_for_log_); diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.h b/modules/audio_processing/aec_dump/aec_dump_impl.h index a5416a07da..df949ca7bd 100644 --- a/modules/audio_processing/aec_dump/aec_dump_impl.h +++ b/modules/audio_processing/aec_dump/aec_dump_impl.h @@ -67,6 +67,9 @@ class AecDumpImpl : public AecDump { void WriteConfig(const InternalAPMConfig& config) override; + void WriteRuntimeSetting( + const AudioProcessing::RuntimeSetting& runtime_setting) override; + private: std::unique_ptr CreateWriteToFileTask(); diff --git a/modules/audio_processing/aec_dump/mock_aec_dump.h b/modules/audio_processing/aec_dump/mock_aec_dump.h index c01de51e37..8910b423f8 100644 --- a/modules/audio_processing/aec_dump/mock_aec_dump.h +++ b/modules/audio_processing/aec_dump/mock_aec_dump.h @@ -43,6 +43,9 @@ class MockAecDump : public AecDump { void(const AudioFrameView& src)); MOCK_METHOD1(WriteConfig, void(const InternalAPMConfig& config)); + + MOCK_METHOD1(WriteRuntimeSetting, + void(const AudioProcessing::RuntimeSetting& config)); }; } // namespace test diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 8848b734d4..398b574174 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -876,6 +876,9 @@ int AudioProcessingImpl::ProcessStream(const float* const* src, void AudioProcessingImpl::HandleCaptureRuntimeSettings() { RuntimeSetting setting; while (capture_runtime_settings_.Remove(&setting)) { + if (aec_dump_) { + aec_dump_->WriteRuntimeSetting(setting); + } switch (setting.type()) { case RuntimeSetting::Type::kCapturePreGain: if (config_.pre_amplifier.enabled) { @@ -898,6 +901,9 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() { void AudioProcessingImpl::HandleRenderRuntimeSettings() { RuntimeSetting setting; while (render_runtime_settings_.Remove(&setting)) { + if (aec_dump_) { + aec_dump_->WriteRuntimeSetting(setting); + } switch (setting.type()) { case RuntimeSetting::Type::kCustomRenderProcessingRuntimeSetting: if (private_submodules_->render_pre_processor) { diff --git a/modules/audio_processing/debug.proto b/modules/audio_processing/debug.proto index b19f7feafc..10a98d53f6 100644 --- a/modules/audio_processing/debug.proto +++ b/modules/audio_processing/debug.proto @@ -80,6 +80,11 @@ message Config { // Next field number 21. } +message RuntimeSetting { + optional float capture_pre_gain = 1; + optional float custom_render_processing_setting = 2; +} + message Event { enum Type { INIT = 0; @@ -87,6 +92,7 @@ message Event { STREAM = 2; CONFIG = 3; UNKNOWN_EVENT = 4; + RUNTIME_SETTING = 5; } required Type type = 1; @@ -95,4 +101,5 @@ message Event { optional ReverseStream reverse_stream = 3; optional Stream stream = 4; optional Config config = 5; + optional RuntimeSetting runtime_setting = 6; } diff --git a/modules/audio_processing/include/aec_dump.h b/modules/audio_processing/include/aec_dump.h index e32fa67945..313e9d7b1d 100644 --- a/modules/audio_processing/include/aec_dump.h +++ b/modules/audio_processing/include/aec_dump.h @@ -98,6 +98,9 @@ class AecDump { virtual void WriteRenderStreamMessage( const AudioFrameView& src) = 0; + virtual void WriteRuntimeSetting( + const AudioProcessing::RuntimeSetting& runtime_setting) = 0; + // Logs Event::Type CONFIG message. virtual void WriteConfig(const InternalAPMConfig& config) = 0; }; diff --git a/modules/audio_processing/test/aec_dump_based_simulator.cc b/modules/audio_processing/test/aec_dump_based_simulator.cc index 743bbd0e83..7038b9c85c 100644 --- a/modules/audio_processing/test/aec_dump_based_simulator.cc +++ b/modules/audio_processing/test/aec_dump_based_simulator.cc @@ -11,6 +11,7 @@ #include #include "modules/audio_processing/test/aec_dump_based_simulator.h" +#include "modules/audio_processing/test/runtime_setting_util.h" #include "modules/audio_processing/test/protobuf_utils.h" #include "rtc_base/checks.h" @@ -253,8 +254,12 @@ void AecDumpBasedSimulator::Process() { RTC_CHECK(event_msg.has_config()); HandleMessage(event_msg.config()); break; - default: + case webrtc::audioproc::Event::RUNTIME_SETTING: + HandleMessage(event_msg.runtime_setting()); + break; + case webrtc::audioproc::Event::UNKNOWN_EVENT: RTC_CHECK(false); + break; } } @@ -552,5 +557,11 @@ void AecDumpBasedSimulator::HandleMessage( ProcessReverseStream(interface_used_ == InterfaceType::kFixedInterface); } +void AecDumpBasedSimulator::HandleMessage( + const webrtc::audioproc::RuntimeSetting& msg) { + RTC_CHECK(ap_.get()); + ReplayRuntimeSetting(ap_.get(), msg); +} + } // namespace test } // namespace webrtc diff --git a/modules/audio_processing/test/aec_dump_based_simulator.h b/modules/audio_processing/test/aec_dump_based_simulator.h index 9899c6c29f..3358fcf276 100644 --- a/modules/audio_processing/test/aec_dump_based_simulator.h +++ b/modules/audio_processing/test/aec_dump_based_simulator.h @@ -42,6 +42,7 @@ class AecDumpBasedSimulator final : public AudioProcessingSimulator { void HandleMessage(const webrtc::audioproc::Stream& msg); void HandleMessage(const webrtc::audioproc::ReverseStream& msg); void HandleMessage(const webrtc::audioproc::Config& msg); + void HandleMessage(const webrtc::audioproc::RuntimeSetting& msg); void PrepareProcessStreamCall(const webrtc::audioproc::Stream& msg); void PrepareReverseProcessStreamCall( const webrtc::audioproc::ReverseStream& msg); diff --git a/modules/audio_processing/test/debug_dump_replayer.cc b/modules/audio_processing/test/debug_dump_replayer.cc index c7767f75e8..6350c8cd34 100644 --- a/modules/audio_processing/test/debug_dump_replayer.cc +++ b/modules/audio_processing/test/debug_dump_replayer.cc @@ -11,6 +11,7 @@ #include "modules/audio_processing/test/debug_dump_replayer.h" #include "modules/audio_processing/test/protobuf_utils.h" +#include "modules/audio_processing/test/runtime_setting_util.h" #include "rtc_base/checks.h" namespace webrtc { @@ -73,8 +74,12 @@ bool DebugDumpReplayer::RunNextEvent() { case audioproc::Event::CONFIG: OnConfigEvent(next_event_.config()); break; + case audioproc::Event::RUNTIME_SETTING: + OnRuntimeSettingEvent(next_event_.runtime_setting()); + break; case audioproc::Event::UNKNOWN_EVENT: // We do not expect to receive UNKNOWN event. + RTC_CHECK(false); return false; } LoadNextMessage(); @@ -167,6 +172,12 @@ void DebugDumpReplayer::OnConfigEvent(const audioproc::Config& msg) { ConfigureApm(msg); } +void DebugDumpReplayer::OnRuntimeSettingEvent( + const audioproc::RuntimeSetting& msg) { + RTC_CHECK(apm_.get()); + ReplayRuntimeSetting(apm_.get(), msg); +} + void DebugDumpReplayer::MaybeRecreateApm(const audioproc::Config& msg) { // These configurations cannot be changed on the fly. Config config; @@ -252,6 +263,11 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) { apm_->noise_suppression()->set_level( static_cast(msg.ns_level()))); + RTC_CHECK(msg.has_pre_amplifier_enabled()); + apm_config.pre_amplifier.enabled = msg.pre_amplifier_enabled(); + apm_config.pre_amplifier.fixed_gain_factor = + msg.pre_amplifier_fixed_gain_factor(); + apm_->ApplyConfig(apm_config); } diff --git a/modules/audio_processing/test/debug_dump_replayer.h b/modules/audio_processing/test/debug_dump_replayer.h index aa5d72735a..4139149024 100644 --- a/modules/audio_processing/test/debug_dump_replayer.h +++ b/modules/audio_processing/test/debug_dump_replayer.h @@ -48,6 +48,7 @@ class DebugDumpReplayer { void OnStreamEvent(const audioproc::Stream& msg); void OnReverseStreamEvent(const audioproc::ReverseStream& msg); void OnConfigEvent(const audioproc::Config& msg); + void OnRuntimeSettingEvent(const audioproc::RuntimeSetting& msg); void MaybeRecreateApm(const audioproc::Config& msg); void ConfigureApm(const audioproc::Config& msg); diff --git a/modules/audio_processing/test/debug_dump_test.cc b/modules/audio_processing/test/debug_dump_test.cc index 72cefdd791..8b83c0f63e 100644 --- a/modules/audio_processing/test/debug_dump_test.cc +++ b/modules/audio_processing/test/debug_dump_test.cc @@ -48,7 +48,8 @@ class DebugDumpGenerator { int reverse_channels, const Config& config, const std::string& dump_file_name, - bool enable_aec3); + bool enable_aec3, + bool enable_pre_amplifier); // Constructor that uses default input files. explicit DebugDumpGenerator(const Config& config, @@ -112,6 +113,8 @@ class DebugDumpGenerator { std::unique_ptr> reverse_; std::unique_ptr> output_; + bool enable_pre_amplifier_; + rtc::TaskQueue worker_queue_; std::unique_ptr apm_; @@ -126,7 +129,8 @@ DebugDumpGenerator::DebugDumpGenerator(const std::string& input_file_name, int reverse_channels, const Config& config, const std::string& dump_file_name, - bool enable_aec3) + bool enable_aec3, + bool enable_pre_amplifier) : input_config_(input_rate_hz, input_channels), reverse_config_(reverse_rate_hz, reverse_channels), output_config_(input_rate_hz, input_channels), @@ -140,6 +144,7 @@ DebugDumpGenerator::DebugDumpGenerator(const std::string& input_file_name, reverse_config_.num_channels())), output_(new ChannelBuffer(output_config_.num_frames(), output_config_.num_channels())), + enable_pre_amplifier_(enable_pre_amplifier), worker_queue_("debug_dump_generator_worker_queue"), dump_file_name_(dump_file_name) { AudioProcessingBuilder apm_builder; @@ -162,7 +167,8 @@ DebugDumpGenerator::DebugDumpGenerator( 2, config, TempFilename(OutputPath(), "debug_aec"), - enable_aec3) { + enable_aec3, + apm_config.pre_amplifier.enabled) { apm_->ApplyConfig(apm_config); } @@ -223,6 +229,10 @@ void DebugDumpGenerator::Process(size_t num_blocks) { ReadAndDeinterleave(&input_audio_, input_file_channels_, input_config_, input_->channels()); RTC_CHECK_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100)); + if (enable_pre_amplifier_) { + apm_->SetRuntimeSetting( + AudioProcessing::RuntimeSetting::CreateCapturePreGain(1 + i % 10)); + } apm_->set_stream_key_pressed(i % 10 == 9); RTC_CHECK_EQ(AudioProcessing::kNoError, apm_->ProcessStream(input_->channels(), input_config_, @@ -596,5 +606,16 @@ TEST_F(DebugDumpTest, TransientSuppressionOn) { VerifyDebugDump(generator.dump_file_name()); } +TEST_F(DebugDumpTest, PreAmplifierIsOn) { + Config config; + AudioProcessing::Config apm_config; + apm_config.pre_amplifier.enabled = true; + DebugDumpGenerator generator(config, apm_config); + generator.StartRecording(); + generator.Process(100); + generator.StopRecording(); + VerifyDebugDump(generator.dump_file_name()); +} + } // namespace test } // namespace webrtc diff --git a/modules/audio_processing/test/runtime_setting_util.cc b/modules/audio_processing/test/runtime_setting_util.cc new file mode 100644 index 0000000000..104b6005a8 --- /dev/null +++ b/modules/audio_processing/test/runtime_setting_util.cc @@ -0,0 +1,25 @@ +/* + * 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/test/runtime_setting_util.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +void ReplayRuntimeSetting(AudioProcessing* apm, + const webrtc::audioproc::RuntimeSetting& setting) { + RTC_CHECK(apm); + // TODO(bugs.webrtc.org/9138): Add ability to handle different types + // of settings. Currently only CapturePreGain is supported. + RTC_CHECK(setting.has_capture_pre_gain()); + apm->SetRuntimeSetting(AudioProcessing::RuntimeSetting::CreateCapturePreGain( + setting.capture_pre_gain())); +} +} // namespace webrtc diff --git a/modules/audio_processing/test/runtime_setting_util.h b/modules/audio_processing/test/runtime_setting_util.h new file mode 100644 index 0000000000..d8cbe82076 --- /dev/null +++ b/modules/audio_processing/test/runtime_setting_util.h @@ -0,0 +1,23 @@ +/* + * 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. + */ + +#ifndef MODULES_AUDIO_PROCESSING_TEST_RUNTIME_SETTING_UTIL_H_ +#define MODULES_AUDIO_PROCESSING_TEST_RUNTIME_SETTING_UTIL_H_ + +#include "modules/audio_processing/include/audio_processing.h" +#include "modules/audio_processing/test/protobuf_utils.h" + +namespace webrtc { + +void ReplayRuntimeSetting(AudioProcessing* apm, + const webrtc::audioproc::RuntimeSetting& setting); +} + +#endif // MODULES_AUDIO_PROCESSING_TEST_RUNTIME_SETTING_UTIL_H_