diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 5a5a434846333bbcc752cf8e1e0dbcfa5ab08241..704b2e21b36fc338419b3cfe11093e7b6e3b3ef0 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -616,6 +616,12 @@ Word16 shl( Word16 var1, Word16 var2 ) return ( var_out ); } + +Word16 shl_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return shl_o( var1, var2, &Overflow ); +} #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ diff --git a/lib_com/basop32.h b/lib_com/basop32.h index a8a72aed04825925a8ce418730d929c571b70203..c72e18e82462bb95ca10ff995e823309c24599f3 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -252,6 +252,7 @@ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 * Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ); +Word16 shl_sat( Word16 var1, Word16 var2 ); Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ); Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 round_fx_o( Word32 L_var1, Flag *Overflow ); diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 197fe884082c1c57d3a8b56b9da51875bc1002a9..0b4784ef3726edc068a4c3ebfe1beca83141a214 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -636,6 +636,53 @@ static Word16 fixp_sin_cos_residual_16( return residual; } +Word16 getCosWord16( Word16 theta ) +{ + Word16 result, residual, sine, cosine; + + residual = fixp_sin_cos_residual_16( theta, 2, &sine, &cosine, 0 ); + /* This negation prevents the subsequent addition from overflow */ + /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */ + sine = negate( sine ); + result = mac_r( L_mult0( sine, residual ), cosine, 16384 ); + + + return result; +} + +#define EVS_PI_BY_2_FX ( Word16 )( 0x3244 ) // Q13 +#define EVS_PI_FX 25736 /* pi in Q13 */ +#define ONE_IN_Q14 16384 + +Word16 getSinWord16( Word16 theta ) +{ + Word16 sine; + Word32 theta_new = L_sub( EVS_PI_BY_2_FX, theta ); + Word16 l_theta; + IF( GT_32( theta_new, EVS_PI_FX ) ) + { + l_theta = extract_l( L_sub( L_sub( theta_new, EVS_PI_FX ), EVS_PI_FX ) ); + } + ELSE IF( LT_32( theta_new, -EVS_PI_FX ) ) + { + l_theta = extract_l( L_add( L_add( theta_new, EVS_PI_FX ), EVS_PI_FX ) ); + } + ELSE + { + l_theta = extract_l( theta_new ); + } + sine = getCosWord16( l_theta ); + IF( EQ_16( sine, ONE_IN_Q14 ) ) + { + sine = MAX_16; + } + ELSE + { + sine = shl( sine, 1 ); + } + return sine; +} + Word16 getCosWord16R2( Word16 theta ) diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index b76d5982f23fec7be3bd0b8ac7680b283dd75da1..5c23b55861d7e7c96b614404f8cfd82aef813ad9 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -273,6 +273,9 @@ Word16 mult0( Word16 x, /* i : Multiplier */ */ Word16 getCosWord16R2( Word16 theta ); +Word16 getSinWord16( Word16 theta ); +Word16 getCosWord16( Word16 theta ); + /****************************************************************************/ /*! \brief 16/16->16 unsigned integer division diff --git a/lib_com/options.h b/lib_com/options.h index 4c31c1480c9763e7cd41e1ce80f6c8cb195126dd..6b90358a0ac52dfe4d81cbd9dc162dea44fa208b 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -185,6 +185,7 @@ #define NONBE_1412_AVOID_ROUNDING_AZ_ELEV /* FhG: Avoid rounding when passing azimuth and elevation to efap_determine_gains() */ #define NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG /* FhG: Fix MDCT-Stereo comfort noise for certain noise types */ +#define NONBE_TRIG_FUNC_2_BASOP_IN_DFT_STEREO /* FhG: Fix for non-BE between different optimization levels in dft stereo code by using BASOPs for trigonometric functions */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c old mode 100755 new mode 100644 index 0ae36724d89b7ea3237ae4f4e897a6569f518e2c..1cbd8b209aa4e0272be4ff2e915c2112ad6a1303 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -42,6 +42,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef NONBE_TRIG_FUNC_2_BASOP_IN_DFT_STEREO +#include "basop_util.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -1316,12 +1319,26 @@ void stereo_dft_enc_process( if ( hStereoDft->hItd->deltaItd[k_offset] != 0 && hStereoDft->hConfig->dmx_active ) { +#ifdef NONBE_TRIG_FUNC_2_BASOP_IN_DFT_STEREO + Word16 alpha_fx, c1_fx, s1_fx; +#endif /*time shift channels*/ alpha = -2.0f * EVS_PI * hStereoDft->hItd->deltaItd[k_offset] / hStereoDft->NFFT; c = 1.f; /*cos(0)*/ s = 0.f; /*sin(0)*/ +#ifdef NONBE_TRIG_FUNC_2_BASOP_IN_DFT_STEREO + /* Use BASOPs for calculating trigonometric functions to be independent of compiler optimization levels */ + /* convert angle to Q13 */ + alpha_fx = (Word16) ( alpha * 8192 ); + c1_fx = shl_sat( getCosWord16( alpha_fx ), 1 ); // Q15 + s1_fx = getSinWord16( alpha_fx ); // Q15 + + c1 = c1_fx / 32768.f; + s1 = s1_fx / 32768.f; +#else c1 = cosf( alpha ); s1 = sinf( alpha ); +#endif if ( alpha >= 0 ) {