• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
q_gain_code(enum Mode mode,Word16 exp_gcode0,Word16 frac_gcode0,Word16 * gain,Word16 * qua_ener_MR122,Word16 * qua_ener,Flag * pOverflow)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