| 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
|
| deleted file mode 100644
|
| index 8baa45606f5474c598ada890a2a4fb2a276e0540..0000000000000000000000000000000000000000
|
| --- a/webrtc/modules/audio_processing/aec3/echo_canceller3_unittest.cc
|
| +++ /dev/null
|
| @@ -1,717 +0,0 @@
|
| -/*
|
| - * 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/aec3/echo_canceller3.h"
|
| -
|
| -#include <deque>
|
| -#include <memory>
|
| -#include <sstream>
|
| -#include <string>
|
| -#include <utility>
|
| -#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/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;
|
| -using testing::_;
|
| -
|
| -// 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[kMaxNumBands][2 * kSubFrameLength];
|
| - float* reference_frame[kMaxNumBands];
|
| - 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) {}
|
| - ~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;
|
| - std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
|
| - block_processor_mock(
|
| - new StrictMock<webrtc::test::MockBlockProcessor>());
|
| - EXPECT_CALL(*block_processor_mock, BufferRender(_))
|
| - .Times(expected_num_block_to_process);
|
| - EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(_)).Times(0);
|
| -
|
| - switch (echo_path_change_test_variant) {
|
| - case EchoPathChangeTestVariant::kNone:
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _))
|
| - .Times(expected_num_block_to_process);
|
| - break;
|
| - case EchoPathChangeTestVariant::kOneSticky:
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _))
|
| - .Times(expected_num_block_to_process);
|
| - break;
|
| - case EchoPathChangeTestVariant::kOneNonSticky:
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _))
|
| - .Times(num_full_blocks_per_frame);
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _))
|
| - .Times(expected_num_block_to_process - num_full_blocks_per_frame);
|
| - break;
|
| - }
|
| -
|
| - EchoCanceller3 aec3(sample_rate_hz_, false,
|
| - std::move(block_processor_mock));
|
| -
|
| - 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;
|
| - std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
|
| - block_processor_mock(
|
| - new StrictMock<webrtc::test::MockBlockProcessor>());
|
| - EXPECT_CALL(*block_processor_mock, BufferRender(_))
|
| - .Times(expected_num_block_to_process);
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _))
|
| - .Times(expected_num_block_to_process);
|
| -
|
| - switch (leakage_report_variant) {
|
| - case EchoLeakageTestVariant::kNone:
|
| - EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(_)).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: {
|
| - testing::InSequence s;
|
| - EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(true)).Times(1);
|
| - EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(false))
|
| - .Times(kNumFramesToProcess - 1);
|
| - } break;
|
| - }
|
| -
|
| - EchoCanceller3 aec3(sample_rate_hz_, false,
|
| - std::move(block_processor_mock));
|
| -
|
| - 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;
|
| - std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
|
| - block_processor_mock(
|
| - new StrictMock<webrtc::test::MockBlockProcessor>());
|
| - EXPECT_CALL(*block_processor_mock, BufferRender(_))
|
| - .Times(expected_num_block_to_process);
|
| - EXPECT_CALL(*block_processor_mock, ReportEchoLeakage(_)).Times(0);
|
| -
|
| - switch (saturation_variant) {
|
| - case SaturationTestVariant::kNone:
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
|
| - .Times(expected_num_block_to_process);
|
| - break;
|
| - case SaturationTestVariant::kOneNegative: {
|
| - testing::InSequence s;
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _))
|
| - .Times(num_full_blocks_per_frame);
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
|
| - .Times(expected_num_block_to_process - num_full_blocks_per_frame);
|
| - } break;
|
| - case SaturationTestVariant::kOnePositive: {
|
| - testing::InSequence s;
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _))
|
| - .Times(num_full_blocks_per_frame);
|
| - EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
|
| - .Times(expected_num_block_to_process - num_full_blocks_per_frame);
|
| - } break;
|
| - }
|
| -
|
| - EchoCanceller3 aec3(sample_rate_hz_, false,
|
| - std::move(block_processor_mock));
|
| -
|
| - 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_));
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| -#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
| - // Verifies the that the check for the number of bands in the AnalyzeRender
|
| - // input is correct by adjusting the sample rates of EchoCanceller3 and the
|
| - // input AudioBuffer to have a different number of bands.
|
| - void RunAnalyzeRenderNumBandsCheckVerification() {
|
| - // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
|
| - // way that the number of bands for the rates are different.
|
| - const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
|
| - EchoCanceller3 aec3(aec3_sample_rate_hz, false);
|
| - PopulateInputFrame(frame_length_, num_bands_, 0,
|
| - &render_buffer_.split_bands_f(0)[0], 0);
|
| -
|
| - EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
|
| - }
|
| -
|
| - // Verifies the that the check for the number of bands in the ProcessCapture
|
| - // input is correct by adjusting the sample rates of EchoCanceller3 and the
|
| - // input AudioBuffer to have a different number of bands.
|
| - void RunProcessCaptureNumBandsCheckVerification() {
|
| - // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
|
| - // way that the number of bands for the rates are different.
|
| - const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
|
| - EchoCanceller3 aec3(aec3_sample_rate_hz, false);
|
| - PopulateInputFrame(frame_length_, num_bands_, 0,
|
| - &capture_buffer_.split_bands_f(0)[0], 100);
|
| - EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
|
| - }
|
| -
|
| - // Verifies the that the check for the frame length in the AnalyzeRender input
|
| - // is correct by adjusting the sample rates of EchoCanceller3 and the input
|
| - // AudioBuffer to have a different frame lengths.
|
| - void RunAnalyzeRenderFrameLengthCheckVerification() {
|
| - // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
|
| - // way that the band frame lengths are different.
|
| - const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000;
|
| - EchoCanceller3 aec3(aec3_sample_rate_hz, false);
|
| -
|
| - OptionalBandSplit();
|
| - PopulateInputFrame(frame_length_, num_bands_, 0,
|
| - &render_buffer_.split_bands_f(0)[0], 0);
|
| -
|
| - EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
|
| - }
|
| -
|
| - // Verifies the that the check for the frame length in the AnalyzeRender input
|
| - // is correct by adjusting the sample rates of EchoCanceller3 and the input
|
| - // AudioBuffer to have a different frame lengths.
|
| - void RunProcessCaptureFrameLengthCheckVerification() {
|
| - // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
|
| - // way that the band frame lengths are different.
|
| - const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000;
|
| - EchoCanceller3 aec3(aec3_sample_rate_hz, false);
|
| -
|
| - OptionalBandSplit();
|
| - PopulateInputFrame(frame_length_, num_bands_, 0,
|
| - &capture_buffer_.split_bands_f(0)[0], 100);
|
| -
|
| - EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
|
| - }
|
| -
|
| -#endif
|
| -
|
| - 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;
|
| - 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);
|
| - }
|
| - }
|
| -}
|
| -
|
| -#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
| -TEST(EchoCanceller3InputCheck, WrongRenderNumBandsCheckVerification) {
|
| - for (auto rate : {8000, 16000, 32000, 48000}) {
|
| - SCOPED_TRACE(ProduceDebugText(rate));
|
| - EchoCanceller3Tester(rate).RunAnalyzeRenderNumBandsCheckVerification();
|
| - }
|
| -}
|
| -
|
| -TEST(EchoCanceller3InputCheck, WrongCaptureNumBandsCheckVerification) {
|
| - for (auto rate : {8000, 16000, 32000, 48000}) {
|
| - SCOPED_TRACE(ProduceDebugText(rate));
|
| - EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
|
| - }
|
| -}
|
| -
|
| -TEST(EchoCanceller3InputCheck, WrongRenderFrameLengthCheckVerification) {
|
| - for (auto rate : {8000, 16000}) {
|
| - SCOPED_TRACE(ProduceDebugText(rate));
|
| - EchoCanceller3Tester(rate).RunAnalyzeRenderFrameLengthCheckVerification();
|
| - }
|
| -}
|
| -
|
| -TEST(EchoCanceller3InputCheck, WrongCaptureFrameLengthCheckVerification) {
|
| - for (auto rate : {8000, 16000}) {
|
| - SCOPED_TRACE(ProduceDebugText(rate));
|
| - EchoCanceller3Tester(rate).RunProcessCaptureFrameLengthCheckVerification();
|
| - }
|
| -}
|
| -
|
| -// Verifiers that the verification for null input to the render analysis api
|
| -// call works.
|
| -TEST(EchoCanceller3InputCheck, NullRenderAnalysisParameter) {
|
| - EXPECT_DEATH(EchoCanceller3(8000, false).AnalyzeRender(nullptr), "");
|
| -}
|
| -
|
| -// Verifiers that the verification for null input to the capture analysis api
|
| -// call works.
|
| -TEST(EchoCanceller3InputCheck, NullCaptureAnalysisParameter) {
|
| - EXPECT_DEATH(EchoCanceller3(8000, false).AnalyzeCapture(nullptr), "");
|
| -}
|
| -
|
| -// Verifiers that the verification for null input to the capture processing api
|
| -// call works.
|
| -TEST(EchoCanceller3InputCheck, NullCaptureProcessingParameter) {
|
| - EXPECT_DEATH(EchoCanceller3(8000, false).ProcessCapture(nullptr, false), "");
|
| -}
|
| -
|
| -#endif
|
| -
|
| -} // namespace webrtc
|
|
|