/* Autocorrelations for a warped frequency axis */ void silk_warped_autocorrelation_FIX( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) { opus_int n, i, lsh; opus_int32 tmp1_QS, tmp2_QS; opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* Order must be even */ SKP_assert( ( order & 1 ) == 0 ); SKP_assert( 2 * QS - QC >= 0 ); /* Loop over samples */ for( n = 0; n < length; n++ ) { tmp1_QS = SKP_LSHIFT32( ( opus_int32 )input[ n ], QS ); /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2_QS = SKP_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); state_QS[ i ] = tmp1_QS; corr_QC[ i ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); /* Output of allpass section */ tmp1_QS = SKP_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); state_QS[ i + 1 ] = tmp2_QS; corr_QC[ i + 1 ] += SKP_RSHIFT64( SKP_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); } state_QS[ order ] = tmp1_QS; corr_QC[ order ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); } lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35; lsh = SKP_LIMIT( lsh, -12 - QC, 30 - QC ); *scale = -( QC + lsh ); SKP_assert( *scale >= -30 && *scale <= 12 ); if( lsh >= 0 ) { for( i = 0; i < order + 1; i++ ) { corr[ i ] = ( opus_int32 )SKP_CHECK_FIT32( SKP_LSHIFT64( corr_QC[ i ], lsh ) ); } } else { for( i = 0; i < order + 1; i++ ) { corr[ i ] = ( opus_int32 )SKP_CHECK_FIT32( SKP_RSHIFT64( corr_QC[ i ], -lsh ) ); } } SKP_assert( corr_QC[ 0 ] >= 0 ); // If breaking, decrease QC }
/* Control SNR of redidual quantizer */ SKP_int silk_control_SNR( silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */ ) { SKP_int k, ret = SILK_NO_ERROR; SKP_int32 frac_Q6; const SKP_int32 *rateTable; /* Set bitrate/coding quality */ TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS ); if( TargetRate_bps != psEncC->TargetRate_bps ) { psEncC->TargetRate_bps = TargetRate_bps; /* If new TargetRate_bps, translate to SNR_dB value */ if( psEncC->fs_kHz == 8 ) { rateTable = silk_TargetRate_table_NB; } else if( psEncC->fs_kHz == 12 ) { rateTable = silk_TargetRate_table_MB; } else { rateTable = silk_TargetRate_table_WB; } /* Reduce bitrate for 10 ms modes in these calculations */ if( psEncC->nb_subfr == 2 ) { TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS; } /* Find bitrate interval in table and interpolate */ for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) { if( TargetRate_bps <= rateTable[ k ] ) { frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] ); psEncC->SNR_dB_Q7 = SKP_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] ); break; } } } return ret; }
void silk_NLSF_decode( opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ ) { opus_int i; opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; opus_int16 ec_ix[ MAX_LPC_ORDER ]; opus_int16 res_Q10[ MAX_LPC_ORDER ]; opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; opus_int32 W_tmp_Q9, NLSF_Q15_tmp; const opus_uint8 *pCB_element; /* Decode first stage */ pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; for( i = 0; i < psNLSF_CB->order; i++ ) { pNLSF_Q15[ i ] = SKP_LSHIFT( ( opus_int16 )pCB_element[ i ], 7 ); } /* Unpack entropy table indices and predictor for current CB1 index */ silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); /* Trellis dequantizer */ silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); /* Weights from codebook vector */ silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); /* Apply inverse square-rooted weights and add to output */ for( i = 0; i < psNLSF_CB->order; i++ ) { W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( opus_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); NLSF_Q15_tmp = SKP_ADD32( pNLSF_Q15[ i ], SKP_DIV32_16( SKP_LSHIFT( ( opus_int32 )res_Q10[ i ], 14 ), W_tmp_Q9 ) ); pNLSF_Q15[ i ] = (opus_int16)SKP_LIMIT( NLSF_Q15_tmp, 0, 32767 ); } /* NLSF stabilization */ silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); }
void silk_LTP_scale_ctrl_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */ ) { opus_int round_loss; /* 1st order high-pass filter */ //g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1); psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - 0.5 * psEnc->prevLTPredCodGain, 0.0f ) + 0.5f * psEnc->HPLTPredCodGain; psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain; /* Only scale if first frame in packet */ if( psEnc->sCmn.nFramesEncoded == 0 ) { round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)SKP_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; } psEncCtrl->LTP_scale = (SKP_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; }
/* Deactivate by setting psEncC->mode = 0; */ void silk_LP_variable_cutoff( silk_LP_state *psLP, /* I/O LP filter state */ SKP_int16 *signal, /* I/O Low-pass filtered output signal */ const SKP_int frame_length /* I Frame length */ ) { SKP_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; SKP_int ind = 0; SKP_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES ); /* Run filter if needed */ if( psLP->mode != 0 ) { /* Calculate index and interpolation factor for interpolation */ #if( TRANSITION_INT_STEPS == 64 ) fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 ); #else fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES ); #endif ind = SKP_RSHIFT( fac_Q16, 16 ); fac_Q16 -= SKP_LSHIFT( ind, 16 ); SKP_assert( ind >= 0 ); SKP_assert( ind < TRANSITION_INT_NUM ); /* Interpolate filter coefficients */ silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); /* Update transition frame number for next frame */ psLP->transition_frame_no = SKP_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES ); /* ARMA low-pass filtering */ SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); silk_biquad_alt( signal, B_Q28, A_Q28, psLP->In_LP_State, signal, frame_length ); } }
/* NLSF stabilizer, for a single input data vector */ void SKP_Silk_NLSF_stabilize( SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */ const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */ const SKP_int L /* I: Number of NLSF parameters in the input vector */ ) { SKP_int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15; SKP_int32 min_diff_Q15; SKP_int loops; SKP_int i, I=0, k; /* This is necessary to ensure an output within range of a SKP_int16 */ SKP_assert( NDeltaMin_Q15[L] >= 1 ); for( loops = 0; loops < MAX_LOOPS; loops++ ) { /**************************/ /* Find smallest distance */ /**************************/ /* First element */ min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; I = 0; /* Middle elements */ for( i = 1; i <= L-1; i++ ) { diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = i; } } /* Last element */ diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = L; } /***************************************************/ /* Now check if the smallest distance non-negative */ /***************************************************/ if (min_diff_Q15 >= 0) { return; } if( I == 0 ) { /* Move away from lower limit */ NLSF_Q15[0] = NDeltaMin_Q15[0]; } else if( I == L) { /* Move away from higher limit */ NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L]; } else { /* Find the lower extreme for the location of the current center frequency */ min_center_Q15 = 0; for( k = 0; k < I; k++ ) { min_center_Q15 += NDeltaMin_Q15[k]; } min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 ); /* Find the upper extreme for the location of the current center frequency */ max_center_Q15 = (1<<15); for( k = L; k > I; k-- ) { max_center_Q15 -= NDeltaMin_Q15[k]; } max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) ); /* Move apart, sorted by value, keeping the same center frequency */ center_freq_Q15 = SKP_LIMIT( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ), min_center_Q15, max_center_Q15 ); NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ); NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; } } /* Safe and simple fall back method, which is less ideal than the above */ if( loops == MAX_LOOPS ) { /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L); /* First NLSF should be no less than NDeltaMin[0] */ NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); /* Keep delta_min distance between the NLSFs */ for( i = 1; i < L; i++ ) NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); /* Keep NDeltaMin distance between the NLSFs */ for( i = L-2; i >= 0; i-- ) NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] ); } }
/* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */ void SKP_Silk_LBRR_encode_FIX(SKP_Silk_encoder_state_FIX * psEnc, /* I/O Pointer to Silk encoder state */ SKP_Silk_encoder_control_FIX * psEncCtrl, /* I/O Pointer to Silk encoder control struct */ uint8_t * pCode, /* O Pointer to payload */ int16_t * pnBytesOut, /* I/O Pointer to number of payload bytes */ int16_t xfw[] /* I Input signal */ ) { int i, TempGainsIndices[NB_SUBFR], frame_terminator; int nBytes, nFramesInPayloadBuf; int32_t TempGains_Q16[NB_SUBFR]; int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ SKP_Silk_LBRR_ctrl_FIX(psEnc, psEncCtrl); if (psEnc->sCmn.LBRR_enabled) { /* Save original Gains */ SKP_memcpy(TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof(int)); SKP_memcpy(TempGains_Q16, psEncCtrl->Gains_Q16, NB_SUBFR * sizeof(int32_t)); typeOffset = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex; /* Set max rate where quant signal is encoded */ if (psEnc->sCmn.fs_kHz == 8) { Rate_only_parameters = 13500; } else if (psEnc->sCmn.fs_kHz == 12) { Rate_only_parameters = 15500; } else if (psEnc->sCmn.fs_kHz == 16) { Rate_only_parameters = 17500; } else if (psEnc->sCmn.fs_kHz == 24) { Rate_only_parameters = 19500; } else { assert(0); } if (psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters) { if (psEnc->sCmn.nFramesInPayloadBuf == 0) { /* First frame in packet copy Everything */ SKP_memcpy(&psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof(SKP_Silk_nsq_state)); psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psEncCtrl->sCmn.GainsIndices[0] = psEncCtrl->sCmn.GainsIndices[0] + psEnc->sCmn.LBRR_GainIncreases; psEncCtrl->sCmn.GainsIndices[0] = SKP_LIMIT(psEncCtrl->sCmn.GainsIndices[0], 0, N_LEVELS_QGAIN - 1); } /* Decode to get Gains in sync with decoder */ /* Overwrite unquantized gains with quantized gains */ SKP_Silk_gains_dequant(psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, &psEnc->sCmn. LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ psEnc->NoiseShapingQuantizer(&psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[psEnc-> sCmn. nFramesInPayloadBuf * psEnc-> sCmn. frame_length], psEncCtrl->sCmn. NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[0], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR2_Q13, psEncCtrl-> HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14); } else { SKP_memset(&psEnc->sCmn. q_LBRR[psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length], 0, psEnc->sCmn.frame_length * sizeof(int)); psEncCtrl->sCmn.LTP_scaleIndex = 0; } /****************************************/ /* Initialize arithmetic coder */ /****************************************/ if (psEnc->sCmn.nFramesInPayloadBuf == 0) { SKP_Silk_range_enc_init(&psEnc->sCmn.sRC_LBRR); psEnc->sCmn.nBytesInPayloadBuf = 0; } /****************************************/ /* Encode Parameters */ /****************************************/ if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) { SKP_Silk_encode_parameters_v4(&psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR); } else { SKP_Silk_encode_parameters(&psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR, &psEnc->sCmn.q_LBRR[psEnc-> sCmn. nFramesInPayloadBuf * psEnc-> sCmn. frame_length]); } if (psEnc->sCmn.sRC_LBRR.error) { /* encoder returned error: clear payload buffer */ nFramesInPayloadBuf = 0; } else { nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1; } /****************************************/ /* finalize payload and copy to output */ /****************************************/ if (SKP_SMULBB(nFramesInPayloadBuf, FRAME_LENGTH_MS) >= psEnc->sCmn.PacketSize_ms) { /* Check if FEC information should be added */ frame_terminator = SKP_SILK_LAST_FRAME; /* Add the frame termination info to stream */ SKP_Silk_range_encoder(&psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF); if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) { /*********************************************/ /* Encode quantization indices of excitation */ /*********************************************/ for (i = 0; i < nFramesInPayloadBuf; i++) { SKP_Silk_encode_pulses(&psEnc->sCmn. sRC_LBRR, psEnc->sCmn. sigtype[i], psEnc->sCmn. QuantOffsetType [i], &psEnc->sCmn. q_LBRR[i * psEnc-> sCmn. frame_length], psEnc->sCmn. frame_length); } } /* payload length so far */ SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC_LBRR, &nBytes); /* check that there is enough space in external output buffer, and move data */ if (*pnBytesOut >= nBytes) { SKP_Silk_range_enc_wrap_up(&psEnc->sCmn. sRC_LBRR); SKP_memcpy(pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof(uint8_t)); *pnBytesOut = nBytes; } else { /* not enough space: payload will be discarded */ *pnBytesOut = 0; assert(0); } } else { /* no payload for you this time */ *pnBytesOut = 0; /* Encode that more frames follows */ frame_terminator = SKP_SILK_MORE_FRAMES; SKP_Silk_range_encoder(&psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF); } /* Restore original Gains */ SKP_memcpy(psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof(int)); SKP_memcpy(psEncCtrl->Gains_Q16, TempGains_Q16, NB_SUBFR * sizeof(int32_t)); /* Restore LTP scale index and typeoffset */ psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex; psEnc->sCmn.typeOffsetPrev = typeOffset; } }
int SKP_Silk_encode_frame_FIX(SKP_Silk_encoder_state_FIX * psEnc, /* I/O Pointer to Silk FIX encoder state */ uint8_t * pCode, /* O Pointer to payload */ int16_t * pnBytesOut, /* I/O Pointer to number of payload bytes */ /* input: max length; output: used */ const int16_t * pIn /* I Pointer to input speech frame */ ) { SKP_Silk_encoder_control_FIX sEncCtrl; int i, nBytes, ret = 0; int16_t *x_frame, *res_pitch_frame; int16_t xfw[MAX_FRAME_LENGTH]; int16_t pIn_HP[MAX_FRAME_LENGTH]; int16_t res_pitch[2 * MAX_FRAME_LENGTH + LA_PITCH_MAX]; int LBRR_idx, frame_terminator, SNR_dB_Q7; const uint16_t *FrameTermination_CDF; /* Low bitrate redundancy parameters */ uint8_t LBRRpayload[MAX_ARITHM_BYTES]; int16_t nBytesLBRR; //int32_t Seed[ MAX_LAYERS ]; sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3; /**************************************************************/ /* Setup Input Pointers, and insert frame in input buffer */ /*************************************************************/ x_frame = psEnc->x_buf + psEnc->sCmn.frame_length; /* start of frame to encode */ res_pitch_frame = res_pitch + psEnc->sCmn.frame_length; /* start of pitch LPC residual frame */ /****************************/ /* Voice Activity Detection */ /****************************/ ret = SKP_Silk_VAD_GetSA_Q8(&psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15, pIn, psEnc->sCmn.frame_length); /*******************************************/ /* High-pass filtering of the input signal */ /*******************************************/ #if HIGH_PASS_INPUT /* Variable high-pass filter */ SKP_Silk_HP_variable_cutoff_FIX(psEnc, &sEncCtrl, pIn_HP, pIn); #else SKP_memcpy(pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof(int16_t)); #endif #if SWITCH_TRANSITION_FILTERING /* Ensure smooth bandwidth transitions */ SKP_Silk_LP_variable_cutoff(&psEnc->sCmn.sLP, x_frame + psEnc->sCmn.la_shape, pIn_HP, psEnc->sCmn.frame_length); #else SKP_memcpy(x_frame + psEnc->sCmn.la_shape, pIn_HP, psEnc->sCmn.frame_length * sizeof(int16_t)); #endif /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ SKP_Silk_find_pitch_lags_FIX(psEnc, &sEncCtrl, res_pitch, x_frame); /************************/ /* Noise shape analysis */ /************************/ SKP_Silk_noise_shape_analysis_FIX(psEnc, &sEncCtrl, res_pitch_frame, x_frame); /*****************************************/ /* Prefiltering for noise shaper */ /*****************************************/ SKP_Silk_prefilter_FIX(psEnc, &sEncCtrl, xfw, x_frame); /***************************************************/ /* Find linear prediction coefficients (LPC + LTP) */ /***************************************************/ SKP_Silk_find_pred_coefs_FIX(psEnc, &sEncCtrl, res_pitch); /****************************************/ /* Process gains */ /****************************************/ SKP_Silk_process_gains_FIX(psEnc, &sEncCtrl); psEnc->sCmn.sigtype[psEnc->sCmn.nFramesInPayloadBuf] = sEncCtrl.sCmn.sigtype; psEnc->sCmn.QuantOffsetType[psEnc->sCmn.nFramesInPayloadBuf] = sEncCtrl.sCmn.QuantOffsetType; /****************************************/ /* Low Bitrate Redundant Encoding */ /****************************************/ nBytesLBRR = MAX_ARITHM_BYTES; SKP_Silk_LBRR_encode_FIX(psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ psEnc->NoiseShapingQuantizer(&psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, &psEnc->sCmn.q[psEnc->sCmn. nFramesInPayloadBuf * psEnc->sCmn.frame_length], sEncCtrl.sCmn.NLSFInterpCoef_Q2, sEncCtrl.PredCoef_Q12[0], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14); /**************************************************/ /* Convert speech activity into VAD and DTX flags */ /**************************************************/ if (psEnc->speech_activity_Q8 < SPEECH_ACTIVITY_DTX_THRES_Q8) { psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY; psEnc->sCmn.noSpeechCounter++; if (psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX) { psEnc->sCmn.inDTX = 1; } if (psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX) { psEnc->sCmn.noSpeechCounter = 0; psEnc->sCmn.inDTX = 0; } } else { psEnc->sCmn.noSpeechCounter = 0; psEnc->sCmn.inDTX = 0; psEnc->sCmn.vadFlag = VOICE_ACTIVITY; } /****************************************/ /* Initialize arithmetic coder */ /****************************************/ if (psEnc->sCmn.nFramesInPayloadBuf == 0) { SKP_Silk_range_enc_init(&psEnc->sCmn.sRC); psEnc->sCmn.nBytesInPayloadBuf = 0; } /****************************************/ /* Encode Parameters */ /****************************************/ if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) { SKP_Silk_encode_parameters_v4(&psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC); FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF; } else { SKP_Silk_encode_parameters(&psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, &psEnc->sCmn.q[psEnc->sCmn. nFramesInPayloadBuf * psEnc->sCmn. frame_length]); FrameTermination_CDF = SKP_Silk_FrameTermination_CDF; } /****************************************/ /* Update Buffers and State */ /****************************************/ /* Update Input buffer */ SKP_memmove(psEnc->x_buf, &psEnc->x_buf[psEnc->sCmn.frame_length], (psEnc->sCmn.frame_length + psEnc->sCmn.la_shape) * sizeof(int16_t)); /* parameters needed for next frame */ psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype; psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[NB_SUBFR - 1]; psEnc->sCmn.first_frame_after_reset = 0; if (psEnc->sCmn.sRC.error) { /* encoder returned error: clear payload buffer */ psEnc->sCmn.nFramesInPayloadBuf = 0; } else { psEnc->sCmn.nFramesInPayloadBuf++; } /****************************************/ /* finalize payload and copy to output */ /****************************************/ if (psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms) { LBRR_idx = (psEnc->sCmn.oldest_LBRR_idx + 1) & LBRR_IDX_MASK; /* Check if FEC information should be added */ frame_terminator = SKP_SILK_LAST_FRAME; if (psEnc->sCmn.LBRR_buffer[LBRR_idx].usage == SKP_SILK_ADD_LBRR_TO_PLUS1) { frame_terminator = SKP_SILK_LBRR_VER1; } if (psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx]. usage == SKP_SILK_ADD_LBRR_TO_PLUS2) { frame_terminator = SKP_SILK_LBRR_VER2; LBRR_idx = psEnc->sCmn.oldest_LBRR_idx; } /* Add the frame termination info to stream */ SKP_Silk_range_encoder(&psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF); if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) { /* Code excitation signal */ for (i = 0; i < psEnc->sCmn.nFramesInPayloadBuf; i++) { SKP_Silk_encode_pulses(&psEnc->sCmn.sRC, psEnc->sCmn.sigtype[i], psEnc->sCmn. QuantOffsetType[i], &psEnc->sCmn.q[i * psEnc-> sCmn. frame_length], psEnc->sCmn. frame_length); } } /* payload length so far */ SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC, &nBytes); /* check that there is enough space in external output buffer, and move data */ if (*pnBytesOut >= nBytes) { SKP_Silk_range_enc_wrap_up(&psEnc->sCmn.sRC); SKP_memcpy(pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof(uint8_t)); if (frame_terminator > SKP_SILK_MORE_FRAMES && *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[LBRR_idx].nBytes) { /* Get old packet and add to payload. */ SKP_memcpy(&pCode[nBytes], psEnc->sCmn.LBRR_buffer[LBRR_idx]. payload, psEnc->sCmn.LBRR_buffer[LBRR_idx]. nBytes * sizeof(uint8_t)); nBytes += psEnc->sCmn.LBRR_buffer[LBRR_idx].nBytes; } *pnBytesOut = nBytes; /* Update FEC buffer */ SKP_memcpy(psEnc->sCmn. LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx]. payload, LBRRpayload, nBytesLBRR * sizeof(uint8_t)); psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx]. nBytes = nBytesLBRR; /* This line tells describes how FEC should be used */ psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx]. usage = sEncCtrl.sCmn.LBRR_usage; psEnc->sCmn.oldest_LBRR_idx = (psEnc->sCmn.oldest_LBRR_idx + 1) & LBRR_IDX_MASK; /* Reset number of frames in payload buffer */ psEnc->sCmn.nFramesInPayloadBuf = 0; } else { /* Not enough space: Payload will be discarded */ *pnBytesOut = 0; nBytes = 0; psEnc->sCmn.nFramesInPayloadBuf = 0; ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT; } } else { /* no payload for you this time */ *pnBytesOut = 0; /* Encode that more frames follows */ frame_terminator = SKP_SILK_MORE_FRAMES; SKP_Silk_range_encoder(&psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF); /* payload length so far */ SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC, &nBytes); if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) { /* Take into account the q signal that isnt in the bitstream yet */ nBytes += SKP_Silk_pulses_to_bytes(&psEnc->sCmn, &psEnc->sCmn. q[(psEnc->sCmn. nFramesInPayloadBuf - 1) * psEnc->sCmn. frame_length]); } } /* Check for arithmetic coder errors */ if (psEnc->sCmn.sRC.error) { ret = SKP_SILK_ENC_INTERNAL_ERROR; } /* simulate number of ms buffered in channel because of exceeding TargetRate */ assert((8 * 1000 * ((int64_t) nBytes - (int64_t) psEnc->sCmn.nBytesInPayloadBuf)) == SKP_SAT32(8 * 1000 * ((int64_t) nBytes - (int64_t) psEnc->sCmn.nBytesInPayloadBuf))); assert(psEnc->sCmn.TargetRate_bps > 0); psEnc->BufferedInChannel_ms += SKP_DIV32(8 * 1000 * (nBytes - psEnc->sCmn.nBytesInPayloadBuf), psEnc->sCmn.TargetRate_bps); psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS; psEnc->BufferedInChannel_ms = SKP_LIMIT(psEnc->BufferedInChannel_ms, 0, 100); psEnc->sCmn.nBytesInPayloadBuf = nBytes; if (psEnc->speech_activity_Q8 > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES_Q8) { psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32(psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS); } return (ret); }
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void SKP_Silk_HP_variable_cutoff_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ SKP_int16 *out, /* O high-pass filtered output signal */ const SKP_int16 *in /* I input signal */ ) { SKP_int quality_Q15; SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ]; SKP_int32 Fc_Q19, r_Q28, r_Q22; SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; /*********************************************/ /* Estimate Low End of Pitch Frequency Range */ /*********************************************/ if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) { /* difference, in log domain */ pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag ); pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70 /* adjustment based on quality */ quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ]; pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ), pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) ); pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( 19661 - quality_Q15, 9 ) ); // 19661_Q15 = 0.6_Q0 //delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 ); if( delta_freq_Q7 < 0 ) { /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 ); } /* limit delta, to reduce impact of outliers */ delta_freq_Q7 = SKP_LIMIT( delta_freq_Q7, -VARIABLE_HP_MAX_DELTA_FREQ_Q7, VARIABLE_HP_MAX_DELTA_FREQ_Q7 ); /* update smoother */ psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15, SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), VARIABLE_HP_SMTH_COEF1_Q16 ); } /* second smoother */ psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15, psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, VARIABLE_HP_SMTH_COEF2_Q16 ); /* convert from log scale to Hertz */ psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) ); //pow( 2.0, psEnc->variable_HP_smth2 ); /* limit frequency range */ psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT( psEncCtrl->pitch_freq_low_Hz, VARIABLE_HP_MIN_FREQ_Q0, VARIABLE_HP_MAX_FREQ_Q0 ); /********************************/ /* Compute Filter Coefficients */ /********************************/ /* compute cut-off frequency, in radians */ //Fc_num = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz ); //Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz ); SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 ); Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits SKP_assert( Fc_Q19 >= 3704 ); SKP_assert( Fc_Q19 <= 27787 ); r_Q28 = ( 1 << 28 ) - SKP_MUL( 471, Fc_Q19 ); // 471_Q9 = 0.92_Q0, range: 255347779 to 266690872, 27-28 bits SKP_assert( r_Q28 >= 255347779 ); SKP_assert( r_Q28 <= 266690872 ); /* b = r * [ 1; -2; 1 ]; */ /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ B_Q28[ 0 ] = r_Q28; B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 ); B_Q28[ 2 ] = r_Q28; // -r * ( 2 - Fc * Fc ); r_Q22 = SKP_RSHIFT( r_Q28, 6 ); A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - ( 2 << 22 ) ); A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 ); /********************************/ /* High-Pass Filter */ /********************************/ SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length ); }
void SKP_Silk_NSQ_wrapper_FLP( SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const SKP_float x[], /* I Prefiltered input signal */ SKP_int8 q[], /* O Quantized pulse signal */ const SKP_int useLBRR /* I LBRR flag */ ) { SKP_int i, j; SKP_float tmp_float; SKP_int16 x_16[ MAX_FRAME_LENGTH ]; /* Prediction and coding parameters */ SKP_int32 Gains_Q16[ NB_SUBFR ]; SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ]; SKP_int LTP_scale_Q14; /* Noise shaping parameters */ /* Testing */ SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; SKP_int32 LF_shp_Q14[ NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ SKP_int Lambda_Q10; SKP_int Tilt_Q14[ NB_SUBFR ]; SKP_int HarmShapeGain_Q14[ NB_SUBFR ]; /* Convert control struct to fix control struct */ /* Noise shape parameters */ for( i = 0; i < NB_SUBFR * MAX_SHAPE_LPC_ORDER; i++ ) { AR2_Q13[ i ] = SKP_float2int( psEncCtrl->AR2[ i ] * 8192.0f ); } for( i = 0; i < NB_SUBFR; i++ ) { LF_shp_Q14[ i ] = SKP_LSHIFT32( SKP_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | (SKP_uint16)SKP_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); Tilt_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); HarmShapeGain_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); } Lambda_Q10 = ( SKP_int )SKP_float2int( psEncCtrl->Lambda * 1024.0f ); /* prediction and coding parameters */ for( i = 0; i < NB_SUBFR * LTP_ORDER; i++ ) { LTPCoef_Q14[ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); } for( j = 0; j < NB_SUBFR >> 1; j++ ) { for( i = 0; i < MAX_LPC_ORDER; i++ ) { PredCoef_Q12[ j ][ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); } } for( i = 0; i < NB_SUBFR; i++ ) { tmp_float = SKP_LIMIT( ( psEncCtrl->Gains[ i ] * 65536.0f ), 2147483000.0f, -2147483000.0f ); Gains_Q16[ i ] = SKP_float2int( tmp_float ); if( psEncCtrl->Gains[ i ] > 0.0f ) { SKP_assert( tmp_float >= 0.0f ); SKP_assert( Gains_Q16[ i ] >= 0 ); } } if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ]; } else { LTP_scale_Q14 = 0; } /* Convert input to fix */ SKP_float2short_array( x_16, x, psEnc->sCmn.frame_length ); /* Call NSQ */ if( useLBRR ) { if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); } else { SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); } } else { if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ, x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); } else { SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ, x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); } } }
static SKP_int process_enc_control_struct( SKP_Silk_encoder_state_Fxx *psEnc, /* I/O: State */ SKP_Silk_EncodeControlStruct *encControl /* I: Control structure */ ) { SKP_int max_internal_fs_kHz, min_internal_fs_kHz, Complexity, PacketSize_ms, PacketLoss_perc, UseInBandFEC, ret = SKP_SILK_NO_ERROR; SKP_int32 TargetRate_bps, API_fs_Hz; SKP_assert( encControl != NULL ); /* Check sampling frequency first, to avoid divide by zero later */ if( ( ( encControl->API_sampleRate != 8000 ) && ( encControl->API_sampleRate != 12000 ) && ( encControl->API_sampleRate != 16000 ) && ( encControl->API_sampleRate != 24000 ) && ( encControl->API_sampleRate != 32000 ) && ( encControl->API_sampleRate != 44100 ) && ( encControl->API_sampleRate != 48000 ) ) || ( ( encControl->maxInternalSampleRate != 8000 ) && ( encControl->maxInternalSampleRate != 12000 ) && ( encControl->maxInternalSampleRate != 16000 ) ) || ( ( encControl->minInternalSampleRate != 8000 ) && ( encControl->minInternalSampleRate != 12000 ) && ( encControl->minInternalSampleRate != 16000 ) ) || ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) { ret = SKP_SILK_ENC_FS_NOT_SUPPORTED; SKP_assert( 0 ); return( ret ); } if( encControl->useDTX < 0 || encControl->useDTX > 1 ) { ret = SKP_SILK_ENC_INVALID_DTX_SETTING; } if( encControl->useCBR < 0 || encControl->useCBR > 1 ) { ret = SKP_SILK_ENC_INVALID_CBR_SETTING; } /* Set encoder parameters from control structure */ API_fs_Hz = encControl->API_sampleRate; max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */ min_internal_fs_kHz = (SKP_int)( encControl->minInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */ PacketSize_ms = encControl->payloadSize_ms; TargetRate_bps = encControl->bitRate; PacketLoss_perc = encControl->packetLossPercentage; UseInBandFEC = encControl->useInBandFEC; Complexity = encControl->complexity; psEnc->sCmn.useDTX = encControl->useDTX; psEnc->sCmn.useCBR = encControl->useCBR; /* Save values in state */ psEnc->sCmn.API_fs_Hz = API_fs_Hz; psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz; psEnc->sCmn.minInternal_fs_kHz = min_internal_fs_kHz; psEnc->sCmn.useInBandFEC = UseInBandFEC; TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS ); if( ( ret = SKP_Silk_control_encoder_Fxx( psEnc, PacketSize_ms, TargetRate_bps, PacketLoss_perc, Complexity) ) != 0 ) { SKP_assert( 0 ); return( ret ); } encControl->internalSampleRate = SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ); return ret; }
void SKP_Silk_find_pred_coefs_FIX(SKP_Silk_encoder_state_FIX * psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX * psEncCtrl, /* I/O encoder control */ const int16_t res_pitch[] /* I Residual from pitch analysis */ ) { int i; int32_t WLTP[NB_SUBFR * LTP_ORDER * LTP_ORDER]; int32_t invGains_Q16[NB_SUBFR], local_gains_Qx[NB_SUBFR], Wght_Q15[NB_SUBFR]; int NLSF_Q15[MAX_LPC_ORDER]; const int16_t *x_ptr; int16_t *x_pre_ptr, LPC_in_pre[NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH]; int32_t tmp, min_gain_Q16; #if !VARQ int LZ; #endif int LTP_corrs_rshift[NB_SUBFR]; /* weighting for weighted least squares */ min_gain_Q16 = int32_t_MAX >> 6; for (i = 0; i < NB_SUBFR; i++) { min_gain_Q16 = SKP_min(min_gain_Q16, psEncCtrl->Gains_Q16[i]); } #if !VARQ LZ = SKP_Silk_CLZ32(min_gain_Q16) - 1; LZ = SKP_LIMIT(LZ, 0, 16); min_gain_Q16 = SKP_RSHIFT(min_gain_Q16, 2); /* Ensure that maximum invGains_Q16 is within range of a 16 bit int */ #endif for (i = 0; i < NB_SUBFR; i++) { /* Divide to Q16 */ assert(psEncCtrl->Gains_Q16[i] > 0); #if VARQ /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ invGains_Q16[i] = SKP_DIV32_varQ(min_gain_Q16, psEncCtrl->Gains_Q16[i], 16 - 2); #else invGains_Q16[i] = SKP_DIV32(SKP_LSHIFT(min_gain_Q16, LZ), SKP_RSHIFT(psEncCtrl->Gains_Q16[i], 16 - LZ)); #endif /* Ensure Wght_Q15 a minimum value 1 */ invGains_Q16[i] = SKP_max(invGains_Q16[i], 363); /* Square the inverted gains */ assert(invGains_Q16[i] == SKP_SAT16(invGains_Q16[i])); tmp = SKP_SMULWB(invGains_Q16[i], invGains_Q16[i]); Wght_Q15[i] = SKP_RSHIFT(tmp, 1); /* Invert the inverted and normalized gains */ local_gains_Qx[i] = SKP_DIV32((1 << (16 + Qx)), invGains_Q16[i]); } if (psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED) { /**********/ /* VOICED */ /**********/ assert(psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->sCmn.pitchL[0] + LTP_ORDER / 2); /* LTP analysis */ SKP_Silk_find_LTP_FIX(psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, res_pitch, res_pitch + SKP_RSHIFT(psEnc->sCmn.frame_length, 1), psEncCtrl->sCmn.pitchL, Wght_Q15, psEnc->sCmn.subfr_length, psEnc->sCmn.frame_length, LTP_corrs_rshift); /* Quantize LTP gain parameters */ SKP_Silk_quant_LTP_gains_FIX(psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.LTPIndex, &psEncCtrl->sCmn.PERIndex, WLTP, psEnc->mu_LTP_Q8, psEnc->sCmn.LTPQuantLowComplexity); /* Control LTP scaling */ SKP_Silk_LTP_scale_ctrl_FIX(psEnc, psEncCtrl); /* Create LTP residual */ SKP_Silk_LTP_analysis_filter_FIX(LPC_in_pre, psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.pitchL, invGains_Q16, 16, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder); } else { /************/ /* UNVOICED */ /************/ /* Create signal with prepended subframes, scaled by inverse gains */ x_ptr = psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder; x_pre_ptr = LPC_in_pre; for (i = 0; i < NB_SUBFR; i++) { SKP_Silk_scale_copy_vector16(x_pre_ptr, x_ptr, invGains_Q16[i], psEnc->sCmn.subfr_length + psEnc->sCmn. predictLPCOrder); x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; x_ptr += psEnc->sCmn.subfr_length; } SKP_memset(psEncCtrl->LTPCoef_Q14, 0, NB_SUBFR * LTP_ORDER * sizeof(int16_t)); psEncCtrl->LTPredCodGain_Q7 = 0; } /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ TIC(FIND_LPC) SKP_Silk_find_LPC_FIX(NLSF_Q15, &psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sPred.prev_NLSFq_Q15, psEnc->sCmn.useInterpolatedNLSFs * (1 - psEnc-> sCmn. first_frame_after_reset), psEnc->sCmn.predictLPCOrder, LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder); TOC(FIND_LPC) /* Quantize LSFs */ TIC(PROCESS_LSFS) SKP_Silk_process_NLSFs_FIX(psEnc, psEncCtrl, NLSF_Q15); TOC(PROCESS_LSFS) /* Calculate residual energy using quantized LPC coefficients */ SKP_Silk_residual_energy_FIX(psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, (const int16_t(*)[])psEncCtrl->PredCoef_Q12, local_gains_Qx, Qx, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder); /* Copy to prediction struct for use in next frame for fluctuation reduction */ SKP_memcpy(psEnc->sPred.prev_NLSFq_Q15, NLSF_Q15, psEnc->sCmn.predictLPCOrder * sizeof(int)); }