media/libopus/silk/NLSF_del_dec_quant.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libopus/silk/NLSF_del_dec_quant.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,207 @@
     1.4 +/***********************************************************************
     1.5 +Copyright (c) 2006-2011, Skype Limited. All rights reserved.
     1.6 +Redistribution and use in source and binary forms, with or without
     1.7 +modification, are permitted provided that the following conditions
     1.8 +are met:
     1.9 +- Redistributions of source code must retain the above copyright notice,
    1.10 +this list of conditions and the following disclaimer.
    1.11 +- Redistributions in binary form must reproduce the above copyright
    1.12 +notice, this list of conditions and the following disclaimer in the
    1.13 +documentation and/or other materials provided with the distribution.
    1.14 +- Neither the name of Internet Society, IETF or IETF Trust, nor the
    1.15 +names of specific contributors, may be used to endorse or promote
    1.16 +products derived from this software without specific prior written
    1.17 +permission.
    1.18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.21 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    1.22 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.23 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.24 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.25 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.26 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.27 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.28 +POSSIBILITY OF SUCH DAMAGE.
    1.29 +***********************************************************************/
    1.30 +
    1.31 +#ifdef HAVE_CONFIG_H
    1.32 +#include "config.h"
    1.33 +#endif
    1.34 +
    1.35 +#include "main.h"
    1.36 +
    1.37 +/* Delayed-decision quantizer for NLSF residuals */
    1.38 +opus_int32 silk_NLSF_del_dec_quant(                             /* O    Returns RD value in Q25                     */
    1.39 +    opus_int8                   indices[],                      /* O    Quantization indices [ order ]              */
    1.40 +    const opus_int16            x_Q10[],                        /* I    Input [ order ]                             */
    1.41 +    const opus_int16            w_Q5[],                         /* I    Weights [ order ]                           */
    1.42 +    const opus_uint8            pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */
    1.43 +    const opus_int16            ec_ix[],                        /* I    Indices to entropy coding tables [ order ]  */
    1.44 +    const opus_uint8            ec_rates_Q5[],                  /* I    Rates []                                    */
    1.45 +    const opus_int              quant_step_size_Q16,            /* I    Quantization step size                      */
    1.46 +    const opus_int16            inv_quant_step_size_Q6,         /* I    Inverse quantization step size              */
    1.47 +    const opus_int32            mu_Q20,                         /* I    R/D tradeoff                                */
    1.48 +    const opus_int16            order                           /* I    Number of input values                      */
    1.49 +)
    1.50 +{
    1.51 +    opus_int         i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
    1.52 +    opus_int         pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5;
    1.53 +    opus_int32       RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16;
    1.54 +    opus_int         ind_sort[         NLSF_QUANT_DEL_DEC_STATES ];
    1.55 +    opus_int8        ind[              NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
    1.56 +    opus_int16       prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
    1.57 +    opus_int32       RD_Q25[       2 * NLSF_QUANT_DEL_DEC_STATES ];
    1.58 +    opus_int32       RD_min_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
    1.59 +    opus_int32       RD_max_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
    1.60 +    const opus_uint8 *rates_Q5;
    1.61 +
    1.62 +    silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 );     /* must be power of two */
    1.63 +
    1.64 +    nStates = 1;
    1.65 +    RD_Q25[ 0 ] = 0;
    1.66 +    prev_out_Q10[ 0 ] = 0;
    1.67 +    for( i = order - 1; ; i-- ) {
    1.68 +        rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
    1.69 +        pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 );
    1.70 +        in_Q10 = x_Q10[ i ];
    1.71 +        for( j = 0; j < nStates; j++ ) {
    1.72 +            pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] );
    1.73 +            res_Q10  = silk_SUB16( in_Q10, pred_Q10 );
    1.74 +            ind_tmp  = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 );
    1.75 +            ind_tmp  = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
    1.76 +            ind[ j ][ i ] = (opus_int8)ind_tmp;
    1.77 +
    1.78 +            /* compute outputs for ind_tmp and ind_tmp + 1 */
    1.79 +            out0_Q10 = silk_LSHIFT( ind_tmp, 10 );
    1.80 +            out1_Q10 = silk_ADD16( out0_Q10, 1024 );
    1.81 +            if( ind_tmp > 0 ) {
    1.82 +                out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.83 +                out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.84 +            } else if( ind_tmp == 0 ) {
    1.85 +                out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.86 +            } else if( ind_tmp == -1 ) {
    1.87 +                out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.88 +            } else {
    1.89 +                out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.90 +                out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
    1.91 +            }
    1.92 +            out0_Q10  = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 );
    1.93 +            out1_Q10  = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 );
    1.94 +            out0_Q10  = silk_ADD16( out0_Q10, pred_Q10 );
    1.95 +            out1_Q10  = silk_ADD16( out1_Q10, pred_Q10 );
    1.96 +            prev_out_Q10[ j           ] = out0_Q10;
    1.97 +            prev_out_Q10[ j + nStates ] = out1_Q10;
    1.98 +
    1.99 +            /* compute RD for ind_tmp and ind_tmp + 1 */
   1.100 +            if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
   1.101 +                if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
   1.102 +                    rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
   1.103 +                    rate1_Q5 = 280;
   1.104 +                } else {
   1.105 +                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
   1.106 +                    rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
   1.107 +                }
   1.108 +            } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
   1.109 +                if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
   1.110 +                    rate0_Q5 = 280;
   1.111 +                    rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
   1.112 +                } else {
   1.113 +                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
   1.114 +                    rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
   1.115 +                }
   1.116 +            } else {
   1.117 +                rate0_Q5 = rates_Q5[ ind_tmp +     NLSF_QUANT_MAX_AMPLITUDE ];
   1.118 +                rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
   1.119 +            }
   1.120 +            RD_tmp_Q25            = RD_Q25[ j ];
   1.121 +            diff_Q10              = silk_SUB16( in_Q10, out0_Q10 );
   1.122 +            RD_Q25[ j ]           = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
   1.123 +            diff_Q10              = silk_SUB16( in_Q10, out1_Q10 );
   1.124 +            RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
   1.125 +        }
   1.126 +
   1.127 +        if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {
   1.128 +            /* double number of states and copy */
   1.129 +            for( j = 0; j < nStates; j++ ) {
   1.130 +                ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
   1.131 +            }
   1.132 +            nStates = silk_LSHIFT( nStates, 1 );
   1.133 +            for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
   1.134 +                ind[ j ][ i ] = ind[ j - nStates ][ i ];
   1.135 +            }
   1.136 +        } else if( i > 0 ) {
   1.137 +            /* sort lower and upper half of RD_Q25, pairwise */
   1.138 +            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
   1.139 +                if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
   1.140 +                    RD_max_Q25[ j ]                         = RD_Q25[ j ];
   1.141 +                    RD_min_Q25[ j ]                         = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
   1.142 +                    RD_Q25[ j ]                             = RD_min_Q25[ j ];
   1.143 +                    RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
   1.144 +                    /* swap prev_out values */
   1.145 +                    out0_Q10 = prev_out_Q10[ j ];
   1.146 +                    prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
   1.147 +                    prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
   1.148 +                    ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
   1.149 +                } else {
   1.150 +                    RD_min_Q25[ j ] = RD_Q25[ j ];
   1.151 +                    RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
   1.152 +                    ind_sort[ j ] = j;
   1.153 +                }
   1.154 +            }
   1.155 +            /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
   1.156 +            /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
   1.157 +            while( 1 ) {
   1.158 +                min_max_Q25 = silk_int32_MAX;
   1.159 +                max_min_Q25 = 0;
   1.160 +                ind_min_max = 0;
   1.161 +                ind_max_min = 0;
   1.162 +                for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
   1.163 +                    if( min_max_Q25 > RD_max_Q25[ j ] ) {
   1.164 +                        min_max_Q25 = RD_max_Q25[ j ];
   1.165 +                        ind_min_max = j;
   1.166 +                    }
   1.167 +                    if( max_min_Q25 < RD_min_Q25[ j ] ) {
   1.168 +                        max_min_Q25 = RD_min_Q25[ j ];
   1.169 +                        ind_max_min = j;
   1.170 +                    }
   1.171 +                }
   1.172 +                if( min_max_Q25 >= max_min_Q25 ) {
   1.173 +                    break;
   1.174 +                }
   1.175 +                /* copy ind_min_max to ind_max_min */
   1.176 +                ind_sort[     ind_max_min ] = ind_sort[     ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
   1.177 +                RD_Q25[       ind_max_min ] = RD_Q25[       ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
   1.178 +                prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
   1.179 +                RD_min_Q25[   ind_max_min ] = 0;
   1.180 +                RD_max_Q25[   ind_min_max ] = silk_int32_MAX;
   1.181 +                silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
   1.182 +            }
   1.183 +            /* increment index if it comes from the upper half */
   1.184 +            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
   1.185 +                ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
   1.186 +            }
   1.187 +        } else {  /* i == 0 */
   1.188 +            break;
   1.189 +        }
   1.190 +    }
   1.191 +
   1.192 +    /* last sample: find winner, copy indices and return RD value */
   1.193 +    ind_tmp = 0;
   1.194 +    min_Q25 = silk_int32_MAX;
   1.195 +    for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
   1.196 +        if( min_Q25 > RD_Q25[ j ] ) {
   1.197 +            min_Q25 = RD_Q25[ j ];
   1.198 +            ind_tmp = j;
   1.199 +        }
   1.200 +    }
   1.201 +    for( j = 0; j < order; j++ ) {
   1.202 +        indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
   1.203 +        silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
   1.204 +        silk_assert( indices[ j ] <=  NLSF_QUANT_MAX_AMPLITUDE_EXT );
   1.205 +    }
   1.206 +    indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
   1.207 +    silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
   1.208 +    silk_assert( min_Q25 >= 0 );
   1.209 +    return min_Q25;
   1.210 +}

mercurial