Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / g_code.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: g_code.cpp
35
36 ------------------------------------------------------------------------------
37 */
38
39 /*----------------------------------------------------------------------------
40 ; INCLUDES
41 ----------------------------------------------------------------------------*/
42 #include    "g_code.h"
43 #include    "cnst.h"
44 #include    "basic_op.h"
45 /*----------------------------------------------------------------------------
46 ; MACROS
47 ; [Define module specific macros here]
48 ----------------------------------------------------------------------------*/
49
50 /*----------------------------------------------------------------------------
51 ; DEFINES
52 ; [Include all pre-processor statements here. Include conditional
53 ; compile variables also.]
54 ----------------------------------------------------------------------------*/
55
56 /*----------------------------------------------------------------------------
57 ; LOCAL FUNCTION DEFINITIONS
58 ; [List function prototypes here]
59 ----------------------------------------------------------------------------*/
60
61 /*----------------------------------------------------------------------------
62 ; LOCAL VARIABLE DEFINITIONS
63 ; [Variable declaration - defined here and used outside this module]
64 ----------------------------------------------------------------------------*/
65
66 /*
67 ------------------------------------------------------------------------------
68  FUNCTION NAME: G_code
69 ------------------------------------------------------------------------------
70  INPUT AND OUTPUT DEFINITIONS
71
72  Inputs:
73     xn2[] = target vector (Word16)
74     y2[] = filtered innovation vector
75     pOverflow = pointer to overflow (Flag)
76
77  Outputs:
78     pOverflow -> 1 if the innovative gain calculation resulted in overflow
79
80  Returns:
81     gain = Gain of Innovation code (Word16)
82
83  Global Variables Used:
84     None
85
86  Local Variables Needed:
87     None
88
89 ------------------------------------------------------------------------------
90  FUNCTION DESCRIPTION
91
92  This function computes the innovative codebook gain.
93
94  The innovative codebook gain is given by
95     g = <x[], y[]> / <y[], y[]>
96
97  where x[] is the target vector, y[] is the filtered innovative codevector,
98  and <> denotes dot product.
99
100 ------------------------------------------------------------------------------
101  REQUIREMENTS
102
103  None
104
105 ------------------------------------------------------------------------------
106  REFERENCES
107
108  [1] g_code.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
109
110 ------------------------------------------------------------------------------
111  PSEUDO-CODE
112
113 Word16 G_code (         // out   : Gain of innovation code
114     Word16 xn2[],       // in    : target vector
115     Word16 y2[]         // in    : filtered innovation vector
116 )
117 {
118     Word16 i;
119     Word16 xy, yy, exp_xy, exp_yy, gain;
120     Word16 scal_y2[L_SUBFR];
121     Word32 s;
122
123 // The original ETSI implementation uses a global overflow flag. However in
124 // actual implementation a pointer to Overflow flag is passed into the
125 // function for access by the low level math functions.
126
127     // Scale down Y[] by 2 to avoid overflow
128
129     for (i = 0; i < L_SUBFR; i++)
130     {
131         scal_y2[i] = shr (y2[i], 1);
132     }
133
134     // Compute scalar product <X[],Y[]>
135
136     s = 1L; // Avoid case of all zeros
137     for (i = 0; i < L_SUBFR; i++)
138     {
139         s = L_mac (s, xn2[i], scal_y2[i]);
140     }
141     exp_xy = norm_l (s);
142     xy = extract_h (L_shl (s, exp_xy));
143
144     // If (xy < 0) gain = 0
145
146     if (xy <= 0)
147         return ((Word16) 0);
148
149     // Compute scalar product <Y[],Y[]>
150
151     s = 0L;
152     for (i = 0; i < L_SUBFR; i++)
153     {
154         s = L_mac (s, scal_y2[i], scal_y2[i]);
155     }
156     exp_yy = norm_l (s);
157     yy = extract_h (L_shl (s, exp_yy));
158
159     // compute gain = xy/yy
160
161     xy = shr (xy, 1);                 // Be sure xy < yy
162     gain = div_s (xy, yy);
163
164     // Denormalization of division
165     i = add (exp_xy, 5);              // 15-1+9-18 = 5
166     i = sub (i, exp_yy);
167
168     gain = shl (shr (gain, i), 1);    // Q0 -> Q1/
169
170     return (gain);
171 }
172
173
174 ------------------------------------------------------------------------------
175  CAUTION [optional]
176  [State any special notes, constraints or cautions for users of this function]
177
178 ------------------------------------------------------------------------------
179 */
180
181 /*----------------------------------------------------------------------------
182 ; FUNCTION CODE
183 ----------------------------------------------------------------------------*/
184 Word16 G_code(          /* o     : Gain of innovation code         */
185     Word16 xn2[],       /* i     : target vector                   */
186     Word16 y2[],        /* i     : filtered innovation vector      */
187     Flag   *pOverflow   /* i/o   : overflow flag                   */
188 )
189 {
190     Word16 i;
191     Word16 xy, yy, exp_xy, exp_yy, gain;
192     Word32 s;
193
194     Word16 *p_xn2 = xn2;
195     Word16 *p_y2  = y2;
196     Word16 temp;
197     Word32 temp2;
198
199     OSCL_UNUSED_ARG(pOverflow);
200
201     /* Compute scalar product <X[],Y[]> */
202     s = 0;
203
204     for (i = (L_SUBFR >> 2); i != 0 ; i--)
205     {
206         temp2 = (Word32)(*(p_y2++) >> 1);
207         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
208         temp2 = (Word32)(*(p_y2++) >> 1);
209         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
210         temp2 = (Word32)(*(p_y2++) >> 1);
211         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
212         temp2 = (Word32)(*(p_y2++) >> 1);
213         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
214     }
215     s <<= 1;
216     exp_xy = norm_l(s + 1); /* Avoid case of all zeros, add 1 */
217
218     if (exp_xy < 17)        /* extra right shift to be sure xy < yy */
219     {
220         xy = (Word16)(s >> (17 - exp_xy));
221     }
222     else
223     {
224         xy = (Word16)(s << (exp_xy - 17));
225     }
226
227     /* If (xy < 0) gain = 0  */
228
229     if (xy <= 0)
230     {
231         return ((Word16) 0);
232     }
233
234     /* Compute scalar product <Y[],Y[]> */
235
236     s = 0L;
237     p_y2  = y2;
238
239     for (i = (L_SUBFR >> 1); i != 0 ; i--)
240     {
241         temp = *(p_y2++) >> 1;
242         s += ((Word32) temp * temp) >> 2;
243         temp = *(p_y2++) >> 1;
244         s += ((Word32) temp * temp) >> 2;
245     }
246     s <<= 3;
247     exp_yy = norm_l(s);
248
249     if (exp_yy < 16)
250     {
251         yy = (Word16)(s >> (16 - exp_yy));
252     }
253     else
254     {
255         yy = (Word16)(s << (exp_yy - 16));
256     }
257
258     gain = div_s(xy, yy);
259
260     /* Denormalization of division */
261     i  = exp_xy + 5;                                /* 15-1+9-18 = 5 */
262     i -= exp_yy;
263
264     // gain = shl (shr (gain, i), 1);    /* Q0 -> Q1 */
265
266     if (i > 1)
267     {
268         gain >>= i - 1;
269     }
270     else
271     {
272         gain <<= 1 - i;
273     }
274
275
276     return (gain);
277 }