cor_h_x.c revision 5d5c3a132bb446ac78a37dfaac24a46cacf0dd73
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
35void 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 += vo_L_mult(*p1++, *p2++);
59
60        y32[i] = L_tmp;
61        L_tmp = (L_tmp > 0)? L_tmp:-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 += vo_L_mult(*p1++, *p2++);
72
73        y32[i+1] = L_tmp;
74        L_tmp = (L_tmp > 0)? L_tmp:-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 += vo_L_mult(*p1++, *p2++);
85
86        y32[i+2] = L_tmp;
87        L_tmp = (L_tmp > 0)? L_tmp:-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 += vo_L_mult(*p1++, *p2++);
98
99        y32[i+3] = L_tmp;
100        L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
101        if(L_tmp > L_max3)
102        {
103            L_max3 = L_tmp;
104        }
105    }
106    /* tot += 3*max / 8 */
107    L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);
108    L_tot = vo_L_add(L_tot, L_max);       /* +max/4 */
109    L_tot = vo_L_add(L_tot, (L_max >> 1));  /* +max/8 */
110
111    /* Find the number of right shifts to do on y32[] so that    */
112    /* 6.0 x sumation of max of dn[] in each track not saturate. */
113    j = norm_l(L_tot) - 4;             /* 4 -> 16 x tot */
114    p1 = dn;
115    p3 = y32;
116    for (i = 0; i < L_SUBFR; i+=4)
117    {
118        *p1++ = vo_round(L_shl(*p3++, j));
119        *p1++ = vo_round(L_shl(*p3++, j));
120        *p1++ = vo_round(L_shl(*p3++, j));
121        *p1++ = vo_round(L_shl(*p3++, j));
122    }
123    return;
124}
125
126
127
128