blob: 0e316b9622a5c37deb48c76cf7ef0338f3f3ff71 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
bjornv@webrtc.org53096392012-02-07 08:10:46 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
kwibergbca568b2016-05-23 04:07:00 -070011#include <algorithm>
kwibergbca568b2016-05-23 04:07:00 -070012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "common_audio/signal_processing/include/signal_processing_library.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020014#include "rtc_base/strings/string_builder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "test/gtest.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000016
Peter Kastingdce40cf2015-08-24 14:52:23 -070017static const size_t kVector16Size = 9;
Yves Gerey665174f2018-06-19 15:03:05 +020018static const int16_t vector16[kVector16Size] = {1,
19 -15511,
20 4323,
21 1963,
22 WEBRTC_SPL_WORD16_MAX,
23 0,
24 WEBRTC_SPL_WORD16_MIN + 5,
25 -3333,
26 345};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +000027
Mirko Bonadei6a489f22019-04-09 15:11:12 +020028class SplTest : public ::testing::Test {
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +000029 protected:
Yves Gerey665174f2018-06-19 15:03:05 +020030 SplTest() { WebRtcSpl_Init(); }
Mirko Bonadei91df0912018-07-17 11:08:15 +020031 ~SplTest() override {}
niklase@google.com470e71d2011-07-07 08:21:25 +000032};
33
niklase@google.com470e71d2011-07-07 08:21:25 +000034TEST_F(SplTest, MacroTest) {
Yves Gerey665174f2018-06-19 15:03:05 +020035 // Macros with inputs.
36 int A = 10;
37 int B = 21;
38 int a = -3;
39 int b = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +000040
Yves Gerey665174f2018-06-19 15:03:05 +020041 EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B));
42 EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B));
niklase@google.com470e71d2011-07-07 08:21:25 +000043
Yves Gerey665174f2018-06-19 15:03:05 +020044 EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a));
45 EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a));
niklase@google.com470e71d2011-07-07 08:21:25 +000046
Yves Gerey665174f2018-06-19 15:03:05 +020047 EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B));
48 EXPECT_EQ(2147483651u, WEBRTC_SPL_UMUL(a, b));
49 b = WEBRTC_SPL_WORD16_MAX >> 1;
50 EXPECT_EQ(4294918147u, WEBRTC_SPL_UMUL_32_16(a, b));
51 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000052
Yves Gerey665174f2018-06-19 15:03:05 +020053 a = b;
54 b = -3;
niklase@google.com470e71d2011-07-07 08:21:25 +000055
Yves Gerey665174f2018-06-19 15:03:05 +020056 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
57 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
58 EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b));
59 EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000060
Yves Gerey665174f2018-06-19 15:03:05 +020061 EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2));
62 EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000063
Yves Gerey665174f2018-06-19 15:03:05 +020064 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B));
65 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A));
niklase@google.com470e71d2011-07-07 08:21:25 +000066
Yves Gerey665174f2018-06-19 15:03:05 +020067 // Shifting with negative numbers allowed
68 int shift_amount = 1; // Workaround compiler warning using variable here.
69 // Positive means left shift
70 EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, shift_amount));
niklase@google.com470e71d2011-07-07 08:21:25 +000071
Yves Gerey665174f2018-06-19 15:03:05 +020072 // Shifting with negative numbers not allowed
73 // We cannot do casting here due to signed/unsigned problem
74 EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +000075
Yves Gerey665174f2018-06-19 15:03:05 +020076 EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +000077
Yves Gerey665174f2018-06-19 15:03:05 +020078 EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
kma@webrtc.org76117912012-08-28 00:43:55 +000079
Yves Gerey665174f2018-06-19 15:03:05 +020080 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b));
81 EXPECT_EQ(1073676289,
82 WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MAX));
83 EXPECT_EQ(1073709055, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MAX,
84 WEBRTC_SPL_WORD32_MAX));
85 EXPECT_EQ(1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
86 WEBRTC_SPL_WORD32_MIN));
kma@webrtc.org9b1cf542012-09-03 21:22:28 +000087#ifdef WEBRTC_ARCH_ARM_V7
Yves Gerey665174f2018-06-19 15:03:05 +020088 EXPECT_EQ(-1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
89 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000090#else
Yves Gerey665174f2018-06-19 15:03:05 +020091 EXPECT_EQ(-1073741823, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
92 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000093#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000094}
95
96TEST_F(SplTest, InlineTest) {
Yves Gerey665174f2018-06-19 15:03:05 +020097 int16_t a16 = 121;
98 int16_t b16 = -17;
99 int32_t a32 = 111121;
100 int32_t b32 = -1711;
niklase@google.com470e71d2011-07-07 08:21:25 +0000101
Yves Gerey665174f2018-06-19 15:03:05 +0200102 EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000103
Yves Gerey665174f2018-06-19 15:03:05 +0200104 EXPECT_EQ(0, WebRtcSpl_NormW32(0));
105 EXPECT_EQ(31, WebRtcSpl_NormW32(-1));
106 EXPECT_EQ(0, WebRtcSpl_NormW32(WEBRTC_SPL_WORD32_MIN));
107 EXPECT_EQ(14, WebRtcSpl_NormW32(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000108
Yves Gerey665174f2018-06-19 15:03:05 +0200109 EXPECT_EQ(0, WebRtcSpl_NormW16(0));
110 EXPECT_EQ(15, WebRtcSpl_NormW16(-1));
111 EXPECT_EQ(0, WebRtcSpl_NormW16(WEBRTC_SPL_WORD16_MIN));
112 EXPECT_EQ(4, WebRtcSpl_NormW16(b32));
113 for (int ii = 0; ii < 15; ++ii) {
114 int16_t value = 1 << ii;
115 EXPECT_EQ(14 - ii, WebRtcSpl_NormW16(value));
116 EXPECT_EQ(15 - ii, WebRtcSpl_NormW16(-value));
117 }
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000118
Yves Gerey665174f2018-06-19 15:03:05 +0200119 EXPECT_EQ(0, WebRtcSpl_NormU32(0u));
120 EXPECT_EQ(0, WebRtcSpl_NormU32(0xffffffff));
121 EXPECT_EQ(15, WebRtcSpl_NormU32(static_cast<uint32_t>(a32)));
niklase@google.com470e71d2011-07-07 08:21:25 +0000122
Yves Gerey665174f2018-06-19 15:03:05 +0200123 EXPECT_EQ(104, WebRtcSpl_AddSatW16(a16, b16));
124 EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16));
kwibergbca568b2016-05-23 04:07:00 -0700125}
niklase@google.com470e71d2011-07-07 08:21:25 +0000126
kwibergbca568b2016-05-23 04:07:00 -0700127TEST_F(SplTest, AddSubSatW32) {
128 static constexpr int32_t kAddSubArgs[] = {
129 INT32_MIN, INT32_MIN + 1, -3, -2, -1, 0, 1, -1, 2,
130 3, INT32_MAX - 1, INT32_MAX};
131 for (int32_t a : kAddSubArgs) {
132 for (int32_t b : kAddSubArgs) {
133 const int64_t sum = std::max<int64_t>(
134 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) + b));
135 const int64_t diff = std::max<int64_t>(
136 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) - b));
Jonas Olsson366a50c2018-09-06 13:41:30 +0200137 rtc::StringBuilder ss;
kwibergbca568b2016-05-23 04:07:00 -0700138 ss << a << " +/- " << b << ": sum " << sum << ", diff " << diff;
139 SCOPED_TRACE(ss.str());
140 EXPECT_EQ(sum, WebRtcSpl_AddSatW32(a, b));
141 EXPECT_EQ(diff, WebRtcSpl_SubSatW32(a, b));
142 }
143 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000144}
145
kwiberg729b21f2016-06-02 04:02:12 -0700146TEST_F(SplTest, CountLeadingZeros32) {
147 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32(0));
148 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32_NotBuiltin(0));
149 for (int i = 0; i < 32; ++i) {
150 const uint32_t single_one = uint32_t{1} << i;
151 const uint32_t all_ones = 2 * single_one - 1;
152 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(single_one));
153 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(single_one));
154 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(all_ones));
155 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(all_ones));
156 }
157}
158
159TEST_F(SplTest, CountLeadingZeros64) {
160 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64(0));
161 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64_NotBuiltin(0));
162 for (int i = 0; i < 64; ++i) {
163 const uint64_t single_one = uint64_t{1} << i;
164 const uint64_t all_ones = 2 * single_one - 1;
165 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(single_one));
166 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(single_one));
167 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(all_ones));
168 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(all_ones));
169 }
170}
171
niklase@google.com470e71d2011-07-07 08:21:25 +0000172TEST_F(SplTest, MathOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200173 int A = 1134567892;
174 int32_t num = 117;
175 int32_t den = -5;
176 uint16_t denU = 5;
177 EXPECT_EQ(33700, WebRtcSpl_Sqrt(A));
178 EXPECT_EQ(33683, WebRtcSpl_SqrtFloor(A));
niklase@google.com470e71d2011-07-07 08:21:25 +0000179
Yves Gerey665174f2018-06-19 15:03:05 +0200180 EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num));
181 EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (int16_t)den));
182 EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (int16_t)den));
183 EXPECT_EQ(23u, WebRtcSpl_DivU32U16(num, denU));
184 EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
niklase@google.com470e71d2011-07-07 08:21:25 +0000185}
186
187TEST_F(SplTest, BasicArrayOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200188 const size_t kVectorSize = 4;
189 int B[] = {4, 12, 133, 1100};
190 int16_t b16[kVectorSize];
191 int32_t b32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000192
Yves Gerey665174f2018-06-19 15:03:05 +0200193 int16_t bTmp16[kVectorSize];
194 int32_t bTmp32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000195
Yves Gerey665174f2018-06-19 15:03:05 +0200196 WebRtcSpl_MemSetW16(b16, 3, kVectorSize);
197 for (size_t kk = 0; kk < kVectorSize; ++kk) {
198 EXPECT_EQ(3, b16[kk]);
199 }
200 WebRtcSpl_ZerosArrayW16(b16, kVectorSize);
201 for (size_t kk = 0; kk < kVectorSize; ++kk) {
202 EXPECT_EQ(0, b16[kk]);
203 }
204 WebRtcSpl_MemSetW32(b32, 3, kVectorSize);
205 for (size_t kk = 0; kk < kVectorSize; ++kk) {
206 EXPECT_EQ(3, b32[kk]);
207 }
208 WebRtcSpl_ZerosArrayW32(b32, kVectorSize);
209 for (size_t kk = 0; kk < kVectorSize; ++kk) {
210 EXPECT_EQ(0, b32[kk]);
211 }
212 for (size_t kk = 0; kk < kVectorSize; ++kk) {
213 bTmp16[kk] = (int16_t)kk;
214 bTmp32[kk] = (int32_t)kk;
215 }
216 WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize);
217 for (size_t kk = 0; kk < kVectorSize; ++kk) {
218 EXPECT_EQ(b16[kk], bTmp16[kk]);
219 }
220 // WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize);
221 // for (int kk = 0; kk < kVectorSize; ++kk) {
222 // EXPECT_EQ(b32[kk], bTmp32[kk]);
223 // }
224 WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16);
225 for (size_t kk = 0; kk < 2; ++kk) {
226 EXPECT_EQ(static_cast<int16_t>(kk + 2), bTmp16[kk]);
227 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000228
Yves Gerey665174f2018-06-19 15:03:05 +0200229 for (size_t kk = 0; kk < kVectorSize; ++kk) {
230 b32[kk] = B[kk];
231 b16[kk] = (int16_t)B[kk];
232 }
233 WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1);
234 for (size_t kk = 0; kk < kVectorSize; ++kk) {
235 EXPECT_EQ((B[kk] >> 1), bTmp16[kk]);
236 }
237 WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1);
238 for (size_t kk = 0; kk < kVectorSize; ++kk) {
239 EXPECT_EQ((B[kk] >> 1), bTmp16[kk]);
240 }
241 WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1);
242 for (size_t kk = 0; kk < kVectorSize; ++kk) {
243 EXPECT_EQ((B[kk] >> 1), bTmp32[kk]);
244 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000245
Yves Gerey665174f2018-06-19 15:03:05 +0200246 WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize);
247 for (size_t kk = 0; kk < kVectorSize; ++kk) {
248 EXPECT_EQ(b16[3 - kk], bTmp16[kk]);
249 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000250}
251
252TEST_F(SplTest, MinMaxOperationsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700253 const size_t kVectorSize = 17;
niklase@google.com470e71d2011-07-07 08:21:25 +0000254
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000255 // Vectors to test the cases where minimum values have to be caught
256 // outside of the unrolled loops in ARM-Neon.
Yves Gerey665174f2018-06-19 15:03:05 +0200257 int16_t vector16[kVectorSize] = {-1,
258 7485,
259 0,
260 3333,
261 -18283,
262 0,
263 12334,
264 -29871,
265 988,
266 -3333,
267 345,
268 -456,
269 222,
270 999,
271 888,
272 8774,
273 WEBRTC_SPL_WORD16_MIN};
274 int32_t vector32[kVectorSize] = {-1,
275 0,
276 283211,
277 3333,
278 8712345,
279 0,
280 -3333,
281 89345,
282 -374585456,
283 222,
284 999,
285 122345334,
286 -12389756,
287 -987329871,
288 888,
289 -2,
290 WEBRTC_SPL_WORD32_MIN};
niklase@google.com470e71d2011-07-07 08:21:25 +0000291
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000292 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
293 WebRtcSpl_MinValueW16(vector16, kVectorSize));
294 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
295 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700296 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
297 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000298
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000299 // Test the cases where maximum values have to be caught
300 // outside of the unrolled loops in ARM-Neon.
301 vector16[kVectorSize - 1] = WEBRTC_SPL_WORD16_MAX;
302 vector32[kVectorSize - 1] = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +0000303
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000304 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
305 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
306 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
307 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
308 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
309 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
310 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
311 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700312 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
313 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
314 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000315
316 // Test the cases where multiple maximum and minimum values are present.
317 vector16[1] = WEBRTC_SPL_WORD16_MAX;
318 vector16[6] = WEBRTC_SPL_WORD16_MIN;
319 vector16[11] = WEBRTC_SPL_WORD16_MIN;
320 vector32[1] = WEBRTC_SPL_WORD32_MAX;
321 vector32[6] = WEBRTC_SPL_WORD32_MIN;
322 vector32[11] = WEBRTC_SPL_WORD32_MIN;
323
324 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
325 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
326 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
327 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
328 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
329 WebRtcSpl_MinValueW16(vector16, kVectorSize));
330 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
331 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
332 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
333 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
334 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
335 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700336 EXPECT_EQ(6u, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
337 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
338 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
339 EXPECT_EQ(6u, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
340 EXPECT_EQ(6u, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000341}
342
343TEST_F(SplTest, VectorOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200344 const size_t kVectorSize = 4;
345 int B[] = {4, 12, 133, 1100};
346 int16_t a16[kVectorSize];
347 int16_t b16[kVectorSize];
348 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000349
Yves Gerey665174f2018-06-19 15:03:05 +0200350 for (size_t kk = 0; kk < kVectorSize; ++kk) {
351 a16[kk] = B[kk];
352 b16[kk] = B[kk];
353 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000354
Yves Gerey665174f2018-06-19 15:03:05 +0200355 WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize);
356 for (size_t kk = 0; kk < kVectorSize; ++kk) {
357 EXPECT_EQ((B[kk] * 3 + 7) >> 2, bTmp16[kk]);
358 }
359 WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize);
360 for (size_t kk = 0; kk < kVectorSize; ++kk) {
361 EXPECT_EQ((B[kk] * 3 + B[kk] * 2 + 2) >> 2, bTmp16[kk]);
362 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000363
Yves Gerey665174f2018-06-19 15:03:05 +0200364 WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize);
365 for (size_t kk = 0; kk < kVectorSize; ++kk) {
366 EXPECT_EQ(((B[kk] * 3 + B[kk] * 2 + 2) >> 2) + ((b16[kk] * 3 + 7) >> 2),
367 bTmp16[kk]);
368 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000369
Yves Gerey665174f2018-06-19 15:03:05 +0200370 WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
371 for (size_t kk = 0; kk < kVectorSize; ++kk) {
372 EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]);
373 }
374 WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2);
375 for (size_t kk = 0; kk < kVectorSize; ++kk) {
376 EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]);
377 }
378 WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize);
379 for (size_t kk = 0; kk < kVectorSize; ++kk) {
380 EXPECT_EQ(((a16[kk] * 13) >> 2) + ((b16[kk] * 7) >> 2), bTmp16[kk]);
381 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000382
Yves Gerey665174f2018-06-19 15:03:05 +0200383 WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2);
384 for (size_t kk = 0; kk < kVectorSize; ++kk) {
385 EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
386 }
387 WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2);
388 for (size_t kk = 0; kk < kVectorSize; ++kk) {
389 EXPECT_EQ((a16[kk] * b16[3 - kk]) >> 2, bTmp16[kk]);
390 }
391 WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6);
392 for (size_t kk = 0; kk < kVectorSize; ++kk) {
393 EXPECT_EQ((a16[kk] * b16[kk]) >> 6, bTmp16[kk]);
394 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000395
Yves Gerey665174f2018-06-19 15:03:05 +0200396 WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16);
397 for (size_t kk = 0; kk < kVectorSize - 1; ++kk) {
398 EXPECT_EQ(32767, bTmp16[kk]);
399 }
400 EXPECT_EQ(32749, bTmp16[kVectorSize - 1]);
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000401
Yves Gerey665174f2018-06-19 15:03:05 +0200402 EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +0000403}
404
405TEST_F(SplTest, EstimatorsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700406 const size_t kOrder = 2;
Yves Gerey665174f2018-06-19 15:03:05 +0200407 const int32_t unstable_filter[] = {4, 12, 133, 1100};
408 const int32_t stable_filter[] = {1100, 133, 12, 4};
409 int16_t lpc[kOrder + 2] = {0};
410 int16_t refl[kOrder + 2] = {0};
411 int16_t lpc_result[] = {4096, -497, 15, 0};
412 int16_t refl_result[] = {-3962, 123, 0, 0};
niklase@google.com470e71d2011-07-07 08:21:25 +0000413
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000414 EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(unstable_filter, lpc, refl, kOrder));
415 EXPECT_EQ(1, WebRtcSpl_LevinsonDurbin(stable_filter, lpc, refl, kOrder));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700416 for (size_t i = 0; i < kOrder + 2; ++i) {
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000417 EXPECT_EQ(lpc_result[i], lpc[i]);
418 EXPECT_EQ(refl_result[i], refl[i]);
419 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000420}
421
422TEST_F(SplTest, FilterTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200423 const size_t kVectorSize = 4;
424 const size_t kFilterOrder = 3;
425 int16_t A[] = {1, 2, 33, 100};
426 int16_t A5[] = {1, 2, 33, 100, -5};
427 int16_t B[] = {4, 12, 133, 110};
428 int16_t data_in[kVectorSize];
429 int16_t data_out[kVectorSize];
430 int16_t bTmp16Low[kVectorSize];
431 int16_t bState[kVectorSize];
432 int16_t bStateLow[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000433
Yves Gerey665174f2018-06-19 15:03:05 +0200434 WebRtcSpl_ZerosArrayW16(bState, kVectorSize);
435 WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize);
niklase@google.com470e71d2011-07-07 08:21:25 +0000436
Yves Gerey665174f2018-06-19 15:03:05 +0200437 for (size_t kk = 0; kk < kVectorSize; ++kk) {
438 data_in[kk] = A[kk];
439 data_out[kk] = 0;
440 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000441
Yves Gerey665174f2018-06-19 15:03:05 +0200442 // MA filters.
443 // Note that the input data has |kFilterOrder| states before the actual
444 // data (one sample).
445 WebRtcSpl_FilterMAFastQ12(&data_in[kFilterOrder], data_out, B,
446 kFilterOrder + 1, 1);
447 EXPECT_EQ(0, data_out[0]);
448 // AR filters.
449 // Note that the output data has |kFilterOrder| states before the actual
450 // data (one sample).
451 WebRtcSpl_FilterARFastQ12(data_in, &data_out[kFilterOrder], A,
452 kFilterOrder + 1, 1);
453 EXPECT_EQ(0, data_out[kFilterOrder]);
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000454
Yves Gerey665174f2018-06-19 15:03:05 +0200455 EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5, 5, data_in, kVectorSize, bState,
456 kVectorSize, bStateLow, kVectorSize,
457 data_out, bTmp16Low, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000458}
459
460TEST_F(SplTest, RandTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200461 const int kVectorSize = 4;
462 int16_t BU[] = {3653, 12446, 8525, 30691};
463 int16_t b16[kVectorSize];
464 uint32_t bSeed = 100000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000465
Yves Gerey665174f2018-06-19 15:03:05 +0200466 EXPECT_EQ(7086, WebRtcSpl_RandU(&bSeed));
467 EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed));
468 EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed));
469 EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed));
470 for (int kk = 0; kk < kVectorSize; ++kk) {
471 EXPECT_EQ(BU[kk], b16[kk]);
472 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000473}
474
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000475TEST_F(SplTest, DotProductWithScaleTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200476 EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16, vector16,
477 kVector16Size, 2));
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000478}
479
480TEST_F(SplTest, CrossCorrelationTest) {
481 // Note the function arguments relation specificed by API.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700482 const size_t kCrossCorrelationDimension = 3;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000483 const int kShift = 2;
484 const int kStep = 1;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700485 const size_t kSeqDimension = 6;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000486
Yves Gerey665174f2018-06-19 15:03:05 +0200487 const int16_t kVector16[kVector16Size] = {
488 1, 4323, 1963, WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333,
489 -876, 8483, 142};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000490 int32_t vector32[kCrossCorrelationDimension] = {0};
491
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000492 WebRtcSpl_CrossCorrelation(vector32, vector16, kVector16, kSeqDimension,
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000493 kCrossCorrelationDimension, kShift, kStep);
494
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000495 // WebRtcSpl_CrossCorrelationC() and WebRtcSpl_CrossCorrelationNeon()
496 // are not bit-exact.
Yves Gerey665174f2018-06-19 15:03:05 +0200497 const int32_t kExpected[kCrossCorrelationDimension] = {-266947903, -15579555,
498 -171282001};
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000499 const int32_t* expected = kExpected;
500#if !defined(MIPS32_LE)
Yves Gerey665174f2018-06-19 15:03:05 +0200501 const int32_t kExpectedNeon[kCrossCorrelationDimension] = {
502 -266947901, -15579553, -171281999};
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000503 if (WebRtcSpl_CrossCorrelation != WebRtcSpl_CrossCorrelationC) {
504 expected = kExpectedNeon;
505 }
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000506#endif
Peter Kastingdce40cf2015-08-24 14:52:23 -0700507 for (size_t i = 0; i < kCrossCorrelationDimension; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000508 EXPECT_EQ(expected[i], vector32[i]);
509 }
510}
511
512TEST_F(SplTest, AutoCorrelationTest) {
513 int scale = 0;
514 int32_t vector32[kVector16Size];
Yves Gerey665174f2018-06-19 15:03:05 +0200515 const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063,
516 -85221647, -17104971, 61806945,
517 6644603, -669329, 43};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000518
Peter Kasting1380e262015-08-28 17:31:03 -0700519 EXPECT_EQ(kVector16Size,
Peter Kasting728d9032015-06-11 14:31:38 -0700520 WebRtcSpl_AutoCorrelation(vector16, kVector16Size,
521 kVector16Size - 1, vector32, &scale));
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000522 EXPECT_EQ(3, scale);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700523 for (size_t i = 0; i < kVector16Size; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000524 EXPECT_EQ(expected[i], vector32[i]);
525 }
526}
527
niklase@google.com470e71d2011-07-07 08:21:25 +0000528TEST_F(SplTest, SignalProcessingTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200529 const size_t kVectorSize = 4;
530 int A[] = {1, 2, 33, 100};
531 const int16_t kHanning[4] = {2399, 8192, 13985, 16384};
532 int16_t b16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000533
Yves Gerey665174f2018-06-19 15:03:05 +0200534 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000535
Yves Gerey665174f2018-06-19 15:03:05 +0200536 int bScale = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000537
Yves Gerey665174f2018-06-19 15:03:05 +0200538 for (size_t kk = 0; kk < kVectorSize; ++kk) {
539 b16[kk] = A[kk];
540 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000541
Yves Gerey665174f2018-06-19 15:03:05 +0200542 // TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
543 // WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
544 //// for (int kk = 0; kk < kVectorSize; ++kk) {
545 //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
546 //// }
547 // WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16);
548 //// for (int kk = 0; kk < kVectorSize; ++kk) {
549 //// EXPECT_EQ(a16[kk], b16[kk]);
550 //// }
551 // WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16);
552 //// for (int kk = 0; kk < kVectorSize; ++kk) {
553 //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
554 //// }
bjornv@webrtc.org53096392012-02-07 08:10:46 +0000555
Yves Gerey665174f2018-06-19 15:03:05 +0200556 WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize);
557 for (size_t kk = 0; kk < kVectorSize; ++kk) {
558 EXPECT_EQ(kHanning[kk], bTmp16[kk]);
559 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000560
Yves Gerey665174f2018-06-19 15:03:05 +0200561 for (size_t kk = 0; kk < kVectorSize; ++kk) {
562 b16[kk] = A[kk];
563 }
564 EXPECT_EQ(11094, WebRtcSpl_Energy(b16, kVectorSize, &bScale));
565 EXPECT_EQ(0, bScale);
niklase@google.com470e71d2011-07-07 08:21:25 +0000566}
567
568TEST_F(SplTest, FFTTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200569 int16_t B[] = {1, 2, 33, 100, 2, 3, 34, 101, 3, 4, 35, 102, 4, 5, 36, 103};
niklase@google.com470e71d2011-07-07 08:21:25 +0000570
Yves Gerey665174f2018-06-19 15:03:05 +0200571 EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
572 // for (int kk = 0; kk < 16; ++kk) {
573 // EXPECT_EQ(A[kk], B[kk]);
574 // }
575 EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1));
576 // for (int kk = 0; kk < 16; ++kk) {
577 // EXPECT_EQ(A[kk], B[kk]);
578 // }
579 WebRtcSpl_ComplexBitReverse(B, 3);
580 for (int kk = 0; kk < 16; ++kk) {
581 // EXPECT_EQ(A[kk], B[kk]);
582 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000584
585TEST_F(SplTest, Resample48WithSaturationTest) {
586 // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number
587 // of samples.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700588 const size_t kBlockSize = 16;
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000589
590 // Saturated input vector of 48 samples.
591 const int32_t kVectorSaturated[3 * kBlockSize + 7] = {
Yves Gerey665174f2018-06-19 15:03:05 +0200592 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
593 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
594 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
595 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
596 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
597 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
598 32767, 32767, 32767, 32767, 32767, 32767, 32767};
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000599
600 // All values in |out_vector| should be |kRefValue32kHz|.
601 const int32_t kRefValue32kHz1 = -1077493760;
602 const int32_t kRefValue32kHz2 = 1077493645;
603
604 // After bit shift with saturation, |out_vector_w16| is saturated.
605
606 const int16_t kRefValue16kHz1 = -32768;
607 const int16_t kRefValue16kHz2 = 32767;
608 // Vector for storing output.
609 int32_t out_vector[2 * kBlockSize];
610 int16_t out_vector_w16[2 * kBlockSize];
611
612 WebRtcSpl_Resample48khzTo32khz(kVectorSaturated, out_vector, kBlockSize);
613 WebRtcSpl_VectorBitShiftW32ToW16(out_vector_w16, 2 * kBlockSize, out_vector,
614 15);
615
616 // Comparing output values against references. The values at position
617 // 12-15 are skipped to account for the filter lag.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700618 for (size_t i = 0; i < 12; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000619 EXPECT_EQ(kRefValue32kHz1, out_vector[i]);
620 EXPECT_EQ(kRefValue16kHz1, out_vector_w16[i]);
621 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700622 for (size_t i = 16; i < 2 * kBlockSize; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000623 EXPECT_EQ(kRefValue32kHz2, out_vector[i]);
624 EXPECT_EQ(kRefValue16kHz2, out_vector_w16[i]);
625 }
626}