diff --git a/lib_com/options.h b/lib_com/options.h index 598299d16be2487400788cbb8f308feabd723e21..8a530622ff171543bf0f7b7eba37f04c812d85cf 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -94,6 +94,7 @@ /* #################### Start NON-BE switches ############################ */ /* any switch which is non-be wrt. TS 26.251 V3.0 */ +#define FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN /* Eri: Basop issue 2469: TD renderer gain has wrong Q and does not support the object editing gain range */ #define FIX_BASOP_2486_HQ_FINE_GAIN_ALIGNMENT /* Eri: Basop issue 2486: IVAS BASOP used calculations with truncation, EVS BASOP used rounding. This aligns the use of a table lookup. */ #define FIX_1543_MID_LSF_BITS /* VA: float issue 1543: Resolve "MSAN: use-of-uninitialized-value in lib_enc/lsf_enc.c:262:5 for EVS encoder" */ #define FIX_2488_PREVENT_NEG_PITCH /* VA: Fix for 2488, use saturation to prevent possible wrap-around, thus negative pitch values */ diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index daa06bbf4ff3e02369be234e144727f7f12da5f2..19e0d450a0ded186a8996ed4319a3eb881842d65 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -665,7 +665,11 @@ ivas_error TDREND_Update_object_positions_fx( { return error; } +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + if ( ( error = TDREND_MIX_SRC_SetGain( hBinRendererTd, nS, hIsmMetaData[nS]->gain_fx ) ) != IVAS_ERR_OK ) +#else if ( ( error = TDREND_MIX_SRC_SetGain( hBinRendererTd, nS, hIsmMetaData[nS]->gain_fx ) ) != IVAS_ERR_OK ) // TODO: Check Gain has correct Q-value +#endif { return error; } diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index a6a26609fdae1653534eee140add32230892d862..3d7e42a7eb143cd6d75d6743b69f8b70acbf29d8 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -177,8 +177,14 @@ ivas_error TDREND_MIX_Init_fx( ) { ivas_error error; +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + hBinRendererTd->Gain_fx = ONE_IN_Q29; + move32(); +#else hBinRendererTd->Gain_fx = ONE_IN_Q14; move16(); +#endif + /* Init source list */ /* Spatial settings */ IF( MixSpatSpec_p != NULL ) diff --git a/lib_rend/ivas_objectRenderer_sfx_fx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c index 1c899f95ba696e8f9ed036b5b4169c2c57b6e4bc..3649d9c98b4801d05ac9e615bde4a0336704ae31 100644 --- a/lib_rend/ivas_objectRenderer_sfx_fx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -278,8 +278,14 @@ void TDREND_firfilt_fx( Word32 *mem_fx, /* i/o: filter memory Qx */ const Word16 subframe_length, /* i : Length of signal Q0 */ const Word16 filterlength, /* i : Filter length Q0 */ - const Word32 Gain_fx, /* i : Gain Q30 */ - const Word32 prevGain_fx /* i : Previous gain Q30 */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + const Word32 Gain_fx, /* i : Gain Q29 */ + const Word32 prevGain_fx /* i : Previous gain Q29 */ +#else + const Word32 Gain_fx, /* i : Gain Q30 */ + const Word32 prevGain_fx /* i : Previous gain Q30 */ +#endif + ) { /* NOTE: this function is implemented with the assumption that the exponent/Q-factor of input signal will not change. */ @@ -289,15 +295,30 @@ void TDREND_firfilt_fx( Word32 *p_filter_fx; // exp(filter_e) Word16 i, j; Word32 tmp_fx; +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 step_fx /* Q29 */, gain_tmp_fx /* Q29 */, gain_delta_fx /* Q29 */; +#else Word32 step_fx /* Q31 */, gain_tmp_fx /* Q31 */, gain_delta_fx /* Q30 */; +#endif Word16 tmp_e; Word64 tmp64_fx; Word16 shift = sub( filter_e, 32 ); - gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q30 +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q29 +#else + gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q30 +#endif step_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( gain_delta_fx, subframe_length, &tmp_e ) ); // exp(tmp_e) +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + tmp_e = sub( tmp_e, Q31 ); + step_fx = L_shl_sat( step_fx, tmp_e ); // Q29 + gain_tmp_fx = prevGain_fx; // Q29 + move32(); +#else tmp_e = sub( tmp_e, Q30 ); step_fx = L_shl_sat( step_fx, tmp_e ); // Q31 gain_tmp_fx = L_shl_sat( prevGain_fx, 1 ); // Q31 +#endif /* Handle memory */ p_signal_fx = buffer_fx + sub( filterlength, 1 ); // Qx @@ -325,8 +346,13 @@ void TDREND_firfilt_fx( tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx /* Apply linear gain interpolation in case of abrupt gain changes */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 4, Q29*/ + signal_fx[i] = L_shl( Mpy_32_32( tmp_fx, gain_tmp_fx ), 2 ); // Qx +#else gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx +#endif move32(); v_add_fx( filter_fx, filter_delta_fx, filter_fx, filterlength ); // exp(filter_e) } @@ -349,8 +375,13 @@ void TDREND_firfilt_fx( tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx /* Apply linear gain interpolation in case of abrupt gain changes */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 4, Q29*/ + signal_fx[i] = L_shl( Mpy_32_32( tmp_fx, gain_tmp_fx ), 2 ); // Qx +#else gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx +#endif move32(); } diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 222a5b0f88bdd907ba61038d88e190c87200bffa..7a278a8bb75086e823400585a42c2d01282259c0 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -139,7 +139,11 @@ ivas_error TDREND_MIX_SRC_SetDir_fx( ivas_error TDREND_MIX_SRC_SetGain( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ - const Word32 Gain /* i : Gain */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + const Word32 Gain /* i : Gain Q29 */ +#else + const Word32 Gain /* i : Gain */ +#endif ) { TDREND_SRC_SPATIAL_SetGain( hBinRendererTd->Sources[SrcInd], Gain ); @@ -270,12 +274,17 @@ static void TDREND_SRC_REND_Init_fx( /* SrcGain */ FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + SrcRend_p->SrcGain_p_fx[nC] = ONE_IN_Q29; /* Q29 */ + move32(); +#else SrcRend_p->SrcGainMin_p_fx[nC] = 0; /* Q15 */ move16(); SrcRend_p->SrcGain_p_fx[nC] = ONE_IN_Q14; // Q14 move16(); SrcRend_p->SrcGainMax_p_fx[nC] = 32767; // TODO: make it 2, this is one in Q15, i thinki, need to change Q for that move16(); +#endif } SrcRend_p->SrcGainUpdated = FALSE; move16(); @@ -312,8 +321,12 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word16 *intp_count, /* o : Interpolation count Q0 */ Word16 *filterlength, /* o : Length of filters Q0 */ Word16 *itd, /* o : ITD value Q0 */ - Word32 *Gain, /* o : Gain value Q30 */ - TDREND_SRC_t *Src_p /* i/o: Source pointer */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 *Gain, /* o : Gain value Q29 */ +#else + Word32 *Gain, /* o : Gain value Q30 */ +#endif + TDREND_SRC_t *Src_p /* i/o: Source pointer */ ) { TDREND_MIX_Listener_t *Listener_p; @@ -403,7 +416,16 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( } /* Update total gains */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + { + Word32 tmp1, tmp2; + tmp1 = L_shl( Mpy_32_16( extract_h( *SrcRend_p->SrcGain_p_fx ), extract_l( *SrcRend_p->SrcGain_p_fx ), *SrcRend_p->DirGain_p_fx ), 1 ); /* Q29 */ + tmp2 = L_shl( Mpy_32_16( extract_h( hBinRendererTd->Gain_fx ), extract_l( hBinRendererTd->Gain_fx ), *SrcRend_p->DistGain_p_fx ), 1 ); /* Q29 */ + *Gain = L_shl( Mpy_32_32( tmp1, tmp2 ), 2 ); /* Q29 */ + } +#else *Gain = L_shl( Mpy_32_32( L_shl( L_mult( *SrcRend_p->SrcGain_p_fx, *SrcRend_p->DirGain_p_fx ), 1 ), L_shl( L_mult( *SrcRend_p->DistGain_p_fx, hBinRendererTd->Gain_fx ), 1 ) ), 1 ); // Q30 +#endif move32(); /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP=0.01f */ @@ -453,7 +475,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( { *itd = 0; // Q0 move16(); +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + *Gain = ONE_IN_Q29; /* Q29 */ +#else *Gain = ONE_IN_Q30; // Q30 +#endif move32(); set32_fx( hrf_left, 0, *filterlength ); set32_fx( hrf_right, 0, *filterlength ); @@ -692,11 +718,21 @@ static void TDREND_SRC_SPATIAL_SetDistAtten( --------------------------------------------------------------------*/ static void TDREND_SRC_SPATIAL_SetGain( +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + const TDREND_SRC_t *Src_p, /* i : Source */ + const Word32 Gain /* i : Gain Q29 */ +#else const TDREND_SRC_t *Src_p, /* i : Directional attenuation specification */ const Word32 Gain /* i : Front-pointing vector */ +#endif ) { +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Src_p->SrcRend_p->SrcGain_p_fx[0] = Gain; /* Q29 */ + move32(); +#else Src_p->SrcRend_p->SrcGain_p_fx[0] = shl_sat( extract_h( Gain ), Q1 ); // TODO: Check incoming Q-value and fix this +#endif return; } @@ -978,10 +1014,17 @@ void TDREND_SRC_Init_fx( move32(); Src_p->elev_prev_fx = 0; // Q22 move32(); +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Src_p->Gain_fx = ONE_IN_Q29; // Q29 + move32(); + Src_p->prevGain_fx = ONE_IN_Q29; // Q29 + move32(); +#else Src_p->Gain_fx = ONE_IN_Q30; // Q30 move32(); Src_p->prevGain_fx = ONE_IN_Q30; // Q30 move32(); +#endif return; } diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 92caf486ff2239c99454a54b6bf9ee480db9c3bf..017d662374604951be578ec05c26e41ade3ca003 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -817,7 +817,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word16 *intp_count, /* o : Interpolation count */ Word16 *filterlength, /* o : Length of filters */ Word16 *itd, /* o : ITD value */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 *Gain, /* o : Gain value Q29 */ +#else Word32 *Gain, /* o : Gain value Q30 */ +#endif TDREND_SRC_t *Src_p /* i/o: Source pointer */ ); @@ -897,8 +901,13 @@ void TDREND_firfilt_fx( Word32 *mem_fx, /* i/o: filter memory Qx */ const Word16 subframe_length, /* i : Length of signal */ const Word16 filterlength, /* i : Filter length */ +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + const Word32 Gain_fx, /* i : Gain Q29 */ + const Word32 prevGain_fx /* i : Previous gain Q29 */ +#else const Word32 Gain_fx, /* i : Gain Q30 */ const Word32 prevGain_fx /* i : Previous gain Q30 */ +#endif ); diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 00a5ba8057779d112c4cf58beaf2016a4d6e82c9..ea5fbcd4ec65ee6fa1e0e2568a28a5fda26a4595 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1208,9 +1208,13 @@ typedef struct TDREND_SRC_REND_s /* Gains */ Word16 SrcGainUpdated; +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 SrcGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; /* Q29 */ +#else Word16 SrcGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; // Q14 Word16 SrcGainMin_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; Word16 SrcGainMax_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; +#endif Word16 DirGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; // Q14 Word16 DistGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; // Q14 } TDREND_SRC_REND_t; @@ -1247,8 +1251,13 @@ typedef struct Word16 hrf_right_prev_e; Word32 azim_prev_fx; Word32 elev_prev_fx; +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 Gain_fx; // Q29 + Word32 prevGain_fx; // Q29 +#else Word32 Gain_fx; // Q30 Word32 prevGain_fx; // Q30 +#endif } TDREND_SRC_t; @@ -1261,7 +1270,11 @@ typedef struct ivas_binaural_td_rendering_struct Word16 MaxSrcInd; TDREND_SRC_t *Sources[MAX_NUM_TDREND_CHANNELS]; +#ifdef FIX_BASOP_2469_OBJ_EDIT_TD_REND_GAIN + Word32 Gain_fx; /* Q29 */ +#else Word16 Gain_fx; /* Q14 */ +#endif TDREND_MIX_Listener_t *Listener_p; /* The virtual listener */ TDREND_HRFILT_FiltSet_t *HrFiltSet_p; /* HR filter set */