1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 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 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /**************************************************************************************** 19 Portions of this file are derived from the following 3GPP standard: 20 21 3GPP TS 26.073 22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec 23 Available from http://www.3gpp.org 24 25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) 26 Permission to distribute, modify and use this file under the standard license 27 terms listed above has been obtained from the copyright holder. 28 ****************************************************************************************/ 29 /* 30 ------------------------------------------------------------------------------ 31 32 33 34 Pathname: ./audio/gsm-amr/c/src/qua_gain.c 35 Functions: 36 37 Date: 02/05/2002 38 39 ------------------------------------------------------------------------------ 40 REVISION HISTORY 41 42 Description: Updated template used to PV coding template. 43 Changed to accept the pOverflow flag for EPOC compatibility. 44 45 Description: Changed include files to lowercase. 46 47 Description: Replaced OSCL mem type functions and eliminated include 48 files that now are chosen by OSCL definitions 49 50 Description: Replaced "int" and/or "char" with OSCL defined types. 51 52 Description: Added #ifdef __cplusplus around extern'ed table. 53 54 Description: 55 56 ------------------------------------------------------------------------------ 57 MODULE DESCRIPTION 58 59 Quantization of pitch and codebook gains. 60 ------------------------------------------------------------------------------ 61 */ 62 63 /*---------------------------------------------------------------------------- 64 ; INCLUDES 65 ----------------------------------------------------------------------------*/ 66 #include "qua_gain.h" 67 #include "typedef.h" 68 #include "basic_op.h" 69 70 #include "mode.h" 71 #include "cnst.h" 72 #include "pow2.h" 73 #include "gc_pred.h" 74 75 /*--------------------------------------------------------------------------*/ 76 #ifdef __cplusplus 77 extern "C" 78 { 79 #endif 80 81 /*---------------------------------------------------------------------------- 82 ; MACROS 83 ; Define module specific macros here 84 ----------------------------------------------------------------------------*/ 85 86 /*---------------------------------------------------------------------------- 87 ; DEFINES 88 ; Include all pre-processor statements here. Include conditional 89 ; compile variables also. 90 ----------------------------------------------------------------------------*/ 91 92 /*---------------------------------------------------------------------------- 93 ; LOCAL FUNCTION DEFINITIONS 94 ; Function Prototype declaration 95 ----------------------------------------------------------------------------*/ 96 97 /*---------------------------------------------------------------------------- 98 ; LOCAL VARIABLE DEFINITIONS 99 ; Variable declaration - defined here and used outside this module 100 ----------------------------------------------------------------------------*/ 101 102 /*---------------------------------------------------------------------------- 103 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 104 ; Declare variables used in this module but defined elsewhere 105 ----------------------------------------------------------------------------*/ 106 extern const Word16 table_gain_lowrates[]; 107 extern const Word16 table_gain_highrates[]; 108 109 /*--------------------------------------------------------------------------*/ 110 #ifdef __cplusplus 111 } 112 #endif 113 114 /* 115 ------------------------------------------------------------------------------ 116 FUNCTION NAME: 117 ------------------------------------------------------------------------------ 118 INPUT AND OUTPUT DEFINITIONS 119 120 121 Inputs: 122 mode -- enum Mode -- AMR mode 123 Word16 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 124 Word16 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 125 Word16 frac_coeff -- Word16 Array -- energy coeff. (5), fraction part, Q15 126 Word16 exp_coeff -- Word16 Array -- energy coeff. (5), exponent part, Q0 127 (frac_coeff and exp_coeff computed in 128 calc_filt_energies()) 129 130 Word16 gp_limit -- Word16 -- pitch gain limit 131 132 Outputs: 133 Word16 *gain_pit -- Pointer to Word16 -- Pitch gain, Q14 134 Word16 *gain_cod -- Pointer to Word16 -- Code gain, Q1 135 Word16 *qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 136 (for MR122 MA predictor update) 137 Word16 *qua_ener -- Pointer to Word16 -- quantized energy error, Q10 138 (for other MA predictor update) 139 Flag *pOverflow -- Pointer to Flag -- overflow indicator 140 141 Returns: 142 Word16 -- index of quantization. 143 144 Global Variables Used: 145 146 147 Local Variables Needed: 148 None 149 150 ------------------------------------------------------------------------------ 151 FUNCTION DESCRIPTION 152 153 Quantization of pitch and codebook gains. 154 ------------------------------------------------------------------------------ 155 REQUIREMENTS 156 157 None 158 159 ------------------------------------------------------------------------------ 160 REFERENCES 161 162 qua_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 163 164 ------------------------------------------------------------------------------ 165 PSEUDO-CODE 166 167 168 ------------------------------------------------------------------------------ 169 RESOURCES USED [optional] 170 171 When the code is written for a specific target processor the 172 the resources used should be documented below. 173 174 HEAP MEMORY USED: x bytes 175 176 STACK MEMORY USED: x bytes 177 178 CLOCK CYCLES: (cycle count equation for this function) + (variable 179 used to represent cycle count for each subroutine 180 called) 181 where: (cycle count variable) = cycle count for [subroutine 182 name] 183 184 ------------------------------------------------------------------------------ 185 CAUTION [optional] 186 [State any special notes, constraints or cautions for users of this function] 187 188 ------------------------------------------------------------------------------ 189 */ 190 191 192 Word16 193 Qua_gain( /* o : index of quantization. */ 194 enum Mode mode, /* i : AMR mode */ 195 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ 196 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ 197 Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ 198 Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ 199 /* (frac_coeff and exp_coeff computed in */ 200 /* calc_filt_energies()) */ 201 Word16 gp_limit, /* i : pitch gain limit */ 202 Word16 *gain_pit, /* o : Pitch gain, Q14 */ 203 Word16 *gain_cod, /* o : Code gain, Q1 */ 204 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ 205 /* (for MR122 MA predictor update) */ 206 Word16 *qua_ener, /* o : quantized energy error, Q10 */ 207 /* (for other MA predictor update) */ 208 Flag *pOverflow /* o : overflow indicator */ 209 ) 210 { 211 const Word16 *p; 212 Word16 i; 213 Word16 j; 214 Word16 index = 0; 215 Word16 gcode0; 216 Word16 e_max; 217 Word16 temp; 218 Word16 exp_code; 219 Word16 g_pitch; 220 Word16 g2_pitch; 221 Word16 g_code; 222 Word16 g2_code; 223 Word16 g_pit_cod; 224 Word16 coeff[5]; 225 Word16 coeff_lo[5]; 226 Word16 exp_max[5]; 227 Word32 L_tmp; 228 Word32 L_tmp2; 229 Word32 dist_min; 230 const Word16 *table_gain; 231 Word16 table_len; 232 233 if (mode == MR102 || mode == MR74 || mode == MR67) 234 { 235 table_len = VQ_SIZE_HIGHRATES; 236 table_gain = table_gain_highrates; 237 } 238 else 239 { 240 table_len = VQ_SIZE_LOWRATES; 241 table_gain = table_gain_lowrates; 242 } 243 244 /*-------------------------------------------------------------------* 245 * predicted codebook gain * 246 * ~~~~~~~~~~~~~~~~~~~~~~~ * 247 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * 248 * * 249 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * 250 *-------------------------------------------------------------------*/ 251 252 gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); 253 254 /*-------------------------------------------------------------------* 255 * Scaling considerations: * 256 * ~~~~~~~~~~~~~~~~~~~~~~~ * 257 *-------------------------------------------------------------------*/ 258 259 /* 260 * The error energy (sum) to be minimized consists of five terms, t[0..4]. 261 * 262 * t[0] = gp^2 * <y1 y1> 263 * t[1] = -2*gp * <xn y1> 264 * t[2] = gc^2 * <y2 y2> 265 * t[3] = -2*gc * <xn y2> 266 * t[4] = 2*gp*gc * <y1 y2> 267 * 268 */ 269 270 /* determine the scaling exponent for g_code: ec = ec0 - 11 */ 271 exp_code = sub(exp_gcode0, 11, pOverflow); 272 273 /* calculate exp_max[i] = s[i]-1 */ 274 exp_max[0] = sub(exp_coeff[0], 13, pOverflow); 275 exp_max[1] = sub(exp_coeff[1], 14, pOverflow); 276 277 temp = shl(exp_code, 1, pOverflow); 278 temp = add(15, temp, pOverflow); 279 exp_max[2] = add(exp_coeff[2], temp, pOverflow); 280 281 exp_max[3] = add(exp_coeff[3], exp_code, pOverflow); 282 283 temp = add(1, exp_code, pOverflow); 284 exp_max[4] = add(exp_coeff[4], temp, pOverflow); 285 286 287 /*-------------------------------------------------------------------* 288 * Find maximum exponent: * 289 * ~~~~~~~~~~~~~~~~~~~~~~ * 290 * * 291 * For the sum operation, all terms must have the same scaling; * 292 * that scaling should be low enough to prevent overflow. There- * 293 * fore, the maximum scale is determined and all coefficients are * 294 * re-scaled: * 295 * * 296 * e_max = max(exp_max[i]) + 1; * 297 * e = exp_max[i]-e_max; e <= 0! * 298 * c[i] = c[i]*2^e * 299 *-------------------------------------------------------------------*/ 300 301 e_max = exp_max[0]; 302 for (i = 1; i < 5; i++) 303 { 304 if (exp_max[i] > e_max) 305 { 306 e_max = exp_max[i]; 307 } 308 } 309 310 e_max = add(e_max, 1, pOverflow); /* To avoid overflow */ 311 312 for (i = 0; i < 5; i++) 313 { 314 j = sub(e_max, exp_max[i], pOverflow); 315 L_tmp = L_deposit_h(frac_coeff[i]); 316 L_tmp = L_shr(L_tmp, j, pOverflow); 317 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); 318 } 319 320 321 /*-------------------------------------------------------------------* 322 * Codebook search: * 323 * ~~~~~~~~~~~~~~~~ * 324 * * 325 * For each pair (g_pitch, g_fac) in the table calculate the * 326 * terms t[0..4] and sum them up; the result is the mean squared * 327 * error for the quantized gains from the table. The index for the * 328 * minimum MSE is stored and finally used to retrieve the quantized * 329 * gains * 330 *-------------------------------------------------------------------*/ 331 332 /* start with "infinite" MSE */ 333 dist_min = MAX_32; 334 335 p = &table_gain[0]; 336 337 for (i = 0; i < table_len; i++) 338 { 339 g_pitch = *p++; 340 g_code = *p++; /* this is g_fac */ 341 p++; /* skip log2(g_fac) */ 342 p++; /* skip 20*log10(g_fac) */ 343 344 if (g_pitch <= gp_limit) 345 { 346 g_code = mult(g_code, gcode0, pOverflow); 347 g2_pitch = mult(g_pitch, g_pitch, pOverflow); 348 g2_code = mult(g_code, g_code, pOverflow); 349 g_pit_cod = mult(g_code, g_pitch, pOverflow); 350 351 L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); 352 L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow); 353 L_tmp = L_add(L_tmp, L_tmp2, pOverflow); 354 355 L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow); 356 L_tmp = L_add(L_tmp, L_tmp2, pOverflow); 357 358 L_tmp2 = Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow); 359 L_tmp = L_add(L_tmp, L_tmp2, pOverflow); 360 361 L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow); 362 L_tmp = L_add(L_tmp, L_tmp2, pOverflow); 363 364 /* store table index if MSE for this index is lower 365 than the minimum MSE seen so far */ 366 if (L_tmp < dist_min) 367 { 368 dist_min = L_tmp; 369 index = i; 370 } 371 } 372 } 373 374 /*------------------------------------------------------------------* 375 * read quantized gains and new values for MA predictor memories * 376 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * 377 *------------------------------------------------------------------*/ 378 379 /* Read the quantized gains */ 380 p = &table_gain[shl(index, 2, pOverflow)]; 381 *gain_pit = *p++; 382 g_code = *p++; 383 *qua_ener_MR122 = *p++; 384 *qua_ener = *p; 385 386 /*------------------------------------------------------------------* 387 * calculate final fixed codebook gain: * 388 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * 389 * * 390 * gc = gc0 * g * 391 *------------------------------------------------------------------*/ 392 393 L_tmp = L_mult(g_code, gcode0, pOverflow); 394 temp = sub(10, exp_gcode0, pOverflow); 395 L_tmp = L_shr(L_tmp, temp, pOverflow); 396 397 *gain_cod = extract_h(L_tmp); 398 399 return index; 400 } 401