LCOV - code coverage report
Current view: top level - media/libopus/silk - NLSF_del_dec_quant.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 106 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 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             : #ifdef HAVE_CONFIG_H
      29             : #include "config.h"
      30             : #endif
      31             : 
      32             : #include "main.h"
      33             : 
      34             : /* Delayed-decision quantizer for NLSF residuals */
      35           0 : opus_int32 silk_NLSF_del_dec_quant(                             /* O    Returns RD value in Q25                     */
      36             :     opus_int8                   indices[],                      /* O    Quantization indices [ order ]              */
      37             :     const opus_int16            x_Q10[],                        /* I    Input [ order ]                             */
      38             :     const opus_int16            w_Q5[],                         /* I    Weights [ order ]                           */
      39             :     const opus_uint8            pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */
      40             :     const opus_int16            ec_ix[],                        /* I    Indices to entropy coding tables [ order ]  */
      41             :     const opus_uint8            ec_rates_Q5[],                  /* I    Rates []                                    */
      42             :     const opus_int              quant_step_size_Q16,            /* I    Quantization step size                      */
      43             :     const opus_int16            inv_quant_step_size_Q6,         /* I    Inverse quantization step size              */
      44             :     const opus_int32            mu_Q20,                         /* I    R/D tradeoff                                */
      45             :     const opus_int16            order                           /* I    Number of input values                      */
      46             : )
      47             : {
      48             :     opus_int         i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
      49             :     opus_int         pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
      50             :     opus_int16       out0_Q10, out1_Q10;
      51             :     opus_int32       RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
      52             :     opus_int         ind_sort[         NLSF_QUANT_DEL_DEC_STATES ];
      53             :     opus_int8        ind[              NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
      54             :     opus_int16       prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
      55             :     opus_int32       RD_Q25[       2 * NLSF_QUANT_DEL_DEC_STATES ];
      56             :     opus_int32       RD_min_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
      57             :     opus_int32       RD_max_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
      58             :     const opus_uint8 *rates_Q5;
      59             : 
      60             :     opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
      61             :     opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
      62             : 
      63           0 :     for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
      64             :     {
      65           0 :         out0_Q10 = silk_LSHIFT( i, 10 );
      66           0 :         out1_Q10 = silk_ADD16( out0_Q10, 1024 );
      67           0 :         if( i > 0 ) {
      68           0 :             out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      69           0 :             out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      70           0 :         } else if( i == 0 ) {
      71           0 :             out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      72           0 :         } else if( i == -1 ) {
      73           0 :             out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      74             :         } else {
      75           0 :             out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      76           0 :             out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
      77             :         }
      78           0 :         out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
      79           0 :         out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
      80             :     }
      81             : 
      82             :     silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 );     /* must be power of two */
      83             : 
      84           0 :     nStates = 1;
      85           0 :     RD_Q25[ 0 ] = 0;
      86           0 :     prev_out_Q10[ 0 ] = 0;
      87           0 :     for( i = order - 1; i >= 0; i-- ) {
      88           0 :         rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
      89           0 :         in_Q10 = x_Q10[ i ];
      90           0 :         for( j = 0; j < nStates; j++ ) {
      91           0 :             pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
      92           0 :             res_Q10  = silk_SUB16( in_Q10, pred_Q10 );
      93           0 :             ind_tmp  = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
      94           0 :             ind_tmp  = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
      95           0 :             ind[ j ][ i ] = (opus_int8)ind_tmp;
      96             : 
      97             :             /* compute outputs for ind_tmp and ind_tmp + 1 */
      98           0 :             out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
      99           0 :             out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
     100             : 
     101           0 :             out0_Q10  = silk_ADD16( out0_Q10, pred_Q10 );
     102           0 :             out1_Q10  = silk_ADD16( out1_Q10, pred_Q10 );
     103           0 :             prev_out_Q10[ j           ] = out0_Q10;
     104           0 :             prev_out_Q10[ j + nStates ] = out1_Q10;
     105             : 
     106             :             /* compute RD for ind_tmp and ind_tmp + 1 */
     107           0 :             if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
     108           0 :                 if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
     109           0 :                     rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
     110           0 :                     rate1_Q5 = 280;
     111             :                 } else {
     112           0 :                     rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
     113           0 :                     rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
     114             :                 }
     115           0 :             } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
     116           0 :                 if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
     117           0 :                     rate0_Q5 = 280;
     118           0 :                     rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
     119             :                 } else {
     120           0 :                     rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
     121           0 :                     rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
     122             :                 }
     123             :             } else {
     124           0 :                 rate0_Q5 = rates_Q5[ ind_tmp +     NLSF_QUANT_MAX_AMPLITUDE ];
     125           0 :                 rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
     126             :             }
     127           0 :             RD_tmp_Q25            = RD_Q25[ j ];
     128           0 :             diff_Q10              = silk_SUB16( in_Q10, out0_Q10 );
     129           0 :             RD_Q25[ j ]           = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
     130           0 :             diff_Q10              = silk_SUB16( in_Q10, out1_Q10 );
     131           0 :             RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
     132             :         }
     133             : 
     134           0 :         if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
     135             :             /* double number of states and copy */
     136           0 :             for( j = 0; j < nStates; j++ ) {
     137           0 :                 ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
     138             :             }
     139           0 :             nStates = silk_LSHIFT( nStates, 1 );
     140           0 :             for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
     141           0 :                 ind[ j ][ i ] = ind[ j - nStates ][ i ];
     142             :             }
     143             :         } else {
     144             :             /* sort lower and upper half of RD_Q25, pairwise */
     145           0 :             for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
     146           0 :                 if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
     147           0 :                     RD_max_Q25[ j ]                         = RD_Q25[ j ];
     148           0 :                     RD_min_Q25[ j ]                         = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
     149           0 :                     RD_Q25[ j ]                             = RD_min_Q25[ j ];
     150           0 :                     RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
     151             :                     /* swap prev_out values */
     152           0 :                     out0_Q10 = prev_out_Q10[ j ];
     153           0 :                     prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
     154           0 :                     prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
     155           0 :                     ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
     156             :                 } else {
     157           0 :                     RD_min_Q25[ j ] = RD_Q25[ j ];
     158           0 :                     RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
     159           0 :                     ind_sort[ j ] = j;
     160             :                 }
     161             :             }
     162             :             /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
     163             :             /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
     164             :             while( 1 ) {
     165           0 :                 min_max_Q25 = silk_int32_MAX;
     166           0 :                 max_min_Q25 = 0;
     167           0 :                 ind_min_max = 0;
     168           0 :                 ind_max_min = 0;
     169           0 :                 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
     170           0 :                     if( min_max_Q25 > RD_max_Q25[ j ] ) {
     171           0 :                         min_max_Q25 = RD_max_Q25[ j ];
     172           0 :                         ind_min_max = j;
     173             :                     }
     174           0 :                     if( max_min_Q25 < RD_min_Q25[ j ] ) {
     175           0 :                         max_min_Q25 = RD_min_Q25[ j ];
     176           0 :                         ind_max_min = j;
     177             :                     }
     178             :                 }
     179           0 :                 if( min_max_Q25 >= max_min_Q25 ) {
     180           0 :                     break;
     181             :                 }
     182             :                 /* copy ind_min_max to ind_max_min */
     183           0 :                 ind_sort[     ind_max_min ] = ind_sort[     ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
     184           0 :                 RD_Q25[       ind_max_min ] = RD_Q25[       ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
     185           0 :                 prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
     186           0 :                 RD_min_Q25[   ind_max_min ] = 0;
     187           0 :                 RD_max_Q25[   ind_min_max ] = silk_int32_MAX;
     188           0 :                 silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
     189             :             }
     190             :             /* increment index if it comes from the upper half */
     191           0 :             for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
     192           0 :                 ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
     193             :             }
     194             :         }
     195             :     }
     196             : 
     197             :     /* last sample: find winner, copy indices and return RD value */
     198           0 :     ind_tmp = 0;
     199           0 :     min_Q25 = silk_int32_MAX;
     200           0 :     for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
     201           0 :         if( min_Q25 > RD_Q25[ j ] ) {
     202           0 :             min_Q25 = RD_Q25[ j ];
     203           0 :             ind_tmp = j;
     204             :         }
     205             :     }
     206           0 :     for( j = 0; j < order; j++ ) {
     207           0 :         indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
     208           0 :         silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
     209           0 :         silk_assert( indices[ j ] <=  NLSF_QUANT_MAX_AMPLITUDE_EXT );
     210             :     }
     211           0 :     indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
     212           0 :     silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
     213           0 :     silk_assert( min_Q25 >= 0 );
     214           0 :     return min_Q25;
     215             : }

Generated by: LCOV version 1.13