diff --git a/lib_com/options.h b/lib_com/options.h index 97eafb65e8821b99bb135823ee0021f03646cf6f..37865063a6fa3796f923ed70d0dfb921841c8061 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -102,6 +102,7 @@ #define FIX_955_FASTCONV_REND_IN_ISM /* VA: put FastConv rendering call under DEBUGGING */ #define FIX_956_DECODER_COMMAND_LINE_FIX /* VA: Output correct error message when the decoder command-line has too many mandatory arguments. */ +#define NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX /* FhG : issue #968: differences between 5ms and 20ms rendering for discrete ISM with BRIR and head rotation*/ /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 888bfb060e9d3fe31c04eb5fcdf26b910bbd8007..7f4f32731abc0f08e8e17b5882e507c7cf88da65 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -149,6 +149,7 @@ void ivas_ism_renderer_close( return; } + /*-------------------------------------------------------------------------* * ivas_ism_render_sf() * @@ -170,6 +171,25 @@ void ivas_ism_render_sf_fx( Word32 gain_fx, prev_gain_fx; Word32 tc_local_fx[MAX_NUM_OBJECTS][L_FRAME48k]; Word32 *p_tc_fx[MAX_NUM_OBJECTS]; +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + Word16 ism_md_subframe_update_jbm, slots_to_render, first_sf, last_sf, subframe_idx; + Word16 n_samples_rendered_loop; + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = s_min( sub( st_ivas->hTcBuffer->num_slots, st_ivas->hTcBuffer->slots_rendered ), n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + move16(); + last_sf = first_sf; + move16(); + n_samples_rendered_loop = 0; + move16(); + + WHILE( slots_to_render > 0 ) + { + slots_to_render = sub( slots_to_render, st_ivas->hTcBuffer->subframe_nbslots[last_sf] ); + last_sf = add( last_sf, 1 ); + } +#endif num_objects = st_ivas->nchan_transport; move16(); @@ -187,6 +207,18 @@ void ivas_ism_render_sf_fx( interp_offset = st_ivas->hTcBuffer->n_samples_rendered; move16(); +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + /* Number of subframes to delay metadata to sync with audio */ + IF( st_ivas->hDecoderConfig->Opt_delay_comp ) + { + ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 3 ) ); + } + ELSE + { + ism_md_subframe_update_jbm = sub( st_ivas->hTcBuffer->nb_subframes, 2 ); + } +#endif + IF( st_ivas->hDecoderConfig->Opt_tsm ) { FOR( i = 0; i < num_objects; i++ ) @@ -208,76 +240,126 @@ void ivas_ism_render_sf_fx( set32_fx( output_fx[i], 0, n_samples_to_render ); } - test(); - IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) ) - { - ivas_jbm_dec_get_adapted_linear_interpolator_fx( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator_fx ); - interp_offset = 0; - move16(); - } - FOR( i = 0; i < num_objects; i++ ) +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { - /* Combined rotation: rotate the object positions depending the head and external orientations */ + int16_t n_samples_in_subframe; + + n_samples_in_subframe = st_ivas->hTcBuffer->n_samples_granularity * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; +#endif test(); - IF( st_ivas->hCombinedOrientationData != NULL && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) ) + IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) ) { - rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup ); - - IF( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], L_shl( azimuth, 22 ), L_shl( elevation, 22 ), EFAP_MODE_EFAP ); - } +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + ivas_jbm_dec_get_adapted_linear_interpolator_fx( n_samples_in_subframe, n_samples_in_subframe, st_ivas->hIsmRendererData->interpolator_fx ); +#else + ivas_jbm_dec_get_adapted_linear_interpolator_fx( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator_fx ); +#endif + interp_offset = 0; + move16(); } - lfe_index = 0; - move16(); - FOR( ( j = 0, j2 = 0 ); j < nchan_out_woLFE; ( j++, j2++ ) ) + FOR( i = 0; i < num_objects; i++ ) { + /* Combined rotation: rotate the object positions depending the head and external orientations */ test(); - IF( ( st_ivas->hIntSetup.num_lfe > 0 ) && EQ_16( st_ivas->hIntSetup.index_lfe[lfe_index], j ) ) + IF( st_ivas->hCombinedOrientationData != NULL && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) ) { - IF( LT_16( lfe_index, sub( st_ivas->hIntSetup.num_lfe, 1 ) ) ) +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + if ( GE_16( subframe_idx, ism_md_subframe_update_jbm ) ) { - lfe_index = add( lfe_index, 1 ); - j2 = add( j2, 1 ); + rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); } - ELSE + else { - j2 = add( j2, 1 ); + rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->last_azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->last_elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); } - } - - gain_fx = st_ivas->hIsmRendererData->gains_fx[i][j]; - move32(); - prev_gain_fx = st_ivas->hIsmRendererData->prev_gains_fx[i][j]; - move32(); +#else + rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup ); +#endif - test(); - IF( ( L_abs( gain_fx ) > 0 ) || ( L_abs( prev_gain_fx ) > 0 ) ) - { - g1_fx = &st_ivas->hIsmRendererData->interpolator_fx[interp_offset]; - tc_fx = p_tc_fx[i]; - FOR( k = 0; k < n_samples_to_render; k++ ) + IF( st_ivas->hEFAPdata != NULL ) { - g2_fx = sub( 32767, *g1_fx ); // 32767 = (1.0f in Q15) - 1 - output_fx[j2][k] = L_add( output_fx[j2][k], L_shl( Mpy_32_32( L_add( Mpy_32_16_1( gain_fx, *( g1_fx++ ) ), Mpy_32_16_1( prev_gain_fx, g2_fx ) ), *( tc_fx++ ) ), 1 ) ); // Q11( (30+15+1-16) + 11 -31 +1) - move16(); + efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], L_shl( azimuth, 22 ), L_shl( elevation, 22 ), EFAP_MODE_EFAP ); } } - /* update here only in case of head rotation */ - test(); - IF( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + lfe_index = 0; + move16(); + FOR( ( j = 0, j2 = 0 ); j < nchan_out_woLFE; ( j++, j2++ ) ) { - st_ivas->hIsmRendererData->prev_gains_fx[i][j] = gain_fx; // Q30 + test(); + IF( ( st_ivas->hIntSetup.num_lfe > 0 ) && EQ_16( st_ivas->hIntSetup.index_lfe[lfe_index], j ) ) + { + IF( LT_16( lfe_index, sub( st_ivas->hIntSetup.num_lfe, 1 ) ) ) + { + lfe_index = add( lfe_index, 1 ); + j2 = add( j2, 1 ); + } + ELSE + { + j2 = add( j2, 1 ); + } + } + + gain_fx = st_ivas->hIsmRendererData->gains_fx[i][j]; move32(); + prev_gain_fx = st_ivas->hIsmRendererData->prev_gains_fx[i][j]; + move32(); + + test(); + IF( ( L_abs( gain_fx ) > 0 ) || ( L_abs( prev_gain_fx ) > 0 ) ) + { + g1_fx = &st_ivas->hIsmRendererData->interpolator_fx[interp_offset]; + tc_fx = p_tc_fx[i]; +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + FOR( k = 0; k < n_samples_in_subframe; k++ ) +#else + FOR( k = 0; k < n_samples_to_render; k++ ) +#endif + { + g2_fx = sub( 32767, *g1_fx ); // 32767 = (1.0f in Q15) - 1 +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + output_fx[j2][k + n_samples_rendered_loop] = L_add( output_fx[j2][k + n_samples_rendered_loop], L_shl( Mpy_32_32( L_add( Mpy_32_16_1( gain_fx, *( g1_fx++ ) ), Mpy_32_16_1( prev_gain_fx, g2_fx ) ), *( tc_fx++ ) ), 1 ) ); // Q11( (30+15+1-16) + 11 -31 +1) +#else + output_fx[j2][k] = L_add( output_fx[j2][k], L_shl( Mpy_32_32( L_add( Mpy_32_16_1( gain_fx, *( g1_fx++ ) ), Mpy_32_16_1( prev_gain_fx, g2_fx ) ), *( tc_fx++ ) ), 1 ) ); // Q11( (30+15+1-16) + 11 -31 +1) +#endif + move16(); + } + } + + /* update here only in case of head rotation */ + test(); + IF( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + { + st_ivas->hIsmRendererData->prev_gains_fx[i][j] = gain_fx; // Q30 + move32(); + } } +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + p_tc_fx[i] += n_samples_in_subframe; +#endif } - } - /* update combined orientation access index */ + /* update combined orientation access index */ +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_in_subframe ); +#else ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); +#endif + +#ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX + n_samples_rendered_loop = add( n_samples_rendered_loop, n_samples_in_subframe ); + IF( EQ_16( st_ivas->renderer_type, RENDERER_TD_PANNING ) ) + { + st_ivas->hTcBuffer->subframes_rendered = add( st_ivas->hTcBuffer->subframes_rendered, 1 ); + st_ivas->hTcBuffer->slots_rendered = add( st_ivas->hTcBuffer->slots_rendered, st_ivas->hTcBuffer->subframe_nbslots[subframe_idx] ); + } + tc_offset = add( tc_offset, n_samples_in_subframe ); + interp_offset = add( interp_offset, n_samples_in_subframe ); + } +#endif return; }