SKP_int SKP_Silk_init_encoder_FLP( SKP_Silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ ) { SKP_int ret = 0; /* Clear the entire encoder state */ SKP_memset( psEnc, 0, sizeof( SKP_Silk_encoder_state_FLP ) ); #if HIGH_PASS_INPUT psEnc->variable_HP_smth1 = SKP_Silk_log2( 70.0 ); psEnc->variable_HP_smth2 = SKP_Silk_log2( 70.0 ); #endif /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ psEnc->sCmn.first_frame_after_reset = 1; /* Initialize Silk VAD */ ret += SKP_Silk_VAD_Init( &psEnc->sCmn.sVAD ); /* Initialize NSQ */ psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536; psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536; return( ret ); }
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void SKP_Silk_HP_variable_cutoff_FLP( SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ SKP_int16 *out, /* O High-pass filtered output signal */ const SKP_int16 *in /* I Input signal */ ) { SKP_float pitch_freq_Hz, pitch_freq_log, quality, delta_freq, smth_coef, Fc, r; SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ]; /*********************************************/ /* Estimate low end of pitch frequency range */ /*********************************************/ if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) { /* Difference, in log domain */ pitch_freq_Hz = 1e3f * psEnc->sCmn.fs_kHz / psEnc->sCmn.prevLag; pitch_freq_log = SKP_Silk_log2( pitch_freq_Hz ); /* Adjustment based on quality */ quality = psEncCtrl->input_quality_bands[ 0 ]; pitch_freq_log -= quality * quality * ( pitch_freq_log - SKP_Silk_log2( VARIABLE_HP_MIN_FREQ ) ); pitch_freq_log += 0.5f * ( 0.6f - quality ); delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; if( delta_freq < 0.0 ) { /* Less smoothing for decreasing pitch frequency, to track something close to the minimum */ delta_freq *= 3.0f; } /* Limit delta, to reduce impact of outliers */ delta_freq = SKP_LIMIT_float( delta_freq, -VARIABLE_HP_MAX_DELTA_FREQ, VARIABLE_HP_MAX_DELTA_FREQ ); /* Update smoother */ smth_coef = VARIABLE_HP_SMTH_COEF1 * psEnc->speech_activity; psEnc->variable_HP_smth1 += smth_coef * delta_freq; } /* Second smoother */ psEnc->variable_HP_smth2 += VARIABLE_HP_SMTH_COEF2 * ( psEnc->variable_HP_smth1 - psEnc->variable_HP_smth2 ); /* Convert from log scale to Hertz */ psEncCtrl->pitch_freq_low_Hz = ( SKP_float )pow( 2.0f, psEnc->variable_HP_smth2 ); /* Limit frequency range */ psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_float( psEncCtrl->pitch_freq_low_Hz, VARIABLE_HP_MIN_FREQ, VARIABLE_HP_MAX_FREQ ); /*******************************/ /* Compute filter coefficients */ /*******************************/ /* Compute cut-off frequency, in radians */ Fc = ( SKP_float )( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz / ( 1e3f * psEnc->sCmn.fs_kHz ) ); /* 2nd order ARMA coefficients */ r = 1.0f - 0.92f * Fc; /* b = r * [1; -2; 1]; */ /* a = [1; -2 * r * (1 - 0.5 * Fc^2); r^2]; */ B_Q28[ 0 ] = SKP_float2int( ( 1 << 28 ) * r ); B_Q28[ 1 ] = SKP_float2int( ( 1 << 28 ) * -2.0f * r ); B_Q28[ 2 ] = B_Q28[ 0 ]; A_Q28[ 0 ] = SKP_float2int( ( 1 << 28 ) * -2.0f * r * ( 1.0f - 0.5f * Fc * Fc ) ); A_Q28[ 1 ] = SKP_float2int( ( 1 << 28 ) * r * r ); /********************/ /* High-pass filter */ /********************/ SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length ); }