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