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 #include "NSQ.h" 35 36 37 static OPUS_INLINE void silk_nsq_scale_states( 38 const silk_encoder_state *psEncC, /* I Encoder State */ 39 silk_nsq_state *NSQ, /* I/O NSQ state */ 40 const opus_int16 x16[], /* I input */ 41 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ 42 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ 43 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ 44 opus_int subfr, /* I subframe number */ 45 const opus_int LTP_scale_Q14, /* I */ 46 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ 47 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ 48 const opus_int signal_type /* I Signal type */ 49 ); 50 51 #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) 52 static OPUS_INLINE void silk_noise_shape_quantizer( 53 silk_nsq_state *NSQ, /* I/O NSQ state */ 54 opus_int signalType, /* I Signal type */ 55 const opus_int32 x_sc_Q10[], /* I */ 56 opus_int8 pulses[], /* O */ 57 opus_int16 xq[], /* O */ 58 opus_int32 sLTP_Q15[], /* I/O LTP state */ 59 const opus_int16 a_Q12[], /* I Short term prediction coefs */ 60 const opus_int16 b_Q14[], /* I Long term prediction coefs */ 61 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ 62 opus_int lag, /* I Pitch lag */ 63 opus_int32 HarmShapeFIRPacked_Q14, /* I */ 64 opus_int Tilt_Q14, /* I Spectral tilt */ 65 opus_int32 LF_shp_Q14, /* I */ 66 opus_int32 Gain_Q16, /* I */ 67 opus_int Lambda_Q10, /* I */ 68 opus_int offset_Q10, /* I */ 69 opus_int length, /* I Input length */ 70 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ 71 opus_int predictLPCOrder, /* I Prediction filter order */ 72 int arch /* I Architecture */ 73 ); 74 #endif 75 76 void silk_NSQ_c 77 ( 78 const silk_encoder_state *psEncC, /* I Encoder State */ 79 silk_nsq_state *NSQ, /* I/O NSQ state */ 80 SideInfoIndices *psIndices, /* I/O Quantization Indices */ 81 const opus_int16 x16[], /* I Input */ 82 opus_int8 pulses[], /* O Quantized pulse signal */ 83 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 84 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 85 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 86 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 87 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 88 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 89 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ 90 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ 91 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ 92 const opus_int LTP_scale_Q14 /* I LTP state scaling */ 93 ) 94 { 95 opus_int k, lag, start_idx, LSF_interpolation_flag; 96 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; 97 opus_int16 *pxq; 98 VARDECL( opus_int32, sLTP_Q15 ); 99 VARDECL( opus_int16, sLTP ); 100 opus_int32 HarmShapeFIRPacked_Q14; 101 opus_int offset_Q10; 102 VARDECL( opus_int32, x_sc_Q10 ); 103 SAVE_STACK; 104 105 NSQ->rand_seed = psIndices->Seed; 106 107 /* Set unvoiced lag to the previous one, overwrite later for voiced */ 108 lag = NSQ->lagPrev; 109 110 silk_assert( NSQ->prev_gain_Q16 != 0 ); 111 112 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; 113 114 if( psIndices->NLSFInterpCoef_Q2 == 4 ) { 115 LSF_interpolation_flag = 0; 116 } else { 117 LSF_interpolation_flag = 1; 118 } 119 120 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); 121 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); 122 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); 123 /* Set up pointers to start of sub frame */ 124 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; 125 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; 126 pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; 127 for( k = 0; k < psEncC->nb_subfr; k++ ) { 128 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; 129 B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; 130 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; 131 132 /* Noise shape parameters */ 133 silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); 134 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); 135 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); 136 137 NSQ->rewhite_flag = 0; 138 if( psIndices->signalType == TYPE_VOICED ) { 139 /* Voiced */ 140 lag = pitchL[ k ]; 141 142 /* Re-whitening */ 143 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { 144 /* Rewhiten with new A coefs */ 145 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; 146 silk_assert( start_idx > 0 ); 147 148 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], 149 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); 150 151 NSQ->rewhite_flag = 1; 152 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; 153 } 154 } 155 156 silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); 157 158 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, 159 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, 160 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); 161 162 x16 += psEncC->subfr_length; 163 pulses += psEncC->subfr_length; 164 pxq += psEncC->subfr_length; 165 } 166 167 /* Update lagPrev for next frame */ 168 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; 169 170 /* Save quantized speech and noise shaping signals */ 171 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); 172 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); 173 RESTORE_STACK; 174 } 175 176 /***********************************/ 177 /* silk_noise_shape_quantizer */ 178 /***********************************/ 179 180 #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) 181 static OPUS_INLINE 182 #endif 183 void silk_noise_shape_quantizer( 184 silk_nsq_state *NSQ, /* I/O NSQ state */ 185 opus_int signalType, /* I Signal type */ 186 const opus_int32 x_sc_Q10[], /* I */ 187 opus_int8 pulses[], /* O */ 188 opus_int16 xq[], /* O */ 189 opus_int32 sLTP_Q15[], /* I/O LTP state */ 190 const opus_int16 a_Q12[], /* I Short term prediction coefs */ 191 const opus_int16 b_Q14[], /* I Long term prediction coefs */ 192 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ 193 opus_int lag, /* I Pitch lag */ 194 opus_int32 HarmShapeFIRPacked_Q14, /* I */ 195 opus_int Tilt_Q14, /* I Spectral tilt */ 196 opus_int32 LF_shp_Q14, /* I */ 197 opus_int32 Gain_Q16, /* I */ 198 opus_int Lambda_Q10, /* I */ 199 opus_int offset_Q10, /* I */ 200 opus_int length, /* I Input length */ 201 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ 202 opus_int predictLPCOrder, /* I Prediction filter order */ 203 int arch /* I Architecture */ 204 ) 205 { 206 opus_int i; 207 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; 208 opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; 209 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; 210 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; 211 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; 212 #ifdef silk_short_prediction_create_arch_coef 213 opus_int32 a_Q12_arch[MAX_LPC_ORDER]; 214 #endif 215 216 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; 217 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; 218 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); 219 220 /* Set up short term AR state */ 221 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; 222 223 #ifdef silk_short_prediction_create_arch_coef 224 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); 225 #endif 226 227 for( i = 0; i < length; i++ ) { 228 /* Generate dither */ 229 NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); 230 231 /* Short-term prediction */ 232 LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); 233 234 /* Long-term prediction */ 235 if( signalType == TYPE_VOICED ) { 236 /* Unrolled loop */ 237 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 238 LTP_pred_Q13 = 2; 239 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); 240 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); 241 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); 242 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); 243 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); 244 pred_lag_ptr++; 245 } else { 246 LTP_pred_Q13 = 0; 247 } 248 249 /* Noise shape feedback */ 250 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ 251 n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch); 252 253 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); 254 255 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); 256 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); 257 258 silk_assert( lag > 0 || signalType != TYPE_VOICED ); 259 260 /* Combine prediction and noise shaping signals */ 261 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ 262 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ 263 if( lag > 0 ) { 264 /* Symmetric, packed FIR coefficients */ 265 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); 266 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); 267 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); 268 shp_lag_ptr++; 269 270 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ 271 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ 272 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ 273 } else { 274 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ 275 } 276 277 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ 278 279 /* Flip sign depending on dither */ 280 if( NSQ->rand_seed < 0 ) { 281 r_Q10 = -r_Q10; 282 } 283 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); 284 285 /* Find two quantization level candidates and measure their rate-distortion */ 286 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); 287 q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); 288 if (Lambda_Q10 > 2048) { 289 /* For aggressive RDO, the bias becomes more than one pulse. */ 290 int rdo_offset = Lambda_Q10/2 - 512; 291 if (q1_Q10 > rdo_offset) { 292 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); 293 } else if (q1_Q10 < -rdo_offset) { 294 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); 295 } else if (q1_Q10 < 0) { 296 q1_Q0 = -1; 297 } else { 298 q1_Q0 = 0; 299 } 300 } 301 if( q1_Q0 > 0 ) { 302 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); 303 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); 304 q2_Q10 = silk_ADD32( q1_Q10, 1024 ); 305 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); 306 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 307 } else if( q1_Q0 == 0 ) { 308 q1_Q10 = offset_Q10; 309 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); 310 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); 311 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 312 } else if( q1_Q0 == -1 ) { 313 q2_Q10 = offset_Q10; 314 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); 315 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); 316 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); 317 } else { /* Q1_Q0 < -1 */ 318 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); 319 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); 320 q2_Q10 = silk_ADD32( q1_Q10, 1024 ); 321 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); 322 rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); 323 } 324 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); 325 rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); 326 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); 327 rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); 328 329 if( rd2_Q20 < rd1_Q20 ) { 330 q1_Q10 = q2_Q10; 331 } 332 333 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); 334 335 /* Excitation */ 336 exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); 337 if ( NSQ->rand_seed < 0 ) { 338 exc_Q14 = -exc_Q14; 339 } 340 341 /* Add predictions */ 342 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); 343 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); 344 345 /* Scale XQ back to normal level before saving */ 346 xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); 347 348 /* Update states */ 349 psLPC_Q14++; 350 *psLPC_Q14 = xq_Q14; 351 NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 ); 352 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 ); 353 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; 354 355 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); 356 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); 357 NSQ->sLTP_shp_buf_idx++; 358 NSQ->sLTP_buf_idx++; 359 360 /* Make dither dependent on quantized signal */ 361 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); 362 } 363 364 /* Update LPC synth buffer */ 365 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); 366 } 367 368 static OPUS_INLINE void silk_nsq_scale_states( 369 const silk_encoder_state *psEncC, /* I Encoder State */ 370 silk_nsq_state *NSQ, /* I/O NSQ state */ 371 const opus_int16 x16[], /* I input */ 372 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ 373 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ 374 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ 375 opus_int subfr, /* I subframe number */ 376 const opus_int LTP_scale_Q14, /* I */ 377 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ 378 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ 379 const opus_int signal_type /* I Signal type */ 380 ) 381 { 382 opus_int i, lag; 383 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; 384 385 lag = pitchL[ subfr ]; 386 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); 387 silk_assert( inv_gain_Q31 != 0 ); 388 389 /* Scale input */ 390 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); 391 for( i = 0; i < psEncC->subfr_length; i++ ) { 392 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); 393 } 394 395 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ 396 if( NSQ->rewhite_flag ) { 397 if( subfr == 0 ) { 398 /* Do LTP downscaling */ 399 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); 400 } 401 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { 402 silk_assert( i < MAX_FRAME_LENGTH ); 403 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); 404 } 405 } 406 407 /* Adjust for changing gain */ 408 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { 409 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); 410 411 /* Scale long-term shaping state */ 412 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { 413 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); 414 } 415 416 /* Scale long-term prediction state */ 417 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { 418 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { 419 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); 420 } 421 } 422 423 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); 424 NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 ); 425 426 /* Scale short-term prediction and shaping states */ 427 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { 428 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); 429 } 430 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { 431 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); 432 } 433 434 /* Save inverse gain */ 435 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; 436 } 437 } 438