Clean up: replace tabs by spaces
[opus.git] / silk / NSQ.c
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/O  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      = &LTPCoef_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     /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
172     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
173     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
174     RESTORE_STACK;
175 }
176
177 /***********************************/
178 /* silk_noise_shape_quantizer  */
179 /***********************************/
180
181 #if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
182 static OPUS_INLINE
183 #endif
184 void silk_noise_shape_quantizer(
185     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
186     opus_int            signalType,             /* I    Signal type                     */
187     const opus_int32    x_sc_Q10[],             /* I                                    */
188     opus_int8           pulses[],               /* O                                    */
189     opus_int16          xq[],                   /* O                                    */
190     opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */
191     const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */
192     const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */
193     const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */
194     opus_int            lag,                    /* I    Pitch lag                       */
195     opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */
196     opus_int            Tilt_Q14,               /* I    Spectral tilt                   */
197     opus_int32          LF_shp_Q14,             /* I                                    */
198     opus_int32          Gain_Q16,               /* I                                    */
199     opus_int            Lambda_Q10,             /* I                                    */
200     opus_int            offset_Q10,             /* I                                    */
201     opus_int            length,                 /* I    Input length                    */
202     opus_int            shapingLPCOrder,        /* I    Noise shaping AR filter order   */
203     opus_int            predictLPCOrder,        /* I    Prediction filter order         */
204     int                 arch                    /* I    Architecture                    */
205 )
206 {
207     opus_int     i;
208     opus_int32   LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
209     opus_int32   n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
210     opus_int32   exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
211     opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
212     opus_int32   *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
213 #ifdef silk_short_prediction_create_arch_coef
214     opus_int32   a_Q12_arch[MAX_LPC_ORDER];
215 #endif
216
217     shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
218     pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
219     Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );
220
221     /* Set up short term AR state */
222     psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
223
224 #ifdef silk_short_prediction_create_arch_coef
225     silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
226 #endif
227
228     /* We're getting desperate to hit the target -- pretend there's
229        no dithering to make hitting the target more likely. */
230     if (Lambda_Q10 > 3072) offset_Q10 = 0;
231
232     for( i = 0; i < length; i++ ) {
233         /* Generate dither */
234         NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
235
236         /* Short-term prediction */
237         LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
238
239         /* Long-term prediction */
240         if( signalType == TYPE_VOICED ) {
241             /* Unrolled loop */
242             /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
243             LTP_pred_Q13 = 2;
244             LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[  0 ], b_Q14[ 0 ] );
245             LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
246             LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
247             LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
248             LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
249             pred_lag_ptr++;
250         } else {
251             LTP_pred_Q13 = 0;
252         }
253
254         /* Noise shape feedback */
255         silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
256         n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
257
258         n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
259
260         n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
261         n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
262
263         silk_assert( lag > 0 || signalType != TYPE_VOICED );
264
265         /* Combine prediction and noise shaping signals */
266         tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 );        /* Q12 */
267         tmp1 = silk_SUB32( tmp1, n_LF_Q12 );                                    /* Q12 */
268         if( lag > 0 ) {
269             /* Symmetric, packed FIR coefficients */
270             n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
271             n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );
272             n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
273             shp_lag_ptr++;
274
275             tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 );                       /* Q13 */
276             tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 );                          /* Q13 */
277             tmp1 = silk_RSHIFT_ROUND( tmp1, 3 );                                /* Q10 */
278         } else {
279             tmp1 = silk_RSHIFT_ROUND( tmp1, 2 );                                /* Q10 */
280         }
281
282         r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */
283
284         /* Flip sign depending on dither */
285         if( NSQ->rand_seed < 0 ) {
286             r_Q10 = -r_Q10;
287         }
288         r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
289
290         /* Find two quantization level candidates and measure their rate-distortion */
291         q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
292         q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
293         if (Lambda_Q10 > 2048) {
294             /* For aggressive RDO, the bias becomes more than one pulse. */
295             int rdo_offset = Lambda_Q10/2 - 512;
296             if (q1_Q10 > rdo_offset) {
297                 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
298             } else if (q1_Q10 < -rdo_offset) {
299                 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
300             } else if (q1_Q10 < 0) {
301                 q1_Q0 = -1;
302             } else {
303                 q1_Q0 = 0;
304             }
305         }
306         if( q1_Q0 > 0 ) {
307             q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
308             q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
309             q2_Q10  = silk_ADD32( q1_Q10, 1024 );
310             rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
311             rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
312         } else if( q1_Q0 == 0 ) {
313             q1_Q10  = offset_Q10;
314             q2_Q10  = silk_ADD32( q1_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 if( q1_Q0 == -1 ) {
318             q2_Q10  = offset_Q10;
319             q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
320             rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
321             rd2_Q20 = silk_SMULBB(  q2_Q10, Lambda_Q10 );
322         } else {            /* Q1_Q0 < -1 */
323             q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
324             q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
325             q2_Q10  = silk_ADD32( q1_Q10, 1024 );
326             rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
327             rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
328         }
329         rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );
330         rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
331         rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );
332         rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
333
334         if( rd2_Q20 < rd1_Q20 ) {
335             q1_Q10 = q2_Q10;
336         }
337
338         pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
339
340         /* Excitation */
341         exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
342         if ( NSQ->rand_seed < 0 ) {
343            exc_Q14 = -exc_Q14;
344         }
345
346         /* Add predictions */
347         LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
348         xq_Q14      = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
349
350         /* Scale XQ back to normal level before saving */
351         xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
352
353         /* Update states */
354         psLPC_Q14++;
355         *psLPC_Q14 = xq_Q14;
356         NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
357         sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
358         NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
359
360         NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
361         sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
362         NSQ->sLTP_shp_buf_idx++;
363         NSQ->sLTP_buf_idx++;
364
365         /* Make dither dependent on quantized signal */
366         NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
367     }
368
369     /* Update LPC synth buffer */
370     silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
371 }
372
373 static OPUS_INLINE void silk_nsq_scale_states(
374     const silk_encoder_state *psEncC,           /* I    Encoder State                   */
375     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
376     const opus_int16    x16[],                  /* I    input                           */
377     opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */
378     const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */
379     opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */
380     opus_int            subfr,                  /* I    subframe number                 */
381     const opus_int      LTP_scale_Q14,          /* I                                    */
382     const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */
383     const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */
384     const opus_int      signal_type             /* I    Signal type                     */
385 )
386 {
387     opus_int   i, lag;
388     opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
389
390     lag          = pitchL[ subfr ];
391     inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
392     silk_assert( inv_gain_Q31 != 0 );
393
394     /* Scale input */
395     inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
396     for( i = 0; i < psEncC->subfr_length; i++ ) {
397         x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
398     }
399
400     /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
401     if( NSQ->rewhite_flag ) {
402         if( subfr == 0 ) {
403             /* Do LTP downscaling */
404             inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
405         }
406         for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
407             silk_assert( i < MAX_FRAME_LENGTH );
408             sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
409         }
410     }
411
412     /* Adjust for changing gain */
413     if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
414         gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
415
416         /* Scale long-term shaping state */
417         for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
418             NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
419         }
420
421         /* Scale long-term prediction state */
422         if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
423             for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
424                 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
425             }
426         }
427
428         NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
429         NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
430
431         /* Scale short-term prediction and shaping states */
432         for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
433             NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
434         }
435         for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
436             NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
437         }
438
439         /* Save inverse gain */
440         NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
441     }
442 }