From 48896bdd431a14506fd30891b09ae07d60d1c22d Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 16:46:00 +0200 Subject: [PATCH 01/10] port UNIFIED_DECODING_PATHS_LEFTOVERS --- lib_com/ivas_cnst.h | 4 + lib_com/ivas_prot_fx.h | 19 +- lib_com/options.h | 1 + lib_dec/ivas_dirac_dec_fx.c | 2 +- lib_dec/ivas_ism_param_dec_fx.c | 134 +- lib_dec/ivas_jbm_dec_fx.c | 1409 ++++---- lib_dec/ivas_mc_param_dec_fx.c | 3923 +++++++++++----------- lib_dec/ivas_osba_dec_fx.c | 2 +- lib_dec/ivas_sba_rendering_internal_fx.c | 49 +- lib_dec/ivas_stat_dec.h | 6 +- lib_dec/lib_dec_fx.c | 2 + 11 files changed, 2942 insertions(+), 2609 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index f40dad61d..f028bce4d 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -195,7 +195,11 @@ typedef enum #define MAX_JBM_L_FRAME48k 1920 #define MAX_JBM_L_FRAME_NS 40000000L #define MAX_SPAR_INTERNAL_CHANNELS IVAS_SPAR_MAX_CH +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS +#define MAX_CLDFB_DIGEST_CHANNELS 3 /* == maximum of ParamISM TCs and ParamMC TCs */ +#else #define MAX_CLDFB_DIGEST_CHANNELS (FOA_CHANNELS + MAX_NUM_OBJECTS) +#endif typedef enum { diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index dce0bac13..b72abcb42 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -641,6 +641,7 @@ void ivas_jbm_dec_get_adapted_subframes_fx( Word16 *nb_subframes /* i/o: number of subframes in the frame */ ); +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS void ivas_jbm_dec_copy_tc_no_tsm_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle Q0 */ Word32 *tc_fx[], /* i : transport channels Q11 */ @@ -654,7 +655,7 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( Word32 *transport_channels_f[], /* i : synthesized core-coder transport channels/DirAC output Q_tc*/ Word16 *Q_tc /* i/o : Q of input tc buffer */ ); - +#endif /*! r: number of bits read */ Word16 read_GR0( const UWord16 *bit_stream, /* i : bitstream to be read */ @@ -4249,14 +4250,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const Word16 nSamplesForRendering, /* i : number of TC samples available for rendering */ Word16 *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/ - Word32 *data /* i/o: transport channels/output synthesis signal */ -); - -void ivas_jbm_dec_feed_tc_to_renderer_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const Word16 nSamplesForRendering, /* i : number of TC samples available for rendering */ - Word16 *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/ - Word32 *data /* i/o: transport channels/output synthesis signal */ + Word32 *data_fx /* i/o: transport channels/output synthesis signal */ ); #ifdef OBJ_EDITING_API @@ -4353,11 +4347,10 @@ void ivas_ism_dec_digest_tc_fx( void ivas_param_ism_dec_digest_tc_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output */ - const Word16 q_tc_in + Word32 *p_data_fx[], /* i : synthesized core-coder transport channels/DirAC output */ + const Word16 q_data_in /* i : Q-factor of input signal for single channel */ ); - #ifdef OBJ_EDITING_API void ivas_param_ism_dec_dequant_md_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ @@ -5164,7 +5157,7 @@ void ivas_param_mc_dec_digest_tc_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ Word32 *p_data_fx[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const Word16 transport_f_e + const Word16 q_data /* i : Q-factor of input signal for single channel */ ); #ifdef OBJ_EDITING_API diff --git a/lib_com/options.h b/lib_com/options.h index a6ba3a9cf..3d8b906bb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -122,6 +122,7 @@ #define FIX_1388_MSAN_ivas_init_decoder /* VA: issue 1388: fix use-of-uninitialized value in ivas_init_decoder() */ #define FIX_1288_SPLIT_REND_XSAN /* Dlb: Fix asan, msan and usan issues in split rendering mode*/ #define LIB_DEC_REVISION /* VA: cleaning and simplification of lib_dec.c */ +#define UNIFIED_DECODING_PATHS_LEFTOVERS /* VA: issue 880: remove leftovers after NONBE_UNIFIED_DECODING_PATHS */ // object-editing feature porting #define OBJ_EDITING_INTERFACE /* Interface for object editing */ diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 1c20d23a8..dd7442029 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2076,7 +2076,7 @@ void ivas_dirac_dec_render_fx( move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS]; - Word32 output_f_local_buff_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k] = { 0 }; // VE2SB: TBV + Word32 output_f_local_buff_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k] = { 0 }; hSpatParamRendCom = st_ivas->hSpatParamRendCom; diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 50e2ee439..86c4c13fd 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -44,6 +44,15 @@ #include "debug.h" +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS +/*-----------------------------------------------------------------------* + * Local function declarations + *-----------------------------------------------------------------------*/ + +static void ivas_ism_param_dec_tc_gain_adjust_fx( Decoder_Struct *st_ivas, const Word16 nSamples, const Word16 nFadeLength, Word32 *p_data_fx[], Word16 *q_data ); + +#endif + /*-----------------------------------------------------------------------* * Local function definitions *-----------------------------------------------------------------------*/ @@ -580,6 +589,7 @@ static void ivas_param_ism_update_mixing_matrix_fx( * * Open Param ISM handle *-------------------------------------------------------------------------*/ + ivas_error ivas_param_ism_dec_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) @@ -917,6 +927,7 @@ void ivas_param_ism_dec_close_fx( * * *-------------------------------------------------------------------------*/ + void ivas_ism_dec_digest_tc_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) @@ -1100,11 +1111,19 @@ void ivas_ism_dec_digest_tc_fx( *-------------------------------------------------------------------------*/ void ivas_param_ism_dec_digest_tc_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord16 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output q_tc_in */ - const Word16 q_tc_in ) + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + Word32 *p_data_fx[], /* i : synthesized core-coder transport channels/DirAC output q_data_in */ + const Word16 q_data_in /* i : Q-factor of input signal for single channel */ +) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Word16 i, ch, slot_idx, output_frame; + Word16 num_freq_bands, cldfb_ch, n_ch_cldfb; + Word32 *cldfb_real_buffer, *cldfb_imag_buffer; + Word16 q_data = q_data_in; + move16(); +#else move16(); move16(); move16(); @@ -1115,7 +1134,7 @@ void ivas_param_ism_dec_digest_tc_fx( Word16 exp_real_tmp = 0, exp_imag_tmp = 0; #endif - Word16 q_tc = q_tc_in; + Word16 q_tc = q_data_in; move16(); #ifndef OBJ_EDITING_API Word16 ch, nchan_transport, nchan_out, nchan_out_woLFE, i; @@ -1134,8 +1153,18 @@ void ivas_param_ism_dec_digest_tc_fx( PARAM_ISM_DEC_HANDLE hParamIsmDec; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word16 fade_len; +#endif /* Initialization */ +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; + move16(); + output_frame = imult1616( nCldfbSlots, hSpatParamRendCom->num_freq_bands ); + n_ch_cldfb = sub( st_ivas->hTcBuffer->nchan_transport_jbm, st_ivas->hTcBuffer->nchan_buffer_full ); + + cldfb_real_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx; + cldfb_imag_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx; +#else #ifndef OBJ_EDITING_API set32_fx( &direct_response_fx[0][0], 0, MAX_NUM_OBJECTS * PARAM_ISM_MAX_CHAN ); #endif @@ -1172,9 +1201,7 @@ void ivas_param_ism_dec_digest_tc_fx( move16(); } #endif - - push_wmops( "ivas_param_ism_dec" ); - +#endif #ifndef OBJ_EDITING_API /* general setup */ ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator_fx ); @@ -1259,7 +1286,19 @@ void ivas_param_ism_dec_digest_tc_fx( } } #endif +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + ivas_ism_param_dec_tc_gain_adjust_fx( st_ivas, output_frame, shr( output_frame, 1 ), p_data_fx, &q_data ); + IF( NE_16( q_data, q_data_in ) ) + { + FOR( i = 0; i < 2; i++ ) + { + scale_sig32( p_data_fx[i], output_frame, sub( q_data_in, q_data ) ); // q_data_in + } + q_data = q_data_in; + move16(); + } +#else IF( st_ivas->hDecoderConfig->Opt_tsm ) { /*TODO : FhG to check*/ @@ -1275,7 +1314,29 @@ void ivas_param_ism_dec_digest_tc_fx( move16(); } } +#endif + +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + /* CLDFB Analysis */ + FOR( ( ch = 0, cldfb_ch = 0 ); cldfb_ch < n_ch_cldfb; ( cldfb_ch++, ch++ ) ) + { + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + q_data = q_data_in; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][num_freq_bands * slot_idx] ), + &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch], &q_data ); + + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = sub( 31, q_data ); + move16(); + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = sub( 31, q_data ); + move16(); + } + } +#else FOR( ch = 0; ch < nchan_transport; ch++ ) { /* CLDFB Analysis */ @@ -1336,9 +1397,8 @@ void ivas_param_ism_dec_digest_tc_fx( /* Compute mixing matrix */ ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); - #endif - pop_wmops(); +#endif return; } @@ -1429,7 +1489,6 @@ void ivas_param_ism_dec_prepare_renderer_fx( nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; move16(); } - push_wmops( "ivas_param_ism_dec_digest_tc" ); /* general setup */ ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator_fx ); @@ -1557,34 +1616,33 @@ void ivas_param_ism_dec_prepare_renderer_fx( ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); - - pop_wmops(); - return; } #endif + /*-------------------------------------------------------------------------* - * ivas_ism_param_dec_tc_gain_ajust() + * ivas_ism_param_dec_tc_gain_adjust() * * *-------------------------------------------------------------------------*/ +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS +static void ivas_ism_param_dec_tc_gain_adjust_fx( +#else void ivas_ism_param_dec_tc_gain_ajust_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord16 nSamples, /* i : number of samples to be compensate */ - const UWord16 nFadeLength, /* i : length of the crossfade in samples */ - Word32 *transport_channels_f[], /* i : synthesized core-coder transport channels/DirAC output Q_tc*/ - Word16 *Q_tc /* i/o : Q of input tc buffer */ +#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const Word16 nSamples, /* i : number of samples to be compensate */ + const Word16 nFadeLength, /* i : length of the crossfade in samples */ + Word32 *p_data_fx[], /* i : synthesized core-coder transport channels/DirAC output q_data */ + Word16 *q_data /* i/o : Q of input data buffer */ ) - { Word16 i, tmp_e1, tmp_e2, tmp, tmp2, invFade; Word32 L_tmp1, L_tmp2; - Word16 gain_fx, last_gain_fx; Word32 ene_tc_fx, ene_sum_fx; - Word16 ene_tc_e, ene_sum_e; ene_tc_fx = 0; @@ -1596,7 +1654,6 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( ene_sum_e = 0; move16(); - last_gain_fx = st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx; move16(); @@ -1613,14 +1670,13 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( move16(); ch1_e = 0; move16(); - ch0 = transport_channels_f[0][i]; + ch0 = p_data_fx[0][i]; move16(); - ch1 = transport_channels_f[1][i]; + ch1 = p_data_fx[1][i]; move16(); ch0 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, 0, 0, &ch0_e ); ch1 = BASOP_Util_Add_Mant32Exp( ch1, ch1_e, 0, 0, &ch1_e ); - L_tmp1 = Mpy_32_32( ch0, ch0 ); /*L*L*/ tmp_e1 = add( ch0_e, ch0_e ); L_tmp2 = Mpy_32_32( ch1, ch1 ); /*R*R*/ @@ -1629,7 +1685,6 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp1, tmp_e1, &ene_tc_e ); ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp2, tmp_e2, &ene_tc_e ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, ch1, ch1_e, &tmp_e1 ); /*L + R*/ L_tmp1 = Mpy_32_32( L_tmp1, L_tmp1 ); // Q(31-(tmp_e1+tmp_e1 /*(L + R)*(L + R)*/ tmp_e1 = add( tmp_e1, tmp_e1 ); @@ -1679,6 +1734,7 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( { /* Smoothing */ gain_fx = add( mult_r( 24574, gain_fx ), mult_r( 8192, last_gain_fx ) ); // 24574 =.75f in Q15 , 8192=.25f in Q15 + /* 10ms ramp */ /* slope between two consecutive gains, 480 samples length */ invFade = div_s( 1, nFadeLength ); // Q15 @@ -1689,18 +1745,18 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( /* tmp2 = ( last_gain_fx + i * grad_fx )*/ tmp2 = add( mult_r( sub( 32767, tmp ), last_gain_fx ), mult_r( tmp, gain_fx ) ); // 32767= 1.0f in Q15, - transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], tmp2 ); // Q(Q_tc-tmp_e1) + p_data_fx[0][i] = Mpy_32_16_1( p_data_fx[0][i], tmp2 ); // Q(Q_tc-tmp_e1) move32(); - transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], tmp2 ); // Q(Q_tc-tmp_e1) + p_data_fx[1][i] = Mpy_32_16_1( p_data_fx[1][i], tmp2 ); // Q(Q_tc-tmp_e1) move32(); tmp = add( tmp, invFade ); } FOR( ; i < nSamples; i++ ) { - transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); // Q(Q_tc-tmp_e1) + p_data_fx[0][i] = Mpy_32_16_1( p_data_fx[0][i], gain_fx ); // Q(Q_tc-tmp_e1) move32(); - transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); // Q(Q_tc-tmp_e1) + p_data_fx[1][i] = Mpy_32_16_1( p_data_fx[1][i], gain_fx ); // Q(Q_tc-tmp_e1) move32(); } } @@ -1708,9 +1764,9 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( { FOR( i = 0; i < nSamples; i++ ) { - transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); // Q(Q_tc-tmp_e1) + p_data_fx[0][i] = Mpy_32_16_1( p_data_fx[0][i], gain_fx ); // Q(Q_tc-tmp_e1) move32(); - transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); // Q(Q_tc-tmp_e1) + p_data_fx[1][i] = Mpy_32_16_1( p_data_fx[1][i], gain_fx ); // Q(Q_tc-tmp_e1) move32(); } } @@ -1720,16 +1776,19 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e = tmp_e1; move16(); - *Q_tc = sub( *Q_tc, tmp_e1 ); + *q_data = sub( *q_data, tmp_e1 ); move16(); + return; } + /*-------------------------------------------------------------------------* * ivas_ism_param_dec_render_sf() * * *-------------------------------------------------------------------------*/ + static void ivas_ism_param_dec_render_sf_fx( Decoder_Struct *st_ivas, IVAS_OUTPUT_SETUP hSetup, @@ -1752,12 +1811,14 @@ static void ivas_ism_param_dec_render_sf_fx( Word16 idx_lfe; Word16 subframe_idx; Word16 samplesProcessed, no_col_cldfb, size_cldfb; + hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; slot_idx_start = hSpatParamRendCom->slots_rendered; move16(); subframe_idx = hSpatParamRendCom->subframes_rendered; move16(); + /* Set some memories to zero */ FOR( ch = 0; ch < nchan_out_woLFE; ch++ ) { @@ -1768,7 +1829,6 @@ static void ivas_ism_param_dec_render_sf_fx( } } - Word16 real_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME]; Word16 imag_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME]; FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) @@ -1815,7 +1875,6 @@ static void ivas_ism_param_dec_render_sf_fx( } ELSE { - Word32 *RealBuffer_fx[16]; Word32 *ImagBuffer_fx[16]; @@ -2059,7 +2118,6 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( } #endif - IF( st_ivas->hISMDTX.dtx_flag ) { Word32 energy_ratio_fx; /* Q30 */ diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 045e4b110..ab87013da 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -51,8 +51,9 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS static void ivas_jbm_dec_copy_tc( Decoder_Struct *st_ivas, const Word16 nSamplesForRendering, Word16 *nSamplesResidual, Word32 *data, Word32 *tc_digest_f[], Word16 data_q ); - +#endif static void ivas_jbm_dec_tc_buffer_playout_fx( Decoder_Struct *st_ivas, const UWord16 nSamplesAsked, UWord16 *nSamplesRendered, Word32 *output_fx[] ); static void ivas_jbm_dec_copy_masa_meta_to_buffer( Decoder_Struct *st_ivas ); @@ -117,6 +118,7 @@ ivas_error ivas_jbm_dec_tc_fx( output_frame = extract_l( Mult_32_16( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) /* output_Fs / FRAMES_PER_SEC */; + /* set pointers to transport channels audio */ FOR( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ ) { p_output_fx[n] = st_ivas->p_output_fx[n]; @@ -287,12 +289,13 @@ ivas_error ivas_jbm_dec_tc_fx( { return error; } - +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS test(); IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && st_ivas->hDecoderConfig->Opt_tsm ) { ivas_jbm_dec_copy_masa_meta_to_buffer( st_ivas ); } +#endif } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) { @@ -665,7 +668,7 @@ ivas_error ivas_jbm_dec_tc_fx( test(); /* external output */ - IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_32( st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) ) + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_32( st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) ) { FOR( n = 0; n < st_ivas->nchan_ism; n++ ) { @@ -796,756 +799,928 @@ ivas_error ivas_jbm_dec_tc_fx( output_q = 8; move16(); } - ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) - { - IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) - { + ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ){ + IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ){ ivas_omasa_rearrange_channels_fx( p_output_fx, nchan_transport_ism, output_frame ); - } - ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) - { - /* Convert separate object to MASA, combine with the original MASA, and output combined MASA + empty objects. */ - ivas_omasa_combine_separate_ism_with_masa_fx( st_ivas, p_output_fx, &output_q, st_ivas->nchan_ism, output_frame ); - } - ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) - { - /* Extract objects from MASA, output MASA + all objects (i.e., extracted and separated objects) */ - ivas_omasa_render_objects_from_mix_fx( st_ivas, p_output_fx, st_ivas->nchan_ism, output_frame, &output_q ); - } + } + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) + { + /* Convert separate object to MASA, combine with the original MASA, and output combined MASA + empty objects. */ + ivas_omasa_combine_separate_ism_with_masa_fx( st_ivas, p_output_fx, &output_q, st_ivas->nchan_ism, output_frame ); + } + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) + { + /* Extract objects from MASA, output MASA + all objects (i.e., extracted and separated objects) */ + ivas_omasa_render_objects_from_mix_fx( st_ivas, p_output_fx, st_ivas->nchan_ism, output_frame, &output_q ); + } +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + ivas_jbm_dec_copy_masa_meta_to_buffer( st_ivas ); + } +#endif +} +IF( NE_16( output_q, Q11 ) ) +{ + FOR( n = 0; n < s_max( getNumChanSynthesis( st_ivas ), nchan_transport_ism + st_ivas->nchan_transport ); n++ ) + { + Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 + } +} +} +ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) +{ + Word16 nchan_ism, sba_ch_idx; - IF( st_ivas->hDecoderConfig->Opt_tsm ) - { - ivas_jbm_dec_copy_masa_meta_to_buffer( st_ivas ); - } - } - IF( NE_16( output_q, Q11 ) ) + set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); + nchan_ism = st_ivas->nchan_ism; + move16(); + IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + { + /* set ISM parameters and decode ISM metadata in OSBA format */ + IF( NE_32( ( error = ivas_osba_ism_metadata_dec_fx( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) { - FOR( n = 0; n < s_max( getNumChanSynthesis( st_ivas ), nchan_transport_ism + st_ivas->nchan_transport ); n++ ) - { - Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 - } + return error; } + sba_ch_idx = st_ivas->nchan_ism; + move16(); } - ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) + ELSE { - Word16 nchan_ism, sba_ch_idx; - - set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); - nchan_ism = st_ivas->nchan_ism; + nb_bits_metadata[1] = add( nb_bits_metadata[1], NO_BITS_MASA_ISM_NO_OBJ ); + sba_ch_idx = 0; move16(); - IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + move16(); + } + + /* SBA metadata decoding */ + IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) ) + { + return error; + } + + test(); + IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + move32(); + } + + /* core-decoding of transport channels */ + Word16 q_output = 11; + move16(); + + IF( EQ_16( st_ivas->nSCE, 1 ) ) + { + set32_fx( p_output_fx[0], 0, L_FRAME48k ); + + IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) { - /* set ISM parameters and decode ISM metadata in OSBA format */ - IF( NE_32( ( error = ivas_osba_ism_metadata_dec_fx( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) - { - return error; - } - sba_ch_idx = st_ivas->nchan_ism; - move16(); + return error; } - ELSE + } + ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) + { + + IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, add( nb_bits_metadata[0], nb_bits_metadata[1] ) ) ), IVAS_ERR_OK ) ) { - nb_bits_metadata[1] = add( nb_bits_metadata[1], NO_BITS_MASA_ISM_NO_OBJ ); - sba_ch_idx = 0; - move16(); - move16(); + return error; } - /* SBA metadata decoding */ - IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) ) + IF( NE_16( q_output, Q11 ) ) + { + Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 + Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 + } + } + ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) + { + IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) { return error; } + } - test(); - IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) ) + IF( st_ivas->sba_dirac_stereo_flag ) + { + FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ ) { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - move32(); + Scale_sig32( p_output_fx[i + sba_ch_idx], output_frame, Q14 - Q11 ); // Q14 } - - /* core-decoding of transport channels */ - Word16 q_output = 11; + SPAR_DEC_HANDLE hSpar = st_ivas->hSpar; + Word16 nchan_transport; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + move16(); + nchan_out = nchan_transport; move16(); + ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx + sba_ch_idx ), ( p_output_fx + sba_ch_idx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - IF( EQ_16( st_ivas->nSCE, 1 ) ) + IF( st_ivas->hSpar->hPCA != NULL ) { - set32_fx( p_output_fx[0], 0, L_FRAME48k ); - - IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) - { - return error; - } + ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output_fx[sba_ch_idx] ); } - ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) + ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); { - - IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, add( nb_bits_metadata[0], nb_bits_metadata[1] ) ) ), IVAS_ERR_OK ) ) + Word16 q; + hCPE = st_ivas->hCPE[0]; + hSCE = st_ivas->hSCE[0]; + s = 0; + move16(); + FOR( i = 0; i < 2; i++ ) { - return error; + s = s_min( s, L_norm_arr( p_output_fx[sba_ch_idx + i], L_FRAME48k ) - 11 /* Guard bits */ ); } - - IF( NE_16( q_output, Q11 ) ) + FOR( i = 0; i < 2; i++ ) { - Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 - Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 + Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, s ); // Q(11+s) } - } - ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) - { - IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) ) + hCPE->hStereoDft->q_dft = add( Q11, s ); + move16(); + IF( EQ_16( hCPE->hStereoDft->first_frame, 1 ) ) { - return error; + hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; + hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; + move16(); + move16(); } - } - IF( st_ivas->sba_dirac_stereo_flag ) - { - FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ ) - { - Scale_sig32( p_output_fx[i + sba_ch_idx], output_frame, Q14 - Q11 ); // Q14 - } - SPAR_DEC_HANDLE hSpar = st_ivas->hSpar; - Word16 nchan_transport; - nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + q = hCPE->hStereoDft->q_dft; move16(); - nchan_out = nchan_transport; - move16(); - ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx + sba_ch_idx ), ( p_output_fx + sba_ch_idx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - - IF( st_ivas->hSpar->hPCA != NULL ) + scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); + FOR( i = 0; i < CPE_CHANNELS; ++i ) { - ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output_fx[sba_ch_idx] ); + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } - ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); + IF( hCPE->hCoreCoder[0] != NULL ) { - Word16 q; - hCPE = st_ivas->hCPE[0]; - hSCE = st_ivas->hSCE[0]; - s = 0; + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q + hCPE->hCoreCoder[0]->hHQ_core->Q_old_out_fx32 = q; move16(); - FOR( i = 0; i < 2; i++ ) - { - s = s_min( s, L_norm_arr( p_output_fx[sba_ch_idx + i], L_FRAME48k ) - 11 /* Guard bits */ ); - } - FOR( i = 0; i < 2; i++ ) - { - Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, s ); // Q(11+s) - } - hCPE->hStereoDft->q_dft = add( Q11, s ); + } + IF( hCPE->hStereoDft != NULL ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft + hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; move16(); - IF( EQ_16( hCPE->hStereoDft->first_frame, 1 ) ) - { - hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; - hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; - move16(); - move16(); - } + } - q = hCPE->hStereoDft->q_dft; + IF( hSCE != NULL ) + { + Scale_sig32( &hSCE->save_hb_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_hb_synth_fx ); // q_dft + hSCE->q_save_hb_synth_fx = hCPE->hStereoDft->q_dft; + move16(); + Scale_sig32( &hSCE->save_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_synth_fx ); // q_dft + hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); - scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); - FOR( i = 0; i < CPE_CHANNELS; ++i ) - { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - } - IF( hCPE->hCoreCoder[0] != NULL ) - { - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_out_fx32 = q; - move16(); - } - IF( hCPE->hStereoDft != NULL ) - { - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft - hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; - move16(); - } - - IF( hSCE != NULL ) - { - Scale_sig32( &hSCE->save_hb_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_hb_synth_fx ); // q_dft - hSCE->q_save_hb_synth_fx = hCPE->hStereoDft->q_dft; - move16(); - Scale_sig32( &hSCE->save_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_synth_fx ); // q_dft - hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; - move16(); - } - FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) - { - scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; - move16(); - } - FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx - ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame, 0 ); - FOR( i = 0; i < 2; i++ ) - { - Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, negate( s ) ); - } - - FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 - - scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - FOR( i = 0; i < CPE_CHANNELS; ++i ) - { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - } - - IF( hCPE->hCoreCoder[0] != NULL ) - { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda - } - IF( hCPE->hStereoDft != NULL ) - { - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 - hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; - move16(); - } - - FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) - { - scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - hCPE->q_output_mem_fx[ii] = Q11; - move16(); - } } - } - - /* HP filtering */ - FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); - } - - nchan_remapped = ivas_sba_remapTCs_fx( &p_output_fx[sba_ch_idx], st_ivas, output_frame ); - - test(); - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) - { - num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - SPAR_DEC_HANDLE hSpar = st_ivas->hSpar; - Word16 nchan_transport; - // num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; - nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; - move16(); - nchan_out = nchan_transport; - move16(); - Word16 Q_p_output; - Word16 min_norm = 31; - move16(); - - FOR( ch = 0; ch < nchan_transport; ++ch ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) + { + scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; + move16(); + } + FOR( i = 0; i < CPE_CHANNELS; i++ ) + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx + ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame, 0 ); + FOR( i = 0; i < 2; i++ ) { - Word16 norm = L_norm_arr( p_output_fx[sba_ch_idx + ch], output_frame ); // Normalize per channel - min_norm = s_min( norm, min_norm ); + Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, negate( s ) ); } - Q_p_output = s_max( 3, sub( min_norm, 1 ) ); + FOR( i = 0; i < CPE_CHANNELS; i++ ) + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 - Q_p_output = s_min( Q_p_output, 19 ); // to restrict Q-factor of p_ouptut to Q30 - FOR( ch = 0; ch < nchan_transport; ch++ ) + scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + FOR( i = 0; i < CPE_CHANNELS; ++i ) { - Scale_sig32( p_output_fx[sba_ch_idx + ch], output_frame, Q_p_output ); // Q_p_output + Q11 + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 } - Q_p_output = add( Q11, Q_p_output ); - hSpar->hMdDec->Q_mixer_mat = 31; - move16(); - ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, &p_output_fx[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, sub( Q_p_output, Q11 ) ); - FOR( Word16 c = 0; c < nchan_transport; c++ ) + IF( hCPE->hCoreCoder[0] != NULL ) { - Scale_sig32( p_output_fx[sba_ch_idx + c], output_frame, Q11 ); // Q11 + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda } - } - ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && st_ivas->sba_dirac_stereo_flag == 0 ) - { - Word16 size = add( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, sba_ch_idx ); - if ( EQ_16( size, 3 ) ) + IF( hCPE->hStereoDft != NULL ) { - size = add( size, 1 ); + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 + hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; + move16(); } - FOR( i = sba_ch_idx; i < size; i++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { - Scale_sig32( p_output_fx[i], output_frame, ( Q14 - Q11 ) ); // Q14 + scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + hCPE->q_output_mem_fx[ii] = Q11; + move16(); } - - ivas_spar_dec_agc_pca_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame ); } + } - test(); - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain_fx( &p_output_fx[sba_ch_idx], nchan_remapped, output_frame ); /*returns Q-1*/ + /* HP filtering */ + FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); + } - FOR( i = 0; i < nchan_remapped; i++ ) - { - Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q - } - } - ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + nchan_remapped = ivas_sba_remapTCs_fx( &p_output_fx[sba_ch_idx], st_ivas, output_frame ); + + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); + SPAR_DEC_HANDLE hSpar = st_ivas->hSpar; + Word16 nchan_transport; + // num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + move16(); + nchan_out = nchan_transport; + move16(); + Word16 Q_p_output; + Word16 min_norm = 31; + move16(); + + FOR( ch = 0; ch < nchan_transport; ++ch ) { - ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame ); + Word16 norm = L_norm_arr( p_output_fx[sba_ch_idx + ch], output_frame ); // Normalize per channel + min_norm = s_min( norm, min_norm ); + } - Scale_sig32( p_output_fx[0], L_FRAME48k, Q11 - Q8 ); // Q11 + Q_p_output = s_max( 3, sub( min_norm, 1 ) ); - /* add W */ - FOR( n = 0; n < nchan_out; n++ ) - { - v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); - } + Q_p_output = s_min( Q_p_output, 19 ); // to restrict Q-factor of p_ouptut to Q30 + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + Scale_sig32( p_output_fx[sba_ch_idx + ch], output_frame, Q_p_output ); // Q_p_output + Q11 } - } - ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) - { + Q_p_output = add( Q11, Q_p_output ); + hSpar->hMdDec->Q_mixer_mat = 31; + move16(); - // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - IF( st_ivas->nSCE > 0 ) + ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, &p_output_fx[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, sub( Q_p_output, Q11 ) ); + FOR( Word16 c = 0; c < nchan_transport; c++ ) { - st = st_ivas->hSCE[0]->hCoreCoder[0]; + Scale_sig32( p_output_fx[sba_ch_idx + c], output_frame, Q11 ); // Q11 } - ELSE + } + ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && st_ivas->sba_dirac_stereo_flag == 0 ) + { + Word16 size = add( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, sba_ch_idx ); + if ( EQ_16( size, 3 ) ) { - st = st_ivas->hCPE[0]->hCoreCoder[0]; + size = add( size, 1 ); } - IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) + FOR( i = sba_ch_idx; i < size; i++ ) { - /* LFE channel decoder */ - ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] ); + Scale_sig32( p_output_fx[i], output_frame, ( Q14 - Q11 ) ); // Q14 + } - Scale_sig32( p_output_fx[LFE_CHANNEL], L_FRAME48k, Q11 - Q9 ); // Q11 - IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, 0 ) ), IVAS_ERR_OK ) ) - { - return error; - } - /* HP filtering */ - FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + ivas_spar_dec_agc_pca_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame ); + } + + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + /* loudness correction */ + ivas_dirac_dec_binaural_sba_gain_fx( &p_output_fx[sba_ch_idx], nchan_remapped, output_frame ); /*returns Q-1*/ + + FOR( i = 0; i < nchan_remapped; i++ ) + { + Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q + } + } + ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + { + ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame ); + + Scale_sig32( p_output_fx[0], L_FRAME48k, Q11 - Q8 ); // Q11 + + /* add W */ + FOR( n = 0; n < nchan_out; n++ ) + { + v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); + } + } +} +ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) +{ + + // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + IF( st_ivas->nSCE > 0 ) + { + st = st_ivas->hSCE[0]->hCoreCoder[0]; + } + ELSE + { + st = st_ivas->hCPE[0]->hCoreCoder[0]; + } + + IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) + { + /* LFE channel decoder */ + ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] ); + + Scale_sig32( p_output_fx[LFE_CHANNEL], L_FRAME48k, Q11 - Q9 ); // Q11 + IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + /* HP filtering */ + FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + { + IF( NE_16( n, LFE_CHANNEL ) ) { - IF( NE_16( n, LFE_CHANNEL ) ) - { - hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); - } + hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); } + } - test(); - test(); - test(); - IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) + test(); + test(); + test(); + IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) + { + IF( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) ) { - IF( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) ) - { - ivas_mc2sba_fx( st_ivas->hTransSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX ); - } + ivas_mc2sba_fx( st_ivas->hTransSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX ); } + } - test(); - test(); - IF( ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) ) + test(); + test(); + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) ) + { + IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) ) { - IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) ) + s = Q16 - Q11; + move16(); + s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) ); + FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) { - s = Q16 - Q11; - move16(); - s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, s ); // Q(11+s) - } - ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 - } + Scale_sig32( p_output_fx[i], output_frame, s ); // Q(11+s) } - ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); + FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) { - ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hOutSetup.ambisonics_order, 0 ); + Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } + ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hOutSetup.ambisonics_order, 0 ); + } } - ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) - { - /* LFE channel decoder */ - ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] ); + } + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) + { + /* LFE channel decoder */ + ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] ); - Scale_sig32( p_output_fx[LFE_CHANNEL], L_FRAME48k, Q11 - Q9 ); // Q11 + Scale_sig32( p_output_fx[LFE_CHANNEL], L_FRAME48k, Q11 - Q9 ); // Q11 - ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); + ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); - IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + { + return error; + } + /* HP filtering */ + FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + { + IF( NE_16( n, LFE_CHANNEL ) ) { - return error; + hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); } - /* HP filtering */ - FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + } + + /* Rendering */ + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) ) + { + /* Compensate loudness for not doing full upmix */ + FOR( n = 4; n < 8; n++ ) { - IF( NE_16( n, LFE_CHANNEL ) ) - { - hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); - } + Scale_sig32( p_output_fx[n], output_frame, 1 ); } - /* Rendering */ - test(); test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) ) + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) { - /* Compensate loudness for not doing full upmix */ - FOR( n = 4; n < 8; n++ ) + s = Q16 - Q11; + move16(); + Word16 nchan_transport; + nchan_transport = audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ); + s = sub( s, find_guarded_bits_fx( nchan_transport ) ); + FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i ) { - Scale_sig32( p_output_fx[n], output_frame, 1 ); + Scale_sig32( p_output_fx[i], output_frame, s ); } - - test(); - IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) + ivas_ls_setup_conversion_fx( st_ivas, nchan_transport, output_frame, p_output_fx, p_output_fx ); + FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i ) { - s = Q16 - Q11; - move16(); - Word16 nchan_transport; - nchan_transport = audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ); - s = sub( s, find_guarded_bits_fx( nchan_transport ) ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, s ); - } - ivas_ls_setup_conversion_fx( st_ivas, nchan_transport, output_frame, p_output_fx, p_output_fx ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); - } + Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); } } } - ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) + } + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) + { + /* read Parametric MC parameters from the bitstream */ + ivas_param_mc_dec_read_BS_fx( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] ); + + IF( EQ_16( st_ivas->nCPE, 1 ) ) { - /* read Parametric MC parameters from the bitstream */ - ivas_param_mc_dec_read_BS_fx( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] ); + Word16 q_output = 11; + move16(); - IF( EQ_16( st_ivas->nCPE, 1 ) ) + IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) { - Word16 q_output = 11; - move16(); - - IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) - { - return error; - } - IF( NE_16( q_output, Q11 ) ) - { - Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 - Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 - } + return error; } - ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) + IF( NE_16( q_output, Q11 ) ) { - IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) - { - return error; - } + Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 + Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 } - - /* HP filtering */ - FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + } + ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) + { + IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) { - hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); + return error; } + } - /* Rendering */ - test(); - IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) - { - ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); - } + /* HP filtering */ + FOR( n = 0; n < st_ivas->nchan_transport; n++ ) + { + hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); } - ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + + /* Rendering */ + test(); + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) { - IF( st_ivas->hOutSetup.separateChannelEnabled ) - { - st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ - } + ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); + } + } + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + IF( st_ivas->hOutSetup.separateChannelEnabled ) + { + st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ + } - /* read McMASA parameters from the bitstream */ + /* read McMASA parameters from the bitstream */ - IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + { + return error; + } + + IF( st_ivas->hOutSetup.separateChannelEnabled ) + { + /* Decode the transport audio signals */ + Word16 q_output = 11; + move16(); + + IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) { return error; } - - IF( st_ivas->hOutSetup.separateChannelEnabled ) + IF( NE_16( q_output, Q11 ) ) { - /* Decode the transport audio signals */ - Word16 q_output = 11; - move16(); - - IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) - { - return error; - } - IF( NE_16( q_output, Q11 ) ) - { - Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 - Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 - } + Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 + Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 + } - /* Identify the index of the separated channel, always LFE_CHANNEL-1 here */ - n = LFE_CHANNEL - 1; - move16(); + /* Identify the index of the separated channel, always LFE_CHANNEL-1 here */ + n = LFE_CHANNEL - 1; + move16(); - /* Decode the separated channel to output[n] to be combined with the synthesized channels */ + /* Decode the separated channel to output[n] to be combined with the synthesized channels */ - set32_fx( p_output_fx[n], 0, L_FRAME48k ); + set32_fx( p_output_fx[n], 0, L_FRAME48k ); - IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[n], output_frame, 0 ) ), IVAS_ERR_OK ) ) - { - return error; - } - test(); - test(); - test(); - test(); - test(); - test(); - test(); - /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ - IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) || - EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) - { - ivas_lfe_synth_with_filters_fx( st_ivas->hMasa->hMasaLfeSynth, p_output_fx, output_frame, n, LFE_CHANNEL ); - } - ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 ) - { - /* Delay the separated channel to sync with the DirAC rendering */ - delay_signal32_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); - } + IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[n], output_frame, 0 ) ), IVAS_ERR_OK ) ) + { + return error; } - ELSE + test(); + test(); + test(); + test(); + test(); + test(); + test(); + /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) || + EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) { - Word16 q_output = 11; - move16(); - IF( EQ_16( st_ivas->nSCE, 1 ) ) - { - set32_fx( p_output_fx[0], 0, L_FRAME48k ); - - IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) - { - - IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) - { - return error; - } - IF( NE_16( q_output, Q11 ) ) - { - Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 - Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 - } - } + ivas_lfe_synth_with_filters_fx( st_ivas->hMasa->hMasaLfeSynth, p_output_fx, output_frame, n, LFE_CHANNEL ); } - - IF( st_ivas->sba_dirac_stereo_flag != 0 ) /* use the flag to trigger the DFT upmix */ + ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 ) { - Word16 q; - hCPE = st_ivas->hCPE[0]; - hSCE = st_ivas->hSCE[0]; - s = 0; - move16(); - FOR( i = 0; i < 2; i++ ) - { - s = s_min( s, L_norm_arr( p_output_fx[i], L_FRAME48k ) - 11 /* Guard bits */ ); - } - FOR( i = 0; i < 2; i++ ) - { - Scale_sig32( p_output_fx[i], L_FRAME48k, s ); // Q(11+s) - } - - hCPE->hStereoDft->q_dft = add( Q11, s ); - move16(); - IF( EQ_16( hCPE->hStereoDft->first_frame, 1 ) ) - { - hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; - hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; - - move16(); - move16(); - } - - q = hCPE->hStereoDft->q_dft; - move16(); - - scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); - FOR( i = 0; i < CPE_CHANNELS; ++i ) - { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - } - - IF( hCPE->hCoreCoder[0] != NULL ) - { - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_out_fx32 = q; - move16(); - } - IF( hCPE->hStereoDft != NULL ) - { - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft - hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; - move16(); - } - IF( st_ivas->hSpar != NULL ) - { - st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; - move16(); - } - - IF( hSCE != NULL ) - { - Scale_sig32( &hSCE->save_hb_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_hb_synth_fx ); // q_dft - hSCE->q_save_hb_synth_fx = hCPE->hStereoDft->q_dft; - move16(); - Scale_sig32( &hSCE->save_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_synth_fx ); // q_dft - hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; - move16(); - } - FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) - { - scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); // q_dft - hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; - move16(); - } - FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx - ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, 1 ); - FOR( i = 0; i < 2; i++ ) - { - Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); - } - FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 + /* Delay the separated channel to sync with the DirAC rendering */ + delay_signal32_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); + } + } + ELSE + { + Word16 q_output = 11; + move16(); + IF( EQ_16( st_ivas->nSCE, 1 ) ) + { + set32_fx( p_output_fx[0], 0, L_FRAME48k ); - scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); - FOR( i = 0; i < CPE_CHANNELS; ++i ) + IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + return error; } + } + ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) + { - IF( hCPE->hCoreCoder[0] != NULL ) - { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda - } - IF( hCPE->hStereoDft != NULL ) + IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) { - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 - hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; - move16(); + return error; } - IF( st_ivas->hSpar != NULL ) + IF( NE_16( q_output, Q11 ) ) { - FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) - { - scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - hCPE->q_output_mem_fx[ii] = Q11; - move16(); - } + Scale_sig32( p_output_fx[0], output_frame, sub( Q11, q_output ) ); // Q11 + Scale_sig32( p_output_fx[1], output_frame, sub( Q11, q_output ) ); // Q11 } } + } - /* HP filtering */ - FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + IF( st_ivas->sba_dirac_stereo_flag != 0 ) /* use the flag to trigger the DFT upmix */ + { + Word16 q; + hCPE = st_ivas->hCPE[0]; + hSCE = st_ivas->hSCE[0]; + s = 0; + move16(); + FOR( i = 0; i < 2; i++ ) { - hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); + s = s_min( s, L_norm_arr( p_output_fx[i], L_FRAME48k ) - 11 /* Guard bits */ ); + } + FOR( i = 0; i < 2; i++ ) + { + Scale_sig32( p_output_fx[i], L_FRAME48k, s ); // Q(11+s) + } + + hCPE->hStereoDft->q_dft = add( Q11, s ); + move16(); + IF( EQ_16( hCPE->hStereoDft->first_frame, 1 ) ) + { + hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; + hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; + + move16(); + move16(); + } + + q = hCPE->hStereoDft->q_dft; + move16(); + + scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); + FOR( i = 0; i < CPE_CHANNELS; ++i ) + { + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + } + + IF( hCPE->hCoreCoder[0] != NULL ) + { + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q + hCPE->hCoreCoder[0]->hHQ_core->Q_old_out_fx32 = q; + move16(); + } + IF( hCPE->hStereoDft != NULL ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft + hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; + move16(); + } + IF( st_ivas->hSpar != NULL ) + { + st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; + move16(); + } + + IF( hSCE != NULL ) + { + Scale_sig32( &hSCE->save_hb_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_hb_synth_fx ); // q_dft + hSCE->q_save_hb_synth_fx = hCPE->hStereoDft->q_dft; + move16(); + Scale_sig32( &hSCE->save_synth_fx[0], extract_l( Mpy_32_32( hCPE->hCoreCoder[0]->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), hCPE->hStereoDft->q_dft - hSCE->q_save_synth_fx ); // q_dft + hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; + move16(); + } + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) + { + scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); // q_dft + hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; + move16(); + } + FOR( i = 0; i < CPE_CHANNELS; i++ ) + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx + ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, 1 ); + FOR( i = 0; i < 2; i++ ) + { + Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); + } + FOR( i = 0; i < CPE_CHANNELS; i++ ) + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 + + scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); + FOR( i = 0; i < CPE_CHANNELS; ++i ) + { + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 } - IF( EQ_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) ) + IF( hCPE->hCoreCoder[0] != NULL ) + { + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda + } + IF( hCPE->hStereoDft != NULL ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 + hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; + move16(); + } + IF( st_ivas->hSpar != NULL ) { - ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) + { + scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + hCPE->q_output_mem_fx[ii] = Q11; + move16(); + } } } + + /* HP filtering */ + FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs ); + } + + IF( EQ_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) ) + { + ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); + } } +} - /*----------------------------------------------------------------* - * Write IVAS transport channels - *----------------------------------------------------------------*/ +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS +/*----------------------------------------------------------------* + * Write IVAS transport channels + *----------------------------------------------------------------*/ #ifdef LIB_DEC_REVISION - IF( st_ivas->hDecoderConfig->Opt_tsm == 0 ) +IF( st_ivas->hDecoderConfig->Opt_tsm == 0 ) #else - IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) +IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) +{ + ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); +} +ELSE +#endif +{ + /* directly copy to tc buffers */ + /*note : the q of cldfb buffers (imag/real) are needed to be Q_p_output - 5 here 6 is taken for that*/ + ivas_jbm_dec_copy_tc_no_tsm_fx( st_ivas, p_output_fx, output_frame ); +} +#endif +/*----------------------------------------------------------------* + * Common updates + *----------------------------------------------------------------*/ + +IF( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */ +{ + st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate; + move32(); + IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) ) { - ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); + st_ivas->last_active_ivas_total_brate = st_ivas->last_active_ivas_total_brate; + move32(); } ELSE -#endif { - /* directly copy to tc buffers */ - /*note : the q of cldfb buffers (imag/real) are needed to be Q_p_output - 5 here 6 is taken for that*/ - ivas_jbm_dec_copy_tc_no_tsm_fx( st_ivas, p_output_fx, output_frame ); + st_ivas->last_active_ivas_total_brate = ivas_total_brate; + move32(); } +} - /*----------------------------------------------------------------* - * Common updates - *----------------------------------------------------------------*/ +test(); +test(); +if ( LT_16( st_ivas->ini_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */ +{ + st_ivas->ini_frame = add( st_ivas->ini_frame, 1 ); + move16(); +} + +test(); +test(); +if ( LT_16( st_ivas->ini_active_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ +{ + st_ivas->ini_active_frame = add( st_ivas->ini_active_frame, 1 ); + move16(); +} + +st_ivas->last_ivas_format = st_ivas->ivas_format; +move32(); +pop_wmops(); + +return IVAS_ERR_OK; +} + + +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + +/*--------------------------------------------------------------------------* + * ivas_dec_feed_tc_to_renderer() + * + * Feed decoded transport channels to the IVAS renderer routine + * + digest TC channels in ParamISM and ParamMC + *--------------------------------------------------------------------------*/ + +void ivas_jbm_dec_feed_tc_to_renderer_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const Word16 nSamplesForRendering, /* i : number of TC samples available for rendering */ + Word16 *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/ + Word32 *data /* i : transport channels */ +) +{ + Word32 data_fx[MAX_CLDFB_DIGEST_CHANNELS][MAX_JBM_L_FRAME48k]; /* buffer for transport channels that will be directly converted with the CLDFB */ + Word32 *p_data_fx[MAX_CLDFB_DIGEST_CHANNELS]; + Word16 n, n_render_timeslots, n_ch_cldfb; + Word16 ch; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + hTcBuffer = st_ivas->hTcBuffer; + n_ch_cldfb = sub( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + move16(); - IF( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */ + IF( st_ivas->hDecoderConfig->Opt_tsm ) { - st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate; - move32(); - IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) ) + Word16 n_samples_still_available, m; + Word16 n_ch_full_copy; + Word16 n_ch_res_copy; + + FOR( n = 0; n < n_ch_cldfb; n++ ) { - st_ivas->last_active_ivas_total_brate = st_ivas->last_active_ivas_total_brate; - move32(); + p_data_fx[n] = &data_fx[n][0]; } - ELSE + + n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered ); + hTcBuffer->n_samples_buffered = add( add( n_samples_still_available, nSamplesForRendering ), hTcBuffer->n_samples_discard ); + hTcBuffer->n_samples_available = i_mult( hTcBuffer->n_samples_granularity, idiv1616( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_granularity ) ); + *nSamplesResidual = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_available ); + move16(); + move16(); + move16(); + n_ch_full_copy = s_min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + n_ch_res_copy = sub( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + + FOR( ch = 0; ch < n_ch_full_copy; ch++ ) { - st_ivas->last_active_ivas_total_brate = ivas_total_brate; - move32(); + set32_fx( hTcBuffer->tc_fx[ch], 0, hTcBuffer->n_samples_discard ); + Copy32( hTcBuffer->tc_fx[ch] + hTcBuffer->n_samples_rendered, hTcBuffer->tc_fx[ch] + hTcBuffer->n_samples_discard, n_samples_still_available ); + FOR( m = 0; m < nSamplesForRendering; m++ ) + { + hTcBuffer->tc_fx[ch][n_samples_still_available + hTcBuffer->n_samples_discard + m] = data[m * hTcBuffer->nchan_transport_jbm + ch]; + move32(); + } } - } - test(); - test(); - if ( LT_16( st_ivas->ini_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */ + IF( n_ch_res_copy > 0 ) + { + FOR( ; ch < hTcBuffer->nchan_transport_jbm; ch++ ) + { + Copy32( hTcBuffer->tc_fx[ch], p_data_fx[ch], n_samples_still_available ); + + FOR( m = 0; m < nSamplesForRendering; m++ ) + { + p_data_fx[ch][n_samples_still_available + m] = data[m * hTcBuffer->nchan_transport_jbm + ch]; + move32(); + } + Copy32( p_data_fx[ch] + hTcBuffer->n_samples_available, hTcBuffer->tc_fx[ch], *nSamplesResidual ); + } + } + + n_render_timeslots = idiv1616( st_ivas->hTcBuffer->n_samples_available, st_ivas->hTcBuffer->n_samples_granularity ); + } + ELSE { - st_ivas->ini_frame = add( st_ivas->ini_frame, 1 ); + FOR( n = 0; n < n_ch_cldfb; n++ ) + { + p_data_fx[n] = &st_ivas->p_output_fx[n][0]; + move16(); + } + + FOR( n = 0; n < ivas_get_nchan_buffers_dec_fx( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) + { + hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; /* note: buffers needed in the TD decorellator */ + move16(); + } + + hTcBuffer->n_samples_buffered = nSamplesForRendering; + hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered; + *nSamplesResidual = 0; + move16(); + move16(); + move16(); + + n_render_timeslots = DEFAULT_JBM_CLDFB_TIMESLOTS; move16(); } + /* CLDFB analysis for ParamMC/ParamISM */ + test(); + test(); test(); test(); - if ( LT_16( st_ivas->ini_active_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ + test(); + test(); + IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) ) + { + ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_fx, Q11 ); + } + ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER ) { - st_ivas->ini_active_frame = add( st_ivas->ini_active_frame, 1 ); + Word16 nchan_transport = st_ivas->nchan_transport; + move16(); + Word16 nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + Word16 nchan_out_cov; + + test(); + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + } + ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + } + + scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, -1 ); // Q(31-1) + st_ivas->hParamMC->proto_matrix_int_e = 1; move16(); + + ivas_param_mc_dec_digest_tc_fx( st_ivas, (uint8_t) n_render_timeslots, p_data_fx, Q11 ); + + scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, 1 ); // Q(31-1+1) + + Word16 shift, param_band_idx; + FOR( param_band_idx = 0; param_band_idx < st_ivas->hParamMC->num_param_bands_synth; param_band_idx++ ) + { + shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, nchan_transport * nchan_transport ) ); + scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, i_mult( nchan_transport, nchan_transport ) ), shift ); // Q(31-cx_old_e+shift) + st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], shift ); + move16(); + + shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], nchan_out_cov * nchan_out_cov ); + scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], i_mult( nchan_out_cov, nchan_out_cov ), shift ); // Q(31-cy_old_e+shift) + st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], shift ); + move16(); + } } - st_ivas->last_ivas_format = st_ivas->ivas_format; - move32(); - pop_wmops(); + hTcBuffer->n_samples_rendered = 0; + move16(); + hTcBuffer->subframes_rendered = 0; + move16(); - return IVAS_ERR_OK; + return; } +#else /*--------------------------------------------------------------------------* * ivas_jbm_dec_feed_tc_to_renderer() @@ -1620,7 +1795,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE #endif - IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) ) + IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) ) { /* Rendering */ IF( EQ_16( st_ivas->ism_mode, ISM_MODE_PARAM ) ) @@ -1637,7 +1812,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE #endif - IF( EQ_16( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + IF( EQ_16( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) { ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_f_fx, Q11 ); @@ -1892,6 +2067,8 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( return; } +#endif + /*--------------------------------------------------------------------------* * ivas_dec_render() * @@ -1918,7 +2095,9 @@ ivas_error ivas_jbm_dec_render_fx( Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch; const Word16 output_q_factor = Q11; move16(); +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; +#endif Word16 nchan_out_syn_output; push_wmops( "ivas_dec_render" ); @@ -1926,7 +2105,9 @@ ivas_error ivas_jbm_dec_render_fx( * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS hSpatParamRendCom = st_ivas->hSpatParamRendCom; +#endif output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hDecoderConfig->nchan_out; @@ -1942,28 +2123,36 @@ ivas_error ivas_jbm_dec_render_fx( { p_output_fx[n] = st_ivas->p_output_fx[n]; } + IF( !st_ivas->hDecoderConfig->Opt_tsm ) { +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS FOR( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc_fx[n] = &p_output_fx[n][st_ivas->hTcBuffer->n_samples_rendered]; } - +#endif FOR( n = 0; n < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { st_ivas->hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; } } + +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS ELSE { +#endif FOR( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc_fx[n] = &st_ivas->hTcBuffer->tc_fx[n][st_ivas->hTcBuffer->n_samples_rendered]; } +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS } +#endif st_ivas->hTcBuffer->no_channels = st_ivas->hTcBuffer->nchan_buffer_full; move16(); + /*----------------------------------------------------------------* * Update combined orientation access index *----------------------------------------------------------------*/ @@ -2067,7 +2256,11 @@ ivas_error ivas_jbm_dec_render_fx( } } +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + ivas_ism2sba_sf_fx( p_tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); +#else ivas_ism2sba_sf_fx( st_ivas->hTcBuffer->tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); +#endif Word16 sba_num_chans = imult1616( add( st_ivas->hIntSetup.ambisonics_order, 1 ), add( st_ivas->hIntSetup.ambisonics_order, 1 ) ); FOR( j = 0; j < sba_num_chans; j++ ) @@ -2284,7 +2477,7 @@ ivas_error ivas_jbm_dec_render_fx( return error; } } - ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/ + ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/ { IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) ) { @@ -2293,7 +2486,11 @@ ivas_error ivas_jbm_dec_render_fx( FOR( n = 0; n < st_ivas->nchan_ism; n++ ) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Copy32( p_tc_fx[n], p_output_fx[n], *nSamplesRendered ); +#else Copy32( st_ivas->hTcBuffer->tc_fx[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output_fx[n], *nSamplesRendered ); +#endif } } ELSE @@ -2307,6 +2504,7 @@ ivas_error ivas_jbm_dec_render_fx( ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx ); + FOR( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ ) { scale_sig32( p_output_fx[n], *nSamplesRendered, 1 ); @@ -2319,7 +2517,7 @@ ivas_error ivas_jbm_dec_render_fx( return error; } - IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) { FOR( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) { @@ -2338,12 +2536,12 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS FOR( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc_fx[n] = &st_ivas->hTcBuffer->tc_fx[n][st_ivas->hTcBuffer->n_samples_rendered]; } - +#endif IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) { Word16 crendInPlaceRotation = FALSE; @@ -2647,7 +2845,9 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) { +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS Word16 offset = imult1616( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->slot_size ); +#endif nchan_remapped = st_ivas->nchan_transport; move16(); @@ -2670,7 +2870,11 @@ ivas_error ivas_jbm_dec_render_fx( /* we still need to copy the separate channel if available */ IF( st_ivas->hOutSetup.separateChannelEnabled ) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else Copy32( st_ivas->hTcBuffer->tc_fx[LFE_CHANNEL - 1] + offset, p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); @@ -2698,13 +2902,22 @@ ivas_error ivas_jbm_dec_render_fx( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( st_ivas->hOutSetup.num_lfe, 0 ) ) ) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Copy32( p_tc_fx[LFE_CHANNEL], p_output_fx[LFE_CHANNEL], *nSamplesRendered ); + Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else Copy32( st_ivas->hTcBuffer->tc_fx[LFE_CHANNEL] + offset, p_output_fx[LFE_CHANNEL], *nSamplesRendered ); Copy32( st_ivas->hTcBuffer->tc_fx[LFE_CHANNEL - 1] + offset, p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 ) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else /* Delay the separated channel to sync with the DirAC rendering */ Copy32( st_ivas->hTcBuffer->tc_fx[LFE_CHANNEL - 1] + offset, p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } } } @@ -3569,6 +3782,8 @@ Word16 ivas_jbm_dec_get_num_tc_channels_fx( return num_tc; } +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS + /*--------------------------------------------------------------------------* * ivas_jbm_dec_copy_tc() * @@ -3634,6 +3849,8 @@ static void ivas_jbm_dec_copy_tc( return; } +#endif + /*--------------------------------------------------------------------------* * ivas_jbm_dec_get_render_granularity() * @@ -4054,11 +4271,13 @@ void ivas_jbm_dec_tc_buffer_close_fx( return; } + /*--------------------------------------------------------------------------* * ivas_jbm_dec_td_renderers_adapt_subframes() * * Close JBM transport channel buffer *--------------------------------------------------------------------------*/ + void ivas_jbm_dec_td_renderers_adapt_subframes( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) @@ -4125,6 +4344,8 @@ void ivas_jbm_dec_td_renderers_adapt_subframes( return; } + + /*--------------------------------------------------------------------------* * ivas_jbm_dec_get_tc_buffer_mode() * @@ -4136,6 +4357,7 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode_fx( ) { TC_BUFFER_MODE buffer_mode; + buffer_mode = TC_BUFFER_MODE_BUFFER; move16(); @@ -4233,6 +4455,7 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode_fx( return buffer_mode; } +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS /*--------------------------------------------------------------------------* * ivas_jbm_dec_copy_tc_no_tsm() @@ -4324,6 +4547,8 @@ void ivas_jbm_dec_copy_tc_no_tsm_fx( return; } +#endif + /*--------------------------------------------------------------------------* * ivas_jbm_dec_metadata_open() * @@ -4334,10 +4559,12 @@ ivas_error ivas_jbm_dec_metadata_open( Decoder_Struct *st_ivas ) { JBM_METADATA_HANDLE hJbmMetadata; + IF( ( hJbmMetadata = (JBM_METADATA_HANDLE) malloc( sizeof( JBM_METADATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM metadata handle\n" ) ); } + hJbmMetadata->sf_write_idx = 0; move16(); hJbmMetadata->sf_md_buffer_length = MASA_JBM_RINGBUFFER_FRAMES * MAX_PARAM_SPATIAL_SUBFRAMES; diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 8741769c8..39473139d 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1525,8 +1525,13 @@ void ivas_param_mc_dec_digest_tc_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord8 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ Word32 *p_data_fx[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const Word16 transport_f_e ) + const Word16 q_data /* i : Q-factor of input signal for single channel */ +) { +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + Word16 ch, num_freq_bands, slot_idx, cldfb_ch, n_ch_cldfb; + Word32 *cldfb_real_buffer, *cldfb_imag_buffer; +#else PARAM_MC_DEC_HANDLE hParamMC; #ifdef OBJ_EDITING_API Word16 ch, slot_idx; @@ -1562,18 +1567,26 @@ void ivas_param_mc_dec_digest_tc_fx( /* format converter */ Word16 channel_active[MAX_OUTPUT_CHANNELS]; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; +#endif #endif Word16 qout = 0; move16(); + /* Initialization */ +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + num_freq_bands = st_ivas->hParamMC->num_freq_bands; + move16(); + n_ch_cldfb = sub( st_ivas->hTcBuffer->nchan_transport_jbm, st_ivas->hTcBuffer->nchan_buffer_full ); - push_wmops( "param_mc_dec_digest_tc" ); - + cldfb_real_buffer = st_ivas->hParamMC->Cldfb_RealBuffer_tc_fx; + cldfb_imag_buffer = st_ivas->hParamMC->Cldfb_ImagBuffer_tc_fx; +#else #ifndef OBJ_EDITING_API set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); #endif nchan_transport = st_ivas->nchan_transport; move16(); +#endif #ifndef OBJ_EDITING_API nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); @@ -1654,2448 +1667,2468 @@ void ivas_param_mc_dec_digest_tc_fx( move16(); #endif - /* slot loop for gathering the input data */ - FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + /* CLDFB Analysis */ + FOR( ( ch = 0, cldfb_ch = 0 ); cldfb_ch < n_ch_cldfb; ( cldfb_ch++, ch++ ) ) { - IF( st_ivas->hDecoderConfig->Opt_tsm ) + qout = q_data; + move16(); + + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { + cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][num_freq_bands * slot_idx] ), + &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch], &qout ); + } + + st_ivas->hParamMC->Cldfb_ImagBuffer_tc_e = qout; + move16(); + } +#else + + /* slot loop for gathering the input data */ + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { #ifndef OBJ_EDITING_API - IF( param_band_idx == 0 ) /* only run cldfbAna once */ - { + IF( param_band_idx == 0 ) /* only run cldfbAna once */ + { #endif - Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX]; - Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX]; - /* CLDFB Analysis*/ - FOR( ch = 0; ch < nchan_transport; ch++ ) - { - qout = transport_f_e; - move16(); - cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &qout ); + /* CLDFB Analysis*/ + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + qout = transport_f_e; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &qout ); - Copy32( RealBuffer_fx, &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - Copy32( ImagBuffer_fx, &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - } + Copy32( RealBuffer_fx, &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + Copy32( ImagBuffer_fx, &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + } - hParamMC->Cldfb_ImagBuffer_tc_e = qout; - move16(); + hParamMC->Cldfb_ImagBuffer_tc_e = qout; + move16(); #ifndef OBJ_EDITING_API - } -#endif } +#endif + } #ifndef OBJ_EDITING_API - IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) + IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) + { + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + test(); + IF( is_next_band && skip_next_band ) { - test(); - IF( is_next_band && skip_next_band ) - { - CONTINUE; - } - IF( is_next_band ) - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_next_band_fx, - &cx_next_band_e, - cx_imag_next_band_fx, - &cx_imag_next_band_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); - } - ELSE - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_fx, - &cx_e, - cx_imag_fx, - &cx_imag_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); - } + CONTINUE; + } + IF( is_next_band ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_next_band_fx, + &cx_next_band_e, + cx_imag_next_band_fx, + &cx_imag_next_band_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + ELSE + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_fx, + &cx_e, + cx_imag_fx, + &cx_imag_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); } } -#endif } +#endif + } #ifndef OBJ_EDITING_API - Word16 tmp_cx_e, tmp_cx_imag_e; - /* map from complex input covariance to real values */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + Word16 tmp_cx_e, tmp_cx_imag_e; + /* map from complex input covariance to real values */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) { - test(); - IF( is_next_band && skip_next_band ) - { - CONTINUE; - } - /* Cx for transport channels */ - IF( is_next_band ) + CONTINUE; + } + /* Cx for transport channels */ + IF( is_next_band ) + { + pCx = &cx_next_band_fx[0]; + pCx_imag = &cx_imag_next_band_fx[0]; + tmp_cx_e = cx_next_band_e; + tmp_cx_imag_e = cx_imag_next_band_e; + } + ELSE + { + pCx = &cx_fx[0]; + pCx_imag = &cx_imag_fx[0]; + tmp_cx_e = cx_e; + tmp_cx_imag_e = cx_imag_e; + } + + FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part_fx = pCx[i]; // Q(31 - cx_buff_e) + imag_part_fx = pCx_imag[i]; + move32(); + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) { - pCx = &cx_next_band_fx[0]; - pCx_imag = &cx_imag_next_band_fx[0]; - tmp_cx_e = cx_next_band_e; - tmp_cx_imag_e = cx_imag_next_band_e; + L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); + L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); + pCx[i] = Sqrt32( L_tmp1, &tmp_e ); + move32(); + cx_buff_e[is_next_band][i] = tmp_e; + move16(); } ELSE { - pCx = &cx_fx[0]; - pCx_imag = &cx_imag_fx[0]; - tmp_cx_e = cx_e; - tmp_cx_imag_e = cx_imag_e; - } - - FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) - { - real_part_fx = pCx[i]; // Q(31 - cx_buff_e) - imag_part_fx = pCx_imag[i]; - move32(); + pCx[i] = real_part_fx; move32(); cx_buff_e[is_next_band][i] = tmp_cx_e; move16(); - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ - IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) - { - L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); - L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); - pCx[i] = Sqrt32( L_tmp1, &tmp_e ); - move32(); - cx_buff_e[is_next_band][i] = tmp_e; - move16(); - } - ELSE - { - pCx[i] = real_part_fx; - move32(); - cx_buff_e[is_next_band][i] = tmp_cx_e; - move16(); - } } } + } - max_e = cx_buff_e[0][0]; - move16(); + max_e = cx_buff_e[0][0]; + move16(); - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) - { - IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) - { - max_e = cx_buff_e[is_next_band][i]; - } + IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) + { + max_e = cx_buff_e[is_next_band][i]; } } - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + } + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + if ( is_next_band == 0 ) { - if ( is_next_band == 0 ) - { - cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); - } - else - { - cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); - } - move32(); + cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + else + { + cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); } + move32(); } - cx_e = max_e; - move16(); + } + cx_e = max_e; + move16(); - /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + test(); + test(); + IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) + { + Word16 len = imult1616( nchan_transport, nchan_transport ); + Word16 sc = s_min( getScaleFactor32( cx_fx, len ), getScaleFactor32( cx_next_band_fx, len ) ); + IF( EQ_16( sc, 0 ) ) + { + Scale_sig32( cx_fx, len, -Q1 ); // add one bit head room + Scale_sig32( cx_next_band_fx, len, -Q1 ); // add one bit head room + cx_e = add( cx_e, Q1 ); + cx_next_band_e = add( cx_e, Q1 ); + } + v_add_fx( cx_fx, cx_next_band_fx, cx_fx, len ); + Copy32( cx_fx, cx_next_band_fx, len ); + } + + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { test(); - test(); - IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) + IF( is_next_band && skip_next_band ) { - Word16 len = imult1616( nchan_transport, nchan_transport ); - Word16 sc = s_min( getScaleFactor32( cx_fx, len ), getScaleFactor32( cx_next_band_fx, len ) ); - IF( EQ_16( sc, 0 ) ) - { - Scale_sig32( cx_fx, len, -Q1 ); // add one bit head room - Scale_sig32( cx_next_band_fx, len, -Q1 ); // add one bit head room - cx_e = add( cx_e, Q1 ); - cx_next_band_e = add( cx_e, Q1 ); - } - v_add_fx( cx_fx, cx_next_band_fx, cx_fx, len ); - Copy32( cx_fx, cx_next_band_fx, len ); + CONTINUE; } - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) { - test(); - IF( is_next_band && skip_next_band ) + IF( is_next_band ) { - CONTINUE; - } - IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + ELSE { - IF( is_next_band ) - { - - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); - } - ELSE - { - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); - } + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); } } } +} +#endif #endif - pop_wmops(); - return; -} + return; + } #ifdef OBJ_EDITING_API -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_prepare_renderer() - * - * - *------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------- + * ivas_param_mc_dec_prepare_renderer() + * + * + *------------------------------------------------------------------------*/ -void ivas_param_mc_dec_prepare_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord8 nCldfbSlots /* i : number of CLDFB slots in transport channels */ -) -{ - Word16 i; - Word16 is_next_band, skip_next_band; - Word16 slot_idx, param_band_idx; - Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; - Word16 nchan_out_cov; - PARAM_MC_DEC_HANDLE hParamMC; + void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots /* i : number of CLDFB slots in transport channels */ + ) + { + Word16 i; + Word16 is_next_band, skip_next_band; + Word16 slot_idx, param_band_idx; + Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; + Word16 nchan_out_cov; + PARAM_MC_DEC_HANDLE hParamMC; - Word32 *pCx, *pCx_imag; - Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) - Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) - Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) - Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) - Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; + Word32 *pCx, *pCx_imag; + Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) + Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) + Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) + Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) + Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; - Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word16 cx_e; - Word16 cx_imag_e, tmp_e; - Word16 cx_imag_next_band_e, cx_next_band_e; + Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 cx_e; + Word16 cx_imag_e, tmp_e; + Word16 cx_imag_next_band_e, cx_next_band_e; - Word16 max_e; + Word16 max_e; - /* format converter */ - Word16 channel_active[MAX_OUTPUT_CHANNELS]; - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; - hParamMC = st_ivas->hParamMC; - assert( hParamMC ); + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); - set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); + set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_transport = st_ivas->nchan_transport; - move16(); + nchan_transport = st_ivas->nchan_transport; + move16(); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - test(); - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - nchan_out_cldfb = BINAURAL_CHANNELS; - move16(); - set16_fx( channel_active, 1, nchan_out_cldfb ); - nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } - ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - nchan_out_cov = nchan_out_transport; + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + move16(); + set16_fx( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + nchan_out_cldfb = nchan_out_cov; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = nchan_out_transport; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + IF( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = s_max( 0, add( hParamMC->hMetadataPMC->attackIndex, shr( sub( nCldfbSlots, DEFAULT_JBM_CLDFB_TIMESLOTS ), 1 ) ) ); + move16(); + } + + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; move16(); - nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } - ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - nchan_out_cldfb = nchan_out_cov; + hParamMC->slots_rendered = 0; move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hOutSetup; - } - ELSE - { - nchan_out_cov = nchan_out_transport; + hParamMC->subframes_rendered = 0; move16(); - nchan_out_cldfb = nchan_out_transport; + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } + Copy( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); - /* adapt transient position */ - IF( hParamMC->hMetadataPMC->bAttackPresent ) - { - hParamMC->hMetadataPMC->attackIndex = s_max( 0, add( hParamMC->hMetadataPMC->attackIndex, shr( sub( nCldfbSlots, DEFAULT_JBM_CLDFB_TIMESLOTS ), 1 ) ) ); - move16(); - } + ivas_param_mc_dec_compute_interpolator_fx( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator_fx ); - /* adapt subframes */ - hParamMC->num_slots = nCldfbSlots; - move16(); - hParamMC->slots_rendered = 0; - move16(); - hParamMC->subframes_rendered = 0; - move16(); - ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); - st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; - move16(); - Copy( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); + /* loop over two bands at a time */ + FOR( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) + { + /* don't process next band if it exceeds the limit */ + skip_next_band = ( ( param_band_idx + 1 ) == hParamMC->num_param_bands_synth ) ? 1 : 0; - ivas_param_mc_dec_compute_interpolator_fx( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator_fx ); + set_zero_fx( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - /* loop over two bands at a time */ - FOR( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) - { - /* don't process next band if it exceeds the limit */ - skip_next_band = ( ( param_band_idx + 1 ) == hParamMC->num_param_bands_synth ) ? 1 : 0; + cx_e = 0; + move16(); + cx_imag_e = 0; + move16(); + cx_next_band_e = 0; + move16(); + cx_imag_next_band_e = 0; + move16(); - set_zero_fx( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_imag_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - - cx_e = 0; - move16(); - cx_imag_e = 0; - move16(); - cx_next_band_e = 0; - move16(); - cx_imag_next_band_e = 0; - move16(); - - /* slot loop for gathering the input data */ - FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) - { - IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) + /* slot loop for gathering the input data */ + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) { - test(); - IF( is_next_band && skip_next_band ) + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - CONTINUE; - } + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } - IF( is_next_band ) - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_next_band_fx, - &cx_next_band_e, - cx_imag_next_band_fx, - &cx_imag_next_band_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); - } - ELSE - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_fx, - &cx_e, - cx_imag_fx, - &cx_imag_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); + IF( is_next_band ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_next_band_fx, + &cx_next_band_e, + cx_imag_next_band_fx, + &cx_imag_next_band_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + ELSE + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_fx, + &cx_e, + cx_imag_fx, + &cx_imag_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } } } } - } - - Word16 tmp_cx_e, tmp_cx_imag_e; - /* map from complex input covariance to real values */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - test(); - IF( is_next_band && skip_next_band ) - { - CONTINUE; - } - /* Cx for transport channels */ - IF( is_next_band ) - { - pCx = &cx_next_band_fx[0]; - pCx_imag = &cx_imag_next_band_fx[0]; - tmp_cx_e = cx_next_band_e; - tmp_cx_imag_e = cx_imag_next_band_e; - } - ELSE - { - pCx = &cx_fx[0]; - pCx_imag = &cx_imag_fx[0]; - tmp_cx_e = cx_e; - tmp_cx_imag_e = cx_imag_e; - } - FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) + Word16 tmp_cx_e, tmp_cx_imag_e; + /* map from complex input covariance to real values */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - real_part_fx = pCx[i]; // Q(31 - cx_buff_e) - imag_part_fx = pCx_imag[i]; - move32(); - move32(); - cx_buff_e[is_next_band][i] = tmp_cx_e; - move16(); - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ - IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) + test(); + IF( is_next_band && skip_next_band ) { - L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); - L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); - pCx[i] = Sqrt32( L_tmp1, &tmp_e ); - move32(); - cx_buff_e[is_next_band][i] = tmp_e; - move16(); + CONTINUE; + } + /* Cx for transport channels */ + IF( is_next_band ) + { + pCx = &cx_next_band_fx[0]; + pCx_imag = &cx_imag_next_band_fx[0]; + tmp_cx_e = cx_next_band_e; + tmp_cx_imag_e = cx_imag_next_band_e; } ELSE { - pCx[i] = real_part_fx; + pCx = &cx_fx[0]; + pCx_imag = &cx_imag_fx[0]; + tmp_cx_e = cx_e; + tmp_cx_imag_e = cx_imag_e; + } + + FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part_fx = pCx[i]; // Q(31 - cx_buff_e) + imag_part_fx = pCx_imag[i]; + move32(); move32(); cx_buff_e[is_next_band][i] = tmp_cx_e; move16(); + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) + { + L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); + L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); + pCx[i] = Sqrt32( L_tmp1, &tmp_e ); + move32(); + cx_buff_e[is_next_band][i] = tmp_e; + move16(); + } + ELSE + { + pCx[i] = real_part_fx; + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + } } } - } - max_e = cx_buff_e[0][0]; - move16(); + max_e = cx_buff_e[0][0]; + move16(); - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - - IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) { - max_e = cx_buff_e[is_next_band][i]; + + IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) + { + max_e = cx_buff_e[is_next_band][i]; + } } } - } - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - if ( is_next_band == 0 ) - { - cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); - } - else + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) { - cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + if ( is_next_band == 0 ) + { + cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + else + { + cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + move32(); } - move32(); - } - } - cx_e = max_e; - move16(); - - /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ - test(); - test(); - IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) - { - Word16 len = imult1616( nchan_transport, nchan_transport ); - Word16 sc = s_min( getScaleFactor32( cx_fx, len ), getScaleFactor32( cx_next_band_fx, len ) ); - IF( EQ_16( sc, 0 ) ) - { - Scale_sig32( cx_fx, len, -Q1 ); // add one bit head room - Scale_sig32( cx_next_band_fx, len, -Q1 ); // add one bit head room - cx_e = add( cx_e, Q1 ); - cx_next_band_e = add( cx_e, Q1 ); } - v_add_fx( cx_fx, cx_next_band_fx, cx_fx, len ); - Copy32( cx_fx, cx_next_band_fx, len ); - } + cx_e = max_e; + move16(); - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + test(); test(); - IF( is_next_band && skip_next_band ) + IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) { - CONTINUE; + Word16 len = imult1616( nchan_transport, nchan_transport ); + Word16 sc = s_min( getScaleFactor32( cx_fx, len ), getScaleFactor32( cx_next_band_fx, len ) ); + IF( EQ_16( sc, 0 ) ) + { + Scale_sig32( cx_fx, len, -Q1 ); // add one bit head room + Scale_sig32( cx_next_band_fx, len, -Q1 ); // add one bit head room + cx_e = add( cx_e, Q1 ); + cx_next_band_e = add( cx_e, Q1 ); + } + v_add_fx( cx_fx, cx_next_band_fx, cx_fx, len ); + Copy32( cx_fx, cx_next_band_fx, len ); } - IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) { - IF( is_next_band ) + test(); + IF( is_next_band && skip_next_band ) { - - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + CONTINUE; } - ELSE + + IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) { + IF( is_next_band ) + { - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + ELSE + { + + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } } } } - } - return; -} + return; + } #endif -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_render() - * - * Parametric MC rendering process - *------------------------------------------------------------------------*/ - -void ivas_param_mc_dec_render_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ - UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ - UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - Word32 *output_f_fx[], /* o : rendered time signal Q11*/ - Word16 channel_active_fx[MAX_OUTPUT_CHANNELS] ) -{ - PARAM_MC_DEC_HANDLE hParamMC; - Word16 i, ch; - Word16 subframe_idx; - Word16 slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; - Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; - Word16 nchan_out_cov; - - /*CLDFB*/ - Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 *p_output_f_fx[MAX_OUTPUT_CHANNELS]; - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - p_output_f_fx[i] = output_f_fx[i]; // Q11 - } - /*Decorrelator*/ - Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; // Q31 + /*------------------------------------------------------------------------- + * ivas_param_mc_dec_render() + * + * Parametric MC rendering process + *------------------------------------------------------------------------*/ + + void ivas_param_mc_dec_render_fx( + Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ + UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ + UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + Word32 *output_f_fx[], /* o : rendered time signal Q11*/ + Word16 channel_active_fx[MAX_OUTPUT_CHANNELS] ) + { + PARAM_MC_DEC_HANDLE hParamMC; + Word16 i, ch; + Word16 subframe_idx; + Word16 slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; + Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; + Word16 nchan_out_cov; + + /*CLDFB*/ + Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 *p_output_f_fx[MAX_OUTPUT_CHANNELS]; + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_output_f_fx[i] = output_f_fx[i]; // Q11 + } + /*Decorrelator*/ + Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; // Q31 + + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + UWord16 nband_synth; + UWord32 output_Fs; + Word16 tmp_q = 0; + move16(); - /* format converter */ - Word16 channel_active[MAX_OUTPUT_CHANNELS]; - UWord16 nband_synth; - UWord32 output_Fs; - Word16 tmp_q = 0; - move16(); + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); - hParamMC = st_ivas->hParamMC; - assert( hParamMC ); + push_wmops( "param_mc_dec_render" ); - push_wmops( "param_mc_dec_render" ); + set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + move16(); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + output_Fs = st_ivas->hDecoderConfig->output_Fs; + move32(); - set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_transport = st_ivas->nchan_transport; - move16(); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - output_Fs = st_ivas->hDecoderConfig->output_Fs; - move32(); + test(); + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set16_fx( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + nchan_out_cldfb = nchan_out_cov; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = nchan_out_transport; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + } - test(); - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - nchan_out_cldfb = BINAURAL_CHANNELS; - set16_fx( channel_active, 1, nchan_out_cldfb ); - nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - nchan_out_cov = nchan_out_transport; + /* set everything to zero that will not be decoded */ + nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; move16(); - nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - nchan_out_cldfb = nchan_out_cov; + FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { + set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + /* loop FOR synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + /*slots_to_render = min(sub(hParamMC->num_slots, hParamMC->slots_rendered), nSamplesAsked / NS2SA(output_Fs, CLDFB_SLOT_NS)); + *nSamplesRendered = slots_to_render * NS2SA(output_Fs, CLDFB_SLOT_NS);*/ + Word16 temp_e; + Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ), &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); + slots_to_render = s_min( sub( hParamMC->num_slots, hParamMC->slots_rendered ), temp ); + *nSamplesRendered = imult1616( slots_to_render, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - } - ELSE - { - nchan_out_cov = nchan_out_transport; + Word16 j, k; + first_sf = hParamMC->subframes_rendered; move16(); - nchan_out_cldfb = nchan_out_transport; + last_sf = first_sf; move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - } - - /* set everything to zero that will not be decoded */ - nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; - move16(); - FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) - { - FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + WHILE( slots_to_render > 0 ) { - set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); + slots_to_render = sub( slots_to_render, hParamMC->subframe_nbslots[last_sf] ); + last_sf = add( last_sf, 1 ); } - } - - /* loop FOR synthesis, assume we always have to render in multiples of 5ms subframes with spills */ - /*slots_to_render = min(sub(hParamMC->num_slots, hParamMC->slots_rendered), nSamplesAsked / NS2SA(output_Fs, CLDFB_SLOT_NS)); - *nSamplesRendered = slots_to_render * NS2SA(output_Fs, CLDFB_SLOT_NS);*/ - Word16 temp_e; - Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ), &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); - slots_to_render = s_min( sub( hParamMC->num_slots, hParamMC->slots_rendered ), temp ); - *nSamplesRendered = imult1616( slots_to_render, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); - move16(); - Word16 j, k; - first_sf = hParamMC->subframes_rendered; - move16(); - last_sf = first_sf; - move16(); - WHILE( slots_to_render > 0 ) - { - slots_to_render = sub( slots_to_render, hParamMC->subframe_nbslots[last_sf] ); - last_sf = add( last_sf, 1 ); - } - IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) { - slots_to_render = add( slots_to_render, hParamMC->subframe_nbslots[subframe_idx] ); + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + slots_to_render = add( slots_to_render, hParamMC->subframe_nbslots[subframe_idx] ); + } } - } - slot_idx_start = hParamMC->slots_rendered; - move16(); - slot_idx_start_cldfb_synth = 0; - move16(); + slot_idx_start = hParamMC->slots_rendered; + move16(); + slot_idx_start_cldfb_synth = 0; + move16(); - FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) - { - Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); + FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) { - if ( is_zero != 0 ) + Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; - move16(); + if ( is_zero != 0 ) + { + hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; + move16(); + } } - } - IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) - { - is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); - if ( is_zero != 0 ) + IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; - move16(); + is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); + if ( is_zero != 0 ) + { + hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; + move16(); + } } } - } - FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) - { - FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; ( slot_idx++, hParamMC->slots_rendered++ ) ) + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { - IF( hParamMC->max_band_decorr > 0 ) + FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; ( slot_idx++, hParamMC->slots_rendered++ ) ) { - /*-----------------------------------------------------------------* - * protoype signal computation - *-----------------------------------------------------------------*/ - param_mc_protoSignalComputation_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - hParamMC->proto_frame_f_fx, hParamMC->diff_proto_info, - hParamMC->num_freq_bands, hParamMC->Cldfb_RealBuffer_tc_e, &hParamMC->proto_frame_f_fx_q ); - /*-----------------------------------------------------------------* - * frequency domain decorrelation - *-----------------------------------------------------------------*/ - /* decorrelate prototype frame */ - - ivas_dirac_dec_decorr_process_fx( hParamMC->num_freq_bands, - hParamMC->num_outputs_diff, - hParamMC->diff_proto_info->num_protos_diff, - DIRAC_SYNTHESIS_COV_MC_LS, - nchan_transport, - hParamMC->proto_frame_f_fx, - hParamMC->proto_frame_f_fx_q, - hParamMC->diff_proto_info->num_protos_diff, - hParamMC->diff_proto_info->proto_index_diff, - hParamMC->proto_frame_dec_f_fx, // output - &tmp_q, - onset_filter_fx, - hParamMC->h_freq_domain_decorr_ap_params, - hParamMC->h_freq_domain_decorr_ap_state ); - - /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ - /* memory FOR the decorrelated signal */ - ivas_param_mc_dec_copy_diffuse_proto( hParamMC, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nchan_out_cov, slot_idx ); // Returns Cldfb buffers in Q11(tmp_q) - - FOR( k = 0; k < nchan_out_cov; k++ ) + IF( hParamMC->max_band_decorr > 0 ) { - FOR( Word16 l = 0; l < hParamMC->h_output_synthesis_params.max_band_decorr; l++ ) + /*-----------------------------------------------------------------* + * protoype signal computation + *-----------------------------------------------------------------*/ + param_mc_protoSignalComputation_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + hParamMC->proto_frame_f_fx, hParamMC->diff_proto_info, + hParamMC->num_freq_bands, hParamMC->Cldfb_RealBuffer_tc_e, &hParamMC->proto_frame_f_fx_q ); + /*-----------------------------------------------------------------* + * frequency domain decorrelation + *-----------------------------------------------------------------*/ + /* decorrelate prototype frame */ + + ivas_dirac_dec_decorr_process_fx( hParamMC->num_freq_bands, + hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, + DIRAC_SYNTHESIS_COV_MC_LS, + nchan_transport, + hParamMC->proto_frame_f_fx, + hParamMC->proto_frame_f_fx_q, + hParamMC->diff_proto_info->num_protos_diff, + hParamMC->diff_proto_info->proto_index_diff, + hParamMC->proto_frame_dec_f_fx, // output + &tmp_q, + onset_filter_fx, + hParamMC->h_freq_domain_decorr_ap_params, + hParamMC->h_freq_domain_decorr_ap_state ); + + /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ + /* memory FOR the decorrelated signal */ + ivas_param_mc_dec_copy_diffuse_proto( hParamMC, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nchan_out_cov, slot_idx ); // Returns Cldfb buffers in Q11(tmp_q) + + FOR( k = 0; k < nchan_out_cov; k++ ) { - Cldfb_RealBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_RealBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 - move32(); - Cldfb_ImagBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_ImagBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 - move32(); + FOR( Word16 l = 0; l < hParamMC->h_output_synthesis_params.max_band_decorr; l++ ) + { + Cldfb_RealBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_RealBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 + move32(); + Cldfb_ImagBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_ImagBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 + move32(); + } } } - } - /*-----------------------------------------------------------------* - * output synthesis - *-----------------------------------------------------------------*/ - ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( - &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, slot_idx, add( slot_idx, slot_idx_start ), - nchan_transport, nchan_out_cov, hParamMC ); + /*-----------------------------------------------------------------* + * output synthesis + *-----------------------------------------------------------------*/ + ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( + &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, slot_idx, add( slot_idx, slot_idx_start ), + nchan_transport, nchan_out_cov, hParamMC ); - test(); - IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) - { test(); - IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) + IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) { - Word16 Q_Cldfb_ImagBuffer, Q_Cldfb_RealBuffer; - Q_Cldfb_ImagBuffer = Q6 - 5; /*max value =MAX_INTERN_CHANNELS(=16)*Cldfb_ImagBuffer_fx*/ - move16(); - Q_Cldfb_RealBuffer = Q6 - 5; - move16(); - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + test(); + IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + Word16 Q_Cldfb_ImagBuffer, Q_Cldfb_RealBuffer; + Q_Cldfb_ImagBuffer = Q6 - 5; /*max value =MAX_INTERN_CHANNELS(=16)*Cldfb_ImagBuffer_fx*/ + move16(); + Q_Cldfb_RealBuffer = Q6 - 5; + move16(); + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { - Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_ImagBuffer, Q6 ) ); // Q1 - Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_RealBuffer, Q6 ) ); // Q1 + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_ImagBuffer, Q6 ) ); // Q1 + Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_RealBuffer, Q6 ) ); // Q1 + } } - } - ivas_param_mc_mc2sba_cldfb_fx( st_ivas->hTransSetup, hParamMC->hoa_encoder_fx, slot_idx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nband_synth, GAIN_LFE_FX ); - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + ivas_param_mc_mc2sba_cldfb_fx( st_ivas->hTransSetup, hParamMC->hoa_encoder_fx, slot_idx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nband_synth, GAIN_LFE_FX ); + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { - Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_ImagBuffer ) ); // Q6 - Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_RealBuffer ) ); // Q6 + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_ImagBuffer ) ); // Q6 + Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_RealBuffer ) ); // Q6 + } } } - } - ELSE - { - /* remove LFE */ - UWord16 idx_out; - UWord16 idx_lfe; - IVAS_OUTPUT_SETUP hLsSetup; - - hLsSetup = st_ivas->hTransSetup; - /* If LFE should be rendered, add it to other channels before removing */ - IF( st_ivas->hBinRenderer->render_lfe ) + ELSE { - Word16 tmp_exp = 0; - move16(); - Word16 tmp = BASOP_Util_Divide1616_Scale( GAIN_LFE_FX, hLsSetup.nchan_out_woLFE, &tmp_exp ); - tmp_exp = add( tmp_exp, ( 1 - 15 ) ); - FOR( idx_lfe = 0; idx_lfe < hLsSetup.num_lfe; idx_lfe++ ) + /* remove LFE */ + UWord16 idx_out; + UWord16 idx_lfe; + IVAS_OUTPUT_SETUP hLsSetup; + + hLsSetup = st_ivas->hTransSetup; + /* If LFE should be rendered, add it to other channels before removing */ + IF( st_ivas->hBinRenderer->render_lfe ) { - /* Copy just the first band of LFE*/ - v_multc_fx_16( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); - v_multc_fx_16( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); - - Scale_sig32( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); - Scale_sig32( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); - FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) + Word16 tmp_exp = 0; + move16(); + Word16 tmp = BASOP_Util_Divide1616_Scale( GAIN_LFE_FX, hLsSetup.nchan_out_woLFE, &tmp_exp ); + tmp_exp = add( tmp_exp, ( 1 - 15 ) ); + FOR( idx_lfe = 0; idx_lfe < hLsSetup.num_lfe; idx_lfe++ ) { - IF( hLsSetup.index_lfe[idx_lfe] != ch ) + /* Copy just the first band of LFE*/ + v_multc_fx_16( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + v_multc_fx_16( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + + Scale_sig32( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); + Scale_sig32( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); + FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) { - v_add_fx_no_hdrm( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1 ); - v_add_fx_no_hdrm( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1 ); + IF( hLsSetup.index_lfe[idx_lfe] != ch ) + { + v_add_fx_no_hdrm( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1 ); + v_add_fx_no_hdrm( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1 ); + } } } } - } - idx_out = 0; - move16(); - idx_lfe = 0; - move16(); + idx_out = 0; + move16(); + idx_lfe = 0; + move16(); - FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) - { - test(); - IF( ( hLsSetup.num_lfe > 0 ) && EQ_16( hLsSetup.index_lfe[idx_lfe], ch ) ) + FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) { - IF( LT_16( idx_lfe, ( sub( hLsSetup.num_lfe, 1 ) ) ) ) + test(); + IF( ( hLsSetup.num_lfe > 0 ) && EQ_16( hLsSetup.index_lfe[idx_lfe], ch ) ) { - idx_lfe = add( idx_lfe, 1 ); + IF( LT_16( idx_lfe, ( sub( hLsSetup.num_lfe, 1 ) ) ) ) + { + idx_lfe = add( idx_lfe, 1 ); + } + } + ELSE IF( NE_16( ch, idx_out ) ) + { + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[idx_out][slot_idx], nband_synth ); + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[idx_out][slot_idx], nband_synth ); + idx_out = add( idx_out, 1 ); + } + ELSE + { + idx_out = add( idx_out, 1 ); } - } - ELSE IF( NE_16( ch, idx_out ) ) - { - Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[idx_out][slot_idx], nband_synth ); - Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[idx_out][slot_idx], nband_synth ); - idx_out = add( idx_out, 1 ); - } - ELSE - { - idx_out = add( idx_out, 1 ); } } } } - } - - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - Word16 input_q = 6; - move16(); - IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) { - IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) + Word16 input_q = 6; + move16(); + + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { - FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { - Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); - Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + } } - } - st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; - move16(); - } - } - - /* Implement binaural rendering */ - /*Binaural output in Q6 format*/ - ivas_binRenderer_fx( st_ivas->hBinRenderer, - ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, - st_ivas->hCombinedOrientationData, - hParamMC->subframe_nbslots[subframe_idx], - Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, - Cldfb_RealBuffer_fx, - Cldfb_ImagBuffer_fx, &input_q ); - - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - Cldfb_RealBuffer_fx[i][j][k] = L_shl( Cldfb_RealBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 - Cldfb_ImagBuffer_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + move16(); } } - } - Word16 pos_idx; - IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + /* Implement binaural rendering */ + /*Binaural output in Q6 format*/ + ivas_binRenderer_fx( st_ivas->hBinRenderer, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, + st_ivas->hCombinedOrientationData, + hParamMC->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, + Cldfb_RealBuffer_fx, + Cldfb_ImagBuffer_fx, &input_q ); + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { - FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++ ) + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) { - Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); - Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + Cldfb_RealBuffer_fx[i][j][k] = L_shl( Cldfb_RealBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 + Cldfb_ImagBuffer_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 } } } - } - /* update combined orientation access index */ - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - /* format conversion*/ - ivas_lssetupconversion_process_param_mc_fx( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, channel_active ); - } - - /* CLDFB synthesis */ - FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) - { - Word32 *RealBuffer_fx[16]; - Word32 *ImagBuffer_fx[16]; - - IF( channel_active[ch] ) - { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands FOR 48kHz */ - FOR( i = 0; i < hParamMC->subframe_nbslots[subframe_idx]; i++ ) + Word16 pos_idx; + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i]; // Q6 - ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i]; // Q6 - } - ELSE + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) { - RealBuffer_fx[i] = Cldfb_RealBuffer_fx[ch][i]; // Q6 - ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[ch][i]; // Q6 + FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + } + } } } - - Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); - scale_sig32( output_f_fx[ch], len, 5 - 11 ); - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), - imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] ); - - scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 - } - ELSE - { - set32_fx( &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), 0, imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); } - } - slot_idx_start = add( slot_idx_start, hParamMC->subframe_nbslots[subframe_idx] ); - slot_idx_start_cldfb_synth = add( slot_idx_start_cldfb_synth, hParamMC->subframe_nbslots[subframe_idx] ); - } - IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); - } - - /* update */ - - IF( EQ_16( hParamMC->slots_rendered, hParamMC->num_slots ) ) - { - hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; - move16(); - param_mc_update_mixing_matrices_fx( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_transport, nchan_out_cov ); - } - - - hParamMC->subframes_rendered = last_sf; - move16(); - *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); - move16(); - - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - channel_active_fx[i] = channel_active[i]; - move16(); - } - pop_wmops(); - - return; -} - -/*------------------------------------------------------------------------- - * param_mc_dec_init() - * - * Parametric MC decoding initialization - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_init_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder DirAC handle */ - const Word16 nchan_transport, /* i : number of input (transport) channels */ - const Word16 nchan_cov ) /* i : number of cov synthesis channels */ -{ - Word16 k; - UWord16 max_param_band_residual; - Word16 len; - - /*-----------------------------------------------------------------* - * init sub-modules - *-----------------------------------------------------------------*/ - - /* decorrelation */ - IF( hParamMC->max_band_decorr > 0 ) - { - len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); - - /* init onsetDetectionPower */ - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); - hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; - move16(); - } - - max_param_band_residual = 0; - move16(); - - /* output synthesis */ - FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) - { - IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) - { - max_param_band_residual = k; - move16(); - BREAK; - } - } - - ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); - - /*-----------------------------------------------------------------* - * init proto frames - *-----------------------------------------------------------------*/ - - IF( hParamMC->max_band_decorr > 0 ) - { - set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); - set32_fx( hParamMC->proto_frame_dec_f_fx, 0, shl( imult1616( nchan_cov, hParamMC->num_freq_bands ), 1 ) ); - } - - return; -} - - -/*------------------------------------------------------------------------- - * Local functions - *-------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_compute_diffuse_proto() - * - * Compute prototypes for decorrelation - *------------------------------------------------------------------------*/ - -static void param_mc_protoSignalComputation_fx( - Word32 *RealBuffer_fx, /* i : CLDFB samples of the transport channels (real part) */ - Word32 *ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ - Word32 *proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ - const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ - const Word16 num_freq_bands, /* i : number of frequency bands for the prototypes */ - const Word16 Cldfb_Real_Imag_exp, /*i: Exponent of real and imag buffers */ - Word16 *proto_frame_f_fx_q ) -{ - Word16 band; - Word16 proto_ch_idx, source_ch_cnt; - - Word32 *p_proto_frame_fx; - Word32 *p_real_buffer_fx; // Q12 - Word32 *p_imag_buffer_fx; // Q12 - - set32_fx( proto_frame_f_fx, 0, shl( imult1616( num_freq_bands, diff_proto_info->num_protos_diff ), 1 ) ); - - - FOR( proto_ch_idx = 0; proto_ch_idx < diff_proto_info->num_protos_diff; proto_ch_idx++ ) - { - Word16 num_source_ch = diff_proto_info->num_source_chan_diff[proto_ch_idx]; - move16(); - - FOR( source_ch_cnt = 0; source_ch_cnt < num_source_ch; source_ch_cnt++ ) - { - - Word32 fac_fx = diff_proto_info->proto_fac_fx[proto_ch_idx][source_ch_cnt]; - move32(); - - Word16 source_ch_idx = diff_proto_info->source_chan_idx[proto_ch_idx][source_ch_cnt]; - move16(); - - p_proto_frame_fx = &proto_frame_f_fx[shl( imult1616( proto_ch_idx, num_freq_bands ), 1 )]; - p_real_buffer_fx = &RealBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; - p_imag_buffer_fx = &ImagBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; - - FOR( band = 0; band < num_freq_bands; band++ ) + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) { - - Word32 tmp_x = L_shl( Mpy_32_32( fac_fx, ( *( p_real_buffer_fx++ ) ) ), 4 ); // Q(26 + 4 + 6 - 31) :: Q5 - - *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); - move32(); - p_proto_frame_fx++; - - tmp_x = L_shl( Mpy_32_32( fac_fx, ( *( p_imag_buffer_fx++ ) ) ), 4 ); // Q(26 + 4 + 6 - 31) :: Q5 - - *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); - move32(); - p_proto_frame_fx++; + /* format conversion*/ + ivas_lssetupconversion_process_param_mc_fx( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, channel_active ); } - *proto_frame_f_fx_q = sub( 30, Cldfb_Real_Imag_exp ); - move16(); - } - } - - return; -} - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_compute_diffuse_proto() - * - * Transfer decorrelated signals back from the decorrelator buffer to - * the buffers used in the final synthesis - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_copy_diffuse_proto( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (real part) */ - Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (imaginary part) */ - const Word16 nY, /* i : number of decorrelated channels */ - const Word16 slot_idx /* i : current time slot index */ -) -{ - Word16 k, l; - Word16 num_freq_bands, num_freq_bands_diff; - Word32 *p_proto_diff_fx; - num_freq_bands = hParamMC->num_freq_bands; - move16(); - num_freq_bands_diff = hParamMC->h_output_synthesis_params.max_band_decorr; - move16(); - - FOR( k = 0; k < nY; k++ ) - { - p_proto_diff_fx = hParamMC->proto_frame_dec_f_fx + imult1616( shl( k, 1 ), num_freq_bands ); // Q11 - - FOR( l = 0; l < num_freq_bands_diff; l++ ) - { - Cldfb_buffer_real_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 - move32(); - Cldfb_buffer_imag_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 - move32(); - } - } - - return; -} - -/*------------------------------------------------------------------------- - * ivas_param_mc_bin2dec() - * - * decode a number of bits to an integer - *------------------------------------------------------------------------*/ -/* r : decoded integer */ -static Word16 ivas_param_mc_bin2dec_fx( - UWord16 bits[PARAM_MC_MAX_BITS], /* i : bit buffer */ - const Word16 N /* i : number of bits to decode */ -) -{ - Word16 i; - Word16 out; - - assert( N <= 16 ); - out = 0; - move16(); - FOR( i = 0; i < N; i++ ) - { - out = add( out, shl( bits[i], sub( sub( N, 1 ), i ) ) ); - } - - return out; -} -/*------------------------------------------------------------------------- - * ivas_param_mc_uniform_decoder() - * - * decode a uniformily coded sequence of float values - *------------------------------------------------------------------------*/ -static Word16 ivas_param_mc_uniform_decoder_fx( - Word16 *seq, /* o : decoded sequence of float values hParamCodingInfo -> Q-quant*/ - const Word16 sz_seq, /* i : number of values to decode */ - const Word16 *alphabet, /* i : codebook hParamCodingInfo -> Q-quant*/ - const Word16 N, /* i : number of bits per coded index */ - UWord16 bit_buffer[PARAM_MC_MAX_BITS] /* i : bit buffer to decode */ -) -{ - Word16 i; - Word16 idx; - Word16 n_bits; - n_bits = 0; - move16(); - assert( N * sz_seq < PARAM_MC_MAX_BITS ); + /* CLDFB synthesis */ + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + Word32 *RealBuffer_fx[16]; + Word32 *ImagBuffer_fx[16]; - FOR( i = 0; i < sz_seq; ++i ) - { - idx = ivas_param_mc_bin2dec_fx( &bit_buffer[i * N], N ); - seq[i] = alphabet[idx]; - move16(); - } + IF( channel_active[ch] ) + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands FOR 48kHz */ + FOR( i = 0; i < hParamMC->subframe_nbslots[subframe_idx]; i++ ) + { + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i]; // Q6 + ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i]; // Q6 + } + ELSE + { + RealBuffer_fx[i] = Cldfb_RealBuffer_fx[ch][i]; // Q6 + ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[ch][i]; // Q6 + } + } - n_bits = imult1616( N, sz_seq ); + Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); + scale_sig32( output_f_fx[ch], len, 5 - 11 ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] ); - return n_bits; -} + scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 + } + ELSE + { + set32_fx( &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), 0, imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); + } + } + slot_idx_start = add( slot_idx_start, hParamMC->subframe_nbslots[subframe_idx] ); + slot_idx_start_cldfb_synth = add( slot_idx_start_cldfb_synth, hParamMC->subframe_nbslots[subframe_idx] ); + } + IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); + } + /* update */ -/*------------------------------------------------------------------------- - * ivas_param_mc_range_decoder_LC() - * - * decode a sequency of inidices coded with a range coder - *------------------------------------------------------------------------*/ -static Word16 ivas_param_mc_range_decoder_LC_fx( - UWord16 *bit_buffer, /* i : bit buffer to read from */ - Word16 *x, /* o : decoded indices */ - Word16 *BER_detect, /* o : flag for indicating a bit error */ - const Word16 sz_seq, /* i : size of the sequence to be decoded */ - const Word16 sz_alphabet, /* i : size of the alphabet */ - const UWord16 *cft, /* i : cumulative frequency table */ - const UWord16 *sft, /* i : symbol frequency table */ - const Word16 tot_shift, /* i : total frequency as a power of 2 */ - const Word16 nbbits /* i : maximum bit budget */ -) -{ - RangeUniDecState rc_st_dec; /* State of the range decoder */ - Word16 cur_bit_pos; - Word16 k; - Word16 r; - - /* Start Decoding */ - /* Initialize range decoder */ - cur_bit_pos = 0; - move16(); - rc_uni_dec_init_fx( &rc_st_dec, bit_buffer, sub( nbbits, 32 ) ); /* (nbbits + 30) entries are read by the decoder */ + IF( EQ_16( hParamMC->slots_rendered, hParamMC->num_slots ) ) + { + hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; + move16(); + param_mc_update_mixing_matrices_fx( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_transport, nchan_out_cov ); + } - /* Main Loop through the indices */ - FOR( k = 0; k < sz_seq; k++ ) - { - r = rc_uni_dec_read_symbol_fastS_fx( &rc_st_dec, cft, sft, sz_alphabet, tot_shift ); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ - /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ - /* Update bitstream pointer */ - cur_bit_pos = rc_uni_dec_virtual_finish_fx( &rc_st_dec ); + hParamMC->subframes_rendered = last_sf; + move16(); + *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); + move16(); - /* Confirm that there is no overflow */ - IF( GT_16( cur_bit_pos, nbbits ) ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { - *BER_detect = s_or( *BER_detect, 1 ); + channel_active_fx[i] = channel_active[i]; move16(); } + pop_wmops(); - x[k] = r; - move16(); + return; } - /* We don't need to finish because virtual_finish() already does the same */ - /*st->next_bit_pos = rc_uni_dec_finish(&rc_st_dec);*/ + /*------------------------------------------------------------------------- + * param_mc_dec_init() + * + * Parametric MC decoding initialization + *------------------------------------------------------------------------*/ - /* Check for bitstream errors */ - IF( rc_st_dec.bit_error_detected != 0 ) + static void ivas_param_mc_dec_init_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder DirAC handle */ + const Word16 nchan_transport, /* i : number of input (transport) channels */ + const Word16 nchan_cov ) /* i : number of cov synthesis channels */ { - *BER_detect = s_or( *BER_detect, 1 ); - move16(); - } - - return cur_bit_pos; -} - -/*------------------------------------------------------------------------- - * param_mc_compute_interpolator() - * - * compute the interpolator used in the final synthesis - *------------------------------------------------------------------------*/ + Word16 k; + UWord16 max_param_band_residual; + Word16 len; -static void ivas_param_mc_dec_compute_interpolator_fx( - const UWord16 bAttackPresent, /* i : flag indicating if we have a transient in the current frame */ - const UWord16 attackPos, /* i : position of the transient */ - const UWord16 interp_length, /* i : number of interpolation values to be calculated */ - Word16 *interpolator /* o : interpolator */ -) -{ - Word16 idx; + /*-----------------------------------------------------------------* + * init sub-modules + *-----------------------------------------------------------------*/ - IF( bAttackPresent ) - { - FOR( idx = 0; idx < attackPos * 2; idx++ ) - { - interpolator[idx] = 0; - move16(); - } - FOR( ; idx < interp_length; idx++ ) + /* decorrelation */ + IF( hParamMC->max_band_decorr > 0 ) { - interpolator[idx] = 32767; /* 1.0f Q15 */ + len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); + + /* init onsetDetectionPower */ + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); + hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; move16(); } - } - ELSE - { - ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, interp_length, interpolator ); - } - - return; -} - - -/*------------------------------------------------------------------------- - * remove_lfe_from_cy() - * - * remove all LFE related values from a covariance matrix - *------------------------------------------------------------------------*/ - -static void remove_lfe_from_cy_fx( - const Word16 nY, /* i : dimension of the covariance matrix */ - Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP], /* i : LFE index */ - Word16 num_lfe, /* i : number of LFEs */ - Word32 *cy, /* i : covariance matrix */ - Word32 *cy_woLFE /* o : covariance matrix with LFE removed */ -) -{ - Word16 ch_idx1, ch_idx2; - Word16 lfe_idx1, lfe_idx2; - Word32 *ptrCy; - Word32 *ptrCy_out; - ptrCy = cy; - ptrCy_out = cy_woLFE; + max_param_band_residual = 0; + move16(); - FOR( lfe_idx1 = 0; lfe_idx1 < num_lfe + 1; lfe_idx1++ ) - { - FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + /* output synthesis */ + FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) { - FOR( lfe_idx2 = 0; lfe_idx2 < num_lfe + 1; lfe_idx2++ ) + IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) { - FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) - { - *( ptrCy_out++ ) = *( ptrCy++ ); - move32(); - } - ptrCy++; + max_param_band_residual = k; + move16(); + BREAK; } - ptrCy--; } - ptrCy += nY; - } - return; -} + ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); + /*-----------------------------------------------------------------* + * init proto frames + *-----------------------------------------------------------------*/ -/*------------------------------------------------------------------------- - * ivas_param_mc_get_mixing_matrices() - * - * calculate the direct and residual mixing matrices - * using the covariance method - *------------------------------------------------------------------------*/ + IF( hParamMC->max_band_decorr > 0 ) + { + set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); + set32_fx( hParamMC->proto_frame_dec_f_fx, 0, shl( imult1616( nchan_cov, hParamMC->num_freq_bands ), 1 ) ); + } -static void ivas_param_mc_get_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, - Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands Q(31 - Cx_in_e)*/ - Word16 Cx_in_e, - const Word16 param_band_idx, /* i : parameter band index */ - Word32 *mixing_matrix_fx[], // Q(31 - mixing_matrix_e) - Word16 *mixing_matrix_e, - Word32 *mixing_matrix_res_fx[], // Q(31 - mixing_matrix_res_e) - Word16 *mixing_matrix_res_e, - const Word16 nY_intern, /* i : number of channels in the transported format */ - const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ - const Word16 nX, /* i : number of transport channels */ - const Word16 nY_cov /* i : number of covariance synthesis output channels */ -) -{ - Word16 matSize = MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS; - Word16 nY_band; - Word16 num_lfe_bands; - Word16 brange[2]; - UWord16 i; - Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; - Word16 remove_lfe; - Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; - - Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - Word32 Cy_full_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - Word32 Cr_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cr_e) - Word16 Cr_e; - Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Cy_diag_buff_e) - Word16 Cy_diag_buff_e[MAX_OUTPUT_CHANNELS]; - Word32 mixing_matrix_local_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - mixing_matrix_local_e) - Word16 Cy_diag_e = 0, mixing_matrix_local_e = 0; - Word32 Cproto_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cproto_e) - Word16 Cproto_e; - Word32 *proto_matrix_ptr_fx; // Q(31 - proto_matrix_ptr_e) - Word32 *Cx_state_fx; // Q(31 - Cx_state_e) - Word32 *Cx_old_state_fx; - Word32 Cy_state_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cy_state_e) - Word32 *Cy_old_state_fx; - Word16 Cx_state_e; - Word16 Cy_state_e; - Word32 mixing_matrix_res_local_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mixing_matrix_res_local_e) - Word16 mixing_matrix_res_local_e; - Word32 L_tmp; - Word16 tmp_e, tmp; - - Word16 proto_matrix_e = hParamMC->h_output_synthesis_params.proto_matrix_e; - move16(); - Word32 proto_matrix_noLFE_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; // Q(31 - proto_matrix_noLFE_e) + return; + } - Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) - Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e; + /*------------------------------------------------------------------------- + * Local functions + *-------------------------------------------------------------------------*/ - Word32 *ptrMM_fx; - Word32 *ptrMM_out_fx; - Word16 Cy_e, Cx_e; - Word16 Cy_full_e; - Word16 new_e = 0; - move16(); + /*------------------------------------------------------------------------- + * ivas_param_mc_dec_compute_diffuse_proto() + * + * Compute prototypes for decorrelation + *------------------------------------------------------------------------*/ - set_zero_fx( Cproto_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - Word16 proto_matrix_noLFE_e = 0; - move16(); + static void param_mc_protoSignalComputation_fx( + Word32 * RealBuffer_fx, /* i : CLDFB samples of the transport channels (real part) */ + Word32 * ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ + Word32 * proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ + const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ + const Word16 num_freq_bands, /* i : number of frequency bands for the prototypes */ + const Word16 Cldfb_Real_Imag_exp, /*i: Exponent of real and imag buffers */ + Word16 *proto_frame_f_fx_q ) + { + Word16 band; + Word16 proto_ch_idx, source_ch_cnt; - Word32 Cx_in_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 *p_proto_frame_fx; + Word32 *p_real_buffer_fx; // Q12 + Word32 *p_imag_buffer_fx; // Q12 - Copy32( Cx_in_fixed, Cx_in_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set32_fx( proto_frame_f_fx, 0, shl( imult1616( num_freq_bands, diff_proto_info->num_protos_diff ), 1 ) ); - nY_band = nY_cov; - move16(); - num_lfe_bands = 0; - move16(); - remove_lfe = 0; - move16(); - set16_fx( lfe_indices, -1, PARAM_MC_LOCAL_SZ_LFE_MAP ); - IF( hSynthesisOutputSetup->num_lfe ) - { - Word32 *proto_matrix_ptr_in_fx; - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe; lfe_idx1++ ) + FOR( proto_ch_idx = 0; proto_ch_idx < diff_proto_info->num_protos_diff; proto_ch_idx++ ) { - lfe_indices[lfe_idx1 + 1] = hSynthesisOutputSetup->index_lfe[lfe_idx1]; + Word16 num_source_ch = diff_proto_info->num_source_chan_diff[proto_ch_idx]; move16(); - } - lfe_indices[hSynthesisOutputSetup->num_lfe + 1] = nY_cov; - move16(); - proto_matrix_ptr_fx = &proto_matrix_noLFE_fx[0]; - proto_matrix_ptr_in_fx = &hParamMC->h_output_synthesis_params.proto_matrix_fx[0]; - proto_matrix_noLFE_e = proto_matrix_e; - move16(); - set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - - FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) - { - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + FOR( source_ch_cnt = 0; source_ch_cnt < num_source_ch; source_ch_cnt++ ) { - FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) + + Word32 fac_fx = diff_proto_info->proto_fac_fx[proto_ch_idx][source_ch_cnt]; + move32(); + + Word16 source_ch_idx = diff_proto_info->source_chan_idx[proto_ch_idx][source_ch_cnt]; + move16(); + + p_proto_frame_fx = &proto_frame_f_fx[shl( imult1616( proto_ch_idx, num_freq_bands ), 1 )]; + p_real_buffer_fx = &RealBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; + p_imag_buffer_fx = &ImagBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; + + FOR( band = 0; band < num_freq_bands; band++ ) { - *( proto_matrix_ptr_fx++ ) = *( proto_matrix_ptr_in_fx++ ); + + Word32 tmp_x = L_shl( Mpy_32_32( fac_fx, ( *( p_real_buffer_fx++ ) ) ), 4 ); // Q(26 + 4 + 6 - 31) :: Q5 + + *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); + move32(); + p_proto_frame_fx++; + + tmp_x = L_shl( Mpy_32_32( fac_fx, ( *( p_imag_buffer_fx++ ) ) ), 4 ); // Q(26 + 4 + 6 - 31) :: Q5 + + *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); move32(); + p_proto_frame_fx++; } - proto_matrix_ptr_in_fx++; + *proto_frame_f_fx_q = sub( 30, Cldfb_Real_Imag_exp ); + move16(); } - proto_matrix_ptr_in_fx--; } - proto_matrix_ptr_e = proto_matrix_e; - move16(); + return; } - if ( hParamMC->hMetadataPMC->lfe_on ) - { - num_lfe_bands = PARAM_MC_MAX_BAND_LFE; - move16(); - } - IF( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) - { - remove_lfe = 1; - move16(); - nY_band = sub( nY_cov, hSynthesisOutputSetup->num_lfe ); - proto_matrix_ptr_fx = proto_matrix_noLFE_fx; - proto_matrix_ptr_e = proto_matrix_noLFE_e; + /*------------------------------------------------------------------------- + * ivas_param_mc_dec_compute_diffuse_proto() + * + * Transfer decorrelated signals back from the decorrelator buffer to + * the buffers used in the final synthesis + *------------------------------------------------------------------------*/ + + static void ivas_param_mc_dec_copy_diffuse_proto( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (real part) */ + Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (imaginary part) */ + const Word16 nY, /* i : number of decorrelated channels */ + const Word16 slot_idx /* i : current time slot index */ + ) + { + Word16 k, l; + Word16 num_freq_bands, num_freq_bands_diff; + Word32 *p_proto_diff_fx; + num_freq_bands = hParamMC->num_freq_bands; move16(); - } - ELSE - { - proto_matrix_ptr_fx = hParamMC->h_output_synthesis_params.proto_matrix_fx; - proto_matrix_ptr_e = hParamMC->h_output_synthesis_params.proto_matrix_e; + num_freq_bands_diff = hParamMC->h_output_synthesis_params.max_band_decorr; move16(); - } - - brange[0] = hParamMC->band_grouping[param_band_idx]; - move16(); - brange[1] = hParamMC->band_grouping[param_band_idx + 1]; - move16(); - - Cx_state_fx = Cx_in_fx; - Cx_old_state_fx = hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx]; - Cy_old_state_fx = hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx]; + FOR( k = 0; k < nY; k++ ) + { + p_proto_diff_fx = hParamMC->proto_frame_dec_f_fx + imult1616( shl( k, 1 ), num_freq_bands ); // Q11 - /* Getting mixing mtx */ - /* estimate target cov from input cov and proto_matrix */ - - Cx_state_e = Cx_in_e; - move16(); - matrix_product_fx( hParamMC->proto_matrix_int_fx, nY_intern, nX, 0, Cx_state_fx, nX, nX, 0, mat_mult_buffer1_fx ); - mat_mult_buffer1_e = add( hParamMC->proto_matrix_int_e, Cx_in_e ); + FOR( l = 0; l < num_freq_bands_diff; l++ ) + { + Cldfb_buffer_real_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 + move32(); + Cldfb_buffer_imag_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 + move32(); + } + } - matrix_product_fx( mat_mult_buffer1_fx, nY_intern, nX, 0, hParamMC->proto_matrix_int_fx, nY_intern, nX, 1, Cproto_fx ); - Cproto_e = add( mat_mult_buffer1_e, hParamMC->proto_matrix_int_e ); + return; + } - FOR( ch_idx1 = 0; ch_idx1 < nY_intern; ch_idx1++ ) + /*------------------------------------------------------------------------- + * ivas_param_mc_bin2dec() + * + * decode a number of bits to an integer + *------------------------------------------------------------------------*/ + /* r : decoded integer */ + static Word16 ivas_param_mc_bin2dec_fx( + UWord16 bits[PARAM_MC_MAX_BITS], /* i : bit buffer */ + const Word16 N /* i : number of bits to decode */ + ) { - IF( BASOP_Util_Cmp_Mant32Exp( Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )], Cproto_e, 0, 0 ) < 0 ) + Word16 i; + Word16 out; + + assert( N <= 16 ); + out = 0; + move16(); + FOR( i = 0; i < N; i++ ) { - Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )] = 0; - move32(); + out = add( out, shl( bits[i], sub( sub( N, 1 ), i ) ) ); } + + return out; } - set_zero_fx( Cy_state_fx, matSize ); - Cy_state_e = 0; - move16(); + /*------------------------------------------------------------------------- + * ivas_param_mc_uniform_decoder() + * + * decode a uniformily coded sequence of float values + *------------------------------------------------------------------------*/ + static Word16 ivas_param_mc_uniform_decoder_fx( + Word16 * seq, /* o : decoded sequence of float values hParamCodingInfo -> Q-quant*/ + const Word16 sz_seq, /* i : number of values to decode */ + const Word16 *alphabet, /* i : codebook hParamCodingInfo -> Q-quant*/ + const Word16 N, /* i : number of bits per coded index */ + UWord16 bit_buffer[PARAM_MC_MAX_BITS] /* i : bit buffer to decode */ + ) + { + Word16 i; + Word16 idx; + Word16 n_bits; - ivas_param_mc_dequantize_cov_fx( hParamMC, - hParamMC->icld_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ), - hParamMC->icc_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ), - param_band_idx, nY_cov, - synth_config, - nY_intern, - nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); + n_bits = 0; + move16(); + assert( N * sz_seq < PARAM_MC_MAX_BITS ); - // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); + FOR( i = 0; i < sz_seq; ++i ) + { + idx = ivas_param_mc_bin2dec_fx( &bit_buffer[i * N], N ); + seq[i] = alphabet[idx]; + move16(); + } - /* Smoothing: Sum over two buffers */ - IF( hParamMC->hMetadataPMC->bAttackPresent ) - { - /* no smoothing on attacks */ - Copy32( Cx_state_fx, Cx_fx, imult1616( nX, nX ) ); - Copy32( Cy_state_fx, Cy_full_fx, imult1616( nY_cov, nY_cov ) ); - Cy_full_e = Cy_state_e; + n_bits = imult1616( N, sz_seq ); + + return n_bits; + } + + + /*------------------------------------------------------------------------- + * ivas_param_mc_range_decoder_LC() + * + * decode a sequency of inidices coded with a range coder + *------------------------------------------------------------------------*/ + static Word16 ivas_param_mc_range_decoder_LC_fx( + UWord16 * bit_buffer, /* i : bit buffer to read from */ + Word16 * x, /* o : decoded indices */ + Word16 * BER_detect, /* o : flag for indicating a bit error */ + const Word16 sz_seq, /* i : size of the sequence to be decoded */ + const Word16 sz_alphabet, /* i : size of the alphabet */ + const UWord16 *cft, /* i : cumulative frequency table */ + const UWord16 *sft, /* i : symbol frequency table */ + const Word16 tot_shift, /* i : total frequency as a power of 2 */ + const Word16 nbbits /* i : maximum bit budget */ + ) + { + RangeUniDecState rc_st_dec; /* State of the range decoder */ + Word16 cur_bit_pos; + Word16 k; + Word16 r; + + /* Start Decoding */ + /* Initialize range decoder */ + cur_bit_pos = 0; move16(); - Cx_e = Cx_state_e; - move16(); - } - ELSE - { - /* smoothing gains are now identical to one, simply add up */ - // v_add( Cy_state, Cy_old_state, Cy_full, nY_cov * nY_cov ); - - v_add_fx_me( Cx_state_fx, Cx_state_e, Cx_old_state_fx, hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], Cx_fx, &Cx_e, imult1616( nX, nX ), 1 ); - v_add_fx_me( Cy_state_fx, Cy_state_e, Cy_old_state_fx, hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], Cy_full_fx, &Cy_full_e, imult1616( nY_cov, nY_cov ), 1 ); - } + rc_uni_dec_init_fx( &rc_st_dec, bit_buffer, sub( nbbits, 32 ) ); /* (nbbits + 30) entries are read by the decoder */ - Copy32( Cx_state_fx, Cx_old_state_fx, imult1616( nX, nX ) ); + /* Main Loop through the indices */ + FOR( k = 0; k < sz_seq; k++ ) + { + r = rc_uni_dec_read_symbol_fastS_fx( &rc_st_dec, cft, sft, sz_alphabet, tot_shift ); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ + /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ - Copy32( Cy_state_fx, Cy_old_state_fx, imult1616( nY_cov, nY_cov ) ); + /* Update bitstream pointer */ + cur_bit_pos = rc_uni_dec_virtual_finish_fx( &rc_st_dec ); - hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = Cx_state_e; - move16(); - hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = Cy_state_e; - move16(); + /* Confirm that there is no overflow */ + IF( GT_16( cur_bit_pos, nbbits ) ) + { + *BER_detect = s_or( *BER_detect, 1 ); + move16(); + } - FOR( i = 0; i < nX * nX; i++ ) - { - if ( Cx_old_state_fx[i] != 0 ) - { - new_e = hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx]; + x[k] = r; move16(); - BREAK; } - } - - hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = new_e; - move16(); - new_e = 0; - move16(); + /* We don't need to finish because virtual_finish() already does the same */ + /*st->next_bit_pos = rc_uni_dec_finish(&rc_st_dec);*/ - FOR( i = 0; i < nY_cov * nY_cov; i++ ) - { - if ( Cy_old_state_fx[i] != 0 ) + /* Check for bitstream errors */ + IF( rc_st_dec.bit_error_detected != 0 ) { - new_e = hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx]; + *BER_detect = s_or( *BER_detect, 1 ); move16(); - BREAK; } + + return cur_bit_pos; } - hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = new_e; - move16(); + /*------------------------------------------------------------------------- + * param_mc_compute_interpolator() + * + * compute the interpolator used in the final synthesis + *------------------------------------------------------------------------*/ - /* remove LFE IF necessary */ - IF( remove_lfe ) + static void ivas_param_mc_dec_compute_interpolator_fx( + const UWord16 bAttackPresent, /* i : flag indicating if we have a transient in the current frame */ + const UWord16 attackPos, /* i : position of the transient */ + const UWord16 interp_length, /* i : number of interpolation values to be calculated */ + Word16 *interpolator /* o : interpolator */ + ) { + Word16 idx; - Cy_e = Cy_full_e; - remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); - } - ELSE - { - Copy32( Cy_full_fx, Cy_fx, imult1616( nY_band, nY_band ) ); - Cy_e = Cy_full_e; - move16(); - } + IF( bAttackPresent ) + { + FOR( idx = 0; idx < attackPos * 2; idx++ ) + { + interpolator[idx] = 0; + move16(); + } + FOR( ; idx < interp_length; idx++ ) + { + interpolator[idx] = 32767; /* 1.0f Q15 */ + move16(); + } + } + ELSE + { + ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, interp_length, interpolator ); + } - matrix_product_fx( proto_matrix_ptr_fx, nY_band, nX, 0, Cx_fx, nX, nX, 0, mat_mult_buffer1_fx ); - mat_mult_buffer1_e = add( proto_matrix_ptr_e, Cx_e ); + return; + } - matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e ); - /* make sure we have no negative entries in Cproto_diag due to rounding errors */ + /*------------------------------------------------------------------------- + * remove_lfe_from_cy() + * + * remove all LFE related values from a covariance matrix + *------------------------------------------------------------------------*/ - FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) + static void remove_lfe_from_cy_fx( + const Word16 nY, /* i : dimension of the covariance matrix */ + Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP], /* i : LFE index */ + Word16 num_lfe, /* i : number of LFEs */ + Word32 *cy, /* i : covariance matrix */ + Word32 *cy_woLFE /* o : covariance matrix with LFE removed */ + ) { - if ( Cproto_diag_fx[ch_idx1] < 0 ) + Word16 ch_idx1, ch_idx2; + Word16 lfe_idx1, lfe_idx2; + Word32 *ptrCy; + Word32 *ptrCy_out; + + ptrCy = cy; + ptrCy_out = cy_woLFE; + + FOR( lfe_idx1 = 0; lfe_idx1 < num_lfe + 1; lfe_idx1++ ) { - Cproto_diag_fx[ch_idx1] = 0; - move16(); + FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + { + FOR( lfe_idx2 = 0; lfe_idx2 < num_lfe + 1; lfe_idx2++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) + { + *( ptrCy_out++ ) = *( ptrCy++ ); + move32(); + } + ptrCy++; + } + ptrCy--; + } + ptrCy += nY; } + + return; } - /* Computing the mixing matrices */ + /*------------------------------------------------------------------------- + * ivas_param_mc_get_mixing_matrices() + * + * calculate the direct and residual mixing matrices + * using the covariance method + *------------------------------------------------------------------------*/ + + static void ivas_param_mc_get_mixing_matrices_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + IVAS_OUTPUT_SETUP * hSynthesisOutputSetup, + Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands Q(31 - Cx_in_e)*/ + Word16 Cx_in_e, + const Word16 param_band_idx, /* i : parameter band index */ + Word32 *mixing_matrix_fx[], // Q(31 - mixing_matrix_e) + Word16 *mixing_matrix_e, + Word32 *mixing_matrix_res_fx[], // Q(31 - mixing_matrix_res_e) + Word16 *mixing_matrix_res_e, + const Word16 nY_intern, /* i : number of channels in the transported format */ + const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ + const Word16 nX, /* i : number of transport channels */ + const Word16 nY_cov /* i : number of covariance synthesis output channels */ + ) + { + Word16 matSize = MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS; + Word16 nY_band; + Word16 num_lfe_bands; + Word16 brange[2]; + UWord16 i; + Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; + Word16 remove_lfe; + Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; + + Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + Word32 Cy_full_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + Word32 Cr_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cr_e) + Word16 Cr_e; + Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Cy_diag_buff_e) + Word16 Cy_diag_buff_e[MAX_OUTPUT_CHANNELS]; + Word32 mixing_matrix_local_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - mixing_matrix_local_e) + Word16 Cy_diag_e = 0, mixing_matrix_local_e = 0; + Word32 Cproto_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cproto_e) + Word16 Cproto_e; + Word32 *proto_matrix_ptr_fx; // Q(31 - proto_matrix_ptr_e) + Word32 *Cx_state_fx; // Q(31 - Cx_state_e) + Word32 *Cx_old_state_fx; + Word32 Cy_state_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cy_state_e) + Word32 *Cy_old_state_fx; + Word16 Cx_state_e; + Word16 Cy_state_e; + Word32 mixing_matrix_res_local_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mixing_matrix_res_local_e) + Word16 mixing_matrix_res_local_e; + Word32 L_tmp; + Word16 tmp_e, tmp; + + Word16 proto_matrix_e = hParamMC->h_output_synthesis_params.proto_matrix_e; + move16(); + Word32 proto_matrix_noLFE_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; // Q(31 - proto_matrix_noLFE_e) - /* bands with decorr */ - IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) - { - computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 0, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); - /* Compute mixing matrix FOR residual */ - computeMixingMatricesResidual_fx( nY_band, Cproto_diag_fx, Cproto_diag_e, Cr_fx, Cr_e, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_res_local_fx, &mixing_matrix_res_local_e ); + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - IF( NE_16( mixing_matrix_res_local_e, mixing_matrix_local_e ) ) - { - tmp = getScaleFactor32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); - scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, tmp ); - mixing_matrix_local_e = sub( mixing_matrix_local_e, tmp ); + Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) + Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e; - tmp = getScaleFactor32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, tmp ); - mixing_matrix_res_local_e = sub( mixing_matrix_res_local_e, tmp ); + Word32 *ptrMM_fx; + Word32 *ptrMM_out_fx; - scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, sub( mixing_matrix_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); - scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, sub( mixing_matrix_res_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); + Word16 Cy_e, Cx_e; + Word16 Cy_full_e; + Word16 new_e = 0; + move16(); - mixing_matrix_res_local_e = mixing_matrix_local_e = s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ); - move16(); - } - IF( remove_lfe ) + set_zero_fx( Cproto_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); + set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + Word16 proto_matrix_noLFE_e = 0; + move16(); + + Word32 Cx_in_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + + Copy32( Cx_in_fixed, Cx_in_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + nY_band = nY_cov; + move16(); + num_lfe_bands = 0; + move16(); + remove_lfe = 0; + move16(); + + set16_fx( lfe_indices, -1, PARAM_MC_LOCAL_SZ_LFE_MAP ); + IF( hSynthesisOutputSetup->num_lfe ) { - set_zero_fx( mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); + Word32 *proto_matrix_ptr_in_fx; + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe; lfe_idx1++ ) + { + lfe_indices[lfe_idx1 + 1] = hSynthesisOutputSetup->index_lfe[lfe_idx1]; + move16(); + } + lfe_indices[hSynthesisOutputSetup->num_lfe + 1] = nY_cov; + move16(); + proto_matrix_ptr_fx = &proto_matrix_noLFE_fx[0]; + proto_matrix_ptr_in_fx = &hParamMC->h_output_synthesis_params.proto_matrix_fx[0]; + proto_matrix_noLFE_e = proto_matrix_e; + move16(); - ptrMM_fx = mixing_matrix_res_local_fx; - ptrMM_out_fx = mixing_matrix_res_fx[param_band_idx]; - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); + + FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) { - FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) { - FOR( lfe_idx2 = 0; lfe_idx2 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx2++ ) + FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) { - FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) - { - *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); - move32(); - } - ptrMM_out_fx++; + *( proto_matrix_ptr_fx++ ) = *( proto_matrix_ptr_in_fx++ ); + move32(); } - ptrMM_out_fx--; + proto_matrix_ptr_in_fx++; } - ptrMM_out_fx += nY_cov; + proto_matrix_ptr_in_fx--; } - mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + + proto_matrix_ptr_e = proto_matrix_e; move16(); } - ELSE + + if ( hParamMC->hMetadataPMC->lfe_on ) { - Copy32( mixing_matrix_res_local_fx, mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); - mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + num_lfe_bands = PARAM_MC_MAX_BAND_LFE; move16(); } - } - ELSE IF( brange[0] < hParamMC->max_band_energy_compensation ) - { - /* Compute mixing matrices (energy compensation only) */ - computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 1, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); - } - ELSE - { - /*IF neither decorrelation nor energy compensation is applied*/ - FOR( i = 0; i < nY_band; i++ ) + IF( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) { - tmp = BASOP_Util_Divide3232_Scale( Cy_fx[i], L_add( Cproto_diag_fx[i], EPSILON_FX ), &tmp_e ); - tmp_e = add( Cy_diag_e, Cproto_diag_e ); - L_tmp = Sqrt32( L_deposit_h( tmp ), &tmp_e ); - Cy_diag_fx[i] = L_tmp; - move32(); - Cy_diag_buff_e[i] = tmp_e; + remove_lfe = 1; + move16(); + nY_band = sub( nY_cov, hSynthesisOutputSetup->num_lfe ); + proto_matrix_ptr_fx = proto_matrix_noLFE_fx; + proto_matrix_ptr_e = proto_matrix_noLFE_e; + move16(); + } + ELSE + { + proto_matrix_ptr_fx = hParamMC->h_output_synthesis_params.proto_matrix_fx; + proto_matrix_ptr_e = hParamMC->h_output_synthesis_params.proto_matrix_e; move16(); } + brange[0] = hParamMC->band_grouping[param_band_idx]; + move16(); + brange[1] = hParamMC->band_grouping[param_band_idx + 1]; + move16(); + + Cx_state_fx = Cx_in_fx; + Cx_old_state_fx = hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx]; + Cy_old_state_fx = hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx]; - Cy_diag_e = Cy_diag_buff_e[0]; + + /* Getting mixing mtx */ + /* estimate target cov from input cov and proto_matrix */ + + Cx_state_e = Cx_in_e; move16(); + matrix_product_fx( hParamMC->proto_matrix_int_fx, nY_intern, nX, 0, Cx_state_fx, nX, nX, 0, mat_mult_buffer1_fx ); + mat_mult_buffer1_e = add( hParamMC->proto_matrix_int_e, Cx_in_e ); - FOR( i = 1; i < nY_band; i++ ) + matrix_product_fx( mat_mult_buffer1_fx, nY_intern, nX, 0, hParamMC->proto_matrix_int_fx, nY_intern, nX, 1, Cproto_fx ); + Cproto_e = add( mat_mult_buffer1_e, hParamMC->proto_matrix_int_e ); + + FOR( ch_idx1 = 0; ch_idx1 < nY_intern; ch_idx1++ ) { - if ( LT_16( Cy_diag_e, Cy_diag_buff_e[i] ) ) + IF( BASOP_Util_Cmp_Mant32Exp( Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )], Cproto_e, 0, 0 ) < 0 ) { - Cy_diag_e = Cy_diag_buff_e[i]; - move16(); + Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )] = 0; + move32(); } } - FOR( i = 0; i < nY_band; i++ ) + set_zero_fx( Cy_state_fx, matSize ); + Cy_state_e = 0; + move16(); + + ivas_param_mc_dequantize_cov_fx( hParamMC, + hParamMC->icld_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ), + hParamMC->icc_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ), + param_band_idx, nY_cov, + synth_config, + nY_intern, + nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); + + // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); + + /* Smoothing: Sum over two buffers */ + IF( hParamMC->hMetadataPMC->bAttackPresent ) { - Cy_diag_fx[i] = L_shr( Cy_diag_fx[i], sub( Cy_diag_e, Cy_diag_buff_e[i] ) ); - move32(); + /* no smoothing on attacks */ + Copy32( Cx_state_fx, Cx_fx, imult1616( nX, nX ) ); + Copy32( Cy_state_fx, Cy_full_fx, imult1616( nY_cov, nY_cov ) ); + Cy_full_e = Cy_state_e; + move16(); + Cx_e = Cx_state_e; + move16(); } + ELSE + { + /* smoothing gains are now identical to one, simply add up */ + // v_add( Cy_state, Cy_old_state, Cy_full, nY_cov * nY_cov ); - diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e ); - } + v_add_fx_me( Cx_state_fx, Cx_state_e, Cx_old_state_fx, hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], Cx_fx, &Cx_e, imult1616( nX, nX ), 1 ); + v_add_fx_me( Cy_state_fx, Cy_state_e, Cy_old_state_fx, hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], Cy_full_fx, &Cy_full_e, imult1616( nY_cov, nY_cov ), 1 ); + } - IF( remove_lfe ) - { - set_zero_fx( mixing_matrix_fx[param_band_idx], imult1616( nX, nY_cov ) ); - ptrMM_fx = mixing_matrix_local_fx; - ptrMM_out_fx = mixing_matrix_fx[param_band_idx]; - FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) + Copy32( Cx_state_fx, Cx_old_state_fx, imult1616( nX, nX ) ); + + Copy32( Cy_state_fx, Cy_old_state_fx, imult1616( nY_cov, nY_cov ) ); + + hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = Cx_state_e; + move16(); + hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = Cy_state_e; + move16(); + + FOR( i = 0; i < nX * nX; i++ ) { - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + if ( Cx_old_state_fx[i] != 0 ) { - FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) - { - *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); - move32(); - } - ptrMM_out_fx++; + new_e = hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx]; + move16(); + BREAK; } - ptrMM_out_fx--; } - mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; + hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = new_e; move16(); - } - ELSE - { - Copy32( mixing_matrix_local_fx, mixing_matrix_fx[param_band_idx], imult1616( nY_cov, nX ) ); - mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; + + new_e = 0; move16(); - } - return; -} + FOR( i = 0; i < nY_cov * nY_cov; i++ ) + { + if ( Cy_old_state_fx[i] != 0 ) + { + new_e = hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx]; + move16(); + BREAK; + } + } + hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = new_e; + move16(); -/*------------------------------------------------------------------------- - * param_mc_update_mixing_matrices() - * - * update mixing matrix buffers - *------------------------------------------------------------------------*/ + /* remove LFE IF necessary */ + IF( remove_lfe ) + { -static void param_mc_update_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ - Word32 *mixing_matrix[], /* i : direct mixing matrices for the frame just processed */ - Word16 *mixing_matrix_exp, - Word32 *mixing_matrix_res[], /* i : residual mixing matrices for the frame just processed */ - Word16 *mixing_matrix_res_exp, - const UWord16 nX, /* i : number of transport channels */ - const UWord16 nY ) /* i : number of synthesis channels */ -{ - UWord16 param_band_idx; + Cy_e = Cy_full_e; + remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); + } + ELSE + { + Copy32( Cy_full_fx, Cy_fx, imult1616( nY_band, nY_band ) ); + Cy_e = Cy_full_e; + move16(); + } - FOR( param_band_idx = 0; param_band_idx < hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ ) - { - Word16 brange[2]; + matrix_product_fx( proto_matrix_ptr_fx, nY_band, nX, 0, Cx_fx, nX, nX, 0, mat_mult_buffer1_fx ); + mat_mult_buffer1_e = add( proto_matrix_ptr_e, Cx_e ); - brange[0] = hParamMC->band_grouping[param_band_idx]; - move16(); - brange[1] = hParamMC->band_grouping[param_band_idx + 1]; - move16(); + matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e ); - Copy32( mixing_matrix[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nX, nY ) ); - hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = mixing_matrix_exp[param_band_idx]; - move16(); + /* make sure we have no negative entries in Cproto_diag due to rounding errors */ - IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) + FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) { - Copy32( mixing_matrix_res[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nY, nY ) ); - hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = mixing_matrix_res_exp[param_band_idx]; - move16(); + if ( Cproto_diag_fx[ch_idx1] < 0 ) + { + Cproto_diag_fx[ch_idx1] = 0; + move16(); + } } - } - return; -} + /* Computing the mixing matrices */ -/*------------------------------------------------------------------------- - * ivas_param_mc_dequantize_cov() - * - * generate the target covariance matrix - *------------------------------------------------------------------------*/ + /* bands with decorr */ + IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) + { + computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 0, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); + /* Compute mixing matrix FOR residual */ + computeMixingMatricesResidual_fx( nY_band, Cproto_diag_fx, Cproto_diag_e, Cr_fx, Cr_e, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_res_local_fx, &mixing_matrix_res_local_e ); + IF( NE_16( mixing_matrix_res_local_e, mixing_matrix_local_e ) ) + { + tmp = getScaleFactor32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); + scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, tmp ); + mixing_matrix_local_e = sub( mixing_matrix_local_e, tmp ); -/*------------------------------------------------------------------------- - * ivas_param_mc_dequantize_cov_fx() - * - * generate the target covariance matrix - *------------------------------------------------------------------------*/ + tmp = getScaleFactor32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, tmp ); + mixing_matrix_res_local_e = sub( mixing_matrix_res_local_e, tmp ); -static void ivas_param_mc_dequantize_cov_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - Word16 *ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ - Word16 *icc_q_fx, /* i : sequence of dequantized ICC values Q15*/ - const Word16 param_band_index, /* i : current parameter band */ - const Word16 nY_cov, /* i : number of output channels in the covariance synthesis */ - const PARAM_MC_SYNTHESIS_CONF synth_conf, /* i : Parametric MC synthesis configuration */ - const Word16 nY_int, /* i : number of channels in the transported format */ - const Word16 nX, /* i : number of transport channels */ - Word32 *Cx_state_fx, /* i : transport channel covariance matrix */ - Word16 Cx_state_e, /* i : exponent for transport channel covariance matrix */ - Word32 *Cproto_fx, /* i : prototype matrix */ - Word16 Cproto_e, /* i : exponent for prototype matrix */ - Word32 *Cy_state_fx, /* o : target covariance matrix */ - Word16 *Cy_state_e /* o : exponent for target covariance matrix */ -) -{ - Word16 Cy_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Cp_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - - Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Nrqq_e) - Word16 Nrqq_e[MAX_OUTPUT_CHANNELS]; - Word32 a_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - a_e) - Word16 a_e[MAX_OUTPUT_CHANNELS]; - Word16 k; - Word16 l; - Word32 *Cyp_fx; // Q(31 - Cyp_e) - Word16 *Cyp_e; - Word32 ap_fx; // Q(31 - ap_e) - Word16 ap_e; - Word32 L_tmp; - Word16 tmp, tmp_e; - const PARAM_MC_ILD_MAPPING *h_ild_mapping; - Word32 Cy_state_int_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Cy_state_int_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - - set16_fx( Cp_buf_e, Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - set32_fx( Nrqq_fx, 0, MAX_OUTPUT_CHANNELS ); - set16_fx( Nrqq_e, 0, MAX_OUTPUT_CHANNELS ); - h_ild_mapping = hParamMC->hMetadataPMC->ild_mapping_conf; - - /*get back Nrg*/ - tmp = 0; - move16(); + scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, sub( mixing_matrix_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); + scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, sub( mixing_matrix_res_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); - FOR( k = 0; k < nY_int; k++ ) - { - Word32 ref_ener_fx = 0; // Q(31 - ref_ener_e) - move32(); - Word16 ref_ener_e = 0; - move16(); - Word16 ref_channel_cnt; - Word16 ref_channel_idx; + mixing_matrix_res_local_e = mixing_matrix_local_e = s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ); + move16(); + } + IF( remove_lfe ) + { + set_zero_fx( mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); - FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) + ptrMM_fx = mixing_matrix_res_local_fx; + ptrMM_out_fx = mixing_matrix_res_fx[param_band_idx]; + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + { + FOR( lfe_idx2 = 0; lfe_idx2 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx2++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) + { + *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); + move32(); + } + ptrMM_out_fx++; + } + ptrMM_out_fx--; + } + ptrMM_out_fx += nY_cov; + } + mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + move16(); + } + ELSE + { + Copy32( mixing_matrix_res_local_fx, mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); + mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + move16(); + } + } + ELSE IF( brange[0] < hParamMC->max_band_energy_compensation ) { - ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; - move16(); - ref_ener_fx = BASOP_Util_Add_Mant32Exp( Cx_state_fx[ref_channel_idx + ( ref_channel_idx * nX )], Cx_state_e, ref_ener_fx, ref_ener_e, &ref_ener_e ); - move32(); + /* Compute mixing matrices (energy compensation only) */ + computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 1, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); } + ELSE + { + /*IF neither decorrelation nor energy compensation is applied*/ + FOR( i = 0; i < nY_band; i++ ) + { + tmp = BASOP_Util_Divide3232_Scale( Cy_fx[i], L_add( Cproto_diag_fx[i], EPSILON_FX ), &tmp_e ); + tmp_e = add( Cy_diag_e, Cproto_diag_e ); + L_tmp = Sqrt32( L_deposit_h( tmp ), &tmp_e ); + Cy_diag_fx[i] = L_tmp; + move32(); + Cy_diag_buff_e[i] = tmp_e; + move16(); + } - L_tmp = Mpy_32_16_1( 713378626, ild_q_fx[k] ); /*Q24 : L_tmp Q31 for log2(10)/10 -> 713378626 */ - L_tmp = BASOP_util_Pow2( L_tmp, 31 - 24, &tmp_e ); /*powf( 10.0f, ild_q_fx[k] / 10.0f )*/ - L_tmp = Mpy_32_32( L_tmp, Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC->ild_factors_fx[k] ) ); - Nrqq_fx[h_ild_mapping->ild_index[k]] = L_tmp; - move32(); - Nrqq_e[h_ild_mapping->ild_index[k]] = add( tmp_e, ref_ener_e ); - move16(); - } + Cy_diag_e = Cy_diag_buff_e[0]; + move16(); - /* estimate ICCs from estimated Cproto */ + FOR( i = 1; i < nY_band; i++ ) + { + if ( LT_16( Cy_diag_e, Cy_diag_buff_e[i] ) ) + { + Cy_diag_e = Cy_diag_buff_e[i]; + move16(); + } + } - FOR( k = 0; k < nY_int; k++ ) - { - // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); - tmp_e = Cp_buf_e[k + ( nY_int * k )]; - move16(); + FOR( i = 0; i < nY_band; i++ ) + { + Cy_diag_fx[i] = L_shr( Cy_diag_fx[i], sub( Cy_diag_e, Cy_diag_buff_e[i] ) ); + move32(); + } - IF( Cproto_fx[k + ( nY_int * k )] != 0 ) - { - L_tmp = ISqrt32( Cproto_fx[k + ( nY_int * k )], &tmp_e ); + diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e ); } - ELSE + + IF( remove_lfe ) { - L_tmp = INV_EPSILON_MANT; - move32(); - tmp_e = 15; + set_zero_fx( mixing_matrix_fx[param_band_idx], imult1616( nX, nY_cov ) ); + ptrMM_fx = mixing_matrix_local_fx; + ptrMM_out_fx = mixing_matrix_fx[param_band_idx]; + FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) + { + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) + { + *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); + move32(); + } + ptrMM_out_fx++; + } + ptrMM_out_fx--; + } + + mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; move16(); } - a_fx[k] = L_tmp; - move32(); - a_e[k] = tmp_e; - move16(); - - FOR( l = 0; l < nY_int; l++ ) + ELSE { - Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cproto_fx[( k * nY_int ) + l], a_fx[k] ); - move32(); - Cy_state_int_e[( k * nY_int ) + l] = add( Cp_buf_e[( k * nY_int ) + l], a_e[k] ); + Copy32( mixing_matrix_local_fx, mixing_matrix_fx[param_band_idx], imult1616( nY_cov, nX ) ); + mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; move16(); } + + return; } - FOR( k = 0; k < nY_int; k++ ) + + /*------------------------------------------------------------------------- + * param_mc_update_mixing_matrices() + * + * update mixing matrix buffers + *------------------------------------------------------------------------*/ + + static void param_mc_update_mixing_matrices_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ + Word32 * mixing_matrix[], /* i : direct mixing matrices for the frame just processed */ + Word16 * mixing_matrix_exp, + Word32 * mixing_matrix_res[], /* i : residual mixing matrices for the frame just processed */ + Word16 * mixing_matrix_res_exp, + const UWord16 nX, /* i : number of transport channels */ + const UWord16 nY ) /* i : number of synthesis channels */ { - Cyp_fx = Cy_state_int_fx + k; - Cyp_e = Cy_state_int_e + k; - ap_fx = a_fx[k]; - move32(); - ap_e = a_e[k]; - move16(); + UWord16 param_band_idx; - FOR( l = 0; l < nY_int; l++ ) + FOR( param_band_idx = 0; param_band_idx < hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ ) { - ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); - move32(); - *Cyp_e = add( *Cyp_e, ap_e ); + Word16 brange[2]; + + brange[0] = hParamMC->band_grouping[param_band_idx]; + move16(); + brange[1] = hParamMC->band_grouping[param_band_idx + 1]; + move16(); + + Copy32( mixing_matrix[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nX, nY ) ); + hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = mixing_matrix_exp[param_band_idx]; move16(); - Cyp_fx += nY_int; - Cyp_e += nY_int; + IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) + { + Copy32( mixing_matrix_res[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nY, nY ) ); + hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = mixing_matrix_res_exp[param_band_idx]; + move16(); + } } + + return; } - /*normalizing the Cy_state_int_fx to a common exponent*/ - /* replace some estimated ICCs with transmitted values */ - FOR( k = 0; k < hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; k++ ) - { - Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); - move32(); - Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = tmp; - move16(); - Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); - move32(); - Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = tmp; + /*------------------------------------------------------------------------- + * ivas_param_mc_dequantize_cov() + * + * generate the target covariance matrix + *------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------- + * ivas_param_mc_dequantize_cov_fx() + * + * generate the target covariance matrix + *------------------------------------------------------------------------*/ + + static void ivas_param_mc_dequantize_cov_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + Word16 * ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ + Word16 * icc_q_fx, /* i : sequence of dequantized ICC values Q15*/ + const Word16 param_band_index, /* i : current parameter band */ + const Word16 nY_cov, /* i : number of output channels in the covariance synthesis */ + const PARAM_MC_SYNTHESIS_CONF synth_conf, /* i : Parametric MC synthesis configuration */ + const Word16 nY_int, /* i : number of channels in the transported format */ + const Word16 nX, /* i : number of transport channels */ + Word32 *Cx_state_fx, /* i : transport channel covariance matrix */ + Word16 Cx_state_e, /* i : exponent for transport channel covariance matrix */ + Word32 *Cproto_fx, /* i : prototype matrix */ + Word16 Cproto_e, /* i : exponent for prototype matrix */ + Word32 *Cy_state_fx, /* o : target covariance matrix */ + Word16 *Cy_state_e /* o : exponent for target covariance matrix */ + ) + { + Word16 Cy_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cp_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Nrqq_e) + Word16 Nrqq_e[MAX_OUTPUT_CHANNELS]; + Word32 a_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - a_e) + Word16 a_e[MAX_OUTPUT_CHANNELS]; + Word16 k; + Word16 l; + Word32 *Cyp_fx; // Q(31 - Cyp_e) + Word16 *Cyp_e; + Word32 ap_fx; // Q(31 - ap_e) + Word16 ap_e; + Word32 L_tmp; + Word16 tmp, tmp_e; + const PARAM_MC_ILD_MAPPING *h_ild_mapping; + Word32 Cy_state_int_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cy_state_int_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + set16_fx( Cp_buf_e, Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + set32_fx( Nrqq_fx, 0, MAX_OUTPUT_CHANNELS ); + set16_fx( Nrqq_e, 0, MAX_OUTPUT_CHANNELS ); + h_ild_mapping = hParamMC->hMetadataPMC->ild_mapping_conf; + + /*get back Nrg*/ + tmp = 0; move16(); - } - test(); - IF( GE_16( param_band_index, PARAM_MC_MAX_BAND_LFE ) || ( hParamMC->hMetadataPMC->lfe_on == 0 ) ) - { FOR( k = 0; k < nY_int; k++ ) { - Cy_state_int_fx[k + ( 3 * nY_int )] = ONE_IN_Q31; - move32(); - Cy_state_int_e[k + ( 3 * nY_int )] = 0; - move16(); - Cy_state_int_fx[3 + ( k * nY_int )] = ONE_IN_Q31; + Word32 ref_ener_fx = 0; // Q(31 - ref_ener_e) move32(); - Cy_state_int_e[3 + ( k * nY_int )] = 0; + Word16 ref_ener_e = 0; move16(); - } - Nrqq_fx[3] = 0; - move32(); - } + Word16 ref_channel_cnt; + Word16 ref_channel_idx; - /* Generate back Covariance Mtx */ - FOR( k = 0; k < nY_int; k++ ) - { - tmp_e = Nrqq_e[k]; - move16(); - a_fx[k] = Sqrt32( Nrqq_fx[k], &tmp_e ); - move32(); - a_e[k] = tmp_e; - move16(); + FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) + { + ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; + move16(); + ref_ener_fx = BASOP_Util_Add_Mant32Exp( Cx_state_fx[ref_channel_idx + ( ref_channel_idx * nX )], Cx_state_e, ref_ener_fx, ref_ener_e, &ref_ener_e ); + move32(); + } - /* v_multc( Cy_state_int_fx + k * nY_int, a_fx[k], Cy_state_int_fx + k * nY_int, nY_int ) */ - FOR( l = 0; l < nY_int; l++ ) - { - Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cy_state_int_fx[( k * nY_int ) + l], a_fx[k] ); + L_tmp = Mpy_32_16_1( 713378626, ild_q_fx[k] ); /*Q24 : L_tmp Q31 for log2(10)/10 -> 713378626 */ + L_tmp = BASOP_util_Pow2( L_tmp, 31 - 24, &tmp_e ); /*powf( 10.0f, ild_q_fx[k] / 10.0f )*/ + L_tmp = Mpy_32_32( L_tmp, Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC->ild_factors_fx[k] ) ); + + Nrqq_fx[h_ild_mapping->ild_index[k]] = L_tmp; move32(); - Cy_state_int_e[( k * nY_int ) + l] = add( Cy_state_int_e[( k * nY_int ) + l], a_e[k] ); + Nrqq_e[h_ild_mapping->ild_index[k]] = add( tmp_e, ref_ener_e ); move16(); } - } - FOR( k = 0; k < nY_int; k++ ) - { - Cyp_fx = Cy_state_int_fx + k; - Cyp_e = Cy_state_int_e + k; - ap_fx = a_fx[k]; - move32(); - ap_e = a_e[k]; - move16(); + /* estimate ICCs from estimated Cproto */ - FOR( l = 0; l < nY_int; l++ ) + FOR( k = 0; k < nY_int; k++ ) { - ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); - move32(); - ( *Cyp_e ) = add( *Cyp_e, ap_e ); + // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); + tmp_e = Cp_buf_e[k + ( nY_int * k )]; move16(); - Cyp_fx += nY_int; - Cyp_e += nY_int; - } - } - - IF( EQ_32( synth_conf, PARAM_MC_SYNTH_LS_CONV_COV ) ) - { - /* Cy = dmx*Cy*dmx' */ - Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - Word16 mat_mult_buffer1_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; // Q(31 - target_ch_ener_e) - Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; - Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; - - Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); - set16_fx( target_ch_ener_e, 0, MAX_CICP_CHANNELS ); - set32_fx( dmx_ch_ener_fx, 0, MAX_CICP_CHANNELS ); - set16_fx( ls_conv_dmx_matrix_e, 1, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 0, - Cy_state_int_fx, Cy_state_int_e, nY_int, nY_int, 0, - mat_mult_buffer1_fx, mat_mult_buffer1_e ); - - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_cov, nY_int, 0, - hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 1, - Cy_state_fx, Cy_buf_e ); + IF( Cproto_fx[k + ( nY_int * k )] != 0 ) + { + L_tmp = ISqrt32( Cproto_fx[k + ( nY_int * k )], &tmp_e ); + } + ELSE + { + L_tmp = INV_EPSILON_MANT; + move32(); + tmp_e = 15; + move16(); + } + a_fx[k] = L_tmp; + move32(); + a_e[k] = tmp_e; + move16(); - FOR( k = 0; k < nY_cov; k++ ) - { FOR( l = 0; l < nY_int; l++ ) { - L_tmp = Mpy_32_32( hParamMC->ls_conv_dmx_matrix_fx[k + ( l * nY_cov )], Nrqq_fx[l] ); - tmp_e = add( ls_conv_dmx_matrix_e[k + ( l + nY_cov )], Nrqq_e[l] ); - L_tmp = BASOP_Util_Add_Mant32Exp( target_ch_ener_fx[k], target_ch_ener_e[k], L_tmp, tmp_e, &tmp_e ); - target_ch_ener_fx[k] = L_tmp; + Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cproto_fx[( k * nY_int ) + l], a_fx[k] ); move32(); - target_ch_ener_e[k] = tmp_e; + Cy_state_int_e[( k * nY_int ) + l] = add( Cp_buf_e[( k * nY_int ) + l], a_e[k] ); move16(); } + } - dmx_ch_ener_fx[k] = Cy_state_fx[k + ( nY_cov * k )]; + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; move32(); + ap_e = a_e[k]; + move16(); - IF( dmx_ch_ener_fx[k] < 0 ) + FOR( l = 0; l < nY_int; l++ ) { - Cy_state_fx[k + ( nY_cov * k )] = L_negate( Cy_state_fx[k + ( nY_cov * k )] ); - move32(); - dmx_ch_ener_fx[k] = L_negate( dmx_ch_ener_fx[k] ); + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); move32(); + *Cyp_e = add( *Cyp_e, ap_e ); + move16(); + + Cyp_fx += nY_int; + Cyp_e += nY_int; } + } + + /*normalizing the Cy_state_int_fx to a common exponent*/ + + /* replace some estimated ICCs with transmitted values */ + FOR( k = 0; k < hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; k++ ) + { + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = tmp; + move16(); + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = tmp; + move16(); + } - IF( extract_h( dmx_ch_ener_fx[k] ) == 0 ) + test(); + IF( GE_16( param_band_index, PARAM_MC_MAX_BAND_LFE ) || ( hParamMC->hMetadataPMC->lfe_on == 0 ) ) + { + FOR( k = 0; k < nY_int; k++ ) { - target_ch_ener_fx[k] = 0; + Cy_state_int_fx[k + ( 3 * nY_int )] = ONE_IN_Q31; move32(); - target_ch_ener_e[k] = 0; + Cy_state_int_e[k + ( 3 * nY_int )] = 0; move16(); - } - ELSE - { - BASOP_Util_Divide_MantExp( extract_h( target_ch_ener_fx[k] ), target_ch_ener_e[k], extract_h( dmx_ch_ener_fx[k] ), Cy_buf_e[k + ( nY_cov * k )], &tmp, &tmp_e ); - tmp = Sqrt16( tmp, &tmp_e ); - target_ch_ener_fx[k] = L_deposit_h( tmp ); + Cy_state_int_fx[3 + ( k * nY_int )] = ONE_IN_Q31; move32(); - target_ch_ener_e[k] = tmp_e; + Cy_state_int_e[3 + ( k * nY_int )] = 0; move16(); } + Nrqq_fx[3] = 0; + move32(); + } + + /* Generate back Covariance Mtx */ + FOR( k = 0; k < nY_int; k++ ) + { + tmp_e = Nrqq_e[k]; + move16(); + a_fx[k] = Sqrt32( Nrqq_fx[k], &tmp_e ); + move32(); + a_e[k] = tmp_e; + move16(); - FOR( l = 0; l < nY_cov; l++ ) + /* v_multc( Cy_state_int_fx + k * nY_int, a_fx[k], Cy_state_int_fx + k * nY_int, nY_int ) */ + FOR( l = 0; l < nY_int; l++ ) { - Cy_state_fx[( k * nY_cov ) + l] = Mpy_32_32( target_ch_ener_fx[k], Cy_state_fx[( k * nY_cov ) + l] ); + Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cy_state_int_fx[( k * nY_int ) + l], a_fx[k] ); move32(); - Cy_buf_e[( k * nY_cov ) + l] = add( target_ch_ener_e[k], Cy_buf_e[( k * nY_cov ) + l] ); + Cy_state_int_e[( k * nY_int ) + l] = add( Cy_state_int_e[( k * nY_int ) + l], a_e[k] ); move16(); } + } - Cyp_fx = Cy_state_fx + k; - Cyp_e = Cy_buf_e + k; - ap_fx = target_ch_ener_fx[k]; + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; move32(); - ap_e = target_ch_ener_e[k]; + ap_e = a_e[k]; move16(); - FOR( l = 0; l < nY_cov; l++ ) + + FOR( l = 0; l < nY_int; l++ ) { ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); move32(); - *Cyp_e = add( *Cyp_e, ap_e ); + ( *Cyp_e ) = add( *Cyp_e, ap_e ); move16(); - Cyp_fx += nY_cov; - Cyp_e += nY_cov; + Cyp_fx += nY_int; + Cyp_e += nY_int; } } - } - ELSE - { - Copy32( Cy_state_int_fx, Cy_state_fx, imult1616( nY_int, nY_int ) ); - Copy( Cy_state_int_e, Cy_buf_e, imult1616( nY_int, nY_int ) ); - } - /*normalize output matrix to a common exponent*/ - tmp = 0; - FOR( k = 0; k < nY_int * nY_int; k++ ) - { - Cy_state_fx[k] = BASOP_Util_Add_Mant32Exp( Cy_state_fx[k], Cy_buf_e[k], 0, 0, &Cy_buf_e[k] ); - move32(); - tmp = s_max( tmp, Cy_buf_e[k] ); - } - FOR( k = 0; k < nY_int * nY_int; k++ ) - { - L_tmp = L_shr( Cy_state_fx[k], sub( tmp, Cy_buf_e[k] ) ); - Cy_state_fx[k] = L_tmp; - move32(); - } - *Cy_state_e = tmp; - move16(); + IF( EQ_32( synth_conf, PARAM_MC_SYNTH_LS_CONV_COV ) ) + { + /* Cy = dmx*Cy*dmx' */ + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) + Word16 mat_mult_buffer1_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; // Q(31 - target_ch_ener_e) + Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; + Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; - return; -} + Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; -/*-------------------------------------------------------------------------* - * param_mc_set_num_synth_bands() - * - * set the number of frequency bands to be synthesized - *-------------------------------------------------------------------------*/ + set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( target_ch_ener_e, 0, MAX_CICP_CHANNELS ); + set32_fx( dmx_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( ls_conv_dmx_matrix_e, 1, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); -static void param_mc_set_num_synth_bands( - const Word32 output_Fs, /* i : output sampling frequency */ - PARAM_MC_DEC_HANDLE hParamMC /* i/o: Parametric MC handle */ -) -{ - UWord16 max_param_band_synth; - const Word16 *param_mc_bands_coded; + matrix_product_mant_exp( hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 0, + Cy_state_int_fx, Cy_state_int_e, nY_int, nY_int, 0, + mat_mult_buffer1_fx, mat_mult_buffer1_e ); - SWITCH( hParamMC->hMetadataPMC->num_parameter_bands ) - { - case 20: - param_mc_bands_coded = param_mc_bands_coded_20; - BREAK; - case 10: - param_mc_bands_coded = param_mc_bands_coded_10; - BREAK; - case 14: - default: - param_mc_bands_coded = param_mc_bands_coded_14; - BREAK; - } - move16(); - SWITCH( output_Fs ) - { - case 8000: - max_param_band_synth = (UWord16) param_mc_bands_coded[NB]; - BREAK; - case 16000: - max_param_band_synth = (UWord16) param_mc_bands_coded[WB]; - BREAK; - case 32000: - max_param_band_synth = (UWord16) param_mc_bands_coded[SWB]; - BREAK; - case 48000: - default: - max_param_band_synth = (UWord16) param_mc_bands_coded[FB]; - BREAK; - } - move16(); - hParamMC->num_param_bands_synth = s_min( hParamMC->hMetadataPMC->nbands_coded, max_param_band_synth ); - move16(); + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_cov, nY_int, 0, + hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 1, + Cy_state_fx, Cy_buf_e ); - return; -} + FOR( k = 0; k < nY_cov; k++ ) + { + FOR( l = 0; l < nY_int; l++ ) + { + L_tmp = Mpy_32_32( hParamMC->ls_conv_dmx_matrix_fx[k + ( l * nY_cov )], Nrqq_fx[l] ); + tmp_e = add( ls_conv_dmx_matrix_e[k + ( l + nY_cov )], Nrqq_e[l] ); + L_tmp = BASOP_Util_Add_Mant32Exp( target_ch_ener_fx[k], target_ch_ener_e[k], L_tmp, tmp_e, &tmp_e ); + target_ch_ener_fx[k] = L_tmp; + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + dmx_ch_ener_fx[k] = Cy_state_fx[k + ( nY_cov * k )]; + move32(); -/*-------------------------------------------------------------------------* - * param_mc_get_diff_proto_info() - * - * calculated the diffuse prototype information - *-------------------------------------------------------------------------*/ + IF( dmx_ch_ener_fx[k] < 0 ) + { + Cy_state_fx[k + ( nY_cov * k )] = L_negate( Cy_state_fx[k + ( nY_cov * k )] ); + move32(); + dmx_ch_ener_fx[k] = L_negate( dmx_ch_ener_fx[k] ); + move32(); + } + + IF( extract_h( dmx_ch_ener_fx[k] ) == 0 ) + { + target_ch_ener_fx[k] = 0; + move32(); + target_ch_ener_e[k] = 0; + move16(); + } + ELSE + { + BASOP_Util_Divide_MantExp( extract_h( target_ch_ener_fx[k] ), target_ch_ener_e[k], extract_h( dmx_ch_ener_fx[k] ), Cy_buf_e[k + ( nY_cov * k )], &tmp, &tmp_e ); + tmp = Sqrt16( tmp, &tmp_e ); + target_ch_ener_fx[k] = L_deposit_h( tmp ); + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + FOR( l = 0; l < nY_cov; l++ ) + { + Cy_state_fx[( k * nY_cov ) + l] = Mpy_32_32( target_ch_ener_fx[k], Cy_state_fx[( k * nY_cov ) + l] ); + move32(); + Cy_buf_e[( k * nY_cov ) + l] = add( target_ch_ener_e[k], Cy_buf_e[( k * nY_cov ) + l] ); + move16(); + } -static ivas_error param_mc_get_diff_proto_info_fx( - const Word32 *proto_mtx, /* i : protoype matrix for the synthesis */ - const UWord16 nchan_transport, /* i : number of transport channels */ - const UWord16 nchan_out_cov, /* i : number if output channels of the covariance synthesis */ - PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, /* o : generated diffuse prototype info */ - Word16 Q_proto_mtx ) -{ - Word32 proto_fac_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - UWord16 cur_out_ch; - UWord16 cur_diff_proto; - UWord16 cur_transport_ch; - UWord16 max_num_src_chan; - - /* Initializations */ - max_num_src_chan = 0; - move16(); + Cyp_fx = Cy_state_fx + k; + Cyp_e = Cy_buf_e + k; + ap_fx = target_ch_ener_fx[k]; + move32(); + ap_e = target_ch_ener_e[k]; + move16(); + FOR( l = 0; l < nY_cov; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + move32(); + *Cyp_e = add( *Cyp_e, ap_e ); + move16(); - set_zero_fx( proto_fac_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); - IF( ( p_diff_proto_info->proto_index_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( p_diff_proto_info->proto_index_diff, 0, nchan_out_cov ); + Cyp_fx += nY_cov; + Cyp_e += nY_cov; + } + } + } + ELSE + { + Copy32( Cy_state_int_fx, Cy_state_fx, imult1616( nY_int, nY_int ) ); + Copy( Cy_state_int_e, Cy_buf_e, imult1616( nY_int, nY_int ) ); + } - IF( ( p_diff_proto_info->num_source_chan_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( p_diff_proto_info->num_source_chan_diff, 0, nchan_out_cov ); + /*normalize output matrix to a common exponent*/ + tmp = 0; + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + Cy_state_fx[k] = BASOP_Util_Add_Mant32Exp( Cy_state_fx[k], Cy_buf_e[k], 0, 0, &Cy_buf_e[k] ); + move32(); + tmp = s_max( tmp, Cy_buf_e[k] ); + } + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + L_tmp = L_shr( Cy_state_fx[k], sub( tmp, Cy_buf_e[k] ) ); + Cy_state_fx[k] = L_tmp; + move32(); + } + *Cy_state_e = tmp; + move16(); - /* we have at least one prototype, copy the first one */ - p_diff_proto_info->num_protos_diff = 1; - move16(); + return; + } - mvr2r_inc_fx( proto_mtx, nchan_out_cov, proto_fac_fx, nchan_out_cov, nchan_transport ); - p_diff_proto_info->proto_index_diff[0] = 0; - move16(); + /*-------------------------------------------------------------------------* + * param_mc_set_num_synth_bands() + * + * set the number of frequency bands to be synthesized + *-------------------------------------------------------------------------*/ - /* search for distinct prototypes */ - FOR( cur_out_ch = 1; cur_out_ch < nchan_out_cov; cur_out_ch++ ) + static void param_mc_set_num_synth_bands( + const Word32 output_Fs, /* i : output sampling frequency */ + PARAM_MC_DEC_HANDLE hParamMC /* i/o: Parametric MC handle */ + ) { - UWord16 found = 0; - move16(); + UWord16 max_param_band_synth; + const Word16 *param_mc_bands_coded; - FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + SWITCH( hParamMC->hMetadataPMC->num_parameter_bands ) { - Word32 diff_fx = 0; - move32(); - Word32 *proto_fac_ptr_fx = proto_fac_fx + cur_diff_proto; - const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) - { - diff_fx = L_add( diff_fx, L_abs( L_sub( *proto_fac_ptr_fx, *proto_mtx_ptr ) ) ); - proto_fac_ptr_fx += nchan_out_cov; - proto_mtx_ptr += nchan_out_cov; - } - - /* we already have this prototype, save the index */ - IF( LT_64( W_mult0_32_32( diff_fx, 10 ), L_shl_sat( 1, Q_proto_mtx ) ) ) - { - found = 1; - move16(); - p_diff_proto_info->proto_index_diff[cur_out_ch] = cur_diff_proto; - move16(); + case 20: + param_mc_bands_coded = param_mc_bands_coded_20; + BREAK; + case 10: + param_mc_bands_coded = param_mc_bands_coded_10; + BREAK; + case 14: + default: + param_mc_bands_coded = param_mc_bands_coded_14; BREAK; - } } - - /* new distinct prototype, add it */ - IF( found == 0 ) + move16(); + SWITCH( output_Fs ) { - const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; - Word16 cur_num_src_chan; + case 8000: + max_param_band_synth = (UWord16) param_mc_bands_coded[NB]; + BREAK; + case 16000: + max_param_band_synth = (UWord16) param_mc_bands_coded[WB]; + BREAK; + case 32000: + max_param_band_synth = (UWord16) param_mc_bands_coded[SWB]; + BREAK; + case 48000: + default: + max_param_band_synth = (UWord16) param_mc_bands_coded[FB]; + BREAK; + } + move16(); + hParamMC->num_param_bands_synth = s_min( hParamMC->hMetadataPMC->nbands_coded, max_param_band_synth ); + move16(); - cur_num_src_chan = 0; - move16(); - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) - { - if ( GT_32( *proto_mtx_ptr, 0 /*EPSILON*/ ) ) - { - cur_num_src_chan = add( cur_num_src_chan, 1 ); - } - proto_mtx_ptr += nchan_out_cov; - } + return; + } - mvr2r_inc_fx( proto_mtx + cur_out_ch, nchan_out_cov, proto_fac_fx + p_diff_proto_info->num_protos_diff, nchan_out_cov, nchan_transport ); - p_diff_proto_info->proto_index_diff[cur_out_ch] = p_diff_proto_info->num_protos_diff; - move16(); - p_diff_proto_info->num_protos_diff = add( p_diff_proto_info->num_protos_diff, 1 ); - move16(); - max_num_src_chan = s_max( max_num_src_chan, cur_num_src_chan ); - } - } + /*-------------------------------------------------------------------------* + * param_mc_get_diff_proto_info() + * + * calculated the diffuse prototype information + *-------------------------------------------------------------------------*/ - /* set up the prototype info struct */ - IF( ( p_diff_proto_info->source_chan_idx = (Word16 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word16 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - IF( ( p_diff_proto_info->proto_fac_fx = (Word32 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word32 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + static ivas_error param_mc_get_diff_proto_info_fx( + const Word32 *proto_mtx, /* i : protoype matrix for the synthesis */ + const UWord16 nchan_transport, /* i : number of transport channels */ + const UWord16 nchan_out_cov, /* i : number if output channels of the covariance synthesis */ + PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, /* o : generated diffuse prototype info */ + Word16 Q_proto_mtx ) { - Word32 *proto_fac_ptr; + Word32 proto_fac_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; + UWord16 cur_out_ch; + UWord16 cur_diff_proto; + UWord16 cur_transport_ch; + UWord16 max_num_src_chan; - IF( ( p_diff_proto_info->source_chan_idx[cur_diff_proto] = (Word16 *) malloc( max_num_src_chan * sizeof( Word16 ) ) ) == NULL ) + /* Initializations */ + max_num_src_chan = 0; + move16(); + + set_zero_fx( proto_fac_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); + IF( ( p_diff_proto_info->proto_index_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } + set16_fx( p_diff_proto_info->proto_index_diff, 0, nchan_out_cov ); - IF( ( p_diff_proto_info->proto_fac_fx[cur_diff_proto] = (Word32 *) malloc( max_num_src_chan * sizeof( Word32 ) ) ) == NULL ) + IF( ( p_diff_proto_info->num_source_chan_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } + set16_fx( p_diff_proto_info->num_source_chan_diff, 0, nchan_out_cov ); + + /* we have at least one prototype, copy the first one */ + p_diff_proto_info->num_protos_diff = 1; + move16(); - proto_fac_ptr = proto_fac_fx + cur_diff_proto; - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + mvr2r_inc_fx( proto_mtx, nchan_out_cov, proto_fac_fx, nchan_out_cov, nchan_transport ); + p_diff_proto_info->proto_index_diff[0] = 0; + move16(); + + /* search for distinct prototypes */ + FOR( cur_out_ch = 1; cur_out_ch < nchan_out_cov; cur_out_ch++ ) { - IF( GT_32( *proto_fac_ptr, EPSILON_FX_SMALL ) ) + UWord16 found = 0; + move16(); + + FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + { + Word32 diff_fx = 0; + move32(); + Word32 *proto_fac_ptr_fx = proto_fac_fx + cur_diff_proto; + const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + diff_fx = L_add( diff_fx, L_abs( L_sub( *proto_fac_ptr_fx, *proto_mtx_ptr ) ) ); + proto_fac_ptr_fx += nchan_out_cov; + proto_mtx_ptr += nchan_out_cov; + } + + /* we already have this prototype, save the index */ + IF( LT_64( W_mult0_32_32( diff_fx, 10 ), L_shl_sat( 1, Q_proto_mtx ) ) ) + { + found = 1; + move16(); + p_diff_proto_info->proto_index_diff[cur_out_ch] = cur_diff_proto; + move16(); + BREAK; + } + } + + /* new distinct prototype, add it */ + IF( found == 0 ) { - p_diff_proto_info->source_chan_idx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = cur_transport_ch; + const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; + Word16 cur_num_src_chan; + + cur_num_src_chan = 0; move16(); - p_diff_proto_info->proto_fac_fx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = *proto_fac_ptr; // (proto_fac_fx)Q26 = Q26 + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + if ( GT_32( *proto_mtx_ptr, 0 /*EPSILON*/ ) ) + { + cur_num_src_chan = add( cur_num_src_chan, 1 ); + } + proto_mtx_ptr += nchan_out_cov; + } + + mvr2r_inc_fx( proto_mtx + cur_out_ch, nchan_out_cov, proto_fac_fx + p_diff_proto_info->num_protos_diff, nchan_out_cov, nchan_transport ); + + p_diff_proto_info->proto_index_diff[cur_out_ch] = p_diff_proto_info->num_protos_diff; move16(); - p_diff_proto_info->num_source_chan_diff[cur_diff_proto] = add( p_diff_proto_info->num_source_chan_diff[cur_diff_proto], 1 ); + p_diff_proto_info->num_protos_diff = add( p_diff_proto_info->num_protos_diff, 1 ); move16(); + max_num_src_chan = s_max( max_num_src_chan, cur_num_src_chan ); } - proto_fac_ptr += nchan_out_cov; } - } - return IVAS_ERR_OK; -} + /* set up the prototype info struct */ + IF( ( p_diff_proto_info->source_chan_idx = (Word16 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word16 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } -/*-------------------------------------------------------------------------* - * ivas_param_mc_bs_decode_parameter_values() - * - * reads and decodes a sequence of Parametric MC parameters from the bitstream - *-------------------------------------------------------------------------*/ - -static void ivas_param_mc_bs_decode_parameter_values_fx( - UWord16 bit_buffer[], /* i : bitstream buffer */ - Word16 *bit_pos, /* i/o: current bitstream buffer position */ - const Word16 max_bits, /* i : maximum available bits in the buffer */ - Word16 *BER_detect, /* i/o: bit error detection flag */ - HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata information */ - HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, /* i : Parametric MC parameter quantization and coding tables */ - const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFEs) */ - const Word16 map_size, /* i : number of parameters per band (total) */ - const Word16 num_lfe_bands, /* i : number of parameter bands with coded LFE */ - const Word16 band_step, /* i : parameter band step */ - const Word16 num_param_bands, /* i : number of parameter bands to decode */ - Word16 *value_buffer /* o : output buffer for decoded parameter values hParamCodingInfo -> Q-quant*/ -) -{ - Word16 range_coding; - Word16 sz_seq; - Word16 delta_coding; - Word16 delta_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 idx_prev; - Word16 idx_offset; - Word16 sz_alphabet; - Word16 i, j, k; - Word16 dequant_seq_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 dequant_ordered_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 n_lfe_idx; + IF( ( p_diff_proto_info->proto_fac_fx = (Word32 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + { + Word32 *proto_fac_ptr; - range_coding = bit_buffer[*bit_pos]; - move16(); - *bit_pos = add( *bit_pos, 1 ); - move16(); + IF( ( p_diff_proto_info->source_chan_idx[cur_diff_proto] = (Word16 *) malloc( max_num_src_chan * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } - /* Decoding the sequence */ - n_lfe_idx = sub( map_size, map_size_wo_lfe ); - sz_seq = add( imult1616( num_param_bands, map_size_wo_lfe ), imult1616( num_lfe_bands, n_lfe_idx ) ); + IF( ( p_diff_proto_info->proto_fac_fx[cur_diff_proto] = (Word32 *) malloc( max_num_src_chan * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } - set16_fx( idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - set16_fx( dequant_ordered_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - IF( range_coding ) - { - delta_coding = bit_buffer[*bit_pos]; + proto_fac_ptr = proto_fac_fx + cur_diff_proto; + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + IF( GT_32( *proto_fac_ptr, EPSILON_FX_SMALL ) ) + { + p_diff_proto_info->source_chan_idx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = cur_transport_ch; + move16(); + p_diff_proto_info->proto_fac_fx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = *proto_fac_ptr; // (proto_fac_fx)Q26 = Q26 + move16(); + p_diff_proto_info->num_source_chan_diff[cur_diff_proto] = add( p_diff_proto_info->num_source_chan_diff[cur_diff_proto], 1 ); + move16(); + } + proto_fac_ptr += nchan_out_cov; + } + } + return IVAS_ERR_OK; + } + + + /*-------------------------------------------------------------------------* + * ivas_param_mc_bs_decode_parameter_values() + * + * reads and decodes a sequence of Parametric MC parameters from the bitstream + *-------------------------------------------------------------------------*/ + + static void ivas_param_mc_bs_decode_parameter_values_fx( + UWord16 bit_buffer[], /* i : bitstream buffer */ + Word16 * bit_pos, /* i/o: current bitstream buffer position */ + const Word16 max_bits, /* i : maximum available bits in the buffer */ + Word16 *BER_detect, /* i/o: bit error detection flag */ + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata information */ + HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, /* i : Parametric MC parameter quantization and coding tables */ + const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFEs) */ + const Word16 map_size, /* i : number of parameters per band (total) */ + const Word16 num_lfe_bands, /* i : number of parameter bands with coded LFE */ + const Word16 band_step, /* i : parameter band step */ + const Word16 num_param_bands, /* i : number of parameter bands to decode */ + Word16 *value_buffer /* o : output buffer for decoded parameter values hParamCodingInfo -> Q-quant*/ + ) + { + Word16 range_coding; + Word16 sz_seq; + Word16 delta_coding; + Word16 delta_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 idx_prev; + Word16 idx_offset; + Word16 sz_alphabet; + Word16 i, j, k; + Word16 dequant_seq_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 dequant_ordered_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 n_lfe_idx; + + range_coding = bit_buffer[*bit_pos]; move16(); *bit_pos = add( *bit_pos, 1 ); move16(); - IF( delta_coding ) - { - idx_prev = sub( add( shr( hParamCodingInfo->quantizer_size, 1 ), hParamCodingInfo->quantizer_size % 2 ), 1 ); - sz_alphabet = sub( shl( hParamCodingInfo->quantizer_size, 1 ), 1 ); - idx_offset = sub( hParamCodingInfo->quantizer_size, 1 ); + /* Decoding the sequence */ + n_lfe_idx = sub( map_size, map_size_wo_lfe ); + sz_seq = add( imult1616( num_param_bands, map_size_wo_lfe ), imult1616( num_lfe_bands, n_lfe_idx ) ); - /* read range coded delta ICC indices */ - *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], delta_idx, BER_detect, sz_seq, sz_alphabet, - hParamCodingInfo->cum_freq_delta, hParamCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); + set16_fx( idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + set16_fx( dequant_ordered_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + IF( range_coding ) + { + delta_coding = bit_buffer[*bit_pos]; + move16(); + *bit_pos = add( *bit_pos, 1 ); move16(); - /* delta index to absolute index */ + IF( delta_coding ) + { + idx_prev = sub( add( shr( hParamCodingInfo->quantizer_size, 1 ), hParamCodingInfo->quantizer_size % 2 ), 1 ); + sz_alphabet = sub( shl( hParamCodingInfo->quantizer_size, 1 ), 1 ); + idx_offset = sub( hParamCodingInfo->quantizer_size, 1 ); + + /* read range coded delta ICC indices */ + *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], delta_idx, BER_detect, sz_seq, sz_alphabet, + hParamCodingInfo->cum_freq_delta, hParamCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); + move16(); + + /* delta index to absolute index */ + FOR( j = 0; j < sz_seq; j++ ) + { + idx[j] = add( idx_prev, sub( delta_idx[j], idx_offset ) ); + idx_prev = idx[j]; + move16(); + } + } + ELSE + { + /* read range coded absolute ICC indices */ + sz_alphabet = hParamCodingInfo->quantizer_size; + move16(); + *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], idx, BER_detect, sz_seq, sz_alphabet, + hParamCodingInfo->cum_freq, hParamCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); + move16(); + } + + /* dequantize */ FOR( j = 0; j < sz_seq; j++ ) { - idx[j] = add( idx_prev, sub( delta_idx[j], idx_offset ) ); - idx_prev = idx[j]; + dequant_seq_fx[j] = hParamCodingInfo->quantizer_fx[idx[j]]; // hParamCodingInfo -> Q-quant move16(); } } ELSE { - /* read range coded absolute ICC indices */ - sz_alphabet = hParamCodingInfo->quantizer_size; - move16(); - *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], idx, BER_detect, sz_seq, sz_alphabet, - hParamCodingInfo->cum_freq, hParamCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); - move16(); - } - - /* dequantize */ - FOR( j = 0; j < sz_seq; j++ ) - { - dequant_seq_fx[j] = hParamCodingInfo->quantizer_fx[idx[j]]; // hParamCodingInfo -> Q-quant + set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + /* read uniformly coded ICCs */ + *bit_pos = add( *bit_pos, ivas_param_mc_uniform_decoder_fx( dequant_seq_fx, sz_seq, hParamCodingInfo->quantizer_fx, hParamCodingInfo->uni_bits, &bit_buffer[*bit_pos] ) ); move16(); } - } - ELSE - { - set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - /* read uniformly coded ICCs */ - *bit_pos = add( *bit_pos, ivas_param_mc_uniform_decoder_fx( dequant_seq_fx, sz_seq, hParamCodingInfo->quantizer_fx, hParamCodingInfo->uni_bits, &bit_buffer[*bit_pos] ) ); - move16(); - } - /* reorder from sequential to parameter-band-wise */ - k = 0; - FOR( j = 0; j < map_size_wo_lfe; ++j ) - { - FOR( i = 0; i < num_param_bands; ++i ) + /* reorder from sequential to parameter-band-wise */ + k = 0; + FOR( j = 0; j < map_size_wo_lfe; ++j ) { - dequant_ordered_fx[j + ( i * map_size )] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant - move16(); - k = add( k, 1 ); + FOR( i = 0; i < num_param_bands; ++i ) + { + dequant_ordered_fx[j + ( i * map_size )] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant + move16(); + k = add( k, 1 ); + } } - } - FOR( i = 0; i < num_lfe_bands; i++ ) - { - FOR( j = 0; j < n_lfe_idx; j++ ) + FOR( i = 0; i < num_lfe_bands; i++ ) { - dequant_ordered_fx[map_size - n_lfe_idx + j + i * map_size] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant - move16(); - k = add( k, 1 ); + FOR( j = 0; j < n_lfe_idx; j++ ) + { + dequant_ordered_fx[map_size - n_lfe_idx + j + i * map_size] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant + move16(); + k = add( k, 1 ); + } } - } - IF( !( *BER_detect ) ) - { - j = 0; - FOR( k = 0; k < hMetadataPMC->nbands_coded; k += band_step ) + IF( !( *BER_detect ) ) { - test(); - IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[k] ) ) + j = 0; + FOR( k = 0; k < hMetadataPMC->nbands_coded; k += band_step ) { - Copy( dequant_ordered_fx + imult1616( j, map_size ), value_buffer + imult1616( k, map_size ), map_size ); // hParamCodingInfo -> Q-quant - j++; - } - IF( hMetadataPMC->bAttackPresent && k + 1 < hMetadataPMC->nbands_coded ) - { - Copy( value_buffer + imult1616( k, map_size ), value_buffer + imult1616( add( k, 1 ), map_size ), map_size ); + test(); + IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[k] ) ) + { + Copy( dequant_ordered_fx + imult1616( j, map_size ), value_buffer + imult1616( k, map_size ), map_size ); // hParamCodingInfo -> Q-quant + j++; + } + IF( hMetadataPMC->bAttackPresent && k + 1 < hMetadataPMC->nbands_coded ) + { + Copy( value_buffer + imult1616( k, map_size ), value_buffer + imult1616( add( k, 1 ), map_size ), map_size ); + } } } - } - return; -} + return; + } diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index a5d5065be..04a6c80b2 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -134,7 +134,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( { Word16 n; ivas_error error; - Word32 output_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV + Word32 output_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k]; Word32 *p_sepobj_fx[BINAURAL_CHANNELS]; Word16 channel_offset; Word16 slot_idx_start; diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index af03f4b6e..05417a821 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -121,6 +121,7 @@ void ivas_sba2mc_cldfb_fx( return; } + /*-------------------------------------------------------------------------* * ivas_mc2sba() * @@ -129,12 +130,11 @@ void ivas_sba2mc_cldfb_fx( void ivas_mc2sba_fx( IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - Word32 *in_buffer_td_fx[], - /* i : MC signals (on input) and the HOA3 (on output) */ /*Q*/ - Word32 *buffer_td_fx[], /* i/o: MC signals (on input) and the HOA3 (on output) Q*/ - const Word16 output_frame, /* i : output frame length per channel Q0*/ - const Word16 sba_order, /* i : Ambisonic (SBA) order Q0*/ - const Word16 gain_lfe_fx /* i : gain for LFE, 0 = ignore LFE Q14*/ + Word32 *in_buffer_td_fx[], /* i : MC signals (on input) and the HOA3 (on output) Q*/ + Word32 *buffer_td_fx[], /* i/o: MC signals (on input) and the HOA3 (on output) Q*/ + const Word16 output_frame, /* i : output frame length per channel Q0*/ + const Word16 sba_order, /* i : Ambisonic (SBA) order Q0*/ + const Word16 gain_lfe_fx /* i : gain for LFE, 0 = ignore LFE Q14*/ ) { Word16 i, j, k; @@ -218,6 +218,7 @@ void ivas_mc2sba_fx( * MC signals transformed into SBA in CLDFB domain * used for binaural rendering with head rotation *-------------------------------------------------------------------------*/ + void ivas_param_mc_mc2sba_cldfb_fx( IVAS_OUTPUT_SETUP hTransSetup, /* i : transported MC Format */ Word32 *hoa_encoder_fx, /* i : HOA3 encoder for the transported MC format Q31*/ @@ -342,23 +343,25 @@ Word16 ivas_sba_remapTCs_fx( } } } + return ( nchan_remapped ); } + /*-------------------------------------------------------------------------* * ivas_ism2sba_sf() * * ISM transformed into SBA in TD domain. *-------------------------------------------------------------------------*/ + void ivas_ism2sba_sf_fx( - Word32 *buffer_in_fx[], - /* i : TC buffer */ /*Q_buffer_in*/ - Word32 *buffer_out_fx[], /* o : TD signal buffers Q_buffer_in + 29 - 31*/ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const Word16 num_objects, /* i : number of objects Q0*/ - const Word16 n_samples_to_render, /* i : output frame length per channel Q0*/ - const Word16 offset, /* i : offset for the interpolatr Q0*/ - const Word16 sba_order /* i : Ambisonic (SBA) order Q0*/ + Word32 *buffer_in_fx[], /* i : TC buffer Q_buffer_in*/ + Word32 *buffer_out_fx[], /* o : TD signal buffers Q_buffer_in + 29 - 31*/ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const Word16 num_objects, /* i : number of objects Q0*/ + const Word16 n_samples_to_render, /* i : output frame length per channel Q0*/ + const Word16 offset, /* i : offset for the interpolatr Q0*/ + const Word16 sba_order /* i : Ambisonic (SBA) order Q0*/ ) { Word16 i, j, k; @@ -380,9 +383,13 @@ void ivas_ism2sba_sf_fx( FOR( j = 0; j < sba_num_chans; j++ ) { g2_fx = hIsmRendererData->interpolator_fx + offset; /*Pointer addition*/ /*Q15*/ - tc_fx = buffer_in_fx[i] + offset; /*Pointer addition*/ /*Q_buffer_in*/ - out_fx = buffer_tmp_fx[j]; /*Q_buffer_in + 29 - 31*/ - gain_fx = hIsmRendererData->gains_fx[i][j]; /*Q29*/ +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + tc_fx = buffer_in_fx[i]; /*Q_buffer_in*/ +#else + tc_fx = buffer_in_fx[i] + offset; /*Pointer addition*/ /*Q_buffer_in*/ +#endif + out_fx = buffer_tmp_fx[j]; /*Q_buffer_in + 29 - 31*/ + gain_fx = hIsmRendererData->gains_fx[i][j]; /*Q29*/ move32(); prev_gain_fx = hIsmRendererData->prev_gains_fx[i][j]; /*Q29*/ move32(); @@ -397,13 +404,16 @@ void ivas_ism2sba_sf_fx( } } } + FOR( j = 0; j < sba_num_chans; j++ ) { Copy32( buffer_tmp_fx[j], buffer_out_fx[j], n_samples_to_render ); /*Q_buffer_in + 29 - 31*/ } + return; } + /*-------------------------------------------------------------------* * ivas_sba_linear_renderer() * @@ -477,6 +487,7 @@ ivas_error ivas_sba_linear_renderer_fx( * * Determine SBA mixing matrices *-------------------------------------------------------------------*/ + void ivas_sba_mix_matrix_determiner_fx( SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ Word32 *output_fx[], /* i/o: transport/output audio channels Q_output*/ @@ -491,6 +502,7 @@ void ivas_sba_mix_matrix_determiner_fx( Word16 num_bands_out, nchan_transport, nchan_out; Word16 Q_p_output = add( 11, Q_output ); Word32 temp_fx; + /* Convert numeric range */ FOR( ch = 0; ch < nchan_remapped; ch++ ) { @@ -520,6 +532,7 @@ void ivas_sba_mix_matrix_determiner_fx( move16(); nchan_out = nchan_transport; /*Q0*/ move16(); + ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output_fx ), ( output_fx ), nchan_transport, output_frame ); Q_p_output = sub( Q_p_output, 3 ); #ifdef DEBUGGING @@ -538,6 +551,8 @@ void ivas_sba_mix_matrix_determiner_fx( /* Mixing matrix determiner */ num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/ move16(); + ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, bfi, num_md_sub_frames ); + return; } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index b6129f3c7..11568f98c 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1030,9 +1030,9 @@ typedef struct ivas_masa_ism_data_structure typedef struct decoder_tc_buffer_structure { - Word32 *tc_buffer_fx; /* the buffer itself */ /*stores memory length of tc buffer*/ - Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV - Word16 no_channels; /*Stores no of channels in tc_fx with values*/ + Word32 *tc_buffer_fx; /* the buffer itself */ /*stores memory length of tc buffer*/ + Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ + Word16 no_channels; /*Stores no of channels in tc_fx with values*/ Word16 q_tc_fx; TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 5cb27fa2e..f69e36116 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -5747,10 +5747,12 @@ static ivas_error evs_dec_main_fx( Copy32( pcm_buf_local, p_output_fx[ch], nOutSamples ); } } +#ifndef UNIFIED_DECODING_PATHS_LEFTOVERS ELSE // ToDo: the 'else' branch can be removed once UNIFIED_DECODING_PATHS_LEFTOVERS is merged { ivas_jbm_dec_copy_tc_no_tsm_fx( st_ivas, p_output_fx, nOutSamples ); } +#endif #else IF( !st_ivas->hDecoderConfig->Opt_tsm ) { -- GitLab From 29bd7045809f2c4fb4476f0c2acd661b8c45223d Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 16:49:04 +0200 Subject: [PATCH 02/10] fix --- lib_dec/ivas_ism_param_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 86c4c13fd..4bd47b7cf 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1159,7 +1159,7 @@ void ivas_param_ism_dec_digest_tc_fx( #ifdef UNIFIED_DECODING_PATHS_LEFTOVERS num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; move16(); - output_frame = imult1616( nCldfbSlots, hSpatParamRendCom->num_freq_bands ); + output_frame = imult1616( nCldfbSlots, st_ivas->hSpatParamRendCom->num_freq_bands ); n_ch_cldfb = sub( st_ivas->hTcBuffer->nchan_transport_jbm, st_ivas->hTcBuffer->nchan_buffer_full ); cldfb_real_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx; -- GitLab From 5f0209bd5381aa984e9fbe1198505172abbd468b Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 17:22:39 +0200 Subject: [PATCH 03/10] fix --- lib_dec/ivas_ism_param_dec_fx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index e85645a07..61c5befe6 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1129,7 +1129,19 @@ void ivas_param_ism_dec_digest_tc_fx( cldfb_real_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx; cldfb_imag_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx; + + ivas_ism_param_dec_tc_gain_adjust_fx( st_ivas, output_frame, shr( output_frame, 1 ), p_data_fx, &q_data ); #else + hParamIsmDec = st_ivas->hParamIsmDec; + assert( hParamIsmDec ); + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + assert( hSpatParamRendCom ); + output_frame = imult1616( nCldfbSlots, hSpatParamRendCom->num_freq_bands ); + fade_len = shr( output_frame, 1 ); + + nchan_transport = st_ivas->nchan_transport; + move16(); + IF( st_ivas->hDecoderConfig->Opt_tsm ) { /*TODO : FhG to check*/ -- GitLab From afd123c7a33f6b2632d7ba5e879bcd96330ef795 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 20:42:19 +0200 Subject: [PATCH 04/10] fix merge --- lib_dec/ivas_jbm_dec_fx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index e3914f03f..f2c2801ee 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -4327,6 +4327,7 @@ static void ivas_jbm_dec_copy_masa_meta_to_buffer( * * Map input MASA metadata subframes to slots in JBM processing *--------------------------------------------------------------------------*/ + static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const Word16 nCldfbTs /* i : number of CLDFB time slots */ @@ -4338,6 +4339,10 @@ static void ivas_jbm_masa_sf_to_slot_map( Word16 slot_idx; Word16 write_idx, sf_index; +#ifdef UNIFIED_DECODING_PATHS_LEFTOVERS + ivas_jbm_dec_copy_masa_meta_to_buffer( st_ivas ); + +#endif /* Set values */ hJbmMetadata = st_ivas->hJbmMetadata; num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; -- GitLab From 263f74f6c9d046bd32da4128379bad75992c0859 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 21:50:12 +0200 Subject: [PATCH 05/10] fix --- lib_dec/ivas_jbm_dec_fx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index f2c2801ee..4a90a6d3e 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1572,6 +1572,9 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( n_ch_cldfb = sub( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); move16(); + hTcBuffer->q_tc_fx = Q11; + move16(); + IF( st_ivas->hDecoderConfig->Opt_tsm ) { Word16 n_samples_still_available, m; -- GitLab From f8c3c1b8904c88a3a4dee2048e6e5f12da107667 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 22:48:09 +0200 Subject: [PATCH 06/10] fix --- lib_dec/ivas_jbm_dec_fx.c | 2 +- lib_dec/ivas_mc_param_dec_fx.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 4a90a6d3e..ce5ad3c5b 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1660,7 +1660,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( { ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_fx, Q11 ); } - ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER ) + ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32(hTcBuffer->tc_buffer_mode , TC_BUFFER_MODE_RENDERER )) { Word16 nchan_transport = st_ivas->nchan_transport; move16(); diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 9dd7f9a01..755675124 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1562,11 +1562,11 @@ void ivas_param_mc_dec_digest_tc_fx( /* CLDFB Analysis */ FOR( ( ch = 0, cldfb_ch = 0 ); cldfb_ch < n_ch_cldfb; ( cldfb_ch++, ch++ ) ) { - qout = q_data; - move16(); - FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { + qout = q_data; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][num_freq_bands * slot_idx] ), &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], -- GitLab From 0afb835eefdaa54095467eca0b256aa59e38c717 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 22:51:41 +0200 Subject: [PATCH 07/10] clang-format --- lib_dec/ivas_jbm_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index ce5ad3c5b..bdc4d5ad4 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1660,7 +1660,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( { ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_fx, Q11 ); } - ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32(hTcBuffer->tc_buffer_mode , TC_BUFFER_MODE_RENDERER )) + ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32( hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_RENDERER ) ) { Word16 nchan_transport = st_ivas->nchan_transport; move16(); -- GitLab From 3b18e2ce60481670d8dd80440592d215abdb73b2 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 21 Oct 2025 23:34:50 +0200 Subject: [PATCH 08/10] fix --- lib_dec/ivas_ism_param_dec_fx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 61c5befe6..6d9104fe6 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1131,6 +1131,13 @@ void ivas_param_ism_dec_digest_tc_fx( cldfb_imag_buffer = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx; ivas_ism_param_dec_tc_gain_adjust_fx( st_ivas, output_frame, shr( output_frame, 1 ), p_data_fx, &q_data ); + + IF( !st_ivas->hDecoderConfig->Opt_tsm ) + { + Scale_sig32( p_data_fx[0], output_frame, sub( Q11, q_data ) ); /*keepeing p_data_fx at Q11*/ + Scale_sig32( p_data_fx[1], output_frame, sub( Q11, q_data ) ); /*keepeing p_data_fx at Q11*/ + } + #else hParamIsmDec = st_ivas->hParamIsmDec; assert( hParamIsmDec ); -- GitLab From f087b5625740640cec58ae156cd76095d1700633 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 22 Oct 2025 13:56:24 +0200 Subject: [PATCH 09/10] fix merging with OBJ_EDITING_API in MC_MODE_PARAMMC --- lib_dec/ivas_jbm_dec_fx.c | 46 ---------------------------------- lib_dec/ivas_mc_param_dec_fx.c | 19 ++++++++------ 2 files changed, 11 insertions(+), 54 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index bdc4d5ad4..13880a204 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1662,53 +1662,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32( hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_RENDERER ) ) { - Word16 nchan_transport = st_ivas->nchan_transport; - move16(); - Word16 nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - Word16 nchan_out_cov; - - test(); - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - nchan_out_cov = nchan_out_transport; - move16(); - } - ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - ELSE - { - nchan_out_cov = nchan_out_transport; - move16(); - } - - scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, -1 ); // Q(31-1) - st_ivas->hParamMC->proto_matrix_int_e = 1; - move16(); - ivas_param_mc_dec_digest_tc_fx( st_ivas, (uint8_t) n_render_timeslots, p_data_fx, Q11 ); - - scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, 1 ); // Q(31-1+1) - - Word16 shift, param_band_idx; - FOR( param_band_idx = 0; param_band_idx < st_ivas->hParamMC->num_param_bands_synth; param_band_idx++ ) - { - shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, nchan_transport * nchan_transport ) ); - scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, i_mult( nchan_transport, nchan_transport ) ), shift ); // Q(31-cx_old_e+shift) - st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], shift ); - move16(); - - shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], nchan_out_cov * nchan_out_cov ); - scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], i_mult( nchan_out_cov, nchan_out_cov ), shift ); // Q(31-cy_old_e+shift) - st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], shift ); - move16(); - } } hTcBuffer->n_samples_rendered = 0; diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 755675124..60db02a4c 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1542,7 +1542,7 @@ void ivas_param_mc_dec_digest_tc_fx( assert( hParamMC ); #endif - Word16 qout = 0; + Word16 q_out = 0; move16(); /* Initialization */ @@ -1564,17 +1564,20 @@ void ivas_param_mc_dec_digest_tc_fx( { FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - qout = q_data; + q_out = q_data; move16(); cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][num_freq_bands * slot_idx] ), &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], - num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch], &qout ); + num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch], &q_out ); } - st_ivas->hParamMC->Cldfb_ImagBuffer_tc_e = qout; - move16(); + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + st_ivas->hParamMC->Cldfb_ImagBuffer_tc_e = q_out; + move16(); + } } #else /* slot loop for gathering the input data */ @@ -1588,15 +1591,15 @@ void ivas_param_mc_dec_digest_tc_fx( /* CLDFB Analysis*/ FOR( ch = 0; ch < nchan_transport; ch++ ) { - qout = transport_f_e; + q_out = q_data; move16(); - cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &qout ); + cldfbAnalysis_ts_fx_fixed_q( &( p_data_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &q_out ); Copy32( RealBuffer_fx, &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); Copy32( ImagBuffer_fx, &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); } - hParamMC->Cldfb_ImagBuffer_tc_e = qout; + hParamMC->Cldfb_ImagBuffer_tc_e = q_out; move16(); } } -- GitLab From 77a632a2fa4240c6b06d3405971b90983c85b6f1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 22 Oct 2025 17:44:32 +0200 Subject: [PATCH 10/10] fix merging with OBJ_EDITING_API in ParamISM -> FOA JBM --- lib_com/ivas_prot_fx.h | 4 +- lib_dec/ivas_ism_param_dec_fx.c | 52 +++++++++++------- lib_dec/ivas_mc_param_dec_fx.c | 95 +++++++++++---------------------- 3 files changed, 68 insertions(+), 83 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 8b8be57ac..faaf2b55a 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4330,7 +4330,7 @@ void ivas_ism_dec_digest_tc_fx( void ivas_param_ism_dec_digest_tc_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - Word32 *p_data_fx[], /* i : synthesized core-coder transport channels/DirAC output */ + Word32 *p_data_fx[], /* i/o: synthesized core-coder transport channels/DirAC output */ const Word16 q_data_in /* i : Q-factor of input signal for single channel */ ); @@ -4348,7 +4348,7 @@ void ivas_param_ism_dec_render_fx( const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - Word32 *output_f_fx[] + Word32 *output_f_fx[] /* i/o: synthesized core-coder TCs / rendered signal*/ ); void ivas_param_ism_params_to_masa_param_mapping_fx( diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 6d9104fe6..a094d8cf2 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -81,6 +81,7 @@ static void ivas_param_ism_dec_dequant_DOA_fx( return; } + static void ivas_param_ism_dec_dequant_powrat_fx( PARAM_ISM_DEC_HANDLE hParamIsmDec /* i/o: decoder ParamISM handle */ ) @@ -176,6 +177,7 @@ static void ivas_ism_get_proto_matrix_fx( return; } + static void ivas_param_ism_collect_slot_fx( PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ Word32 *Cldfb_RealBuffer_in_fx, /*Q(31-exp_real)*/ @@ -192,7 +194,6 @@ static void ivas_param_ism_collect_slot_fx( Word16 exp_tmp; /* loop over parameter bands to collect transport channel energies */ - FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) { brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; @@ -219,6 +220,7 @@ static void ivas_param_ism_collect_slot_fx( move16(); } } + return; } @@ -400,6 +402,7 @@ static void ivas_param_ism_compute_mixing_matrix_fx( return; } + static void ivas_param_ism_render_slot_fx( PARAM_ISM_DEC_HANDLE hParamIsmDec, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, @@ -444,6 +447,7 @@ static void ivas_param_ism_render_slot_fx( } } } + FOR( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) { /* smooth the mixing matrix */ @@ -528,11 +532,11 @@ static ivas_error ivas_param_ism_rendering_init_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for proto matrix\n" ) ); } - IF( ( hParamIsmRendering->interpolator_fx = (Word16 *) malloc( subframe_nbslots * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); } + test(); test(); test(); @@ -548,6 +552,7 @@ static ivas_error ivas_param_ism_rendering_init_fx( return IVAS_ERR_OK; } + static void ivas_param_ism_update_mixing_matrix_fx( PARAM_ISM_DEC_HANDLE hParamIsmDec, Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_exp)*/ @@ -639,6 +644,7 @@ ivas_error ivas_param_ism_dec_open_fx( move32(); output_config = st_ivas->hDecoderConfig->output_config; move32(); + ivas_param_ism_config_fx( hParamIsmDec->hParamIsm, st_ivas->nchan_ism ); // assuming Q14 for gains; /*-----------------------------------------------------------------* @@ -843,6 +849,7 @@ ivas_error ivas_param_ism_dec_open_fx( return error; } + /*-------------------------------------------------------------------------* * ivas_param_ism_dec_close() * @@ -1094,12 +1101,12 @@ void ivas_ism_dec_digest_tc_fx( void ivas_param_ism_dec_digest_tc_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - Word32 *p_data_fx[], /* i : synthesized core-coder transport channels/DirAC output q_data_in */ + Word32 *p_data_fx[], /* i/o: synthesized core-coder transport channels/DirAC output q_data_in */ const Word16 q_data_in /* i : Q-factor of input signal for single channel */ ) { #ifdef UNIFIED_DECODING_PATHS_LEFTOVERS - Word16 ch, slot_idx, output_frame; + Word16 i, ch, slot_idx, output_frame; Word16 num_freq_bands, cldfb_ch, n_ch_cldfb; Word32 *cldfb_real_buffer, *cldfb_imag_buffer; Word16 q_data = q_data_in; @@ -1137,7 +1144,18 @@ void ivas_param_ism_dec_digest_tc_fx( Scale_sig32( p_data_fx[0], output_frame, sub( Q11, q_data ) ); /*keepeing p_data_fx at Q11*/ Scale_sig32( p_data_fx[1], output_frame, sub( Q11, q_data ) ); /*keepeing p_data_fx at Q11*/ } - + ELSE + { + IF( NE_16( q_data, q_data_in ) ) + { + FOR( i = 0; i < MAX_PARAM_ISM_WAVE; i++ ) + { + scale_sig32( p_data_fx[i], output_frame, sub( q_data_in, q_data ) ); // q_data_in + } + q_data = q_data_in; + move16(); + } + } #else hParamIsmDec = st_ivas->hParamIsmDec; assert( hParamIsmDec ); @@ -1278,10 +1296,9 @@ void ivas_param_ism_dec_prepare_renderer_fx( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; /* Initialization */ - - hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = 25; + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = Q25; move16(); - hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = 25; + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = Q25; move16(); IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) { @@ -1606,7 +1623,7 @@ static void ivas_ism_param_dec_render_sf_fx( Word32 *output_f_fx[], /*Q_output*/ Word16 Q_output[] ) { - Word16 ch, slot_idx, i, index_slot; + Word16 ch, slot_idx, i, index_slot, cldfb_idx; /* CLDFB Output Buffers */ Word32 Cldfb_RealBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; // Q(31-real_exp) Word32 Cldfb_ImagBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; // Q(31-imag_exp) @@ -1643,10 +1660,9 @@ static void ivas_ism_param_dec_render_sf_fx( { index_slot = add( slot_idx_start, slot_idx ); - FOR( ch = 0; ch < nchan_transport; ch++ ) { - Word16 cldfb_idx = add( imult1616( imult1616( index_slot, hSpatParamRendCom->num_freq_bands ), nchan_transport ), imult1616( ch, hSpatParamRendCom->num_freq_bands ) ); + cldfb_idx = add( imult1616( imult1616( index_slot, hSpatParamRendCom->num_freq_bands ), nchan_transport ), imult1616( ch, hSpatParamRendCom->num_freq_bands ) ); Cldfb_RealBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[cldfb_idx]; // Q11 Cldfb_ImagBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[cldfb_idx]; // Q11 } @@ -1747,15 +1763,15 @@ static void ivas_ism_param_dec_render_sf_fx( * * *-------------------------------------------------------------------------*/ + void ivas_param_ism_dec_render_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ - UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ - UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - Word32 *output_f_fx[] /*Q11*/ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ + UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ + UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + Word32 *output_f_fx[] /* i/o: synthesized core-coder TCs / rendered signal Q11*/ ) { - Word16 ch, slots_to_render, first_sf, last_sf, subframe_idx; UWord16 slot_size, n_samples_sf; PARAM_ISM_DEC_HANDLE hParamIsmDec; @@ -1854,6 +1870,7 @@ void ivas_param_ism_dec_render_fx( *nSamplesAvailableNext = imult1616( sub( hSpatParamRendCom->num_slots, hSpatParamRendCom->slots_rendered ), (Word16) slot_size ); move16(); + return; } @@ -1888,7 +1905,6 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( nBins = hSpatParamRendCom->num_freq_bands; move16(); - IF( st_ivas->hISMDTX.dtx_flag ) { Word32 energy_ratio_fx; /* Q30 */ diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 60db02a4c..4dd7e82f9 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -73,38 +73,26 @@ typedef struct parameter_band_mapping_struct static void ivas_param_mc_dec_init_fx( PARAM_MC_DEC_HANDLE hParamMC, const Word16 nchan_in, const Word16 nchan_out ); static void ivas_param_mc_dec_copy_diffuse_proto( PARAM_MC_DEC_HANDLE hParamMC, Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nY, const Word16 slot_idx ); + static Word16 ivas_param_mc_range_decoder_LC_fx( UWord16 *bit_buffer, Word16 *x, Word16 *BER_detect, const Word16 sz_seq, const Word16 sz_alphabet, const UWord16 *cft, const UWord16 *sft, const Word16 tot_shift, const Word16 nbbits ); - -static void ivas_param_mc_get_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, - Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands */ - Word16 Cx_in_e, - const Word16 param_band_idx, - Word32 *mixing_matrix_fx[], - Word16 *mixing_matrix_e, - Word32 *mixing_matrix_res_fx[], - Word16 *mixing_matrix_res_e, - const Word16 nY_intern, /* i : number of channels in the transported format */ - const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ - const Word16 nX, /* i : number of transport channels */ - const Word16 nY_cov /* i : number of covariance synthesis output channels */ -); +static void ivas_param_mc_get_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_in_e, const Word16 param_band_idx, Word32 *mixing_matrix_fx[], Word16 *mixing_matrix_e, Word32 *mixing_matrix_res_fx[], Word16 *mixing_matrix_res_e, const Word16 nY_intern, const PARAM_MC_SYNTHESIS_CONF synth_config, const Word16 nX, const Word16 nY_cov ); static Word16 ivas_param_mc_uniform_decoder_fx( Word16 *seq, const Word16 sz_seq, const Word16 *alphabet, const Word16 N, UWord16 bit_buffer[PARAM_MC_MAX_BITS] ); + static void ivas_param_mc_dec_compute_interpolator_fx( const UWord16 bAttackPresent, const UWord16 attackPos, const UWord16 interp_length, Word16 *interpolator ); static void param_mc_set_num_synth_bands( const Word32 output_Fs, PARAM_MC_DEC_HANDLE hParamMC ); static void ivas_param_mc_get_param_band_mapping( const Word16 n_target_bands, const Word16 *target_band_grouping, const Word16 n_source_bands, const Word16 *source_band_grouping, PARAM_MC_PARAMETER_BAND_MAPPING *parameter_band_mapping ); - static void ivas_param_mc_bs_decode_parameter_values_fx( UWord16 bit_buffer[], Word16 *bit_pos, const Word16 max_bits, Word16 *BER_detect, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, const Word16 map_size_wo_lfe, const Word16 map_size, const Word16 num_lfe_bands, const Word16 band_step, const Word16 num_param_bands, Word16 *value_buffer ); + static void ivas_param_mc_dequantize_cov_fx( PARAM_MC_DEC_HANDLE hParamMC, Word16 *ild_q_fx, Word16 *icc_q_fx, const Word16 param_band_index, const Word16 nY_cov, const PARAM_MC_SYNTHESIS_CONF synth_conf, const Word16 nY_int, const Word16 nX, Word32 *Cx_state_fx, Word16 Cx_state_e, Word32 *Cproto_fx, Word16 Cproto_e, Word32 *Cy_state_fx, Word16 *Cy_state_e ); + static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, const UWord16 nchan_transport, const UWord16 nchan_out_cov, PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, Word16 Q_proto_mtx ); -static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); +static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const Word16 num_freq_bands, const Word16 Cldfb_Real_Imag_exp, Word16 *proto_frame_f_fx_q /* Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); @@ -263,7 +251,6 @@ ivas_error ivas_param_mc_dec_open_fx( ivas_param_mc_metadata_open_fx( mc_ls_setup, ivas_total_brate, hParamMC->hMetadataPMC ); /* init arrays for quantized parameters */ - IF( ( hParamMC->icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); @@ -352,6 +339,7 @@ ivas_error ivas_param_mc_dec_open_fx( } } } + IF( ( hParamMC->proto_matrix_int_fx = (Word32 *) malloc( nchan_out_transport * nchan_transport * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); @@ -528,6 +516,7 @@ ivas_error ivas_param_mc_dec_open_fx( set32_fx( hParamMC->Cldfb_RealBuffer_tc_fx, 0, cldfb_buf_size ); hParamMC->Cldfb_RealBuffer_tc_e = 25; // Q6 , Initialised with Q6 to match non jbm and jbm cases move16(); + IF( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( cldfb_buf_size * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); @@ -564,6 +553,7 @@ ivas_error ivas_param_mc_dec_open_fx( move16(); st_ivas->hParamMC = hParamMC; + return error; } @@ -629,6 +619,7 @@ static void ivas_param_mc_get_param_band_mapping( parameter_band_mapping->n_source_bands[target_band_idx] = source_band_in_target_band_cnt; move16(); } + return; } @@ -662,6 +653,7 @@ ivas_error ivas_param_mc_dec_reconfig_fx( hParamMC = st_ivas->hParamMC; error = IVAS_ERR_OK; move32(); + /* save important config information from the previous state */ nchan_transport_old = st_ivas->nchan_transport; move32(); @@ -721,6 +713,7 @@ ivas_error ivas_param_mc_dec_reconfig_fx( /*-----------------------------------------------------------------* * set input parameters *-----------------------------------------------------------------*/ + hParamMC->num_freq_bands = shr( add( (Word16) Mpy_32_32( output_Fs, INV_CLDFB_BANDWIDTH_Q31 << 1 ), 1 ), 1 ); // Q0 move16(); hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; @@ -837,7 +830,6 @@ ivas_error ivas_param_mc_dec_reconfig_fx( *-----------------------------------------------------------------*/ /* prototype signal computation */ - IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) { IF( NE_16( nchan_transport_old, nchan_transport ) ) @@ -864,8 +856,8 @@ ivas_error ivas_param_mc_dec_reconfig_fx( Copy32( st_ivas->hLsSetUpConversion->dmxMtx_fx[k], &hParamMC->ls_conv_dmx_matrix_fx[k * nchan_out_cov], nchan_out_cov ); } } - /* convert ParamMC parameter bands to SFB */ + /* convert ParamMC parameter bands to SFB */ st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth; move16(); FOR( k = 0; k <= hParamMC->num_param_bands_synth; k++ ) @@ -1075,6 +1067,7 @@ ivas_error ivas_param_mc_dec_reconfig_fx( } } } + ivas_dirac_dec_output_synthesis_cov_close_fx( ¶ms_old, &cov_state_old ); } @@ -1093,7 +1086,6 @@ ivas_error ivas_param_mc_dec_reconfig_fx( set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); } - IF( NE_16( nchan_transport_old, nchan_transport ) ) { IF( NE_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) @@ -1144,6 +1136,7 @@ ivas_error ivas_param_mc_dec_reconfig_fx( } } } + return error; } @@ -1261,6 +1254,7 @@ void ivas_param_mc_dec_close_fx( free( hParamMC->diff_proto_info ); hParamMC->diff_proto_info = NULL; } + /* States */ /* free prototype signal buffers */ IF( hParamMC->proto_frame_f_fx != NULL ) @@ -1626,21 +1620,18 @@ void ivas_param_mc_dec_prepare_renderer( Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; Word16 nchan_out_cov; PARAM_MC_DEC_HANDLE hParamMC; - + /*CLDFB*/ Word32 *pCx, *pCx_imag; Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; - Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word16 cx_e; Word16 cx_imag_e, tmp_e; Word16 cx_imag_next_band_e, cx_next_band_e; - Word16 max_e; - /* format converter */ Word16 channel_active[MAX_OUTPUT_CHANNELS]; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; @@ -1931,7 +1922,6 @@ void ivas_param_mc_dec_render_fx( Word16 slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; Word16 nchan_out_cov; - /*CLDFB*/ Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; @@ -1944,7 +1934,6 @@ void ivas_param_mc_dec_render_fx( } /*Decorrelator*/ Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; // Q31 - /* format converter */ Word16 channel_active[MAX_OUTPUT_CHANNELS]; UWord16 nband_synth; @@ -2066,6 +2055,7 @@ void ivas_param_mc_dec_render_fx( /*-----------------------------------------------------------------* * protoype signal computation *-----------------------------------------------------------------*/ + param_mc_protoSignalComputation_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], hParamMC->proto_frame_f_fx, hParamMC->diff_proto_info, @@ -2073,8 +2063,8 @@ void ivas_param_mc_dec_render_fx( /*-----------------------------------------------------------------* * frequency domain decorrelation *-----------------------------------------------------------------*/ - /* decorrelate prototype frame */ + /* decorrelate prototype frame */ ivas_dirac_dec_decorr_process_fx( hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, @@ -2109,6 +2099,7 @@ void ivas_param_mc_dec_render_fx( /*-----------------------------------------------------------------* * output synthesis *-----------------------------------------------------------------*/ + ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, slot_idx, add( slot_idx, slot_idx_start ), @@ -2276,7 +2267,6 @@ void ivas_param_mc_dec_render_fx( ivas_lssetupconversion_process_param_mc_fx( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, channel_active ); } - /* CLDFB synthesis */ FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { @@ -2315,13 +2305,13 @@ void ivas_param_mc_dec_render_fx( slot_idx_start = add( slot_idx_start, hParamMC->subframe_nbslots[subframe_idx] ); slot_idx_start_cldfb_synth = add( slot_idx_start_cldfb_synth, hParamMC->subframe_nbslots[subframe_idx] ); } + IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) { ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); } /* update */ - IF( EQ_16( hParamMC->slots_rendered, hParamMC->num_slots ) ) { hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; @@ -2329,7 +2319,6 @@ void ivas_param_mc_dec_render_fx( param_mc_update_mixing_matrices_fx( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_transport, nchan_out_cov ); } - hParamMC->subframes_rendered = last_sf; move16(); *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); @@ -2435,7 +2424,6 @@ static void param_mc_protoSignalComputation_fx( set32_fx( proto_frame_f_fx, 0, shl( imult1616( num_freq_bands, diff_proto_info->num_protos_diff ), 1 ) ); - FOR( proto_ch_idx = 0; proto_ch_idx < diff_proto_info->num_protos_diff; proto_ch_idx++ ) { Word16 num_source_ch = diff_proto_info->num_source_chan_diff[proto_ch_idx]; @@ -2456,7 +2444,6 @@ static void param_mc_protoSignalComputation_fx( FOR( band = 0; band < num_freq_bands; band++ ) { - Word32 tmp_x = L_shl( Mpy_32_32( fac_fx, ( *( p_real_buffer_fx++ ) ) ), 4 ); // Q(26 + 4 + 6 - 31) :: Q5 *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); @@ -2495,6 +2482,7 @@ static void ivas_param_mc_dec_copy_diffuse_proto( Word16 k, l; Word16 num_freq_bands, num_freq_bands_diff; Word32 *p_proto_diff_fx; + num_freq_bands = hParamMC->num_freq_bands; move16(); num_freq_bands_diff = hParamMC->h_output_synthesis_params.max_band_decorr; @@ -2541,11 +2529,13 @@ static Word16 ivas_param_mc_bin2dec_fx( return out; } + /*------------------------------------------------------------------------- * ivas_param_mc_uniform_decoder() * * decode a uniformily coded sequence of float values *------------------------------------------------------------------------*/ + static Word16 ivas_param_mc_uniform_decoder_fx( Word16 *seq, /* o : decoded sequence of float values hParamCodingInfo -> Q-quant*/ const Word16 sz_seq, /* i : number of values to decode */ @@ -2580,6 +2570,7 @@ static Word16 ivas_param_mc_uniform_decoder_fx( * * decode a sequency of inidices coded with a range coder *------------------------------------------------------------------------*/ + static Word16 ivas_param_mc_range_decoder_LC_fx( UWord16 *bit_buffer, /* i : bit buffer to read from */ Word16 *x, /* o : decoded indices */ @@ -2636,6 +2627,7 @@ static Word16 ivas_param_mc_range_decoder_LC_fx( return cur_bit_pos; } + /*------------------------------------------------------------------------- * param_mc_compute_interpolator() * @@ -2748,12 +2740,9 @@ static void ivas_param_mc_get_mixing_matrices_fx( Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; Word16 remove_lfe; Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; - Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - Word32 Cy_full_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - Word32 Cr_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cr_e) Word16 Cr_e; Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Cy_diag_buff_e) @@ -2773,19 +2762,14 @@ static void ivas_param_mc_get_mixing_matrices_fx( Word16 mixing_matrix_res_local_e; Word32 L_tmp; Word16 tmp_e, tmp; - Word16 proto_matrix_e = hParamMC->h_output_synthesis_params.proto_matrix_e; move16(); Word32 proto_matrix_noLFE_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; // Q(31 - proto_matrix_noLFE_e) - - Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - - Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) + Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e; - Word32 *ptrMM_fx; Word32 *ptrMM_out_fx; - Word16 Cy_e, Cx_e; Word16 Cy_full_e; Word16 new_e = 0; @@ -2851,6 +2835,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( num_lfe_bands = PARAM_MC_MAX_BAND_LFE; move16(); } + IF( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) { remove_lfe = 1; @@ -2876,10 +2861,8 @@ static void ivas_param_mc_get_mixing_matrices_fx( Cx_old_state_fx = hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx]; Cy_old_state_fx = hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx]; - /* Getting mixing mtx */ /* estimate target cov from input cov and proto_matrix */ - Cx_state_e = Cx_in_e; move16(); matrix_product_fx( hParamMC->proto_matrix_int_fx, nY_intern, nX, 0, Cx_state_fx, nX, nX, 0, mat_mult_buffer1_fx ); @@ -2909,8 +2892,6 @@ static void ivas_param_mc_get_mixing_matrices_fx( nY_intern, nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); - // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); - /* Smoothing: Sum over two buffers */ IF( hParamMC->hMetadataPMC->bAttackPresent ) { @@ -2925,8 +2906,6 @@ static void ivas_param_mc_get_mixing_matrices_fx( ELSE { /* smoothing gains are now identical to one, simply add up */ - // v_add( Cy_state, Cy_old_state, Cy_full, nY_cov * nY_cov ); - v_add_fx_me( Cx_state_fx, Cx_state_e, Cx_old_state_fx, hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], Cx_fx, &Cx_e, imult1616( nX, nX ), 1 ); v_add_fx_me( Cy_state_fx, Cy_state_e, Cy_old_state_fx, hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], Cy_full_fx, &Cy_full_e, imult1616( nY_cov, nY_cov ), 1 ); } @@ -2972,7 +2951,6 @@ static void ivas_param_mc_get_mixing_matrices_fx( /* remove LFE IF necessary */ IF( remove_lfe ) { - Cy_e = Cy_full_e; remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); } @@ -2989,7 +2967,6 @@ static void ivas_param_mc_get_mixing_matrices_fx( matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e ); /* make sure we have no negative entries in Cproto_diag due to rounding errors */ - FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) { if ( Cproto_diag_fx[ch_idx1] < 0 ) @@ -2999,13 +2976,13 @@ static void ivas_param_mc_get_mixing_matrices_fx( } } - /* Computing the mixing matrices */ /* bands with decorr */ IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) { computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 0, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); + /* Compute mixing matrix FOR residual */ computeMixingMatricesResidual_fx( nY_band, Cproto_diag_fx, Cproto_diag_e, Cr_fx, Cr_e, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_res_local_fx, &mixing_matrix_res_local_e ); @@ -3180,13 +3157,6 @@ static void param_mc_update_mixing_matrices_fx( * generate the target covariance matrix *------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------- - * ivas_param_mc_dequantize_cov_fx() - * - * generate the target covariance matrix - *------------------------------------------------------------------------*/ - static void ivas_param_mc_dequantize_cov_fx( PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ Word16 *ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ @@ -3260,7 +3230,6 @@ static void ivas_param_mc_dequantize_cov_fx( } /* estimate ICCs from estimated Cproto */ - FOR( k = 0; k < nY_int; k++ ) { // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); @@ -3395,7 +3364,6 @@ static void ivas_param_mc_dequantize_cov_fx( Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; // Q(31 - target_ch_ener_e) Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; - Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); @@ -3504,6 +3472,7 @@ static void ivas_param_mc_dequantize_cov_fx( return; } + /*-------------------------------------------------------------------------* * param_mc_set_num_synth_bands() * @@ -3562,7 +3531,6 @@ static void param_mc_set_num_synth_bands( * calculated the diffuse prototype information *-------------------------------------------------------------------------*/ - static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, /* i : protoype matrix for the synthesis */ const UWord16 nchan_transport, /* i : number of transport channels */ @@ -3697,6 +3665,7 @@ static ivas_error param_mc_get_diff_proto_info_fx( proto_fac_ptr += nchan_out_cov; } } + return IVAS_ERR_OK; } -- GitLab