annotate src/opus-1.3/silk/NSQ.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 7aeed7906520
children
rev   line source
Chris@69 1 /***********************************************************************
Chris@69 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
Chris@69 3 Redistribution and use in source and binary forms, with or without
Chris@69 4 modification, are permitted provided that the following conditions
Chris@69 5 are met:
Chris@69 6 - Redistributions of source code must retain the above copyright notice,
Chris@69 7 this list of conditions and the following disclaimer.
Chris@69 8 - Redistributions in binary form must reproduce the above copyright
Chris@69 9 notice, this list of conditions and the following disclaimer in the
Chris@69 10 documentation and/or other materials provided with the distribution.
Chris@69 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
Chris@69 12 names of specific contributors, may be used to endorse or promote
Chris@69 13 products derived from this software without specific prior written
Chris@69 14 permission.
Chris@69 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Chris@69 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Chris@69 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Chris@69 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Chris@69 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Chris@69 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Chris@69 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Chris@69 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Chris@69 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Chris@69 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Chris@69 25 POSSIBILITY OF SUCH DAMAGE.
Chris@69 26 ***********************************************************************/
Chris@69 27
Chris@69 28 #ifdef HAVE_CONFIG_H
Chris@69 29 #include "config.h"
Chris@69 30 #endif
Chris@69 31
Chris@69 32 #include "main.h"
Chris@69 33 #include "stack_alloc.h"
Chris@69 34 #include "NSQ.h"
Chris@69 35
Chris@69 36
Chris@69 37 static OPUS_INLINE void silk_nsq_scale_states(
Chris@69 38 const silk_encoder_state *psEncC, /* I Encoder State */
Chris@69 39 silk_nsq_state *NSQ, /* I/O NSQ state */
Chris@69 40 const opus_int16 x16[], /* I input */
Chris@69 41 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
Chris@69 42 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
Chris@69 43 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Chris@69 44 opus_int subfr, /* I subframe number */
Chris@69 45 const opus_int LTP_scale_Q14, /* I */
Chris@69 46 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
Chris@69 47 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
Chris@69 48 const opus_int signal_type /* I Signal type */
Chris@69 49 );
Chris@69 50
Chris@69 51 #if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
Chris@69 52 static OPUS_INLINE void silk_noise_shape_quantizer(
Chris@69 53 silk_nsq_state *NSQ, /* I/O NSQ state */
Chris@69 54 opus_int signalType, /* I Signal type */
Chris@69 55 const opus_int32 x_sc_Q10[], /* I */
Chris@69 56 opus_int8 pulses[], /* O */
Chris@69 57 opus_int16 xq[], /* O */
Chris@69 58 opus_int32 sLTP_Q15[], /* I/O LTP state */
Chris@69 59 const opus_int16 a_Q12[], /* I Short term prediction coefs */
Chris@69 60 const opus_int16 b_Q14[], /* I Long term prediction coefs */
Chris@69 61 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
Chris@69 62 opus_int lag, /* I Pitch lag */
Chris@69 63 opus_int32 HarmShapeFIRPacked_Q14, /* I */
Chris@69 64 opus_int Tilt_Q14, /* I Spectral tilt */
Chris@69 65 opus_int32 LF_shp_Q14, /* I */
Chris@69 66 opus_int32 Gain_Q16, /* I */
Chris@69 67 opus_int Lambda_Q10, /* I */
Chris@69 68 opus_int offset_Q10, /* I */
Chris@69 69 opus_int length, /* I Input length */
Chris@69 70 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
Chris@69 71 opus_int predictLPCOrder, /* I Prediction filter order */
Chris@69 72 int arch /* I Architecture */
Chris@69 73 );
Chris@69 74 #endif
Chris@69 75
Chris@69 76 void silk_NSQ_c
Chris@69 77 (
Chris@69 78 const silk_encoder_state *psEncC, /* I Encoder State */
Chris@69 79 silk_nsq_state *NSQ, /* I/O NSQ state */
Chris@69 80 SideInfoIndices *psIndices, /* I/O Quantization Indices */
Chris@69 81 const opus_int16 x16[], /* I Input */
Chris@69 82 opus_int8 pulses[], /* O Quantized pulse signal */
Chris@69 83 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
Chris@69 84 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
Chris@69 85 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
Chris@69 86 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
Chris@69 87 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
Chris@69 88 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
Chris@69 89 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
Chris@69 90 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
Chris@69 91 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
Chris@69 92 const opus_int LTP_scale_Q14 /* I LTP state scaling */
Chris@69 93 )
Chris@69 94 {
Chris@69 95 opus_int k, lag, start_idx, LSF_interpolation_flag;
Chris@69 96 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
Chris@69 97 opus_int16 *pxq;
Chris@69 98 VARDECL( opus_int32, sLTP_Q15 );
Chris@69 99 VARDECL( opus_int16, sLTP );
Chris@69 100 opus_int32 HarmShapeFIRPacked_Q14;
Chris@69 101 opus_int offset_Q10;
Chris@69 102 VARDECL( opus_int32, x_sc_Q10 );
Chris@69 103 SAVE_STACK;
Chris@69 104
Chris@69 105 NSQ->rand_seed = psIndices->Seed;
Chris@69 106
Chris@69 107 /* Set unvoiced lag to the previous one, overwrite later for voiced */
Chris@69 108 lag = NSQ->lagPrev;
Chris@69 109
Chris@69 110 silk_assert( NSQ->prev_gain_Q16 != 0 );
Chris@69 111
Chris@69 112 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
Chris@69 113
Chris@69 114 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
Chris@69 115 LSF_interpolation_flag = 0;
Chris@69 116 } else {
Chris@69 117 LSF_interpolation_flag = 1;
Chris@69 118 }
Chris@69 119
Chris@69 120 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
Chris@69 121 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
Chris@69 122 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
Chris@69 123 /* Set up pointers to start of sub frame */
Chris@69 124 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
Chris@69 125 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
Chris@69 126 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
Chris@69 127 for( k = 0; k < psEncC->nb_subfr; k++ ) {
Chris@69 128 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
Chris@69 129 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
Chris@69 130 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
Chris@69 131
Chris@69 132 /* Noise shape parameters */
Chris@69 133 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
Chris@69 134 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
Chris@69 135 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
Chris@69 136
Chris@69 137 NSQ->rewhite_flag = 0;
Chris@69 138 if( psIndices->signalType == TYPE_VOICED ) {
Chris@69 139 /* Voiced */
Chris@69 140 lag = pitchL[ k ];
Chris@69 141
Chris@69 142 /* Re-whitening */
Chris@69 143 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
Chris@69 144 /* Rewhiten with new A coefs */
Chris@69 145 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
Chris@69 146 celt_assert( start_idx > 0 );
Chris@69 147
Chris@69 148 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
Chris@69 149 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
Chris@69 150
Chris@69 151 NSQ->rewhite_flag = 1;
Chris@69 152 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
Chris@69 153 }
Chris@69 154 }
Chris@69 155
Chris@69 156 silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
Chris@69 157
Chris@69 158 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
Chris@69 159 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
Chris@69 160 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
Chris@69 161
Chris@69 162 x16 += psEncC->subfr_length;
Chris@69 163 pulses += psEncC->subfr_length;
Chris@69 164 pxq += psEncC->subfr_length;
Chris@69 165 }
Chris@69 166
Chris@69 167 /* Update lagPrev for next frame */
Chris@69 168 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
Chris@69 169
Chris@69 170 /* Save quantized speech and noise shaping signals */
Chris@69 171 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
Chris@69 172 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
Chris@69 173 RESTORE_STACK;
Chris@69 174 }
Chris@69 175
Chris@69 176 /***********************************/
Chris@69 177 /* silk_noise_shape_quantizer */
Chris@69 178 /***********************************/
Chris@69 179
Chris@69 180 #if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
Chris@69 181 static OPUS_INLINE
Chris@69 182 #endif
Chris@69 183 void silk_noise_shape_quantizer(
Chris@69 184 silk_nsq_state *NSQ, /* I/O NSQ state */
Chris@69 185 opus_int signalType, /* I Signal type */
Chris@69 186 const opus_int32 x_sc_Q10[], /* I */
Chris@69 187 opus_int8 pulses[], /* O */
Chris@69 188 opus_int16 xq[], /* O */
Chris@69 189 opus_int32 sLTP_Q15[], /* I/O LTP state */
Chris@69 190 const opus_int16 a_Q12[], /* I Short term prediction coefs */
Chris@69 191 const opus_int16 b_Q14[], /* I Long term prediction coefs */
Chris@69 192 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
Chris@69 193 opus_int lag, /* I Pitch lag */
Chris@69 194 opus_int32 HarmShapeFIRPacked_Q14, /* I */
Chris@69 195 opus_int Tilt_Q14, /* I Spectral tilt */
Chris@69 196 opus_int32 LF_shp_Q14, /* I */
Chris@69 197 opus_int32 Gain_Q16, /* I */
Chris@69 198 opus_int Lambda_Q10, /* I */
Chris@69 199 opus_int offset_Q10, /* I */
Chris@69 200 opus_int length, /* I Input length */
Chris@69 201 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
Chris@69 202 opus_int predictLPCOrder, /* I Prediction filter order */
Chris@69 203 int arch /* I Architecture */
Chris@69 204 )
Chris@69 205 {
Chris@69 206 opus_int i;
Chris@69 207 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
Chris@69 208 opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
Chris@69 209 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
Chris@69 210 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
Chris@69 211 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
Chris@69 212 #ifdef silk_short_prediction_create_arch_coef
Chris@69 213 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
Chris@69 214 #endif
Chris@69 215
Chris@69 216 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
Chris@69 217 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
Chris@69 218 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
Chris@69 219
Chris@69 220 /* Set up short term AR state */
Chris@69 221 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
Chris@69 222
Chris@69 223 #ifdef silk_short_prediction_create_arch_coef
Chris@69 224 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
Chris@69 225 #endif
Chris@69 226
Chris@69 227 for( i = 0; i < length; i++ ) {
Chris@69 228 /* Generate dither */
Chris@69 229 NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
Chris@69 230
Chris@69 231 /* Short-term prediction */
Chris@69 232 LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
Chris@69 233
Chris@69 234 /* Long-term prediction */
Chris@69 235 if( signalType == TYPE_VOICED ) {
Chris@69 236 /* Unrolled loop */
Chris@69 237 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
Chris@69 238 LTP_pred_Q13 = 2;
Chris@69 239 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
Chris@69 240 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
Chris@69 241 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
Chris@69 242 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
Chris@69 243 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
Chris@69 244 pred_lag_ptr++;
Chris@69 245 } else {
Chris@69 246 LTP_pred_Q13 = 0;
Chris@69 247 }
Chris@69 248
Chris@69 249 /* Noise shape feedback */
Chris@69 250 celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
Chris@69 251 n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
Chris@69 252
Chris@69 253 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
Chris@69 254
Chris@69 255 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
Chris@69 256 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
Chris@69 257
Chris@69 258 celt_assert( lag > 0 || signalType != TYPE_VOICED );
Chris@69 259
Chris@69 260 /* Combine prediction and noise shaping signals */
Chris@69 261 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
Chris@69 262 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
Chris@69 263 if( lag > 0 ) {
Chris@69 264 /* Symmetric, packed FIR coefficients */
Chris@69 265 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
Chris@69 266 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
Chris@69 267 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
Chris@69 268 shp_lag_ptr++;
Chris@69 269
Chris@69 270 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
Chris@69 271 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
Chris@69 272 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
Chris@69 273 } else {
Chris@69 274 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
Chris@69 275 }
Chris@69 276
Chris@69 277 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
Chris@69 278
Chris@69 279 /* Flip sign depending on dither */
Chris@69 280 if( NSQ->rand_seed < 0 ) {
Chris@69 281 r_Q10 = -r_Q10;
Chris@69 282 }
Chris@69 283 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
Chris@69 284
Chris@69 285 /* Find two quantization level candidates and measure their rate-distortion */
Chris@69 286 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
Chris@69 287 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
Chris@69 288 if (Lambda_Q10 > 2048) {
Chris@69 289 /* For aggressive RDO, the bias becomes more than one pulse. */
Chris@69 290 int rdo_offset = Lambda_Q10/2 - 512;
Chris@69 291 if (q1_Q10 > rdo_offset) {
Chris@69 292 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
Chris@69 293 } else if (q1_Q10 < -rdo_offset) {
Chris@69 294 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
Chris@69 295 } else if (q1_Q10 < 0) {
Chris@69 296 q1_Q0 = -1;
Chris@69 297 } else {
Chris@69 298 q1_Q0 = 0;
Chris@69 299 }
Chris@69 300 }
Chris@69 301 if( q1_Q0 > 0 ) {
Chris@69 302 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Chris@69 303 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
Chris@69 304 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
Chris@69 305 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
Chris@69 306 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Chris@69 307 } else if( q1_Q0 == 0 ) {
Chris@69 308 q1_Q10 = offset_Q10;
Chris@69 309 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
Chris@69 310 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
Chris@69 311 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Chris@69 312 } else if( q1_Q0 == -1 ) {
Chris@69 313 q2_Q10 = offset_Q10;
Chris@69 314 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
Chris@69 315 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
Chris@69 316 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
Chris@69 317 } else { /* Q1_Q0 < -1 */
Chris@69 318 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
Chris@69 319 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
Chris@69 320 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
Chris@69 321 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
Chris@69 322 rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
Chris@69 323 }
Chris@69 324 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
Chris@69 325 rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
Chris@69 326 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
Chris@69 327 rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
Chris@69 328
Chris@69 329 if( rd2_Q20 < rd1_Q20 ) {
Chris@69 330 q1_Q10 = q2_Q10;
Chris@69 331 }
Chris@69 332
Chris@69 333 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
Chris@69 334
Chris@69 335 /* Excitation */
Chris@69 336 exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
Chris@69 337 if ( NSQ->rand_seed < 0 ) {
Chris@69 338 exc_Q14 = -exc_Q14;
Chris@69 339 }
Chris@69 340
Chris@69 341 /* Add predictions */
Chris@69 342 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
Chris@69 343 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
Chris@69 344
Chris@69 345 /* Scale XQ back to normal level before saving */
Chris@69 346 xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
Chris@69 347
Chris@69 348 /* Update states */
Chris@69 349 psLPC_Q14++;
Chris@69 350 *psLPC_Q14 = xq_Q14;
Chris@69 351 NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
Chris@69 352 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
Chris@69 353 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
Chris@69 354
Chris@69 355 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
Chris@69 356 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
Chris@69 357 NSQ->sLTP_shp_buf_idx++;
Chris@69 358 NSQ->sLTP_buf_idx++;
Chris@69 359
Chris@69 360 /* Make dither dependent on quantized signal */
Chris@69 361 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
Chris@69 362 }
Chris@69 363
Chris@69 364 /* Update LPC synth buffer */
Chris@69 365 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
Chris@69 366 }
Chris@69 367
Chris@69 368 static OPUS_INLINE void silk_nsq_scale_states(
Chris@69 369 const silk_encoder_state *psEncC, /* I Encoder State */
Chris@69 370 silk_nsq_state *NSQ, /* I/O NSQ state */
Chris@69 371 const opus_int16 x16[], /* I input */
Chris@69 372 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
Chris@69 373 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
Chris@69 374 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
Chris@69 375 opus_int subfr, /* I subframe number */
Chris@69 376 const opus_int LTP_scale_Q14, /* I */
Chris@69 377 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
Chris@69 378 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
Chris@69 379 const opus_int signal_type /* I Signal type */
Chris@69 380 )
Chris@69 381 {
Chris@69 382 opus_int i, lag;
Chris@69 383 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
Chris@69 384
Chris@69 385 lag = pitchL[ subfr ];
Chris@69 386 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
Chris@69 387 silk_assert( inv_gain_Q31 != 0 );
Chris@69 388
Chris@69 389 /* Scale input */
Chris@69 390 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
Chris@69 391 for( i = 0; i < psEncC->subfr_length; i++ ) {
Chris@69 392 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
Chris@69 393 }
Chris@69 394
Chris@69 395 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
Chris@69 396 if( NSQ->rewhite_flag ) {
Chris@69 397 if( subfr == 0 ) {
Chris@69 398 /* Do LTP downscaling */
Chris@69 399 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
Chris@69 400 }
Chris@69 401 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
Chris@69 402 silk_assert( i < MAX_FRAME_LENGTH );
Chris@69 403 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
Chris@69 404 }
Chris@69 405 }
Chris@69 406
Chris@69 407 /* Adjust for changing gain */
Chris@69 408 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
Chris@69 409 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
Chris@69 410
Chris@69 411 /* Scale long-term shaping state */
Chris@69 412 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
Chris@69 413 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
Chris@69 414 }
Chris@69 415
Chris@69 416 /* Scale long-term prediction state */
Chris@69 417 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
Chris@69 418 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
Chris@69 419 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
Chris@69 420 }
Chris@69 421 }
Chris@69 422
Chris@69 423 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
Chris@69 424 NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
Chris@69 425
Chris@69 426 /* Scale short-term prediction and shaping states */
Chris@69 427 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
Chris@69 428 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
Chris@69 429 }
Chris@69 430 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
Chris@69 431 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
Chris@69 432 }
Chris@69 433
Chris@69 434 /* Save inverse gain */
Chris@69 435 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
Chris@69 436 }
Chris@69 437 }