OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / codecs / amrwbenc / src / cor_h_x.c
1 /*\r
2  ** Copyright 2003-2010, VisualOn, Inc.\r
3  **\r
4  ** Licensed under the Apache License, Version 2.0 (the "License");\r
5  ** you may not use this file except in compliance with the License.\r
6  ** You may obtain a copy of the License at\r
7  **\r
8  **     http://www.apache.org/licenses/LICENSE-2.0\r
9  **\r
10  ** Unless required by applicable law or agreed to in writing, software\r
11  ** distributed under the License is distributed on an "AS IS" BASIS,\r
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  ** See the License for the specific language governing permissions and\r
14  ** limitations under the License.\r
15  */\r
16 \r
17 /***********************************************************************\r
18 *       File: cor_h_x.c                                                *\r
19 *                                                                      *\r
20 *          Description:Compute correlation between target "x[]" and "h[]"  *\r
21 *                      Designed for codebook search (24 pulses, 4 tracks,  * \r
22 *                                  4 pulses per track, 16 positions in each track) to  *\r
23 *                                  avoid saturation.                                   *\r
24 *                                                                      *\r
25 ************************************************************************/\r
26 \r
27 #include "typedef.h"\r
28 #include "basic_op.h"\r
29 #include "math_op.h"\r
30 \r
31 #define L_SUBFR   64\r
32 #define NB_TRACK  4\r
33 #define STEP      4\r
34 \r
35 void cor_h_x(\r
36                 Word16 h[],                           /* (i) Q12 : impulse response of weighted synthesis filter */\r
37                 Word16 x[],                           /* (i) Q0  : target vector                                 */\r
38                 Word16 dn[]                           /* (o) <12bit : correlation between target and h[]         */\r
39             )\r
40 {\r
41         Word32 i, j;\r
42         Word32 L_tmp, y32[L_SUBFR], L_tot;\r
43         Word16 *p1, *p2;\r
44         Word32 *p3;\r
45         Word32 L_max, L_max1, L_max2, L_max3;\r
46         /* first keep the result on 32 bits and find absolute maximum */\r
47         L_tot  = 1;                            \r
48         L_max  = 0; \r
49         L_max1 = 0;\r
50         L_max2 = 0;\r
51         L_max3 = 0;\r
52         for (i = 0; i < L_SUBFR; i += STEP)\r
53         {\r
54                 L_tmp = 1;                                    /* 1 -> to avoid null dn[] */\r
55                 p1 = &x[i];\r
56                 p2 = &h[0];\r
57                 for (j = i; j < L_SUBFR; j++)\r
58                         L_tmp += vo_L_mult(*p1++, *p2++);\r
59 \r
60                 y32[i] = L_tmp;               \r
61                 L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;\r
62                 if(L_tmp > L_max)\r
63                 {\r
64                         L_max = L_tmp;             \r
65                 }\r
66 \r
67                 L_tmp = 1L;\r
68                 p1 = &x[i+1];\r
69                 p2 = &h[0];\r
70                 for (j = i+1; j < L_SUBFR; j++)\r
71                         L_tmp += vo_L_mult(*p1++, *p2++);\r
72 \r
73                 y32[i+1] = L_tmp;               \r
74                 L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;\r
75                 if(L_tmp > L_max1)\r
76                 {\r
77                         L_max1 = L_tmp;             \r
78                 }\r
79 \r
80                 L_tmp = 1;\r
81                 p1 = &x[i+2];\r
82                 p2 = &h[0];\r
83                 for (j = i+2; j < L_SUBFR; j++)\r
84                         L_tmp += vo_L_mult(*p1++, *p2++);\r
85 \r
86                 y32[i+2] = L_tmp;               \r
87                 L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;\r
88                 if(L_tmp > L_max2)\r
89                 {\r
90                         L_max2 = L_tmp;             \r
91                 }\r
92 \r
93                 L_tmp = 1;\r
94                 p1 = &x[i+3];\r
95                 p2 = &h[0];\r
96                 for (j = i+3; j < L_SUBFR; j++)\r
97                         L_tmp += vo_L_mult(*p1++, *p2++);\r
98 \r
99                 y32[i+3] = L_tmp;               \r
100                 L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;\r
101                 if(L_tmp > L_max3)\r
102                 {\r
103                         L_max3 = L_tmp;             \r
104                 }\r
105         }\r
106         /* tot += 3*max / 8 */\r
107         L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);\r
108         L_tot = vo_L_add(L_tot, L_max);       /* +max/4 */\r
109         L_tot = vo_L_add(L_tot, (L_max >> 1));  /* +max/8 */\r
110 \r
111         /* Find the number of right shifts to do on y32[] so that    */\r
112         /* 6.0 x sumation of max of dn[] in each track not saturate. */\r
113         j = norm_l(L_tot) - 4;             /* 4 -> 16 x tot */\r
114         p1 = dn;\r
115         p3 = y32;\r
116         for (i = 0; i < L_SUBFR; i+=4)\r
117         {\r
118                 *p1++ = vo_round(L_shl(*p3++, j));\r
119                 *p1++ = vo_round(L_shl(*p3++, j));\r
120                 *p1++ = vo_round(L_shl(*p3++, j));\r
121                 *p1++ = vo_round(L_shl(*p3++, j));\r
122         }\r
123         return;\r
124 }\r
125 \r
126 \r
127 \r