Home | History | Annotate | Download | only in src
      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 
     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 += 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