Optimized a filter bank function in iSAC/fix for ARM.

Review URL: https://webrtc-codereview.appspot.com/631008

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2500 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
kma@webrtc.org 2012-07-10 17:59:44 +00:00
parent cf9855d9eb
commit e2c16a83bc
3 changed files with 70 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@ -17,48 +17,46 @@
*/
#include "filterbank_tables.h"
#include "settings.h"
/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
* In float, they are:
* {-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f};
* In float, they are: {-1.94895953203325f, 0.94984516000000f,
* -0.05101826139794f, 0.05015484000000f};
*/
const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8] = {
-31932, 16189, /* Q30 hi/lo pair */
15562, 17243, /* Q30 hi/lo pair */
-26748, -17186, /* Q35 hi/lo pair */
26296, -27476 /* Q35 hi/lo pair */
const int16_t WebRtcIsacfix_kHpStCoeffInQ30[8] = {
16189, -31932, /* Q30 lo/hi pair */
17243, 15562, /* Q30 lo/hi pair */
-17186, -26748, /* Q35 lo/hi pair */
-27476, 26296 /* Q35 lo/hi pair */
};
/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
* In float, they are:
* {-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
* In float, they are: {-1.99701049409000f, 0.99714204490000f,
* 0.01701049409000f, -0.01704204490000f};
*/
const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8] = {
-32719, -1306, /* Q30 hi/lo pair */
16337, 11486, /* Q30 hi/lo pair */
8918, 26078, /* Q35 hi/lo pair */
-8935, 3956 /* Q35 hi/lo pair */
const int16_t WebRtcIsacfix_kHPStCoeffOut1Q30[8] = {
-1306, -32719, /* Q30 lo/hi pair */
11486, 16337, /* Q30 lo/hi pair */
26078, 8918, /* Q35 lo/hi pair */
3956, -8935 /* Q35 lo/hi pair */
};
/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
* In float, they are:
* {-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
* In float, they are: {-1.98645294509837f, 0.98672435560000f,
* 0.00645294509837f, -0.00662435560000f};
*/
const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8] = {
-32546, -2953, /* Q30 hi/lo pair */
16166, 32233, /* Q30 hi/lo pair */
3383, 13217, /* Q35 hi/lo pair */
-3473, -4597 /* Q35 hi/lo pair */
const int16_t WebRtcIsacfix_kHPStCoeffOut2Q30[8] = {
-2953, -32546, /* Q30 lo/hi pair */
32233, 16166, /* Q30 lo/hi pair */
13217, 3383, /* Q35 lo/hi pair */
-4597, -3473 /* Q35 lo/hi pair */
};
/* The upper channel all-pass filter factors */
const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2] = {
const int16_t WebRtcIsacfix_kUpperApFactorsQ15[2] = {
1137, 12537
};
/* The lower channel all-pass filter factors */
const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2] = {
const int16_t WebRtcIsacfix_kLowerApFactorsQ15[2] = {
5059, 24379
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@ -24,18 +24,21 @@
/********************* Coefficient Tables ************************/
/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
extern const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
extern const int16_t WebRtcIsacfix_kHpStCoeffInQ30[8];
/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
extern const int16_t WebRtcIsacfix_kHPStCoeffOut1Q30[8];
/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */
/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
extern const int16_t WebRtcIsacfix_kHPStCoeffOut2Q30[8];
/* The upper channel all-pass filter factors */
extern const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2];
extern const int16_t WebRtcIsacfix_kUpperApFactorsQ15[2];
/* The lower channel all-pass filter factors */
extern const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2];
extern const int16_t WebRtcIsacfix_kLowerApFactorsQ15[2];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@ -56,31 +56,52 @@ static void HighpassFilterFixDec32(
WebRtc_Word32 *state) /* Q4:filter state Input/Output */
{
int k;
WebRtc_Word32 a, b, c, in;
WebRtc_Word32 a1 = 0, b1 = 0, c = 0, in = 0;
WebRtc_Word32 a2 = 0, b2 = 0;
WebRtc_Word32 state0 = state[0];
WebRtc_Word32 state1 = state[1];
for (k=0; k<len; k++) {
in = (WebRtc_Word32)io[k];
/* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*2], coeff[2*2+1], state[0]);
b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*3], coeff[2*3+1], state[1]);
c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a+b, 7); // Q0
//c = WEBRTC_SPL_RSHIFT_W32(c, 1); // Q-1
io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c); // Write output as Q0
#ifdef WEBRTC_ARCH_ARM_V7A
__asm __volatile(
"smmul %[a2], %[coeff01], %[state0]\n\t"
"smmul %[b2], %[coeff23], %[state1]\n\t"
"smmul %[a1], %[coeff45], %[state0]\n\t"
"smmul %[b1], %[coeff67], %[state1]\n\t"
:[a2]"+r"(a2),
[b2]"+r"(b2),
[a1]"+r"(a1),
[b1]"+r"(b1)
:[coeff01]"r"(coeff_ptr[0]),
[coeff23]"r"(coeff_ptr[1]),
[coeff45]"r"(coeff_ptr[2]),
[coeff67]"r"(coeff_ptr[3]),
[state0]"r"(state0),
[state1]"r"(state1)
);
#else
/* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[5], coeff[4], state[0]);
b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[7], coeff[6], state[1]);
/* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*0], coeff[2*0+1], state[0]);
b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*1], coeff[2*1+1], state[1]);
a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[1], coeff[0], state[0]);
b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[3], coeff[2], state[1]);
#endif
c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a - b; // New state in Q2
c= (WebRtc_Word32)WEBRTC_SPL_SAT((WebRtc_Word32)536870911, c, (WebRtc_Word32)-536870912); // Check for wrap-around
c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0
io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c); // Write output as Q0.
state[1] = state[0];
state[0] = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a2 - b2; // In Q2.
c = (WebRtc_Word32)WEBRTC_SPL_SAT(536870911, c, -536870912);
state1 = state0;
state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
}
state[0] = state0;
state[1] = state1;
}