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

          Line data    Source code
       1             : /***********************************************************************
       2             : Copyright (c) 2006-2011, Skype Limited. All rights reserved.
       3             : Redistribution and use in source and binary forms, with or without
       4             : modification, are permitted provided that the following conditions
       5             : are met:
       6             : - Redistributions of source code must retain the above copyright notice,
       7             : this list of conditions and the following disclaimer.
       8             : - Redistributions in binary form must reproduce the above copyright
       9             : notice, this list of conditions and the following disclaimer in the
      10             : documentation and/or other materials provided with the distribution.
      11             : - Neither the name of Internet Society, IETF or IETF Trust, nor the
      12             : names of specific contributors, may be used to endorse or promote
      13             : products derived from this software without specific prior written
      14             : permission.
      15             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      16             : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      17             : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      18             : ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      19             : LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      20             : CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      21             : SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      22             : INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      23             : CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      24             : ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      25             : POSSIBILITY OF SUCH DAMAGE.
      26             : ***********************************************************************/
      27             : 
      28             : /*! \file silk_Inlines.h
      29             :  *  \brief silk_Inlines.h defines OPUS_INLINE signal processing functions.
      30             :  */
      31             : 
      32             : #ifndef SILK_FIX_INLINES_H
      33             : #define SILK_FIX_INLINES_H
      34             : 
      35             : #ifdef  __cplusplus
      36             : extern "C"
      37             : {
      38             : #endif
      39             : 
      40             : /* count leading zeros of opus_int64 */
      41             : static OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in )
      42             : {
      43             :     opus_int32 in_upper;
      44             : 
      45             :     in_upper = (opus_int32)silk_RSHIFT64(in, 32);
      46             :     if (in_upper == 0) {
      47             :         /* Search in the lower 32 bits */
      48             :         return 32 + silk_CLZ32( (opus_int32) in );
      49             :     } else {
      50             :         /* Search in the upper 32 bits */
      51             :         return silk_CLZ32( in_upper );
      52             :     }
      53             : }
      54             : 
      55             : /* get number of leading zeros and fractional part (the bits right after the leading one */
      56           0 : static OPUS_INLINE void silk_CLZ_FRAC(
      57             :     opus_int32 in,            /* I  input                               */
      58             :     opus_int32 *lz,           /* O  number of leading zeros             */
      59             :     opus_int32 *frac_Q7       /* O  the 7 bits right after the leading one */
      60             : )
      61             : {
      62           0 :     opus_int32 lzeros = silk_CLZ32(in);
      63             : 
      64           0 :     * lz = lzeros;
      65           0 :     * frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f;
      66           0 : }
      67             : 
      68             : /* Approximation of square root                                          */
      69             : /* Accuracy: < +/- 10%  for output values > 15                           */
      70             : /*           < +/- 2.5% for output values > 120                          */
      71           0 : static OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x )
      72             : {
      73             :     opus_int32 y, lz, frac_Q7;
      74             : 
      75           0 :     if( x <= 0 ) {
      76           0 :         return 0;
      77             :     }
      78             : 
      79           0 :     silk_CLZ_FRAC(x, &lz, &frac_Q7);
      80             : 
      81           0 :     if( lz & 1 ) {
      82           0 :         y = 32768;
      83             :     } else {
      84           0 :         y = 46214;        /* 46214 = sqrt(2) * 32768 */
      85             :     }
      86             : 
      87             :     /* get scaling right */
      88           0 :     y >>= silk_RSHIFT(lz, 1);
      89             : 
      90             :     /* increment using fractional part of input */
      91           0 :     y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7));
      92             : 
      93           0 :     return y;
      94             : }
      95             : 
      96             : /* Divide two int32 values and return result as int32 in a given Q-domain */
      97           0 : static OPUS_INLINE opus_int32 silk_DIV32_varQ(   /* O    returns a good approximation of "(a32 << Qres) / b32" */
      98             :     const opus_int32     a32,               /* I    numerator (Q0)                  */
      99             :     const opus_int32     b32,               /* I    denominator (Q0)                */
     100             :     const opus_int       Qres               /* I    Q-domain of result (>= 0)       */
     101             : )
     102             : {
     103             :     opus_int   a_headrm, b_headrm, lshift;
     104             :     opus_int32 b32_inv, a32_nrm, b32_nrm, result;
     105             : 
     106           0 :     silk_assert( b32 != 0 );
     107           0 :     silk_assert( Qres >= 0 );
     108             : 
     109             :     /* Compute number of bits head room and normalize inputs */
     110           0 :     a_headrm = silk_CLZ32( silk_abs(a32) ) - 1;
     111           0 :     a32_nrm = silk_LSHIFT(a32, a_headrm);                                       /* Q: a_headrm                  */
     112           0 :     b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;
     113           0 :     b32_nrm = silk_LSHIFT(b32, b_headrm);                                       /* Q: b_headrm                  */
     114             : 
     115             :     /* Inverse of b32, with 14 bits of precision */
     116           0 :     b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) );   /* Q: 29 + 16 - b_headrm        */
     117             : 
     118             :     /* First approximation */
     119           0 :     result = silk_SMULWB(a32_nrm, b32_inv);                                     /* Q: 29 + a_headrm - b_headrm  */
     120             : 
     121             :     /* Compute residual by subtracting product of denominator and first approximation */
     122             :     /* It's OK to overflow because the final value of a32_nrm should always be small */
     123           0 :     a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 ));  /* Q: a_headrm   */
     124             : 
     125             :     /* Refinement */
     126           0 :     result = silk_SMLAWB(result, a32_nrm, b32_inv);                             /* Q: 29 + a_headrm - b_headrm  */
     127             : 
     128             :     /* Convert to Qres domain */
     129           0 :     lshift = 29 + a_headrm - b_headrm - Qres;
     130           0 :     if( lshift < 0 ) {
     131           0 :         return silk_LSHIFT_SAT32(result, -lshift);
     132             :     } else {
     133           0 :         if( lshift < 32){
     134           0 :             return silk_RSHIFT(result, lshift);
     135             :         } else {
     136             :             /* Avoid undefined result */
     137           0 :             return 0;
     138             :         }
     139             :     }
     140             : }
     141             : 
     142             : /* Invert int32 value and return result as int32 in a given Q-domain */
     143           0 : static OPUS_INLINE opus_int32 silk_INVERSE32_varQ(   /* O    returns a good approximation of "(1 << Qres) / b32" */
     144             :     const opus_int32     b32,                   /* I    denominator (Q0)                */
     145             :     const opus_int       Qres                   /* I    Q-domain of result (> 0)        */
     146             : )
     147             : {
     148             :     opus_int   b_headrm, lshift;
     149             :     opus_int32 b32_inv, b32_nrm, err_Q32, result;
     150             : 
     151           0 :     silk_assert( b32 != 0 );
     152           0 :     silk_assert( Qres > 0 );
     153             : 
     154             :     /* Compute number of bits head room and normalize input */
     155           0 :     b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;
     156           0 :     b32_nrm = silk_LSHIFT(b32, b_headrm);                                       /* Q: b_headrm                */
     157             : 
     158             :     /* Inverse of b32, with 14 bits of precision */
     159           0 :     b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) );   /* Q: 29 + 16 - b_headrm    */
     160             : 
     161             :     /* First approximation */
     162           0 :     result = silk_LSHIFT(b32_inv, 16);                                          /* Q: 61 - b_headrm            */
     163             : 
     164             :     /* Compute residual by subtracting product of denominator and first approximation from one */
     165           0 :     err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 );        /* Q32                        */
     166             : 
     167             :     /* Refinement */
     168           0 :     result = silk_SMLAWW(result, err_Q32, b32_inv);                             /* Q: 61 - b_headrm            */
     169             : 
     170             :     /* Convert to Qres domain */
     171           0 :     lshift = 61 - b_headrm - Qres;
     172           0 :     if( lshift <= 0 ) {
     173           0 :         return silk_LSHIFT_SAT32(result, -lshift);
     174             :     } else {
     175           0 :         if( lshift < 32){
     176           0 :             return silk_RSHIFT(result, lshift);
     177             :         }else{
     178             :             /* Avoid undefined result */
     179           0 :             return 0;
     180             :         }
     181             :     }
     182             : }
     183             : 
     184             : #ifdef  __cplusplus
     185             : }
     186             : #endif
     187             : 
     188             : #endif /* SILK_FIX_INLINES_H */

Generated by: LCOV version 1.13