Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / dec_gain.cpp
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  Filename: dec_gain.cpp
35  Functions: dec_gain
36
37 ------------------------------------------------------------------------------
38 */
39
40
41 /*----------------------------------------------------------------------------
42 ; INCLUDES
43 ----------------------------------------------------------------------------*/
44
45 #include "dec_gain.h"
46 #include "typedef.h"
47 #include "mode.h"
48 #include "cnst.h"
49 #include "pow2.h"
50 #include "log2.h"
51 #include "gc_pred.h"
52 #include "basic_op.h"
53 #include "qua_gain_tbl.h"
54 #include "qgain475_tab.h"
55
56 /*----------------------------------------------------------------------------
57 ; MACROS
58 ; Define module specific macros here
59 ----------------------------------------------------------------------------*/
60
61
62 /*----------------------------------------------------------------------------
63 ; DEFINES
64 ; Include all pre-processor statements here. Include conditional
65 ; compile variables also.
66 ----------------------------------------------------------------------------*/
67
68 /*----------------------------------------------------------------------------
69 ; LOCAL FUNCTION DEFINITIONS
70 ; Function Prototype declaration
71 ----------------------------------------------------------------------------*/
72
73 /*----------------------------------------------------------------------------
74 ; LOCAL VARIABLE DEFINITIONS
75 ; Variable declaration - defined here and used outside this module
76 ----------------------------------------------------------------------------*/
77
78 /*
79 ------------------------------------------------------------------------------
80  FUNCTION NAME: dec_gain
81 ------------------------------------------------------------------------------
82  INPUT AND OUTPUT DEFINITIONS
83
84  Inputs:
85     pred_state = pointer to MA predictor state of type gc_predState
86     index = AMR mode of type enum Mode
87     code[] = pointer to innovative vector of type Word16
88     evenSubfr = Flag for even subframes of type Word16
89     pOverflow = pointer to overflow flag
90
91
92  Outputs:
93     pred_state = pointer to MA predictor state of type gc_predState
94     gain_pit = pointer to pitch gain of type Word16
95     gain_cod = pointer to code gain of type Word16
96
97  Returns:
98     None.
99
100  Global Variables Used:
101     None.
102
103  Local Variables Needed:
104     None.
105
106 ------------------------------------------------------------------------------
107  FUNCTION DESCRIPTION
108
109       File             : dec_gain.c
110       Purpose          : Decode the pitch and codebook gains
111
112 ------------------------------------------------------------------------------
113  REQUIREMENTS
114
115  None.
116
117 ------------------------------------------------------------------------------
118  REFERENCES
119
120  agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
121
122 ------------------------------------------------------------------------------
123  PSEUDO-CODE
124
125
126
127
128
129
130
131
132 ------------------------------------------------------------------------------
133  CAUTION [optional]
134  [State any special notes, constraints or cautions for users of this function]
135
136 ------------------------------------------------------------------------------
137 */
138
139
140 void Dec_gain(
141     gc_predState *pred_state, /* i/o: MA predictor state           */
142     enum Mode mode,           /* i  : AMR mode                     */
143     Word16 index,             /* i  : index of quantization.       */
144     Word16 code[],            /* i  : Innovative vector.           */
145     Word16 evenSubfr,         /* i  : Flag for even subframes      */
146     Word16 * gain_pit,        /* o  : Pitch gain.                  */
147     Word16 * gain_cod,        /* o  : Code gain.                   */
148     CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbls ptrs */
149     Flag   * pOverflow
150 )
151 {
152     const Word16 *p;
153     Word16 frac;
154     Word16 gcode0;
155     Word16 exp;
156     Word16 qua_ener;
157     Word16 qua_ener_MR122;
158     Word16 g_code;
159     Word32 L_tmp;
160     Word16 temp1;
161     Word16 temp2;
162
163     /* Read the quantized gains (table depends on mode) */
164     index = shl(index, 2, pOverflow);
165
166     if (mode == MR102 || mode == MR74 || mode == MR67)
167     {
168         p = &(common_amr_tbls->table_gain_highrates_ptr[index]);
169
170         *gain_pit = *p++;
171         g_code = *p++;
172         qua_ener_MR122 = *p++;
173         qua_ener = *p;
174     }
175     else
176     {
177         if (mode == MR475)
178         {
179             index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */
180
181             if (index > (MR475_VQ_SIZE*4 - 2))
182             {
183                 index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */
184             }
185
186             p = &table_gain_MR475[index];
187
188             *gain_pit = *p++;
189             g_code = *p++;
190
191             /*---------------------------------------------------------*
192              *  calculate predictor update values (not stored in 4.75  *
193              *  quantizer table to save space):                        *
194              *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
195              *                                                         *
196              *   qua_ener       = log2(g)                              *
197              *   qua_ener_MR122 = 20*log10(g)                          *
198              *---------------------------------------------------------*/
199
200             /* Log2(x Q12) = log2(x) + 12 */
201             temp1 = g_code;
202             Log2(temp1, &exp, &frac, pOverflow);
203             exp -= 12;
204
205             temp1 = shr_r(frac, 5, pOverflow);
206             temp2 = shl(exp, 10, pOverflow);
207             qua_ener_MR122 = add_16(temp1, temp2, pOverflow);
208
209             /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
210             L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
211             L_tmp = L_shl(L_tmp, 13, pOverflow);
212             qua_ener = pv_round(L_tmp, pOverflow);
213             /* Q12 * Q0 = Q13 -> Q10 */
214         }
215         else
216         {
217             p = &(common_amr_tbls->table_gain_lowrates_ptr[index]);
218
219             *gain_pit = *p++;
220             g_code = *p++;
221             qua_ener_MR122 = *p++;
222             qua_ener = *p;
223         }
224     }
225
226     /*-------------------------------------------------------------------*
227      *  predict codebook gain                                            *
228      *  ~~~~~~~~~~~~~~~~~~~~~                                            *
229      *  gc0     = Pow2(int(d)+frac(d))                                   *
230      *          = 2^exp + 2^frac                                         *
231      *                                                                   *
232      *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
233      *-------------------------------------------------------------------*/
234
235     gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow);
236
237     gcode0 = (Word16) Pow2(14, frac, pOverflow);
238
239     /*------------------------------------------------------------------*
240      *  read quantized gains, update table of past quantized energies   *
241      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
242      *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
243      *                       = Log2(g_fac)                              *
244      *                       = qua_ener                                 *
245      *                                           constant = 20*Log10(2) *
246      *------------------------------------------------------------------*/
247
248     L_tmp = L_mult(g_code, gcode0, pOverflow);
249     temp1 = 10 - exp;
250     L_tmp = L_shr(L_tmp, temp1, pOverflow);
251     *gain_cod = (Word16)(L_tmp >> 16);
252
253     /* update table of past quantized energies */
254
255     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
256
257     return;
258 }
259
260
261
262
263
264
265