diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index ebc874cce241ba02c88bb41b7f695733f7066b32..ebd958e1bc048b3bf303847e41e45fac74076112 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -636,9 +636,9 @@ void computeDirectionVectors_fixed( #ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC IF( i_e_band != NULL ) { - e_x = sub( i_e_band[i - enc_param_start_band], norm_x ); - e_y = sub( i_e_band[i - enc_param_start_band], norm_y ); - e_z = sub( i_e_band[i - enc_param_start_band], norm_z ); + e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) ); + e_y = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_y ) ); + e_z = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_z ) ); } ELSE { diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 53aee57e3dab049b7f8323d4eaa022b1ade7d68c..df8f7d0f54092ae9eeba2b564b3319e773efba21 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -560,7 +560,11 @@ void ivas_fb_mixer_pcm_ingest_fx( move16(); ivas_mdft_fx( ppOut_pcm[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], shl( frame_len, 1 ), frame_len ); - hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = q_ppOut_pcm[fb_cfg->remix_order[i]]; + q_shift = L_norm_arr( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len ); + q_shift = s_min( q_shift, L_norm_arr( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len ) ); + scale_sig32( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len, q_shift ); + scale_sig32( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len, q_shift ); + hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = add( q_shift, q_ppOut_pcm[fb_cfg->remix_order[i]] ); move16(); } diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 467ce529876b569d43604e8f153d4f8603f9f4a0..f44454c874c14f2c295f42ab3670275d0e1a2050 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4846,7 +4846,8 @@ void ivas_dirac_param_est_enc_fx( const Word16 hodirac_flag, const Word16 nchan_fb_in, Word16 *mono_frame_count, - Word16 *dirac_mono_flag ); + Word16 *dirac_mono_flag, + const Word16 shift ); ivas_error ivas_cldfb_dec_reconfig_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5746,8 +5747,8 @@ ivas_error ivas_dirac_enc_fx( const Word16 input_frame, /* i : input frame length */ const Word16 dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const Word16 hodirac_flag /* i : hodirac flag */ -); + const Word16 hodirac_flag, /* i : hodirac flag */ + const Word16 shift ); ivas_error ivas_spar_md_enc_init_fx( ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */ diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 58a916858f789a241ff886158dd6951e3e79d27b..c54d7aa1ed2b602d6fc3d5d482ee7feabb4d677b 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -327,8 +327,8 @@ ivas_error ivas_dirac_enc_fx( const Word16 input_frame, /* i : input frame length Q0*/ const Word16 dtx_vad, /* i : DTX vad flag Q0*/ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const Word16 hodirac_flag /* i : hodirac flag Q0*/ -) + const Word16 hodirac_flag, /* i : hodirac flag Q0*/ + const Word16 shift ) { Word16 orig_dirac_bands; Word32 dir_fx[3], avg_dir_fx[3]; @@ -338,18 +338,18 @@ ivas_error ivas_dirac_enc_fx( Word16 nchan_fb_in; - if ( hodirac_flag ) + IF( hodirac_flag ) { nchan_fb_in = HOA2_CHANNELS; move16(); } - else + ELSE { nchan_fb_in = FOA_CHANNELS; move16(); } - ivas_dirac_param_est_enc_fx( hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f_fx, pp_fr_real_fx, pp_fr_imag_fx, pp_fr_q, input_frame, ivas_format, hodirac_flag, nchan_fb_in, &( hDirAC->mono_frame_count ), &( hQMetaData->dirac_mono_flag ) ); + ivas_dirac_param_est_enc_fx( hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f_fx, pp_fr_real_fx, pp_fr_imag_fx, pp_fr_q, input_frame, ivas_format, hodirac_flag, nchan_fb_in, &( hDirAC->mono_frame_count ), &( hQMetaData->dirac_mono_flag ), shift ); IF( hQMetaData->q_direction->cfg.nbands > 0 ) { @@ -585,29 +585,33 @@ static Word16 ivas_dirac_get_mono_flag_fx( move16(); move16(); + Word16 gb = find_guarded_bits_fx( sub( brange[1], brange[0] ) ); + /* Loop over the W channel bins to calculate the power in the band */ FOR( j = brange[0]; j < brange[1]; j++ ) { - acc = W_mac_32_32( acc, Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ); /* exp(2 * e_Cldfb) */ - acc = W_mac_32_32( acc, Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ); /* exp(2 * e_Cldfb) */ - shift1 = W_norm( acc ); - W_band_power = W_extract_h( W_shl( acc, shift1 ) ); /* exp(2 * e_Cldfb - shift1) */ - W_band_power_e = sub( imult1616( (Word16) 2, e_Cldfb ), shift1 ); + acc = W_mac_32_32( acc, L_shr( Cldfb_RealBuffer[0][j], gb ), L_shr( Cldfb_RealBuffer[0][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ + acc = W_mac_32_32( acc, L_shr( Cldfb_ImagBuffer[0][j], gb ), L_shr( Cldfb_ImagBuffer[0][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ } + shift1 = W_norm( acc ); + W_band_power = W_extract_h( W_shl( acc, shift1 ) ); /*Q:(2*(31-e_Cldfb-gb)+1+shift1-32*/ + W_band_power_e = sub( shl( add( e_Cldfb, gb ), 1 ), shift1 ); + gb = find_guarded_bits_fx( imult1616( sub( brange[1], brange[0] ), sub( nchan_ana, 1 ) ) ); /* Loop over the other channels and bins to calculate the power in the band */ FOR( ch_idx = 1; ch_idx < nchan_ana; ch_idx++ ) { /* abs()^2 */ FOR( j = brange[0]; j < brange[1]; j++ ) { - acc1 = W_mac_32_32( acc1, Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ); /* exp(2 * e_Cldfb) */ - acc1 = W_mac_32_32( acc1, Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ); /* exp(2 * e_Cldfb) */ - shift2 = W_norm( acc1 ); - other_ch_band_power = W_extract_h( W_shl( acc1, shift2 ) ); /* exp(2 * e_Cldfb - shift2) */ - other_ch_band_power_e = sub( imult1616( (Word16) 2, e_Cldfb ), shift2 ); + acc1 = W_mac_32_32( acc1, L_shr( Cldfb_RealBuffer[ch_idx][j], gb ), L_shr( Cldfb_RealBuffer[ch_idx][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ + acc1 = W_mac_32_32( acc1, L_shr( Cldfb_ImagBuffer[ch_idx][j], gb ), L_shr( Cldfb_ImagBuffer[ch_idx][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ } } + shift2 = W_norm( acc1 ); + other_ch_band_power = W_extract_h( W_shl( acc1, shift2 ) ); /*Q:(2*(31-e_Cldfb-gb)+1+shift2-32*/ + other_ch_band_power_e = sub( shl( add( e_Cldfb, gb ), 1 ), shift2 ); + IF( BASOP_Util_Cmp_Mant32Exp( other_ch_band_power, other_ch_band_power_e, EPSILON_FX_M, EPSILON_FX_E ) < 0 ) { if ( BASOP_Util_Cmp_Mant32Exp( W_band_power, W_band_power_e, DIRAC_MONO_THRESH_SILENCE_FX, 31 ) > 0 ) @@ -967,8 +971,8 @@ void ivas_dirac_param_est_enc_fx( const Word16 hodirac_flag, /* Q0 */ const Word16 nchan_fb_in, /* Q0 */ Word16 *mono_frame_count, /* Q0 */ - Word16 *dirac_mono_flag /* Q0 */ -) + Word16 *dirac_mono_flag, /* Q0 */ + const Word16 shift ) { Word16 i, j, k, d, ts, index, l_ts, num_freq_bands; Word16 band_m_idx, block_m_idx; @@ -990,7 +994,7 @@ void ivas_dirac_param_est_enc_fx( Word32 diffuseness_vector_fx[DIRAC_MAX_NBANDS]; Word16 diffuseness_vector_q; Word32 renormalization_factor_fx[DIRAC_MAX_NBANDS]; - Word16 renormalization_factor_exp; + Word16 renormalization_factor_exp[DIRAC_MAX_NBANDS]; Word32 renormalization_factor_diff_fx[DIRAC_MAX_NBANDS]; Word16 renormalization_factor_diff_exp[DIRAC_MAX_NBANDS]; Word32 norm_tmp_fx; @@ -1072,11 +1076,20 @@ void ivas_dirac_param_est_enc_fx( move16(); set32_fx( renormalization_factor_fx, EPSILON_FX, hDirAC->hConfig->nbands ); - renormalization_factor_exp = 0; - move16(); + set16_fx( renormalization_factor_exp, 0, hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[0][block_m_idx], hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[1][block_m_idx], hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[2][block_m_idx], hDirAC->hConfig->nbands ); + Word64 dir[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; + Word16 direction_vector_exp_tmp[DIRAC_NUM_DIMS][MAX_PARAM_SPATIAL_SUBFRAMES][DIRAC_MAX_NBANDS] = { 0 }; + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + set64_fx( dir[i], 0, DIRAC_MAX_NBANDS ); + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + set16_fx( direction_vector_exp_tmp[i][j], 0, DIRAC_MAX_NBANDS ); + } + } hDirAC->direction_vector_m_exp[block_m_idx] = 0; move16(); @@ -1084,8 +1097,17 @@ void ivas_dirac_param_est_enc_fx( { IF( hDirAC->hFbMixer ) { + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( pcm_in_fx[i], input_frame, shift ); // Q:Qx+shift + scale_sig32( hDirAC->hFbMixer->ppFilterbank_prior_input_fx[i], hDirAC->hFbMixer->fb_cfg->prior_input_length, shift ); // Q:Qx+shift + } ivas_fb_mixer_get_windowed_fr_fx( hDirAC->hFbMixer, pcm_in_fx, p_Cldfb_RealBuffer_fx, p_Cldfb_ImagBuffer_fx, l_ts, l_ts, hDirAC->hFbMixer->fb_cfg->num_in_chans, 0 ); - + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( pcm_in_fx[i], input_frame, negate( shift ) ); // Q:Qx + scale_sig32( hDirAC->hFbMixer->ppFilterbank_prior_input_fx[i], hDirAC->hFbMixer->fb_cfg->prior_input_length, negate( shift ) ); // Q:Qx + } ivas_fb_mixer_update_prior_input_fx( hDirAC->hFbMixer, pcm_in_fx, l_ts, hDirAC->hFbMixer->fb_cfg->num_in_chans ); FOR( i = 0; i < nchan_fb_in; i++ ) @@ -1251,8 +1273,6 @@ void ivas_dirac_param_est_enc_fx( ene_secs_exp ); } - const Word16 gbits = 4; // 4 guard bits - move16(); IF( hodirac_flag ) { FOR( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) @@ -1267,18 +1287,44 @@ void ivas_dirac_param_est_enc_fx( } ELSE { + norm_tmp_exp = add( reference_power_exp, 1 ); + FOR( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) { Word32 tmp_diff = L_shr( diffuseness_vector_fx[band_m_idx], sub( diffuseness_vector_q, 30 ) ); // diffueseness_vector_q -> Q30 norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, tmp_diff ) ); - hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), gbits ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + dir[0][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ); + move64(); + dir[1][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ); + move64(); + dir[2][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ); + move64(); + Word16 norm = 62; + move16(); + IF( dir[0][band_m_idx] != 0 ) + { + norm = W_norm( dir[0][band_m_idx] ); + } + IF( dir[1][band_m_idx] != 0 ) + { + norm = s_min( norm, W_norm( dir[1][band_m_idx] ) ); + } + IF( dir[2][band_m_idx] != 0 ) + { + norm = s_min( norm, W_norm( dir[2][band_m_idx] ) ); + } + Word32 tmp = W_extract_h( W_shl( dir[0][band_m_idx], norm ) ); + Word16 tmp_e = sub( Q31, add( sub( direction_vector_q, norm_tmp_exp ), sub( norm, 0 ) ) ); + hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], direction_vector_exp_tmp[0][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[0][block_m_idx][band_m_idx] ); move32(); - hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), gbits ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + tmp = W_extract_h( W_shl( dir[1][band_m_idx], norm ) ); + hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], direction_vector_exp_tmp[1][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[1][block_m_idx][band_m_idx] ); move32(); - hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), gbits ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + tmp = W_extract_h( W_shl( dir[2][band_m_idx], norm ) ); + hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], direction_vector_exp_tmp[2][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[2][block_m_idx][band_m_idx] ); move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], L_shr( norm_tmp_fx, gbits ) ); /* exp(norm_tmp_exp + gbits) */ + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[band_m_idx], norm_tmp_fx, norm_tmp_exp, &renormalization_factor_exp[band_m_idx] ); /* exp(norm_tmp_exp + gbits) */ move32(); hDirAC->diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->diffuseness_m_fx[band_m_idx], hDirAC->diffuseness_m_exp[band_m_idx], Mpy_32_32( reference_power_fx[ts][band_m_idx], tmp_diff ), add( reference_power_exp, 1 ), &hDirAC->diffuseness_m_exp[band_m_idx] ); /* exp(hDirAC->diffuseness_m_exp) */ @@ -1287,10 +1333,6 @@ void ivas_dirac_param_est_enc_fx( reference_power_fx[ts][band_m_idx], reference_power_exp, &renormalization_factor_diff_exp[band_m_idx] ); /* exp(renormalization_factor_diff_exp) */ move32(); } - norm_tmp_exp = add( reference_power_exp, 1 ); - hDirAC->direction_vector_m_exp[block_m_idx] = add( norm_tmp_exp, add( sub( 31, direction_vector_q ), gbits ) ); - move32(); - renormalization_factor_exp = add( norm_tmp_exp, gbits ); } } @@ -1298,41 +1340,48 @@ void ivas_dirac_param_est_enc_fx( { FOR( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) { - renormalization_factor_fx[band_m_idx] = EPSILON_FX; - move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + Word16 tmp_e = shl( direction_vector_exp_tmp[0][block_m_idx][block_m_idx], 1 ); + + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[block_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[block_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + tmp_e = shl( direction_vector_exp_tmp[1][block_m_idx][block_m_idx], 1 ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[block_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[block_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ) ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ + tmp_e = shl( direction_vector_exp_tmp[2][block_m_idx][block_m_idx], 1 ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[block_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[block_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_exp = shl( hDirAC->direction_vector_m_exp[block_m_idx], 1 ); // 2 * direction_vector_m_exp - renormalization_factor_fx[band_m_idx] = Sqrt32( renormalization_factor_fx[band_m_idx], &renormalization_factor_exp ); + IF( renormalization_factor_fx[band_m_idx] == 0 ) + { + renormalization_factor_fx[band_m_idx] = EPSILON_FX; + move32(); + renormalization_factor_exp[block_m_idx] = 0; + move16(); + } + renormalization_factor_fx[band_m_idx] = Sqrt32( renormalization_factor_fx[band_m_idx], &renormalization_factor_exp[block_m_idx] ); move32(); IF( GT_32( renormalization_factor_fx[band_m_idx], EPSILON_FX ) ) { - Word16 tmp_e; Word32 tmp32; tmp32 = hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx]; move32(); tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[0][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 move32(); tmp32 = hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx]; // Q30 move32(); tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[1][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 move32(); tmp32 = hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx]; // Q30 move32(); tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[2][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 move32(); } @@ -1345,8 +1394,6 @@ void ivas_dirac_param_est_enc_fx( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0; move32(); } - hDirAC->direction_vector_m_exp[block_m_idx] = 1; - move16(); /* save the elevation and azimuth values to be used later by the ivas_dirac_QuantizeParameters function */ FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) @@ -1367,6 +1414,8 @@ void ivas_dirac_param_est_enc_fx( &q_direction->band_data[band_m_idx].azimuth_fx[block_m_idx], &q_direction->band_data[band_m_idx].elevation_fx[block_m_idx] ); } + hDirAC->direction_vector_m_exp[block_m_idx] = 1; + move16(); } /* Sectors */ diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 4d032cee87854a5cfce40268a34bff9b2700ab87..8c194bed19057993fb0cd12f0e8f4419bf8bc201 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -284,9 +284,6 @@ ivas_error ivas_mct_enc_fx( Word16 q_spec = Q31; Word16 q_origSpec = Q31; - Word16 q_com = Q31, q_com_spec = Q31; - move16(); - move16(); move16(); move16(); Word16 length, ch, nCPE; @@ -303,6 +300,7 @@ ivas_error ivas_mct_enc_fx( { FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { + Word16 norm; IF( EQ_32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { CONTINUE; @@ -324,24 +322,14 @@ ivas_error ivas_mct_enc_fx( { length = add( length, idiv1616( length, 4 ) ); } - - FOR( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) - { - IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) - { - q_spec = s_min( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ); - q_com_spec = s_min( q_com_spec, L_norm_arr( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length ) ); - } - } IF( hMCT->p_orig_spectrum_long_fx[cpe_id][ch] ) { - q_origSpec = s_min( q_origSpec, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ); - q_com = s_min( q_com, L_norm_arr( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k ) ); + norm = L_norm_arr( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k ); + q_origSpec = s_min( q_origSpec, add( norm, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ) ); } } } - q_spec = sub( add( q_spec, q_com_spec ), 1 ); - q_origSpec = sub( add( q_origSpec, q_com ), 1 ); + q_origSpec = sub( q_origSpec, 1 ); FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { @@ -361,73 +349,39 @@ ivas_error ivas_mct_enc_fx( } hMCT->q_orig_spectrum_long_com = q_origSpec; move16(); + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - // length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); - - IF( EQ_16( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + IF( EQ_16( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core, TCX_20 ) ) { length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX; move16(); } ELSE { - length = idiv1616( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX, NB_DIV ); // st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / NB_DIV + length = idiv1616( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX, NB_DIV ); } - IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) { length = add( length, idiv1616( length, 4 ) ); } + Word16 norm = L_norm_arr( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_fx, N_MAX ); + q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); + q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); FOR( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) { IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) { - Scale_sig32( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length, sub( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); // q_spec - hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] = q_spec; - move16(); + norm = L_norm_arr( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length ); + q_spec = s_min( q_spec, add( norm, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); } } } } - Encoder_State *sts_tmp[MCT_MAX_CHANNELS]; - Encoder_State *st; - Word16 i; - nCPE = shr( hMCT->nchan_out_woLFE, 1 ); // nChannels / CPE_CHANNELS - - /*in case of odd number of channels*/ - IF( NE_16( ( nCPE * CPE_CHANNELS ), hMCT->nchan_out_woLFE ) ) - { - nCPE = add( nCPE, 1 ); - } - FOR( ( cpe_id = 0, i = 0 ); cpe_id < nCPE; cpe_id++ ) - { - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts_tmp[i] = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]; - IF( EQ_32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - i = add( i, 1 ); - CONTINUE; - } - i = add( i, 1 ); - } - } - - FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) - { - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - Word16 norm = L_norm_arr( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_fx, N_MAX ); - q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); - q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); - } - } - FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) @@ -447,6 +401,21 @@ ivas_error ivas_mct_enc_fx( move16(); st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[1] = sub( 31, q_spec ); move16(); + + IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) + { + length = add( length, idiv1616( length, 4 ) ); + } + + FOR( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) + { + Scale_sig32( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length, sub( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); // q_spec + hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] = q_spec; + move16(); + } + } } } @@ -496,26 +465,6 @@ ivas_error ivas_mct_enc_fx( q_spec = 31; move16(); - FOR( ch = 0; ch < hMCT->nchan_out_woLFE; ch++ ) - { - // length = sts_tmp[ch]->hTcxEnc->L_frameTCX / ( ( sts_tmp[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); - - IF( EQ_16( sts_tmp[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - length = sts_tmp[ch]->hTcxEnc->L_frameTCX; - move16(); - } - ELSE - { - length = idiv1616( sts_tmp[ch]->hTcxEnc->L_frameTCX, NB_DIV ); // st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / NB_DIV - } - - IF( sts_tmp[ch]->last_core == ACELP_CORE ) - { - length = add( length, idiv1616( length, 4 ) ); - } - } - /* Spectrum quantization and coding */ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) @@ -527,21 +476,8 @@ ivas_error ivas_mct_enc_fx( hCPE->hCoreCoder[0]->hBstr->ind_list = st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->ind_list + st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->nb_ind_tot; } - Encoder_State /**st,*/ **sts; - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts = hCPE->hCoreCoder; - st = sts[ch]; - } - ivas_mdct_quant_coder_fx( hCPE, hMCT->tnsBits[cpe_id], hMCT->tnsSize[cpe_id], hMCT->p_param[cpe_id], 1 ); - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts = hCPE->hCoreCoder; - st = sts[ch]; - } - /* update input samples buffer (as done in ivas_cpe_enc() for other than MCT coding) */ FOR( n = 0; n < CPE_CHANNELS; n++ ) { @@ -550,8 +486,7 @@ ivas_error ivas_mct_enc_fx( move16(); /* common encoder updates */ - st = hCPE->hCoreCoder[n]; - updt_enc_common_ivas_fx( st, Q_new_out[cpe_id][n] ); + updt_enc_common_ivas_fx( hCPE->hCoreCoder[n], Q_new_out[cpe_id][n] ); } } diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index a366d86fba24b7fb7e3ac041f02f6e4f7344d7be..632b921260cbf123564756b0cf0a32e84be4a1b4 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -766,11 +766,15 @@ static ivas_error ivas_spar_enc_process_fx( } /* prepare Parameter MDFT analysis */ + Word16 shift = Q31; + move16(); FOR( i = 0; i < nchan_fb_in; i++ ) { ppIn_FR_real_fx[i] = p_pcm_tmp_fx[i]; ppIn_FR_imag_fx[i] = p_pcm_tmp_fx[i] + input_frame; p_pcm_tmp_fx[i] = data_fx[i]; + shift = s_min( shift, L_norm_arr( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length ) ); + shift = s_min( shift, L_norm_arr( data_fx[i], input_frame ) ); } l_ts = idiv1616( input_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); @@ -778,8 +782,17 @@ static ivas_error ivas_spar_enc_process_fx( Word16 gb = find_guarded_bits_fx( l_ts ); FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( data_fx[i], input_frame, shift ); // Q:q_data+shift + scale_sig32( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length, shift ); // Q:q_data+shift + } ivas_fb_mixer_get_windowed_fr_fx( hSpar->hFbMixer, p_pcm_tmp_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, l_ts, l_ts, nchan_fb_in, gb ); - + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( data_fx[i], input_frame, negate( shift ) ); // Q:q_data + scale_sig32( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length, negate( shift ) ); // Q:q_data + } ivas_fb_mixer_update_prior_input_fx( hSpar->hFbMixer, p_pcm_tmp_fx, l_ts, nchan_fb_in ); FOR( i = 0; i < nchan_fb_in; i++ ) @@ -818,7 +831,7 @@ static ivas_error ivas_spar_enc_process_fx( /*Finding max possible q*/ Word16 pp_fr_q; - pp_fr_q = sub( q_data, gb ); + pp_fr_q = sub( add( q_data, shift ), gb ); Word16 re_q = MAX_16, im_q = MAX_16, FR_q; move16(); move16(); @@ -835,7 +848,7 @@ static ivas_error ivas_spar_enc_process_fx( } pp_fr_q = add( FR_q, pp_fr_q ); - IF( NE_32( ( error = ivas_dirac_enc_fx( st_ivas->hDirAC, hQMetaData, hMetaData, data_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, pp_fr_q, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_dirac_enc_fx( st_ivas->hDirAC, hQMetaData, hMetaData, data_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, pp_fr_q, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag, shift ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 181c668256f8f41d80466ac46cc66a1b63f04659..e7bb62f931f49a3f989436040c65d0fd2a63c294 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -142,6 +142,79 @@ static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *p *pbIsAttackPresent = bIsAttackPresent; } +static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) +{ + Word16 i; + Word16 bIsAttackPresent, attackIndex; + Word16 attackRatioThreshold_1_5; + + (void) nPastSubblocks; + (void) nSubblocks; + assert( nSubblocks >= NSUBBLOCKS ); + assert( nPastSubblocks >= 2 ); + + /* attackRatioThreshold_1_5 = attackRatioThreshold * 1.5, exponent is ATTACKTHRESHOLD_E+1 */ + attackRatioThreshold_1_5 = add( shr( attackRatioThreshold, 2 ), shr( attackRatioThreshold, 1 ) ); + + move16(); + move16(); + bIsAttackPresent = FALSE; + attackIndex = -1; + /* Search for the last attack in the subblocks */ + if ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) + { + move16(); + bIsAttackPresent = TRUE; + } + + FOR( i = 0; i < NSUBBLOCKS; i++ ) + { + IF( GT_32( L_shr( pSubblockNrg[i], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[i], attackRatioThreshold ) ) ) + { + if ( i < 6 ) + { + move16(); + bIsAttackPresent = TRUE; + } + + if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + } + } + ELSE /* no attack, but set index anyway in case of strong energy increase */ + { + IF( s_and( ( (Word16) GT_32( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 1 )], attackRatioThreshold_1_5 ) ) ), + ( L_sub( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 2 )], attackRatioThreshold_1_5 ) ) > 0 ) ) ) + { + + if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + } + } + } + } + /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */ + if ( EQ_16( attackIndex, 4 ) ) + { + move16(); + attackIndex = 7; + } + if ( EQ_16( attackIndex, 5 ) ) + { + move16(); + attackIndex = 6; + } + + move16(); + move16(); + *pAttackIndex = attackIndex; + *pbIsAttackPresent = bIsAttackPresent; +} void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) { @@ -257,7 +330,7 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, /* Init a subblock energies buffer used for the TCX Short/Long decision. */ InitSubblockEnergies_ivas_fx( nFrameLength, nTCXDelay, &pTransientDetection->delayBuffer, &pTransientDetection->subblockEnergies ); /* Init the TCX Short/Long transient detector. */ - InitTransientDetector_ivas_fx( &pTransientDetection->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision, 17408 /*8.5f/(1<transientDetector ); + InitTransientDetector_ivas_fx( &pTransientDetection->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_ivas_fx, 17408 /*8.5f/(1<transientDetector ); /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */ IF( ext_mem_flag ) {