blob: b9efe01fe7e86fbde987fec18bf869e3d2a69c21 [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>
12#include <sstream>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "common_audio/signal_processing/include/signal_processing_library.h"
15#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;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +000018static const int16_t vector16[kVector16Size] = {1, -15511, 4323, 1963,
19 WEBRTC_SPL_WORD16_MAX, 0, WEBRTC_SPL_WORD16_MIN + 5, -3333, 345};
20
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +000021class SplTest : public testing::Test {
22 protected:
oprypin67fdb802017-03-09 06:25:06 -080023 SplTest() {
24 WebRtcSpl_Init();
25 }
26 virtual ~SplTest() {
27 }
niklase@google.com470e71d2011-07-07 08:21:25 +000028};
29
niklase@google.com470e71d2011-07-07 08:21:25 +000030TEST_F(SplTest, MacroTest) {
31 // Macros with inputs.
32 int A = 10;
33 int B = 21;
34 int a = -3;
35 int b = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +000036
37 EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B));
38 EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B));
39
40 EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a));
41 EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a));
niklase@google.com470e71d2011-07-07 08:21:25 +000042
43 EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B));
phoglund@webrtc.org78088c22012-02-07 14:56:45 +000044 EXPECT_EQ(2147483651u, WEBRTC_SPL_UMUL(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000045 b = WEBRTC_SPL_WORD16_MAX >> 1;
phoglund@webrtc.org78088c22012-02-07 14:56:45 +000046 EXPECT_EQ(4294918147u, WEBRTC_SPL_UMUL_32_16(a, b));
niklase@google.com470e71d2011-07-07 08:21:25 +000047 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
48
49 a = b;
50 b = -3;
niklase@google.com470e71d2011-07-07 08:21:25 +000051
52 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
53 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
54 EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b));
55 EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b));
56
niklase@google.com470e71d2011-07-07 08:21:25 +000057 EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000058 EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000059
niklase@google.com470e71d2011-07-07 08:21:25 +000060 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B));
61 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A));
niklase@google.com470e71d2011-07-07 08:21:25 +000062
niklase@google.com470e71d2011-07-07 08:21:25 +000063 // Shifting with negative numbers allowed
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +000064 int shift_amount = 1; // Workaround compiler warning using variable here.
niklase@google.com470e71d2011-07-07 08:21:25 +000065 // Positive means left shift
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +000066 EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, shift_amount));
niklase@google.com470e71d2011-07-07 08:21:25 +000067
68 // Shifting with negative numbers not allowed
69 // We cannot do casting here due to signed/unsigned problem
niklase@google.com470e71d2011-07-07 08:21:25 +000070 EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
71
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +000072 EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +000073
74 EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
kma@webrtc.org76117912012-08-28 00:43:55 +000075
76 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b));
77 EXPECT_EQ(1073676289, WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX,
78 WEBRTC_SPL_WORD16_MAX));
79 EXPECT_EQ(1073709055, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MAX,
80 WEBRTC_SPL_WORD32_MAX));
81 EXPECT_EQ(1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
82 WEBRTC_SPL_WORD32_MIN));
kma@webrtc.org9b1cf542012-09-03 21:22:28 +000083#ifdef WEBRTC_ARCH_ARM_V7
kma@webrtc.org76117912012-08-28 00:43:55 +000084 EXPECT_EQ(-1073741824,
85 WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
86 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000087#else
88 EXPECT_EQ(-1073741823,
89 WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
90 WEBRTC_SPL_WORD32_MAX));
kma@webrtc.org76117912012-08-28 00:43:55 +000091#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000092}
93
94TEST_F(SplTest, InlineTest) {
pbos@webrtc.orgb0913072013-04-09 16:40:28 +000095 int16_t a16 = 121;
96 int16_t b16 = -17;
97 int32_t a32 = 111121;
98 int32_t b32 = -1711;
niklase@google.com470e71d2011-07-07 08:21:25 +000099
kma@webrtc.orgee508e52012-08-16 19:19:51 +0000100 EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000101
102 EXPECT_EQ(0, WebRtcSpl_NormW32(0));
103 EXPECT_EQ(31, WebRtcSpl_NormW32(-1));
104 EXPECT_EQ(0, WebRtcSpl_NormW32(WEBRTC_SPL_WORD32_MIN));
kma@webrtc.orgee508e52012-08-16 19:19:51 +0000105 EXPECT_EQ(14, WebRtcSpl_NormW32(a32));
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000106
107 EXPECT_EQ(0, WebRtcSpl_NormW16(0));
108 EXPECT_EQ(15, WebRtcSpl_NormW16(-1));
109 EXPECT_EQ(0, WebRtcSpl_NormW16(WEBRTC_SPL_WORD16_MIN));
kma@webrtc.orgee508e52012-08-16 19:19:51 +0000110 EXPECT_EQ(4, WebRtcSpl_NormW16(b32));
Bjorn Volckerbc46bf22015-03-30 23:38:28 +0200111 for (int ii = 0; ii < 15; ++ii) {
112 int16_t value = 1 << ii;
113 EXPECT_EQ(14 - ii, WebRtcSpl_NormW16(value));
114 EXPECT_EQ(15 - ii, WebRtcSpl_NormW16(-value));
115 }
kma@webrtc.org6679dcc2012-10-05 00:27:10 +0000116
henrike@webrtc.org6ac22e62014-08-11 21:06:30 +0000117 EXPECT_EQ(0, WebRtcSpl_NormU32(0u));
bjornv@webrtc.orgcf8f33a2014-08-12 10:27:21 +0000118 EXPECT_EQ(0, WebRtcSpl_NormU32(0xffffffff));
henrike@webrtc.org6ac22e62014-08-11 21:06:30 +0000119 EXPECT_EQ(15, WebRtcSpl_NormU32(static_cast<uint32_t>(a32)));
niklase@google.com470e71d2011-07-07 08:21:25 +0000120
kma@webrtc.orgee508e52012-08-16 19:19:51 +0000121 EXPECT_EQ(104, WebRtcSpl_AddSatW16(a16, b16));
122 EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16));
kwibergbca568b2016-05-23 04:07:00 -0700123}
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
kwibergbca568b2016-05-23 04:07:00 -0700125TEST_F(SplTest, AddSubSatW32) {
126 static constexpr int32_t kAddSubArgs[] = {
127 INT32_MIN, INT32_MIN + 1, -3, -2, -1, 0, 1, -1, 2,
128 3, INT32_MAX - 1, INT32_MAX};
129 for (int32_t a : kAddSubArgs) {
130 for (int32_t b : kAddSubArgs) {
131 const int64_t sum = std::max<int64_t>(
132 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) + b));
133 const int64_t diff = std::max<int64_t>(
134 INT32_MIN, std::min<int64_t>(INT32_MAX, static_cast<int64_t>(a) - b));
135 std::ostringstream ss;
136 ss << a << " +/- " << b << ": sum " << sum << ", diff " << diff;
137 SCOPED_TRACE(ss.str());
138 EXPECT_EQ(sum, WebRtcSpl_AddSatW32(a, b));
139 EXPECT_EQ(diff, WebRtcSpl_SubSatW32(a, b));
140 }
141 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000142}
143
kwiberg729b21f2016-06-02 04:02:12 -0700144TEST_F(SplTest, CountLeadingZeros32) {
145 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32(0));
146 EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32_NotBuiltin(0));
147 for (int i = 0; i < 32; ++i) {
148 const uint32_t single_one = uint32_t{1} << i;
149 const uint32_t all_ones = 2 * single_one - 1;
150 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(single_one));
151 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(single_one));
152 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32(all_ones));
153 EXPECT_EQ(31 - i, WebRtcSpl_CountLeadingZeros32_NotBuiltin(all_ones));
154 }
155}
156
157TEST_F(SplTest, CountLeadingZeros64) {
158 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64(0));
159 EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64_NotBuiltin(0));
160 for (int i = 0; i < 64; ++i) {
161 const uint64_t single_one = uint64_t{1} << i;
162 const uint64_t all_ones = 2 * single_one - 1;
163 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(single_one));
164 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(single_one));
165 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64(all_ones));
166 EXPECT_EQ(63 - i, WebRtcSpl_CountLeadingZeros64_NotBuiltin(all_ones));
167 }
168}
169
niklase@google.com470e71d2011-07-07 08:21:25 +0000170TEST_F(SplTest, MathOperationsTest) {
kma@webrtc.orgc839f082012-08-13 21:49:23 +0000171 int A = 1134567892;
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000172 int32_t num = 117;
173 int32_t den = -5;
174 uint16_t denU = 5;
kma@webrtc.orgc839f082012-08-13 21:49:23 +0000175 EXPECT_EQ(33700, WebRtcSpl_Sqrt(A));
176 EXPECT_EQ(33683, WebRtcSpl_SqrtFloor(A));
niklase@google.com470e71d2011-07-07 08:21:25 +0000177
178
179 EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num));
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000180 EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (int16_t)den));
181 EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (int16_t)den));
kjellander@webrtc.org0403ef42011-11-17 08:35:47 +0000182 EXPECT_EQ(23u, WebRtcSpl_DivU32U16(num, denU));
niklase@google.com470e71d2011-07-07 08:21:25 +0000183 EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
184}
185
186TEST_F(SplTest, BasicArrayOperationsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700187 const size_t kVectorSize = 4;
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 int B[] = {4, 12, 133, 1100};
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000189 int16_t b16[kVectorSize];
190 int32_t b32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000191
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000192 int16_t bTmp16[kVectorSize];
193 int32_t bTmp32[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000194
bjornv@google.com801809c2011-07-18 14:05:24 +0000195 WebRtcSpl_MemSetW16(b16, 3, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700196 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 EXPECT_EQ(3, b16[kk]);
198 }
bjornv@webrtc.org3cbd6c22014-09-04 13:21:44 +0000199 WebRtcSpl_ZerosArrayW16(b16, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700200 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000201 EXPECT_EQ(0, b16[kk]);
202 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000203 WebRtcSpl_MemSetW32(b32, 3, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700204 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000205 EXPECT_EQ(3, b32[kk]);
206 }
bjornv@webrtc.org3cbd6c22014-09-04 13:21:44 +0000207 WebRtcSpl_ZerosArrayW32(b32, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700208 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 EXPECT_EQ(0, b32[kk]);
210 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700211 for (size_t kk = 0; kk < kVectorSize; ++kk) {
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000212 bTmp16[kk] = (int16_t)kk;
213 bTmp32[kk] = (int32_t)kk;
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000215 WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700216 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 EXPECT_EQ(b16[kk], bTmp16[kk]);
218 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000219// WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize);
220// for (int kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000221// EXPECT_EQ(b32[kk], bTmp32[kk]);
222// }
bjornv@webrtc.org3cbd6c22014-09-04 13:21:44 +0000223 WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700224 for (size_t kk = 0; kk < 2; ++kk) {
225 EXPECT_EQ(static_cast<int16_t>(kk+2), bTmp16[kk]);
niklase@google.com470e71d2011-07-07 08:21:25 +0000226 }
227
Peter Kastingdce40cf2015-08-24 14:52:23 -0700228 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 b32[kk] = B[kk];
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000230 b16[kk] = (int16_t)B[kk];
niklase@google.com470e71d2011-07-07 08:21:25 +0000231 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000232 WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700233 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000234 EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
235 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000236 WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700237 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000238 EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
239 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000240 WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700241 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000242 EXPECT_EQ((B[kk]>>1), bTmp32[kk]);
243 }
244
bjornv@google.com801809c2011-07-18 14:05:24 +0000245 WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700246 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000247 EXPECT_EQ(b16[3-kk], bTmp16[kk]);
248 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000249}
250
251TEST_F(SplTest, MinMaxOperationsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700252 const size_t kVectorSize = 17;
niklase@google.com470e71d2011-07-07 08:21:25 +0000253
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000254 // Vectors to test the cases where minimum values have to be caught
255 // outside of the unrolled loops in ARM-Neon.
256 int16_t vector16[kVectorSize] = {-1, 7485, 0, 3333,
257 -18283, 0, 12334, -29871, 988, -3333,
258 345, -456, 222, 999, 888, 8774, WEBRTC_SPL_WORD16_MIN};
259 int32_t vector32[kVectorSize] = {-1, 0, 283211, 3333,
260 8712345, 0, -3333, 89345, -374585456, 222, 999, 122345334,
261 -12389756, -987329871, 888, -2, WEBRTC_SPL_WORD32_MIN};
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000263 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
264 WebRtcSpl_MinValueW16(vector16, kVectorSize));
265 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
266 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700267 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
268 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000269
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000270 // Test the cases where maximum values have to be caught
271 // outside of the unrolled loops in ARM-Neon.
272 vector16[kVectorSize - 1] = WEBRTC_SPL_WORD16_MAX;
273 vector32[kVectorSize - 1] = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +0000274
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000275 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
276 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
277 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
278 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
279 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
280 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
281 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
282 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700283 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
284 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
285 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000286
287 // Test the cases where multiple maximum and minimum values are present.
288 vector16[1] = WEBRTC_SPL_WORD16_MAX;
289 vector16[6] = WEBRTC_SPL_WORD16_MIN;
290 vector16[11] = WEBRTC_SPL_WORD16_MIN;
291 vector32[1] = WEBRTC_SPL_WORD32_MAX;
292 vector32[6] = WEBRTC_SPL_WORD32_MIN;
293 vector32[11] = WEBRTC_SPL_WORD32_MIN;
294
295 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
296 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
297 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
298 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
299 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
300 WebRtcSpl_MinValueW16(vector16, kVectorSize));
301 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
302 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
303 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
304 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
305 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
306 WebRtcSpl_MinValueW32(vector32, kVectorSize));
Peter Kasting1380e262015-08-28 17:31:03 -0700307 EXPECT_EQ(6u, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
308 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
309 EXPECT_EQ(1u, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
310 EXPECT_EQ(6u, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
311 EXPECT_EQ(6u, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000312}
313
314TEST_F(SplTest, VectorOperationsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700315 const size_t kVectorSize = 4;
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 int B[] = {4, 12, 133, 1100};
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000317 int16_t a16[kVectorSize];
318 int16_t b16[kVectorSize];
319 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000320
Peter Kastingdce40cf2015-08-24 14:52:23 -0700321 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 a16[kk] = B[kk];
323 b16[kk] = B[kk];
324 }
325
bjornv@google.com801809c2011-07-18 14:05:24 +0000326 WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700327 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 EXPECT_EQ((B[kk]*3+7)>>2, bTmp16[kk]);
329 }
oprypin67fdb802017-03-09 06:25:06 -0800330 WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16,
331 kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700332 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 EXPECT_EQ((B[kk]*3+B[kk]*2+2)>>2, bTmp16[kk]);
334 }
335
bjornv@google.com801809c2011-07-18 14:05:24 +0000336 WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700337 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
339 }
340
bjornv@google.com801809c2011-07-18 14:05:24 +0000341 WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700342 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
344 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000345 WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700346 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
348 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000349 WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700350 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 EXPECT_EQ(((a16[kk]*13)>>2)+((b16[kk]*7)>>2), bTmp16[kk]);
352 }
353
bjornv@google.com801809c2011-07-18 14:05:24 +0000354 WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700355 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
357 }
oprypin67fdb802017-03-09 06:25:06 -0800358 WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3],
359 kVectorSize, 2);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700360 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 EXPECT_EQ((a16[kk]*b16[3-kk])>>2, bTmp16[kk]);
362 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000363 WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700364 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000365 EXPECT_EQ((a16[kk]*b16[kk])>>6, bTmp16[kk]);
366 }
367
bjornv@google.com801809c2011-07-18 14:05:24 +0000368 WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700369 for (size_t kk = 0; kk < kVectorSize - 1; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000370 EXPECT_EQ(32767, bTmp16[kk]);
371 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000372 EXPECT_EQ(32749, bTmp16[kVectorSize - 1]);
kma@webrtc.orgda236df2012-08-07 19:35:00 +0000373
374 EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
niklase@google.com470e71d2011-07-07 08:21:25 +0000375}
376
377TEST_F(SplTest, EstimatorsTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700378 const size_t kOrder = 2;
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000379 const int32_t unstable_filter[] = { 4, 12, 133, 1100 };
380 const int32_t stable_filter[] = { 1100, 133, 12, 4 };
381 int16_t lpc[kOrder + 2] = { 0 };
382 int16_t refl[kOrder + 2] = { 0 };
383 int16_t lpc_result[] = { 4096, -497, 15, 0 };
384 int16_t refl_result[] = { -3962, 123, 0, 0 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000385
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000386 EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(unstable_filter, lpc, refl, kOrder));
387 EXPECT_EQ(1, WebRtcSpl_LevinsonDurbin(stable_filter, lpc, refl, kOrder));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700388 for (size_t i = 0; i < kOrder + 2; ++i) {
bjornv@webrtc.org88a42982015-01-12 05:53:43 +0000389 EXPECT_EQ(lpc_result[i], lpc[i]);
390 EXPECT_EQ(refl_result[i], refl[i]);
391 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000392}
393
394TEST_F(SplTest, FilterTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700395 const size_t kVectorSize = 4;
396 const size_t kFilterOrder = 3;
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000397 int16_t A[] = {1, 2, 33, 100};
398 int16_t A5[] = {1, 2, 33, 100, -5};
399 int16_t B[] = {4, 12, 133, 110};
400 int16_t data_in[kVectorSize];
401 int16_t data_out[kVectorSize];
402 int16_t bTmp16Low[kVectorSize];
403 int16_t bState[kVectorSize];
404 int16_t bStateLow[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000405
bjornv@google.com801809c2011-07-18 14:05:24 +0000406 WebRtcSpl_ZerosArrayW16(bState, kVectorSize);
407 WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize);
niklase@google.com470e71d2011-07-07 08:21:25 +0000408
Peter Kastingdce40cf2015-08-24 14:52:23 -0700409 for (size_t kk = 0; kk < kVectorSize; ++kk) {
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000410 data_in[kk] = A[kk];
411 data_out[kk] = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 }
413
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000414 // MA filters.
415 // Note that the input data has |kFilterOrder| states before the actual
416 // data (one sample).
417 WebRtcSpl_FilterMAFastQ12(&data_in[kFilterOrder], data_out, B,
418 kFilterOrder + 1, 1);
419 EXPECT_EQ(0, data_out[0]);
420 // AR filters.
421 // Note that the output data has |kFilterOrder| states before the actual
422 // data (one sample).
423 WebRtcSpl_FilterARFastQ12(data_in, &data_out[kFilterOrder], A,
424 kFilterOrder + 1, 1);
425 EXPECT_EQ(0, data_out[kFilterOrder]);
426
bjornv@google.com801809c2011-07-18 14:05:24 +0000427 EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5,
428 5,
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000429 data_in,
bjornv@google.com801809c2011-07-18 14:05:24 +0000430 kVectorSize,
431 bState,
432 kVectorSize,
433 bStateLow,
434 kVectorSize,
bjornv@webrtc.org67480872012-01-19 10:41:39 +0000435 data_out,
bjornv@google.com801809c2011-07-18 14:05:24 +0000436 bTmp16Low,
437 kVectorSize));
niklase@google.com470e71d2011-07-07 08:21:25 +0000438}
439
440TEST_F(SplTest, RandTest) {
bjornv@google.com801809c2011-07-18 14:05:24 +0000441 const int kVectorSize = 4;
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000442 int16_t BU[] = {3653, 12446, 8525, 30691};
443 int16_t b16[kVectorSize];
444 uint32_t bSeed = 100000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000445
bjornv@webrtc.orgd83d6072014-05-16 06:38:47 +0000446 EXPECT_EQ(7086, WebRtcSpl_RandU(&bSeed));
bjornv@google.com801809c2011-07-18 14:05:24 +0000447 EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed));
448 EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed));
449 EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed));
450 for (int kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000451 EXPECT_EQ(BU[kk], b16[kk]);
452 }
453}
454
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000455TEST_F(SplTest, DotProductWithScaleTest) {
456 EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16,
457 vector16, kVector16Size, 2));
458}
459
460TEST_F(SplTest, CrossCorrelationTest) {
461 // Note the function arguments relation specificed by API.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700462 const size_t kCrossCorrelationDimension = 3;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000463 const int kShift = 2;
464 const int kStep = 1;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700465 const size_t kSeqDimension = 6;
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000466
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000467 const int16_t kVector16[kVector16Size] = {1, 4323, 1963,
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000468 WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333, -876, 8483, 142};
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000469 int32_t vector32[kCrossCorrelationDimension] = {0};
470
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000471 WebRtcSpl_CrossCorrelation(vector32, vector16, kVector16, kSeqDimension,
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000472 kCrossCorrelationDimension, kShift, kStep);
473
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000474 // WebRtcSpl_CrossCorrelationC() and WebRtcSpl_CrossCorrelationNeon()
475 // are not bit-exact.
476 const int32_t kExpected[kCrossCorrelationDimension] =
477 {-266947903, -15579555, -171282001};
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000478 const int32_t* expected = kExpected;
479#if !defined(MIPS32_LE)
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000480 const int32_t kExpectedNeon[kCrossCorrelationDimension] =
481 {-266947901, -15579553, -171281999};
kma@webrtc.org0a4cdc42012-10-03 21:15:39 +0000482 if (WebRtcSpl_CrossCorrelation != WebRtcSpl_CrossCorrelationC) {
483 expected = kExpectedNeon;
484 }
andrew@webrtc.org8bf755d2013-09-18 17:40:46 +0000485#endif
Peter Kastingdce40cf2015-08-24 14:52:23 -0700486 for (size_t i = 0; i < kCrossCorrelationDimension; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000487 EXPECT_EQ(expected[i], vector32[i]);
488 }
489}
490
491TEST_F(SplTest, AutoCorrelationTest) {
492 int scale = 0;
493 int32_t vector32[kVector16Size];
494 const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063,
495 -85221647, -17104971, 61806945, 6644603, -669329, 43};
496
Peter Kasting1380e262015-08-28 17:31:03 -0700497 EXPECT_EQ(kVector16Size,
Peter Kasting728d9032015-06-11 14:31:38 -0700498 WebRtcSpl_AutoCorrelation(vector16, kVector16Size,
499 kVector16Size - 1, vector32, &scale));
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000500 EXPECT_EQ(3, scale);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700501 for (size_t i = 0; i < kVector16Size; ++i) {
kma@webrtc.org8fe5f322012-08-06 20:19:56 +0000502 EXPECT_EQ(expected[i], vector32[i]);
503 }
504}
505
niklase@google.com470e71d2011-07-07 08:21:25 +0000506TEST_F(SplTest, SignalProcessingTest) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700507 const size_t kVectorSize = 4;
niklase@google.com470e71d2011-07-07 08:21:25 +0000508 int A[] = {1, 2, 33, 100};
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000509 const int16_t kHanning[4] = { 2399, 8192, 13985, 16384 };
510 int16_t b16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000511
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000512 int16_t bTmp16[kVectorSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000513
514 int bScale = 0;
515
Peter Kastingdce40cf2015-08-24 14:52:23 -0700516 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000517 b16[kk] = A[kk];
niklase@google.com470e71d2011-07-07 08:21:25 +0000518 }
519
bjornv@webrtc.org53096392012-02-07 08:10:46 +0000520 // TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
521// WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
522//// for (int kk = 0; kk < kVectorSize; ++kk) {
523//// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
524//// }
525// WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16);
526//// for (int kk = 0; kk < kVectorSize; ++kk) {
527//// EXPECT_EQ(a16[kk], b16[kk]);
528//// }
529// WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16);
530//// for (int kk = 0; kk < kVectorSize; ++kk) {
531//// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
532//// }
533
bjornv@google.com801809c2011-07-18 14:05:24 +0000534 WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700535 for (size_t kk = 0; kk < kVectorSize; ++kk) {
bjornv@webrtc.org53096392012-02-07 08:10:46 +0000536 EXPECT_EQ(kHanning[kk], bTmp16[kk]);
537 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000538
Peter Kastingdce40cf2015-08-24 14:52:23 -0700539 for (size_t kk = 0; kk < kVectorSize; ++kk) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 b16[kk] = A[kk];
541 }
bjornv@google.com801809c2011-07-18 14:05:24 +0000542 EXPECT_EQ(11094 , WebRtcSpl_Energy(b16, kVectorSize, &bScale));
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 EXPECT_EQ(0, bScale);
544}
545
546TEST_F(SplTest, FFTTest) {
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000547 int16_t B[] = {1, 2, 33, 100,
niklase@google.com470e71d2011-07-07 08:21:25 +0000548 2, 3, 34, 101,
549 3, 4, 35, 102,
550 4, 5, 36, 103};
551
552 EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
553// for (int kk = 0; kk < 16; ++kk) {
554// EXPECT_EQ(A[kk], B[kk]);
555// }
556 EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1));
557// for (int kk = 0; kk < 16; ++kk) {
558// EXPECT_EQ(A[kk], B[kk]);
559// }
560 WebRtcSpl_ComplexBitReverse(B, 3);
561 for (int kk = 0; kk < 16; ++kk) {
oprypin67fdb802017-03-09 06:25:06 -0800562// EXPECT_EQ(A[kk], B[kk]);
niklase@google.com470e71d2011-07-07 08:21:25 +0000563 }
564}
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000565
566TEST_F(SplTest, Resample48WithSaturationTest) {
567 // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number
568 // of samples.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700569 const size_t kBlockSize = 16;
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000570
571 // Saturated input vector of 48 samples.
572 const int32_t kVectorSaturated[3 * kBlockSize + 7] = {
573 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
574 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
575 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
576 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
577 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
578 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
579 32767, 32767, 32767, 32767, 32767, 32767, 32767
580 };
581
582 // All values in |out_vector| should be |kRefValue32kHz|.
583 const int32_t kRefValue32kHz1 = -1077493760;
584 const int32_t kRefValue32kHz2 = 1077493645;
585
586 // After bit shift with saturation, |out_vector_w16| is saturated.
587
588 const int16_t kRefValue16kHz1 = -32768;
589 const int16_t kRefValue16kHz2 = 32767;
590 // Vector for storing output.
591 int32_t out_vector[2 * kBlockSize];
592 int16_t out_vector_w16[2 * kBlockSize];
593
594 WebRtcSpl_Resample48khzTo32khz(kVectorSaturated, out_vector, kBlockSize);
595 WebRtcSpl_VectorBitShiftW32ToW16(out_vector_w16, 2 * kBlockSize, out_vector,
596 15);
597
598 // Comparing output values against references. The values at position
599 // 12-15 are skipped to account for the filter lag.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700600 for (size_t i = 0; i < 12; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000601 EXPECT_EQ(kRefValue32kHz1, out_vector[i]);
602 EXPECT_EQ(kRefValue16kHz1, out_vector_w16[i]);
603 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700604 for (size_t i = 16; i < 2 * kBlockSize; ++i) {
tina.legrand@webrtc.org53a8be22012-11-15 08:34:38 +0000605 EXPECT_EQ(kRefValue32kHz2, out_vector[i]);
606 EXPECT_EQ(kRefValue16kHz2, out_vector_w16[i]);
607 }
608}