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