1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libopus/silk/NSQ_del_dec.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,719 @@ 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 +typedef struct { 1.39 + opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; 1.40 + opus_int32 RandState[ DECISION_DELAY ]; 1.41 + opus_int32 Q_Q10[ DECISION_DELAY ]; 1.42 + opus_int32 Xq_Q14[ DECISION_DELAY ]; 1.43 + opus_int32 Pred_Q15[ DECISION_DELAY ]; 1.44 + opus_int32 Shape_Q14[ DECISION_DELAY ]; 1.45 + opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; 1.46 + opus_int32 LF_AR_Q14; 1.47 + opus_int32 Seed; 1.48 + opus_int32 SeedInit; 1.49 + opus_int32 RD_Q10; 1.50 +} NSQ_del_dec_struct; 1.51 + 1.52 +typedef struct { 1.53 + opus_int32 Q_Q10; 1.54 + opus_int32 RD_Q10; 1.55 + opus_int32 xq_Q14; 1.56 + opus_int32 LF_AR_Q14; 1.57 + opus_int32 sLTP_shp_Q14; 1.58 + opus_int32 LPC_exc_Q14; 1.59 +} NSQ_sample_struct; 1.60 + 1.61 +typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; 1.62 + 1.63 +static OPUS_INLINE void silk_nsq_del_dec_scale_states( 1.64 + const silk_encoder_state *psEncC, /* I Encoder State */ 1.65 + silk_nsq_state *NSQ, /* I/O NSQ state */ 1.66 + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ 1.67 + const opus_int32 x_Q3[], /* I Input in Q3 */ 1.68 + opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ 1.69 + const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ 1.70 + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ 1.71 + opus_int subfr, /* I Subframe number */ 1.72 + opus_int nStatesDelayedDecision, /* I Number of del dec states */ 1.73 + const opus_int LTP_scale_Q14, /* I LTP state scaling */ 1.74 + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ 1.75 + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ 1.76 + const opus_int signal_type, /* I Signal type */ 1.77 + const opus_int decisionDelay /* I Decision delay */ 1.78 +); 1.79 + 1.80 +/******************************************/ 1.81 +/* Noise shape quantizer for one subframe */ 1.82 +/******************************************/ 1.83 +static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( 1.84 + silk_nsq_state *NSQ, /* I/O NSQ state */ 1.85 + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ 1.86 + opus_int signalType, /* I Signal type */ 1.87 + const opus_int32 x_Q10[], /* I */ 1.88 + opus_int8 pulses[], /* O */ 1.89 + opus_int16 xq[], /* O */ 1.90 + opus_int32 sLTP_Q15[], /* I/O LTP filter state */ 1.91 + opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ 1.92 + const opus_int16 a_Q12[], /* I Short term prediction coefs */ 1.93 + const opus_int16 b_Q14[], /* I Long term prediction coefs */ 1.94 + const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ 1.95 + opus_int lag, /* I Pitch lag */ 1.96 + opus_int32 HarmShapeFIRPacked_Q14, /* I */ 1.97 + opus_int Tilt_Q14, /* I Spectral tilt */ 1.98 + opus_int32 LF_shp_Q14, /* I */ 1.99 + opus_int32 Gain_Q16, /* I */ 1.100 + opus_int Lambda_Q10, /* I */ 1.101 + opus_int offset_Q10, /* I */ 1.102 + opus_int length, /* I Input length */ 1.103 + opus_int subfr, /* I Subframe number */ 1.104 + opus_int shapingLPCOrder, /* I Shaping LPC filter order */ 1.105 + opus_int predictLPCOrder, /* I Prediction filter order */ 1.106 + opus_int warping_Q16, /* I */ 1.107 + opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ 1.108 + opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ 1.109 + opus_int decisionDelay /* I */ 1.110 +); 1.111 + 1.112 +void silk_NSQ_del_dec( 1.113 + const silk_encoder_state *psEncC, /* I/O Encoder State */ 1.114 + silk_nsq_state *NSQ, /* I/O NSQ state */ 1.115 + SideInfoIndices *psIndices, /* I/O Quantization Indices */ 1.116 + const opus_int32 x_Q3[], /* I Prefiltered input signal */ 1.117 + opus_int8 pulses[], /* O Quantized pulse signal */ 1.118 + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 1.119 + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 1.120 + const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 1.121 + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 1.122 + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 1.123 + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 1.124 + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ 1.125 + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ 1.126 + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ 1.127 + const opus_int LTP_scale_Q14 /* I LTP state scaling */ 1.128 +) 1.129 +{ 1.130 + opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; 1.131 + opus_int last_smple_idx, smpl_buf_idx, decisionDelay; 1.132 + const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; 1.133 + opus_int16 *pxq; 1.134 + VARDECL( opus_int32, sLTP_Q15 ); 1.135 + VARDECL( opus_int16, sLTP ); 1.136 + opus_int32 HarmShapeFIRPacked_Q14; 1.137 + opus_int offset_Q10; 1.138 + opus_int32 RDmin_Q10, Gain_Q10; 1.139 + VARDECL( opus_int32, x_sc_Q10 ); 1.140 + VARDECL( opus_int32, delayedGain_Q10 ); 1.141 + VARDECL( NSQ_del_dec_struct, psDelDec ); 1.142 + NSQ_del_dec_struct *psDD; 1.143 + SAVE_STACK; 1.144 + 1.145 + /* Set unvoiced lag to the previous one, overwrite later for voiced */ 1.146 + lag = NSQ->lagPrev; 1.147 + 1.148 + silk_assert( NSQ->prev_gain_Q16 != 0 ); 1.149 + 1.150 + /* Initialize delayed decision states */ 1.151 + ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); 1.152 + silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); 1.153 + for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { 1.154 + psDD = &psDelDec[ k ]; 1.155 + psDD->Seed = ( k + psIndices->Seed ) & 3; 1.156 + psDD->SeedInit = psDD->Seed; 1.157 + psDD->RD_Q10 = 0; 1.158 + psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; 1.159 + psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; 1.160 + silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); 1.161 + silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); 1.162 + } 1.163 + 1.164 + offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; 1.165 + smpl_buf_idx = 0; /* index of oldest samples */ 1.166 + 1.167 + decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); 1.168 + 1.169 + /* For voiced frames limit the decision delay to lower than the pitch lag */ 1.170 + if( psIndices->signalType == TYPE_VOICED ) { 1.171 + for( k = 0; k < psEncC->nb_subfr; k++ ) { 1.172 + decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); 1.173 + } 1.174 + } else { 1.175 + if( lag > 0 ) { 1.176 + decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); 1.177 + } 1.178 + } 1.179 + 1.180 + if( psIndices->NLSFInterpCoef_Q2 == 4 ) { 1.181 + LSF_interpolation_flag = 0; 1.182 + } else { 1.183 + LSF_interpolation_flag = 1; 1.184 + } 1.185 + 1.186 + ALLOC( sLTP_Q15, 1.187 + psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); 1.188 + ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); 1.189 + ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); 1.190 + ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); 1.191 + /* Set up pointers to start of sub frame */ 1.192 + pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; 1.193 + NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; 1.194 + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; 1.195 + subfr = 0; 1.196 + for( k = 0; k < psEncC->nb_subfr; k++ ) { 1.197 + A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; 1.198 + B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; 1.199 + AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; 1.200 + 1.201 + /* Noise shape parameters */ 1.202 + silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); 1.203 + HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); 1.204 + HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); 1.205 + 1.206 + NSQ->rewhite_flag = 0; 1.207 + if( psIndices->signalType == TYPE_VOICED ) { 1.208 + /* Voiced */ 1.209 + lag = pitchL[ k ]; 1.210 + 1.211 + /* Re-whitening */ 1.212 + if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { 1.213 + if( k == 2 ) { 1.214 + /* RESET DELAYED DECISIONS */ 1.215 + /* Find winner */ 1.216 + RDmin_Q10 = psDelDec[ 0 ].RD_Q10; 1.217 + Winner_ind = 0; 1.218 + for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { 1.219 + if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { 1.220 + RDmin_Q10 = psDelDec[ i ].RD_Q10; 1.221 + Winner_ind = i; 1.222 + } 1.223 + } 1.224 + for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { 1.225 + if( i != Winner_ind ) { 1.226 + psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); 1.227 + silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); 1.228 + } 1.229 + } 1.230 + 1.231 + /* Copy final part of signals from winner state to output and long-term filter states */ 1.232 + psDD = &psDelDec[ Winner_ind ]; 1.233 + last_smple_idx = smpl_buf_idx + decisionDelay; 1.234 + for( i = 0; i < decisionDelay; i++ ) { 1.235 + last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; 1.236 + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); 1.237 + pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( 1.238 + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); 1.239 + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; 1.240 + } 1.241 + 1.242 + subfr = 0; 1.243 + } 1.244 + 1.245 + /* Rewhiten with new A coefs */ 1.246 + start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; 1.247 + silk_assert( start_idx > 0 ); 1.248 + 1.249 + silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], 1.250 + A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder ); 1.251 + 1.252 + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; 1.253 + NSQ->rewhite_flag = 1; 1.254 + } 1.255 + } 1.256 + 1.257 + silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, 1.258 + psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); 1.259 + 1.260 + silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, 1.261 + delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], 1.262 + Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, 1.263 + psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); 1.264 + 1.265 + x_Q3 += psEncC->subfr_length; 1.266 + pulses += psEncC->subfr_length; 1.267 + pxq += psEncC->subfr_length; 1.268 + } 1.269 + 1.270 + /* Find winner */ 1.271 + RDmin_Q10 = psDelDec[ 0 ].RD_Q10; 1.272 + Winner_ind = 0; 1.273 + for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { 1.274 + if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { 1.275 + RDmin_Q10 = psDelDec[ k ].RD_Q10; 1.276 + Winner_ind = k; 1.277 + } 1.278 + } 1.279 + 1.280 + /* Copy final part of signals from winner state to output and long-term filter states */ 1.281 + psDD = &psDelDec[ Winner_ind ]; 1.282 + psIndices->Seed = psDD->SeedInit; 1.283 + last_smple_idx = smpl_buf_idx + decisionDelay; 1.284 + Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); 1.285 + for( i = 0; i < decisionDelay; i++ ) { 1.286 + last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; 1.287 + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); 1.288 + pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( 1.289 + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); 1.290 + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; 1.291 + } 1.292 + silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); 1.293 + silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); 1.294 + 1.295 + /* Update states */ 1.296 + NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; 1.297 + NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; 1.298 + 1.299 + /* Save quantized speech signal */ 1.300 + /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */ 1.301 + silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); 1.302 + silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); 1.303 + RESTORE_STACK; 1.304 +} 1.305 + 1.306 +/******************************************/ 1.307 +/* Noise shape quantizer for one subframe */ 1.308 +/******************************************/ 1.309 +static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( 1.310 + silk_nsq_state *NSQ, /* I/O NSQ state */ 1.311 + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ 1.312 + opus_int signalType, /* I Signal type */ 1.313 + const opus_int32 x_Q10[], /* I */ 1.314 + opus_int8 pulses[], /* O */ 1.315 + opus_int16 xq[], /* O */ 1.316 + opus_int32 sLTP_Q15[], /* I/O LTP filter state */ 1.317 + opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ 1.318 + const opus_int16 a_Q12[], /* I Short term prediction coefs */ 1.319 + const opus_int16 b_Q14[], /* I Long term prediction coefs */ 1.320 + const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ 1.321 + opus_int lag, /* I Pitch lag */ 1.322 + opus_int32 HarmShapeFIRPacked_Q14, /* I */ 1.323 + opus_int Tilt_Q14, /* I Spectral tilt */ 1.324 + opus_int32 LF_shp_Q14, /* I */ 1.325 + opus_int32 Gain_Q16, /* I */ 1.326 + opus_int Lambda_Q10, /* I */ 1.327 + opus_int offset_Q10, /* I */ 1.328 + opus_int length, /* I Input length */ 1.329 + opus_int subfr, /* I Subframe number */ 1.330 + opus_int shapingLPCOrder, /* I Shaping LPC filter order */ 1.331 + opus_int predictLPCOrder, /* I Prediction filter order */ 1.332 + opus_int warping_Q16, /* I */ 1.333 + opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ 1.334 + opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ 1.335 + opus_int decisionDelay /* I */ 1.336 +) 1.337 +{ 1.338 + opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; 1.339 + opus_int32 Winner_rand_state; 1.340 + opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; 1.341 + opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; 1.342 + opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; 1.343 + opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; 1.344 + opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; 1.345 + VARDECL( NSQ_sample_pair, psSampleState ); 1.346 + NSQ_del_dec_struct *psDD; 1.347 + NSQ_sample_struct *psSS; 1.348 + SAVE_STACK; 1.349 + 1.350 + silk_assert( nStatesDelayedDecision > 0 ); 1.351 + ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); 1.352 + 1.353 + shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; 1.354 + pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; 1.355 + Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); 1.356 + 1.357 + for( i = 0; i < length; i++ ) { 1.358 + /* Perform common calculations used in all states */ 1.359 + 1.360 + /* Long-term prediction */ 1.361 + if( signalType == TYPE_VOICED ) { 1.362 + /* Unrolled loop */ 1.363 + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 1.364 + LTP_pred_Q14 = 2; 1.365 + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); 1.366 + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); 1.367 + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); 1.368 + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); 1.369 + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); 1.370 + LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ 1.371 + pred_lag_ptr++; 1.372 + } else { 1.373 + LTP_pred_Q14 = 0; 1.374 + } 1.375 + 1.376 + /* Long-term shaping */ 1.377 + if( lag > 0 ) { 1.378 + /* Symmetric, packed FIR coefficients */ 1.379 + n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); 1.380 + n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); 1.381 + n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ 1.382 + shp_lag_ptr++; 1.383 + } else { 1.384 + n_LTP_Q14 = 0; 1.385 + } 1.386 + 1.387 + for( k = 0; k < nStatesDelayedDecision; k++ ) { 1.388 + /* Delayed decision state */ 1.389 + psDD = &psDelDec[ k ]; 1.390 + 1.391 + /* Sample state */ 1.392 + psSS = psSampleState[ k ]; 1.393 + 1.394 + /* Generate dither */ 1.395 + psDD->Seed = silk_RAND( psDD->Seed ); 1.396 + 1.397 + /* Pointer used in short term prediction and shaping */ 1.398 + psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; 1.399 + /* Short-term prediction */ 1.400 + silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); 1.401 + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 1.402 + LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 ); 1.403 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] ); 1.404 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); 1.405 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); 1.406 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); 1.407 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); 1.408 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); 1.409 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); 1.410 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); 1.411 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); 1.412 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); 1.413 + if( predictLPCOrder == 16 ) { 1.414 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] ); 1.415 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] ); 1.416 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] ); 1.417 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] ); 1.418 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] ); 1.419 + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] ); 1.420 + } 1.421 + LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ 1.422 + 1.423 + /* Noise shape feedback */ 1.424 + silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ 1.425 + /* Output of lowpass section */ 1.426 + tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); 1.427 + /* Output of allpass section */ 1.428 + tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); 1.429 + psDD->sAR2_Q14[ 0 ] = tmp2; 1.430 + n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); 1.431 + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); 1.432 + /* Loop over allpass sections */ 1.433 + for( j = 2; j < shapingLPCOrder; j += 2 ) { 1.434 + /* Output of allpass section */ 1.435 + tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); 1.436 + psDD->sAR2_Q14[ j - 1 ] = tmp1; 1.437 + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); 1.438 + /* Output of allpass section */ 1.439 + tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); 1.440 + psDD->sAR2_Q14[ j + 0 ] = tmp2; 1.441 + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); 1.442 + } 1.443 + psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; 1.444 + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); 1.445 + 1.446 + n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ 1.447 + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ 1.448 + n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ 1.449 + 1.450 + n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ 1.451 + n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ 1.452 + n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ 1.453 + 1.454 + /* Input minus prediction plus noise feedback */ 1.455 + /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ 1.456 + tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ 1.457 + tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ 1.458 + tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ 1.459 + tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ 1.460 + 1.461 + r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ 1.462 + 1.463 + /* Flip sign depending on dither */ 1.464 + if ( psDD->Seed < 0 ) { 1.465 + r_Q10 = -r_Q10; 1.466 + } 1.467 + r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); 1.468 + 1.469 + /* Find two quantization level candidates and measure their rate-distortion */ 1.470 + q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); 1.471 + q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); 1.472 + if( q1_Q0 > 0 ) { 1.473 + q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); 1.474 + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); 1.475 + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); 1.476 + rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); 1.477 + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 1.478 + } else if( q1_Q0 == 0 ) { 1.479 + q1_Q10 = offset_Q10; 1.480 + q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); 1.481 + rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); 1.482 + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 1.483 + } else if( q1_Q0 == -1 ) { 1.484 + q2_Q10 = offset_Q10; 1.485 + q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); 1.486 + rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); 1.487 + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 1.488 + } else { /* q1_Q0 < -1 */ 1.489 + q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); 1.490 + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); 1.491 + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); 1.492 + rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); 1.493 + rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); 1.494 + } 1.495 + rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); 1.496 + rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); 1.497 + rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); 1.498 + rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); 1.499 + 1.500 + if( rd1_Q10 < rd2_Q10 ) { 1.501 + psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); 1.502 + psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); 1.503 + psSS[ 0 ].Q_Q10 = q1_Q10; 1.504 + psSS[ 1 ].Q_Q10 = q2_Q10; 1.505 + } else { 1.506 + psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); 1.507 + psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); 1.508 + psSS[ 0 ].Q_Q10 = q2_Q10; 1.509 + psSS[ 1 ].Q_Q10 = q1_Q10; 1.510 + } 1.511 + 1.512 + /* Update states for best quantization */ 1.513 + 1.514 + /* Quantized excitation */ 1.515 + exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); 1.516 + if ( psDD->Seed < 0 ) { 1.517 + exc_Q14 = -exc_Q14; 1.518 + } 1.519 + 1.520 + /* Add predictions */ 1.521 + LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); 1.522 + xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); 1.523 + 1.524 + /* Update states */ 1.525 + sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); 1.526 + psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); 1.527 + psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; 1.528 + psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; 1.529 + psSS[ 0 ].xq_Q14 = xq_Q14; 1.530 + 1.531 + /* Update states for second best quantization */ 1.532 + 1.533 + /* Quantized excitation */ 1.534 + exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); 1.535 + if ( psDD->Seed < 0 ) { 1.536 + exc_Q14 = -exc_Q14; 1.537 + } 1.538 + 1.539 + 1.540 + /* Add predictions */ 1.541 + LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); 1.542 + xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); 1.543 + 1.544 + /* Update states */ 1.545 + sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); 1.546 + psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); 1.547 + psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; 1.548 + psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; 1.549 + psSS[ 1 ].xq_Q14 = xq_Q14; 1.550 + } 1.551 + 1.552 + *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */ 1.553 + last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */ 1.554 + 1.555 + /* Find winner */ 1.556 + RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; 1.557 + Winner_ind = 0; 1.558 + for( k = 1; k < nStatesDelayedDecision; k++ ) { 1.559 + if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { 1.560 + RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; 1.561 + Winner_ind = k; 1.562 + } 1.563 + } 1.564 + 1.565 + /* Increase RD values of expired states */ 1.566 + Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; 1.567 + for( k = 0; k < nStatesDelayedDecision; k++ ) { 1.568 + if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { 1.569 + psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); 1.570 + psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); 1.571 + silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); 1.572 + } 1.573 + } 1.574 + 1.575 + /* Find worst in first set and best in second set */ 1.576 + RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; 1.577 + RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; 1.578 + RDmax_ind = 0; 1.579 + RDmin_ind = 0; 1.580 + for( k = 1; k < nStatesDelayedDecision; k++ ) { 1.581 + /* find worst in first set */ 1.582 + if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { 1.583 + RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; 1.584 + RDmax_ind = k; 1.585 + } 1.586 + /* find best in second set */ 1.587 + if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { 1.588 + RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; 1.589 + RDmin_ind = k; 1.590 + } 1.591 + } 1.592 + 1.593 + /* Replace a state if best from second set outperforms worst in first set */ 1.594 + if( RDmin_Q10 < RDmax_Q10 ) { 1.595 + silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, 1.596 + ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); 1.597 + silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); 1.598 + } 1.599 + 1.600 + /* Write samples from winner to output and long-term filter states */ 1.601 + psDD = &psDelDec[ Winner_ind ]; 1.602 + if( subfr > 0 || i >= decisionDelay ) { 1.603 + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); 1.604 + xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( 1.605 + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); 1.606 + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; 1.607 + sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; 1.608 + } 1.609 + NSQ->sLTP_shp_buf_idx++; 1.610 + NSQ->sLTP_buf_idx++; 1.611 + 1.612 + /* Update states */ 1.613 + for( k = 0; k < nStatesDelayedDecision; k++ ) { 1.614 + psDD = &psDelDec[ k ]; 1.615 + psSS = &psSampleState[ k ][ 0 ]; 1.616 + psDD->LF_AR_Q14 = psSS->LF_AR_Q14; 1.617 + psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; 1.618 + psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; 1.619 + psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; 1.620 + psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); 1.621 + psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; 1.622 + psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); 1.623 + psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; 1.624 + psDD->RD_Q10 = psSS->RD_Q10; 1.625 + } 1.626 + delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; 1.627 + } 1.628 + /* Update LPC states */ 1.629 + for( k = 0; k < nStatesDelayedDecision; k++ ) { 1.630 + psDD = &psDelDec[ k ]; 1.631 + silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); 1.632 + } 1.633 + RESTORE_STACK; 1.634 +} 1.635 + 1.636 +static OPUS_INLINE void silk_nsq_del_dec_scale_states( 1.637 + const silk_encoder_state *psEncC, /* I Encoder State */ 1.638 + silk_nsq_state *NSQ, /* I/O NSQ state */ 1.639 + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ 1.640 + const opus_int32 x_Q3[], /* I Input in Q3 */ 1.641 + opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ 1.642 + const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ 1.643 + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ 1.644 + opus_int subfr, /* I Subframe number */ 1.645 + opus_int nStatesDelayedDecision, /* I Number of del dec states */ 1.646 + const opus_int LTP_scale_Q14, /* I LTP state scaling */ 1.647 + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ 1.648 + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ 1.649 + const opus_int signal_type, /* I Signal type */ 1.650 + const opus_int decisionDelay /* I Decision delay */ 1.651 +) 1.652 +{ 1.653 + opus_int i, k, lag; 1.654 + opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; 1.655 + NSQ_del_dec_struct *psDD; 1.656 + 1.657 + lag = pitchL[ subfr ]; 1.658 + inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); 1.659 + silk_assert( inv_gain_Q31 != 0 ); 1.660 + 1.661 + /* Calculate gain adjustment factor */ 1.662 + if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { 1.663 + gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); 1.664 + } else { 1.665 + gain_adj_Q16 = (opus_int32)1 << 16; 1.666 + } 1.667 + 1.668 + /* Scale input */ 1.669 + inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); 1.670 + for( i = 0; i < psEncC->subfr_length; i++ ) { 1.671 + x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); 1.672 + } 1.673 + 1.674 + /* Save inverse gain */ 1.675 + NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; 1.676 + 1.677 + /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ 1.678 + if( NSQ->rewhite_flag ) { 1.679 + if( subfr == 0 ) { 1.680 + /* Do LTP downscaling */ 1.681 + inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); 1.682 + } 1.683 + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { 1.684 + silk_assert( i < MAX_FRAME_LENGTH ); 1.685 + sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); 1.686 + } 1.687 + } 1.688 + 1.689 + /* Adjust for changing gain */ 1.690 + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { 1.691 + /* Scale long-term shaping state */ 1.692 + for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { 1.693 + NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); 1.694 + } 1.695 + 1.696 + /* Scale long-term prediction state */ 1.697 + if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { 1.698 + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { 1.699 + sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); 1.700 + } 1.701 + } 1.702 + 1.703 + for( k = 0; k < nStatesDelayedDecision; k++ ) { 1.704 + psDD = &psDelDec[ k ]; 1.705 + 1.706 + /* Scale scalar states */ 1.707 + psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); 1.708 + 1.709 + /* Scale short-term prediction and shaping states */ 1.710 + for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { 1.711 + psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); 1.712 + } 1.713 + for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { 1.714 + psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); 1.715 + } 1.716 + for( i = 0; i < DECISION_DELAY; i++ ) { 1.717 + psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); 1.718 + psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); 1.719 + } 1.720 + } 1.721 + } 1.722 +}