/* every other sample of window is linearly interpolated, for speed */ void SKP_Silk_apply_sine_window( SKP_int16 px_win[], /* O Pointer to windowed signal */ const SKP_int16 px[], /* I Pointer to input signal */ const SKP_int win_type, /* I Selects a window type */ const SKP_int length /* I Window length, multiple of 4 */ ) { SKP_int k; SKP_int32 f_Q16, c_Q20, S0_Q16, S1_Q16; /* Length must be multiple of 4 */ SKP_assert( ( length & 3 ) == 0 ); /* Input pointer must be 4-byte aligned */ SKP_assert( ( (SKP_int64)px & 3 ) == 0 ); if( win_type == 0 ) { f_Q16 = SKP_DIV32_16( 411775, length + 1 ); // 411775 = 2 * 65536 * pi } else { f_Q16 = SKP_DIV32_16( 205887, length + 1 ); // 205887 = 65536 * pi } /* factor used for cosine approximation */ c_Q20 = -SKP_RSHIFT( SKP_MUL( f_Q16, f_Q16 ), 12 ); /* c_Q20 becomes too large if length is too small */ SKP_assert( c_Q20 >= -32768 ); /* initialize state */ if( win_type < 2 ) { /* start from 0 */ S0_Q16 = 0; /* approximation of sin(f) */ S1_Q16 = f_Q16; } else { /* start from 1 */ S0_Q16 = ( 1 << 16 ); /* approximation of cos(f) */ S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q20, 5 ); } /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ /* 4 samples at a time */ for( k = 0; k < length; k += 4 ) { px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] ); S0_Q16 = SKP_RSHIFT( SKP_MUL( c_Q20, S1_Q16 ), 20 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) ); px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] ); S1_Q16 = SKP_RSHIFT( SKP_MUL( c_Q20, S0_Q16 ), 20 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16; S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) ); } }
SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ) { SKP_int b, ret = 0; /* reset state memory */ SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) ); /* init noise levels */ /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); } /* Initialize state */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NL[ b ] = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] ); } psSilk_VAD->counter = 15; /* init smoothed energy-to-noise ratio*/ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ } return( ret ); }
SKP_INLINE opus_int silk_setup_LBRR( silk_encoder_state *psEncC, /* I/O */ const opus_int32 TargetRate_bps /* I */ ) { opus_int ret = SILK_NO_ERROR; opus_int32 LBRR_rate_thres_bps; psEncC->LBRR_enabled = 0; if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) { if( psEncC->fs_kHz == 8 ) { LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS; } else if( psEncC->fs_kHz == 12 ) { LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS; } else { LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS; } LBRR_rate_thres_bps = SKP_SMULWB( SKP_MUL( LBRR_rate_thres_bps, 125 - SKP_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) ); if( TargetRate_bps > LBRR_rate_thres_bps ) { /* Set gain increase for coding LBRR excitation */ psEncC->LBRR_enabled = 1; psEncC->LBRR_GainIncreases = SKP_max_int( 7 - SKP_SMULWB( psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); } } return ret; }
/* Convert input to a log scale */ opus_int32 silk_lin2log( const opus_int32 inLin ) /* I: Input in linear scale */ { opus_int32 lz, frac_Q7; silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); /* Piece-wise parabolic approximation */ return SKP_LSHIFT( 31 - lz, 7 ) + SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 ); }
/* Convert input to a linear scale */ SKP_int32 silk_log2lin( const SKP_int32 inLog_Q7 ) /* I: Input on log scale */ { SKP_int32 out, frac_Q7; if( inLog_Q7 < 0 ) { return 0; } out = SKP_LSHIFT( 1, SKP_RSHIFT( inLog_Q7, 7 ) ); frac_Q7 = inLog_Q7 & 0x7F; if( inLog_Q7 < 2048 ) { /* Piece-wise parabolic approximation */ out = SKP_ADD_RSHIFT( out, SKP_MUL( out, SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); } else { /* Piece-wise parabolic approximation */ out = SKP_MLA( out, SKP_RSHIFT( out, 7 ), SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ); } return out; }
/* Glues concealed frames with new good recieved frames */ void SKP_Silk_PLC_glue_frames( SKP_Silk_decoder_state *psDec, /* I/O decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O signal */ SKP_int length /* I length of residual */ ) { SKP_int i, energy_shift; SKP_int32 energy; SKP_Silk_PLC_struct *psPLC; psPLC = &psDec->sPLC; if( psDec->lossCnt ) { /* Calculate energy in concealed residual */ SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length ); psPLC->last_frame_lost = 1; } else { if( psDec->sPLC.last_frame_lost ) { /* Calculate residual in decoded signal if last frame was lost */ SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length ); /* Normalize energies */ if( energy_shift > psPLC->conc_energy_shift ) { psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift ); } else if( energy_shift < psPLC->conc_energy_shift ) { energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift ); } /* Fade in the energy difference */ if( energy > psPLC->conc_energy ) { SKP_int32 frac_Q24, LZ; SKP_int32 gain_Q12, slope_Q12; LZ = SKP_Silk_CLZ32( psPLC->conc_energy ); LZ = LZ - 1; psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ ); energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) ); frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) ); gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 ); slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length ); for( i = 0; i < length; i++ ) { signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 ); gain_Q12 += slope_Q12; gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) ); } } } psPLC->last_frame_lost = 0; } }
/* Chirp (bandwidth expand) LP AR filter */ void SKP_Silk_bwexpander(int16_t * ar, /* I/O AR filter to be expanded (without leading 1) */ const int d, /* I Length of ar */ int32_t chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ ) { int i; int32_t chirp_minus_one_Q16; chirp_minus_one_Q16 = chirp_Q16 - 65536; /* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */ /* Bias in SKP_SMULWB can lead to unstable filters */ for (i = 0; i < d - 1; i++) { ar[i] = (int16_t) SKP_RSHIFT_ROUND(SKP_MUL(chirp_Q16, ar[i]), 16); chirp_Q16 += SKP_RSHIFT_ROUND(SKP_MUL(chirp_Q16, chirp_minus_one_Q16), 16); } ar[d - 1] = (int16_t) SKP_RSHIFT_ROUND(SKP_MUL(chirp_Q16, ar[d - 1]), 16); }
/* First order low-pass filter, with input as SKP_int16, running at 48 kHz */ void SKP_Silk_lowpass_short( const SKP_int16 *in, /* I: Q15 48 kHz signal; [len] */ SKP_int32 *S, /* I/O: Q25 state; length = 1 */ SKP_int32 *out, /* O: Q25 48 kHz signal; [len] */ const SKP_int32 len /* O: Signal length */ ) { SKP_int k; SKP_int32 in_tmp, out_tmp, state; state = S[ 0 ]; for( k = 0; k < len; k++ ) { in_tmp = SKP_MUL( 768, (SKP_int32)in[k] ); /* multiply by 0.75, going from Q15 to Q25 */ out_tmp = state + in_tmp; /* zero at nyquist */ state = in_tmp - SKP_RSHIFT( out_tmp, 1 ); /* pole */ out[ k ] = out_tmp; } S[ 0 ] = state; }
/* 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; }
/* compute whitening filter coefficients from normalized line spectral frequencies */ void SKP_Silk_NLSF2A(int16_t * a, /* o monic whitening filter coefficients in Q12, [d] */ const int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */ const int d /* i filter order (should be even) */ ) { int k, i, dd; int32_t cos_LSF_Q20[SigProc_MAX_ORDER_LPC]; int32_t P[SigProc_MAX_ORDER_LPC / 2 + 1], Q[SigProc_MAX_ORDER_LPC / 2 + 1]; int32_t Ptmp, Qtmp; int32_t f_int; int32_t f_frac; int32_t cos_val, delta; int32_t a_int32[SigProc_MAX_ORDER_LPC]; int32_t maxabs, absval, idx = 0, sc_Q16; assert(LSF_COS_TAB_SZ_FIX == 128); memzero(a_int32, SigProc_MAX_ORDER_LPC * sizeof(int32_t)); memzero(cos_LSF_Q20, SigProc_MAX_ORDER_LPC * sizeof(int32_t)); /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */ for (k = 0; k < d; k++) { assert(NLSF[k] >= 0); assert(NLSF[k] <= 32767); /* f_int on a scale 0-127 (rounded down) */ f_int = SKP_RSHIFT(NLSF[k], 15 - 7); /* f_frac, range: 0..255 */ f_frac = NLSF[k] - SKP_LSHIFT(f_int, 15 - 7); assert(f_int >= 0); assert(f_int < LSF_COS_TAB_SZ_FIX); /* Read start and end value from table */ cos_val = SKP_Silk_LSFCosTab_FIX_Q12[f_int]; /* Q12 */ delta = SKP_Silk_LSFCosTab_FIX_Q12[f_int + 1] - cos_val; /* Q12, with a range of 0..200 */ /* Linear interpolation */ cos_LSF_Q20[k] = SKP_LSHIFT(cos_val, 8) + SKP_MUL(delta, f_frac); /* Q20 */ } dd = SKP_RSHIFT(d, 1); assert(dd < SigProc_MAX_ORDER_LPC / 2 + 3); /* generate even and odd polynomials using convolution */ SKP_Silk_NLSF2A_find_poly(P, &cos_LSF_Q20[0], dd); SKP_Silk_NLSF2A_find_poly(Q, &cos_LSF_Q20[1], dd); /* convert even and odd polynomials to int32_t Q12 filter coefs */ for (k = 0; k < dd; k++) { Ptmp = P[k + 1] + P[k]; Qtmp = Q[k + 1] - Q[k]; /* the Ptmp and Qtmp values at this stage need to fit in int32 */ a_int32[k] = -SKP_RSHIFT_ROUND(Ptmp + Qtmp, 9); /* Q20 -> Q12 */ a_int32[d - k - 1] = SKP_RSHIFT_ROUND(Qtmp - Ptmp, 9); /* Q20 -> Q12 */ } /* Limit the maximum absolute value of the prediction coefficients */ for (i = 0; i < 10; i++) { /* Find maximum absolute value and its index */ maxabs = 0; for (k = 0; k < d; k++) { absval = SKP_abs(a_int32[k]); if (absval > maxabs) { maxabs = absval; idx = k; } } if (maxabs > int16_t_MAX) { /* Reduce magnitude of prediction coefficients */ sc_Q16 = 65470 - SKP_DIV32(SKP_MUL(65470 >> 2, maxabs - int16_t_MAX), SKP_RSHIFT32(SKP_MUL(maxabs, idx + 1), 2)); SKP_Silk_bwexpander_32(a_int32, d, sc_Q16); } else { break;
/* Control encoder SNR */ SKP_int SKP_Silk_control_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */ const SKP_int API_fs_kHz, /* I External (API) sampling rate (kHz) */ const SKP_int PacketSize_ms, /* I Packet length (ms) */ SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) (used if SNR_dB == 0) */ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */ const SKP_int INBandFec_enabled, /* I Enable (1) / disable (0) inband FEC */ const SKP_int DTX_enabled, /* I Enable / disable DTX */ const SKP_int InputFramesize_ms, /* I Inputframe in ms */ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ ) { SKP_int32 LBRRRate_thres_bps; SKP_int k, fs_kHz, ret = 0; SKP_int32 frac_Q6; const SKP_int32 *rateTable; /* State machine for the SWB/WB switching */ fs_kHz = psEnc->sCmn.fs_kHz; /* Only switch during low speech activity, when no frames are sitting in the payload buffer */ if( API_fs_kHz == 8 || fs_kHz == 0 || API_fs_kHz < fs_kHz ) { // Switching is not possible, encoder just initialized, or internal mode higher than external fs_kHz = API_fs_kHz; } else { /* Resample all valid data in x_buf. Resampling the last part gets rid of a click, 5ms after switching */ /* this is because the same state is used when downsampling in API.c and is then up to date */ /* the click immidiatly after switching is most of the time still there */ if( psEnc->sCmn.fs_kHz == 24 ) { /* Accumulate the difference between the target rate and limit */ if( psEnc->sCmn.fs_kHz_changed == 0 ) { psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS_INITIAL ); } else { psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS ); } psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 ); /* Check if we should switch from 24 to 16 kHz */ #if SWITCH_TRANSITION_FILTERING if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */ ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) && ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) { psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */ psEnc->sCmn.sLP.mode = 0; /* Switch down */ } if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */ #else if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) && #endif ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) { SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; SKP_int16 x_bufout[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; psEnc->sCmn.bitrateDiff = 0; fs_kHz = 16; SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); SKP_memset( psEnc->sCmn.resample24To16state, 0, sizeof( psEnc->sCmn.resample24To16state ) ); #if LOW_COMPLEXITY_ONLY { SKP_int16 scratch[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ]; SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, (SKP_int16*)scratch ); } #else SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ); #endif /* set the first frame to zero, no performance difference was noticed though */ SKP_memset( x_bufout, 0, 320 * sizeof( SKP_int16 ) ); SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); #if SWITCH_TRANSITION_FILTERING psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */ #endif } } else if( psEnc->sCmn.fs_kHz == 16 ) { /* Check if we should switch from 16 to 24 kHz */ #if SWITCH_TRANSITION_FILTERING if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* No transition phase running, ready to switch */ #else if( #endif ( API_fs_kHz > psEnc->sCmn.fs_kHz && TargetRate_bps >= WB2SWB_BITRATE_BPS && psEnc->sCmn.sSWBdetect.WB_detected == 0 ) && ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) { SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; SKP_int32 resample16To24state[ 11 ]; psEnc->sCmn.bitrateDiff = 0; fs_kHz = 24; SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); SKP_memset( resample16To24state, 0, sizeof(resample16To24state) ); SKP_Silk_resample_3_2( &x_bufout[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ); /* set the first frame to zero, no performance difference was noticed though */ SKP_memset( x_bufout, 0, 480 * sizeof( SKP_int16 ) ); SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); #if SWITCH_TRANSITION_FILTERING psEnc->sCmn.sLP.mode = 1; /* Switch up */ #endif } else { /* accumulate the difference between the target rate and limit */ psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - WB2MB_BITRATE_BPS ); psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 ); /* Check if we should switch from 16 to 12 kHz */ #if SWITCH_TRANSITION_FILTERING if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */ ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) && ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) { psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */ psEnc->sCmn.sLP.mode = 0; /* Switch down */ } if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */ #else if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) && #endif ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) { SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); psEnc->sCmn.bitrateDiff = 0; fs_kHz = 12; if( API_fs_kHz == 24 ) { /* Intermediate upsampling of x_bufFIX from 16 to 24 kHz */ SKP_int16 x_buf24[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; SKP_int32 scratch[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ]; SKP_int32 resample16To24state[ 11 ]; SKP_memset( resample16To24state, 0, sizeof( resample16To24state ) ); SKP_Silk_resample_3_2( &x_buf24[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ); /* Update the state of the resampler used in API.c, from 24 to 12 kHz */ SKP_memset( psEnc->sCmn.resample24To12state, 0, sizeof( psEnc->sCmn.resample24To12state ) ); SKP_Silk_resample_1_2_coarse( &x_buf24[ 0 ], psEnc->sCmn.resample24To12state, &x_buf[ 0 ], scratch, SKP_RSHIFT( SKP_SMULBB( 3, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ), 2 ) ); /* set the first frame to zero, no performance difference was noticed though */ SKP_memset( x_buf, 0, 240 * sizeof( SKP_int16 ) ); SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); } else if( API_fs_kHz == 16 ) { SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 4 ]; SKP_memset( psEnc->sCmn.resample16To12state, 0, sizeof( psEnc->sCmn.resample16To12state ) ); SKP_Silk_resample_3_4( &x_bufout[ 0 ], psEnc->sCmn.resample16To12state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ); /* set the first frame to zero, no performance difference was noticed though */ SKP_memset( x_bufout, 0, 240 * sizeof( SKP_int16 ) ); SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) ); } #if SWITCH_TRANSITION_FILTERING psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */ #endif } } } else if( psEnc->sCmn.fs_kHz == 12 ) {
/* Resamples input data with a factor 2/3 */ void SKP_Silk_resample_2_3_coarse(int16_t * out, /* O: Output signal */ int16_t * S, /* I/O: Resampler state [ SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ] */ const int16_t * in, /* I: Input signal */ const int frameLenIn, /* I: Number of input samples */ int16_t * scratch /* I: Scratch memory [ frameLenIn + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ] */ ) { int32_t n, ind, interpol_ind, tmp, index_Q16; int16_t *in_ptr; int frameLenOut; const int16_t *interpol_ptr; /* Copy buffered samples to start of scratch */ SKP_memcpy(scratch, S, (SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1) * sizeof(int16_t)); /* Then append by the input signal */ SKP_memcpy(&scratch[SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1], in, frameLenIn * sizeof(int16_t)); frameLenOut = SKP_DIV32_16(SKP_MUL(2, frameLenIn), 3); index_Q16 = 0; assert(frameLenIn == ((frameLenOut * 3) / 2)); /* Interpolate */ for (n = frameLenOut; n > 0; n--) { /* Integer part */ ind = SKP_RSHIFT(index_Q16, 16); /* Pointer to buffered input */ in_ptr = scratch + ind; /* Fractional part */ interpol_ind = (SKP_SMULWB (index_Q16, SigProc_Resample_2_3_coarse_NUM_INTERPOLATORS) & (SigProc_Resample_2_3_coarse_NUM_INTERPOLATORS - 1)); /* Pointer to FIR taps */ interpol_ptr = SigProc_Resample_2_3_coarse_INTERPOL[interpol_ind]; /* Interpolate */ /* Hardcoded for 32 FIR taps */ assert(SigProc_Resample_2_3_coarse_NUM_FIR_COEFS == 32); tmp = (int32_t) interpol_ptr[0] * in_ptr[0] + (int32_t) interpol_ptr[1] * in_ptr[1] + (int32_t) interpol_ptr[2] * in_ptr[2] + (int32_t) interpol_ptr[3] * in_ptr[3] + (int32_t) interpol_ptr[4] * in_ptr[4] + (int32_t) interpol_ptr[5] * in_ptr[5] + (int32_t) interpol_ptr[6] * in_ptr[6] + (int32_t) interpol_ptr[7] * in_ptr[7] + (int32_t) interpol_ptr[8] * in_ptr[8] + (int32_t) interpol_ptr[9] * in_ptr[9] + (int32_t) interpol_ptr[10] * in_ptr[10] + (int32_t) interpol_ptr[11] * in_ptr[11] + (int32_t) interpol_ptr[12] * in_ptr[12] + (int32_t) interpol_ptr[13] * in_ptr[13] + (int32_t) interpol_ptr[14] * in_ptr[14] + (int32_t) interpol_ptr[15] * in_ptr[15] + (int32_t) interpol_ptr[16] * in_ptr[16] + (int32_t) interpol_ptr[17] * in_ptr[17] + (int32_t) interpol_ptr[18] * in_ptr[18] + (int32_t) interpol_ptr[19] * in_ptr[19] + (int32_t) interpol_ptr[20] * in_ptr[20] + (int32_t) interpol_ptr[21] * in_ptr[21] + (int32_t) interpol_ptr[22] * in_ptr[22] + (int32_t) interpol_ptr[23] * in_ptr[23] + (int32_t) interpol_ptr[24] * in_ptr[24] + (int32_t) interpol_ptr[25] * in_ptr[25] + (int32_t) interpol_ptr[26] * in_ptr[26] + (int32_t) interpol_ptr[27] * in_ptr[27] + (int32_t) interpol_ptr[28] * in_ptr[28] + (int32_t) interpol_ptr[29] * in_ptr[29]; /* Round, saturate and store to output array */ *out++ = (int16_t) SKP_SAT16(SKP_RSHIFT_ROUND(tmp, 15)); /* Update index */ index_Q16 += ((1 << 16) + (1 << 15)); // (3/2)_Q0; } /* Move last part of input signal to the sample buffer to prepare for the next call */ SKP_memcpy(S, &in[frameLenIn - (SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1)], (SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1) * sizeof(int16_t)); }
/* Decode parameters from payload */ void silk_decode_parameters( silk_decoder_state *psDec, /* I/O State */ silk_decoder_control *psDecCtrl /* I/O Decoder control */ ) { SKP_int i, k, Ix; SKP_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; const SKP_int8 *cbk_ptr_Q7; /* Dequant Gains */ silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded, psDec->nb_subfr ); /****************/ /* Decode NLSFs */ /****************/ silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ /* improves the case of packet loss in the first frame after a switch */ if( psDec->first_frame_after_reset == 1 ) { psDec->indices.NLSFInterpCoef_Q2 = 4; } if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) { /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ /* the previous NLSF1, and the current NLSF1 */ for( i = 0; i < psDec->LPC_order; i++ ) { pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDec->indices.NLSFInterpCoef_Q2, pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 ); } /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); } else { /* Copy LPC coefficients for first half from second half */ SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) ); } SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int16 ) ); /* After a packet loss do BWE of LPC coefs */ if( psDec->lossCnt ) { silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); } if( psDec->indices.signalType == TYPE_VOICED ) { /*********************/ /* Decode pitch lags */ /*********************/ /* Decode pitch values */ silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr ); /* Decode Codebook Index */ cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */ for( k = 0; k < psDec->nb_subfr; k++ ) { Ix = psDec->indices.LTPIndex[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = SKP_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 ); } } /**********************/ /* Decode LTP scaling */ /**********************/ Ix = psDec->indices.LTP_scaleIndex; psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ]; } else { SKP_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( SKP_int ) ); SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( SKP_int16 ) ); psDec->indices.PERIndex = 0; psDecCtrl->LTP_scale_Q14 = 0; } }
/* Control encoder SNR */ SKP_int SKP_Silk_control_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */ const SKP_int32 API_fs_Hz, /* I External (API) sampling rate (Hz) */ const SKP_int max_internal_fs_kHz,/* I Maximum internal sampling rate (kHz) */ const SKP_int PacketSize_ms, /* I Packet length (ms) */ SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) (used if SNR_dB == 0) */ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */ const SKP_int INBandFEC_enabled, /* I Enable (1) / disable (0) inband FEC */ const SKP_int DTX_enabled, /* I Enable / disable DTX */ const SKP_int InputFramesize_ms, /* I Inputframe in ms */ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ ) { SKP_int32 LBRRRate_thres_bps; SKP_int k, fs_kHz, ret = 0; SKP_int32 frac_Q6; const SKP_int32 *rateTable; /* State machine for the SWB/WB switching */ fs_kHz = psEnc->sCmn.fs_kHz; /* Only switch during low speech activity, when no frames are sitting in the payload buffer */ if( API_fs_Hz == 8000 || fs_kHz == 0 || API_fs_Hz < SKP_SMULBB( fs_kHz, 1000 ) || fs_kHz > max_internal_fs_kHz ) { /* Switching is not possible, encoder just initialized, internal mode higher than external, */ /* or internal mode higher than maximum allowed internal mode */ fs_kHz = SKP_min( SKP_DIV32_16( API_fs_Hz, 1000 ), max_internal_fs_kHz ); } else { /* Accumulate the difference between the target rate and limit for switching down */ psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - psEnc->sCmn.bitrate_threshold_down ); psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 ); if( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) { /* Low speech activity and payload buffer empty */ /* Check if we should switch down */ #if SWITCH_TRANSITION_FILTERING if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */ ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */ ( psEnc->sCmn.sSWBdetect.WB_detected * psEnc->sCmn.fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */ psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */ psEnc->sCmn.sLP.mode = 0; /* Switch down */ } else if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */ ( psEnc->sCmn.sLP.mode == 0 ) ) { /* Ready to switch down */ psEnc->sCmn.sLP.transition_frame_no = 0; /* Ready for new transition phase */ #else if( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */ #endif psEnc->sCmn.bitrateDiff = 0; /* Switch to a lower sample frequency */ if( psEnc->sCmn.fs_kHz == 24 ) { fs_kHz = 16; } else if( psEnc->sCmn.fs_kHz == 16 ) { fs_kHz = 12; } else { SKP_assert( psEnc->sCmn.fs_kHz == 12 ); fs_kHz = 8; } } /* Check if we should switch up */ if( ( ( SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) < API_fs_Hz ) && ( TargetRate_bps >= psEnc->sCmn.bitrate_threshold_up ) && ( psEnc->sCmn.sSWBdetect.WB_detected * psEnc->sCmn.fs_kHz != 16 ) ) && ( ( psEnc->sCmn.fs_kHz == 16 ) && ( max_internal_fs_kHz >= 24 ) || ( psEnc->sCmn.fs_kHz == 12 ) && ( max_internal_fs_kHz >= 16 ) || ( psEnc->sCmn.fs_kHz == 8 ) && ( max_internal_fs_kHz >= 12 ) ) #if SWITCH_TRANSITION_FILTERING && ( psEnc->sCmn.sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */ psEnc->sCmn.sLP.mode = 1; /* Switch up */ #else ) { #endif psEnc->sCmn.bitrateDiff = 0; /* Switch to a higher sample frequency */ if( psEnc->sCmn.fs_kHz == 8 ) { fs_kHz = 12; } else if( psEnc->sCmn.fs_kHz == 12 ) { fs_kHz = 16; } else { SKP_assert( psEnc->sCmn.fs_kHz == 16 ); fs_kHz = 24; } } } }
void SKP_Silk_NLSF_MSVQ_encode_FIX( SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */ SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */ const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */ const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */ const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */ const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */ const SKP_int LPC_order, /* I LPC order */ const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */ ) { SKP_int i, s, k, cur_survivors = 0, prev_survivors, input_index, cb_index, bestIndex; SKP_int32 rateDistThreshold_Q18; SKP_int pNLSF_in_Q15[ MAX_LPC_ORDER ]; #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 ) SKP_int32 se_Q15, wsse_Q20, bestRateDist_Q20; #endif #if( LOW_COMPLEXITY_ONLY == 1 ) SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ]; SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ]; SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ]; #else SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ]; SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ]; SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ]; #endif const SKP_int *pConstInt; SKP_int *pInt; const SKP_int16 *pCB_element; const SKP_Silk_NLSF_CBS *pCurrentCBStage; SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS ); SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) ); /* Copy the input vector */ SKP_memcpy( pNLSF_in_Q15, pNLSF_Q15, LPC_order * sizeof( SKP_int ) ); /****************************************************/ /* Tree search for the multi-stage vector quantizer */ /****************************************************/ /* Clear accumulated rates */ SKP_memset( pRate_Q5, 0, NLSF_MSVQ_Survivors * sizeof( SKP_int32 ) ); /* Copy NLSFs into residual signal vector */ for( i = 0; i < LPC_order; i++ ) { pRes_Q15[ i ] = pNLSF_Q15[ i ]; } /* Set first stage values */ prev_survivors = 1; /* Loop over all stages */ for( s = 0; s < psNLSF_CB->nStages; s++ ) { /* Set a pointer to the current stage codebook */ pCurrentCBStage = &psNLSF_CB->CBStages[ s ]; /* Calculate the number of survivors in the current stage */ cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, SKP_SMULBB( prev_survivors, pCurrentCBStage->nVectors ) ); #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 ) /* Find a single best survivor in the last stage, if we */ /* do not need candidates for fluctuation reduction */ if( s == psNLSF_CB->nStages - 1 ) { cur_survivors = 1; } #endif /* Nearest neighbor clustering for multiple input data vectors */ SKP_Silk_NLSF_VQ_rate_distortion_FIX( pRateDist_Q18, pCurrentCBStage, pRes_Q15, pW_Q6, pRate_Q5, NLSF_mu_Q15, prev_survivors, LPC_order ); /* Sort the rate-distortion errors */ SKP_Silk_insertion_sort_increasing( pRateDist_Q18, pTempIndices, prev_survivors * pCurrentCBStage->nVectors, cur_survivors ); /* Discard survivors with rate-distortion values too far above the best one */ if( pRateDist_Q18[ 0 ] < SKP_int32_MAX / NLSF_MSVQ_SURV_MAX_REL_RD ) { rateDistThreshold_Q18 = SKP_MUL( NLSF_MSVQ_SURV_MAX_REL_RD, pRateDist_Q18[ 0 ] ); while( pRateDist_Q18[ cur_survivors - 1 ] > rateDistThreshold_Q18 && cur_survivors > 1 ) { cur_survivors--; } } /* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */ for( k = 0; k < cur_survivors; k++ ) { if( s > 0 ) { /* Find the indices of the input and the codebook vector */ if( pCurrentCBStage->nVectors == 8 ) { input_index = SKP_RSHIFT( pTempIndices[ k ], 3 ); cb_index = pTempIndices[ k ] & 7; } else { input_index = SKP_DIV32_16( pTempIndices[ k ], pCurrentCBStage->nVectors ); cb_index = pTempIndices[ k ] - SKP_SMULBB( input_index, pCurrentCBStage->nVectors ); } } else { /* Find the indices of the input and the codebook vector */ input_index = 0; cb_index = pTempIndices[ k ]; } /* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */ pConstInt = &pRes_Q15[ SKP_SMULBB( input_index, LPC_order ) ]; pCB_element = &pCurrentCBStage->CB_NLSF_Q15[ SKP_SMULBB( cb_index, LPC_order ) ]; pInt = &pRes_new_Q15[ SKP_SMULBB( k, LPC_order ) ]; for( i = 0; i < LPC_order; i++ ) { pInt[ i ] = pConstInt[ i ] - ( SKP_int )pCB_element[ i ]; } /* Update accumulated rate for stage 1 to the current */ pRate_new_Q5[ k ] = pRate_Q5[ input_index ] + pCurrentCBStage->Rates_Q5[ cb_index ]; /* Copy paths from previous matrix, starting with the best path */ pConstInt = &pPath[ SKP_SMULBB( input_index, psNLSF_CB->nStages ) ]; pInt = &pPath_new[ SKP_SMULBB( k, psNLSF_CB->nStages ) ]; for( i = 0; i < s; i++ ) { pInt[ i ] = pConstInt[ i ]; } /* Write the current stage indices for the 'cur_survivors' to the best path matrix */ pInt[ s ] = cb_index; } if( s < psNLSF_CB->nStages - 1 ) { /* Copy NLSF residual matrix for next stage */ SKP_memcpy( pRes_Q15, pRes_new_Q15, SKP_SMULBB( cur_survivors, LPC_order ) * sizeof( SKP_int ) ); /* Copy rate vector for next stage */ SKP_memcpy( pRate_Q5, pRate_new_Q5, cur_survivors * sizeof( SKP_int32 ) ); /* Copy best path matrix for next stage */ SKP_memcpy( pPath, pPath_new, SKP_SMULBB( cur_survivors, psNLSF_CB->nStages ) * sizeof( SKP_int ) ); } prev_survivors = cur_survivors; } /* (Preliminary) index of the best survivor, later to be decoded */ bestIndex = 0; #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 ) /******************************/ /* NLSF fluctuation reduction */ /******************************/ if( deactivate_fluc_red != 1 ) { /* Search among all survivors, now taking also weighted fluctuation errors into account */ bestRateDist_Q20 = SKP_int32_MAX; for( s = 0; s < cur_survivors; s++ ) { /* Decode survivor to compare with previous quantized NLSF vector */ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, &pPath_new[ SKP_SMULBB( s, psNLSF_CB->nStages ) ], LPC_order ); /* Compare decoded NLSF vector with the previously quantized vector */ wsse_Q20 = 0; for( i = 0; i < LPC_order; i += 2 ) { /* Compute weighted squared quantization error for index i */ se_Q15 = pNLSF_Q15[ i ] - pNLSF_q_Q15_prev[ i ]; // range: [ -32767 : 32767 ] wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i ] ); /* Compute weighted squared quantization error for index i + 1 */ se_Q15 = pNLSF_Q15[ i + 1 ] - pNLSF_q_Q15_prev[ i + 1 ]; // range: [ -32767 : 32767 ] wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i + 1 ] ); } SKP_assert( wsse_Q20 >= 0 ); /* Add the fluctuation reduction penalty to the rate distortion error */ wsse_Q20 = SKP_ADD_POS_SAT32( pRateDist_Q18[ s ], SKP_SMULWB( wsse_Q20, NLSF_mu_fluc_red_Q16 ) ); /* Keep index of best survivor */ if( wsse_Q20 < bestRateDist_Q20 ) { bestRateDist_Q20 = wsse_Q20; bestIndex = s; } } } #endif /* Copy best path to output argument */ SKP_memcpy( NLSFIndices, &pPath_new[ SKP_SMULBB( bestIndex, psNLSF_CB->nStages ) ], psNLSF_CB->nStages * sizeof( SKP_int ) ); /* Decode and stabilize the best survivor */ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, LPC_order ); }
/* 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( SKP_FIX_CONST( 0.6, 15 ) - quality_Q15, 9 ) ); //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_32( delta_freq_Q7, -SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); /* 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 ), SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); } /* second smoother */ psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15, psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); /* convert from log scale to Hertz */ psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) ); /* limit frequency range */ psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_32( psEncCtrl->pitch_freq_low_Hz, SKP_FIX_CONST( VARIABLE_HP_MIN_FREQ, 0 ), SKP_FIX_CONST( VARIABLE_HP_MAX_FREQ, 0 ) ); /********************************/ /* 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 = SKP_FIX_CONST( 1.0, 28 ) - SKP_MUL( SKP_FIX_CONST( 0.92, 9 ), Fc_Q19 ); 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 ) - SKP_FIX_CONST( 2.0, 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 ); }
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ SKP_INLINE void limit_warped_coefs( SKP_int32 *coefs_syn_Q24, SKP_int32 *coefs_ana_Q24, SKP_int lambda_Q16, SKP_int32 limit_Q24, SKP_int order ) { SKP_int i, iter, ind = 0; SKP_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; SKP_int32 nom_Q16, den_Q24; /* Convert to monic coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } for( iter = 0; iter < 10; iter++ ) { /* Find maximum absolute value */ maxabs_Q24 = -1; for( i = 0; i < order; i++ ) { tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) ); if( tmp > maxabs_Q24 ) { maxabs_Q24 = tmp; ind = i; } } if( maxabs_Q24 <= limit_Q24 ) { /* Coefficients are within range - done */ return; } /* Convert back to true warped coefficients */ for( i = 1; i < order; i++ ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } gain_syn_Q16 = SKP_INVERSE32_varQ( gain_syn_Q16, 32 ); gain_ana_Q16 = SKP_INVERSE32_varQ( gain_ana_Q16, 32 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } /* Apply bandwidth expansion */ chirp_Q16 = SKP_FIX_CONST( 0.99, 16 ) - SKP_DIV32_varQ( SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SKP_FIX_CONST( 0.8, 10 ), SKP_FIX_CONST( 0.1, 10 ), iter ) ), SKP_MUL( maxabs_Q24, ind + 1 ), 22 ); SKP_Silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); SKP_Silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); /* Convert to monic warped coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } } SKP_assert( 0 ); }
/* Control internal sampling rate */ SKP_int SKP_Silk_control_audio_bandwidth( SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */ ) { SKP_int fs_kHz; fs_kHz = psEncC->fs_kHz; if( fs_kHz == 0 ) { /* Encoder has just been initialized */ if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) { fs_kHz = 24; } else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) { fs_kHz = 16; } else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) { fs_kHz = 12; } else { fs_kHz = 8; } /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) ); fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); } else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) { /* Make sure internal rate is not higher than external rate or maximum allowed */ fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ); fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); } else { /* State machine for the internal sampling rate switching */ if( psEncC->API_fs_Hz > 8000 ) { /* Accumulate the difference between the target rate and limit for switching down */ psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, psEncC->TargetRate_bps - psEncC->bitrate_threshold_down ); psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 ); if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */ /* Check if we should switch down */ #if SWITCH_TRANSITION_FILTERING if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */ ( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */ ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */ psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */ psEncC->sLP.mode = 0; /* Switch down */ } else if( ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */ ( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */ psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */ #else if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */ #endif psEncC->bitrateDiff = 0; /* Switch to a lower sample frequency */ if( psEncC->fs_kHz == 24 ) { fs_kHz = 16; } else if( psEncC->fs_kHz == 16 ) { fs_kHz = 12; } else { SKP_assert( psEncC->fs_kHz == 12 ); fs_kHz = 8; } } /* Check if we should switch up */ if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) && ( psEncC->TargetRate_bps >= psEncC->bitrate_threshold_up ) && ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) && ( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) || ( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) || ( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) ) #if SWITCH_TRANSITION_FILTERING && ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */ psEncC->sLP.mode = 1; /* Switch up */ #else ) { #endif psEncC->bitrateDiff = 0; /* Switch to a higher sample frequency */ if( psEncC->fs_kHz == 8 ) { fs_kHz = 12; } else if( psEncC->fs_kHz == 12 ) { fs_kHz = 16; } else { SKP_assert( psEncC->fs_kHz == 16 ); fs_kHz = 24; } } } }