1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY 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
37static 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_int32    x_Q3[],                 /* I    input in Q3                     */
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)
52static 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
76void 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_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
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            AR2_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,
121           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
122    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
123    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
124    /* Set up pointers to start of sub frame */
125    NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
126    NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;
127    pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];
128    for( k = 0; k < psEncC->nb_subfr; k++ ) {
129        A_Q12      = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
130        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER ];
131        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];
132
133        /* Noise shape parameters */
134        silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
135        HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
136        HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
137
138        NSQ->rewhite_flag = 0;
139        if( psIndices->signalType == TYPE_VOICED ) {
140            /* Voiced */
141            lag = pitchL[ k ];
142
143            /* Re-whitening */
144            if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
145                /* Rewhiten with new A coefs */
146                start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
147                silk_assert( start_idx > 0 );
148
149                silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
150                    A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
151
152                NSQ->rewhite_flag = 1;
153                NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
154            }
155        }
156
157        silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
158
159        silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
160            AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
161            offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
162
163        x_Q3   += psEncC->subfr_length;
164        pulses += psEncC->subfr_length;
165        pxq    += psEncC->subfr_length;
166    }
167
168    /* Update lagPrev for next frame */
169    NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
170
171    /* Save quantized speech and noise shaping signals */
172    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
173    silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
174    silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
175    RESTORE_STACK;
176}
177
178/***********************************/
179/* silk_noise_shape_quantizer  */
180/***********************************/
181
182#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
183static OPUS_INLINE
184#endif
185void silk_noise_shape_quantizer(
186    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
187    opus_int            signalType,             /* I    Signal type                     */
188    const opus_int32    x_sc_Q10[],             /* I                                    */
189    opus_int8           pulses[],               /* O                                    */
190    opus_int16          xq[],                   /* O                                    */
191    opus_int32          sLTP_Q15[],             /* I/O  LTP state                       */
192    const opus_int16    a_Q12[],                /* I    Short term prediction coefs     */
193    const opus_int16    b_Q14[],                /* I    Long term prediction coefs      */
194    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping AR coefs          */
195    opus_int            lag,                    /* I    Pitch lag                       */
196    opus_int32          HarmShapeFIRPacked_Q14, /* I                                    */
197    opus_int            Tilt_Q14,               /* I    Spectral tilt                   */
198    opus_int32          LF_shp_Q14,             /* I                                    */
199    opus_int32          Gain_Q16,               /* I                                    */
200    opus_int            Lambda_Q10,             /* I                                    */
201    opus_int            offset_Q10,             /* I                                    */
202    opus_int            length,                 /* I    Input length                    */
203    opus_int            shapingLPCOrder,        /* I    Noise shaping AR filter order   */
204    opus_int            predictLPCOrder,        /* I    Prediction filter order         */
205    int                 arch                    /* I    Architecture                    */
206)
207{
208    opus_int     i;
209    opus_int32   LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
210    opus_int32   n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
211    opus_int32   exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
212    opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
213    opus_int32   *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
214#ifdef silk_short_prediction_create_arch_coef
215    opus_int32   a_Q12_arch[MAX_LPC_ORDER];
216#endif
217
218    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
219    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
220    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );
221
222    /* Set up short term AR state */
223    psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
224
225#ifdef silk_short_prediction_create_arch_coef
226    silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
227#endif
228
229    for( i = 0; i < length; i++ ) {
230        /* Generate dither */
231        NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
232
233        /* Short-term prediction */
234        LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
235
236        /* Long-term prediction */
237        if( signalType == TYPE_VOICED ) {
238            /* Unrolled loop */
239            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
240            LTP_pred_Q13 = 2;
241            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[  0 ], b_Q14[ 0 ] );
242            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
243            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
244            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
245            LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
246            pred_lag_ptr++;
247        } else {
248            LTP_pred_Q13 = 0;
249        }
250
251        /* Noise shape feedback */
252        silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
253        n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(psLPC_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
254
255        n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
256
257        n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
258        n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
259
260        silk_assert( lag > 0 || signalType != TYPE_VOICED );
261
262        /* Combine prediction and noise shaping signals */
263        tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 );        /* Q12 */
264        tmp1 = silk_SUB32( tmp1, n_LF_Q12 );                                    /* Q12 */
265        if( lag > 0 ) {
266            /* Symmetric, packed FIR coefficients */
267            n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
268            n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );
269            n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
270            shp_lag_ptr++;
271
272            tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 );                       /* Q13 */
273            tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 );                          /* Q13 */
274            tmp1 = silk_RSHIFT_ROUND( tmp1, 3 );                                /* Q10 */
275        } else {
276            tmp1 = silk_RSHIFT_ROUND( tmp1, 2 );                                /* Q10 */
277        }
278
279        r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */
280
281        /* Flip sign depending on dither */
282        if ( NSQ->rand_seed < 0 ) {
283           r_Q10 = -r_Q10;
284        }
285        r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
286
287        /* Find two quantization level candidates and measure their rate-distortion */
288        q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
289        q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
290        if( q1_Q0 > 0 ) {
291            q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
292            q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
293            q2_Q10  = silk_ADD32( q1_Q10, 1024 );
294            rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
295            rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
296        } else if( q1_Q0 == 0 ) {
297            q1_Q10  = offset_Q10;
298            q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
299            rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
300            rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
301        } else if( q1_Q0 == -1 ) {
302            q2_Q10  = offset_Q10;
303            q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
304            rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
305            rd2_Q20 = silk_SMULBB(  q2_Q10, Lambda_Q10 );
306        } else {            /* Q1_Q0 < -1 */
307            q1_Q10  = silk_ADD32( 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        }
313        rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );
314        rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
315        rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );
316        rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
317
318        if( rd2_Q20 < rd1_Q20 ) {
319            q1_Q10 = q2_Q10;
320        }
321
322        pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
323
324        /* Excitation */
325        exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
326        if ( NSQ->rand_seed < 0 ) {
327           exc_Q14 = -exc_Q14;
328        }
329
330        /* Add predictions */
331        LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
332        xq_Q14      = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
333
334        /* Scale XQ back to normal level before saving */
335        xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
336
337        /* Update states */
338        psLPC_Q14++;
339        *psLPC_Q14 = xq_Q14;
340        sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
341        NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
342
343        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
344        sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
345        NSQ->sLTP_shp_buf_idx++;
346        NSQ->sLTP_buf_idx++;
347
348        /* Make dither dependent on quantized signal */
349        NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
350    }
351
352    /* Update LPC synth buffer */
353    silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
354}
355
356static OPUS_INLINE void silk_nsq_scale_states(
357    const silk_encoder_state *psEncC,           /* I    Encoder State                   */
358    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
359    const opus_int32    x_Q3[],                 /* I    input in Q3                     */
360    opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */
361    const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */
362    opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */
363    opus_int            subfr,                  /* I    subframe number                 */
364    const opus_int      LTP_scale_Q14,          /* I                                    */
365    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ], /* I                                 */
366    const opus_int      pitchL[ MAX_NB_SUBFR ], /* I    Pitch lag                       */
367    const opus_int      signal_type             /* I    Signal type                     */
368)
369{
370    opus_int   i, lag;
371    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
372
373    lag          = pitchL[ subfr ];
374    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
375    silk_assert( inv_gain_Q31 != 0 );
376
377    /* Calculate gain adjustment factor */
378    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
379        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
380    } else {
381        gain_adj_Q16 = (opus_int32)1 << 16;
382    }
383
384    /* Scale input */
385    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
386    for( i = 0; i < psEncC->subfr_length; i++ ) {
387        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
388    }
389
390    /* Save inverse gain */
391    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
392
393    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
394    if( NSQ->rewhite_flag ) {
395        if( subfr == 0 ) {
396            /* Do LTP downscaling */
397            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
398        }
399        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
400            silk_assert( i < MAX_FRAME_LENGTH );
401            sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
402        }
403    }
404
405    /* Adjust for changing gain */
406    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
407        /* Scale long-term shaping state */
408        for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
409            NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
410        }
411
412        /* Scale long-term prediction state */
413        if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
414            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
415                sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
416            }
417        }
418
419        NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
420
421        /* Scale short-term prediction and shaping states */
422        for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
423            NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
424        }
425        for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
426            NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
427        }
428    }
429}
430