diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index de44884898256ff7f2de65400dabada858e7cc4c..02e28fa0e716ff807759b7b2452c51db8bc850bc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: TESTV_DIR: "/usr/local/testv" LTV_DIR: "/usr/local/ltv" EVS_BE_TEST_DIR_BASOP: "/usr/local/be_2_evs_basop" - REFERENCE_TAG: "20231128_Update_Ittiam" + REFERENCE_BRANCH: "ivas-float-update" BUILD_OUTPUT: "build_output.txt" SCRIPTS_DIR: "/usr/local/scripts" EXIT_CODE_NON_BE: 123 @@ -92,7 +92,8 @@ stages: .setup-codec: &setup-codec - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries - - git checkout $REFERENCE_TAG + - git checkout $REFERENCE_BRANCH + - git pull - make clean - make -j - mv ./IVAS_cod ./IVAS_cod_ref diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 2e36dc4693b011a6ad2a49646143033cf40c2b66..dae981352862bdd34dfbb55e26fdce08ef018807 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1187,6 +1187,10 @@ enum #define MASA_MAXIMUM_DIRECTIONS 2 #define MASA_MAX_TRANSPORT_CHANNELS 2 +#ifdef NON_BE_FIX_1048_THRESHOLD_COH_BASOP +#define MASA_SUR_COH_THRESHOLD 1e-7f +#define MASA_SUR_COH_PRECISION 1e7f +#endif #define MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS 5 diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 39a1c4c69927c2f27108a11532227b573a4ab68a..77fb370a729bef1d0c1f37be36d28dfa9bb72364 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -919,7 +919,11 @@ void deindex_lvq_SHB( /* find idx_leader */ i = 1; +#ifdef NONBE_FIX_1054_NEGATIVE_LVQ_INDEX + while ( index > table_no_cv[i] ) +#else while ( index >= table_no_cv[i] ) +#endif { i++; } diff --git a/lib_com/options.h b/lib_com/options.h index ab10c15b7d934cf49c5445f866171fbdfec49052..366354dc890d594c3814771366c0b9b3bc016745 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,6 +68,12 @@ /* #################### End DEBUGGING switches ############################ */ +/* ################### Start FIXES switches ########################### */ + +#define NON_BE_FIX_1048_THRESHOLD_COH_BASOP /* Nokia: Fix 1048 replace comparison with 0 with comparison to threshold, to align with BASOP*/ +#define NONBE_FIX_1054_NEGATIVE_LVQ_INDEX /* Nokia: issue 1054: Input to decode_comb in deindex_lvq_SHB should be positive */ + +/* #################### End FIXES switches ############################ */ #define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ @@ -94,6 +100,7 @@ #define BE_FIX_832_ASAN_ERROR_EFAP_OSBA /* FhG: issue #832: fix ASAN error caused by re-allocating EFAP memories in OSBA*/ #define NONBE_FIX_819_DOUBLE_PREC_COMB_FORMATS /* VA: issue 820: Double precision arithmetic in combined formats */ #define NONBE_FIX_849_OMASA_BFI_CRASH /* VA: issue 849: fix OMASA 2TC and FEC crashes */ +#define NONBE_FIX_738_QUATERNION_SLERP_PRECISION /* Quaternion slerp changes*/ #define IVAS_FLOAT_FIXED #define ISM_DISABLE #define FIX_TMP_714 diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 369ca37b067432f88dac662bf686a35d16f0ba62..9242d0672747e08a387d203893032a54c41723c9 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -7940,6 +7940,9 @@ static int16_t read_surround_coherence_hr( IVAS_QDIRECTION *q_direction; int16_t min_index; int16_t d, idx; +#ifdef NON_BE_FIX_1048_THRESHOLD_COH_BASOP + int32_t int_error_ratio_surr; +#endif coding_subbands = hQMetaData->q_direction[0].cfg.nbands; q_direction = hQMetaData->q_direction; @@ -7963,6 +7966,11 @@ static int16_t read_surround_coherence_hr( error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[sf]; } +#ifdef NON_BE_FIX_1048_THRESHOLD_COH_BASOP + int_error_ratio_surr = (int32_t)(MASA_SUR_COH_PRECISION * error_ratio_surr); + error_ratio_surr = (float)(int_error_ratio_surr * MASA_SUR_COH_THRESHOLD); +#endif + if ( error_ratio_surr <= 0 ) { error_ratio_surr = 0; @@ -8087,7 +8095,7 @@ static Word16 read_surround_coherence_hr_fx( Word16 coding_subbands; Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS]; Word16 bit_pos; - Word32 error_ratio_surr_fx; + Word64 error_ratio_surr_fx; Word16 idx_ER[MASA_MAXIMUM_CODING_SUBBANDS]; Word16 bits_sur_coherence, bits_GR; Word16 j, k, sf; @@ -8096,6 +8104,7 @@ static Word16 read_surround_coherence_hr_fx( IVAS_QDIRECTION *q_direction; Word16 min_index; Word16 d, idx; + Word32 int_error_ratio_surr; coding_subbands = hQMetaData->q_direction[0].cfg.nbands; q_direction = hQMetaData->q_direction; @@ -8105,63 +8114,24 @@ static Word16 read_surround_coherence_hr_fx( FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ ) { d = 0; -#ifdef IVAS_FLOAT_FIXED_TBD - FOR( j = 0; j < coding_subbands; j++ ) - { - error_ratio_surr_fx = 1 << *q; - if ( hQMetaData->no_directions == 2 ) - { - d += hQMetaData->twoDirBands[j]; - idx = max( d - 1, 0 ); - error_ratio_surr_fx = L_sub( - L_sub( 1 << *q, q_direction[0].band_data[j].energy_ratio_fx[sf] ), - q_direction[1].band_data[idx].energy_ratio_fx[sf] * hQMetaData->twoDirBands[j] ); - } - ELSE - { - error_ratio_surr_fx = L_sub( 1 << *q, q_direction[0].band_data[j].energy_ratio_fx[sf] ); - } - if ( error_ratio_surr_fx <= 53667 ) // Assuming max error of 10^(-4) in q = 29 => 10^(-4) * 2^(29) - { - error_ratio_surr_fx = 0; - no_cv_vec[j] = 1; - idx_ER[j] = 0; - } - ELSE - { - idx_ER[j] = 7; // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); - no_cv_vec[j] = idx_cb_sur_coh_masa[idx_ER[j]] + 2; - } - } -#else - /* NOTE: This block gives incorrect output with fixed point resulting in failures in pytest */ - /* TODO: Remove the intermediate conversion from fixed to float below */ - float tmp; - float energy_ratio_j_sf; - float energy_ratio_idx_sf; FOR( j = 0; j < coding_subbands; j++ ) { - energy_ratio_j_sf = (float) energy_ratio[0][j][sf] / ( ONE_IN_Q62 ); - - tmp = 1.0f; - IF( hQMetaData->no_directions == 2 ) + error_ratio_surr_fx = ONE_IN_Q62; + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { - d += hQMetaData->twoDirBands[j]; - idx = max( d - 1, 0 ); - - energy_ratio_idx_sf = (float) energy_ratio[1][idx][sf] / ( ONE_IN_Q62 ); - - tmp = 1.0f - energy_ratio_j_sf - energy_ratio_idx_sf * hQMetaData->twoDirBands[j]; + d = add( d, hQMetaData->twoDirBands[j] ); + idx = s_max( sub( d, 1 ), 0 ); + error_ratio_surr_fx = W_sub( + W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ), + energy_ratio[1][idx][sf] * hQMetaData->twoDirBands[j] ); } ELSE { - tmp = 1.0f - energy_ratio_j_sf; + error_ratio_surr_fx = W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ); } - error_ratio_surr_fx = (Word32) ( tmp * ONE_IN_Q30 ); - - IF( error_ratio_surr_fx <= 0 ) + IF( LE_64( error_ratio_surr_fx, ( 461168601842 ) ) ) // 1e-7 in Q62 { error_ratio_surr_fx = 0; no_cv_vec[j] = 1; @@ -8173,9 +8143,8 @@ static Word16 read_surround_coherence_hr_fx( no_cv_vec[j] = idx_cb_sur_coh_masa[idx_ER[j]] + 2; } } -#endif // !IVAS_FLOAT_FIXED_TBD - IF( sum_s( no_cv_vec, coding_subbands ) == coding_subbands ) + IF( EQ_16( sum_s( no_cv_vec, coding_subbands ), coding_subbands ) ) { /* surround coherence is zero */ FOR( j = 0; j < coding_subbands; j++ ) @@ -8193,29 +8162,29 @@ static Word16 read_surround_coherence_hr_fx( { /* read how the surround coherence is encoded */ byteBuffer = bitstream[bit_pos--]; - bits_sur_coherence += 1; + bits_sur_coherence = add( bits_sur_coherence, 1 ); IF( byteBuffer & 1 ) { /* GR decoding */ /* read GR order */ byteBuffer = bitstream[bit_pos--]; - bits_sur_coherence += 1; + bits_sur_coherence = add( bits_sur_coherence, 1 ); /* read min index */ bits_GR = bit_pos; min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); - bits_sur_coherence += bits_GR - bit_pos; + bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) ); /* read GR data */ FOR( j = 0; j < coding_subbands; j++ ) { bits_GR = bit_pos; /* decoding for min removed */ - IF( no_cv_vec[j] > 1 ) + IF( GT_16( no_cv_vec[j], 1 ) ) { idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_cv_vec[j] - min_index, ( byteBuffer & 1 ) ); - bits_sur_coherence += bits_GR - bit_pos; + bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) ); } ELSE { @@ -8225,9 +8194,9 @@ static Word16 read_surround_coherence_hr_fx( FOR( j = 0; j < coding_subbands; j++ ) { - IF( no_cv_vec[j] > 1 ) + IF( GT_16( no_cv_vec[j], 1 ) ) { - hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j] + min_index; + hQMetaData->surcoh_band_data[j].sur_coherence_index = L_add( (Word32) idx_sur_coh[j], L_deposit_l( min_index ) ); hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH + hQMetaData->surcoh_band_data[j].sur_coherence_index]; } ELSE @@ -8253,7 +8222,7 @@ static Word16 read_surround_coherence_hr_fx( /* deindex surround coherence */ FOR( j = 0; j < coding_subbands; j++ ) { - IF( no_cv_vec[j] > 1 ) + IF( GT_16( no_cv_vec[j], 1 ) ) { hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH + hQMetaData->surcoh_band_data[j].sur_coherence_index]; } @@ -8267,7 +8236,7 @@ static Word16 read_surround_coherence_hr_fx( } /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */ - bits_sur_coherence = *p_bit_pos - bit_pos; + bits_sur_coherence = sub( *p_bit_pos, bit_pos ); *p_bit_pos = bit_pos; return bits_sur_coherence; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 711269dc514764acac0e6cd3a5169c5428bd021c..c7540036229895858cd8aad4d1c14bc86e21dd9f 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -3049,7 +3049,11 @@ void stereo_dft_dec_smooth_parameters( if ( hStereoDft->frame_sid_nodata ) { /* set new xfade target if new itd received */ +#ifdef NONBE_FIX_1010_STEREO_CNG_DIV_BY_ZERO + if ( hStereoDft->ipd_xfade_counter < STEREO_DFT_ITD_CNG_XFADE ) +#else if ( hStereoDft->gipd[k + k_offset] != hStereoDft->ipd_xfade_target ) +#endif { if ( ( hStereoDft->gipd[k + k_offset] - hStereoDft->ipd_xfade_prev ) > EVS_PI ) { @@ -3095,7 +3099,11 @@ void stereo_dft_dec_smooth_parameters( if ( hStereoDft->frame_sid_nodata ) { /* set new xfade target if new itd received */ +#ifdef NONBE_FIX_1010_STEREO_CNG_DIV_BY_ZERO + if ( hStereoDft->itd_xfade_counter < STEREO_DFT_ITD_CNG_XFADE ) +#else if ( hStereoDft->itd[k + k_offset] != hStereoDft->itd_xfade_target ) +#endif { hStereoDft->itd_xfade_target = hStereoDft->itd[k + k_offset]; hStereoDft->itd_xfade_step = ( hStereoDft->itd_xfade_target - hStereoDft->itd_xfade_prev ) / ( STEREO_DFT_ITD_CNG_XFADE - hStereoDft->itd_xfade_counter ); diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 5e1c4597ed9e762ccacd841dc7a58e81bc951f74..5ca49dbbf4b909574cb27fdd472ee82a1573eae9 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -4515,6 +4515,9 @@ static int16_t encode_surround_coherence_hr( int16_t max_val = 0, nbits_max; int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; int16_t idx16; +#ifdef NON_BE_FIX_1048_THRESHOLD_COH_BASOP + int32_t int_error_ratio_surr; +#endif coding_subbands = hQMetaData->q_direction[0].cfg.nbands; all_coherence_zero = hQMetaData->all_coherence_zero; @@ -4544,7 +4547,10 @@ static int16_t encode_surround_coherence_hr( { error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[sf]; } - +#ifdef NON_BE_FIX_1048_THRESHOLD_COH_BASOP + int_error_ratio_surr = (int32_t) ( MASA_SUR_COH_PRECISION * error_ratio_surr ); + error_ratio_surr = (float) ( int_error_ratio_surr * MASA_SUR_COH_THRESHOLD ); +#endif if ( error_ratio_surr <= 0 ) { diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index 0e92bf6b3410a3f2a8de2f1d65a4986dab89e1ad..a6d08f15b85d5465b3ef64e962f0beb148afa1fd 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -49,6 +49,10 @@ *------------------------------------------------------------------------------------------*/ #define OTR_UPDATE_RATE (float) FRAMES_PER_SEC /* rate of the Process() calls [Hz]; 1x per IVAS frame */ +#ifdef NONBE_FIX_738_QUATERNION_SLERP_PRECISION +#define COS_ONE_TENTH_DEGREE ( 0.999998476913288f ) +#endif +#define COS_ONE_TENTH_DEGREE_FX 2147480320 //Q31 /*------------------------------------------------------------------------------------------* @@ -298,21 +302,21 @@ static void QuaternionDivision_fx( IVAS_QUATERNION *const r, Word16 den_e ) { - float den = me2f( d, den_e ); - IVAS_QUATERNION q_flt; - Word16 e_temp; - q_flt.w = me2f( q.w_fx, 31 - q.w_qfact ); - q_flt.x = me2f( q.x_fx, 31 - q.x_qfact ); - q_flt.y = me2f( q.y_fx, 31 - q.y_qfact ); - q_flt.z = me2f( q.z_fx, 31 - q.z_qfact ); - f2me( ( q_flt.w / den ), &r->w_fx, &e_temp ); - r->w_qfact = 31 - e_temp; - f2me( ( q_flt.x / den ), &r->x_fx, &e_temp ); - r->x_qfact = 31 - e_temp; - f2me( ( q_flt.y / den ), &r->y_fx, &e_temp ); - r->y_qfact = 31 - e_temp; - f2me( ( q_flt.z / den ), &r->z_fx, &e_temp ); - r->z_qfact = 31 - e_temp; + Word16 scale_e, result_e = 0; + r->w_fx = L_deposit_h(BASOP_Util_Divide3232_Scale((q.w_fx), d, &scale_e)); + result_e = scale_e + ((31 - q.w_qfact) - den_e); // e+e1-e2// + r->w_qfact = 31 - result_e; + r->x_fx = L_deposit_h(BASOP_Util_Divide3232_Scale((q.x_fx), d, &scale_e)); + result_e = scale_e + ((31 - q.x_qfact) - den_e); + r->x_qfact = 31 - result_e; + r->y_fx = L_deposit_h(BASOP_Util_Divide3232_Scale((q.y_fx), d, &scale_e)); + result_e = scale_e + ((31 - q.y_qfact) - den_e); + r->y_qfact = 31 - result_e; + r->z_fx = L_deposit_h(BASOP_Util_Divide3232_Scale((q.z_fx), d, &scale_e)); + result_e = scale_e + ((31 - q.z_qfact) - den_e); + r->z_qfact = 31 - result_e; + + } #endif @@ -355,85 +359,156 @@ static void QuaternionNormalize_fx( * Computes a spherical linear interpolation between two quaternions *------------------------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void QuaternionSlerp( const IVAS_QUATERNION q1, const IVAS_QUATERNION q2, const float t, IVAS_QUATERNION *const r ) { - float angle, denom, s, s2; +#ifdef NONBE_FIX_738_QUATERNION_SLERP_PRECISION + IVAS_QUATERNION r1, r2; + float phi, sinPhi, cosPhi, s1, s2; - s = QuaternionDotProduct( q1, q2 ); + QuaternionNormalize( q1, &r1 ); + QuaternionNormalize( q2, &r2 ); + + cosPhi = QuaternionDotProduct( r1, r2 ); - if ( fabsf( s ) >= 1.0f ) + if ( cosPhi < 0 ) { + cosPhi = -cosPhi; + r2.w = -r2.w; + r2.x = -r2.x; + r2.y = -r2.y; + r2.z = -r2.z; + } - *r = q2; - return; + /* Angle less than one degree, use linear interpolation */ + if ( cosPhi >= COS_ONE_TENTH_DEGREE ) + { + r->w = r1.w + t * ( r2.w - r1.w ); + r->x = r1.x + t * ( r2.x - r1.x ); + r->y = r1.y + t * ( r2.y - r1.y ); + r->z = r1.z + t * ( r2.z - r1.z ); } + else + { + phi = acosf( cosPhi ); + sinPhi = sinf( phi ); - angle = acosf( s ); - denom = sinf( angle ); + s1 = sinf( ( 1 - t ) * phi ); + s2 = sinf( t * phi ); - s = sinf( ( 1 - t ) * angle ); - s2 = sinf( t * angle ); - r->x = ( q1.x * s + q2.x * s2 ) / denom; + r->w = ( s1 * r1.w + s2 * r2.w ) / sinPhi; + r->x = ( s1 * r1.x + s2 * r2.x ) / sinPhi; + r->y = ( s1 * r1.y + s2 * r2.y ) / sinPhi; + r->z = ( s1 * r1.z + s2 * r2.z ) / sinPhi; + } +#else + float angle, denom, s, s2; + + s = QuaternionDotProduct( q1, q2 ); r->y = ( q1.y * s + q2.y * s2 ) / denom; r->z = ( q1.z * s + q2.z * s2 ) / denom; r->w = ( q1.w * s + q2.w * s2 ) / denom; +#endif QuaternionNormalize( *r, r ); return; } -#ifdef IVAS_FLOAT_FIXED +#else void QuaternionSlerp_fx( const IVAS_QUATERNION q1_fx, const IVAS_QUATERNION q2_fx, const Word32 t_fx, IVAS_QUATERNION *const r_fx ) { - float angle, denom, s, s2; - float t = me2f( t_fx, 1 ); - IVAS_QUATERNION q1, q2; + IVAS_QUATERNION r1, r2; + Word32 sinPhi, cosPhi, temp_32; + Word16 q_min, sin_e, phi, s1, s2, temp_16, e_div; + + QuaternionNormalize_fx( q1_fx, &r1 ); + QuaternionNormalize_fx( q2_fx, &r2 ); + Word16 q_dot = 0; - Word32 s_fx = QuaternionDotProduct_fx( q1_fx, q2_fx, &q_dot ); - s = me2f( s_fx, 31 - q_dot ); + cosPhi = QuaternionDotProduct_fx( r1, r2, &q_dot ); + + q_min = s_min( s_min( r1.w_qfact, r1.x_qfact ), s_min( r1.y_qfact, r1.z_qfact ) ); + q_min = s_min( q_min, s_min( s_min( r1.w_qfact, r1.x_qfact ), s_min( r1.y_qfact, r1.z_qfact ) ) ); + r1.w_fx = L_shr( r1.w_fx, sub( r1.w_qfact, q_min ) ); + r1.x_fx = L_shr( r1.x_fx, sub( r1.x_qfact, q_min ) ); + r1.y_fx = L_shr( r1.y_fx, sub( r1.y_qfact, q_min ) ); + r1.z_fx = L_shr( r1.z_fx, sub( r1.z_qfact, q_min ) ); + r2.w_fx = L_shr( r2.w_fx, sub( r2.w_qfact, q_min ) ); + r2.x_fx = L_shr( r2.x_fx, sub( r2.x_qfact, q_min ) ); + r2.y_fx = L_shr( r2.y_fx, sub( r2.y_qfact, q_min ) ); + r2.z_fx = L_shr( r2.z_fx, sub( r2.z_qfact, q_min ) ); + r1.w_qfact = r1.x_qfact = r1.y_qfact = r1.z_qfact = r2.w_qfact = r2.x_qfact = r2.y_qfact = r2.z_qfact = q_min; + + IF( LT_32( cosPhi, 0 ) ) + { + cosPhi = L_negate( cosPhi ); + r2.w_fx = L_negate( r2.w_fx ); + r2.x_fx = L_negate( r2.x_fx ); + r2.y_fx = L_negate( r2.y_fx ); + r2.z_fx = L_negate( r2.z_fx ); + } - if ( fabsf( s ) >= 1.0f ) + /* Angle less than one degree, use linear interpolation */ + IF( GE_32( cosPhi, L_shr( COS_ONE_TENTH_DEGREE_FX, sub( 31, q_dot ) ) ) ) { - *r_fx = q2_fx; - return; + r_fx->w_fx = L_add( L_shr( r1.w_fx, 1 ), Mpy_32_32( L_sub( r2.w_fx, r1.w_fx ), t_fx ) ); // q_min-1 + r_fx->x_fx = L_add( L_shr( r1.x_fx, 1 ), Mpy_32_32( L_sub( r2.x_fx, r1.x_fx ), t_fx ) ); // q_min-1 + r_fx->y_fx = L_add( L_shr( r1.y_fx, 1 ), Mpy_32_32( L_sub( r2.y_fx, r1.y_fx ), t_fx ) ); // q_min-1 + r_fx->z_fx = L_add( L_shr( r1.z_fx, 1 ), Mpy_32_32( L_sub( r2.z_fx, r1.z_fx ), t_fx ) ); // q_min-1 + + r2.w_qfact = r2.x_qfact = r2.y_qfact = r2.z_qfact = sub( q_min, 1 ); } + ELSE + { + temp_32 = L_sub( L_shr( ONE_IN_Q31, sub( 62, 2 * q_dot ) ), ( Mpy_32_32( cosPhi, cosPhi ) ) ); + sin_e = sub( 62, 2 * q_dot ); + sinPhi = Sqrt32( temp_32, &sin_e ); - angle = acosf( s ); - denom = sinf( angle ); - - s = sinf( ( 1 - t ) * angle ); - s2 = sinf( t * angle ); - q1.w = me2f( q1_fx.w_fx, 31 - q1_fx.w_qfact ); - q1.x = me2f( q1_fx.x_fx, 31 - q1_fx.x_qfact ); - q1.y = me2f( q1_fx.y_fx, 31 - q1_fx.y_qfact ); - q1.z = me2f( q1_fx.z_fx, 31 - q1_fx.z_qfact ); - q2.w = me2f( q2_fx.w_fx, 31 - q2_fx.w_qfact ); - q2.x = me2f( q2_fx.x_fx, 31 - q2_fx.x_qfact ); - q2.y = me2f( q2_fx.y_fx, 31 - q2_fx.y_qfact ); - q2.z = me2f( q2_fx.z_fx, 31 - q2_fx.z_qfact ); - r_fx->x = ( q1.x * s + q2.x * s2 ) / denom; - r_fx->y = ( q1.y * s + q2.y * s2 ) / denom; - r_fx->z = ( q1.z * s + q2.z * s2 ) / denom; - r_fx->w = ( q1.w * s + q2.w * s2 ) / denom; - - r_fx->w_fx = float_to_fix(r_fx->w, Q29 ); - r_fx->x_fx = float_to_fix(r_fx->x, Q29 ); - r_fx->y_fx = float_to_fix(r_fx->y, Q29 ); - r_fx->z_fx = float_to_fix(r_fx->z, Q29 ); - r_fx->w_qfact = r_fx->x_qfact = r_fx->y_qfact = r_fx->z_qfact = Q29; - QuaternionNormalize_fx( *r_fx, r_fx ); + phi = BASOP_util_atan2( sinPhi, cosPhi, sub( sin_e, sub( 31, q_dot ) ) ); // Q13 + temp_32 = L_shl(Mpy_32_16_1( L_sub( ONE_IN_Q30, t_fx ), phi ),1); // Q29 + + temp_16 = extract_h( temp_32 ); // Q13 + s1 = getSineWord16R2( mult( temp_16, 20860 ) ); // Q15 + + temp_32 = L_shl(Mpy_32_16_1( t_fx, phi ),1); // Q29 + temp_16 = extract_h( temp_32 ); // Q13 + s2 = getSineWord16R2( mult( temp_16, 20860 ) ); // Q15 + + temp_32 = L_add( Mpy_32_16_1( r1.w_fx, s1 ), Mpy_32_16_1( r2.w_fx, s2 ) ); // q_min + r_fx->w_fx = L_deposit_h(BASOP_Util_Divide3232_Scale( temp_32, sinPhi, &e_div )); + e_div = e_div + ( 31 - q_min - sin_e ); + r_fx->w_qfact = 31 - e_div; + + temp_32 = L_add( Mpy_32_16_1( r1.x_fx, s1 ), Mpy_32_16_1( r2.x_fx, s2 ) ); // q_min + r_fx->x_fx = L_deposit_h(BASOP_Util_Divide3232_Scale( temp_32, sinPhi, &e_div )); + e_div = e_div + ( 31 - q_min - sin_e ); + r_fx->x_qfact = 31 - e_div; + + temp_32 = L_add( Mpy_32_16_1( r1.y_fx, s1 ), Mpy_32_16_1( r2.y_fx, s2 ) ); // q_min + r_fx->y_fx = L_deposit_h(BASOP_Util_Divide3232_Scale( temp_32, sinPhi, &e_div )); + e_div = e_div + ( 31 - q_min - sin_e ); + r_fx->y_qfact = 31 - e_div; + + temp_32 = L_add( Mpy_32_16_1( r1.z_fx, s1 ), Mpy_32_16_1( r2.z_fx, s2 ) ); // q_min + r_fx->z_fx = L_deposit_h(BASOP_Util_Divide3232_Scale( temp_32, sinPhi, &e_div )); + e_div = e_div + ( 31 - q_min - sin_e ); + r_fx->z_qfact = 31 - e_div; + } + + QuaternionNormalize_fx(*r_fx, r_fx); return; + } #endif diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 93b32afa105e1754ee3b9d4551d37eb11703d1a5..fcd93b3ac9cac41186303ae92260c4873383428c 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1689,21 +1689,21 @@ ivas_error ivas_combined_orientation_open( identity.x = identity.y = identity.z = 0.0f; origo.x = origo.y = origo.z = 0.0f; #ifdef IVAS_FLOAT_FIXED - identity.w_fx = ONE_IN_Q30; - identity.w_qfact = 1; + identity.w_fx = ONE_IN_Q31; + identity.w_qfact = 31; identity.x_fx = 0; - identity.x_qfact = 1; + identity.x_qfact = 31; identity.y_fx = 0; - identity.y_qfact = 1; + identity.y_qfact = 31; identity.z_fx = 0; - identity.z_qfact = 1; + identity.z_qfact = 31; origo.x_fx = 0; - origo.x_qfact = 0; + origo.x_qfact = 31; origo.y_fx = 0; - origo.y_qfact = 0; + origo.y_qfact = 31; origo.z_fx = 0; - origo.z_qfact = 0; + origo.z_qfact = 31; #endif /* Allocate handle */ @@ -1980,7 +1980,31 @@ ivas_error combine_external_and_head_orientations( if ( hCombinedOrientationData->isInterpolationOngoing == true && hCombinedOrientationData->interpolationCoefficient <= 1.0f && are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == true ) { /* Continue interpolation */ - QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); +#ifdef IVAS_FLOAT_FIXED + hCombinedOrientationData->interpolationCoefficient_fx = float_to_fix(hCombinedOrientationData->interpolationCoefficient, Q30); + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.w, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.x, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.y, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.z, Q29); + + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.w, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.x, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.y, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.z, Q29); + + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.x_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.y_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.z_qfact = Q29; + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.x_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.y_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.z_qfact = Q29; + + QuaternionSlerp_fx(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); + + hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].w_fx, hCombinedOrientationData->Quaternions[i].w_qfact); + hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].x_fx, hCombinedOrientationData->Quaternions[i].x_qfact); + hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].y_fx, hCombinedOrientationData->Quaternions[i].y_qfact); + hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].z_fx, hCombinedOrientationData->Quaternions[i].z_qfact); + +#else + QuaternionSlerp(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); +#endif hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else @@ -2231,7 +2255,31 @@ static void external_target_interpolation( /* Interpolate */ hCombinedOrientationData->isInterpolationOngoing = TRUE; - QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); +#ifdef IVAS_FLOAT_FIXED + hCombinedOrientationData->interpolationCoefficient_fx = float_to_fix(hCombinedOrientationData->interpolationCoefficient, Q30); + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.w, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.x, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.y, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.z, Q29); + + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.w, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.x, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.y, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.z, Q29); + + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.x_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.y_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_start.z_qfact = Q29; + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.x_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.y_qfact = hCombinedOrientationData->Quaternions_ext_interpolation_target.z_qfact = Q29; + + QuaternionSlerp_fx(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); + + hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].w_fx, hCombinedOrientationData->Quaternions[i].w_qfact); + hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].x_fx, hCombinedOrientationData->Quaternions[i].x_qfact); + hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].y_fx, hCombinedOrientationData->Quaternions[i].y_qfact); + hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].z_fx, hCombinedOrientationData->Quaternions[i].z_qfact); + +#else + QuaternionSlerp(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); +#endif hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index d3348f9dda1beb88aec6fc8a1153756f85131a53..677ca58fe3dc6bafb7689a7b9910a4b2c0da0d73 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1104,6 +1104,8 @@ typedef struct ivas_combined_orientation_struct float procChEneIIR[2][MASA_FREQUENCY_BANDS]; #ifdef IVAS_FLOAT_FIXED Word32 lrSwitchInterpVal_fx; + Word32 interpolationCoefficient_fx; + Word32 interpolationIncrement_Fx; Word32 chEneIIR_fx[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ Word16 q_chEneIIR; Word32 procChEneIIR_fx[2][MASA_FREQUENCY_BANDS];