MIPS optimizations
[opus.git] / silk / mips / NSQ_del_dec_mipsr1.h
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 #ifndef __NSQ_DEL_DEC_MIPSR1_H__
29 #define __NSQ_DEL_DEC_MIPSR1_H__
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "main.h"
36 #include "stack_alloc.h"
37
38 #define OVERRIDE_silk_noise_shape_quantizer_del_dec
39 static inline void silk_noise_shape_quantizer_del_dec(
40     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */
41     NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */
42     opus_int            signalType,             /* I    Signal type                         */
43     const opus_int32    x_Q10[],                /* I                                        */
44     opus_int8           pulses[],               /* O                                        */
45     opus_int16          xq[],                   /* O                                        */
46     opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */
47     opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */
48     const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */
49     const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */
50     const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */
51     opus_int            lag,                    /* I    Pitch lag                           */
52     opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */
53     opus_int            Tilt_Q14,               /* I    Spectral tilt                       */
54     opus_int32          LF_shp_Q14,             /* I                                        */
55     opus_int32          Gain_Q16,               /* I                                        */
56     opus_int            Lambda_Q10,             /* I                                        */
57     opus_int            offset_Q10,             /* I                                        */
58     opus_int            length,                 /* I    Input length                        */
59     opus_int            subfr,                  /* I    Subframe number                     */
60     opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */
61     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
62     opus_int            warping_Q16,            /* I                                        */
63     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
64     opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
65     opus_int            decisionDelay           /* I                                        */
66 )
67 {
68     opus_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
69     opus_int32   Winner_rand_state;
70     opus_int32   LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
71     opus_int32   n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
72     opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
73     opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
74     opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
75     NSQ_sample_struct  psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
76     NSQ_del_dec_struct *psDD;
77     NSQ_sample_struct  *psSS;
78     opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4;
79     opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6;
80     opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13;
81     opus_int16 a_Q12_14, a_Q12_15;
82
83     opus_int32 cur, prev, next;
84
85     //Intialize b_Q14 variables
86     b_Q14_0 = b_Q14[ 0 ];
87     b_Q14_1 = b_Q14[ 1 ];
88     b_Q14_2 = b_Q14[ 2 ];
89     b_Q14_3 = b_Q14[ 3 ];
90     b_Q14_4 = b_Q14[ 4 ];
91
92     //Intialize a_Q12 variables
93     a_Q12_0 = a_Q12[0];
94     a_Q12_1 = a_Q12[1];
95     a_Q12_2 = a_Q12[2];
96     a_Q12_3 = a_Q12[3];
97     a_Q12_4 = a_Q12[4];
98     a_Q12_5 = a_Q12[5];
99     a_Q12_6 = a_Q12[6];
100     a_Q12_7 = a_Q12[7];
101     a_Q12_8 = a_Q12[8];
102     a_Q12_9 = a_Q12[9];
103     a_Q12_10 = a_Q12[10];
104     a_Q12_11 = a_Q12[11];
105     a_Q12_12 = a_Q12[12];
106     a_Q12_13 = a_Q12[13];
107     a_Q12_14 = a_Q12[14];
108     a_Q12_15 = a_Q12[15];
109
110     long long temp64;
111
112     silk_assert( nStatesDelayedDecision > 0 );
113
114     shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
115     pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
116     Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );
117
118     for( i = 0; i < length; i++ ) {
119         /* Perform common calculations used in all states */
120
121         /* Long-term prediction */
122         if( signalType == TYPE_VOICED ) {
123             /* Unrolled loop */
124             /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
125             temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 );
126             temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 );
127             temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 );
128             temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 );
129             temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 );
130                         temp64 += 32768;
131             LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
132             LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 );                          /* Q13 -> Q14 */
133             pred_lag_ptr++;
134         } else {
135             LTP_pred_Q14 = 0;
136         }
137
138         /* Long-term shaping */
139         if( lag > 0 ) {
140             /* Symmetric, packed FIR coefficients */
141             n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
142             n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );
143             n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 );            /* Q12 -> Q14 */
144             shp_lag_ptr++;
145         } else {
146             n_LTP_Q14 = 0;
147         }
148
149         for( k = 0; k < nStatesDelayedDecision; k++ ) {
150             /* Delayed decision state */
151             psDD = &psDelDec[ k ];
152
153             /* Sample state */
154             psSS = psSampleState[ k ];
155
156             /* Generate dither */
157             psDD->Seed = silk_RAND( psDD->Seed );
158
159             /* Pointer used in short term prediction and shaping */
160             psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
161             /* Short-term prediction */
162             silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
163             temp64 = __builtin_mips_mult(psLPC_Q14[  0 ], a_Q12_0 );
164             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 );
165             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 );
166             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 );
167             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 );
168             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 );
169             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 );
170             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 );
171             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 );
172             temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 );
173             if( predictLPCOrder == 16 ) {
174                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 );
175                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 );
176                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 );
177                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 );
178                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 );
179                 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 );
180             }
181             temp64 += 32768;
182             LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
183
184             LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 );                              /* Q10 -> Q14 */
185
186             /* Noise shape feedback */
187             silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
188             /* Output of lowpass section */
189             tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
190             /* Output of allpass section */
191             tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
192             psDD->sAR2_Q14[ 0 ] = tmp2;
193
194             temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] );
195
196             prev = psDD->sAR2_Q14[ 1 ];
197
198             /* Loop over allpass sections */
199             for( j = 2; j < shapingLPCOrder; j += 2 ) {
200                 cur = psDD->sAR2_Q14[ j ];
201                 next = psDD->sAR2_Q14[ j+1 ];
202                 /* Output of allpass section */
203                 tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 );
204                 psDD->sAR2_Q14[ j - 1 ] = tmp1;
205                 temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] );
206                 temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] );
207                 /* Output of allpass section */
208                 tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 );
209                 psDD->sAR2_Q14[ j + 0 ] = tmp2;
210                 prev = next;
211             }
212             psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
213             temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
214             temp64 += 32768;
215             n_AR_Q14 = __builtin_mips_extr_w(temp64, 16);
216             n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 );                                      /* Q11 -> Q12 */
217             n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 );              /* Q12 */
218             n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 );                                      /* Q12 -> Q14 */
219
220             n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 );     /* Q12 */
221             n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 );            /* Q12 */
222             n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 );                                      /* Q12 -> Q14 */
223
224             /* Input minus prediction plus noise feedback                       */
225             /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */
226             tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 );                                    /* Q14 */
227             tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 );                               /* Q13 */
228             tmp1 = silk_SUB32( tmp2, tmp1 );                                            /* Q13 */
229             tmp1 = silk_RSHIFT_ROUND( tmp1, 4 );                                        /* Q10 */
230
231             r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 );                                     /* residual error Q10 */
232
233             /* Flip sign depending on dither */
234             if ( psDD->Seed < 0 ) {
235                 r_Q10 = -r_Q10;
236             }
237             r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
238
239             /* Find two quantization level candidates and measure their rate-distortion */
240             q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
241             q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
242             if( q1_Q0 > 0 ) {
243                 q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
244                 q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
245                 q2_Q10  = silk_ADD32( q1_Q10, 1024 );
246                 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
247                 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
248             } else if( q1_Q0 == 0 ) {
249                 q1_Q10  = offset_Q10;
250                 q2_Q10  = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
251                 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
252                 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
253             } else if( q1_Q0 == -1 ) {
254                 q2_Q10  = offset_Q10;
255                 q1_Q10  = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
256                 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
257                 rd2_Q10 = silk_SMULBB(  q2_Q10, Lambda_Q10 );
258             } else {            /* q1_Q0 < -1 */
259                 q1_Q10  = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
260                 q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
261                 q2_Q10  = silk_ADD32( q1_Q10, 1024 );
262                 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
263                 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
264             }
265             rr_Q10  = silk_SUB32( r_Q10, q1_Q10 );
266             rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
267             rr_Q10  = silk_SUB32( r_Q10, q2_Q10 );
268             rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
269
270             if( rd1_Q10 < rd2_Q10 ) {
271                 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
272                 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
273                 psSS[ 0 ].Q_Q10  = q1_Q10;
274                 psSS[ 1 ].Q_Q10  = q2_Q10;
275             } else {
276                 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
277                 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
278                 psSS[ 0 ].Q_Q10  = q2_Q10;
279                 psSS[ 1 ].Q_Q10  = q1_Q10;
280             }
281
282             /* Update states for best quantization */
283
284             /* Quantized excitation */
285             exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
286             if ( psDD->Seed < 0 ) {
287                 exc_Q14 = -exc_Q14;
288             }
289
290             /* Add predictions */
291             LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
292             xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
293
294             /* Update states */
295             sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );
296             psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
297             psSS[ 0 ].LF_AR_Q14    = sLF_AR_shp_Q14;
298             psSS[ 0 ].LPC_exc_Q14  = LPC_exc_Q14;
299             psSS[ 0 ].xq_Q14       = xq_Q14;
300
301             /* Update states for second best quantization */
302
303             /* Quantized excitation */
304             exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
305             if ( psDD->Seed < 0 ) {
306                 exc_Q14 = -exc_Q14;
307             }
308
309
310             /* Add predictions */
311             LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
312             xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
313
314             /* Update states */
315             sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );
316             psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
317             psSS[ 1 ].LF_AR_Q14    = sLF_AR_shp_Q14;
318             psSS[ 1 ].LPC_exc_Q14  = LPC_exc_Q14;
319             psSS[ 1 ].xq_Q14       = xq_Q14;
320         }
321
322         *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */
323         last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */
324
325         /* Find winner */
326         RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
327         Winner_ind = 0;
328         for( k = 1; k < nStatesDelayedDecision; k++ ) {
329             if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
330                 RDmin_Q10  = psSampleState[ k ][ 0 ].RD_Q10;
331                 Winner_ind = k;
332             }
333         }
334
335         /* Increase RD values of expired states */
336         Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
337         for( k = 0; k < nStatesDelayedDecision; k++ ) {
338             if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
339                 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
340                 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
341                 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
342             }
343         }
344
345         /* Find worst in first set and best in second set */
346         RDmax_Q10  = psSampleState[ 0 ][ 0 ].RD_Q10;
347         RDmin_Q10  = psSampleState[ 0 ][ 1 ].RD_Q10;
348         RDmax_ind = 0;
349         RDmin_ind = 0;
350         for( k = 1; k < nStatesDelayedDecision; k++ ) {
351             /* find worst in first set */
352             if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
353                 RDmax_Q10  = psSampleState[ k ][ 0 ].RD_Q10;
354                 RDmax_ind = k;
355             }
356             /* find best in second set */
357             if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
358                 RDmin_Q10  = psSampleState[ k ][ 1 ].RD_Q10;
359                 RDmin_ind = k;
360             }
361         }
362
363         /* Replace a state if best from second set outperforms worst in first set */
364         if( RDmin_Q10 < RDmax_Q10 ) {
365             silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
366                          ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
367             silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
368         }
369
370         /* Write samples from winner to output and long-term filter states */
371         psDD = &psDelDec[ Winner_ind ];
372         if( subfr > 0 || i >= decisionDelay ) {
373             pulses[  i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
374             xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
375                 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
376             NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
377             sLTP_Q15[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDD->Pred_Q15[  last_smple_idx ];
378         }
379         NSQ->sLTP_shp_buf_idx++;
380         NSQ->sLTP_buf_idx++;
381
382         /* Update states */
383         for( k = 0; k < nStatesDelayedDecision; k++ ) {
384             psDD                                     = &psDelDec[ k ];
385             psSS                                     = &psSampleState[ k ][ 0 ];
386             psDD->LF_AR_Q14                          = psSS->LF_AR_Q14;
387             psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
388             psDD->Xq_Q14[    *smpl_buf_idx ]         = psSS->xq_Q14;
389             psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;
390             psDD->Pred_Q15[  *smpl_buf_idx ]         = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
391             psDD->Shape_Q14[ *smpl_buf_idx ]         = psSS->sLTP_shp_Q14;
392             psDD->Seed                               = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
393             psDD->RandState[ *smpl_buf_idx ]         = psDD->Seed;
394             psDD->RD_Q10                             = psSS->RD_Q10;
395         }
396         delayedGain_Q10[     *smpl_buf_idx ]         = Gain_Q10;
397     }
398     /* Update LPC states */
399     for( k = 0; k < nStatesDelayedDecision; k++ ) {
400         psDD = &psDelDec[ k ];
401         silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
402     }
403 }
404
405 #endif /* __NSQ_DEL_DEC_MIPSR1_H__ */
406