diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 3805c9d363571d649a8d9912fef768669012b217..361215e221087eb26272647ecb88781b4ff73081 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -4017,7 +4017,12 @@ void ivas_compute_spar_params_fx( Word32 diff_norm_order1_table[4] = { 0, 805306368, 402653184, 268435456 }; // q28 Word32 diff_norm_order2_table[6] = { 0, 1342177280, 671088640, 447392416, 335544320, 268435456 }; // q28 Word32 diff_norm_order3_table[8] = { 0, 1879048192, 939524096, 626349376, 469762048, 375809632, 313174688, 268435456 }; // q28 -#define EPSILON_FX_THR 70 +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT +#define EPSILON_FX_SHIFT 6 +#define EPSILON_FX_THR ( 1 << EPSILON_FX_SHIFT ) +#else +#define EPSILON_FX_THR 70 +#endif #define ONE_BY_THREE_Q31 715827882 #define ONE_BY_FIVE_Q31 429496729 #define ONE_BY_SEVEN_Q31 306783378 @@ -4257,10 +4262,20 @@ void ivas_get_spar_md_from_dirac_enc_fx( { Word32 norm_fx; Word16 norm_q; + +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + Word16 num_ch_order, norm_t; + Word32 tmp_norm_out; +#else Word16 num_ch_order, hoa2_ch_order; +#endif num_ch_order = ivas_sba_get_nchan_fx( order, 0 ); +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT hoa2_ch_order = ivas_sba_get_nchan_fx( SBA_HOA2_ORDER, 0 ); +#else + assert( order == 1 ); +#endif FOR( ch = 0; ch < num_ch_order; ch++ ) { @@ -4275,16 +4290,26 @@ void ivas_get_spar_md_from_dirac_enc_fx( } /*normalize 1st order*/ +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + norm_t = L_norm_arr( &response_avg_fx[1], sub( foa_ch, 1 ) ); + norm_t = sub( norm_t, 1 ); + scale_sig32( &response_avg_fx[1], sub( foa_ch, 1 ), norm_t ); +#endif norm_fx = 0; move32(); +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT norm_q = 0; move16(); +#endif FOR( ch = 1; ch < foa_ch; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } norm_q = sub( 31, ( sub( add( 30, 30 ), 31 ) ) ); +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q +#else IF( norm_fx ) { norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q @@ -4294,6 +4319,7 @@ void ivas_get_spar_md_from_dirac_enc_fx( norm_fx = EPSILON_FX; move32(); } +#endif IF( norm_q <= 0 ) { norm_fx = L_shr( norm_fx, ( negate( norm_q ) ) ); // q=31 @@ -4301,6 +4327,27 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 + +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + IF( LT_32( norm_fx, EPSILON_FX_THR ) ) + { + FOR( ch = 1; ch < foa_ch; ch++ ) + { + /*when control comes here, response_avg_fx[ch] should be less than EPSILON*/ + response_avg_fx[ch] = L_shl( response_avg_fx[ch], Q30 - EPSILON_FX_SHIFT ); // q30 + move32(); + } + } + ELSE + { + FOR( ch = 1; ch < foa_ch; ch++ ) + { + tmp_norm_out = divide3232( response_avg_fx[ch], L_max( norm_fx, L_abs( response_avg_fx[ch] ) ) ); // q15 + response_avg_fx[ch] = L_shl( tmp_norm_out, 15 ); // q30 + move32(); + } + } +#else FOR( ch = 1; ch < foa_ch; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) @@ -4326,6 +4373,9 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } +#endif + +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT /*normalize 2nd order*/ norm_fx = 0; @@ -4426,6 +4476,7 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } +#endif } } @@ -4815,10 +4866,19 @@ void ivas_get_spar_md_from_dirac_fx( { Word32 norm_fx; Word16 norm_q; +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + Word16 num_ch_order, norm_t; + Word32 tmp_norm_out; +#else Word16 num_ch_order, hoa2_ch_order; +#endif num_ch_order = ivas_sba_get_nchan_fx( order, 0 ); +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT hoa2_ch_order = ivas_sba_get_nchan_fx( SBA_HOA2_ORDER, 0 ); +#else + assert( order == 1 ); +#endif FOR( ch = 0; ch < num_ch_order; ch++ ) { @@ -4833,16 +4893,27 @@ void ivas_get_spar_md_from_dirac_fx( } /*normalize 1st order*/ +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + norm_t = L_norm_arr( &response_avg_fx[1], sub( foa_ch, 1 ) ); + norm_t = sub( norm_t, 1 ); + scale_sig32( &response_avg_fx[1], sub( foa_ch, 1 ), norm_t ); +#endif norm_fx = 0; move32(); +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT norm_q = 0; move16(); +#endif FOR( ch = 1; ch < foa_ch; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } norm_q = sub( 31, ( sub( add( 30, 30 ), 31 ) ) ); + +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q +#else IF( norm_fx ) { norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q @@ -4852,6 +4923,8 @@ void ivas_get_spar_md_from_dirac_fx( norm_fx = EPSILON_FX; move32(); } +#endif + IF( norm_q <= 0 ) { norm_fx = L_shr( norm_fx, ( negate( norm_q ) ) ); // q=31 @@ -4859,6 +4932,27 @@ void ivas_get_spar_md_from_dirac_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 + +#ifdef NONBE_FIX_1748_SPAR_DIV_OPT + IF( LT_32( norm_fx, EPSILON_FX_THR ) ) + { + FOR( ch = 1; ch < foa_ch; ch++ ) + { + /*when control comes here, response_avg_fx[ch] should be less than EPSILON*/ + response_avg_fx[ch] = L_shl( response_avg_fx[ch], Q30 - EPSILON_FX_SHIFT ); // q30 + move32(); + } + } + ELSE + { + FOR( ch = 1; ch < foa_ch; ch++ ) + { + tmp_norm_out = divide3232( response_avg_fx[ch], L_max( norm_fx, L_abs( response_avg_fx[ch] ) ) ); // q15 + response_avg_fx[ch] = L_shl( tmp_norm_out, 15 ); // q30 + move32(); + } + } +#else FOR( ch = 1; ch < foa_ch; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) @@ -4884,7 +4978,9 @@ void ivas_get_spar_md_from_dirac_fx( move32(); } } +#endif +#ifndef NONBE_FIX_1748_SPAR_DIV_OPT /*normalize 2nd order*/ norm_fx = 0; move32(); @@ -4984,6 +5080,7 @@ void ivas_get_spar_md_from_dirac_fx( move32(); } } +#endif } } diff --git a/lib_com/options.h b/lib_com/options.h index 3c6148817b417321a5546dc1d63d603e0b32a232..02e90326452f6185378b02a05a33486879a2b69f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -119,5 +119,6 @@ #define FIX_ISSUE_1792 /* FhG: fix noise bursts in binaural rendering */ #define FIX_ISSUE_1795_Q3_OVERFLOW /* FhG: Q3 overflow in function WB_BWE_gain_pred_fx (EVS legacy code) BE, MR1855 */ +#define NONBE_FIX_1748_SPAR_DIV_OPT /*Dlb: issue 1748: SPAR common div optimizations*/ #endif