blob: e9a16d06d5602b9c3561dc02c561b83ece0a9b76 [file] [log] [blame]
peahd0263542017-01-03 04:20:34 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/aec3/block_framer.h"
peahd0263542017-01-03 04:20:34 -080012
peahd0263542017-01-03 04:20:34 -080013#include <string>
14#include <vector>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/audio_processing/aec3/aec3_common.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020017#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "test/gtest.h"
peahd0263542017-01-03 04:20:34 -080019
20namespace webrtc {
21namespace {
22
Per Åhgrence202a02019-09-02 17:01:19 +020023void SetupSubFrameView(
24 std::vector<std::vector<std::vector<float>>>* sub_frame,
25 std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
26 for (size_t band = 0; band < sub_frame_view->size(); ++band) {
27 for (size_t channel = 0; channel < (*sub_frame_view)[band].size();
28 ++channel) {
29 (*sub_frame_view)[band][channel] =
30 rtc::ArrayView<float>((*sub_frame)[band][channel].data(),
31 (*sub_frame)[band][channel].size());
32 }
peahd0263542017-01-03 04:20:34 -080033 }
34}
35
36float ComputeSampleValue(size_t chunk_counter,
37 size_t chunk_size,
38 size_t band,
Per Åhgrence202a02019-09-02 17:01:19 +020039 size_t channel,
peahd0263542017-01-03 04:20:34 -080040 size_t sample_index,
41 int offset) {
Per Åhgrence202a02019-09-02 17:01:19 +020042 float value = static_cast<int>(100 + chunk_counter * chunk_size +
43 sample_index + channel) +
44 offset;
45 return 5000 * band + value;
peahd0263542017-01-03 04:20:34 -080046}
47
Per Åhgrence202a02019-09-02 17:01:19 +020048bool VerifySubFrame(
49 size_t sub_frame_counter,
50 int offset,
51 const std::vector<std::vector<rtc::ArrayView<float>>>& sub_frame_view) {
52 for (size_t band = 0; band < sub_frame_view.size(); ++band) {
53 for (size_t channel = 0; channel < sub_frame_view[band].size(); ++channel) {
54 for (size_t sample = 0; sample < sub_frame_view[band][channel].size();
55 ++sample) {
56 const float reference_value = ComputeSampleValue(
57 sub_frame_counter, kSubFrameLength, band, channel, sample, offset);
58 if (reference_value != sub_frame_view[band][channel][sample]) {
59 return false;
60 }
peahd0263542017-01-03 04:20:34 -080061 }
62 }
63 }
64 return true;
65}
66
Per Åhgrence202a02019-09-02 17:01:19 +020067void FillBlock(size_t block_counter,
68 std::vector<std::vector<std::vector<float>>>* block) {
69 for (size_t band = 0; band < block->size(); ++band) {
70 for (size_t channel = 0; channel < (*block)[band].size(); ++channel) {
71 for (size_t sample = 0; sample < (*block)[band][channel].size();
72 ++sample) {
73 (*block)[band][channel][sample] = ComputeSampleValue(
74 block_counter, kBlockSize, band, channel, sample, 0);
75 }
peahd0263542017-01-03 04:20:34 -080076 }
77 }
78}
79
80// Verifies that the BlockFramer is able to produce the expected frame content.
Per Åhgrence202a02019-09-02 17:01:19 +020081void RunFramerTest(int sample_rate_hz, size_t num_channels) {
82 constexpr size_t kNumSubFramesToProcess = 10;
peahd0263542017-01-03 04:20:34 -080083 const size_t num_bands = NumBandsForRate(sample_rate_hz);
84
Per Åhgrence202a02019-09-02 17:01:19 +020085 std::vector<std::vector<std::vector<float>>> block(
86 num_bands, std::vector<std::vector<float>>(
87 num_channels, std::vector<float>(kBlockSize, 0.f)));
88 std::vector<std::vector<std::vector<float>>> output_sub_frame(
89 num_bands, std::vector<std::vector<float>>(
90 num_channels, std::vector<float>(kSubFrameLength, 0.f)));
91 std::vector<std::vector<rtc::ArrayView<float>>> output_sub_frame_view(
92 num_bands, std::vector<rtc::ArrayView<float>>(num_channels));
peahd0263542017-01-03 04:20:34 -080093 SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
Per Åhgrence202a02019-09-02 17:01:19 +020094 BlockFramer framer(num_bands, num_channels);
peahd0263542017-01-03 04:20:34 -080095
96 size_t block_index = 0;
97 for (size_t sub_frame_index = 0; sub_frame_index < kNumSubFramesToProcess;
98 ++sub_frame_index) {
99 FillBlock(block_index++, &block);
100 framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view);
Per Åhgrence202a02019-09-02 17:01:19 +0200101 if (sub_frame_index > 1) {
102 EXPECT_TRUE(VerifySubFrame(sub_frame_index, -64, output_sub_frame_view));
103 }
peahd0263542017-01-03 04:20:34 -0800104
105 if ((sub_frame_index + 1) % 4 == 0) {
106 FillBlock(block_index++, &block);
107 framer.InsertBlock(block);
108 }
109 }
110}
111
112#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
113// Verifies that the BlockFramer crashes if the InsertBlockAndExtractSubFrame
114// method is called for inputs with the wrong number of bands or band lengths.
Per Åhgrence202a02019-09-02 17:01:19 +0200115void RunWronglySizedInsertAndExtractParametersTest(
116 int sample_rate_hz,
117 size_t correct_num_channels,
118 size_t num_block_bands,
119 size_t num_block_channels,
120 size_t block_length,
121 size_t num_sub_frame_bands,
122 size_t num_sub_frame_channels,
123 size_t sub_frame_length) {
peahd0263542017-01-03 04:20:34 -0800124 const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
125
Per Åhgrence202a02019-09-02 17:01:19 +0200126 std::vector<std::vector<std::vector<float>>> block(
127 num_block_bands,
128 std::vector<std::vector<float>>(num_block_channels,
129 std::vector<float>(block_length, 0.f)));
130 std::vector<std::vector<std::vector<float>>> output_sub_frame(
131 num_sub_frame_bands,
132 std::vector<std::vector<float>>(
133 num_sub_frame_channels, std::vector<float>(sub_frame_length, 0.f)));
134 std::vector<std::vector<rtc::ArrayView<float>>> output_sub_frame_view(
135 output_sub_frame.size(),
136 std::vector<rtc::ArrayView<float>>(num_sub_frame_channels));
peahd0263542017-01-03 04:20:34 -0800137 SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
Per Åhgrence202a02019-09-02 17:01:19 +0200138 BlockFramer framer(correct_num_bands, correct_num_channels);
peahd0263542017-01-03 04:20:34 -0800139 EXPECT_DEATH(
140 framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view), "");
141}
142
143// Verifies that the BlockFramer crashes if the InsertBlock method is called for
144// inputs with the wrong number of bands or band lengths.
145void RunWronglySizedInsertParameterTest(int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +0200146 size_t correct_num_channels,
peahd0263542017-01-03 04:20:34 -0800147 size_t num_block_bands,
Per Åhgrence202a02019-09-02 17:01:19 +0200148 size_t num_block_channels,
peahd0263542017-01-03 04:20:34 -0800149 size_t block_length) {
150 const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
151
Per Åhgrence202a02019-09-02 17:01:19 +0200152 std::vector<std::vector<std::vector<float>>> correct_block(
153 correct_num_bands,
154 std::vector<std::vector<float>>(correct_num_channels,
155 std::vector<float>(kBlockSize, 0.f)));
156 std::vector<std::vector<std::vector<float>>> wrong_block(
157 num_block_bands,
158 std::vector<std::vector<float>>(num_block_channels,
159 std::vector<float>(block_length, 0.f)));
160 std::vector<std::vector<std::vector<float>>> output_sub_frame(
161 correct_num_bands,
162 std::vector<std::vector<float>>(
163 correct_num_channels, std::vector<float>(kSubFrameLength, 0.f)));
164 std::vector<std::vector<rtc::ArrayView<float>>> output_sub_frame_view(
165 output_sub_frame.size(),
166 std::vector<rtc::ArrayView<float>>(correct_num_channels));
peahd0263542017-01-03 04:20:34 -0800167 SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
Per Åhgrence202a02019-09-02 17:01:19 +0200168 BlockFramer framer(correct_num_bands, correct_num_channels);
peahd0263542017-01-03 04:20:34 -0800169 framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
170 framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
171 framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
172 framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
173
174 EXPECT_DEATH(framer.InsertBlock(wrong_block), "");
175}
176
177// Verifies that the BlockFramer crashes if the InsertBlock method is called
178// after a wrong number of previous InsertBlockAndExtractSubFrame method calls
179// have been made.
Per Åhgrence202a02019-09-02 17:01:19 +0200180
peahd0263542017-01-03 04:20:34 -0800181void RunWronglyInsertOrderTest(int sample_rate_hz,
Per Åhgrence202a02019-09-02 17:01:19 +0200182 size_t num_channels,
peahd0263542017-01-03 04:20:34 -0800183 size_t num_preceeding_api_calls) {
184 const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
185
Per Åhgrence202a02019-09-02 17:01:19 +0200186 std::vector<std::vector<std::vector<float>>> block(
187 correct_num_bands,
188 std::vector<std::vector<float>>(num_channels,
189 std::vector<float>(kBlockSize, 0.f)));
190 std::vector<std::vector<std::vector<float>>> output_sub_frame(
191 correct_num_bands,
192 std::vector<std::vector<float>>(
193 num_channels, std::vector<float>(kSubFrameLength, 0.f)));
194 std::vector<std::vector<rtc::ArrayView<float>>> output_sub_frame_view(
195 output_sub_frame.size(),
196 std::vector<rtc::ArrayView<float>>(num_channels));
peahd0263542017-01-03 04:20:34 -0800197 SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
Per Åhgrence202a02019-09-02 17:01:19 +0200198 BlockFramer framer(correct_num_bands, num_channels);
peahd0263542017-01-03 04:20:34 -0800199 for (size_t k = 0; k < num_preceeding_api_calls; ++k) {
200 framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view);
201 }
202
203 EXPECT_DEATH(framer.InsertBlock(block), "");
204}
205#endif
206
Per Åhgrence202a02019-09-02 17:01:19 +0200207std::string ProduceDebugText(int sample_rate_hz, size_t num_channels) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200208 rtc::StringBuilder ss;
peahd0263542017-01-03 04:20:34 -0800209 ss << "Sample rate: " << sample_rate_hz;
Per Åhgrence202a02019-09-02 17:01:19 +0200210 ss << ", number of channels: " << num_channels;
Jonas Olsson84df1c72018-09-14 16:59:32 +0200211 return ss.Release();
peahd0263542017-01-03 04:20:34 -0800212}
213
214} // namespace
215
216#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
217TEST(BlockFramer, WrongNumberOfBandsInBlockForInsertBlockAndExtractSubFrame) {
Per Åhgrence202a02019-09-02 17:01:19 +0200218 for (auto rate : {16000, 32000, 48000}) {
219 for (auto correct_num_channels : {1, 2, 8}) {
220 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
221 const size_t correct_num_bands = NumBandsForRate(rate);
222 const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
223 RunWronglySizedInsertAndExtractParametersTest(
224 rate, correct_num_channels, wrong_num_bands, correct_num_channels,
225 kBlockSize, correct_num_bands, correct_num_channels, kSubFrameLength);
226 }
227 }
228}
229
230TEST(BlockFramer,
231 WrongNumberOfChannelsInBlockForInsertBlockAndExtractSubFrame) {
232 for (auto rate : {16000, 32000, 48000}) {
233 for (auto correct_num_channels : {1, 2, 8}) {
234 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
235 const size_t correct_num_bands = NumBandsForRate(rate);
236 const size_t wrong_num_channels = correct_num_channels + 1;
237 RunWronglySizedInsertAndExtractParametersTest(
238 rate, correct_num_channels, correct_num_bands, wrong_num_channels,
239 kBlockSize, correct_num_bands, correct_num_channels, kSubFrameLength);
240 }
peahd0263542017-01-03 04:20:34 -0800241 }
242}
243
244TEST(BlockFramer,
245 WrongNumberOfBandsInSubFrameForInsertBlockAndExtractSubFrame) {
Per Åhgrence202a02019-09-02 17:01:19 +0200246 for (auto rate : {16000, 32000, 48000}) {
247 for (auto correct_num_channels : {1, 2, 8}) {
248 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
249 const size_t correct_num_bands = NumBandsForRate(rate);
250 const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
251 RunWronglySizedInsertAndExtractParametersTest(
252 rate, correct_num_channels, correct_num_bands, correct_num_channels,
253 kBlockSize, wrong_num_bands, correct_num_channels, kSubFrameLength);
254 }
255 }
256}
257
258TEST(BlockFramer,
259 WrongNumberOfChannelsInSubFrameForInsertBlockAndExtractSubFrame) {
260 for (auto rate : {16000, 32000, 48000}) {
261 for (auto correct_num_channels : {1, 2, 8}) {
262 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
263 const size_t correct_num_bands = NumBandsForRate(rate);
264 const size_t wrong_num_channels = correct_num_channels + 1;
265 RunWronglySizedInsertAndExtractParametersTest(
266 rate, correct_num_channels, correct_num_bands, correct_num_channels,
267 kBlockSize, correct_num_bands, wrong_num_channels, kSubFrameLength);
268 }
peahd0263542017-01-03 04:20:34 -0800269 }
270}
271
272TEST(BlockFramer, WrongNumberOfSamplesInBlockForInsertBlockAndExtractSubFrame) {
Per Åhgrence202a02019-09-02 17:01:19 +0200273 for (auto rate : {16000, 32000, 48000}) {
274 for (auto correct_num_channels : {1, 2, 8}) {
275 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
276 const size_t correct_num_bands = NumBandsForRate(rate);
277 RunWronglySizedInsertAndExtractParametersTest(
278 rate, correct_num_channels, correct_num_bands, correct_num_channels,
279 kBlockSize - 1, correct_num_bands, correct_num_channels,
280 kSubFrameLength);
281 }
peahd0263542017-01-03 04:20:34 -0800282 }
283}
284
285TEST(BlockFramer,
286 WrongNumberOfSamplesInSubFrameForInsertBlockAndExtractSubFrame) {
Per Åhgrence202a02019-09-02 17:01:19 +0200287 const size_t correct_num_channels = 1;
288 for (auto rate : {16000, 32000, 48000}) {
289 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
peahd0263542017-01-03 04:20:34 -0800290 const size_t correct_num_bands = NumBandsForRate(rate);
Per Åhgrence202a02019-09-02 17:01:19 +0200291 RunWronglySizedInsertAndExtractParametersTest(
292 rate, correct_num_channels, correct_num_bands, correct_num_channels,
293 kBlockSize, correct_num_bands, correct_num_channels,
294 kSubFrameLength - 1);
peahd0263542017-01-03 04:20:34 -0800295 }
296}
297
298TEST(BlockFramer, WrongNumberOfBandsInBlockForInsertBlock) {
Per Åhgrence202a02019-09-02 17:01:19 +0200299 for (auto rate : {16000, 32000, 48000}) {
300 for (auto correct_num_channels : {1, 2, 8}) {
301 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
302 const size_t correct_num_bands = NumBandsForRate(rate);
303 const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
304 RunWronglySizedInsertParameterTest(rate, correct_num_channels,
305 wrong_num_bands, correct_num_channels,
306 kBlockSize);
Per Åhgrena66395e2019-08-30 08:54:09 +0200307 }
308 }
309}
310
Per Åhgrence202a02019-09-02 17:01:19 +0200311TEST(BlockFramer, WrongNumberOfChannelsInBlockForInsertBlock) {
312 for (auto rate : {16000, 32000, 48000}) {
313 for (auto correct_num_channels : {1, 2, 8}) {
314 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
315 const size_t correct_num_bands = NumBandsForRate(rate);
316 const size_t wrong_num_channels = correct_num_channels + 1;
317 RunWronglySizedInsertParameterTest(rate, correct_num_channels,
318 correct_num_bands, wrong_num_channels,
319 kBlockSize);
320 }
321 }
322}
323
324TEST(BlockFramer, WrongNumberOfSamplesInBlockForInsertBlock) {
325 for (auto rate : {16000, 32000, 48000}) {
326 for (auto correct_num_channels : {1, 2, 8}) {
327 SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
328 const size_t correct_num_bands = NumBandsForRate(rate);
329 RunWronglySizedInsertParameterTest(rate, correct_num_channels,
330 correct_num_bands,
331 correct_num_channels, kBlockSize - 1);
332 }
333 }
334}
335
336TEST(BlockFramer, WrongNumberOfPreceedingApiCallsForInsertBlock) {
337 for (size_t num_channels : {1, 2, 8}) {
338 for (auto rate : {16000, 32000, 48000}) {
339 for (size_t num_calls = 0; num_calls < 4; ++num_calls) {
340 rtc::StringBuilder ss;
341 ss << "Sample rate: " << rate;
342 ss << ", Num channels: " << num_channels;
343 ss << ", Num preceeding InsertBlockAndExtractSubFrame calls: "
344 << num_calls;
345
346 SCOPED_TRACE(ss.str());
347 RunWronglyInsertOrderTest(rate, num_channels, num_calls);
348 }
349 }
350 }
351}
352
353// Verifies that the verification for 0 number of channels works.
354TEST(BlockFramer, ZeroNumberOfChannelsParameter) {
355 EXPECT_DEATH(BlockFramer(16000, 0), "");
356}
357
358// Verifies that the verification for 0 number of bands works.
359TEST(BlockFramer, ZeroNumberOfBandsParameter) {
360 EXPECT_DEATH(BlockFramer(0, 1), "");
361}
362
363// Verifies that the verification for null sub_frame pointer works.
peahd0263542017-01-03 04:20:34 -0800364TEST(BlockFramer, NullSubFrameParameter) {
Per Åhgrence202a02019-09-02 17:01:19 +0200365 EXPECT_DEATH(BlockFramer(1, 1).InsertBlockAndExtractSubFrame(
366 std::vector<std::vector<std::vector<float>>>(
367 1, std::vector<std::vector<float>>(
368 1, std::vector<float>(kBlockSize, 0.f))),
peahd0263542017-01-03 04:20:34 -0800369 nullptr),
370 "");
371}
372
373#endif
374
375TEST(BlockFramer, FrameBitexactness) {
Per Åhgrence202a02019-09-02 17:01:19 +0200376 for (auto rate : {16000, 32000, 48000}) {
377 for (auto num_channels : {1, 2, 4, 8}) {
378 SCOPED_TRACE(ProduceDebugText(rate, num_channels));
379 RunFramerTest(rate, num_channels);
380 }
peahd0263542017-01-03 04:20:34 -0800381 }
382}
383
384} // namespace webrtc