From 87d67fd32147aff81409714d52b3b4f16bb6cef3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sun, 5 May 2024 12:12:40 +0530 Subject: [PATCH] ivas_param_mc_dec_render fixed conversion [x] mc2sba function integration [x] param_mc_protosignal_computation in fixed [x] dirac_dec_decorr_process in fixed --- lib_com/ivas_prot.h | 18 + lib_dec/ivas_dirac_output_synthesis_cov.c | 175 ++++++- lib_dec/ivas_jbm_dec.c | 57 ++- lib_dec/ivas_mc_param_dec.c | 271 +++++++++- lib_dec/ivas_sba_rendering_internal.c | 4 +- lib_dec/ivas_stat_dec.h | 10 +- lib_rend/ivas_dirac_decorr_dec.c | 1 + lib_rend/ivas_orient_trk.c | 15 +- lib_rend/ivas_render_config.c | 33 ++ lib_rend/ivas_rotation.c | 36 ++ lib_rend/ivas_stat_rend.h | 3 +- lib_rend/lib_rend.c | 584 ++++++++++++++++++---- lib_rend/lib_rend.h | 7 + 13 files changed, 1073 insertions(+), 141 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 52fd2480c..4341c8900 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4985,6 +4985,24 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( + Word32 *Cldfb_RealBuffer_in_fx, + Word32 *Cldfb_ImagBuffer_in_fx, + Word32 Cldfb_RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ + Word32 Cldfb_ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ + Word32 *mixing_matrix_fx[], /* i : parameter band wise mixing matrices (direct part) */ + Word16 *mixing_matrix_e, /* i : parameter band wise mixing matrices (direct part) */ + Word32 *mixing_matrix_res_fx[], /* i : parameter band wise mixing matrices (residual part) */ + Word16 *mixing_matrix_res_e, /* i : parameter band wise mixing matrices (residual part) */ + const UWord16 slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ + const UWord16 slot_idx_tot, /* i : time slot index for the current slot within the frame */ + const Word16 nX, /* i : number of input channels */ + const Word16 nY, /* i : number of output channels */ + PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ +); +#endif + int16_t computeMixingMatricesISM( const int16_t num_inputs, const int16_t num_responses, diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index c6d48cc4d..a4b34f908 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -146,7 +146,7 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open_fx( h_dirac_output_synthesis_state->mixing_matrix_res_fx[idx] = NULL; } - if ((h_dirac_output_synthesis_state->cx_old_e = (Word16 *)malloc(CLDFB_NO_CHANNELS_MAX * sizeof(Word16))) == NULL) + if ((h_dirac_output_synthesis_state->cx_old_e = (Word16 *)malloc(CLDFB_NO_CHANNELS_MAX * sizeof(Word16))) == NULL) { return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis covariance\n")); } @@ -155,8 +155,8 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open_fx( return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis covariance\n")); } - set16_fx(h_dirac_output_synthesis_state->cx_old_e, 0, CLDFB_NO_CHANNELS_MAX); - set16_fx(h_dirac_output_synthesis_state->cy_old_e, 0, CLDFB_NO_CHANNELS_MAX); + set16_fx(h_dirac_output_synthesis_state->cx_old_e, 0, CLDFB_NO_CHANNELS_MAX); + set16_fx(h_dirac_output_synthesis_state->cy_old_e, 0, CLDFB_NO_CHANNELS_MAX); if ((h_dirac_output_synthesis_state->mixing_matrix_res_exp = (Word16 *)malloc(CLDFB_NO_CHANNELS_MAX * sizeof(Word16))) == NULL) { @@ -1136,7 +1136,176 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( + Word32 *Cldfb_RealBuffer_in_fx, + Word32 *Cldfb_ImagBuffer_in_fx, + Word32 Cldfb_RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ + Word32 Cldfb_ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ + Word32 *mixing_matrix_fx[], /* i : parameter band wise mixing matrices (direct part) */ + Word16 *mixing_matrix_e, /* i : parameter band wise mixing matrices (direct part) */ + Word32 *mixing_matrix_res_fx[], /* i : parameter band wise mixing matrices (residual part) */ + Word16 *mixing_matrix_res_e, /* i : parameter band wise mixing matrices (residual part) */ + const UWord16 slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ + const UWord16 slot_idx_tot, /* i : time slot index for the current slot within the frame */ + const Word16 nX, /* i : number of input channels */ + const Word16 nY, /* i : number of output channels */ + PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ +) +{ + Word16 param_band_idx, band, ch_idx; + Word16 have_residual; + Word16 brange[2]; + DIRAC_OUTPUT_SYNTHESIS_COV_STATE h_synthesis_state = hParamMC->h_output_synthesis_cov_state; + + Word32 mixing_matrix_smooth_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 mixing_matrix_smooth_e; + Word32 mixing_matrix_res_smooth_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word16 mixing_matrix_res_smooth_e; + Word32 mixing_matrix_buffer_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word16 mixing_matrix_buffer_e; + Word32 input_f_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 input_f_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 output_f_real_fx[MAX_CICP_CHANNELS]; + Word32 output_f_imag_fx[MAX_CICP_CHANNELS]; + Word16 output_f_real_e; + Word16 output_f_imag_e; + Word32 diff_f_real_fx[MAX_CICP_CHANNELS]; + Word32 diff_f_imag_fx[MAX_CICP_CHANNELS]; + Word16 diff_f_real_e; + Word16 diff_f_imag_e; + + set_zero_fx( input_f_real_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( input_f_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( output_f_real_fx, MAX_CICP_CHANNELS ); + set_zero_fx( output_f_imag_fx, MAX_CICP_CHANNELS ); + set_zero_fx( diff_f_real_fx, MAX_CICP_CHANNELS ); + set_zero_fx( diff_f_imag_fx, MAX_CICP_CHANNELS ); + + FOR ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx++ ) + { + /* final mixing */ + have_residual = 0; + move16(); + brange[0] = hParamMC->band_grouping[param_band_idx]; + move16(); + brange[1] = hParamMC->band_grouping[param_band_idx + 1]; + move16(); + + IF ( brange[0] < hParamMC->h_output_synthesis_params.max_band_decorr ) + { + have_residual = 1; + move16(); + } + + v_multc_fixed(mixing_matrix_fx[param_band_idx], L_deposit_h(hParamMC->h_output_synthesis_params.interpolator_fx[slot_idx_tot]), mixing_matrix_smooth_fx, nY * nX); + mixing_matrix_smooth_e = mixing_matrix_e[param_band_idx]; // interpolator is W16 + move16(); + + v_multc_fixed(h_synthesis_state.mixing_matrix_old_fx[param_band_idx], L_sub( ONE_IN_Q31, L_deposit_h(hParamMC->h_output_synthesis_params.interpolator_fx[slot_idx_tot] ) ), mixing_matrix_buffer_fx, nY * nX); + mixing_matrix_buffer_e = h_synthesis_state.mixing_matrix_old_exp[param_band_idx]; // interpolator is W16 + + v_add_fixed_me(mixing_matrix_smooth_fx, mixing_matrix_smooth_e, mixing_matrix_buffer_fx, mixing_matrix_buffer_e, mixing_matrix_smooth_fx, &mixing_matrix_smooth_e, nY * nX, 0); + + IF ( have_residual ) + { + /* residual mixing matrix interpolation*/ + + v_multc_fixed(mixing_matrix_res_fx[param_band_idx], L_deposit_h(hParamMC->h_output_synthesis_params.interpolator_fx[slot_idx_tot]), mixing_matrix_res_smooth_fx, nY * nY ); + mixing_matrix_res_smooth_e = mixing_matrix_res_e[param_band_idx] ; // interpolator is W16 + + set_zero_fx(mixing_matrix_buffer_fx, nY * nY); + v_multc_fixed(h_synthesis_state.mixing_matrix_res_old_fx[param_band_idx], L_sub( ONE_IN_Q31, L_deposit_h( hParamMC->h_output_synthesis_params.interpolator_fx[slot_idx_tot]) ), mixing_matrix_buffer_fx, nY * nY); + mixing_matrix_buffer_e = h_synthesis_state.mixing_matrix_res_old_exp[param_band_idx]; // interpolator is W16 + + + v_add_fixed_me(mixing_matrix_res_smooth_fx, mixing_matrix_res_smooth_e, mixing_matrix_buffer_fx, mixing_matrix_buffer_e, mixing_matrix_res_smooth_fx, &mixing_matrix_res_smooth_e, nY * nY, 0); + } + + + + FOR ( band = brange[0]; band < brange[1]; band++ ) + { + assert( band >= 0 ); + IF ( have_residual ) + { + /* collect diffuse prototypes */ + assert( band < hParamMC->h_output_synthesis_params.max_band_decorr ); + FOR ( ch_idx = 0; ch_idx < nY; ch_idx++ ) + { + diff_f_real_fx[ch_idx] = Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band]; // Q6 + move32(); + diff_f_imag_fx[ch_idx] = Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band]; + move32(); + } + + /* apply residual mixing */ + + matrix_product_fx( mixing_matrix_res_smooth_fx, nY, nY, 0, diff_f_real_fx, nY, 1, 0, output_f_real_fx ); + output_f_real_e = add( mixing_matrix_res_smooth_e, 25 ); + scale_sig32(output_f_real_fx, nY, 6 - (31 - output_f_real_e) ); + + + matrix_product_fx(mixing_matrix_res_smooth_fx, nY, nY, 0, diff_f_imag_fx, nY, 1, 0, output_f_imag_fx); + output_f_imag_e = mixing_matrix_res_smooth_e + 25; + scale_sig32(output_f_imag_fx, nY, 6 - (31 - output_f_imag_e) ); + + FOR ( ch_idx = 0; ch_idx < nY; ch_idx++ ) + { + Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = output_f_real_fx[ch_idx]; // Q6 + move32(); + Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = output_f_imag_fx[ch_idx]; + move32(); + } + } + ELSE + { + FOR ( ch_idx = 0; ch_idx < nY; ch_idx++ ) + { + Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = 0; + move32(); + Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = 0; + move32(); + } + } + + /* collect input signals, still in cldfb buffers */ + FOR ( ch_idx = 0; ch_idx < nX; ch_idx++ ) + { + + input_f_real_fx[ch_idx] = Cldfb_RealBuffer_in_fx[ch_idx * hParamMC->num_freq_bands + band]; // Q6 + move32(); + input_f_imag_fx[ch_idx] = Cldfb_ImagBuffer_in_fx[ch_idx * hParamMC->num_freq_bands + band]; + move32(); + + } + + /* apply mixing matrix */ + + matrix_product_fx(mixing_matrix_smooth_fx, nY, nX, 0, input_f_real_fx, nX, 1, 0, output_f_real_fx); + output_f_real_e = add( mixing_matrix_smooth_e, 25 ); + scale_sig32(output_f_real_fx, MAX_CICP_CHANNELS, sub( 6, sub(31, output_f_real_e) ) ); + + + matrix_product_fx(mixing_matrix_smooth_fx, nY, nX, 0, input_f_imag_fx, nX, 1, 0, output_f_imag_fx); + output_f_imag_e = add( mixing_matrix_smooth_e, 25 ); + scale_sig32(output_f_imag_fx, MAX_CICP_CHANNELS, sub( 6, sub( 31, output_f_imag_e ) ) ); + + /* collect output */ + FOR ( ch_idx = 0; ch_idx < nY; ch_idx++ ) + { + Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add(Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band], output_f_real_fx[ch_idx] ); + Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add(Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band], output_f_imag_fx[ch_idx] ); + + } + } + } + + return; +} + +#endif /*-------------------------------------------------------------------* * computeMixingMatrices() * diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e63c61572..2e860b00d 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -4442,21 +4442,16 @@ ivas_error ivas_jbm_dec_render( { /* Convert CICP19 -> Ambisonics */ #if 1 - Word16 Q_in_buffer_td = 31; FOR( i = 0; i < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { - Q_in_buffer_td = s_min( Q_in_buffer_td, Q_factor_arrL( p_output[i], *nSamplesRendered ) ); - } - FOR( i = 0; i < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) - { - floatToFixed_arrL( p_output[i], p_output_fx[i], Q_in_buffer_td, *nSamplesRendered ); + floatToFixed_arrL( p_output[i], p_output_fx[i], Q11, *nSamplesRendered ); } #endif ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); #if 1 FOR( i = 0; i < ( st_ivas->hOutSetup.ambisonics_order + 1 ) * ( st_ivas->hOutSetup.ambisonics_order + 1 ); i++ ) { - fixedToFloat_arrL( p_output_fx[i], p_output[i], Q_in_buffer_td - 3, *nSamplesRendered ); + fixedToFloat_arrL( p_output_fx[i], p_output[i], Q11, *nSamplesRendered ); } #endif } @@ -5263,7 +5258,17 @@ ivas_error ivas_jbm_dec_render( if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) ) { crendInPlaceRotation = TRUE; +#ifdef IVAS_FLOAT_FIXED + ivas_mc2sba_fx( st_ivas->hTransSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX ); +#if 1 + FOR( i = 0; i < ( st_ivas->hIntSetup.ambisonics_order + 1 ) * ( st_ivas->hIntSetup.ambisonics_order + 1 ); i++ ) + { + fixedToFloat_arrL( p_output_fx[i], p_output[i], Q11, *nSamplesRendered ); + } +#endif +#else ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); +#endif // IVAS_FLOAT_FIXED } } @@ -5334,7 +5339,17 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef IVAS_FLOAT_FIXED + ivas_mc2sba_fx( st_ivas->hIntSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); +#if 1 + FOR( i = 0; i < ( st_ivas->hOutSetup.ambisonics_order + 1 ) * ( st_ivas->hOutSetup.ambisonics_order + 1 ); i++ ) + { + fixedToFloat_arrL( p_output_fx[i], p_output[i], Q11, *nSamplesRendered ); + } +#endif +#else ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { @@ -5465,7 +5480,21 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) + { + floatToFixed_arrL( p_output[i], p_output_fx[i], Q11, *nSamplesRendered ); + } + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); +#if 1 + FOR( i = 0; i < ( st_ivas->hOutSetup.ambisonics_order + 1 ) * ( st_ivas->hOutSetup.ambisonics_order + 1 ); i++ ) + { + fixedToFloat_arrL( p_output_fx[i], p_output[i], Q11, *nSamplesRendered ); + } +#endif +#else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { @@ -5514,7 +5543,21 @@ ivas_error ivas_jbm_dec_render( mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); } +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) + { + floatToFixed_arrL( p_output[i], p_output_fx[i], Q11, *nSamplesRendered ); + } + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); +#if 1 + FOR( i = 0; i < ( st_ivas->hOutSetup.ambisonics_order + 1 ) * ( st_ivas->hOutSetup.ambisonics_order + 1 ); i++ ) + { + fixedToFloat_arrL( p_output_fx[i], p_output[i], Q11, *nSamplesRendered ); + } +#endif +#else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 55373068d..f8a225606 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -134,6 +134,10 @@ static void ivas_param_mc_bs_decode_parameter_values_fx(UWord16 bit_buffer[], Wo 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 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); + +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 int16_t num_freq_bands/*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/); #endif /*------------------------------------------------------------------------- @@ -511,6 +515,7 @@ ivas_error ivas_param_mc_dec_open_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } + hParamMC->proto_frame_f_len = 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands; IF ( ( hParamMC->proto_frame_dec_f_fx = (Word32 *) malloc( 2 * nchan_out_cov * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); @@ -549,6 +554,8 @@ ivas_error ivas_param_mc_dec_open_fx( } set32_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, 0, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); + hParamMC->sz = n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands; + #if 1/*TODO: To be removed later(floating point malloc)*/ if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { @@ -798,7 +805,7 @@ ivas_error ivas_param_mc_dec_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } #else - IF ( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) + IF ( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } @@ -978,6 +985,14 @@ ivas_error ivas_param_mc_dec_open( if ( hParamMC->max_band_decorr > 0 ) { +#ifdef IVAS_FLOAT_FIXED + IF ((hParamMC->proto_frame_f_fx = (Word32 *)malloc(2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof(Word32))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n")); + } + hParamMC->proto_frame_f_len = 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands; + hParamMC->proto_frame_dec_f_len = 2 * nchan_out_cov * hParamMC->num_freq_bands; +#endif if ( ( hParamMC->proto_frame_f = (float *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); @@ -988,18 +1003,28 @@ ivas_error ivas_param_mc_dec_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } #ifdef IVAS_FLOAT_FIXED + hParamMC->proto_frame_f_len = 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands; + hParamMC->proto_frame_dec_f_len = 2 * nchan_out_cov * hParamMC->num_freq_bands; if ((hParamMC->proto_frame_dec_f_fx = (Word32 *)malloc(2 * nchan_out_cov * hParamMC->num_freq_bands * sizeof(Word32))) == NULL) { return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n")); } + + if ( ( hParamMC->proto_frame_f_fx = (Word32 *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + #endif } else { hParamMC->proto_frame_f = NULL; hParamMC->proto_frame_dec_f = NULL; + #ifdef IVAS_FLOAT_FIXED hParamMC->proto_frame_dec_f_fx = NULL; + hParamMC->proto_frame_f_fx = NULL; #endif } @@ -1021,6 +1046,7 @@ ivas_error ivas_param_mc_dec_open( set_zero( hParamMC->Cldfb_RealBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); #ifdef IVAS_FLOAT_FIXED + hParamMC->sz = n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands; IF ( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); @@ -1058,6 +1084,11 @@ ivas_error ivas_param_mc_dec_open( { hParamMC->Cldfb_RealBuffer_tc = NULL; hParamMC->Cldfb_ImagBuffer_tc = NULL; + +#ifdef IVAS_FLOAT_FIXED + hParamMC->Cldfb_RealBuffer_tc_fx = NULL; + hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; +#endif } hParamMC->subframes_rendered = 0; @@ -1645,12 +1676,14 @@ ivas_error ivas_param_mc_dec_reconfig_fx( IF ( GT_16(hParamMC->max_band_decorr , 0) && NE_16(nchan_transport_old , nchan_transport) ) { -#if 1 /*To be removed later:floating point memory alocations*/ +#ifdef IVAS_FLOAT_FIXED /*To be removed later:floating point memory alocations*/ free( hParamMC->proto_frame_f ); + hParamMC->proto_frame_f_len = 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands; IF ( ( hParamMC->proto_frame_f = (float *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } + set_zero( hParamMC->proto_frame_f, 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands ); #endif free( hParamMC->proto_frame_f_fx ); @@ -2212,6 +2245,16 @@ ivas_error ivas_param_mc_dec_reconfig( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } set_zero( hParamMC->proto_frame_f, 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands ); + +#ifdef IVAS_FLOAT_FIXED + free(hParamMC->proto_frame_f_fx); + hParamMC->proto_frame_f_len = 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands; + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n")); + } + + set_zero_fx(hParamMC->proto_frame_f_fx, 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands); +#endif } @@ -2248,6 +2291,7 @@ ivas_error ivas_param_mc_dec_reconfig( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); } set_zero( hParamMC->Cldfb_ImagBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); + } else { @@ -2261,6 +2305,7 @@ ivas_error ivas_param_mc_dec_reconfig( free( hParamMC->Cldfb_ImagBuffer_tc ); hParamMC->Cldfb_ImagBuffer_tc = NULL; } + } } return error; @@ -2572,6 +2617,11 @@ void ivas_param_mc_dec_close( { free( hParamMC->proto_frame_f ); hParamMC->proto_frame_f = NULL; + +#ifdef IVAS_FLOAT_FIXED + free(hParamMC->proto_frame_f_fx); + hParamMC->proto_frame_f_fx = NULL; +#endif } if ( hParamMC->proto_frame_dec_f != NULL ) @@ -3358,11 +3408,16 @@ void ivas_param_mc_dec_render( for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++) { p_output_f_fx[i] = output_f_fx[i]; } + #endif float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; /*Decorrelator*/ float onset_filter[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; + +#ifdef IVAS_FLOAT_FIXED + Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; +#endif /* format converter */ int16_t channel_active[MAX_OUTPUT_CHANNELS]; uint16_t nband_synth, nbands_to_zero; @@ -3459,16 +3514,61 @@ void ivas_param_mc_dec_render( /*-----------------------------------------------------------------* * protoype signal computation *-----------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED + + floatToFixed_arrL(hParamMC->Cldfb_RealBuffer_tc, hParamMC->Cldfb_RealBuffer_tc_fx, Q12, hParamMC->sz); + + floatToFixed_arrL(hParamMC->Cldfb_ImagBuffer_tc, hParamMC->Cldfb_ImagBuffer_tc_fx, Q12, hParamMC->sz); + + FOR(Word16 x = 0; x < hParamMC->diff_proto_info->num_protos_diff; x++) + { + Word16 num_source_ch = hParamMC->diff_proto_info->num_source_chan_diff[x]; + move16(); + + floatToFixed_arrL(hParamMC->diff_proto_info->proto_fac[x], hParamMC->diff_proto_info->proto_fac_fx[x], Q30, num_source_ch); + } + + 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); + + fixedToFloat_arrL(hParamMC->proto_frame_f_fx, hParamMC->proto_frame_f, Q11, 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands); + +#else param_mc_protoSignalComputation( &hParamMC->Cldfb_RealBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], &hParamMC->Cldfb_ImagBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], hParamMC->proto_frame_f, hParamMC->diff_proto_info, hParamMC->num_freq_bands ); +#endif /*-----------------------------------------------------------------* * frequency domain decorrelation *-----------------------------------------------------------------*/ - /* decorrelate prototype frame */ + +#ifdef IVAS_FLOAT_FIXED + Word16 tmp_e; + f2me_buf(hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer, hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_fx, &tmp_e, hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_len ); + hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer = 31 - tmp_e; + 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, + 11, + hParamMC->diff_proto_info->num_protos_diff, + hParamMC->diff_proto_info->proto_index_diff, + hParamMC->proto_frame_dec_f_fx,//output + &hParamMC->exp_proto_frame_dec_f, + onset_filter_fx, + hParamMC->h_freq_domain_decorr_ap_params, + hParamMC->h_freq_domain_decorr_ap_state ); + fixedToFloat_arrL32(onset_filter_fx, onset_filter, 31, MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX); + fixedToFloat_arrL32(hParamMC->proto_frame_dec_f_fx, hParamMC->proto_frame_dec_f, 11, nchan_out_cov * 2 * hParamMC->num_freq_bands); +#else ivas_dirac_dec_decorr_process( hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, @@ -3481,11 +3581,12 @@ void ivas_param_mc_dec_render( onset_filter, hParamMC->h_freq_domain_decorr_ap_params, hParamMC->h_freq_domain_decorr_ap_state ); +#endif /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ /* memory for the decorrelated signal */ #ifdef IVAS_FLOAT_FIXED - f2me_buf(hParamMC->proto_frame_dec_f, hParamMC->proto_frame_dec_f_fx, &hParamMC->exp_proto_frame_dec_f, nchan_out_cov * 2 * hParamMC->num_freq_bands); + //f2me_buf(hParamMC->proto_frame_dec_f, hParamMC->proto_frame_dec_f_fx, &hParamMC->exp_proto_frame_dec_f, nchan_out_cov * 2 * hParamMC->num_freq_bands); ivas_param_mc_dec_copy_diffuse_proto(hParamMC, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nchan_out_cov, slot_idx); FOR(int k = 0; k < nchan_out_cov; k++) { @@ -3504,11 +3605,70 @@ void ivas_param_mc_dec_render( * output synthesis *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + Word16 j, k; + + 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] = (Word32) (floatToFixed( Cldfb_RealBuffer[i][j][k], 6 ) ); + Cldfb_ImagBuffer_fx[i][j][k] = (Word32) (floatToFixed(Cldfb_ImagBuffer[i][j][k], 6 ) ); + } + } + } + + Word16 length = nchan_transport; + FOR (Word16 i = 0; i < 16 * nchan_transport * hParamMC->num_freq_bands; i++) + { + st_ivas->hParamMC->Cldfb_RealBuffer_tc_fx[i] = + floatToFixed(st_ivas->hParamMC->Cldfb_RealBuffer_tc[i], 6); + st_ivas->hParamMC->Cldfb_ImagBuffer_tc_fx[i] = + floatToFixed(st_ivas->hParamMC->Cldfb_ImagBuffer_tc[i], 6); + } + + FOR(Word16 param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx++) { + + + f2me_buf(hParamMC->h_output_synthesis_cov_state.mixing_matrix[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx], nchan_transport * nchan_out_cov); + + IF(hParamMC->band_grouping[param_band_idx] < hParamMC->h_output_synthesis_params.max_band_decorr) { + f2me_buf(hParamMC->h_output_synthesis_cov_state.mixing_matrix_res[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx], nchan_out_cov * nchan_out_cov); + + f2me_buf(hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx], nchan_out_cov * nchan_out_cov); + } + } + + floatToFixed_arr16(hParamMC->h_output_synthesis_params.interpolator, hParamMC->h_output_synthesis_params.interpolator_fx, 15, DEFAULT_JBM_CLDFB_TIMESLOTS); + + + 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, slot_idx + slot_idx_start, + nchan_transport, nchan_out_cov, hParamMC ); + + + 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[i][j][k] = ((float)Cldfb_RealBuffer_fx[i][j][k] / ( 1 << 6)); + Cldfb_ImagBuffer[i][j][k] = ((float)Cldfb_ImagBuffer_fx[i][j][k] / ( 1 << 6)); + } + } + } + +#else ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( &hParamMC->Cldfb_RealBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], &hParamMC->Cldfb_ImagBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer, Cldfb_ImagBuffer, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, slot_idx, slot_idx + slot_idx_start, nchan_transport, nchan_out_cov, hParamMC ); +#endif if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) { @@ -3795,7 +3955,17 @@ void ivas_param_mc_dec_render( #endif if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef IVAS_FLOAT_FIXED + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); +#if 1 + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + fixedToFloat_arrL(output_f_fx[i], output_f[i], Q11 , *nSamplesRendered ); + } +#endif +#else ivas_mc2sba( st_ivas->hIntSetup, output_f, output_f, hParamMC->num_freq_bands * slots_to_render, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif // IVAS_FLOAT_FIXED } /* update */ @@ -3825,6 +3995,8 @@ void ivas_param_mc_dec_render( } hParamMC->subframes_rendered = last_sf; *nSamplesAvailableNext = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); + //fclose(fp1); + //fclose(fp); pop_wmops(); return; @@ -4141,9 +4313,6 @@ void ivas_param_mc_dec( nSamplesAsked = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); ivas_param_mc_dec_digest_tc( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS, output_f ); -#ifdef IVAS_FLOAT_FIXED - me2f_buf_16(st_ivas->hParamMC->h_output_synthesis_params.interpolator_fx, 0, st_ivas->hParamMC->h_output_synthesis_params.interpolator, DEFAULT_JBM_CLDFB_TIMESLOTS ); -#endif ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailableNext, output_f ); /* set handle pointers back to NULL */ @@ -4324,6 +4493,71 @@ static void param_mc_protoSignalComputation( return; } +#ifdef IVAS_FLOAT_FIXED +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 int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ +) +{ + 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 + + Word16 proto_frame_f_q[ MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS * 120]; + + set32_fx(proto_frame_f_fx, 0, 2 * num_freq_bands * diff_proto_info->num_protos_diff); + + + 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[proto_ch_idx * num_freq_bands * 2]; + p_real_buffer_fx = &RealBuffer_fx[source_ch_idx * num_freq_bands]; + p_imag_buffer_fx = &ImagBuffer_fx[source_ch_idx * num_freq_bands]; + + Word16 i = shl(imult1616(proto_ch_idx, num_freq_bands), 1); + move16(); + + FOR (band = 0; band < num_freq_bands; band++) + { + + Word32 tmp_x = Mpy_32_32(fac_fx, (*(p_real_buffer_fx++))); // Q(30 + 12 - 31) :: Q11 + + *(p_proto_frame_fx) = L_add(*(p_proto_frame_fx), tmp_x); + move32(); + p_proto_frame_fx++; + + tmp_x = Mpy_32_32(fac_fx, (*(p_imag_buffer_fx++))); // Q(30 + 12 - 31) :: Q11 + + *(p_proto_frame_fx) = L_add(*(p_proto_frame_fx), tmp_x); + move32(); + p_proto_frame_fx++; + + } + } + } + + return; +} +#endif + /*------------------------------------------------------------------------- * ivas_param_mc_dec_compute_diffuse_proto() * @@ -4679,7 +4913,7 @@ static void remove_lfe_from_cy_fx( FOR ( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) { *( ptrCy_out++ ) = *( ptrCy++ ); - move32(); + move32(); } ptrCy++; } @@ -4872,7 +5106,7 @@ static void ivas_param_mc_get_mixing_matrices( synth_config, nY_intern, nX, Cx_state, Cproto, Cy_state ); - //dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state.txt"); + //dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state.txt"); #endif /* Smoothing: Sum over two buffers */ @@ -5770,7 +6004,7 @@ static void ivas_param_mc_dequantize_cov( } Nrqq[h_ild_mapping->ild_index[k]] = powf( 10.0f, ild_q[k] / 10.0f ) * hParamMC->hMetadataPMC->ild_factors[k] * ref_ener; } - //dbgwrite2_txt(Nrqq,size,"../nrqq.txt"); + //dbgwrite2_txt(Nrqq,size,"../nrqq.txt"); /* estimate ICCs from estimated Cproto */ for ( k = 0; k < nY_int; k++ ) @@ -6045,8 +6279,8 @@ static void ivas_param_mc_dequantize_cov_fx( #endif } - test(); - test(); + test(); + test(); IF( GE_16(param_band_index , PARAM_MC_MAX_BAND_LFE) || EQ_16(hParamMC->hMetadataPMC->lfe_on,0) ) { FOR( k = 0; k < nY_int; k++ ) @@ -6583,6 +6817,12 @@ static ivas_error param_mc_get_diff_proto_info( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + 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")); + } +#endif #ifdef IVAS_FLOAT_FIXED if ( ( p_diff_proto_info->proto_fac_fx = (Word32 **) malloc( p_diff_proto_info->num_protos_diff * sizeof(Word32 * ) ) ) == NULL ) @@ -6609,6 +6849,13 @@ static ivas_error param_mc_get_diff_proto_info( } #endif // IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED + 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")); + } +#endif + proto_fac_ptr = proto_fac + cur_diff_proto; for ( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) { diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index a779b98b1..5b479f344 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -234,7 +234,7 @@ void ivas_mc2sba_fx( /* Add LFE to omni W with gain*/ FOR( k = 0; k < output_frame; k++ ) { - buffer_tmp_fx[0][k] = L_add( buffer_tmp_fx[0][k], L_shr( Mult_32_16( in_buffer_td_fx[i][k], gain_lfe_fx ), 2 ) ); /*Q+14-15-2==Q-3*/ + buffer_tmp_fx[0][k] = L_add( buffer_tmp_fx[0][k], L_shl( Mult_32_16( in_buffer_td_fx[i][k], gain_lfe_fx ), 1 ) ); /*Q+14-15+1==Q*/ } } @@ -259,7 +259,7 @@ void ivas_mc2sba_fx( { FOR( k = 0; k < output_frame; k++ ) { - buffer_tmp_fx[j][k] = L_add( buffer_tmp_fx[j][k], L_shr( Mult_32_32( in_buffer_td_fx[i][k], gains_fx[j] ), 1 ) ); /*Q+29-31-1==Q-3*/ + buffer_tmp_fx[j][k] = L_add( buffer_tmp_fx[j][k], L_shl( Mult_32_32( in_buffer_td_fx[i][k], gains_fx[j] ), 2 ) ); /*Q+29-31+2==Q*/ } } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 33b101cb6..5cf0a60b8 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -828,10 +828,11 @@ typedef struct ivas_param_mc_dec_data_structure float *Cldfb_RealBuffer_tc; float *Cldfb_ImagBuffer_tc; #ifdef IVAS_FLOAT_FIXED - Word32 *Cldfb_RealBuffer_tc_fx; + Word32 *Cldfb_RealBuffer_tc_fx; // Q12 Word16 Cldfb_RealBuffer_tc_e; - Word32 *Cldfb_ImagBuffer_tc_fx; + Word32 *Cldfb_ImagBuffer_tc_fx; // Q12 Word16 Cldfb_ImagBuffer_tc_e; + Word16 sz; #endif int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; int16_t nb_subframes; @@ -858,6 +859,10 @@ typedef struct ivas_param_mc_dec_data_structure #ifdef IVAS_FLOAT_FIXED Word32 *proto_frame_dec_f_fx; Word16 exp_proto_frame_dec_f; + + Word32 *proto_frame_f_fx; // Q11 + Word16 proto_frame_f_len; + Word16 proto_frame_dec_f_len; #endif DIRAC_OUTPUT_SYNTHESIS_COV_STATE h_output_synthesis_cov_state; @@ -876,7 +881,6 @@ typedef struct ivas_param_mc_dec_data_structure #endif float *proto_matrix_int; #ifdef IVAS_FLOAT_FIXED - Word32 *proto_frame_f_fx; Word16 q_proto_frame_f; Word32 *ls_conv_dmx_matrix_fx; Word16 ls_conv_dmx_e; diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index f50aeb074..ce125f9a1 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -594,6 +594,7 @@ ivas_error ivas_dirac_dec_decorr_open_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } + freq_domain_decorr_ap_state->decorr_buffer_len = 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr; set32_fx( freq_domain_decorr_ap_state->decorr_buffer_fx, 0, 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr ); freq_domain_decorr_ap_state->q_decorr_buffer = Q31; diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index add5bd875..0e92bf6b3 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -990,6 +990,7 @@ ivas_error ivas_orient_trk_Init_fx( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_SetTrackingType( ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ @@ -1004,14 +1005,13 @@ ivas_error ivas_orient_trk_SetTrackingType( return IVAS_ERR_OK; } - -#ifdef IVAS_FLOAT_FIXED +#else ivas_error ivas_orient_trk_SetTrackingType_fx( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ ) { - IF ( pOTR == NULL ) + IF( pOTR == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1145,6 +1145,7 @@ ivas_error ivas_orient_trk_GetMainOrientation_fx( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_GetTrackedRotation( ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ IVAS_QUATERNION *pRotation /* i/o: processed rotation */ @@ -1159,14 +1160,14 @@ ivas_error ivas_orient_trk_GetTrackedRotation( return IVAS_ERR_OK; } - -#ifdef IVAS_FLOAT_FIXED +#else ivas_error ivas_orient_trk_GetTrackedRotation_fx( ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ IVAS_QUATERNION *pRotation /* i/o: processed rotation */ ) { - IF ( pOTR == NULL || pRotation == NULL ) + test(); + IF( pOTR == NULL || pRotation == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 31bada63e..fb788fa4e 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -55,6 +55,20 @@ * Allocates the renderer configuration structure *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_render_config_open( + RENDER_CONFIG_HANDLE *hRenderConfig /* i/o: Renderer config handle */ +) +{ + /* Allocate HR filter set for headphones configuration */ + IF( ( *hRenderConfig = (RENDER_CONFIG_HANDLE) malloc( sizeof( RENDER_CONFIG_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for renderer configuration!" ); + } + + return IVAS_ERR_OK; +} +#else ivas_error ivas_render_config_open( RENDER_CONFIG_HANDLE *hRenderConfig /* i/o: Renderer config handle */ ) @@ -67,6 +81,7 @@ ivas_error ivas_render_config_open( return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -75,6 +90,23 @@ ivas_error ivas_render_config_open( * Deallocates the renderer configuration structure *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_render_config_close( + RENDER_CONFIG_HANDLE *hRenderConfig /* i/o: Renderer config handle */ +) +{ + test(); + IF( hRenderConfig == NULL || *hRenderConfig == NULL ) + { + return; + } + + free( *hRenderConfig ); + *hRenderConfig = NULL; + + return; +} +#else void ivas_render_config_close( RENDER_CONFIG_HANDLE *hRenderConfig /* i/o: Renderer config handle */ ) @@ -89,6 +121,7 @@ void ivas_render_config_close( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index ca299c1e1..93b32afa1 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1634,6 +1634,23 @@ ivas_error ivas_external_orientation_open( * Deallocate external orientation handle *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_external_orientation_close( + EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* i/o: external orientation handle */ +) +{ + test(); + IF( hExtOrientationData == NULL || *hExtOrientationData == NULL ) + { + return; + } + + free( ( *hExtOrientationData ) ); + *hExtOrientationData = NULL; + + return; +} +#else void ivas_external_orientation_close( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* i/o: external orientation handle */ ) @@ -1648,6 +1665,7 @@ void ivas_external_orientation_close( return; } +#endif /*-----------------------------------------------------------------------* @@ -1771,6 +1789,23 @@ ivas_error ivas_combined_orientation_open( * Deallocate combined orientation handle *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_combined_orientation_close( + COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* i/o: combined orientation handle */ +) +{ + test(); + IF( hCombinedOrientationData == NULL || *hCombinedOrientationData == NULL ) + { + return; + } + + free( ( *hCombinedOrientationData ) ); + *hCombinedOrientationData = NULL; + + return; +} +#else void ivas_combined_orientation_close( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* i/o: combined orientation handle */ ) @@ -1785,6 +1820,7 @@ void ivas_combined_orientation_close( return; } +#endif /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index d266aecfe..d3348f9dd 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -191,6 +191,7 @@ typedef struct dirac_decorr_state_structure #ifdef IVAS_FLOAT_FIXED Word32 *decorr_buffer_fx; Word16 q_decorr_buffer; + Word16 decorr_buffer_len; Word32 *direct_energy_smooth_fx; Word16 q_direct_energy_smooth; Word32 *reverb_energy_smooth_fx; @@ -1823,7 +1824,7 @@ typedef struct ivas_binaural_td_rendering_struct typedef struct { - int32_t binaural_latency_ns; + Word32 binaural_latency_ns; BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; TDREND_HRFILT_FiltSet_t *hHrtfTD; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index dbbdbd13f..3b93eaf6e 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -767,9 +767,9 @@ static ivas_error validateOutputAudioConfig( * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED IVAS_REND_AudioConfigType getAudioConfigType( const AUDIO_CONFIG config ) -#ifdef IVAS_FLOAT_FIXED { IVAS_REND_AudioConfigType type; @@ -818,6 +818,8 @@ IVAS_REND_AudioConfigType getAudioConfigType( return type; } #else +IVAS_REND_AudioConfigType getAudioConfigType( + const AUDIO_CONFIG config) { IVAS_REND_AudioConfigType type; @@ -938,6 +940,7 @@ ivas_error getAudioConfigNumChannels( case IVAS_AUDIO_CONFIG_OBA: case IVAS_AUDIO_CONFIG_MASA1: *numChannels = 1; + move16(); BREAK; case IVAS_AUDIO_CONFIG_STEREO: case IVAS_AUDIO_CONFIG_BINAURAL: @@ -945,28 +948,36 @@ ivas_error getAudioConfigNumChannels( case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA2: *numChannels = 2; + move16(); BREAK; case IVAS_AUDIO_CONFIG_FOA: *numChannels = 4; + move16(); BREAK; case IVAS_AUDIO_CONFIG_5_1: *numChannels = 6; + move16(); BREAK; case IVAS_AUDIO_CONFIG_7_1: case IVAS_AUDIO_CONFIG_5_1_2: *numChannels = 8; + move16(); BREAK; case IVAS_AUDIO_CONFIG_HOA2: *numChannels = 9; + move16(); BREAK; case IVAS_AUDIO_CONFIG_5_1_4: *numChannels = 10; + move16(); BREAK; case IVAS_AUDIO_CONFIG_7_1_4: *numChannels = 12; + move16(); BREAK; case IVAS_AUDIO_CONFIG_HOA3: *numChannels = 16; + move16(); BREAK; default: return IVAS_ERR_NUM_CHANNELS_UNKNOWN; @@ -1142,6 +1153,8 @@ static LSSETUP_CUSTOM_STRUCT defaultCustomLs( return ls; } #endif + + #ifdef IVAS_FLOAT_FIXED static ivas_error getSpeakerAzimuths_fx( AUDIO_CONFIG config, @@ -1285,17 +1298,20 @@ static ivas_error getAmbisonicsOrder_fx( AUDIO_CONFIG config, Word16 *order ) { - switch ( config ) + SWITCH ( config ) { case IVAS_AUDIO_CONFIG_FOA: *order = 1; - break; + move16(); + BREAK; case IVAS_AUDIO_CONFIG_HOA2: *order = 2; - break; + move16(); + BREAK; case IVAS_AUDIO_CONFIG_HOA3: *order = 3; - break; + move16(); + BREAK; default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported audio config" ); } @@ -1658,12 +1674,12 @@ static ivas_error getEfapGains_fx( IF( EQ_32( efapWrapper.speakerConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) { numChannels = add( efapWrapper.pCustomLsSetup->num_spk, efapWrapper.pCustomLsSetup->num_lfe ); - move16(); readPtr = tmpPanGains; - move16(); lfeCount = 0; + move16(); FOR( i = 0; i < numChannels; ++i ) { + test(); IF( LT_16( lfeCount, efapWrapper.pCustomLsSetup->num_lfe ) && EQ_16( i, efapWrapper.pCustomLsSetup->lfe_idx[lfeCount] ) ) { panGains[i] = 0; @@ -1686,7 +1702,6 @@ static ivas_error getEfapGains_fx( } readPtr = tmpPanGains; - move32(); FOR( i = 0; i < numChannels; ++i ) { @@ -1850,6 +1865,21 @@ static ivas_error initHeadRotation( return IVAS_ERR_OK; } #endif + + +#ifdef IVAS_FLOAT_FIXED +static void closeHeadRotation( + IVAS_REND_HANDLE hIvasRend ) +{ + test(); + IF( ( hIvasRend != NULL ) && ( hIvasRend->headRotData.hOrientationTracker != NULL ) ) + { + free( hIvasRend->headRotData.hOrientationTracker ); + } + + return; +} +#else static void closeHeadRotation( IVAS_REND_HANDLE hIvasRend ) { @@ -1860,6 +1890,7 @@ static void closeHeadRotation( return; } +#endif static void initRotMatrix( @@ -2020,19 +2051,51 @@ static rendering_context getRendCtx( } +#ifdef IVAS_FLOAT_FIXED static TDREND_WRAPPER defaultTdRendWrapper( void ) { TDREND_WRAPPER w; w.binaural_latency_ns = 0; + move32(); w.hBinRendererTd = NULL; w.hHrtfTD = NULL; return w; } +#else +static TDREND_WRAPPER defaultTdRendWrapper( + void ) +{ + TDREND_WRAPPER w; + w.binaural_latency_ns = 0; + w.hBinRendererTd = NULL; + w.hHrtfTD = NULL; + return w; +} +#endif + + +#ifdef IVAS_FLOAT_FIXED +static bool isIoConfigPairSupported( + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig ) +{ + /* Rendering mono or stereo to binaural is not supported */ + test(); + test(); + IF( ( EQ_32( inConfig, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( inConfig, IVAS_AUDIO_CONFIG_STEREO ) ) && EQ_32( getAudioConfigType( outConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) ) + { + return false; + } + + /* If not returned so far, config pair is supported */ + return true; +} +#else static bool isIoConfigPairSupported( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig ) @@ -2046,6 +2109,7 @@ static bool isIoConfigPairSupported( /* If not returned so far, config pair is supported */ return true; } +#endif static ivas_error initIsmMasaRendering( @@ -2320,9 +2384,10 @@ static void fillIdentityPanMatrix_fx( { Word16 i; - FOR( i = 0; i < min( MAX_INPUT_CHANNELS, MAX_OUTPUT_CHANNELS ); ++i ) + FOR( i = 0; i < s_min( MAX_INPUT_CHANNELS, MAX_OUTPUT_CHANNELS ); ++i ) { panMatrix[i][i] = ONE_IN_Q31; + move32(); } return; @@ -2369,12 +2434,15 @@ static ivas_error initMcPanGainsWithConversionMapping_fx( Word16 i; ivasConfigIn = inputMc->base.inConfig; + move32(); ivasConfigOut = outConfig; + move32(); /* Find conversion mapping for current I/O config pair. * Stay with default panning matrix if conversion_matrix is NULL */ FOR( i = 0; i < LS_SETUP_CONVERSION_NUM_MAPPINGS; ++i ) { + test(); IF( EQ_32( ls_conversion_mapping_fx[i].input_config, ivasConfigIn ) && EQ_32( ls_conversion_mapping_fx[i].output_config, ivasConfigOut ) ) { /* Mapping found with valid matrix - copy */ @@ -2459,6 +2527,7 @@ static ivas_error initMcPanGainsWithEfap_fx( } inLfeChIdx = LFE_CHANNEL; + move16(); } ELSE { @@ -2491,6 +2560,8 @@ static ivas_error initMcPanGainsWithEfap_fx( ++outChIdx; } + test(); + test(); IF( NE_32( outConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GE_16( inLfeChIdx, 0 ) ) { inputMc->panGains_fx[inLfeChIdx][LFE_CHANNEL] = ONE_IN_Q31; @@ -2668,6 +2739,7 @@ static ivas_error initMcPanGainsWithMonoOut_fx( /* ls_conversion_cicpX_stereo contains gains for side speakers. * These should be skipped with 5.1+X inputs. */ skipSideSpeakers = false; + test(); IF( EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_5_1_2 ) || EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_5_1_4 ) ) { skipSideSpeakers = true; @@ -2676,6 +2748,7 @@ static ivas_error initMcPanGainsWithMonoOut_fx( move16(); FOR( writeIdx = 0; writeIdx < numInChannels; ++writeIdx ) { + test(); IF( ( skipSideSpeakers ) && EQ_16( readIdx, 4 ) ) { /* Skip gains for side speakers in lookup table */ @@ -2770,6 +2843,7 @@ static ivas_error initMcPanGainsWithStereoLookup_fx( /* ls_conversion_cicpX_stereo contains gains for side speakers. * These should be skipped with 5.1+X inputs. */ skipSideSpeakers = false; + test(); IF( EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_5_1_2 ) || EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_5_1_4 ) ) { skipSideSpeakers = true; @@ -2859,35 +2933,37 @@ static bool configsAreEqual( Word16 i; /* Both input and output are custom LS - compare structs */ - IF ( EQ_16(configA , IVAS_AUDIO_CONFIG_LS_CUSTOM) && EQ_16(configB , IVAS_AUDIO_CONFIG_LS_CUSTOM) ) + test(); + IF( EQ_16( configA, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && EQ_16( configB, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) { - IF ( NE_16(customLsA.num_spk , customLsB.num_spk) ) + IF( NE_16( customLsA.num_spk, customLsB.num_spk ) ) { return false; } - IF ( NE_16(customLsA.num_lfe , customLsB.num_lfe )) + IF( NE_16( customLsA.num_lfe, customLsB.num_lfe ) ) { return false; } - IF ( NE_16(customLsA.is_planar_setup , customLsB.is_planar_setup) ) + IF( NE_16( customLsA.is_planar_setup, customLsB.is_planar_setup ) ) { return false; } - FOR ( i = 0; i < customLsA.num_spk; ++i ) + FOR( i = 0; i < customLsA.num_spk; ++i ) { /* Compare to nearest degree (hence the int16_t cast) */ - IF ( NE_32(customLsA.ls_azimuth_fx[i] , customLsB.ls_azimuth_fx[i]) || - NE_32(customLsA.ls_elevation_fx[i] , customLsB.ls_elevation_fx[i] )) + test(); + IF( NE_32( customLsA.ls_azimuth_fx[i], customLsB.ls_azimuth_fx[i] ) || + NE_32( customLsA.ls_elevation_fx[i], customLsB.ls_elevation_fx[i] ) ) { return false; } } - FOR ( i = 0; i < customLsA.num_lfe; ++i ) + FOR( i = 0; i < customLsA.num_lfe; ++i ) { - IF ( NE_16(customLsA.lfe_idx[i] , customLsB.lfe_idx[i]) ) + IF( NE_16( customLsA.lfe_idx[i], customLsB.lfe_idx[i] ) ) { return false; } @@ -2960,31 +3036,29 @@ static ivas_error updateLfePanGainsForMcOut( error = IVAS_ERR_OK; /* If panning is not required, simply return */ - IF ( !inputMc->lfeRouting.pan_lfe ) + IF( !inputMc->lfeRouting.pan_lfe ) { return error; } numLfeIn = getNumLfeChannels( inputMc ); - move16(); - IF ( EQ_16(outConfig , IVAS_AUDIO_CONFIG_LS_CUSTOM) ) + IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) { numOutChannels = add( inputMc->base.ctx.pCustomLsOut->num_spk, inputMc->base.ctx.pCustomLsOut->num_lfe ); - move16(); } ELSE { - IF ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + IF( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) { return error; } } - FOR ( i = 0; i < numLfeIn; i++ ) + FOR( i = 0; i < numLfeIn; i++ ) { /* panning gains */ - IF ( ( error = getEfapGains_fx( *inputMc->base.ctx.pEfapOutWrapper, inputMc->lfeRouting.lfeOutputAzimuth_fx, inputMc->lfeRouting.lfeOutputElevation_fx, inputMc->lfeRouting.lfePanMtx_fx[i] ) ) != IVAS_ERR_OK ) + IF( ( error = getEfapGains_fx( *inputMc->base.ctx.pEfapOutWrapper, inputMc->lfeRouting.lfeOutputAzimuth_fx, inputMc->lfeRouting.lfeOutputElevation_fx, inputMc->lfeRouting.lfePanMtx_fx[i] ) ) != IVAS_ERR_OK ) { return error; } @@ -3127,17 +3201,20 @@ static ivas_error updateMcPanGainsForMcOut( +-----------+-------------+---------------+-----------+--------------------+ */ - IF ( configsAreEqual( inputMc->base.inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ) ) + test(); + test(); + IF( configsAreEqual( inputMc->base.inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ) ) { error = initMcPanGainsWithIdentMatrix( inputMc ); } - ELSE IF ( EQ_16(outConfig , IVAS_AUDIO_CONFIG_LS_CUSTOM) || - EQ_16(inputMc->base.inConfig , IVAS_AUDIO_CONFIG_MONO) || - EQ_16(inputMc->base.inConfig , IVAS_AUDIO_CONFIG_LS_CUSTOM )) + ELSE IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) || + EQ_16( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_MONO ) || + EQ_16( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) { - IF ( EQ_16(inputMc->base.inConfig , IVAS_AUDIO_CONFIG_MONO ) && ( inputMc->nonDiegeticPan ) ) + test(); + IF( EQ_16( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_MONO ) && ( inputMc->nonDiegeticPan ) ) { - inputMc->panGains_fx[0][0] = EQ_32(inputMc->nonDiegeticPanGain_fx , ONE_IN_Q31 ) ? ONE_IN_Q31 : L_add( L_shr( inputMc->nonDiegeticPanGain_fx, 1 ), ONE_IN_Q30 ); + inputMc->panGains_fx[0][0] = EQ_32( inputMc->nonDiegeticPanGain_fx, ONE_IN_Q31 ) ? ONE_IN_Q31 : L_add( L_shr( inputMc->nonDiegeticPanGain_fx, 1 ), ONE_IN_Q30 ); move32(); inputMc->panGains_fx[0][1] = L_sub( ONE_IN_Q31, inputMc->panGains_fx[0][0] ); move32(); @@ -3148,11 +3225,11 @@ static ivas_error updateMcPanGainsForMcOut( error = initMcPanGainsWithEfap_fx( inputMc, outConfig ); } } - ELSE IF ( EQ_16(outConfig , IVAS_AUDIO_CONFIG_MONO) ) + ELSE IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_MONO ) ) { error = initMcPanGainsWithMonoOut_fx( inputMc ); } - ELSE IF( EQ_16(outConfig , IVAS_AUDIO_CONFIG_STEREO) ) + ELSE IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_STEREO ) ) { error = initMcPanGainsWithStereoLookup_fx( inputMc ); } @@ -3162,7 +3239,7 @@ static ivas_error updateMcPanGainsForMcOut( } /* check for errors from above block */ - IF ( error != IVAS_ERR_OK ) + IF( error != IVAS_ERR_OK ) { return error; } @@ -3268,14 +3345,14 @@ static ivas_error updateMcPanGainsForAmbiOut( } ch_in = 0; move16(); - FOR ( ch_out = 0; ch_in < numNonLfeInChannels; ++ch_out ) + FOR( ch_out = 0; ch_in < numNonLfeInChannels; ++ch_out ) { - IF ( EQ_16(ch_in , LFE_CHANNEL )) + IF( EQ_16( ch_in, LFE_CHANNEL ) ) { ++ch_out; } ivas_dirac_dec_get_response_fixed( (Word16) L_shr( spkAzi_fx[ch_in], 22 ), (Word16) L_shr( spkEle_fx[ch_in], 22 ), inputMc->panGains_fx[ch_out], outAmbiOrder ); - FOR ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); @@ -3296,11 +3373,11 @@ static ivas_error updateMcPanGainsForAmbiOut( move32(); ch_in = 0; move16(); - FOR ( ch_out = 0; ch_in < numNonLfeInChannels; ++ch_out ) + FOR( ch_out = 0; ch_in < numNonLfeInChannels; ++ch_out ) { - FOR ( lfeIdx = 0; lfeIdx < inputMc->customLsInput.num_lfe; ++lfeIdx ) + FOR( lfeIdx = 0; lfeIdx < inputMc->customLsInput.num_lfe; ++lfeIdx ) { - IF ( EQ_16(inputMc->customLsInput.lfe_idx[lfeIdx] , ch_in )) + IF( EQ_16( inputMc->customLsInput.lfe_idx[lfeIdx], ch_in ) ) { ++ch_out; BREAK; @@ -3308,7 +3385,7 @@ static ivas_error updateMcPanGainsForAmbiOut( } ivas_dirac_dec_get_response_fixed( (Word16) L_shr( spkAzi_fx[ch_in], 22 ), (Word16) L_shr( spkEle_fx[ch_in], 22 ), inputMc->panGains_fx[ch_out], outAmbiOrder ); - FOR ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); @@ -3321,7 +3398,7 @@ static ivas_error updateMcPanGainsForAmbiOut( } /* update LFE panning */ - IF ( ( error = updateLfePanGainsForAmbiOut( inputMc, outConfig ) ) != IVAS_ERR_OK ) + IF( ( error = updateLfePanGainsForAmbiOut( inputMc, outConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -3411,7 +3488,7 @@ static ivas_error updateMcPanGains( setZeroPanMatrix_fx( inputMc->panGains_fx ); error = IVAS_ERR_OK; - SWITCH ( getAudioConfigType( outConfig ) ) + SWITCH( getAudioConfigType( outConfig ) ) { case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: error = updateMcPanGainsForMcOut( inputMc, outConfig ); @@ -3439,23 +3516,23 @@ static ivas_error updateMcPanGains( return IVAS_ERR_INVALID_OUTPUT_FORMAT; } /* Check error here to keep switch statement more compact */ - IF ( error != IVAS_ERR_OK ) + IF( error != IVAS_ERR_OK ) { return error; } /* Copy LFE routing to pan gains array */ - IF (EQ_16( inputMc->base.inConfig , IVAS_AUDIO_CONFIG_LS_CUSTOM )) + IF( EQ_16( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) { - FOR ( i = 0; i < inputMc->customLsInput.num_lfe; ++i ) + FOR( i = 0; i < inputMc->customLsInput.num_lfe; ++i ) { - mvr2r_Word32( inputMc->lfeRouting.lfePanMtx_fx[i], inputMc->panGains_fx[inputMc->customLsInput.lfe_idx[i]], IVAS_MAX_OUTPUT_CHANNELS ); + Copy32( inputMc->lfeRouting.lfePanMtx_fx[i], inputMc->panGains_fx[inputMc->customLsInput.lfe_idx[i]], IVAS_MAX_OUTPUT_CHANNELS ); } } ELSE { /* For code simplicity, always copy LFE gains. If config has no LFE, gains will be zero anyway. */ - mvr2r_Word32( inputMc->lfeRouting.lfePanMtx_fx[0], inputMc->panGains_fx[LFE_CHANNEL], IVAS_MAX_OUTPUT_CHANNELS ); + Copy32( inputMc->lfeRouting.lfePanMtx_fx[0], inputMc->panGains_fx[LFE_CHANNEL], IVAS_MAX_OUTPUT_CHANNELS ); } return IVAS_ERR_OK; @@ -3731,14 +3808,15 @@ static lfe_routing defaultLfeRouting( /* Set all output gains to zero, then route each input LFE consecutively to the next available output LFE. */ - FOR ( i = 0; i < RENDERER_MAX_INPUT_LFE_CHANNELS; ++i ) + FOR( i = 0; i < RENDERER_MAX_INPUT_LFE_CHANNELS; ++i ) { set_val_Word32( routing.lfePanMtx_fx[i], 0, IVAS_MAX_OUTPUT_CHANNELS ); } routing.pan_lfe = false; routing.lfeInputGain_fx = ONE_IN_Q31; + move32(); - SWITCH ( inConfig ) + SWITCH( inConfig ) { case IVAS_AUDIO_CONFIG_5_1: case IVAS_AUDIO_CONFIG_5_1_2: @@ -3757,7 +3835,7 @@ static lfe_routing defaultLfeRouting( move16(); } - SWITCH ( outConfig ) + SWITCH( outConfig ) { case IVAS_AUDIO_CONFIG_5_1: case IVAS_AUDIO_CONFIG_5_1_2: @@ -3768,7 +3846,7 @@ static lfe_routing defaultLfeRouting( move32(); BREAK; case IVAS_AUDIO_CONFIG_LS_CUSTOM: - FOR ( i = 0; i < routing.numLfeChannels && i < customLsOut.num_lfe; ++i ) + FOR( i = 0; i < routing.numLfeChannels && i < customLsOut.num_lfe; ++i ) { routing.lfePanMtx_fx[i][customLsOut.lfe_idx[i]] = ONE_IN_Q31; move32(); @@ -4922,6 +5000,38 @@ static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( } #endif + +#ifdef IVAS_FLOAT_FIXED +static ivas_error validateCustomLsLayout_fx( + const IVAS_CUSTOM_LS_DATA layout ) +{ + Word16 i; + + /* Negative number of speakers or LFEs makes no sense */ + test(); + IF( LT_16( layout.num_spk, 0 ) || LT_16( layout.num_lfe, 0 ) ) + { + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } + + /* There must be at least one speaker or LFE in the layout */ + IF( LE_16( add( layout.num_spk, layout.num_lfe ), 0 ) ) + { + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } + + /* LFE indices must be positive */ + FOR( i = 0; i < layout.num_lfe; ++i ) + { + IF( LT_16( layout.lfe_idx[i], 0 ) ) + { + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } + } + + return IVAS_ERR_OK; +} +#else static ivas_error validateCustomLsLayout( const IVAS_CUSTOM_LS_DATA layout ) { @@ -4950,6 +5060,7 @@ static ivas_error validateCustomLsLayout( return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -4979,10 +5090,17 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( return IVAS_ERR_INVALID_OUTPUT_FORMAT; } +#ifdef IVAS_FLOAT_FIXED + IF( ( error = validateCustomLsLayout_fx( layout ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) { return error; } +#endif hIvasRend->customLsOut = makeCustomLsSetup( layout ); @@ -5057,6 +5175,7 @@ ivas_error IVAS_REND_NumOutChannels( ivas_error error; /* Validate function arguments */ + test(); IF( hIvasRend == NULL || numOutChannels == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -5066,7 +5185,7 @@ ivas_error IVAS_REND_NumOutChannels( SWITCH( hIvasRend->outputConfig ) { case IVAS_AUDIO_CONFIG_LS_CUSTOM: - *numOutChannels = hIvasRend->customLsOut.num_spk + hIvasRend->customLsOut.num_lfe; + *numOutChannels = add( hIvasRend->customLsOut.num_spk, hIvasRend->customLsOut.num_lfe ); BREAK; default: IF( ( error = getAudioConfigNumChannels( hIvasRend->outputConfig, numOutChannels ) ) != IVAS_ERR_OK ) @@ -5115,6 +5234,18 @@ ivas_error IVAS_REND_NumOutChannels( } #endif + +#ifdef IVAS_FLOAT_FIXED +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const Word32 inputIndex ) +{ + /* Put config type in second byte (from LSB), put index + 1 in first byte + * + * Index is incremented here so that a valid ID can never be 0. */ + return (IVAS_REND_InputId) UL_or( UL_lshl( ( (UWord32) getAudioConfigType( config ) ), 8 ), L_add( inputIndex, 1 ) ); +} +#else static IVAS_REND_InputId makeInputId( AUDIO_CONFIG config, const int32_t inputIndex ) @@ -5124,8 +5255,75 @@ static IVAS_REND_InputId makeInputId( * Index is incremented here so that a valid ID can never be 0. */ return (IVAS_REND_InputId) ( ( ( (uint32_t) getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); } +#endif + + +#ifdef IVAS_FLOAT_FIXED +static ivas_error getInputById( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + void **ppInput ) +{ + Word32 inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = L_sub( L_and( inputId, 0xFF ), 1 ); + configType = L_shr( L_and( inputId, 0xFF00 ), 8 ); + /* Validate values derived from input ID */ + IF( LT_32( inputIndex, 0 ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + SWITCH( configType ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + IF( GT_32( inputIndex, RENDERER_MAX_ISM_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsIsm[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + IF( GT_32( inputIndex, RENDERER_MAX_MC_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMc[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + IF( GT_32( inputIndex, RENDERER_MAX_SBA_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSba[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + IF( GT_32( inputIndex, RENDERER_MAX_MASA_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMasa[inputIndex].base; + BREAK; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + test(); + IF( NE_32( pInputBase->id, inputId ) || EQ_32( pInputBase->inConfig, IVAS_AUDIO_CONFIG_INVALID ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + return IVAS_ERR_OK; +} +#else static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId inputId, @@ -5189,8 +5387,75 @@ static ivas_error getInputById( return IVAS_ERR_OK; } +#endif +#ifdef IVAS_FLOAT_FIXED +static ivas_error getConstInputById( + IVAS_REND_CONST_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + const void **ppInput ) +{ + Word32 inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = L_sub( L_and( inputId, 0xFF ), 1 ); + configType = L_shr( L_and( inputId, 0xFF00 ), 8 ); + + /* Validate values derived from input ID */ + IF( LT_32( inputIndex, 0 ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + SWITCH( configType ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + IF( GT_32( inputIndex, RENDERER_MAX_ISM_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsIsm[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + IF( GT_32( inputIndex, RENDERER_MAX_MC_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMc[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + IF( GT_32( inputIndex, RENDERER_MAX_SBA_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSba[inputIndex].base; + BREAK; + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + IF( GT_32( inputIndex, RENDERER_MAX_MASA_INPUTS ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMasa[inputIndex].base; + BREAK; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + test(); + IF( NE_32( pInputBase->id, inputId ) || EQ_32( pInputBase->inConfig, IVAS_AUDIO_CONFIG_INVALID ) ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} +#else static ivas_error getConstInputById( IVAS_REND_CONST_HANDLE hIvasRend, const IVAS_REND_InputId inputId, @@ -5254,6 +5519,7 @@ static ivas_error getConstInputById( return IVAS_ERR_OK; } +#endif static ivas_error findFreeInputSlot( @@ -5393,10 +5659,17 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef IVAS_FLOAT_FIXED + IF( ( error = validateCustomLsLayout_fx( layout ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputMc ) ) != IVAS_ERR_OK ) { @@ -5942,6 +6215,41 @@ ivas_error IVAS_REND_FeedInputAudio( * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error IVAS_REND_FeedInputObjectMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_ISM_METADATA objectPosition /* i : object position struct */ +) +{ + input_base *inputBase; + input_ism *inputIsm; + ivas_error error; + + /* Validate function arguments */ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( NE_32( inputBase->inConfig, IVAS_AUDIO_CONFIG_OBA ) ) + { + /* Object metadata should only be fed for object inputs */ + return IVAS_ERR_METADATA_NOT_EXPECTED; + } + + inputIsm = (input_ism *) inputBase; + inputIsm->previousPos = inputIsm->currentPos; + inputIsm->currentPos = objectPosition; + + return IVAS_ERR_OK; +} +#else ivas_error IVAS_REND_FeedInputObjectMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_REND_InputId inputId, /* i : ID of the input */ @@ -5975,6 +6283,7 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -6009,6 +6318,41 @@ ivas_error IVAS_REND_FeedInputObjectMetadataToOMasa( * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error IVAS_REND_FeedInputMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_MASA_METADATA_HANDLE masaMetadata /* i : MASA metadata frame */ +) +{ + ivas_error error; + input_base *inputBase; + input_masa *inputMasa; + + /* Validate function arguments */ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( NE_32( getAudioConfigType( inputBase->inConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) ) + { + /* MASA metadata should only be fed for MASA inputs */ + return IVAS_ERR_METADATA_NOT_EXPECTED; + } + + inputMasa = (input_masa *) inputBase; + inputMasa->masaMetadata = *masaMetadata; + inputMasa->metadataHasBeenFed = true; + + return IVAS_ERR_OK; +} +#else ivas_error IVAS_REND_FeedInputMasaMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_REND_InputId inputId, /* i : ID of the input */ @@ -6042,6 +6386,7 @@ ivas_error IVAS_REND_FeedInputMasaMetadata( return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -6297,19 +6642,23 @@ ivas_error IVAS_REND_DisableHeadRotation( * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED ivas_error IVAS_REND_SetOrientationTrackingMode( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : Head orientation tracking type */ ) { -#ifdef IVAS_FLOAT_FIXED - ivas_error ret; - ret = ivas_orient_trk_SetTrackingType_fx( hIvasRend->headRotData.hOrientationTracker, orientation_tracking ); - return ret; + return ivas_orient_trk_SetTrackingType_fx( hIvasRend->headRotData.hOrientationTracker, orientation_tracking ); +} #else +ivas_error IVAS_REND_SetOrientationTrackingMode( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : Head orientation tracking type */ +) +{ return ivas_orient_trk_SetTrackingType( hIvasRend->headRotData.hOrientationTracker, orientation_tracking ); -#endif } +#endif /*-------------------------------------------------------------------* @@ -6366,7 +6715,8 @@ ivas_error IVAS_REND_SetReferenceRotation( * * *-------------------------------------------------------------------*/ -// ToDo: not used + +#ifndef IVAS_FLOAT_FIXED ivas_error IVAS_REND_GetMainOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer for main orientation */ @@ -6379,40 +6729,14 @@ ivas_error IVAS_REND_GetMainOrientation( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef IVAS_FLOAT_FIXED - Word16 q_fact = hIvasRend->headRotData.hOrientationTracker->refRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->refRot.x_qfact = - hIvasRend->headRotData.hOrientationTracker->refRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->refRot.z_qfact = Q29; - hIvasRend->headRotData.hOrientationTracker->refRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.w, q_fact ); - hIvasRend->headRotData.hOrientationTracker->refRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.x, q_fact ); - hIvasRend->headRotData.hOrientationTracker->refRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.y, q_fact ); - hIvasRend->headRotData.hOrientationTracker->refRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.z, q_fact ); - - - hIvasRend->headRotData.hOrientationTracker->absAvgRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.w, Q29 ); - hIvasRend->headRotData.hOrientationTracker->absAvgRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.x, Q29 ); - hIvasRend->headRotData.hOrientationTracker->absAvgRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.y, Q29 ); - hIvasRend->headRotData.hOrientationTracker->absAvgRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.z, Q29 ); - hIvasRend->headRotData.hOrientationTracker->absAvgRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->absAvgRot.x_qfact = - hIvasRend->headRotData.hOrientationTracker->absAvgRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->absAvgRot.z_qfact = Q29; - - error = ivas_orient_trk_GetMainOrientation_fx( hIvasRend->headRotData.hOrientationTracker, pOrientation ); - pOrientation->w = fix_to_float( pOrientation->w_fx, pOrientation->w_qfact ); - pOrientation->x = fix_to_float( pOrientation->x_fx, pOrientation->x_qfact ); - pOrientation->y = fix_to_float( pOrientation->y_fx, pOrientation->y_qfact ); - pOrientation->z = fix_to_float( pOrientation->z_fx, pOrientation->z_qfact ); - IF( error != IVAS_ERR_OK ) - { - return error; - } -#else if ( ( error = ivas_orient_trk_GetMainOrientation( hIvasRend->headRotData.hOrientationTracker, pOrientation ) ) != IVAS_ERR_OK ) { return error; } -#endif return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -6420,7 +6744,8 @@ ivas_error IVAS_REND_GetMainOrientation( * * *-------------------------------------------------------------------*/ -// ToDo: not used + +#ifndef IVAS_FLOAT_FIXED ivas_error IVAS_REND_GetTrackedRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *pRotation /* i/o: Quaternion pointer processed rotation */ @@ -6433,31 +6758,14 @@ ivas_error IVAS_REND_GetTrackedRotation( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef IVAS_FLOAT_FIXED - hIvasRend->headRotData.hOrientationTracker->trkRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.w, Q29 ); - hIvasRend->headRotData.hOrientationTracker->trkRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.x, Q29 ); - hIvasRend->headRotData.hOrientationTracker->trkRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.y, Q29 ); - hIvasRend->headRotData.hOrientationTracker->trkRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.z, Q29 ); - hIvasRend->headRotData.hOrientationTracker->trkRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->trkRot.x_qfact = - hIvasRend->headRotData.hOrientationTracker->trkRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->trkRot.z_qfact = Q29; - error = ivas_orient_trk_GetTrackedRotation_fx( hIvasRend->headRotData.hOrientationTracker, pRotation ); - pRotation->w = fix_to_float( pRotation->w_fx, pRotation->w_qfact ); - pRotation->x = fix_to_float( pRotation->x_fx, pRotation->x_qfact ); - pRotation->y = fix_to_float( pRotation->y_fx, pRotation->y_qfact ); - pRotation->z = fix_to_float( pRotation->z_fx, pRotation->z_qfact ); - IF( error != IVAS_ERR_OK ) - { - return error; - } -#else if ( ( error = ivas_orient_trk_GetTrackedRotation( hIvasRend->headRotData.hOrientationTracker, pRotation ) ) != IVAS_ERR_OK ) { return error; } -#endif return IVAS_ERR_OK; } +#endif /*---------------------------------------------------------------------* @@ -6546,7 +6854,8 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation( * * *---------------------------------------------------------------------*/ -// ToDo: not used + +#ifndef IVAS_FLOAT_FIXED ivas_error IVAS_REND_GetCombinedOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ @@ -6569,6 +6878,7 @@ ivas_error IVAS_REND_GetCombinedOrientation( return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* @@ -7352,6 +7662,14 @@ static ivas_error renderIsmToBinaural( } +#ifdef IVAS_FLOAT_FIXED +static Word16 getNumSubframesInBuffer( + const IVAS_REND_AudioBuffer *buffer, + const Word32 sampleRate ) +{ + return extract_l( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); +} +#else static int16_t getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const int32_t sampleRate ) @@ -7360,6 +7678,8 @@ static int16_t getNumSubframesInBuffer( return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); } +#endif + #ifdef IVAS_FLOAT_FIXED static ivas_error renderIsmToBinauralRoom( @@ -10024,6 +10344,39 @@ static ivas_error renderActiveInputsMasa( * Get metadata of the estimated MASA frame *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error IVAS_REND_GetMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to analyzed MASA metadata */ + const IVAS_REND_AudioConfigType inputType /* i : Input type */ +) +{ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* Get the metadata handle */ + IF( EQ_32( inputType, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) ) + { + *hMasaExtOutMeta = hIvasRend->inputsIsm->hOMasa->hMasaOut; + } + ELSE IF( EQ_32( inputType, IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ) + { + *hMasaExtOutMeta = hIvasRend->inputsMc->hMcMasa->hMasaOut; + } + ELSE IF( EQ_32( inputType, IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) + { + *hMasaExtOutMeta = hIvasRend->inputsSba->hDirAC->hMasaOut; + } + ELSE + { + return IVAS_ERR_NOT_SUPPORTED_OPTION; + } + + return IVAS_ERR_OK; +} +#else ivas_error IVAS_REND_GetMasaMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to analyzed MASA metadata */ @@ -10055,6 +10408,7 @@ ivas_error IVAS_REND_GetMasaMetadata( return IVAS_ERR_OK; } +#endif /*---------------------------------------------------------------------* @@ -10145,6 +10499,23 @@ ivas_error IVAS_REND_MergeMasaMetadata( * Set the total number of objects to the first object data *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error IVAS_REND_SetTotalNumberOfObjects( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const UWord16 total_num_objects /* i : total number of objects */ +) +{ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasRend->inputsIsm[0].total_num_objects = total_num_objects; + move16(); + + return IVAS_ERR_OK; +} +#else ivas_error IVAS_REND_SetTotalNumberOfObjects( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ const uint16_t total_num_objects /* i : total number of objects */ @@ -10159,6 +10530,7 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( return IVAS_ERR_OK; } +#endif /*---------------------------------------------------------------------* diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index a5fb7b313..4c9728612 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -325,10 +325,17 @@ ivas_error IVAS_REND_MergeMasaMetadata( const IVAS_REND_AudioConfigType inputType2 /* i : Input type 2 */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error IVAS_REND_SetTotalNumberOfObjects( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const UWord16 total_num_objects /* i : total number of objects */ +); +#else ivas_error IVAS_REND_SetTotalNumberOfObjects( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ const uint16_t total_num_objects /* i : total number of objects */ ); +#endif ivas_error IVAS_REND_SetIsmMetadataDelay( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ -- GitLab