Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / common / src / inv_sqrt.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  Filename: inv_sqrt.cpp
31
32 ------------------------------------------------------------------------------
33 */
34
35 /*----------------------------------------------------------------------------
36 ; INCLUDES
37 ----------------------------------------------------------------------------*/
38 #include    "inv_sqrt.h"
39 #include    "typedef.h"
40 #include    "basic_op.h"
41
42 /*----------------------------------------------------------------------------
43 ; MACROS
44 ; Define module specific macros here
45 ----------------------------------------------------------------------------*/
46
47
48 /*----------------------------------------------------------------------------
49 ; DEFINES
50 ; Include all pre-processor statements here. Include conditional
51 ; compile variables also.
52 ----------------------------------------------------------------------------*/
53
54
55 /*----------------------------------------------------------------------------
56 ; LOCAL FUNCTION DEFINITIONS
57 ; Function Prototype declaration
58 ----------------------------------------------------------------------------*/
59
60
61 /*----------------------------------------------------------------------------
62 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
63 ; Variable declaration - defined here and used outside this module
64 ----------------------------------------------------------------------------*/
65
66
67 /*
68 ------------------------------------------------------------------------------
69  FUNCTION NAME: Inv_sqrt
70 ------------------------------------------------------------------------------
71  INPUT AND OUTPUT DEFINITIONS
72
73  Inputs:
74     L_x = input value (Word32)
75     pOverflow = pointer to overflow flag
76
77  Outputs:
78     pOverflow -> if the Inv_sqrt operation resulted in an overflow.
79
80  Returns:
81     L_y = inverse squareroot of L_x (Word32)
82
83  Global Variables Used:
84     None.
85
86  Local Variables Needed:
87     None.
88
89 ------------------------------------------------------------------------------
90  FUNCTION DESCRIPTION
91
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).
94
95  The function 1/sqrt(L_x) is approximated by a table and linear
96  interpolation. The inverse square root is computed using the
97  following steps:
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.
102     5- a = bit10-b24
103     6- i -=16
104     7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2
105     8- L_y >>= exponent
106
107 ------------------------------------------------------------------------------
108  REQUIREMENTS
109
110  None.
111
112 ------------------------------------------------------------------------------
113  REFERENCES
114
115  inv_sqrt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
116
117 ------------------------------------------------------------------------------
118  PSEUDO-CODE
119
120 Word32 Inv_sqrt (       // (o) : output value
121     Word32 L_x          // (i) : input value
122 )
123 {
124     Word16 exp, i, a, tmp;
125     Word32 L_y;
126
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.
131
132     if (L_x <= (Word32) 0)
133         return ((Word32) 0x3fffffffL);
134
135     exp = norm_l (L_x);
136     L_x = L_shl (L_x, exp);     // L_x is normalize
137
138     exp = sub (30, exp);
139
140     if ((exp & 1) == 0)         // If exponent even -> shift right
141     {
142         L_x = L_shr (L_x, 1);
143     }
144     exp = shr (exp, 1);
145     exp = add (exp, 1);
146
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;
152
153     i = sub (i, 16);
154
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
158
159     L_y = L_shr (L_y, exp);     // denormalization
160
161     return (L_y);
162 }
163
164 ------------------------------------------------------------------------------
165  CAUTION [optional]
166  [State any special notes, constraints or cautions for users of this function]
167
168 ------------------------------------------------------------------------------
169 */
170
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 */
174 )
175 {
176     Word16 exp;
177     Word16 i;
178     Word16 a;
179     Word16 tmp;
180     Word32 L_y;
181     OSCL_UNUSED_ARG(pOverflow);
182
183     if (L_x <= (Word32) 0)
184     {
185         return ((Word32) 0x3fffffffL);
186     }
187
188     exp = norm_l(L_x);
189     L_x <<= exp;         /* L_x is normalize */
190
191     exp = 30 - exp;
192
193     if ((exp & 1) == 0)             /* If exponent even -> shift right */
194     {
195         L_x >>= 1;
196     }
197     exp >>= 1;
198     exp += 1;
199
200     L_x >>= 9;
201     i = (Word16)(L_x >> 16);        /* Extract b25-b31 */
202     a = (Word16)(L_x >> 1);         /* Extract b10-b24 */
203     a &= (Word16) 0x7fff;
204
205     i -= 16;
206
207     L_y = (Word32)inv_sqrt_tbl[i] << 16;    /* inv_sqrt_tbl[i] << 16    */
208
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 */
212
213     L_y -= ((Word32)tmp * a) << 1;        /* L_y -=  tmp*a*2         */
214     /* always a positive minus a small negative number */
215
216     L_y >>= exp;                /* denormalization, exp always 0< exp < 31 */
217
218     return (L_y);
219 }
220