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 ----------------------------------------------------------------------------*/
47 /*----------------------------------------------------------------------------
49 ; Define module specific macros here
50 ----------------------------------------------------------------------------*/
53 /*----------------------------------------------------------------------------
55 ; Include all pre-processor statements here. Include conditional
56 ; compile variables also.
57 ----------------------------------------------------------------------------*/
59 /*----------------------------------------------------------------------------
60 ; LOCAL FUNCTION DEFINITIONS
61 ; Function Prototype declaration
62 ----------------------------------------------------------------------------*/
64 /*----------------------------------------------------------------------------
65 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
66 ; Variable declaration - defined here and used outside this module
67 ----------------------------------------------------------------------------*/
71 ------------------------------------------------------------------------------
72 FUNCTION NAME: G_pitch
73 ------------------------------------------------------------------------------
74 INPUT AND OUTPUT DEFINITIONS
77 mode = AMR mode (enum Mode)
78 xn = pointer to pitch target buffer (Word16)
79 y1 = pointer to filtered adaptive codebook buffer (Word16)
80 g_coeff = pointer to buffer of correlations needed for gain quantization
82 L_subfr = length of subframe (Word16)
83 pOverflow = pointer to overflow flag (Flag)
86 g_coeff contains the mantissa and exponent of the two dot products.
87 pOverflow -> 1 if an overflow occurs
90 gain = ratio of dot products.(Word16)
92 Global Variables Used:
95 Local Variables Needed:
98 ------------------------------------------------------------------------------
101 This function computes the pitch (adaptive codebook) gain. The adaptive
102 codebook gain is given by
104 g = <x[], y[]> / <y[], y[]>
106 where: x[] is the target vector
107 y[] is the filtered adaptive codevector
108 <> denotes dot product.
110 The gain is limited to the range [0,1.2] (=0..19661 Q14)
112 ------------------------------------------------------------------------------
117 ------------------------------------------------------------------------------
120 g_pitch.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
122 ------------------------------------------------------------------------------
125 Word16 G_pitch ( // o : Gain of pitch lag saturated to 1.2
126 enum Mode mode, // i : AMR mode
127 Word16 xn[], // i : Pitch target.
128 Word16 y1[], // i : Filtered adaptive codebook.
129 Word16 g_coeff[], // i : Correlations need for gain quantization
130 Word16 L_subfr // i : Length of subframe.
134 Word16 xy, yy, exp_xy, exp_yy, gain;
137 Word16 scaled_y1[L_SUBFR]; // Usually dynamic allocation of (L_subfr)
139 // divide "y1[]" by 4 to avoid overflow
141 // The reference ETSI code uses a global overflow Flag. However in the actual
142 // implementation a pointer to the overflow flag is passed into the function.
144 for (i = 0; i < L_subfr; i++)
146 scaled_y1[i] = shr (y1[i], 2);
149 // Compute scalar product <y1[],y1[]>
151 // Q12 scaling / MR122
153 s = 1L; // Avoid case of all zeros
154 for (i = 0; i < L_subfr; i++)
156 s = L_mac (s, y1[i], y1[i]);
158 if (Overflow == 0) // Test for overflow
161 yy = pv_round (L_shl (s, exp_yy));
165 s = 1L; // Avoid case of all zeros
166 for (i = 0; i < L_subfr; i++)
168 s = L_mac (s, scaled_y1[i], scaled_y1[i]);
171 yy = pv_round (L_shl (s, exp_yy));
172 exp_yy = sub (exp_yy, 4);
175 // Compute scalar product <xn[],y1[]>
178 s = 1L; // Avoid case of all zeros
180 for (i = 0; i < L_subfr; i++)
182 s = L_mac(s, xn[i], y1[i]);
187 xy = pv_round (L_shl (s, exp_xy));
191 s = 1L; // Avoid case of all zeros
192 for (i = 0; i < L_subfr; i++)
194 s = L_mac (s, xn[i], scaled_y1[i]);
197 xy = pv_round (L_shl (s, exp_xy));
198 exp_xy = sub (exp_xy, 2);
202 g_coeff[1] = sub (15, exp_yy);
204 g_coeff[3] = sub (15, exp_xy);
206 // If (xy < 4) gain = 0
213 // compute gain = xy/yy
215 xy = shr (xy, 1); // Be sure xy < yy
216 gain = div_s (xy, yy);
218 i = sub (exp_xy, exp_yy); // Denormalization of division
219 gain = shr (gain, i);
221 // if(gain >1.2) gain = 1.2
223 if (sub (gain, 19661) > 0)
228 if (sub(mode, MR122) == 0)
231 gain = gain & 0xfffC;
237 ------------------------------------------------------------------------------
239 [State any special notes, constraints or cautions for users of this function]
241 ------------------------------------------------------------------------------
244 Word16 G_pitch( /* o : Gain of pitch lag saturated to 1.2 */
245 enum Mode mode, /* i : AMR mode */
246 Word16 xn[], /* i : Pitch target. Q0 */
247 Word16 y1[], /* i : Filtered adaptive codebook. Q12 */
248 Word16 g_coeff[], /* i : Correlations need for gain quantization */
249 Word16 L_subfr, /* i : Length of subframe. */
250 Flag *pOverflow /* i/o : Overflow flag */
263 Word32 L_temp; /* Use this as an intermediate value */
264 Word16 *p_xn = &xn[0];
265 Word16 *p_y1 = &y1[0];
267 /* Compute scalar product <y1[],y1[]> */
269 /* Q12 scaling / MR122 */
273 for (i = L_subfr >> 2; i != 0; i--)
275 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s);
277 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s);
279 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s);
281 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s);
284 if ((s >= 0) & (s < 0x40000000))
287 s += 1; /* Avoid case of all zeros */
289 exp_yy = norm_l(s); /* Note 0<=exp_yy <= 31 */
290 L_temp = s << exp_yy;
291 yy = pv_round(L_temp, pOverflow);
295 s = 0; /* Avoid case of all zeros */
297 for (i = (L_subfr >> 1); i != 0; i--)
299 tmp = *(p_y1++) >> 2;
300 s = amrnb_fxp_mac_16_by_16bb((Word32) tmp, (Word32) tmp, s);
301 tmp = *(p_y1++) >> 2;
302 s = amrnb_fxp_mac_16_by_16bb((Word32) tmp, (Word32) tmp, s);
306 s += 1; /* Avoid case of all zeros */
309 L_temp = s << exp_yy;
310 yy = pv_round(L_temp, pOverflow);
315 /* Compute scalar product <xn[],y1[]> */
321 for (i = L_subfr; i != 0; i--)
323 L_temp = ((Word32) * (p_xn++) * *(p_y1++));
327 if ((s1 ^ L_temp) > 0)
341 s += 1; /* Avoid case of all zeros */
343 exp_xy = norm_l(s); /* Note 0<=exp_yy <= 31 */
344 L_temp = s << exp_xy;
345 xy = pv_round(L_temp, pOverflow);
349 s = 0; /* re-initialize calculations */
353 for (i = (L_subfr >> 2); i != 0; i--)
355 L_temp = (Word32)(*(p_y1++) >> 2);
356 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s);
357 L_temp = (Word32)(*(p_y1++) >> 2);
358 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s);
359 L_temp = (Word32)(*(p_y1++) >> 2);
360 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s);
361 L_temp = (Word32)(*(p_y1++) >> 2);
362 s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s);
366 s += 1; /* Avoid case of all zeros */
369 L_temp = s << exp_xy;
370 xy = pv_round(L_temp, pOverflow);
376 g_coeff[1] = 15 - exp_yy;
378 g_coeff[3] = 15 - exp_xy;
380 /* If (xy < 4) gain = 0 */
386 /* compute gain = xy/yy */
387 /* Be sure xy < yy */
391 gain = div_s(xy, yy);
393 i = exp_xy - exp_yy; /* Denormalization of division */
395 gain = shr(gain, i, pOverflow);
398 /* if(gain >1.2) gain = 1.2 */
407 gain = gain & 0xfffC;