niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
bjornv@webrtc.org | 5309639 | 2012-02-07 08:10:46 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 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 | |
kwiberg | bca568b | 2016-05-23 04:07:00 -0700 | [diff] [blame] | 11 | #include <algorithm> |
kwiberg | bca568b | 2016-05-23 04:07:00 -0700 | [diff] [blame] | 12 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 13 | #include "common_audio/signal_processing/include/signal_processing_library.h" |
Jonas Olsson | 366a50c | 2018-09-06 13:41:30 +0200 | [diff] [blame] | 14 | #include "rtc_base/strings/string_builder.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 15 | #include "test/gtest.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 16 | |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 17 | static const size_t kVector16Size = 9; |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 18 | static 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.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 27 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 28 | TEST(SplTest, MacroTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 29 | // Macros with inputs. |
| 30 | int A = 10; |
| 31 | int B = 21; |
| 32 | int a = -3; |
| 33 | int b = WEBRTC_SPL_WORD32_MAX; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 34 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 35 | EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B)); |
| 36 | EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 37 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 38 | EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a)); |
| 39 | EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 40 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 41 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 46 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 47 | a = b; |
| 48 | b = -3; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 49 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 50 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 54 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 55 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 57 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 58 | EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B)); |
| 59 | EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 60 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 61 | // 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 65 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 66 | // 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 69 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 70 | EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 71 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 72 | EXPECT_EQ(1470, WEBRTC_SPL_RAND(A)); |
kma@webrtc.org | 7611791 | 2012-08-28 00:43:55 +0000 | [diff] [blame] | 73 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 74 | 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.org | 9b1cf54 | 2012-09-03 21:22:28 +0000 | [diff] [blame] | 81 | #ifdef WEBRTC_ARCH_ARM_V7 |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 82 | EXPECT_EQ(-1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN, |
| 83 | WEBRTC_SPL_WORD32_MAX)); |
kma@webrtc.org | 7611791 | 2012-08-28 00:43:55 +0000 | [diff] [blame] | 84 | #else |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 85 | EXPECT_EQ(-1073741823, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN, |
| 86 | WEBRTC_SPL_WORD32_MAX)); |
kma@webrtc.org | 7611791 | 2012-08-28 00:43:55 +0000 | [diff] [blame] | 87 | #endif |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 88 | } |
| 89 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 90 | TEST(SplTest, InlineTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 91 | int16_t a16 = 121; |
| 92 | int16_t b16 = -17; |
| 93 | int32_t a32 = 111121; |
| 94 | int32_t b32 = -1711; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 95 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 96 | EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(a32)); |
kma@webrtc.org | 6679dcc | 2012-10-05 00:27:10 +0000 | [diff] [blame] | 97 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 98 | 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.org | 6679dcc | 2012-10-05 00:27:10 +0000 | [diff] [blame] | 102 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 103 | 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.org | 6679dcc | 2012-10-05 00:27:10 +0000 | [diff] [blame] | 112 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 113 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 116 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 117 | EXPECT_EQ(104, WebRtcSpl_AddSatW16(a16, b16)); |
| 118 | EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16)); |
kwiberg | bca568b | 2016-05-23 04:07:00 -0700 | [diff] [blame] | 119 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 120 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 121 | TEST(SplTest, AddSubSatW32) { |
kwiberg | bca568b | 2016-05-23 04:07:00 -0700 | [diff] [blame] | 122 | 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 Olsson | 366a50c | 2018-09-06 13:41:30 +0200 | [diff] [blame] | 131 | rtc::StringBuilder ss; |
kwiberg | bca568b | 2016-05-23 04:07:00 -0700 | [diff] [blame] | 132 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 138 | } |
| 139 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 140 | TEST(SplTest, CountLeadingZeros32) { |
kwiberg | 729b21f | 2016-06-02 04:02:12 -0700 | [diff] [blame] | 141 | 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 Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 153 | TEST(SplTest, CountLeadingZeros64) { |
kwiberg | 729b21f | 2016-06-02 04:02:12 -0700 | [diff] [blame] | 154 | 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 Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 166 | TEST(SplTest, MathOperationsTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 167 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 173 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 174 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 179 | } |
| 180 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 181 | TEST(SplTest, BasicArrayOperationsTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 182 | const size_t kVectorSize = 4; |
| 183 | int B[] = {4, 12, 133, 1100}; |
| 184 | int16_t b16[kVectorSize]; |
| 185 | int32_t b32[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 186 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 187 | int16_t bTmp16[kVectorSize]; |
| 188 | int32_t bTmp32[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 189 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 190 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 222 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 223 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 239 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 240 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 244 | } |
| 245 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 246 | TEST(SplTest, MinMaxOperationsTest) { |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 247 | const size_t kVectorSize = 17; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 248 | |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 249 | // Vectors to test the cases where minimum values have to be caught |
| 250 | // outside of the unrolled loops in ARM-Neon. |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 251 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 285 | |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 286 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 287 | WebRtcSpl_MinValueW16(vector16, kVectorSize)); |
| 288 | EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, |
| 289 | WebRtcSpl_MinValueW32(vector32, kVectorSize)); |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 290 | EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize)); |
| 291 | EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize)); |
Ivo Creusen | 6031b74 | 2021-01-20 16:26:43 +0100 | [diff] [blame] | 292 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 293 | WebRtcSpl_MaxAbsElementW16(vector16, kVectorSize)); |
| 294 | int16_t min_value, max_value; |
| 295 | WebRtcSpl_MinMaxW16(vector16, kVectorSize, &min_value, &max_value); |
| 296 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, min_value); |
| 297 | EXPECT_EQ(12334, max_value); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 298 | |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 299 | // 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 303 | |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 304 | 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 Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 312 | 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)); |
Ivo Creusen | 6031b74 | 2021-01-20 16:26:43 +0100 | [diff] [blame] | 315 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, |
| 316 | WebRtcSpl_MaxAbsElementW16(vector16, kVectorSize)); |
| 317 | WebRtcSpl_MinMaxW16(vector16, kVectorSize, &min_value, &max_value); |
| 318 | EXPECT_EQ(-29871, min_value); |
| 319 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, max_value); |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 320 | |
| 321 | // Test the cases where multiple maximum and minimum values are present. |
| 322 | vector16[1] = WEBRTC_SPL_WORD16_MAX; |
| 323 | vector16[6] = WEBRTC_SPL_WORD16_MIN; |
| 324 | vector16[11] = WEBRTC_SPL_WORD16_MIN; |
| 325 | vector32[1] = WEBRTC_SPL_WORD32_MAX; |
| 326 | vector32[6] = WEBRTC_SPL_WORD32_MIN; |
| 327 | vector32[11] = WEBRTC_SPL_WORD32_MIN; |
| 328 | |
| 329 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, |
| 330 | WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize)); |
| 331 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, |
| 332 | WebRtcSpl_MaxValueW16(vector16, kVectorSize)); |
| 333 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 334 | WebRtcSpl_MinValueW16(vector16, kVectorSize)); |
| 335 | EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, |
| 336 | WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize)); |
| 337 | EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, |
| 338 | WebRtcSpl_MaxValueW32(vector32, kVectorSize)); |
| 339 | EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, |
| 340 | WebRtcSpl_MinValueW32(vector32, kVectorSize)); |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 341 | EXPECT_EQ(6u, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize)); |
| 342 | EXPECT_EQ(1u, WebRtcSpl_MaxIndexW16(vector16, kVectorSize)); |
| 343 | EXPECT_EQ(1u, WebRtcSpl_MaxIndexW32(vector32, kVectorSize)); |
| 344 | EXPECT_EQ(6u, WebRtcSpl_MinIndexW16(vector16, kVectorSize)); |
| 345 | EXPECT_EQ(6u, WebRtcSpl_MinIndexW32(vector32, kVectorSize)); |
Ivo Creusen | 6031b74 | 2021-01-20 16:26:43 +0100 | [diff] [blame] | 346 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 347 | WebRtcSpl_MaxAbsElementW16(vector16, kVectorSize)); |
| 348 | WebRtcSpl_MinMaxW16(vector16, kVectorSize, &min_value, &max_value); |
| 349 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, min_value); |
| 350 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, max_value); |
| 351 | |
| 352 | // Test a one-element vector. |
| 353 | int16_t single_element_vector = 0; |
| 354 | EXPECT_EQ(0, WebRtcSpl_MaxAbsValueW16(&single_element_vector, 1)); |
| 355 | EXPECT_EQ(0, WebRtcSpl_MaxValueW16(&single_element_vector, 1)); |
| 356 | EXPECT_EQ(0, WebRtcSpl_MinValueW16(&single_element_vector, 1)); |
| 357 | EXPECT_EQ(0u, WebRtcSpl_MaxAbsIndexW16(&single_element_vector, 1)); |
| 358 | EXPECT_EQ(0u, WebRtcSpl_MaxIndexW16(&single_element_vector, 1)); |
| 359 | EXPECT_EQ(0u, WebRtcSpl_MinIndexW16(&single_element_vector, 1)); |
| 360 | EXPECT_EQ(0, WebRtcSpl_MaxAbsElementW16(&single_element_vector, 1)); |
| 361 | WebRtcSpl_MinMaxW16(&single_element_vector, 1, &min_value, &max_value); |
| 362 | EXPECT_EQ(0, min_value); |
| 363 | EXPECT_EQ(0, max_value); |
| 364 | |
| 365 | // Test a two-element vector with the values WEBRTC_SPL_WORD16_MIN and |
| 366 | // WEBRTC_SPL_WORD16_MAX. |
| 367 | int16_t two_element_vector[2] = {WEBRTC_SPL_WORD16_MIN, |
| 368 | WEBRTC_SPL_WORD16_MAX}; |
| 369 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, |
| 370 | WebRtcSpl_MaxAbsValueW16(two_element_vector, 2)); |
| 371 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, |
| 372 | WebRtcSpl_MaxValueW16(two_element_vector, 2)); |
| 373 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 374 | WebRtcSpl_MinValueW16(two_element_vector, 2)); |
| 375 | EXPECT_EQ(0u, WebRtcSpl_MaxAbsIndexW16(two_element_vector, 2)); |
| 376 | EXPECT_EQ(1u, WebRtcSpl_MaxIndexW16(two_element_vector, 2)); |
| 377 | EXPECT_EQ(0u, WebRtcSpl_MinIndexW16(two_element_vector, 2)); |
| 378 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, |
| 379 | WebRtcSpl_MaxAbsElementW16(two_element_vector, 2)); |
| 380 | WebRtcSpl_MinMaxW16(two_element_vector, 2, &min_value, &max_value); |
| 381 | EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, min_value); |
| 382 | EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, max_value); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 383 | } |
| 384 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 385 | TEST(SplTest, VectorOperationsTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 386 | const size_t kVectorSize = 4; |
| 387 | int B[] = {4, 12, 133, 1100}; |
| 388 | int16_t a16[kVectorSize]; |
| 389 | int16_t b16[kVectorSize]; |
| 390 | int16_t bTmp16[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 391 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 392 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 393 | a16[kk] = B[kk]; |
| 394 | b16[kk] = B[kk]; |
| 395 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 396 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 397 | WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize); |
| 398 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 399 | EXPECT_EQ((B[kk] * 3 + 7) >> 2, bTmp16[kk]); |
| 400 | } |
| 401 | WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize); |
| 402 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 403 | EXPECT_EQ((B[kk] * 3 + B[kk] * 2 + 2) >> 2, bTmp16[kk]); |
| 404 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 405 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 406 | WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize); |
| 407 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 408 | EXPECT_EQ(((B[kk] * 3 + B[kk] * 2 + 2) >> 2) + ((b16[kk] * 3 + 7) >> 2), |
| 409 | bTmp16[kk]); |
| 410 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 411 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 412 | WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2); |
| 413 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 414 | EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]); |
| 415 | } |
| 416 | WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2); |
| 417 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 418 | EXPECT_EQ((b16[kk] * 13) >> 2, bTmp16[kk]); |
| 419 | } |
| 420 | WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize); |
| 421 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 422 | EXPECT_EQ(((a16[kk] * 13) >> 2) + ((b16[kk] * 7) >> 2), bTmp16[kk]); |
| 423 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 424 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 425 | WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2); |
| 426 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 427 | EXPECT_EQ(B[kk] >> 1, bTmp16[kk]); |
| 428 | } |
| 429 | WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2); |
| 430 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 431 | EXPECT_EQ((a16[kk] * b16[3 - kk]) >> 2, bTmp16[kk]); |
| 432 | } |
| 433 | WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6); |
| 434 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 435 | EXPECT_EQ((a16[kk] * b16[kk]) >> 6, bTmp16[kk]); |
| 436 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 437 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 438 | WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16); |
| 439 | for (size_t kk = 0; kk < kVectorSize - 1; ++kk) { |
| 440 | EXPECT_EQ(32767, bTmp16[kk]); |
| 441 | } |
| 442 | EXPECT_EQ(32749, bTmp16[kVectorSize - 1]); |
kma@webrtc.org | da236df | 2012-08-07 19:35:00 +0000 | [diff] [blame] | 443 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 444 | EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 445 | } |
| 446 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 447 | TEST(SplTest, EstimatorsTest) { |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 448 | const size_t kOrder = 2; |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 449 | const int32_t unstable_filter[] = {4, 12, 133, 1100}; |
| 450 | const int32_t stable_filter[] = {1100, 133, 12, 4}; |
| 451 | int16_t lpc[kOrder + 2] = {0}; |
| 452 | int16_t refl[kOrder + 2] = {0}; |
| 453 | int16_t lpc_result[] = {4096, -497, 15, 0}; |
| 454 | int16_t refl_result[] = {-3962, 123, 0, 0}; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 455 | |
bjornv@webrtc.org | 88a4298 | 2015-01-12 05:53:43 +0000 | [diff] [blame] | 456 | EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(unstable_filter, lpc, refl, kOrder)); |
| 457 | EXPECT_EQ(1, WebRtcSpl_LevinsonDurbin(stable_filter, lpc, refl, kOrder)); |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 458 | for (size_t i = 0; i < kOrder + 2; ++i) { |
bjornv@webrtc.org | 88a4298 | 2015-01-12 05:53:43 +0000 | [diff] [blame] | 459 | EXPECT_EQ(lpc_result[i], lpc[i]); |
| 460 | EXPECT_EQ(refl_result[i], refl[i]); |
| 461 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 462 | } |
| 463 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 464 | TEST(SplTest, FilterTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 465 | const size_t kVectorSize = 4; |
| 466 | const size_t kFilterOrder = 3; |
| 467 | int16_t A[] = {1, 2, 33, 100}; |
| 468 | int16_t A5[] = {1, 2, 33, 100, -5}; |
| 469 | int16_t B[] = {4, 12, 133, 110}; |
| 470 | int16_t data_in[kVectorSize]; |
| 471 | int16_t data_out[kVectorSize]; |
| 472 | int16_t bTmp16Low[kVectorSize]; |
| 473 | int16_t bState[kVectorSize]; |
| 474 | int16_t bStateLow[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 475 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 476 | WebRtcSpl_ZerosArrayW16(bState, kVectorSize); |
| 477 | WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 478 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 479 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 480 | data_in[kk] = A[kk]; |
| 481 | data_out[kk] = 0; |
| 482 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 483 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 484 | // MA filters. |
Artem Titov | 9631575 | 2021-07-26 12:15:29 +0200 | [diff] [blame^] | 485 | // Note that the input data has `kFilterOrder` states before the actual |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 486 | // data (one sample). |
| 487 | WebRtcSpl_FilterMAFastQ12(&data_in[kFilterOrder], data_out, B, |
| 488 | kFilterOrder + 1, 1); |
| 489 | EXPECT_EQ(0, data_out[0]); |
| 490 | // AR filters. |
Artem Titov | 9631575 | 2021-07-26 12:15:29 +0200 | [diff] [blame^] | 491 | // Note that the output data has `kFilterOrder` states before the actual |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 492 | // data (one sample). |
| 493 | WebRtcSpl_FilterARFastQ12(data_in, &data_out[kFilterOrder], A, |
| 494 | kFilterOrder + 1, 1); |
| 495 | EXPECT_EQ(0, data_out[kFilterOrder]); |
bjornv@webrtc.org | 6748087 | 2012-01-19 10:41:39 +0000 | [diff] [blame] | 496 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 497 | EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5, 5, data_in, kVectorSize, bState, |
| 498 | kVectorSize, bStateLow, kVectorSize, |
| 499 | data_out, bTmp16Low, kVectorSize)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 500 | } |
| 501 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 502 | TEST(SplTest, RandTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 503 | const int kVectorSize = 4; |
| 504 | int16_t BU[] = {3653, 12446, 8525, 30691}; |
| 505 | int16_t b16[kVectorSize]; |
| 506 | uint32_t bSeed = 100000; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 507 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 508 | EXPECT_EQ(7086, WebRtcSpl_RandU(&bSeed)); |
| 509 | EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed)); |
| 510 | EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed)); |
| 511 | EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed)); |
| 512 | for (int kk = 0; kk < kVectorSize; ++kk) { |
| 513 | EXPECT_EQ(BU[kk], b16[kk]); |
| 514 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 515 | } |
| 516 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 517 | TEST(SplTest, DotProductWithScaleTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 518 | EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16, vector16, |
| 519 | kVector16Size, 2)); |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 520 | } |
| 521 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 522 | TEST(SplTest, CrossCorrelationTest) { |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 523 | // Note the function arguments relation specificed by API. |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 524 | const size_t kCrossCorrelationDimension = 3; |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 525 | const int kShift = 2; |
| 526 | const int kStep = 1; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 527 | const size_t kSeqDimension = 6; |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 528 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 529 | const int16_t kVector16[kVector16Size] = { |
| 530 | 1, 4323, 1963, WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333, |
| 531 | -876, 8483, 142}; |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 532 | int32_t vector32[kCrossCorrelationDimension] = {0}; |
| 533 | |
kma@webrtc.org | 0a4cdc4 | 2012-10-03 21:15:39 +0000 | [diff] [blame] | 534 | WebRtcSpl_CrossCorrelation(vector32, vector16, kVector16, kSeqDimension, |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 535 | kCrossCorrelationDimension, kShift, kStep); |
| 536 | |
kma@webrtc.org | 0a4cdc4 | 2012-10-03 21:15:39 +0000 | [diff] [blame] | 537 | // WebRtcSpl_CrossCorrelationC() and WebRtcSpl_CrossCorrelationNeon() |
| 538 | // are not bit-exact. |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 539 | const int32_t kExpected[kCrossCorrelationDimension] = {-266947903, -15579555, |
| 540 | -171282001}; |
andrew@webrtc.org | 8bf755d | 2013-09-18 17:40:46 +0000 | [diff] [blame] | 541 | const int32_t* expected = kExpected; |
| 542 | #if !defined(MIPS32_LE) |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 543 | const int32_t kExpectedNeon[kCrossCorrelationDimension] = { |
| 544 | -266947901, -15579553, -171281999}; |
kma@webrtc.org | 0a4cdc4 | 2012-10-03 21:15:39 +0000 | [diff] [blame] | 545 | if (WebRtcSpl_CrossCorrelation != WebRtcSpl_CrossCorrelationC) { |
| 546 | expected = kExpectedNeon; |
| 547 | } |
andrew@webrtc.org | 8bf755d | 2013-09-18 17:40:46 +0000 | [diff] [blame] | 548 | #endif |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 549 | for (size_t i = 0; i < kCrossCorrelationDimension; ++i) { |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 550 | EXPECT_EQ(expected[i], vector32[i]); |
| 551 | } |
| 552 | } |
| 553 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 554 | TEST(SplTest, AutoCorrelationTest) { |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 555 | int scale = 0; |
| 556 | int32_t vector32[kVector16Size]; |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 557 | const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063, |
| 558 | -85221647, -17104971, 61806945, |
| 559 | 6644603, -669329, 43}; |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 560 | |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 561 | EXPECT_EQ(kVector16Size, |
Peter Kasting | 728d903 | 2015-06-11 14:31:38 -0700 | [diff] [blame] | 562 | WebRtcSpl_AutoCorrelation(vector16, kVector16Size, |
| 563 | kVector16Size - 1, vector32, &scale)); |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 564 | EXPECT_EQ(3, scale); |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 565 | for (size_t i = 0; i < kVector16Size; ++i) { |
kma@webrtc.org | 8fe5f32 | 2012-08-06 20:19:56 +0000 | [diff] [blame] | 566 | EXPECT_EQ(expected[i], vector32[i]); |
| 567 | } |
| 568 | } |
| 569 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 570 | TEST(SplTest, SignalProcessingTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 571 | const size_t kVectorSize = 4; |
| 572 | int A[] = {1, 2, 33, 100}; |
| 573 | const int16_t kHanning[4] = {2399, 8192, 13985, 16384}; |
| 574 | int16_t b16[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 575 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 576 | int16_t bTmp16[kVectorSize]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 577 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 578 | int bScale = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 579 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 580 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 581 | b16[kk] = A[kk]; |
| 582 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 583 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 584 | // TODO(bjornv): Activate the Reflection Coefficient tests when refactoring. |
| 585 | // WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16); |
| 586 | //// for (int kk = 0; kk < kVectorSize; ++kk) { |
| 587 | //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); |
| 588 | //// } |
| 589 | // WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16); |
| 590 | //// for (int kk = 0; kk < kVectorSize; ++kk) { |
| 591 | //// EXPECT_EQ(a16[kk], b16[kk]); |
| 592 | //// } |
| 593 | // WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16); |
| 594 | //// for (int kk = 0; kk < kVectorSize; ++kk) { |
| 595 | //// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); |
| 596 | //// } |
bjornv@webrtc.org | 5309639 | 2012-02-07 08:10:46 +0000 | [diff] [blame] | 597 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 598 | WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize); |
| 599 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 600 | EXPECT_EQ(kHanning[kk], bTmp16[kk]); |
| 601 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 602 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 603 | for (size_t kk = 0; kk < kVectorSize; ++kk) { |
| 604 | b16[kk] = A[kk]; |
| 605 | } |
| 606 | EXPECT_EQ(11094, WebRtcSpl_Energy(b16, kVectorSize, &bScale)); |
| 607 | EXPECT_EQ(0, bScale); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 608 | } |
| 609 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 610 | TEST(SplTest, FFTTest) { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 611 | int16_t B[] = {1, 2, 33, 100, 2, 3, 34, 101, 3, 4, 35, 102, 4, 5, 36, 103}; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 612 | |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 613 | EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1)); |
| 614 | // for (int kk = 0; kk < 16; ++kk) { |
| 615 | // EXPECT_EQ(A[kk], B[kk]); |
| 616 | // } |
| 617 | EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1)); |
| 618 | // for (int kk = 0; kk < 16; ++kk) { |
| 619 | // EXPECT_EQ(A[kk], B[kk]); |
| 620 | // } |
| 621 | WebRtcSpl_ComplexBitReverse(B, 3); |
| 622 | for (int kk = 0; kk < 16; ++kk) { |
| 623 | // EXPECT_EQ(A[kk], B[kk]); |
| 624 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 625 | } |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 626 | |
Karl Wiberg | 225842c | 2019-06-28 14:51:49 +0200 | [diff] [blame] | 627 | TEST(SplTest, Resample48WithSaturationTest) { |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 628 | // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number |
| 629 | // of samples. |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 630 | const size_t kBlockSize = 16; |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 631 | |
| 632 | // Saturated input vector of 48 samples. |
| 633 | const int32_t kVectorSaturated[3 * kBlockSize + 7] = { |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 634 | -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, |
| 635 | -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, |
| 636 | -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, |
| 637 | 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, |
| 638 | 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, |
| 639 | 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, |
| 640 | 32767, 32767, 32767, 32767, 32767, 32767, 32767}; |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 641 | |
Artem Titov | 9631575 | 2021-07-26 12:15:29 +0200 | [diff] [blame^] | 642 | // All values in `out_vector` should be `kRefValue32kHz`. |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 643 | const int32_t kRefValue32kHz1 = -1077493760; |
| 644 | const int32_t kRefValue32kHz2 = 1077493645; |
| 645 | |
Artem Titov | 9631575 | 2021-07-26 12:15:29 +0200 | [diff] [blame^] | 646 | // After bit shift with saturation, `out_vector_w16` is saturated. |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 647 | |
| 648 | const int16_t kRefValue16kHz1 = -32768; |
| 649 | const int16_t kRefValue16kHz2 = 32767; |
| 650 | // Vector for storing output. |
| 651 | int32_t out_vector[2 * kBlockSize]; |
| 652 | int16_t out_vector_w16[2 * kBlockSize]; |
| 653 | |
| 654 | WebRtcSpl_Resample48khzTo32khz(kVectorSaturated, out_vector, kBlockSize); |
| 655 | WebRtcSpl_VectorBitShiftW32ToW16(out_vector_w16, 2 * kBlockSize, out_vector, |
| 656 | 15); |
| 657 | |
| 658 | // Comparing output values against references. The values at position |
| 659 | // 12-15 are skipped to account for the filter lag. |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 660 | for (size_t i = 0; i < 12; ++i) { |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 661 | EXPECT_EQ(kRefValue32kHz1, out_vector[i]); |
| 662 | EXPECT_EQ(kRefValue16kHz1, out_vector_w16[i]); |
| 663 | } |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 664 | for (size_t i = 16; i < 2 * kBlockSize; ++i) { |
tina.legrand@webrtc.org | 53a8be2 | 2012-11-15 08:34:38 +0000 | [diff] [blame] | 665 | EXPECT_EQ(kRefValue32kHz2, out_vector[i]); |
| 666 | EXPECT_EQ(kRefValue16kHz2, out_vector_w16[i]); |
| 667 | } |
| 668 | } |