1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/aec3/block_processor.h"
12 
13 #include <memory>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 
18 #include "modules/audio_processing/aec3/aec3_common.h"
19 #include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
20 #include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
21 #include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
22 #include "modules/audio_processing/test/echo_canceller_test_tools.h"
23 #include "rtc_base/checks.h"
24 #include "rtc_base/random.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27 
28 namespace webrtc {
29 namespace {
30 
31 using testing::AtLeast;
32 using testing::Return;
33 using testing::StrictMock;
34 using testing::_;
35 
36 // Verifies that the basic BlockProcessor functionality works and that the API
37 // methods are callable.
RunBasicSetupAndApiCallTest(int sample_rate_hz)38 void RunBasicSetupAndApiCallTest(int sample_rate_hz) {
39   std::unique_ptr<BlockProcessor> block_processor(
40       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
41   std::vector<std::vector<float>> block(NumBandsForRate(sample_rate_hz),
42                                         std::vector<float>(kBlockSize, 0.f));
43 
44   block_processor->BufferRender(block);
45   block_processor->ProcessCapture(false, false, &block);
46   block_processor->UpdateEchoLeakageStatus(false);
47 }
48 
49 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
RunRenderBlockSizeVerificationTest(int sample_rate_hz)50 void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
51   std::unique_ptr<BlockProcessor> block_processor(
52       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
53   std::vector<std::vector<float>> block(
54       NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));
55 
56   EXPECT_DEATH(block_processor->BufferRender(block), "");
57 }
58 
RunCaptureBlockSizeVerificationTest(int sample_rate_hz)59 void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
60   std::unique_ptr<BlockProcessor> block_processor(
61       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
62   std::vector<std::vector<float>> block(
63       NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));
64 
65   EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
66 }
67 
RunRenderNumBandsVerificationTest(int sample_rate_hz)68 void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
69   const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
70                                      ? NumBandsForRate(sample_rate_hz) + 1
71                                      : 1;
72   std::unique_ptr<BlockProcessor> block_processor(
73       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
74   std::vector<std::vector<float>> block(wrong_num_bands,
75                                         std::vector<float>(kBlockSize, 0.f));
76 
77   EXPECT_DEATH(block_processor->BufferRender(block), "");
78 }
79 
RunCaptureNumBandsVerificationTest(int sample_rate_hz)80 void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
81   const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
82                                      ? NumBandsForRate(sample_rate_hz) + 1
83                                      : 1;
84   std::unique_ptr<BlockProcessor> block_processor(
85       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
86   std::vector<std::vector<float>> block(wrong_num_bands,
87                                         std::vector<float>(kBlockSize, 0.f));
88 
89   EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
90 }
91 #endif
92 
ProduceDebugText(int sample_rate_hz)93 std::string ProduceDebugText(int sample_rate_hz) {
94   std::ostringstream ss;
95   ss << "Sample rate: " << sample_rate_hz;
96   return ss.str();
97 }
98 
99 }  // namespace
100 
101 // Verifies that the delay controller functionality is properly integrated with
102 // the render delay buffer inside block processor.
103 // TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor,DISABLED_DelayControllerIntegration)104 TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
105   constexpr size_t kNumBlocks = 310;
106   constexpr size_t kDelayInSamples = 640;
107   constexpr size_t kDelayHeadroom = 1;
108   constexpr size_t kDelayInBlocks =
109       kDelayInSamples / kBlockSize - kDelayHeadroom;
110   Random random_generator(42U);
111   for (auto rate : {8000, 16000, 32000, 48000}) {
112     SCOPED_TRACE(ProduceDebugText(rate));
113     std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
114         render_delay_buffer_mock(
115             new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
116     EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
117         .Times(kNumBlocks)
118         .WillRepeatedly(Return(true));
119     EXPECT_CALL(*render_delay_buffer_mock, IsBlockAvailable())
120         .Times(kNumBlocks)
121         .WillRepeatedly(Return(true));
122     EXPECT_CALL(*render_delay_buffer_mock, SetDelay(kDelayInBlocks))
123         .Times(AtLeast(1));
124     EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
125     EXPECT_CALL(*render_delay_buffer_mock, Delay())
126         .Times(kNumBlocks + 1)
127         .WillRepeatedly(Return(0));
128     std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
129         EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock)));
130 
131     std::vector<std::vector<float>> render_block(
132         NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
133     std::vector<std::vector<float>> capture_block(
134         NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
135     DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
136     for (size_t k = 0; k < kNumBlocks; ++k) {
137       RandomizeSampleVector(&random_generator, render_block[0]);
138       signal_delay_buffer.Delay(render_block[0], capture_block[0]);
139       block_processor->BufferRender(render_block);
140       block_processor->ProcessCapture(false, false, &capture_block);
141     }
142   }
143 }
144 
145 // Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor,DISABLED_SubmoduleIntegration)146 TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
147   constexpr size_t kNumBlocks = 310;
148   Random random_generator(42U);
149   for (auto rate : {8000, 16000, 32000, 48000}) {
150     SCOPED_TRACE(ProduceDebugText(rate));
151     std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
152         render_delay_buffer_mock(
153             new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
154     std::unique_ptr<
155         testing::StrictMock<webrtc::test::MockRenderDelayController>>
156         render_delay_controller_mock(
157             new StrictMock<webrtc::test::MockRenderDelayController>());
158     std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
159         echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());
160 
161     EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
162         .Times(kNumBlocks - 1)
163         .WillRepeatedly(Return(true));
164     EXPECT_CALL(*render_delay_buffer_mock, IsBlockAvailable())
165         .Times(kNumBlocks)
166         .WillRepeatedly(Return(true));
167     EXPECT_CALL(*render_delay_buffer_mock, UpdateBuffers()).Times(kNumBlocks);
168     EXPECT_CALL(*render_delay_buffer_mock, SetDelay(9)).Times(AtLeast(1));
169     EXPECT_CALL(*render_delay_buffer_mock, Delay())
170         .Times(kNumBlocks)
171         .WillRepeatedly(Return(0));
172     EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _))
173         .Times(kNumBlocks)
174         .WillRepeatedly(Return(9));
175     EXPECT_CALL(*render_delay_controller_mock, AlignmentHeadroomSamples())
176         .Times(kNumBlocks);
177     EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _, _))
178         .Times(kNumBlocks);
179     EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
180         .Times(kNumBlocks);
181 
182     std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
183         EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock),
184         std::move(render_delay_controller_mock), std::move(echo_remover_mock)));
185 
186     std::vector<std::vector<float>> render_block(
187         NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
188     std::vector<std::vector<float>> capture_block(
189         NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
190     DelayBuffer<float> signal_delay_buffer(640);
191     for (size_t k = 0; k < kNumBlocks; ++k) {
192       RandomizeSampleVector(&random_generator, render_block[0]);
193       signal_delay_buffer.Delay(render_block[0], capture_block[0]);
194       block_processor->BufferRender(render_block);
195       block_processor->ProcessCapture(false, false, &capture_block);
196       block_processor->UpdateEchoLeakageStatus(false);
197     }
198   }
199 }
200 
TEST(BlockProcessor,BasicSetupAndApiCalls)201 TEST(BlockProcessor, BasicSetupAndApiCalls) {
202   for (auto rate : {8000, 16000, 32000, 48000}) {
203     SCOPED_TRACE(ProduceDebugText(rate));
204     RunBasicSetupAndApiCallTest(rate);
205   }
206 }
207 
208 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
209 // TODO(gustaf): Re-enable the test once the issue with memory leaks during
210 // DEATH tests on test bots has been fixed.
TEST(BlockProcessor,DISABLED_VerifyRenderBlockSizeCheck)211 TEST(BlockProcessor, DISABLED_VerifyRenderBlockSizeCheck) {
212   for (auto rate : {8000, 16000, 32000, 48000}) {
213     SCOPED_TRACE(ProduceDebugText(rate));
214     RunRenderBlockSizeVerificationTest(rate);
215   }
216 }
217 
TEST(BlockProcessor,VerifyCaptureBlockSizeCheck)218 TEST(BlockProcessor, VerifyCaptureBlockSizeCheck) {
219   for (auto rate : {8000, 16000, 32000, 48000}) {
220     SCOPED_TRACE(ProduceDebugText(rate));
221     RunCaptureBlockSizeVerificationTest(rate);
222   }
223 }
224 
TEST(BlockProcessor,VerifyRenderNumBandsCheck)225 TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
226   for (auto rate : {8000, 16000, 32000, 48000}) {
227     SCOPED_TRACE(ProduceDebugText(rate));
228     RunRenderNumBandsVerificationTest(rate);
229   }
230 }
231 
232 // TODO(peah): Verify the check for correct number of bands in the capture
233 // signal.
TEST(BlockProcessor,VerifyCaptureNumBandsCheck)234 TEST(BlockProcessor, VerifyCaptureNumBandsCheck) {
235   for (auto rate : {8000, 16000, 32000, 48000}) {
236     SCOPED_TRACE(ProduceDebugText(rate));
237     RunCaptureNumBandsVerificationTest(rate);
238   }
239 }
240 
241 // Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessor,NullProcessCaptureParameter)242 TEST(BlockProcessor, NullProcessCaptureParameter) {
243   EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
244                    BlockProcessor::Create(EchoCanceller3Config(), 8000))
245                    ->ProcessCapture(false, false, nullptr),
246                "");
247 }
248 
249 // Verifies the check for correct sample rate.
250 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
251 // tests on test bots has been fixed.
TEST(BlockProcessor,DISABLED_WrongSampleRate)252 TEST(BlockProcessor, DISABLED_WrongSampleRate) {
253   EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
254                    BlockProcessor::Create(EchoCanceller3Config(), 8001)),
255                "");
256 }
257 
258 #endif
259 
260 }  // namespace webrtc
261