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  Pathname: ./audio/gsm-amr/c/src/log2_norm.c
32 
33 ------------------------------------------------------------------------------
34  REVISION HISTORY
35 
36  Description: Created separate file for Log2_norm function.
37 
38  Description: Synchronized file with UMTS version 3.2.0. Updated coding
39               template. Removed unnecessary include file.
40 
41  Description: Made the following changes per comments from Phase 2/3 review:
42               1. Modified code to improve performance.
43               2. Fixed typecasting issue with TI C compiler.
44               3. Added more comments to the code.
45 
46  Description: Removed unnecessary line of code (line 208).
47 
48  Description: Removed inclusion of "log2.tab"
49 
50  Who:                           Date:
51  Description:
52 
53 ------------------------------------------------------------------------------
54 */
55 
56 /*----------------------------------------------------------------------------
57 ; INCLUDES
58 ----------------------------------------------------------------------------*/
59 #include    "log2_norm.h"
60 
61 /*----------------------------------------------------------------------------
62 ; MACROS
63 ; Define module specific macros here
64 ----------------------------------------------------------------------------*/
65 
66 
67 /*----------------------------------------------------------------------------
68 ; DEFINES
69 ; Include all pre-processor statements here. Include conditional
70 ; compile variables also.
71 ----------------------------------------------------------------------------*/
72 
73 /*----------------------------------------------------------------------------
74 ; LOCAL FUNCTION DEFINITIONS
75 ; Function Prototype declaration
76 ----------------------------------------------------------------------------*/
77 
78 /*----------------------------------------------------------------------------
79 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
80 ; Variable declaration - defined here and used outside this module
81 ----------------------------------------------------------------------------*/
82 
83 
84 /*
85 ------------------------------------------------------------------------------
86  FUNCTION NAME: Log2_norm
87 ------------------------------------------------------------------------------
88  INPUT AND OUTPUT DEFINITIONS
89 
90  Inputs:
91     L_x = normalized input value of type Word32
92     exp = number of shifts required to normalize L_x; it is of type Word16
93     exponent = pointer to the integer part of Log2 (of type Word16)
94            whose valid range is: 0 <= value <= 30
95     fraction = pointer to the fractional part of Log2 (of type Word16)
96            whose valid range is: 0 <= value < 1
97 
98  Outputs:
99     exponent points to the newly calculated integer part of Log2
100     fraction points to the newly calculated fractional part of Log2
101 
102  Returns:
103     None
104 
105  Global Variables Used:
106     None
107 
108  Local Variables Needed:
109     table = Log2 table of constants of type Word16
110 
111 ------------------------------------------------------------------------------
112  FUNCTION DESCRIPTION
113 
114  The function Log2(L_x) calculates the logarithm of the normalized input
115  buffer L_x. The logarithm is approximated by a table and linear
116  interpolation. The following steps are used to compute Log2(L_x):
117 
118  1. exponent = 30 - norm_exponent
119  2. i = bit25-b31 of L_x;  32<=i<=63  (because of normalization).
120  3. a = bit10-b24
121  4. i = i - 32
122  5. fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
123 
124 ------------------------------------------------------------------------------
125  REQUIREMENTS
126 
127  None
128 
129 ------------------------------------------------------------------------------
130  REFERENCES
131 
132  log2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
133 
134 ------------------------------------------------------------------------------
135  PSEUDO-CODE
136 
137 void Log2_norm (
138     Word32 L_x,         // (i) : input value (normalized)
139     Word16 exp,         // (i) : norm_l (L_x)
140     Word16 *exponent,   // (o) : Integer part of Log2.   (range: 0<=val<=30)
141     Word16 *fraction    // (o) : Fractional part of Log2. (range: 0<=val<1)
142 )
143 {
144     Word16 i, a, tmp;
145     Word32 L_y;
146 
147     if (L_x <= (Word32) 0)
148     {
149         *exponent = 0;
150         *fraction = 0;
151         return;
152     }
153 
154     *exponent = sub (30, exp);
155 
156     L_x = L_shr (L_x, 9);
157     i = extract_h (L_x);                // Extract b25-b31
158     L_x = L_shr (L_x, 1);
159     a = extract_l (L_x);                // Extract b10-b24 of fraction
160     a = a & (Word16) 0x7fff;
161 
162     i = sub (i, 32);
163 
164     L_y = L_deposit_h (table[i]);       // table[i] << 16
165     tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1]
166     L_y = L_msu (L_y, tmp, a);          // L_y -= tmp*a*2
167 
168     *fraction = extract_h (L_y);
169 
170     return;
171 }
172 
173 ------------------------------------------------------------------------------
174  RESOURCES USED [optional]
175 
176  When the code is written for a specific target processor the
177  the resources used should be documented below.
178 
179  HEAP MEMORY USED: x bytes
180 
181  STACK MEMORY USED: x bytes
182 
183  CLOCK CYCLES: (cycle count equation for this function) + (variable
184                 used to represent cycle count for each subroutine
185                 called)
186      where: (cycle count variable) = cycle count for [subroutine
187                                      name]
188 
189 ------------------------------------------------------------------------------
190  CAUTION [optional]
191  [State any special notes, constraints or cautions for users of this function]
192 
193 ------------------------------------------------------------------------------
194 */
195 
Log2_norm(Word32 L_x,Word16 exp,Word16 * exponent,Word16 * fraction)196 void Log2_norm(
197     Word32 L_x,         /* (i) : input value (normalized)                   */
198     Word16 exp,         /* (i) : norm_l (L_x)                               */
199     Word16 *exponent,   /* (o) : Integer part of Log2.   (range: 0<=val<=30)*/
200     Word16 *fraction    /* (o) : Fractional part of Log2. (range: 0<=val<1) */
201 )
202 {
203     Word16 i, a, tmp;
204     Word32 L_y;
205 
206     if (L_x <= (Word32) 0)
207     {
208         *exponent = 0;
209         *fraction = 0;
210     }
211     else
212     {
213         /* Calculate exponent portion of Log2 */
214         *exponent = 30 - exp;
215 
216         /* At this point, L_x > 0       */
217         /* Shift L_x to the right by 10 to extract bits 10-31,  */
218         /* which is needed to calculate fractional part of Log2 */
219         L_x >>= 10;
220         i = (Word16)(L_x >> 15);    /* Extract b25-b31 */
221         a = L_x & 0x7fff;           /* Extract b10-b24 of fraction */
222 
223         /* Calculate table index -> subtract by 32 is done for           */
224         /* proper table indexing, since 32<=i<=63 (due to normalization) */
225         i -= 32;
226 
227         /* Fraction part of Log2 is approximated by using table[]    */
228         /* and linear interpolation, i.e.,                           */
229         /* fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 */
230         L_y = (Word32) log2_tbl[i] << 16;  /* table[i] << 16        */
231         tmp = log2_tbl[i] - log2_tbl[i + 1];  /* table[i] - table[i+1] */
232         L_y -= (((Word32) tmp) * a) << 1; /* L_y -= tmp*a*2        */
233 
234         *fraction = (Word16)(L_y >> 16);
235     }
236 
237     return;
238 }
239