From 7611791ade8dd4966e1da58ac8ce792c75426c76 Mon Sep 17 00:00:00 2001 From: "kma@webrtc.org" Date: Tue, 28 Aug 2012 00:43:55 +0000 Subject: [PATCH] Added unit tests for several SPL macros/functions, and detailed all factors contributing to bit-not-exact between ARM assembly and generic C versions in iSAC and SPL, by code comments. Review URL: https://webrtc-codereview.appspot.com/741004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2673 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/build/common.gypi | 3 --- .../signal_processing/include/spl_inl_armv7.h | 8 ++++++ .../signal_processing_unittest.cc | 27 +++++++++++++++++-- .../codecs/isac/fix/source/lattice.c | 5 ++-- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/build/common.gypi b/src/build/common.gypi index 33a27d141a..f333b2b073 100644 --- a/src/build/common.gypi +++ b/src/build/common.gypi @@ -170,9 +170,6 @@ 'msvs_disabled_warnings!': [4189,], }], ['OS=="android"', { - # On Android, we always prefer fixed_point to reduce CPU usage. - 'prefer_fixed_point%': 1, - 'defines': [ 'WEBRTC_LINUX', 'WEBRTC_ANDROID', diff --git a/src/common_audio/signal_processing/include/spl_inl_armv7.h b/src/common_audio/signal_processing/include/spl_inl_armv7.h index 1ea2d78881..2eff496b86 100644 --- a/src/common_audio/signal_processing/include/spl_inl_armv7.h +++ b/src/common_audio/signal_processing/include/spl_inl_armv7.h @@ -20,6 +20,10 @@ * (e.g. __builtin_clz). */ +/* This function produces result that is not bit exact with that by the generic + * C version in some cases, although the former is at least as accurate as the + * later. + */ static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, WebRtc_Word32 b) { WebRtc_Word32 tmp = 0; @@ -27,6 +31,10 @@ static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, return tmp; } +/* This function produces result that is not bit exact with that by the generic + * C version in some cases, although the former is at least as accurate as the + * later. + */ static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a, WebRtc_Word16 b, WebRtc_Word32 c) { diff --git a/src/common_audio/signal_processing/signal_processing_unittest.cc b/src/common_audio/signal_processing/signal_processing_unittest.cc index 97f69ab668..970889ff01 100644 --- a/src/common_audio/signal_processing/signal_processing_unittest.cc +++ b/src/common_audio/signal_processing/signal_processing_unittest.cc @@ -70,9 +70,7 @@ TEST_F(SplTest, MacroTest) { EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, A)); EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, A)); - EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b)); EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2)); - EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2)); EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b)); @@ -106,6 +104,31 @@ TEST_F(SplTest, MacroTest) { EXPECT_EQ(32766u, WEBRTC_SPL_LSHIFT_U32(a, 1)); EXPECT_EQ(1470, WEBRTC_SPL_RAND(A)); + + EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b)); + EXPECT_EQ(1073676289, WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX, + WEBRTC_SPL_WORD16_MAX)); + EXPECT_EQ(1073709055, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MAX, + WEBRTC_SPL_WORD32_MAX)); + EXPECT_EQ(1073741824, WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN, + WEBRTC_SPL_WORD32_MIN)); +#ifdef WEBRTC_ARCH_ARM_V7A + EXPECT_EQ(-1073741824, + WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN, + WEBRTC_SPL_WORD32_MAX)); + EXPECT_EQ(0x3fffffff, WEBRTC_SPL_MUL_32_32_RSFT32(WEBRTC_SPL_WORD16_MAX, + 0xffff, WEBRTC_SPL_WORD32_MAX)); + EXPECT_EQ(0x3fffffff, WEBRTC_SPL_MUL_32_32_RSFT32BI(WEBRTC_SPL_WORD32_MAX, + WEBRTC_SPL_WORD32_MAX)); +#else + EXPECT_EQ(-1073741823, + WEBRTC_SPL_MUL_16_32_RSFT16(WEBRTC_SPL_WORD16_MIN, + WEBRTC_SPL_WORD32_MAX)); + EXPECT_EQ(0x3fff7ffe, WEBRTC_SPL_MUL_32_32_RSFT32(WEBRTC_SPL_WORD16_MAX, + 0xffff, WEBRTC_SPL_WORD32_MAX)); + EXPECT_EQ(0x3ffffffd, WEBRTC_SPL_MUL_32_32_RSFT32BI(WEBRTC_SPL_WORD32_MAX, + WEBRTC_SPL_WORD32_MAX)); +#endif } TEST_F(SplTest, InlineTest) { diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lattice.c b/src/modules/audio_coding/codecs/isac/fix/source/lattice.c index 8822c6e9b8..14588d0f0d 100644 --- a/src/modules/audio_coding/codecs/isac/fix/source/lattice.c +++ b/src/modules/audio_coding/codecs/isac/fix/source/lattice.c @@ -45,11 +45,12 @@ void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0, int16_t* sth_Q15, int16_t order_coef); -/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa(). - It does: +/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa(). It does: for 0 <= n < HALF_SUBFRAMELEN - 1: *ptr2 = input2 * (*ptr2) + input0 * (*ptr0)); *ptr1 = input1 * (*ptr0) + input0 * (*ptr2); + Note, function WebRtcIsacfix_FilterMaLoopNeon and WebRtcIsacfix_FilterMaLoopC + are not bit-exact. The accuracy by the ARM Neon function is same or better. */ void WebRtcIsacfix_FilterMaLoopC(int16_t input0, // Filter coefficient int16_t input1, // Filter coefficient