q_gain_p.cpp revision b841f14f8e51f2365945281fbfa54ef6a1b1b5a6
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_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
70extern "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
179Word16 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