diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 602a042e5b60ce473e3894b859e35fefd3cd3c22..66ba43c93f8a49f5b31a734418c92ded52bc5eab 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1430,7 +1430,9 @@ typedef enum typedef enum { IVAS_FILTER_ORDER_1 = 1, +#ifndef NONBE_FIX_MC_LFE_LPF IVAS_FILTER_ORDER_2 = 2, +#endif IVAS_FILTER_ORDER_4 = 4, } ivas_filter_order; diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters.c index 46f878a2dae7ca41682f4be74a50bb2e6c0bce20..82d4f5a0001b00ac372d1110c5a2320cb22154b1 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -62,7 +62,11 @@ void ivas_filters_init( int16_t i; filter_state->order = order; +#ifdef NONBE_FIX_MC_LFE_LPF + if ( order == IVAS_FILTER_ORDER_1 ) +#else if ( order == IVAS_FILTER_ORDER_2 || order == IVAS_FILTER_ORDER_1 ) +#endif { filter_state->filt_len = order + 1; @@ -116,7 +120,9 @@ void ivas_filter_process( switch ( filter_state->order ) { case IVAS_FILTER_ORDER_1: +#ifndef NONBE_FIX_MC_LFE_LPF case IVAS_FILTER_ORDER_2: +#endif ivas_iir_2_filter( filter_state, pIn_Out, length, IVAS_FILTER_STAGE_0 ); break; case IVAS_FILTER_ORDER_4: diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com.c index 4a44ceadffd2ad6be3db808b87b6e7edf60d41f7..af6026ae699a3399fb121c80e6b1635190ba7951 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com.c @@ -60,6 +60,7 @@ void ivas_lfe_lpf_select_filt_coeff( { switch ( order ) { +#ifndef NONBE_FIX_MC_LFE_LPF case IVAS_FILTER_ORDER_2: switch ( sampling_rate ) { @@ -76,6 +77,7 @@ void ivas_lfe_lpf_select_filt_coeff( break; } break; +#endif case IVAS_FILTER_ORDER_4: switch ( sampling_rate ) { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 470115c11e18154013b19a653f5b2599fb9fb61d..2b8caea611bf5cc00932fd7a827a0f6fe6f6b81c 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5486,7 +5486,11 @@ void ivas_lfe_enc( ivas_error ivas_create_lfe_dec( LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ const int32_t output_Fs, /* i : output sampling rate */ +#ifdef NONBE_FIX_MC_LFE_LPF + const int32_t delay_ns /* i : additional LFE delay to sync other channel outputs */ +#else const int32_t binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ +#endif ); void ivas_lfe_dec_close( diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 3b0c10581022c9b156d3504777cc8674d9300d37..443e6190a6cb7163a95510425405b004529c8682 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -3120,6 +3120,7 @@ const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2] = 1.00000000471366f, 1.f , -1.98677297369091f, 0.987060670205863f }; +#ifndef NONBE_FIX_MC_LFE_LPF const float ivas_lpf_2_butter_16k[IVAS_BIQUAD_FILT_LEN << 1] = { 0.000628720643081143f, 0.00125744128616229f, 0.000628720643081143f, 1.f, -1.92783286977036f, 0.930347752342683f @@ -3134,6 +3135,7 @@ const float ivas_lpf_2_butter_48k[IVAS_BIQUAD_FILT_LEN << 1] = { 7.15317998432330e-05f, 0.000143063599686466f, 7.15317998432330e-05f, 1.f, -1.97593552482925f, 0.976221652028620f }; +#endif const ivas_lfe_freq_models ivas_str_lfe_freq_models = { diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 6cce7f9ecc6945614fcb00a6b4062c7ea1282e5d..c73fbf38d64592ba153d31bc8c409e6c2b0f34ad 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -352,9 +352,11 @@ extern const int16_t Param_ISM_band_grouping[MAX_PARAM_ISM_NBANDS + 1]; extern const float ivas_lpf_4_butter_16k_sos[IVAS_BIQUAD_FILT_LEN << 2]; extern const float ivas_lpf_4_butter_32k_sos[IVAS_BIQUAD_FILT_LEN << 2]; extern const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2]; +#ifndef NONBE_FIX_MC_LFE_LPF extern const float ivas_lpf_2_butter_16k[IVAS_BIQUAD_FILT_LEN << 1]; extern const float ivas_lpf_2_butter_32k[IVAS_BIQUAD_FILT_LEN << 1]; extern const float ivas_lpf_2_butter_48k[IVAS_BIQUAD_FILT_LEN << 1]; +#endif extern const float ivas_lfe_window_coeff_48k[IVAS_LFE_FADE_LEN_48K]; extern const float ivas_lfe_window_coeff_32k[IVAS_LFE_FADE_LEN_32K]; diff --git a/lib_com/options.h b/lib_com/options.h index 852d7b8d6afb3f14b200d516ffbba85c46a3a99b..39e99c6f63546659aca9d3426fa14dc0c0e02830 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,6 +170,7 @@ #define NONBE_1319_M2R_PRECISION_ALIGN /* Nokia: bring updates from PC code related to OMASA masa2total ratios */ #define NONBE_FIX_864_JBM_RENDER_FRAMESIZE /* FhG: issue #864: fix different behaviour of JBM TSM with different render frame sizes */ #define NONBE_FIX_TCX5_INTERLEAVING_FOR_FS_IN_UNEQUAL_FS_OUT /* FhG: apply correct TCX5 grouping/interleaving when input_fs != output_fs */ +#define NONBE_FIX_MC_LFE_LPF /* Dlb: Adding the LFE LPF filter back for MC content. */ /* #################### End FIXES switches ############################ */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 81be8626f3ac3808b3d1866831f7c8931ee73be2..a0e215d848164a59edb833aa8e2b0e4a0f2e17cb 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1077,7 +1077,11 @@ ivas_error ivas_init_decoder( int16_t numCldfbAnalyses, numCldfbSyntheses; int16_t granularity, n_channels_transport_jbm; int32_t output_Fs, ivas_total_brate; +#ifdef NONBE_FIX_MC_LFE_LPF + int32_t delay_ns; +#else int32_t binauralization_delay_ns; +#endif AUDIO_CONFIG output_config; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -2163,8 +2167,9 @@ ivas_error ivas_init_decoder( } } +#ifndef NONBE_FIX_MC_LFE_LPF /*-----------------------------------------------------------------* - * LFE handles for rendering after rendering to adjust LFE delay to binaural filter delay + * LFE handles for rendering after rendering to adjust LFE delay to filter delay *-----------------------------------------------------------------*/ if ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) @@ -2194,6 +2199,7 @@ ivas_error ivas_init_decoder( set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN ); set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k ); } +#endif /*-----------------------------------------------------------------* * CLDFB handles for rendering @@ -2231,6 +2237,47 @@ ivas_error ivas_init_decoder( ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); } +#ifdef NONBE_FIX_MC_LFE_LPF + /*-----------------------------------------------------------------* + * LFE handles for rendering after rendering to adjust LFE delay to filter delay + *-----------------------------------------------------------------*/ + + if ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + delay_ns = st_ivas->binaural_latency_ns; + if ( st_ivas->hBinRenderer != NULL ) + { + if ( st_ivas->hBinRenderer->render_lfe ) + { + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* Account for filterbank delay */ + delay_ns += IVAS_FB_DEC_DELAY_NS; + } + } + else + { + delay_ns = 0; + } + } + else + { + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( st_ivas->cldfbSynDec[0] != NULL ) ) + { + delay_ns += IVAS_FB_DEC_DELAY_NS; + } + } + + if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, output_Fs, delay_ns ) ) != IVAS_ERR_OK ) + { + return error; + } + + set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN ); + set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k ); + } +#endif + /*-----------------------------------------------------------------* * Allocate and initialize limiter struct *-----------------------------------------------------------------*/ diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index 2f0f79f5e9c9c0d2de146646aafba36dd6f18a61..9079fff27ddc2869e9deb7f57e040c5f8c7368fc 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -252,6 +252,27 @@ static int16_t ivas_lfe_dec_dequant( } +#ifdef NONBE_FIX_MC_LFE_LPF +/*------------------------------------------------------------------------- + * ivas_create_lfe_lpf_dec() + * + * Create, allocate and initialize IVAS decoder LFE low pass filter state handle + *-------------------------------------------------------------------------*/ + +static void ivas_create_lfe_lpf_dec( + ivas_filters_process_state_t *hLfeLpf, /* o : LFE LPF handle */ + const int32_t input_Fs /* i : input sampling rate */ +) +{ + const float *filt_coeff; + + ivas_lfe_lpf_select_filt_coeff( input_Fs, IVAS_FILTER_ORDER_4, &filt_coeff ); + ivas_filters_init( hLfeLpf, filt_coeff, IVAS_FILTER_ORDER_4 ); + + return; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_lfe_dec() * @@ -350,9 +371,15 @@ void ivas_lfe_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_create_lfe_dec( +#ifdef NONBE_FIX_MC_LFE_LPF + LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ + const int32_t output_Fs, /* i : output sampling rate */ + const int32_t delay_ns /* i : additional LFE delay to sync other channel outputs */ +#else LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ const int32_t output_Fs, /* i : output sampling rate */ const int32_t binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ +#endif ) { float low_pass_delay_dec_out, block_offset_s; @@ -403,6 +430,14 @@ ivas_error ivas_create_lfe_dec( block_offset_s = BLOCK_OFFSET_MS * 0.001f; filt_order = 0; low_pass_delay_dec_out = 0; +#ifdef NONBE_FIX_MC_LFE_LPF + if ( ( delay_ns / 1000000000.f ) > ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] ) + { + filt_order = 4; + low_pass_delay_dec_out = ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000.f; + ivas_create_lfe_lpf_dec( &( hLFE->filter_state ), output_Fs ); + } +#endif hLFE->filter_state.order = filt_order; hLFE->lfe_block_delay_s = hLFE->lfe_block_delay_s + low_pass_delay_dec_out; hLFE->lfe_prior_buf_len = NS2SA( output_Fs, IVAS_LFE_FADE_NS ); @@ -411,7 +446,11 @@ ivas_error ivas_create_lfe_dec( lfe_addl_delay_s = block_offset_s - hLFE->lfe_block_delay_s; lfe_addl_delay_s = max( 0.0f, lfe_addl_delay_s ); +#ifdef NONBE_FIX_MC_LFE_LPF + add_delay_sa = (int16_t) roundf( (float) delay_ns * output_Fs / 1000000000.f ); +#else add_delay_sa = (int16_t) roundf( (float) binauralization_delay_ns * output_Fs / 1000000000.f ); +#endif hLFE->lfe_addl_delay = (int16_t) ( lfe_addl_delay_s * output_Fs ) + add_delay_sa; hLFE->lfe_block_delay_s += lfe_addl_delay_s + add_delay_sa / output_Fs; diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index e65338d6ce6f5edfd5c5b59c379027375296d1d9..f5318a54e00abf8a5ac44b492e183e93856150b8 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1130,21 +1130,46 @@ static ivas_error ivas_mc_dec_reconfig( if ( ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && st_ivas->hLFE == NULL ) { +#ifdef NONBE_FIX_MC_LFE_LPF + int32_t delay_ns = st_ivas->binaural_latency_ns; +#else int32_t binauralization_delay_ns = st_ivas->binaural_latency_ns; +#endif if ( st_ivas->hBinRenderer != NULL ) { if ( st_ivas->hBinRenderer->render_lfe ) { /* Account for filterbank delay */ +#ifdef NONBE_FIX_MC_LFE_LPF + delay_ns += IVAS_FB_DEC_DELAY_NS; +#else binauralization_delay_ns += IVAS_FB_DEC_DELAY_NS; +#endif } else { +#ifdef NONBE_FIX_MC_LFE_LPF + delay_ns = 0; +#else binauralization_delay_ns = 0; +#endif + } + } +#ifdef NONBE_FIX_MC_LFE_LPF + else + { + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( st_ivas->cldfbSynDec[0] != NULL ) ) + { + delay_ns += IVAS_FB_DEC_DELAY_NS; } } +#endif +#ifdef NONBE_FIX_MC_LFE_LPF + if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, delay_ns ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, binauralization_delay_ns ) ) != IVAS_ERR_OK ) +#endif { return error; }