LCOV - code coverage report
Current view: top level - lib_com - lsp_conv_poly.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 127 158 80.4 %
Date: 2025-05-23 08:37:30 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "cnst.h"
      43             : #include "rom_com.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * Local constants
      49             :  *-------------------------------------------------------------------*/
      50             : 
      51             : /* The conversion modes. */
      52             : #define DOWNCONV 0
      53             : #define UPCONV   1
      54             : /* The cap of the inverse power spectrum. */
      55             : #define MAXPOWERSPECT 1e-5f
      56             : #define N50           GRID50_POINTS
      57             : #define N40           GRID40_POINTS
      58             : 
      59             : 
      60             : /*-------------------------------------------------------------------*
      61             :  * Local function prototypes
      62             :  *-------------------------------------------------------------------*/
      63             : 
      64             : static void powerspect( const float x[], const int16_t N, float R[], float S[], float G[], const int16_t mode );
      65             : 
      66             : static void spectautocorr( const float x[], const int16_t N, const float G[], float r[] );
      67             : 
      68             : static void zeros2poly( float x[], float R[], float S[] );
      69             : 
      70             : static void polydecomp( float A[], float P[], float Q[] );
      71             : 
      72             : static void cheb2poly( float P[] );
      73             : 
      74             : 
      75             : /*---------------------------------------------------------------------*
      76             :  *  lsp_convert_poly()
      77             :  *
      78             :  *  Converts the LP filter estimated at 16.0 kHz sampling rate down
      79             :  *  12.8 kHz frequency scale or alternatively from 12.8 kHz up to
      80             :  *  16.0 kHz.  The former is called down conversation and latter up
      81             :  *  conversion.  The resulting LP filter is characterized with its
      82             :  *  line spectrum pairs.  The original Lp filter can be either in
      83             :  *  its immittance, used for the AMR-WB IO mode, or line spectrum
      84             :  *  pair representation.
      85             :  *
      86             :  *  The conversion is based the autocorrelation computed from the
      87             :  *  power spectrum of the LP filter that is truncated or extrapolated
      88             :  *  to the desired frequency scale.
      89             :  *---------------------------------------------------------------------*/
      90             : 
      91      110024 : int16_t lsp_convert_poly(
      92             :     float w[],              /* i/o: LSP or ISP parameters          */
      93             :     const int16_t L_frame,  /* i  : flag for up or down conversion */
      94             :     const int16_t Opt_AMRWB /* i  : flag for the AMR-WB IO mode    */
      95             : )
      96             : {
      97             :     float epsP[M + 1];
      98             :     float G[GRID50_POINTS], r[M + 1], A[M + 1], A_old[M + 1], R[NC + 1], S[NC + 1];
      99             :     int16_t i;
     100             :     int16_t flag;
     101             : 
     102             :     /*---------------------------------------------------------------------*
     103             :      * Because AMR-WB IO uses immittance spectrum frequency representation
     104             :      * instead of line spectrum frequency representation, the input
     105             :      * parameters do not give the zeros of the polynomials R(x) and S(x).
     106             :      * Hence R(x) and S(x) are formed via the polynomial A(z) of the linear
     107             :      * prediction filter.
     108             :      *---------------------------------------------------------------------*/
     109             : 
     110      110024 :     if ( Opt_AMRWB )
     111             :     {
     112           0 :         isp2a( w, A_old, M );
     113           0 :         polydecomp( A_old, R, S );
     114             :     }
     115             : 
     116             :     /*---------------------------------------------------------------------*
     117             :      * Form the polynomials R(x) and S(x) from their zeros that are the
     118             :      * line spectrum pairs of A(z).  The polynomial coefficients can be
     119             :      * scaled for convenience, because scaling will not affect the
     120             :      * resulting LP coefficients.  Scaling by 128 gives the correct offset
     121             :      * to the power spectrum for n = 16.
     122             :      *---------------------------------------------------------------------*/
     123             : 
     124             :     else
     125             :     {
     126      110024 :         zeros2poly( w, R, S );
     127     1100240 :         for ( i = 0; i <= NC; i++ )
     128             :         {
     129      990216 :             R[i] *= 128.0f;
     130      990216 :             S[i] *= 128.0f;
     131             :         }
     132      110024 :         lsp2a_stab( w, A_old, M );
     133             :     }
     134             : 
     135             :     /*---------------------------------------------------------------------*
     136             :      * Conversion from 16.0 kHz down to 12.8 kHz.  The power spectrum
     137             :      * needs to be computed only up to 6.4 kHz, because the upper band
     138             :      * is omitted.
     139             :      *---------------------------------------------------------------------*/
     140             : 
     141      110024 :     if ( L_frame == L_FRAME )
     142             :     {
     143       10234 :         powerspect( grid50, N50, R, S, G, DOWNCONV );
     144       10234 :         spectautocorr( grid40, N40, G, r );
     145             :     }
     146             : 
     147             :     /*---------------------------------------------------------------------*
     148             :      * Conversion from 12.8 kHz up to 16.0 kHz.
     149             :      * Compute the power spectrum of the LP filter, extrapolate the
     150             :      * power spectrum from 6.4 kHz to 8.0 kHz, and compute auto-
     151             :      * correlation on this power spectrum.
     152             :      *---------------------------------------------------------------------*/
     153             : 
     154             :     else
     155             :     {
     156       99790 :         powerspect( grid40, N40, R, S, G, UPCONV );
     157     1097690 :         for ( i = N40; i < N50; i++ )
     158             :         {
     159      997900 :             G[i] = G[N40 - 1];
     160             :         }
     161             : 
     162       99790 :         spectautocorr( grid50, N50, G, r );
     163             :     }
     164             : 
     165             :     /*---------------------------------------------------------------------*
     166             :      * Compute the linear prediction coefficients from the autocorrelation
     167             :      * and convert to line spectrum pairs.
     168             :      *---------------------------------------------------------------------*/
     169             : 
     170      110024 :     flag = lev_dur( A, r, M, epsP );
     171      110024 :     a2lsp_stab( A, w, stable_LSP );
     172             : 
     173      110024 :     return ( flag );
     174             : }
     175             : 
     176             : 
     177             : /*---------------------------------------------------------------------*
     178             :  *  powerspect()
     179             :  *
     180             :  *  Computes the power spectrum G(w) = 1/|A(w)|^2 at N points on
     181             :  *  the real axis x = cos w by utilizing the line spectrum frequency
     182             :  *  decomposition
     183             :  *
     184             :  *     A(z) = (P(z) + Q(z))/2,
     185             :  *
     186             :  *  where assuming A(z) of an even degree n,
     187             :  *
     188             :  *     P(z) = [A(z) + z^(n+1) A(1/z)]/(1/z + 1),
     189             :  *     Q(z) = [A(z) - z^(n+1) A(1/z)]/(1/z - 1).
     190             :  *
     191             :  *  The zeros of these polynomials give the line spectrum frequencies
     192             :  *  of A(z).  It can be shown that for an even n,
     193             :  *
     194             :  *     |A(x)|^2 = 2 (1 + x) R(x)^2 + 2 (1 - x) S(x)^2,
     195             :  *
     196             :  *  where x = cos w, and R(x) and S(x) are the direct polynomials
     197             :  *  resulting from the Chebyshev series representation of P(z)
     198             :  *  and Q(z).
     199             :  *
     200             :  *  This routine assumes the grid X = 1, x[0], x[1], .., x[m-1],
     201             :  *  -, ..., -x[1], -x[0], -1 such that x[i] = cos((i+1)*pi/N) for
     202             :  *  evaluating the power spectrum.  Only m = (N-1)/2 - 1 grid points
     203             :  *  need to be stored, because cos(0) and cos(pi/2) are trivial,
     204             :  *  and the points above pi/2 are obtained readily using the symmetry
     205             :  *  of cosine.
     206             :  *
     207             :  *  The power spectrum can be scaled as a*G[], where a is chosen
     208             :  *  for convenience. This is because the scaling has no impact on
     209             :  *  the LP coefficients to be determined based on the power spectrum.
     210             :  *---------------------------------------------------------------------*/
     211             : 
     212      110024 : static void powerspect(
     213             :     const float x[],   /* i  : Grid points x[0:N-1]             */
     214             :     const int16_t N,   /* i  : Number of grid points            */
     215             :     float R[],         /* i  : Coefficients of R(x) in R[0:NC]  */
     216             :     float S[],         /* i  : Coefficients of S(x) in S[0:NC]  */
     217             :     float G[],         /* o  : Power spectrum G[0:N]            */
     218             :     const int16_t mode /* i  : Flag for up or down conversion   */
     219             : )
     220             : {
     221             :     float re, ro, se, so;
     222             :     float s0, s1, r0, r1, x0, x1, x2;
     223             :     Word16 i, j;
     224             :     Word16 iuni, imid;
     225             : 
     226             :     /* init buffer */
     227     4723348 :     for ( i = 0; i < N; i++ )
     228             :     {
     229     4613324 :         G[i] = 0;
     230             :     }
     231             :     /*---------------------------------------------------------------------*
     232             :      * Down conversion yields iuni unique grid points that do not have
     233             :      * symmetric counterparts above x = cos(pi/2) = 0.
     234             :      * Set the mid point of the frequency grid.
     235             :      *---------------------------------------------------------------------*/
     236             : 
     237      110024 :     if ( mode == DOWNCONV )
     238             :     {
     239       10234 :         iuni = ( GRID50_POINTS - 1 ) / 5 - 1;
     240       10234 :         imid = ( GRID50_POINTS - 1 ) / 2;
     241             :     }
     242             : 
     243             :     /*---------------------------------------------------------------------*
     244             :      * Power spectrum at x = cos(pi) = -1 that is not needed in down
     245             :      * conversion. Set the mid point of the frequency grid.
     246             :      *---------------------------------------------------------------------*/
     247             : 
     248             :     else
     249             :     {
     250       99790 :         iuni = 0;
     251       99790 :         imid = ( GRID40_POINTS - 1 ) / 2;
     252             : 
     253       99790 :         s0 = S[0];
     254      898110 :         for ( j = 1; j <= NC; j++ )
     255             :         {
     256      798320 :             s0 = S[j] - s0;
     257             :         }
     258       99790 :         G[N - 1] = 4.0f * s0 * s0;
     259             :     }
     260             : 
     261             :     /*---------------------------------------------------------------------*
     262             :      * Power spectrum at x = cos(0) = 1.
     263             :      *---------------------------------------------------------------------*/
     264             : 
     265      110024 :     r0 = R[0];
     266      990216 :     for ( j = 1; j <= NC; j++ )
     267             :     {
     268      880192 :         r0 += R[j];
     269             :     }
     270      110024 :     r0 = max( r0, 0.000000953674316f );
     271      110024 :     G[0] = 4.0f * r0 * r0;
     272             : 
     273             :     /*---------------------------------------------------------------------*
     274             :      * Power spectrum at x = cos(pi/2) = 0.
     275             :      *---------------------------------------------------------------------*/
     276             : 
     277      110024 :     r0 = R[NC];
     278      110024 :     s0 = S[NC];
     279      110024 :     r0 = r0 * r0;
     280      110024 :     s0 = s0 * s0;
     281             : 
     282      110024 :     G[imid] = 2.0f * ( r0 + s0 );
     283             : 
     284             :     /*---------------------------------------------------------------------*
     285             :      * Power spectrum at unique points that do not have symmetric
     286             :      * counterparts at x > cos(pi/2) = 0.
     287             :      *---------------------------------------------------------------------*/
     288             : 
     289      202130 :     for ( i = 1; i <= iuni; i++ )
     290             :     {
     291       92106 :         x0 = x[i - 1];
     292       92106 :         r0 = R[0];
     293       92106 :         s0 = S[0];
     294             : 
     295      828954 :         for ( j = 1; j <= NC; j++ )
     296             :         {
     297      736848 :             r0 = x0 * r0 + R[j];
     298      736848 :             s0 = x0 * s0 + S[j];
     299             :         }
     300       92106 :         r0 = ( 1.0f + x0 ) * r0 * r0;
     301       92106 :         s0 = ( 1.0f - x0 ) * s0 * s0;
     302             : 
     303       92106 :         G[i] = 2.0f * ( r0 + s0 );
     304             :     }
     305             : 
     306             :     /*---------------------------------------------------------------------*
     307             :      * Power spectrum at points other than x = -1, 0, and 1 and unique
     308             :      * points is computed using the anti-symmetry of the grid relative
     309             :      * to the midpoint x = 0 in order to reduce looping.
     310             :      *---------------------------------------------------------------------*/
     311             : 
     312     2159544 :     for ( ; i < imid; i++ )
     313             :     {
     314     2049520 :         x0 = x[i - 1];
     315     2049520 :         x2 = x0 * x0;
     316             : 
     317     2049520 :         re = R[0];
     318     2049520 :         se = S[0];
     319     2049520 :         ro = R[1];
     320     2049520 :         so = S[1];
     321             : 
     322     8198080 :         for ( j = 2; j < NC; j += 2 )
     323             :         {
     324     6148560 :             re = x2 * re + R[j];
     325     6148560 :             ro = x2 * ro + R[j + 1];
     326     6148560 :             se = x2 * se + S[j];
     327     6148560 :             so = x2 * so + S[j + 1];
     328             :         }
     329             : 
     330     2049520 :         re = x2 * re + R[j];
     331     2049520 :         ro *= x0;
     332     2049520 :         se = x2 * se + S[j];
     333     2049520 :         so *= x0;
     334             : 
     335     2049520 :         r0 = re + ro;
     336     2049520 :         s0 = se + so;
     337     2049520 :         r1 = re - ro;
     338     2049520 :         s1 = se - so;
     339             : 
     340     2049520 :         x1 = 1.0f + x0;
     341     2049520 :         x2 = 1.0f - x0;
     342             : 
     343     2049520 :         r0 = x1 * r0 * r0;
     344     2049520 :         s0 = x2 * s0 * s0;
     345     2049520 :         r1 = x2 * r1 * r1;
     346     2049520 :         s1 = x1 * s1 * s1;
     347             : 
     348     2049520 :         G[i] = 2.0f * ( r0 + s0 );
     349     2049520 :         G[N - i - 1] = 2.0f * ( r1 + s1 );
     350             :     }
     351             : 
     352             :     /*---------------------------------------------------------------------*
     353             :      * Compute the power spectrum 1/|A(x)|^2 from |A(x)|^2 with logic
     354             :      * to prevent division by small number and upper bound the spectrum.
     355             :      * This upper bound is implicit in fixed point arithmetic, but is
     356             :      * needed explicitly in floating point implementations to avoid numeric
     357             :      * problems.
     358             :      *---------------------------------------------------------------------*/
     359             : 
     360     4723348 :     for ( i = 0; i < N; i++ )
     361             :     {
     362     4613324 :         if ( G[i] < MAXPOWERSPECT )
     363             :         {
     364      102345 :             G[i] = MAXPOWERSPECT;
     365             :         }
     366     4613324 :         G[i] = 1.0f / G[i];
     367             :     }
     368      110024 :     return;
     369             : }
     370             : 
     371             : /*---------------------------------------------------------------------*
     372             :  *  spectautocorr()
     373             :  *
     374             :  *  Computes the autocorrelation r[j] for j = 0, 1, ..., M from
     375             :  *  the power spectrum P(w) by using the rectangle rule to
     376             :  *  approximate the integral
     377             :  *
     378             :  *             1     pi
     379             :  *     r[j] = ---    I  P(w) cos(j*w) dw.
     380             :  *            2*pi -pi
     381             :  *
     382             :  *  It is sufficient to evaluate the integrand only from w = 0 to
     383             :  *  w = pi due to the symmetry P(-w) = P(w).  We can further
     384             :  *  employ the relation
     385             :  *
     386             :  *      cos(j*(pi - w)) = (-1)^j cos(j*w)
     387             :  *
     388             :  *  to use symmetries relative to w = pi/2 for w in (0, pi/2).
     389             :  *
     390             :  *  When applying the rectangle rule, it is convenient to evaluate
     391             :  *  w = 0, w = pi/2, and w = pi separately.  By using a frequency
     392             :  *  grid of N points, we can express the rectangle rule as
     393             :  *
     394             :  *     r[j] = G[0] + 2*a*G[(N-1)/2] + b*G[N-1]
     395             :  *
     396             :  *                      M
     397             :  *                 + 2 sum (G[i] - G[N-i-1]) cos(j*x[i])
     398             :  *                     i=1
     399             :  *
     400             :  *  where G[i] is the power spectrum at x[i] = i*pi/(N-1) and
     401             :  *  M = (N-1)/2 - 1 is the number of the grid points in the
     402             :  *  interval(0, pi/2).  The number of grid points N is assumed odd.
     403             :  *
     404             :  *  The coefficients
     405             :  *
     406             :  *     b = (-1)^j
     407             :  *     a = (1 + (-1)^(j+1))(-1)^floor(j/2)
     408             :  *
     409             :  *  follow from the properties of the cosine function.  The
     410             :  *  computation further uses the recursion
     411             :  *
     412             :  *     cos(j*w) = 2*cos(w)*cos((j-1)*w) - cos((j-2)*w)
     413             :  *
     414             :  *  Note that the autocorrelation can be scaled for convenience,
     415             :  *  because this scaling has no impact on the LP coefficients to be
     416             :  *  calculated from the autocorrelation. The expression of r[j] thus
     417             :  *  omits the division by N.
     418             :  *
     419             :  *  See the powerspect function on the definition of the grid.
     420             :  *
     421             :  *  References
     422             :  *  J. Makhoul, "Spectral linear prediction: properties and
     423             :  *  applications," IEEE Trans. on Acoustics, Speech and Signal
     424             :  *  Processing, Vol. 23, No. 3, pp.283-296, June 1975
     425             :  *---------------------------------------------------------------------*/
     426             : 
     427      110024 : static void spectautocorr(
     428             :     const float x[], /* i  : Grid points x[0:N-1]             */
     429             :     const int16_t N, /* i  : Number of grid points            */
     430             :     const float G[], /* i  : Power spectrum G[0:N-1]          */
     431             :     float r[]        /* o  : Autocorrelation r[0:M]           */
     432             : )
     433             : {
     434             :     float c[M + 1]; /* c[j] = cos(j*w) */
     435             :     float gp, gn, c2;
     436             :     Word16 i, j;
     437             :     Word16 imid;
     438             : 
     439             :     /*---------------------------------------------------------------------*
     440             :      * The midpoint of the cosine table x of N entries. Only the entries
     441             :      * x[0] = cos(d), x[1] = cos(2*d), ..., x[imid-1] = cos((imid-1)*d)
     442             :      * need to be stored due to trivial cos(0), cos(pi/2), cos(pi), and
     443             :      * symmetry relative to pi/2. Here d = pi/(N - 1).
     444             :      *---------------------------------------------------------------------*/
     445             : 
     446      110024 :     imid = ( N - 1 ) / 2;
     447             : 
     448             :     /*---------------------------------------------------------------------*
     449             :      * Autocorrelation r[j] at zero lag j = 0 for the upper half of the
     450             :      * unit circle, but excluding the points x = cos(0) and x = cos(pi).
     451             :      *---------------------------------------------------------------------*/
     452             : 
     453      110024 :     r[0] = G[1];
     454     5288836 :     for ( i = 2; i < N - 1; i++ )
     455             :     {
     456     5178812 :         r[0] += G[i];
     457             :     }
     458             : 
     459             :     /*---------------------------------------------------------------------*
     460             :      * Initialize the autocorrelation r[j] at lags greater than zero
     461             :      * by adding the midpoint x = cos(pi/2) = 0.
     462             :      *---------------------------------------------------------------------*/
     463             : 
     464      110024 :     r[1] = 0.0f;
     465      110024 :     r[2] = -G[imid];
     466             : 
     467      880192 :     for ( j = 3; j < M; j += 2 )
     468             :     {
     469      770168 :         r[j] = 0.0f;
     470      770168 :         r[j + 1] = -r[j - 1];
     471             :     }
     472             : 
     473             :     /*---------------------------------------------------------------------*
     474             :      * Autocorrelation r[j] at lags j = 1, 2, ..., M.  The computation
     475             :      * employes the relation cos(j*(pi - w)) = (-1)^j cos(j*w) and
     476             :      * cos(j*w) = 2*cos(w)*cos((j-1)*w) - cos((j-2)*w) for obtaining
     477             :      * the cosine c[j] = cos(j*w).
     478             :      *---------------------------------------------------------------------*/
     479             : 
     480      110024 :     c[0] = 1.0f;
     481             : 
     482     2699430 :     for ( i = 1; i < imid; i++ )
     483             :     {
     484     2589406 :         gp = G[i] + G[N - i - 1];
     485     2589406 :         gn = G[i] - G[N - i - 1];
     486             : 
     487     2589406 :         c[1] = x[i - 1];
     488     2589406 :         c2 = 2.0f * c[1];
     489             : 
     490     2589406 :         r[1] += gn * c[1];
     491             : 
     492    20715248 :         for ( j = 2; j < M; j += 2 )
     493             :         {
     494    18125842 :             c[j] = c2 * c[j - 1] - c[j - 2];
     495    18125842 :             r[j] += gp * c[j];
     496    18125842 :             c[j + 1] = c2 * c[j] - c[j - 1];
     497    18125842 :             r[j + 1] += gn * c[j + 1];
     498             :         }
     499             : 
     500     2589406 :         c[j] = c2 * c[j - 1] - c[j - 2];
     501     2589406 :         r[j] += gp * c[j];
     502             :     }
     503             : 
     504             :     /*---------------------------------------------------------------------*
     505             :      * Add the endpoints x = cos(0) = 1 and x = cos(pi) = -1 as
     506             :      * well as the lower half of the unit circle.
     507             :      *---------------------------------------------------------------------*/
     508             : 
     509      110024 :     gp = G[0] + G[N - 1];
     510      110024 :     gn = G[0] - G[N - 1];
     511             : 
     512      990216 :     for ( j = 0; j < M; j += 2 )
     513             :     {
     514      880192 :         r[j] = 2.0f * r[j] + gp;
     515      880192 :         r[j + 1] = 2.0f * r[j + 1] + gn;
     516             :     }
     517      110024 :     r[j] = 2.0f * r[j] + gp;
     518             : 
     519      110024 :     return;
     520             : }
     521             : 
     522             : /*---------------------------------------------------------------------*
     523             :  *  zeros2poly()
     524             :  *
     525             :  *  Computes the coefficients of the polynomials
     526             :  *
     527             :  *      R(x) =   prod  (x - x[i]),
     528             :  *             i = 0,2,4,...
     529             :  *
     530             :  *      S(x) =   prod  (x - x[i]),
     531             :  *             i = 1,3,5,...
     532             :  *
     533             :  *  given their zeros x[i] for i = 0, 1, ..., n-1. The routine
     534             :  *  assumes n = 1 or even n greater than or equal to 4.
     535             :  *
     536             :  *  The polynomial coefficients are returned in R[0:n/2-1] and
     537             :  *  S[0:n/2-1]. The leading coefficients are in R[0] and S[0].
     538             :  *
     539             :  *  In this implementation, n is set to a compile time constant.
     540             :  *---------------------------------------------------------------------*/
     541             : 
     542      110024 : static void zeros2poly(
     543             :     float x[], /* i  : Zeros of R(x) and S(x)      */
     544             :     float R[], /* o  : Coefficients of R(x)        */
     545             :     float S[]  /* o  : Coefficients of S(x)        */
     546             : )
     547             : {
     548             :     float xr, xs;
     549             :     Word16 i, j;
     550             : 
     551      110024 :     R[0] = 1.0f;
     552      110024 :     R[1] = -*x++;
     553      110024 :     S[0] = 1.0f;
     554      110024 :     S[1] = -*x++;
     555             : 
     556      880192 :     for ( i = 2; i <= NC; i++ )
     557             :     {
     558      770168 :         xr = -*x++;
     559      770168 :         xs = -*x++;
     560             : 
     561      770168 :         R[i] = xr * R[i - 1];
     562      770168 :         S[i] = xs * S[i - 1];
     563             : 
     564     3850840 :         for ( j = i - 1; j > 0; j-- )
     565             :         {
     566     3080672 :             R[j] += xr * R[j - 1];
     567     3080672 :             S[j] += xs * S[j - 1];
     568             :         }
     569             :     }
     570             : 
     571      110024 :     return;
     572             : }
     573             : 
     574             : /*---------------------------------------------------------------------*
     575             :  *  polydecomp()
     576             :  *
     577             :  *  Computes the coefficients of the symmetric and antisymmetric
     578             :  *  polynomials P(z) and Q(z) that define the line spectrum pair
     579             :  *  decomposition of a given polynomial A(z) of order n. For even n,
     580             :  *
     581             :  *      P(z) = [A(z) + z^(n+1) A(1/z)]/(1/z + 1),
     582             :  *      Q(z) = [A(z) - z^(n+1) A(1/z)]/(1/z - 1),
     583             :  *
     584             :  *  These polynomials are then expressed in their direct form,
     585             :  *  respectively, R(x) and S(x), on the real axis x = cos w using
     586             :  *  explicit Chebyshev polynomials of the first kind.
     587             :  *
     588             :  *  The coefficients of the polynomials R(x) and S(x) are returned
     589             :  *  in R[0:n/2] and S[0:n/2] for the given linear prediction
     590             :  *  coefficients A[0:n/2]. Note that R(x) and S(x) are formed in
     591             :  *  place such that P(z) is stored in the same array than R(x),
     592             :  *  and Q(z) is stored in the same array than S(x).
     593             :  *
     594             :  *  The routines assumes n = 16.
     595             :  *---------------------------------------------------------------------*/
     596             : 
     597           0 : static void polydecomp(
     598             :     float A[], /* i  : linear prediction coefficients */
     599             :     float R[], /* o  : coefficients of R(x)           */
     600             :     float S[]  /* o  : coefficients of S(x)           */
     601             : )
     602             : {
     603           0 :     float *P = &R[0], *Q = &S[0];
     604             :     Word16 i, j;
     605             : 
     606           0 :     P[0] = A[0];
     607           0 :     Q[0] = A[0];
     608           0 :     for ( i = 1, j = M; i <= NC; i++, j-- )
     609             :     {
     610           0 :         P[i] = A[i] + A[j] - P[i - 1];
     611           0 :         Q[i] = A[i] - A[j] + Q[i - 1];
     612             :     }
     613             : 
     614           0 :     cheb2poly( P );
     615           0 :     cheb2poly( Q );
     616             : 
     617           0 :     return;
     618             : }
     619             : 
     620             : /*---------------------------------------------------------------------*
     621             :  *  cheb2poly()
     622             :  *
     623             :  *  Computes the coefficients of the explicit Chebyshev polynomial
     624             :  *  P(x) = P[0]*x^n + P[1]*x^(n-1) + ... + P[n] given the coefficients
     625             :  *  of the series
     626             :  *
     627             :  *     C(x) = C[0]*T_n(x) + C[1]*T_n-1(x) + ... + C[n]*T_0(x),
     628             :  *
     629             :  *  where T_n(x) is the nth Chebyshev polynomial of the first kind.
     630             :  *  This implementation assumes C[0] = 1. Only the value n = 8 is
     631             :  *  supported.
     632             :  *
     633             :  *  The conversion from C(x) to P(x) is done in place such that the
     634             :  *  coefficients of C(x) are given in P[0:8] and those of P(x) are
     635             :  *  returned in the same array.
     636             :  *---------------------------------------------------------------------*/
     637             : 
     638           0 : static void cheb2poly(
     639             :     float P[] /* i/o: The coefficients of C(x) and P(x) */
     640             : )
     641             : {
     642             :     float c1, c2, c3, c4, c5, c6, c7, c8;
     643             : 
     644           0 :     c1 = P[1];
     645           0 :     c2 = P[2];
     646           0 :     c3 = P[3];
     647           0 :     c4 = P[4];
     648           0 :     c5 = P[5];
     649           0 :     c6 = P[6];
     650           0 :     c7 = P[7];
     651           0 :     c8 = P[8];
     652             : 
     653           0 :     P[0] = 128.0f;
     654           0 :     P[1] = 64.0f * c1;
     655           0 :     P[2] = 32.0f * c2 - 256.0f;
     656           0 :     P[3] = 16.0f * c3 - 112.0f * c1;
     657           0 :     P[4] = 160.0f - 48.0f * c2 + 8.0f * c4;
     658           0 :     P[5] = 56.0f * c1 - 20.0f * c3 + 4.0f * c5;
     659           0 :     P[6] = 18.0f * c2 - 32.0f - 8.0f * c4 + 2.0f * c6;
     660           0 :     P[7] = 5.0f * c3 - 7.0f * c1 - 3.0f * c5 + c7;
     661           0 :     P[8] = 1.0f - c2 + c4 - c6 + 0.5f * c8;
     662             : 
     663           0 :     return;
     664             : }

Generated by: LCOV version 1.14