blob: 3495613b2b61e70cbbbdf349b23b0de7d2d70ca8 [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.
Ralph Gilesf2446c22013-09-16 14:40:04 -070011- Neither the name of Internet Society, IETF or IETF Trust, nor the
Jean-Marc Valinae00e602012-04-20 16:31:04 -040012names 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"
Jonathan Lennox81a19422015-12-22 19:21:45 -050034#include "NSQ.h"
35
Gregory Maxwellae231142011-07-30 08:18:48 -040036
37typedef struct {
Koen Vosbf75c8e2011-12-13 14:47:31 -050038 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
Gregory Maxwellae231142011-07-30 08:18:48 -040039 opus_int32 RandState[ DECISION_DELAY ];
40 opus_int32 Q_Q10[ DECISION_DELAY ];
Koen Vosa51ebd62011-12-14 11:39:29 -050041 opus_int32 Xq_Q14[ DECISION_DELAY ];
42 opus_int32 Pred_Q15[ DECISION_DELAY ];
43 opus_int32 Shape_Q14[ DECISION_DELAY ];
Gregory Maxwellae231142011-07-30 08:18:48 -040044 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
Koen Vosa51ebd62011-12-14 11:39:29 -050045 opus_int32 LF_AR_Q14;
Koen Vos6e40eb52016-02-21 11:34:11 +080046 opus_int32 Diff_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -040047 opus_int32 Seed;
48 opus_int32 SeedInit;
49 opus_int32 RD_Q10;
50} NSQ_del_dec_struct;
51
52typedef struct {
53 opus_int32 Q_Q10;
54 opus_int32 RD_Q10;
55 opus_int32 xq_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -050056 opus_int32 LF_AR_Q14;
Koen Vos6e40eb52016-02-21 11:34:11 +080057 opus_int32 Diff_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -050058 opus_int32 sLTP_shp_Q14;
59 opus_int32 LPC_exc_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -040060} NSQ_sample_struct;
61
Timothy B. Terriberryc152d602013-05-08 10:32:37 -070062typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
63
Rhishikesh Agashef133bac2014-06-19 03:40:09 -040064#if defined(MIPSr1_ASM)
65#include "mips/NSQ_del_dec_mipsr1.h"
66#endif
Gregory Maxwell7830cf12013-10-17 15:56:52 -070067static OPUS_INLINE void silk_nsq_del_dec_scale_states(
Gregory Maxwellae231142011-07-30 08:18:48 -040068 const silk_encoder_state *psEncC, /* I Encoder State */
69 silk_nsq_state *NSQ, /* I/O NSQ state */
70 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vos6e40eb52016-02-21 11:34:11 +080071 const opus_int16 x16[], /* I Input */
Koen Vosacc7a6c2011-10-28 19:44:26 -040072 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
73 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
Koen Vosbf75c8e2011-12-13 14:47:31 -050074 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Koen Vosacc7a6c2011-10-28 19:44:26 -040075 opus_int subfr, /* I Subframe number */
76 opus_int nStatesDelayedDecision, /* I Number of del dec states */
77 const opus_int LTP_scale_Q14, /* I LTP state scaling */
78 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
79 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
80 const opus_int signal_type, /* I Signal type */
81 const opus_int decisionDelay /* I Decision delay */
Gregory Maxwellae231142011-07-30 08:18:48 -040082);
83
84/******************************************/
85/* Noise shape quantizer for one subframe */
86/******************************************/
Gregory Maxwell7830cf12013-10-17 15:56:52 -070087static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
Gregory Maxwellae231142011-07-30 08:18:48 -040088 silk_nsq_state *NSQ, /* I/O NSQ state */
89 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosacc7a6c2011-10-28 19:44:26 -040090 opus_int signalType, /* I Signal type */
91 const opus_int32 x_Q10[], /* I */
92 opus_int8 pulses[], /* O */
93 opus_int16 xq[], /* O */
Koen Vosbf75c8e2011-12-13 14:47:31 -050094 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
Koen Vosa51ebd62011-12-14 11:39:29 -050095 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
Koen Vosacc7a6c2011-10-28 19:44:26 -040096 const opus_int16 a_Q12[], /* I Short term prediction coefs */
97 const opus_int16 b_Q14[], /* I Long term prediction coefs */
98 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
99 opus_int lag, /* I Pitch lag */
100 opus_int32 HarmShapeFIRPacked_Q14, /* I */
101 opus_int Tilt_Q14, /* I Spectral tilt */
102 opus_int32 LF_shp_Q14, /* I */
103 opus_int32 Gain_Q16, /* I */
104 opus_int Lambda_Q10, /* I */
105 opus_int offset_Q10, /* I */
106 opus_int length, /* I Input length */
107 opus_int subfr, /* I Subframe number */
108 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
109 opus_int predictLPCOrder, /* I Prediction filter order */
110 opus_int warping_Q16, /* I */
111 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
112 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
Jonathan Lennox81a19422015-12-22 19:21:45 -0500113 opus_int decisionDelay, /* I */
114 int arch /* I */
Gregory Maxwellae231142011-07-30 08:18:48 -0400115);
116
xiangmingzhuc95c9a02014-04-30 15:48:07 +0800117void silk_NSQ_del_dec_c(
Koen Vosacc7a6c2011-10-28 19:44:26 -0400118 const silk_encoder_state *psEncC, /* I/O Encoder State */
119 silk_nsq_state *NSQ, /* I/O NSQ state */
120 SideInfoIndices *psIndices, /* I/O Quantization Indices */
Koen Vos90f8c5e2016-02-21 16:21:03 +0800121 const opus_int16 x16[], /* I Input */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400122 opus_int8 pulses[], /* O Quantized pulse signal */
123 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
124 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
Koen Vos6e40eb52016-02-21 11:34:11 +0800125 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400126 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
127 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
128 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
129 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
130 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
131 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
132 const opus_int LTP_scale_Q14 /* I LTP state scaling */
Gregory Maxwellae231142011-07-30 08:18:48 -0400133)
134{
Koen Vosbf75c8e2011-12-13 14:47:31 -0500135 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
136 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700137 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500138 opus_int16 *pxq;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700139 VARDECL( opus_int32, sLTP_Q15 );
140 VARDECL( opus_int16, sLTP );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500141 opus_int32 HarmShapeFIRPacked_Q14;
142 opus_int offset_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500143 opus_int32 RDmin_Q10, Gain_Q10;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700144 VARDECL( opus_int32, x_sc_Q10 );
145 VARDECL( opus_int32, delayedGain_Q10 );
146 VARDECL( NSQ_del_dec_struct, psDelDec );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500147 NSQ_del_dec_struct *psDD;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700148 SAVE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400149
150 /* Set unvoiced lag to the previous one, overwrite later for voiced */
151 lag = NSQ->lagPrev;
152
Koen Vosa51ebd62011-12-14 11:39:29 -0500153 silk_assert( NSQ->prev_gain_Q16 != 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400154
155 /* Initialize delayed decision states */
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700156 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700157 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400158 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
159 psDD = &psDelDec[ k ];
160 psDD->Seed = ( k + psIndices->Seed ) & 3;
161 psDD->SeedInit = psDD->Seed;
162 psDD->RD_Q10 = 0;
Koen Vosa51ebd62011-12-14 11:39:29 -0500163 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
Koen Vos6e40eb52016-02-21 11:34:11 +0800164 psDD->Diff_Q14 = NSQ->sDiff_shp_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -0500165 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700166 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
167 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400168 }
169
170 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
171 smpl_buf_idx = 0; /* index of oldest samples */
172
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700173 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
Gregory Maxwellae231142011-07-30 08:18:48 -0400174
175 /* For voiced frames limit the decision delay to lower than the pitch lag */
176 if( psIndices->signalType == TYPE_VOICED ) {
177 for( k = 0; k < psEncC->nb_subfr; k++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700178 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400179 }
180 } else {
181 if( lag > 0 ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700182 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400183 }
184 }
185
186 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
187 LSF_interpolation_flag = 0;
188 } else {
189 LSF_interpolation_flag = 1;
190 }
191
Koen Vos6e40eb52016-02-21 11:34:11 +0800192 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700193 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
194 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
195 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500196 /* Set up pointers to start of sub frame */
Gregory Maxwellae231142011-07-30 08:18:48 -0400197 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
198 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
199 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
200 subfr = 0;
201 for( k = 0; k < psEncC->nb_subfr; k++ ) {
202 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
203 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
Koen Vos6e40eb52016-02-21 11:34:11 +0800204 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400205
206 /* Noise shape parameters */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700207 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
208 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500209 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400210
211 NSQ->rewhite_flag = 0;
212 if( psIndices->signalType == TYPE_VOICED ) {
213 /* Voiced */
214 lag = pitchL[ k ];
215
216 /* Re-whitening */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700217 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400218 if( k == 2 ) {
219 /* RESET DELAYED DECISIONS */
220 /* Find winner */
221 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
222 Winner_ind = 0;
223 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
224 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
225 RDmin_Q10 = psDelDec[ i ].RD_Q10;
226 Winner_ind = i;
227 }
228 }
229 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
230 if( i != Winner_ind ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700231 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
232 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400233 }
234 }
235
236 /* Copy final part of signals from winner state to output and long-term filter states */
237 psDD = &psDelDec[ Winner_ind ];
238 last_smple_idx = smpl_buf_idx + decisionDelay;
239 for( i = 0; i < decisionDelay; i++ ) {
Koen Vos2799c532016-06-01 21:49:11 +0800240 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
241 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500242 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
243 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500244 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
245 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400246 }
247
248 subfr = 0;
249 }
250
251 /* Rewhiten with new A coefs */
252 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700253 silk_assert( start_idx > 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400254
255 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
xiangmingzhuc95c9a02014-04-30 15:48:07 +0800256 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
Gregory Maxwellae231142011-07-30 08:18:48 -0400257
258 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
259 NSQ->rewhite_flag = 1;
260 }
261 }
262
Koen Vos6e40eb52016-02-21 11:34:11 +0800263 silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
Gregory Maxwell99253662011-09-27 23:30:18 -0400264 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
Gregory Maxwellae231142011-07-30 08:18:48 -0400265
Koen Vosbf75c8e2011-12-13 14:47:31 -0500266 silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
Koen Vosa51ebd62011-12-14 11:39:29 -0500267 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 -0400268 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
Jonathan Lennox81a19422015-12-22 19:21:45 -0500269 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
Gregory Maxwellae231142011-07-30 08:18:48 -0400270
Koen Vos6e40eb52016-02-21 11:34:11 +0800271 x16 += psEncC->subfr_length;
Gregory Maxwellae231142011-07-30 08:18:48 -0400272 pulses += psEncC->subfr_length;
273 pxq += psEncC->subfr_length;
274 }
275
276 /* Find winner */
277 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
278 Winner_ind = 0;
279 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
280 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
281 RDmin_Q10 = psDelDec[ k ].RD_Q10;
282 Winner_ind = k;
283 }
284 }
285
286 /* Copy final part of signals from winner state to output and long-term filter states */
287 psDD = &psDelDec[ Winner_ind ];
288 psIndices->Seed = psDD->SeedInit;
289 last_smple_idx = smpl_buf_idx + decisionDelay;
Koen Vosa51ebd62011-12-14 11:39:29 -0500290 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400291 for( i = 0; i < decisionDelay; i++ ) {
Koen Vos2799c532016-06-01 21:49:11 +0800292 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
293 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
294
Koen Vosbf75c8e2011-12-13 14:47:31 -0500295 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
296 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500297 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
298 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400299 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700300 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
301 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400302
303 /* Update states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500304 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
Koen Vos6e40eb52016-02-21 11:34:11 +0800305 NSQ->sDiff_shp_Q14 = psDD->Diff_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400306 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
307
Koen Vosbf75c8e2011-12-13 14:47:31 -0500308 /* Save quantized speech signal */
309 /* 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 -0700310 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
Koen Vosa51ebd62011-12-14 11:39:29 -0500311 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 -0700312 RESTORE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400313}
314
315/******************************************/
316/* Noise shape quantizer for one subframe */
317/******************************************/
Rhishikesh Agashef133bac2014-06-19 03:40:09 -0400318#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec
Gregory Maxwell7830cf12013-10-17 15:56:52 -0700319static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
Koen Vosacc7a6c2011-10-28 19:44:26 -0400320 silk_nsq_state *NSQ, /* I/O NSQ state */
Gregory Maxwellae231142011-07-30 08:18:48 -0400321 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400322 opus_int signalType, /* I Signal type */
323 const opus_int32 x_Q10[], /* I */
324 opus_int8 pulses[], /* O */
325 opus_int16 xq[], /* O */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500326 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
Koen Vosa51ebd62011-12-14 11:39:29 -0500327 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400328 const opus_int16 a_Q12[], /* I Short term prediction coefs */
329 const opus_int16 b_Q14[], /* I Long term prediction coefs */
330 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
331 opus_int lag, /* I Pitch lag */
332 opus_int32 HarmShapeFIRPacked_Q14, /* I */
333 opus_int Tilt_Q14, /* I Spectral tilt */
334 opus_int32 LF_shp_Q14, /* I */
335 opus_int32 Gain_Q16, /* I */
336 opus_int Lambda_Q10, /* I */
337 opus_int offset_Q10, /* I */
338 opus_int length, /* I Input length */
339 opus_int subfr, /* I Subframe number */
340 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
341 opus_int predictLPCOrder, /* I Prediction filter order */
342 opus_int warping_Q16, /* I */
343 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
344 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
Jonathan Lennox81a19422015-12-22 19:21:45 -0500345 opus_int decisionDelay, /* I */
346 int arch /* I */
Gregory Maxwellae231142011-07-30 08:18:48 -0400347)
348{
349 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
350 opus_int32 Winner_rand_state;
Koen Vosa51ebd62011-12-14 11:39:29 -0500351 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
352 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
Koen Vos54518c82012-01-31 01:51:22 -0500353 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500354 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400355 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
Jonathan Lennox81a19422015-12-22 19:21:45 -0500356#ifdef silk_short_prediction_create_arch_coef
357 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
358#endif
359
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700360 VARDECL( NSQ_sample_pair, psSampleState );
Gregory Maxwellae231142011-07-30 08:18:48 -0400361 NSQ_del_dec_struct *psDD;
362 NSQ_sample_struct *psSS;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700363 SAVE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400364
Gregory Maxwell5d5875a2011-10-03 21:07:39 -0400365 silk_assert( nStatesDelayedDecision > 0 );
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700366 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
Gregory Maxwell5d5875a2011-10-03 21:07:39 -0400367
Koen Vosa51ebd62011-12-14 11:39:29 -0500368 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 -0500369 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500370 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400371
Jonathan Lennox81a19422015-12-22 19:21:45 -0500372#ifdef silk_short_prediction_create_arch_coef
373 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
374#endif
375
Gregory Maxwellae231142011-07-30 08:18:48 -0400376 for( i = 0; i < length; i++ ) {
377 /* Perform common calculations used in all states */
378
379 /* Long-term prediction */
380 if( signalType == TYPE_VOICED ) {
381 /* Unrolled loop */
Koen Vosbbfc9c92011-12-13 14:50:12 -0500382 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
Koen Vosa51ebd62011-12-14 11:39:29 -0500383 LTP_pred_Q14 = 2;
384 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
385 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
386 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
387 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
388 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
389 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400390 pred_lag_ptr++;
391 } else {
Koen Vosa51ebd62011-12-14 11:39:29 -0500392 LTP_pred_Q14 = 0;
Gregory Maxwellae231142011-07-30 08:18:48 -0400393 }
394
395 /* Long-term shaping */
396 if( lag > 0 ) {
397 /* Symmetric, packed FIR coefficients */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700398 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500399 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500400 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400401 shp_lag_ptr++;
Gregory Maxwellae231142011-07-30 08:18:48 -0400402 } else {
Koen Vosa51ebd62011-12-14 11:39:29 -0500403 n_LTP_Q14 = 0;
Gregory Maxwellae231142011-07-30 08:18:48 -0400404 }
405
406 for( k = 0; k < nStatesDelayedDecision; k++ ) {
407 /* Delayed decision state */
408 psDD = &psDelDec[ k ];
409
410 /* Sample state */
411 psSS = psSampleState[ k ];
412
413 /* Generate dither */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700414 psDD->Seed = silk_RAND( psDD->Seed );
Gregory Maxwellae231142011-07-30 08:18:48 -0400415
Gregory Maxwellae231142011-07-30 08:18:48 -0400416 /* Pointer used in short term prediction and shaping */
417 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
418 /* Short-term prediction */
Jonathan Lennox81a19422015-12-22 19:21:45 -0500419 LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
Koen Vosa51ebd62011-12-14 11:39:29 -0500420 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400421
422 /* Noise shape feedback */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700423 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
Gregory Maxwellae231142011-07-30 08:18:48 -0400424 /* Output of lowpass section */
Koen Vos6e40eb52016-02-21 11:34:11 +0800425 tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400426 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700427 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400428 psDD->sAR2_Q14[ 0 ] = tmp2;
Koen Vosa51ebd62011-12-14 11:39:29 -0500429 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
430 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400431 /* Loop over allpass sections */
432 for( j = 2; j < shapingLPCOrder; j += 2 ) {
433 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700434 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400435 psDD->sAR2_Q14[ j - 1 ] = tmp1;
Koen Vosa51ebd62011-12-14 11:39:29 -0500436 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400437 /* Output of allpass section */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700438 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400439 psDD->sAR2_Q14[ j + 0 ] = tmp2;
Koen Vosa51ebd62011-12-14 11:39:29 -0500440 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400441 }
442 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
Koen Vosa51ebd62011-12-14 11:39:29 -0500443 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400444
Koen Vosa51ebd62011-12-14 11:39:29 -0500445 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
446 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
447 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400448
Koen Vosa51ebd62011-12-14 11:39:29 -0500449 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
450 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
451 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400452
453 /* Input minus prediction plus noise feedback */
454 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
Koen Vosa51ebd62011-12-14 11:39:29 -0500455 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
456 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
457 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
458 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
459
460 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
Gregory Maxwellae231142011-07-30 08:18:48 -0400461
462 /* Flip sign depending on dither */
Koen Vos54518c82012-01-31 01:51:22 -0500463 if ( psDD->Seed < 0 ) {
464 r_Q10 = -r_Q10;
465 }
Jean-Marc Valin1ee139b2011-09-23 13:08:04 -0400466 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400467
468 /* Find two quantization level candidates and measure their rate-distortion */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700469 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500470 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
Jean-Marc Valin894f7292016-04-20 03:37:32 -0400471 if (Lambda_Q10 > 2048) {
472 /* For aggressive RDO, the bias becomes more than one pulse. */
473 int rdo_offset = Lambda_Q10/2 - 512;
474 if (q1_Q10 > rdo_offset) {
475 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
476 } else if (q1_Q10 < -rdo_offset) {
477 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
478 } else if (q1_Q10 < 0) {
479 q1_Q0 = -1;
480 } else {
481 q1_Q0 = 0;
482 }
483 }
Koen Vosa51ebd62011-12-14 11:39:29 -0500484 if( q1_Q0 > 0 ) {
485 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700486 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
487 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
488 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
489 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500490 } else if( q1_Q0 == 0 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400491 q1_Q10 = offset_Q10;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700492 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
493 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
494 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500495 } else if( q1_Q0 == -1 ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400496 q2_Q10 = offset_Q10;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700497 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
498 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
499 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500500 } else { /* q1_Q0 < -1 */
501 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700502 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
503 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
504 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
505 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400506 }
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700507 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
508 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
509 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
510 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400511
512 if( rd1_Q10 < rd2_Q10 ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700513 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
514 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400515 psSS[ 0 ].Q_Q10 = q1_Q10;
516 psSS[ 1 ].Q_Q10 = q2_Q10;
517 } else {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700518 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
519 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400520 psSS[ 0 ].Q_Q10 = q2_Q10;
521 psSS[ 1 ].Q_Q10 = q1_Q10;
522 }
523
524 /* Update states for best quantization */
525
526 /* Quantized excitation */
Koen Vos54518c82012-01-31 01:51:22 -0500527 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
528 if ( psDD->Seed < 0 ) {
529 exc_Q14 = -exc_Q14;
530 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400531
532 /* Add predictions */
Koen Vosa51ebd62011-12-14 11:39:29 -0500533 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
534 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400535
536 /* Update states */
Koen Vos6e40eb52016-02-21 11:34:11 +0800537 psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
538 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500539 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
540 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
541 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
542 psSS[ 0 ].xq_Q14 = xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400543
544 /* Update states for second best quantization */
545
546 /* Quantized excitation */
Koen Vos54518c82012-01-31 01:51:22 -0500547 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
548 if ( psDD->Seed < 0 ) {
549 exc_Q14 = -exc_Q14;
550 }
551
Gregory Maxwellae231142011-07-30 08:18:48 -0400552 /* Add predictions */
Koen Vosa51ebd62011-12-14 11:39:29 -0500553 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
554 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400555
556 /* Update states */
Koen Vos6e40eb52016-02-21 11:34:11 +0800557 psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
558 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
Koen Vosa51ebd62011-12-14 11:39:29 -0500559 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
560 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
561 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
562 psSS[ 1 ].xq_Q14 = xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400563 }
564
Koen Vos2799c532016-06-01 21:49:11 +0800565 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
566 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
567 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
Gregory Maxwellae231142011-07-30 08:18:48 -0400568
569 /* Find winner */
570 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
571 Winner_ind = 0;
572 for( k = 1; k < nStatesDelayedDecision; k++ ) {
573 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
574 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
575 Winner_ind = k;
576 }
577 }
578
579 /* Increase RD values of expired states */
580 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
581 for( k = 0; k < nStatesDelayedDecision; k++ ) {
582 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500583 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
584 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700585 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400586 }
587 }
588
589 /* Find worst in first set and best in second set */
590 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
591 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
592 RDmax_ind = 0;
593 RDmin_ind = 0;
594 for( k = 1; k < nStatesDelayedDecision; k++ ) {
595 /* find worst in first set */
596 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
597 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
598 RDmax_ind = k;
599 }
600 /* find best in second set */
601 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
602 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
603 RDmin_ind = k;
604 }
605 }
606
607 /* Replace a state if best from second set outperforms worst in first set */
608 if( RDmin_Q10 < RDmax_Q10 ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500609 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
610 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700611 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400612 }
613
614 /* Write samples from winner to output and long-term filter states */
615 psDD = &psDelDec[ Winner_ind ];
616 if( subfr > 0 || i >= decisionDelay ) {
Koen Vosbf75c8e2011-12-13 14:47:31 -0500617 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
618 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
Koen Vosa51ebd62011-12-14 11:39:29 -0500619 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
620 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
621 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400622 }
623 NSQ->sLTP_shp_buf_idx++;
624 NSQ->sLTP_buf_idx++;
625
626 /* Update states */
627 for( k = 0; k < nStatesDelayedDecision; k++ ) {
628 psDD = &psDelDec[ k ];
629 psSS = &psSampleState[ k ][ 0 ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500630 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
Koen Vos6e40eb52016-02-21 11:34:11 +0800631 psDD->Diff_Q14 = psSS->Diff_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400632 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
Koen Vosa51ebd62011-12-14 11:39:29 -0500633 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
Gregory Maxwellae231142011-07-30 08:18:48 -0400634 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
Koen Vosa51ebd62011-12-14 11:39:29 -0500635 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
636 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
Jean-Marc Valina4885a52011-10-11 18:00:23 -0400637 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400638 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
639 psDD->RD_Q10 = psSS->RD_Q10;
640 }
Koen Vosa51ebd62011-12-14 11:39:29 -0500641 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
Gregory Maxwellae231142011-07-30 08:18:48 -0400642 }
643 /* Update LPC states */
644 for( k = 0; k < nStatesDelayedDecision; k++ ) {
645 psDD = &psDelDec[ k ];
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700646 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400647 }
Timothy B. Terriberryc152d602013-05-08 10:32:37 -0700648 RESTORE_STACK;
Gregory Maxwellae231142011-07-30 08:18:48 -0400649}
Rhishikesh Agashef133bac2014-06-19 03:40:09 -0400650#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */
Gregory Maxwellae231142011-07-30 08:18:48 -0400651
Gregory Maxwell7830cf12013-10-17 15:56:52 -0700652static OPUS_INLINE void silk_nsq_del_dec_scale_states(
Gregory Maxwellae231142011-07-30 08:18:48 -0400653 const silk_encoder_state *psEncC, /* I Encoder State */
654 silk_nsq_state *NSQ, /* I/O NSQ state */
655 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
Koen Vos6e40eb52016-02-21 11:34:11 +0800656 const opus_int16 x16[], /* I Input */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400657 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
658 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500659 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Koen Vosacc7a6c2011-10-28 19:44:26 -0400660 opus_int subfr, /* I Subframe number */
661 opus_int nStatesDelayedDecision, /* I Number of del dec states */
662 const opus_int LTP_scale_Q14, /* I LTP state scaling */
663 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
664 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
665 const opus_int signal_type, /* I Signal type */
666 const opus_int decisionDelay /* I Decision delay */
Gregory Maxwellae231142011-07-30 08:18:48 -0400667)
668{
669 opus_int i, k, lag;
Koen Vos6e40eb52016-02-21 11:34:11 +0800670 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
Koen Vosbf75c8e2011-12-13 14:47:31 -0500671 NSQ_del_dec_struct *psDD;
Gregory Maxwellae231142011-07-30 08:18:48 -0400672
Gregory Maxwellae231142011-07-30 08:18:48 -0400673 lag = pitchL[ subfr ];
Koen Vosa51ebd62011-12-14 11:39:29 -0500674 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
675 silk_assert( inv_gain_Q31 != 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400676
Koen Vosbbfc9c92011-12-13 14:50:12 -0500677 /* Scale input */
Koen Vos6e40eb52016-02-21 11:34:11 +0800678 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
Koen Vosbbfc9c92011-12-13 14:50:12 -0500679 for( i = 0; i < psEncC->subfr_length; i++ ) {
Koen Vos6e40eb52016-02-21 11:34:11 +0800680 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
Koen Vosbbfc9c92011-12-13 14:50:12 -0500681 }
682
Gregory Maxwellae231142011-07-30 08:18:48 -0400683 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
684 if( NSQ->rewhite_flag ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400685 if( subfr == 0 ) {
686 /* Do LTP downscaling */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500687 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400688 }
689 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700690 silk_assert( i < MAX_FRAME_LENGTH );
Koen Vosbf75c8e2011-12-13 14:47:31 -0500691 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400692 }
693 }
694
695 /* Adjust for changing gain */
Koen Vos6e40eb52016-02-21 11:34:11 +0800696 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
697 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
698
Gregory Maxwellae231142011-07-30 08:18:48 -0400699 /* Scale long-term shaping state */
700 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 -0500701 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400702 }
703
704 /* Scale long-term prediction state */
Koen Voscc340502011-09-21 14:50:17 -0400705 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
706 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
Koen Vosbf75c8e2011-12-13 14:47:31 -0500707 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400708 }
709 }
710
711 for( k = 0; k < nStatesDelayedDecision; k++ ) {
712 psDD = &psDelDec[ k ];
713
714 /* Scale scalar states */
Koen Vosa51ebd62011-12-14 11:39:29 -0500715 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
Koen Vos6e40eb52016-02-21 11:34:11 +0800716 psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400717
718 /* Scale short-term prediction and shaping states */
719 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700720 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400721 }
722 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700723 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400724 }
725 for( i = 0; i < DECISION_DELAY; i++ ) {
Koen Vosa51ebd62011-12-14 11:39:29 -0500726 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
727 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400728 }
729 }
Koen Vos6e40eb52016-02-21 11:34:11 +0800730
731 /* Save inverse gain */
732 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
Gregory Maxwellae231142011-07-30 08:18:48 -0400733 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400734}