/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include #include #include #include "options.h" #include "cnst.h" #include "prot.h" #include "rom_com.h" /*-------------------------------------------------------------------* * WB_BWE_gain_pred() * * predict WB frequency envelopes for 0b WB BWE *-------------------------------------------------------------------*/ short WB_BWE_gain_pred( float *WB_fenv, /* o : WB frequency envelopes */ const float *core_dec_freq, /* i : Frequency domain core decoded signal */ const short coder_type, /* i : coding type */ short prev_coder_type, /* i : coding type of last frame */ float prev_WB_fenv, /* i : envelope for last frame */ float *voice_factors, /* i : voicing factors */ const float pitch_buf[], /* i : pitch buffer */ long last_core_brate, /* i : previous frame core bitrate */ float last_wb_bwe_ener /* i : previous frame wb bwe signal energy */ ,short last_extl /* i : extl. layer for last frame */ ,float tilt ) { float enerL, alfa = 1.0f; short n_freq, mode; short ener_var_flag = 0; float voice_factor, pitch; short env_var_flag = 0; mode = NORMAL; enerL = EPSILON; for (n_freq = 128; n_freq<192; n_freq++) { enerL += core_dec_freq[n_freq] * core_dec_freq[n_freq]; } WB_fenv[0] = EPSILON; for (n_freq = 192; n_freq<224; n_freq++) { WB_fenv[0] += core_dec_freq[n_freq] * core_dec_freq[n_freq]; } WB_fenv[1] = EPSILON; for (n_freq = 224; n_freq<256; n_freq++) { WB_fenv[1] += core_dec_freq[n_freq] * core_dec_freq[n_freq]; } voice_factor = sum_f( voice_factors, 4 ); pitch = sum_f( pitch_buf, 4 ) + EPSILON; if(enerL < 16.0f*max(WB_fenv[0], WB_fenv[1]) && pitch < 308) { ener_var_flag = 1; } if(WB_fenv[0] > 2.0f*WB_fenv[1]) { alfa = max(2.0f*WB_fenv[1]/WB_fenv[0], 0.1f); WB_fenv[0] *= alfa; } else if (2.0f*WB_fenv[0] < WB_fenv[1] && coder_type != UNVOICED) { alfa = max(2.0f*WB_fenv[0]/WB_fenv[1], 0.1f); WB_fenv[1] *= alfa; } WB_fenv[0] = (float)sqrt((WB_fenv[0]+WB_fenv[1])/64); if(coder_type != AUDIO && coder_type != UNVOICED && ener_var_flag == 0) { WB_fenv[0] *= 1.5f; } if( coder_type != TRANSITION && coder_type != AUDIO && coder_type != UNVOICED && sqrt(enerL) > 40.0f*WB_fenv[0] && alfa > 0.9f && !(coder_type == prev_coder_type && WB_fenv[0] > prev_WB_fenv) ) { WB_fenv[0] *= min((float)(0.025f*sqrt(enerL)/WB_fenv[0]), 4.0f); if( WB_fenv[0] > prev_WB_fenv ) { WB_fenv[0] = 0.3f*WB_fenv[0] + 0.7f*prev_WB_fenv; } } alfa = min(1.5f, max(0.5f, 77.0f*voice_factor/pitch)); if( sqrt(enerL) > 64.0f*alfa*WB_fenv[0] && 3.0f*WB_fenv[0]*WB_fenv[0] < sqrt(enerL) && prev_coder_type != UNVOICED ) { env_var_flag = 1; WB_fenv[0] *= min((float)(0.015625f*sqrt(enerL)/WB_fenv[0]), 4.0f); if( WB_fenv[0] > prev_WB_fenv ) { WB_fenv[0] = 0.3f*WB_fenv[0] + 0.7f*prev_WB_fenv; } } if( coder_type == UNVOICED || prev_coder_type == UNVOICED ) { WB_fenv[0] *= 0.5f; } if( coder_type != AUDIO ) { WB_fenv[0] /= max(1.2f * voice_factor, 1.0f); WB_fenv[0] *= min(2.0f, max(0.125f, pitch/400.0f)); } if( last_core_brate > ACELP_8k00 && WB_fenv[0] > last_wb_bwe_ener ) { WB_fenv[0] = 0.9f*last_wb_bwe_ener + 0.1f*WB_fenv[0]; } if(last_extl != WB_BWE && (tilt < 8.f)) { WB_fenv[0] *= min(0.5, 16.0f*tilt); } if(env_var_flag == 1) { WB_fenv[1] = 1.5f*WB_fenv[0]; WB_fenv[0] *= 0.75f; } else { WB_fenv[1] = WB_fenv[0]; } if(coder_type == UNVOICED || prev_coder_type == UNVOICED) { WB_fenv[1] *= 0.5f; } return (mode); } /*-------------------------------------------------------------------* * calc_normal_length() * *-------------------------------------------------------------------*/ void calc_normal_length( const short core, /* i : core */ const float *sp, /* i : input signal */ const short mode, /* i : input mode */ const short extl, /* i : extension layer */ short *L_swb_norm, /* o : normalize length */ short *prev_L_swb_norm /*i/o : last normalize length */ ) { short i, n_freq, n_band, THRES; const float *pit; float peak, mean, mag; short L_swb_norm_trans, L_swb_norm_norm, L_swb_norm_harm, L_swb_norm_cur; short N; if( core == HQ_CORE || extl == SWB_BWE || extl == FB_BWE ) { THRES = 8; } else { THRES = 4; } if( core == HQ_CORE && (mode == HQ_HARMONIC || mode == HQ_HVQ) ) { N = 13; } else { N = 16; } n_band = 0; pit = sp; for(i = 0; i < N; i ++) { peak = 0.0f; mean = 0; for(n_freq = 0; n_freq < 16; n_freq ++) { mag = (float) fabs(*pit); if (mag > peak) { peak = mag; } mean += mag; pit ++; } if((15+THRES)*peak > THRES*mean && peak>10) { n_band += 1; } } if( core == ACELP_CORE ) { L_swb_norm_trans = (short)(4 + 0.25f*n_band); L_swb_norm_norm = (short)(8 + 0.5f*n_band); L_swb_norm_harm = max((short)(32 + 2.0f*n_band), 24); if( mode == HARMONIC ) { L_swb_norm_cur = L_swb_norm_harm; } else if( mode == NORMAL ) { L_swb_norm_cur = L_swb_norm_norm; } else { L_swb_norm_cur = L_swb_norm_trans; } *L_swb_norm = (short)(0.5f*L_swb_norm_cur + 0.5f* (*prev_L_swb_norm)); *prev_L_swb_norm = L_swb_norm_cur; } else { if( mode == HQ_HARMONIC || mode == HQ_HVQ ) { L_swb_norm_cur = (short)( 32 + 2.5f*n_band); } else { L_swb_norm_cur = (short)(8 + 0.5f*n_band); } *L_swb_norm = (short)(0.1f*L_swb_norm_cur + 0.9f* (*prev_L_swb_norm) + 0.5f); *prev_L_swb_norm = L_swb_norm_cur; } return; } /*-------------------------------------------------------------------* * calc_tilt_bwe() * * calculate tilt parameter *-------------------------------------------------------------------*/ void calc_tilt_bwe( const float *sp, /* i : input signal */ float *tilt, /* o : signal tilt */ const short N /* i : signal length */ ) { short i; float r0, r1; r0 = EPSILON; for(i=0; i 0) { WB_signal[n_freq] *= (0.55f - weight); } WB_signal[n_freq] *= signum[n_freq]; } } /* Normalize with envelope */ for (n_freq = swb_bwe_subband[0]; n_freq prev_WB_fenv[0] ) { alfa = 0.4f; beta = 2.5f; } else { alfa = 0.6f; beta = 1.67f; } if( coder_type == GENERIC || ((EnergyL > 0.5f*(*prev_Energy) && EnergyL < 2.0f*(*prev_Energy) && *prev_flag == 1)) ) { WB_fenv[0] *= 0.5f; WB_fenv[1] *= 0.5f; flag = 1; } } if( (mode == HARMONIC && WB_fenv[1] < 0.25f*WB_fenv[0]) || mode == NORMAL ) { if( last_extl == WB_BWE && ( (prev_coder_type == AUDIO && coder_type != AUDIO) || (prev_coder_type != AUDIO && coder_type == AUDIO)) && total_brate <= ACELP_8k00 ) { if( WB_fenv[0] > prev_WB_fenv[0] ) { wfenv[0] = 0.3f*WB_fenv[0] + 0.7f*prev_WB_fenv[0]; wfenv[1] = 0.3f*WB_fenv[1] + 0.7f*prev_WB_fenv[1]; } else { wfenv[0] = 0.5f*WB_fenv[0] + 0.5f*prev_WB_fenv[0]; wfenv[1] = 0.4f*WB_fenv[1] + 0.4f*prev_WB_fenv[1]; } } else if ( last_extl == WB_BWE && prev_WB_fenv[0]*EnergyL < WB_fenv[0]*(*prev_Energy) && WB_fenv[0] > prev_WB_fenv[0] && coder_type != AUDIO && coder_type != UNVOICED && total_brate <= ACELP_8k00) { wfenv[0] = 0.3f*WB_fenv[0] + 0.7f*prev_WB_fenv[0]; wfenv[1] = 0.3f*WB_fenv[1] + 0.7f*prev_WB_fenv[1]; } else if ( last_extl == WB_BWE && EnergyL > alfa*(*prev_Energy) && EnergyL < beta*(*prev_Energy) && prev_coder_type != UNVOICED ) { wfenv[0] = 0.5f*(WB_fenv[0] + prev_WB_fenv[0]); wfenv[1] = 0.5f*(WB_fenv[1] + prev_WB_fenv[1]); } else { wfenv[0] = WB_fenv[0]; wfenv[1] = WB_fenv[1]; } for (n_freq = swb_bwe_subband[0]; n_freq 0.5f*(*prev_Energy) && EnergyL < 2.0f*(*prev_Energy)) { wfenv[0] = 0.25f*wfenv[0] + 0.375f*(prev_WB_fenv[0] + prev_WB_fenv[1]); } for (n_freq = swb_bwe_subband[0]; n_freq 8.0f*SWB_fenv[0]) { fenvL = SWB_fenv[0]; } calc_normal_length( ACELP_CORE, core_dec_freq, mode, extl, &L_swb_norm, prev_L_swb_norm ); if( mode == TRANSIENT ) { Energy = 0.0f; for(n_band = 0; n_band < SWB_FENV_TRANS; n_band++) { Energy += SWB_fenv[n_band]*SWB_fenv[n_band]; } Energy /= SWB_FENV_TRANS; /* Reconstruct excitation from LF signal */ mvr2r(&core_dec_freq[112], &SWB_signal[240+st_offset], 128); mvr2r(&core_dec_freq[112], &SWB_signal[368+st_offset], 128); mvr2r(&core_dec_freq[176], &SWB_signal[496+st_offset], 64); /* calculate envelope */ calc_norm_envelop(SWB_signal, envelope, L_swb_norm, SWB_flength, st_offset); /* Normalize with envelope */ for (n_freq = swb_bwe_trans_subband[0]+st_offset; n_freq EnergyL || (tilt_nb > 7 && Energy > 0.5f*EnergyL) || tilt_nb > 12) && Energy > 75 && fenvL > 25)) { for (n_freq=swb_bwe_subband[0]+st_offset; n_freq SWB_fenv[n_band+1] ) { SWB_fenv[n_band+1] *= (0.8f+0.015f*n_band); } else if( SWB_fenv[n_band+1] * 0.9f > SWB_fenv[n_band] ) { SWB_fenv[n_band] *= (0.8f+0.015f*n_band); } } mvr2r(&core_dec_freq[112], &SWB_signal[240+st_offset], 128); mvr2r(&core_dec_freq[112], &SWB_signal[368+st_offset], 128); mvr2r(&core_dec_freq[176], &SWB_signal[496+st_offset], 64); tmp1 = (float)(fabs(SWB_signal[368+st_offset]) + fabs(SWB_signal[369+st_offset])) + EPSILON; tmp2 = (float)(fabs(SWB_signal[365+st_offset]) + fabs(SWB_signal[366+st_offset])) + EPSILON; pit1 = &SWB_signal[368+st_offset]; tmp3 = tmp2/tmp1; if(tmp3 < 0.3) { tmp3 = 0.3f; } while(tmp3 < 1) { *pit1++ *= tmp3; tmp3 += 0.1f; } pit1 = &SWB_signal[367+st_offset]; tmp3 = tmp1/tmp2; if( tmp3 > 5 ) { tmp3 = 5; while( tmp3 > 1 ) { *pit1-- *= tmp3; tmp3 -= 0.5f; } } tmp1 = (float)(fabs(SWB_signal[496+st_offset]) + fabs(SWB_signal[497+st_offset])) + EPSILON; tmp2 = (float)(fabs(SWB_signal[492+st_offset]) + fabs(SWB_signal[493+st_offset]) + fabs(SWB_signal[494+st_offset]) + fabs(SWB_signal[495+st_offset])) + EPSILON; pit1 = &SWB_signal[496+st_offset]; tmp3 = tmp2/tmp1; if( tmp3 < 0.3 ) { tmp3 = 0.3f; } while(tmp3 < 1) { *pit1++ *= tmp3; tmp3 += 0.1f; } pit1 = &SWB_signal[495+st_offset]; tmp3 = tmp1/tmp2; tmp3 = 0.5f*tmp3; tmp4 = 0.05f*tmp3; while( tmp3 > 1 ) { *pit1-- *= tmp3; tmp3 -= tmp4; } /* calculate envelope */ calc_norm_envelop(SWB_signal, envelope, L_swb_norm, SWB_flength, st_offset); } } /* Normalize with envelope */ if( *frica_flag == 0 && mode != NOISE ) { L = swb_bwe_subband[0]+st_offset; inv_L_swb_norm = 1.0f/L_swb_norm; weight = (mode != HARMONIC) ? max(min(3.0f*inv_L_swb_norm, 0.5f), 0.2f) : 0.2f; weight = 0.4f*weight + 0.6f*(*prev_weight); for(n_freq = L; n_freq 0) { SWB_signal[n_freq] *= (1.2f - weight); } SWB_signal[n_freq] *= signum[n_freq]; } for (n_freq = L; n_freq 1.25f*Energy && Energy > 0 ) { weight = 0.5f*Energy/(*prev_Energy); } else { weight = 0.5f; } wfenv = weight*prev_SWB_fenv[0] + (1-weight)*SWB_fenv[0]; factor = fenvL; factor1 = (wfenv - fenvL) * 0.125f; for (n_freq = swb_bwe_subband[0]+st_offset; n_freq < swb_bwe_subband[0]+8+st_offset; n_freq++) { SWB_signal[n_freq] *= factor; factor += factor1; } for(n_band = 0; n_band < 12; n_band++) { wfenv = weight*prev_SWB_fenv[n_band+1] + (1-weight)*SWB_fenv[n_band+1]; factor = SWB_fenv[n_band]; factor1 = (wfenv - SWB_fenv[n_band]) * smooth_factor[n_band]; for (; n_freq < swb_bwe_sm_subband[n_band+1]+st_offset; n_freq++) { SWB_signal[n_freq] *= factor; factor += factor1; } } wfenv = weight*prev_SWB_fenv[13] + (1-weight)*SWB_fenv[13]; factor = SWB_fenv[12]; factor1 = (wfenv - SWB_fenv[12]) * smooth_factor[12]; for ( ; n_freq < swb_bwe_sm_subband[13]+st_offset; n_freq++) { SWB_signal[n_freq] *= factor; factor += factor1; } for(n_band=13; n_band 1.8f*energyL[i] && energyL[i+1] > 50) { pos = i+1; break; } } if (pos > 0) { if(pos < 3) { pos ++; } energy = EPSILON; j = L*pos; for(i=0; i0 ? 1.0f: -1.0f); } } else { for ( n_freq = sfidx; n_freq < efidx; n_freq++ ) { coeff_out1[n_freq] =coeff_out1[n_freq]*signum[n_freq]; } } /* normalizing modified low frequency spectrum */ for( k =0 ; k < nband_lf; ++k ) { energy = EPSILON; for ( i = k*blen+sfidx; i < (k+1)*blen+sfidx; ++i ) { energy += coeff_out1[i] * coeff_out1[i]; } energy = (float)sqrt(energy/blen); for ( i = k*blen+sfidx; i < (k+1)*blen+sfidx; ++i ) { coeff_out1[i] /= energy; } } mvr2r(coeff_out1+HQ_GENERIC_OFFSET, &coeff_out[HQ_GENERIC_HIGH0+hq_generic_offset], HQ_GENERIC_LEN0); mvr2r(coeff_out1+HQ_GENERIC_OFFSET, &coeff_out[HQ_GENERIC_HIGH1+hq_generic_offset], HQ_GENERIC_LEN0); if ( hq_generic_offset <= HQ_GENERIC_FOFFSET_24K4 ) { mvr2r( &coeff_out1[HQ_GENERIC_LOW0], &coeff_out[HQ_GENERIC_HIGH2+hq_generic_offset], HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2 ); } if ( HQ_mode == HQ_GEN_FB ) { if ( hq_generic_offset <= HQ_GENERIC_FOFFSET_24K4 ) { mvr2r(coeff_out1+HQ_GENERIC_LOW0 + HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2, &coeff_out[fb_bwe_subband[0]], 160); } else { mvr2r(coeff_out1+HQ_GENERIC_OFFSET + HQ_GENERIC_LEN0, &coeff_out[fb_bwe_subband[0]], 160); } } tmp1 = EPSILON; tmp2 = EPSILON; for(i=0; i<5; ++i) { tmp1 += (float)fabs(coeff_out[HQ_GENERIC_HIGH1+hq_generic_offset+i]); tmp2 += (float)fabs(coeff_out[HQ_GENERIC_HIGH1-2+hq_generic_offset-i]); } pit1 = &coeff_out[HQ_GENERIC_HIGH1+hq_generic_offset]; tmp3 = tmp2/tmp1; if( tmp3 < 0.3f ) { tmp3 = 0.3f; } while( tmp3 < 1 ) { *pit1++ *= tmp3; tmp3 += 0.1f; } pit1 = &coeff_out[HQ_GENERIC_HIGH1-1+hq_generic_offset]; tmp3 = tmp1/tmp2; if( tmp3 > 5 ) { tmp3 = 5; while( tmp3 > 1 ) { *pit1-- *= tmp3; tmp3 -= 0.5f; } } if ( hq_generic_offset <= HQ_GENERIC_FOFFSET_24K4 ) { tmp1 = (float)(fabs(coeff_out[HQ_GENERIC_HIGH2+hq_generic_offset]) + fabs(coeff_out[HQ_GENERIC_HIGH2+1+hq_generic_offset])) + EPSILON; tmp2 = (float)(fabs(coeff_out[HQ_GENERIC_HIGH2-4+hq_generic_offset]) + fabs(coeff_out[HQ_GENERIC_HIGH2-3+hq_generic_offset]) + fabs(coeff_out[HQ_GENERIC_HIGH2-2+hq_generic_offset]) + fabs(coeff_out[HQ_GENERIC_HIGH2-1+hq_generic_offset])) + EPSILON; pit1 = &coeff_out[HQ_GENERIC_HIGH2+hq_generic_offset]; tmp3 = tmp2/tmp1; if( tmp3 < 0.3f ) { tmp3 = 0.3f; } while( tmp3 < 1 ) { *pit1++ *= tmp3; tmp3 += 0.1f; } pit1 = &coeff_out[HQ_GENERIC_HIGH2-1+hq_generic_offset]; tmp3 = tmp1/tmp2; tmp3 = 0.5f*tmp3; tmp4 = 0.05f*tmp3; while(tmp3 > 1) { *pit1-- *= tmp3; tmp3 -= tmp4; } } wfenv = hq_generic_fenv[0]; for (n_freq = swb_bwe_subband[0]+hq_generic_offset,i=0; n_freq 15.f || hq_generic_fenv[nenv] < 5.f) { wfenv = hq_generic_fenv[nenv-1]; for ( i=0; n_freq