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