1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
36 ------------------------------------------------------------------------------
39 /*----------------------------------------------------------------------------
41 ----------------------------------------------------------------------------*/
45 /*----------------------------------------------------------------------------
47 ; [Define module specific macros here]
48 ----------------------------------------------------------------------------*/
50 /*----------------------------------------------------------------------------
52 ; [Include all pre-processor statements here. Include conditional
53 ; compile variables also.]
54 ----------------------------------------------------------------------------*/
56 /*----------------------------------------------------------------------------
57 ; LOCAL FUNCTION DEFINITIONS
58 ; [List function prototypes here]
59 ----------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------
62 ; LOCAL VARIABLE DEFINITIONS
63 ; [Variable declaration - defined here and used outside this module]
64 ----------------------------------------------------------------------------*/
67 ------------------------------------------------------------------------------
69 ------------------------------------------------------------------------------
70 INPUT AND OUTPUT DEFINITIONS
73 xn2[] = target vector (Word16)
74 y2[] = filtered innovation vector
75 pOverflow = pointer to overflow (Flag)
78 pOverflow -> 1 if the innovative gain calculation resulted in overflow
81 gain = Gain of Innovation code (Word16)
83 Global Variables Used:
86 Local Variables Needed:
89 ------------------------------------------------------------------------------
92 This function computes the innovative codebook gain.
94 The innovative codebook gain is given by
95 g = <x[], y[]> / <y[], y[]>
97 where x[] is the target vector, y[] is the filtered innovative codevector,
98 and <> denotes dot product.
100 ------------------------------------------------------------------------------
105 ------------------------------------------------------------------------------
108 [1] g_code.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
110 ------------------------------------------------------------------------------
113 Word16 G_code ( // out : Gain of innovation code
114 Word16 xn2[], // in : target vector
115 Word16 y2[] // in : filtered innovation vector
119 Word16 xy, yy, exp_xy, exp_yy, gain;
120 Word16 scal_y2[L_SUBFR];
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.
127 // Scale down Y[] by 2 to avoid overflow
129 for (i = 0; i < L_SUBFR; i++)
131 scal_y2[i] = shr (y2[i], 1);
134 // Compute scalar product <X[],Y[]>
136 s = 1L; // Avoid case of all zeros
137 for (i = 0; i < L_SUBFR; i++)
139 s = L_mac (s, xn2[i], scal_y2[i]);
142 xy = extract_h (L_shl (s, exp_xy));
144 // If (xy < 0) gain = 0
149 // Compute scalar product <Y[],Y[]>
152 for (i = 0; i < L_SUBFR; i++)
154 s = L_mac (s, scal_y2[i], scal_y2[i]);
157 yy = extract_h (L_shl (s, exp_yy));
159 // compute gain = xy/yy
161 xy = shr (xy, 1); // Be sure xy < yy
162 gain = div_s (xy, yy);
164 // Denormalization of division
165 i = add (exp_xy, 5); // 15-1+9-18 = 5
168 gain = shl (shr (gain, i), 1); // Q0 -> Q1/
174 ------------------------------------------------------------------------------
176 [State any special notes, constraints or cautions for users of this function]
178 ------------------------------------------------------------------------------
181 /*----------------------------------------------------------------------------
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 */
191 Word16 xy, yy, exp_xy, exp_yy, gain;
199 OSCL_UNUSED_ARG(pOverflow);
201 /* Compute scalar product <X[],Y[]> */
204 for (i = (L_SUBFR >> 2); i != 0 ; i--)
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);
216 exp_xy = norm_l(s + 1); /* Avoid case of all zeros, add 1 */
218 if (exp_xy < 17) /* extra right shift to be sure xy < yy */
220 xy = (Word16)(s >> (17 - exp_xy));
224 xy = (Word16)(s << (exp_xy - 17));
227 /* If (xy < 0) gain = 0 */
234 /* Compute scalar product <Y[],Y[]> */
239 for (i = (L_SUBFR >> 1); i != 0 ; i--)
241 temp = *(p_y2++) >> 1;
242 s += ((Word32) temp * temp) >> 2;
243 temp = *(p_y2++) >> 1;
244 s += ((Word32) temp * temp) >> 2;
251 yy = (Word16)(s >> (16 - exp_yy));
255 yy = (Word16)(s << (exp_yy - 16));
258 gain = div_s(xy, yy);
260 /* Denormalization of division */
261 i = exp_xy + 5; /* 15-1+9-18 = 5 */
264 // gain = shl (shr (gain, i), 1); /* Q0 -> Q1 */