blob: cdc61dc622348a1504af38c03928954c4ef04cb2 [file] [log] [blame]
Gregory Maxwellae231142011-07-30 08:18:48 -04001/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
Jean-Marc Valinae00e602012-04-20 16:31:04 -04004modification, are permitted provided that the following conditions
5are met:
Gregory Maxwellae231142011-07-30 08:18:48 -04006- 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.
Jean-Marc Valinae00e602012-04-20 16:31:04 -040011- 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.
Timothy B. Terriberry80ad3832013-05-19 18:00:39 -070015THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Jean-Marc Valinae00e602012-04-20 16:31:04 -040016AND 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.
Gregory Maxwellae231142011-07-30 08:18:48 -040026***********************************************************************/
27
Jean-Marc Valin5a484122011-08-15 10:49:53 -040028#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070032#include "main.h"
Timothy B. Terriberryc152d602013-05-08 10:32:37 -070033#include "stack_alloc.h"
Gregory Maxwellae231142011-07-30 08:18:48 -040034
35typedef struct {
Koen Vosbf75c8e2011-12-13 14:47:31 -050036 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
Gregory Maxwellae231142011-07-30 08:18:48 -040037 opus_int32 RandState[ DECISION_DELAY ];
38 opus_int32 Q_Q10[ DECISION_DELAY ];
Koen Vosa51ebd62011-12-14 11:39:29 -050039 opus_int32 Xq_Q14[ DECISION_DELAY ];
40 opus_int32 Pred_Q15[ DECISION_DELAY ];
41 opus_int32 Shape_Q14[ DECISION_DELAY ];
Gregory Maxwellae231142011-07-30 08:18:48 -040042 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
Koen Vosa51ebd62011-12-14 11:39:29 -050043 opus_int32 LF_AR_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -040044 opus_int32 Seed;
45 opus_int32 SeedInit;
46 opus_int32 RD_Q10;
47} NSQ_del_dec_struct;
48
49typedef struct {
50 opus_int32 Q_Q10;
51 opus_int32 RD_Q10;
52 opus_int32 xq_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -050053 opus_int32 LF_AR_Q14;
54 opus_int32 sLTP_shp_Q14;
55 opus_int32 LPC_exc_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -040056} NSQ_sample_struct;
57
Timothy B. Terriberryc152d602013-05-08 10:32:37 -070058typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
59
Jean-Marc Valin4dc0b392011-08-15 11:24:37 -040060static inline void silk_nsq_del_dec_scale_states(
Gregory Maxwellae231142011-07-30 08:18:48 -040061 const silk_encoder_state *psEncC, /* I Encoder State */
62 silk_nsq_state *NSQ, /* I/O NSQ state */
63 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosbbfc9c92011-12-13 14:50:12 -050064 const opus_int32 x_Q3[], /* I Input in Q3 */
Koen Vosacc7a6c2011-10-28 19:44:26 -040065 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
66 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
Koen Vosbf75c8e2011-12-13 14:47:31 -050067 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Koen Vosacc7a6c2011-10-28 19:44:26 -040068 opus_int subfr, /* I Subframe number */
69 opus_int nStatesDelayedDecision, /* I Number of del dec states */
70 const opus_int LTP_scale_Q14, /* I LTP state scaling */
71 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
72 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
73 const opus_int signal_type, /* I Signal type */
74 const opus_int decisionDelay /* I Decision delay */
Gregory Maxwellae231142011-07-30 08:18:48 -040075);
76
77/******************************************/
78/* Noise shape quantizer for one subframe */
79/******************************************/
Jean-Marc Valin4dc0b392011-08-15 11:24:37 -040080static inline void silk_noise_shape_quantizer_del_dec(
Gregory Maxwellae231142011-07-30 08:18:48 -040081 silk_nsq_state *NSQ, /* I/O NSQ state */
82 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosacc7a6c2011-10-28 19:44:26 -040083 opus_int signalType, /* I Signal type */
84 const opus_int32 x_Q10[], /* I */
85 opus_int8 pulses[], /* O */
86 opus_int16 xq[], /* O */
Koen Vosbf75c8e2011-12-13 14:47:31 -050087 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
Koen Vosa51ebd62011-12-14 11:39:29 -050088 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
Koen Vosacc7a6c2011-10-28 19:44:26 -040089 const opus_int16 a_Q12[], /* I Short term prediction coefs */
90 const opus_int16 b_Q14[], /* I Long term prediction coefs */
91 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
92 opus_int lag, /* I Pitch lag */
93 opus_int32 HarmShapeFIRPacked_Q14, /* I */
94 opus_int Tilt_Q14, /* I Spectral tilt */
95 opus_int32 LF_shp_Q14, /* I */
96 opus_int32 Gain_Q16, /* I */
97 opus_int Lambda_Q10, /* I */
98 opus_int offset_Q10, /* I */
99 opus_int length, /* I Input length */
100 opus_int subfr, /* I Subframe number */
101 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
102 opus_int predictLPCOrder, /* I Prediction filter order */
103 opus_int warping_Q16, /* I */
104 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
105 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
106 opus_int decisionDelay /* I */
Gregory Maxwellae231142011-07-30 08:18:48 -0400107);
108
109void silk_NSQ_del_dec(
Koen Vosacc7a6c2011-10-28 19:44:26 -0400110 const silk_encoder_state *psEncC, /* I/O Encoder State */
111 silk_nsq_state *NSQ, /* I/O NSQ state */
112 SideInfoIndices *psIndices, /* I/O Quantization Indices */
Koen Vosbbfc9c92011-12-13 14:50:12 -0500113 const opus_int32 x_Q3[], /* I Prefiltered input signal */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400114 opus_int8 pulses[], /* O Quantized pulse signal */
115 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
116 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
117 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
118 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
119 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
120 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
121 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
122 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
123 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
124 const opus_int LTP_scale_Q14 /* I LTP state scaling */
Gregory Maxwellae231142011-07-30 08:18:48 -0400125)
126{
Koen Vosbf75c8e2011-12-13 14:47:31 -0500127 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
128 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700129 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500130 opus_int16 *pxq;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700131 VARDECL( opus_int32, sLTP_Q15 );
132 VARDECL( opus_int16, sLTP );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500133 opus_int32 HarmShapeFIRPacked_Q14;
134 opus_int offset_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500135 opus_int32 RDmin_Q10, Gain_Q10;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700136 VARDECL( opus_int32, x_sc_Q10 );
137 VARDECL( opus_int32, delayedGain_Q10 );
138 VARDECL( NSQ_del_dec_struct, psDelDec );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500139 NSQ_del_dec_struct *psDD;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700140 SAVE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400141
142 /* Set unvoiced lag to the previous one, overwrite later for voiced */
143 lag = NSQ->lagPrev;
144
Koen Vosa51ebd62011-12-14 11:39:29 -0500145 silk_assert( NSQ->prev_gain_Q16 != 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400146
147 /* Initialize delayed decision states */
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700148 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700149 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400150 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
151 psDD = &psDelDec[ k ];
152 psDD->Seed = ( k + psIndices->Seed ) & 3;
153 psDD->SeedInit = psDD->Seed;
154 psDD->RD_Q10 = 0;
Koen Vosa51ebd62011-12-14 11:39:29 -0500155 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
156 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700157 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
158 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400159 }
160
161 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
162 smpl_buf_idx = 0; /* index of oldest samples */
163
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700164 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
Gregory Maxwellae231142011-07-30 08:18:48 -0400165
166 /* For voiced frames limit the decision delay to lower than the pitch lag */
167 if( psIndices->signalType == TYPE_VOICED ) {
168 for( k = 0; k < psEncC->nb_subfr; k++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700169 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400170 }
171 } else {
172 if( lag > 0 ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700173 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400174 }
175 }
176
177 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
178 LSF_interpolation_flag = 0;
179 } else {
180 LSF_interpolation_flag = 1;
181 }
182
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700183 ALLOC( sLTP_Q15,
184 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
185 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
186 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
187 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500188 /* Set up pointers to start of sub frame */
Gregory Maxwellae231142011-07-30 08:18:48 -0400189 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
190 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
191 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
192 subfr = 0;
193 for( k = 0; k < psEncC->nb_subfr; k++ ) {
194 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
195 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
196 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
197
198 /* Noise shape parameters */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700199 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
200 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500201 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400202
203 NSQ->rewhite_flag = 0;
204 if( psIndices->signalType == TYPE_VOICED ) {
205 /* Voiced */
206 lag = pitchL[ k ];
207
208 /* Re-whitening */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700209 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400210 if( k == 2 ) {
211 /* RESET DELAYED DECISIONS */
212 /* Find winner */
213 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
214 Winner_ind = 0;
215 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
216 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
217 RDmin_Q10 = psDelDec[ i ].RD_Q10;
218 Winner_ind = i;
219 }
220 }
221 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
222 if( i != Winner_ind ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700223 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
224 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400225 }
226 }
227
228 /* Copy final part of signals from winner state to output and long-term filter states */
229 psDD = &psDelDec[ Winner_ind ];
230 last_smple_idx = smpl_buf_idx + decisionDelay;
231 for( i = 0; i < decisionDelay; i++ ) {
232 last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500233 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
234 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500235 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
236 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400237 }
238
239 subfr = 0;
240 }
241
242 /* Rewhiten with new A coefs */
243 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700244 silk_assert( start_idx > 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400245
246 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
247 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder );
248
249 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
250 NSQ->rewhite_flag = 1;
251 }
252 }
253
Koen Vosbbfc9c92011-12-13 14:50:12 -0500254 silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
Gregory Maxwell99253662011-09-27 23:30:18 -0400255 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
Gregory Maxwellae231142011-07-30 08:18:48 -0400256
Koen Vosbf75c8e2011-12-13 14:47:31 -0500257 silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
Koen Vosa51ebd62011-12-14 11:39:29 -0500258 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
Gregory Maxwellae231142011-07-30 08:18:48 -0400259 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
260 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
261
Koen Vosbbfc9c92011-12-13 14:50:12 -0500262 x_Q3 += psEncC->subfr_length;
Gregory Maxwellae231142011-07-30 08:18:48 -0400263 pulses += psEncC->subfr_length;
264 pxq += psEncC->subfr_length;
265 }
266
267 /* Find winner */
268 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
269 Winner_ind = 0;
270 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
271 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
272 RDmin_Q10 = psDelDec[ k ].RD_Q10;
273 Winner_ind = k;
274 }
275 }
276
277 /* Copy final part of signals from winner state to output and long-term filter states */
278 psDD = &psDelDec[ Winner_ind ];
279 psIndices->Seed = psDD->SeedInit;
280 last_smple_idx = smpl_buf_idx + decisionDelay;
Koen Vosa51ebd62011-12-14 11:39:29 -0500281 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400282 for( i = 0; i < decisionDelay; i++ ) {
283 last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500284 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
285 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500286 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
287 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400288 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700289 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
290 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400291
292 /* Update states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500293 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400294 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
295
Koen Vosbf75c8e2011-12-13 14:47:31 -0500296 /* Save quantized speech signal */
297 /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700298 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
Koen Vosa51ebd62011-12-14 11:39:29 -0500299 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700300 RESTORE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400301}
302
303/******************************************/
304/* Noise shape quantizer for one subframe */
305/******************************************/
Jean-Marc Valin4dc0b392011-08-15 11:24:37 -0400306static inline void silk_noise_shape_quantizer_del_dec(
Koen Vosacc7a6c2011-10-28 19:44:26 -0400307 silk_nsq_state *NSQ, /* I/O NSQ state */
Gregory Maxwellae231142011-07-30 08:18:48 -0400308 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400309 opus_int signalType, /* I Signal type */
310 const opus_int32 x_Q10[], /* I */
311 opus_int8 pulses[], /* O */
312 opus_int16 xq[], /* O */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500313 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
Koen Vosa51ebd62011-12-14 11:39:29 -0500314 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400315 const opus_int16 a_Q12[], /* I Short term prediction coefs */
316 const opus_int16 b_Q14[], /* I Long term prediction coefs */
317 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
318 opus_int lag, /* I Pitch lag */
319 opus_int32 HarmShapeFIRPacked_Q14, /* I */
320 opus_int Tilt_Q14, /* I Spectral tilt */
321 opus_int32 LF_shp_Q14, /* I */
322 opus_int32 Gain_Q16, /* I */
323 opus_int Lambda_Q10, /* I */
324 opus_int offset_Q10, /* I */
325 opus_int length, /* I Input length */
326 opus_int subfr, /* I Subframe number */
327 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
328 opus_int predictLPCOrder, /* I Prediction filter order */
329 opus_int warping_Q16, /* I */
330 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
331 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
332 opus_int decisionDelay /* I */
Gregory Maxwellae231142011-07-30 08:18:48 -0400333)
334{
335 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
336 opus_int32 Winner_rand_state;
Koen Vosa51ebd62011-12-14 11:39:29 -0500337 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
338 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
Koen Vos54518c82012-01-31 01:51:22 -0500339 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500340 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400341 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700342 VARDECL( NSQ_sample_pair, psSampleState );
Gregory Maxwellae231142011-07-30 08:18:48 -0400343 NSQ_del_dec_struct *psDD;
344 NSQ_sample_struct *psSS;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700345 SAVE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400346
Gregory Maxwell5d5875a2011-10-03 21:07:39 -0400347 silk_assert( nStatesDelayedDecision > 0 );
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700348 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
Gregory Maxwell5d5875a2011-10-03 21:07:39 -0400349
Koen Vosa51ebd62011-12-14 11:39:29 -0500350 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
Koen Vosbf75c8e2011-12-13 14:47:31 -0500351 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500352 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400353
354 for( i = 0; i < length; i++ ) {
355 /* Perform common calculations used in all states */
356
357 /* Long-term prediction */
358 if( signalType == TYPE_VOICED ) {
359 /* Unrolled loop */
Koen Vosbbfc9c92011-12-13 14:50:12 -0500360 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
Koen Vosa51ebd62011-12-14 11:39:29 -0500361 LTP_pred_Q14 = 2;
362 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
363 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
364 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
365 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
366 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
367 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400368 pred_lag_ptr++;
369 } else {
Koen Vosa51ebd62011-12-14 11:39:29 -0500370 LTP_pred_Q14 = 0;
Gregory Maxwellae231142011-07-30 08:18:48 -0400371 }
372
373 /* Long-term shaping */
374 if( lag > 0 ) {
375 /* Symmetric, packed FIR coefficients */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700376 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500377 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500378 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400379 shp_lag_ptr++;
Gregory Maxwellae231142011-07-30 08:18:48 -0400380 } else {
Koen Vosa51ebd62011-12-14 11:39:29 -0500381 n_LTP_Q14 = 0;
Gregory Maxwellae231142011-07-30 08:18:48 -0400382 }
383
384 for( k = 0; k < nStatesDelayedDecision; k++ ) {
385 /* Delayed decision state */
386 psDD = &psDelDec[ k ];
387
388 /* Sample state */
389 psSS = psSampleState[ k ];
390
391 /* Generate dither */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700392 psDD->Seed = silk_RAND( psDD->Seed );
Gregory Maxwellae231142011-07-30 08:18:48 -0400393
Gregory Maxwellae231142011-07-30 08:18:48 -0400394 /* Pointer used in short term prediction and shaping */
395 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
396 /* Short-term prediction */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500397 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
Koen Vosbbfc9c92011-12-13 14:50:12 -0500398 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
Koen Vosa51ebd62011-12-14 11:39:29 -0500399 LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
400 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
401 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
402 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
403 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
404 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
405 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
406 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
407 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
408 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
409 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500410 if( predictLPCOrder == 16 ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500411 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
412 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
413 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
414 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
415 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
416 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400417 }
Koen Vosa51ebd62011-12-14 11:39:29 -0500418 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400419
420 /* Noise shape feedback */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700421 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
Gregory Maxwellae231142011-07-30 08:18:48 -0400422 /* Output of lowpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700423 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400424 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700425 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400426 psDD->sAR2_Q14[ 0 ] = tmp2;
Koen Vosa51ebd62011-12-14 11:39:29 -0500427 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
428 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400429 /* Loop over allpass sections */
430 for( j = 2; j < shapingLPCOrder; j += 2 ) {
431 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700432 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400433 psDD->sAR2_Q14[ j - 1 ] = tmp1;
Koen Vosa51ebd62011-12-14 11:39:29 -0500434 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400435 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700436 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400437 psDD->sAR2_Q14[ j + 0 ] = tmp2;
Koen Vosa51ebd62011-12-14 11:39:29 -0500438 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400439 }
440 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
Koen Vosa51ebd62011-12-14 11:39:29 -0500441 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400442
Koen Vosa51ebd62011-12-14 11:39:29 -0500443 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
444 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
445 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400446
Koen Vosa51ebd62011-12-14 11:39:29 -0500447 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
448 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
449 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400450
451 /* Input minus prediction plus noise feedback */
452 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
Koen Vosa51ebd62011-12-14 11:39:29 -0500453 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
454 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
455 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
456 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
457
458 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400459
460 /* Flip sign depending on dither */
Koen Vos54518c82012-01-31 01:51:22 -0500461 if ( psDD->Seed < 0 ) {
462 r_Q10 = -r_Q10;
463 }
Jean-Marc Valin1ee139b2011-09-23 13:08:04 -0400464 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400465
466 /* Find two quantization level candidates and measure their rate-distortion */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700467 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500468 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
469 if( q1_Q0 > 0 ) {
470 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700471 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
472 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
473 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
474 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500475 } else if( q1_Q0 == 0 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400476 q1_Q10 = offset_Q10;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700477 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
478 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
479 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500480 } else if( q1_Q0 == -1 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400481 q2_Q10 = offset_Q10;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700482 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
483 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
484 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500485 } else { /* q1_Q0 < -1 */
486 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700487 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
488 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
489 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
490 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400491 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700492 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
493 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
494 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
495 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400496
497 if( rd1_Q10 < rd2_Q10 ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700498 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
499 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400500 psSS[ 0 ].Q_Q10 = q1_Q10;
501 psSS[ 1 ].Q_Q10 = q2_Q10;
502 } else {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700503 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
504 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400505 psSS[ 0 ].Q_Q10 = q2_Q10;
506 psSS[ 1 ].Q_Q10 = q1_Q10;
507 }
508
509 /* Update states for best quantization */
510
511 /* Quantized excitation */
Koen Vos54518c82012-01-31 01:51:22 -0500512 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
513 if ( psDD->Seed < 0 ) {
514 exc_Q14 = -exc_Q14;
515 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400516
517 /* Add predictions */
Koen Vosa51ebd62011-12-14 11:39:29 -0500518 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
519 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400520
521 /* Update states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500522 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
523 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
524 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
525 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
526 psSS[ 0 ].xq_Q14 = xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400527
528 /* Update states for second best quantization */
529
530 /* Quantized excitation */
Koen Vos54518c82012-01-31 01:51:22 -0500531 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
532 if ( psDD->Seed < 0 ) {
533 exc_Q14 = -exc_Q14;
534 }
535
Gregory Maxwellae231142011-07-30 08:18:48 -0400536
537 /* Add predictions */
Koen Vosa51ebd62011-12-14 11:39:29 -0500538 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
539 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400540
541 /* Update states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500542 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
543 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
544 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
545 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
546 psSS[ 1 ].xq_Q14 = xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400547 }
548
549 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
550 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
551
552 /* Find winner */
553 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
554 Winner_ind = 0;
555 for( k = 1; k < nStatesDelayedDecision; k++ ) {
556 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
557 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
558 Winner_ind = k;
559 }
560 }
561
562 /* Increase RD values of expired states */
563 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
564 for( k = 0; k < nStatesDelayedDecision; k++ ) {
565 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500566 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
567 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700568 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400569 }
570 }
571
572 /* Find worst in first set and best in second set */
573 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
574 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
575 RDmax_ind = 0;
576 RDmin_ind = 0;
577 for( k = 1; k < nStatesDelayedDecision; k++ ) {
578 /* find worst in first set */
579 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
580 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
581 RDmax_ind = k;
582 }
583 /* find best in second set */
584 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
585 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
586 RDmin_ind = k;
587 }
588 }
589
590 /* Replace a state if best from second set outperforms worst in first set */
591 if( RDmin_Q10 < RDmax_Q10 ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500592 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
593 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700594 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400595 }
596
597 /* Write samples from winner to output and long-term filter states */
598 psDD = &psDelDec[ Winner_ind ];
599 if( subfr > 0 || i >= decisionDelay ) {
Koen Vosbf75c8e2011-12-13 14:47:31 -0500600 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
601 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500602 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
603 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
604 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400605 }
606 NSQ->sLTP_shp_buf_idx++;
607 NSQ->sLTP_buf_idx++;
608
609 /* Update states */
610 for( k = 0; k < nStatesDelayedDecision; k++ ) {
611 psDD = &psDelDec[ k ];
612 psSS = &psSampleState[ k ][ 0 ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500613 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400614 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -0500615 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400616 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500617 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
618 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
Jean-Marc Valina4885a52011-10-11 18:00:23 -0400619 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400620 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
621 psDD->RD_Q10 = psSS->RD_Q10;
622 }
Koen Vosa51ebd62011-12-14 11:39:29 -0500623 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
Gregory Maxwellae231142011-07-30 08:18:48 -0400624 }
625 /* Update LPC states */
626 for( k = 0; k < nStatesDelayedDecision; k++ ) {
627 psDD = &psDelDec[ k ];
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700628 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400629 }
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700630 RESTORE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400631}
632
Jean-Marc Valin4dc0b392011-08-15 11:24:37 -0400633static inline void silk_nsq_del_dec_scale_states(
Gregory Maxwellae231142011-07-30 08:18:48 -0400634 const silk_encoder_state *psEncC, /* I Encoder State */
635 silk_nsq_state *NSQ, /* I/O NSQ state */
636 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosbbfc9c92011-12-13 14:50:12 -0500637 const opus_int32 x_Q3[], /* I Input in Q3 */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400638 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
639 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500640 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400641 opus_int subfr, /* I Subframe number */
642 opus_int nStatesDelayedDecision, /* I Number of del dec states */
643 const opus_int LTP_scale_Q14, /* I LTP state scaling */
644 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
645 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
646 const opus_int signal_type, /* I Signal type */
647 const opus_int decisionDelay /* I Decision delay */
Gregory Maxwellae231142011-07-30 08:18:48 -0400648)
649{
650 opus_int i, k, lag;
Koen Vosbbfc9c92011-12-13 14:50:12 -0500651 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500652 NSQ_del_dec_struct *psDD;
Gregory Maxwellae231142011-07-30 08:18:48 -0400653
Gregory Maxwellae231142011-07-30 08:18:48 -0400654 lag = pitchL[ subfr ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500655 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
656 silk_assert( inv_gain_Q31 != 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400657
Koen Vosbbfc9c92011-12-13 14:50:12 -0500658 /* Calculate gain adjustment factor */
Koen Vosa51ebd62011-12-14 11:39:29 -0500659 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
660 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
Koen Vosbbfc9c92011-12-13 14:50:12 -0500661 } else {
Jean-Marc Valin905197d2012-03-08 14:09:09 -0500662 gain_adj_Q16 = (opus_int32)1 << 16;
Koen Vosbbfc9c92011-12-13 14:50:12 -0500663 }
664
665 /* Scale input */
666 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
667 for( i = 0; i < psEncC->subfr_length; i++ ) {
668 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
669 }
670
671 /* Save inverse gain */
Koen Vosa51ebd62011-12-14 11:39:29 -0500672 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
Koen Vosbbfc9c92011-12-13 14:50:12 -0500673
Gregory Maxwellae231142011-07-30 08:18:48 -0400674 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
675 if( NSQ->rewhite_flag ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400676 if( subfr == 0 ) {
677 /* Do LTP downscaling */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500678 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400679 }
680 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700681 silk_assert( i < MAX_FRAME_LENGTH );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500682 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400683 }
684 }
685
686 /* Adjust for changing gain */
Jean-Marc Valin905197d2012-03-08 14:09:09 -0500687 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400688 /* Scale long-term shaping state */
689 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500690 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400691 }
692
693 /* Scale long-term prediction state */
Koen Voscc340502011-09-21 14:50:17 -0400694 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
695 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
Koen Vosbf75c8e2011-12-13 14:47:31 -0500696 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400697 }
698 }
699
700 for( k = 0; k < nStatesDelayedDecision; k++ ) {
701 psDD = &psDelDec[ k ];
702
703 /* Scale scalar states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500704 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400705
706 /* Scale short-term prediction and shaping states */
707 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700708 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400709 }
710 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700711 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400712 }
713 for( i = 0; i < DECISION_DELAY; i++ ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500714 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
715 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400716 }
717 }
718 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400719}