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