1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libopus/silk/decode_core.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,238 @@ 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 +#include "stack_alloc.h" 1.37 + 1.38 +/**********************************************************/ 1.39 +/* Core decoder. Performs inverse NSQ operation LTP + LPC */ 1.40 +/**********************************************************/ 1.41 +void silk_decode_core( 1.42 + silk_decoder_state *psDec, /* I/O Decoder state */ 1.43 + silk_decoder_control *psDecCtrl, /* I Decoder control */ 1.44 + opus_int16 xq[], /* O Decoded speech */ 1.45 + const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ 1.46 +) 1.47 +{ 1.48 + opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; 1.49 + opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; 1.50 + VARDECL( opus_int16, sLTP ); 1.51 + VARDECL( opus_int32, sLTP_Q15 ); 1.52 + opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10; 1.53 + opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14; 1.54 + VARDECL( opus_int32, res_Q14 ); 1.55 + VARDECL( opus_int32, sLPC_Q14 ); 1.56 + SAVE_STACK; 1.57 + 1.58 + silk_assert( psDec->prev_gain_Q16 != 0 ); 1.59 + 1.60 + ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); 1.61 + ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); 1.62 + ALLOC( res_Q14, psDec->subfr_length, opus_int32 ); 1.63 + ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 ); 1.64 + 1.65 + offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ]; 1.66 + 1.67 + if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) { 1.68 + NLSF_interpolation_flag = 1; 1.69 + } else { 1.70 + NLSF_interpolation_flag = 0; 1.71 + } 1.72 + 1.73 + /* Decode excitation */ 1.74 + rand_seed = psDec->indices.Seed; 1.75 + for( i = 0; i < psDec->frame_length; i++ ) { 1.76 + rand_seed = silk_RAND( rand_seed ); 1.77 + psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 ); 1.78 + if( psDec->exc_Q14[ i ] > 0 ) { 1.79 + psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4; 1.80 + } else 1.81 + if( psDec->exc_Q14[ i ] < 0 ) { 1.82 + psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4; 1.83 + } 1.84 + psDec->exc_Q14[ i ] += offset_Q10 << 4; 1.85 + if( rand_seed < 0 ) { 1.86 + psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ]; 1.87 + } 1.88 + 1.89 + rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] ); 1.90 + } 1.91 + 1.92 + /* Copy LPC state */ 1.93 + silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 1.94 + 1.95 + pexc_Q14 = psDec->exc_Q14; 1.96 + pxq = xq; 1.97 + sLTP_buf_idx = psDec->ltp_mem_length; 1.98 + /* Loop over subframes */ 1.99 + for( k = 0; k < psDec->nb_subfr; k++ ) { 1.100 + pres_Q14 = res_Q14; 1.101 + A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ]; 1.102 + 1.103 + /* Preload LPC coeficients to array on stack. Gives small performance gain */ 1.104 + silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); 1.105 + B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ]; 1.106 + signalType = psDec->indices.signalType; 1.107 + 1.108 + Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 ); 1.109 + inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 ); 1.110 + 1.111 + /* Calculate gain adjustment factor */ 1.112 + if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) { 1.113 + gain_adj_Q16 = silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 ); 1.114 + 1.115 + /* Scale short term state */ 1.116 + for( i = 0; i < MAX_LPC_ORDER; i++ ) { 1.117 + sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] ); 1.118 + } 1.119 + } else { 1.120 + gain_adj_Q16 = (opus_int32)1 << 16; 1.121 + } 1.122 + 1.123 + /* Save inv_gain */ 1.124 + silk_assert( inv_gain_Q31 != 0 ); 1.125 + psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ]; 1.126 + 1.127 + /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ 1.128 + if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED && 1.129 + psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) { 1.130 + 1.131 + silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); 1.132 + B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 ); 1.133 + 1.134 + signalType = TYPE_VOICED; 1.135 + psDecCtrl->pitchL[ k ] = psDec->lagPrev; 1.136 + } 1.137 + 1.138 + if( signalType == TYPE_VOICED ) { 1.139 + /* Voiced */ 1.140 + lag = psDecCtrl->pitchL[ k ]; 1.141 + 1.142 + /* Re-whitening */ 1.143 + if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { 1.144 + /* Rewhiten with new A coefs */ 1.145 + start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; 1.146 + silk_assert( start_idx > 0 ); 1.147 + 1.148 + if( k == 2 ) { 1.149 + silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); 1.150 + } 1.151 + 1.152 + silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], 1.153 + A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); 1.154 + 1.155 + /* After rewhitening the LTP state is unscaled */ 1.156 + if( k == 0 ) { 1.157 + /* Do LTP downscaling to reduce inter-packet dependency */ 1.158 + inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 ); 1.159 + } 1.160 + for( i = 0; i < lag + LTP_ORDER/2; i++ ) { 1.161 + sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] ); 1.162 + } 1.163 + } else { 1.164 + /* Update LTP state when Gain changes */ 1.165 + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { 1.166 + for( i = 0; i < lag + LTP_ORDER/2; i++ ) { 1.167 + sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] ); 1.168 + } 1.169 + } 1.170 + } 1.171 + } 1.172 + 1.173 + /* Long-term prediction */ 1.174 + if( signalType == TYPE_VOICED ) { 1.175 + /* Set up pointer */ 1.176 + pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; 1.177 + for( i = 0; i < psDec->subfr_length; i++ ) { 1.178 + /* Unrolled loop */ 1.179 + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 1.180 + LTP_pred_Q13 = 2; 1.181 + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); 1.182 + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); 1.183 + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); 1.184 + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); 1.185 + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); 1.186 + pred_lag_ptr++; 1.187 + 1.188 + /* Generate LPC excitation */ 1.189 + pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 ); 1.190 + 1.191 + /* Update states */ 1.192 + sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 ); 1.193 + sLTP_buf_idx++; 1.194 + } 1.195 + } else { 1.196 + pres_Q14 = pexc_Q14; 1.197 + } 1.198 + 1.199 + for( i = 0; i < psDec->subfr_length; i++ ) { 1.200 + /* Short-term prediction */ 1.201 + silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); 1.202 + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 1.203 + LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); 1.204 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); 1.205 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); 1.206 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); 1.207 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); 1.208 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); 1.209 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); 1.210 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); 1.211 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); 1.212 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); 1.213 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); 1.214 + if( psDec->LPC_order == 16 ) { 1.215 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] ); 1.216 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] ); 1.217 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] ); 1.218 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] ); 1.219 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] ); 1.220 + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] ); 1.221 + } 1.222 + 1.223 + /* Add prediction to LPC excitation */ 1.224 + sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); 1.225 + 1.226 + /* Scale with gain */ 1.227 + pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); 1.228 + } 1.229 + 1.230 + /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */ 1.231 + 1.232 + /* Update LPC filter state */ 1.233 + silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 1.234 + pexc_Q14 += psDec->subfr_length; 1.235 + pxq += psDec->subfr_length; 1.236 + } 1.237 + 1.238 + /* Save LPC state */ 1.239 + silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 1.240 + RESTORE_STACK; 1.241 +}