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 Filename: inv_sqrt.cpp
32 ------------------------------------------------------------------------------
35 /*----------------------------------------------------------------------------
37 ----------------------------------------------------------------------------*/
42 /*----------------------------------------------------------------------------
44 ; Define module specific macros here
45 ----------------------------------------------------------------------------*/
48 /*----------------------------------------------------------------------------
50 ; Include all pre-processor statements here. Include conditional
51 ; compile variables also.
52 ----------------------------------------------------------------------------*/
55 /*----------------------------------------------------------------------------
56 ; LOCAL FUNCTION DEFINITIONS
57 ; Function Prototype declaration
58 ----------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------
62 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
63 ; Variable declaration - defined here and used outside this module
64 ----------------------------------------------------------------------------*/
68 ------------------------------------------------------------------------------
69 FUNCTION NAME: Inv_sqrt
70 ------------------------------------------------------------------------------
71 INPUT AND OUTPUT DEFINITIONS
74 L_x = input value (Word32)
75 pOverflow = pointer to overflow flag
78 pOverflow -> if the Inv_sqrt operation resulted in an overflow.
81 L_y = inverse squareroot of L_x (Word32)
83 Global Variables Used:
86 Local Variables Needed:
89 ------------------------------------------------------------------------------
92 This function computes 1/sqrt(L_x), where L_x is positive.
93 If L_x is negative or zero, the result is 1 (3fff ffff).
95 The function 1/sqrt(L_x) is approximated by a table and linear
96 interpolation. The inverse square root is computed using the
98 1- Normalization of L_x.
99 2- If (30-exponent) is even then shift right once.
100 3- exponent = (30-exponent)/2 +1
101 4- i = bit25-b31 of L_x; 16<=i<=63 because of normalization.
104 7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2
107 ------------------------------------------------------------------------------
112 ------------------------------------------------------------------------------
115 inv_sqrt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
117 ------------------------------------------------------------------------------
120 Word32 Inv_sqrt ( // (o) : output value
121 Word32 L_x // (i) : input value
124 Word16 exp, i, a, tmp;
127 * The reference ETSI code uses a global Overflow flag. In the actual
128 * implementation a pointer to the overflow flag is passed into the function.
129 * This pointer is in turn passed into the basic math functions such as add(),
130 * L_shl(), L_shr(), sub() called by this module.
132 if (L_x <= (Word32) 0)
133 return ((Word32) 0x3fffffffL);
136 L_x = L_shl (L_x, exp); // L_x is normalize
140 if ((exp & 1) == 0) // If exponent even -> shift right
142 L_x = L_shr (L_x, 1);
147 L_x = L_shr (L_x, 9);
148 i = extract_h (L_x); // Extract b25-b31
149 L_x = L_shr (L_x, 1);
150 a = extract_l (L_x); // Extract b10-b24
151 a = a & (Word16) 0x7fff;
155 L_y = L_deposit_h (table[i]); // table[i] << 16
156 tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1])
157 L_y = L_msu (L_y, tmp, a); // L_y -= tmp*a*2
159 L_y = L_shr (L_y, exp); // denormalization
164 ------------------------------------------------------------------------------
166 [State any special notes, constraints or cautions for users of this function]
168 ------------------------------------------------------------------------------
171 OSCL_EXPORT_REF Word32 Inv_sqrt( /* (o) : output value */
172 Word32 L_x, /* (i) : input value */
173 Flag * pOverflow /* (i) : pointer to overflow flag */
181 OSCL_UNUSED_ARG(pOverflow);
183 if (L_x <= (Word32) 0)
185 return ((Word32) 0x3fffffffL);
189 L_x <<= exp; /* L_x is normalize */
193 if ((exp & 1) == 0) /* If exponent even -> shift right */
201 i = (Word16)(L_x >> 16); /* Extract b25-b31 */
202 a = (Word16)(L_x >> 1); /* Extract b10-b24 */
203 a &= (Word16) 0x7fff;
207 L_y = (Word32)inv_sqrt_tbl[i] << 16; /* inv_sqrt_tbl[i] << 16 */
209 /* inv_sqrt_tbl[i] - inv_sqrt_tbl[i+1]) */
210 tmp = inv_sqrt_tbl[i] - inv_sqrt_tbl[i + 1];
211 /* always a positive number less than 200 */
213 L_y -= ((Word32)tmp * a) << 1; /* L_y -= tmp*a*2 */
214 /* always a positive minus a small negative number */
216 L_y >>= exp; /* denormalization, exp always 0< exp < 31 */