tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

decode_core.c (12216B)


      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 #include "stack_alloc.h"
     34 
     35 /**********************************************************/
     36 /* Core decoder. Performs inverse NSQ operation LTP + LPC */
     37 /**********************************************************/
     38 void silk_decode_core(
     39    silk_decoder_state          *psDec,                         /* I/O  Decoder state                               */
     40    silk_decoder_control        *psDecCtrl,                     /* I    Decoder control                             */
     41    opus_int16                  xq[],                           /* O    Decoded speech                              */
     42    const opus_int16            pulses[ MAX_FRAME_LENGTH ],     /* I    Pulse signal                                */
     43    int                         arch                            /* I    Run-time architecture                       */
     44 )
     45 {
     46    opus_int   i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
     47    opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
     48    VARDECL( opus_int16, sLTP );
     49    VARDECL( opus_int32, sLTP_Q15 );
     50    opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;
     51    opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14;
     52    VARDECL( opus_int32, res_Q14 );
     53    VARDECL( opus_int32, sLPC_Q14 );
     54    SAVE_STACK;
     55 
     56    silk_assert( psDec->prev_gain_Q16 != 0 );
     57 
     58    ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
     59    ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
     60    ALLOC( res_Q14, psDec->subfr_length, opus_int32 );
     61    /* Work around a clang bug (verified with clang 6.0 through clang 20.1.0) that causes the last
     62       memset to be flagged as an invalid read by valgrind (not caught by asan). */
     63 #if defined(__clang__) && defined(VAR_ARRAYS)
     64    ALLOC( sLPC_Q14, MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER, opus_int32 );
     65 #else
     66    ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 );
     67 #endif
     68 
     69    offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ];
     70 
     71    if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) {
     72        NLSF_interpolation_flag = 1;
     73    } else {
     74        NLSF_interpolation_flag = 0;
     75    }
     76 
     77    /* Decode excitation */
     78    rand_seed = psDec->indices.Seed;
     79    for( i = 0; i < psDec->frame_length; i++ ) {
     80        rand_seed = silk_RAND( rand_seed );
     81        psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 );
     82        if( psDec->exc_Q14[ i ] > 0 ) {
     83            psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4;
     84        } else
     85        if( psDec->exc_Q14[ i ] < 0 ) {
     86            psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4;
     87        }
     88        psDec->exc_Q14[ i ] += offset_Q10 << 4;
     89        if( rand_seed < 0 ) {
     90           psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ];
     91        }
     92 
     93        rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] );
     94    }
     95 
     96    /* Copy LPC state */
     97    silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
     98 
     99    pexc_Q14 = psDec->exc_Q14;
    100    pxq      = xq;
    101    sLTP_buf_idx = psDec->ltp_mem_length;
    102    /* Loop over subframes */
    103    for( k = 0; k < psDec->nb_subfr; k++ ) {
    104        pres_Q14 = res_Q14;
    105        A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];
    106 
    107        /* Preload LPC coefficients to array on stack. Gives small performance gain */
    108        silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) );
    109        B_Q14        = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];
    110        signalType   = psDec->indices.signalType;
    111 
    112        Gain_Q10     = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 );
    113        inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 );
    114 
    115        /* Calculate gain adjustment factor */
    116        if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) {
    117            gain_adj_Q16 =  silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 );
    118 
    119            /* Scale short term state */
    120            for( i = 0; i < MAX_LPC_ORDER; i++ ) {
    121                sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] );
    122            }
    123        } else {
    124            gain_adj_Q16 = (opus_int32)1 << 16;
    125        }
    126 
    127        /* Save inv_gain */
    128        silk_assert( inv_gain_Q31 != 0 );
    129        psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ];
    130 
    131        /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */
    132        if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED &&
    133            psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) {
    134 
    135            silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) );
    136            B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 );
    137 
    138            signalType = TYPE_VOICED;
    139            psDecCtrl->pitchL[ k ] = psDec->lagPrev;
    140        }
    141 
    142        if( signalType == TYPE_VOICED ) {
    143            /* Voiced */
    144            lag = psDecCtrl->pitchL[ k ];
    145 
    146            /* Re-whitening */
    147            if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
    148                /* Rewhiten with new A coefs */
    149                start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
    150                celt_assert( start_idx > 0 );
    151 
    152                if( k == 2 ) {
    153                    silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
    154                }
    155 
    156                silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ],
    157                    A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch );
    158 
    159                /* After rewhitening the LTP state is unscaled */
    160                if( k == 0 ) {
    161                    /* Do LTP downscaling to reduce inter-packet dependency */
    162                    inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 );
    163                }
    164                for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
    165                    sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] );
    166                }
    167            } else {
    168                /* Update LTP state when Gain changes */
    169                if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
    170                    for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
    171                        sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] );
    172                    }
    173                }
    174            }
    175        }
    176 
    177        /* Long-term prediction */
    178        if( signalType == TYPE_VOICED ) {
    179            /* Set up pointer */
    180            pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
    181            for( i = 0; i < psDec->subfr_length; i++ ) {
    182                /* Unrolled loop */
    183                /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
    184                LTP_pred_Q13 = 2;
    185                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[  0 ], B_Q14[ 0 ] );
    186                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
    187                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
    188                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
    189                LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
    190                pred_lag_ptr++;
    191 
    192                /* Generate LPC excitation */
    193                pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 );
    194 
    195                /* Update states */
    196                sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 );
    197                sLTP_buf_idx++;
    198            }
    199        } else {
    200            pres_Q14 = pexc_Q14;
    201        }
    202 
    203        for( i = 0; i < psDec->subfr_length; i++ ) {
    204            /* Short-term prediction */
    205            celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
    206            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
    207            LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
    208            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], A_Q12_tmp[ 0 ] );
    209            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], A_Q12_tmp[ 1 ] );
    210            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], A_Q12_tmp[ 2 ] );
    211            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], A_Q12_tmp[ 3 ] );
    212            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], A_Q12_tmp[ 4 ] );
    213            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], A_Q12_tmp[ 5 ] );
    214            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], A_Q12_tmp[ 6 ] );
    215            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], A_Q12_tmp[ 7 ] );
    216            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], A_Q12_tmp[ 8 ] );
    217            LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
    218            if( psDec->LPC_order == 16 ) {
    219                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] );
    220                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] );
    221                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] );
    222                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] );
    223                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] );
    224                LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] );
    225            }
    226 
    227            /* Add prediction to LPC excitation */
    228            sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
    229 
    230            /* Scale with gain */
    231            pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
    232        }
    233 
    234        /* Update LPC filter state */
    235        silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
    236        pexc_Q14 += psDec->subfr_length;
    237        pxq      += psDec->subfr_length;
    238    }
    239 
    240    /* Save LPC state */
    241    silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) );
    242    RESTORE_STACK;
    243 }