blob: a68840e8df64548bbf990af7d880c4ac8ad80858 [file] [log] [blame]
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orgabf0cd82013-05-27 09:49:58 +000011#include "testing/gtest/include/gtest/gtest.h"
12#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000013
14static const int kVector16Size = 9;
15static const int16_t vector16[kVector16Size] = {1, -15511, 4323, 1963,
16 WEBRTC_SPL_WORD16_MAX, 0, WEBRTC_SPL_WORD16_MIN + 5, -3333, 345};
17
18class SplTest : public testing::Test {
19 protected:
20 SplTest() {
21 WebRtcSpl_Init();
22 }
23 virtual ~SplTest() {
24 }
25};
26
27TEST_F(SplTest, MacroTest) {
28 // Macros with inputs.
29 int A = 10;
30 int B = 21;
31 int a = -3;
32 int b = WEBRTC_SPL_WORD32_MAX;
33 int nr = 2;
34 int d_ptr2 = 0;
35
36 EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B));
37 EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B));
38
39 EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a));
40 EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a));
41 EXPECT_EQ(0, WEBRTC_SPL_GET_BYTE(&B, nr));
42 WEBRTC_SPL_SET_BYTE(&d_ptr2, 1, nr);
43 EXPECT_EQ(65536, d_ptr2);
44
45 EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B));
46 EXPECT_EQ(-2147483645, WEBRTC_SPL_MUL(a, b));
47 EXPECT_EQ(2147483651u, WEBRTC_SPL_UMUL(a, b));
48 b = WEBRTC_SPL_WORD16_MAX >> 1;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000049 EXPECT_EQ(1073627139u, WEBRTC_SPL_UMUL_16_16(a, b));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000050 EXPECT_EQ(4294918147u, WEBRTC_SPL_UMUL_32_16(a, b));
51 EXPECT_EQ(65535u, WEBRTC_SPL_UMUL_32_16_RSFT16(a, b));
52 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
53
54 a = b;
55 b = -3;
56 EXPECT_EQ(-5461, WEBRTC_SPL_DIV(a, b));
57 EXPECT_EQ(0u, WEBRTC_SPL_UDIV(a, b));
58
59 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
60 EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
61 EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b));
62 EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b));
63
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000064 int a32a = (WEBRTC_SPL_WORD32_MAX >> 16);
65 int a32b = (WEBRTC_SPL_WORD32_MAX & 0x0000ffff);
66 EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, A));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000067
68 EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2));
69 EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000070
71 EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W32(a, b));
72 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B));
73 EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A));
74 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_32_16(a, b));
75
76 EXPECT_EQ(16386, WEBRTC_SPL_SUB_SAT_W32(a, b));
77 EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W16(a, b));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000078
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000079 // Shifting with negative numbers allowed
80 int shift_amount = 1; // Workaround compiler warning using variable here.
81 // Positive means left shift
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000082 EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, shift_amount));
83
84 // Shifting with negative numbers not allowed
85 // We cannot do casting here due to signed/unsigned problem
86 EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W16(a, 1));
87 EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W16(a, 1));
88 EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W32(a, 1));
89 EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
90
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000091 EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1));
92 EXPECT_EQ(32766u, WEBRTC_SPL_LSHIFT_U32(a, 1));
93
94 EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
95
96 EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b));
97 EXPECT_EQ(1073676289, WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX,
98 WEBRTC_SPL_WORD16_MAX));
99 EXPECT_EQ(1073709055, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MAX,
100 WEBRTC_SPL_WORD32_MAX));
101 EXPECT_EQ(1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
102 WEBRTC_SPL_WORD32_MIN));
103#ifdef WEBRTC_ARCH_ARM_V7
104 EXPECT_EQ(-1073741824,
105 WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
106 WEBRTC_SPL_WORD32_MAX));
107 EXPECT_EQ(0x3fffffff, WEBRTC_SPL_MUL_32_32_RSFT32(WEBRTC_SPL_WORD16_MAX,
108 0xffff, WEBRTC_SPL_WORD32_MAX));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000109#else
110 EXPECT_EQ(-1073741823,
111 WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN,
112 WEBRTC_SPL_WORD32_MAX));
113 EXPECT_EQ(0x3fff7ffe, WEBRTC_SPL_MUL_32_32_RSFT32(WEBRTC_SPL_WORD16_MAX,
114 0xffff, WEBRTC_SPL_WORD32_MAX));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000115#endif
116}
117
118TEST_F(SplTest, InlineTest) {
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000119 int16_t a16 = 121;
120 int16_t b16 = -17;
121 int32_t a32 = 111121;
122 int32_t b32 = -1711;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000123 char bVersion[8];
124
125 EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(a32));
126
127 EXPECT_EQ(0, WebRtcSpl_NormW32(0));
128 EXPECT_EQ(31, WebRtcSpl_NormW32(-1));
129 EXPECT_EQ(0, WebRtcSpl_NormW32(WEBRTC_SPL_WORD32_MIN));
130 EXPECT_EQ(14, WebRtcSpl_NormW32(a32));
131
132 EXPECT_EQ(0, WebRtcSpl_NormW16(0));
133 EXPECT_EQ(15, WebRtcSpl_NormW16(-1));
134 EXPECT_EQ(0, WebRtcSpl_NormW16(WEBRTC_SPL_WORD16_MIN));
135 EXPECT_EQ(4, WebRtcSpl_NormW16(b32));
136
137 EXPECT_EQ(0, WebRtcSpl_NormU32(0));
138 EXPECT_EQ(0, WebRtcSpl_NormU32(-1));
139 EXPECT_EQ(0, WebRtcSpl_NormU32(WEBRTC_SPL_WORD32_MIN));
140 EXPECT_EQ(15, WebRtcSpl_NormU32(a32));
141
142 EXPECT_EQ(104, WebRtcSpl_AddSatW16(a16, b16));
143 EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16));
144
145 EXPECT_EQ(109410, WebRtcSpl_AddSatW32(a32, b32));
146 EXPECT_EQ(112832, WebRtcSpl_SubSatW32(a32, b32));
147
148 a32 = 0x80000000;
149 b32 = 0x80000000;
150 // Cast to signed int to avoid compiler complaint on gtest.h.
151 EXPECT_EQ(static_cast<int>(0x80000000), WebRtcSpl_AddSatW32(a32, b32));
152 a32 = 0x7fffffff;
153 b32 = 0x7fffffff;
154 EXPECT_EQ(0x7fffffff, WebRtcSpl_AddSatW32(a32, b32));
155 a32 = 0;
156 b32 = 0x80000000;
157 EXPECT_EQ(0x7fffffff, WebRtcSpl_SubSatW32(a32, b32));
158 a32 = 0x7fffffff;
159 b32 = 0x80000000;
160 EXPECT_EQ(0x7fffffff, WebRtcSpl_SubSatW32(a32, b32));
161 a32 = 0x80000000;
162 b32 = 0x7fffffff;
163 EXPECT_EQ(static_cast<int>(0x80000000), WebRtcSpl_SubSatW32(a32, b32));
164
165 EXPECT_EQ(0, WebRtcSpl_get_version(bVersion, 8));
166}
167
168TEST_F(SplTest, MathOperationsTest) {
169 int A = 1134567892;
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000170 int32_t num = 117;
171 int32_t den = -5;
172 uint16_t denU = 5;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000173 EXPECT_EQ(33700, WebRtcSpl_Sqrt(A));
174 EXPECT_EQ(33683, WebRtcSpl_SqrtFloor(A));
175
176
177 EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num));
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000178 EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (int16_t)den));
179 EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (int16_t)den));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000180 EXPECT_EQ(23u, WebRtcSpl_DivU32U16(num, denU));
181 EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
182}
183
184TEST_F(SplTest, BasicArrayOperationsTest) {
185 const int kVectorSize = 4;
186 int B[] = {4, 12, 133, 1100};
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000187 uint8_t b8[kVectorSize];
188 int16_t b16[kVectorSize];
189 int32_t b32[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000190
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000191 uint8_t bTmp8[kVectorSize];
192 int16_t bTmp16[kVectorSize];
193 int32_t bTmp32[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000194
195 WebRtcSpl_MemSetW16(b16, 3, kVectorSize);
196 for (int kk = 0; kk < kVectorSize; ++kk) {
197 EXPECT_EQ(3, b16[kk]);
198 }
199 EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW16(b16, kVectorSize));
200 for (int kk = 0; kk < kVectorSize; ++kk) {
201 EXPECT_EQ(0, b16[kk]);
202 }
203 EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW16(b16, kVectorSize));
204 for (int kk = 0; kk < kVectorSize; ++kk) {
205 EXPECT_EQ(1, b16[kk]);
206 }
207 WebRtcSpl_MemSetW32(b32, 3, kVectorSize);
208 for (int kk = 0; kk < kVectorSize; ++kk) {
209 EXPECT_EQ(3, b32[kk]);
210 }
211 EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW32(b32, kVectorSize));
212 for (int kk = 0; kk < kVectorSize; ++kk) {
213 EXPECT_EQ(0, b32[kk]);
214 }
215 EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW32(b32, kVectorSize));
216 for (int kk = 0; kk < kVectorSize; ++kk) {
217 EXPECT_EQ(1, b32[kk]);
218 }
219 for (int kk = 0; kk < kVectorSize; ++kk) {
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000220 bTmp8[kk] = (int8_t)kk;
221 bTmp16[kk] = (int16_t)kk;
222 bTmp32[kk] = (int32_t)kk;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000223 }
224 WEBRTC_SPL_MEMCPY_W8(b8, bTmp8, kVectorSize);
225 for (int kk = 0; kk < kVectorSize; ++kk) {
226 EXPECT_EQ(b8[kk], bTmp8[kk]);
227 }
228 WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize);
229 for (int kk = 0; kk < kVectorSize; ++kk) {
230 EXPECT_EQ(b16[kk], bTmp16[kk]);
231 }
232// WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize);
233// for (int kk = 0; kk < kVectorSize; ++kk) {
234// EXPECT_EQ(b32[kk], bTmp32[kk]);
235// }
236 EXPECT_EQ(2, WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16));
237 for (int kk = 0; kk < 2; ++kk) {
238 EXPECT_EQ(kk+2, bTmp16[kk]);
239 }
240
241 for (int kk = 0; kk < kVectorSize; ++kk) {
242 b32[kk] = B[kk];
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000243 b16[kk] = (int16_t)B[kk];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000244 }
245 WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1);
246 for (int kk = 0; kk < kVectorSize; ++kk) {
247 EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
248 }
249 WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1);
250 for (int kk = 0; kk < kVectorSize; ++kk) {
251 EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
252 }
253 WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1);
254 for (int kk = 0; kk < kVectorSize; ++kk) {
255 EXPECT_EQ((B[kk]>>1), bTmp32[kk]);
256 }
257
258 WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize);
259 for (int kk = 0; kk < kVectorSize; ++kk) {
260 EXPECT_EQ(b16[3-kk], bTmp16[kk]);
261 }
262}
263
264TEST_F(SplTest, ExeptionsHandlingMinMaxOperationsTest) {
265 // Test how the functions handle exceptional cases.
266 const int kVectorSize = 2;
267 int16_t vector16[kVectorSize] = {0};
268 int32_t vector32[kVectorSize] = {0};
269
270 EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW16(vector16, 0));
271 EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW16(NULL, kVectorSize));
272 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, WebRtcSpl_MaxValueW16(vector16, 0));
273 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, WebRtcSpl_MaxValueW16(NULL, kVectorSize));
274 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, WebRtcSpl_MinValueW16(vector16, 0));
275 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, WebRtcSpl_MinValueW16(NULL, kVectorSize));
276 EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW32(vector32, 0));
277 EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW32(NULL, kVectorSize));
278 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, WebRtcSpl_MaxValueW32(vector32, 0));
279 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, WebRtcSpl_MaxValueW32(NULL, kVectorSize));
280 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, WebRtcSpl_MinValueW32(vector32, 0));
281 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, WebRtcSpl_MinValueW32(NULL, kVectorSize));
282 EXPECT_EQ(-1, WebRtcSpl_MaxAbsIndexW16(vector16, 0));
283 EXPECT_EQ(-1, WebRtcSpl_MaxAbsIndexW16(NULL, kVectorSize));
284 EXPECT_EQ(-1, WebRtcSpl_MaxIndexW16(vector16, 0));
285 EXPECT_EQ(-1, WebRtcSpl_MaxIndexW16(NULL, kVectorSize));
286 EXPECT_EQ(-1, WebRtcSpl_MaxIndexW32(vector32, 0));
287 EXPECT_EQ(-1, WebRtcSpl_MaxIndexW32(NULL, kVectorSize));
288 EXPECT_EQ(-1, WebRtcSpl_MinIndexW16(vector16, 0));
289 EXPECT_EQ(-1, WebRtcSpl_MinIndexW16(NULL, kVectorSize));
290 EXPECT_EQ(-1, WebRtcSpl_MinIndexW32(vector32, 0));
291 EXPECT_EQ(-1, WebRtcSpl_MinIndexW32(NULL, kVectorSize));
292}
293
294TEST_F(SplTest, MinMaxOperationsTest) {
295 const int kVectorSize = 17;
296
297 // Vectors to test the cases where minimum values have to be caught
298 // outside of the unrolled loops in ARM-Neon.
299 int16_t vector16[kVectorSize] = {-1, 7485, 0, 3333,
300 -18283, 0, 12334, -29871, 988, -3333,
301 345, -456, 222, 999, 888, 8774, WEBRTC_SPL_WORD16_MIN};
302 int32_t vector32[kVectorSize] = {-1, 0, 283211, 3333,
303 8712345, 0, -3333, 89345, -374585456, 222, 999, 122345334,
304 -12389756, -987329871, 888, -2, WEBRTC_SPL_WORD32_MIN};
305
306 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
307 WebRtcSpl_MinValueW16(vector16, kVectorSize));
308 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
309 WebRtcSpl_MinValueW32(vector32, kVectorSize));
310 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
311 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
312
313 // Test the cases where maximum values have to be caught
314 // outside of the unrolled loops in ARM-Neon.
315 vector16[kVectorSize - 1] = WEBRTC_SPL_WORD16_MAX;
316 vector32[kVectorSize - 1] = WEBRTC_SPL_WORD32_MAX;
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_WORD32_MAX,
323 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
324 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
325 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
326 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
327 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
328 EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
329
330 // Test the cases where multiple maximum and minimum values are present.
331 vector16[1] = WEBRTC_SPL_WORD16_MAX;
332 vector16[6] = WEBRTC_SPL_WORD16_MIN;
333 vector16[11] = WEBRTC_SPL_WORD16_MIN;
334 vector32[1] = WEBRTC_SPL_WORD32_MAX;
335 vector32[6] = WEBRTC_SPL_WORD32_MIN;
336 vector32[11] = WEBRTC_SPL_WORD32_MIN;
337
338 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
339 WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize));
340 EXPECT_EQ(WEBRTC_SPL_WORD16_MAX,
341 WebRtcSpl_MaxValueW16(vector16, kVectorSize));
342 EXPECT_EQ(WEBRTC_SPL_WORD16_MIN,
343 WebRtcSpl_MinValueW16(vector16, kVectorSize));
344 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
345 WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize));
346 EXPECT_EQ(WEBRTC_SPL_WORD32_MAX,
347 WebRtcSpl_MaxValueW32(vector32, kVectorSize));
348 EXPECT_EQ(WEBRTC_SPL_WORD32_MIN,
349 WebRtcSpl_MinValueW32(vector32, kVectorSize));
350 EXPECT_EQ(6, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize));
351 EXPECT_EQ(1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize));
352 EXPECT_EQ(1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize));
353 EXPECT_EQ(6, WebRtcSpl_MinIndexW16(vector16, kVectorSize));
354 EXPECT_EQ(6, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
355}
356
357TEST_F(SplTest, VectorOperationsTest) {
358 const int kVectorSize = 4;
359 int B[] = {4, 12, 133, 1100};
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000360 int16_t a16[kVectorSize];
361 int16_t b16[kVectorSize];
362 int16_t bTmp16[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000363
364 for (int kk = 0; kk < kVectorSize; ++kk) {
365 a16[kk] = B[kk];
366 b16[kk] = B[kk];
367 }
368
369 WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize);
370 for (int kk = 0; kk < kVectorSize; ++kk) {
371 EXPECT_EQ((B[kk]*3+7)>>2, bTmp16[kk]);
372 }
373 WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize);
374 for (int kk = 0; kk < kVectorSize; ++kk) {
375 EXPECT_EQ((B[kk]*3+B[kk]*2+2)>>2, bTmp16[kk]);
376 }
377
378 WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize);
379 for (int kk = 0; kk < kVectorSize; ++kk) {
380 EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
381 }
382
383 WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
384 for (int kk = 0; kk < kVectorSize; ++kk) {
385 EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
386 }
387 WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2);
388 for (int kk = 0; kk < kVectorSize; ++kk) {
389 EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
390 }
391 WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize);
392 for (int kk = 0; kk < kVectorSize; ++kk) {
393 EXPECT_EQ(((a16[kk]*13)>>2)+((b16[kk]*7)>>2), bTmp16[kk]);
394 }
395
396 WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2);
397 for (int kk = 0; kk < kVectorSize; ++kk) {
398 EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
399 }
400 WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2);
401 for (int kk = 0; kk < kVectorSize; ++kk) {
402 EXPECT_EQ((a16[kk]*b16[3-kk])>>2, bTmp16[kk]);
403 }
404 WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6);
405 for (int kk = 0; kk < kVectorSize; ++kk) {
406 EXPECT_EQ((a16[kk]*b16[kk])>>6, bTmp16[kk]);
407 }
408
409 WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16);
410 for (int kk = 0; kk < kVectorSize - 1; ++kk) {
411 EXPECT_EQ(32767, bTmp16[kk]);
412 }
413 EXPECT_EQ(32749, bTmp16[kVectorSize - 1]);
414
415 EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
416}
417
418TEST_F(SplTest, EstimatorsTest) {
419 const int kVectorSize = 4;
420 int B[] = {4, 12, 133, 1100};
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000421 int16_t b16[kVectorSize];
422 int32_t b32[kVectorSize];
423 int16_t bTmp16[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000424
425 for (int kk = 0; kk < kVectorSize; ++kk) {
426 b16[kk] = B[kk];
427 b32[kk] = B[kk];
428 }
429
430 EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(b32, b16, bTmp16, 2));
431}
432
433TEST_F(SplTest, FilterTest) {
434 const int kVectorSize = 4;
435 const int kFilterOrder = 3;
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000436 int16_t A[] = {1, 2, 33, 100};
437 int16_t A5[] = {1, 2, 33, 100, -5};
438 int16_t B[] = {4, 12, 133, 110};
439 int16_t data_in[kVectorSize];
440 int16_t data_out[kVectorSize];
441 int16_t bTmp16Low[kVectorSize];
442 int16_t bState[kVectorSize];
443 int16_t bStateLow[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000444
445 WebRtcSpl_ZerosArrayW16(bState, kVectorSize);
446 WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize);
447
448 for (int kk = 0; kk < kVectorSize; ++kk) {
449 data_in[kk] = A[kk];
450 data_out[kk] = 0;
451 }
452
453 // MA filters.
454 // Note that the input data has |kFilterOrder| states before the actual
455 // data (one sample).
456 WebRtcSpl_FilterMAFastQ12(&data_in[kFilterOrder], data_out, B,
457 kFilterOrder + 1, 1);
458 EXPECT_EQ(0, data_out[0]);
459 // AR filters.
460 // Note that the output data has |kFilterOrder| states before the actual
461 // data (one sample).
462 WebRtcSpl_FilterARFastQ12(data_in, &data_out[kFilterOrder], A,
463 kFilterOrder + 1, 1);
464 EXPECT_EQ(0, data_out[kFilterOrder]);
465
466 EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5,
467 5,
468 data_in,
469 kVectorSize,
470 bState,
471 kVectorSize,
472 bStateLow,
473 kVectorSize,
474 data_out,
475 bTmp16Low,
476 kVectorSize));
477}
478
479TEST_F(SplTest, RandTest) {
480 const int kVectorSize = 4;
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000481 int16_t BU[] = {3653, 12446, 8525, 30691};
482 int16_t b16[kVectorSize];
483 uint32_t bSeed = 100000;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000484
bjornv@webrtc.org9d1179d2014-05-16 06:38:47 +0000485 EXPECT_EQ(7086, WebRtcSpl_RandU(&bSeed));
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000486 EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed));
487 EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed));
488 EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed));
489 for (int kk = 0; kk < kVectorSize; ++kk) {
490 EXPECT_EQ(BU[kk], b16[kk]);
491 }
492}
493
494TEST_F(SplTest, DotProductWithScaleTest) {
495 EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16,
496 vector16, kVector16Size, 2));
497}
498
499TEST_F(SplTest, CrossCorrelationTest) {
500 // Note the function arguments relation specificed by API.
501 const int kCrossCorrelationDimension = 3;
502 const int kShift = 2;
503 const int kStep = 1;
504 const int kSeqDimension = 6;
505
506 const int16_t kVector16[kVector16Size] = {1, 4323, 1963,
507 WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333, -876, 8483, 142};
508 int32_t vector32[kCrossCorrelationDimension] = {0};
509
510 WebRtcSpl_CrossCorrelation(vector32, vector16, kVector16, kSeqDimension,
511 kCrossCorrelationDimension, kShift, kStep);
512
513 // WebRtcSpl_CrossCorrelationC() and WebRtcSpl_CrossCorrelationNeon()
514 // are not bit-exact.
515 const int32_t kExpected[kCrossCorrelationDimension] =
516 {-266947903, -15579555, -171282001};
andrew@webrtc.orgfccf64c2013-09-18 17:40:46 +0000517 const int32_t* expected = kExpected;
518#if !defined(MIPS32_LE)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000519 const int32_t kExpectedNeon[kCrossCorrelationDimension] =
520 {-266947901, -15579553, -171281999};
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000521 if (WebRtcSpl_CrossCorrelation != WebRtcSpl_CrossCorrelationC) {
522 expected = kExpectedNeon;
523 }
andrew@webrtc.orgfccf64c2013-09-18 17:40:46 +0000524#endif
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000525 for (int i = 0; i < kCrossCorrelationDimension; ++i) {
526 EXPECT_EQ(expected[i], vector32[i]);
527 }
528}
529
530TEST_F(SplTest, AutoCorrelationTest) {
531 int scale = 0;
532 int32_t vector32[kVector16Size];
533 const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063,
534 -85221647, -17104971, 61806945, 6644603, -669329, 43};
535
536 EXPECT_EQ(-1, WebRtcSpl_AutoCorrelation(vector16,
537 kVector16Size, kVector16Size + 1, vector32, &scale));
538 EXPECT_EQ(kVector16Size, WebRtcSpl_AutoCorrelation(vector16,
539 kVector16Size, kVector16Size - 1, vector32, &scale));
540 EXPECT_EQ(3, scale);
541 for (int i = 0; i < kVector16Size; ++i) {
542 EXPECT_EQ(expected[i], vector32[i]);
543 }
544}
545
546TEST_F(SplTest, SignalProcessingTest) {
547 const int kVectorSize = 4;
548 int A[] = {1, 2, 33, 100};
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000549 const int16_t kHanning[4] = { 2399, 8192, 13985, 16384 };
550 int16_t b16[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000551
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000552 int16_t bTmp16[kVectorSize];
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000553
554 int bScale = 0;
555
556 for (int kk = 0; kk < kVectorSize; ++kk) {
557 b16[kk] = A[kk];
558 }
559
560 // TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
561// WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
562//// for (int kk = 0; kk < kVectorSize; ++kk) {
563//// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
564//// }
565// WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16);
566//// for (int kk = 0; kk < kVectorSize; ++kk) {
567//// EXPECT_EQ(a16[kk], b16[kk]);
568//// }
569// WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16);
570//// for (int kk = 0; kk < kVectorSize; ++kk) {
571//// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
572//// }
573
574 WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize);
575 for (int kk = 0; kk < kVectorSize; ++kk) {
576 EXPECT_EQ(kHanning[kk], bTmp16[kk]);
577 }
578
579 for (int kk = 0; kk < kVectorSize; ++kk) {
580 b16[kk] = A[kk];
581 }
582 EXPECT_EQ(11094 , WebRtcSpl_Energy(b16, kVectorSize, &bScale));
583 EXPECT_EQ(0, bScale);
584}
585
586TEST_F(SplTest, FFTTest) {
pbos@webrtc.org1727dc72013-04-09 16:40:28 +0000587 int16_t B[] = {1, 2, 33, 100,
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000588 2, 3, 34, 101,
589 3, 4, 35, 102,
590 4, 5, 36, 103};
591
592 EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
593// for (int kk = 0; kk < 16; ++kk) {
594// EXPECT_EQ(A[kk], B[kk]);
595// }
596 EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1));
597// for (int kk = 0; kk < 16; ++kk) {
598// EXPECT_EQ(A[kk], B[kk]);
599// }
600 WebRtcSpl_ComplexBitReverse(B, 3);
601 for (int kk = 0; kk < 16; ++kk) {
602 //EXPECT_EQ(A[kk], B[kk]);
603 }
604}
tina.legrand@webrtc.org82e863b2012-11-15 08:34:38 +0000605
606TEST_F(SplTest, Resample48WithSaturationTest) {
607 // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number
608 // of samples.
609 const int kBlockSize = 16;
610
611 // Saturated input vector of 48 samples.
612 const int32_t kVectorSaturated[3 * kBlockSize + 7] = {
613 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
614 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
615 -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
616 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
617 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
618 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
619 32767, 32767, 32767, 32767, 32767, 32767, 32767
620 };
621
622 // All values in |out_vector| should be |kRefValue32kHz|.
623 const int32_t kRefValue32kHz1 = -1077493760;
624 const int32_t kRefValue32kHz2 = 1077493645;
625
626 // After bit shift with saturation, |out_vector_w16| is saturated.
627
628 const int16_t kRefValue16kHz1 = -32768;
629 const int16_t kRefValue16kHz2 = 32767;
630 // Vector for storing output.
631 int32_t out_vector[2 * kBlockSize];
632 int16_t out_vector_w16[2 * kBlockSize];
633
634 WebRtcSpl_Resample48khzTo32khz(kVectorSaturated, out_vector, kBlockSize);
635 WebRtcSpl_VectorBitShiftW32ToW16(out_vector_w16, 2 * kBlockSize, out_vector,
636 15);
637
638 // Comparing output values against references. The values at position
639 // 12-15 are skipped to account for the filter lag.
640 for (int i = 0; i < 12; ++i) {
641 EXPECT_EQ(kRefValue32kHz1, out_vector[i]);
642 EXPECT_EQ(kRefValue16kHz1, out_vector_w16[i]);
643 }
644 for (int i = 16; i < 2 * kBlockSize; ++i) {
645 EXPECT_EQ(kRefValue32kHz2, out_vector[i]);
646 EXPECT_EQ(kRefValue16kHz2, out_vector_w16[i]);
647 }
648}