blob: 3106c47d2d2b54522ab46b3ef11b5ff3987a5cea [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
Karl Wiberg225842c2019-06-28 14:51:49 +020028TEST(SplTest, MacroTest) {
Yves Gerey665174f2018-06-19 15:03:05 +020029 // Macros with inputs.
30 int A = 10;
31 int B = 21;
32 int a = -3;
33 int b = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +000034
Yves Gerey665174f2018-06-19 15:03:05 +020035 EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B));
36 EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B));
niklase@google.com470e71d2011-07-07 08:21:25 +000037
Yves Gerey665174f2018-06-19 15:03:05 +020038 EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a));
39 EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a));
niklase@google.com470e71d2011-07-07 08:21:25 +000040
Yves Gerey665174f2018-06-19 15:03:05 +020041 EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B));
42 EXPECT_EQ(2147483651u, WEBRTC_SPL_UMUL(a, b));
43 b = WEBRTC_SPL_WORD16_MAX >> 1;
44 EXPECT_EQ(4294918147u, WEBRTC_SPL_UMUL_32_16(a, b));
45 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000046
Yves Gerey665174f2018-06-19 15:03:05 +020047 a = b;
48 b = -3;
niklase@google.com470e71d2011-07-07 08:21:25 +000049
Yves Gerey665174f2018-06-19 15:03:05 +020050 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
51 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
52 EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b));
53 EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000054
Yves Gerey665174f2018-06-19 15:03:05 +020055 EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2));
56 EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000057
Yves Gerey665174f2018-06-19 15:03:05 +020058 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B));
59 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A));
niklase@google.com470e71d2011-07-07 08:21:25 +000060
Yves Gerey665174f2018-06-19 15:03:05 +020061 // Shifting with negative numbers allowed
62 int shift_amount = 1; // Workaround compiler warning using variable here.
63 // Positive means left shift
64 EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, shift_amount));
niklase@google.com470e71d2011-07-07 08:21:25 +000065
Yves Gerey665174f2018-06-19 15:03:05 +020066 // Shifting with negative numbers not allowed
67 // We cannot do casting here due to signed/unsigned problem
68 EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +000069
Yves Gerey665174f2018-06-19 15:03:05 +020070 EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +000071
Yves Gerey665174f2018-06-19 15:03:05 +020072 EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
kma@webrtc.org76117912012-08-28 00:43:55 +000073
Yves Gerey665174f2018-06-19 15:03:05 +020074 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b));
75 EXPECT_EQ(1073676289,
76 WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MAX));
77 EXPECT_EQ(1073709055, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MAX,
78 WEBRTC_SPL_WORD32_MAX));
79 EXPECT_EQ(1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
80 WEBRTC_SPL_WORD32_MIN));
kma@webrtc.org9b1cf542012-09-03 21:22:28 +000081#ifdef WEBRTC_ARCH_ARM_V7
Yves Gerey665174f2018-06-19 15:03:05 +020082 EXPECT_EQ(-1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
83 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000084#else
Yves Gerey665174f2018-06-19 15:03:05 +020085 EXPECT_EQ(-1073741823, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
86 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000087#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000088}
89
Karl Wiberg225842c2019-06-28 14:51:49 +020090TEST(SplTest, InlineTest) {
Yves Gerey665174f2018-06-19 15:03:05 +020091 int16_t a16 = 121;
92 int16_t b16 = -17;
93 int32_t a32 = 111121;
94 int32_t b32 = -1711;
niklase@google.com470e71d2011-07-07 08:21:25 +000095
Yves Gerey665174f2018-06-19 15:03:05 +020096 EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +000097
Yves Gerey665174f2018-06-19 15:03:05 +020098 EXPECT_EQ(0, WebRtcSpl_NormW32(0));
99 EXPECT_EQ(31, WebRtcSpl_NormW32(-1));
100 EXPECT_EQ(0, WebRtcSpl_NormW32(WEBRTC_SPL_WORD32_MIN));
101 EXPECT_EQ(14, WebRtcSpl_NormW32(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000102
Yves Gerey665174f2018-06-19 15:03:05 +0200103 EXPECT_EQ(0, WebRtcSpl_NormW16(0));
104 EXPECT_EQ(15, WebRtcSpl_NormW16(-1));
105 EXPECT_EQ(0, WebRtcSpl_NormW16(WEBRTC_SPL_WORD16_MIN));
106 EXPECT_EQ(4, WebRtcSpl_NormW16(b32));
107 for (int ii = 0; ii < 15; ++ii) {
108 int16_t value = 1 << ii;
109 EXPECT_EQ(14 - ii, WebRtcSpl_NormW16(value));
110 EXPECT_EQ(15 - ii, WebRtcSpl_NormW16(-value));
111 }
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000112
Yves Gerey665174f2018-06-19 15:03:05 +0200113 EXPECT_EQ(0, WebRtcSpl_NormU32(0u));
114 EXPECT_EQ(0, WebRtcSpl_NormU32(0xffffffff));
115 EXPECT_EQ(15, WebRtcSpl_NormU32(static_cast<uint32_t>(a32)));
niklase@google.com470e71d2011-07-07 08:21:25 +0000116
Yves Gerey665174f2018-06-19 15:03:05 +0200117 EXPECT_EQ(104, WebRtcSpl_AddSatW16(a16, b16));
118 EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16));
kwibergbca568b2016-05-23 04:07:00 -0700119}
niklase@google.com470e71d2011-07-07 08:21:25 +0000120
Karl Wiberg225842c2019-06-28 14:51:49 +0200121TEST(SplTest, AddSubSatW32) {
kwibergbca568b2016-05-23 04:07:00 -0700122 static constexpr int32_t kAddSubArgs[] = {
123 INT32_MIN, INT32_MIN + 1, -3, -2, -1, 0, 1, -1, 2,
124 3, INT32_MAX - 1, INT32_MAX};
125 for (int32_t a : kAddSubArgs) {
126 for (int32_t b : kAddSubArgs) {
127 const int64_t sum = std::max<int64_t>(
128 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) + b));
129 const int64_t diff = std::max<int64_t>(
130 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) - b));
Jonas Olsson366a50c2018-09-06 13:41:30 +0200131 rtc::StringBuilder ss;
kwibergbca568b2016-05-23 04:07:00 -0700132 ss << a << " +/- " << b << ": sum " << sum << ", diff " << diff;
133 SCOPED_TRACE(ss.str());
134 EXPECT_EQ(sum, WebRtcSpl_AddSatW32(a, b));
135 EXPECT_EQ(diff, WebRtcSpl_SubSatW32(a, b));
136 }
137 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000138}
139
Karl Wiberg225842c2019-06-28 14:51:49 +0200140TEST(SplTest, CountLeadingZeros32) {
kwiberg729b21f2016-06-02 04:02:12 -0700141 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32(0));
142 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32_NotBuiltin(0));
143 for (int i = 0; i < 32; ++i) {
144 const uint32_t single_one = uint32_t{1} << i;
145 const uint32_t all_ones = 2 * single_one - 1;
146 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(single_one));
147 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(single_one));
148 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(all_ones));
149 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(all_ones));
150 }
151}
152
Karl Wiberg225842c2019-06-28 14:51:49 +0200153TEST(SplTest, CountLeadingZeros64) {
kwiberg729b21f2016-06-02 04:02:12 -0700154 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64(0));
155 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64_NotBuiltin(0));
156 for (int i = 0; i < 64; ++i) {
157 const uint64_t single_one = uint64_t{1} << i;
158 const uint64_t all_ones = 2 * single_one - 1;
159 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(single_one));
160 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(single_one));
161 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(all_ones));
162 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(all_ones));
163 }
164}
165
Karl Wiberg225842c2019-06-28 14:51:49 +0200166TEST(SplTest, MathOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200167 int A = 1134567892;
168 int32_t num = 117;
169 int32_t den = -5;
170 uint16_t denU = 5;
171 EXPECT_EQ(33700, WebRtcSpl_Sqrt(A));
172 EXPECT_EQ(33683, WebRtcSpl_SqrtFloor(A));
niklase@google.com470e71d2011-07-07 08:21:25 +0000173
Yves Gerey665174f2018-06-19 15:03:05 +0200174 EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num));
175 EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (int16_t)den));
176 EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (int16_t)den));
177 EXPECT_EQ(23u, WebRtcSpl_DivU32U16(num, denU));
178 EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
niklase@google.com470e71d2011-07-07 08:21:25 +0000179}
180
Karl Wiberg225842c2019-06-28 14:51:49 +0200181TEST(SplTest, BasicArrayOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200182 const size_t kVectorSize = 4;
183 int B[] = {4, 12, 133, 1100};
184 int16_t b16[kVectorSize];
185 int32_t b32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000186
Yves Gerey665174f2018-06-19 15:03:05 +0200187 int16_t bTmp16[kVectorSize];
188 int32_t bTmp32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000189
Yves Gerey665174f2018-06-19 15:03:05 +0200190 WebRtcSpl_MemSetW16(b16, 3, kVectorSize);
191 for (size_t kk = 0; kk < kVectorSize; ++kk) {
192 EXPECT_EQ(3, b16[kk]);
193 }
194 WebRtcSpl_ZerosArrayW16(b16, kVectorSize);
195 for (size_t kk = 0; kk < kVectorSize; ++kk) {
196 EXPECT_EQ(0, b16[kk]);
197 }
198 WebRtcSpl_MemSetW32(b32, 3, kVectorSize);
199 for (size_t kk = 0; kk < kVectorSize; ++kk) {
200 EXPECT_EQ(3, b32[kk]);
201 }
202 WebRtcSpl_ZerosArrayW32(b32, kVectorSize);
203 for (size_t kk = 0; kk < kVectorSize; ++kk) {
204 EXPECT_EQ(0, b32[kk]);
205 }
206 for (size_t kk = 0; kk < kVectorSize; ++kk) {
207 bTmp16[kk] = (int16_t)kk;
208 bTmp32[kk] = (int32_t)kk;
209 }
210 WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize);
211 for (size_t kk = 0; kk < kVectorSize; ++kk) {
212 EXPECT_EQ(b16[kk], bTmp16[kk]);
213 }
214 // WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize);
215 // for (int kk = 0; kk < kVectorSize; ++kk) {
216 // EXPECT_EQ(b32[kk], bTmp32[kk]);
217 // }
218 WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16);
219 for (size_t kk = 0; kk < 2; ++kk) {
220 EXPECT_EQ(static_cast<int16_t>(kk + 2), bTmp16[kk]);
221 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
Yves Gerey665174f2018-06-19 15:03:05 +0200223 for (size_t kk = 0; kk < kVectorSize; ++kk) {
224 b32[kk] = B[kk];
225 b16[kk] = (int16_t)B[kk];
226 }
227 WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1);
228 for (size_t kk = 0; kk < kVectorSize; ++kk) {
229 EXPECT_EQ((B[kk] >> 1), bTmp16[kk]);
230 }
231 WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1);
232 for (size_t kk = 0; kk < kVectorSize; ++kk) {
233 EXPECT_EQ((B[kk] >> 1), bTmp16[kk]);
234 }
235 WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1);
236 for (size_t kk = 0; kk < kVectorSize; ++kk) {
237 EXPECT_EQ((B[kk] >> 1), bTmp32[kk]);
238 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000239
Yves Gerey665174f2018-06-19 15:03:05 +0200240 WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize);
241 for (size_t kk = 0; kk < kVectorSize; ++kk) {
242 EXPECT_EQ(b16[3 - kk], bTmp16[kk]);
243 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000244}
245
Karl Wiberg225842c2019-06-28 14:51:49 +0200246TEST(SplTest, MinMaxOperationsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700247 const size_t kVectorSize = 17;
niklase@google.com470e71d2011-07-07 08:21:25 +0000248
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000249 // Vectors to test the cases where minimum values have to be caught
250 // outside of the unrolled loops in ARM-Neon.
Yves Gerey665174f2018-06-19 15:03:05 +0200251 int16_t vector16[kVectorSize] = {-1,
252 7485,
253 0,
254 3333,
255 -18283,
256 0,
257 12334,
258 -29871,
259 988,
260 -3333,
261 345,
262 -456,
263 222,
264 999,
265 888,
266 8774,
267 WEBRTC_SPL_WORD16_MIN};
268 int32_t vector32[kVectorSize] = {-1,
269 0,
270 283211,
271 3333,
272 8712345,
273 0,
274 -3333,
275 89345,
276 -374585456,
277 222,
278 999,
279 122345334,
280 -12389756,
281 -987329871,
282 888,
283 -2,
284 WEBRTC_SPL_WORD32_MIN};
niklase@google.com470e71d2011-07-07 08:21:25 +0000285
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000286 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
287 WebRtcSpl_MinValueW16(vector16, kVectorSize));
288 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
289 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700290 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
291 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000293 // Test the cases where maximum values have to be caught
294 // outside of the unrolled loops in ARM-Neon.
295 vector16[kVectorSize - 1] = WEBRTC_SPL_WORD16_MAX;
296 vector32[kVectorSize - 1] = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +0000297
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000298 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
299 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
300 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
301 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
302 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
303 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
304 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
305 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700306 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
307 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
308 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000309
310 // Test the cases where multiple maximum and minimum values are present.
311 vector16[1] = WEBRTC_SPL_WORD16_MAX;
312 vector16[6] = WEBRTC_SPL_WORD16_MIN;
313 vector16[11] = WEBRTC_SPL_WORD16_MIN;
314 vector32[1] = WEBRTC_SPL_WORD32_MAX;
315 vector32[6] = WEBRTC_SPL_WORD32_MIN;
316 vector32[11] = WEBRTC_SPL_WORD32_MIN;
317
318 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
319 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
320 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
321 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
322 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
323 WebRtcSpl_MinValueW16(vector16, kVectorSize));
324 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
325 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
326 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
327 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
328 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
329 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700330 EXPECT_EQ(6u, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
331 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
332 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
333 EXPECT_EQ(6u, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
334 EXPECT_EQ(6u, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000335}
336
Karl Wiberg225842c2019-06-28 14:51:49 +0200337TEST(SplTest, VectorOperationsTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200338 const size_t kVectorSize = 4;
339 int B[] = {4, 12, 133, 1100};
340 int16_t a16[kVectorSize];
341 int16_t b16[kVectorSize];
342 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000343
Yves Gerey665174f2018-06-19 15:03:05 +0200344 for (size_t kk = 0; kk < kVectorSize; ++kk) {
345 a16[kk] = B[kk];
346 b16[kk] = B[kk];
347 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000348
Yves Gerey665174f2018-06-19 15:03:05 +0200349 WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize);
350 for (size_t kk = 0; kk < kVectorSize; ++kk) {
351 EXPECT_EQ((B[kk] * 3 + 7) >> 2, bTmp16[kk]);
352 }
353 WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize);
354 for (size_t kk = 0; kk < kVectorSize; ++kk) {
355 EXPECT_EQ((B[kk] * 3 + B[kk] * 2 + 2) >> 2, bTmp16[kk]);
356 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000357
Yves Gerey665174f2018-06-19 15:03:05 +0200358 WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize);
359 for (size_t kk = 0; kk < kVectorSize; ++kk) {
360 EXPECT_EQ(((B[kk] * 3 + B[kk] * 2 + 2) >> 2) + ((b16[kk] * 3 + 7) >> 2),
361 bTmp16[kk]);
362 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000363
Yves Gerey665174f2018-06-19 15:03:05 +0200364 WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
365 for (size_t kk = 0; kk < kVectorSize; ++kk) {
366 EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]);
367 }
368 WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2);
369 for (size_t kk = 0; kk < kVectorSize; ++kk) {
370 EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]);
371 }
372 WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize);
373 for (size_t kk = 0; kk < kVectorSize; ++kk) {
374 EXPECT_EQ(((a16[kk] * 13) >> 2) + ((b16[kk] * 7) >> 2), bTmp16[kk]);
375 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000376
Yves Gerey665174f2018-06-19 15:03:05 +0200377 WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2);
378 for (size_t kk = 0; kk < kVectorSize; ++kk) {
379 EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
380 }
381 WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2);
382 for (size_t kk = 0; kk < kVectorSize; ++kk) {
383 EXPECT_EQ((a16[kk] * b16[3 - kk]) >> 2, bTmp16[kk]);
384 }
385 WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6);
386 for (size_t kk = 0; kk < kVectorSize; ++kk) {
387 EXPECT_EQ((a16[kk] * b16[kk]) >> 6, bTmp16[kk]);
388 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000389
Yves Gerey665174f2018-06-19 15:03:05 +0200390 WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16);
391 for (size_t kk = 0; kk < kVectorSize - 1; ++kk) {
392 EXPECT_EQ(32767, bTmp16[kk]);
393 }
394 EXPECT_EQ(32749, bTmp16[kVectorSize - 1]);
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000395
Yves Gerey665174f2018-06-19 15:03:05 +0200396 EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +0000397}
398
Karl Wiberg225842c2019-06-28 14:51:49 +0200399TEST(SplTest, EstimatorsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700400 const size_t kOrder = 2;
Yves Gerey665174f2018-06-19 15:03:05 +0200401 const int32_t unstable_filter[] = {4, 12, 133, 1100};
402 const int32_t stable_filter[] = {1100, 133, 12, 4};
403 int16_t lpc[kOrder + 2] = {0};
404 int16_t refl[kOrder + 2] = {0};
405 int16_t lpc_result[] = {4096, -497, 15, 0};
406 int16_t refl_result[] = {-3962, 123, 0, 0};
niklase@google.com470e71d2011-07-07 08:21:25 +0000407
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000408 EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(unstable_filter, lpc, refl, kOrder));
409 EXPECT_EQ(1, WebRtcSpl_LevinsonDurbin(stable_filter, lpc, refl, kOrder));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700410 for (size_t i = 0; i < kOrder + 2; ++i) {
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000411 EXPECT_EQ(lpc_result[i], lpc[i]);
412 EXPECT_EQ(refl_result[i], refl[i]);
413 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000414}
415
Karl Wiberg225842c2019-06-28 14:51:49 +0200416TEST(SplTest, FilterTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200417 const size_t kVectorSize = 4;
418 const size_t kFilterOrder = 3;
419 int16_t A[] = {1, 2, 33, 100};
420 int16_t A5[] = {1, 2, 33, 100, -5};
421 int16_t B[] = {4, 12, 133, 110};
422 int16_t data_in[kVectorSize];
423 int16_t data_out[kVectorSize];
424 int16_t bTmp16Low[kVectorSize];
425 int16_t bState[kVectorSize];
426 int16_t bStateLow[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000427
Yves Gerey665174f2018-06-19 15:03:05 +0200428 WebRtcSpl_ZerosArrayW16(bState, kVectorSize);
429 WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize);
niklase@google.com470e71d2011-07-07 08:21:25 +0000430
Yves Gerey665174f2018-06-19 15:03:05 +0200431 for (size_t kk = 0; kk < kVectorSize; ++kk) {
432 data_in[kk] = A[kk];
433 data_out[kk] = 0;
434 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000435
Yves Gerey665174f2018-06-19 15:03:05 +0200436 // MA filters.
437 // Note that the input data has |kFilterOrder| states before the actual
438 // data (one sample).
439 WebRtcSpl_FilterMAFastQ12(&data_in[kFilterOrder], data_out, B,
440 kFilterOrder + 1, 1);
441 EXPECT_EQ(0, data_out[0]);
442 // AR filters.
443 // Note that the output data has |kFilterOrder| states before the actual
444 // data (one sample).
445 WebRtcSpl_FilterARFastQ12(data_in, &data_out[kFilterOrder], A,
446 kFilterOrder + 1, 1);
447 EXPECT_EQ(0, data_out[kFilterOrder]);
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000448
Yves Gerey665174f2018-06-19 15:03:05 +0200449 EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5, 5, data_in, kVectorSize, bState,
450 kVectorSize, bStateLow, kVectorSize,
451 data_out, bTmp16Low, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000452}
453
Karl Wiberg225842c2019-06-28 14:51:49 +0200454TEST(SplTest, RandTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200455 const int kVectorSize = 4;
456 int16_t BU[] = {3653, 12446, 8525, 30691};
457 int16_t b16[kVectorSize];
458 uint32_t bSeed = 100000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000459
Yves Gerey665174f2018-06-19 15:03:05 +0200460 EXPECT_EQ(7086, WebRtcSpl_RandU(&bSeed));
461 EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed));
462 EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed));
463 EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed));
464 for (int kk = 0; kk < kVectorSize; ++kk) {
465 EXPECT_EQ(BU[kk], b16[kk]);
466 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000467}
468
Karl Wiberg225842c2019-06-28 14:51:49 +0200469TEST(SplTest, DotProductWithScaleTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200470 EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16, vector16,
471 kVector16Size, 2));
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000472}
473
Karl Wiberg225842c2019-06-28 14:51:49 +0200474TEST(SplTest, CrossCorrelationTest) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000475 // Note the function arguments relation specificed by API.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700476 const size_t kCrossCorrelationDimension = 3;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000477 const int kShift = 2;
478 const int kStep = 1;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700479 const size_t kSeqDimension = 6;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000480
Yves Gerey665174f2018-06-19 15:03:05 +0200481 const int16_t kVector16[kVector16Size] = {
482 1, 4323, 1963, WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333,
483 -876, 8483, 142};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000484 int32_t vector32[kCrossCorrelationDimension] = {0};
485
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000486 WebRtcSpl_CrossCorrelation(vector32, vector16, kVector16, kSeqDimension,
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000487 kCrossCorrelationDimension, kShift, kStep);
488
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000489 // WebRtcSpl_CrossCorrelationC() and WebRtcSpl_CrossCorrelationNeon()
490 // are not bit-exact.
Yves Gerey665174f2018-06-19 15:03:05 +0200491 const int32_t kExpected[kCrossCorrelationDimension] = {-266947903, -15579555,
492 -171282001};
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000493 const int32_t* expected = kExpected;
494#if !defined(MIPS32_LE)
Yves Gerey665174f2018-06-19 15:03:05 +0200495 const int32_t kExpectedNeon[kCrossCorrelationDimension] = {
496 -266947901, -15579553, -171281999};
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000497 if (WebRtcSpl_CrossCorrelation != WebRtcSpl_CrossCorrelationC) {
498 expected = kExpectedNeon;
499 }
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000500#endif
Peter Kastingdce40cf2015-08-24 14:52:23 -0700501 for (size_t i = 0; i < kCrossCorrelationDimension; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000502 EXPECT_EQ(expected[i], vector32[i]);
503 }
504}
505
Karl Wiberg225842c2019-06-28 14:51:49 +0200506TEST(SplTest, AutoCorrelationTest) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000507 int scale = 0;
508 int32_t vector32[kVector16Size];
Yves Gerey665174f2018-06-19 15:03:05 +0200509 const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063,
510 -85221647, -17104971, 61806945,
511 6644603, -669329, 43};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000512
Peter Kasting1380e262015-08-28 17:31:03 -0700513 EXPECT_EQ(kVector16Size,
Peter Kasting728d9032015-06-11 14:31:38 -0700514 WebRtcSpl_AutoCorrelation(vector16, kVector16Size,
515 kVector16Size - 1, vector32, &scale));
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000516 EXPECT_EQ(3, scale);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700517 for (size_t i = 0; i < kVector16Size; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000518 EXPECT_EQ(expected[i], vector32[i]);
519 }
520}
521
Karl Wiberg225842c2019-06-28 14:51:49 +0200522TEST(SplTest, SignalProcessingTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200523 const size_t kVectorSize = 4;
524 int A[] = {1, 2, 33, 100};
525 const int16_t kHanning[4] = {2399, 8192, 13985, 16384};
526 int16_t b16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000527
Yves Gerey665174f2018-06-19 15:03:05 +0200528 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000529
Yves Gerey665174f2018-06-19 15:03:05 +0200530 int bScale = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000531
Yves Gerey665174f2018-06-19 15:03:05 +0200532 for (size_t kk = 0; kk < kVectorSize; ++kk) {
533 b16[kk] = A[kk];
534 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000535
Yves Gerey665174f2018-06-19 15:03:05 +0200536 // TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
537 // WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
538 //// for (int kk = 0; kk < kVectorSize; ++kk) {
539 //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
540 //// }
541 // WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16);
542 //// for (int kk = 0; kk < kVectorSize; ++kk) {
543 //// EXPECT_EQ(a16[kk], b16[kk]);
544 //// }
545 // WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16);
546 //// for (int kk = 0; kk < kVectorSize; ++kk) {
547 //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
548 //// }
bjornv@webrtc.org53096392012-02-07 08:10:46 +0000549
Yves Gerey665174f2018-06-19 15:03:05 +0200550 WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize);
551 for (size_t kk = 0; kk < kVectorSize; ++kk) {
552 EXPECT_EQ(kHanning[kk], bTmp16[kk]);
553 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000554
Yves Gerey665174f2018-06-19 15:03:05 +0200555 for (size_t kk = 0; kk < kVectorSize; ++kk) {
556 b16[kk] = A[kk];
557 }
558 EXPECT_EQ(11094, WebRtcSpl_Energy(b16, kVectorSize, &bScale));
559 EXPECT_EQ(0, bScale);
niklase@google.com470e71d2011-07-07 08:21:25 +0000560}
561
Karl Wiberg225842c2019-06-28 14:51:49 +0200562TEST(SplTest, FFTTest) {
Yves Gerey665174f2018-06-19 15:03:05 +0200563 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 +0000564
Yves Gerey665174f2018-06-19 15:03:05 +0200565 EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
566 // for (int kk = 0; kk < 16; ++kk) {
567 // EXPECT_EQ(A[kk], B[kk]);
568 // }
569 EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1));
570 // for (int kk = 0; kk < 16; ++kk) {
571 // EXPECT_EQ(A[kk], B[kk]);
572 // }
573 WebRtcSpl_ComplexBitReverse(B, 3);
574 for (int kk = 0; kk < 16; ++kk) {
575 // EXPECT_EQ(A[kk], B[kk]);
576 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000577}
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000578
Karl Wiberg225842c2019-06-28 14:51:49 +0200579TEST(SplTest, Resample48WithSaturationTest) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000580 // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number
581 // of samples.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700582 const size_t kBlockSize = 16;
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000583
584 // Saturated input vector of 48 samples.
585 const int32_t kVectorSaturated[3 * kBlockSize + 7] = {
Yves Gerey665174f2018-06-19 15:03:05 +0200586 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
587 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
588 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
589 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
590 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
591 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
592 32767, 32767, 32767, 32767, 32767, 32767, 32767};
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000593
594 // All values in |out_vector| should be |kRefValue32kHz|.
595 const int32_t kRefValue32kHz1 = -1077493760;
596 const int32_t kRefValue32kHz2 = 1077493645;
597
598 // After bit shift with saturation, |out_vector_w16| is saturated.
599
600 const int16_t kRefValue16kHz1 = -32768;
601 const int16_t kRefValue16kHz2 = 32767;
602 // Vector for storing output.
603 int32_t out_vector[2 * kBlockSize];
604 int16_t out_vector_w16[2 * kBlockSize];
605
606 WebRtcSpl_Resample48khzTo32khz(kVectorSaturated, out_vector, kBlockSize);
607 WebRtcSpl_VectorBitShiftW32ToW16(out_vector_w16, 2 * kBlockSize, out_vector,
608 15);
609
610 // Comparing output values against references. The values at position
611 // 12-15 are skipped to account for the filter lag.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700612 for (size_t i = 0; i < 12; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000613 EXPECT_EQ(kRefValue32kHz1, out_vector[i]);
614 EXPECT_EQ(kRefValue16kHz1, out_vector_w16[i]);
615 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700616 for (size_t i = 16; i < 2 * kBlockSize; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000617 EXPECT_EQ(kRefValue32kHz2, out_vector[i]);
618 EXPECT_EQ(kRefValue16kHz2, out_vector_w16[i]);
619 }
620}