The current scheme for setting parameters and specifying the behavior

of the audio processing module is quite complex and hard to implement
in a threadsafe and efficient manner. Therefore a new scheme for setting
the parameters in the audio processing module is introduced in this CL.

The idea is to roll this scheme out gradually and as a first functionality
in the audio processing module where this is applied the level controller
was chosen. This CL includes the replacement of the Config-based
level controller scheme with the new scheme.

BUG=webrtc:5298

Review-Url: https://codereview.webrtc.org/2292863002
Cr-Commit-Position: refs/heads/master@{#14171}
This commit is contained in:
peah
2016-09-09 14:15:57 -07:00
committed by Commit bot
parent e753641ef1
commit c8bbe3fe9a
17 changed files with 167 additions and 76 deletions

View File

@ -70,6 +70,7 @@ class FakeAudioProcessing : public webrtc::AudioProcessing {
WEBRTC_STUB(Initialize, ( WEBRTC_STUB(Initialize, (
const webrtc::ProcessingConfig& processing_config)); const webrtc::ProcessingConfig& processing_config));
WEBRTC_VOID_STUB(ApplyConfig, (const AudioProcessing::Config& config));
WEBRTC_VOID_FUNC(SetExtraOptions, (const webrtc::Config& config)) { WEBRTC_VOID_FUNC(SetExtraOptions, (const webrtc::Config& config)) {
experimental_ns_enabled_ = config.Get<webrtc::ExperimentalNs>().enabled; experimental_ns_enabled_ = config.Get<webrtc::ExperimentalNs>().enabled;
} }

View File

@ -868,8 +868,9 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
LOG(LS_INFO) << "Level control: " LOG(LS_INFO) << "Level control: "
<< (!!level_control_ ? *level_control_ : -1); << (!!level_control_ ? *level_control_ : -1);
webrtc::AudioProcessing::Config apm_config;
if (level_control_) { if (level_control_) {
config.Set<webrtc::LevelControl>(new webrtc::LevelControl(*level_control_)); apm_config.level_controller.enabled = *level_control_;
} }
// We check audioproc for the benefit of tests, since FakeWebRtcVoiceEngine // We check audioproc for the benefit of tests, since FakeWebRtcVoiceEngine
@ -877,6 +878,7 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
webrtc::AudioProcessing* audioproc = voe_wrapper_->base()->audio_processing(); webrtc::AudioProcessing* audioproc = voe_wrapper_->base()->audio_processing();
if (audioproc) { if (audioproc) {
audioproc->SetExtraOptions(config); audioproc->SetExtraOptions(config);
audioproc->ApplyConfig(apm_config);
} }
if (options.recording_sample_rate) { if (options.recording_sample_rate) {

View File

@ -154,15 +154,15 @@ struct AudioProcessingImpl::ApmPrivateSubmodules {
}; };
AudioProcessing* AudioProcessing::Create() { AudioProcessing* AudioProcessing::Create() {
Config config; webrtc::Config config;
return Create(config, nullptr); return Create(config, nullptr);
} }
AudioProcessing* AudioProcessing::Create(const Config& config) { AudioProcessing* AudioProcessing::Create(const webrtc::Config& config) {
return Create(config, nullptr); return Create(config, nullptr);
} }
AudioProcessing* AudioProcessing::Create(const Config& config, AudioProcessing* AudioProcessing::Create(const webrtc::Config& config,
NonlinearBeamformer* beamformer) { NonlinearBeamformer* beamformer) {
AudioProcessingImpl* apm = new AudioProcessingImpl(config, beamformer); AudioProcessingImpl* apm = new AudioProcessingImpl(config, beamformer);
if (apm->Initialize() != kNoError) { if (apm->Initialize() != kNoError) {
@ -173,10 +173,10 @@ AudioProcessing* AudioProcessing::Create(const Config& config,
return apm; return apm;
} }
AudioProcessingImpl::AudioProcessingImpl(const Config& config) AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
: AudioProcessingImpl(config, nullptr) {} : AudioProcessingImpl(config, nullptr) {}
AudioProcessingImpl::AudioProcessingImpl(const Config& config, AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config,
NonlinearBeamformer* beamformer) NonlinearBeamformer* beamformer)
: public_submodules_(new ApmPublicSubmodules()), : public_submodules_(new ApmPublicSubmodules()),
private_submodules_(new ApmPrivateSubmodules(beamformer)), private_submodules_(new ApmPrivateSubmodules(beamformer)),
@ -194,8 +194,7 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config,
config.Get<Beamforming>().array_geometry, config.Get<Beamforming>().array_geometry,
config.Get<Beamforming>().target_direction), config.Get<Beamforming>().target_direction),
capture_nonlocked_(config.Get<Beamforming>().enabled, capture_nonlocked_(config.Get<Beamforming>().enabled,
config.Get<Intelligibility>().enabled, config.Get<Intelligibility>().enabled) {
config.Get<LevelControl>().enabled) {
{ {
rtc::CritScope cs_render(&crit_render_); rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_); rtc::CritScope cs_capture(&crit_capture_);
@ -432,7 +431,34 @@ int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) {
return InitializeLocked(); return InitializeLocked();
} }
void AudioProcessingImpl::SetExtraOptions(const Config& config) { void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
AudioProcessing::Config config_to_use = config;
bool config_ok = LevelController::Validate(config_to_use.level_controller);
if (!config_ok) {
LOG(LS_ERROR) << "AudioProcessing module config error" << std::endl
<< "level_controller: "
<< LevelController::ToString(config_to_use.level_controller)
<< std::endl
<< "Reverting to default parameter set";
config_to_use.level_controller = AudioProcessing::Config::LevelController();
}
// Run in a single-threaded manner when applying the settings.
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
if (config.level_controller.enabled !=
capture_nonlocked_.level_controller_enabled) {
InitializeLevelController();
LOG(LS_INFO) << "Level controller activated: "
<< capture_nonlocked_.level_controller_enabled;
capture_nonlocked_.level_controller_enabled =
config.level_controller.enabled;
}
}
void AudioProcessingImpl::SetExtraOptions(const webrtc::Config& config) {
// Run in a single-threaded manner when setting the extra options. // Run in a single-threaded manner when setting the extra options.
rtc::CritScope cs_render(&crit_render_); rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_); rtc::CritScope cs_capture(&crit_capture_);
@ -446,16 +472,6 @@ void AudioProcessingImpl::SetExtraOptions(const Config& config) {
InitializeTransient(); InitializeTransient();
} }
if (capture_nonlocked_.level_controller_enabled !=
config.Get<LevelControl>().enabled) {
capture_nonlocked_.level_controller_enabled =
config.Get<LevelControl>().enabled;
LOG(LS_INFO) << "Level controller activated: "
<< config.Get<LevelControl>().enabled;
InitializeLevelController();
}
#if WEBRTC_INTELLIGIBILITY_ENHANCER #if WEBRTC_INTELLIGIBILITY_ENHANCER
if(capture_nonlocked_.intelligibility_enabled != if(capture_nonlocked_.intelligibility_enabled !=
config.Get<Intelligibility>().enabled) { config.Get<Intelligibility>().enabled) {

View File

@ -42,9 +42,10 @@ class AudioProcessingImpl : public AudioProcessing {
public: public:
// Methods forcing APM to run in a single-threaded manner. // Methods forcing APM to run in a single-threaded manner.
// Acquires both the render and capture locks. // Acquires both the render and capture locks.
explicit AudioProcessingImpl(const Config& config); explicit AudioProcessingImpl(const webrtc::Config& config);
// AudioProcessingImpl takes ownership of beamformer. // AudioProcessingImpl takes ownership of beamformer.
AudioProcessingImpl(const Config& config, NonlinearBeamformer* beamformer); AudioProcessingImpl(const webrtc::Config& config,
NonlinearBeamformer* beamformer);
~AudioProcessingImpl() override; ~AudioProcessingImpl() override;
int Initialize() override; int Initialize() override;
int Initialize(int input_sample_rate_hz, int Initialize(int input_sample_rate_hz,
@ -54,7 +55,8 @@ class AudioProcessingImpl : public AudioProcessing {
ChannelLayout output_layout, ChannelLayout output_layout,
ChannelLayout reverse_layout) override; ChannelLayout reverse_layout) override;
int Initialize(const ProcessingConfig& processing_config) override; int Initialize(const ProcessingConfig& processing_config) override;
void SetExtraOptions(const Config& config) override; void ApplyConfig(const AudioProcessing::Config& config) override;
void SetExtraOptions(const webrtc::Config& config) override;
void UpdateHistogramsOnCallEnd() override; void UpdateHistogramsOnCallEnd() override;
int StartDebugRecording(const char filename[kMaxFilenameSize], int StartDebugRecording(const char filename[kMaxFilenameSize],
int64_t max_log_size_bytes) override; int64_t max_log_size_bytes) override;
@ -312,14 +314,12 @@ class AudioProcessingImpl : public AudioProcessing {
struct ApmCaptureNonLockedState { struct ApmCaptureNonLockedState {
ApmCaptureNonLockedState(bool beamformer_enabled, ApmCaptureNonLockedState(bool beamformer_enabled,
bool intelligibility_enabled, bool intelligibility_enabled)
bool level_controller_enabled)
: fwd_proc_format(kSampleRate16kHz), : fwd_proc_format(kSampleRate16kHz),
split_rate(kSampleRate16kHz), split_rate(kSampleRate16kHz),
stream_delay_ms(0), stream_delay_ms(0),
beamformer_enabled(beamformer_enabled), beamformer_enabled(beamformer_enabled),
intelligibility_enabled(intelligibility_enabled), intelligibility_enabled(intelligibility_enabled) {}
level_controller_enabled(level_controller_enabled) {}
// Only the rate and samples fields of fwd_proc_format_ are used because the // Only the rate and samples fields of fwd_proc_format_ are used because the
// forward processing number of channels is mutable and is tracked by the // forward processing number of channels is mutable and is tracked by the
// capture_audio_. // capture_audio_.
@ -328,7 +328,7 @@ class AudioProcessingImpl : public AudioProcessing {
int stream_delay_ms; int stream_delay_ms;
bool beamformer_enabled; bool beamformer_enabled;
bool intelligibility_enabled; bool intelligibility_enabled;
bool level_controller_enabled; bool level_controller_enabled = false;
} capture_nonlocked_; } capture_nonlocked_;
struct ApmRenderState { struct ApmRenderState {

View File

@ -23,8 +23,8 @@ namespace webrtc {
class MockInitialize : public AudioProcessingImpl { class MockInitialize : public AudioProcessingImpl {
public: public:
explicit MockInitialize(const Config& config) : AudioProcessingImpl(config) { explicit MockInitialize(const webrtc::Config& config)
} : AudioProcessingImpl(config) {}
MOCK_METHOD0(InitializeLocked, int()); MOCK_METHOD0(InitializeLocked, int());
int RealInitializeLocked() NO_THREAD_SAFETY_ANALYSIS { int RealInitializeLocked() NO_THREAD_SAFETY_ANALYSIS {
@ -33,7 +33,7 @@ class MockInitialize : public AudioProcessingImpl {
}; };
TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) { TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
Config config; webrtc::Config config;
MockInitialize mock(config); MockInitialize mock(config);
ON_CALL(mock, InitializeLocked()) ON_CALL(mock, InitializeLocked())
.WillByDefault(Invoke(&mock, &MockInitialize::RealInitializeLocked)); .WillByDefault(Invoke(&mock, &MockInitialize::RealInitializeLocked));

View File

@ -538,7 +538,7 @@ void EchoCancellationImpl::AllocateRenderQueue() {
} }
} }
void EchoCancellationImpl::SetExtraOptions(const Config& config) { void EchoCancellationImpl::SetExtraOptions(const webrtc::Config& config) {
{ {
rtc::CritScope cs(crit_capture_); rtc::CritScope cs(crit_capture_);
extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled;

View File

@ -43,7 +43,7 @@ class EchoCancellationImpl : public EchoCancellation {
size_t num_reverse_channels_, size_t num_reverse_channels_,
size_t num_output_channels_, size_t num_output_channels_,
size_t num_proc_channels_); size_t num_proc_channels_);
void SetExtraOptions(const Config& config); void SetExtraOptions(const webrtc::Config& config);
bool is_delay_agnostic_enabled() const; bool is_delay_agnostic_enabled() const;
bool is_extended_filter_enabled() const; bool is_extended_filter_enabled() const;
bool is_aec3_enabled() const; bool is_aec3_enabled() const;

View File

@ -91,14 +91,6 @@ struct RefinedAdaptiveFilter {
bool enabled; bool enabled;
}; };
// Enables the adaptive level controller.
struct LevelControl {
LevelControl() : enabled(false) {}
explicit LevelControl(bool enabled) : enabled(enabled) {}
static const ConfigOptionID identifier = ConfigOptionID::kLevelControl;
bool enabled;
};
// Enables delay-agnostic echo cancellation. This feature relies on internally // Enables delay-agnostic echo cancellation. This feature relies on internally
// estimated delays between the process and reverse streams, thus not relying // estimated delays between the process and reverse streams, thus not relying
// on reported system delays. This configuration only applies to // on reported system delays. This configuration only applies to
@ -205,6 +197,10 @@ struct Intelligibility {
// Usage example, omitting error checking: // Usage example, omitting error checking:
// AudioProcessing* apm = AudioProcessing::Create(0); // AudioProcessing* apm = AudioProcessing::Create(0);
// //
// AudioProcessing::Config config;
// config.level_controller.enabled = true;
// apm->ApplyConfig(config)
//
// apm->high_pass_filter()->Enable(true); // apm->high_pass_filter()->Enable(true);
// //
// apm->echo_cancellation()->enable_drift_compensation(false); // apm->echo_cancellation()->enable_drift_compensation(false);
@ -244,14 +240,29 @@ struct Intelligibility {
// //
class AudioProcessing { class AudioProcessing {
public: public:
// The struct below constitutes the new parameter scheme for the audio
// processing. It is being introduced gradually and until it is fully
// introduced, it is prone to change.
// TODO(peah): Remove this comment once the new config scheme is fully rolled
// out.
//
// The parameters and behavior of the audio processing module are controlled
// by changing the default values in the AudioProcessing::Config struct.
// The config is applied by passing the struct to the ApplyConfig method.
struct Config {
struct LevelController {
bool enabled = false;
} level_controller;
};
// TODO(mgraczyk): Remove once all methods that use ChannelLayout are gone. // TODO(mgraczyk): Remove once all methods that use ChannelLayout are gone.
enum ChannelLayout { enum ChannelLayout {
kMono, kMono,
// Left, right. // Left, right.
kStereo, kStereo,
// Mono, keyboard mic. // Mono, keyboard, and mic.
kMonoAndKeyboard, kMonoAndKeyboard,
// Left, right, keyboard mic. // Left, right, keyboard, and mic.
kStereoAndKeyboard kStereoAndKeyboard
}; };
@ -262,9 +273,9 @@ class AudioProcessing {
// be one instance for every incoming stream. // be one instance for every incoming stream.
static AudioProcessing* Create(); static AudioProcessing* Create();
// Allows passing in an optional configuration at create-time. // Allows passing in an optional configuration at create-time.
static AudioProcessing* Create(const Config& config); static AudioProcessing* Create(const webrtc::Config& config);
// Only for testing. // Only for testing.
static AudioProcessing* Create(const Config& config, static AudioProcessing* Create(const webrtc::Config& config,
NonlinearBeamformer* beamformer); NonlinearBeamformer* beamformer);
virtual ~AudioProcessing() {} virtual ~AudioProcessing() {}
@ -300,9 +311,13 @@ class AudioProcessing {
ChannelLayout output_layout, ChannelLayout output_layout,
ChannelLayout reverse_layout) = 0; ChannelLayout reverse_layout) = 0;
// TODO(peah): This method is a temporary solution used to take control
// over the parameters in the audio processing module and is likely to change.
virtual void ApplyConfig(const Config& config) = 0;
// Pass down additional options which don't have explicit setters. This // Pass down additional options which don't have explicit setters. This
// ensures the options are applied immediately. // ensures the options are applied immediately.
virtual void SetExtraOptions(const Config& config) = 0; virtual void SetExtraOptions(const webrtc::Config& config) = 0;
// TODO(ajm): Only intended for internal use. Make private and friend the // TODO(ajm): Only intended for internal use. Make private and friend the
// necessary classes? // necessary classes?

View File

@ -190,8 +190,8 @@ class MockAudioProcessing : public AudioProcessing {
ChannelLayout reverse_layout)); ChannelLayout reverse_layout));
MOCK_METHOD1(Initialize, MOCK_METHOD1(Initialize,
int(const ProcessingConfig& processing_config)); int(const ProcessingConfig& processing_config));
MOCK_METHOD1(SetExtraOptions, MOCK_METHOD1(ApplyConfig, void(const Config& config));
void(const Config& config)); MOCK_METHOD1(SetExtraOptions, void(const webrtc::Config& config));
MOCK_METHOD1(set_sample_rate_hz, MOCK_METHOD1(set_sample_rate_hz,
int(int rate)); int(int rate));
MOCK_CONST_METHOD0(input_sample_rate_hz, MOCK_CONST_METHOD0(input_sample_rate_hz,

View File

@ -262,4 +262,17 @@ void LevelController::Process(AudioBuffer* audio) {
audio->channels_f()[0], *sample_rate_hz_, 1); audio->channels_f()[0], *sample_rate_hz_, 1);
} }
std::string LevelController::ToString(
const AudioProcessing::Config::LevelController& config) {
std::stringstream ss;
ss << "{"
<< "enabled: " << (config.enabled ? "true" : "false") << "}";
return ss.str();
}
bool LevelController::Validate(
const AudioProcessing::Config::LevelController& config) {
return true;
}
} // namespace webrtc } // namespace webrtc

View File

@ -38,6 +38,12 @@ class LevelController {
void Process(AudioBuffer* audio); void Process(AudioBuffer* audio);
float GetLastGain() { return last_gain_; } float GetLastGain() { return last_gain_; }
// Validates a config.
static bool Validate(const AudioProcessing::Config::LevelController& config);
// Dumps a config to a string.
static std::string ToString(
const AudioProcessing::Config::LevelController& config);
private: private:
class Metrics { class Metrics {
public: public:

View File

@ -198,16 +198,18 @@ void RunTogetherWithApm(std::string test_description,
SubmodulePerformanceTimer capture_timer; SubmodulePerformanceTimer capture_timer;
SubmodulePerformanceTimer total_timer; SubmodulePerformanceTimer total_timer;
Config config; webrtc::Config config;
AudioProcessing::Config apm_config;
if (include_default_apm_processing) { if (include_default_apm_processing) {
config.Set<DelayAgnostic>(new DelayAgnostic(true)); config.Set<DelayAgnostic>(new DelayAgnostic(true));
config.Set<ExtendedFilter>(new ExtendedFilter(true)); config.Set<ExtendedFilter>(new ExtendedFilter(true));
} }
config.Set<LevelControl>(new LevelControl(true)); apm_config.level_controller.enabled = true;
std::unique_ptr<AudioProcessing> apm; std::unique_ptr<AudioProcessing> apm;
apm.reset(AudioProcessing::Create(config)); apm.reset(AudioProcessing::Create(config));
ASSERT_TRUE(apm.get()); ASSERT_TRUE(apm.get());
apm->ApplyConfig(apm_config);
ASSERT_EQ(AudioProcessing::kNoError, ASSERT_EQ(AudioProcessing::kNoError,
apm->gain_control()->Enable(include_default_apm_processing)); apm->gain_control()->Enable(include_default_apm_processing));

View File

@ -68,6 +68,25 @@ void RunBitexactnessTest(int sample_rate_hz,
} // namespace } // namespace
TEST(LevelControlConfigTest, ToStringEnabled) {
AudioProcessing::Config config;
config.level_controller.enabled = true;
EXPECT_EQ("{enabled: true}",
LevelController::ToString(config.level_controller));
}
TEST(LevelControlConfigTest, ToStringNotEnabled) {
AudioProcessing::Config config;
config.level_controller.enabled = false;
EXPECT_EQ("{enabled: false}",
LevelController::ToString(config.level_controller));
}
TEST(LevelControlConfigTest, DefaultValue) {
AudioProcessing::Config config;
EXPECT_FALSE(config.level_controller.enabled);
}
TEST(LevelControlBitExactnessTest, DISABLED_Mono8kHz) { TEST(LevelControlBitExactnessTest, DISABLED_Mono8kHz) {
const float kOutputReference[] = {-0.013939f, -0.012154f, -0.009054f}; const float kOutputReference[] = {-0.013939f, -0.012154f, -0.009054f};
RunBitexactnessTest(AudioProcessing::kSampleRate8kHz, 1, RunBitexactnessTest(AudioProcessing::kSampleRate8kHz, 1,

View File

@ -236,6 +236,7 @@ void AecDumpBasedSimulator::HandleMessage(
std::cout << "Setting used in config:" << std::endl; std::cout << "Setting used in config:" << std::endl;
} }
Config config; Config config;
AudioProcessing::Config apm_config;
if (msg.has_aec_enabled() || settings_.use_aec) { if (msg.has_aec_enabled() || settings_.use_aec) {
bool enable = settings_.use_aec ? *settings_.use_aec : msg.aec_enabled(); bool enable = settings_.use_aec ? *settings_.use_aec : msg.aec_enabled();
@ -442,9 +443,10 @@ void AecDumpBasedSimulator::HandleMessage(
} }
if (settings_.use_lc) { if (settings_.use_lc) {
config.Set<LevelControl>(new LevelControl(true)); apm_config.level_controller.enabled = true;
} }
ap_->ApplyConfig(apm_config);
ap_->SetExtraOptions(config); ap_->SetExtraOptions(config);
} }
} }

View File

@ -218,6 +218,7 @@ void AudioProcessingSimulator::DestroyAudioProcessor() {
void AudioProcessingSimulator::CreateAudioProcessor() { void AudioProcessingSimulator::CreateAudioProcessor() {
Config config; Config config;
AudioProcessing::Config apm_config;
if (settings_.use_bf && *settings_.use_bf) { if (settings_.use_bf && *settings_.use_bf) {
config.Set<Beamforming>(new Beamforming( config.Set<Beamforming>(new Beamforming(
true, ParseArrayGeometry(*settings_.microphone_positions), true, ParseArrayGeometry(*settings_.microphone_positions),
@ -234,7 +235,7 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
config.Set<EchoCanceller3>(new EchoCanceller3(*settings_.use_aec3)); config.Set<EchoCanceller3>(new EchoCanceller3(*settings_.use_aec3));
} }
if (settings_.use_lc) { if (settings_.use_lc) {
config.Set<LevelControl>(new LevelControl(true)); apm_config.level_controller.enabled = *settings_.use_lc;
} }
if (settings_.use_refined_adaptive_filter) { if (settings_.use_refined_adaptive_filter) {
config.Set<RefinedAdaptiveFilter>( config.Set<RefinedAdaptiveFilter>(
@ -246,6 +247,9 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
*settings_.use_delay_agnostic)); *settings_.use_delay_agnostic));
ap_.reset(AudioProcessing::Create(config)); ap_.reset(AudioProcessing::Create(config));
RTC_CHECK(ap_);
ap_->ApplyConfig(apm_config);
if (settings_.use_aec) { if (settings_.use_aec) {
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,

View File

@ -48,7 +48,8 @@ class DebugDumpGenerator {
const std::string& dump_file_name); const std::string& dump_file_name);
// Constructor that uses default input files. // Constructor that uses default input files.
explicit DebugDumpGenerator(const Config& config); explicit DebugDumpGenerator(const Config& config,
const AudioProcessing::Config& apm_config);
~DebugDumpGenerator(); ~DebugDumpGenerator();
@ -133,11 +134,18 @@ DebugDumpGenerator::DebugDumpGenerator(const std::string& input_file_name,
dump_file_name_(dump_file_name) { dump_file_name_(dump_file_name) {
} }
DebugDumpGenerator::DebugDumpGenerator(const Config& config) DebugDumpGenerator::DebugDumpGenerator(
: DebugDumpGenerator(ResourcePath("near32_stereo", "pcm"), 32000, 2, const Config& config,
ResourcePath("far32_stereo", "pcm"), 32000, 2, const AudioProcessing::Config& apm_config)
config, : DebugDumpGenerator(ResourcePath("near32_stereo", "pcm"),
TempFilename(OutputPath(), "debug_aec")) { 32000,
2,
ResourcePath("far32_stereo", "pcm"),
32000,
2,
config,
TempFilename(OutputPath(), "debug_aec")) {
apm_->ApplyConfig(apm_config);
} }
DebugDumpGenerator::~DebugDumpGenerator() { DebugDumpGenerator::~DebugDumpGenerator() {
@ -265,7 +273,7 @@ void DebugDumpTest::VerifyDebugDump(const std::string& in_filename) {
TEST_F(DebugDumpTest, SimpleCase) { TEST_F(DebugDumpTest, SimpleCase) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -274,7 +282,8 @@ TEST_F(DebugDumpTest, SimpleCase) {
TEST_F(DebugDumpTest, ChangeInputFormat) { TEST_F(DebugDumpTest, ChangeInputFormat) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.SetInputRate(48000); generator.SetInputRate(48000);
@ -291,7 +300,7 @@ TEST_F(DebugDumpTest, ChangeInputFormat) {
TEST_F(DebugDumpTest, ChangeReverseFormat) { TEST_F(DebugDumpTest, ChangeReverseFormat) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.SetReverseRate(48000); generator.SetReverseRate(48000);
@ -303,7 +312,7 @@ TEST_F(DebugDumpTest, ChangeReverseFormat) {
TEST_F(DebugDumpTest, ChangeOutputFormat) { TEST_F(DebugDumpTest, ChangeOutputFormat) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.SetOutputRate(48000); generator.SetOutputRate(48000);
@ -315,7 +324,7 @@ TEST_F(DebugDumpTest, ChangeOutputFormat) {
TEST_F(DebugDumpTest, ToggleAec) { TEST_F(DebugDumpTest, ToggleAec) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
@ -330,7 +339,7 @@ TEST_F(DebugDumpTest, ToggleAec) {
TEST_F(DebugDumpTest, ToggleDelayAgnosticAec) { TEST_F(DebugDumpTest, ToggleDelayAgnosticAec) {
Config config; Config config;
config.Set<DelayAgnostic>(new DelayAgnostic(true)); config.Set<DelayAgnostic>(new DelayAgnostic(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
@ -345,7 +354,7 @@ TEST_F(DebugDumpTest, ToggleDelayAgnosticAec) {
TEST_F(DebugDumpTest, VerifyRefinedAdaptiveFilterExperimentalString) { TEST_F(DebugDumpTest, VerifyRefinedAdaptiveFilterExperimentalString) {
Config config; Config config;
config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true)); config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -370,7 +379,7 @@ TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringInclusive) {
Config config; Config config;
config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true)); config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
config.Set<EchoCanceller3>(new EchoCanceller3(true)); config.Set<EchoCanceller3>(new EchoCanceller3(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -396,7 +405,7 @@ TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringInclusive) {
TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringExclusive) { TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringExclusive) {
Config config; Config config;
config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true)); config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -422,7 +431,7 @@ TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringExclusive) {
TEST_F(DebugDumpTest, VerifyAec3ExperimentalString) { TEST_F(DebugDumpTest, VerifyAec3ExperimentalString) {
Config config; Config config;
config.Set<EchoCanceller3>(new EchoCanceller3(true)); config.Set<EchoCanceller3>(new EchoCanceller3(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -445,8 +454,9 @@ TEST_F(DebugDumpTest, VerifyAec3ExperimentalString) {
TEST_F(DebugDumpTest, VerifyLevelControllerExperimentalString) { TEST_F(DebugDumpTest, VerifyLevelControllerExperimentalString) {
Config config; Config config;
config.Set<LevelControl>(new LevelControl(true)); AudioProcessing::Config apm_config;
DebugDumpGenerator generator(config); apm_config.level_controller.enabled = true;
DebugDumpGenerator generator(config, apm_config);
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -469,7 +479,7 @@ TEST_F(DebugDumpTest, VerifyLevelControllerExperimentalString) {
TEST_F(DebugDumpTest, VerifyEmptyExperimentalString) { TEST_F(DebugDumpTest, VerifyEmptyExperimentalString) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();
@ -491,7 +501,7 @@ TEST_F(DebugDumpTest, VerifyEmptyExperimentalString) {
TEST_F(DebugDumpTest, ToggleAecLevel) { TEST_F(DebugDumpTest, ToggleAecLevel) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
EchoCancellation* aec = generator.apm()->echo_cancellation(); EchoCancellation* aec = generator.apm()->echo_cancellation();
EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(true)); EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(true));
EXPECT_EQ(AudioProcessing::kNoError, EXPECT_EQ(AudioProcessing::kNoError,
@ -514,7 +524,7 @@ TEST_F(DebugDumpTest, ToggleAecLevel) {
#endif #endif
TEST_F(DebugDumpTest, MAYBE_ToggleAgc) { TEST_F(DebugDumpTest, MAYBE_ToggleAgc) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
@ -528,7 +538,7 @@ TEST_F(DebugDumpTest, MAYBE_ToggleAgc) {
TEST_F(DebugDumpTest, ToggleNs) { TEST_F(DebugDumpTest, ToggleNs) {
Config config; Config config;
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
@ -543,7 +553,7 @@ TEST_F(DebugDumpTest, ToggleNs) {
TEST_F(DebugDumpTest, TransientSuppressionOn) { TEST_F(DebugDumpTest, TransientSuppressionOn) {
Config config; Config config;
config.Set<ExperimentalNs>(new ExperimentalNs(true)); config.Set<ExperimentalNs>(new ExperimentalNs(true));
DebugDumpGenerator generator(config); DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording(); generator.StartRecording();
generator.Process(100); generator.Process(100);
generator.StopRecording(); generator.StopRecording();

View File

@ -177,6 +177,7 @@ void void_main(int argc, char* argv[]) {
int extra_delay_ms = 0; int extra_delay_ms = 0;
int override_delay_ms = 0; int override_delay_ms = 0;
Config config; Config config;
AudioProcessing::Config apm_config;
ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true)); ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
@ -262,8 +263,7 @@ void void_main(int argc, char* argv[]) {
suppression_level))); suppression_level)));
} else if (strcmp(argv[i], "--level_control") == 0) { } else if (strcmp(argv[i], "--level_control") == 0) {
config.Set<LevelControl>(new LevelControl(true)); apm_config.level_controller.enabled = true;
} else if (strcmp(argv[i], "--extended_filter") == 0) { } else if (strcmp(argv[i], "--extended_filter") == 0) {
config.Set<ExtendedFilter>(new ExtendedFilter(true)); config.Set<ExtendedFilter>(new ExtendedFilter(true));
@ -452,6 +452,7 @@ void void_main(int argc, char* argv[]) {
FAIL() << "Unrecognized argument " << argv[i]; FAIL() << "Unrecognized argument " << argv[i];
} }
} }
apm->ApplyConfig(apm_config);
apm->SetExtraOptions(config); apm->SetExtraOptions(config);
// If we're reading a protobuf file, ensure a simulation hasn't also // If we're reading a protobuf file, ensure a simulation hasn't also