117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*
217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Copyright 2003-2010, VisualOn, Inc.
317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Licensed under the Apache License, Version 2.0 (the "License");
517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** you may not use this file except in compliance with the License.
617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** You may obtain a copy of the License at
717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **     http://www.apache.org/licenses/LICENSE-2.0
917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
1017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Unless required by applicable law or agreed to in writing, software
1117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** distributed under the License is distributed on an "AS IS" BASIS,
1217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** See the License for the specific language governing permissions and
1417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** limitations under the License.
1517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong */
1617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
1717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/***********************************************************************
1817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  File: az_isp.c
1917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*
2017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  Description:
2117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*-----------------------------------------------------------------------*
2217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* Compute the ISPs from  the LPC coefficients  (order=M)                *
2317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*-----------------------------------------------------------------------*
2417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
2517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* The ISPs are the roots of the two polynomials F1(z) and F2(z)         *
2617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* defined as                                                            *
2717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*               F1(z) = A(z) + z^-m A(z^-1)                             *
2817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  and          F2(z) = A(z) - z^-m A(z^-1)                             *
2917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* For a even order m=2n, F1(z) has M/2 conjugate roots on the unit      *
3117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* circle and F2(z) has M/2-1 conjugate roots on the unit circle in      *
3217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* addition to two roots at 0 and pi.                                    *
3317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* For a 16th order LP analysis, F1(z) and F2(z) can be written as       *
3517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*   F1(z) = (1 + a[M])   PRODUCT  (1 - 2 cos(w_i) z^-1 + z^-2 )         *
3717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                        i=0,2,4,6,8,10,12,14                           *
3817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*   F2(z) = (1 - a[M]) (1 - z^-2) PRODUCT (1 - 2 cos(w_i) z^-1 + z^-2 ) *
4017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                 i=1,3,5,7,9,11,13                     *
4117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
4217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* The ISPs are the M-1 frequencies w_i, i=0...M-2 plus the last         *
4317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* predictor coefficient a[M].                                           *
4417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*-----------------------------------------------------------------------*
4517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong************************************************************************/
4717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "typedef.h"
4917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "basic_op.h"
5017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "oper_32b.h"
5117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "stdio.h"
5217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "grid100.tab"
5317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
5417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define M   16
5517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NC  (M/2)
5617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
5717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/* local function */
5817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n);
5917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
6017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid Az_isp(
6117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 a[],                           /* (i) Q12 : predictor coefficients                 */
6217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 isp[],                         /* (o) Q15 : Immittance spectral pairs              */
6317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 old_isp[]                      /* (i)     : old isp[] (in case not found M roots)  */
6417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	   )
6517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
6617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 i, j, nf, ip, order;
6717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
6817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 x, y, sign, exp;
6917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *coef;
7017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 f1[NC + 1], f2[NC];
7117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 t0;
7217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*-------------------------------------------------------------*
7317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * find the sum and diff polynomials F1(z) and F2(z)           *
7417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *      F1(z) = [A(z) + z^M A(z^-1)]                           *
7517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *      F2(z) = [A(z) - z^M A(z^-1)]/(1-z^-2)                  *
7617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                                                             *
7717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * for (i=0; i<NC; i++)                                        *
7817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * {                                                           *
7917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *   f1[i] = a[i] + a[M-i];                                    *
8017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *   f2[i] = a[i] - a[M-i];                                    *
8117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * }                                                           *
8217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * f1[NC] = 2.0*a[NC];                                         *
8317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                                                             *
8417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * for (i=2; i<NC; i++)            Divide by (1-z^-2)          *
8517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *   f2[i] += f2[i-2];                                         *
8617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *-------------------------------------------------------------*/
8717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NC; i++)
8817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
8917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 = a[i] << 15;
9017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		f1[i] = vo_round(t0 + (a[M - i] << 15));        /* =(a[i]+a[M-i])/2 */
9117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		f2[i] = vo_round(t0 - (a[M - i] << 15));        /* =(a[i]-a[M-i])/2 */
9217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
9317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	f1[NC] = a[NC];
9417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 2; i < NC; i++)               /* Divide by (1-z^-2) */
9517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		f2[i] = add1(f2[i], f2[i - 2]);
9617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
9717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*---------------------------------------------------------------------*
9817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Find the ISPs (roots of F1(z) and F2(z) ) using the                 *
9917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Chebyshev polynomial evaluation.                                    *
10017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * The roots of F1(z) and F2(z) are alternatively searched.            *
10117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * We start by finding the first root of F1(z) then we switch          *
10217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * to F2(z) then back to F1(z) and so on until all roots are found.    *
10317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                                                                     *
10417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *  - Evaluate Chebyshev pol. at grid points and check for sign change.*
10517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *  - If sign change track the root by subdividing the interval        *
10617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *    2 times and ckecking sign change.                                *
10717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *---------------------------------------------------------------------*/
10817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	nf = 0;                                  /* number of found frequencies */
10917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	ip = 0;                                  /* indicator for f1 or f2      */
11017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	coef = f1;
11117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	order = NC;
11217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	xlow = vogrid[0];
11317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	ylow = Chebps2(xlow, coef, order);
11417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	j = 0;
11517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	while ((nf < M - 1) && (j < GRID_POINTS))
11617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
11717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		j ++;
11817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		xhigh = xlow;
11917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		yhigh = ylow;
12017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		xlow = vogrid[j];
12117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ylow = Chebps2(xlow, coef, order);
12217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if ((ylow * yhigh) <= (Word32) 0)
12317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
12417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/* divide 2 times the interval */
12517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < 2; i++)
12617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
12717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				xmid = (xlow >> 1) + (xhigh >> 1);        /* xmid = (xlow + xhigh)/2 */
12817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ymid = Chebps2(xmid, coef, order);
12917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				if ((ylow * ymid) <= (Word32) 0)
13017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				{
13117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					yhigh = ymid;
13217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					xhigh = xmid;
13317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				} else
13417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				{
13517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					ylow = ymid;
13617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					xlow = xmid;
13717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				}
13817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
13917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/*-------------------------------------------------------------*
14017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 * Linear interpolation                                        *
14117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
14217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 *-------------------------------------------------------------*/
14317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			x = xhigh - xlow;
14417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			y = yhigh - ylow;
14517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (y == 0)
14617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
14717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				xint = xlow;
14817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			} else
14917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
15017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				sign = y;
15117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				y = abs_s(y);
15217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				exp = norm_s(y);
15317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				y = y << exp;
15417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				y = div_s((Word16) 16383, y);
15517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				t0 = x * y;
15617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				t0 = (t0 >> (19 - exp));
15717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				y = vo_extract_l(t0);         /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */
15817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				if (sign < 0)
15917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					y = -y;
16017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				t0 = ylow * y;      /* result in Q26 */
16117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				t0 = (t0 >> 10);        /* result in Q15 */
16217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				xint = vo_sub(xlow, vo_extract_l(t0));        /* xint = xlow - ylow*y */
16317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
16417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			isp[nf] = xint;
16517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			xlow = xint;
16617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nf++;
16717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (ip == 0)
16817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
16917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ip = 1;
17017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				coef = f2;
17117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				order = NC - 1;
17217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			} else
17317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
17417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ip = 0;
17517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				coef = f1;
17617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				order = NC;
17717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
17817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ylow = Chebps2(xlow, coef, order);
17917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
18017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
18117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* Check if M-1 roots found */
18217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	if(nf < M - 1)
18317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
18417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (i = 0; i < M; i++)
18517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
18617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			isp[i] = old_isp[i];
18717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
18817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else
18917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
19017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		isp[M - 1] = a[M] << 3;                      /* From Q12 to Q15 with saturation */
19117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
19217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return;
19317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
19417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
19517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*--------------------------------------------------------------*
19617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* function  Chebps2:                                           *
19717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*           ~~~~~~~                                            *
19817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*    Evaluates the Chebishev polynomial series                 *
19917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*--------------------------------------------------------------*
20017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                              *
20117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  The polynomial order is                                     *
20217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*     n = M/2   (M is the prediction order)                    *
20317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  The polynomial is given by                                  *
20417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*    C(x) = f(0)T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
20517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* Arguments:                                                   *
20617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  x:     input value of evaluation; x = cos(frequency) in Q15 *
20717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  f[]:   coefficients of the pol.                      in Q11 *
20817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*  n:     order of the pol.                                    *
20917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                              *
21017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* The value of C(x) is returned. (Satured to +-1.99 in Q14)    *
21117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                              *
21217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*--------------------------------------------------------------*/
21317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
21417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n)
21517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
21617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 i, cheb;
21717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
21817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 t0;
21917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
22017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* Note: All computation are done in Q24. */
22117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
22217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 = f[0] << 13;
22317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	b2_h = t0 >> 16;
22417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	b2_l = (t0 & 0xffff)>>1;
22517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
22617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 = ((b2_h * x)<<1) + (((b2_l * x)>>15)<<1);
22717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 <<= 1;
22817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 += (f[1] << 13);						/* + f[1] in Q24        */
22917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
23017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	b1_h = t0 >> 16;
23117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	b1_l = (t0 & 0xffff) >> 1;
23217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
23317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 2; i < n; i++)
23417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
23517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
23617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
23717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 += (b2_h * (-16384))<<1;
23817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 += (f[i] << 12);
23917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 <<= 1;
24017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		t0 -= (b2_l << 1);					/* t0 = 2.0*x*b1 - b2 + f[i]; */
24117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
24217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b0_h = t0 >> 16;
24317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b0_l = (t0 & 0xffff) >> 1;
24417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
24517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b2_l = b1_l;                         /* b2 = b1; */
24617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b2_h = b1_h;
24717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b1_l = b0_l;                         /* b1 = b0; */
24817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		b1_h = b0_h;
24917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
25017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
25117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
25217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 += (b2_h * (-32768))<<1;				/* t0 = x*b1 - b2          */
25317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 -= (b2_l << 1);
25417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 += (f[n] << 12);						/* t0 = x*b1 - b2 + f[i]/2 */
25517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
25617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	t0 = L_shl2(t0, 6);                     /* Q24 to Q30 with saturation */
25717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
25817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cheb = extract_h(t0);                  /* Result in Q14              */
25917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
26017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	if (cheb == -32768)
26117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
26217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cheb = -32767;                     /* to avoid saturation in Az_isp */
26317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
26417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return (cheb);
26517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
26617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
26717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
26817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
269