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 <string>
15 #include <vector>
16 
17 #include "modules/audio_processing/aec3/aec3_common.h"
18 #include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
19 #include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
20 #include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
21 #include "modules/audio_processing/test/echo_canceller_test_tools.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/random.h"
24 #include "rtc_base/strings/string_builder.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27 
28 namespace webrtc {
29 namespace {
30 
31 using ::testing::_;
32 using ::testing::AtLeast;
33 using ::testing::Return;
34 using ::testing::StrictMock;
35 
36 // Verifies that the basic BlockProcessor functionality works and that the API
37 // methods are callable.
RunBasicSetupAndApiCallTest(int sample_rate_hz,int num_iterations)38 void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
39   constexpr size_t kNumRenderChannels = 1;
40   constexpr size_t kNumCaptureChannels = 1;
41 
42   std::unique_ptr<BlockProcessor> block_processor(
43       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
44                              kNumRenderChannels, kNumCaptureChannels));
45   std::vector<std::vector<std::vector<float>>> block(
46       NumBandsForRate(sample_rate_hz),
47       std::vector<std::vector<float>>(kNumRenderChannels,
48                                       std::vector<float>(kBlockSize, 1000.f)));
49   for (int k = 0; k < num_iterations; ++k) {
50     block_processor->BufferRender(block);
51     block_processor->ProcessCapture(false, false, nullptr, &block);
52     block_processor->UpdateEchoLeakageStatus(false);
53   }
54 }
55 
56 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
RunRenderBlockSizeVerificationTest(int sample_rate_hz)57 void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
58   constexpr size_t kNumRenderChannels = 1;
59   constexpr size_t kNumCaptureChannels = 1;
60 
61   std::unique_ptr<BlockProcessor> block_processor(
62       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
63                              kNumRenderChannels, kNumCaptureChannels));
64   std::vector<std::vector<std::vector<float>>> block(
65       NumBandsForRate(sample_rate_hz),
66       std::vector<std::vector<float>>(kNumRenderChannels,
67                                       std::vector<float>(kBlockSize - 1, 0.f)));
68 
69   EXPECT_DEATH(block_processor->BufferRender(block), "");
70 }
71 
RunCaptureBlockSizeVerificationTest(int sample_rate_hz)72 void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
73   constexpr size_t kNumRenderChannels = 1;
74   constexpr size_t kNumCaptureChannels = 1;
75 
76   std::unique_ptr<BlockProcessor> block_processor(
77       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
78                              kNumRenderChannels, kNumCaptureChannels));
79   std::vector<std::vector<std::vector<float>>> block(
80       NumBandsForRate(sample_rate_hz),
81       std::vector<std::vector<float>>(kNumRenderChannels,
82                                       std::vector<float>(kBlockSize - 1, 0.f)));
83 
84   EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
85                "");
86 }
87 
RunRenderNumBandsVerificationTest(int sample_rate_hz)88 void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
89   constexpr size_t kNumRenderChannels = 1;
90   constexpr size_t kNumCaptureChannels = 1;
91 
92   const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
93                                      ? NumBandsForRate(sample_rate_hz) + 1
94                                      : 1;
95   std::unique_ptr<BlockProcessor> block_processor(
96       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
97                              kNumRenderChannels, kNumCaptureChannels));
98   std::vector<std::vector<std::vector<float>>> block(
99       wrong_num_bands,
100       std::vector<std::vector<float>>(kNumRenderChannels,
101                                       std::vector<float>(kBlockSize, 0.f)));
102 
103   EXPECT_DEATH(block_processor->BufferRender(block), "");
104 }
105 
RunCaptureNumBandsVerificationTest(int sample_rate_hz)106 void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
107   constexpr size_t kNumRenderChannels = 1;
108   constexpr size_t kNumCaptureChannels = 1;
109 
110   const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
111                                      ? NumBandsForRate(sample_rate_hz) + 1
112                                      : 1;
113   std::unique_ptr<BlockProcessor> block_processor(
114       BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
115                              kNumRenderChannels, kNumCaptureChannels));
116   std::vector<std::vector<std::vector<float>>> block(
117       wrong_num_bands,
118       std::vector<std::vector<float>>(kNumRenderChannels,
119                                       std::vector<float>(kBlockSize, 0.f)));
120 
121   EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
122                "");
123 }
124 #endif
125 
ProduceDebugText(int sample_rate_hz)126 std::string ProduceDebugText(int sample_rate_hz) {
127   rtc::StringBuilder ss;
128   ss << "Sample rate: " << sample_rate_hz;
129   return ss.Release();
130 }
131 
132 }  // namespace
133 
134 // Verifies that the delay controller functionality is properly integrated with
135 // the render delay buffer inside block processor.
136 // TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor,DISABLED_DelayControllerIntegration)137 TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
138   constexpr size_t kNumRenderChannels = 1;
139   constexpr size_t kNumCaptureChannels = 1;
140   constexpr size_t kNumBlocks = 310;
141   constexpr size_t kDelayInSamples = 640;
142   constexpr size_t kDelayHeadroom = 1;
143   constexpr size_t kDelayInBlocks =
144       kDelayInSamples / kBlockSize - kDelayHeadroom;
145   Random random_generator(42U);
146   for (auto rate : {16000, 32000, 48000}) {
147     SCOPED_TRACE(ProduceDebugText(rate));
148     std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
149         render_delay_buffer_mock(
150             new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
151     EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
152         .Times(kNumBlocks)
153         .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
154     EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(kDelayInBlocks))
155         .Times(AtLeast(1));
156     EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
157     EXPECT_CALL(*render_delay_buffer_mock, Delay())
158         .Times(kNumBlocks + 1)
159         .WillRepeatedly(Return(0));
160     std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
161         EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
162         std::move(render_delay_buffer_mock)));
163 
164     std::vector<std::vector<std::vector<float>>> render_block(
165         NumBandsForRate(rate),
166         std::vector<std::vector<float>>(kNumRenderChannels,
167                                         std::vector<float>(kBlockSize, 0.f)));
168     std::vector<std::vector<std::vector<float>>> capture_block(
169         NumBandsForRate(rate),
170         std::vector<std::vector<float>>(kNumCaptureChannels,
171                                         std::vector<float>(kBlockSize, 0.f)));
172     DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
173     for (size_t k = 0; k < kNumBlocks; ++k) {
174       RandomizeSampleVector(&random_generator, render_block[0][0]);
175       signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
176       block_processor->BufferRender(render_block);
177       block_processor->ProcessCapture(false, false, nullptr, &capture_block);
178     }
179   }
180 }
181 
182 // Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor,DISABLED_SubmoduleIntegration)183 TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
184   constexpr size_t kNumBlocks = 310;
185   constexpr size_t kNumRenderChannels = 1;
186   constexpr size_t kNumCaptureChannels = 1;
187 
188   Random random_generator(42U);
189   for (auto rate : {16000, 32000, 48000}) {
190     SCOPED_TRACE(ProduceDebugText(rate));
191     std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
192         render_delay_buffer_mock(
193             new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
194     std::unique_ptr<
195         ::testing::StrictMock<webrtc::test::MockRenderDelayController>>
196         render_delay_controller_mock(
197             new StrictMock<webrtc::test::MockRenderDelayController>());
198     std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
199         echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());
200 
201     EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
202         .Times(kNumBlocks - 1)
203         .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
204     EXPECT_CALL(*render_delay_buffer_mock, PrepareCaptureProcessing())
205         .Times(kNumBlocks);
206     EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(9)).Times(AtLeast(1));
207     EXPECT_CALL(*render_delay_buffer_mock, Delay())
208         .Times(kNumBlocks)
209         .WillRepeatedly(Return(0));
210     EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _, _))
211         .Times(kNumBlocks);
212     EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _, _, _))
213         .Times(kNumBlocks);
214     EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
215         .Times(kNumBlocks);
216 
217     std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
218         EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
219         std::move(render_delay_buffer_mock),
220         std::move(render_delay_controller_mock), std::move(echo_remover_mock)));
221 
222     std::vector<std::vector<std::vector<float>>> render_block(
223         NumBandsForRate(rate),
224         std::vector<std::vector<float>>(kNumRenderChannels,
225                                         std::vector<float>(kBlockSize, 0.f)));
226     std::vector<std::vector<std::vector<float>>> capture_block(
227         NumBandsForRate(rate),
228         std::vector<std::vector<float>>(kNumCaptureChannels,
229                                         std::vector<float>(kBlockSize, 0.f)));
230     DelayBuffer<float> signal_delay_buffer(640);
231     for (size_t k = 0; k < kNumBlocks; ++k) {
232       RandomizeSampleVector(&random_generator, render_block[0][0]);
233       signal_delay_buffer.Delay(render_block[0][0], capture_block[0][0]);
234       block_processor->BufferRender(render_block);
235       block_processor->ProcessCapture(false, false, nullptr, &capture_block);
236       block_processor->UpdateEchoLeakageStatus(false);
237     }
238   }
239 }
240 
TEST(BlockProcessor,BasicSetupAndApiCalls)241 TEST(BlockProcessor, BasicSetupAndApiCalls) {
242   for (auto rate : {16000, 32000, 48000}) {
243     SCOPED_TRACE(ProduceDebugText(rate));
244     RunBasicSetupAndApiCallTest(rate, 1);
245   }
246 }
247 
TEST(BlockProcessor,TestLongerCall)248 TEST(BlockProcessor, TestLongerCall) {
249   RunBasicSetupAndApiCallTest(16000, 20 * kNumBlocksPerSecond);
250 }
251 
252 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
253 // TODO(gustaf): Re-enable the test once the issue with memory leaks during
254 // DEATH tests on test bots has been fixed.
TEST(BlockProcessorDeathTest,DISABLED_VerifyRenderBlockSizeCheck)255 TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
256   for (auto rate : {16000, 32000, 48000}) {
257     SCOPED_TRACE(ProduceDebugText(rate));
258     RunRenderBlockSizeVerificationTest(rate);
259   }
260 }
261 
TEST(BlockProcessorDeathTest,VerifyCaptureBlockSizeCheck)262 TEST(BlockProcessorDeathTest, VerifyCaptureBlockSizeCheck) {
263   for (auto rate : {16000, 32000, 48000}) {
264     SCOPED_TRACE(ProduceDebugText(rate));
265     RunCaptureBlockSizeVerificationTest(rate);
266   }
267 }
268 
TEST(BlockProcessorDeathTest,VerifyRenderNumBandsCheck)269 TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
270   for (auto rate : {16000, 32000, 48000}) {
271     SCOPED_TRACE(ProduceDebugText(rate));
272     RunRenderNumBandsVerificationTest(rate);
273   }
274 }
275 
276 // TODO(peah): Verify the check for correct number of bands in the capture
277 // signal.
TEST(BlockProcessorDeathTest,VerifyCaptureNumBandsCheck)278 TEST(BlockProcessorDeathTest, VerifyCaptureNumBandsCheck) {
279   for (auto rate : {16000, 32000, 48000}) {
280     SCOPED_TRACE(ProduceDebugText(rate));
281     RunCaptureNumBandsVerificationTest(rate);
282   }
283 }
284 
285 // Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessorDeathTest,NullProcessCaptureParameter)286 TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
287   EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
288                    BlockProcessor::Create(EchoCanceller3Config(), 16000, 1, 1))
289                    ->ProcessCapture(false, false, nullptr, nullptr),
290                "");
291 }
292 
293 // Verifies the check for correct sample rate.
294 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
295 // tests on test bots has been fixed.
TEST(BlockProcessor,DISABLED_WrongSampleRate)296 TEST(BlockProcessor, DISABLED_WrongSampleRate) {
297   EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
298                    BlockProcessor::Create(EchoCanceller3Config(), 8001, 1, 1)),
299                "");
300 }
301 
302 #endif
303 
304 }  // namespace webrtc
305