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/dec_gain.c
35  Funtions: dec_gain
36 
37      Date: 01/31/2002
38 
39 ------------------------------------------------------------------------------
40  REVISION HISTORY
41 
42  Description: Updating include file lists, and other things as per review
43               comments.
44 
45  Description: Added fixes to the code as per review comments. Removed nested
46               function calls and declared temp2 as a variable.
47 
48  Description: A Word32 was being stored improperly in a Word16.
49 
50  Description: Removed qua_gain.tab and qgain475.tab from Include section and
51               added qua_gain_tbl.h and qgain475_tab.h to Include section.
52 
53  Description: Changed round function name to pv_round to avoid conflict with
54               round function in C standard library.
55 
56  Description:  Added casting to eliminate warnings
57 
58  Description:  Replaced "int" and/or "char" with OSCL defined types.
59 
60  Description:
61 
62 ------------------------------------------------------------------------------
63 */
64 
65 
66 /*----------------------------------------------------------------------------
67 ; INCLUDES
68 ----------------------------------------------------------------------------*/
69 
70 #include "dec_gain.h"
71 #include "typedef.h"
72 #include "mode.h"
73 #include "cnst.h"
74 #include "pow2.h"
75 #include "log2.h"
76 #include "gc_pred.h"
77 #include "basic_op.h"
78 #include "qua_gain_tbl.h"
79 #include "qgain475_tab.h"
80 
81 /*----------------------------------------------------------------------------
82 ; MACROS
83 ; Define module specific macros here
84 ----------------------------------------------------------------------------*/
85 
86 
87 /*----------------------------------------------------------------------------
88 ; DEFINES
89 ; Include all pre-processor statements here. Include conditional
90 ; compile variables also.
91 ----------------------------------------------------------------------------*/
92 
93 /*----------------------------------------------------------------------------
94 ; LOCAL FUNCTION DEFINITIONS
95 ; Function Prototype declaration
96 ----------------------------------------------------------------------------*/
97 
98 /*----------------------------------------------------------------------------
99 ; LOCAL VARIABLE DEFINITIONS
100 ; Variable declaration - defined here and used outside this module
101 ----------------------------------------------------------------------------*/
102 
103 /*
104 ------------------------------------------------------------------------------
105  FUNCTION NAME: dec_gain
106 ------------------------------------------------------------------------------
107  INPUT AND OUTPUT DEFINITIONS
108 
109  Inputs:
110     pred_state = pointer to MA predictor state of type gc_predState
111     index = AMR mode of type enum Mode
112     code[] = pointer to innovative vector of type Word16
113     evenSubfr = Flag for even subframes of type Word16
114     pOverflow = pointer to overflow flag
115 
116 
117  Outputs:
118     pred_state = pointer to MA predictor state of type gc_predState
119     gain_pit = pointer to pitch gain of type Word16
120     gain_cod = pointer to code gain of type Word16
121 
122  Returns:
123     None.
124 
125  Global Variables Used:
126     None.
127 
128  Local Variables Needed:
129     None.
130 
131 ------------------------------------------------------------------------------
132  FUNCTION DESCRIPTION
133 
134       File             : dec_gain.c
135       Purpose          : Decode the pitch and codebook gains
136 
137 ------------------------------------------------------------------------------
138  REQUIREMENTS
139 
140  None.
141 
142 ------------------------------------------------------------------------------
143  REFERENCES
144 
145  agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
146 
147 ------------------------------------------------------------------------------
148  PSEUDO-CODE
149 
150 
151 
152 
153 
154 
155 
156 
157 ------------------------------------------------------------------------------
158  RESOURCES USED [optional]
159 
160  When the code is written for a specific target processor the
161  the resources used should be documented below.
162 
163  HEAP MEMORY USED: x bytes
164 
165  STACK MEMORY USED: x bytes
166 
167  CLOCK CYCLES: (cycle count equation for this function) + (variable
168                 used to represent cycle count for each subroutine
169                 called)
170      where: (cycle count variable) = cycle count for [subroutine
171                                      name]
172 
173 ------------------------------------------------------------------------------
174  CAUTION [optional]
175  [State any special notes, constraints or cautions for users of this function]
176 
177 ------------------------------------------------------------------------------
178 */
179 
180 
Dec_gain(gc_predState * pred_state,enum Mode mode,Word16 index,Word16 code[],Word16 evenSubfr,Word16 * gain_pit,Word16 * gain_cod,Flag * pOverflow)181 void Dec_gain(
182     gc_predState *pred_state, /* i/o: MA predictor state           */
183     enum Mode mode,           /* i  : AMR mode                     */
184     Word16 index,             /* i  : index of quantization.       */
185     Word16 code[],            /* i  : Innovative vector.           */
186     Word16 evenSubfr,         /* i  : Flag for even subframes      */
187     Word16 * gain_pit,        /* o  : Pitch gain.                  */
188     Word16 * gain_cod,        /* o  : Code gain.                   */
189     Flag   * pOverflow
190 )
191 {
192     const Word16 *p;
193     Word16 frac;
194     Word16 gcode0;
195     Word16 exp;
196     Word16 qua_ener;
197     Word16 qua_ener_MR122;
198     Word16 g_code;
199     Word32 L_tmp;
200     Word16 temp1;
201     Word16 temp2;
202 
203     /* Read the quantized gains (table depends on mode) */
204     index = shl(index, 2, pOverflow);
205 
206     if (mode == MR102 || mode == MR74 || mode == MR67)
207     {
208         p = &table_gain_highrates[index];
209 
210         *gain_pit = *p++;
211         g_code = *p++;
212         qua_ener_MR122 = *p++;
213         qua_ener = *p;
214     }
215     else
216     {
217         if (mode == MR475)
218         {
219             index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */
220 
221             if (index > (MR475_VQ_SIZE*4 - 2))
222             {
223                 index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */
224             }
225 
226             p = &table_gain_MR475[index];
227 
228             *gain_pit = *p++;
229             g_code = *p++;
230 
231             /*---------------------------------------------------------*
232              *  calculate predictor update values (not stored in 4.75  *
233              *  quantizer table to save space):                        *
234              *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
235              *                                                         *
236              *   qua_ener       = log2(g)                              *
237              *   qua_ener_MR122 = 20*log10(g)                          *
238              *---------------------------------------------------------*/
239 
240             /* Log2(x Q12) = log2(x) + 12 */
241             temp1 = (Word16) L_deposit_l(g_code);
242             Log2(temp1, &exp, &frac, pOverflow);
243             exp = sub(exp, 12, pOverflow);
244 
245             temp1 = shr_r(frac, 5, pOverflow);
246             temp2 = shl(exp, 10, pOverflow);
247             qua_ener_MR122 = add(temp1, temp2, pOverflow);
248 
249             /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
250             L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
251             L_tmp = L_shl(L_tmp, 13, pOverflow);
252             qua_ener = pv_round(L_tmp, pOverflow);
253             /* Q12 * Q0 = Q13 -> Q10 */
254         }
255         else
256         {
257             p = &table_gain_lowrates[index];
258 
259             *gain_pit = *p++;
260             g_code = *p++;
261             qua_ener_MR122 = *p++;
262             qua_ener = *p;
263         }
264     }
265 
266     /*-------------------------------------------------------------------*
267      *  predict codebook gain                                            *
268      *  ~~~~~~~~~~~~~~~~~~~~~                                            *
269      *  gc0     = Pow2(int(d)+frac(d))                                   *
270      *          = 2^exp + 2^frac                                         *
271      *                                                                   *
272      *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
273      *-------------------------------------------------------------------*/
274 
275     gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow);
276 
277     gcode0 = (Word16) Pow2(14, frac, pOverflow);
278 
279     /*------------------------------------------------------------------*
280      *  read quantized gains, update table of past quantized energies   *
281      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
282      *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
283      *                       = Log2(g_fac)                              *
284      *                       = qua_ener                                 *
285      *                                           constant = 20*Log10(2) *
286      *------------------------------------------------------------------*/
287 
288     L_tmp = L_mult(g_code, gcode0, pOverflow);
289     temp1 = sub(10, exp, pOverflow);
290     L_tmp = L_shr(L_tmp, temp1, pOverflow);
291     *gain_cod = extract_h(L_tmp);
292 
293     /* update table of past quantized energies */
294 
295     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
296 
297     return;
298 }
299 
300 
301 
302 
303 
304 
305 
306