From 0de1c1374c4dba65ade1ec96f839dbd5bc620e3e Mon Sep 17 00:00:00 2001 From: minyue Date: Thu, 17 Mar 2016 02:39:30 -0700 Subject: [PATCH] Adding DebugDumpReplayer. It would be good to have a dedicated DebugDumpReplayer. There is one but it hides itself in DebugDumpTest. This CL is to separate it out. BUG= Review URL: https://codereview.webrtc.org/1810463002 Cr-Commit-Position: refs/heads/master@{#12029} --- .../test/debug_dump_replayer.cc | 266 ++++++++++++++++++ .../test/debug_dump_replayer.h | 73 +++++ .../audio_processing/test/debug_dump_test.cc | 249 ++-------------- webrtc/modules/modules.gyp | 2 + 4 files changed, 362 insertions(+), 228 deletions(-) create mode 100644 webrtc/modules/audio_processing/test/debug_dump_replayer.cc create mode 100644 webrtc/modules/audio_processing/test/debug_dump_replayer.h diff --git a/webrtc/modules/audio_processing/test/debug_dump_replayer.cc b/webrtc/modules/audio_processing/test/debug_dump_replayer.cc new file mode 100644 index 0000000000..fc127e610e --- /dev/null +++ b/webrtc/modules/audio_processing/test/debug_dump_replayer.cc @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2016 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 "webrtc/modules/audio_processing/test/debug_dump_replayer.h" + +#include "webrtc/base/checks.h" +#include "webrtc/modules/audio_processing/test/protobuf_utils.h" + + +namespace webrtc { +namespace test { + +namespace { + +void MaybeResetBuffer(std::unique_ptr>* buffer, + const StreamConfig& config) { + auto& buffer_ref = *buffer; + if (!buffer_ref.get() || buffer_ref->num_frames() != config.num_frames() || + buffer_ref->num_channels() != config.num_channels()) { + buffer_ref.reset(new ChannelBuffer(config.num_frames(), + config.num_channels())); + } +} + +} // namespace + +DebugDumpReplayer::DebugDumpReplayer() + : input_(nullptr), // will be created upon usage. + reverse_(nullptr), + output_(nullptr), + apm_(nullptr), + debug_file_(nullptr) {} + +DebugDumpReplayer::~DebugDumpReplayer() { + if (debug_file_) + fclose(debug_file_); +} + +bool DebugDumpReplayer::SetDumpFile(const std::string& filename) { + debug_file_ = fopen(filename.c_str(), "rb"); + LoadNextMessage(); + return debug_file_; +} + +// Get next event that has not run. +rtc::Optional DebugDumpReplayer::GetNextEvent() const { + if (!has_next_event_) + return rtc::Optional(); + else + return rtc::Optional(next_event_); +} + +// Run the next event. Returns the event type. +bool DebugDumpReplayer::RunNextEvent() { + if (!has_next_event_) + return false; + switch (next_event_.type()) { + case audioproc::Event::INIT: + OnInitEvent(next_event_.init()); + break; + case audioproc::Event::STREAM: + OnStreamEvent(next_event_.stream()); + break; + case audioproc::Event::REVERSE_STREAM: + OnReverseStreamEvent(next_event_.reverse_stream()); + break; + case audioproc::Event::CONFIG: + OnConfigEvent(next_event_.config()); + break; + case audioproc::Event::UNKNOWN_EVENT: + // We do not expect to receive UNKNOWN event. + return false; + } + LoadNextMessage(); + return true; +} + +const ChannelBuffer* DebugDumpReplayer::GetOutput() const { + return output_.get(); +} + +StreamConfig DebugDumpReplayer::GetOutputConfig() const { + return output_config_; +} + +// OnInitEvent reset the input/output/reserve channel format. +void DebugDumpReplayer::OnInitEvent(const audioproc::Init& msg) { + RTC_CHECK(msg.has_num_input_channels()); + RTC_CHECK(msg.has_output_sample_rate()); + RTC_CHECK(msg.has_num_output_channels()); + RTC_CHECK(msg.has_reverse_sample_rate()); + RTC_CHECK(msg.has_num_reverse_channels()); + + input_config_ = StreamConfig(msg.sample_rate(), msg.num_input_channels()); + output_config_ = + StreamConfig(msg.output_sample_rate(), msg.num_output_channels()); + reverse_config_ = + StreamConfig(msg.reverse_sample_rate(), msg.num_reverse_channels()); + + MaybeResetBuffer(&input_, input_config_); + MaybeResetBuffer(&output_, output_config_); + MaybeResetBuffer(&reverse_, reverse_config_); +} + +// OnStreamEvent replays an input signal and verifies the output. +void DebugDumpReplayer::OnStreamEvent(const audioproc::Stream& msg) { + // APM should have been created. + RTC_CHECK(apm_.get()); + + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->gain_control()->set_stream_analog_level(msg.level())); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->set_stream_delay_ms(msg.delay())); + + apm_->echo_cancellation()->set_stream_drift_samples(msg.drift()); + if (msg.has_keypress()) { + apm_->set_stream_key_pressed(msg.keypress()); + } else { + apm_->set_stream_key_pressed(true); + } + + RTC_CHECK_EQ(input_config_.num_channels(), + static_cast(msg.input_channel_size())); + RTC_CHECK_EQ(input_config_.num_frames() * sizeof(float), + msg.input_channel(0).size()); + + for (int i = 0; i < msg.input_channel_size(); ++i) { + memcpy(input_->channels()[i], msg.input_channel(i).data(), + msg.input_channel(i).size()); + } + + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->ProcessStream(input_->channels(), input_config_, + output_config_, output_->channels())); +} + +void DebugDumpReplayer::OnReverseStreamEvent( + const audioproc::ReverseStream& msg) { + // APM should have been created. + RTC_CHECK(apm_.get()); + + RTC_CHECK_GT(msg.channel_size(), 0); + RTC_CHECK_EQ(reverse_config_.num_channels(), + static_cast(msg.channel_size())); + RTC_CHECK_EQ(reverse_config_.num_frames() * sizeof(float), + msg.channel(0).size()); + + for (int i = 0; i < msg.channel_size(); ++i) { + memcpy(reverse_->channels()[i], msg.channel(i).data(), + msg.channel(i).size()); + } + + RTC_CHECK_EQ( + AudioProcessing::kNoError, + apm_->ProcessReverseStream(reverse_->channels(), reverse_config_, + reverse_config_, reverse_->channels())); +} + +void DebugDumpReplayer::OnConfigEvent(const audioproc::Config& msg) { + MaybeRecreateApm(msg); + ConfigureApm(msg); +} + +void DebugDumpReplayer::MaybeRecreateApm(const audioproc::Config& msg) { + // These configurations cannot be changed on the fly. + Config config; + RTC_CHECK(msg.has_aec_delay_agnostic_enabled()); + config.Set( + new DelayAgnostic(msg.aec_delay_agnostic_enabled())); + + RTC_CHECK(msg.has_noise_robust_agc_enabled()); + config.Set( + new ExperimentalAgc(msg.noise_robust_agc_enabled())); + + RTC_CHECK(msg.has_transient_suppression_enabled()); + config.Set( + new ExperimentalNs(msg.transient_suppression_enabled())); + + RTC_CHECK(msg.has_aec_extended_filter_enabled()); + config.Set( + new ExtendedFilter(msg.aec_extended_filter_enabled())); + + // We only create APM once, since changes on these fields should not + // happen in current implementation. + if (!apm_.get()) { + apm_.reset(AudioProcessing::Create(config)); + } +} + +void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) { + // AEC configs. + RTC_CHECK(msg.has_aec_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_cancellation()->Enable(msg.aec_enabled())); + + RTC_CHECK(msg.has_aec_drift_compensation_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_cancellation()->enable_drift_compensation( + msg.aec_drift_compensation_enabled())); + + RTC_CHECK(msg.has_aec_suppression_level()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_cancellation()->set_suppression_level( + static_cast( + msg.aec_suppression_level()))); + + // AECM configs. + RTC_CHECK(msg.has_aecm_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_control_mobile()->Enable(msg.aecm_enabled())); + + RTC_CHECK(msg.has_aecm_comfort_noise_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_control_mobile()->enable_comfort_noise( + msg.aecm_comfort_noise_enabled())); + + RTC_CHECK(msg.has_aecm_routing_mode()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->echo_control_mobile()->set_routing_mode( + static_cast( + msg.aecm_routing_mode()))); + + // AGC configs. + RTC_CHECK(msg.has_agc_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->gain_control()->Enable(msg.agc_enabled())); + + RTC_CHECK(msg.has_agc_mode()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->gain_control()->set_mode( + static_cast(msg.agc_mode()))); + + RTC_CHECK(msg.has_agc_limiter_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->gain_control()->enable_limiter(msg.agc_limiter_enabled())); + + // HPF configs. + RTC_CHECK(msg.has_hpf_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->high_pass_filter()->Enable(msg.hpf_enabled())); + + // NS configs. + RTC_CHECK(msg.has_ns_enabled()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->noise_suppression()->Enable(msg.ns_enabled())); + + RTC_CHECK(msg.has_ns_level()); + RTC_CHECK_EQ(AudioProcessing::kNoError, + apm_->noise_suppression()->set_level( + static_cast(msg.ns_level()))); +} + +void DebugDumpReplayer::LoadNextMessage() { + has_next_event_ = + debug_file_ && ReadMessageFromFile(debug_file_, &next_event_); +} + +} // namespace test +} // namespace webrtc diff --git a/webrtc/modules/audio_processing/test/debug_dump_replayer.h b/webrtc/modules/audio_processing/test/debug_dump_replayer.h new file mode 100644 index 0000000000..09022542d9 --- /dev/null +++ b/webrtc/modules/audio_processing/test/debug_dump_replayer.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 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 WEBRTC_MODULES_AUDIO_PROCESSING_TEST_DEBUG_DUMP_REPLAYER_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_TEST_DEBUG_DUMP_REPLAYER_H_ + +#include +#include + +#include "webrtc/common_audio/channel_buffer.h" +#include "webrtc/modules/audio_processing/debug.pb.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" + +namespace webrtc { +namespace test { + +class DebugDumpReplayer { + public: + DebugDumpReplayer(); + ~DebugDumpReplayer(); + + // Set dump file + bool SetDumpFile(const std::string& filename); + + // Return next event. + rtc::Optional GetNextEvent() const; + + // Run the next event. Returns true if succeeded. + bool RunNextEvent(); + + const ChannelBuffer* GetOutput() const; + StreamConfig GetOutputConfig() const; + + private: + // Following functions are facilities for replaying debug dumps. + void OnInitEvent(const audioproc::Init& msg); + void OnStreamEvent(const audioproc::Stream& msg); + void OnReverseStreamEvent(const audioproc::ReverseStream& msg); + void OnConfigEvent(const audioproc::Config& msg); + + void MaybeRecreateApm(const audioproc::Config& msg); + void ConfigureApm(const audioproc::Config& msg); + + void LoadNextMessage(); + + // Buffer for APM input/output. + std::unique_ptr> input_; + std::unique_ptr> reverse_; + std::unique_ptr> output_; + + std::unique_ptr apm_; + + FILE* debug_file_; + + StreamConfig input_config_; + StreamConfig reverse_config_; + StreamConfig output_config_; + + bool has_next_event_; + audioproc::Event next_event_; +}; + +} // namespace test +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_TEST_DEBUG_DUMP_REPLAYER_H_ diff --git a/webrtc/modules/audio_processing/test/debug_dump_test.cc b/webrtc/modules/audio_processing/test/debug_dump_test.cc index 6ca82a4d43..06ec63bcdb 100644 --- a/webrtc/modules/audio_processing/test/debug_dump_test.cc +++ b/webrtc/modules/audio_processing/test/debug_dump_test.cc @@ -10,20 +10,16 @@ #include // size_t -#include #include #include #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/checks.h" -#include "webrtc/common_audio/channel_buffer.h" #include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h" -#include "webrtc/modules/audio_processing/debug.pb.h" -#include "webrtc/modules/audio_processing/include/audio_processing.h" -#include "webrtc/modules/audio_processing/test/protobuf_utils.h" +#include "webrtc/modules/audio_processing/test/debug_dump_replayer.h" #include "webrtc/modules/audio_processing/test/test_utils.h" #include "webrtc/test/testsupport/fileutils.h" + namespace webrtc { namespace test { @@ -233,240 +229,37 @@ void DebugDumpGenerator::ReadAndDeinterleave(ResampleInputAudioFile* audio, class DebugDumpTest : public ::testing::Test { public: - DebugDumpTest(); - // VerifyDebugDump replays a debug dump using APM and verifies that the result // is bit-exact-identical to the output channel in the dump. This is only // guaranteed if the debug dump is started on the first frame. void VerifyDebugDump(const std::string& dump_file_name); private: - // Following functions are facilities for replaying debug dumps. - void OnInitEvent(const audioproc::Init& msg); - void OnStreamEvent(const audioproc::Stream& msg); - void OnReverseStreamEvent(const audioproc::ReverseStream& msg); - void OnConfigEvent(const audioproc::Config& msg); - - void MaybeRecreateApm(const audioproc::Config& msg); - void ConfigureApm(const audioproc::Config& msg); - - // Buffer for APM input/output. - std::unique_ptr> input_; - std::unique_ptr> reverse_; - std::unique_ptr> output_; - - std::unique_ptr apm_; - - StreamConfig input_config_; - StreamConfig reverse_config_; - StreamConfig output_config_; + DebugDumpReplayer debug_dump_replayer_; }; -DebugDumpTest::DebugDumpTest() - : input_(nullptr), // will be created upon usage. - reverse_(nullptr), - output_(nullptr), - apm_(nullptr) { -} - void DebugDumpTest::VerifyDebugDump(const std::string& in_filename) { - FILE* in_file = fopen(in_filename.c_str(), "rb"); - ASSERT_TRUE(in_file); - audioproc::Event event_msg; + ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(in_filename)); - while (ReadMessageFromFile(in_file, &event_msg)) { - switch (event_msg.type()) { - case audioproc::Event::INIT: - OnInitEvent(event_msg.init()); - break; - case audioproc::Event::STREAM: - OnStreamEvent(event_msg.stream()); - break; - case audioproc::Event::REVERSE_STREAM: - OnReverseStreamEvent(event_msg.reverse_stream()); - break; - case audioproc::Event::CONFIG: - OnConfigEvent(event_msg.config()); - break; - case audioproc::Event::UNKNOWN_EVENT: - // We do not expect receive UNKNOWN event currently. - FAIL(); + if (const rtc::Optional event = + debug_dump_replayer_.GetNextEvent()) { + debug_dump_replayer_.RunNextEvent(); + if (event->type() == audioproc::Event::STREAM) { + const audioproc::Stream* msg = &event->stream(); + const StreamConfig output_config = debug_dump_replayer_.GetOutputConfig(); + const ChannelBuffer* output = debug_dump_replayer_.GetOutput(); + // Check that output of APM is bit-exact to the output in the dump. + ASSERT_EQ(output_config.num_channels(), + static_cast(msg->output_channel_size())); + ASSERT_EQ(output_config.num_frames() * sizeof(float), + msg->output_channel(0).size()); + for (int i = 0; i < msg->output_channel_size(); ++i) { + ASSERT_EQ(0, memcmp(output->channels()[i], + msg->output_channel(i).data(), + msg->output_channel(i).size())); + } } } - fclose(in_file); -} - -// OnInitEvent reset the input/output/reserve channel format. -void DebugDumpTest::OnInitEvent(const audioproc::Init& msg) { - ASSERT_TRUE(msg.has_num_input_channels()); - ASSERT_TRUE(msg.has_output_sample_rate()); - ASSERT_TRUE(msg.has_num_output_channels()); - ASSERT_TRUE(msg.has_reverse_sample_rate()); - ASSERT_TRUE(msg.has_num_reverse_channels()); - - input_config_ = StreamConfig(msg.sample_rate(), msg.num_input_channels()); - output_config_ = - StreamConfig(msg.output_sample_rate(), msg.num_output_channels()); - reverse_config_ = - StreamConfig(msg.reverse_sample_rate(), msg.num_reverse_channels()); - - MaybeResetBuffer(&input_, input_config_); - MaybeResetBuffer(&output_, output_config_); - MaybeResetBuffer(&reverse_, reverse_config_); -} - -// OnStreamEvent replays an input signal and verifies the output. -void DebugDumpTest::OnStreamEvent(const audioproc::Stream& msg) { - // APM should have been created. - ASSERT_TRUE(apm_.get()); - - EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(msg.level())); - EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay())); - apm_->echo_cancellation()->set_stream_drift_samples(msg.drift()); - if (msg.has_keypress()) - apm_->set_stream_key_pressed(msg.keypress()); - else - apm_->set_stream_key_pressed(true); - - ASSERT_EQ(input_config_.num_channels(), - static_cast(msg.input_channel_size())); - ASSERT_EQ(input_config_.num_frames() * sizeof(float), - msg.input_channel(0).size()); - - for (int i = 0; i < msg.input_channel_size(); ++i) { - memcpy(input_->channels()[i], msg.input_channel(i).data(), - msg.input_channel(i).size()); - } - - ASSERT_EQ(AudioProcessing::kNoError, - apm_->ProcessStream(input_->channels(), input_config_, - output_config_, output_->channels())); - - // Check that output of APM is bit-exact to the output in the dump. - ASSERT_EQ(output_config_.num_channels(), - static_cast(msg.output_channel_size())); - ASSERT_EQ(output_config_.num_frames() * sizeof(float), - msg.output_channel(0).size()); - for (int i = 0; i < msg.output_channel_size(); ++i) { - ASSERT_EQ(0, memcmp(output_->channels()[i], msg.output_channel(i).data(), - msg.output_channel(i).size())); - } -} - -void DebugDumpTest::OnReverseStreamEvent(const audioproc::ReverseStream& msg) { - // APM should have been created. - ASSERT_TRUE(apm_.get()); - - ASSERT_GT(msg.channel_size(), 0); - ASSERT_EQ(reverse_config_.num_channels(), - static_cast(msg.channel_size())); - ASSERT_EQ(reverse_config_.num_frames() * sizeof(float), - msg.channel(0).size()); - - for (int i = 0; i < msg.channel_size(); ++i) { - memcpy(reverse_->channels()[i], msg.channel(i).data(), - msg.channel(i).size()); - } - - ASSERT_EQ(AudioProcessing::kNoError, - apm_->ProcessReverseStream(reverse_->channels(), - reverse_config_, - reverse_config_, - reverse_->channels())); -} - -void DebugDumpTest::OnConfigEvent(const audioproc::Config& msg) { - MaybeRecreateApm(msg); - ConfigureApm(msg); -} - -void DebugDumpTest::MaybeRecreateApm(const audioproc::Config& msg) { - // These configurations cannot be changed on the fly. - Config config; - ASSERT_TRUE(msg.has_aec_delay_agnostic_enabled()); - config.Set( - new DelayAgnostic(msg.aec_delay_agnostic_enabled())); - - ASSERT_TRUE(msg.has_noise_robust_agc_enabled()); - config.Set( - new ExperimentalAgc(msg.noise_robust_agc_enabled())); - - ASSERT_TRUE(msg.has_transient_suppression_enabled()); - config.Set( - new ExperimentalNs(msg.transient_suppression_enabled())); - - ASSERT_TRUE(msg.has_aec_extended_filter_enabled()); - config.Set(new ExtendedFilter( - msg.aec_extended_filter_enabled())); - - // We only create APM once, since changes on these fields should not - // happen in current implementation. - if (!apm_.get()) { - apm_.reset(AudioProcessing::Create(config)); - } -} - -void DebugDumpTest::ConfigureApm(const audioproc::Config& msg) { - // AEC configs. - ASSERT_TRUE(msg.has_aec_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_cancellation()->Enable(msg.aec_enabled())); - - ASSERT_TRUE(msg.has_aec_drift_compensation_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_cancellation()->enable_drift_compensation( - msg.aec_drift_compensation_enabled())); - - ASSERT_TRUE(msg.has_aec_suppression_level()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_cancellation()->set_suppression_level( - static_cast( - msg.aec_suppression_level()))); - - // AECM configs. - ASSERT_TRUE(msg.has_aecm_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_control_mobile()->Enable(msg.aecm_enabled())); - - ASSERT_TRUE(msg.has_aecm_comfort_noise_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_control_mobile()->enable_comfort_noise( - msg.aecm_comfort_noise_enabled())); - - ASSERT_TRUE(msg.has_aecm_routing_mode()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->echo_control_mobile()->set_routing_mode( - static_cast( - msg.aecm_routing_mode()))); - - // AGC configs. - ASSERT_TRUE(msg.has_agc_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->gain_control()->Enable(msg.agc_enabled())); - - ASSERT_TRUE(msg.has_agc_mode()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->gain_control()->set_mode( - static_cast(msg.agc_mode()))); - - ASSERT_TRUE(msg.has_agc_limiter_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->gain_control()->enable_limiter(msg.agc_limiter_enabled())); - - // HPF configs. - ASSERT_TRUE(msg.has_hpf_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->high_pass_filter()->Enable(msg.hpf_enabled())); - - // NS configs. - ASSERT_TRUE(msg.has_ns_enabled()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->noise_suppression()->Enable(msg.ns_enabled())); - - ASSERT_TRUE(msg.has_ns_level()); - EXPECT_EQ(AudioProcessing::kNoError, - apm_->noise_suppression()->set_level( - static_cast(msg.ns_level()))); } TEST_F(DebugDumpTest, SimpleCase) { diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index bad2cb496a..5abf6afc65 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -444,6 +444,8 @@ 'audio_processing/test/audio_buffer_tools.cc', 'audio_processing/test/audio_buffer_tools.h', 'audio_processing/test/audio_processing_unittest.cc', + 'audio_processing/test/debug_dump_replayer.cc', + 'audio_processing/test/debug_dump_replayer.h', 'audio_processing/test/debug_dump_test.cc', 'audio_processing/test/test_utils.h', ],