/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include #include "options.h" #include "cnst.h" #include "rom_com.h" #include "prot.h" /*-------------------------------------------------------------------* * gs_noisf() * * Noise fill-in function *-------------------------------------------------------------------*/ static void gs_noisf( const short Start_BIN, /* i : First bin for noise fill */ const short NB_Qbins, /* i : Number of bin per band */ const float Noise_fac, /* i : Noise level */ const float *y_norm, /* i : Quantized pulses */ float *exc_diffQ, /* o : Quantized pulses with noise added */ short *seed_tcx, /* i : Random generator seed */ const short coder_type /* i : coder type */ ) { float ftmp; short i, k; short NB_zer = NB_Qbins/2; if( coder_type == INACTIVE ) { NB_zer = 2; } /*----------------------------------------------* * noise fill-in on unquantized subvector * * injected only from 1066Hz to 6400Hz. * *----------------------------------------------*/ for( k=Start_BIN; k ACELP_24k40 ) { noise_offset = .2f; } else if( bitrate >= ACELP_22k60 ) { noise_offset = .3f; } else if( bitrate >= ACELP_9k60 ) { noise_offset = 0.35f; } else { noise_offset = .4f; } set_f( noisepb + i_band, noise_offset, Mbands_gn - i_band ); for( i = i_band; i < 5; i++ ) { if( noisepb[i] > 0.2f ) { noisepb[i] = 0.2f; } } return; } /*-------------------------------------------------------------------* * EstimateNoiseLevel() * * *-------------------------------------------------------------------*/ static void EstimateNoiseLevel( float *noisepb, /* o : Noise per band */ const long bitrate, /* i : Bitrate of the codec */ const short Diff_len, /* i : number of bin before cut-off frequency */ const short Mbands_gn, /* i : number of bands */ const short coder_type, /* i : coder type */ const short noise_lev, /* i : pulses dynamic */ const short pit_band_idx, /* i : bin position of the cut-off frequency */ short last_bin, /* i : the last bin of bit allocation */ short bwidth ) { short i_band; i_band = 0; if( Diff_len < L_FRAME ) { EstimateNoiseLevel_inner(noisepb, bitrate, i_band, Mbands_gn); if( coder_type != INACTIVE ) { if( (bitrate == ACELP_8k00 && last_bin > 8) && bwidth != NB) { while(Mbands_gn > i_band ) { noisepb[i_band] *= 2.0f; i_band++; } } else { while(pit_band_idx > i_band ) { noisepb[i_band] /= 2.0f; i_band++; } } } } if ( (coder_type == INACTIVE || noise_lev >= NOISE_LEVEL_SP3) ) { for( i_band = 9; i_band < Mbands_gn; i_band++ ) { noisepb[i_band] *= 1.15f; } } return; } /*-------------------------------------------------------------------* * Apply_NoiseFill() * * *-------------------------------------------------------------------*/ static void Apply_NoiseFill( float *exc_diffQ, /* i/o: Noise per band */ short *seed_tcx, /* i : Seed for noise */ const float *noisepb, /* i : Noise per band */ const short Diff_len, /* i : number of bin before cut-off frequency */ const short Mbands_gn, /* i : number of bands */ const short coder_type, /* i : coder type */ const short *freq_nsbin_per_band /* i : bin per bands tables */ ) { short StartBin, NB_Qbins, i_band; StartBin = 0; NB_Qbins = 0; for( i_band = 0; i_band < Mbands_gn; i_band++ ) { StartBin += NB_Qbins; NB_Qbins = freq_nsbin_per_band[i_band]; if( Diff_len < L_FRAME ) { gs_noisf( StartBin, NB_Qbins, noisepb[i_band], exc_diffQ, exc_diffQ, seed_tcx, coder_type ); } } return; } /*-------------------------------------------------------------------* * freq_dnw_scaling() * * *-------------------------------------------------------------------*/ void freq_dnw_scaling( const short cor_strong_limit, /* i : HF correlation */ const short coder_type, /* i : coder type */ const short noise_lev, /* i : Noise level */ const long core_brate, /* i : Core bitrate */ float fy_norm[] /* i/o: Frequency quantized parameter */ ) { float sc_dyn; short start_sc, i; sc_dyn = 1.0f; start_sc = L_FRAME; if( core_brate <= ACELP_8k00 && coder_type == INACTIVE ) { sc_dyn *= .15f; start_sc = 64; } else if( coder_type == INACTIVE ) { sc_dyn *= .25f; start_sc = 80; } else { sc_dyn = (float)(NOISE_LEVEL_SP3 - noise_lev)/10.0f + 0.4f; start_sc = 112 + (NOISE_LEVEL_SP3 - noise_lev) * 16; if( noise_lev == NOISE_LEVEL_SP0 ) { start_sc = L_FRAME; } } for(i = start_sc; i < L_FRAME; i++) { fy_norm[i] *= sc_dyn; } if( (core_brate < ACELP_13k20 && cor_strong_limit == 0) || core_brate < ACELP_9k60) { for(i = 160; i < L_FRAME; i++) { if( fy_norm[i] > 1.0f ) { fy_norm[i] = 1.0f; } if( fy_norm[i] < -1.0f ) { fy_norm[i] = -1.0f; } } } else if( core_brate < ACELP_22k60 ) { for(i = 160; i < L_FRAME; i++) { if( fy_norm[i] > 1.5f ) { fy_norm[i] = 1.5f; } if( fy_norm[i] < -1.5f ) { fy_norm[i] = -1.5f; } } } return; } /*-------------------------------------------------------------------* * Decreas_freqPeak() * * *-------------------------------------------------------------------*/ static void Decreas_freqPeak( float *lsf_new, /* i : ISFs at the end of the frame */ float *exc_diffQ, /* i/o: frequency coefficients of per band */ float rat /* i : threshold of ratio between consecutive lsf_new_diff */ ) { short i, j, k; short last_bin = 0; short pos = 0; float *src; float avrg, max; float lsf_new_diff[M]; for(j=1; j<(M-1); j++) { lsf_new_diff[j] = lsf_new[j] - lsf_new[j-1]; } avrg = 0.0f; /* This is to prevent a possible div by 0 in the '*(src) = (*src > 0) ?...' loop. The value of 'max' is not important because it will be mutiplied by 'avrg' and the result will be close to 0. The 'fabs(*src)/max' div by 0 error will be avoided. */ max = 0.001f; for(i=160; i max) { max = (float)fabs(exc_diffQ[i]); pos = i; } avrg += (float)fabs(exc_diffQ[i]); } avrg /= 96; for(i=0; i<(M-1); i++) { if(lsf_new[i] > 4000) { last_bin = i; break; } } for(i=last_bin; i<14; i++) { if(lsf_new_diff[i] < rat*lsf_new_diff[i-1]) { src = &exc_diffQ[(i-1)*16]; for(j=0; j<2; j++) { for(k=0; k<16; k++) { if(fabs(*src) > 2.0f*avrg) { *(src) = (*src > 0) ? (float)(avrg*(2.0f-fabs(*src)/max)) : (float)(-avrg*(2.0f-fabs(*src)/max)); } src++; } } } } if(fabs(exc_diffQ[pos]) == max && max > 4.0f*avrg) { for(i=pos-1; i 8 || Diff_len != 0) && last_coder_type == AUDIO) { MAX_Bin = 10; bwe_flag = 1; } else { MAX_Bin = 15; } last_bin_tmp = last_bin; if(last_bin < MAX_Bin) { last_bin = MAX_Bin; } last_bin += 1; } else { last_bin = MBANDS_GN; last_bin_tmp = last_bin; } if( bfi ) { set_f( noisepb, 0.4f, MBANDS_GN ); } else { EstimateNoiseLevel( noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth ); } if( exc_wo_nf != NULL ) { mvr2r( exc_diffQ, exc_wo_nf, L_FRAME ); } if( GSC_noisy_speech && !bfi ) { set_f( noisepb, 0.1f, MBANDS_GN ); } Apply_NoiseFill( exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv_loc ); /*--------------------------------------------------------------------------------------* * Quantize average gain * Substract Q averaged gain * VQ of remaining gain per band *--------------------------------------------------------------------------------------*/ if( core_brate == ACELP_8k00 && bwidth != NB ) { Ener_per_band_comp( exc_diffQ, Ener_per_bd_yQ, last_bin+1, 0 ); } else { Ener_per_band_comp( exc_diffQ, Ener_per_bd_yQ, MBANDS_GN, 1 ); if( nb_subfr < 4 ) { for( i = L_FRAME-16; i < L_FRAME; i++ ) { exc_diffQ[i] *= (0.067f * i - 15.0f); } } } /*--------------------------------------------------------------------------------------* * Check potential energy excitation overshoot *--------------------------------------------------------------------------------------*/ if( bfi ) { if (GSC_noisy_speech == 0 && coder_type > UNVOICED) /* Here coder_type == last_coder_type because of the bfi */ { for( i=0; i end) { *src-- = *dst--; } if( (bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0) && core_brate == ACELP_8k00 ) { exc_diffQ[160] = 0.0f; } envelop_modify(exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ); mvr2r( &exc_diffQ[last_bin*16], &exc_dct_in[last_bin*16], L_FRAME-last_bin*16 ); } if( nb_subfr < 4 ) { for( i = L_FRAME-16; i < L_FRAME; i++ ) { exc_dct_in[i] *= (0.067f*i-15.f); } } if( ener < 2*(*last_ener) && ener > 0.5f*(*last_ener) ) { length_bin = 6; if(last_coder_type != AUDIO) { set_s( last_bitallocation_band, 0, 6 ); mvr2r( &exc_dct_in[(4+length_bin)*16], &last_exc_dct_in[(4+length_bin)*16], length_bin*16 ); } for(i=4; i<(4+length_bin); i++) { if( !(bitallocation_band[i] == 0 && last_bitallocation_band[i-4] == 0)) { src = &exc_dct_in[(i+length_bin)*16]; dst = &last_exc_dct_in[(i+length_bin)*16]; for(j=0; j<16; j++) { if(fabs(*src) > 3.0f*fabs(*dst)) { *src = (*src > 0) ? (float)(0.5f*(*src + fabs(*dst))) : (float)(0.5f*(*src - fabs(*dst))); } else if(fabs(*dst) > 3.0f*fabs(*src)) { *src = (*src > 0) ? (float)(0.7f*(*src) + 0.3f*fabs(*dst)) : (float)(0.7f*(*src) - 0.3f*fabs(*dst)); } src++; dst++; } } } } if( bwe_flag == 1 ) { Decreas_freqPeak( lsf_new, exc_dct_in, 0.3f ); } else { Decreas_freqPeak( lsf_new, exc_dct_in, 0.5f ); } } mvr2r( &exc_dct_in[64], &last_exc_dct_in[64], L_FRAME-64 ); mvs2s( &bitallocation_band[4], last_bitallocation_band, 6 ); *last_ener = ener; return; }