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 
32 
33 
34  Filename:  /audio/gsm-amr/c/src/a_refl.c
35  Functions: a_refl
36 
37      Date: 02/05/2002
38 
39 ------------------------------------------------------------------------------
40  REVISION HISTORY
41 
42  Description: Removing unneeded include files and the goto statement.
43 
44 
45  Description: Changed function name to pv_round to avoid conflict with
46               round function in C standard library.
47 
48  Description:  Replaced "int" and/or "char" with OSCL defined types.
49 
50  Description:  Using inline functions from basic_op.h .
51                Removing unneeded include files.
52 
53  Description:
54 
55 ------------------------------------------------------------------------------
56 */
57 
58 
59 /*----------------------------------------------------------------------------
60 ; INCLUDES
61 ----------------------------------------------------------------------------*/
62 #define LOG_TAG "a_refl"
63 #include <log/log.h>
64 
65 #include "a_refl.h"
66 #include "typedef.h"
67 #include "cnst.h"
68 #include "basic_op.h"
69 
70 /*----------------------------------------------------------------------------
71 ; MACROS [optional]
72 ; [Define module specific macros here]
73 ----------------------------------------------------------------------------*/
74 
75 /*----------------------------------------------------------------------------
76 ; DEFINES [optional]
77 ; [Include all pre-processor statements here. Include conditional
78 ; compile variables also.]
79 ----------------------------------------------------------------------------*/
80 
81 /*----------------------------------------------------------------------------
82 ; LOCAL FUNCTION DEFINITIONS
83 ; [List function prototypes here]
84 ----------------------------------------------------------------------------*/
85 
86 /*----------------------------------------------------------------------------
87 ; LOCAL VARIABLE DEFINITIONS
88 ; [Variable declaration - defined here and used outside this module]
89 ----------------------------------------------------------------------------*/
90 
91 /*
92 ------------------------------------------------------------------------------
93  FUNCTION NAME: AMREncode
94 ------------------------------------------------------------------------------
95  INPUT AND OUTPUT DEFINITIONS
96 
97  Inputs:
98     a[] = pointer to directform coefficients of type Word16
99     refl[] = pointer to reflection coefficients of type Word16
100 
101  Outputs:
102     pOverflow = 1 if overflow exists in the math operations else zero.
103 
104  Returns:
105     None
106 
107  Global Variables Used:
108     None
109 
110  Local Variables Needed:
111     None
112 
113 ------------------------------------------------------------------------------
114  FUNCTION DESCRIPTION
115 
116      File             : a_refl.c
117      Purpose          : Convert from direct form coefficients to
118                         reflection coefficients
119 
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122 
123  None
124 
125 ------------------------------------------------------------------------------
126  REFERENCES
127 
128  [1] a_refl.c , 3GPP TS 26.101 version 4.1.0 Release 4, June 2001
129 
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132 
133 
134 void A_Refl(
135    Word16 a[],        // i   : Directform coefficients
136    Word16 refl[]      // o   : Reflection coefficients
137 )
138 {
139    // local variables
140    Word16 i,j;
141    Word16 aState[M];
142    Word16 bState[M];
143    Word16 normShift;
144    Word16 normProd;
145    Word32 L_acc;
146    Word16 scale;
147    Word32 L_temp;
148    Word16 temp;
149    Word16 mult;
150 
151    // initialize states
152    for (i = 0; i < M; i++)
153    {
154       aState[i] = a[i];
155    }
156 
157    // backward Levinson recursion
158    for (i = M-1; i >= 0; i--)
159    {
160       if (sub(abs_s(aState[i]), 4096) >= 0)
161       {
162          goto ExitRefl;
163       }
164 
165       refl[i] = shl(aState[i], 3);
166 
167       L_temp = L_mult(refl[i], refl[i]);
168       L_acc = L_sub(MAX_32, L_temp);
169 
170       normShift = norm_l(L_acc);
171       scale = sub(15, normShift);
172 
173       L_acc = L_shl(L_acc, normShift);
174       normProd = pv_round(L_acc);
175 
176       mult = div_s(16384, normProd);
177 
178       for (j = 0; j < i; j++)
179       {
180          L_acc = L_deposit_h(aState[j]);
181          L_acc = L_msu(L_acc, refl[i], aState[i-j-1]);
182 
183          temp = pv_round(L_acc);
184          L_temp = L_mult(mult, temp);
185          L_temp = L_shr_r(L_temp, scale);
186 
187          if (L_sub(L_abs(L_temp), 32767) > 0)
188          {
189             goto ExitRefl;
190          }
191 
192          bState[j] = extract_l(L_temp);
193       }
194 
195       for (j = 0; j < i; j++)
196       {
197          aState[j] = bState[j];
198       }
199    }
200    return;
201 
202 ExitRefl:
203    for (i = 0; i < M; i++)
204    {
205       refl[i] = 0;
206    }
207 }
208 
209 ------------------------------------------------------------------------------
210  RESOURCES USED [optional]
211 
212  When the code is written for a specific target processor the
213  the resources used should be documented below.
214 
215  HEAP MEMORY USED: x bytes
216 
217  STACK MEMORY USED: x bytes
218 
219  CLOCK CYCLES: (cycle count equation for this function) + (variable
220                 used to represent cycle count for each subroutine
221                 called)
222      where: (cycle count variable) = cycle count for [subroutine
223                                      name]
224 
225 ------------------------------------------------------------------------------
226  CAUTION [optional]
227  [State any special notes, constraints or cautions for users of this function]
228 
229 ------------------------------------------------------------------------------
230 */
231 
A_Refl(Word16 a[],Word16 refl[],Flag * pOverflow)232 void A_Refl(
233     Word16 a[],        /* i   : Directform coefficients */
234     Word16 refl[],     /* o   : Reflection coefficients */
235     Flag   *pOverflow
236 )
237 {
238     /* local variables */
239     Word16 i;
240     Word16 j;
241     Word16 aState[M];
242     Word16 bState[M];
243     Word16 normShift;
244     Word16 normProd;
245     Word32 L_acc;
246     Word16 scale;
247     Word32 L_temp;
248     Word16 temp;
249     Word16 mult;
250 
251     /* initialize states */
252     for (i = 0; i < M; i++)
253     {
254         aState[i] = a[i];
255     }
256 
257     /* backward Levinson recursion */
258     for (i = M - 1; i >= 0; i--)
259     {
260         if (abs_s(aState[i]) >= 4096)
261         {
262             for (i = 0; i < M; i++)
263             {
264                 refl[i] = 0;
265             }
266             break;
267         }
268 
269         refl[i] = shl(aState[i], 3, pOverflow);
270 
271         L_temp = L_mult(refl[i], refl[i], pOverflow);
272         L_acc = L_sub(MAX_32, L_temp, pOverflow);
273 
274         normShift = norm_l(L_acc);
275         scale = sub(15, normShift, pOverflow);
276 
277         L_acc = L_shl(L_acc, normShift, pOverflow);
278         normProd = pv_round(L_acc, pOverflow);
279 
280         mult = div_s(16384, normProd);
281 
282         for (j = 0; j < i; j++)
283         {
284             L_acc = L_deposit_h(aState[j]);
285             L_acc = L_msu(L_acc, refl[i], aState[i-j-1], pOverflow);
286 
287             temp = pv_round(L_acc, pOverflow);
288             L_temp = L_mult(mult, temp, pOverflow);
289             L_temp = L_shr_r(L_temp, scale, pOverflow);
290 
291             if (L_abs(L_temp) > 32767)
292             {
293                 for (i = 0; i < M; i++)
294                 {
295                     refl[i] = 0;
296                 }
297                 ALOGE("b/23609206");
298                 return;
299             }
300 
301             bState[j] = extract_l(L_temp);
302         }
303 
304         for (j = 0; j < i; j++)
305         {
306             aState[j] = bState[j];
307         }
308     }
309     return;
310 }
311 
312 
313 
314 
315 
316 
317 
318