/* even order AR filter */ void SKP_Silk_LPC_synthesis_filter( const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [Order] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len, /* I: signal length */ const SKP_int Order /* I: filter order, must be even */ ) { SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 ); SKP_int32 SA, SB, out32_Q10, out32; /* Order must be even */ SKP_assert( 2 * Order_half == Order ); /* S[] values are in Q14 */ for( k = 0; k < len; k++ ) { SA = S[ Order - 1 ]; out32_Q10 = 0; for( j = 0; j < ( Order_half - 1 ); j++ ) { idx = SKP_SMULBB( 2, j ) + 1; SB = S[ Order - 1 - idx ]; S[ Order - 1 - idx ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] ); out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] ); SA = S[ Order - 2 - idx ]; S[ Order - 2 - idx ] = SB; } /* unrolled loop: epilog */ SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] ); out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] ); /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* move result into delay line */ S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } }
/* Processing of gains */ void silk_process_gains_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */ silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */ ) { silk_shape_state_FIX *psShapeSt = &psEnc->sShape; opus_int k; opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; /* Gain reduction when LTP coding gain is high */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ s_Q16 = -silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); } } /* Limit the quantized signal */ /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ InvMaxSqrVal_Q16 = SKP_DIV32_16( silk_log2lin( SKP_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Soft limit on ratio residual energy and squared gains */ ResNrg = psEncCtrl->ResNrg[ k ]; ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); if( psEncCtrl->ResNrgQ[ k ] > 0 ) { ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); } else { if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { ResNrgPart = SKP_int32_MAX; } else { ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); } } gain = psEncCtrl->Gains_Q16[ k ]; gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) ); if( gain_squared < SKP_int16_MAX ) { /* recalculate with higher precision */ gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain ); SKP_assert( gain_squared > 0 ); gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */ gain = SKP_min( gain, SKP_int32_MAX >> 8 ); psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */ } else {
SKP_INLINE void SKP_Silk_LDL_factorize_FIX( SKP_int32 *A, /* I Pointer to Symetric Square Matrix */ SKP_int M, /* I Size of Matrix */ SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ ) { SKP_int i, j, k, status, loop_count; const SKP_int32 *ptr1, *ptr2; SKP_int32 diag_min_value, tmp_32, err; SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; SKP_assert( M <= MAX_MATRIX_SIZE ); status = 1; diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { status = 0; for( j = 0; j < M; j++ ) { ptr1 = matrix_adr( L_Q16, j, 0, M ); tmp_32 = 0; for( i = 0; i < j; i++ ) { v_Q0[ i ] = SKP_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ } tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); if( tmp_32 < diag_min_value ) { tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); /* Matrix not positive semi-definite, or ill conditioned */ for( i = 0; i < M; i++ ) { matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); } status = 1; break; } D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ /* two-step division */ one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ /* Save 1/Ds */ inv_D[ j ].Q36_part = one_div_diag_Q36; inv_D[ j ].Q48_part = one_div_diag_Q48; matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ ptr1 = matrix_adr( A, j, 0, M ); ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); for( i = j + 1; i < M; i++ ) { tmp_32 = 0; for( k = 0; k < j; k++ ) { tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ } tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ /* tmp_32 / D_Q0[j] : Divide to Q16 */ matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); /* go to next column */ ptr2 += M; } } } SKP_assert( status == 0 ); }
/* 16th order AR filter */ void SKP_Silk_LPC_synthesis_order16(const int16_t * in, /* I: excitation signal */ const int16_t * A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */ const int32_t Gain_Q26, /* I: gain */ int32_t * S, /* I/O: state vector [16] */ int16_t * out, /* O: output signal */ const int32_t len /* I: signal length, must be multiple of 16 */ ) { int k; int32_t SA, SB, Atmp, A_align_Q12[8], out32_Q10, out32; /* combine two A_Q12 values and ensure 32-bit alignment */ for (k = 0; k < 8; k++) { A_align_Q12[k] = (((int32_t) A_Q12[2 * k]) & 0x0000ffff) | SKP_LSHIFT((int32_t) A_Q12[2 * k + 1], 16); } /* S[] values are in Q14 */ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ for (k = 0; k < len; k++) { /* unrolled loop: prolog */ /* multiply-add two prediction coefficients per iteration */ SA = S[15]; Atmp = A_align_Q12[0]; SB = S[14]; S[14] = SA; out32_Q10 = SKP_SMULWB(SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[13]; S[13] = SB; /* unrolled loop: main loop */ Atmp = A_align_Q12[1]; SB = S[12]; S[12] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[11]; S[11] = SB; Atmp = A_align_Q12[2]; SB = S[10]; S[10] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[9]; S[9] = SB; Atmp = A_align_Q12[3]; SB = S[8]; S[8] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[7]; S[7] = SB; Atmp = A_align_Q12[4]; SB = S[6]; S[6] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[5]; S[5] = SB; Atmp = A_align_Q12[5]; SB = S[4]; S[4] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[3]; S[3] = SB; Atmp = A_align_Q12[6]; SB = S[2]; S[2] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); SA = S[1]; S[1] = SB; /* unrolled loop: epilog */ Atmp = A_align_Q12[7]; SB = S[0]; S[0] = SA; out32_Q10 = SKP_SMLAWB_ovflw(out32_Q10, SA, Atmp); out32_Q10 = SKP_SMLAWT_ovflw(out32_Q10, SB, Atmp); /* unrolled loop: end */ /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32(out32_Q10, SKP_SMULWB(Gain_Q26, in[k])); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND(out32_Q10, 10); /* saturate output */ out[k] = (int16_t) SKP_SAT16(out32); /* move result into delay line */ S[15] = SKP_LSHIFT_SAT32(out32_Q10, 4); } }
/* even order AR filter */ void SKP_Silk_LPC_synthesis_filter( const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [Order] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len, /* I: signal length */ const SKP_int Order /* I: filter order, must be even */ ) { SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 ); SKP_int32 SA, SB, Atmp, A_align_Q12[SigProc_MAX_ORDER_LPC >> 1], out32_Q10, out32; /* Order must be even */ SKP_assert( 2*Order_half == Order ); /* combine two A_Q12 values and ensure 32-bit alignment */ for( k = 0; k < Order_half; k++ ) { idx = SKP_SMULBB( 2, k ); A_align_Q12[k] = (((SKP_int32)A_Q12[idx]) & 0x0000ffff) | SKP_LSHIFT( (SKP_int32)A_Q12[idx+1], 16 ); } /* S[] values are in Q14 */ for( k = 0; k < len; k++ ) { SA = S[Order-1]; out32_Q10 = 0; for( j=0;j<(Order_half-1); j++ ) { idx = SKP_SMULBB( 2, j ) + 1; /* multiply-add two prediction coefficients for each loop */ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ Atmp = A_align_Q12[j]; SB = S[Order - 1 - idx]; S[Order - 1 - idx] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp ); SA = S[Order - 2 - idx]; S[Order - 2 - idx] = SB; } /* unrolled loop: epilog */ Atmp = A_align_Q12[Order_half-1]; SB = S[0]; S[0] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp ); /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[k] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[k] = (SKP_int16)SKP_SAT16( out32 ); /* move result into delay line */ S[Order - 1] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } }
/* Convert from Q24 to Q13 and store in int16 */ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); } } /*****************/ /* Gain tweaking */ /*****************/ /* Increase gains during low speech activity and put lower limit on gains */ gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -SKP_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SKP_FIX_CONST( 0.16, 16 ) ) ); gain_add_Q16 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( NOISE_FLOOR_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); tmp32 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( RELATIVE_MIN_GAIN_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); tmp32 = SKP_SMULWW( psEnc->avgGain_Q16, tmp32 ); gain_add_Q16 = SKP_ADD_SAT32( gain_add_Q16, tmp32 ); SKP_assert( gain_mult_Q16 >= 0 ); for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); if( psEncCtrl->Gains_Q16[ k ] < 0 ) { psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX; } } for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); psEnc->avgGain_Q16 = SKP_ADD_SAT32( psEnc->avgGain_Q16, SKP_SMULWB( psEncCtrl->Gains_Q16[ k ] - psEnc->avgGain_Q16,
/* 16th order AR filter */ void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [16] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len /* I: signal length, must be multiple of 16 */ ) { SKP_int k; SKP_int32 SA, SB, out32_Q10, out32; for( k = 0; k < len; k++ ) { /* unrolled loop: prolog */ /* multiply-add two prediction coefficients per iteration */ SA = S[ 15 ]; SB = S[ 14 ]; S[ 14 ] = SA; out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] ); SA = S[ 13 ]; S[ 13 ] = SB; /* unrolled loop: main loop */ SB = S[ 12 ]; S[ 12 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] ); SA = S[ 11 ]; S[ 11 ] = SB; SB = S[ 10 ]; S[ 10 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] ); SA = S[ 9 ]; S[ 9 ] = SB; SB = S[ 8 ]; S[ 8 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] ); SA = S[ 7 ]; S[ 7 ] = SB; SB = S[ 6 ]; S[ 6 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] ); SA = S[ 5 ]; S[ 5 ] = SB; SB = S[ 4 ]; S[ 4 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] ); SA = S[ 3 ]; S[ 3 ] = SB; SB = S[ 2 ]; S[ 2 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] ); SA = S[ 1 ]; S[ 1 ] = SB; /* unrolled loop: epilog */ SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] ); /* unrolled loop: end */ /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* move result into delay line */ S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } }
/* Processing of gains */ void SKP_Silk_process_gains_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */ ) { SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; SKP_int k; SKP_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart; /* Gain reduction when LTP coding gain is high */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ s_Q16 = -SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - (12 << 7), 4 ) ); for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); } } /* Limit the quantized signal */ /* 69 = 21.0f + 16/0.33 */ InvMaxSqrVal_Q16 = SKP_DIV32_16( SKP_Silk_log2lin( SKP_SMULWB( (69 << 7) - psEncCtrl->current_SNR_dB_Q7, SKP_FIX_CONST( 0.33, 16 )) ), psEnc->sCmn.subfr_length ); for( k = 0; k < NB_SUBFR; k++ ) { /* Soft limit on ratio residual energy and squared gains */ ResNrg = psEncCtrl->ResNrg[ k ]; ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); if( psEncCtrl->ResNrgQ[ k ] > 0 ) { if( psEncCtrl->ResNrgQ[ k ] < 32 ) { ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); } else { ResNrgPart = 0; } } else if( psEncCtrl->ResNrgQ[k] != 0 ) { if( ResNrgPart > SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { ResNrgPart = SKP_int32_MAX; } else { ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); } } gain = psEncCtrl->Gains_Q16[ k ]; gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) ); if( gain_squared < SKP_int16_MAX ) { /* recalculate with higher precision */ gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain ); SKP_assert( gain_squared > 0 ); gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q8 */ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */ } else { gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q0 */ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 ); /* Q16 */ } } /* Noise shaping quantization */ SKP_Silk_gains_quant( psEncCtrl->sCmn.GainsIndices, psEncCtrl->Gains_Q16, &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesInPayloadBuf ); /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEncCtrl->input_tilt_Q15, 8 ) > ( 1 << 7 ) ) { psEncCtrl->sCmn.QuantOffsetType = 0; } else { psEncCtrl->sCmn.QuantOffsetType = 1; } } /* Quantizer boundary adjustment */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( 1.3, 10 ) - SKP_SMULWB( SKP_FIX_CONST( 0.5, 18 ), psEnc->speech_activity_Q8 ) - SKP_SMULWB( SKP_FIX_CONST( 0.3, 12 ), psEncCtrl->input_quality_Q14 ) + SKP_SMULBB( SKP_FIX_CONST( 0.2, 10 ), psEncCtrl->sCmn.QuantOffsetType ) - SKP_SMULWB( SKP_FIX_CONST( 0.1, 12 ), psEncCtrl->coding_quality_Q14 ); } else { psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( 1.3, 10 ) - SKP_SMULWB( SKP_FIX_CONST( 0.5, 18 ), psEnc->speech_activity_Q8 ) - SKP_SMULWB( SKP_FIX_CONST( 0.4, 12 ), psEncCtrl->input_quality_Q14 ) + SKP_SMULBB( SKP_FIX_CONST( 0.4, 10 ), psEncCtrl->sCmn.QuantOffsetType ) - SKP_SMULWB( SKP_FIX_CONST( 0.1, 12 ), psEncCtrl->coding_quality_Q14 ); } SKP_assert( psEncCtrl->Lambda_Q10 >= 0 ); SKP_assert( psEncCtrl->Lambda_Q10 < SKP_FIX_CONST( 2, 10 ) ); }