diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 9dbac8dd61d242323f6738c89ce48e78f9403b0c..739e4de2eabd2f2d95c1c7063ea473cc670cb319 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -194,13 +194,6 @@ ivas_error acelp_core_dec_ivas_fx( } #endif ApplyFdCng_ivas_fx( NULL, 0, NULL, 0, NULL, NULL, NULL, st, 0, 0 ); - - IF( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp < 0 ) - { - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; - move16(); - } } ELSE { @@ -698,26 +691,7 @@ ivas_error acelp_core_dec_ivas_fx( move32(); } #endif - Word16 new_sidNoiseEstExp = 31 - Q4; - move16(); - Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, new_sidNoiseEstExp ) ); - Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, new_sidNoiseEstExp ) ); - st->hFdCngDec->hFdCngCom->sidNoiseEstExp = new_sidNoiseEstExp; - move16(); - Word16 new_cngNoiseLevelExp = 31 - Q4; - move16(); - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp - new_cngNoiseLevelExp ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = new_cngNoiseLevelExp; - move16(); - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); - - IF( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp < 0 ) - { - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; - move16(); - } } IF( !read_sid_info ) @@ -1547,30 +1521,9 @@ ivas_error acelp_core_dec_ivas_fx( IF( NE_16( st->element_mode, IVAS_CPE_TD ) && !st->cng_ism_flag ) { /*Noise estimate*/ - - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, Q27 ) ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 31 - Q4; // Q4 - move16(); - - Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, Q27 ) ); - Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, Q27 ) ); - st->hFdCngDec->hFdCngCom->sidNoiseEstExp = 31 - Q4; // Q4 - move16(); /*==========================================================*/ ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); /*==========================================================*/ - IF( st->hFdCngDec->partNoiseShape_exp < 0 ) - { - Scale_sig32( st->hFdCngDec->partNoiseShape, NPART, st->hFdCngDec->partNoiseShape_exp ); - st->hFdCngDec->partNoiseShape_exp = 0; - move16(); - } - IF( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp < 0 ) - { - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; - move16(); - } } IF( !st->cna_dirac_flag ) @@ -1656,24 +1609,6 @@ ivas_error acelp_core_dec_ivas_fx( IF( ( st->idchan == 0 ) && ( EQ_16( nchan_out, 2 ) || ( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) ) ) { ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); - IF( st->hFdCngDec->partNoiseShape_exp < 0 ) - { - Scale_sig32( st->hFdCngDec->partNoiseShape, NPART, -st->hFdCngDec->partNoiseShape_exp ); - st->hFdCngDec->partNoiseShape_exp = 0; - move16(); - } - IF( st->hFdCngDec->partNoiseShape_exp < 0 ) - { - Scale_sig32( st->hFdCngDec->partNoiseShape, NPART, st->hFdCngDec->partNoiseShape_exp ); - st->hFdCngDec->partNoiseShape_exp = 0; - move16(); - } - IF( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp < 0 ) - { - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; - move16(); - } } } } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index ae13e69c8cc42a9075b4cf7f9088b46f8f08f0fd..2dc687237f59983b56245c11bdd08cdb87278c42 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1383,16 +1383,26 @@ Word16 ApplyFdCng_ivas_fx( IF( NE_16( s2, -( WORD32_BITS - 1 ) ) ) { s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); + Word16 e_shift = 0; + IF( s > 0 ) + { + Word16 q_norm = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); + IF( GT_16( s, q_norm ) ) + { + scale_sig32( cngNoiseLevel, j, sub( q_norm, s ) ); + e_shift = sub( s, q_norm ); + } + } FOR( ; k < hFdCngCom->npart; k++ ) { FOR( ; j <= hFdCngCom->part[k]; j++ ) { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); + cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], sub( s, e_shift ) ); move32(); } } - *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); + *cngNoiseLevel_exp = add( add( hFdCngDec->bandNoiseShape_exp, s2 ), e_shift ); move16(); } } @@ -2410,14 +2420,16 @@ void perform_noise_estimation_dec_ivas_fx( Word32 temp, ftemp, delta, L_tmp; Word16 e_temp, wght, periodog_exp; Word32 enr, enr_tot, enr_tot0; - Word16 enr_ratio, alpha; + Word16 enr_e, enr_ratio, alpha; Word32 *msPeriodog; Word32 *msNoiseEst; Word32 *reIter; Word32 rescale_fac = 0; Word64 W_tmp; Word16 tmp_s, tmp_q, min_q = 31; - Word16 exp_flag = 0; + Word16 q_shift; + Word32 max_l; + Word16 norm_shift; #ifdef IVAS_CODE_CNG PMT( "lots of code related to IVAS needs to be done " ) #endif @@ -2639,62 +2651,47 @@ void perform_noise_estimation_dec_ivas_fx( enr_tot0 = L_add_sat( L_shr( sum32_fx( msNoiseEst, npart ), sub( hFdCngDec->msPeriodog_exp, hFdCngDec->msNoiseEst_exp ) ), 1 ); } + /* update short-term periodogram on larger partitions */ + maximum_32_fx( &msPeriodog[CNA_ACT_DN_LARGE_PARTITION], sub( npart, CNA_ACT_DN_LARGE_PARTITION ), &max_l ); + q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp ); + norm_shift = norm_l( max_l ); test(); - IF( !( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) ) ) + IF( max_l && GT_16( q_shift, norm_shift ) ) { - IF( GT_16( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp ) ) - { - exp_flag = 1; - move16(); - } - ELSE - { - exp_flag = 0; - move16(); - } + scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, sub( norm_shift, q_shift ) ); + hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, sub( norm_shift, q_shift ) ); + move16(); + q_shift = norm_shift; + move16(); } - - /* update short-term periodogram on larger partitions */ FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) { test(); + q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp ); IF( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) ) { /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */ - hFdCngDec->msPeriodog_ST_fx[p] = msPeriodog[p]; + hFdCngDec->msPeriodog_ST_fx[p] = L_shl( msPeriodog[p], q_shift ); move32(); - hFdCngDec->msPeriodog_ST_exp = hFdCngDec->hFdCngCom->periodog_exp; - move16(); } ELSE { - temp = msPeriodog[p]; - move32(); - IF( exp_flag ) - { - hFdCngDec->msPeriodog_ST_fx[p] = L_shr( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp ) ); - move32(); - } - ELSE - { - temp = L_shr( temp, sub( hFdCngDec->msPeriodog_ST_exp, hFdCngDec->hFdCngCom->periodog_exp ) ); - } #ifdef IVAS_ENH32_CADENCE_CHANGES - hFdCngDec->msPeriodog_ST_fx[p] = Madd_32_16( Mpy_32_16_1( hFdCngDec->msPeriodog_ST_fx[p], ST_PERIODOG_FACT_Q15 ), temp, sub( MAX_16, ST_PERIODOG_FACT_Q15 ) ); + temp = L_shl( msPeriodog[p], q_shift ); + hFdCngDec->msPeriodog_ST_fx[p] = Madd_32_16( Mpy_32_16_1( hFdCngDec->msPeriodog_ST_fx[p], ST_PERIODOG_FACT_Q15 ), temp, MAX_16 - ST_PERIODOG_FACT_Q15 ); #else hFdCngDec->msPeriodog_ST_fx[p] = L_add( Mpy_32_16_1( hFdCngDec->msPeriodog_ST_fx[p], ST_PERIODOG_FACT_Q15 ), Mpy_32_16_1( temp, sub( MAX_16, ST_PERIODOG_FACT_Q15 ) ) ); #endif move32(); } } - test(); - IF( !( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) ) ) + maximum_32_fx( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, &max_l ); + IF( max_l ) { - IF( exp_flag ) - { - hFdCngDec->msPeriodog_ST_exp = hFdCngDec->hFdCngCom->periodog_exp; - move16(); - } + q_shift = sub( norm_l( max_l ), 2 ); + scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, q_shift ); + hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, q_shift ); + move16(); } /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */ @@ -2755,30 +2752,35 @@ void perform_noise_estimation_dec_ivas_fx( IF( NE_16( hFdCngDec->first_cna_noise_update_cnt, 0 ) ) { alpha = Inv16( add( hFdCngDec->first_cna_noise_update_cnt, 1 ), &e ); - IF( LT_16( e, 0 ) ) + alpha = shl_sat( alpha, e ); // Q15 + maximum_32_fx( msPeriodog, npart, &max_l ); + q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msNoiseEst_exp ); + norm_shift = norm_l( max_l ); + test(); + IF( max_l && GT_16( q_shift, norm_shift ) ) { - alpha = shr( alpha, negate( e ) ); // Q15 + scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); + hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) ); + move16(); + q_shift = norm_shift; + move16(); } FOR( p = 0; p < npart; p++ ) { - temp = msPeriodog[p]; - move32(); - temp = L_shr( temp, sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); + temp = L_shl( msPeriodog[p], q_shift ); #ifdef IVAS_ENH32_CADENCE_CHANGES - msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], sub( shl_sat( 1, sub( 15, e ) ), alpha ) ), temp, alpha ); + msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], sub( MAX_16, alpha ) ), temp, alpha ); #else - msNoiseEst[p] = L_add( Mpy_32_16_1( msNoiseEst[p], sub( shl_sat( 1, sub( 15, e ) ), alpha ) ), Mpy_32_16_1( temp, alpha ) ); + msNoiseEst[p] = L_add( Mpy_32_16_1( msNoiseEst[p], sub( MAX_16, alpha ) ), Mpy_32_16_1( temp, alpha ) ); #endif move32(); } } ELSE { - FOR( p = 0; p < npart; p++ ) - { - msNoiseEst[p] = L_shr( msPeriodog[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); - move32(); - } + Copy32( msPeriodog, msNoiseEst, npart ); + scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); + hFdCngDec->msNoiseEst_exp = hFdCngDec->msPeriodog_exp; } /* check, if we reached the required number of first CNA noise update frames */ @@ -2863,7 +2865,7 @@ void perform_noise_estimation_dec_ivas_fx( /* energy significantly decreases in one of the larger partitions during active frames -> downward update */ FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) { - L_tmp = L_shr( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_ST_exp ) ); + L_tmp = L_shr_sat( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_ST_exp ) ); IF( LT_32( L_tmp, msNoiseEst[p] ) ) { #ifdef IVAS_ENH32_CADENCE_CHANGES @@ -2895,7 +2897,8 @@ void perform_noise_estimation_dec_ivas_fx( move16(); enr = msPeriodog[p]; move32(); - temp = L_shr( enr, sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); + enr_e = hFdCngDec->msPeriodog_exp; + move16(); alpha = 31130; // 0.95f in Q15 move16(); /* bandwidth increased -> do fast re-initilization */ @@ -2908,16 +2911,29 @@ void perform_noise_estimation_dec_ivas_fx( alpha = shr( alpha, negate( i_e ) ); // Q15 } } - ELSE IF( LT_32( temp, *ptr_per ) && EQ_16( part[p], 1 ) ) + ELSE IF( ( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, hFdCngDec->msNoiseEst_exp ) < 0 ) && EQ_16( part[p], 1 ) ) { /* faster downward update for single-bin partitions */ alpha = 26214; // 0.8f in Q15 move16(); } - ELSE IF( GT_32( temp, L_shl( ( *ptr_per ), 1 ) ) ) + ELSE IF( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, add( hFdCngDec->msNoiseEst_exp, 1 ) ) > 0 ) { /* prevent abrupt upward updates */ - temp = L_shl( ( *ptr_per ), 1 ); + test(); + IF( ( norm_l( *ptr_per ) == 0 ) && *ptr_per ) + { + enr = *ptr_per; + scale_sig32( msNoiseEst, NPART_SHAPING, -1 ); + hFdCngDec->msNoiseEst_exp = add( hFdCngDec->msNoiseEst_exp, 1 ); + move16(); + } + ELSE + { + enr = L_shl( *ptr_per, 1 ); + } + enr_e = hFdCngDec->msNoiseEst_exp; + move16(); } /* IIR smoothing */ @@ -2938,9 +2954,27 @@ void perform_noise_estimation_dec_ivas_fx( move32(); } #ifdef IVAS_ENH32_CADENCE_CHANGES - *ptr_per = Madd_32_16( ( *ptr_per ), temp, sub( MAX_16, alpha ) ); + if ( enr ) + { + q_shift = sub( enr_e, hFdCngDec->msNoiseEst_exp ); + norm_shift = norm_l( enr ); + if ( LE_16( q_shift, norm_shift ) ) + { + enr = L_shl( enr, q_shift ); + move32(); + } + else + { + enr_e = sub( enr_e, norm_shift ); + enr = L_shl( enr, norm_shift ); + scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); + hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) ); + move16(); + } + } + *ptr_per = Madd_32_16( ( *ptr_per ), enr, sub( MAX_16, alpha ) ); #else - *ptr_per = L_add( ( *ptr_per ), Mpy_32_16_1( temp, sub( MAX_16, alpha ) ) ); + *ptr_per = L_add( ( *ptr_per ), Mpy_32_16_1( enr, sub( MAX_16, alpha ) ) ); #endif ptr_per++; } @@ -2951,6 +2985,14 @@ void perform_noise_estimation_dec_ivas_fx( } } } + maximum_32_fx( msNoiseEst, NPART_SHAPING, &max_l ); + if ( max_l ) + { + q_shift = sub( norm_l( max_l ), 2 ); + scale_sig32( msNoiseEst, NPART_SHAPING, q_shift ); + hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, q_shift ); + move16(); + } Copy32( msNoiseEst, hFdCngDec->msPsd_fx, npart ); hFdCngDec->msPsd_exp_fft = hFdCngDec->msNoiseEst_exp; diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 800e20f5b30173db199dedd9c34323c92b30ae37..2bfd615b0bb8ffef84285cb0d43404eb167a83f2 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -531,10 +531,6 @@ ivas_error ivas_core_dec_fx( IF( st->hFdCngDec != NULL ) { - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - move16(); - Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); } @@ -613,9 +609,6 @@ ivas_error ivas_core_dec_fx( /* TCX decoder */ Scale_sig( st->hPFstat->mem_stp, L_SUBFR, -Qsyn_temp ); Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, -Qsyn_temp ); - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - move16(); Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, -st->hHQ_core->Q_old_wtda_LB ); Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, -st->hHQ_core->Q_old_wtda ); @@ -822,10 +815,6 @@ ivas_error ivas_core_dec_fx( { IF( NE_16( sts[n]->last_core_bfi, ACELP_CORE ) ) { - Scale_sig32( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 27 ) ); - sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 27; - move16(); - TonalMdctConceal_whiten_noise_shape_ivas_fx( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); } } diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 728709de509354eaaf7aa0b6d85db219e4aa9093..364b0316a25a48ef87d0d4266caa727fa57b8549 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -695,6 +695,7 @@ static void stereo_dft_generate_comfort_noise_fx( Word16 numSlots; Word16 scale, inv_scale, tmp_16; Word32 lp_noise; + Word16 lp_noise_e; Word32 tmp, enr; Word16 q_enr; Word32 shb_shape[L_FRAME16k]; @@ -704,7 +705,8 @@ static void stereo_dft_generate_comfort_noise_fx( Word32 cngNoiseLevel_upd[L_FRAME16k], cngNoiseLevel_hist[L_FRAME16k - 2]; Word16 e_norm_temp[L_FRAME16k]; Word32 *ptr_tmp, *ptr_cng; - Word32 E0, E1; + Word64 E0, E1; + Word16 E0_e, E1_e; Word16 b, q_cngNoiseLevel_upd, q_cngNoiseLevel; Word32 *pSideGain; Word16 gamma; @@ -734,21 +736,22 @@ static void stereo_dft_generate_comfort_noise_fx( set_zero_fx( DFT[chan], STEREO_DFT_BUF_MAX ); set32_fx( cngNoiseLevel_upd, 0, L_FRAME16k ); - q_shift = s_min( getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ), sub( hFdCngCom->cngNoiseLevelExp, 27 ) ); - scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, q_shift ); - hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, q_shift ); - move16(); - enr = 0; /* Eliminates compiler warning. They are always set before they are used */ move32(); q_enr = 0; move16(); E0 = 0; - move32(); + move64(); + E0_e = 0; + move16(); E1 = 0; - move32(); + move64(); + E1_e = 0; + move16(); lp_noise = 0; move32(); + lp_noise_e = 0; + move16(); q_shb_shape = 0; move16(); @@ -1032,10 +1035,10 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_cng = cngNoiseLevel_hist; FOR( i = 0; i < shr( sub( st->last_L_frame, hFdCngCom->startBand ), 1 ); i++ ) { - tmp = *( cngNoiseLevel_hist + shl( i, 1 ) ); + tmp = L_shr( *( cngNoiseLevel_hist + shl( i, 1 ) ), 1 ); move32(); - tmp = L_add( tmp, *( cngNoiseLevel_hist + add( shl( i, 1 ), 1 ) ) ); - *ptr_cng++ = L_shr( tmp, 1 ); + tmp = L_add( tmp, L_shr( *( cngNoiseLevel_hist + add( shl( i, 1 ), 1 ) ), 1 ) ); + *ptr_cng++ = tmp; move32(); } @@ -1048,14 +1051,21 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_tmp = cngNoiseLevel_upd + hFdCngCom->startBand; FOR( i = 0; i < shr( sub( st->last_L_frame, hFdCngCom->startBand ), 1 ); i++ ) { - E0 = L_add( E0, *ptr_cng++ ); - E1 = L_add( E1, Mpy_32_32( ( *ptr_tmp ), ( *ptr_tmp ) ) ); + E0 = W_add( E0, *ptr_cng++ ); + E1 = W_mac_32_32( E1, ( *ptr_tmp ), ( *ptr_tmp ) ); ptr_tmp++; } + E0_e = W_norm( E0 ); + E0 = W_shl( E0, E0_e ); + E0_e = add( sub( st->hFdCngDec->bandNoiseShape_exp, E0_e ), 32 ); + E1_e = W_norm( E1 ); + E1 = W_shl( E0, E1_e ); + E1_e = sub( 63, add( E1_e, add( shl( q_cngNoiseLevel_upd, 1 ), 1 ) ) ); - tmp_16 = BASOP_Util_Divide3232_Scale( E0, E1, &q_div ); + tmp_16 = BASOP_Util_Divide3232_Scale( W_extract_h( E0 ), W_extract_h( E1 ), &q_div ); + q_div = add( q_div, sub( E0_e, E1_e ) ); tmp_16 = Sqrt16( tmp_16, &q_div ); - IF( LT_16( tmp_16, shr_sat( MAX_16, q_div ) ) ) + IF( BASOP_Util_Cmp_Mant32Exp( tmp_16, add( 16, q_div ), MAX_32, 0 ) < 0 ) { tmp_16 = shl( tmp_16, q_div ); hStereoCng->xfade_length = sub( MAX_XFADE_FX, extract_l( L_shr( imult3216( MAX_XFADE_FX, tmp_16 ), Q15 ) ) ); @@ -1063,9 +1073,8 @@ static void stereo_dft_generate_comfort_noise_fx( } ELSE { - Word16 q_inv; - tmp_16 = Invert16( tmp_16, &q_inv ); - tmp_16 = shl( tmp_16, add( q_inv, q_div ) ); + tmp_16 = Inv16( tmp_16, &q_div ); + tmp_16 = shl( tmp_16, q_div ); hStereoCng->xfade_length = sub( MAX_XFADE_FX, extract_l( L_shr( imult3216( MAX_XFADE_FX, tmp_16 ), Q15 ) ) ); move16(); } @@ -1221,6 +1230,8 @@ static void stereo_dft_generate_comfort_noise_fx( /* Expand cngNoiseLevel_flt from 0-159 to 0-318, compute noise level */ lp_noise = 0; move32(); + lp_noise_e = 0; + move16(); ptr_level = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, add( hFdCngCom->startBand, 1 ) ); ptr_tmp = cngNoiseLevel_upd + sub( shr( sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), 1 ), 1 ); @@ -1236,7 +1247,7 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_tmp--; *ptr_level = *( ptr_level + 1 ); move32(); - lp_noise = L_add( lp_noise, L_shl( *ptr_level--, 1 ) ); + lp_noise = BASOP_Util_Add_Mant32Exp( lp_noise, lp_noise_e, *ptr_level--, add( hFdCngCom->cngNoiseLevelExp, 1 ), &lp_noise_e ); } } ELSE @@ -1254,13 +1265,22 @@ static void stereo_dft_generate_comfort_noise_fx( FOR( k = 0; k < sub( hFdCngCom->nFFTpart, 2 ); k++ ) { factor = BASOP_Util_Divide3232_Scale_cadence( L_add( hFdCngCom->sidNoiseEstLp[k], DELTA_FX ), L_add( st->hFdCngDec->partNoiseShape[k], DELTA_FX ), &q_div ); - factor = s_min( add( hStereoDft->scale_fx, extract_l( Mpy_32_16_1( L_mult( sub( extract_h( factor ), hStereoDft->scale_fx ), hStereoCng->xfade_frame_counter ), ONE_BY_MAX_K ) ) ), extract_h( factor ) ); + q_div = add( q_div, sub( hFdCngCom->sidNoiseEstExp, st->hFdCngDec->partNoiseShape_exp ) ); + IF( q_div < 0 ) + { + factor = L_shl( factor, q_div ); // Q31 + q_div = 0; + move16(); + } + factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); FOR( ; j <= hFdCngCom->part[k]; j++ ) { - hFdCngCom->cngNoiseLevel[j] = Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ); + hFdCngCom->cngNoiseLevel[j] = L_shl( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); move32(); } } + hFdCngCom->cngNoiseLevelExp = st->hFdCngDec->bandNoiseShape_exp; + move16(); } } scale = shr( output_frame, 1 ); @@ -1318,17 +1338,20 @@ static void stereo_dft_generate_comfort_noise_fx( /* Compute noise level */ lp_noise = 0; move32(); + lp_noise_e = 0; + move16(); ptr_level = hFdCngCom->cngNoiseLevel; FOR( i = 0; i < sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); i++ ) { - lp_noise = L_add( lp_noise, *ptr_level++ ); + // lp_noise = L_add( lp_noise, *ptr_level++ ); + lp_noise = BASOP_Util_Add_Mant32Exp( lp_noise, lp_noise_e, *ptr_level++, hFdCngCom->cngNoiseLevelExp, &lp_noise_e ); } } test(); IF( EQ_16( hStereoCng->last_act_element_mode, IVAS_CPE_TD ) && ( chan > 0 ) ) { - Word32 log_lp_noise = L_add( L_shl( hFdCngCom->cngNoiseLevelExp, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); + Word32 log_lp_noise = L_add( L_shl( lp_noise_e, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); // log10(x) is computed as log2(x) * log10(2) // log_lp_noise at this stage is in Q25. where as the structure value is in Q23 // Hence the 16-bit constant log10(2) will be stored in Q13 @@ -1340,7 +1363,7 @@ static void stereo_dft_generate_comfort_noise_fx( { Word16 q_lp_noise = 0; // st->hFdCngDec->q_lp_noise; // to be populated appropriately. move16(); - Word32 log_lp_noise = L_add( L_shl( hFdCngCom->cngNoiseLevelExp, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); + Word32 log_lp_noise = L_add( L_shl( lp_noise_e, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); // log10(x) is computed as log2(x) * log10(2) // log_lp_noise at this stage is in Q25. where as the structure value is in Q23 // Hence the 16-bit constant log10(2) will be stored in Q13 @@ -1359,20 +1382,27 @@ static void stereo_dft_generate_comfort_noise_fx( test(); IF( ( chan == 0 ) && LE_32( st->core_brate, SID_2k40 ) ) { - Word32 max_smoothed_psd = 0; - move32(); - (void) maximum_32_fx( &st->hFdCngDec->smoothed_psd_fx[hFdCngCom->startBand], sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), &max_smoothed_psd ); /* update smoothed periodogram used by stereo CNA in SID and NO_DATA frames from cngNoiseLevel_flt */ + Word16 l_shift_val = sub( st->hFdCngDec->q_smoothed_psd, sub( Q31, hFdCngCom->cngNoiseLevelExp ) ); + q_shift = L_norm_arr( st->hFdCngDec->smoothed_psd_fx, L_FRAME16k ); + IF( GE_16( q_shift, negate( l_shift_val ) ) ) + { + scale_sig32( st->hFdCngDec->smoothed_psd_fx, L_FRAME16k, negate( l_shift_val ) ); + st->hFdCngDec->q_smoothed_psd = sub( Q31, hFdCngCom->cngNoiseLevelExp ); + move16(); + } + ELSE + { + scale_sig32( st->hFdCngDec->smoothed_psd_fx, L_FRAME16k, q_shift ); + st->hFdCngDec->q_smoothed_psd = add( st->hFdCngDec->q_smoothed_psd, q_shift ); + move16(); + l_shift_val = add( q_shift, l_shift_val ); + scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, l_shift_val ); + hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, l_shift_val ); + move16(); + } FOR( i = hFdCngCom->startBand; i < hFdCngCom->stopFFTbin; i++ ) { - Word16 l_shift_val = sub( st->hFdCngDec->q_smoothed_psd, sub( Q31, hFdCngCom->cngNoiseLevelExp ) ); - - if ( max_smoothed_psd == 0 ) - { - l_shift_val = 0; - move16(); - } - ftmp = hFdCngCom->cngNoiseLevel[sub( i, hFdCngCom->startBand )]; move32(); IF( !st->hFdCngDec->first_cna_noise_updated ) @@ -1385,14 +1415,14 @@ static void stereo_dft_generate_comfort_noise_fx( { alpha = (Word16) ( 0x799A ); move16(); - IF( ( st->hFdCngDec->smoothed_psd_fx[i] > 0 ) && GT_32( Mpy_32_16_1( ftmp, (Word16) 0x3333 ), L_shr_sat( st->hFdCngDec->smoothed_psd_fx[i], l_shift_val ) ) ) + test(); + IF( ( st->hFdCngDec->smoothed_psd_fx[i] > 0 ) && GT_32( Mpy_32_16_1( ftmp, (Word16) 0x3333 ), st->hFdCngDec->smoothed_psd_fx[i] ) ) { /* prevent abrupt upward update steps */ ftmp = L_add( L_shl( st->hFdCngDec->smoothed_psd_fx[i], 1 ), L_shr( st->hFdCngDec->smoothed_psd_fx[i], 1 ) ); - l_shift_val = 0; move16(); } - ELSE IF( LT_32( ftmp, L_shr( st->hFdCngDec->smoothed_psd_fx[i], l_shift_val ) ) ) + ELSE IF( LT_32( ftmp, st->hFdCngDec->smoothed_psd_fx[i] ) ) { /* faster downward updates */ alpha = (Word16) ( 0x599A ); @@ -1401,18 +1431,26 @@ static void stereo_dft_generate_comfort_noise_fx( } /* smoothing */ - st->hFdCngDec->smoothed_psd_fx[i] = L_add( Mpy_32_16_1( st->hFdCngDec->smoothed_psd_fx[i], alpha ), L_shl( Mpy_32_16_1( ftmp, sub( MAX_16, alpha ) ), l_shift_val ) ); + st->hFdCngDec->smoothed_psd_fx[i] = L_add( Mpy_32_16_1( st->hFdCngDec->smoothed_psd_fx[i], alpha ), Mpy_32_16_1( ftmp, sub( MAX_16, alpha ) ) ); move32(); } /* update msNoiseEst in SID and NO_DATA frames */ bandcombinepow( &st->hFdCngDec->smoothed_psd_fx[hFdCngCom->startBand], sub( Q31, st->hFdCngDec->q_smoothed_psd ), sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->psize_inv_shaping, st->hFdCngDec->msNoiseEst, &st->hFdCngDec->msNoiseEst_exp ); - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - move16(); + + Word32 max_l; + maximum_32_fx( st->hFdCngDec->msNoiseEst, NPART_SHAPING, &max_l ); + IF( max_l ) + { + q_shift = sub( norm_l( max_l ), 2 ); + scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, q_shift ); + st->hFdCngDec->msNoiseEst_exp = sub( st->hFdCngDec->msNoiseEst_exp, q_shift ); + move16(); + } st->hFdCngDec->first_cna_noise_updated = 1; move16(); Copy32( st->hFdCngDec->msNoiseEst, st->hFdCngDec->msPeriodog_ST_fx, st->hFdCngDec->nFFTpart_shaping ); + st->hFdCngDec->msPeriodog_ST_exp = st->hFdCngDec->msNoiseEst_exp; st->hFdCngDec->ms_last_inactive_bwidth = st->bwidth; move16(); } diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 7323d051324499f674af7eaebcb911f85fb9b1a7..7eef8c14a5c8888c7a464c818212e4aca294839a 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -1053,17 +1053,6 @@ static void run_min_stats_fx( test(); IF( will_estimate_noise_on_channel[0] || will_estimate_noise_on_channel[1] || st->bfi ) { - // for ( int p = 0; p < FFTCLDFBLEN; p++ ) - { - // st->hFdCngDec->hFdCngCom->cngNoiseLevel[p] = L_shr ( st->hFdCngDec->hFdCngCom->cngNoiseLevel[p], sub( 28, st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ) ); - } - Scale_sig32( st->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 28 ) ); - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 31 - Q3; // Q3 - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - // Scale_sig32(power_spec, L_FRAME16k, sub(power_spec_e, 31)); - // power_spec_e = 31; - /*=================================================*/ Word32 *arr_tmp; IF( st->bfi ) {