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