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/q_gain_c.c 35 Functions: q_gain_code 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: 46 (1) Removed optimization -- mult(i, 3, pOverflow) is NOT the same as adding 47 i to itself 3 times. The reason is because the mult function does a 48 right shift by 15, which will obliterate smaller numbers. 49 50 Description: 51 1. Eliminated unused include files. 52 2. Eliminated math operations that unnecessary checked for 53 saturation by evaluating the operands 54 55 Description: Replaced "int" and/or "char" with OSCL defined types. 56 57 Description: Added #ifdef __cplusplus around extern'ed table. 58 59 Description: 60 61 ------------------------------------------------------------------------------ 62 MODULE DESCRIPTION 63 64 Scalar quantization of the innovative codebook gain. 65 66 ------------------------------------------------------------------------------ 67 */ 68 69 /*---------------------------------------------------------------------------- 70 ; INCLUDES 71 ----------------------------------------------------------------------------*/ 72 #include "q_gain_c.h" 73 #include "mode.h" 74 #include "oper_32b.h" 75 #include "basic_op.h" 76 #include "log2.h" 77 #include "pow2.h" 78 79 /*--------------------------------------------------------------------------*/ 80 #ifdef __cplusplus 81 extern "C" 82 { 83 #endif 84 85 /*---------------------------------------------------------------------------- 86 ; MACROS 87 ; Define module specific macros here 88 ----------------------------------------------------------------------------*/ 89 90 /*---------------------------------------------------------------------------- 91 ; DEFINES 92 ; Include all pre-processor statements here. Include conditional 93 ; compile variables also. 94 ----------------------------------------------------------------------------*/ 95 #define NB_QUA_CODE 32 96 97 /*---------------------------------------------------------------------------- 98 ; LOCAL FUNCTION DEFINITIONS 99 ; Function Prototype declaration 100 ----------------------------------------------------------------------------*/ 101 102 /*---------------------------------------------------------------------------- 103 ; LOCAL VARIABLE DEFINITIONS 104 ; Variable declaration - defined here and used outside this module 105 ----------------------------------------------------------------------------*/ 106 107 /*---------------------------------------------------------------------------- 108 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 109 ; Declare variables used in this module but defined elsewhere 110 ----------------------------------------------------------------------------*/ 111 extern const Word16 qua_gain_code[NB_QUA_CODE*3]; 112 113 /*--------------------------------------------------------------------------*/ 114 #ifdef __cplusplus 115 } 116 #endif 117 118 /* 119 ------------------------------------------------------------------------------ 120 FUNCTION NAME: q_gain_code 121 ------------------------------------------------------------------------------ 122 INPUT AND OUTPUT DEFINITIONS 123 124 Inputs: 125 mode -- enum Mode -- AMR mode 126 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 127 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 128 gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1 129 130 Outputs: 131 gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1 132 133 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 134 (for MR122 MA predictor update) 135 136 qua_ener -- Pointer to Word16 -- quantized energy error, Q10 137 (for other MA predictor update) 138 139 pOverflow -- Pointer to Flag -- overflow indicator 140 Returns: 141 quantization index -- Word16 -- Q0 142 143 Global Variables Used: 144 qua_gain_code[] 145 146 Local Variables Needed: 147 None 148 149 ------------------------------------------------------------------------------ 150 FUNCTION DESCRIPTION 151 152 Scalar quantization of the innovative codebook gain. 153 154 ------------------------------------------------------------------------------ 155 REQUIREMENTS 156 157 None 158 159 ------------------------------------------------------------------------------ 160 REFERENCES 161 162 q_gain_c.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 Word16 q_gain_code( /* o : quantization index, Q0 */ 192 enum Mode mode, /* i : AMR mode */ 193 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ 194 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ 195 Word16 *gain, /* i/o: quantized fixed codebook gain, Q1 */ 196 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ 197 /* (for MR122 MA predictor update) */ 198 Word16 *qua_ener, /* o : quantized energy error, Q10 */ 199 /* (for other MA predictor update) */ 200 Flag *pOverflow 201 ) 202 { 203 const Word16 *p; 204 Word16 i; 205 Word16 index; 206 Word16 gcode0; 207 Word16 err; 208 Word16 err_min; 209 Word16 g_q0; 210 Word16 temp; 211 212 if (mode == MR122) 213 { 214 g_q0 = *gain >> 1; /* Q1 -> Q0 */ 215 } 216 else 217 { 218 g_q0 = *gain; 219 } 220 221 /*-------------------------------------------------------------------* 222 * predicted codebook gain * 223 * ~~~~~~~~~~~~~~~~~~~~~~~ * 224 * gc0 = Pow2(int(d)+frac(d)) * 225 * = 2^exp + 2^frac * 226 * * 227 *-------------------------------------------------------------------*/ 228 229 gcode0 = (Word16) Pow2(exp_gcode0, frac_gcode0, pOverflow); /* predicted gain */ 230 231 if (mode == MR122) 232 { 233 gcode0 = shl(gcode0, 4, pOverflow); 234 } 235 else 236 { 237 gcode0 = shl(gcode0, 5, pOverflow); 238 } 239 240 /*-------------------------------------------------------------------* 241 * Search for best quantizer * 242 *-------------------------------------------------------------------*/ 243 244 p = &qua_gain_code[0]; 245 err_min = ((Word32)gcode0 * *(p++)) >> 15; 246 err_min = g_q0 - err_min; 247 if (err_min < 0) 248 { 249 err_min = -err_min; 250 } 251 252 p += 2; /* skip quantized energy errors */ 253 index = 0; 254 255 for (i = 1; i < NB_QUA_CODE; i++) 256 { 257 err = ((Word32)gcode0 * *(p++)) >> 15; 258 err = g_q0 - err; 259 260 if (err < 0) 261 { 262 err = -err; 263 } 264 265 p += 2; /* skip quantized energy error */ 266 267 if (err < err_min) 268 { 269 err_min = err; 270 index = i; 271 } 272 } 273 274 temp = index + (index << 1); 275 276 p = &qua_gain_code[temp]; 277 278 temp = (gcode0 * *(p++)) >> 15; 279 if (mode == MR122) 280 { 281 *gain = temp << 1; 282 } 283 else 284 { 285 *gain = temp; 286 } 287 288 /* quantized error energies (for MA predictor update) */ 289 *qua_ener_MR122 = *p++; 290 *qua_ener = *p; 291 292 return index; 293 } 294