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