diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 47ce9b8710e9d246bf21389e9e5e1aff82ffd2e4..abd6865ca09c1fa0288f35ebb264e03ca43f3f43 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1063,6 +1063,11 @@ typedef enum #define IVAS_ACTIVEW_DM_F_SCALE_VLBR 0.25f #define IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN 24000 +#ifdef FIX_SBA_VANISHING_RESIDUAL +#define IVAS_SPAR_DYN_ACTIVEW_THRESH (0.0039f) +#define IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH (32.0f) +#endif + #define MAX_QUANT_STRATS 3 #define MAX_CODING_STRATS 3 #define IVAS_NUM_PROB_MODELS 4 diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index a94a92c548785667f9cff7d72d53bf681d57ea4a..070a0ff5faf42c23c46d09360719d546789afc35 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -590,14 +590,22 @@ void ivas_fb_mixer_get_windowed_fr( * * FB Mixer cross fading *-----------------------------------------------------------------------------------------*/ - -static void ivas_fb_mixer_cross_fading( - IVAS_FB_MIXER_HANDLE hFbMixer, - float **ppOut_pcm, - float *pMdft_out_old, - float *pMdft_out_new, - const int16_t ch, - const int16_t frame_len ) +#ifndef FIX_SBA_VANISHING_RESIDUAL +static +#endif + void + ivas_fb_mixer_cross_fading( + IVAS_FB_MIXER_HANDLE hFbMixer, + float **ppOut_pcm, + float *pMdft_out_old, + float *pMdft_out_new, + const int16_t ch, + const int16_t frame_len +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t cf_offset +#endif + ) { int16_t k, fade_start_offset, fade_end_offset; @@ -608,17 +616,29 @@ static void ivas_fb_mixer_cross_fading( for ( k = 0; k < fade_start_offset; k++ ) { +#ifdef FIX_SBA_VANISHING_RESIDUAL + ppOut_pcm[ch][k] = pMdft_out_old[k + cf_offset]; +#else ppOut_pcm[ch][k] = pMdft_out_old[k + frame_len]; +#endif } for ( k = fade_start_offset; k < fade_end_offset; k++ ) { +#ifdef FIX_SBA_VANISHING_RESIDUAL + ppOut_pcm[ch][k] = pMdft_out_new[k + cf_offset] * hFbMixer->pFilterbank_cross_fade[k - fade_start_offset] + pMdft_out_old[k + cf_offset] * ( 1.0f - hFbMixer->pFilterbank_cross_fade[k - fade_start_offset] ); +#else ppOut_pcm[ch][k] = pMdft_out_new[k + frame_len] * hFbMixer->pFilterbank_cross_fade[k - fade_start_offset] + pMdft_out_old[k + frame_len] * ( 1.0f - hFbMixer->pFilterbank_cross_fade[k - fade_start_offset] ); +#endif } for ( k = fade_end_offset; k < frame_len; k++ ) { +#ifdef FIX_SBA_VANISHING_RESIDUAL + ppOut_pcm[ch][k] = pMdft_out_new[k + cf_offset]; +#else ppOut_pcm[ch][k] = pMdft_out_new[k + frame_len]; +#endif } } else @@ -627,7 +647,11 @@ static void ivas_fb_mixer_cross_fading( for ( k = 0; k < frame_len; k++ ) { +#ifdef FIX_SBA_VANISHING_RESIDUAL + ppOut_pcm[ch][k] = pMdft_out_new[k + cf_offset]; +#else ppOut_pcm[ch][k] = pMdft_out_new[k + frame_len]; +#endif } } @@ -717,7 +741,12 @@ void ivas_fb_mixer_process( ivas_imdft( pOut_fr_re, pOut_fr_im, pMdft_out[hist], frame_len ); } - ivas_fb_mixer_cross_fading( hFbMixer, ppOut_pcm, pMdft_out[0], pMdft_out[1], ch, frame_len ); + ivas_fb_mixer_cross_fading( hFbMixer, ppOut_pcm, pMdft_out[0], pMdft_out[1], ch, frame_len +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + frame_len +#endif + ); } return; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index d6efef32df9a50950a6b6ccf6af083252d175b88..315970a6c29cea9f48b08e5f8919159f8bba99f3 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -114,6 +114,18 @@ ivas_error ivas_spar_md_enc_init const int16_t sba_order /* i : Ambisonic (SBA) order */ ); +#ifdef FIX_SBA_VANISHING_RESIDUAL +int16_t ivas_spar_get_activeW_flag( + ivas_enc_cov_handler_state_t *hCovEnc, + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + const int16_t dtx_vad, + const int16_t nchan_inp, + const int16_t nchan_transport, + int16_t *res_ind, + const int16_t *dmx_order); +#endif + ivas_error ivas_sba_enc_reconfigure( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); @@ -4390,8 +4402,13 @@ ivas_error ivas_spar_md_enc_process( const int16_t nchan_inp, const int16_t sba_order, /* i : Ambisonic (SBA) order */ float *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i : prior mixer_matrix */ +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag /* i : flag to indicate dynamic active W*/ +#endif #ifdef FIX_527_SBA_MONO_INPUT - ,const int16_t dirac_mono_flag + , + const int16_t dirac_mono_flag /* i : flag to indicate mono only mode in SBA*/ #endif ); @@ -4411,6 +4428,10 @@ void ivas_compute_spar_params( ivas_spar_md_t *hSparMd, float *pWscale, const int16_t from_dirac +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif ); void ivas_create_fullr_dmx_mat( @@ -4438,6 +4459,10 @@ void ivas_calc_c_p_coeffs( , const int16_t planarCP #endif +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif ); void ivas_get_spar_md_from_dirac( @@ -4456,6 +4481,10 @@ void ivas_get_spar_md_from_dirac( , const uint8_t useLowerRes, const int16_t active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif ); /*! r: number of MD subframes */ @@ -4525,7 +4554,11 @@ void ivas_spar_to_dirac( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t dtx_vad, /* i : DTX frame flag */ const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bw /* i : band joining factor */ + const int16_t bw /* i : band joining factor */ +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag /* i : dynamic active W flag */ +#endif ); void ivas_spar_update_md_hist( @@ -4585,6 +4618,14 @@ void ivas_enc_cov_handler_process( const int16_t dtx_vad, const int16_t transient_det[2], const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + int16_t *res_ind, + const int16_t *remix_order, + int16_t *dyn_active_w_flag, + const int16_t nchan_transport, + const int16_t is_sba +#endif ); ivas_error ivas_spar_covar_smooth_enc_open( @@ -5935,6 +5976,18 @@ void ivas_fb_mixer_get_in_out_mapping( int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping */ ); +#ifdef FIX_SBA_VANISHING_RESIDUAL +void ivas_fb_mixer_cross_fading( + IVAS_FB_MIXER_HANDLE hFbMixer, + float **ppOut_pcm, + float *pMdft_out_old, + float *pMdft_out_new, + const int16_t ch, + const int16_t frame_len, + const int16_t cf_offset + ); +#endif + /*! r: number of spectral bands */ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index d597d133fdb1338edae6d76e1181f0e22c3396f0..fa462313d6beb05395520c7048e986171c8a669a 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -77,11 +77,22 @@ *------------------------------------------------------------------------------------------*/ -static void ivas_get_pred_coeffs( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], const int16_t in_chans, const int16_t start_band, const int16_t end_band, const int16_t active_w, const int16_t active_w_vlbr, const int16_t dtx_vad, const int16_t from_dirac ); +static void ivas_get_pred_coeffs( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], const int16_t in_chans, const int16_t start_band, const int16_t end_band, const int16_t active_w, const int16_t active_w_vlbr, const int16_t dtx_vad, const int16_t from_dirac +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag, + const int16_t res_ind +#endif +); static void ivas_reorder_array( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS], const int16_t in_chans, const int16_t order[IVAS_SPAR_MAX_CH], float ***mixer_mat, const int16_t start_band, const int16_t end_band ); -static void ivas_get_Wscaling_factor( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ***mixer_mat, const int16_t start_band, const int16_t end_band, const int16_t dtx_vad, const int16_t num_ch, const int16_t *pNum_dmx, const int16_t bands_bw, const int16_t active_w, const int16_t active_w_vlbr, float *pWscale ); +static void ivas_get_Wscaling_factor( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ***mixer_mat, const int16_t start_band, const int16_t end_band, const int16_t dtx_vad, const int16_t num_ch, const int16_t *pNum_dmx, const int16_t bands_bw, const int16_t active_w, const int16_t active_w_vlbr, float *pWscale +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +); static void ivas_calc_post_pred_per_band( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float ***mixer_mat, const int16_t num_ch, const int16_t num_dmx, const int16_t band_idx, float postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] ); @@ -462,7 +473,13 @@ static void ivas_get_pred_coeffs( const int16_t active_w, const int16_t active_w_vlbr, const int16_t dtx_vad, - const int16_t from_dirac ) + const int16_t from_dirac +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag, + const int16_t res_ind +#endif +) { int16_t i, j, k, b; float abs_value; @@ -517,7 +534,21 @@ static void ivas_get_pred_coeffs( float real[IVAS_SPAR_MAX_CH - 1], dm_beta_re = 0, dm_g[IVAS_MAX_NUM_BANDS]; float dm_f_local, dm_w, dm_y, DM_F[IVAS_MAX_NUM_BANDS]; float num_f, den_f, passive_g; +#ifdef FIX_SBA_VANISHING_RESIDUAL + float activew_quad_thresh, g_th_sq; + if ( dyn_active_w_flag == 1 ) + { + activew_quad_thresh = 1.0f; + } + else + { + activew_quad_thresh = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH; + } + g_th_sq = activew_quad_thresh * activew_quad_thresh; +#else float g_th_sq = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH * IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH; +#endif + set_zero( dm_alpha, IVAS_MAX_NUM_BANDS ); @@ -580,7 +611,26 @@ static void ivas_get_pred_coeffs( den_f = max( dm_w, 1e-20f ); passive_g = dm_alpha[b] / den_f; +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( dyn_active_w_flag == 1 ) + { + dm_alpha[b] = 0.0f; + dm_w = 0.0f; + for ( i = 0; i < pred_dim; i++ ) + { + dm_v_re[i][b] = 0.0f; + } + dm_v_re[res_ind - 1][b] = 1.0f; + passive_g = activew_quad_thresh; + } +#endif + + +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( passive_g < activew_quad_thresh ) +#else if ( passive_g < IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH ) +#endif { /*linear activeW*/ dm_y = 0; @@ -604,7 +654,13 @@ static void ivas_get_pred_coeffs( float sqrt_val; /* quadratic activeW */ + +#ifdef FIX_SBA_VANISHING_RESIDUAL + num_f = ( dm_beta_re - ( 2 * dm_alpha[b] * activew_quad_thresh ) ); +#else num_f = ( dm_beta_re - ( 2 * dm_alpha[b] * IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH ) ); +#endif + sqrt_val = 4 * dm_alpha[b] * dm_alpha[b] * g_th_sq; sqrt_val += dm_beta_re * dm_beta_re; sqrt_val -= 4 * dm_beta_re * g_th_sq * dm_w; @@ -613,7 +669,11 @@ static void ivas_get_pred_coeffs( den_f = 2 * dm_beta_re * g_th_sq; den_f = max( den_f, 1e-20f ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + dm_g[b] = activew_quad_thresh; +#else dm_g[b] = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH; +#endif DM_F[b] = ( dm_g[b] * num_f ) / den_f; } } @@ -651,7 +711,12 @@ static void ivas_get_Wscaling_factor( const int16_t bands_bw, const int16_t active_w, const int16_t active_w_vlbr, - float *pWscale ) + float *pWscale +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +) { int16_t b, ch; float dm_f_local, abs_val; @@ -670,7 +735,11 @@ static void ivas_get_Wscaling_factor( { pWscale[b] = 1; +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( ( active_w == 1 ) && ( dyn_active_w_flag == 0 ) ) +#else if ( ( active_w == 1 ) && ( pNum_dmx[b * bands_bw] == 1 ) ) +#endif { float Gw_sq, g_sq = 0; @@ -1260,9 +1329,13 @@ void ivas_calc_c_p_coeffs( , const int16_t planarCP #endif +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif ) { -#ifndef FIX_280_PLANAR_CP +#ifdef FIX_SBA_VANISHING_RESIDUAL int16_t i, j; #endif float postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; @@ -1276,36 +1349,29 @@ void ivas_calc_c_p_coeffs( ivas_calc_c_coeffs_per_band( pSparMd, i_ts, postpred_cov_re, num_ch, num_dmx, band_idx, dtx_vad ); } -#ifndef FIX_280_PLANAR_CP - if ( planarCP ) +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( dyn_active_w_flag ) { for ( i = 0; i < num_ch - num_dmx; i++ ) { - if ( !keep_planar[i] ) + for ( j = 0; j < num_dmx - 1; j++ ) { - for ( j = 0; j < num_dmx - 1; j++ ) - { - pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].C_re[i][j] = 0.0f; - } + pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].C_re[i][j] = 0.0f; } } } #endif - if ( compute_p_flag == 1 ) { ivas_calc_p_coeffs_per_band( pSparMd, i_ts, postpred_cov_re, num_ch, dtx_vad, num_dmx, band_idx ); } -#ifndef FIX_280_PLANAR_CP - if ( planarCP ) +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( dyn_active_w_flag ) { for ( i = num_dmx; i < num_ch; i++ ) { - if ( !keep_planar[i - num_dmx] ) - { - pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re[i - num_dmx] = 0; - } + pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re[i - num_dmx] = 0; } } #endif @@ -1560,14 +1626,25 @@ void ivas_compute_spar_params( ivas_spar_md_com_cfg *hSparCfg, ivas_spar_md_t *hSparMd, float *pWscale, - const int16_t from_dirac ) + const int16_t from_dirac +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +) { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; int16_t b, i, ndm; ivas_get_pred_coeffs( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, - dtx_vad, from_dirac ); + dtx_vad, from_dirac +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag, + hSparMd->res_ind +#endif + ); #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n Prediction Coefficients:\n"); @@ -1601,7 +1678,12 @@ void ivas_compute_spar_params( ivas_get_Wscaling_factor( cov_real, pred_coeffs_re, mixer_mat, start_band, end_band, dtx_vad, num_ch, hSparCfg->num_dmx_chans_per_band, bands_bw, active_w, active_w_vlbr, - pWscale ); + pWscale +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); for ( b = start_band; b < end_band; b++ ) { @@ -1624,9 +1706,19 @@ void ivas_compute_spar_params( if ( ndm != num_ch ) { #ifndef FIX_280_PLANAR_CP - ivas_calc_c_p_coeffs( hSparMd, cov_real, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1, 0 ); + ivas_calc_c_p_coeffs( hSparMd, cov_real, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1, 0 +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); #else - ivas_calc_c_p_coeffs( hSparMd, cov_real, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1 ); + ivas_calc_c_p_coeffs( hSparMd, cov_real, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1 +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); #endif #ifdef SPAR_HOA_DBG @@ -1677,7 +1769,12 @@ void ivas_get_spar_md_from_dirac( const int16_t dtx_vad, float Wscale_d[IVAS_MAX_NUM_BANDS], const uint8_t useLowerRes, - const int16_t active_w_vlbr ) + const int16_t active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +) { int16_t num_ch, band, i, j; int16_t block, ch; @@ -1691,6 +1788,10 @@ void ivas_get_spar_md_from_dirac( float **ppMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH]; float *pMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3; +#ifdef FIX_SBA_VANISHING_RESIDUAL + int16_t active_w; +#endif + int16_t ndm, foa_ch, hoa2_ch; float P_dir_fact[IVAS_SPAR_MAX_CH - 1]; const int16_t *remix_order; @@ -1852,7 +1953,6 @@ void ivas_get_spar_md_from_dirac( en_ratio_fac = ( 1.0f - diffuseness[band] ); - for ( i = 0; i < num_ch; i++ ) { for ( j = 0; j < num_ch; j++ ) @@ -1948,8 +2048,23 @@ void ivas_get_spar_md_from_dirac( } #endif +#ifdef FIX_SBA_VANISHING_RESIDUAL + active_w = ( dyn_active_w_flag == 1 ) || ( hSpar_md_cfg->active_w == 1 ); +#endif ivas_compute_spar_params( pCov_real, dm_fv_re, i_ts, ppMixer_mat, start_band, end_band, dtx_vad, - num_ch, 1, hSpar_md_cfg->active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale, 1 ); + num_ch, 1, +#ifdef FIX_SBA_VANISHING_RESIDUAL + active_w, +#else + hSpar_md_cfg->active_w, +#endif + active_w_vlbr, + hSpar_md_cfg, hSpar_md, Wscale, 1 +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); if ( mixer_mat != NULL ) { diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 04a8c5ed4b7200b25a3b8b9fb682515b166723a3..975fb77a7150d49c77c2a4a3ace871d751da00d8 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -229,6 +229,10 @@ typedef struct ivas_spar_md_t int16_t dtx_vad; float en_ratio_slow[IVAS_MAX_NUM_BANDS]; float ref_pow_slow[IVAS_MAX_NUM_BANDS]; +#ifdef FIX_SBA_VANISHING_RESIDUAL + int16_t res_ind; + int16_t prior_dyn_active_w_flag; +#endif } ivas_spar_md_t; typedef struct ivas_spar_md_prev_t diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index 26a75598c99f3f47db0653b567def4c31d14797c..0bf8ff7170246fa3134a0f771f531a61b3d36660 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -223,6 +223,7 @@ #define MASA_AND_OBJECTS /* Nokia: Combination of MASA and objects */ +#define FIX_SBA_VANISHING_RESIDUAL /*Dlb : Fix for vanishing residual cases when W channel is 0*/ #define FIX_527_SBA_MONO_INPUT /* Dlb : Fix for mono content in a HOA input format */ #define FIX_653_BUG_IN_SKIP_MATRIX /* Dlb: fix for issue #653, bug in the ivas_spar_get_skip_mat function*/ #define FIX_663_PARAM_ISM_EXT /* FhG: Issue 663: ParamISM EXT output improvement */ diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 5f8a65e7ac8996ca8743eea34ec5d6f7833f30f3..eaf08a8de82753f131db0b3d2962db8d47e79496 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -178,7 +178,9 @@ ivas_error ivas_spar_dec_open( } } hSpar->i_subframe = 0; - +#ifdef FIX_SBA_VANISHING_RESIDUAL + hSpar->AGC_flag = 0; +#endif /*-----------------------------------------------------------------* * Configuration - set SPAR high-level parameters *-----------------------------------------------------------------*/ @@ -787,7 +789,14 @@ static void ivas_spar_dec_MD( if ( ivas_total_brate > IVAS_SID_5k2 && !bfi && hSpar->hMdDec->dtx_vad ) { +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) + { + hSpar->AGC_flag = get_next_indice( st0, 1 ); + } +#else hSpar->AGC_flag = get_next_indice( st0, 1 ); +#endif ivas_agc_read_bits( hSpar->hAgcDec, st0, hSpar->hMdDec->spar_md_cfg.nchan_transport, hSpar->AGC_flag ); } diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 62af38c63c0026c99d3055cf51a6bf702f8797f7..1a9a87cddf3ef1be2b5095a29b69cb95ecc6ff5a 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -62,7 +62,12 @@ static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0 * Static functions declaration *------------------------------------------------------------------------------------------*/ -static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t numch_out, const int16_t active_w_vlbr ); +static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t numch_out, const int16_t active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +); #ifndef FIX_280_PLANAR_CP static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP, const int16_t strat, const int32_t ivas_total_brate ); @@ -805,6 +810,9 @@ void ivas_spar_md_dec_process( ivas_spar_md_dec_state_t *hMdDec; int16_t num_md_chs; int16_t num_md_sub_frames; +#ifdef FIX_SBA_VANISHING_RESIDUAL + int16_t dyn_active_w_flag; +#endif int16_t active_w_vlbr; hMdDec = st_ivas->hSpar->hMdDec; @@ -820,6 +828,35 @@ void ivas_spar_md_dec_process( #endif ); + +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( hMdDec->spar_md_cfg.nchan_transport > 1 && hMdDec->spar_md_cfg.nchan_transport <= 3 ) + { + hMdDec->spar_md.res_ind = 0; + dyn_active_w_flag = get_next_indice( st0, 1 ); + if ( dyn_active_w_flag == 1 ) + { + if ( hMdDec->spar_md_cfg.nchan_transport == 2 ) + { + hMdDec->spar_md.res_ind = get_next_indice( st0, 1 ); + hMdDec->spar_md.res_ind += hMdDec->spar_md_cfg.nchan_transport; + } + else if ( hMdDec->spar_md_cfg.nchan_transport == 3 ) + { + hMdDec->spar_md.res_ind = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order][hMdDec->spar_md_cfg.nchan_transport]; + } + } + } + else + { + dyn_active_w_flag = 0; + if ( hMdDec->spar_md_cfg.nchan_transport == FOA_CHANNELS ) + { + get_next_indice( st0, 1 ); + } + } +#endif + ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, #ifndef FIX_280_PLANAR_CP ivas_spar_br_table_consts[hMdDec->table_idx].usePlanarCoeff, @@ -970,7 +1007,12 @@ void ivas_spar_md_dec_process( /* SPAR to DirAC conversion */ if ( hMdDec->spar_hoa_dirac2spar_md_flag == 1 ) { - ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out, bw ); + ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out, bw +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); } /* set correct number of bands*/ @@ -1128,7 +1170,15 @@ void ivas_spar_md_dec_process( } } - ivas_get_spar_matrices( hMdDec, num_bands_out, num_md_sub_frames, bw, dtx_vad, nB, num_md_chs, active_w_vlbr ); + ivas_get_spar_matrices( hMdDec, num_bands_out, num_md_sub_frames, bw, dtx_vad, nB, + num_md_chs, + active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + + ); #ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS { @@ -1439,7 +1489,12 @@ static void ivas_get_spar_matrices( const int16_t dtx_vad, const int16_t nB, const int16_t numch_out, - const int16_t active_w_vlbr ) + const int16_t active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif +) { int16_t num_bands, dmx_ch, split_band; int16_t i, j, k, m, b, i_ts, active_w; @@ -1484,7 +1539,12 @@ static void ivas_get_spar_matrices( { num_bands = num_bands >> 1; } +#ifdef FIX_SBA_VANISHING_RESIDUAL + active_w = ( dyn_active_w_flag == 1 ) || ( hMdDec->spar_md_cfg.active_w == 1 ); +#else active_w = hMdDec->spar_md_cfg.active_w; +#endif + active_w_dm_fac = ( dtx_vad == 0 ) ? IVAS_ACTIVEW_DM_F_SCALE_DTX : ( ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_SCALE_VLBR : IVAS_ACTIVEW_DM_F_SCALE ); for ( i_ts = 0; i_ts < n_ts; i_ts++ ) { @@ -1538,6 +1598,13 @@ static void ivas_get_spar_matrices( IVAS_RMULT_FLOAT( tmp_C2_re[0][3], tmp_C1_re[3][0], re ); tmp_dm_re[0][0] += re; +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( dyn_active_w_flag == 1 ) + { + tmp_dm_re[0][0] *= IVAS_SPAR_DYN_ACTIVEW_THRESH; + } +#endif + tmp_dm_re[0][1] = tmp_C2_re[0][1]; tmp_dm_re[0][2] = tmp_C2_re[0][2]; @@ -3092,6 +3159,12 @@ static void ivas_parse_parameter_bitstream_dtx( sid_bits_len = st0->next_bit_pos - sid_bits_len; zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; assert( zero_pad_bits >= 0 ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( num_dmx_per_band[0] == 2 ) + { + zero_pad_bits -= 1; + } +#endif for ( j = 0; j < zero_pad_bits; j++ ) { get_next_indice( st0, 1 ); @@ -3155,8 +3228,13 @@ void ivas_spar_to_dirac( Decoder_Struct *st_ivas, ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t dtx_vad, /* i : DTX frame flag */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bw /* i : band joining factor */ + const int16_t num_bands_out /* i : number of output bands */ + , + const int16_t bw /* i : band joining factor */ +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag +#endif ) { DIRAC_DEC_HANDLE hDirAC; @@ -3181,7 +3259,13 @@ void ivas_spar_to_dirac( int16_t enc_param_start_band; int16_t active_w_vlbr; int16_t i, num_subframes; +#ifdef FIX_SBA_VANISHING_RESIDUAL + int16_t active_w; +#endif +#ifdef FIX_SBA_VANISHING_RESIDUAL + active_w = ( dyn_active_w_flag == 1 ) || ( hMdDec->spar_md_cfg.active_w == 1 ); +#endif sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); start_band = 0; end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ) / bw; @@ -3229,8 +3313,11 @@ void ivas_spar_to_dirac( if ( st_ivas->nchan_transport == 1 ) { float w_en_norm, f_scale; - +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( active_w ) +#else if ( hMdDec->spar_md_cfg.active_w ) +#endif { if ( dtx_vad == 0 ) { @@ -3360,8 +3447,13 @@ void ivas_spar_to_dirac( /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */ if ( hMdDec->spar_md_cfg.nchan_transport > 1 ) { - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, + st_ivas->hQMetaData->useLowerRes, active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) @@ -3382,7 +3474,12 @@ void ivas_spar_to_dirac( #endif ); ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, num_md_sub_frames, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr ); + end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); #else num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; @@ -3392,7 +3489,12 @@ void ivas_spar_to_dirac( } ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, num_subframes, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr ); + end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); #endif if ( st_ivas->hQMetaData->useLowerRes && dtx_vad ) { diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index fcf2efc6c293b5e8fd24ec16342dabff6ea2e153..5b9ab2801cfb779ae0954f0bce5415f80b26c02e 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -107,6 +107,11 @@ ivas_error ivas_spar_covar_enc_open( hCovState->num_bins = (int16_t) ( input_Fs / FRAMES_PER_SEC ); hCovState->prior_dtx_present = 0; +#ifdef FIX_SBA_VANISHING_RESIDUAL + set_zero( hCovState->bb_var_lt, FOA_CHANNELS ); + hCovState->prior_var_flag = -1; +#endif + *hCovEnc = hCovState; return error; @@ -143,6 +148,119 @@ void ivas_spar_covar_enc_close( } +#ifdef FIX_SBA_VANISHING_RESIDUAL +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_get_activeW_flag() + * + * + *-----------------------------------------------------------------------------------------*/ +int16_t ivas_spar_get_activeW_flag( + ivas_enc_cov_handler_state_t *hCovEnc, + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + const int16_t dtx_vad, + const int16_t nchan_inp, + const int16_t nchan_transport, + int16_t *res_ind, + const int16_t *dmx_order ) +{ + int16_t b, ch, num_bands, num_chs, activeW_flag; + float bb_var[FOA_CHANNELS], sm_fact, side_ch_var, en_ratio; + num_chs = min( nchan_inp, FOA_CHANNELS ); + num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); + + set_zero( bb_var, FOA_CHANNELS ); + + if ( dtx_vad == 1 ) + { + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + bb_var[ch] += cov_real[ch][ch][b]; + } + } + } + else + { + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + bb_var[ch] += cov_dtx_real[ch][ch][b]; + } + } + } + + if ( hCovEnc->prior_var_flag == -1 ) + { + for ( ch = 0; ch < num_chs; ch++ ) + { + hCovEnc->bb_var_lt[ch] = bb_var[ch]; + } + // hCovEnc->prior_var_flag = 0; + } + else + { + sm_fact = 0.5f; + for ( ch = 0; ch < num_chs; ch++ ) + { + hCovEnc->bb_var_lt[ch] = sm_fact * hCovEnc->bb_var_lt[ch] + ( 1 - sm_fact ) * bb_var[ch]; + } + } + + side_ch_var = 0.0f; + for ( ch = nchan_transport; ch < num_chs; ch++ ) + { + side_ch_var += hCovEnc->bb_var_lt[dmx_order[ch]]; + } + + if ( side_ch_var < ( IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH * IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH ) ) + { + activeW_flag = 0; + } + else + { + en_ratio = hCovEnc->bb_var_lt[0] / side_ch_var; + if ( en_ratio < ( IVAS_SPAR_DYN_ACTIVEW_THRESH * IVAS_SPAR_DYN_ACTIVEW_THRESH ) ) + { + activeW_flag = 1; + } + else + { + activeW_flag = 0; + } + } + + if ( activeW_flag ) + { + *res_ind = 0; + if ( nchan_transport == 2 ) + { + int16_t max_idx; + float max_val; + max_idx = nchan_transport; + max_val = hCovEnc->bb_var_lt[max_idx]; + for ( ch = nchan_transport + 1; ch < num_chs; ch++ ) + { + if ( hCovEnc->bb_var_lt[ch] > max_val ) + { + max_idx = ch; + max_val = hCovEnc->bb_var_lt[ch]; + } + } + *res_ind = max_idx; + } + else if ( nchan_transport == 3 ) + { + *res_ind = dmx_order[nchan_transport]; + } + } + + return activeW_flag; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_enc_cov_handler_process() * @@ -161,7 +279,17 @@ void ivas_enc_cov_handler_process( const int16_t num_ch, const int16_t dtx_vad, const int16_t transient_det[2], - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] ) + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + int16_t *res_ind, + const int16_t *remix_order, + int16_t *dyn_active_w_flag, + const int16_t nchan_transport, + const int16_t is_sba +#endif + +) { int16_t i, j; int16_t dtx_cov_flag; @@ -177,6 +305,22 @@ void ivas_enc_cov_handler_process( cov_real, HOA_md_ind ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( is_sba ) + { + *res_ind = 0; + if ( nchan_transport > 1 && nchan_transport <= ( FOA_CHANNELS - 1 ) ) + { + *dyn_active_w_flag = ivas_spar_get_activeW_flag( hCovEnc, cov_real, cov_real, dtx_vad, num_ch, nchan_transport, res_ind, + remix_order ); + } + else + { + *dyn_active_w_flag = 0; + } + } +#endif + #ifdef DEBUG_SPAR_WRITE_OUT_COV { static FILE *fid = 0; diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 5c50c3d6bdd6946ff42c6dca80a34e953cf3fbc2..8c442a51c6d357c9d6dc597992901dc90da299aa 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -821,7 +821,12 @@ static void ivas_mc_paramupmix_param_est_enc( } } - ivas_enc_cov_handler_process( hMCParamUpmix->hCovEnc[b], pp_in_fr_real, pp_in_fr_imag, cov_real, cov_dtx_real, hMCParamUpmix->hFbMixer->pFb, 0, hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands, MC_PARAMUPMIX_NCH, 0 /*dtx_vad*/, transient_det[b], HOA_md_ind ); + ivas_enc_cov_handler_process( hMCParamUpmix->hCovEnc[b], pp_in_fr_real, pp_in_fr_imag, cov_real, cov_dtx_real, hMCParamUpmix->hFbMixer->pFb, 0, hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands, MC_PARAMUPMIX_NCH, 0 /*dtx_vad*/, transient_det[b], HOA_md_ind +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + NULL, NULL, NULL, 0, 0 +#endif + ); } maxbands = hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; for ( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 516104c79b8ef60eb0582b094e1fe08c27d48367..2b09d00b42e9a614545c26c04d96660c949e0ae0 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -386,7 +386,13 @@ static ivas_error ivas_spar_cov_md_process( float *ppIn_FR_real[IVAS_SPAR_MAX_CH], float *ppIn_FR_imag[IVAS_SPAR_MAX_CH], const int16_t transient_det[2], - const int16_t dtx_vad ) + const int16_t dtx_vad +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t nchan_transport, + int16_t *dyn_active_w_flag +#endif +) { int16_t i, j, i_ts, b, table_idx; int16_t active_w_vlbr; @@ -443,7 +449,34 @@ static ivas_error ivas_spar_cov_md_process( } } - ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind ); + ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + &hSpar->hMdEnc->spar_md.res_ind, + remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order], + dyn_active_w_flag, nchan_transport, 1 + +#endif + ); + +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( nchan_transport > 1 && nchan_transport <= ( FOA_CHANNELS - 1 ) ) + { + push_next_indice( hMetaData, *dyn_active_w_flag, 1 ); + if ( ( *dyn_active_w_flag == 1 ) && ( nchan_transport == 2 ) ) + { + push_next_indice( hMetaData, hSpar->hMdEnc->spar_md.res_ind - nchan_transport, 1 ); + } + hSpar->front_vad_flag = ( *dyn_active_w_flag == 1 ) ? 1 : hSpar->front_vad_flag; + } + else + { + if ( nchan_transport == FOA_CHANNELS ) + { + push_next_indice( hMetaData, 0, 1 ); + } + } +#endif /*-----------------------------------------------------------------------------------------* * MetaData encoder @@ -452,6 +485,10 @@ static ivas_error ivas_spar_cov_md_process( if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + *dyn_active_w_flag +#endif #ifdef FIX_527_SBA_MONO_INPUT , hQMetaData->dirac_mono_flag @@ -499,12 +536,21 @@ static ivas_error ivas_spar_cov_md_process( Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); } - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, hQMetaData->useLowerRes, active_w_vlbr ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, hQMetaData->useLowerRes, active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + *dyn_active_w_flag +#endif + ); } if ( hSpar->hMdEnc->spar_hoa_md_flag ) { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + *dyn_active_w_flag +#endif #ifdef FIX_527_SBA_MONO_INPUT , hQMetaData->dirac_mono_flag @@ -556,6 +602,9 @@ static ivas_error ivas_spar_enc_process( float *ppIn_FR_real[IVAS_SPAR_MAX_CH], *ppIn_FR_imag[IVAS_SPAR_MAX_CH]; float wyzx_del_buf[FOA_CHANNELS][IVAS_FB_1MS_48K_SAMP]; +#ifdef FIX_SBA_VANISHING_RESIDUAL + int16_t dyn_active_w_flag; +#endif int16_t nchan_fb_in; /* ToDo: Commented for now*/ @@ -609,7 +658,11 @@ static ivas_error ivas_spar_enc_process( if ( hSpar->hFbMixer->fb_cfg->active_w_mixing == 0 ) { /* fill delay (1 ms) buffer for all Transport channels */ +#ifndef FIX_SBA_VANISHING_RESIDUAL for ( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) +#else + for ( i = 0; i < FOA_CHANNELS; i++ ) +#endif { int16_t idx = hSpar->hFbMixer->fb_cfg->remix_order[i]; mvr2r( &hSpar->hFbMixer->ppFilterbank_prior_input[idx][hSpar->hFbMixer->fb_cfg->prior_input_length - num_del_samples], wyzx_del_buf[idx], num_del_samples ); @@ -689,7 +742,13 @@ static ivas_error ivas_spar_enc_process( * Covariance and MD processing *-----------------------------------------------------------------------------------------*/ - if ( ( error = ivas_spar_cov_md_process( hEncoderConfig, st_ivas->hSpar, st_ivas->hQMetaData, hMetaData, nchan_inp, sba_order, ppIn_FR_real, ppIn_FR_imag, transient_det, dtx_vad ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_spar_cov_md_process( hEncoderConfig, st_ivas->hSpar, st_ivas->hQMetaData, hMetaData, nchan_inp, sba_order, ppIn_FR_real, ppIn_FR_imag, transient_det, dtx_vad +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + nchan_transport, + &dyn_active_w_flag +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -729,9 +788,35 @@ static ivas_error ivas_spar_enc_process( } } - ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind ); + ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + &hSpar->hMdEnc->spar_md.res_ind, + remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order], + &dyn_active_w_flag, st_ivas->nchan_transport, 1 + +#endif + ); nchan_transport = st_ivas->nchan_transport; +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( nchan_transport > 1 && nchan_transport <= ( FOA_CHANNELS - 1 ) ) + { + push_next_indice( hMetaData, dyn_active_w_flag, 1 ); + if ( ( dyn_active_w_flag == 1 ) && ( nchan_transport == 2 ) ) + { + push_next_indice( hMetaData, hSpar->hMdEnc->spar_md.res_ind - nchan_transport, 1 ); + } + st_ivas->hSpar->front_vad_flag = ( dyn_active_w_flag == 1 ) ? 1 : st_ivas->hSpar->front_vad_flag; + } + else + { + if ( nchan_transport == FOA_CHANNELS ) + { + push_next_indice( hMetaData, 0, 1 ); + } + } +#endif /*-----------------------------------------------------------------------------------------* * MetaData encoder @@ -740,6 +825,10 @@ static ivas_error ivas_spar_enc_process( if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif #ifdef FIX_527_SBA_MONO_INPUT , hQMetaData->dirac_mono_flag @@ -787,12 +876,22 @@ static ivas_error ivas_spar_enc_process( Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); } - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, hQMetaData->useLowerRes, active_w_vlbr ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, + hQMetaData->useLowerRes, active_w_vlbr +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); } if ( hSpar->hMdEnc->spar_hoa_md_flag ) { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif #ifdef FIX_527_SBA_MONO_INPUT , hQMetaData->dirac_mono_flag @@ -916,9 +1015,44 @@ static ivas_error ivas_spar_enc_process( #endif if ( hSpar->hFbMixer->fb_cfg->active_w_mixing == 0 ) { - /* delayed W */ - mvr2r( wyzx_del_buf[0], p_pcm_tmp[0], num_del_samples ); - mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); + +#ifdef FIX_SBA_VANISHING_RESIDUAL + /*cross fade between new active W channels and old passive W channel*/ + if ( dyn_active_w_flag == 1 ) + { + if ( hSpar->hMdEnc->spar_md.prior_dyn_active_w_flag != dyn_active_w_flag ) + { + float new_w[L_FRAME48k]; + + /* delayed W */ + mvr2r( wyzx_del_buf[0], p_pcm_tmp[0], num_del_samples ); + mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); + + mvr2r( wyzx_del_buf[hSpar->hMdEnc->spar_md.res_ind], new_w, num_del_samples ); + mvr2r( data_f[hSpar->hMdEnc->spar_md.res_ind], &new_w[num_del_samples], input_frame - num_del_samples ); + + if ( hSpar->hMdEnc->spar_md.prior_dyn_active_w_flag == 0 && dyn_active_w_flag == 1 ) + { + ivas_fb_mixer_cross_fading( hSpar->hFbMixer, p_pcm_tmp, p_pcm_tmp[0], new_w, 0, input_frame, 0 ); + } + else if ( hSpar->hMdEnc->spar_md.prior_dyn_active_w_flag == 1 && dyn_active_w_flag == 0 ) + { + ivas_fb_mixer_cross_fading( hSpar->hFbMixer, p_pcm_tmp, new_w, p_pcm_tmp[0], 0, input_frame, 0 ); + } + } + else + { + mvr2r( wyzx_del_buf[hSpar->hMdEnc->spar_md.res_ind], p_pcm_tmp[0], num_del_samples ); + mvr2r( data_f[hSpar->hMdEnc->spar_md.res_ind], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); + } + } + else +#endif + { + /* delayed W */ + mvr2r( wyzx_del_buf[0], p_pcm_tmp[0], num_del_samples ); + mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); + } for ( i = 1; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) { @@ -985,6 +1119,7 @@ static ivas_error ivas_spar_enc_process( { ivas_agc_enc_process( hSpar->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, hSpar->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); } +#ifndef FIX_SBA_VANISHING_RESIDUAL else { /* IVAS_fmToDo: This AGC on/off bit should be removed when the command line option to force enable/disable AGC is @@ -993,6 +1128,7 @@ static ivas_error ivas_spar_enc_process( * ivas_agc_enc_get_flag function should be moved to ivas_agc_com.c and renamed when this occurs. */ push_next_indice( hMetaData, 0, 1 ); } +#endif } #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_agc_enc_process */ @@ -1043,13 +1179,26 @@ static ivas_error ivas_spar_enc_process( for ( j = 0; j < nchan_transport; j++ ) { - mvr2r( p_pcm_tmp[j], data_f[order[j]], input_frame ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( st_ivas->nchan_transport < 3 ) + { + mvr2r( p_pcm_tmp[j], data_f[j], input_frame ); + } + else +#endif + { + mvr2r( p_pcm_tmp[j], data_f[order[j]], input_frame ); + } } for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) { set_f( data_f[order[j]], 0.0f, input_frame ); } +#ifdef FIX_SBA_VANISHING_RESIDUAL + hSpar->hMdEnc->spar_md.prior_dyn_active_w_flag = dyn_active_w_flag; +#endif + pop_wmops(); /* ToDo: Commented for now */ diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 4e8556cd3789ea7e79d0140dbb5ca609939f0a6e..6b7da65f2cb571675d19fbd1d17b856176038804 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -332,6 +332,10 @@ ivas_error ivas_spar_md_enc_init( ivas_sba_get_spar_hoa_ch_ind( num_channels, hEncoderConfig->ivas_total_brate, hMdEnc->HOA_md_ind ); table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + hMdEnc->spar_md.prior_dyn_active_w_flag = 0; +#endif + ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND, hMdEnc->spar_hoa_dirac2spar_md_flag, 1, hEncoderConfig->Opt_PCA_ON, #ifndef DEBUG_AGC_ENCODER_CMD_OPTION @@ -567,9 +571,13 @@ ivas_error ivas_spar_md_enc_process( const int16_t nchan_inp, const int16_t sba_order, /* i : Ambisonic (SBA) order */ float *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i : prior mixer_matrix */ +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + const int16_t dyn_active_w_flag /* i : flag to indicate dynamic active W*/ +#endif #ifdef FIX_527_SBA_MONO_INPUT , - const int16_t dirac_mono_flag + const int16_t dirac_mono_flag /* i : flag to indicate mono only mode in SBA*/ #endif ) { @@ -601,7 +609,11 @@ ivas_error ivas_spar_md_enc_process( num_quant_strats = hMdEnc->spar_md_cfg.num_quant_strats; num_ch = ivas_sba_get_nchan_metadata( sba_order, hEncoderConfig->ivas_total_brate ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + active_w = ( hMdEnc->spar_md_cfg.active_w == 1 ) || ( dyn_active_w_flag == 1 ); +#else active_w = hMdEnc->spar_md_cfg.active_w; +#endif nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; bwidth = ivas_get_bw_idx_from_sample_rate( hEncoderConfig->input_Fs ); @@ -692,7 +704,12 @@ ivas_error ivas_spar_md_enc_process( ivas_compute_spar_params( cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, bands_bw, active_w, active_w_vlbr, - &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); + &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); #ifdef FIX_527_SBA_MONO_INPUT if ( dirac_mono_flag ) @@ -778,7 +795,12 @@ ivas_error ivas_spar_md_enc_process( if ( ndm != num_ch ) { - ivas_calc_c_p_coeffs( &hMdEnc->spar_md, cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); + ivas_calc_c_p_coeffs( &hMdEnc->spar_md, cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag +#endif + ); } } } @@ -927,6 +949,10 @@ ivas_error ivas_spar_md_enc_process( #ifndef FIX_280_PLANAR_CP , planarCP +#endif +#ifdef FIX_SBA_VANISHING_RESIDUAL + , + dyn_active_w_flag #endif ); #ifdef FIX_527_SBA_MONO_INPUT @@ -2136,6 +2162,12 @@ static void ivas_write_parameter_bitstream_dtx( sid_bits_len = hMetaData->nb_bits_tot - sid_bits_len; zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; assert( zero_pad_bits >= 0 ); +#ifdef FIX_SBA_VANISHING_RESIDUAL + if ( num_dmx[0] == 2 ) + { + zero_pad_bits -= 1; + } +#endif while ( zero_pad_bits > 0 ) { j = min( zero_pad_bits, 16 ); diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index e9f7d34736702c0d200331c83be5a3eaaa854d42..516604fc7235f13d862d4cbf79ada80b2365e0d7 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -651,7 +651,10 @@ typedef struct ivas_enc_cov_handler_state_t ivas_cov_smooth_state_t *pCov_dtx_state; int16_t num_bins; int16_t prior_dtx_present; - +#ifdef FIX_SBA_VANISHING_RESIDUAL + float bb_var_lt[FOA_CHANNELS]; + int16_t prior_var_flag; +#endif } ivas_enc_cov_handler_state_t; diff --git a/tests/codec_be_on_mr_selection/__init__.py b/tests/codec_be_on_mr_selection/__init__.py index da1d8c35785275ca34c6c4bde6eee5f39cf26fe0..14f0bb0b1786eab41c0f22b293d8dc7ecee5689b 100644 --- a/tests/codec_be_on_mr_selection/__init__.py +++ b/tests/codec_be_on_mr_selection/__init__.py @@ -127,6 +127,7 @@ def run_check( is_ref_creation, input_file_num=None, keep_files=True, + compare_bitstream=False, ): sampling_rate = 48 output_mode, options = OUTPUT_MODES_AND_OPTIONS_FOR_EXPERIMENT[experiment] @@ -162,8 +163,9 @@ def run_check( ) if not is_ref_creation: - if not is_be_to_ref(dut_bitstream): - pytest.fail(f"Bitstream file differs from reference") + if compare_bitstream: + if not is_be_to_ref(dut_bitstream): + pytest.fail(f"Bitstream file differs from reference") dut_bitstream_to_decoder = dut_bitstream if error_pattern is not None: diff --git a/tests/codec_be_on_mr_selection/test_experiments.py b/tests/codec_be_on_mr_selection/test_experiments.py index 5b2f51689342117c2e543442a974bce6714ff6fc..53fdd8eba9e18d59fead99844a287f336423a2c3 100644 --- a/tests/codec_be_on_mr_selection/test_experiments.py +++ b/tests/codec_be_on_mr_selection/test_experiments.py @@ -53,6 +53,7 @@ def test_p800( dut_decoder_frontend, update_ref, keep_files, + compare_bitstream, ): run_check( experiment, @@ -65,6 +66,7 @@ def test_p800( dut_decoder_frontend, update_ref == 1, keep_files=keep_files, + compare_bitstream=compare_bitstream, ) @@ -82,6 +84,7 @@ def test_bs1534_no_masa( dut_decoder_frontend, update_ref, keep_files, + compare_bitstream, ): category = "" run_check( @@ -96,6 +99,7 @@ def test_bs1534_no_masa( update_ref == 1, input_file_num=input_file_num, keep_files=keep_files, + compare_bitstream=compare_bitstream, ) @@ -116,6 +120,7 @@ def test_bs1534_masa( dut_decoder_frontend, update_ref, keep_files, + compare_bitstream, ): run_check( experiment, @@ -129,4 +134,5 @@ def test_bs1534_masa( update_ref == 1, input_file_num=input_file_num, keep_files=keep_files, + compare_bitstream=compare_bitstream, ) diff --git a/tests/conftest.py b/tests/conftest.py index e4de453b0ea6698f9600076ded65a53a1a2b7d51..ac1b37121af50d3ba529766cc0ee4eb75b4b9227 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -132,6 +132,14 @@ def pytest_addoption(parser): help="By default, the DUT output files of successful tests are deleted." " Use --keep_files to prevent these deletions.", ) + + parser.addoption( + "--compare_bitstream", + action="store_true", + help="By default, the IVAS encoded bitstream is not compared with ref." + " Use --compare_bitstream to compare IVAS encoded bitstream.", + ) + parser.addoption( "--selection_be_md5_file", @@ -158,6 +166,12 @@ def keep_files(request) -> bool: """ return request.config.option.keep_files +@pytest.fixture(scope="session") +def compare_bitstream(request) -> bool: + """ + Return indication to compare IVAS encoded bitstream. + """ + return request.config.option.compare_bitstream @pytest.fixture(scope="session") def dut_encoder_path(request) -> str: