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#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
133void 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
201ExitRefl:
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
231void 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