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
This commit is contained in:
parent
2bea04076c
commit
7611791ade
@ -170,9 +170,6 @@
|
|||||||
'msvs_disabled_warnings!': [4189,],
|
'msvs_disabled_warnings!': [4189,],
|
||||||
}],
|
}],
|
||||||
['OS=="android"', {
|
['OS=="android"', {
|
||||||
# On Android, we always prefer fixed_point to reduce CPU usage.
|
|
||||||
'prefer_fixed_point%': 1,
|
|
||||||
|
|
||||||
'defines': [
|
'defines': [
|
||||||
'WEBRTC_LINUX',
|
'WEBRTC_LINUX',
|
||||||
'WEBRTC_ANDROID',
|
'WEBRTC_ANDROID',
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
* (e.g. __builtin_clz).
|
* (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,
|
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a,
|
||||||
WebRtc_Word32 b) {
|
WebRtc_Word32 b) {
|
||||||
WebRtc_Word32 tmp = 0;
|
WebRtc_Word32 tmp = 0;
|
||||||
@ -27,6 +31,10 @@ static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a,
|
|||||||
return tmp;
|
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,
|
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a,
|
||||||
WebRtc_Word16 b,
|
WebRtc_Word16 b,
|
||||||
WebRtc_Word32 c) {
|
WebRtc_Word32 c) {
|
||||||
|
@ -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_RSFT32(a32a, a32b, A));
|
||||||
EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, 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(-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(-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));
|
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(32766u, WEBRTC_SPL_LSHIFT_U32(a, 1));
|
||||||
|
|
||||||
EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
|
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) {
|
TEST_F(SplTest, InlineTest) {
|
||||||
|
@ -45,11 +45,12 @@ void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,
|
|||||||
int16_t* sth_Q15,
|
int16_t* sth_Q15,
|
||||||
int16_t order_coef);
|
int16_t order_coef);
|
||||||
|
|
||||||
/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa().
|
/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa(). It does:
|
||||||
It does:
|
|
||||||
for 0 <= n < HALF_SUBFRAMELEN - 1:
|
for 0 <= n < HALF_SUBFRAMELEN - 1:
|
||||||
*ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
|
*ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
|
||||||
*ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
|
*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
|
void WebRtcIsacfix_FilterMaLoopC(int16_t input0, // Filter coefficient
|
||||||
int16_t input1, // Filter coefficient
|
int16_t input1, // Filter coefficient
|
||||||
|
Loading…
Reference in New Issue
Block a user