lsp.c revision 98913fed6520d8849fb2e246be943e04474aefa
198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*---------------------------------------------------------------------------*\ 298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectOriginal copyright 398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project FILE........: lsp.c 498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AUTHOR......: David Rowe 598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project DATE CREATED: 24/2/93 698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectHeavily modified by Jean-Marc Valin (c) 2002-2006 (fixed-point, 898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project optimizations, additional functions, ...) 998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project This file contains functions for converting Linear Prediction 1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the 1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LSP coefficients are not in radians format but in the x domain of the 1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unit circle. 1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Speex License: 1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Redistribution and use in source and binary forms, with or without 1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project modification, are permitted provided that the following conditions 1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project are met: 2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Redistributions of source code must retain the above copyright 2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project notice, this list of conditions and the following disclaimer. 2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Redistributions in binary form must reproduce the above copyright 2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project notice, this list of conditions and the following disclaimer in the 2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project documentation and/or other materials provided with the distribution. 2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Neither the name of the Xiph.org Foundation nor the names of its 2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project contributors may be used to endorse or promote products derived from 3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project this software without specific prior written permission. 3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*---------------------------------------------------------------------------*\ 4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Introduction to Line Spectrum Pairs (LSPs) 4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ------------------------------------------ 4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LSPs are used to encode the LPC filter coefficients {ak} for 5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project transmission over the channel. LSPs have several properties (like 5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project less sensitivity to quantisation noise) that make them superior to 5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project direct quantisation of {ak}. 5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A(z) is a polynomial of order lpcrdr with {ak} as the coefficients. 5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A(z) is transformed to P(z) and Q(z) (using a substitution and some 5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project algebra), to obtain something like: 5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1) 6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project As you can imagine A(z) has complex zeros all over the z-plane. P(z) 6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project and Q(z) have the very neat property of only having zeros _on_ the 6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unit circle. So to find them we take a test point z=exp(jw) and 6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0 6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project and pi. 6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project The zeros (roots) of P(z) also happen to alternate, which is why we 6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project swap coefficients as we find roots. So the process of finding the 7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LSP frequencies is basically finding the roots of 5th order 7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project polynomials. 7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence 7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project the name Line Spectrum Pairs (LSPs). 7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project To convert back to ak we just evaluate (1), "clocking" an impulse 7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project thru it lpcrdr times gives us the impulse response of A(z) which is 7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {ak}. 7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project\*---------------------------------------------------------------------------*/ 8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef HAVE_CONFIG_H 8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "config.h" 8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <math.h> 8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lsp.h" 8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "stack_alloc.h" 8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h" 9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef M_PI 9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define M_PI 3.14159265358979323846 /* pi */ 9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NULL 9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NULL 0 9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FREQ_SCALE 16384 10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/ 10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define ANGLE2X(a) (SHL16(spx_cos(a),2)) 10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/ 10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define X2ANGLE(x) (spx_acos(x)) 10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef BFIN_ASM 11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "lsp_bfin.h" 11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*#define C1 0.99940307 11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define C2 -0.49558072 11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define C3 0.03679168*/ 11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define FREQ_SCALE 1. 12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define ANGLE2X(a) (spx_cos(a)) 12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define X2ANGLE(x) (acos(x)) 12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*---------------------------------------------------------------------------*\ 12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project FUNCTION....: cheb_poly_eva() 12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AUTHOR......: David Rowe 13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project DATE CREATED: 24/2/93 13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project This function evaluates a series of Chebyshev polynomials 13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project\*---------------------------------------------------------------------------*/ 13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_CHEB_POLY_EVA 14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word32_t cheb_poly_eva( 14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *coef, /* P or Q coefs in Q13 format */ 14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */ 14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int m, /* LPC order/2 */ 14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project char *stack 14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t b0, b1; 14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum; 15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*Prevents overflows*/ 15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (x>16383) 15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x = 16383; 15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (x<-16383) 15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x = -16383; 15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Initialise values */ 15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b1=16384; 15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b0=x; 16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Evaluate Chebyshev series formulation usin g iterative approach */ 16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x))); 16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=2;i<=m;i++) 16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp=b0; 16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b0 = SUB16(MULT16_16_Q13(x,b0), b1); 16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b1 = tmp; 16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0))); 16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return sum; 17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic float cheb_poly_eva(spx_word32_t *coef, spx_word16_t x, int m, char *stack) 17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int k; 18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float b0, b1, tmp; 18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Initial conditions */ 18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b0=0; /* b_(m+1) */ 18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b1=0; /* b_(m+2) */ 18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x*=2; 18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Calculate the b_(k) */ 18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(k=m;k>0;k--) 19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp=b0; /* tmp holds the previous value of b0 */ 19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b0=x*b0-b1+coef[m-k]; /* b0 holds its new value based on b0 and b1 */ 19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project b1=tmp; /* b1 holds the previous value of b0 */ 19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return(-b1+.5*x*b0+coef[m]); 19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*---------------------------------------------------------------------------*\ 20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project FUNCTION....: lpc_to_lsp() 20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AUTHOR......: David Rowe 20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project DATE CREATED: 24/2/93 20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project This function converts LPC coefficients to LSP 20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project coefficients. 20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project\*---------------------------------------------------------------------------*/ 21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0)) 21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define SIGN_CHANGE(a,b) (((a)*(b))<0.0) 21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack) 22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *a lpc coefficients */ 22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* int lpcrdr order of LPC coefficients (10) */ 22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *freq LSP frequencies in the x domain */ 22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* int nb number of sub-intervals (4) */ 22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float delta grid spacing interval (0.02) */ 22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t temp_xr,xl,xr,xm=0; 22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/; 23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j,m,flag,k; 23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *Q); /* ptrs for memory allocation */ 23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *P); 23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *Q16); /* ptrs for memory allocation */ 23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *P16); 23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *px; /* ptrs of respective P'(z) & Q'(z) */ 23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *qx; 23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *p; 23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *q; 23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *pt; /* ptr used for cheb_poly_eval() 24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project whether P' or Q' */ 24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int roots=0; /* DR 8/2/94: number of roots found */ 24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project flag = 1; /* program is searching for a root when, 24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1 else has found one */ 24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */ 24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Allocate memory space for polynomials */ 24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(Q, (m+1), spx_word32_t); 24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(P, (m+1), spx_word32_t); 24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* determine P'(z)'s and Q'(z)'s coefficients where 25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ 25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px = P; /* initialise ptrs */ 25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx = Q; 25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project p = px; 25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project q = qx; 25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px++ = LPC_SCALING; 26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx++ = LPC_SCALING; 26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<m;i++){ 26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *p++); 26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *q++); 26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px = P; 26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx = Q; 26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<m;i++) 26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*if (fabs(*px)>=32768) 27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_warning_int("px", *px); 27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (fabs(*qx)>=32768) 27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_warning_int("qx", *qx);*/ 27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px = PSHR32(*px,2); 27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx = PSHR32(*qx,2); 27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px++; 27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx++; 27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */ 27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project P[m] = PSHR32(P[m],3); 28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Q[m] = PSHR32(Q[m],3); 28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px++ = LPC_SCALING; 28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx++ = LPC_SCALING; 28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<m;i++){ 28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px++ = (a[i]+a[lpcrdr-1-i]) - *p++; 28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx++ = (a[i]-a[lpcrdr-1-i]) + *q++; 28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px = P; 28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx = Q; 29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<m;i++){ 29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *px = 2**px; 29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *qx = 2**qx; 29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px++; 29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx++; 29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project px = P; /* re-initialise ptrs */ 29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project qx = Q; 30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* now that we have computed P and Q convert to 16 bits to 30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speed up cheb_poly_eval */ 30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(P16, m+1, spx_word16_t); 30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(Q16, m+1, spx_word16_t); 30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<m+1;i++) 30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project P16[i] = P[i]; 31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Q16[i] = Q[i]; 31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). 31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Keep alternating between the two polynomials as each zero is found */ 31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xr = 0; /* initialise xr to zero */ 31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xl = FREQ_SCALE; /* start at point xl = 1 */ 31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(j=0;j<lpcrdr;j++){ 32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if(j&1) /* determines whether P' or Q' is eval. */ 32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pt = Q16; 32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pt = P16; 32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psuml = cheb_poly_eva(pt,xl,m,stack); /* evals poly. at xl */ 32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project flag = 1; 32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project while(flag && (xr >= -FREQ_SCALE)){ 32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t dd; 32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Modified by JMV to provide smaller steps around x=+-1 */ 33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000))); 33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (psuml<512 && psuml>-512) 33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project dd = PSHR16(dd,1); 33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project dd=delta*(1-.9*xl*xl); 33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (fabs(psuml)<.2) 33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project dd *= .5; 33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xr = SUB16(xl, dd); /* interval spacing */ 34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psumr = cheb_poly_eva(pt,xr,m,stack);/* poly(xl-delta_x) */ 34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project temp_psumr = psumr; 34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project temp_xr = xr; 34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* if no sign change increment xr and re-evaluate poly(xr). Repeat til 34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sign change. 34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if a sign change has occurred the interval is bisected and then 34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project checked again for a sign change which determines in which 34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interval the zero lies in. 34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project If there is no sign change between poly(xm) and poly(xl) set interval 35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project between xm and xr else set interval between xl and xr and repeat till 35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project root is located within the specified limits */ 35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if(SIGN_CHANGE(psumr,psuml)) 35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project roots++; 35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psumm=psuml; 35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(k=0;k<=nb;k++){ 35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xm = ADD16(PSHR16(xl,1),PSHR16(xr,1)); /* bisect the interval */ 36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xm = .5*(xl+xr); /* bisect the interval */ 36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psumm=cheb_poly_eva(pt,xm,m,stack); 36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*if(psumm*psuml>0.)*/ 36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if(!SIGN_CHANGE(psumm,psuml)) 36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psuml=psumm; 36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xl=xm; 37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psumr=psumm; 37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xr=xm; 37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* once zero is found, reset initial interval to xr */ 37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project freq[j] = X2ANGLE(xm); 37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xl = xm; 37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project flag = 0; /* reset flag for next search */ 38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else{ 38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project psuml=temp_psumr; 38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xl=temp_xr; 38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return(roots); 38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*---------------------------------------------------------------------------*\ 39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project FUNCTION....: lsp_to_lpc() 39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AUTHOR......: David Rowe 39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project DATE CREATED: 24/2/93 39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Converts LSP coefficients to LPC coefficients. 39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project\*---------------------------------------------------------------------------*/ 40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack) 40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *freq array of LSP frequencies in the x domain */ 40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *ak array of LPC coefficients */ 40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* int lpcrdr order of LPC coefficients */ 40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t xout1,xout2,xin; 41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t mult, a; 41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *freqn); 41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t **xp); 41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *xpmem); 41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t **xq); 41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *xqmem); 41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int m = lpcrdr>>1; 41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* 41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Reconstruct P(z) and Q(z) by cascading second order polynomials 42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency. 42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project In the time domain this is: 42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y(n) = x(n) - 2cos(w)x(n-1) + x(n-2) 42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project This is what the ALLOCS below are trying to do: 42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP 42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP 43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project These matrices store the output of each stage on each row. The 43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project final (m-th) row has the output of the final (m-th) cascaded 43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2nd order filter. The first row is the impulse input to the 43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project system (not written as it is known). 43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project The version below takes advantage of the fact that a lot of the 43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project outputs are zero or known, for example if we put an inpulse 43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project into the first section the "clock" it 10 times only the first 3 43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project outputs samples are non-zero (it's an FIR filter). 44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project */ 44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xp, (m+1), spx_word32_t*); 44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t); 44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xq, (m+1), spx_word32_t*); 44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t); 44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0; i<=m; i++) { 44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i] = xpmem + i*(lpcrdr+1+2); 45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i] = xqmem + i*(lpcrdr+1+2); 45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* work out 2cos terms in Q14 */ 45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(freqn, lpcrdr, spx_word16_t); 45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<lpcrdr;i++) 45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project freqn[i] = ANGLE2X(freq[i]); 45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project #define QIMP 21 /* scaling for impulse */ 46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin = SHL32(EXTEND32(1), (QIMP-1)); /* 0.5 in QIMP format */ 46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* first col and last non-zero values of each row are trivial */ 46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<=m;i++) { 46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i][1] = 0; 46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i][2] = xin; 46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i][2+2*i] = xin; 46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i][1] = 0; 47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i][2] = xin; 47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i][2+2*i] = xin; 47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* 2nd row (first output row) is trivial */ 47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[1][3] = -MULT16_32_Q14(freqn[0],xp[0][2]); 47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[1][3] = -MULT16_32_Q14(freqn[1],xq[0][2]); 47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout1 = xout2 = 0; 48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* now generate remaining rows */ 48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=1;i<m;i++) { 48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(j=1;j<2*(i+1)-1;j++) { 48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]); 48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i+1][j+2] = ADD32(SUB32(xp[i][j+2], mult), xp[i][j]); 48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]); 48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i+1][j+2] = ADD32(SUB32(xq[i][j+2], mult), xq[i][j]); 49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* for last col xp[i][j+2] = xq[i][j+2] = 0 */ 49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]); 49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xp[i+1][j+2] = SUB32(xp[i][j], mult); 49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]); 49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xq[i+1][j+2] = SUB32(xq[i][j], mult); 49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* process last row to extra a{k} */ 50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(j=1;j<=lpcrdr;j++) { 50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int shift = QIMP-13; 50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* final filter sections */ 50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a = PSHR32(xp[m][j+2] + xout1 + xq[m][j+2] - xout2, shift); 50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout1 = xp[m][j+2]; 50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout2 = xq[m][j+2]; 50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* hard limit ak's to +/- 32767 */ 51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (a < -32767) a = -32767; 51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (a > 32767) a = 32767; 51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ak[j-1] = (short)a; 51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack) 52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *freq array of LSP frequencies in the x domain */ 52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* float *ak array of LPC coefficients */ 52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* int lpcrdr order of LPC coefficients */ 52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float xout1,xout2,xin1,xin2; 53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(float *Wp); 53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float *pw,*n1,*n2,*n3,*n4=NULL; 53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(float *x_freq); 53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int m = lpcrdr>>1; 53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(Wp, 4*m+2, float); 53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pw = Wp; 53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* initialise contents of array */ 54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ 54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *pw++ = 0.0; 54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Set pointers up */ 54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pw = Wp; 54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin1 = 1.0; 54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin2 = 1.0; 55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(x_freq, lpcrdr, float); 55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<lpcrdr;i++) 55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x_freq[i] = ANGLE2X(freq[i]); 55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* reconstruct P(z) and Q(z) by cascading second order 55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project polynomials in form 1 - 2xz(-1) +z(-2), where x is the 55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LSP coefficient */ 55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(j=0;j<=lpcrdr;j++){ 56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i2=0; 56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for(i=0;i<m;i++,i2+=2){ 56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project n1 = pw+(i*4); 56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project n2 = n1 + 1; 56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project n3 = n2 + 1; 56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project n4 = n3 + 1; 56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2; 56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4; 56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *n2 = *n1; 56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *n4 = *n3; 57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *n1 = xin1; 57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *n3 = xin2; 57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin1 = xout1; 57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin2 = xout2; 57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout1 = xin1 + *(n4+1); 57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xout2 = xin2 - *(n4+2); 57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (j>0) 57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ak[j-1] = (xout1 + xout2)*0.5f; 57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *(n4+1) = xin1; 58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *(n4+2) = xin2; 58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin1 = 0.0; 58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xin2 = 0.0; 58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*Makes sure the LSPs are stable*/ 59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin) 59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t m = margin; 59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t m2 = 25736-margin; 59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[0]<m) 60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[0]=m; 60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[len-1]>m2) 60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[len-1]=m2; 60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<len-1;i++) 60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[i]<lsp[i-1]+m) 60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[i]=lsp[i-1]+m; 60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[i]>lsp[i+1]-m) 60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1); 61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes) 61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes); 61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp2 = 16384-tmp; 61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]); 62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/*Makes sure the LSPs are stable*/ 62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin) 62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[0]<LSP_SCALING*margin) 63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[0]=LSP_SCALING*margin; 63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[len-1]>LSP_SCALING*(M_PI-margin)) 63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[len-1]=LSP_SCALING*(M_PI-margin); 63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<len-1;i++) 63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[i]<lsp[i-1]+LSP_SCALING*margin) 63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[i]=lsp[i-1]+LSP_SCALING*margin; 63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (lsp[i]>lsp[i+1]-LSP_SCALING*margin) 64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin); 64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes) 64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float tmp = (1.0f + subframe)/nb_subframes; 65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i]; 65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 657