Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2238)

Unified Diff: webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc

Issue 2584493002: Added first layer of the echo canceller 3 functionality (Closed)
Patch Set: Minor changes Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc
diff --git a/webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc b/webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d738ef3714f5ae8330ecb224d3ca5f7792354b22
--- /dev/null
+++ b/webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc
@@ -0,0 +1,613 @@
+/*
+ * 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 <deque>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "webrtc/modules/audio_processing/aec3/aec3_constants.h"
+#include "webrtc/modules/audio_processing/aec3/block_processor.h"
+#include "webrtc/modules/audio_processing/aec3/echo_canceller3.h"
hlundin-webrtc 2016/12/22 10:23:57 This goes to the top.
peah-webrtc 2016/12/22 16:40:04 Done.
+#include "webrtc/modules/audio_processing/aec3/frame_blocker.h"
+#include "webrtc/modules/audio_processing/aec3/mock/mock_block_processor.h"
+#include "webrtc/modules/audio_processing/audio_buffer.h"
+#include "webrtc/test/gmock.h"
+#include "webrtc/test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+using testing::StrictMock;
+
+// Populates the frame with linearly increasing sample values for each band,
+// with a band-specific offset, in order to allow simple bitexactness
+// verification for each band.
+void PopulateInputFrame(size_t frame_length,
+ size_t num_bands,
+ size_t frame_index,
+ float* const* frame,
+ int offset) {
+ for (size_t k = 0; k < num_bands; ++k) {
+ for (size_t i = 0; i < frame_length; ++i) {
+ float value = static_cast<int>(frame_index * frame_length + i) + offset;
+ frame[k][i] = (value > 0 ? 5000 * k + value : 0);
+ }
+ }
+}
+
+// Verifies the that samples in the output frame are identical to the samples
+// that were produced for the input frame, with an offset in order to compensate
+// for buffering delays.
+bool VerifyOutputFrameBitexactness(size_t frame_length,
+ size_t num_bands,
+ size_t frame_index,
+ const float* const* frame,
+ int offset) {
+ float reference_frame_data[num_bands][frame_length];
+ float* reference_frame[num_bands];
+ for (size_t k = 0; k < num_bands; ++k) {
+ reference_frame[k] = &reference_frame_data[k][0];
+ }
+
+ PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
+ offset);
+ for (size_t k = 0; k < num_bands; ++k) {
+ for (size_t i = 0; i < frame_length; ++i) {
+ if (reference_frame[k][i] != frame[k][i]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// Class for testing that the capture data is properly received by the block
+// processor and that the processor data is properly passed to the
+// EchoCanceller3 output.
+class CaptureTransportVerificationProcessor : public BlockProcessor {
+ public:
+ explicit CaptureTransportVerificationProcessor(size_t num_bands) {}
hlundin-webrtc 2016/12/22 10:23:57 = defualt?
peah-webrtc 2016/12/22 16:40:04 That does not seem to work (the compiler says "onl
+ ~CaptureTransportVerificationProcessor() override = default;
+
+ void ProcessCapture(bool known_echo_path_change,
+ bool saturated_microphone_signal,
+ std::vector<std::vector<float>>* capture_block) override {
+ }
+
+ bool BufferRender(std::vector<std::vector<float>>* block) override {
+ return false;
+ }
+
+ void ReportEchoLeakage(bool leakage_detected) override {}
+
+ private:
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTransportVerificationProcessor);
+};
+
+// Class for testing that the render data is properly received by the block
+// processor.
+class RenderTransportVerificationProcessor : public BlockProcessor {
+ public:
+ explicit RenderTransportVerificationProcessor(size_t num_bands) {}
+ ~RenderTransportVerificationProcessor() override = default;
+
+ void ProcessCapture(bool known_echo_path_change,
+ bool saturated_microphone_signal,
+ std::vector<std::vector<float>>* capture_block) override {
+ std::vector<std::vector<float>> render_block =
+ received_render_blocks_.front();
+ received_render_blocks_.pop_front();
+ capture_block->swap(render_block);
+ }
+
+ bool BufferRender(std::vector<std::vector<float>>* block) override {
+ received_render_blocks_.push_back(*block);
+ return false;
+ }
+
+ void ReportEchoLeakage(bool leakage_detected) override {}
+
+ private:
+ std::deque<std::vector<std::vector<float>>> received_render_blocks_;
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderTransportVerificationProcessor);
+};
+
+class EchoCanceller3Tester {
+ public:
+ explicit EchoCanceller3Tester(int sample_rate_hz)
+ : sample_rate_hz_(sample_rate_hz),
+ num_bands_(NumBandsForRate(sample_rate_hz_)),
+ frame_length_(sample_rate_hz_ == 8000 ? 80 : 160),
+ fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
+ capture_buffer_(fullband_frame_length_,
+ 1,
+ fullband_frame_length_,
+ 1,
+ fullband_frame_length_),
+ render_buffer_(fullband_frame_length_,
+ 1,
+ fullband_frame_length_,
+ 1,
+ fullband_frame_length_) {}
+
+ // Verifies that the capture data is properly received by the block processor
+ // and that the processor data is properly passed to the EchoCanceller3
+ // output.
+ void RunCaptureTransportVerificationTest() {
+ EchoCanceller3 aec3(
+ sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(
+ new CaptureTransportVerificationProcessor(num_bands_)));
+
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ aec3.AnalyzeCapture(&capture_buffer_);
+ OptionalBandSplit();
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 0);
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 100);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ aec3.ProcessCapture(&capture_buffer_, false);
+ EXPECT_TRUE(VerifyOutputFrameBitexactness(
+ frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], -64));
+ }
+ }
+
+ // Test method for testing that the render data is properly received by the
+ // block processor.
+ void RunRenderTransportVerificationTest() {
+ EchoCanceller3 aec3(
+ sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(
+ new RenderTransportVerificationProcessor(num_bands_)));
+
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ aec3.AnalyzeCapture(&capture_buffer_);
+ OptionalBandSplit();
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 100);
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ aec3.ProcessCapture(&capture_buffer_, false);
+ EXPECT_TRUE(VerifyOutputFrameBitexactness(
+ frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], -64));
+ }
+ }
+
+ // Verifies that information about echo path changes are properly propagated
+ // to the block processor.
+ // The cases tested are:
+ // -That no set echo path change flags are received when there is no echo path
+ // change.
+ // -That set echo path change flags are received and continues to be received
+ // as long as echo path changes are flagged.
+ // -That set echo path change flags are no longer received when echo path
+ // change events stop being flagged.
+ enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
+
+ void RunEchoPathChangeVerificationTest(
+ EchoPathChangeTestVariant echo_path_change_test_variant) {
+ const size_t num_full_blocks_per_frame =
+ rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100) / kBlockSize;
+ const size_t expected_num_block_to_process =
+ (kNumFramesToProcess *
+ rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
+ kBlockSize;
+ testing::StrictMock<webrtc::test::MockBlockProcessor>*
+ block_processor_mock =
+ new StrictMock<webrtc::test::MockBlockProcessor>();
+ EXPECT_CALL(*block_processor_mock, BufferRender(testing::_))
hlundin-webrtc 2016/12/22 10:23:57 Add a using testing::_ and simplify all of these t
peah-webrtc 2016/12/22 16:40:04 Great suggestion! Done.
+ .Times(expected_num_block_to_process);
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(testing::_)).Times(0);
+
+ switch (echo_path_change_test_variant) {
+ case EchoPathChangeTestVariant::kNone:
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(false, testing::_, testing::_))
+ .Times(expected_num_block_to_process);
+ break;
+ case EchoPathChangeTestVariant::kOneSticky:
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(true, testing::_, testing::_))
+ .Times(expected_num_block_to_process);
+ break;
+ case EchoPathChangeTestVariant::kOneNonSticky:
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(true, testing::_, testing::_))
+ .Times(num_full_blocks_per_frame);
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(false, testing::_, testing::_))
+ .Times(expected_num_block_to_process - num_full_blocks_per_frame);
+ break;
+ }
+
+ EchoCanceller3 aec3(sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(block_processor_mock));
+ block_processor_mock = nullptr;
hlundin-webrtc 2016/12/22 10:23:56 Looks like you want to make block_processor_mock a
peah-webrtc 2016/12/22 16:40:04 Thanks! That's much better! Done.
+
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ bool echo_path_change = false;
+ switch (echo_path_change_test_variant) {
+ case EchoPathChangeTestVariant::kNone:
+ break;
+ case EchoPathChangeTestVariant::kOneSticky:
+ echo_path_change = true;
+ break;
+ case EchoPathChangeTestVariant::kOneNonSticky:
+ if (frame_index == 0) {
+ echo_path_change = true;
+ }
+ break;
+ }
+
+ aec3.AnalyzeCapture(&capture_buffer_);
+ OptionalBandSplit();
+
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 0);
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ aec3.ProcessCapture(&capture_buffer_, echo_path_change);
+ }
+ }
+
+ // Test for verifying that echo leakage information is being properly passed
+ // to the processor.
+ // The cases tested are:
+ // -That no method calls are received when they should not.
+ // -That false values are received each time they are flagged.
+ // -That true values are received each time they are flagged.
+ // -That a false value is received when flagged after a true value has been
+ // flagged.
+ enum class EchoLeakageTestVariant {
+ kNone,
+ kFalseSticky,
+ kTrueSticky,
+ kTrueNonSticky
+ };
+
+ void RunEchoLeakageVerificationTest(
+ EchoLeakageTestVariant leakage_report_variant) {
+ const size_t expected_num_block_to_process =
+ (kNumFramesToProcess *
+ rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
+ kBlockSize;
+ testing::StrictMock<webrtc::test::MockBlockProcessor>*
+ block_processor_mock =
+ new StrictMock<webrtc::test::MockBlockProcessor>();
+ EXPECT_CALL(*block_processor_mock, BufferRender(testing::_))
+ .Times(expected_num_block_to_process);
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(testing::_, testing::_, testing::_))
+ .Times(expected_num_block_to_process);
+
+ switch (leakage_report_variant) {
+ case EchoLeakageTestVariant::kNone:
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(testing::_))
+ .Times(0);
+ break;
+ case EchoLeakageTestVariant::kFalseSticky:
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(false)).Times(1);
+ break;
+ case EchoLeakageTestVariant::kTrueSticky:
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(true)).Times(1);
+ break;
+ case EchoLeakageTestVariant::kTrueNonSticky:
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(true)).Times(1);
hlundin-webrtc 2016/12/22 10:23:56 I think you will want to enforce the order of the
peah-webrtc 2016/12/22 16:40:04 Great point! Thanks! Done.
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(false))
+ .Times(kNumFramesToProcess - 1);
+ break;
+ }
+
+ EchoCanceller3 aec3(sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(block_processor_mock));
+ block_processor_mock = nullptr;
hlundin-webrtc 2016/12/22 10:23:57 Same here.
peah-webrtc 2016/12/22 16:40:04 Done.
+
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ switch (leakage_report_variant) {
+ case EchoLeakageTestVariant::kNone:
+ break;
+ case EchoLeakageTestVariant::kFalseSticky:
+ if (frame_index == 0) {
+ aec3.ReportEchoLeakage(false);
+ }
+ break;
+ case EchoLeakageTestVariant::kTrueSticky:
+ if (frame_index == 0) {
+ aec3.ReportEchoLeakage(true);
+ }
+ break;
+ case EchoLeakageTestVariant::kTrueNonSticky:
+ if (frame_index == 0) {
+ aec3.ReportEchoLeakage(true);
+ } else {
+ aec3.ReportEchoLeakage(false);
+ }
+ break;
+ }
+
+ aec3.AnalyzeCapture(&capture_buffer_);
+ OptionalBandSplit();
+
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 0);
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ aec3.ProcessCapture(&capture_buffer_, false);
+ }
+ }
+
+ // This verifies that saturation information is properly passed to the
+ // BlockProcessor.
+ // The cases tested are:
+ // -That no saturation event is passed to the processor if there is no
+ // saturation.
+ // -That one frame with one negative saturated sample value is reported to be
+ // saturated and that following non-saturated frames are properly reported as
+ // not being saturated.
+ // -That one frame with one positive saturated sample value is reported to be
+ // saturated and that following non-saturated frames are properly reported as
+ // not being saturated.
+ enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
+
+ void RunCaptureSaturationVerificationTest(
+ SaturationTestVariant saturation_variant) {
+ const size_t num_full_blocks_per_frame =
+ rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100) / kBlockSize;
+ const size_t expected_num_block_to_process =
+ (kNumFramesToProcess *
+ rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
+ kBlockSize;
+ testing::StrictMock<webrtc::test::MockBlockProcessor>*
+ block_processor_mock =
+ new StrictMock<webrtc::test::MockBlockProcessor>();
+ EXPECT_CALL(*block_processor_mock, BufferRender(testing::_))
+ .Times(expected_num_block_to_process);
+ EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(testing::_)).Times(0);
+
+ switch (saturation_variant) {
+ case SaturationTestVariant::kNone:
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(testing::_, false, testing::_))
+ .Times(expected_num_block_to_process);
+ break;
+ case SaturationTestVariant::kOneNegative:
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(testing::_, true, testing::_))
+ .Times(num_full_blocks_per_frame);
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(testing::_, false, testing::_))
+ .Times(expected_num_block_to_process - num_full_blocks_per_frame);
+ break;
+ case SaturationTestVariant::kOnePositive:
+ EXPECT_CALL(*block_processor_mock,
hlundin-webrtc 2016/12/22 10:23:56 Enforce order here too.
peah-webrtc 2016/12/22 16:40:04 Done.
+ ProcessCapture(testing::_, true, testing::_))
+ .Times(num_full_blocks_per_frame);
+ EXPECT_CALL(*block_processor_mock,
+ ProcessCapture(testing::_, false, testing::_))
+ .Times(expected_num_block_to_process - num_full_blocks_per_frame);
+ break;
+ }
+
+ EchoCanceller3 aec3(sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(block_processor_mock));
+ block_processor_mock = nullptr;
hlundin-webrtc 2016/12/22 10:23:57 unique_ptr
peah-webrtc 2016/12/22 16:40:04 Done.
+
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ for (int k = 0; k < fullband_frame_length_; ++k) {
+ capture_buffer_.channels_f()[0][k] = 0.f;
+ }
+ switch (saturation_variant) {
+ case SaturationTestVariant::kNone:
+ break;
+ case SaturationTestVariant::kOneNegative:
+ if (frame_index == 0) {
+ capture_buffer_.channels_f()[0][10] = -32768.f;
+ }
+ break;
+ case SaturationTestVariant::kOnePositive:
+ if (frame_index == 0) {
+ capture_buffer_.channels_f()[0][10] = 32767.f;
+ }
+ break;
+ }
+
+ aec3.AnalyzeCapture(&capture_buffer_);
+ OptionalBandSplit();
+
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 0);
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ aec3.ProcessCapture(&capture_buffer_, false);
+ }
+ }
+
+ // This test verifies that the swapqueue is able to handle jitter in the
+ // capture and render API calls.
+ void RunRenderSwapQueueVerificationTest() {
+ EchoCanceller3 aec3(
+ sample_rate_hz_, false,
+ std::unique_ptr<BlockProcessor>(
+ new RenderTransportVerificationProcessor(num_bands_)));
+
+ constexpr size_t kSwapQueueLength = 30;
+ for (size_t frame_index = 0; frame_index < kSwapQueueLength;
+ ++frame_index) {
+ if (sample_rate_hz_ > 16000) {
+ render_buffer_.SplitIntoFrequencyBands();
+ }
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ }
+
+ for (size_t frame_index = 0; frame_index < kSwapQueueLength;
+ ++frame_index) {
+ aec3.AnalyzeCapture(&capture_buffer_);
+ if (sample_rate_hz_ > 16000) {
+ capture_buffer_.SplitIntoFrequencyBands();
+ }
+
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], 0);
+
+ aec3.ProcessCapture(&capture_buffer_, false);
+ EXPECT_TRUE(VerifyOutputFrameBitexactness(
+ frame_length_, num_bands_, frame_index,
+ &capture_buffer_.split_bands_f(0)[0], -64));
+ }
+ }
+
+ // This test verifies that a buffer overrun in the render swapqueue is
+ // properly reported.
+ void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
+ EchoCanceller3 aec3(sample_rate_hz_, false);
+
+ constexpr size_t kSwapQueueLength = 30;
+ for (size_t k = 0; k < 2; ++k) {
+ for (size_t frame_index = 0; frame_index < kSwapQueueLength;
+ ++frame_index) {
+ if (sample_rate_hz_ > 16000) {
+ render_buffer_.SplitIntoFrequencyBands();
+ }
+ PopulateInputFrame(frame_length_, num_bands_, frame_index,
+ &render_buffer_.split_bands_f(0)[0], 0);
+
+ if (k == 0) {
+ EXPECT_TRUE(aec3.AnalyzeRender(&render_buffer_));
+ } else {
+ EXPECT_FALSE(aec3.AnalyzeRender(&render_buffer_));
+ }
+ }
+ }
+ }
+
+ private:
+ void OptionalBandSplit() {
+ if (sample_rate_hz_ > 16000) {
+ capture_buffer_.SplitIntoFrequencyBands();
+ render_buffer_.SplitIntoFrequencyBands();
+ }
+ }
+
+ static constexpr size_t kNumFramesToProcess = 20;
+ const int sample_rate_hz_;
+ const size_t num_bands_;
+ const size_t frame_length_;
+ const int fullband_frame_length_;
+ AudioBuffer capture_buffer_;
+ AudioBuffer render_buffer_;
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCanceller3Tester);
+};
+
+std::string ProduceDebugText(int sample_rate_hz) {
+ std::ostringstream ss;
hlundin-webrtc 2016/12/22 10:23:57 Won't you have to #include something?
peah-webrtc 2016/12/22 16:40:04 Good find! It must have been indirectly included.
+ ss << "Sample rate: " << sample_rate_hz;
+ return ss.str();
+}
+
+std::string ProduceDebugText(int sample_rate_hz, int variant) {
+ std::ostringstream ss;
+ ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
+ return ss.str();
+}
+
+} // namespace
+
+TEST(EchoCanceller3Buffering, CaptureBitexactness) {
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ SCOPED_TRACE(ProduceDebugText(rate));
+ EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
+ }
+}
+
+TEST(EchoCanceller3Buffering, RenderBitexactness) {
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ SCOPED_TRACE(ProduceDebugText(rate));
+ EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
+ }
+}
+
+TEST(EchoCanceller3Buffering, RenderSwapQueue) {
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ SCOPED_TRACE(ProduceDebugText(rate));
+ EchoCanceller3Tester(rate).RunRenderSwapQueueVerificationTest();
+ }
+}
+
+TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ SCOPED_TRACE(ProduceDebugText(rate));
+ EchoCanceller3Tester(rate)
+ .RunRenderPipelineSwapQueueOverrunReturnValueTest();
+ }
+}
+
+TEST(EchoCanceller3Messaging, CaptureSaturation) {
+ auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
+ EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
+ EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ for (auto variant : variants) {
+ SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
+ EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
+ }
+ }
+}
+
+TEST(EchoCanceller3Messaging, EchoPathChange) {
+ auto variants = {
+ EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
+ EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
+ EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ for (auto variant : variants) {
+ SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
+ EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
+ }
+ }
+}
+
+TEST(EchoCanceller3Messaging, EchoLeakage) {
+ auto variants = {
+ EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
+ EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
+ EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
+ EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ for (auto variant : variants) {
+ SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
+ EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
+ }
+ }
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698