From da236dfde5c4bae0d01f0c84f5290bec03952caa Mon Sep 17 00:00:00 2001 From: "kma@webrtc.org" Date: Tue, 7 Aug 2012 19:35:00 +0000 Subject: [PATCH] Added more unit tests for min-max operations in signal processing module. Review URL: https://webrtc-codereview.appspot.com/668009 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2570 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../include/signal_processing_library.h | 19 ++- .../signal_processing_unittest.cc | 108 ++++++++++++++---- 2 files changed, 101 insertions(+), 26 deletions(-) diff --git a/src/common_audio/signal_processing/include/signal_processing_library.h b/src/common_audio/signal_processing/include/signal_processing_library.h index 38b89cb26..2f2706948 100644 --- a/src/common_audio/signal_processing/include/signal_processing_library.h +++ b/src/common_audio/signal_processing/include/signal_processing_library.h @@ -281,8 +281,11 @@ int32_t WebRtcSpl_MinValueW32(const int32_t* vector, int length); // - vector : 16-bit input vector. // - length : Number of samples in vector. // -// Return value : Index to the maximum absolute value in vector; -// or -1, if (vector == NULL || length <= 0). +// Return value : Index to the maximum absolute value in vector, or -1, +// if (vector == NULL || length <= 0). +// If there are multiple equal maxima, return the index of the +// first. -32768 will always have precedence over 32767 (despite +// -32768 presenting an int16 absolute value of 32767); int WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, int length); // Returns the vector index to the maximum sample value of a 16-bit vector. @@ -291,7 +294,8 @@ int WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, int length); // - vector : 16-bit input vector. // - length : Number of samples in vector. // -// Return value : Index to the maximum value in vector; +// Return value : Index to the maximum value in vector (if multiple +// indexes have the maximum, return the first); // or -1, if (vector == NULL || length <= 0). int WebRtcSpl_MaxIndexW16(const int16_t* vector, int length); @@ -301,7 +305,8 @@ int WebRtcSpl_MaxIndexW16(const int16_t* vector, int length); // - vector : 32-bit input vector. // - length : Number of samples in vector. // -// Return value : Index to the maximum value in vector; +// Return value : Index to the maximum value in vector (if multiple +// indexes have the maximum, return the first); // or -1, if (vector == NULL || length <= 0). int WebRtcSpl_MaxIndexW32(const int32_t* vector, int length); @@ -311,7 +316,8 @@ int WebRtcSpl_MaxIndexW32(const int32_t* vector, int length); // - vector : 16-bit input vector. // - length : Number of samples in vector. // -// Return value : Index to the mimimum value in vector; +// Return value : Index to the mimimum value in vector (if multiple +// indexes have the minimum, return the first); // or -1, if (vector == NULL || length <= 0). int WebRtcSpl_MinIndexW16(const int16_t* vector, int length); @@ -321,7 +327,8 @@ int WebRtcSpl_MinIndexW16(const int16_t* vector, int length); // - vector : 32-bit input vector. // - length : Number of samples in vector. // -// Return value : Index to the mimimum value in vector; +// Return value : Index to the mimimum value in vector (if multiple +// indexes have the minimum, return the first); // or -1, if (vector == NULL || length <= 0). int WebRtcSpl_MinIndexW32(const int32_t* vector, int length); diff --git a/src/common_audio/signal_processing/signal_processing_unittest.cc b/src/common_audio/signal_processing/signal_processing_unittest.cc index 1a371613d..4511a273b 100644 --- a/src/common_audio/signal_processing/signal_processing_unittest.cc +++ b/src/common_audio/signal_processing/signal_processing_unittest.cc @@ -225,31 +225,97 @@ TEST_F(SplTest, BasicArrayOperationsTest) { } } +TEST_F(SplTest, ExeptionsHandlingMinMaxOperationsTest) { + // Test how the functions handle exceptional cases. + const int kVectorSize = 2; + int16_t vector16[kVectorSize] = {0}; + int32_t vector32[kVectorSize] = {0}; + + EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW16(vector16, 0)); + EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW16(NULL, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, WebRtcSpl_MaxValueW16(vector16, 0)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, WebRtcSpl_MaxValueW16(NULL, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, WebRtcSpl_MinValueW16(vector16, 0)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, WebRtcSpl_MinValueW16(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW32(vector32, 0)); + EXPECT_EQ(-1, WebRtcSpl_MaxAbsValueW32(NULL, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, WebRtcSpl_MaxValueW32(vector32, 0)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, WebRtcSpl_MaxValueW32(NULL, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, WebRtcSpl_MinValueW32(vector32, 0)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, WebRtcSpl_MinValueW32(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MaxAbsIndexW16(vector16, 0)); + EXPECT_EQ(-1, WebRtcSpl_MaxAbsIndexW16(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MaxIndexW16(vector16, 0)); + EXPECT_EQ(-1, WebRtcSpl_MaxIndexW16(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MaxIndexW32(vector32, 0)); + EXPECT_EQ(-1, WebRtcSpl_MaxIndexW32(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MinIndexW16(vector16, 0)); + EXPECT_EQ(-1, WebRtcSpl_MinIndexW16(NULL, kVectorSize)); + EXPECT_EQ(-1, WebRtcSpl_MinIndexW32(vector32, 0)); + EXPECT_EQ(-1, WebRtcSpl_MinIndexW32(NULL, kVectorSize)); +} + TEST_F(SplTest, MinMaxOperationsTest) { - const int kVectorSize = 4; - int B[] = {4, 12, 133, -1100}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; + const int kVectorSize = 17; - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = B[kk]; - b32[kk] = B[kk]; - } + // Vectors to test the cases where minimum values have to be caught + // outside of the unrolled loops in ARM-Neon. + int16_t vector16[kVectorSize] = {-1, 7485, 0, 3333, + -18283, 0, 12334, -29871, 988, -3333, + 345, -456, 222, 999, 888, 8774, WEBRTC_SPL_WORD16_MIN}; + int32_t vector32[kVectorSize] = {-1, 0, 283211, 3333, + 8712345, 0, -3333, 89345, -374585456, 222, 999, 122345334, + -12389756, -987329871, 888, -2, WEBRTC_SPL_WORD32_MIN}; - EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW16(b16, kVectorSize)); - EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW32(b32, kVectorSize)); - EXPECT_EQ(133, WebRtcSpl_MaxValueW16(b16, kVectorSize)); - EXPECT_EQ(133, WebRtcSpl_MaxValueW32(b32, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MaxAbsIndexW16(b16, kVectorSize)); - EXPECT_EQ(2, WebRtcSpl_MaxIndexW16(b16, kVectorSize)); - EXPECT_EQ(2, WebRtcSpl_MaxIndexW32(b32, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, + WebRtcSpl_MinValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, + WebRtcSpl_MinValueW32(vector32, kVectorSize)); + EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW16(vector16, kVectorSize)); + EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MinIndexW32(vector32, kVectorSize)); - EXPECT_EQ(-1100, WebRtcSpl_MinValueW16(b16, kVectorSize)); - EXPECT_EQ(-1100, WebRtcSpl_MinValueW32(b32, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MinIndexW16(b16, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MinIndexW32(b32, kVectorSize)); + // Test the cases where maximum values have to be caught + // outside of the unrolled loops in ARM-Neon. + vector16[kVectorSize - 1] = WEBRTC_SPL_WORD16_MAX; + vector32[kVectorSize - 1] = WEBRTC_SPL_WORD32_MAX; - EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, + WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, + WebRtcSpl_MaxValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, + WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, + WebRtcSpl_MaxValueW32(vector32, kVectorSize)); + EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize)); + EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize)); + EXPECT_EQ(kVectorSize - 1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize)); + + // Test the cases where multiple maximum and minimum values are present. + vector16[1] = WEBRTC_SPL_WORD16_MAX; + vector16[6] = WEBRTC_SPL_WORD16_MIN; + vector16[11] = WEBRTC_SPL_WORD16_MIN; + vector32[1] = WEBRTC_SPL_WORD32_MAX; + vector32[6] = WEBRTC_SPL_WORD32_MIN; + vector32[11] = WEBRTC_SPL_WORD32_MIN; + + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, + WebRtcSpl_MaxAbsValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MAX, + WebRtcSpl_MaxValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD16_MIN, + WebRtcSpl_MinValueW16(vector16, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, + WebRtcSpl_MaxAbsValueW32(vector32, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MAX, + WebRtcSpl_MaxValueW32(vector32, kVectorSize)); + EXPECT_EQ(WEBRTC_SPL_WORD32_MIN, + WebRtcSpl_MinValueW32(vector32, kVectorSize)); + EXPECT_EQ(6, WebRtcSpl_MaxAbsIndexW16(vector16, kVectorSize)); + EXPECT_EQ(1, WebRtcSpl_MaxIndexW16(vector16, kVectorSize)); + EXPECT_EQ(1, WebRtcSpl_MaxIndexW32(vector32, kVectorSize)); + EXPECT_EQ(6, WebRtcSpl_MinIndexW16(vector16, kVectorSize)); + EXPECT_EQ(6, WebRtcSpl_MinIndexW32(vector32, kVectorSize)); } TEST_F(SplTest, VectorOperationsTest) { @@ -309,6 +375,8 @@ TEST_F(SplTest, VectorOperationsTest) { EXPECT_EQ(32767, bTmp16[kk]); } EXPECT_EQ(32749, bTmp16[kVectorSize - 1]); + + EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1)); } TEST_F(SplTest, EstimatorsTest) {