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