From 3bfabca264c842971fd416c2d01844a04624e89c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 15:57:00 +0200 Subject: [PATCH 1/5] port MR 1333 from float repo still has todos and needs review --- lib_com/options.h | 1 + lib_dec/ivas_ism_renderer_fx.c | 177 ++++++++++++++++++++++++--------- 2 files changed, 132 insertions(+), 46 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 97eafb65e..37865063a 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 888bfb060..f89b10f4a 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,26 @@ 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 slots_to_render; + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + // TODO: division + slots_to_render = 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(); + + // TODO: comparison correct? Or do I need an operator? + 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 +208,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 = 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 +241,128 @@ 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_idxm 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 + // TODO: add on array index: does this need a BASOP? + output_fx[j2][k + n_samples_rendered_loop] = 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) +#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 + // TODO: pointer arithmetic - does this need a BASOP? + 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 += n_samples_in_subframe; + if ( st_ivas->renderer_type == RENDERER_TD_PANNING ) + { + st_ivas->hTcBuffer->subframes_rendered += 1; + st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; + } + tc_offset += n_samples_in_subframe; + interp_offset += n_samples_in_subframe; + } +#endif return; } -- GitLab From 7468f5093c6804bc64111d2f622cffb54a5b9e36 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 16:10:26 +0200 Subject: [PATCH 2/5] remove todo comments after checking they don't apply --- lib_dec/ivas_ism_renderer_fx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index f89b10f4a..61e0cb41c 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -175,7 +175,6 @@ void ivas_ism_render_sf_fx( Word16 slots_to_render; /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ - // TODO: division slots_to_render = 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(); @@ -184,7 +183,6 @@ void ivas_ism_render_sf_fx( n_samples_rendered_loop = 0; move16(); - // TODO: comparison correct? Or do I need an operator? WHILE( slots_to_render > 0 ) { slots_to_render = sub( slots_to_render, st_ivas->hTcBuffer->subframe_nbslots[last_sf] ); @@ -322,7 +320,6 @@ void ivas_ism_render_sf_fx( { g2_fx = sub( 32767, *g1_fx ); // 32767 = (1.0f in Q15) - 1 #ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX - // TODO: add on array index: does this need a BASOP? output_fx[j2][k + n_samples_rendered_loop] = 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) #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) @@ -340,7 +337,6 @@ void ivas_ism_render_sf_fx( } } #ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX - // TODO: pointer arithmetic - does this need a BASOP? p_tc_fx[i] += n_samples_in_subframe; #endif } -- GitLab From e4ef3b9c10ed74c85797c88429919ddb070b64d9 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 16:15:36 +0200 Subject: [PATCH 3/5] fix build --- lib_dec/ivas_ism_renderer_fx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 61e0cb41c..e5241f9c3 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -172,10 +172,11 @@ void ivas_ism_render_sf_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 slots_to_render; + 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 = MIN( sub( st_ivas->hTcBuffer->num_slots, st_ivas->hTcBuffer->slots_rendered ), n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity ); + 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; @@ -210,7 +211,7 @@ void ivas_ism_render_sf_fx( /* Number of subframes to delay metadata to sync with audio */ IF( st_ivas->hDecoderConfig->Opt_delay_comp ) { - ism_md_subframe_update_jbm = MAX( 0, sub( st_ivas->hTcBuffer->nb_subframes, 3 ) ); + ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 3 ) ); } ELSE { @@ -266,7 +267,7 @@ void ivas_ism_render_sf_fx( IF( st_ivas->hCombinedOrientationData != NULL && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) ) { #ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX - if ( GE_16( subframe_idxm ism_md_subframe_update_jbm ) ) + if ( GE_16( subframe_idx, ism_md_subframe_update_jbm ) ) { 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 ); } -- GitLab From 272f551f541cef3ba823f60a32ac7dc6736c228d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 16:58:50 +0200 Subject: [PATCH 4/5] add a feq forgotten BASOPs --- lib_dec/ivas_ism_renderer_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index e5241f9c3..0b4a624e3 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -242,7 +242,7 @@ void ivas_ism_render_sf_fx( #ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX - for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_in_subframe; @@ -350,14 +350,14 @@ void ivas_ism_render_sf_fx( #endif #ifdef NONBE_FIX_968_ISM_BRIR_WITH_HEADROTATION_5MS_FIX - n_samples_rendered_loop += n_samples_in_subframe; - if ( st_ivas->renderer_type == RENDERER_TD_PANNING ) + 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 += 1; - st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; + 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 += n_samples_in_subframe; - interp_offset += n_samples_in_subframe; + tc_offset = add( tc_offset, n_samples_in_subframe ); + interp_offset = add( interp_offset, n_samples_in_subframe ); } #endif -- GitLab From bfd78dde13bf730283a7dac993a97a319a25dc8e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 5 May 2025 19:40:01 +0200 Subject: [PATCH 5/5] fix indexing error --- lib_dec/ivas_ism_renderer_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 0b4a624e3..7f4f32731 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -321,7 +321,7 @@ void ivas_ism_render_sf_fx( { 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], 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) + 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 -- GitLab