media/libopus/silk/NSQ_del_dec.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /***********************************************************************
michael@0 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
michael@0 3 Redistribution and use in source and binary forms, with or without
michael@0 4 modification, are permitted provided that the following conditions
michael@0 5 are met:
michael@0 6 - Redistributions of source code must retain the above copyright notice,
michael@0 7 this list of conditions and the following disclaimer.
michael@0 8 - Redistributions in binary form must reproduce the above copyright
michael@0 9 notice, this list of conditions and the following disclaimer in the
michael@0 10 documentation and/or other materials provided with the distribution.
michael@0 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
michael@0 12 names of specific contributors, may be used to endorse or promote
michael@0 13 products derived from this software without specific prior written
michael@0 14 permission.
michael@0 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
michael@0 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
michael@0 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
michael@0 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
michael@0 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
michael@0 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
michael@0 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
michael@0 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
michael@0 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
michael@0 25 POSSIBILITY OF SUCH DAMAGE.
michael@0 26 ***********************************************************************/
michael@0 27
michael@0 28 #ifdef HAVE_CONFIG_H
michael@0 29 #include "config.h"
michael@0 30 #endif
michael@0 31
michael@0 32 #include "main.h"
michael@0 33 #include "stack_alloc.h"
michael@0 34
michael@0 35 typedef struct {
michael@0 36 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
michael@0 37 opus_int32 RandState[ DECISION_DELAY ];
michael@0 38 opus_int32 Q_Q10[ DECISION_DELAY ];
michael@0 39 opus_int32 Xq_Q14[ DECISION_DELAY ];
michael@0 40 opus_int32 Pred_Q15[ DECISION_DELAY ];
michael@0 41 opus_int32 Shape_Q14[ DECISION_DELAY ];
michael@0 42 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
michael@0 43 opus_int32 LF_AR_Q14;
michael@0 44 opus_int32 Seed;
michael@0 45 opus_int32 SeedInit;
michael@0 46 opus_int32 RD_Q10;
michael@0 47 } NSQ_del_dec_struct;
michael@0 48
michael@0 49 typedef struct {
michael@0 50 opus_int32 Q_Q10;
michael@0 51 opus_int32 RD_Q10;
michael@0 52 opus_int32 xq_Q14;
michael@0 53 opus_int32 LF_AR_Q14;
michael@0 54 opus_int32 sLTP_shp_Q14;
michael@0 55 opus_int32 LPC_exc_Q14;
michael@0 56 } NSQ_sample_struct;
michael@0 57
michael@0 58 typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
michael@0 59
michael@0 60 static OPUS_INLINE void silk_nsq_del_dec_scale_states(
michael@0 61 const silk_encoder_state *psEncC, /* I Encoder State */
michael@0 62 silk_nsq_state *NSQ, /* I/O NSQ state */
michael@0 63 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
michael@0 64 const opus_int32 x_Q3[], /* I Input in Q3 */
michael@0 65 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
michael@0 66 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
michael@0 67 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
michael@0 68 opus_int subfr, /* I Subframe number */
michael@0 69 opus_int nStatesDelayedDecision, /* I Number of del dec states */
michael@0 70 const opus_int LTP_scale_Q14, /* I LTP state scaling */
michael@0 71 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
michael@0 72 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
michael@0 73 const opus_int signal_type, /* I Signal type */
michael@0 74 const opus_int decisionDelay /* I Decision delay */
michael@0 75 );
michael@0 76
michael@0 77 /******************************************/
michael@0 78 /* Noise shape quantizer for one subframe */
michael@0 79 /******************************************/
michael@0 80 static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
michael@0 81 silk_nsq_state *NSQ, /* I/O NSQ state */
michael@0 82 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
michael@0 83 opus_int signalType, /* I Signal type */
michael@0 84 const opus_int32 x_Q10[], /* I */
michael@0 85 opus_int8 pulses[], /* O */
michael@0 86 opus_int16 xq[], /* O */
michael@0 87 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
michael@0 88 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
michael@0 89 const opus_int16 a_Q12[], /* I Short term prediction coefs */
michael@0 90 const opus_int16 b_Q14[], /* I Long term prediction coefs */
michael@0 91 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
michael@0 92 opus_int lag, /* I Pitch lag */
michael@0 93 opus_int32 HarmShapeFIRPacked_Q14, /* I */
michael@0 94 opus_int Tilt_Q14, /* I Spectral tilt */
michael@0 95 opus_int32 LF_shp_Q14, /* I */
michael@0 96 opus_int32 Gain_Q16, /* I */
michael@0 97 opus_int Lambda_Q10, /* I */
michael@0 98 opus_int offset_Q10, /* I */
michael@0 99 opus_int length, /* I Input length */
michael@0 100 opus_int subfr, /* I Subframe number */
michael@0 101 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
michael@0 102 opus_int predictLPCOrder, /* I Prediction filter order */
michael@0 103 opus_int warping_Q16, /* I */
michael@0 104 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
michael@0 105 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
michael@0 106 opus_int decisionDelay /* I */
michael@0 107 );
michael@0 108
michael@0 109 void silk_NSQ_del_dec(
michael@0 110 const silk_encoder_state *psEncC, /* I/O Encoder State */
michael@0 111 silk_nsq_state *NSQ, /* I/O NSQ state */
michael@0 112 SideInfoIndices *psIndices, /* I/O Quantization Indices */
michael@0 113 const opus_int32 x_Q3[], /* I Prefiltered input signal */
michael@0 114 opus_int8 pulses[], /* O Quantized pulse signal */
michael@0 115 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
michael@0 116 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
michael@0 117 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
michael@0 118 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
michael@0 119 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
michael@0 120 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
michael@0 121 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
michael@0 122 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
michael@0 123 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
michael@0 124 const opus_int LTP_scale_Q14 /* I LTP state scaling */
michael@0 125 )
michael@0 126 {
michael@0 127 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
michael@0 128 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
michael@0 129 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
michael@0 130 opus_int16 *pxq;
michael@0 131 VARDECL( opus_int32, sLTP_Q15 );
michael@0 132 VARDECL( opus_int16, sLTP );
michael@0 133 opus_int32 HarmShapeFIRPacked_Q14;
michael@0 134 opus_int offset_Q10;
michael@0 135 opus_int32 RDmin_Q10, Gain_Q10;
michael@0 136 VARDECL( opus_int32, x_sc_Q10 );
michael@0 137 VARDECL( opus_int32, delayedGain_Q10 );
michael@0 138 VARDECL( NSQ_del_dec_struct, psDelDec );
michael@0 139 NSQ_del_dec_struct *psDD;
michael@0 140 SAVE_STACK;
michael@0 141
michael@0 142 /* Set unvoiced lag to the previous one, overwrite later for voiced */
michael@0 143 lag = NSQ->lagPrev;
michael@0 144
michael@0 145 silk_assert( NSQ->prev_gain_Q16 != 0 );
michael@0 146
michael@0 147 /* Initialize delayed decision states */
michael@0 148 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
michael@0 149 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
michael@0 150 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
michael@0 151 psDD = &psDelDec[ k ];
michael@0 152 psDD->Seed = ( k + psIndices->Seed ) & 3;
michael@0 153 psDD->SeedInit = psDD->Seed;
michael@0 154 psDD->RD_Q10 = 0;
michael@0 155 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
michael@0 156 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
michael@0 157 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
michael@0 158 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
michael@0 159 }
michael@0 160
michael@0 161 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
michael@0 162 smpl_buf_idx = 0; /* index of oldest samples */
michael@0 163
michael@0 164 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
michael@0 165
michael@0 166 /* For voiced frames limit the decision delay to lower than the pitch lag */
michael@0 167 if( psIndices->signalType == TYPE_VOICED ) {
michael@0 168 for( k = 0; k < psEncC->nb_subfr; k++ ) {
michael@0 169 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
michael@0 170 }
michael@0 171 } else {
michael@0 172 if( lag > 0 ) {
michael@0 173 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
michael@0 174 }
michael@0 175 }
michael@0 176
michael@0 177 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
michael@0 178 LSF_interpolation_flag = 0;
michael@0 179 } else {
michael@0 180 LSF_interpolation_flag = 1;
michael@0 181 }
michael@0 182
michael@0 183 ALLOC( sLTP_Q15,
michael@0 184 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
michael@0 185 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
michael@0 186 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
michael@0 187 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
michael@0 188 /* Set up pointers to start of sub frame */
michael@0 189 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
michael@0 190 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
michael@0 191 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
michael@0 192 subfr = 0;
michael@0 193 for( k = 0; k < psEncC->nb_subfr; k++ ) {
michael@0 194 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
michael@0 195 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
michael@0 196 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
michael@0 197
michael@0 198 /* Noise shape parameters */
michael@0 199 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
michael@0 200 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
michael@0 201 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
michael@0 202
michael@0 203 NSQ->rewhite_flag = 0;
michael@0 204 if( psIndices->signalType == TYPE_VOICED ) {
michael@0 205 /* Voiced */
michael@0 206 lag = pitchL[ k ];
michael@0 207
michael@0 208 /* Re-whitening */
michael@0 209 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
michael@0 210 if( k == 2 ) {
michael@0 211 /* RESET DELAYED DECISIONS */
michael@0 212 /* Find winner */
michael@0 213 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
michael@0 214 Winner_ind = 0;
michael@0 215 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
michael@0 216 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
michael@0 217 RDmin_Q10 = psDelDec[ i ].RD_Q10;
michael@0 218 Winner_ind = i;
michael@0 219 }
michael@0 220 }
michael@0 221 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
michael@0 222 if( i != Winner_ind ) {
michael@0 223 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
michael@0 224 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
michael@0 225 }
michael@0 226 }
michael@0 227
michael@0 228 /* Copy final part of signals from winner state to output and long-term filter states */
michael@0 229 psDD = &psDelDec[ Winner_ind ];
michael@0 230 last_smple_idx = smpl_buf_idx + decisionDelay;
michael@0 231 for( i = 0; i < decisionDelay; i++ ) {
michael@0 232 last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
michael@0 233 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
michael@0 234 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
michael@0 235 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
michael@0 236 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
michael@0 237 }
michael@0 238
michael@0 239 subfr = 0;
michael@0 240 }
michael@0 241
michael@0 242 /* Rewhiten with new A coefs */
michael@0 243 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
michael@0 244 silk_assert( start_idx > 0 );
michael@0 245
michael@0 246 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
michael@0 247 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder );
michael@0 248
michael@0 249 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
michael@0 250 NSQ->rewhite_flag = 1;
michael@0 251 }
michael@0 252 }
michael@0 253
michael@0 254 silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
michael@0 255 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
michael@0 256
michael@0 257 silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
michael@0 258 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
michael@0 259 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
michael@0 260 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
michael@0 261
michael@0 262 x_Q3 += psEncC->subfr_length;
michael@0 263 pulses += psEncC->subfr_length;
michael@0 264 pxq += psEncC->subfr_length;
michael@0 265 }
michael@0 266
michael@0 267 /* Find winner */
michael@0 268 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
michael@0 269 Winner_ind = 0;
michael@0 270 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
michael@0 271 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
michael@0 272 RDmin_Q10 = psDelDec[ k ].RD_Q10;
michael@0 273 Winner_ind = k;
michael@0 274 }
michael@0 275 }
michael@0 276
michael@0 277 /* Copy final part of signals from winner state to output and long-term filter states */
michael@0 278 psDD = &psDelDec[ Winner_ind ];
michael@0 279 psIndices->Seed = psDD->SeedInit;
michael@0 280 last_smple_idx = smpl_buf_idx + decisionDelay;
michael@0 281 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
michael@0 282 for( i = 0; i < decisionDelay; i++ ) {
michael@0 283 last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
michael@0 284 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
michael@0 285 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
michael@0 286 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
michael@0 287 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
michael@0 288 }
michael@0 289 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
michael@0 290 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
michael@0 291
michael@0 292 /* Update states */
michael@0 293 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
michael@0 294 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
michael@0 295
michael@0 296 /* Save quantized speech signal */
michael@0 297 /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
michael@0 298 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
michael@0 299 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
michael@0 300 RESTORE_STACK;
michael@0 301 }
michael@0 302
michael@0 303 /******************************************/
michael@0 304 /* Noise shape quantizer for one subframe */
michael@0 305 /******************************************/
michael@0 306 static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
michael@0 307 silk_nsq_state *NSQ, /* I/O NSQ state */
michael@0 308 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
michael@0 309 opus_int signalType, /* I Signal type */
michael@0 310 const opus_int32 x_Q10[], /* I */
michael@0 311 opus_int8 pulses[], /* O */
michael@0 312 opus_int16 xq[], /* O */
michael@0 313 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
michael@0 314 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
michael@0 315 const opus_int16 a_Q12[], /* I Short term prediction coefs */
michael@0 316 const opus_int16 b_Q14[], /* I Long term prediction coefs */
michael@0 317 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
michael@0 318 opus_int lag, /* I Pitch lag */
michael@0 319 opus_int32 HarmShapeFIRPacked_Q14, /* I */
michael@0 320 opus_int Tilt_Q14, /* I Spectral tilt */
michael@0 321 opus_int32 LF_shp_Q14, /* I */
michael@0 322 opus_int32 Gain_Q16, /* I */
michael@0 323 opus_int Lambda_Q10, /* I */
michael@0 324 opus_int offset_Q10, /* I */
michael@0 325 opus_int length, /* I Input length */
michael@0 326 opus_int subfr, /* I Subframe number */
michael@0 327 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
michael@0 328 opus_int predictLPCOrder, /* I Prediction filter order */
michael@0 329 opus_int warping_Q16, /* I */
michael@0 330 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
michael@0 331 opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
michael@0 332 opus_int decisionDelay /* I */
michael@0 333 )
michael@0 334 {
michael@0 335 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
michael@0 336 opus_int32 Winner_rand_state;
michael@0 337 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
michael@0 338 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
michael@0 339 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
michael@0 340 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
michael@0 341 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
michael@0 342 VARDECL( NSQ_sample_pair, psSampleState );
michael@0 343 NSQ_del_dec_struct *psDD;
michael@0 344 NSQ_sample_struct *psSS;
michael@0 345 SAVE_STACK;
michael@0 346
michael@0 347 silk_assert( nStatesDelayedDecision > 0 );
michael@0 348 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
michael@0 349
michael@0 350 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
michael@0 351 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
michael@0 352 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
michael@0 353
michael@0 354 for( i = 0; i < length; i++ ) {
michael@0 355 /* Perform common calculations used in all states */
michael@0 356
michael@0 357 /* Long-term prediction */
michael@0 358 if( signalType == TYPE_VOICED ) {
michael@0 359 /* Unrolled loop */
michael@0 360 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
michael@0 361 LTP_pred_Q14 = 2;
michael@0 362 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
michael@0 363 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
michael@0 364 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
michael@0 365 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
michael@0 366 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
michael@0 367 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
michael@0 368 pred_lag_ptr++;
michael@0 369 } else {
michael@0 370 LTP_pred_Q14 = 0;
michael@0 371 }
michael@0 372
michael@0 373 /* Long-term shaping */
michael@0 374 if( lag > 0 ) {
michael@0 375 /* Symmetric, packed FIR coefficients */
michael@0 376 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
michael@0 377 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
michael@0 378 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
michael@0 379 shp_lag_ptr++;
michael@0 380 } else {
michael@0 381 n_LTP_Q14 = 0;
michael@0 382 }
michael@0 383
michael@0 384 for( k = 0; k < nStatesDelayedDecision; k++ ) {
michael@0 385 /* Delayed decision state */
michael@0 386 psDD = &psDelDec[ k ];
michael@0 387
michael@0 388 /* Sample state */
michael@0 389 psSS = psSampleState[ k ];
michael@0 390
michael@0 391 /* Generate dither */
michael@0 392 psDD->Seed = silk_RAND( psDD->Seed );
michael@0 393
michael@0 394 /* Pointer used in short term prediction and shaping */
michael@0 395 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
michael@0 396 /* Short-term prediction */
michael@0 397 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
michael@0 398 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
michael@0 399 LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
michael@0 400 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
michael@0 401 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
michael@0 402 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
michael@0 403 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
michael@0 404 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
michael@0 405 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
michael@0 406 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
michael@0 407 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
michael@0 408 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
michael@0 409 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
michael@0 410 if( predictLPCOrder == 16 ) {
michael@0 411 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
michael@0 412 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
michael@0 413 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
michael@0 414 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
michael@0 415 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
michael@0 416 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
michael@0 417 }
michael@0 418 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
michael@0 419
michael@0 420 /* Noise shape feedback */
michael@0 421 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
michael@0 422 /* Output of lowpass section */
michael@0 423 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
michael@0 424 /* Output of allpass section */
michael@0 425 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
michael@0 426 psDD->sAR2_Q14[ 0 ] = tmp2;
michael@0 427 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
michael@0 428 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
michael@0 429 /* Loop over allpass sections */
michael@0 430 for( j = 2; j < shapingLPCOrder; j += 2 ) {
michael@0 431 /* Output of allpass section */
michael@0 432 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
michael@0 433 psDD->sAR2_Q14[ j - 1 ] = tmp1;
michael@0 434 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
michael@0 435 /* Output of allpass section */
michael@0 436 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
michael@0 437 psDD->sAR2_Q14[ j + 0 ] = tmp2;
michael@0 438 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
michael@0 439 }
michael@0 440 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
michael@0 441 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
michael@0 442
michael@0 443 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
michael@0 444 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
michael@0 445 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
michael@0 446
michael@0 447 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
michael@0 448 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
michael@0 449 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
michael@0 450
michael@0 451 /* Input minus prediction plus noise feedback */
michael@0 452 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
michael@0 453 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
michael@0 454 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
michael@0 455 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
michael@0 456 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
michael@0 457
michael@0 458 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
michael@0 459
michael@0 460 /* Flip sign depending on dither */
michael@0 461 if ( psDD->Seed < 0 ) {
michael@0 462 r_Q10 = -r_Q10;
michael@0 463 }
michael@0 464 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
michael@0 465
michael@0 466 /* Find two quantization level candidates and measure their rate-distortion */
michael@0 467 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
michael@0 468 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
michael@0 469 if( q1_Q0 > 0 ) {
michael@0 470 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
michael@0 471 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
michael@0 472 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
michael@0 473 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
michael@0 474 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
michael@0 475 } else if( q1_Q0 == 0 ) {
michael@0 476 q1_Q10 = offset_Q10;
michael@0 477 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
michael@0 478 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
michael@0 479 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
michael@0 480 } else if( q1_Q0 == -1 ) {
michael@0 481 q2_Q10 = offset_Q10;
michael@0 482 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
michael@0 483 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
michael@0 484 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
michael@0 485 } else { /* q1_Q0 < -1 */
michael@0 486 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
michael@0 487 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
michael@0 488 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
michael@0 489 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
michael@0 490 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
michael@0 491 }
michael@0 492 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
michael@0 493 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
michael@0 494 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
michael@0 495 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
michael@0 496
michael@0 497 if( rd1_Q10 < rd2_Q10 ) {
michael@0 498 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
michael@0 499 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
michael@0 500 psSS[ 0 ].Q_Q10 = q1_Q10;
michael@0 501 psSS[ 1 ].Q_Q10 = q2_Q10;
michael@0 502 } else {
michael@0 503 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
michael@0 504 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
michael@0 505 psSS[ 0 ].Q_Q10 = q2_Q10;
michael@0 506 psSS[ 1 ].Q_Q10 = q1_Q10;
michael@0 507 }
michael@0 508
michael@0 509 /* Update states for best quantization */
michael@0 510
michael@0 511 /* Quantized excitation */
michael@0 512 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
michael@0 513 if ( psDD->Seed < 0 ) {
michael@0 514 exc_Q14 = -exc_Q14;
michael@0 515 }
michael@0 516
michael@0 517 /* Add predictions */
michael@0 518 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
michael@0 519 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
michael@0 520
michael@0 521 /* Update states */
michael@0 522 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
michael@0 523 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
michael@0 524 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
michael@0 525 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
michael@0 526 psSS[ 0 ].xq_Q14 = xq_Q14;
michael@0 527
michael@0 528 /* Update states for second best quantization */
michael@0 529
michael@0 530 /* Quantized excitation */
michael@0 531 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
michael@0 532 if ( psDD->Seed < 0 ) {
michael@0 533 exc_Q14 = -exc_Q14;
michael@0 534 }
michael@0 535
michael@0 536
michael@0 537 /* Add predictions */
michael@0 538 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
michael@0 539 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
michael@0 540
michael@0 541 /* Update states */
michael@0 542 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
michael@0 543 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
michael@0 544 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
michael@0 545 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
michael@0 546 psSS[ 1 ].xq_Q14 = xq_Q14;
michael@0 547 }
michael@0 548
michael@0 549 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
michael@0 550 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
michael@0 551
michael@0 552 /* Find winner */
michael@0 553 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
michael@0 554 Winner_ind = 0;
michael@0 555 for( k = 1; k < nStatesDelayedDecision; k++ ) {
michael@0 556 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
michael@0 557 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
michael@0 558 Winner_ind = k;
michael@0 559 }
michael@0 560 }
michael@0 561
michael@0 562 /* Increase RD values of expired states */
michael@0 563 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
michael@0 564 for( k = 0; k < nStatesDelayedDecision; k++ ) {
michael@0 565 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
michael@0 566 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
michael@0 567 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
michael@0 568 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
michael@0 569 }
michael@0 570 }
michael@0 571
michael@0 572 /* Find worst in first set and best in second set */
michael@0 573 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
michael@0 574 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
michael@0 575 RDmax_ind = 0;
michael@0 576 RDmin_ind = 0;
michael@0 577 for( k = 1; k < nStatesDelayedDecision; k++ ) {
michael@0 578 /* find worst in first set */
michael@0 579 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
michael@0 580 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
michael@0 581 RDmax_ind = k;
michael@0 582 }
michael@0 583 /* find best in second set */
michael@0 584 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
michael@0 585 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
michael@0 586 RDmin_ind = k;
michael@0 587 }
michael@0 588 }
michael@0 589
michael@0 590 /* Replace a state if best from second set outperforms worst in first set */
michael@0 591 if( RDmin_Q10 < RDmax_Q10 ) {
michael@0 592 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
michael@0 593 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
michael@0 594 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
michael@0 595 }
michael@0 596
michael@0 597 /* Write samples from winner to output and long-term filter states */
michael@0 598 psDD = &psDelDec[ Winner_ind ];
michael@0 599 if( subfr > 0 || i >= decisionDelay ) {
michael@0 600 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
michael@0 601 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
michael@0 602 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
michael@0 603 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
michael@0 604 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
michael@0 605 }
michael@0 606 NSQ->sLTP_shp_buf_idx++;
michael@0 607 NSQ->sLTP_buf_idx++;
michael@0 608
michael@0 609 /* Update states */
michael@0 610 for( k = 0; k < nStatesDelayedDecision; k++ ) {
michael@0 611 psDD = &psDelDec[ k ];
michael@0 612 psSS = &psSampleState[ k ][ 0 ];
michael@0 613 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
michael@0 614 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
michael@0 615 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
michael@0 616 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
michael@0 617 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
michael@0 618 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
michael@0 619 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
michael@0 620 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
michael@0 621 psDD->RD_Q10 = psSS->RD_Q10;
michael@0 622 }
michael@0 623 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
michael@0 624 }
michael@0 625 /* Update LPC states */
michael@0 626 for( k = 0; k < nStatesDelayedDecision; k++ ) {
michael@0 627 psDD = &psDelDec[ k ];
michael@0 628 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
michael@0 629 }
michael@0 630 RESTORE_STACK;
michael@0 631 }
michael@0 632
michael@0 633 static OPUS_INLINE void silk_nsq_del_dec_scale_states(
michael@0 634 const silk_encoder_state *psEncC, /* I Encoder State */
michael@0 635 silk_nsq_state *NSQ, /* I/O NSQ state */
michael@0 636 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
michael@0 637 const opus_int32 x_Q3[], /* I Input in Q3 */
michael@0 638 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
michael@0 639 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
michael@0 640 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
michael@0 641 opus_int subfr, /* I Subframe number */
michael@0 642 opus_int nStatesDelayedDecision, /* I Number of del dec states */
michael@0 643 const opus_int LTP_scale_Q14, /* I LTP state scaling */
michael@0 644 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
michael@0 645 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
michael@0 646 const opus_int signal_type, /* I Signal type */
michael@0 647 const opus_int decisionDelay /* I Decision delay */
michael@0 648 )
michael@0 649 {
michael@0 650 opus_int i, k, lag;
michael@0 651 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
michael@0 652 NSQ_del_dec_struct *psDD;
michael@0 653
michael@0 654 lag = pitchL[ subfr ];
michael@0 655 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
michael@0 656 silk_assert( inv_gain_Q31 != 0 );
michael@0 657
michael@0 658 /* Calculate gain adjustment factor */
michael@0 659 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
michael@0 660 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
michael@0 661 } else {
michael@0 662 gain_adj_Q16 = (opus_int32)1 << 16;
michael@0 663 }
michael@0 664
michael@0 665 /* Scale input */
michael@0 666 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
michael@0 667 for( i = 0; i < psEncC->subfr_length; i++ ) {
michael@0 668 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
michael@0 669 }
michael@0 670
michael@0 671 /* Save inverse gain */
michael@0 672 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
michael@0 673
michael@0 674 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
michael@0 675 if( NSQ->rewhite_flag ) {
michael@0 676 if( subfr == 0 ) {
michael@0 677 /* Do LTP downscaling */
michael@0 678 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
michael@0 679 }
michael@0 680 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
michael@0 681 silk_assert( i < MAX_FRAME_LENGTH );
michael@0 682 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
michael@0 683 }
michael@0 684 }
michael@0 685
michael@0 686 /* Adjust for changing gain */
michael@0 687 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
michael@0 688 /* Scale long-term shaping state */
michael@0 689 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
michael@0 690 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
michael@0 691 }
michael@0 692
michael@0 693 /* Scale long-term prediction state */
michael@0 694 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
michael@0 695 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
michael@0 696 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
michael@0 697 }
michael@0 698 }
michael@0 699
michael@0 700 for( k = 0; k < nStatesDelayedDecision; k++ ) {
michael@0 701 psDD = &psDelDec[ k ];
michael@0 702
michael@0 703 /* Scale scalar states */
michael@0 704 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
michael@0 705
michael@0 706 /* Scale short-term prediction and shaping states */
michael@0 707 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
michael@0 708 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
michael@0 709 }
michael@0 710 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
michael@0 711 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
michael@0 712 }
michael@0 713 for( i = 0; i < DECISION_DELAY; i++ ) {
michael@0 714 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
michael@0 715 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
michael@0 716 }
michael@0 717 }
michael@0 718 }
michael@0 719 }

mercurial