1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  File: az_isp.c
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  Description:
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*-----------------------------------------------------------------------*
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Compute the ISPs from  the LPC coefficients  (order=M)                *
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*-----------------------------------------------------------------------*
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* The ISPs are the roots of the two polynomials F1(z) and F2(z)         *
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* defined as                                                            *
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*               F1(z) = A(z) + z^-m A(z^-1)                             *
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  and          F2(z) = A(z) - z^-m A(z^-1)                             *
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* For a even order m=2n, F1(z) has M/2 conjugate roots on the unit      *
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* circle and F2(z) has M/2-1 conjugate roots on the unit circle in      *
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* addition to two roots at 0 and pi.                                    *
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* For a 16th order LP analysis, F1(z) and F2(z) can be written as       *
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*   F1(z) = (1 + a[M])   PRODUCT  (1 - 2 cos(w_i) z^-1 + z^-2 )         *
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                        i=0,2,4,6,8,10,12,14                           *
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*   F2(z) = (1 - a[M]) (1 - z^-2) PRODUCT (1 - 2 cos(w_i) z^-1 + z^-2 ) *
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                 i=1,3,5,7,9,11,13                     *
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* The ISPs are the M-1 frequencies w_i, i=0...M-2 plus the last         *
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* predictor coefficient a[M].                                           *
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*-----------------------------------------------------------------------*
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h"
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "stdio.h"
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "grid100.tab"
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define M   16
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NC  (M/2)
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* local function */
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n);
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid Az_isp(
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 a[],                           /* (i) Q12 : predictor coefficients                 */
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isp[],                         /* (o) Q15 : Immittance spectral pairs              */
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 old_isp[]                      /* (i)     : old isp[] (in case not found M roots)  */
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	   )
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j, nf, ip, order;
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 x, y, sign, exp;
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *coef;
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 f1[NC + 1], f2[NC];
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 t0;
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*-------------------------------------------------------------*
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * find the sum and diff polynomials F1(z) and F2(z)           *
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *      F1(z) = [A(z) + z^M A(z^-1)]                           *
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *      F2(z) = [A(z) - z^M A(z^-1)]/(1-z^-2)                  *
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                                                             *
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * for (i=0; i<NC; i++)                                        *
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * {                                                           *
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *   f1[i] = a[i] + a[M-i];                                    *
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *   f2[i] = a[i] - a[M-i];                                    *
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * }                                                           *
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * f1[NC] = 2.0*a[NC];                                         *
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                                                             *
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * for (i=2; i<NC; i++)            Divide by (1-z^-2)          *
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *   f2[i] += f2[i-2];                                         *
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *-------------------------------------------------------------*/
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NC; i++)
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 = a[i] << 15;
90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		f1[i] = vo_round(t0 + (a[M - i] << 15));        /* =(a[i]+a[M-i])/2 */
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		f2[i] = vo_round(t0 - (a[M - i] << 15));        /* =(a[i]-a[M-i])/2 */
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
93b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	f1[NC] = a[NC];
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 2; i < NC; i++)               /* Divide by (1-z^-2) */
95b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		f2[i] = add1(f2[i], f2[i - 2]);
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*---------------------------------------------------------------------*
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Find the ISPs (roots of F1(z) and F2(z) ) using the                 *
99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Chebyshev polynomial evaluation.                                    *
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * The roots of F1(z) and F2(z) are alternatively searched.            *
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * We start by finding the first root of F1(z) then we switch          *
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * to F2(z) then back to F1(z) and so on until all roots are found.    *
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                                                                     *
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *  - Evaluate Chebyshev pol. at grid points and check for sign change.*
105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *  - If sign change track the root by subdividing the interval        *
106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *    2 times and ckecking sign change.                                *
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *---------------------------------------------------------------------*/
108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	nf = 0;                                  /* number of found frequencies */
109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	ip = 0;                                  /* indicator for f1 or f2      */
110b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	coef = f1;
111b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	order = NC;
112b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	xlow = vogrid[0];
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	ylow = Chebps2(xlow, coef, order);
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	j = 0;
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	while ((nf < M - 1) && (j < GRID_POINTS))
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		j ++;
118b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		xhigh = xlow;
119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		yhigh = ylow;
120b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		xlow = vogrid[j];
121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ylow = Chebps2(xlow, coef, order);
122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if ((ylow * yhigh) <= (Word32) 0)
123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* divide 2 times the interval */
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < 2; i++)
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				xmid = (xlow >> 1) + (xhigh >> 1);        /* xmid = (xlow + xhigh)/2 */
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				ymid = Chebps2(xmid, coef, order);
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				if ((ylow * ymid) <= (Word32) 0)
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				{
131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					yhigh = ymid;
132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					xhigh = xmid;
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				} else
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				{
135b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					ylow = ymid;
136b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					xlow = xmid;
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				}
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/*-------------------------------------------------------------*
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 * Linear interpolation                                        *
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 *-------------------------------------------------------------*/
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			x = xhigh - xlow;
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			y = yhigh - ylow;
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (y == 0)
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
147b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				xint = xlow;
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			} else
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sign = y;
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				y = abs_s(y);
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				exp = norm_s(y);
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				y = y << exp;
154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				y = div_s((Word16) 16383, y);
155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				t0 = x * y;
156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				t0 = (t0 >> (19 - exp));
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				y = vo_extract_l(t0);         /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */
158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				if (sign < 0)
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard					y = -y;
160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				t0 = ylow * y;      /* result in Q26 */
161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				t0 = (t0 >> 10);        /* result in Q15 */
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				xint = vo_sub(xlow, vo_extract_l(t0));        /* xint = xlow - ylow*y */
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			isp[nf] = xint;
165b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			xlow = xint;
166b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nf++;
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (ip == 0)
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
169b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ip = 1;
170b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				coef = f2;
171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				order = NC - 1;
172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			} else
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
174b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ip = 0;
175b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				coef = f1;
176b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				order = NC;
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ylow = Chebps2(xlow, coef, order);
179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Check if M-1 roots found */
182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(nf < M - 1)
183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = 0; i < M; i++)
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
186b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			isp[i] = old_isp[i];
187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else
189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		isp[M - 1] = a[M] << 3;                      /* From Q12 to Q15 with saturation */
191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*--------------------------------------------------------------*
196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* function  Chebps2:                                           *
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*           ~~~~~~~                                            *
198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*    Evaluates the Chebishev polynomial series                 *
199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*--------------------------------------------------------------*
200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                              *
201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  The polynomial order is                                     *
202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*     n = M/2   (M is the prediction order)                    *
203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  The polynomial is given by                                  *
204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*    C(x) = f(0)T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Arguments:                                                   *
206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  x:     input value of evaluation; x = cos(frequency) in Q15 *
207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  f[]:   coefficients of the pol.                      in Q11 *
208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  n:     order of the pol.                                    *
209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                              *
210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* The value of C(x) is returned. (Satured to +-1.99 in Q14)    *
211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                              *
212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*--------------------------------------------------------------*/
213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic __inline Word16 Chebps2(Word16 x, Word16 f[], Word32 n)
215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, cheb;
217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 t0;
219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Note: All computation are done in Q24. */
221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 = f[0] << 13;
223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	b2_h = t0 >> 16;
224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	b2_l = (t0 & 0xffff)>>1;
225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 = ((b2_h * x)<<1) + (((b2_l * x)>>15)<<1);
227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 <<= 1;
228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 += (f[1] << 13);						/* + f[1] in Q24        */
229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	b1_h = t0 >> 16;
231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	b1_l = (t0 & 0xffff) >> 1;
232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 2; i < n; i++)
234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 += (b2_h * (-16384))<<1;
238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 += (f[i] << 12);
239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 <<= 1;
240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 -= (b2_l << 1);					/* t0 = 2.0*x*b1 - b2 + f[i]; */
241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		b0_h = t0 >> 16;
243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		b0_l = (t0 & 0xffff) >> 1;
244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
245e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		b2_l = b1_l;                         /* b2 = b1; */
246b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		b2_h = b1_h;
247e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		b1_l = b0_l;                         /* b1 = b0; */
248b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		b1_h = b0_h;
249e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 += (b2_h * (-32768))<<1;				/* t0 = x*b1 - b2          */
253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 -= (b2_l << 1);
254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 += (f[n] << 12);						/* t0 = x*b1 - b2 + f[i]/2 */
255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 = L_shl2(t0, 6);                     /* Q24 to Q30 with saturation */
257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cheb = extract_h(t0);                  /* Result in Q14              */
259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (cheb == -32768)
261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cheb = -32767;                     /* to avoid saturation in Az_isp */
263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (cheb);
265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
269