/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include <math.h> #include <stdlib.h> #include <assert.h> #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<N; i++) { r0 += sp[i] * sp[i]; } r1 = (float)fabs(sp[1] - sp[0]); for(i=2; i<N; i++) { if((sp[i] - sp[i-1]) * (sp[i-1] - sp[i-2]) < 0) { r1 += (float)fabs(sp[i] - sp[i-1]); } } *tilt = (float)(r1/sqrt(r0)); return; } /*-------------------------------------------------------------------* * calc_norm_envelop() * * calculate normalized parameter *-------------------------------------------------------------------*/ void calc_norm_envelop( const float SWB_signal[], /* i : SWB spectrum */ float *envelope, /* o : normalized envelope */ const short L_swb_norm, /* i : length of envelope */ const short SWB_flength, /* i : Length of input/output */ const short st_offset /* i : offset */ ) { short i, lookback, env_index, n_freq, n_lag_now, n_lag; lookback = L_swb_norm/2; env_index = swb_bwe_subband[0]+st_offset; n_lag_now = L_swb_norm; for (n_freq = swb_bwe_trans_subband[0]+st_offset-lookback; n_freq<SWB_flength+st_offset-L_swb_norm; n_freq++) { /* Apply MA filter */ envelope[env_index] = EPSILON; for (n_lag=0; n_lag<n_lag_now; n_lag++) { envelope[env_index] += (float)fabs(SWB_signal[n_freq+n_lag]); } env_index++; } for (n_freq = SWB_flength+st_offset-L_swb_norm, i = 0; n_freq<SWB_flength+st_offset-lookback; n_freq++, i++) { n_lag_now = L_swb_norm-i; /* Apply MA filter */ envelope[env_index] = EPSILON; for (n_lag=0; n_lag<n_lag_now; n_lag++) { envelope[env_index] += (float)fabs(SWB_signal[n_freq+n_lag]); } env_index++; } return; } /*-------------------------------------------------------------------* * calc_norm_envelop_lf() * * calc_envelope of low frequency spectrum *-------------------------------------------------------------------*/ static void calc_norm_envelop_lf( const float SWB_signal[], /* i : SWB spectrum */ float *envelope, /* o : normalized envelope */ short *L_swb_norm, /* i/o: length of envelope */ const short HQ_mode, /* i : HQ mode */ const short hq_generic_offset, /* i : frequency offset for representing hq swb bwe */ short *sfreq, /* i : starting frequency index */ short *efreq) /* i : ending frequency index */ { short lookback, env_index, n_freq, n_lag_now, n_lag; *sfreq = 2; if ( hq_generic_offset == HQ_GENERIC_FOFFSET_24K4) { *efreq = 146; if ( HQ_mode == HQ_GEN_FB) { *efreq = 306; } if ( (328 - *efreq)*2 + 1 < *L_swb_norm) { *L_swb_norm = (328 - *efreq)*2 + 1; } } else { *efreq = 130; if (HQ_mode == HQ_GEN_FB) { *efreq = 290; } if ( (400 - *efreq)*2 + 1 < *L_swb_norm) { *L_swb_norm = (400 - *efreq)*2 + 1; } } lookback = *L_swb_norm/2; env_index = 0; n_lag_now = *L_swb_norm; for (n_freq = 0; n_freq<lookback; n_freq++) { envelope[env_index] = EPSILON; for (n_lag=0; n_lag<lookback+n_freq; n_lag++) { envelope[env_index] += (float)fabs(SWB_signal[n_lag]); } env_index++; } for (; n_freq<*efreq; n_freq++) { /* Apply MA filter */ envelope[env_index] = EPSILON; for (n_lag=0; n_lag<n_lag_now; n_lag++) { envelope[env_index] += (float)fabs(SWB_signal[n_freq-lookback+n_lag]); } env_index++; } return; } /*-------------------------------------------------------------------* * WB_BWE_decoding() * * WB BWE decoder *-------------------------------------------------------------------*/ void WB_BWE_decoding( const float *core_dec_freq, /* i : Frequency domain core decoded signal */ float *WB_fenv, /* i : WB frequency envelopes */ float *WB_signal, /* o : WB signal in MDCT domain */ const short WB_flength, /* i : Length of input/output */ const short mode, /* i : classification for WB signal */ const short last_extl, /* i : extl. layer for last frame */ float *prev_Energy, /* i/o: energy for last frame */ float *prev_WB_fenv, /* i/o: envelope for last frame */ short *prev_L_wb_norm, /* i/o: length for last frame wb norm */ const short extl, /* i : extension layer */ const short coder_type, /* i : coding type */ const long total_brate, /* i : core layer bitrate */ short *Seed, /* i/o: random generator seed */ short *prev_flag, /* i/o: attenu flag of last frame */ short prev_coder_type /* i : coding type of last frame */ ) { short n_freq, n_band; short i, L; float envelope[L_FRAME16k]; float energy, wfenv[2], EnergyL; float *pit1; short L_wb_norm; float alfa, beta; short flag = 0; short core_type = 1; short signum[L_FRAME16k]; float inv_L_wb_norm, weight; calc_normal_length( ACELP_CORE, core_dec_freq, mode, extl, &L_wb_norm, prev_L_wb_norm ); set_f( WB_signal, 0, L_FRAME16k ); /* copy excitation */ if( coder_type != AUDIO && total_brate <= ACELP_8k00 ) { core_type = 0; } if( core_type == 0 ) { mvr2r(&core_dec_freq[160], &WB_signal[240], 80); } else { mvr2r(&core_dec_freq[80], &WB_signal[240], 80); } /* calculate envelope */ calc_norm_envelop(WB_signal, envelope, L_wb_norm, WB_flength, 0); if( coder_type != UNVOICED && total_brate <= ACELP_8k00 ) { inv_L_wb_norm = 1.0f/L_wb_norm; weight = (mode != HARMONIC) ? max(min(3.0f*inv_L_wb_norm, 0.5f), 0.25f) : 0.25f; for(n_freq = swb_bwe_subband[0]; n_freq<swb_bwe_subband[4]; n_freq++) { signum[n_freq] = 1; if (WB_signal[n_freq]<0) { signum[n_freq] = -1; WB_signal[n_freq] *= signum[n_freq]; } WB_signal[n_freq] = WB_signal[n_freq] - 0.45f*envelope[n_freq]*inv_L_wb_norm; if(WB_signal[n_freq] > 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<swb_bwe_subband[4]; n_freq++) { WB_signal[n_freq] /= envelope[n_freq]; } if( mode == HARMONIC ) { L = 4; } else { L = 1; } if( coder_type == UNVOICED ) { for ( n_freq = swb_bwe_subband[0]; n_freq < swb_bwe_subband[4]; n_freq++ ) { *Seed = (short)(12345*(*Seed) + 20101); WB_signal[n_freq] = (*Seed)/32768.0f; } } else { for( n_band = 0; n_band < 4; n_band += L ) { energy = EPSILON; for (n_freq = swb_bwe_subband[n_band]; n_freq<swb_bwe_subband[n_band+L]; n_freq++) { energy += WB_signal[n_freq] * WB_signal[n_freq]; } energy = (float)sqrt((swb_bwe_subband[n_band+L] - swb_bwe_subband[n_band])/energy); for (n_freq = swb_bwe_subband[n_band]; n_freq<swb_bwe_subband[n_band+L]; n_freq++) { WB_signal[n_freq] *= energy; } } } EnergyL = 0.0f; if( core_type == 1 ) { if( prev_coder_type != AUDIO && total_brate <= ACELP_8k00 ) { for(i=160; i<240; i++) { EnergyL += (float)fabs(core_dec_freq[i]); } } else { for(i=80; i<240; i++) { EnergyL += (float)fabs(core_dec_freq[i]); } } if(total_brate <= ACELP_8k00) { alfa = 0.8f; beta = 1.25f; } else { alfa = 0.5f; beta = 2.0f; } } else { if( prev_coder_type == AUDIO ) { for(i=80; i<240; i++) { EnergyL += (float)fabs(core_dec_freq[i]); } } else { for(i=160; i<240; i++) { EnergyL += (float)fabs(core_dec_freq[i]); } } if( prev_coder_type == coder_type && WB_fenv[0] > 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<swb_bwe_subband[2]; n_freq++) { WB_signal[n_freq] *= wfenv[0]; } for (n_freq = swb_bwe_subband[2]; n_freq<swb_bwe_subband[4]; n_freq++) { WB_signal[n_freq] *= wfenv[1]; } prev_WB_fenv[0] = wfenv[0]; prev_WB_fenv[1] = wfenv[1]; } else { wfenv[0] = 0.5f*(WB_fenv[0]+WB_fenv[1]); if(last_extl == WB_BWE && EnergyL > 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<swb_bwe_subband[4]; n_freq++) { WB_signal[n_freq] *= wfenv[0]; } prev_WB_fenv[0] = wfenv[0]; prev_WB_fenv[1] = wfenv[0]; } *prev_flag = flag; *prev_Energy = EnergyL; pit1 = &WB_signal[240]; for(n_freq=0; n_freq<16; n_freq++) { *(pit1++) *= (0.2f+n_freq*0.05f); } if( core_type == 1 ) { pit1 = &WB_signal[280]; for(n_freq=0; n_freq<40; n_freq++) { *(pit1++) *= ( 1.0f-n_freq*0.02f); } } else { pit1 = &WB_signal[300]; for(n_freq=0; n_freq<20; n_freq++) { *(pit1++) *= ( 1.0f-n_freq*0.04f); } } return; } /*-------------------------------------------------------------------* * SWB_BWE_decoding() * * SWB BWE decoder *-------------------------------------------------------------------*/ void SWB_BWE_decoding( const float *core_dec_freq, /* i : Frequency domain core decoded signal */ float *SWB_fenv, /* i/o: SWB frequency envelopes */ float *SWB_signal, /* o : SWB signal in MDCT domain */ const short SWB_flength, /* i : Length of input/output */ const short mode, /* i : classification for SWB signal */ short *frica_flag, /* o : fricative signal flag */ float *prev_Energy, /* i/o: energy for last frame */ float *prev_SWB_fenv, /* i/o: envelope for last frame */ short *prev_L_swb_norm, /* i/o: length for last frame wb norm */ const float tilt_nb, /* i : tilt of synthesis wb signal */ short *Seed, /* i/o: random generator seed */ const short st_offset, /* i : offset value due to different core */ float *prev_weight, /* i/o: excitation weight value of last frame */ const short extl /* i : extension layer */ ,const short last_extl /* i : extension layer of last frame */ ) { short n_freq, n_band, L, L_swb_norm; float *pit1; float envelope[L_FRAME32k]; float fenvL, EnergyL, Energy, energy, weight, wfenv, factor; float mean, factor1, tmp1, tmp2, tmp3, tmp4, tmp_ener; short signum[L_FRAME32k]; float inv_L_swb_norm; fenvL = 0.0f; EnergyL = EPSILON; for(n_freq=224+st_offset; n_freq<swb_bwe_trans_subband[0]+st_offset; n_freq++) { fenvL += core_dec_freq[n_freq] * core_dec_freq[n_freq]; } for( n_freq = 16; n_freq < L_FRAME; n_freq++ ) { EnergyL += core_dec_freq[n_freq] * core_dec_freq[n_freq]; } fenvL = (float)sqrt(fenvL/16); EnergyL = (float)sqrt(EnergyL/240); if (fenvL > 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<swb_bwe_trans_subband[SWB_FENV_TRANS]+st_offset; n_freq++) { SWB_signal[n_freq] /= envelope[n_freq]; } for(n_band=0; n_band<SWB_FENV_TRANS; n_band++) { energy = EPSILON; for (n_freq = swb_bwe_trans_subband[n_band]+st_offset; n_freq<swb_bwe_trans_subband[n_band+1]+st_offset; n_freq++) { energy += SWB_signal[n_freq] * SWB_signal[n_freq]; } tmp_ener = (float)(sqrt(swb_bwe_trans_subband_width[n_band] / energy) * SWB_fenv[n_band]); for (n_freq = swb_bwe_trans_subband[n_band]+st_offset; n_freq<swb_bwe_trans_subband[n_band+1]+st_offset; n_freq++) { SWB_signal[n_freq] *= tmp_ener; } } for( n_band = 0; n_band < 8; n_band++ ) { prev_SWB_fenv[n_band] = SWB_fenv[n_band/4]*SWB_fenv[n_band/4]; } for( n_band = 0; n_band < 6; n_band++ ) { prev_SWB_fenv[8+n_band] = SWB_fenv[2+n_band/3]*SWB_fenv[2+n_band/3]; } *prev_weight = 0.5f; } else { Energy = EPSILON; for(n_band = 0; n_band < SWB_FENV; n_band++) { Energy += SWB_fenv[n_band]; } Energy /= SWB_FENV; if(last_extl != SWB_BWE && last_extl != FB_BWE) { if(16.0f*Energy < EnergyL && extl == FB_BWE) { for(n_band=0; n_band <SWB_FENV; n_band++) { SWB_fenv[n_band] *= 0.2f; } fenvL *= 0.2f; } mvr2r(SWB_fenv, prev_SWB_fenv, SWB_FENV); } if( mode == HARMONIC ) { mvr2r( core_dec_freq, &SWB_signal[240+st_offset], 240 ); mvr2r( &core_dec_freq[128], &SWB_signal[480+st_offset], 80 ); /* calculate envelope */ calc_norm_envelop(SWB_signal, envelope, L_swb_norm, SWB_flength, st_offset); } else { if(mode == NOISE || ((Energy > 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_bwe_subband[SWB_FENV]+st_offset; n_freq++) { *Seed = (short)(12345*(*Seed) + 20101); SWB_signal[n_freq] = (*Seed)/32768.0f; } if(mode != NOISE) { *frica_flag = 1; } } else { /* modify SHB frequency envelopes when SHB spectrum is unflat */ for(n_band=0; n_band <13; n_band++) { if( SWB_fenv[n_band] * 0.9f > 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<swb_bwe_subband[SWB_FENV]+st_offset; n_freq++) { signum[n_freq] = 1; if (SWB_signal[n_freq]<0) { signum[n_freq] = -1; SWB_signal[n_freq] *= signum[n_freq]; } SWB_signal[n_freq] = SWB_signal[n_freq] - envelope[n_freq]*inv_L_swb_norm; if(SWB_signal[n_freq] > 0) { SWB_signal[n_freq] *= (1.2f - weight); } SWB_signal[n_freq] *= signum[n_freq]; } for (n_freq = L; n_freq<swb_bwe_subband[SWB_FENV]+st_offset; n_freq++) { SWB_signal[n_freq] /= envelope[n_freq]; } *prev_weight = weight; } else { *prev_weight = max(min(3.0f/L_swb_norm, 0.5f), 0.2f); } if( mode == HARMONIC ) { pit1 = &SWB_signal[swb_bwe_subband[0]+st_offset]; for(n_band=0; n_band<19; n_band++) { mean = 0; for(n_freq=0; n_freq<16; n_freq++) { mean += (float) fabs(*pit1); pit1++; } mean /= 16; pit1 -= 16; for(n_freq=0; n_freq<16; n_freq++) { if(fabs(*pit1) < mean) { *pit1 *= 0.2f; } pit1++; } } } if( mode == HARMONIC ) { L = 2; } else { L = 1; } for(n_band=0; n_band<SWB_FENV; n_band+=L) { energy = EPSILON; for (n_freq = swb_bwe_subband[n_band]+st_offset; n_freq<swb_bwe_subband[n_band+L]+st_offset; n_freq++) { energy += SWB_signal[n_freq] * SWB_signal[n_freq]; } tmp_ener = (float)sqrt((swb_bwe_subband[n_band+L] - swb_bwe_subband[n_band])/energy); for(n_freq = swb_bwe_subband[n_band]+st_offset; n_freq<swb_bwe_subband[n_band+L]+st_offset; n_freq++) { SWB_signal[n_freq] *= tmp_ener; } } if( *prev_Energy > 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<SWB_FENV; n_band++) { wfenv = weight*prev_SWB_fenv[n_band] + (1-weight)*SWB_fenv[n_band]; for ( ; n_freq<swb_bwe_subband[n_band+1]+st_offset; n_freq++) { SWB_signal[n_freq] *= wfenv; } } for(n_band = 0; n_band < SWB_FENV; n_band++) { prev_SWB_fenv[n_band] = SWB_fenv[n_band]; } } pit1 = &SWB_signal[240+st_offset]; for(n_freq=0; n_freq<4; n_freq++) { *(pit1++) *= 0.5f; } *prev_Energy = Energy; return; } /*-------------------------------------------------------------------* * time_envelop_shaping() * * time shaping of the SHB signal *-------------------------------------------------------------------*/ void time_envelop_shaping( float werr[], /* i/o: SHB synthesis */ float SWB_tenv[], /* i/o: frequency envelope */ const short L /* i : frame length */ ) { float *pit; float Energy; short i, j; float tmp_ener; pit = werr; for(i=0; i<SWB_TENV; i++) { Energy = EPSILON; for(j=0; j<L/4; j++) { Energy += *pit **pit; pit++; } Energy = (float)sqrt(4*Energy/L); if(SWB_tenv[i] < 2 && Energy < SWB_tenv[i]) { SWB_tenv[i] = Energy; } pit -= L/4; tmp_ener = 1.0f / Energy; for (j = 0; j < L/4; j++) { *pit *= SWB_tenv[i] * tmp_ener; pit++; } } return; } /*-------------------------------------------------------------------* * time_reduce_pre_echo() * * Pre-echo reduction. *-------------------------------------------------------------------*/ void time_reduce_pre_echo( const float *synth, /* i : ACELP core synthesis */ float *error, /* o : SHB BWE synthesis */ float prev_td_energy, /* o : last td energy */ const short L /* i : subframe length */ ) { short i, j, pos = 0; float energy; float energyL[4]; float tmp_ener; float *pit; float tmpi; for(i=0; i<4; i++) { energyL[i] = 0; for(j=0; j<L; j++) { energyL[i] += synth[L*i+j]*synth[L*i+j]; } energyL[i] = (float)sqrt(energyL[i]/L); } for(i=0; i<3; i++) { if(energyL[i+1] > 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; i<j; i++) { energy += error[i]*error[i]; } energy = (float)sqrt(energy/j); if(prev_td_energy < 0.2f*energy) { prev_td_energy = 0.2f*energy; } tmp_ener = prev_td_energy / energy; for (i = 0; i < j; i++) { error[i] *= tmp_ener; } energy = EPSILON; for(i=j; i<(j+L); i++) { energy += error[i]*error[i]; } energy = (float)sqrt(energy/L); pit = &error[j]; tmp_ener = prev_td_energy / energy; for (i = 0; i < L; i++) { tmpi = i/(1.0f*L); *pit++ *= ((1.0f - tmpi) * tmp_ener + tmpi); } } return; } /*-------------------------------------------------------------------* * hq_generic_hf_decoding() * *-------------------------------------------------------------------*/ void hq_generic_hf_decoding( const short HQ_mode, /* i : HQ mode */ float *coeff_out1, /* i/o: BWE input & temporary buffer */ const float *hq_generic_fenv, /* i : SWB frequency envelopes */ float *coeff_out, /* o : SWB signal in MDCT domain */ const short hq_generic_offset, /* i : frequency offset for representing hq swb bwe*/ short *prev_L_swb_norm, /* i/o: last normalize length */ const short hq_generic_exc_clas, /* i : bwe excitation class */ const short *R ) { short i, n_freq, n_band, L_swb_norm; float fenvL, energy, wfenv, factor; float envelope[L_FRAME16k]; float *pit1; float tmp1, tmp2, tmp3, tmp4; float mean_vector[20]; short k; short nenv; short tenv; float rn_weight0; short blen,nband_lf,sfidx,efidx; short bwe_seed; short signum[L_FRAME16k]; if ( hq_generic_offset <= HQ_GENERIC_FOFFSET_24K4 ) { nenv = SWB_FENV; } else { nenv = SWB_FENV-2; } if ( HQ_mode == HQ_GEN_FB ) { tenv = nenv + DIM_FB; } else { tenv = nenv; } fenvL = 0.0f; for( n_freq = HQ_GENERIC_ST_FREQ + hq_generic_offset; n_freq<swb_bwe_subband[0] + hq_generic_offset; n_freq++ ) { fenvL += coeff_out1[n_freq] * coeff_out1[n_freq]; } fenvL = (float)sqrt(fenvL/16); calc_normal_length( HQ_CORE, coeff_out1, HQ_GEN_SWB, -1, &L_swb_norm, prev_L_swb_norm ); /* calculate envelope */ calc_norm_envelop_lf( coeff_out1, envelope, &L_swb_norm, HQ_mode, hq_generic_offset, &sfidx, &efidx); blen = 16; if (hq_generic_exc_clas == HQ_GENERIC_EXC0 ) { rn_weight0 = 0.8f; } else if (hq_generic_exc_clas == HQ_GENERIC_EXC1 ) { rn_weight0 = 0.05f; } else { rn_weight0 = 0.2f; } nband_lf = (efidx-sfidx)/blen; for ( n_freq = sfidx; n_freq < efidx; n_freq++ ) { if (coeff_out1[n_freq]<0) { signum[n_freq] = -1; coeff_out1[n_freq] *= signum[n_freq]; } else { signum[n_freq] = 1; } } /* applying whitening */ for ( n_freq = sfidx; n_freq < efidx; n_freq++ ) { coeff_out1[n_freq] = coeff_out1[n_freq] / envelope[n_freq]; } /* mean vector generation for controlling dynamic range */ for( k =0 ; k < nband_lf; ++k ) { energy = EPSILON; for ( i = k*blen+sfidx; i < (k+1)*blen+sfidx; ++i ) { energy += coeff_out1[i]; } mean_vector[k] = energy / blen; } /* dynamic range control */ for( k =0 ; k < nband_lf; ++k ) { for ( i = k*blen+sfidx; i < (k+1)*blen+sfidx; ++i ) { coeff_out1[i] = coeff_out1[i] - (coeff_out1[i]-mean_vector[k])*rn_weight0; } } if (hq_generic_exc_clas == HQ_GENERIC_EXC0) { /* applying random sign */ bwe_seed = R[0]*8+R[1]*4+R[2]*2+R[3]; for ( n_freq = sfidx; n_freq < efidx; n_freq++ ) { coeff_out1[n_freq] = coeff_out1[n_freq]*signum[n_freq]*(own_random(&bwe_seed)>0 ? 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<swb_bwe_subband[0]+hq_generic_offset+8; n_freq++,i++) { factor = i*0.125f; coeff_out[n_freq] *= ((1-factor)*fenvL + factor*wfenv); } for(n_band=0; n_band<nenv-2; n_band++) { wfenv = hq_generic_fenv[n_band+1]; for ( i=0; n_freq<swb_bwe_sm_subband[n_band+1]+hq_generic_offset; n_freq++, i++) { factor = i*smooth_factor[n_band]; coeff_out[n_freq] *= ((1-factor)*hq_generic_fenv[n_band] + factor*wfenv); } } wfenv = hq_generic_fenv[nenv-1]; for ( i=0; n_freq<swb_bwe_sm_subband[nenv-1]+hq_generic_offset; n_freq++, i++) { factor = i*smooth_factor[nenv-2]; coeff_out[n_freq] *= ((1-factor)*hq_generic_fenv[nenv-2] + factor*wfenv); } if ( HQ_mode == HQ_GEN_SWB ) { for(n_band=nenv-1; n_band<nenv; ++n_band) { wfenv = hq_generic_fenv[n_band]; for ( ; n_freq<swb_bwe_subband[n_band+1]+hq_generic_offset; n_freq++) { coeff_out[n_freq] *= wfenv; } } } else { if ( hq_generic_fenv[nenv - 1] - hq_generic_fenv[nenv] > 15.f || hq_generic_fenv[nenv] < 5.f) { wfenv = hq_generic_fenv[nenv-1]; for ( i=0; n_freq<fb_bwe_subband[0]; n_freq++, i++) { coeff_out[n_freq] *= wfenv; } for(n_band=0; n_band<DIM_FB ; n_band++) { wfenv = hq_generic_fenv[n_band + nenv]; for ( i=0; n_freq<fb_bwe_subband[n_band+1]; n_freq++, i++) { coeff_out[n_freq] *= wfenv; } } } else { for(n_band=0; n_band<DIM_FB ; n_band++) { wfenv = hq_generic_fenv[n_band + nenv - 1]; for ( i=0; n_freq<fb_bwe_sm_subband[n_band]; n_freq++, i++) { factor = i* fb_smooth_factor[n_band]; coeff_out[n_freq] *= ((1-factor)*hq_generic_fenv[n_band+nenv] + factor*wfenv); } } wfenv = hq_generic_fenv[tenv-1]; for ( ; n_freq<fb_bwe_subband[DIM_FB]; n_freq++) { coeff_out[n_freq] *= wfenv; } } } return; } /*-------------------------------------------------------------------* * save_old_syn() * * Save and delay the ACELP core synthesis signal by * DELAY_FD_BWE_ENC_xxkx to be used by SWB BWE *-------------------------------------------------------------------*/ void save_old_syn( const short L_frame, /* i : frame length */ const float syn[], /* i : ACELP synthesis */ float old_syn[], /* o : old synthesis buffer */ float old_syn_mem[], /* i/o: old synthesis buffer memory */ const float preemph_fac, /* i : preemphasis factor */ float *mem_deemph /* i/o: deemphasis filter memory */ ) { short tmps; if( L_frame == L_FRAME ) { tmps = NS2SA(12800, DELAY_FD_BWE_ENC_12k8_NS); } else { tmps = NS2SA(16000, DELAY_FD_BWE_ENC_16k_NS); } mvr2r( old_syn_mem, old_syn, tmps ); mvr2r( syn, old_syn + tmps, L_frame - tmps ); mvr2r( syn + L_frame - tmps, old_syn_mem, tmps ); deemph( old_syn, preemph_fac, L_frame, mem_deemph ); return; }