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: p_med_ol.c * 19 * * 20 * Description: Compute the open loop pitch lag * 21 * output: open loop pitch lag * 22 ************************************************************************/ 23 24 #include "typedef.h" 25 #include "basic_op.h" 26 #include "acelp.h" 27 #include "oper_32b.h" 28 #include "math_op.h" 29 #include "p_med_ol.tab" 30 31 Word16 Pitch_med_ol( 32 Word16 wsp[], /* i: signal used to compute the open loop pitch*/ 33 /* wsp[-pit_max] to wsp[-1] should be known */ 34 Coder_State *st, /* i/o: codec global structure */ 35 Word16 L_frame /* i: length of frame to compute pitch */ 36 ) 37 { 38 Word16 Tm; 39 Word16 hi, lo; 40 Word16 *ww, *we, *hp_wsp; 41 Word16 exp_R0, exp_R1, exp_R2; 42 Word32 i, j, max, R0, R1, R2; 43 Word16 *p1, *p2; 44 Word16 L_min = 17; /* minimum pitch lag: PIT_MIN / OPL_DECIM */ 45 Word16 L_max = 115; /* maximum pitch lag: PIT_MAX / OPL_DECIM */ 46 Word16 L_0 = st->old_T0_med; /* old open-loop pitch */ 47 Word16 *gain = &(st->ol_gain); /* normalize correlation of hp_wsp for the lag */ 48 Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/ 49 Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */ 50 Word16 wght_flg = st->ol_wght_flg; /* is weighting function used */ 51 52 ww = &corrweight[198]; 53 we = &corrweight[98 + L_max - L_0]; 54 55 max = MIN_32; 56 Tm = 0; 57 for (i = L_max; i > L_min; i--) 58 { 59 /* Compute the correlation */ 60 R0 = 0; 61 p1 = wsp; 62 p2 = &wsp[-i]; 63 for (j = 0; j < L_frame; j+=4) 64 { 65 R0 += vo_L_mult((*p1++), (*p2++)); 66 R0 += vo_L_mult((*p1++), (*p2++)); 67 R0 += vo_L_mult((*p1++), (*p2++)); 68 R0 += vo_L_mult((*p1++), (*p2++)); 69 } 70 /* Weighting of the correlation function. */ 71 hi = R0>>16; 72 lo = (R0 & 0xffff)>>1; 73 74 R0 = Mpy_32_16(hi, lo, *ww); 75 ww--; 76 77 if ((L_0 > 0) && (wght_flg > 0)) 78 { 79 /* Weight the neighbourhood of the old lag. */ 80 hi = R0>>16; 81 lo = (R0 & 0xffff)>>1; 82 R0 = Mpy_32_16(hi, lo, *we); 83 we--; 84 } 85 if(R0 >= max) 86 { 87 max = R0; 88 Tm = i; 89 } 90 } 91 92 /* Hypass the wsp[] vector */ 93 hp_wsp = old_hp_wsp + L_max; 94 Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem); 95 96 /* Compute normalize correlation at delay Tm */ 97 R0 = 0; 98 R1 = 0; 99 R2 = 0; 100 p1 = hp_wsp; 101 p2 = hp_wsp - Tm; 102 for (j = 0; j < L_frame; j+=4) 103 { 104 R2 += vo_mult32(*p1, *p1); 105 R1 += vo_mult32(*p2, *p2); 106 R0 += vo_mult32(*p1++, *p2++); 107 R2 += vo_mult32(*p1, *p1); 108 R1 += vo_mult32(*p2, *p2); 109 R0 += vo_mult32(*p1++, *p2++); 110 R2 += vo_mult32(*p1, *p1); 111 R1 += vo_mult32(*p2, *p2); 112 R0 += vo_mult32(*p1++, *p2++); 113 R2 += vo_mult32(*p1, *p1); 114 R1 += vo_mult32(*p2, *p2); 115 R0 += vo_mult32(*p1++, *p2++); 116 } 117 R0 = R0 <<1; 118 R1 = (R1 <<1) + 1L; 119 R2 = (R2 <<1) + 1L; 120 /* gain = R0/ sqrt(R1*R2) */ 121 122 exp_R0 = norm_l(R0); 123 R0 = (R0 << exp_R0); 124 125 exp_R1 = norm_l(R1); 126 R1 = (R1 << exp_R1); 127 128 exp_R2 = norm_l(R2); 129 R2 = (R2 << exp_R2); 130 131 132 R1 = vo_L_mult(vo_round(R1), vo_round(R2)); 133 134 i = norm_l(R1); 135 R1 = (R1 << i); 136 137 exp_R1 += exp_R2; 138 exp_R1 += i; 139 exp_R1 = 62 - exp_R1; 140 141 Isqrt_n(&R1, &exp_R1); 142 143 R0 = vo_L_mult(voround(R0), voround(R1)); 144 exp_R0 = 31 - exp_R0; 145 exp_R0 += exp_R1; 146 147 *gain = vo_round(L_shl(R0, exp_R0)); 148 149 /* Shitf hp_wsp[] for next frame */ 150 151 for (i = 0; i < L_max; i++) 152 { 153 old_hp_wsp[i] = old_hp_wsp[i + L_frame]; 154 } 155 156 return (Tm); 157 } 158 159 /************************************************************************ 160 * Function: median5 * 161 * * 162 * Returns the median of the set {X[-2], X[-1],..., X[2]}, * 163 * whose elements are 16-bit integers. * 164 * * 165 * Input: * 166 * X[-2:2] 16-bit integers. * 167 * * 168 * Return: * 169 * The median of {X[-2], X[-1],..., X[2]}. * 170 ************************************************************************/ 171 172 Word16 median5(Word16 x[]) 173 { 174 Word16 x1, x2, x3, x4, x5; 175 Word16 tmp; 176 177 x1 = x[-2]; 178 x2 = x[-1]; 179 x3 = x[0]; 180 x4 = x[1]; 181 x5 = x[2]; 182 183 if (x2 < x1) 184 { 185 tmp = x1; 186 x1 = x2; 187 x2 = tmp; 188 } 189 if (x3 < x1) 190 { 191 tmp = x1; 192 x1 = x3; 193 x3 = tmp; 194 } 195 if (x4 < x1) 196 { 197 tmp = x1; 198 x1 = x4; 199 x4 = tmp; 200 } 201 if (x5 < x1) 202 { 203 x5 = x1; 204 } 205 if (x3 < x2) 206 { 207 tmp = x2; 208 x2 = x3; 209 x3 = tmp; 210 } 211 if (x4 < x2) 212 { 213 tmp = x2; 214 x2 = x4; 215 x4 = tmp; 216 } 217 if (x5 < x2) 218 { 219 x5 = x2; 220 } 221 if (x4 < x3) 222 { 223 x3 = x4; 224 } 225 if (x5 < x3) 226 { 227 x3 = x5; 228 } 229 return (x3); 230 } 231 232 233 Word16 Med_olag( /* output : median of 5 previous open-loop lags */ 234 Word16 prev_ol_lag, /* input : previous open-loop lag */ 235 Word16 old_ol_lag[5] 236 ) 237 { 238 Word32 i; 239 240 /* Use median of 5 previous open-loop lags as old lag */ 241 242 for (i = 4; i > 0; i--) 243 { 244 old_ol_lag[i] = old_ol_lag[i - 1]; 245 } 246 247 old_ol_lag[0] = prev_ol_lag; 248 249 i = median5(&old_ol_lag[2]); 250 251 return i; 252 253 } 254 255 256 257