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_p.c
35  Functions: q_gain_pitch
36 
37      Date: 02/04/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:  Replaced "int" and/or "char" with OSCL defined types.
46 
47  Description: Added #ifdef __cplusplus around extern'ed table.
48 
49  Description:
50 
51 ------------------------------------------------------------------------------
52  MODULE DESCRIPTION
53 
54 
55 ------------------------------------------------------------------------------
56 */
57 
58 /*----------------------------------------------------------------------------
59 ; INCLUDES
60 ----------------------------------------------------------------------------*/
61 #include "q_gain_p.h"
62 #include "typedef.h"
63 #include "oper_32b.h"
64 #include "cnst.h"
65 #include "basic_op.h"
66 
67 
68 /*--------------------------------------------------------------------------*/
69 #ifdef __cplusplus
70 extern "C"
71 {
72 #endif
73 
74     /*----------------------------------------------------------------------------
75     ; MACROS
76     ; Define module specific macros here
77     ----------------------------------------------------------------------------*/
78 
79     /*----------------------------------------------------------------------------
80     ; DEFINES
81     ; Include all pre-processor statements here. Include conditional
82     ; compile variables also.
83     ----------------------------------------------------------------------------*/
84 #define NB_QUA_PITCH 16
85 
86     /*----------------------------------------------------------------------------
87     ; LOCAL FUNCTION DEFINITIONS
88     ; Function Prototype declaration
89     ----------------------------------------------------------------------------*/
90 
91     /*----------------------------------------------------------------------------
92     ; LOCAL VARIABLE DEFINITIONS
93     ; Variable declaration - defined here and used outside this module
94     ----------------------------------------------------------------------------*/
95 
96     /*----------------------------------------------------------------------------
97     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
98     ; Declare variables used in this module but defined elsewhere
99     ----------------------------------------------------------------------------*/
100     extern const Word16 qua_gain_pitch[NB_QUA_PITCH];
101 
102     /*--------------------------------------------------------------------------*/
103 #ifdef __cplusplus
104 }
105 #endif
106 
107 /*
108 ------------------------------------------------------------------------------
109  FUNCTION NAME: q_gain_pitch
110 ------------------------------------------------------------------------------
111  INPUT AND OUTPUT DEFINITIONS
112 
113  Inputs:
114     mode -- enum Mode -- AMR mode
115     gp_limit -- Word16 -- pitch gain limit
116     gain -- Pointer to Word16 -- Pitch gain (unquant/quant),              Q14
117 
118  Outputs:
119     gain -- Pointer to Word16 -- Pitch gain (unquant/quant),              Q14
120 
121     gain_cand -- Array of type Word16 -- pitch gain candidates (3),
122                                          MR795 only, Q14
123 
124     gain_cind -- Array of type Word16 -- pitch gain cand. indices (3),
125                                          MR795 only, Q0
126 
127     pOverflow -- Pointer to Flag -- overflow indicator
128 
129  Returns:
130     Word16 -- index of quantization
131 
132  Global Variables Used:
133     qua_gain_pitch
134 
135  Local Variables Needed:
136     None
137 
138 ------------------------------------------------------------------------------
139  FUNCTION DESCRIPTION
140 
141 
142 ------------------------------------------------------------------------------
143  REQUIREMENTS
144 
145  None
146 
147 ------------------------------------------------------------------------------
148  REFERENCES
149 
150  q_gain_p.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
151 
152 ------------------------------------------------------------------------------
153  PSEUDO-CODE
154 
155 
156 ------------------------------------------------------------------------------
157  RESOURCES USED [optional]
158 
159  When the code is written for a specific target processor the
160  the resources used should be documented below.
161 
162  HEAP MEMORY USED: x bytes
163 
164  STACK MEMORY USED: x bytes
165 
166  CLOCK CYCLES: (cycle count equation for this function) + (variable
167                 used to represent cycle count for each subroutine
168                 called)
169      where: (cycle count variable) = cycle count for [subroutine
170                                      name]
171 
172 ------------------------------------------------------------------------------
173  CAUTION [optional]
174  [State any special notes, constraints or cautions for users of this function]
175 
176 ------------------------------------------------------------------------------
177 */
178 
q_gain_pitch(enum Mode mode,Word16 gp_limit,Word16 * gain,Word16 gain_cand[],Word16 gain_cind[],Flag * pOverflow)179 Word16 q_gain_pitch(    /* Return index of quantization                      */
180     enum Mode mode,     /* i  : AMR mode                                     */
181     Word16 gp_limit,    /* i  : pitch gain limit                             */
182     Word16 *gain,       /* i/o: Pitch gain (unquant/quant),              Q14 */
183     Word16 gain_cand[], /* o  : pitch gain candidates (3),   MR795 only, Q14 */
184     Word16 gain_cind[], /* o  : pitch gain cand. indices (3),MR795 only, Q0  */
185     Flag   *pOverflow
186 )
187 {
188     Word16 i;
189     Word16 index;
190     Word16 err;
191     Word16 err_min;
192 
193     err_min = sub(*gain, qua_gain_pitch[0], pOverflow);
194     err_min = abs_s(err_min);
195 
196     index = 0;
197 
198     for (i = 1; i < NB_QUA_PITCH; i++)
199     {
200         if (qua_gain_pitch[i] <= gp_limit)
201         {
202             err = sub(*gain, qua_gain_pitch[i], pOverflow);
203             err = abs_s(err);
204 
205             if (err < err_min)
206             {
207                 err_min = err;
208                 index = i;
209             }
210         }
211     }
212 
213     if (mode == MR795)
214     {
215         /* in MR795 mode, compute three gain_pit candidates around the index
216          * found in the quantization loop: the index found and the two direct
217          * neighbours, except for the extreme cases (i=0 or i=NB_QUA_PITCH-1),
218          * where the direct neighbour and the neighbour to that is used.
219          */
220         Word16 ii;
221 
222         if (index == 0)
223         {
224             ii = index;
225         }
226         else
227         {
228             if (index == (NB_QUA_PITCH - 1) ||
229                     (qua_gain_pitch[index+1] > gp_limit))
230             {
231                 ii = index - 2;
232             }
233             else
234             {
235                 ii = index - 1;
236             }
237         }
238 
239         /* store candidate indices and values */
240         for (i = 0; i < 3; i++)
241         {
242             gain_cind[i] = ii;
243             gain_cand[i] = qua_gain_pitch[ii];
244 
245             ii = add(ii, 1, pOverflow);
246         }
247 
248         *gain = qua_gain_pitch[index];
249     }
250     else
251     {
252         /* in MR122 mode, just return the index and gain pitch found.
253          * If bitexactness is required, mask away the two LSBs (because
254          * in the original EFR, gain_pit was scaled Q12)
255          */
256         if (mode == MR122)
257         {
258             /* clear 2 LSBits */
259             *gain = qua_gain_pitch[index] & 0xFFFC;
260         }
261         else
262         {
263             *gain = qua_gain_pitch[index];
264         }
265     }
266     return index;
267 }
268