cor_h_x.c revision b676a05348e4c516fa8b57e33b10548e6142c3f8
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