LCOV - code coverage report
Current view: top level - media/libopus/celt - celt_lpc.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 100 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (c) 2009-2010 Xiph.Org Foundation
       2             :    Written by Jean-Marc Valin */
       3             : /*
       4             :    Redistribution and use in source and binary forms, with or without
       5             :    modification, are permitted provided that the following conditions
       6             :    are met:
       7             : 
       8             :    - Redistributions of source code must retain the above copyright
       9             :    notice, this list of conditions and the following disclaimer.
      10             : 
      11             :    - Redistributions in binary form must reproduce the above copyright
      12             :    notice, this list of conditions and the following disclaimer in the
      13             :    documentation and/or other materials provided with the distribution.
      14             : 
      15             :    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      16             :    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      17             :    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      18             :    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
      19             :    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      20             :    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      22             :    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      23             :    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      24             :    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      25             :    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             : */
      27             : 
      28             : #ifdef HAVE_CONFIG_H
      29             : #include "config.h"
      30             : #endif
      31             : 
      32             : #include "celt_lpc.h"
      33             : #include "stack_alloc.h"
      34             : #include "mathops.h"
      35             : #include "pitch.h"
      36             : 
      37           0 : void _celt_lpc(
      38             :       opus_val16       *_lpc, /* out: [0...p-1] LPC coefficients      */
      39             : const opus_val32 *ac,  /* in:  [0...p] autocorrelation values  */
      40             : int          p
      41             : )
      42             : {
      43             :    int i, j;
      44             :    opus_val32 r;
      45           0 :    opus_val32 error = ac[0];
      46             : #ifdef FIXED_POINT
      47             :    opus_val32 lpc[LPC_ORDER];
      48             : #else
      49           0 :    float *lpc = _lpc;
      50             : #endif
      51             : 
      52           0 :    OPUS_CLEAR(lpc, p);
      53           0 :    if (ac[0] != 0)
      54             :    {
      55           0 :       for (i = 0; i < p; i++) {
      56             :          /* Sum up this iteration's reflection coefficient */
      57           0 :          opus_val32 rr = 0;
      58           0 :          for (j = 0; j < i; j++)
      59           0 :             rr += MULT32_32_Q31(lpc[j],ac[i - j]);
      60           0 :          rr += SHR32(ac[i + 1],3);
      61           0 :          r = -frac_div32(SHL32(rr,3), error);
      62             :          /*  Update LPC coefficients and total error */
      63           0 :          lpc[i] = SHR32(r,3);
      64           0 :          for (j = 0; j < (i+1)>>1; j++)
      65             :          {
      66             :             opus_val32 tmp1, tmp2;
      67           0 :             tmp1 = lpc[j];
      68           0 :             tmp2 = lpc[i-1-j];
      69           0 :             lpc[j]     = tmp1 + MULT32_32_Q31(r,tmp2);
      70           0 :             lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
      71             :          }
      72             : 
      73           0 :          error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
      74             :          /* Bail out once we get 30 dB gain */
      75             : #ifdef FIXED_POINT
      76             :          if (error<SHR32(ac[0],10))
      77             :             break;
      78             : #else
      79           0 :          if (error<.001f*ac[0])
      80           0 :             break;
      81             : #endif
      82             :       }
      83             :    }
      84             : #ifdef FIXED_POINT
      85             :    for (i=0;i<p;i++)
      86             :       _lpc[i] = ROUND16(lpc[i],16);
      87             : #endif
      88           0 : }
      89             : 
      90             : 
      91           0 : void celt_fir_c(
      92             :          const opus_val16 *x,
      93             :          const opus_val16 *num,
      94             :          opus_val16 *y,
      95             :          int N,
      96             :          int ord,
      97             :          int arch)
      98             : {
      99             :    int i,j;
     100             :    VARDECL(opus_val16, rnum);
     101             :    SAVE_STACK;
     102             : 
     103           0 :    ALLOC(rnum, ord, opus_val16);
     104           0 :    for(i=0;i<ord;i++)
     105           0 :       rnum[i] = num[ord-i-1];
     106           0 :    for (i=0;i<N-3;i+=4)
     107             :    {
     108             :       opus_val32 sum[4];
     109           0 :       sum[0] = SHL32(EXTEND32(x[i  ]), SIG_SHIFT);
     110           0 :       sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT),
     111           0 :       sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
     112           0 :       sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
     113           0 :       xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
     114           0 :       y[i  ] = ROUND16(sum[0], SIG_SHIFT);
     115           0 :       y[i+1] = ROUND16(sum[1], SIG_SHIFT);
     116           0 :       y[i+2] = ROUND16(sum[2], SIG_SHIFT);
     117           0 :       y[i+3] = ROUND16(sum[3], SIG_SHIFT);
     118             :    }
     119           0 :    for (;i<N;i++)
     120             :    {
     121           0 :       opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
     122           0 :       for (j=0;j<ord;j++)
     123           0 :          sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
     124           0 :       y[i] = ROUND16(sum, SIG_SHIFT);
     125             :    }
     126             :    RESTORE_STACK;
     127           0 : }
     128             : 
     129           0 : void celt_iir(const opus_val32 *_x,
     130             :          const opus_val16 *den,
     131             :          opus_val32 *_y,
     132             :          int N,
     133             :          int ord,
     134             :          opus_val16 *mem,
     135             :          int arch)
     136             : {
     137             : #ifdef SMALL_FOOTPRINT
     138             :    int i,j;
     139             :    (void)arch;
     140             :    for (i=0;i<N;i++)
     141             :    {
     142             :       opus_val32 sum = _x[i];
     143             :       for (j=0;j<ord;j++)
     144             :       {
     145             :          sum -= MULT16_16(den[j],mem[j]);
     146             :       }
     147             :       for (j=ord-1;j>=1;j--)
     148             :       {
     149             :          mem[j]=mem[j-1];
     150             :       }
     151             :       mem[0] = SROUND16(sum, SIG_SHIFT);
     152             :       _y[i] = sum;
     153             :    }
     154             : #else
     155             :    int i,j;
     156             :    VARDECL(opus_val16, rden);
     157             :    VARDECL(opus_val16, y);
     158             :    SAVE_STACK;
     159             : 
     160           0 :    celt_assert((ord&3)==0);
     161           0 :    ALLOC(rden, ord, opus_val16);
     162           0 :    ALLOC(y, N+ord, opus_val16);
     163           0 :    for(i=0;i<ord;i++)
     164           0 :       rden[i] = den[ord-i-1];
     165           0 :    for(i=0;i<ord;i++)
     166           0 :       y[i] = -mem[ord-i-1];
     167           0 :    for(;i<N+ord;i++)
     168           0 :       y[i]=0;
     169           0 :    for (i=0;i<N-3;i+=4)
     170             :    {
     171             :       /* Unroll by 4 as if it were an FIR filter */
     172             :       opus_val32 sum[4];
     173           0 :       sum[0]=_x[i];
     174           0 :       sum[1]=_x[i+1];
     175           0 :       sum[2]=_x[i+2];
     176           0 :       sum[3]=_x[i+3];
     177           0 :       xcorr_kernel(rden, y+i, sum, ord, arch);
     178             : 
     179             :       /* Patch up the result to compensate for the fact that this is an IIR */
     180           0 :       y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
     181           0 :       _y[i  ] = sum[0];
     182           0 :       sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
     183           0 :       y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
     184           0 :       _y[i+1] = sum[1];
     185           0 :       sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
     186           0 :       sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
     187           0 :       y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
     188           0 :       _y[i+2] = sum[2];
     189             : 
     190           0 :       sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
     191           0 :       sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
     192           0 :       sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
     193           0 :       y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
     194           0 :       _y[i+3] = sum[3];
     195             :    }
     196           0 :    for (;i<N;i++)
     197             :    {
     198           0 :       opus_val32 sum = _x[i];
     199           0 :       for (j=0;j<ord;j++)
     200           0 :          sum -= MULT16_16(rden[j],y[i+j]);
     201           0 :       y[i+ord] = SROUND16(sum,SIG_SHIFT);
     202           0 :       _y[i] = sum;
     203             :    }
     204           0 :    for(i=0;i<ord;i++)
     205           0 :       mem[i] = _y[N-i-1];
     206             :    RESTORE_STACK;
     207             : #endif
     208           0 : }
     209             : 
     210           0 : int _celt_autocorr(
     211             :                    const opus_val16 *x,   /*  in: [0...n-1] samples x   */
     212             :                    opus_val32       *ac,  /* out: [0...lag-1] ac values */
     213             :                    const opus_val16       *window,
     214             :                    int          overlap,
     215             :                    int          lag,
     216             :                    int          n,
     217             :                    int          arch
     218             :                   )
     219             : {
     220             :    opus_val32 d;
     221             :    int i, k;
     222           0 :    int fastN=n-lag;
     223             :    int shift;
     224             :    const opus_val16 *xptr;
     225             :    VARDECL(opus_val16, xx);
     226             :    SAVE_STACK;
     227           0 :    ALLOC(xx, n, opus_val16);
     228           0 :    celt_assert(n>0);
     229           0 :    celt_assert(overlap>=0);
     230           0 :    if (overlap == 0)
     231             :    {
     232           0 :       xptr = x;
     233             :    } else {
     234           0 :       for (i=0;i<n;i++)
     235           0 :          xx[i] = x[i];
     236           0 :       for (i=0;i<overlap;i++)
     237             :       {
     238           0 :          xx[i] = MULT16_16_Q15(x[i],window[i]);
     239           0 :          xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
     240             :       }
     241           0 :       xptr = xx;
     242             :    }
     243           0 :    shift=0;
     244             : #ifdef FIXED_POINT
     245             :    {
     246             :       opus_val32 ac0;
     247             :       ac0 = 1+(n<<7);
     248             :       if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
     249             :       for(i=(n&1);i<n;i+=2)
     250             :       {
     251             :          ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
     252             :          ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
     253             :       }
     254             : 
     255             :       shift = celt_ilog2(ac0)-30+10;
     256             :       shift = (shift)/2;
     257             :       if (shift>0)
     258             :       {
     259             :          for(i=0;i<n;i++)
     260             :             xx[i] = PSHR32(xptr[i], shift);
     261             :          xptr = xx;
     262             :       } else
     263             :          shift = 0;
     264             :    }
     265             : #endif
     266           0 :    celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
     267           0 :    for (k=0;k<=lag;k++)
     268             :    {
     269           0 :       for (i = k+fastN, d = 0; i < n; i++)
     270           0 :          d = MAC16_16(d, xptr[i], xptr[i-k]);
     271           0 :       ac[k] += d;
     272             :    }
     273             : #ifdef FIXED_POINT
     274             :    shift = 2*shift;
     275             :    if (shift<=0)
     276             :       ac[0] += SHL32((opus_int32)1, -shift);
     277             :    if (ac[0] < 268435456)
     278             :    {
     279             :       int shift2 = 29 - EC_ILOG(ac[0]);
     280             :       for (i=0;i<=lag;i++)
     281             :          ac[i] = SHL32(ac[i], shift2);
     282             :       shift -= shift2;
     283             :    } else if (ac[0] >= 536870912)
     284             :    {
     285             :       int shift2=1;
     286             :       if (ac[0] >= 1073741824)
     287             :          shift2++;
     288             :       for (i=0;i<=lag;i++)
     289             :          ac[i] = SHR32(ac[i], shift2);
     290             :       shift += shift2;
     291             :    }
     292             : #endif
     293             : 
     294             :    RESTORE_STACK;
     295           0 :    return shift;
     296             : }

Generated by: LCOV version 1.13