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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
134void 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
202ExitRefl:
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
232void 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