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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
81extern "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
191Word16 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