diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 0ce50e11e868806e710ca516818e61d0e60e4574..9353570790ea131d84ab75dabd26dec3365c8295 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1168,6 +1168,14 @@ enum #define IVAS_PCA_THRES_MIN_DOT2 0.0f #define IVAS_PCA_THRES_DIST_ALT 6.0f +#ifdef IVAS_FLOAT_FIXED +#define IVAS_PCA_QUAT_EPS_FX 215 // Q31 +#define IVAS_PCA_THRES_MIN_DOT_FX 1717986918 // 0.8 in Q31 +#define IVAS_PCA_THRES_MIN_DOT2_FX 0 +#define IVAS_PCA_THRES_DIST_ALT_FX 1610612736 // 6 in Q28 +#endif + + typedef enum { PCA_MODE_ACTIVE = 0, @@ -1289,11 +1297,16 @@ enum #define MASA_COHERENCE_TOLERANCE 0.1f #define MASA_COHERENCE_THRESHOLD 0.1f #ifdef IVAS_FLOAT_FIXED +#define MASA_COHERENCE_TOLERANCE_FX 419430/*0.1 Q22*/ #define MASA_COHERENCE_THRESHOLD_FX 214748365 // 0.1 in Q31 #endif #define MASA_RATIO_TOLERANCE 0.1f #define MASA_RATIO_THRESHOLD 0.1f #define MASA_ANGLE_TOLERANCE 0.5f +#ifdef IVAS_FLOAT_FIXED +#define MASA_RATIO_TOLERANCE_FX 419430/*0.1 Q22*/ +#define MASA_ANGLE_TOLERANCE_FX ONE_IN_Q21/*0.5f q22*/ +#endif #define MASA_LIMIT_NO_BANDS_SUR_COH 8 #define MINIMUM_BIT_BUDGET_NORMAL_META 100 #define DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC 4 diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools.c index d831d0359b25327ad80b7ff6ce86dfe296bca227..4df06a23d9bebc8837a09eb258630a16ccfde7ed 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools.c @@ -67,6 +67,22 @@ void eye_matrix( return; } +static Word16 check_bound( Word32 tmp ) +{ + IF( GT_32( tmp, MAX16B ) ) + { + return MAX16B; + } + ELSE IF( LT_32( tmp, MIN16B ) ) + { + return MIN16B; + } + ELSE + { + return extract_l( tmp ); + } +} + #ifdef IVAS_FLOAT_FIXED void eye_matrix_fx( Word16 *mat, @@ -88,6 +104,28 @@ void eye_matrix_fx( return; } + +void eye_matrix_fx32( + Word32 *mat, // Q + const Word16 n, + const Word32 d // Q +) +{ + Word16 i; + + FOR( i = 0; i < n * n; i++ ) + { + mat[i] = 0; + move32(); + } + FOR( i = 0; i < n; i++ ) + { + mat[i * n + i] = d; + move32(); + } + + return; +} #endif /*---------------------------------------------------------------------* * cov() @@ -137,6 +175,57 @@ void cov_subfr( return; } +#ifdef IVAS_FLOAT_FIXED +void cov_subfr_fx( + Word32 **ptr_sig_fx, // Q11 + Word64 *r_fx_64, // Q11 + const Word16 n_channels, + const Word16 len ) +{ + Word64 s_fx; + Word16 j, k, l; + Word32 *t_fx, *tt_fx; + + /* Compute diagonal r[k][k] */ + FOR( k = 0; k < n_channels; k++ ) + { + t_fx = &ptr_sig_fx[k][0]; + s_fx = W_shr( W_mult0_32_32( t_fx[0], t_fx[0] ), 11 ); // Q11 + FOR( j = 1; j < len; j++ ) + { + if ( s_fx != 0 ) + { + t_fx[j] = t_fx[j]; + move32(); + } + s_fx = W_add( s_fx, W_shr( W_mult0_32_32( t_fx[j], t_fx[j] ), 11 ) ); // Q11 + } + r_fx_64[k * n_channels + k] = s_fx; // Q11 + move64(); + } + + /* Compute off-diagonal r[k][l] = r[l][k] */ + FOR( k = 0; k < ( n_channels - 1 ); k++ ) + { + t_fx = &ptr_sig_fx[k][0]; + FOR( l = k + 1; l < n_channels; l++ ) + { + tt_fx = &ptr_sig_fx[l][0]; + s_fx = W_shr( W_mult0_32_32( t_fx[0], tt_fx[0] ), 11 ); // Q11 + FOR( j = 1; j < len; j++ ) + { + s_fx = W_add( s_fx, W_shr( W_mult0_32_32( t_fx[j], tt_fx[j] ), 11 ) ); + } + r_fx_64[k * n_channels + l] = s_fx; // Q11 + r_fx_64[l * n_channels + k] = s_fx; // Q11 + move64(); + move64(); + } + } + + return; +} +#endif static void house_refl( const float *px, @@ -183,6 +272,118 @@ static void house_refl( return; } +static void house_refl_fx( + const Word32 *px_fx, // Q: px_q + const Word16 px_q, + const Word16 sizex, + Word32 *pu_fx, // Q: pu_q + Word16 *pu_fx_q, + Word32 *normu_fx, // Q: q_norm + Word16 *q_normu ) +{ + Word16 i; + Word16 exp, tmp, normu_q; + Word32 L_tmp; + + Word16 pu_e[FOA_CHANNELS]; + Copy32( px_fx, pu_fx, sizex ); + set16_fx( pu_e, sub( 31, px_q ), sizex ); + Word64 L64_sum = 1; + move64(); + FOR( Word16 k = 0; k < sizex; k++ ) + { + L64_sum = W_mac_32_32( L64_sum, pu_fx[k], pu_fx[k] ); + } + Word16 norm = W_norm( L64_sum ); + L64_sum = W_shl( L64_sum, norm ); + *normu_fx = W_extract_h( L64_sum ); // ener_side_q + normu_q = sub( 31, sub( 31, sub( add( add( shl( px_q, 1 ), 1 ), norm ), 32 ) ) ); + move32(); + + exp = sub( Q31, normu_q ); + ( *normu_fx ) = Sqrt32( *normu_fx, &exp ); + move32(); + normu_q = sub( Q31, exp ); + + IF( ( *normu_fx ) == 0 ) + { + pu_fx[0] = SQRT2_FIXED; // same q as other elements + pu_e[0] = 1; + move32(); + move16(); + } + ELSE + { + tmp = BASOP_Util_Divide3232_Scale( 1073741824, *normu_fx, &exp ); // Q30 + px_q, 1073741824 ->1 in Q30 + exp = add( exp, sub( 1, sub( 31, normu_q ) ) ); + + Word32 rcp_fx = L_deposit_h( tmp ); + Word16 rcp_q = sub( Q31, exp ); + + rcp_fx = L_shr( rcp_fx, sub( rcp_q, Q31 ) ); // making rcp_fx in Q31 + FOR( i = 0; i < sizex; i++ ) + { + norm = norm_l( pu_fx[i] ); + L_tmp = L_shl( pu_fx[i], norm ); + pu_fx[i] = Mpy_32_32( L_tmp, rcp_fx ); // px_q + Q31 - Q31 -> px_q + pu_e[i] = sub( 31, add( px_q, norm ) ); + move32(); + move16(); + } + + IF( pu_fx[0] >= 0 ) + { + pu_fx[0] = L_add( pu_fx[0], L_shl( 1, 31 - pu_e[0] ) ); + ( *normu_fx ) = L_negate( *normu_fx ); + + move32(); + move32(); + } + ELSE + { + pu_fx[0] = L_sub( pu_fx[0], L_shl( 1, 31 - pu_e[0] ) ); + move32(); + } + + Word16 exp2, exp1 = pu_e[0]; + move16(); + L_tmp = Sqrt32( L_abs( pu_fx[0] ), &exp1 ); + tmp = BASOP_Util_Divide3232_Scale( 2147483647, L_add( L_tmp, EPSILON_FX ), &exp ); // 1 in Q31 + exp = add( exp, sub( 0, exp1 ) ); + L_tmp = L_deposit_h( tmp ); + rcp_fx = BASOP_Util_Add_Mant32Exp( 0, 0, L_tmp, exp, &exp2 ); + FOR( i = 0; i < sizex; i++ ) + { + pu_fx[i] = Mpy_32_32( pu_fx[i], rcp_fx ); // pu_e[i] + exp2 + pu_fx[i] = L_shl( pu_fx[i], exp2 ); // pu_e[i] + exp2 + move32(); + move32(); + } + + Word16 max_e = pu_e[0]; + move16(); + FOR( i = 0; i < sizex; i++ ) + { + IF( GT_16( pu_e[i], max_e ) ) + { + max_e = pu_e[i]; + move16(); + } + } + + FOR( i = 0; i < sizex; i++ ) + { + pu_fx[i] = L_shr( pu_fx[i], sub( max_e, pu_e[i] ) ); // max_e + move32(); + } + *pu_fx_q = sub( 31, max_e ); + *q_normu = normu_q; + move32(); + move16(); + } + + return; +} static void house_qr( const float *pA, @@ -269,6 +470,150 @@ static void house_qr( } +#ifdef IVAS_FLOAT_FIXED +static void house_qr_fx( + const Word32 *pA_fx, // Q: pA_q + Word16 pA_q, + Word32 *pQ_fx, // Q: Q31 + Word32 *pR_fx, // Q: pA_q + const Word16 n ) +{ + Word16 n_rows = FOA_CHANNELS; + move16(); + Word16 pu_fx_q = 0, pR_fx_q, exp2; + move16(); + Word16 i, j, k, c, s, r; + Word32 A_fx[FOA_CHANNELS * FOA_CHANNELS]; + Word32 U_fx[FOA_CHANNELS * FOA_CHANNELS]; + Word16 U_e[FOA_CHANNELS * FOA_CHANNELS]; + Word32 pu_fx[FOA_CHANNELS]; + Word16 pv_exp[FOA_CHANNELS]; + Word32 pa_fx[FOA_CHANNELS]; + Word16 tmp_e; + Word32 pv_fx[FOA_CHANNELS], L_tmp1; + + + Copy32( pA_fx, A_fx, FOA_CHANNELS * FOA_CHANNELS ); + set_zero_fx( U_fx, FOA_CHANNELS * FOA_CHANNELS ); + set16_fx( U_e, 0, FOA_CHANNELS * FOA_CHANNELS ); + set_zero_fx( pR_fx, FOA_CHANNELS * FOA_CHANNELS ); + FOR( k = 0; k < n_rows; k++ ) + { + FOR( i = 0; i < n_rows; i++ ) + { + pa_fx[i] = A_fx[i * n + k]; // pA_q + move32(); + } + + house_refl_fx( &pa_fx[k], pA_q, sub( n_rows, k ), pu_fx, &pu_fx_q, &pR_fx[k * n_rows + k], &pR_fx_q ); + pR_fx[k * n_rows + k] = L_shr( pR_fx[k * n_rows + k], sub( pR_fx_q, pA_q ) ); // pA_q + move32(); + + + U_fx[k * n_rows + k] = pu_fx[0]; // pu_fx_q + U_e[k * n_rows + k] = sub( 31, pu_fx_q ); // pu_fx_q + move32(); + move16(); + FOR( c = k + 1; c < n_rows; c++ ) + { + FOR( i = 0; i < n_rows; i++ ) + { + pa_fx[i] = A_fx[i * n + c]; + move32(); + } + + Word64 L64_sum = 1; + move64(); + Word16 norm; + FOR( Word16 l = 0; l < n_rows - k; l++ ) + { + L64_sum = W_mac_32_32( L64_sum, pa_fx[k + l], pu_fx[l] ); + } + norm = W_norm( L64_sum ); + L64_sum = W_shl( L64_sum, norm ); + pv_fx[c - k - 1] = W_extract_h( L64_sum ); // pv_exp + pv_exp[c - k - 1] = sub( 31, sub( add( add( add( pu_fx_q, pA_q ), 1 ), norm ), 32 ) ); + U_fx[c * n_rows + k] = pu_fx[c - k]; // pu_fx_q + U_e[c * n_rows + k] = sub( 31, pu_fx_q ); // pu_fx_q + move32(); + move32(); + move16(); + move16(); + } + + i = 0; + move16(); + FOR( s = k; s < n_rows; s++ ) + { + j = 0; + move16(); + FOR( r = k + 1; r < n_rows; r++ ) + { + + A_fx[s * n_rows + r] = BASOP_Util_Add_Mant32Exp( A_fx[s * n_rows + r], sub( 31, pA_q ), L_negate( Mpy_32_32( pv_fx[j], pu_fx[i] ) ), add( sub( 31, pu_fx_q ), pv_exp[j] ), &exp2 ); + A_fx[s * n_rows + r] = L_shr_sat( A_fx[s * n_rows + r], sub( sub( 31, exp2 ), pA_q ) ); + move32(); + j = add( j, 1 ); + } + i = add( i, 1 ); + } + + FOR( r = k + 1; r < n_rows; r++ ) + { + pR_fx[k * n_rows + r] = A_fx[k * n_rows + r]; // pA_q + move32(); + } + } + + eye_matrix_fx32( pQ_fx, FOA_CHANNELS, ONE_IN_Q31 ); // 1 in Q31 + + FOR( k = FOA_CHANNELS - 1; k >= 0; k-- ) + { + FOR( i = 0; i < n_rows; i++ ) + { + pu_fx[i] = L_shr( U_fx[i * n + k], sub( sub( 31, U_e[i * n + k] ), pu_fx_q ) ); + move32(); + } + + FOR( s = k; s < n_rows; s++ ) + { + FOR( i = 0; i < n_rows; i++ ) + { + pa_fx[i] = pQ_fx[i * n + s]; + move32(); + } + + + pv_fx[s - k] = dotp_fixed( &pu_fx[k], &pa_fx[k], sub( n_rows, k ) ); // pu_fx_q + Q31 - Q31 + pv_exp[s - k] = sub( 31, pu_fx_q ); + move32(); + move16(); + } + FOR( s = k; s < n_rows; s++ ) + { + FOR( r = k; r < n_rows; r++ ) + { + L_tmp1 = BASOP_Util_Add_Mant32Exp( pQ_fx[s * n_rows + r], 0, L_negate( Mpy_32_32( pv_fx[r - k], U_fx[s * n_rows + k] ) ), pv_exp[r - k] + U_e[s * n_rows + k], &tmp_e ); // Q31 + IF( tmp_e > 0 ) + { + pQ_fx[s * n_rows + r] = check_bounds_l( L_tmp1, L_negate( L_shr( MAX_32, tmp_e ) ), L_shr( MAX_32, tmp_e ) ); // Q31 + pQ_fx[s * n_rows + r] = L_shl( pQ_fx[s * n_rows + r], tmp_e ); // Q31 + move32(); + move32(); + } + ELSE + { + pQ_fx[s * n_rows + r] = L_shl( L_tmp1, tmp_e ); // Q31 + move32(); + } + } + } + } + + return; +} +#endif + /*---------------------------------------------------------------------* * eig_qr() * @@ -308,7 +653,6 @@ void eig_qr( } set_zero( Vals, n ); - while ( breakcnd == 0 ) { iter_num++; @@ -328,7 +672,6 @@ void eig_qr( { breakcnd = 1; } - house_qr( Ak, Qk, Rk, n ); matrix_product( Qk, n, n, 0, Rk, n, n, 0, Ak ); @@ -346,6 +689,95 @@ void eig_qr( return; } +#ifdef IVAS_FLOAT_FIXED +void eig_qr_fx( + const Word32 *A_fx, // A_q + Word16 A_q, + const Word16 num_iter, + Word32 *EV_fx, // Q31 + Word32 *Vals_fx, // A_q + const Word16 n ) +{ + Word16 i; + Word16 breakcnd, iter_num; + + Word32 Ak_fx[FOA_CHANNELS * FOA_CHANNELS], Qk_fx[FOA_CHANNELS * FOA_CHANNELS], Rk_fx[FOA_CHANNELS * FOA_CHANNELS], D_fx[FOA_CHANNELS * FOA_CHANNELS], d_fx; + Word16 d_q, exp; + + assert( n <= FOA_CHANNELS ); + breakcnd = 1; + iter_num = 0; + move16(); + move16(); + + /* check zero matrix */ + d_fx = dotp_fixed( A_fx, A_fx, n * n ); + d_q = sub( add( A_q, A_q ), 31 ); + + if ( d_fx != 0 ) + { + breakcnd = 0; + move16(); + } + /* duplicate */ + Copy32( A_fx, Ak_fx, n * n ); + + /* identity */ + set_zero_fx( EV_fx, n * n ); + + FOR( i = 0; i < n; i++ ) + { + EV_fx[i * n + i] = 2147483647; // 1 in Q31 + move32(); + } + set_zero_fx( Vals_fx, n ); + + WHILE( breakcnd == 0 ) + { + iter_num = add( iter_num, 1 ); + + Copy32( Ak_fx, D_fx, n * n ); + + /* set diagonal */ + + FOR( i = 0; i < n; i++ ) + { + D_fx[i * n + i] = Vals_fx[i]; + move32(); + } + + /* stop condition */ + d_fx = dotp_fixed_guarded( D_fx, D_fx, n * n ); + d_q = sub( sub( add( A_q, A_q ), 31 ), find_guarded_bits_fx( n * n ) ); + exp = sub( 31, d_q ); + d_fx = Sqrt32( d_fx, &exp ); + + test(); + if ( ( d_fx < 0 ) || GE_16( iter_num, num_iter ) ) + { + breakcnd = 1; + move16(); + } + + house_qr_fx( Ak_fx, A_q, Qk_fx, Rk_fx, n ); + + matrix_product_fx( Qk_fx, n, n, 0, Rk_fx, n, n, 0, Ak_fx ); + matrix_product_mant_exp_fx( Qk_fx, 0, n, n, 0, EV_fx, 0, n, n, 0, D_fx, &exp ); + Scale_sig32( D_fx, imult1616( n, n ), exp ); + + Copy32( D_fx, EV_fx, imult1616( n, n ) ); + } + + + /* get diagonal */ + FOR( i = 0; i < n; i++ ) + { + Vals_fx[i] = Ak_fx[i * n + i]; + move32(); + } + return; +} +#endif /*---------------------------------------------------------------------* * exhst_4x4() @@ -405,6 +837,73 @@ void exhst_4x4( } +#ifdef IVAS_FLOAT_FIXED +void exhst_4x4_fx( + Word16 *cost_mtx, // Q + Word16 *path, + const Word16 maximize ) +{ + Word16 i, j, k, l; + Word16 opt_val, cost; + + IF( maximize == 0 ) + { + opt_val = MAX_16; + move16(); + } + ELSE + { + opt_val = -MAX_16; + move16(); + } + + FOR( i = 0; i < 1; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + IF( NE_16( j, i ) ) + { + FOR( k = 0; k < 4; k++ ) + { + test(); + IF( NE_16( k, i ) && NE_16( k, j ) ) + { + FOR( l = 0; l < 4; l++ ) + { + test(); + test(); + IF( NE_16( l, i ) && NE_16( l, j ) && NE_16( l, k ) ) + { + cost = add( add( cost_mtx[0 * 4 + i], cost_mtx[1 * 4 + j] ), add( cost_mtx[2 * 4 + k], cost_mtx[3 * 4 + l] ) ); + test(); + test(); + test(); + IF( ( ( maximize == 0 ) && GT_16( opt_val, cost ) ) || ( ( maximize != 0 ) && LT_16( opt_val, cost ) ) ) + { + opt_val = cost; + path[0] = i; + path[1] = j; + path[2] = k; + path[3] = l; + move16(); + move16(); + move16(); + move16(); + move16(); + } + } + } + } + } + } + } + } + + return; +} + +#endif + /*---------------------------------------------------------------------* * mat2dquat() * @@ -497,6 +996,141 @@ void mat2dquat( return; } +#ifdef IVAS_FLOAT_FIXED +void mat2dquat_fx( + const Word16 *a, // Q15 + Word16 *ql, // Q15 + Word16 *qr // Q15 +) +{ + Word16 AM[16], tmp_l, tmp_r, temp, ql_max, qr_max; + Word16 i, j, k, i_ql, i_qr, tmp_l_e, tmp_r_e; + Word32 M2_fx[16]; + + + /* compute associate matrix */ + + /* Q: Q15*/ + AM[0 * 4 + 0] = check_bound( L_shr( L_add( L_add( L_add( a[0 * 4 + 0], a[1 * 4 + 1] ), a[2 * 4 + 2] ), a[3 * 4 + 3] ), 2 ) ); + AM[1 * 4 + 0] = check_bound( L_shr( L_sub( L_add( L_sub( a[1 * 4 + 0], a[0 * 4 + 1] ), a[3 * 4 + 2] ), a[2 * 4 + 3] ), 2 ) ); + AM[2 * 4 + 0] = check_bound( L_shr( L_add( L_sub( L_sub( a[2 * 4 + 0], a[3 * 4 + 1] ), a[0 * 4 + 2] ), a[1 * 4 + 3] ), 2 ) ); + AM[3 * 4 + 0] = check_bound( L_shr( L_sub( L_sub( L_add( a[3 * 4 + 0], a[2 * 4 + 1] ), a[1 * 4 + 2] ), a[0 * 4 + 3] ), 2 ) ); + AM[0 * 4 + 1] = check_bound( L_shr( L_add( L_sub( L_sub( a[1 * 4 + 0], a[0 * 4 + 1] ), a[3 * 4 + 2] ), a[2 * 4 + 3] ), 2 ) ); + AM[1 * 4 + 1] = check_bound( L_shr( L_add( L_add( L_sub( -a[0 * 4 + 0], a[1 * 4 + 1] ), a[2 * 4 + 2] ), a[3 * 4 + 3] ), 2 ) ); + AM[2 * 4 + 1] = check_bound( L_shr( L_sub( L_sub( L_sub( -a[3 * 4 + 0], a[2 * 4 + 1] ), a[1 * 4 + 2] ), a[0 * 4 + 3] ), 2 ) ); + AM[3 * 4 + 1] = check_bound( L_shr( L_sub( L_add( L_sub( a[2 * 4 + 0], a[3 * 4 + 1] ), a[0 * 4 + 2] ), a[1 * 4 + 3] ), 2 ) ); + AM[0 * 4 + 2] = check_bound( L_shr( L_sub( L_sub( L_add( a[2 * 4 + 0], a[3 * 4 + 1] ), a[0 * 4 + 2] ), a[1 * 4 + 3] ), 2 ) ); + AM[1 * 4 + 2] = check_bound( L_shr( L_add( L_sub( L_sub( a[3 * 4 + 0], a[2 * 4 + 1] ), a[1 * 4 + 2] ), a[0 * 4 + 3] ), 2 ) ); + AM[2 * 4 + 2] = check_bound( L_shr( L_add( L_sub( L_add( -a[0 * 4 + 0], a[1 * 4 + 1] ), a[2 * 4 + 2] ), a[3 * 4 + 3] ), 2 ) ); + AM[3 * 4 + 2] = check_bound( L_shr( L_sub( L_sub( L_sub( -a[1 * 4 + 0], a[0 * 4 + 1] ), a[3 * 4 + 2] ), a[2 * 4 + 3] ), 2 ) ); + AM[0 * 4 + 3] = check_bound( L_shr( L_sub( L_add( L_sub( a[3 * 4 + 0], a[2 * 4 + 1] ), a[1 * 4 + 2] ), a[0 * 4 + 3] ), 2 ) ); + AM[1 * 4 + 3] = check_bound( L_shr( L_sub( L_sub( L_sub( -a[2 * 4 + 0], a[3 * 4 + 1] ), a[0 * 4 + 2] ), a[1 * 4 + 3] ), 2 ) ); + AM[2 * 4 + 3] = check_bound( L_shr( L_sub( L_sub( L_add( a[1 * 4 + 0], a[0 * 4 + 1] ), a[3 * 4 + 2] ), a[2 * 4 + 3] ), 2 ) ); + AM[3 * 4 + 3] = check_bound( L_shr( L_sub( L_add( L_add( -a[0 * 4 + 0], a[1 * 4 + 1] ), a[2 * 4 + 2] ), a[3 * 4 + 3] ), 2 ) ); + + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + /* compute squared matrix */ + FOR( i = 0; i < 16; i++ ) + { + M2_fx[i] = L_shr( L_mult0( AM[i], AM[i] ), 15 ); // Q15 + move16(); + } + + /* determine (absolute) left and right terms */ + i_ql = 0; + i_qr = 0; + ql_max = MIN_16; + qr_max = MIN_16; + move16(); + move16(); + move16(); + move16(); + + FOR( i = 0; i < 4; i++ ) + { + tmp_l = 0; + tmp_r = 0; + move16(); + move16(); + tmp_r_e = 0; + tmp_l_e = 0; + move16(); + move16(); + FOR( j = 0; j < 4; j++ ) + { + /* sum over row */ + tmp_l_e = BASOP_Util_Add_MantExp( tmp_l, tmp_l_e, check_bound( M2_fx[i * 4 + j] ), 0, &tmp_l ); + /* sum over column */ + tmp_r_e = BASOP_Util_Add_MantExp( tmp_r, tmp_r_e, check_bound( M2_fx[j * 4 + i] ), 0, &tmp_r ); + } + + + ql[i] = Sqrt16( tmp_l, &tmp_l_e ); + ql[i] = check_bound( L_shl( ql[i], tmp_l_e ) ); // Q15 + move16(); + move16(); + IF( GT_16( ql[i], ql_max ) ) + { + ql_max = ql[i]; + i_ql = i; + move16(); + move16(); + } + + qr[i] = Sqrt16( tmp_r, &tmp_r_e ); + qr[i] = check_bound( L_shl( qr[i], tmp_r_e ) ); // Q15 + move16(); + move16(); + IF( GT_16( qr[i], qr_max ) ) + { + qr_max = qr[i]; + i_qr = i; + move16(); + move16(); + } + } + + /* set signs */ + FOR( k = 0; k < 4; k++ ) + { + IF( AM[i_ql * 4 + k] < 0 ) + { + qr[k] = negate( qr[k] ); + move16(); + } + } + + FOR( k = 0; k < 4; k++ ) + { + temp = mult( AM[k * 4 + i_qr], mult( ql[k], qr[i_qr] ) ); // Q15 + IF( temp < 0 ) + { + ql[k] = negate( ql[k] ); + move16(); + } + } + + return; +} + +#endif /*---------------------------------------------------------------------* * dquat2mat() @@ -560,27 +1194,13 @@ void dquat2mat( return; } -static Word16 check_bound( Word32 tmp ) -{ - IF( GT_32( tmp, MAX16B ) ) - { - return MAX16B; - } - ELSE IF( LT_32( tmp, MIN16B ) ) - { - return MIN16B; - } - ELSE - { - return extract_l( tmp ); - } -} - + #ifdef IVAS_FLOAT_FIXED void dquat2mat_fx( - const Word16 *ql, - const Word16 *qr, - Word16 *m ) + const Word16 *ql, // Q15 + const Word16 *qr, // Q15 + Word16 *m // Q15 +) { Word16 a, b, c, d; Word16 w, x, y, z; @@ -815,6 +1435,54 @@ float mat_det4( return d; } +Word16 mat_det4_fx( + const Word16 *m // Q15 +) +{ + Word16 d; + +#define a11 m[0] +#define a12 m[1] +#define a13 m[2] +#define a14 m[3] +#define a21 m[4] +#define a22 m[5] +#define a23 m[6] +#define a24 m[7] +#define a31 m[8] +#define a32 m[9] +#define a33 m[10] +#define a34 m[11] +#define a41 m[12] +#define a42 m[13] +#define a43 m[14] +#define a44 m[15] + + /* 4! = 24 terms -> complexity = 24x(4 INDIRECT + 3 MULT) + 23 ADD */ + d = add( add( add( sub( sub( sub( sub( sub( sub( add( add( add( add( add( add( sub( sub( sub( sub( sub( sub( add( add( mult( mult( a11, a22 ), mult( a33, a44 ) ), mult( mult( a11, a24 ), mult( a32, a43 ) ) ), mult( mult( a11, a23 ), mult( a34, a42 ) ) ), mult( mult( a11, a24 ), mult( a33, a42 ) ) ), mult( mult( a11, a22 ), mult( a34, a43 ) ) ), + mult( mult( a11, a23 ), mult( a32, a44 ) ) ), + mult( mult( a12, a21 ), mult( a33, a44 ) ) ), + mult( mult( a12, a23 ), mult( a34, a41 ) ) ), + mult( mult( a12, a24 ), mult( a31, a43 ) ) ), + mult( mult( a12, a24 ), mult( a33, a41 ) ) ), + mult( mult( a12, a21 ), mult( a34, a43 ) ) ), + mult( mult( a12, a23 ), mult( a31, a44 ) ) ), + mult( mult( a13, a21 ), mult( a32, a44 ) ) ), + mult( mult( a13, a22 ), mult( a34, a41 ) ) ), + mult( mult( a13, a24 ), mult( a31, a42 ) ) ), + mult( mult( a13, a24 ), mult( a32, a41 ) ) ), + mult( mult( a13, a21 ), mult( a34, a42 ) ) ), + mult( mult( a13, a22 ), mult( a31, a44 ) ) ), + mult( mult( a14, a21 ), mult( a32, a43 ) ) ), + mult( mult( a14, a22 ), mult( a33, a41 ) ) ), + mult( mult( a14, a23 ), mult( a31, a42 ) ) ), + mult( mult( a14, a23 ), mult( a32, a41 ) ) ), + mult( mult( a14, a21 ), mult( a33, a42 ) ) ), + mult( mult( a14, a22 ), mult( a31, a43 ) ) ); + + return d; // Q15 +} + static void norm_quat( float *q ) @@ -994,6 +1662,32 @@ static float acos_clip( return ph; } +#ifdef IVAS_FLOAT_FIXED +static Word16 acos_clip_fx( + Word16 v_fx // Q15 +) +{ + Word16 ph_fx; + + v_fx = check_bounds_s_fx( v_fx, -32767, 32767 ); + + Word32 tmp1_fx, tmp2_fx; + Word16 tmp1_e, tmp2_e; + tmp1_fx = L_sub( 2147483647, L_deposit_h( mult( v_fx, v_fx ) ) ); // Q31 + tmp1_e = 0; + tmp2_e = 0; + move16(); + move16(); + tmp1_fx = Sqrt32( tmp1_fx, &tmp1_e ); // Q31 - tmp1_e + tmp2_fx = L_deposit_h( v_fx ); // Q31 + + ph_fx = BASOP_util_atan2( tmp1_fx, tmp2_fx, sub( tmp1_e, tmp2_e ) ); // Q13 + + + return ph_fx; // Q13 +} +#endif + static void sp2cart( const float ph1, @@ -1015,10 +1709,11 @@ static void sp2cart( } #ifdef IVAS_FLOAT_FIXED static void sp2cart_fx( - const Word16 ph1, - const Word16 ph2, - const Word16 ph3, - Word16 *q ) + const Word16 ph1, // Q12 + const Word16 ph2, // Q12 + const Word16 ph3, // Q12 + Word16 *q // Q15 +) { Word16 s1, s2, s1s2; Word16 sin_ph3, cos_ph3; @@ -1065,6 +1760,25 @@ static int16_t calc_n2( return n2; } +#ifdef IVAS_FLOAT_FIXED +static Word16 calc_n2_fx( + const Word16 ph1 // Q15 +) +{ + Word16 n2; + + n2 = extract_l( L_shr( L_mult0( 90, getSinWord16( ph1 ) ), 15 ) ); // Q15 + Q0 - Q15 -> Q0 + + if ( n2 % 2 == 0 ) + { + n2 = add( n2, 1 ); + } + + return n2; // Q0 +} + +#endif + static int16_t calc_n3( const float ph1, const float ph2 ) @@ -1173,6 +1887,87 @@ static void q_ang_2surv( return; } +#ifdef IVAS_FLOAT_FIXED +static void q_ang_2surv_fx( + const Word16 a_fx, // Q13 + const Word16 N, + Word16 *a_q_fx, // Q15 + Word16 *index ) +{ + Word16 d_fx, v_fx, d_e, v_e; + Word16 temp; + + IF( EQ_16( N, 1 ) ) + { + index[0] = 0; + index[1] = 0; + + a_q_fx[0] = 0; + a_q_fx[1] = 0; + move16(); + move16(); + move16(); + move16(); + return; + } + + d_fx = BASOP_Util_Divide1616_Scale( EVS_PI_FX, sub( N, 1 ), &d_e ); + d_e = add( d_e, ( 2 - 15 ) ); + IF( GE_16( a_fx, EVS_PI_FX ) ) + { + index[0] = sub( N, 1 ); + index[1] = sub( N, 2 ); + move16(); + move16(); + } + ELSE + { + IF( a_fx <= 0 ) + { + index[0] = 0; + index[1] = 1; + move16(); + move16(); + } + ELSE + { + v_fx = BASOP_Util_Divide1616_Scale( a_fx, d_fx, &v_e ); + v_e = add( v_e, sub( 2, d_e ) ); + + index[0] = shr( v_fx, sub( Q15, v_e ) ); + index[1] = add( shr( v_fx, sub( Q15, v_e ) ), 1 ); + move16(); + move16(); + + IF( EQ_16( index[0], index[1] ) ) + { + /*printf("warning: identical indices\n"); */ + } + ELSE + { + IF( LT_16( sub( shr( v_fx, sub( Q15, v_e ) ), index[0] ), sub( index[1], shr( v_fx, sub( Q15, v_e ) ) ) ) ) + { + temp = index[1]; + index[1] = index[0]; + index[0] = temp; + move16(); + move16(); + move16(); + } + } + } + } + + a_q_fx[0] = extract_l( L_shr( L_mult0( index[0], d_fx ), 2 - d_e ) ); // Q13 + a_q_fx[1] = extract_l( L_shr( L_mult0( index[1], d_fx ), 2 - d_e ) ); // Q13 + move16(); + move16(); + + return; +} + + +#endif static void q_ang_circ( const float a, @@ -1219,6 +2014,64 @@ static void q_ang_circ( } +#ifdef IVAS_FLOAT_FIXED +static void q_ang_circ_fx( + const Word16 a_fx, // Q13 + const Word16 N, + Word16 *a_q_fx, // Q12 + Word16 *index ) +{ + Word16 d_fx, d_e, scale; + IF( EQ_16( N, 1 ) ) + { + *a_q_fx = 0; + *index = 0; + move16(); + move16(); + return; + } + + d_fx = BASOP_Util_Divide1616_Scale( EVS_PI_FX, N, &d_e ); // Q14 + d_e = add( d_e, ( 3 - 15 ) ); + + IF( GE_16( a_fx, EVS_PI_FX ) ) + { + *index = N; + move16(); + } + ELSE + { + IF( a_fx <= 0 ) + { + *index = 0; + move16(); + } + ELSE + { + *index = BASOP_Util_Divide1616_Scale( a_fx, d_fx, &scale ); + scale = add( scale, sub( 3, d_e ) ); + *index = shr( *index, sub( 15, scale ) ); + move16(); + move16(); + } + } + + if ( EQ_16( *index, N ) ) + { + *index = 0; + move16(); + } + + assert( ( *index >= 0 ) && ( *index <= ( N - 1 ) ) ); + d_fx = shl( d_fx, sub( 12, sub( 15, d_e ) ) ); + *a_q_fx = extract_l( L_mult0( *index, d_fx ) ); + move16(); + + return; +} + +#endif + static int16_t sel_q( const float *q, const float *q_cand, @@ -1254,6 +2107,49 @@ static int16_t sel_q( } +#ifdef IVAS_FLOAT_FIXED +static Word16 sel_q_fx( + const Word16 *q, // Q12 + const Word16 *q_cand, // Q12 + const Word16 n ) +{ + Word16 i, i_min, j, temp; + Word32 d, d_min; + const Word16 *p; + + i_min = -1; + move16(); + d_min = MAX_32; + move32(); + p = q_cand; + + FOR( i = 0; i < n; i++ ) + { + d = 0; + move16(); + FOR( j = 0; j < 4; j++ ) + { + temp = sub( q[j], p[j] ); + d = L_add( d, L_mult0( temp, temp ) ); + } + + IF( LT_32( d, d_min ) ) + { + d_min = d; + i_min = i; + move16(); + move16(); + } + p += 4; + } + assert( i_min >= 0 ); + + return i_min; +} + + +#endif + static int16_t get_pca_offset_n2( const int16_t index1 ) { @@ -1403,6 +2299,143 @@ void pca_enc_s3( return; } +#ifdef IVAS_FLOAT_FIXED +void pca_enc_s3_fx( + Word16 *q_fx, // Q15 + Word32 *index ) +{ + Word16 n1, n2[2], n3[4]; + Word16 ind1[2], ind2[4], ind3[4], index1, index2, index3; + Word16 i, j; + Word16 ph1_fx, ph2_fx, ph3_fx, r_fx, v_fx, tmp, r_e; + Word16 ph1_q_fx[2], ph2_q_fx[4], ph3_q_fx[4], v_e; + Word16 q_cand_fx[4 * 4]; + + n1 = IVAS_PCA_N1; + move16(); + ph1_fx = acos_clip_fx( q_fx[0] ); // Q13 + + IF( LT_16( abs_s( sub( abs_s( q_fx[0] ), 32767 ) ), IVAS_PCA_QUAT_EPS_FX ) ) + { + IF( q_fx[0] > 0 ) + { + index1 = 0; + *ph1_q_fx = 0; + move16(); + move16(); + } + ELSE + { + index1 = sub( n1, 1 ); + *ph1_q_fx = EVS_PI_FX; // Q13 + move16(); + move16(); + } + + sp2cart_fx( *ph1_q_fx, 0, 0, q_fx ); + + *index = ivas_pca_offset_index1[index1]; + move32(); + + return; + } + + q_ang_2surv_fx( ph1_fx, n1, ph1_q_fx, ind1 ); + + tmp = add( add( mult( q_fx[1], q_fx[1] ), mult( q_fx[2], q_fx[2] ) ), mult( q_fx[3], q_fx[3] ) ); // Q15 + Q15 - Q15 -> Q15 + r_e = 0; + move16(); + r_fx = Sqrt16( tmp, &r_e ); + v_fx = BASOP_Util_Divide1616_Scale( q_fx[1], r_fx, &v_e ); + v_e = sub( v_e, sub( 0, r_e ) ); + v_fx = shr( v_fx, sub( 0, v_e ) ); + ph2_fx = acos_clip_fx( v_fx ); // Q13 + + IF( LT_16( sub( abs_s( v_fx ), MAX_16 ), IVAS_PCA_QUAT_EPS_FX ) ) + { + FOR( i = 0; i < 2; i++ ) + { + IF( v_fx > 0 ) + { + ph2_q_fx[i] = 0; + ind2[i] = 0; + move16(); + move16(); + } + ELSE + { + ph2_q_fx[i] = EVS_PI_FX; + ind2[i] = sub( n2[i], 1 ); + move16(); + move16(); + } + + sp2cart_fx( ph1_q_fx[i], ph2_q_fx[i], 0, &q_cand_fx[4 * i] ); + } + + j = sel_q_fx( q_fx, q_cand_fx, 2 ); + + Copy( q_cand_fx + 4 * j, q_fx, 4 ); + index1 = ind1[j]; + index2 = ind2[j]; + move16(); + move16(); + + index2 = add( index2, get_pca_offset_n2( index1 ) ); + + *index = L_add( ivas_pca_offset_index1[index1], ivas_pca_offset_index2[index2] ); + move32(); + + return; + } + + FOR( i = 0; i < 2; i++ ) + { + n2[i] = calc_n2_fx( ph1_q_fx[i] ); + move16(); + q_ang_2surv_fx( ph2_fx, n2[i], ph2_q_fx + 2 * i, ind2 + 2 * i ); + } + + r_fx = Sqrt16( add( mult( q_fx[2], q_fx[2] ), mult( q_fx[3], q_fx[3] ) ), &r_e ); + + + v_fx = BASOP_Util_Divide1616_Scale( q_fx[2], r_fx, &v_e ); + v_e = add( v_e, sub( 0, r_e ) ); + v_fx = shr( v_fx, sub( 0, v_e ) ); // Q15 + ph3_fx = acos_clip_fx( v_fx ); // Q13 + + IF( q_fx[3] < 0 ) + { + ph3_fx = sub( EVS_PI_FX, shr( ph3_fx, 1 ) ); // Q12 + } + + FOR( i = 0; i < 4; i++ ) + { + n3[i] = calc_n3_fx( ph1_q_fx[i >> 1], ph2_q_fx[i] ); + move16(); + q_ang_circ_fx( ph3_fx, n3[i], ph3_q_fx + i, ind3 + i ); + sp2cart_fx( ph1_q_fx[i >> 1], ph2_q_fx[i], ph3_q_fx[i], q_cand_fx + ( 4 * i ) ); + } + + j = sel_q_fx( q_fx, q_cand_fx, 4 ); + + Copy( q_cand_fx + 4 * j, q_fx, 4 ); + + index1 = ind1[j >> 1]; + index2 = ind2[j]; + index3 = ind3[j]; + move16(); + move16(); + move16(); + index2 = add( index2, get_pca_offset_n2( index1 ) ); + + *index = L_add( L_add( ivas_pca_offset_index1[index1], ivas_pca_offset_index2[index2] ), index3 ); + move32(); + + return; +} +#endif + /*---------------------------------------------------------------------* * pca_dec_s3() * @@ -1515,12 +2548,6 @@ void pca_dec_s3_fx( assert( index1 > -1 ); - /* - n1 = IVAS_PCA_N1; - d = EVS_PI / ( n1 - 1 ); - ph1_q = index1 * d; - n2 = calc_n2( ph1_q ); - */ ph1_q_fx = ph1_q_n2_tbl[index1][0]; move16(); n2 = ph1_q_n2_tbl[index1][1]; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b39aada25f60102083cf97987f48a9570e2f3838..924a554d664c5808e74ad00dc120a3327a982041 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -159,7 +159,7 @@ void destroy_cpe_enc( void ivas_mct_enc_close( MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ ); -#ifndef IVAS_FLOAT_FIXED + ivas_error ivas_corecoder_enc_reconfig( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const int16_t nSCE_old, /* i : number of SCEs in previous frame */ @@ -169,7 +169,7 @@ ivas_error ivas_corecoder_enc_reconfig( const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */ const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ ); -#endif + ivas_error ivas_sce_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const int16_t sce_id, /* i : SCE # identifier */ @@ -811,21 +811,19 @@ void ivas_smc_mode_selection( ); /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ -#ifndef IVAS_FLOAT_FIXED int16_t ivas_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - const float *inp, /* i : new input signal */ - const float *wsp, /* i : input weighted signal */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - const float *pitch_fr, /* i : fraction pitch values */ - const float *voicing_fr, /* i : fractional voicing values */ - const float currFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac, /* i : LP filter stability */ - float *res_cod_SNR_M, - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + Encoder_State *st, /* i/o: encoder state structure */ + const float *inp, /* i : new input signal */ + const float *wsp, /* i : input weighted signal */ + const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ + const float *pitch_fr, /* i : fraction pitch values */ + const float *voicing_fr, /* i : fractional voicing values */ + const float currFlatness, /* i : flatness */ + const float lsp_mid[M], /* i : LSPs at the middle of the frame */ + const float stab_fac, /* i : LP filter stability */ + float *res_cod_SNR_M, + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ); -#endif #ifndef IVAS_FLOAT_FIXED void ivas_decision_matrix_enc( @@ -6291,21 +6289,22 @@ void ivas_calc_c_p_coeffs( ); #ifdef IVAS_FLOAT_FIXED void ivas_get_spar_md_from_dirac_fx( - Word32 azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - Word32 ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - Word32 diffuseness[IVAS_MAX_NUM_BANDS], + Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 + Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 + Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS], // Q30 const Word16 n_ts, - Word32 ***mixer_mat, + Word32 ***mixer_mat_fx, + Word16 *q_mixer_mat_fx, ivas_spar_md_t *hSpar_md, ivas_spar_md_com_cfg *hSpar_md_cfg, const Word16 start_band, const Word16 end_band, const Word16 order, const Word16 dtx_vad, - Word32 Wscale_d[IVAS_MAX_NUM_BANDS], + Word32 Wscale_d[IVAS_MAX_NUM_BANDS], // Q29 const UWord8 useLowerRes, const Word16 active_w_vlbr, - const Word16 dyn_active_w_flag + const Word16 dyn_active_w_flag ); #endif void ivas_get_spar_md_from_dirac( @@ -6647,6 +6646,17 @@ void ivas_pca_enc( const int16_t n_channels /* i : number of channels */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_pca_enc_fx( + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + PCA_ENC_STATE *hPCA, /* i : PCA encoder structure */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + Word32 *data_f[8], /* i : input/transformed audio channels Q11 */ + const Word16 input_frame, /* i : input frame length */ + const Word16 n_channels /* i : number of channels */ +); +#endif + void ivas_pca_read_bits( Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ PCA_DEC_STATE *hPCA /* i/o: PCA encoder structure */ @@ -6697,6 +6707,11 @@ void eye_matrix_fx( const Word16 n, const Word16 d ); + +void eye_matrix_fx32( + Word32 *mat, // Q + const Word16 n, + const Word32 d ); // Q #endif void cov_subfr( float **ptr_sig, @@ -6705,6 +6720,14 @@ void cov_subfr( const int16_t len ); +#ifdef IVAS_FLOAT_FIXED +void cov_subfr_fx( + Word32 **ptr_sig_fx, // Q11 + Word64 *r_fx_64, // Q11 + const Word16 n_channels, + const Word16 len ); +#endif + void eig_qr( const float *A, const int16_t num_iter, @@ -6712,16 +6735,39 @@ void eig_qr( const int16_t n ); +#ifdef IVAS_FLOAT_FIXED +void eig_qr_fx( + const Word32 *A_fx, // A_q + Word16 A_q, + const Word16 num_iter, + Word32 *EV_fx, // Q31 + Word32 *Vals_fx, // A_q + const Word16 n ); +#endif + void exhst_4x4( float *cost_mtx, int16_t *path, const int16_t maximize ); +#ifdef IVAS_FLOAT_FIXED +void exhst_4x4_fx( + Word16 *cost_mtx, // Q + Word16 *path, + const Word16 maximize ); +#endif + float mat_det4( const float *m ); +#ifdef IVAS_FLOAT_FIXED +Word16 mat_det4_fx( + const Word16 *m // Q15 +); +#endif + /* quaternion utilities */ void mat2dquat( const float *a, @@ -6729,6 +6775,14 @@ void mat2dquat( float *qr ); +#ifdef IVAS_FLOAT_FIXED +void mat2dquat_fx( + const Word16 *a, // Q15 + Word16 *ql, // Q15 + Word16 *qr // Q15 +); +#endif + void dquat2mat( const float *ql, const float *qr, @@ -6751,6 +6805,7 @@ void pca_interp_preproc( float *ql_interp, float *qr_interp ); + #ifdef IVAS_FLOAT_FIXED void dquat2mat_fx( const Word16 *ql, @@ -6777,6 +6832,13 @@ void pca_enc_s3( int32_t *index ); +#ifdef IVAS_FLOAT_FIXED +void pca_enc_s3_fx( + Word16 *q, // Q15 + Word32 *index +); +#endif + void pca_dec_s3( const int32_t index, float *q diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 291f1649a8bb1a4503a1968a66f6dbfcb5acaaaa..a8d7e76597acb3cfb1b32264f57fed5e1be71c35 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3350,6 +3350,13 @@ UWord16 quantize_direction_fx( const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ ); +Word16 quantize_direction2D_fx( + Word32 phi, /* i : input azimuth value Q22 */ + const Word16 no_cw, /* i : number of bits */ + Word32 *phi_q, /* o : quantized azimuth value Q22 */ + UWord16 *index_phi, /* o : quantized azimuth index */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +); void quantize_direction_frame_fx( IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* o : Q22 */ @@ -3392,4 +3399,17 @@ void ivas_merge_masa_transports_fx( Word32 *data_out_f_fx[], const Word16 input_frame, const Word16 num_transport_channels ); + +void ivas_param_mc_enc_close_fx( + PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */ + const Word32 input_Fs /* i : input sampling rate */ +); + +ivas_error ivas_param_mc_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +ivas_error ivas_param_mc_enc_reconfig_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); #endif diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com.c index 4832a4fd96a09004f37bd8db35cb87a5f1e45984..ab10cd57c495f9caccd8f639aa4d0dd9a7c88d8f 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com.c @@ -41,6 +41,7 @@ #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" +#include "prot_fx.h" #ifdef IVAS_FLOAT_FIXED #include "prot_fx.h" #include "ivas_rom_com_fx.h" @@ -490,7 +491,7 @@ ELSE } } -*phi_hat = L_add( L_add( ( id_phi * delta_phi_fx ), dd_fx ), DEGREE_180_Q_22 ); +*phi_hat = L_add_sat( L_add_sat( ( id_phi * delta_phi_fx ), dd_fx ), DEGREE_180_Q_22 ); move32(); id_phi = add( id_phi, shr( n, 1 ) ); diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index b4f3eee06b24b82d8a095cdaf8fb5e9d80dca4a0..facff366706fbb0c1b0b67a329e6020327185200 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -934,23 +934,10 @@ static void ivas_get_pred_coeffs_fx( FOR( k = start_band; k < end_band; k++ ) { - dm_alpha_e = sub( 31, Q29 ); + dm_alpha_e = 31 - Q29; dm_alpha[k] = Sqrt32( dm_alpha[k], &dm_alpha_e ); move32(); - IF( dm_alpha_e < 0 ) - { - dm_alpha[k] = L_shr( dm_alpha[k], abs_s( dm_alpha_e ) ); - move32(); - dm_alpha_e = 0; - move16(); - } - ELSE IF( dm_alpha_e > 0 ) - { - dm_alpha[k] = L_shl( dm_alpha[k], abs_s( dm_alpha_e ) ); - move32(); - dm_alpha_e = 0; - move16(); - } + div_factor[k] = L_max( dm_alpha[k], 1 ); move32(); @@ -958,7 +945,7 @@ static void ivas_get_pred_coeffs_fx( move32(); IF( s_div < 0 ) { - div_shift = add( 15, s_div ); + div_shift = add( 15, sub( s_div, dm_alpha_e ) ); tmp_shift = Q30; move16(); } @@ -966,7 +953,7 @@ static void ivas_get_pred_coeffs_fx( { div_shift = 15; move16(); - tmp_shift = sub( Q30, s_div ); + tmp_shift = sub( Q30, sub( s_div, dm_alpha_e ) ); } div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift move32(); @@ -1110,17 +1097,17 @@ static void ivas_get_pred_coeffs_fx( den_f = L_add( L_tmp1, L_tmp2 ); // Q29 den_f = L_max( den_f, 1 ); - den_f_e = 29; + den_f_e = 31 - 29; move16(); L_tmp2 = Mpy_32_32( DM_F[b], dm_beta_re ); L_tmp2_q = add( 30, sub( ( sub( shl( tmp_shift, 1 ), 34 ) ), 31 ) ); - L_tmp2 = L_shl( L_tmp2, ( sub( ( sub( 30, dm_alpha_e ) ), L_tmp2_q ) ) ); - L_tmp1 = L_shr( dm_alpha[b], ( sub( ( sub( 31, dm_alpha_e ) ), 30 ) ) ); - L_tmp1 = L_add( L_tmp1, L_tmp2 ); // Q30 + L_tmp2 = L_shl( L_tmp2, ( sub( ( sub( 29, dm_alpha_e ) ), L_tmp2_q ) ) ); + L_tmp1 = L_shr( dm_alpha[b], ( sub( ( sub( 31, dm_alpha_e ) ), 29 ) ) ); + L_tmp1 = L_add( L_tmp1, L_tmp2 ); // Q29 - dm_g[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( L_tmp1, den_f, &s_div ) ); // Q30 + den_f_e - 31 + dm_g[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( L_tmp1, den_f, &s_div ) ); // Q29 + den_f_e - 31 + 15 - s_div move32(); - div_shift = add( sub( 15, ( sub( 30, den_f_e ) ) ), s_div ); + div_shift = add( sub( 15, ( sub( 29, sub( 31, den_f_e ) ) ) ), s_div ); dm_g[b] = L_shl( dm_g[b], div_shift ); // Q30 move32(); } @@ -1313,6 +1300,8 @@ static void ivas_get_Wscaling_factor_fx( { pWscale[b] = 1; move32(); + q_pWscale[b] = 0; + move16(); test(); IF( EQ_16( active_w, 1 ) && ( dyn_active_w_flag == 0 ) ) @@ -1340,32 +1329,29 @@ static void ivas_get_Wscaling_factor_fx( } q_g_sq = sub( add( q_pred_coeffs_re, q_pred_coeffs_re ), add( 31, guard_bits ) ); - tmp_exp = sub( 31, q_Gw_sq ); - Gw_sq = Sqrt32( Gw_sq, &tmp_exp ); - q_Gw_sq = sub( 31, tmp_exp ); - - tmp = Mpy_32_32( ONE_IN_Q31 /*4 in Q28*/, Mpy_32_32( dm_f_local, g_sq ) ); + tmp = Mpy_32_32( ONE_IN_Q30 /*4 in Q28*/, Mpy_32_32( dm_f_local, g_sq ) ); q_tmp = sub( q_g_sq, 3 ); q_min = s_min( q_Gw_sq, q_tmp ); - Gw_sq = L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ); - q_Gw_sq = q_min; - move16(); tmp = L_shr( tmp, sub( q_tmp, q_min ) ); - - tmp = L_add( Gw_sq, tmp ); + tmp = L_add( L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ), tmp ); tmp_exp = sub( 31, q_min ); tmp = Sqrt32( tmp, &tmp_exp ); q_tmp = sub( 31, tmp_exp ); + tmp_exp = sub( 31, q_Gw_sq ); + Gw_sq = Sqrt32( Gw_sq, &tmp_exp ); + q_Gw_sq = sub( 31, tmp_exp ); + q_min = s_min( q_Gw_sq, q_tmp ); Gw_sq = L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ); q_Gw_sq = q_min; move16(); + tmp = L_shr( tmp, sub( q_tmp, q_min ) ); - pWscale[b] = Mpy_32_32( L_add( Gw_sq, tmp ), ONE_IN_Q30 /* 0.5 in Q31*/ ); + pWscale[b] = L_add( L_shr( Gw_sq, 1 /* Gw_sq * 0.5 */ ), L_shr( tmp, 1 /* tmp * 0.5 */ ) ); move32(); q_pWscale[b] = q_Gw_sq; move16(); @@ -1780,31 +1766,17 @@ static void ivas_calc_post_pred_per_band_fx( Word32 max_val; Word64 tmp_re; - max_val = 1; - move32(); FOR( i = 0; i < num_ch; i++ ) { FOR( j = 0; j < num_ch; j++ ) { dmx_mat_conj[i][j] = mixer_mat[j][i][band_idx]; move32(); - max_val = L_max( max_val, L_abs( dmx_mat_conj[i][j] ) ); } } guard_bits = find_guarded_bits_fx( num_ch ); - tmp = norm_l( max_val ); - IF( LT_16( tmp, guard_bits ) ) - { - guard_bits = sub( guard_bits, tmp ); - } - ELSE - { - guard_bits = 0; - move16(); - } - FOR( i = 0; i < num_ch; i++ ) { set32_fx( temp_mat[i], 0, num_ch ); @@ -2076,9 +2048,6 @@ static void ivas_calc_p_coeffs_per_band( if ( i == j ) { pSparMd->band_coeffs[b_ts_idx].P_re[j - num_dmx] = cov_uu_re[i - num_dmx][j - num_dmx]; -#ifdef IVAS_FLOAT_FIXED - pSparMd->band_coeffs[b_ts_idx].P_re_fx[j - num_dmx] = (Word32) ( pSparMd->band_coeffs[b_ts_idx].P_re[j - num_dmx] * ONE_IN_Q22 ); -#endif } } } @@ -2579,9 +2548,6 @@ void ivas_calc_c_p_coeffs( for ( j = 0; j < num_dmx - 1; j++ ) { pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].C_re[i][j] = 0.0f; -#ifdef IVAS_FLOAT_FIXED - pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = 0; -#endif } } } @@ -2595,9 +2561,6 @@ void ivas_calc_c_p_coeffs( for ( i = num_dmx; i < num_ch; i++ ) { pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re[i - num_dmx] = 0; -#ifdef IVAS_FLOAT_FIXED - pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re_fx[i - num_dmx] = 0; -#endif } } } @@ -3257,8 +3220,8 @@ void ivas_compute_spar_params_fx( FOR( b = start_band; b < end_band; b++ ) { Word16 tmp_exp, q_tmp, tmp; - Word16 onebyscale_fx = BASOP_Util_Divide3232_Scale( L_shl( 1, q_pWscale[b] ), pWscale_fx[b], &tmp_exp ); - q_tmp = sub( 15, tmp_exp ); + Word16 onebyscale_fx = BASOP_Util_Divide3232_Scale( 1, pWscale_fx[b], &tmp_exp ); + q_tmp = sub( sub( 15, tmp_exp ), q_pWscale[b] ); tmp = sub( add( q_pred_coeffs, q_tmp ), 15 ); FOR( i = 0; i < sub( num_ch, 1 ); i++ ) @@ -3354,26 +3317,27 @@ Word32 diff_norm_order3_table[8] = { 0, 1879048192, 939524096, 626349376, 469762 #define ONE_BY_FIVE_Q31 429496729 #define ONE_BY_SEVEN_Q31 306783378 void ivas_get_spar_md_from_dirac_fx( - Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS], - const int16_t n_ts, + Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 + Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 + Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS], // Q30 + const Word16 n_ts, Word32 ***mixer_mat_fx, + Word16 *q_mixer_mat_fx, ivas_spar_md_t *hSpar_md, ivas_spar_md_com_cfg *hSpar_md_cfg, - const int16_t start_band, - const int16_t end_band, - const int16_t order, - const int16_t dtx_vad, - Word32 Wscale_d[IVAS_MAX_NUM_BANDS], - const uint8_t useLowerRes, - const int16_t active_w_vlbr, - const int16_t dyn_active_w_flag ) + const Word16 start_band, + const Word16 end_band, + const Word16 order, + const Word16 dtx_vad, + Word32 Wscale_d[IVAS_MAX_NUM_BANDS], // Q29 + const UWord8 useLowerRes, + const Word16 active_w_vlbr, + const Word16 dyn_active_w_flag ) { Word16 num_ch, band, i, j; Word16 block, ch; - + Word16 azimuth, elevation; Word32 response_avg_fx[MAX_OUTPUT_CHANNELS]; Word32 response_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS]; @@ -3533,17 +3497,65 @@ void ivas_get_spar_md_from_dirac_fx( IF( GT_16( n_ts, 1 ) ) { - ivas_dirac_dec_get_response_fx( extract_l( L_shr( azi_dirac_fx[band][i_ts], Q22 ) ), extract_l( L_shr( ele_dirac_fx[band][i_ts], Q22 ) ), response_avg_fx, order, Q30 ); + IF( ele_dirac_fx[band][i_ts] < 0 ) + { + elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][i_ts] ), Q22 ) ) ); + } + ELSE + { + elevation = extract_l( L_shr( ele_dirac_fx[band][i_ts], Q22 ) ); + } + IF( azi_dirac_fx[band][i_ts] < 0 ) + { + azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][i_ts] ), Q22 ) ) ); + } + ELSE + { + azimuth = extract_l( L_shr( azi_dirac_fx[band][i_ts], Q22 ) ); + } + ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 ); } ELSE IF( useLowerRes ) { - ivas_dirac_dec_get_response_fx( extract_l( L_shr( azi_dirac_fx[band][0], Q22 ) ), extract_l( L_shr( ele_dirac_fx[band][0], Q22 ) ), response_avg_fx, order, Q30 ); + IF( ele_dirac_fx[band][0] < 0 ) + { + elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][0] ), Q22 ) ) ); + } + ELSE + { + elevation = extract_l( L_shr( ele_dirac_fx[band][0], Q22 ) ); + } + IF( azi_dirac_fx[band][0] < 0 ) + { + azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][0] ), Q22 ) ) ); + } + ELSE + { + azimuth = extract_l( L_shr( azi_dirac_fx[band][0], Q22 ) ); + } + ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 ); } ELSE { FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { - ivas_dirac_dec_get_response_fx( extract_l( L_shr( azi_dirac_fx[band][block], Q22 ) ), extract_l( L_shr( ele_dirac_fx[band][block], Q22 ) ), &( response_fx[block][0] ), order, Q30 ); + IF( ele_dirac_fx[band][block] < 0 ) + { + elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][block] ), Q22 ) ) ); + } + ELSE + { + elevation = extract_l( L_shr( ele_dirac_fx[band][block], Q22 ) ); + } + IF( azi_dirac_fx[band][block] < 0 ) + { + azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][block] ), Q22 ) ) ); + } + ELSE + { + azimuth = extract_l( L_shr( azi_dirac_fx[band][block], Q22 ) ); + } + ivas_dirac_dec_get_response_fx( azimuth, elevation, &( response_fx[block][0] ), order, Q30 ); } /* average responses in all subframes*/ @@ -3825,6 +3837,11 @@ void ivas_get_spar_md_from_dirac_fx( IF( mixer_mat_fx != NULL ) { + if ( *q_mixer_mat_fx == 0 ) + { + *q_mixer_mat_fx = q_ppMixer_mat; + move16(); + } FOR( band = start_band; band < end_band; band++ ) { ndm = hSpar_md_cfg->num_dmx_chans_per_band[band]; @@ -3834,7 +3851,7 @@ void ivas_get_spar_md_from_dirac_fx( { FOR( j = 0; j < num_ch; j++ ) { - mixer_mat_fx[i][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )] = ppMixer_mat_fx[i][j][band]; + mixer_mat_fx[i][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )] = L_shl( ppMixer_mat_fx[i][j][band], sub( *q_mixer_mat_fx, q_ppMixer_mat ) ); move32(); } } @@ -3853,7 +3870,7 @@ void ivas_get_spar_md_from_dirac_fx( { FOR( j = 0; j < num_ch; j++ ) { - mixer_mat_fx[0][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )] = Mpy_32_32( mixer_mat_fx[0][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )], Wscale_d[band] ); + mixer_mat_fx[0][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )] = Mpy_32_32( L_shl( mixer_mat_fx[0][j][add( band, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) )], 2 ), Wscale_d[band] ); move32(); } } diff --git a/lib_com/options.h b/lib_com/options.h index 17a04a6cb50fcb0b5764adf278612835872e8291..ccd2987cc5d6d089e4258cf26c1d31ab010436be 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -183,7 +183,7 @@ #define FIX_875_SATURATION_DURING_ROUNDING /* VA: fix a possible saturation when rounding */ #define FIX_882_LOW_LEVEL_DISCONTINUITIES /* VA: Fix 882, discontinuities for low level signal by adding a scaling function that uses rounding, this function is more complex than normal one, has to be used only when necessary*/ #define FIX_879_DIFF_CONCEAL_PATH /* FhG: Fix for issue 879 and different concelalment paths that led to crash */ -#define FIX_907_MEM_UPDATE_ISSUE /* VA: fix for 907, multiples issues surrounding mem_syn_r and update of mem_syn2 when FS is changing */ +#define FIX_907_MEM_UPDATE_ISSUE /* VA: fix for 907, multiples issues surrounding mem_syn_r and update of mem_syn2 when FS is changing */ #define FIX_918_WRONG_SCALING_ON_MODE_SWITCHING /* VA: Fix wrong scaling of secondary channel when switching from stereo DFT to TD */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 60413a1d291d1d4716c99336edc17c690b784609..618057b043483e9db8c91f53230f15afd884a79b 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -247,14 +247,14 @@ int16_t maximum( const int16_t lvec, /* i : length of input vector */ float *max_val /* o : maximum value in the input vector */ ); - +#ifndef IVAS_FLOAT_FIXED /*! r: index of the maximum value in the input vector */ int16_t maximum_s( const int16_t *vec, /* i : input vector */ const int16_t lvec, /* i : length of input vector */ int16_t *max /* o : maximum value in the input vector */ ); - +#endif /*! r: index of the maximum value in the input vector */ int16_t maximumAbs( const float *vec, /* i : input vector */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 24e5ae866a06a94b4b3e1cf56442d959c7396e05..fea8657eb912f754b6953d7bebd71882bf0e1f9f 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -7816,53 +7816,53 @@ void bandwidth_switching_detect_ivas_fx( ); void bw_switching_pre_proc_fx( - const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ + const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz Qx*/ Decoder_State *st_fx /* i/o: decoder state structure */ ); ivas_error core_switching_pre_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 output_frame /* i : frame length */ + const Word16 output_frame /* i : frame length Q0*/ ); ivas_error core_switching_post_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth */ + Word16 *synth, /* i/o: output synthesis Qsynth Qsynth*/ #ifdef IVAS_CODE_SWITCHING float *output, /* i/o: LB synth/upsampled LB synth */ float output_mem[], /* i : OLA memory from last TCX/HQ frame */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ #endif - const Word16 output_frame, /* i : frame length */ - const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ + const Word16 output_frame, /* i : frame length Q0*/ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ #ifdef IVAS_CODE_SWITCHING const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ const Word16 nchan_out, /* i : number of output channels */ #endif - const Word16 last_element_mode, /* i : element mode of previous frame */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ); ivas_error core_switching_post_dec_ivas_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth */ - Word32 *output_fx, /* i/o: LB synth/upsampled LB synth */ - Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame */ + Word16 *synth, /* i/o: output synthesis Qsynth*/ + Word32 *output_fx, /* i/o: LB synth/upsampled LB synth Q4*/ + Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame Qx*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const Word16 output_frame, /* i : frame length */ - const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ - const Word16 last_element_mode, /* i : element mode of previous frame */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo Q0*/ + const Word16 output_frame, /* i : frame length Q0*/ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC Q0*/ + const Word16 nchan_out, /* i : number of output channels Q0*/ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ); void core_switching_hq_prepare_dec_fx( - Decoder_State *st_fx, /* i/o: encoder state structure */ - Word16 *num_bits, /* i/o: bit budget update */ - const Word16 output_frame /* i : output frame length */ + Decoder_State *st_fx, /* i/o: encoder state structure */ + Word16 *num_bits, /* i/o: bit budget update Q0*/ + const Word16 output_frame /* i : output frame length Q0*/ ); // amr_wb_dec_fx.c @@ -8566,17 +8566,22 @@ void decoder_LPD_fx( ); // core_dec_switch_fx.c -void mode_switch_decoder_LPD_fx( Decoder_State *st, Word16 bandwidth_in, Word32 bitrate, Word16 frame_size_index ); +void mode_switch_decoder_LPD_fx( + Decoder_State *st, /* Q0 */ + Word16 bandwidth_in, /* Q0 */ + Word32 bitrate, /* Q0 */ + Word16 frame_size_index /* Q0 */ +); #ifdef IVAS_FLOAT_FIXED void mode_switch_decoder_LPD_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word16 bwidth, /* i : audio bandwidth */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 last_total_brate, /* i : last frame total bitrate */ - const Word16 frame_size_index, /* i : index determining the frame size */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const Word16 last_element_mode, /* i : last element mode */ + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 bwidth, /* i : audio bandwidth Q0*/ + const Word32 total_brate, /* i : total bitrate Q0*/ + const Word32 last_total_brate, /* i : last frame total bitrate Q0*/ + const Word16 frame_size_index, /* i : index determining the frame size Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 last_element_mode, /* i : last element mode Q0*/ Word16 *Q_syn_Overl_TDAC, Word16 *Q_fer_samples, Word16 *Q_syn_Overl, @@ -9893,7 +9898,10 @@ Word16 mean_no_sat_fx( /* o : mean of vector Qx * const Word16 *vec_fx, /* i : input vector Qx */ const Word16 lvec_fx /* i : length of input vector */ ); - +Word32 mean_no_sat_Word32_fx( /* o : mean of vector Qx */ + const Word32 *vec_fx, /* i : input vector Qx */ + const Word16 lvec_fx, /* i : length of input vector */ + const Word16 gb ); void sort( UWord16 *x, /* i/o: Vector to be sorted */ UWord16 len /* i/o: vector length */ @@ -9992,7 +10000,11 @@ Word32 var_fx_32( /* o: variance of vector Q const Word16 Qx, const Word16 len /* i: length of inputvector */ ); - +Word32 var_fx_32in_32out( /* o: variance of vector Qx+16*/ + const Word32 *x, /* i: input vector Qx*/ + Word16 *Qx, + const Word16 len, /* i: length of inputvector */ + const Word16 gb ); Word16 var_fx( /* o: variance of vector Qx*/ const Word16 *x, /* i: input vector Qx*/ const Word16 Qx, diff --git a/lib_com/syn_filt_fx.c b/lib_com/syn_filt_fx.c index c348776e90d7827bcf1160d475803aa174825fad..6d5bc99b05a9ad574d3bee004ce119fedcc75573 100644 --- a/lib_com/syn_filt_fx.c +++ b/lib_com/syn_filt_fx.c @@ -518,7 +518,7 @@ void ivas_synth_mem_updt2_fx( en1_e = sub( norm_l( en1 ), 1 ); tmp = div_l( L_shl( en1, en1_e ), extract_h( L_shl( en2, en2_e ) ) ); en1_e = sub( en2_e, en1_e ); - tmp1 = L_shl( tmp, sub( 16 + 1, en1_e ) ); /* Q14 because of norm - 1 for the num */ + tmp1 = L_shl_sat( tmp, sub( 16 + 1, en1_e ) ); /* Q14 because of norm - 1 for the num */ tmp2 = Isqrt( tmp1 ); /* Q16 */ loc_rat = round_fx_sat( L_shl_sat( tmp2, sub( 16, en1_e ) ) ); /* loc_rat in Q15 */ } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 140e064a79750d12032cfb56f1c6fffc31319fc0..52f8b01afd569fece19b7fbc9509167f4db4bf76 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -998,7 +998,22 @@ Word16 mean_no_sat_fx( /* o : mean of vector Qx * return extract_l( L_tmp ); } +Word32 mean_no_sat_Word32_fx( /* o : mean of vector Qx */ + const Word32 *vec_fx, /* i : input vector Qx */ + const Word16 lvec_fx, /* i : length of input vector */ + const Word16 gb ) +{ + Word16 i; + Word32 L_tmp = 0; + move32(); + FOR( i = 0; i < lvec_fx; ++i ) + { + L_tmp = L_add( L_tmp, L_shr( vec_fx[i], gb ) ); + } + L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx-gb */ + return L_tmp; +} /*-------------------------------------------------------------------* * Vr_add * @@ -1440,6 +1455,32 @@ Word32 var_fx_32( /* o: variance of vector Q return v; } + +Word32 var_fx_32in_32out( /* o: variance of vector Qx*/ + const Word32 *x, /* i: input vector Qx*/ + Word16 *Qx, /*i/o:Q for input/output */ + const Word16 len, /* i: length of inputvector */ + const Word16 gb ) +{ + Word16 i; + Word16 shift; + Word32 L_tmp1, L_tmp; + Word64 W_temp; + + L_tmp = mean_no_sat_Word32_fx( x, len, gb ); /*Qx-gb */ + W_temp = 0; + FOR( i = 0; i < len; i++ ) + { + L_tmp1 = L_sub( L_shr( x[i], gb ), L_tmp ); /*Qx-gb */ + W_temp = W_add( W_temp, W_mult0_32_32( L_tmp1, L_tmp1 ) ); /*Qx-gb +Qx-gb*/ + } + shift = W_norm( W_temp ); + L_tmp = Mult_32_16( W_extract_h( W_shl( W_temp, shift ) ), div_s( 1, len ) ); /*Q2*(Qx-gb)+shift -32 */ + + *Qx = sub( add( shl( sub( *Qx, gb ), 1 ), shift ), 32 ); + move16(); + return L_tmp; +} /*-------------------------------------------------------------------* * conv() * diff --git a/lib_dec/LD_music_post_filter_fx.c b/lib_dec/LD_music_post_filter_fx.c index f5d492f7293534e4c7000d40263bf2b15b1e9bf2..37f46301deb7432e6a2ddb64643d70199adb5cff 100644 --- a/lib_dec/LD_music_post_filter_fx.c +++ b/lib_dec/LD_music_post_filter_fx.c @@ -52,8 +52,8 @@ void LD_music_post_filter_fx( const Word16 Qdct /* i : input scaling Q0 */ ) { - Word32 fr_bands[MBANDS_GN_LD]; - Word32 lf_E[VOIC_BINS_HR]; + Word32 fr_bands[MBANDS_GN_LD]; /*2*Qdct+10*/ + Word32 lf_E[VOIC_BINS_HR]; /*2*Qdct+10*/ Word32 Ltmp, Ltmp_max; Word16 LG_etot; /*Q8*/ Word16 i, j, k; @@ -80,7 +80,7 @@ void LD_music_post_filter_fx( move32(); - local_min_gain = hMusicPF->LDm_enh_min_ns_gain_fx; + local_min_gain = hMusicPF->LDm_enh_min_ns_gain_fx; /*Q15*/ move16(); /*------------------------------------------------------------------------* @@ -92,7 +92,7 @@ void LD_music_post_filter_fx( *Old_ener_Q = Qdct; move16(); - Scale_sig32( hMusicPF->LDm_enh_lf_EO_fx, VOIC_BINS_HR, diff_sc ); + Scale_sig32( hMusicPF->LDm_enh_lf_EO_fx, VOIC_BINS_HR, diff_sc ); /*Q23*/ /*------------------------------------------------------------------------* * Find signal classification @@ -116,7 +116,7 @@ void LD_music_post_filter_fx( } - hMusicPF->last_nonfull_music = s_min( 51, hMusicPF->last_nonfull_music ); + hMusicPF->last_nonfull_music = s_min( 51 /*Q0*/, hMusicPF->last_nonfull_music ); /*Q0*/ move16(); /*------------------------------------------------------------------------* @@ -167,7 +167,7 @@ void LD_music_post_filter_fx( if ( EQ_16( coder_type, AUDIO ) ) { /* with GSC we know for sure that we are in music */ - min_band = s_min( min_band, 3 ); + min_band = s_min( min_band, 3 ); /*Q0*/ } /*------------------------------------------------------------------------* @@ -188,20 +188,20 @@ void LD_music_post_filter_fx( { /*m_ave += lf_E[k];*/ #ifdef BASOP_NOGLOB - Ltmp = L_add_o( lf_E[k], Ltmp, &Overflow ); + Ltmp = L_add_o( lf_E[k], Ltmp, &Overflow ); /*2*Qdct+10*/ #else Ltmp = L_add( lf_E[k], Ltmp ); #endif max_val = L_max( max_val, lf_E[k] ); } - Ltmp_max = L_max( Ltmp_max, max_val ); + Ltmp_max = L_max( Ltmp_max, max_val ); /*2*Qdct+10*/ /*m_ave -= max_val;*/ Ltmp = L_sub( Ltmp, max_val ); /*m_ave /=(mfreq_bindiv_LD[i]-1);*/ - m_ave = Mult_32_16( Ltmp, inv_mfreq_bindiv_LD_M1_fx[i] ); + m_ave = Mult_32_16( Ltmp, inv_mfreq_bindiv_LD_M1_fx[i] ); /*2*Qdct+10*/ /*bckr[i] = m_ave*sc_qnoise[i];*/ - hMusicPF->LDm_bckr_noise_fx[i] = Mult_32_16( m_ave, sc_qnoise_fx[i] ); + hMusicPF->LDm_bckr_noise_fx[i] = Mult_32_16( m_ave, sc_qnoise_fx[i] ); /*2*Qdct+10*/ move32(); j = add( j, mfreq_bindiv_LD[i] ); @@ -215,33 +215,33 @@ void LD_music_post_filter_fx( *------------------------------------------------------------------------*/ /*m_ave = ALPH/lf_E[i];*/ exp1 = norm_l( Ltmp_max ); - mant = extract_h( L_shl( Ltmp_max, exp1 ) ); + mant = extract_h( L_shl( Ltmp_max, exp1 ) ); /*2*Qdct+exp1-6*/ /*exp1 = sub(16,exp1);*/ - s_ave = div_s( 16384, mant ); - exp1 = sub( 14 /*+15*/ + 16, exp1 ); /*s_ave in Q15 + exp1*/ - old_tmp16 = norm_lfe( lf_E[0], s_ave, exp1 ); - old_tmp16 = s_min( old_tmp16, MAXX_Q12_FX ); - tmp16 = norm_lfe( lf_E[1], s_ave, exp1 ); - tmp16 = s_min( tmp16, MAXX_Q12_FX ); - old_tmp16_1 = tmp16; + s_ave = div_s( 16384 /*1.0f in Q14*/, mant ); + exp1 = sub( 14 /*+15*/ + 16, exp1 ); /*s_ave in Q15 + exp1*/ + old_tmp16 = norm_lfe( lf_E[0], s_ave, exp1 ); /*Q12*/ + old_tmp16 = s_min( old_tmp16, MAXX_Q12_FX ); /*Q12*/ + tmp16 = norm_lfe( lf_E[1], s_ave, exp1 ); /*Q12*/ + tmp16 = s_min( tmp16, MAXX_Q12_FX ); /*Q12*/ + old_tmp16_1 = tmp16; /*Q12*/ move16(); - tmp_lfE[0] = round_fx( L_mac( L_mult( 16384, old_tmp16 ), 16384, tmp16 ) ); + tmp_lfE[0] = round_fx( L_mac( L_mult( 16384 /*0.5f in Q15*/, old_tmp16 ), 16384 /*0.5f in Q15*/, tmp16 ) ); /*Q12*/ move16(); FOR( i = 1; i < DCT_L_POST - 1; i++ ) { /*tmp_lfE[i] = 0.333f*old_ftmp + 0.333f*ftmp; */ - Ltmp = L_mac( L_mult( 10813, old_tmp16 ), 10813, old_tmp16_1 ); + Ltmp = L_mac( L_mult( 10813 /*Q15*/, old_tmp16 ), 10813 /*Q15*/, old_tmp16_1 ); /*Q28*/ - old_tmp16 = old_tmp16_1; + old_tmp16 = old_tmp16_1; /*Q12*/ move16(); - tmp16 = norm_lfe( lf_E[i + 1], s_ave, exp1 ); + tmp16 = norm_lfe( lf_E[i + 1], s_ave, exp1 ); /*Q12*/ /*ftmp = min(ftmp, MAXX); tmp_lfE[i] += 0.333f*ftmp; */ - old_tmp16_1 = s_min( tmp16, MAXX_Q12_FX ); - Ltmp = L_mac( Ltmp, 10813, old_tmp16_1 ); - tmp_lfE[i] = round_fx( Ltmp ); + old_tmp16_1 = s_min( tmp16, MAXX_Q12_FX ); /*Q12*/ + Ltmp = L_mac( Ltmp, 10813 /*Q15*/, old_tmp16_1 ); /*Q28*/ + tmp_lfE[i] = round_fx( Ltmp ); /*Q12*/ move16(); } @@ -249,20 +249,20 @@ void LD_music_post_filter_fx( /*ftmp = min(ftmp, MAXX); tmp_lfE[i] = 0.5f*old_ftmp + 0.5f*ftmp;*/ tmp16 = s_min( tmp16, MAXX_Q12_FX ); - tmp_lfE[i] = round_fx( L_mac( L_mult( 16384, old_tmp16 ), 16384, tmp16 ) ); + tmp_lfE[i] = round_fx( L_mac( L_mult( 16384 /*0.5F in Q15*/, old_tmp16 ), 16384 /*0.5F in Q15*/, tmp16 ) ); /*Q12*/ move16(); FOR( i = 0; i < BIN_4KHZ; i++ ) { /*filt_lfE[i] = tmp_lfE[i]*.05f + .95f*filt_lfE[i] ;*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_mult( tmp_lfE[i], 1638 ), 31130, hMusicPF->filt_lfE_fx[i] ) ); + hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_mult( tmp_lfE[i], 1638 /*Q15*/ ), 31130 /*Q15*/, hMusicPF->filt_lfE_fx[i] ) ); /*Q12*/ move16(); } FOR( ; i < DCT_L_POST; i++ ) { /*filt_lfE[i] = tmp_lfE[i]*(.15f) + .85f*filt_lfE[i] ;*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_mult( tmp_lfE[i], 4915 ), 27853, hMusicPF->filt_lfE_fx[i] ) ); + hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_mult( tmp_lfE[i], 4915 /*Q15*/ ), 27853 /*Q15*/, hMusicPF->filt_lfE_fx[i] ) ); /*Q12*/ move16(); } /*------------------------------------------------------------------------* @@ -277,7 +277,7 @@ void LD_music_post_filter_fx( move16(); } - Copy( dtc_in, dtc_out, DCT_L_POST ); + Copy( dtc_in, dtc_out, DCT_L_POST ); /*Qdct*/ spectrum_mod_dct_fx( Qdct, dtc_out, lf_E, hMusicPF->LDm_enh_lf_EO_fx, hMusicPF->LDm_bckr_noise_fx, local_min_gain, hMusicPF->LDm_enh_lp_gbin_fx, music_flag2, min_band, MAX_GN, MAX_band ); @@ -287,8 +287,8 @@ void LD_music_post_filter_fx( { FOR( i = 0; i < BIN_1KHZ; i++ ) { - tmp16 = s_min( 4096, hMusicPF->filt_lfE_fx[i] ); - dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); + tmp16 = s_min( 4096 /*1.0f in Q12*/, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ move16(); } } @@ -365,11 +365,11 @@ void LD_music_post_filter_fx( FOR( ; i < BIN_2KHZ; i++ ) { - tmp16 = s_min( max_ovf_2k, hMusicPF->filt_lfE_fx[i] ); - tmp16 = s_max( min_g_2k, tmp16 ); - /*DCT_buf[i] *= ftmp;*/ + tmp16 = s_min( max_ovf_2k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_2k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ #ifdef BASOP_NOGLOB - dtc_out[i] = round_fx_sat( L_shl_sat( L_mult( dtc_out[i], tmp16 ), 3 ) ); + dtc_out[i] = round_fx_sat( L_shl_sat( L_mult( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ #else dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); #endif @@ -378,11 +378,11 @@ void LD_music_post_filter_fx( FOR( ; i < BIN_4KHZ; i++ ) { - tmp16 = s_min( max_ovf_4k, hMusicPF->filt_lfE_fx[i] ); - tmp16 = s_max( min_g_4k, tmp16 ); - /*DCT_buf[i] *= ftmp;*/ + tmp16 = s_min( max_ovf_4k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_4k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ #ifdef BASOP_NOGLOB - dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); + dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ #else dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); #endif @@ -395,11 +395,11 @@ void LD_music_post_filter_fx( /* Do not modify HF when coded with GSC at LR, because the spectrum is just noise */ FOR( ; i < DCT_L_POST; i++ ) { - tmp16 = s_min( max_ovf_6k, hMusicPF->filt_lfE_fx[i] ); - tmp16 = s_max( min_g_6k, tmp16 ); - /*DCT_buf[i] *= ftmp;*/ + tmp16 = s_min( max_ovf_6k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_6k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ #ifdef BASOP_NOGLOB - dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); + dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ #else dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); #endif @@ -412,10 +412,10 @@ void LD_music_post_filter_fx( /* When unsure on content type only slight clean-up allowed, no overshoot allowed */ FOR( ; i < DCT_L_POST; i++ ) { - tmp16 = s_min( 4096, hMusicPF->filt_lfE_fx[i] ); - /*DCT_buf[i] *= ftmp;*/ + tmp16 = s_min( 4096 /*1.0f in Q12*/, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ #ifdef BASOP_NOGLOB - dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); + dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ #else dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); #endif @@ -433,7 +433,7 @@ void LD_music_post_filter_fx( static void spectrum_mod_dct_fx( const Word16 Qdct, /* i : scaling factor Q0 */ - Word16 data[], /* i/o: dct spectrum */ + Word16 data[], /* i/o: dct spectrum Qdct */ const Word32 lf_E[], /* i: per bin E for first 46 bins (without DC) 2*Qdct+10 */ Word32 lf_EO[], /* i/o: old per bin E for previous half frame 2*Qdct+10 */ const Word32 noiseE[], /* i: per band background noise energy estimate 2*Qdct+10 */ @@ -497,11 +497,11 @@ static void spectrum_mod_dct_fx( { e_invno[i] = norm_l( noiseE[i] ); move16(); - m_invno[i] = extract_h( L_shl( noiseE[i], e_invno[i] ) ); + m_invno[i] = extract_h( L_shl( noiseE[i], e_invno[i] ) ); /* 2*Qdct + e_invno[i] - 6 */ move16(); e_invno[i] = sub( 14, e_invno[i] ); move16(); - m_invno[i] = div_s( 16384, m_invno[i] ); + m_invno[i] = div_s( 16384 /*1.0f in Q14*/, m_invno[i] ); /*Q15*/ move16(); } ELSE @@ -519,19 +519,19 @@ static void spectrum_mod_dct_fx( FOR( i = 0; i < VOIC_BINS_HR; i++ ) { /*binE[i] = (float)(0.3 * lf_EO[i] + 0.7 * lf_E[i]);*/ - Ltmp = Mult_32_16( lf_EO[i], 9830 ); - binE[i] = Madd_32_16( Ltmp, lf_E[i], 22938 ); + Ltmp = Mult_32_16( lf_EO[i], 9830 /*0.3f in Q15*/ ); /*2*Qdct+10*/ + binE[i] = Madd_32_16( Ltmp, lf_E[i], 22938 /*0.7f in Q15*/ ); /*2*Qdct+10*/ move32(); } - Copy32( lf_E, lf_EO, VOIC_BINS_HR ); /* update */ + Copy32( lf_E, lf_EO, VOIC_BINS_HR ); /* update 2*Qdct+10*/ /*----------------------------------------------------------------------* * Find the maximum noise in a critical band *----------------------------------------------------------------------*/ - maxNoise = L_max( noiseE[0], noiseE[1] ); + maxNoise = L_max( noiseE[0], noiseE[1] ); /*2*Qdct+10*/ FOR( i = 2; i <= MBANDS_GN_LD - 1; i++ ) { - maxNoise = L_max( maxNoise, noiseE[i] ); + maxNoise = L_max( maxNoise, noiseE[i] ); /*2*Qdct+10*/ } /* pointer initialization */ @@ -558,11 +558,11 @@ static void spectrum_mod_dct_fx( minE = shr( mult_r( minGain, minGain ), 1 ); /*Q14*/ } - Lpt2 = binE; + Lpt2 = binE; /*2*Qdct+10*/ freq = 0; move16(); - pt_gbin = lp_gbin; + pt_gbin = lp_gbin; /*Q14*/ FOR( i = 0; i < min_band; i++ ) { @@ -571,7 +571,7 @@ static void spectrum_mod_dct_fx( Lpt2++; /* Lgain is already saturate if it's > 1*/ pt++; - *pt_gbin = 16384; + *pt_gbin = 16384; /*Q14*/ move16(); pt_gbin++; } @@ -591,11 +591,11 @@ static void spectrum_mod_dct_fx( shift = MAX_SNR_SNR1_tab[i] * minE - tmp;*/ /*tmp = 1.0f/ (MAX_SNR1 - 1.0f);*/ - tmp_snr = INV_MAX_SNR_tab_FX[i]; + tmp_snr = INV_MAX_SNR_tab_FX[i]; /*Q15*/ move16(); /*slope = -tmp * minE + tmp;*/ - Ltmp = L_mult( tmp_snr, 16384 ); - slope = msu_r( Ltmp, tmp_snr, minE ); /*Q14*/ + Ltmp = L_mult( tmp_snr, 16384 /*1.0f in Q14*/ ); /*Q30*/ + slope = msu_r( Ltmp, tmp_snr, minE ); /*Q14*/ /*shift = MAX_SNR1 * tmp * minE - tmp;*/ Ltmp = L_mult( MAX_SNR_SNR1_tab_FX[i], minE ); /*Q14*Q14*/ @@ -603,7 +603,7 @@ static void spectrum_mod_dct_fx( Lshift = L_shl( Lshift, 1 ); /*Q29 -> Q30*/ /*tmpN = slope * inv_noise[i];*/ - tmpN = mult( slope, m_invno[i] ); + tmpN = mult( slope, m_invno[i] ); /*Q14*/ e_tmp = e_invno[i]; move16(); @@ -611,21 +611,21 @@ static void spectrum_mod_dct_fx( FOR( ; freq <= mfreq_loc_LD_fx[i]; freq += BIN_16kdct_fx ) { /*gain = 1.0f;*/ - Lgain = L_deposit_h( 16384 ); + Lgain = L_deposit_h( 16384 /*1.0f in Q14*/ ); /*Q30*/ /*if (noiseE[i] >= 0.5f)*/ test(); IF( LT_16( scaling, 32 ) && GT_32( noiseE[i], dot5_scaled ) ) /* Do not alter if noise E very low */ { /*gain = tmpN * *pt2 + shift;*/ /* limits: [x,y] = {[1, minE], [MAX_SNR1, 1]}, */ e_binE = norm_l( *Lpt2 ); - m_binE = extract_h( L_shl( *Lpt2, e_binE ) ); + m_binE = extract_h( L_shl( *Lpt2, e_binE ) ); /*2*Qdct+e_binE-6*/ e_binE = sub( e_binE, 0 ); /* lf_e divided by 4 in anal_sp*/ - Ltmp = L_mult( tmpN, m_binE ); + Ltmp = L_mult( tmpN, m_binE ); /*2*Qdct+e_binE+9*/ e_binE = sub( add( e_tmp, e_binE ), 15 ); #ifdef BASOP_NOGLOB - Ltmp = L_shr_o( Ltmp, e_binE, &Overflow ); + Ltmp = L_shr_o( Ltmp, e_binE, &Overflow ); /*2*Qdct+9*/ Lgain = L_add_o( Ltmp, Lshift, &Overflow ); /*Saturation can occure here result in Q30*/ #else Ltmp = L_shr( Ltmp, e_binE ); @@ -640,33 +640,33 @@ static void spectrum_mod_dct_fx( gain = round_fx( Lgain ); /*gain in Q30-16 = Q14*/ #endif /*if (gain < minE)gain = minE;*/ - gain = s_max( gain, minE ); + gain = s_max( gain, minE ); /*Q14*/ /*if (gain > 1.0f+MAX_GN)gain = 1.0f+MAX_GN;*/ - gain = s_min( gain, add( 16384, MAX_GN ) ); + gain = s_min( gain, add( 16384 /*1.0f in Q14*/, MAX_GN ) ); /*Q14*/ /* prepare gain to find sqrt */ e_gain = norm_s( gain ); - Ltmp = L_shl( gain, add( 16, e_gain ) ); + Ltmp = L_shl( gain, add( 16, e_gain ) ); /* Q30+e_gain */ e_gain = negate( sub( e_gain, 1 ) ); Ltmp = Isqrt_lc( Ltmp, &e_gain ); wtmp = extract_h( Ltmp ); - sqrt_gain = div_s( 16384, wtmp ); + sqrt_gain = div_s( 16384 /*Q14*/, wtmp ); /*Q15*/ /* the gain smoothing control: stronger lp filtering for lower gains */ /*alpha = 1.0f - (float)sqrt(gain);*/ /* keep gain in Q14*/ - sqrt_gain = shr( sqrt_gain, e_gain ); - /*alpha = 1.0f - gain;*/ /* the gain smoothing control: stronger LP filtering for lower gains */ - alpha = shl( sub( 16384, sqrt_gain ), 1 ); + sqrt_gain = shr( sqrt_gain, e_gain ); /*Q14*/ + /*alpha = 1.0f - gain;*/ /* the gain smoothing control: stronger LP filtering for lower gains */ + alpha = shl( sub( 16384 /*Q14*/, sqrt_gain ), 1 ); /*Q15*/ /**pt_gbin = gain + alpha * *pt_gbin;*/ - Ltmp = L_mult( gain, 32767 ); + Ltmp = L_mult( gain, 32767 /*Q15*/ ); /*Q30*/ *pt_gbin = round_fx( L_mac( Ltmp, alpha, *pt_gbin ) ); /*Q14*/ /**pt++ *= *pt_gbin;*/ #ifdef BASOP_NOGLOB - *pt = round_fx_sat( L_shl_sat( L_mult( *pt, *pt_gbin ), 1 ) ); + *pt = round_fx_sat( L_shl_sat( L_mult( *pt, *pt_gbin ), 1 ) ); /*Qdct*/ #else *pt = round_fx( L_shl( L_mult( *pt, *pt_gbin ), 1 ) ); #endif @@ -681,14 +681,14 @@ static void spectrum_mod_dct_fx( { freq = BIN_16kdct_fx; move16(); - pt_gbin = lp_gbin; + pt_gbin = lp_gbin; /*Q14*/ move16(); FOR( i = 0; i < MBANDS_GN_LD; i++ ) { FOR( ; freq <= mfreq_loc_LD[i]; freq += BIN_16kdct_fx ) { /**pt_gbin = 0.9f* *pt_gbin + 0.1f;*/ - *pt_gbin = round_fx( L_mac( L_mult( 29491, *pt_gbin ), 32767, 1638 ) ); + *pt_gbin = round_fx( L_mac( L_mult( 29491 /*0.9f in Q15*/, *pt_gbin ), 32767 /*Q15*/, 1638 /*0.1f in Q14*/ ) ); /*Q14*/ move16(); pt_gbin++; } @@ -726,12 +726,12 @@ static void analy_sp_dct_fx( /* find average log total energy over both half-frames */ /**etot = 10.0f * (float)log10(*etot) - 3.0103f;*/ exp_etot = norm_l( Letot ); - frac_etot = Log2_norm_lc( L_shl( Letot, exp_etot ) ); + frac_etot = Log2_norm_lc( L_shl( Letot, exp_etot ) ); /*Q15*/ exp_etot = sub( 30, exp_etot ); exp_etot = sub( exp_etot, add( shl( Qdct, 1 ), 10 + 1 ) ); /* +(1) */ - Letot = Mpy_32_16( exp_etot, frac_etot, LG10 ); + Letot = Mpy_32_16( exp_etot, frac_etot, LG10 ); /*Q14*/ /* Q8 Averaged the total energy over both half-frames in log10 */ - *etot = extract_l( L_shr( Letot, 14 - 8 ) ); + *etot = extract_l( L_shr( Letot, 14 - 8 ) ); /*Q8*/ move16(); return; @@ -761,9 +761,9 @@ static void find_enr_dct_fx( Word32 LE_min, Ltmp, Ltmp1; - LE_min = L_max( L_shl( E_MIN_Q15, sub( add( shl( Q_dct, 1 ), 10 ), 22 ) ), 1 ); + LE_min = L_max( L_shl( E_MIN_Q15, sub( add( shl( Q_dct, 1 ), 10 ), 22 ) ), 1 ); /* 2*Q_dct + 10*/ - ptR = &data[0]; /* pointer to first real coefficient */ + ptR = &data[0]; /* pointer to first real coefficient Qdct*/ freq = 0; move16(); FOR( i = 0; i < max_band; i++ ) @@ -776,20 +776,20 @@ static void find_enr_dct_fx( /* energy */ /**ptE = *ptR * *ptR; */ #ifdef BASOP_NOGLOB - Ltmp = L_mult_sat( *ptR, *ptR ); + Ltmp = L_mult_sat( *ptR, *ptR ); /*2*Qdct+1*/ #else Ltmp = L_mult( *ptR, *ptR ); #endif /* normalization */ /**ptE *= 1.0f / (DCT_L_POST);*/ - Ltmp = Mult_32_16( Ltmp, 26214 ); /*26214 = 1.0/640 ->Q15+9 --> 2*Q_dct + 9*/ - Ltmp = L_max( Ltmp, LE_min ); - *ptE = Ltmp; + Ltmp = Mult_32_16( Ltmp, 26214 ); /*26214 = 1.0/640 ->Q15+9 --> 2*Q_dct + 10*/ + Ltmp = L_max( Ltmp, LE_min ); /*2*Q_dct + 10*/ + *ptE = Ltmp; /*2*Q_dct + 10*/ move32(); /*band[i] += *ptE++;*/ #ifdef BASOP_NOGLOB - Ltmp1 = L_add_sat( Ltmp, Ltmp1 ); + Ltmp1 = L_add_sat( Ltmp, Ltmp1 ); /*2*Q_dct + 10*/ #else Ltmp1 = L_add( Ltmp, Ltmp1 ); #endif @@ -801,7 +801,7 @@ static void find_enr_dct_fx( /* normalization per frequency bin */ /*band[i] /= cnt;*/ band[i] = L_max( Mult_32_16( Ltmp1, inv_mfreq_bindiv_LD_fx[i] ), LE_min ); - move32(); /* 2*Q_dct + 9*/ + move32(); /* 2*Q_dct + 10*/ } /*-----------------------------------------------------------------* @@ -814,13 +814,13 @@ static void find_enr_dct_fx( { /* total channel energy */ #ifdef BASOP_NOGLOB - Ltmp = L_add_sat( band[i], Ltmp ); + Ltmp = L_add_sat( band[i], Ltmp ); /* 2*Q_dct + 10*/ #else Ltmp = L_add( band[i], Ltmp ); #endif } - *Etot = Ltmp; + *Etot = Ltmp; /* 2*Q_dct + 10*/ move32(); return; @@ -835,7 +835,7 @@ static void find_enr_dct_fx( void Prep_music_postP_fx( Word16 exc_buffer_in[], /* i/o: excitation buffer Q_exc*/ Word16 dct_buffer_out[], /* o : DCT output buffer (qdct)*/ - Word16 filt_lfE[], /* i/o: long term spectrum energy Q15?*/ + Word16 filt_lfE[], /* i/o: long term spectrum energy Q12*/ const Word16 last_core, /* i : last core */ const Word16 element_mode, /* i : element mode */ const Word16 *pitch_buf, /* i : current frame pitch information Q6*/ @@ -852,8 +852,8 @@ void Prep_music_postP_fx( Word16 exc16[DCT_L_POST]; Word16 *pt1_out; - s_pit = shr( pitch_buf[3], 6 ); - fr_pit = shr( sub( pitch_buf[3], shl( s_pit, 6 ) ), 4 ); /* Find fractional part */ + s_pit = shr( pitch_buf[3], 6 ); /*Q0*/ + fr_pit = shr( sub( pitch_buf[3], shl( s_pit, 6 ) ), 4 ); /* Find fractional part Q2*/ /*------------------------------------------------------------* * Resetting some memories in case of switching @@ -865,10 +865,10 @@ void Prep_music_postP_fx( test(); IF( ( EQ_16( element_mode, EVS_MONO ) && EQ_16( last_core, HQ_CORE ) ) || ( NE_16( element_mode, EVS_MONO ) && ( EQ_16( last_core, HQ_CORE ) || EQ_16( last_core, TCX_20_CORE ) || EQ_16( last_core, TCX_10_CORE ) ) ) ) { - set16_fx( filt_lfE, 4096, DCT_L_POST ); - set16_fx( LDm_enh_lp_gbin, 16384, VOIC_BINS_HR ); - pt1 = exc_buffer_in + OFFSET2 - 1; - pt2 = pt1 + shr_r( pitch_buf[0], 6 ); + set16_fx( filt_lfE, 4096 /*Q12*/, DCT_L_POST ); + set16_fx( LDm_enh_lp_gbin, 16384 /*Q14*/, VOIC_BINS_HR ); + pt1 = exc_buffer_in + OFFSET2 - 1; /*Q_exc*/ + pt2 = pt1 + shr_r( pitch_buf[0], 6 ); /*Q_exc*/ FOR( i = 0; i < OFFSET2; i++ ) { *pt1 = *pt2; @@ -881,16 +881,16 @@ void Prep_music_postP_fx( /*------------------------------------------------------------* * Extrapolation of the last future part and windowing *------------------------------------------------------------*/ - pt1 = exc_buffer_in + DCT_L_POST - OFFSET2; + pt1 = exc_buffer_in + DCT_L_POST - OFFSET2; /*Q_exc*/ pred_lt4( pt1, pt1, s_pit, fr_pit, OFFSET2, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*------------------------------------------------------------* * windowing right side *------------------------------------------------------------*/ - pt2 = post_dct_wind_fx; + pt2 = post_dct_wind_fx; /*Q15*/ pt1_out = exc16 + DCT_L_POST - OFFSET2; FOR( i = 0; i < OFFSET2; i++ ) { - *pt1_out = mult_r( *pt1, *pt2 ); + *pt1_out = mult_r( *pt1, *pt2 ); /*Q_exc*/ move16(); pt1++; pt2++; @@ -899,12 +899,12 @@ void Prep_music_postP_fx( /*------------------------------------------------------------* * windowing left side *------------------------------------------------------------*/ - pt1 = exc_buffer_in; + pt1 = exc_buffer_in; /*Q_exc*/ pt1_out = exc16; pt2--; FOR( i = 0; i < OFFSET2; i++ ) { - *pt1_out = mult_r( *pt1, *pt2 ); + *pt1_out = mult_r( *pt1, *pt2 ); /*Q_exc*/ move16(); pt1++; pt1_out++; @@ -916,7 +916,7 @@ void Prep_music_postP_fx( FOR( ; i < L_FRAME + OFFSET2; i++ ) { - *pt1_out = *pt1; + *pt1_out = *pt1; /*Q_exc*/ move16(); pt1++; pt1_out++; @@ -984,24 +984,24 @@ static Word16 norm_lfe( void Post_music_postP_fx( Word16 dct_buffer_in[], /* i/o: excitation buffer */ - Word16 *exc2, /* i/o: Current excitation to be overwriten */ - const Word16 *mem_tmp, /* i : previous frame synthesis memory */ - Word16 *st_mem_syn2, /* i/o: current frame synthesis memory */ - const Word16 *Aq, /* i : LPC filter coefficients */ - Word16 *syn, /* i/o: 12k8 synthesis */ + Word16 *exc2, /* i/o: Current excitation to be overwriten Q_exc*/ + const Word16 *mem_tmp, /* i : previous frame synthesis memory Q_syn*/ + Word16 *st_mem_syn2, /* i/o: current frame synthesis memory Q_syn*/ + const Word16 *Aq, /* i : LPC filter coefficients Q12*/ + Word16 *syn, /* i/o: 12k8 synthesis Q_syn*/ Word16 *Q_exc, /* i : excitation scaling */ Word16 *prev_Q_syn, /* i : previsous frame synthesis scaling */ Word16 *Q_syn, /* i : Current frame synthesis scaling */ - Word16 *mem_syn_clas_estim_fx, /* i : old 12k8 synthesis used for frame classification*/ + Word16 *mem_syn_clas_estim_fx, /* i : old 12k8 synthesis used for frame classification Q_syn*/ const Word16 IsIO, /* i: Flag to indicate IO mode */ - Word16 *mem_deemph, /* i/o: speech deemph filter memory */ - Word16 *st_pst_old_syn_fx, /* i/o: psfiler */ - Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler */ - Word16 *mem_agc, - PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ - const Word16 *tmp_buffer /* tmp_buffer in Q-1 */ + Word16 *mem_deemph, /* i/o: speech deemph filter memory Q_syn*/ + Word16 *st_pst_old_syn_fx, /* i/o: psfiler Q_syn*/ + Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler Q_syn*/ + Word16 *mem_agc, /*Q_syn*/ + PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ + const Word16 *tmp_buffer /* tmp_buffer in Q-1 */ , - Word16 *mem_tmp2 /* Temporary memory used with scale_syn */ + Word16 *mem_tmp2 /* Temporary memory used with scale_syn Q_syn*/ ) { Word16 exc16[DCT_L_POST]; @@ -1014,7 +1014,7 @@ void Post_music_postP_fx( Copy( exc16 + OFFSET2, exc2, L_FRAME ); - Copy( mem_tmp, st_mem_syn2, M ); + Copy( mem_tmp, st_mem_syn2, M ); /*Q_syn*/ /*------------------------------------------------------------------------* * Perform the synthesis filtering using the enhanced excitation @@ -1024,7 +1024,7 @@ void Post_music_postP_fx( Rescale_mem( *Q_exc, prev_Q_syn, Q_syn, st_mem_syn2, mem_syn_clas_estim_fx, 4, mem_deemph, st_pst_old_syn_fx, st_pst_mem_deemp_err_fx, mem_agc, pf_stat, 1, 0, tmp_buffer ); - Copy( st_mem_syn2, mem_tmp2, M ); + Copy( st_mem_syn2, mem_tmp2, M ); /*Q_syn*/ } syn_12k8_fx( L_FRAME, Aq, exc2, syn, st_mem_syn2, 1, *Q_exc, *Q_syn ); @@ -1078,9 +1078,9 @@ void music_postfilt_init( FOR( i = 0; i < VOIC_BINS_HR; i++ ) { - hMusicPF->LDm_enh_lp_gbin_fx[i] = 16384; + hMusicPF->LDm_enh_lp_gbin_fx[i] = 16384; /*1.0f Q14*/ move16(); - hMusicPF->LDm_enh_lf_EO_fx[i] = 328; + hMusicPF->LDm_enh_lf_EO_fx[i] = 328; /*0.01f Q15*/ move16(); } @@ -1089,7 +1089,7 @@ void music_postfilt_init( hMusicPF->LDm_bckr_noise_fx[i] = E_MIN_Q15; move16(); } - set16_fx( hMusicPF->filt_lfE_fx, 4096, DCT_L_POST ); + set16_fx( hMusicPF->filt_lfE_fx, 4096 /*1.0f in Q12*/, DCT_L_POST ); hMusicPF->last_nonfull_music = 0; move16(); hMusicPF->Old_ener_Q = 0; diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index 1c84c1d75a506f6d1811e8b2dbfbd921818484f0..38e7b5cbc1354b10acc0a04d7a17de65a200ba70 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -39,21 +39,21 @@ static void findTonalComponents( Word16 *indexOfTonalPeak, Word16 *lowerIndex, W *-------------------------------------------------------------------*/ void ivas_DetectTonalComponents_fx( - Word16 indexOfTonalPeak[], - Word16 lowerIndex[], - Word16 upperIndex[], - Word16 *pNumIndexes, - const Word32 lastPitchLag, - const Word32 currentPitchLag, + Word16 indexOfTonalPeak[], /*Q0*/ + Word16 lowerIndex[], /*Q0*/ + Word16 upperIndex[], /*Q0*/ + Word16 *pNumIndexes, /*Q0*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ const Word16 lastMDCTSpectrum[], const Word16 lastMDCTSpectrum_exp, const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], + const Word32 secondLastPowerSpectrum[], /*Qx*/ const Word16 nSamples, const Word16 nSamplesCore, - Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ const PsychoacousticParameters *psychParamsCurrent, Word16 element_mode /* i: element mode */ ) @@ -62,14 +62,14 @@ void ivas_DetectTonalComponents_fx( Word16 thresholdModification[L_FRAME_MAX], lastMDCTSpect_exp; Word32 pScaledMdctSpectrum[L_FRAME_MAX]; Word16 nBands; - Word32 sns_int_scf_fx[FDNS_NPTS]; + Word32 sns_int_scf_fx[FDNS_NPTS]; /*Q16*/ Word16 q_pScaledMdctSpectrum; set32_fx( pScaledMdctSpectrum, 0, L_FRAME_MAX ); FOR( Word16 i = 0; i < nSamples; i++ ) { - pScaledMdctSpectrum[i] = L_shl( lastMDCTSpectrum[i], 16 ); // Q31 - lastMDCTSpectrum_exp + pScaledMdctSpectrum[i] = L_shl( lastMDCTSpectrum[i], 16 ); /*15-lastMDCTSpectrum_exp+16 -> 31 - lastMDCTSpectrum_exp*/ move32(); } #ifdef MSAN_FIX @@ -103,20 +103,20 @@ void ivas_DetectTonalComponents_fx( nBands = psychParamsCurrent->nBands; move16(); // till nSamplesCore different Q and nSamples - nSamplesCore in different Q - Scale_sig32( pScaledMdctSpectrum + nSamplesCore, sub( nSamples, nSamplesCore ), sub( lastMDCTSpectrum_exp, tmp_e ) ); + Scale_sig32( pScaledMdctSpectrum + nSamplesCore, sub( nSamples, nSamplesCore ), sub( lastMDCTSpectrum_exp, tmp_e ) ); /*q_pScaledMdctSpectrum+lastMDCTSpectrum_exp-tmp_e*/ lastMDCTSpect_exp = sub( 31, q_pScaledMdctSpectrum ); } FOR( Word16 i = nSamplesCore; i < nSamples; ++i ) { - Word64 tmp = W_mult_32_32( pScaledMdctSpectrum[i], sns_int_scf_fx[nBands - 1] ); // q_pScaledMdctSpectrum + 16 + 1 - pScaledMdctSpectrum[i] = W_extract_h( W_shl( tmp, Q15 ) ); // q_pScaledMdctSpectrum + Word64 tmp = W_mult_32_32( pScaledMdctSpectrum[i], sns_int_scf_fx[nBands - 1] ); /*q_pScaledMdctSpectrum+16+1*/ + pScaledMdctSpectrum[i] = W_extract_h( W_shl( tmp, Q15 ) ); /*q_pScaledMdctSpectrum*/ move32(); } /* Guard bit */ lastMDCTSpect_exp = add( lastMDCTSpect_exp, 1 ); - scale_sig32( pScaledMdctSpectrum, nSamples, -1 ); + scale_sig32( pScaledMdctSpectrum, nSamples, -1 ); /*q_pScaledMdctSpectrum - 1*/ /* Find peak candidates in the last frame. */ findCandidates( nSamples, pScaledMdctSpectrum, lastMDCTSpect_exp, thresholdModification, floorPowerSpectrum ); @@ -129,21 +129,21 @@ void ivas_DetectTonalComponents_fx( } void DetectTonalComponents( - Word16 indexOfTonalPeak[], - Word16 lowerIndex[], - Word16 upperIndex[], - Word16 *pNumIndexes, - const Word32 lastPitchLag, - const Word32 currentPitchLag, + Word16 indexOfTonalPeak[], /*Q0*/ + Word16 lowerIndex[], /*Q0*/ + Word16 upperIndex[], /*Q0*/ + Word16 *pNumIndexes, /*Q0*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ const Word16 lastMDCTSpectrum[], const Word16 lastMDCTSpectrum_exp, const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], + const Word32 secondLastPowerSpectrum[], /*Qx*/ const Word16 nSamples, const Word16 nSamplesCore, - Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ Word16 element_mode #ifdef IVAS_CODE_MDCT_GSHAPE , @@ -195,23 +195,23 @@ void DetectTonalComponents( * again detected Updates indexOfTonalPeak, lowerIndex, upperIndex, * phaseDiff, phases, pNumIndexes accordingly. */ void RefineTonalComponents( - Word16 indexOfTonalPeak[], - Word16 lowerIndex[], - Word16 upperIndex[], - Word16 phaseDiff[], - Word16 phases[], - Word16 *pNumIndexes, - const Word32 lastPitchLag, - const Word32 currentPitchLag, + Word16 indexOfTonalPeak[], /*Q0*/ + Word16 lowerIndex[], /*Q0*/ + Word16 upperIndex[], /*Q0*/ + Word16 phaseDiff[], /*Q12*/ + Word16 phases[], /*Q13*/ + Word16 *pNumIndexes, /*Q0*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ const Word16 lastMDCTSpectrum[], const Word16 lastMDCTSpectrum_exp, const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], + const Word32 secondLastPowerSpectrum[], /*Qx*/ const Word16 nSamples, const Word16 nSamplesCore, - const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ Word16 element_mode #ifdef IVAS_CODE_MDCT_GSHAPE , @@ -219,9 +219,9 @@ void RefineTonalComponents( #endif ) { - Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; - Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; - Word16 newUpperIndex[MAX_NUMBER_OF_IDX]; + Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; /*Q0*/ + Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; /*Q0*/ + Word16 newUpperIndex[MAX_NUMBER_OF_IDX]; /*Q0*/ Word16 newNumIndexes, nPreservedPeaks; Word16 iNew, iOld, j; Word16 *pOldPhase, *pNewPhase; @@ -239,8 +239,8 @@ void RefineTonalComponents( move16(); iNew = 0; move16(); - pOldPhase = phases; - pNewPhase = phases; + pOldPhase = phases; /*Q13*/ + pNewPhase = phases; /*Q13*/ FOR( iOld = 0; iOld < *pNumIndexes; iOld++ ) { @@ -254,66 +254,66 @@ void RefineTonalComponents( test(); IF( LT_16( iNew, newNumIndexes ) && GT_16( indexOfTonalPeak[iOld], newLowerIndex[iNew] ) ) { - newIndexOfTonalPeak[nPreservedPeaks] = indexOfTonalPeak[iOld]; + newIndexOfTonalPeak[nPreservedPeaks] = indexOfTonalPeak[iOld]; /*Q0*/ move16(); - newLowerIndex[nPreservedPeaks] = lowerIndex[iOld]; + newLowerIndex[nPreservedPeaks] = lowerIndex[iOld]; /*Q0*/ move16(); - newUpperIndex[nPreservedPeaks] = upperIndex[iOld]; + newUpperIndex[nPreservedPeaks] = upperIndex[iOld]; /*Q0*/ move16(); - phaseDiff[nPreservedPeaks] = phaseDiff[iOld]; + phaseDiff[nPreservedPeaks] = phaseDiff[iOld]; /*Q12*/ move16(); FOR( j = lowerIndex[iOld]; j <= upperIndex[iOld]; j++ ) { - *pNewPhase++ = *pOldPhase++; + *pNewPhase++ = *pOldPhase++; /*Q13*/ move16(); } nPreservedPeaks = add( nPreservedPeaks, 1 ); } ELSE { - pOldPhase += sub( upperIndex[iOld], add( lowerIndex[iOld], 1 ) ); + pOldPhase += sub( upperIndex[iOld], add( lowerIndex[iOld], 1 ) ); /*Q13*/ } } FOR( iNew = 0; iNew < nPreservedPeaks; iNew++ ) { - indexOfTonalPeak[iNew] = newIndexOfTonalPeak[iNew]; + indexOfTonalPeak[iNew] = newIndexOfTonalPeak[iNew]; /*Q0*/ move16(); - lowerIndex[iNew] = newLowerIndex[iNew]; + lowerIndex[iNew] = newLowerIndex[iNew]; /*Q0*/ move16(); - upperIndex[iNew] = newUpperIndex[iNew]; + upperIndex[iNew] = newUpperIndex[iNew]; /*Q0*/ move16(); } - *pNumIndexes = nPreservedPeaks; + *pNumIndexes = nPreservedPeaks; /*Q0*/ move16(); return; } void ivas_RefineTonalComponents_fx( - Word16 indexOfTonalPeak[], - Word16 lowerIndex[], - Word16 upperIndex[], - Word16 phaseDiff[], - Word16 phases[], - Word16 *pNumIndexes, - const Word32 lastPitchLag, - const Word32 currentPitchLag, + Word16 indexOfTonalPeak[], /*Q0*/ + Word16 lowerIndex[], /*Q0*/ + Word16 upperIndex[], /*Q0*/ + Word16 phaseDiff[], /*Q12*/ + Word16 phases[], /*Q13*/ + Word16 *pNumIndexes, /*Q0*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ const Word16 lastMDCTSpectrum[], const Word16 lastMDCTSpectrum_exp, const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], + const Word32 secondLastPowerSpectrum[], /*Qx*/ const Word16 nSamples, const Word16 nSamplesCore, - const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ Word16 element_mode, const PsychoacousticParameters *psychParamsCurrent ) { - Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; - Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; - Word16 newUpperIndex[MAX_NUMBER_OF_IDX]; + Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; /*Q0*/ + Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; /*Q0*/ + Word16 newUpperIndex[MAX_NUMBER_OF_IDX]; /*Q0*/ Word16 newNumIndexes, nPreservedPeaks; Word16 iNew, iOld, j; Word16 *pOldPhase, *pNewPhase; @@ -327,8 +327,8 @@ void ivas_RefineTonalComponents_fx( move16(); iNew = 0; move16(); - pOldPhase = phases; - pNewPhase = phases; + pOldPhase = phases; /*Q13*/ + pNewPhase = phases; /*Q13*/ FOR( iOld = 0; iOld < *pNumIndexes; iOld++ ) { @@ -342,38 +342,38 @@ void ivas_RefineTonalComponents_fx( test(); IF( LT_16( iNew, newNumIndexes ) && GT_16( indexOfTonalPeak[iOld], newLowerIndex[iNew] ) ) { - newIndexOfTonalPeak[nPreservedPeaks] = indexOfTonalPeak[iOld]; + newIndexOfTonalPeak[nPreservedPeaks] = indexOfTonalPeak[iOld]; /*Q0*/ move16(); - newLowerIndex[nPreservedPeaks] = lowerIndex[iOld]; + newLowerIndex[nPreservedPeaks] = lowerIndex[iOld]; /*Q0*/ move16(); - newUpperIndex[nPreservedPeaks] = upperIndex[iOld]; + newUpperIndex[nPreservedPeaks] = upperIndex[iOld]; /*Q0*/ move16(); - phaseDiff[nPreservedPeaks] = phaseDiff[iOld]; + phaseDiff[nPreservedPeaks] = phaseDiff[iOld]; /*Q12*/ move16(); FOR( j = lowerIndex[iOld]; j <= upperIndex[iOld]; j++ ) { - *pNewPhase++ = *pOldPhase++; + *pNewPhase++ = *pOldPhase++; /*Q13*/ move16(); } nPreservedPeaks = add( nPreservedPeaks, 1 ); } ELSE { - pOldPhase += sub( upperIndex[iOld], add( lowerIndex[iOld], 1 ) ); + pOldPhase += sub( upperIndex[iOld], add( lowerIndex[iOld], 1 ) ); /*Q13*/ } } FOR( iNew = 0; iNew < nPreservedPeaks; iNew++ ) { - indexOfTonalPeak[iNew] = newIndexOfTonalPeak[iNew]; + indexOfTonalPeak[iNew] = newIndexOfTonalPeak[iNew]; /*Q0*/ move16(); - lowerIndex[iNew] = newLowerIndex[iNew]; + lowerIndex[iNew] = newLowerIndex[iNew]; /*Q0*/ move16(); - upperIndex[iNew] = newUpperIndex[iNew]; + upperIndex[iNew] = newUpperIndex[iNew]; /*Q0*/ move16(); } - *pNumIndexes = nPreservedPeaks; + *pNumIndexes = nPreservedPeaks; /*Q0*/ move16(); return; } @@ -384,7 +384,7 @@ static void calcPseudoSpec( const Word32 *mdctSpec, /* i: MDCT spectrum */ const Word16 mdctSpec_exp, /* i: exponent of MDCT spectrum */ const Word16 nSamples, /* i: frame size */ - Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ Word32 *powerSpec, /* o: estimated power spectrum */ Word16 *powerSpec_exp /* o: exponent of estimated power spectrum */ ) @@ -401,33 +401,33 @@ static void calcPseudoSpec( /* If the signal is bellow floor, special care is needed for *powerSpec_exp */ IF( LT_16( add( 16 - 3, norm_s( floorPowerSpectrum ) ), k ) ) /*extra 3 bits of headroom for MA filter in getEnvelope*/ { - k = add( 16 - 3, norm_s( floorPowerSpectrum ) ); /*extra 3 bits of headroom for MA filter in getEnvelope*/ - L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k ); - set32_fx( powerSpec, L_tmp_floor, nSamples ); + k = add( 16 - 3, norm_s( floorPowerSpectrum ) ); /*extra 3 bits of headroom for MA filter in getEnvelope*/ + L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k ); /*Q : 13+norm_s( floorPowerSpectrum )*/ + set32_fx( powerSpec, L_tmp_floor, nSamples ); /*Q : 13+norm_s( floorPowerSpectrum )*/ *powerSpec_exp = sub( 31, k ); } ELSE { - L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k ); + L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k ); /*Q : 31 - *powerSpec_exp*/ tmp_loop = sub( nSamples, 2 ); FOR( k = 1; k <= tmp_loop; k++ ) { - x = L_sub( L_shr( mdctSpec[k + 1], 1 ), L_shr( mdctSpec[k - 1], 1 ) ); /* An MDST estimate */ + x = L_sub( L_shr( mdctSpec[k + 1], 1 ), L_shr( mdctSpec[k - 1], 1 ) ); /* An MDST estimate */ /*30-mdctSpec_exp*/ - x = L_shr( Mpy_32_32( x, x ), 3 ); + x = L_shr( Mpy_32_32( x, x ), 3 ); /*26-2*mdctSpec_exp*/ - L_tmp = Mpy_32_32( mdctSpec[k], mdctSpec[k] ); - L_tmp = L_shr( L_tmp, 5 ); + L_tmp = Mpy_32_32( mdctSpec[k], mdctSpec[k] ); /*31-2*mdctSpec_exp*/ + L_tmp = L_shr( L_tmp, 5 ); /*26-2*mdctSpec_exp*/ - powerSpec[k] = L_max( L_tmp_floor, L_add( L_tmp, x ) ); + powerSpec[k] = L_max( L_tmp_floor, L_add( L_tmp, x ) ); /*Q : 31 - *powerSpec_exp*/ move32(); } } - powerSpec[0] = L_shr( powerSpec[1], 1 ); + powerSpec[0] = L_shr( powerSpec[1], 1 ); /*0.5f * powerSpec[1]*/ move32(); - powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 ); + powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 ); /*0.5f * powerSpec[nSamples - 2]*/ move32(); return; } @@ -437,8 +437,8 @@ static void getEnvelope( const Word16 nSamples, /*i: Q0 */ const Word32 *powerSpec, /*i: powerSpec_exp */ Word16 F0, /*i: 5Q10*/ - Word32 *envelope, /*o: powerSpec_exp + LEVEL_EXP*/ - Word32 *smoothedSpectrum /*o: powerSpec_exp + LEVEL_EXP*/ + Word32 *envelope, /*o: powerSpec_exp + LEVEL_EXP Q28*/ + Word32 *smoothedSpectrum /*o: powerSpec_exp + LEVEL_EXP Q28*/ ) { Word16 nFilterLength, nHalfFilterLength, nSecondHalfFilterLength, n1, n2; @@ -448,12 +448,12 @@ static void getEnvelope( IF( F0 == 0 ) { - nFilterLength = 15; + nFilterLength = 15; /*Q0*/ move16(); } ELSE IF( F0 <= 10240 /*10.0f Q10*/ ) { - nFilterLength = 11; + nFilterLength = 11; /*Q0*/ move16(); } ELSE IF( F0 >= 22528 /*22.0f Q10*/ ) @@ -461,7 +461,7 @@ static void getEnvelope( /* For F0 >= 22 peak is isolated well enough with the filter length of 23. This case is however not triggered due to the limit of pit_min, but the line is left for security reasons. */ - nFilterLength = 23; + nFilterLength = 23; /*Q0*/ move16(); } ELSE @@ -487,13 +487,13 @@ static void getEnvelope( FOR( i = 0; i < n2; i++ ) { - sum = L_add( sum, powerSpec[i] ); + sum = L_add( sum, powerSpec[i] ); /*powerSpec_exp*/ } /* No need for PTR_INIT for powerSpec[i+n2] as we continue from the previous loop */ FOR( i = 0; i < n1; i++ ) { #ifdef BASOP_NOGLOB - sum = L_add_sat( sum, powerSpec[i + n2] ); + sum = L_add_sat( sum, powerSpec[i + n2] ); /*powerSpec_exp*/ #else sum = L_add( sum, powerSpec[i + n2] ); #endif @@ -502,36 +502,36 @@ static void getEnvelope( move32(); } - inv_len = mult_r( level, InvIntTable[nFilterLength] ); + inv_len = mult_r( level, InvIntTable[nFilterLength] ); /*Q12*/ FOR( i = n1; i < nSamples - n2; i++ ) { #ifdef BASOP_NOGLOB - sum = L_add_sat( sum, L_sub( powerSpec[i + n2], powerSpec[i - n1] ) ); + sum = L_add_sat( sum, L_sub( powerSpec[i + n2], powerSpec[i - n1] ) ); /*powerSpec_exp*/ #else sum = L_add( sum, L_sub( powerSpec[i + n2], powerSpec[i - n1] ) ); #endif - envelope[i] = Mpy_32_16_1( sum, inv_len ); + envelope[i] = Mpy_32_16_1( sum, inv_len ); /*Q28*/ move32(); } FOR( i = nSamples - n2; i < nSamples; i++ ) { sum = L_sub( sum, powerSpec[i - n1] ); - tmp = Mpy_32_16_1( sum, level ); - envelope[i] = Mpy_32_16_1( tmp, InvIntTable[sub( nSamples, sub( i, nHalfFilterLength ) )] ); + tmp = Mpy_32_16_1( sum, level ); /*Q28*/ + envelope[i] = Mpy_32_16_1( tmp, InvIntTable[( nSamples - ( i - nHalfFilterLength ) )] ); /*Q28*/ move32(); } FOR( i = 1; i < nSamples - 1; i++ ) { - smoothedSpectrum[i] = L_add( L_add( Mpy_32_16_1( powerSpec[i - 1], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[i], LEVEL_EXP ) ), Mpy_32_16_1( powerSpec[i + 1], 3072 /*0.75f Q12*/ ) ); + smoothedSpectrum[i] = L_add( L_add( Mpy_32_16_1( powerSpec[i - 1], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[i], LEVEL_EXP ) ), Mpy_32_16_1( powerSpec[i + 1], 3072 /*0.75f Q12*/ ) ); /*Q28*/ move32(); } move32(); move32(); - smoothedSpectrum[0] = L_add( Mpy_32_16_1( powerSpec[1], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[0], LEVEL_EXP ) ); - smoothedSpectrum[nSamples - 1] = L_add( Mpy_32_16_1( powerSpec[nSamples - 2], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[nSamples - 1], LEVEL_EXP ) ); + smoothedSpectrum[0] = L_add( Mpy_32_16_1( powerSpec[1], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[0], LEVEL_EXP ) ); /*Q28*/ + smoothedSpectrum[nSamples - 1] = L_add( Mpy_32_16_1( powerSpec[nSamples - 2], 3072 /*0.75f Q12*/ ), L_shr( powerSpec[nSamples - 1], LEVEL_EXP ) ); /**/ return; } @@ -545,7 +545,7 @@ static void GetF0( Word16 /*short*/ *const pF0 ) /*o - Q10*/ { Word16 /*short*/ tmpPitchLag; - Word16 /*short*/ rgiStrongHarmonics[MAX_PEAKS_FROM_PITCH]; + Word16 /*short*/ rgiStrongHarmonics[MAX_PEAKS_FROM_PITCH]; /*Q0*/ Word16 /*short*/ nTotalHarmonics, nStrongHarmonics; Word16 tmp; @@ -557,7 +557,7 @@ static void GetF0( IF( ( pitchLag > 0 ) && ( LE_16( round_fx( pitchLag ), shr( nSamplesCore, 1 ) ) ) ) { - tmpPitchLag /*"halfPitchLag" in FLC - read as Q5 for comparison to halfpitchlag */ + tmpPitchLag /*"halfPitchLag" in FLC - read as Q5 for comparison to halfpitchlag Q4*/ = round_fx( L_shl( pitchLag, 4 ) ); /*no division by 2, will be done in following division - furthermore, do a leftshift before rounding, to preserve more accuracy - will be accommodated also in following division*/ @@ -597,13 +597,13 @@ static void GetF0( static void findStrongestHarmonics( const Word16 nSamples, - const Word32 *powerSpectrum, + const Word32 *powerSpectrum, /*Qx*/ const Word16 F0 /*5Q10*/, const Word16 nTotalHarmonics, - Word16 *pHarmonicIndexes, - Word16 *pnHarmonics ) + Word16 *pHarmonicIndexes, /*Q0*/ + Word16 *pnHarmonics /*Q0*/ ) { - Word32 peaks[MAX_PEAKS_FROM_PITCH], smallestPeak; + Word32 peaks[MAX_PEAKS_FROM_PITCH] /*Qx*/, smallestPeak; Word16 nPeaksToCheck, nPeaks, iSmallestPeak; Word16 i, l, k; (void) nSamples; @@ -623,12 +623,12 @@ static void findStrongestHarmonics( { Word32 newPeak; - k = extract_h( L_shl( L_mult( i, F0 ), 5 ) ); /*k = (int)(i*F0);*/ + k = extract_h( L_shl( L_mult( i, F0 ), 5 ) ); /*k = (int)(i*F0); Q0*/ assert( k > 0 && k < 2 * LAST_HARMONIC_POS_TO_CHECK && k < nSamples ); - newPeak = L_add( powerSpectrum[k], 0 ); + newPeak = L_add( powerSpectrum[k], 0 ); /*Qx*/ - peaks[nPeaks] = newPeak; + peaks[nPeaks] = newPeak; /*Qx*/ move32(); pHarmonicIndexes[nPeaks] = i; move16(); @@ -647,14 +647,14 @@ static void findStrongestHarmonics( { Word32 newPeak; - k = extract_h( L_shl( L_mult( i, F0 ), 5 ) ); + k = extract_h( L_shl( L_mult( i, F0 ), 5 ) ); /*Q0*/ assert( k > 0 && k < 2 * LAST_HARMONIC_POS_TO_CHECK && k < nSamples ); - newPeak = L_add( powerSpectrum[k], 0 ); + newPeak = L_add( powerSpectrum[k], 0 ); /*Qx*/ IF( GT_32( newPeak, smallestPeak ) ) { - peaks[iSmallestPeak] = newPeak; + peaks[iSmallestPeak] = newPeak; /*Qx*/ move32(); pHarmonicIndexes[iSmallestPeak] = i; move16(); @@ -674,7 +674,7 @@ static void findStrongestHarmonics( sort_fx( pHarmonicIndexes, 0, sub( nPeaks, 1 ) ); - *pnHarmonics = nPeaks; + *pnHarmonics = nPeaks; /*Q0*/ move16(); return; } @@ -687,8 +687,8 @@ static void CorrectF0( { Word16 /*short*/ i; Word16 /*short*/ F0; - Word16 /*short*/ diff[MAX_PEAKS_FROM_PITCH - 1], sortedDiff[MAX_PEAKS_FROM_PITCH - 1]; - Word16 /*short*/ iMostCommonDiff, nMostCommonDiff, nSameDiff, iMult; + Word16 /*short*/ diff[MAX_PEAKS_FROM_PITCH - 1], sortedDiff[MAX_PEAKS_FROM_PITCH - 1]; /*Q0*/ + Word16 /*short*/ iMostCommonDiff, nMostCommonDiff, nSameDiff, iMult; /*Q0*/ Word16 tmp; @@ -701,7 +701,7 @@ static void CorrectF0( move16)); } #endif - F0 = *pF0; + F0 = *pF0; /*Q10*/ test(); IF( F0 > 0 && nHarmonics != 0 ) @@ -709,13 +709,13 @@ static void CorrectF0( tmp = sub( nHarmonics, 1 ); FOR( i = 0; i < tmp; i++ ) { - diff[i] = sub( pHarmonicIndexes[i + 1], pHarmonicIndexes[i] ); + diff[i] = sub( pHarmonicIndexes[i + 1], pHarmonicIndexes[i] ); /*Q0*/ move16(); - sortedDiff[i] = diff[i]; + sortedDiff[i] = diff[i]; /*Q0*/ move16(); } sort_fx( sortedDiff, 0, sub( nHarmonics, 1 + 1 ) ); - iMostCommonDiff = sortedDiff[0]; + iMostCommonDiff = sortedDiff[0]; /*Q0*/ move16(); nSameDiff = 1; move16(); @@ -732,7 +732,7 @@ static void CorrectF0( } } } - nMostCommonDiff = nSameDiff; + nMostCommonDiff = nSameDiff; /*Q0*/ move16(); /* If there are at least 3 distances between peaks with length 1 and if the 1st harmonic is in pHarmonicIndexes then keep the original F0 */ @@ -750,9 +750,9 @@ static void CorrectF0( { IF( GT_16( nSameDiff, nMostCommonDiff ) ) { - nMostCommonDiff = nSameDiff; + nMostCommonDiff = nSameDiff; /*Q0*/ move16(); - iMostCommonDiff = sortedDiff[i - 1]; + iMostCommonDiff = sortedDiff[i - 1]; /*Q0*/ move16(); } ELSE @@ -760,9 +760,9 @@ static void CorrectF0( test(); IF( EQ_16( nSameDiff, nMostCommonDiff ) && GT_16( abs_s( sub( iMostCommonDiff, pHarmonicIndexes[0] ) ), abs_s( sub( sortedDiff[i - 1], pHarmonicIndexes[0] ) ) ) ) { - nMostCommonDiff = nSameDiff; + nMostCommonDiff = nSameDiff; /*Q0*/ move16(); - iMostCommonDiff = sortedDiff[i - 1]; + iMostCommonDiff = sortedDiff[i - 1]; /*Q0*/ move16(); } } @@ -772,9 +772,9 @@ static void CorrectF0( } IF( GT_16( nSameDiff, nMostCommonDiff ) ) { - nMostCommonDiff = nSameDiff; + nMostCommonDiff = nSameDiff; /*Q0*/ move16(); - iMostCommonDiff = sortedDiff[nHarmonics - 2]; + iMostCommonDiff = sortedDiff[nHarmonics - 2]; /*Q0*/ move16(); } } @@ -788,7 +788,7 @@ static void CorrectF0( { IF( EQ_16( diff[i], iMostCommonDiff ) ) { - iMult = pHarmonicIndexes[i]; + iMult = pHarmonicIndexes[i]; /*Q0*/ move16(); BREAK; } @@ -797,7 +797,7 @@ static void CorrectF0( test(); IF( GT_16( sub( nHarmonics, 2 ), i ) && ( EQ_16( diff[i], diff[i + 1] ) ) && ( EQ_16( add( diff[i], diff[i + 1] ), iMostCommonDiff ) ) ) { - iMult = pHarmonicIndexes[i]; + iMult = pHarmonicIndexes[i]; /*Q0*/ move16(); BREAK; } @@ -808,7 +808,7 @@ static void CorrectF0( IF( LE_16( iMult, 3 ) ) { /* Use iMostCommonDiff, because the lowest pHarmonicIndexes[i] (which is equal to iMult) may not correspond to the new F0, but to it's multiple */ - F0 = round_fx( L_shl( L_mult( iMostCommonDiff /*Q0*/, F0 /*Q10*/ ), 15 ) ); + F0 = round_fx( L_shl( L_mult( iMostCommonDiff /*Q0*/, F0 /*Q10*/ ), 15 ) ); /*Q10*/ } ELSE { @@ -906,13 +906,13 @@ static void findCandidates( const Word32 *MDCTSpectrum, /* i: MDCT spectrum */ const Word16 MDCTSpectrum_exp, /* i: exponent of MDCT spectrum */ Word16 *thresholdModificationNew, /* o: threshold modification Q10 */ - Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ + Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins Q0*/ ) { Word32 powerSpectrum[L_FRAME_MAX]; Word16 powerSpectrum_exp; - Word32 envelope[L_FRAME_MAX]; - Word32 smoothedSpectrum[L_FRAME_MAX]; + Word32 envelope[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ + Word32 smoothedSpectrum[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ Word16 upperIdx, lowerIdx; Word16 k, j; Word32 biggerNeighbor; @@ -923,7 +923,7 @@ static void findCandidates( getEnvelope( nSamples, powerSpectrum, 0, envelope, smoothedSpectrum ); - set16_fx( thresholdModificationNew, UNREACHABLE_THRESHOLD, nSamples ); + set16_fx( thresholdModificationNew, UNREACHABLE_THRESHOLD, nSamples ); /*Q10*/ k = GROUP_LENGTH / 2; move16(); @@ -935,7 +935,7 @@ static void findCandidates( { /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */ /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */ - biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); + biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); /*powerSpectrum_exp*/ IF( GE_32( powerSpectrum[k], biggerNeighbor ) ) { @@ -1015,12 +1015,12 @@ static void findCandidates( tmp_loop3 = add( k, 2 ); FOR( j = sub( k, 1 ); j < tmp_loop3; j++ ) { - thresholdModificationNew[j] = BIG_THRESHOLD; + thresholdModificationNew[j] = BIG_THRESHOLD; /*Q10*/ move16(); if ( GT_32( smoothedSpectrum[j], envelope[j] ) ) { - thresholdModificationNew[j] = SMALL_THRESHOLD; + thresholdModificationNew[j] = SMALL_THRESHOLD; /*Q10*/ move16(); } } @@ -1037,11 +1037,12 @@ static void findCandidates( static void RefineThresholdsUsingPitch( const Word16 nSamples, const Word16 nSamplesCore, - const Word32 powerSpectrum[], - const Word32 lastPitchLag, - const Word32 currentPitchLag, - Word16 *pF0, - Word16 *thresholdModification ) + const Word32 powerSpectrum[], /*Qx*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ + Word16 *pF0, /*Q10*/ + Word16 *thresholdModification /*Q10*/ +) { Word16 pitchIsStable; Word16 origF0; @@ -1074,18 +1075,18 @@ static void RefineThresholdsUsingPitch( } static void findTonalComponents( - Word16 *indexOfTonalPeak, /* OUT */ - Word16 *lowerIndex, /* OUT */ - Word16 *upperIndex, /* OUT */ - Word16 *numIndexes, /* OUT */ + Word16 *indexOfTonalPeak, /* OUT Q0*/ + Word16 *lowerIndex, /* OUT Q0*/ + Word16 *upperIndex, /* OUT Q0*/ + Word16 *numIndexes, /* OUT Q0*/ Word16 nSamples, /* IN */ - const Word32 *powerSpectrum, /* IN */ + const Word32 *powerSpectrum, /* IN Qx*/ Word16 F0, /* IN */ - Word16 *thresholdModification, /* IN */ + Word16 *thresholdModification, /* IN Q10*/ Word16 element_mode ) /* IN */ { - Word32 envelope[L_FRAME_MAX]; - Word32 smoothedSpectrum[L_FRAME_MAX]; + Word32 envelope[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ + Word32 smoothedSpectrum[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ Word16 nrOfFIS; Word16 upperIdx, lowerIdx, lowerBound; Word16 k, j, m; @@ -1111,7 +1112,7 @@ static void findTonalComponents( { /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */ /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */ - biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); + biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); /*Qx*/ IF( GE_32( powerSpectrum[k], biggerNeighbor ) ) { diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index 06e96c6a333f60631d5c94c651b44ffbb1443502..10c763093eeab94f4b0965a5fd9bd00b226c684a 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -12,19 +12,19 @@ #ifdef IVAS_FLOAT_FIXED void mode_switch_decoder_LPD_fx( - Decoder_State *st, /* i/o: decoder state structure */ - Word16 bwidth, /* i : audio bandwidth */ - Word32 total_brate, /* i : total bitrate */ + Decoder_State *st, /* i/o: decoder state structure */ + Word16 bwidth, /* i : audio bandwidth Q0*/ + Word32 total_brate, /* i : total bitrate Q0*/ #ifdef IVAS_CODE_SWITCHING - const int32_t last_total_brate, /* i : last frame total bitrate */ + const Word32 last_total_brate, /* i : last frame total bitrate */ #endif - Word16 frame_size_index /* i : index determining the frame size*/ + Word16 frame_size_index /* i : index determining the frame size Q0*/ #ifdef IVAS_CODE_SWITCHING , - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT , - const int16_t last_element_mode + const Word16 last_element_mode #endif #endif ) @@ -56,7 +56,7 @@ void mode_switch_decoder_LPD_fx( move16(); /* set number of coded lines */ - st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( bwidth ); + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( bwidth ); /* Q0 */ move16(); test(); test(); @@ -120,10 +120,10 @@ void mode_switch_decoder_LPD_fx( move16(); st->fscale = fscale; move16(); - st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); + st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); /* Q0 */ IF( hTcxDec != NULL ) { - hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); + hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); /* Q0 */ move16(); } IF( st->hTcxCfg != NULL ) @@ -170,8 +170,8 @@ void mode_switch_decoder_LPD_fx( test(); IF( hTcxDec->envWeighted != 0 && hTcxDec->enableTcxLpc == 0 ) { - Copy( st->lspold_uw, st->lsp_old_fx, M ); - Copy( st->lsfold_uw, st->lsf_old_fx, M ); + Copy( st->lspold_uw, st->lsp_old_fx, M ); /* Q15 */ + Copy( st->lsfold_uw, st->lsf_old_fx, M ); /* Q2.56 */ hTcxDec->envWeighted = 0; move16(); } @@ -185,8 +185,8 @@ void mode_switch_decoder_LPD_fx( { E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsfoldbfi1_fx, M ); } - Copy( st->lsfoldbfi1_fx, st->lsfoldbfi0_fx, M ); - Copy( st->lsfoldbfi1_fx, st->lsf_adaptive_mean_fx, M ); + Copy( st->lsfoldbfi1_fx, st->lsfoldbfi0_fx, M ); /* Q2.56 */ + Copy( st->lsfoldbfi1_fx, st->lsf_adaptive_mean_fx, M ); /* Q2.56 */ IF( st->igf != 0 && hBWE_TD != NULL ) { @@ -254,7 +254,7 @@ void mode_switch_decoder_LPD_fx( test(); test(); test(); - IF( ( EQ_32( total_brate, 9600 ) || EQ_32( total_brate, 16400 ) || EQ_32( total_brate, 24400 ) ) && EQ_16( st->element_mode, EVS_MONO ) ) + IF( ( EQ_32( total_brate, 9600 ) || EQ_32( total_brate, 16400 ) || EQ_32( total_brate, 24400 ) ) && st->element_mode == EVS_MONO ) { st->dec_glr = 1; move16(); @@ -264,13 +264,13 @@ void mode_switch_decoder_LPD_fx( } void mode_switch_decoder_LPD_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word16 bwidth, /* i : audio bandwidth */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 last_total_brate, /* i : last frame total bitrate */ - const Word16 frame_size_index, /* i : index determining the frame size */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const Word16 last_element_mode, /* i : last element mode */ + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 bwidth, /* i : audio bandwidth Q0*/ + const Word32 total_brate, /* i : total bitrate Q0*/ + const Word32 last_total_brate, /* i : last frame total bitrate Q0*/ + const Word16 frame_size_index, /* i : index determining the frame size Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 last_element_mode, /* i : last element mode Q0*/ Word16 *Q_syn_Overl_TDAC, Word16 *Q_fer_samples, Word16 *Q_syn_Overl, @@ -364,22 +364,22 @@ void mode_switch_decoder_LPD_ivas_fx( move16(); IF( st->hTcxDec != NULL ) { - st->hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); + st->hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); /* Q0 */ move16(); - st->output_frame_fx = st->hTcxDec->L_frameTCX; + st->output_frame_fx = st->hTcxDec->L_frameTCX; /* Q0 */ move16(); } IF( st->hTcxCfg != NULL ) { - st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, total_brate, st->rf_flag ); + st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, total_brate, st->rf_flag ); /* Q0 */ move16(); - st->hTcxCfg->resq = getResq( total_brate ); + st->hTcxCfg->resq = getResq( total_brate ); /* Q0 */ move16(); } move16(); - hTcxDec->tcx_lpc_shaped_ari = getTcxLpcShapedAri( total_brate, st->rf_flag, st->element_mode ); + hTcxDec->tcx_lpc_shaped_ari = getTcxLpcShapedAri( total_brate, st->rf_flag, st->element_mode ); /* Q0 */ st->narrowBand = 0; move16(); @@ -399,7 +399,7 @@ void mode_switch_decoder_LPD_ivas_fx( IF( st->hTcxCfg != NULL ) { st->hTcxCfg->pCurrentTnsConfig = NULL; - st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( total_brate, st->igf, st->element_mode ); + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( total_brate, st->igf, st->element_mode ); /* Q0 */ move16(); } @@ -418,8 +418,8 @@ void mode_switch_decoder_LPD_ivas_fx( test(); IF( hTcxDec->envWeighted && !hTcxDec->enableTcxLpc ) { - Copy( st->lspold_uw, st->lsp_old_fx, M ); - Copy( st->lsfold_uw, st->lsf_old_fx, M ); + Copy( st->lspold_uw, st->lsp_old_fx, M ); /* Q15 */ + Copy( st->lsfold_uw, st->lsf_old_fx, M ); /* Q2.56 */ hTcxDec->envWeighted = 0; move16(); } @@ -432,8 +432,8 @@ void mode_switch_decoder_LPD_ivas_fx( { E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsfoldbfi1_fx, M ); } - Copy( st->lsfoldbfi1_fx, st->lsfoldbfi0_fx, M ); - Copy( st->lsfoldbfi1_fx, st->lsf_adaptive_mean_fx, M ); + Copy( st->lsfoldbfi1_fx, st->lsfoldbfi0_fx, M ); /* Qx2.56 */ + Copy( st->lsfoldbfi1_fx, st->lsf_adaptive_mean_fx, M ); /* Qx2.56 */ IF( st->igf && hBWE_TD != NULL ) { @@ -487,7 +487,7 @@ void mode_switch_decoder_LPD_ivas_fx( move16(); test(); test(); - IF( GE_16( bwidth, WB ) && EQ_32( total_brate, ACELP_24k40 ) && EQ_16( st->element_mode, EVS_MONO ) ) + IF( GE_16( bwidth, WB ) && EQ_32( total_brate, ACELP_24k40 ) && st->element_mode == EVS_MONO ) { st->enableGplc = 1; move16(); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 8e1a30d8b1d3fd36704a658b045e4221ffe7a46a..d1ace99f7ad36e07e8f5dded56b1b07ec759c6ef 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -58,14 +58,14 @@ void bandwidth_switching_detect_fx( } ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); /* Q0 */ move16(); } ELSE IF( st_fx->bws_cnt1 > 0 ) { IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) { - st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); + st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); /* Q0 */ move16(); } ELSE @@ -83,7 +83,7 @@ void bandwidth_switching_detect_fx( { IF( EQ_16( st_fx->bwidth, SWB ) ) { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); /* Q0 */ move16(); } ELSE @@ -105,14 +105,14 @@ void bandwidth_switching_detect_fx( } ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); /* Q0 */ move16(); } ELSE IF( st_fx->bws_cnt > 0 ) { IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) { - st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); + st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); /* Q0 */ move16(); } ELSE @@ -152,7 +152,9 @@ void bandwidth_switching_detect_fx( *---------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static Word32 Calc_freq_ener_fx( Word32 L_tmp, const Word16 Q_syn2 ) +static Word32 Calc_freq_ener_fx( + Word32 L_tmp, /* 2 * st->Q_syn2 */ + const Word16 Q_syn2 ) { Word32 enerLL_fx; Word16 exp, tmp; @@ -167,11 +169,11 @@ static Word32 Calc_freq_ener_fx( Word32 L_tmp, const Word16 Q_syn2 ) tmp = extract_h( L_shl( L_tmp, exp ) ); exp = sub( exp, sub( 30, shl( Q_syn2, 1 ) ) ); - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp*/ + tmp = div_s( 16384, tmp ); /* Q15 */ + L_tmp = L_deposit_h( tmp ); /* Q31 */ + L_tmp = Isqrt_lc( L_tmp, &exp ); - enerLL_fx = L_shr( L_tmp, sub( sub( 31, exp ), Q_syn2 ) ); /*st_fx->Q_syn2-1*/ + enerLL_fx = L_shr( L_tmp, sub( sub( 31, exp ), Q_syn2 ) ); /* st->Q_syn2 */ } return enerLL_fx; } @@ -185,7 +187,7 @@ static Word32 Calc_freq_ener_fx( Word32 L_tmp, const Word16 Q_syn2 ) #ifdef IVAS_FLOAT_FIXED void bw_switching_pre_proc_fx( - const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ + const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz Qx*/ Decoder_State *st_fx /* i/o: decoder state structure */ ) { @@ -197,7 +199,7 @@ void bw_switching_pre_proc_fx( move32(); #endif #ifdef IVAS_CODE_SWITCHING - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode > EVS_MONO ) { test(); test(); @@ -229,7 +231,7 @@ void bw_switching_pre_proc_fx( *----------------------------------------------------------------------*/ #ifdef BASOP_NOGLOB - st_fx->tilt_wb_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( old_syn_12k8_16k_fx, -1, st_fx->L_frame ), 3, &Overflow ), &Overflow ); + st_fx->tilt_wb_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( old_syn_12k8_16k_fx, -1, st_fx->L_frame ), 3, &Overflow ), &Overflow ); /* Q11 */ move16(); #else st_fx->tilt_wb_fx = round_fx( L_shl( calc_tilt_bwe_fx( old_syn_12k8_16k_fx, -1, st_fx->L_frame ), 3 ) ); @@ -244,13 +246,13 @@ void bw_switching_pre_proc_fx( FOR( i = 0; i < L_FRAME / 2; i++ ) { #ifdef BASOP_NOGLOB - L_tmp = L_mac0_o( L_tmp, syn_dct_fx[i], syn_dct_fx[i], &Overflow ); + L_tmp = L_mac0_o( L_tmp, syn_dct_fx[i], syn_dct_fx[i], &Overflow ); /* (2 * Q_syn2) */ #else L_tmp = L_mac0( L_tmp, syn_dct_fx[i], syn_dct_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 7 ); /*2*(st_fx->Q_syn2-1)*/ - st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ + st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); L_tmp = L_deposit_l( 0 ); FOR( ; i < L_FRAME; i++ ) @@ -261,8 +263,8 @@ void bw_switching_pre_proc_fx( L_tmp = L_mac0( L_tmp, syn_dct_fx[i], syn_dct_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 7 ); /*2*(st_fx->Q_syn2-1)*/ - st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ + st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); } ELSE @@ -273,25 +275,25 @@ void bw_switching_pre_proc_fx( FOR( i = 0; i < 32; i++ ) { #ifdef BASOP_NOGLOB - L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); + L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ #else L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 5 ); /*st_fx->Q_syn2-1*/ - st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 5 ); /* 2 * Q_syn2 */ + st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); L_tmp = L_deposit_l( 0 ); FOR( ; i < 64; i++ ) { #ifdef BASOP_NOGLOB - L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); + L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ #else L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 5 ); /*st_fx->Q_syn2-1*/ - st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 5 ); /* 2 * Q_syn2 */ + st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); } ELSE @@ -300,25 +302,25 @@ void bw_switching_pre_proc_fx( FOR( i = 0; i < L_FRAME / 2; i++ ) { #ifdef BASOP_NOGLOB - L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); + L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ #else L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 7 ); /*st_fx->Q_syn2-1*/ - st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ + st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); L_tmp = L_deposit_l( 0 ); FOR( ; i < L_FRAME; i++ ) { #ifdef BASOP_NOGLOB - L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); + L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ #else L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); #endif } - L_tmp = L_shr( L_tmp, 7 ); /*st_fx->Q_syn2-1*/ - st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); + L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ + st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ move32(); } } @@ -339,7 +341,7 @@ void bw_switching_pre_proc_fx( } ELSE IF( ( ( st_fx->core == ACELP_CORE && ( EQ_16( st_fx->last_core, HQ_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) || EQ_16( st_fx->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st_fx->core, st_fx->last_core ) && NE_16( st_fx->extl, st_fx->last_extl ) ) ) && GE_16( st_fx->last_bwidth, SWB ) ) { - st_fx->attenu_fx = 3277; + st_fx->attenu_fx = 3277; /* Q15 */ move16(); } @@ -508,7 +510,7 @@ static void smoothTransitionMdctStereoDtx( #ifdef IVAS_FLOAT_FIXED ivas_error core_switching_pre_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 output_frame /* i : frame length */ + const Word16 output_frame /* i : frame length Q0*/ ) { Word16 oldLenClasBuff, newLenClasBuff, i; @@ -533,18 +535,18 @@ ivas_error core_switching_pre_dec_fx( /* Codec switching */ IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && st_fx->element_mode > EVS_MONO ) ) { - st_fx->mem_deemph_fx = st_fx->syn[M]; + st_fx->mem_deemph_fx = st_fx->syn[M]; /* Q_syn */ move16(); - set16_fx( st_fx->agc_mem_fx, 0, 2 ); + set16_fx( st_fx->agc_mem_fx, 0, 2 ); /* Q0 */ Scale_sig( &( st_fx->mem_deemph_fx ), 1, st_fx->Q_syn ); /* Brings mem_deemph to Qsyn */ Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/ st_fx->bpf_off = 1; move16(); - Scale_sig( st_fx->hPFstat->mem_pf_in, L_SUBFR, st_fx->Q_syn ); /* Post_filter mem */ - Scale_sig( st_fx->hPFstat->mem_res2, DECMEM_RES2, st_fx->Q_syn ); /* NB post_filter mem */ - Scale_sig( st_fx->hPFstat->mem_stp, L_SUBFR, st_fx->Q_syn ); /* Post_filter mem */ + Scale_sig( st_fx->hPFstat->mem_pf_in, L_SUBFR, st_fx->Q_syn ); /* Post_filter mem */ /* st_fx->Q_syn*/ + Scale_sig( st_fx->hPFstat->mem_res2, DECMEM_RES2, st_fx->Q_syn ); /* NB post_filter mem */ /* st_fx->Q_syn */ + Scale_sig( st_fx->hPFstat->mem_stp, L_SUBFR, st_fx->Q_syn ); /* Post_filter mem */ /* st_fx->Q_syn */ IF( hBPF != NULL ) { set16_fx( hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ @@ -554,16 +556,16 @@ ivas_error core_switching_pre_dec_fx( move16(); } move16(); - st_fx->psf_lp_noise_fx = round_fx( L_shl( st_fx->lp_noise, 1 ) ); + st_fx->psf_lp_noise_fx = round_fx( L_shl( st_fx->lp_noise, 1 ) ); /* 2 * lp_noise_q - 16 */ /* reset old HB synthesis buffer */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - st_fx->old_bwe_delay = NS2SA_FX2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + st_fx->old_bwe_delay = NS2SA_FX2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); /* Q0 */ } ELSE { - st_fx->old_bwe_delay = NS2SA_FX2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + st_fx->old_bwe_delay = NS2SA_FX2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); /* Q0 */ } move16(); set16_fx( st_fx->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); @@ -581,7 +583,7 @@ ivas_error core_switching_pre_dec_fx( hBWE_TD->prev_hb_synth_fx_exp = 31; move16(); /* reset BWE memories */ - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); /* Q_exc */ hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); move32(); } @@ -628,7 +630,7 @@ ivas_error core_switching_pre_dec_fx( { st_fx->last_core = HQ_CORE; move16(); - Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); /* st_fx->q_prev_synth_buffer_fx */ } IF( hHQ_core != NULL ) { @@ -681,7 +683,7 @@ ivas_error core_switching_pre_dec_fx( move32(); } - no_col = s_min( st_fx->cldfbAna->no_col, idiv1616( sub( add( delay_comp, st_fx->cldfbAna->no_channels ), 1 ), st_fx->cldfbAna->no_channels ) ); + no_col = s_min( st_fx->cldfbAna->no_col, idiv1616( sub( add( delay_comp, st_fx->cldfbAna->no_channels ), 1 ), st_fx->cldfbAna->no_channels ) ); /* Q0 */ /* CLDFB analysis of the synthesis at internal sampling rate */ IF( ( error = cldfb_save_memory( st_fx->cldfbAna ) ) != IVAS_ERR_OK ) @@ -792,18 +794,18 @@ ivas_error core_switching_pre_dec_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); - Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi1_fx, M ); - Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi0_fx, M ); - Copy( TRWB2_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); + Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* Q2.56 */ + Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi1_fx, M ); /* Q2.56 */ + Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi0_fx, M ); /* Q2.56*/ + Copy( TRWB2_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); /* Q2.56 */ lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); } ELSE { - Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB_Ave_fx, st_fx->lsfoldbfi1_fx, M ); - Copy( TRWB_Ave_fx, st_fx->lsfoldbfi0_fx, M ); - Copy( TRWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); + Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ /* Q2.56 */ + Copy( TRWB_Ave_fx, st_fx->lsfoldbfi1_fx, M ); /* Q2.56 */ + Copy( TRWB_Ave_fx, st_fx->lsfoldbfi0_fx, M ); /* Q2.56 */ + Copy( TRWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); /* Q2.56 */ lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); } @@ -832,17 +834,17 @@ ivas_error core_switching_pre_dec_fx( set16_fx( st_fx->mem_MA_fx, 0, M ); IF( EQ_32( st_fx->sr_core, INT_FS_16k ) ) { - Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); + Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); /* Q2.56 */ } ELSE { - Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); /* Q2.56 */ } st_fx->tilt_code_fx = 0; move16(); st_fx->gc_threshold_fx = 0; move16(); - st_fx->dm_fx.prev_gain_code = L_deposit_l( 0 ); + st_fx->dm_fx.prev_gain_code = L_deposit_l( 0 ); /* Q16 */ move32(); set16_fx( st_fx->dm_fx.prev_gain_pit, 0, 6 ); st_fx->dm_fx.prev_state = 0; @@ -888,7 +890,7 @@ ivas_error core_switching_pre_dec_fx( test(); test(); - IF( !st_fx->last_con_tcx && !( ( EQ_16( st_fx->last_core, HQ_CORE ) ) && GT_16( st_fx->element_mode, EVS_MONO ) ) ) + IF( !st_fx->last_con_tcx && !( ( EQ_16( st_fx->last_core, HQ_CORE ) ) && st_fx->element_mode > EVS_MONO ) ) { set16_fx( st_fx->old_exc_fx, 0, L_EXC_MEM_DEC ); } @@ -959,7 +961,7 @@ ivas_error core_switching_pre_dec_fx( test(); test(); test(); - IF( hHQ_core != NULL && EQ_16( st_fx->core, HQ_CORE ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) || ( NE_16( st_fx->element_mode, EVS_MONO ) && NE_16( st_fx->last_core, HQ_CORE ) ) ) ) + IF( hHQ_core != NULL && EQ_16( st_fx->core, HQ_CORE ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) || ( st_fx->element_mode != EVS_MONO && NE_16( st_fx->last_core, HQ_CORE ) ) ) ) { set32_fx( hHQ_core->prev_env_fx, 0, SFM_N_WB ); set32_fx( hHQ_core->prev_normq_fx, 0, SFM_N_WB ); @@ -1019,7 +1021,7 @@ ivas_error core_switching_pre_dec_fx( /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ IF( hHQ_core != NULL ) { - hHQ_core->pastpre = sub( hHQ_core->pastpre, 1 ); + hHQ_core->pastpre = sub( hHQ_core->pastpre, 1 ); /* Q0 */ move16(); IF( hHQ_core->pastpre <= 0 ) { @@ -1049,7 +1051,7 @@ ivas_error core_switching_pre_dec_fx( } /*switch on CNA on active frames*/ - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ + IF( st_fx->element_mode == EVS_MONO ) /* for IVAS modes, st->flag_cna is set earlier */ { test(); test(); @@ -1133,7 +1135,7 @@ ivas_error core_switching_pre_dec_fx( { FOR( i = 0; i < shl( st_fx->L_frame, 1 ); i++ ) { - st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i] = mult_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i], 20480 ); + st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i] = mult_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i], 20480 /* Q15*/ ); /* q_olapBuffer */ move16(); } } @@ -1141,7 +1143,7 @@ ivas_error core_switching_pre_dec_fx( { FOR( i = 0; i < shl( st_fx->L_frame, 1 ); i++ ) { - st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i] = mult_r( shl( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i], 1 ), 26214 ); + st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i] = mult_r( shl( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth[i], 1 ), 26214 /* Q14*/ ); /* q_olapBuffer */ move16(); } } @@ -1162,20 +1164,20 @@ ivas_error core_switching_pre_dec_fx( #ifdef IVAS_FLOAT_FIXED ivas_error core_switching_post_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth */ + Word16 *synth, /* i/o: output synthesis Qsynth*/ #ifdef IVAS_CODE_SWITCHING float *output, /* i/o: LB synth/upsampled LB synth */ float output_mem[], /* i : OLA memory from last TCX/HQ frame */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ #endif - const Word16 output_frame, /* i : frame length */ - const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ + const Word16 output_frame, /* i : frame length Q0*/ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ #ifdef IVAS_CODE_SWITCHING const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ const Word16 nchan_out, /* i : number of output channels */ #endif - const Word16 last_element_mode, /* i : element mode of previous frame */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ) { @@ -1223,18 +1225,18 @@ ivas_error core_switching_post_dec_fx( } /* set multiplication factor according to the sampling rate */ - tmp = extract_l( L_shr( st_fx->output_Fs, 13 ) ); - Fs_kHz = shl( add( tmp, 1 ), 3 ); + tmp = extract_l( L_shr( st_fx->output_Fs, 13 ) ); /* Q0 */ + Fs_kHz = shl( add( tmp, 1 ), 3 ); /* Q0 */ delta = 1; move16(); if ( GE_16( output_frame, L_FRAME16k ) ) { - delta = shr( Fs_kHz, 3 ); + delta = shr( Fs_kHz, 3 ); /* Q0 */ } /* set delay compensation between HQ synthesis and ACELP synthesis */ - delay_comp = i_mult2( delta, HQ_DELAY_COMP ); + delay_comp = i_mult2( delta, HQ_DELAY_COMP ); /* Q0 */ IF( EQ_16( st_fx->core, HQ_CORE ) ) { @@ -1262,7 +1264,7 @@ ivas_error core_switching_post_dec_fx( test(); IF( core_switching_flag && EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->prev_bfi ) { - Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); + Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); /* hHQ_core->Q_old_postdec */ Qsubfr = hHQ_core->Q_old_postdec; move16(); } @@ -1270,16 +1272,16 @@ ivas_error core_switching_post_dec_fx( /* delay HQ synthesis to synchronize with ACELP synthesis */ /* rescaling to the min exp of the 2 */ Qtmp = s_min( *Qsynth, hHQ_core->Q_old_postdec ); - Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); /* Qtmp */ *Qsynth = Qtmp; move16(); - Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); - Copy( synth, &synth[delay_comp], output_frame ); - Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); - Copy( &synth[output_frame], st_fx->delay_buf_out_fx, delay_comp ); + Copy( synth, &synth[delay_comp], output_frame ); /* Qsynth */ + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* Q0 */ + Copy( &synth[output_frame], st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth */ test(); test(); @@ -1300,11 +1302,11 @@ ivas_error core_switching_post_dec_fx( ELSE IF( core_switching_flag && EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->prev_bfi ) /* HQ | ACELP | TRANSITION with ACELP frame lost */ { /* Overlapp between old->out (stocked in st_fx->fer_samples)and good HQ frame on L/2 */ - ptmp1 = &synth[delay_comp]; + ptmp1 = &synth[delay_comp]; /* Qsynth */ shift = i_mult2( Fs_kHz, 10 ); tmp = i_mult2( delta, shr( N16_CORE_SW, 1 ) ); - Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); /* Qsynth */ ptmp2 = &hHQ_core->fer_samples_fx[tmp]; tmp = div_s( 1, shift ); /*Q15*/ tmpF = 0; @@ -1332,7 +1334,7 @@ ivas_error core_switching_post_dec_fx( tmpF = 0; move16(); ptmp1 = synth; - Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); /* Qsynth */ ptmp2 = hHQ_core->fer_samples_fx; FOR( i = 0; i < shift; i++ ) { @@ -1368,9 +1370,9 @@ ivas_error core_switching_post_dec_fx( { Qtmp = s_min( s_min( *Qsynth, hHQ_core->Q_old_postdec ), hHQ_core->Q_old_wtda ); - Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); - Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); - Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( Qtmp, hHQ_core->Q_old_wtda ) ); + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); /* Qsynth */ + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ + Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( Qtmp, hHQ_core->Q_old_wtda ) ); /* Qtmp */ *Qsynth = Qtmp; move16(); hHQ_core->Q_old_postdec = Qtmp; @@ -1378,14 +1380,14 @@ ivas_error core_switching_post_dec_fx( hHQ_core->Q_old_wtda = Qtmp; move16(); - Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame */ + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame Q0*/ tmp = i_mult2( delta, N_ZERO_8 ); shift = i_mult2( Fs_kHz, 3 ); test(); IF( st_fx->prev_bfi && hHQ_core->HqVoicing ) { - Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[tmp], shift, *Qsynth ); + Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[tmp], shift, *Qsynth ); /* Qsynth */ } ptmp2 = &hHQ_core->old_out_fx[tmp]; @@ -1395,7 +1397,7 @@ ivas_error core_switching_post_dec_fx( move16(); FOR( i = 0; i < shift; i++ ) { - *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2++ ) ); + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2++ ) ); /* Q0 */ move16(); ptmp1++; tmpF = add( tmpF, tmp ); @@ -1419,7 +1421,7 @@ ivas_error core_switching_post_dec_fx( test(); IF( st_fx->bws_cnt == 0 || ( st_fx->bws_cnt > 0 && NE_16( st_fx->coder_type, INACTIVE ) && NE_16( st_fx->coder_type, AUDIO ) ) ) { - st_fx->attenu_fx = 3277; + st_fx->attenu_fx = 3277; /* Q15 */ move16(); } @@ -1574,16 +1576,16 @@ ivas_error core_switching_post_dec_fx( #ifdef IVAS_FLOAT_FIXED ivas_error core_switching_post_dec_ivas_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth */ - Word32 *output_fx, /* i/o: LB synth/upsampled LB synth */ - Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame */ + Word16 *synth, /* i/o: output synthesis Qsynth*/ + Word32 *output_fx, /* i/o: LB synth/upsampled LB synth Q4*/ + Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame Qx*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const Word16 output_frame, /* i : frame length */ - const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ - const Word16 last_element_mode, /* i : element mode of previous frame */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo Q0*/ + const Word16 output_frame, /* i : frame length Q0*/ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC Q0*/ + const Word16 nchan_out, /* i : number of output channels Q0*/ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ) { @@ -1613,7 +1615,7 @@ ivas_error core_switching_post_dec_ivas_fx( /* Rescale synthesis in Q0 to avoid multiple rescaling after */ tmp = Find_Max_Norm16( synth, output_frame ); - Scale_sig( synth, output_frame, tmp ); + Scale_sig( synth, output_frame, tmp ); /* Qsynth + tmp */ *Qsynth = add( *Qsynth, tmp ); move16(); @@ -1630,7 +1632,7 @@ ivas_error core_switching_post_dec_ivas_fx( } /* set multiplication factor according to the sampling rate */ - tmp = extract_l( L_shr( st_fx->output_Fs, 13 ) ); + tmp = extract_l( L_shr( st_fx->output_Fs, 13 ) ); /* Q0 */ Fs_kHz = shl( add( tmp, 1 ), 3 ); delta = 1; @@ -1641,7 +1643,7 @@ ivas_error core_switching_post_dec_ivas_fx( } /* set delay compensation between HQ synthesis and ACELP synthesis */ - delay_comp = i_mult2( delta, HQ_DELAY_COMP ); + delay_comp = i_mult2( delta, HQ_DELAY_COMP ); /* Q0 */ /*needed to add more condition in if*/ test(); test(); @@ -1687,7 +1689,7 @@ ivas_error core_switching_post_dec_ivas_fx( test(); IF( core_switching_flag && EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->prev_bfi ) { - Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); + Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); /* hHQ_core->Q_old_postdec */ Qsubfr = hHQ_core->Q_old_postdec; move16(); } @@ -1708,25 +1710,25 @@ ivas_error core_switching_post_dec_ivas_fx( test(); IF( hHQ_core->Q_old_postdec >= 0 || EQ_16( NonZero, 1 ) ) { - Scale_sig( st_fx->delay_buf_out_fx, delay_comp, negate( hHQ_core->Q_old_postdec ) ); + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, negate( hHQ_core->Q_old_postdec ) ); /* Q0 */ hHQ_core->Q_old_postdec = 0; move16(); } move16(); Qtmp = s_min( *Qsynth, hHQ_core->Q_old_postdec ); - Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); /* Qtmp */ *Qsynth = Qtmp; move16(); - Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); Word16 temp_buffer[L_FRAME48k]; - Copy( st_fx->delay_buf_out_fx, temp_buffer, delay_comp ); - Copy( synth + sub( output_frame, delay_comp ), st_fx->delay_buf_out_fx, delay_comp ); + Copy( st_fx->delay_buf_out_fx, temp_buffer, delay_comp ); /* Q0 */ + Copy( synth + sub( output_frame, delay_comp ), st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth */ move16(); - Copy( synth, synth + delay_comp, sub( output_frame, delay_comp ) ); - Copy( temp_buffer, synth, delay_comp ); + Copy( synth, synth + delay_comp, sub( output_frame, delay_comp ) ); /* Qsynth */ + Copy( temp_buffer, synth, delay_comp ); /* Q0 */ test(); test(); @@ -1758,7 +1760,7 @@ ivas_error core_switching_post_dec_ivas_fx( shift = i_mult2( Fs_kHz, 10 ); tmp = i_mult2( delta, shr( N16_CORE_SW, 1 ) ); - Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); /* Qsynth */ ptmp2 = &hHQ_core->fer_samples_fx[tmp]; tmp = div_s( 1, shift ); /*Q15*/ tmpF = 0; @@ -1786,7 +1788,7 @@ ivas_error core_switching_post_dec_ivas_fx( tmpF = 0; move16(); ptmp1 = synth; - Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); /* Qsynth */ ptmp2 = hHQ_core->fer_samples_fx; FOR( i = 0; i < shift; i++ ) { @@ -1815,11 +1817,11 @@ ivas_error core_switching_post_dec_ivas_fx( test(); IF( ( ( NE_32( st_fx->last_core_brate, SID_2k40 ) && NE_32( st_fx->last_core_brate, FRAME_NO_DATA ) ) || ( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) && NE_16( st_fx->element_mode, IVAS_CPE_TD ) ) || EQ_16( nchan_out, 1 ) ) && !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( st_fx->idchan, 1 ) && ( EQ_16( nchan_out, 1 ) || EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) ) { - Scale_sig32( output_fx, L_FRAME48k, Q10 - Q4 ); + Scale_sig32( output_fx, L_FRAME48k, Q10 - Q4 ); /* Q10 */ core_switch_lb_upsamp_fx( st_fx, output_fx ); } - Copy_Scale_sig( st_fx->previoussynth_fx, synth, delay_comp, *Qsynth ); + Copy_Scale_sig( st_fx->previoussynth_fx, synth, delay_comp, *Qsynth ); /* Qsynth */ /* Overlap between TCX-LB and TCX-FB*/ Word16 tmpDelta = NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); @@ -1831,11 +1833,11 @@ ivas_error core_switching_post_dec_ivas_fx( move32(); move32(); tmp = st_fx->previoussynth_fx[i + delay_comp]; - L_tmp = L_mac0( L_tmp, div_s( i, tmpDelta ), synth[i + delay_comp] ); + L_tmp = L_mac0( L_tmp, div_s( i, tmpDelta ), synth[i + delay_comp] ); /* Qsynth */ L_tmp = L_shl( L_tmp, 1 ); - L_tmp2 = L_mac0( L_tmp2, div_s( sub( tmpDelta, i ), tmpDelta ), tmp ); + L_tmp2 = L_mac0( L_tmp2, div_s( sub( tmpDelta, i ), tmpDelta ), tmp ); /* Qsynth */ L_tmp2 = L_shl( L_tmp2, 1 ); - synth[i + delay_comp] = round_fx( L_add( L_tmp, L_tmp2 ) ); + synth[i + delay_comp] = round_fx( L_add( L_tmp, L_tmp2 ) ); /* Qsynth */ } test(); test(); @@ -1863,24 +1865,24 @@ ivas_error core_switching_post_dec_ivas_fx( /* Update memories for CLDFB ana for eventual next ACELP frame */ IF( st_fx->cldfbAna != NULL ) { - delta = st_fx->cldfbAna->no_channels; + delta = st_fx->cldfbAna->no_channels; /* Q0 */ move16(); - offset = sub( st_fx->cldfbAna->p_filter_length, st_fx->cldfbAna->no_channels ); + offset = sub( st_fx->cldfbAna->p_filter_length, st_fx->cldfbAna->no_channels ); /* Q0 */ tmp = div_s( 1, delta ); - alpha = tmp; + alpha = tmp; /* Q15 */ move16(); FOR( i = 0; i < delta; i++ ) { st_fx->cldfbAna->cldfb_state_fx[offset - delta + i] = - Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], Q10 - Q4 ), alpha ); + Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], Q10 - Q4 ), alpha ); /* Q10 */ move32(); - IF( alpha < sub( 32767, tmp ) ) + IF( LT_16( alpha, sub( 32767, tmp ) ) ) { - alpha = add( alpha, tmp ); + alpha = add( alpha, tmp ); /* Q15 */ } ELSE { - alpha = 32767; + alpha = 32767; /* Q15 */ move16(); } } @@ -1916,21 +1918,21 @@ ivas_error core_switching_post_dec_ivas_fx( delta = st_fx->cldfbAna->no_channels; move16(); offset = sub( st_fx->cldfbAna->p_filter_length, st_fx->cldfbAna->no_channels ); - tmp = div_s( 1, delta ); - alpha = tmp; + tmp = div_s( 1, delta ); /* Q15 */ + alpha = tmp; /* Q15 */ move16(); FOR( i = 0; i < delta; i++ ) { st_fx->cldfbAna->cldfb_state_fx[offset - delta + i] = - Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], Q10 - Q4 ), alpha ); + Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], Q10 - Q4 ), alpha ); /* Q10 */ move32(); - IF( alpha < sub( 32767, tmp ) ) + IF( LT_16( alpha, sub( 32767, tmp ) ) ) { alpha = add( alpha, tmp ); } ELSE { - alpha = 32767; + alpha = 32767; /* Q15 */ move16(); } } @@ -1969,11 +1971,11 @@ ivas_error core_switching_post_dec_ivas_fx( Qtmp = s_min( s_min( *Qsynth, hHQ_core->Q_old_postdec ), hHQ_core->Q_old_wtda ); } - Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); /* Qtmp */ Scale_sig( st_fx->delay_buf_out_fx, delay_comp, Qtmp ); /*delay buff_out_fx is Q0*/ IF( hHQ_core != NULL ) { - Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( Qtmp, hHQ_core->Q_old_wtda ) ); + Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( Qtmp, hHQ_core->Q_old_wtda ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); hHQ_core->Q_old_wtda = Qtmp; @@ -1981,12 +1983,12 @@ ivas_error core_switching_post_dec_ivas_fx( } IF( output_mem_fx != NULL ) { - Scale_sig( output_mem_fx, NS2SA( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); + Scale_sig( output_mem_fx, NS2SA( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); /* Qtmp */ } *Qsynth = Qtmp; move16(); - Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame */ + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame Q0*/ nzeroes = i_mult2( delta, N_ZERO_8 ); shift = i_mult2( Fs_kHz, 3 ); @@ -1995,7 +1997,7 @@ ivas_error core_switching_post_dec_ivas_fx( test(); IF( st_fx->prev_bfi && st_fx->hHQ_core != NULL && hHQ_core->HqVoicing && EQ_16( st_fx->last_core, HQ_CORE ) ) { - Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nzeroes], shift, *Qsynth ); + Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nzeroes], shift, *Qsynth ); /* Qsynth */ } tmp = div_s( 1, shift ); @@ -2007,24 +2009,24 @@ ivas_error core_switching_post_dec_ivas_fx( ptmp1 = &synth[delay_comp]; FOR( i = 0; i < NS2SA_FX2( st_fx->output_Fs, 3000000 ); i++ ) { - *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); /* Qsynth */ move16(); ptmp1++; ptmp2++; - tmpF = add( tmpF, tmp ); + tmpF = add( tmpF, tmp ); /* Q15 */ } } ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && LE_32( st_fx->core_brate, SID_2k40 ) && st_fx->prev_bfi ) { - ptmp2 = &hHQ_core->old_out_fx[nzeroes]; + ptmp2 = &hHQ_core->old_out_fx[nzeroes]; /* Qsynth */ ptmp1 = &synth[delay_comp]; FOR( i = 0; i < NS2SA_FX2( st_fx->output_Fs, 3000000 ); i++ ) { - L_tmp = Mpy_32_16_1( st_fx->hTcxDec->conceal_eof_gain32, *ptmp2 ); + L_tmp = Mpy_32_16_1( st_fx->hTcxDec->conceal_eof_gain32, *ptmp2 ); /* Q15 */ L_tmp = L_shl( L_tmp, st_fx->hTcxDec->conceal_eof_gain_e ); tmpV = round_fx( L_tmp ); - *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), tmpV ) ); + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), tmpV ) ); /* Qsynth */ move16(); ptmp1++; ptmp2++; @@ -2032,15 +2034,15 @@ ivas_error core_switching_post_dec_ivas_fx( } ELSE { - ptmp2 = &hHQ_core->old_out_fx[nzeroes]; + ptmp2 = &hHQ_core->old_out_fx[nzeroes]; /* Qsynth */ ptmp1 = &synth[delay_comp]; FOR( i = 0; i < shift; i++ ) { - *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); /* Qsynth */ move16(); ptmp1++; ptmp2++; - tmpF = add( tmpF, tmp ); + tmpF = add( tmpF, tmp ); /* Q15 */ } } } @@ -2056,7 +2058,7 @@ ivas_error core_switching_post_dec_ivas_fx( ELSE { /* memory update needed for DFT stereo -> TD stereo switching, scaling synth to Q0 */ - Copy_Scale_sig( synth + sub( output_frame, delay_comp ), st_fx->delay_buf_out_fx, delay_comp, negate( *Qsynth ) ); + Copy_Scale_sig( synth + sub( output_frame, delay_comp ), st_fx->delay_buf_out_fx, delay_comp, negate( *Qsynth ) ); /* Q0 */ hHQ_core->Q_old_postdec = 0; move16(); } @@ -2067,7 +2069,7 @@ ivas_error core_switching_post_dec_ivas_fx( test(); IF( st_fx->bws_cnt == 0 || ( st_fx->bws_cnt > 0 && NE_16( st_fx->coder_type, INACTIVE ) && NE_16( st_fx->coder_type, AUDIO ) ) ) { - st_fx->attenu_fx = 3277; + st_fx->attenu_fx = 3277; /* Q15 */ move16(); } @@ -2256,9 +2258,9 @@ ivas_error core_switching_post_dec_ivas_fx( #ifdef IVAS_FLOAT_FIXED void core_switching_hq_prepare_dec_fx( - Decoder_State *st_fx, /* i/o: encoder state structure */ - Word16 *num_bits, /* i/o: bit budget update */ - const Word16 output_frame /* i : output frame length */ + Decoder_State *st_fx, /* i/o: encoder state structure */ + Word16 *num_bits, /* i/o: bit budget update Q0*/ + const Word16 output_frame /* i : output frame length Q0*/ ) { Word32 cbrate; @@ -2272,7 +2274,7 @@ void core_switching_hq_prepare_dec_fx( /* set switching frame bitrate */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - cbrate = L_add( st_fx->core_brate, 0 ); + cbrate = L_add( st_fx->core_brate, 0 ); /* Q0 */ IF( GT_32( st_fx->core_brate, ACELP_24k40 ) ) { cbrate = L_add( ACELP_24k40, 0 ); @@ -2337,8 +2339,8 @@ void core_switching_hq_prepare_dec_fx( #ifdef IVAS_FLOAT_FIXED static void core_switch_lb_upsamp_fx( - Decoder_State *st, /* i/o: Decoder state */ - Word32 *output /* i/o: LB synth/upsampled LB synth */ + Decoder_State *st, /* i/o: Decoder state */ + Word32 *output /* i/o: LB synth/upsampled LB synth Q10*/ ) { Word16 i, no_col; @@ -2369,7 +2371,7 @@ static void core_switch_lb_upsamp_fx( IF( st->ini_frame > 0 ) { - st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); /* Q10 */ move16(); } } @@ -2411,12 +2413,12 @@ static void core_switch_lb_upsamp_fx( no_col = s_min( no_col, temp ); } - Scale_sig32( output + imult1616( no_col, st->cldfbSyn->no_channels ), sub( L_FRAME48k, imult1616( no_col, st->cldfbSyn->no_channels ) ), 4 - 10 ); + Scale_sig32( output + imult1616( no_col, st->cldfbSyn->no_channels ), sub( L_FRAME48k, imult1616( no_col, st->cldfbSyn->no_channels ) ), 4 - 10 ); /* Q4 */ /* save synthesis - needed in case of core switching */ IF( st->hTcxDec != NULL ) { - Copy_Scale_sig_32_16( output, st->previoussynth_fx, st->hTcxDec->L_frameTCX, -4 ); + Copy_Scale_sig_32_16( output, st->previoussynth_fx, st->hTcxDec->L_frameTCX, -4 ); /* Q0 */ } return; @@ -2427,9 +2429,9 @@ static void core_switch_lb_upsamp_fx( #define TRANSITION_SMOOTHING_LEN_48k 47 static void smoothTransitionDtxToTcx_fx( - Word16 synth[], /* i/o: synthesis */ - const Word16 output_frame, /* i : output frame length */ - const Word16 delay_comp /* i : delay compensation in samples */ + Word16 synth[], /* i/o: synthesis Qsynth*/ + const Word16 output_frame, /* i : output frame length Q0*/ + const Word16 delay_comp /* i : delay compensation in samples Q0*/ ) { Word16 i, filter_len; @@ -2464,22 +2466,22 @@ static void smoothTransitionDtxToTcx_fx( smoothing_input_buffer[i] = synth[0]; move16(); } - Copy( synth, smoothing_input_buffer + shr( filter_len, 1 ), add( shl( delay_comp, 1 ), shr( filter_len, 1 ) ) ); + Copy( synth, smoothing_input_buffer + shr( filter_len, 1 ), add( shl( delay_comp, 1 ), shr( filter_len, 1 ) ) ); /* Qsynth */ /* apply Mean filter */ - w = div_s( 1, filter_len ); + w = div_s( 1, filter_len ); /* Q15 */ mem = 0; move32(); FOR( i = 0; i < filter_len; i++ ) { - mem = L_add( mem, L_deposit_l( smoothing_input_buffer[i] ) ); + mem = L_add( mem, L_deposit_l( smoothing_input_buffer[i] ) ); /* Qsynth */ } // mem = sum32_fx( smoothing_input_buffer, filter_len ); FOR( i = 0; i < shl( delay_comp, 1 ); i++ ) { - smoothing_out_buffer[i] = extract_l( Mpy_32_16_1( mem, w ) ); + smoothing_out_buffer[i] = extract_l( Mpy_32_16_1( mem, w ) ); /* Qsynth */ move16(); - mem = L_add( mem, L_sub( L_deposit_l( smoothing_input_buffer[i + filter_len] ), L_deposit_l( smoothing_input_buffer[i] ) ) ); + mem = L_add( mem, L_sub( L_deposit_l( smoothing_input_buffer[i + filter_len] ), L_deposit_l( smoothing_input_buffer[i] ) ) ); /* Qsynth */ } /* apply fades around transition */ @@ -2490,7 +2492,7 @@ static void smoothTransitionDtxToTcx_fx( fade_in = extract_l( 0 ); FOR( i = 0; i < delay_comp; i++ ) { - synth[i] = add( mult_r( smoothing_out_buffer[i], fade_in ), mult_r( synth[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); + synth[i] = add( mult_r( smoothing_out_buffer[i], fade_in ), mult_r( synth[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); /* Qsynth */ move16(); fade_in = add( fade_in, step ); } @@ -2499,7 +2501,7 @@ static void smoothTransitionDtxToTcx_fx( move16(); FOR( ; i < shl( delay_comp, 1 ); i++ ) { - synth[i] = add( mult_r( synth[i], fade_in ), mult_r( smoothing_out_buffer[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); + synth[i] = add( mult_r( synth[i], fade_in ), mult_r( smoothing_out_buffer[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); /* Qsynth */ move16(); fade_in = add( fade_in, step ); } diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index a3453ac537f656c6de7c7654daaffc59faf9123b..c952e23b8328804048f1cbcbbea483fb6847bc92 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -61,14 +61,15 @@ static void ivas_lfe_dec_delay_adjust_fx( LFE_DEC_HANDLE hLFE, - Word32 *pInbuf, - Word32 output_lfe_ch[] ) + Word32 *pInbuf, // Q9 + Word32 output_lfe_ch[] // Q9 +) { Word16 i, diff, loop_counter; Word16 fade_len, dct_len, zero_pad_len; Word32 tmp_buffer[L_FRAME48k]; - diff = sub( hLFE->lfe_prior_buf_len, hLFE->pWindow_state->fade_len ); + diff = sub( hLFE->lfe_prior_buf_len, hLFE->pWindow_state->fade_len ); // Q0 IF( diff < 0 ) { loop_counter = 0; @@ -78,27 +79,27 @@ static void ivas_lfe_dec_delay_adjust_fx( loop_counter = diff; } move16(); - fade_len = hLFE->pWindow_state->fade_len; + fade_len = hLFE->pWindow_state->fade_len; // Q0 move16(); - dct_len = hLFE->pWindow_state->dct_len; + dct_len = hLFE->pWindow_state->dct_len; // Q0 move16(); - zero_pad_len = hLFE->pWindow_state->zero_pad_len; + zero_pad_len = hLFE->pWindow_state->zero_pad_len; // Q0 move16(); FOR( i = 0; i < loop_counter; i++ ) { - tmp_buffer[i] = hLFE->prior_out_buffer_fx[i]; + tmp_buffer[i] = hLFE->prior_out_buffer_fx[i]; // Q9 move32(); } FOR( i = 0; i < fade_len; i++ ) { - tmp_buffer[i + loop_counter] = L_add( hLFE->prior_out_buffer_fx[i + loop_counter], pInbuf[i] ); + tmp_buffer[i + loop_counter] = L_add( hLFE->prior_out_buffer_fx[i + loop_counter], pInbuf[i] ); // Q9 move32(); } loop_counter = add( loop_counter, fade_len ); - FOR( i = 0; i < add( fade_len, shl( zero_pad_len, 1 ) ); i++ ) + FOR( i = 0; i < fade_len + ( zero_pad_len << 1 ); i++ ) { tmp_buffer[i + loop_counter] = pInbuf[i + fade_len]; move32(); @@ -128,7 +129,8 @@ static void ivas_lfe_dec_delay_adjust_fx( static void ivas_lfe_dec_windowing_fx( LFE_DEC_HANDLE hLFE, - Word32 *pInbuf ) + Word32 *pInbuf // Q9 +) { Word16 i; Word16 fade_len; @@ -139,23 +141,24 @@ static void ivas_lfe_dec_windowing_fx( move16(); zero_pad_len = hLFE->pWindow_state->zero_pad_len; move16(); - pWindow_coeffs = hLFE->pWindow_state->pWindow_coeffs_fx; + pWindow_coeffs = hLFE->pWindow_state->pWindow_coeffs_fx; // Q31 FOR( i = 0; i < fade_len; i++ ) { - pInbuf[i] = Mpy_32_32( pInbuf[add( zero_pad_len, i )], pWindow_coeffs[i] ); + pInbuf[i] = Mpy_32_32( pInbuf[zero_pad_len + i], pWindow_coeffs[i] ); + pInbuf[i] = Mpy_32_32( pInbuf[zero_pad_len + i], pWindow_coeffs[i] ); // Q9 move32(); } - FOR( i = 0; i < shl( zero_pad_len, 1 ); i++ ) + FOR( i = 0; i < zero_pad_len * 2; i++ ) { - pInbuf[add( fade_len, i )] = pInbuf[add( add( zero_pad_len, fade_len ), i )]; + pInbuf[fade_len + i] = pInbuf[zero_pad_len + fade_len + i]; move32(); } FOR( i = 0; i < fade_len; i++ ) { - pInbuf[add( add( shl( zero_pad_len, 1 ), fade_len ), i )] = Mpy_32_32( pInbuf[add( add( i_mult( zero_pad_len, 3 ), fade_len ), i )], pWindow_coeffs[sub( sub( fade_len, i ), 1 )] ); + pInbuf[zero_pad_len * 2 + fade_len + i] = Mpy_32_32( pInbuf[zero_pad_len * 3 + fade_len + i], pWindow_coeffs[fade_len - i - 1] ); // Q9 move32(); } @@ -172,7 +175,7 @@ static void ivas_lfe_dec_windowing_fx( static Word16 ivas_lfe_dec_dequant_fx( LFE_DEC_HANDLE hLFE, Decoder_State *st0, - Word32 *pOut_buf, + Word32 *pOut_buf, // Q24 Word16 *num_dct_pass_bins ) { Word16 shift_bits, i; @@ -239,7 +242,7 @@ static Word16 ivas_lfe_dec_dequant_fx( move16(); FOR( i = 0; i < 4; i++ ) { - abs_values[add( iii * 4, i )] = get_next_indice_fx( st0, base2_bit_size ); + abs_values[iii * 4 + i] = get_next_indice_fx( st0, base2_bit_size ); move16(); } } @@ -254,7 +257,7 @@ static Word16 ivas_lfe_dec_dequant_fx( FOR( i = 0; i < 4; i++ ) { - abs_values[add( iii * 4, i )] = ivas_ari_decode_14bits_bit_ext_1_lfe( st0, &as, hLFE->cum_freq_models[quant_strategy][iii], &extra_bits_read ); + abs_values[iii * 4 + i] = ivas_ari_decode_14bits_bit_ext_1_lfe( st0, &as, hLFE->cum_freq_models[quant_strategy][iii], &extra_bits_read ); move16(); } ivas_ari_done_decoding_14bits_ext_1_lfe( st0, extra_bits_read ); @@ -279,12 +282,12 @@ static Word16 ivas_lfe_dec_dequant_fx( { pOut_buf[2 * i] = Mpy_32_16_1( two_pow_shift_by_4, values[4 * i] ); // Q30 + Q9 >> 15 = Q24 move32(); - pOut_buf[add( 2 * i, 1 )] = Mpy_32_16_1( two_pow_shift_by_4, values[add( 4 * i, 1 )] ); // Q30 + Q9 >> 15 = Q24 + pOut_buf[2 * i + 1] = Mpy_32_16_1( two_pow_shift_by_4, values[4 * i + 1] ); // Q30 + Q9 >> 15 = Q24 move32(); - pOut_buf[add( 2 * i, *num_dct_pass_bins )] = Mpy_32_16_1( two_pow_shift_by_4, values[add( 4 * i, 2 )] ); // Q30 + Q9 >> 15 = Q24 + pOut_buf[2 * i + *num_dct_pass_bins] = Mpy_32_16_1( two_pow_shift_by_4, values[4 * i + 2] ); // Q30 + Q9 >> 15 = Q24 move32(); - pOut_buf[add( add( 2 * i, *num_dct_pass_bins ), 1 )] = Mpy_32_16_1( two_pow_shift_by_4, values[add( 4 * i, 3 )] ); // Q30 + Q9 >> 15 = Q24 + pOut_buf[2 * i + *num_dct_pass_bins + 1] = Mpy_32_16_1( two_pow_shift_by_4, values[4 * i + 3] ); // Q30 + Q9 >> 15 = Q24 move32(); } } @@ -306,15 +309,15 @@ void ivas_lfe_dec_fx( Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ const Word16 output_frame, /* i : output frame length per channel */ const Word16 bfi, /* i : BFI flag */ - Word32 output_lfe_ch[] /* o : output LFE synthesis */ + Word32 output_lfe_ch[] /* o : output LFE synthesis Q9*/ ) { Word16 num_dct_pass_bins; Word16 i, j, dct_len, q_out = 0; move16(); - Word32 out[L_FRAME48k]; - Word32 t_audio[L_FRAME48k]; - Word32 lfe_dct[IVAS_LFE_MAX_NUM_DCT_COEFFS]; + Word32 out[L_FRAME48k]; // Q9 + Word32 t_audio[L_FRAME48k]; // Q24 + Word32 lfe_dct[IVAS_LFE_MAX_NUM_DCT_COEFFS]; // Q24 dct_len = hLFE->pWindow_state->dct_len; move16(); @@ -347,7 +350,7 @@ void ivas_lfe_dec_fx( move16(); FOR( i = 0; i < L_FRAME_1k6; i++ ) { - hLFE->prevsynth_buf_fx[sub( add( i, LFE_PLC_BUFLEN ), L_FRAME_1k6 )] = output_lfe_ch[j]; + hLFE->prevsynth_buf_fx[i + LFE_PLC_BUFLEN - L_FRAME_1k6] = output_lfe_ch[j]; // Q9 move32(); j = add( j, shr( output_frame, 5 ) ); } @@ -407,7 +410,7 @@ void ivas_lfe_dec_fx( ivas_error ivas_create_lfe_dec_fx( LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ - const Word32 output_Fs, /* i : output sampling rate */ + const Word32 output_Fs, /* i : output sampling rate Q0*/ const Word32 binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ ) { @@ -457,20 +460,20 @@ ivas_error ivas_create_lfe_dec_fx( hLFE->cum_freq_models[1][3] = &ivas_str_lfe_freq_models.entropy_coder_model_coarse_sg4; /* delay calculation */ - hLFE->lfe_block_delay_s_fx = add( IVAS_LFE_FADE_S_Q15, ivas_lfe_lpf_delay_Q15[IVAS_FILTER_ORDER_4 - 3] ); + hLFE->lfe_block_delay_s_fx = add( IVAS_LFE_FADE_S_Q15, ivas_lfe_lpf_delay_Q15[IVAS_FILTER_ORDER_4 - 3] ); // Q15 move16(); - block_offset_s = BLOCK_OFFSET_S_Q15; + block_offset_s = BLOCK_OFFSET_S_Q15; // Q15 move16(); filt_order = 0; move16(); - low_pass_delay_dec_out = 0; + low_pass_delay_dec_out = 0; // Q15 move16(); hLFE->filter_state.order = filt_order; move16(); - hLFE->lfe_block_delay_s_fx = add( hLFE->lfe_block_delay_s_fx, low_pass_delay_dec_out ); + hLFE->lfe_block_delay_s_fx = add( hLFE->lfe_block_delay_s_fx, low_pass_delay_dec_out ); // Q15 move16(); - hLFE->lfe_prior_buf_len = NS2SA_FX2( output_Fs, IVAS_LFE_FADE_NS ); + hLFE->lfe_prior_buf_len = NS2SA_FX2( output_Fs, IVAS_LFE_FADE_NS ); // Q0 move16(); hLFE->bfi_count = 0; @@ -480,7 +483,7 @@ ivas_error ivas_create_lfe_dec_fx( { IF( NE_32( output_Fs, 32000 ) ) { - output_fs_fx = FS_16K_IN_NS_Q31; + output_fs_fx = FS_16K_IN_NS_Q31; // Q31 } ELSE { @@ -493,11 +496,11 @@ ivas_error ivas_create_lfe_dec_fx( } move32(); - lfe_addl_delay_s = sub( block_offset_s, hLFE->lfe_block_delay_s_fx ); + lfe_addl_delay_s = sub( block_offset_s, hLFE->lfe_block_delay_s_fx ); // Q15 lfe_addl_delay_s = s_max( 0, lfe_addl_delay_s ); - add_delay_sa = (Word16) W_round64_L( W_mult0_32_32( L_shl( binauralization_delay_ns, 1 ), output_fs_fx ) ); + add_delay_sa = (Word16) W_round64_L( W_mult0_32_32( L_shl( binauralization_delay_ns, 1 ), output_fs_fx ) ); // Q0 move16(); - hLFE->lfe_addl_delay = add( (Word16) L_shr( imult3216( output_Fs, lfe_addl_delay_s ), 15 ), add_delay_sa ); + hLFE->lfe_addl_delay = add( (Word16) L_shr( imult3216( output_Fs, lfe_addl_delay_s ), 15 ), add_delay_sa ); // Q0 move16(); IF( add_delay_sa == 0 ) { diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 007a099caea00ba131806f37e038c84955ba28e7..eaaf1d2a3cab1f980581eb7e7cd58a6204169b92 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -101,7 +101,7 @@ static void d_autocorr_fx( /* time reversed window */ FOR( i = 0; i < len; i++ ) { - t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[sub( sub( len, i ), 1 )] ); // Q = x_q_fx + t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - i - 1] ); // Q = x_q_fx move32(); } } @@ -116,7 +116,7 @@ static void d_autocorr_fx( FOR( ; i < len; i++ ) { - t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[sub( sub( len, 1 ), i )] ); // Q = x_q_fx + t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx move32(); } } @@ -137,11 +137,11 @@ static void d_autocorr_fx( s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) ); r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 ); move16(); - FOR( j = 1; j < sub( len, i ); j++ ) + FOR( j = 1; j < len - i; j++ ) { exp1 = norm_l( t_fx[j] ); - exp2 = norm_l( t_fx[add( i, j )] ); - temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[add( i, j )], exp2 ) ); + exp2 = norm_l( t_fx[i + j] ); + temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) ); tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 ); IF( LT_16( tmp_q, r_q_fx[i] ) ) @@ -486,7 +486,7 @@ static Word16 lfeplc_lev_dur_fx( move16(); WHILE( LT_16( i, m ) ) { - FOR( j = 1; j <= shr( i, 1 ); j++ ) + FOR( j = 1; j <= i / 2; j++ ) { l = sub( i, j ); exp1 = sub( norm_l( rc_fx[i - 1] ), 1 ); @@ -516,19 +516,19 @@ static Word16 lfeplc_lev_dur_fx( IF( LT_16( temp_q2, a_q_fx[j] ) ) { - at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); + at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2) temp_q1 = temp_q2; move16(); } ELSE { - at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); + at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx) temp_q1 = a_q_fx[j]; move16(); } temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] ); - temp_q2 = sub( add( rc_q_fx[sub( i, 1 )], a_q_fx[j] ), 31 ); + temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 ); if ( temp2 == 0 ) { temp_q2 = 31; @@ -553,15 +553,15 @@ static Word16 lfeplc_lev_dur_fx( move16(); } - a_fx[i] = rc_fx[sub( i, 1 )]; + a_fx[i] = rc_fx[i - 1]; move32(); - a_q_fx[i] = rc_q_fx[sub( i, 1 )]; + a_q_fx[i] = rc_q_fx[i - 1]; move16(); - exp1 = sub( norm_l( rc_fx[sub( i, 1 )] ), 1 ); + exp1 = sub( norm_l( rc_fx[i - 1] ), 1 ); exp2 = norm_l( s ); - temp1 = Mpy_32_32( L_shl( rc_fx[sub( i, 1 )], exp1 ), L_shl( s, exp2 ) ); - temp_q1 = sub( add( add( rc_q_fx[sub( i, 1 )], exp1 ), add( s_q_fx, exp2 ) ), 31 ); + temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) ); + temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 ); if ( temp1 == 0 ) { temp_q1 = 31; @@ -696,7 +696,7 @@ static Word16 d_a2rc_fx( } /* Initialization */ - FOR( m = sub( lpcorder, 1 ); m >= 0; m-- ) + FOR( m = lpcorder - 1; m >= 0; m-- ) { km_fx = ff_fx[m]; move32(); @@ -712,7 +712,7 @@ static Word16 d_a2rc_fx( return 0; } - refl_fx[m] = L_negate( km_fx ); + refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx) move32(); exp1 = norm_l( km_fx ); @@ -722,7 +722,7 @@ static Word16 d_a2rc_fx( denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) ); denom_q_fx = sub( 15, temp_q1 ); - FOR( j = 0; j < shr( m, 1 ); j++ ) + FOR( j = 0; j < m / 2; j++ ) { n = sub( sub( m, 1 ), j ); @@ -866,10 +866,10 @@ static void d_syn_filt_fx( } ELSE { - temp_q = yy_q_fx[sub( i, j )]; + temp_q = yy_q_fx[i - j]; move16(); } - temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[sub( i, j )], exp2 ) ); + temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) ); temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 ); IF( LT_16( s_q_fx, temp_q ) ) diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_dec/ivas_ls_custom_dec.c index 491f92ac9d03cccded361505505c473dbe8bdb50..19e2c167f2370c9bdcca58174f3a2f6d692221f9 100644 --- a/lib_dec/ivas_ls_custom_dec.c +++ b/lib_dec/ivas_ls_custom_dec.c @@ -86,8 +86,8 @@ ivas_error ivas_ls_custom_open_fx( ( *hLsSetupCustom )->is_planar_setup = -1; move16(); - set32_fx( ( *hLsSetupCustom )->ls_azimuth_fx, 0, MAX_OUTPUT_CHANNELS ); - set32_fx( ( *hLsSetupCustom )->ls_elevation_fx, 0, MAX_OUTPUT_CHANNELS ); + set32_fx( ( *hLsSetupCustom )->ls_azimuth_fx, 0, MAX_OUTPUT_CHANNELS ); // Q22 + set32_fx( ( *hLsSetupCustom )->ls_elevation_fx, 0, MAX_OUTPUT_CHANNELS ); // Q22 ( *hLsSetupCustom )->num_lfe = -1; move16(); @@ -144,9 +144,9 @@ void ivas_ls_custom_setup_fx( hOutSetup->nchan_out_woLFE = hLsSetupCustom->num_spk; move16(); - hOutSetup->ls_azimuth_fx = hLsSetupCustom->ls_azimuth_fx; + hOutSetup->ls_azimuth_fx = hLsSetupCustom->ls_azimuth_fx; // Q22 move32(); - hOutSetup->ls_elevation_fx = hLsSetupCustom->ls_elevation_fx; + hOutSetup->ls_elevation_fx = hLsSetupCustom->ls_elevation_fx; // Q22 move32(); hOutSetup->num_lfe = hLsSetupCustom->num_lfe; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 0cecfe2e77cf9c8455fb4de7c5b0e3dc3236f9ce..a2f30844149e6d65ec897968d46765683002fea8 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -5408,7 +5408,7 @@ void ivas_spar_to_dirac_fx( order = sba_order_internal; move16(); } - ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); + ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, 1, NULL, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ FOR( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) @@ -5435,7 +5435,7 @@ void ivas_spar_to_dirac_fx( order = sba_order_internal; move16(); } - ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, num_md_sub_frames, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, idiv1616( num_bands_out, bw ), order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); + ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, num_md_sub_frames, NULL, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, idiv1616( num_bands_out, bw ), order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); test(); IF( st_ivas->hQMetaData->useLowerRes && dtx_vad ) diff --git a/lib_dec/ivas_stereo_adapt_GR_dec.c b/lib_dec/ivas_stereo_adapt_GR_dec.c index b47aa68ae69833768431522edfc2411a82c39de0..24d0975caf7ed9451b1437c9da61c54fabb032e1 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec.c @@ -51,9 +51,9 @@ /*! r: number of bits read */ static Word16 read_GR2( - const UWord16 *bit_stream, /* i : bitstream to be read */ - Word16 *ind, /* o : parameters read */ - const Word16 len /* i : number of params to be read */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + Word16 *ind, /* o : parameters read Q0*/ + const Word16 len /* i : number of params to be read Q0*/ ) { Word16 i; @@ -108,9 +108,9 @@ static Word16 read_GR2( /*! r: number of bits read */ static Word16 read_GR1( - const UWord16 *bit_stream, /* i : bitstream to be read */ - Word16 *ind, /* o : parameters read */ - const Word16 len /* i : number of params to be read */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + Word16 *ind, /* o : parameters read Q0*/ + const Word16 len /* i : number of params to be read Q0*/ ) { Word16 i; @@ -146,7 +146,7 @@ static Word16 read_GR1( b = *p++; move16(); - ind[i] = extract_l( L_add( L_shl( temp, 1 ), b ) ); + ind[i] = extract_l( L_add( L_shl( temp, 1 ), b ) ); /* Q0 */ move16(); nb = (UWord16) L_add( nb, L_add( temp, 2 ) ); move16(); @@ -164,9 +164,9 @@ static Word16 read_GR1( /*! r: number of bits read */ Word16 read_GR0( - const UWord16 *bit_stream, /* i : bitstream to be read */ - Word16 *ind, /* o : parameters read */ - const Word16 len /* i : number of params to be read */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + Word16 *ind, /* o : parameters read Q0*/ + const Word16 len /* i : number of params to be read Q0*/ ) { Word16 i; @@ -217,10 +217,10 @@ Word16 read_GR0( /*! r: index in array */ static ivas_error find_map( - Word16 *map_idx, - const Word16 *map, /* i : array to look into */ - const Word16 val, /* i : value to look for */ - const Word16 len /* i : length of array */ + Word16 *map_idx, /* Q0 */ + const Word16 *map, /* i : array to look into Q0*/ + const Word16 val, /* i : value to look for Q0*/ + const Word16 len /* i : length of array Q0*/ ) { *map_idx = 0; @@ -229,7 +229,7 @@ static ivas_error find_map( WHILE( ( NE_16( map[*map_idx], val ) ) && ( NE_16( *map_idx, len ) ) ) { test(); - *map_idx = add( *map_idx, 1 ); + *map_idx = add( *map_idx, 1 ); /* Q0 */ move16(); } @@ -245,11 +245,11 @@ static ivas_error find_map( *---------------------------------------------------------------------*/ static void decode_adapt_GR_indices1( - const Word16 *ind, /* i : array of input encoded symbols */ - const Word16 len, /* i : number of parameters to decode */ - const Word16 no_symb, /* i : number of possible symbols in GR coding */ - Word16 *out, /* o : array of decoded parameters */ - const Word16 *map0 /* i : initial mapping array for the adaptive GR */ + const Word16 *ind, /* i : array of input encoded symbols Q0*/ + const Word16 len, /* i : number of parameters to decode Q0*/ + const Word16 no_symb, /* i : number of possible symbols in GR coding Q0*/ + Word16 *out, /* o : array of decoded parameters Q0*/ + const Word16 *map0 /* i : initial mapping array for the adaptive GR Q0*/ ) { const Word16 *map; @@ -257,7 +257,7 @@ static void decode_adapt_GR_indices1( IF( EQ_16( no_symb, NO_SYMB_GR_SIDE_G ) ) { - map = &map0[i_mult( 15, no_symb )]; + map = &map0[15 * no_symb]; } ELSE { @@ -269,7 +269,7 @@ static void decode_adapt_GR_indices1( map_symb = ind[i]; move16(); find_map( out + i, map, map_symb, no_symb ); - map = &( map0[i_mult( out[i], no_symb )] ); + map = &( map0[out[i] * no_symb] ); } return; @@ -284,8 +284,8 @@ static void decode_adapt_GR_indices1( /*! r: read value */ Word16 get_value( - const UWord16 *bit_stream, /* i : bitstream */ - const Word16 nbits /* i : number of bits to be read */ + const UWord16 *bit_stream, /* i : bitstream Q0*/ + const Word16 nbits /* i : number of bits to be read Q0*/ ) { Word16 i; @@ -293,7 +293,7 @@ Word16 get_value( move16(); move16(); - FOR( i = sub( nbits, 1 ); i >= 0; i-- ) + FOR( i = nbits - 1; i >= 0; i-- ) { val = (UWord16) L_add( val, L_shl( bit_stream[i], mask ) ); mask = (UWord16) L_add( mask, 1 ); @@ -313,11 +313,11 @@ Word16 get_value( /*! r: number of bits read */ Word16 read_BS_GR( - const UWord16 *bit_stream, /* i : bitstream to be read */ - const Word16 nb, /* i : starting point in bitstream */ - Word16 *ind1, /* o : data array read */ - const Word16 len, /* i : number of params to be read */ - Word16 *GR_ord /* o : GR order to be used */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + const Word16 nb, /* i : starting point in bitstream Q0*/ + Word16 *ind1, /* o : data array read Q0*/ + const Word16 len, /* i : number of params to be read Q0*/ + Word16 *GR_ord /* o : GR order to be used Q0*/ ) { Word16 b, ind1_tmp[STEREO_DFT_BAND_MAX], tmp, i; @@ -329,11 +329,11 @@ Word16 read_BS_GR( IF( *GR_ord == 0 ) { - b = add( b, read_GR0( &bit_stream[add( nb, b )], ind1_tmp, len ) ); + b = add( b, read_GR0( &bit_stream[nb + b], ind1_tmp, len ) ); /* Q0 */ } ELSE { - b = add( b, read_GR1( &bit_stream[add( nb, b )], ind1_tmp, len ) ); + b = add( b, read_GR1( &bit_stream[nb + b], ind1_tmp, len ) ); /* Q0 */ } FOR( i = 0; i < len; i++ ) @@ -341,12 +341,12 @@ Word16 read_BS_GR( tmp = add( ind1_tmp[i], 1 ); IF( s_and( tmp, 1 ) ) /* if odd number */ { - ind1[i] = negate( shr( ind1_tmp[i], 1 ) ); + ind1[i] = negate( shr( ind1_tmp[i], 1 ) ); /* Q0 */ move16(); } ELSE { - ind1[i] = shr( tmp, 1 ); + ind1[i] = shr( tmp, 1 ); /* Q0 */ move16(); } } @@ -363,12 +363,12 @@ Word16 read_BS_GR( /*! r: number of bits read */ Word16 read_BS_adapt_GR_sg( - const UWord16 *bit_stream, /* i : bitstream to be read */ - const Word16 nb, /* i : starting position in bitstream */ - Word16 *ind1, /* o : decoded side gain values */ - const Word16 len, /* i : number of params to be read */ - Word16 *GR_ord, /* o : GR order used (read from bitstream)*/ - const Word16 *map0 /* i : initial map */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + const Word16 nb, /* i : starting position in bitstream Q0*/ + Word16 *ind1, /* o : decoded side gain values Q0*/ + const Word16 len, /* i : number of params to be read Q0*/ + Word16 *GR_ord, /* o : GR order used (read from bitstream) Q0*/ + const Word16 *map0 /* i : initial map Q0*/ ) { Word16 b, ind1_tmp[STEREO_DFT_BAND_MAX], ord; @@ -378,7 +378,7 @@ Word16 read_BS_adapt_GR_sg( move16(); b = add( b, read_GR1( &bit_stream[nb], ind1_tmp, 1 ) ); /* read GR ord */ - ord = bit_stream[add( nb, b )]; + ord = bit_stream[nb + b]; move16(); b = add( b, 1 ); @@ -386,25 +386,25 @@ Word16 read_BS_adapt_GR_sg( { *GR_ord = 1; move16(); - b = add( b, read_GR1( &bit_stream[add( nb, b )], &ind1_tmp[1], sub( len, 1 ) ) ); + b = add( b, read_GR1( &bit_stream[nb + b], &ind1_tmp[1], sub( len, 1 ) ) ); /* Q0 */ } ELSE { - ord = bit_stream[add( nb, b )]; + ord = bit_stream[nb + b]; move16(); - b = add( b, 1 ); + b = b + 1; IF( ord == 0 ) { *GR_ord = 0; move16(); - b = add( b, read_GR0( &bit_stream[add( nb, b )], &ind1_tmp[1], sub( len, 1 ) ) ); + b = add( b, read_GR0( &bit_stream[nb + b], &ind1_tmp[1], sub( len, 1 ) ) ); /* Q0 */ } ELSE { *GR_ord = 2; move16(); - b = add( b, read_GR2( &bit_stream[add( nb, b )], &ind1_tmp[1], sub( len, 1 ) ) ); + b = add( b, read_GR2( &bit_stream[nb + b], &ind1_tmp[1], sub( len, 1 ) ) ); /* Q0 */ } } @@ -422,8 +422,8 @@ Word16 read_BS_adapt_GR_sg( /*! r: number of bits read */ Word16 read_itd( - Decoder_State *st, /* i : Decoder state */ - Word16 *pI /* o : ITD value */ + Decoder_State *st, /* i : Decoder state */ + Word16 *pI /* o : ITD value Q0*/ ) { Word16 huff_flag, sign_flag, I, i, nb = 0, ready; @@ -486,19 +486,19 @@ Word16 read_itd( /*! r: number of bits read */ Word16 read_BS_adapt_GR_rpg( - const UWord16 *bit_stream, /* i : bitstream to be read */ - const Word16 nb, /* i : starting point in bitstream */ - Word16 *ind1_pred, /* o : decoded res pred gains */ - const Word16 start, /* i : starting subband */ - const Word16 total_no, /* i : number of params to be read */ - Word16 *GR_ord /* o : GR order - read */ + const UWord16 *bit_stream, /* i : bitstream to be read Q0*/ + const Word16 nb, /* i : starting point in bitstream Q0*/ + Word16 *ind1_pred, /* o : decoded res pred gains Q0*/ + const Word16 start, /* i : starting subband Q0*/ + const Word16 total_no, /* i : number of params to be read Q0*/ + Word16 *GR_ord /* o : GR order - read Q0*/ ) { Word16 b, ind1_tmp[STEREO_DFT_BAND_MAX], i, len; len = sub( total_no, start ); /* read first band */ - b = read_GR1( &bit_stream[nb], ind1_tmp, 1 ); + b = read_GR1( &bit_stream[nb], ind1_tmp, 1 ); /* Q0 */ IF( EQ_16( ind1_tmp[0], dft_maps_rpg[8 * NO_SYMB_GR_PRED_G] ) ) { @@ -510,17 +510,17 @@ Word16 read_BS_adapt_GR_rpg( } ELSE { - *GR_ord = bit_stream[add( nb, b )]; /* GR order */ + *GR_ord = bit_stream[nb + b]; /* GR order */ move16(); b = add( b, 1 ); IF( *GR_ord == 0 ) { - b = add( b, read_GR0( &bit_stream[add( nb, b )], &ind1_tmp[1], sub( len, 1 ) ) ); + b = add( b, read_GR0( &bit_stream[nb + b], &ind1_tmp[1], sub( len, 1 ) ) ); /* Q0 */ } ELSE { /* GR ord 1 */ - b = add( b, read_GR1( &bit_stream[add( nb, b )], &ind1_tmp[1], sub( len, 1 ) ) ); + b = add( b, read_GR1( &bit_stream[nb + b], &ind1_tmp[1], sub( len, 1 ) ) ); /* Q0 */ } decode_adapt_GR_indices1( ind1_tmp, sub( total_no, start ), NO_SYMB_GR_PRED_G, &ind1_pred[start], dft_maps_rpg ); } @@ -537,8 +537,8 @@ Word16 read_BS_adapt_GR_rpg( /*! r: number of bits read */ Word16 read_flag_EC_DFT( - const UWord16 *bit_stream, /* i : bitstream */ - Word16 *flag /* o : flag value */ + const UWord16 *bit_stream, /* i : bitstream Q0*/ + Word16 *flag /* o : flag value Q0*/ ) { Word16 flg; diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index ddb4512ccd32d250b12a8554574d8259171c8cc8..b578a8eeffacb38549253eb9fdb8b595fb3b12ff 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -469,7 +469,7 @@ ivas_error ivas_core_enc( st->hTcxCfg->preemph_fac = float_to_fix16( st->hTcxCfg->preemph_fac_flt, Q15 ); { - st->clip_var_fx[0] = (Word16) ( st->clip_var[8] * 2.56f ); + st->clip_var_fx[0] = (Word16) ( st->clip_var[0] * 2.56f ); st->clip_var_fx[1] = float_to_fix16( st->clip_var[1], Q14 ); st->clip_var_fx[2] = float_to_fix16( st->clip_var[2], Q8 ); st->clip_var_fx[3] = float_to_fix16( st->clip_var[3], 0 ); diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 023434678f357af654de741fd503282e90944a43..3dc5c4cd1d60fed98c012d0b2469cd65e7e4c79d 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -1133,7 +1133,11 @@ ivas_error ivas_init_encoder( } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_param_mc_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1769,7 +1773,11 @@ ivas_error ivas_init_encoder_fx( } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_param_mc_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2153,7 +2161,11 @@ void ivas_destroy_enc( ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); /* Parametric MC handle */ +#ifdef IVAS_FLOAT_FIXED + ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_param_mc_enc_close( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#endif /* Multi-channel MASA handle */ #ifdef IVAS_FLOAT_FIXED diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 81a43a695c68b7e853a21a7e905bcf41b4f05d28..a7eb2b719b423fcb99b4b5c6b3c53f4eeeacf59c 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -91,15 +91,46 @@ static void reduce_metadata_further_fx( MASA_ENCODER_HANDLE hMasa, IVAS_QMETADAT static void average_masa_metadata( MASA_METADATA_FRAME *masaMetadata, float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const SPHERICAL_GRID_DATA *sphGrid, const uint8_t useSphGrid ); +#ifdef IVAS_FLOAT_FIXED +static void copy_masa_metadata_subframe_fx( + const MASA_METADATA_HANDLE hMetaFrom, /* i : MASA frame metdata to be copied */ + const UWord8 sfFrom, /* i : subframe index of the copy source */ + MASA_METADATA_HANDLE hMetaTo, /* o : MASA frame metadata copy destination */ + const UWord8 sfTo /* i : subframe index of the copy target */ +); +#else static void copy_masa_metadata_subframe( const MASA_METADATA_HANDLE hMetaFrom, const uint8_t sfFrom, MASA_METADATA_HANDLE hMetaTo, const uint8_t sfTo ); +#endif // IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED +static void copy_masa_metadata_fx( const MASA_METADATA_HANDLE hMetaFrom, MASA_METADATA_HANDLE hMetaTo ); +#else static void copy_masa_metadata( const MASA_METADATA_HANDLE hMetaFrom, MASA_METADATA_HANDLE hMetaTo ); +#endif +#ifdef IVAS_FLOAT_FIXED +static UWord8 are_masa_subframes_similar_fx( + const MASA_METADATA_HANDLE frame1, /* i : MASA metadata frame 1 */ + const UWord8 sf1_idx, /* i : index of the subframe of frame1 to inspect */ + const MASA_METADATA_HANDLE frame2, /* i : MASA metadata frame 2 */ + const UWord8 sf2_idx /* i : index of the subframe of frame2 to inspect */ +); +#endif static uint8_t are_masa_subframes_similar( const MASA_METADATA_HANDLE frame1, const uint8_t sf1_idx, const MASA_METADATA_HANDLE frame2, const uint8_t sf2_idx ); +#ifdef IVAS_FLOAT_FIXED +static void detect_framing_async_fx( + MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder structure */ +); +#else static void detect_framing_async( MASA_ENCODER_HANDLE hMasa ); +#endif // IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED +static void masa_metadata_direction_alignment_fx( MASA_ENCODER_HANDLE hMasa ); +#else static void masa_metadata_direction_alignment( MASA_ENCODER_HANDLE hMasa ); +#endif // IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------* @@ -1771,9 +1802,100 @@ ivas_error ivas_masa_enc_config( if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) { - masa_metadata_direction_alignment( hMasa ); - - detect_framing_async( hMasa ); /* detect the offset, set 1sf/4sf mode based on this. potentially also shift the metadata using a history buffer */ +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + floatToFixed_arr32( hMasa->data.dir_align_state.previous_ele_dir1, hMasa->data.dir_align_state.previous_ele_dir1_fx, Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arr32( hMasa->data.dir_align_state.previous_ele_dir2, hMasa->data.dir_align_state.previous_ele_dir2_fx, Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arr32( hMasa->data.dir_align_state.previous_azi_dir1, hMasa->data.dir_align_state.previous_azi_dir1_fx, Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arr32( hMasa->data.dir_align_state.previous_azi_dir2, hMasa->data.dir_align_state.previous_azi_dir2_fx, Q22, MASA_FREQUENCY_BANDS ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( int j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + hMasa->masaMetadata.directional_meta[0].azimuth_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].azimuth[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[0].elevation_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].elevation[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[0].energy_ratio_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].energy_ratio[i][j], Q30 ); + hMasa->masaMetadata.directional_meta[0].spread_coherence_fx[i][j] = float_to_fix16( hMasa->masaMetadata.directional_meta[0].spread_coherence[i][j], Q15 ); + hMasa->masaMetadata.directional_meta[1].azimuth_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].azimuth[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[1].elevation_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].elevation[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[1].energy_ratio_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].energy_ratio[i][j], Q30 ); + hMasa->masaMetadata.directional_meta[1].spread_coherence_fx[i][j] = float_to_fix16( hMasa->masaMetadata.directional_meta[1].spread_coherence[i][j], Q15 ); + } + } +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED + masa_metadata_direction_alignment_fx( hMasa ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + fixedToFloat_arrL( hMasa->data.dir_align_state.previous_ele_dir1_fx, hMasa->data.dir_align_state.previous_ele_dir1, Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL( hMasa->data.dir_align_state.previous_ele_dir2_fx, hMasa->data.dir_align_state.previous_ele_dir2, Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL( hMasa->data.dir_align_state.previous_azi_dir1_fx, hMasa->data.dir_align_state.previous_azi_dir1, Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL( hMasa->data.dir_align_state.previous_azi_dir2_fx, hMasa->data.dir_align_state.previous_ele_dir2, Q22, MASA_FREQUENCY_BANDS ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( int j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + hMasa->masaMetadata.directional_meta[0].azimuth[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[0].azimuth_fx[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[0].elevation[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[0].elevation_fx[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[0].energy_ratio[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[0].energy_ratio_fx[i][j], Q30 ); + hMasa->masaMetadata.directional_meta[0].spread_coherence[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[0].spread_coherence_fx[i][j], Q15 ); + hMasa->masaMetadata.directional_meta[1].azimuth[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[1].azimuth_fx[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[1].elevation[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[1].elevation_fx[i][j], Q22 ); + hMasa->masaMetadata.directional_meta[1].energy_ratio[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[1].energy_ratio_fx[i][j], Q30 ); + hMasa->masaMetadata.directional_meta[1].spread_coherence[i][j] = fixedToFloat( hMasa->masaMetadata.directional_meta[1].spread_coherence_fx[i][j], Q15 ); + } + } +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + MASA_METADATA_HANDLE current_meta = &( hMasa->masaMetadata ); + MASA_METADATA_HANDLE previous_meta = &( hMasa->data.sync_state.previous_metadata ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( int j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + for ( int k = 0; k < MASA_MAXIMUM_DIRECTIONS; k++ ) + { + current_meta->directional_meta[k].azimuth_fx[i][j] = float_to_fix( current_meta->directional_meta[k].azimuth[i][j], Q22 ); + current_meta->directional_meta[k].elevation_fx[i][j] = float_to_fix( current_meta->directional_meta[k].elevation[i][j], Q22 ); + current_meta->directional_meta[k].energy_ratio_fx[i][j] = float_to_fix( current_meta->directional_meta[k].energy_ratio[i][j], Q30 ); + current_meta->directional_meta[k].spread_coherence_fx[i][j] = float_to_fix16( current_meta->directional_meta[k].spread_coherence[i][j], Q15 ); + previous_meta->directional_meta[k].azimuth_fx[i][j] = floatToFixed( previous_meta->directional_meta[k].azimuth[i][j], Q22 ); + previous_meta->directional_meta[k].elevation_fx[i][j] = floatToFixed( previous_meta->directional_meta[k].elevation[i][j], Q22 ); + previous_meta->directional_meta[k].energy_ratio_fx[i][j] = floatToFixed( previous_meta->directional_meta[k].energy_ratio[i][j], Q30 ); + previous_meta->directional_meta[k].spread_coherence_fx[i][j] = (Word16) min( 32767, floatToFixed( previous_meta->directional_meta[k].spread_coherence[i][j], Q15 ) ); + } + current_meta->common_meta.surround_coherence_fx[i][j] = float_to_fix16( current_meta->common_meta.surround_coherence[i][j], Q15 ); + current_meta->common_meta.diffuse_to_total_ratio_fx[i][j] = float_to_fix( current_meta->common_meta.diffuse_to_total_ratio[i][j], Q30 ); + current_meta->common_meta.remainder_to_total_ratio_fx[i][j] = float_to_fix( current_meta->common_meta.remainder_to_total_ratio[i][j], Q30 ); + previous_meta->common_meta.surround_coherence_fx[i][j] = (Word16) min( 32767, floatToFixed( previous_meta->common_meta.surround_coherence[i][j], Q15 ) ); + previous_meta->common_meta.diffuse_to_total_ratio_fx[i][j] = floatToFixed( previous_meta->common_meta.diffuse_to_total_ratio[i][j], Q30 ); + previous_meta->common_meta.remainder_to_total_ratio_fx[i][j] = floatToFixed( previous_meta->common_meta.remainder_to_total_ratio[i][j], Q30 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + detect_framing_async_fx( hMasa ); /* detect the offset, set 1sf/4sf mode based on this. potentially also shift the metadata using a history buffer */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( int j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + for ( int k = 0; k < MASA_MAXIMUM_DIRECTIONS; k++ ) + { + current_meta->directional_meta[k].azimuth[i][j] = fixedToFloat( current_meta->directional_meta[k].azimuth_fx[i][j], Q22 ); + current_meta->directional_meta[k].elevation[i][j] = fixedToFloat( current_meta->directional_meta[k].elevation_fx[i][j], Q22 ); + current_meta->directional_meta[k].energy_ratio[i][j] = fixedToFloat( current_meta->directional_meta[k].energy_ratio_fx[i][j], Q30 ); + current_meta->directional_meta[k].spread_coherence[i][j] = fixedToFloat( current_meta->directional_meta[k].spread_coherence_fx[i][j], Q15 ); + previous_meta->directional_meta[k].azimuth[i][j] = fixedToFloat( previous_meta->directional_meta[k].azimuth_fx[i][j], Q22 ); + previous_meta->directional_meta[k].elevation[i][j] = fixedToFloat( previous_meta->directional_meta[k].elevation_fx[i][j], Q22 ); + previous_meta->directional_meta[k].energy_ratio[i][j] = fixedToFloat( previous_meta->directional_meta[k].energy_ratio_fx[i][j], Q30 ); + previous_meta->directional_meta[k].spread_coherence[i][j] = fixedToFloat( previous_meta->directional_meta[k].spread_coherence_fx[i][j], Q15 ); + } + current_meta->common_meta.surround_coherence[i][j] = fixedToFloat( current_meta->common_meta.surround_coherence_fx[i][j], Q15 ); + current_meta->common_meta.diffuse_to_total_ratio[i][j] = fixedToFloat( current_meta->common_meta.diffuse_to_total_ratio_fx[i][j], Q30 ); + current_meta->common_meta.remainder_to_total_ratio[i][j] = fixedToFloat( current_meta->common_meta.remainder_to_total_ratio_fx[i][j], Q30 ); + previous_meta->common_meta.surround_coherence[i][j] = fixedToFloat( previous_meta->common_meta.surround_coherence_fx[i][j], Q15 ); + previous_meta->common_meta.diffuse_to_total_ratio[i][j] = fixedToFloat( previous_meta->common_meta.diffuse_to_total_ratio_fx[i][j], Q30 ); + previous_meta->common_meta.remainder_to_total_ratio[i][j] = fixedToFloat( previous_meta->common_meta.remainder_to_total_ratio_fx[i][j], Q30 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS if ( hMasa->data.sync_state.frame_mode == MASA_FRAME_1SF && hMasa->data.sync_state.prev_offset != 0 ) { @@ -4638,7 +4760,33 @@ static void average_masa_metadata( * * Copy MASA metadata frame subframe contents *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void copy_masa_metadata_subframe_fx( + const MASA_METADATA_HANDLE hMetaFrom, /* i : MASA frame metdata to be copied */ + const UWord8 sfFrom, /* i : subframe index of the copy source */ + MASA_METADATA_HANDLE hMetaTo, /* o : MASA frame metadata copy destination */ + const UWord8 sfTo /* i : subframe index of the copy target */ +) +{ + UWord8 dir; + + /* directional metadata */ + FOR( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) + { + Copy32( hMetaFrom->directional_meta[dir].azimuth_fx[sfFrom], hMetaTo->directional_meta[dir].azimuth_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy32( hMetaFrom->directional_meta[dir].elevation_fx[sfFrom], hMetaTo->directional_meta[dir].elevation_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy32( hMetaFrom->directional_meta[dir].energy_ratio_fx[sfFrom], hMetaTo->directional_meta[dir].energy_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy( hMetaFrom->directional_meta[dir].spread_coherence_fx[sfFrom], hMetaTo->directional_meta[dir].spread_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); + } + /* common metadata */ + Copy32( hMetaFrom->common_meta.diffuse_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.diffuse_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy( hMetaFrom->common_meta.surround_coherence_fx[sfFrom], hMetaTo->common_meta.surround_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy32( hMetaFrom->common_meta.remainder_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.remainder_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); + + return; +} +#else static void copy_masa_metadata_subframe( const MASA_METADATA_HANDLE hMetaFrom, /* i : MASA frame metdata to be copied */ const uint8_t sfFrom, /* i : subframe index of the copy source */ @@ -4664,14 +4812,52 @@ static void copy_masa_metadata_subframe( return; } - +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * copy_masa_metadata() * * Copy MASA metada frame contents *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void copy_masa_metadata_fx( + const MASA_METADATA_HANDLE hMetaFrom, /* i : MASA frame metadata to be copied */ + MASA_METADATA_HANDLE hMetaTo /* o : MASA frame metadata copy destination */ +) +{ + UWord8 sf, byte_idx; + /* descriptive metadata */ + FOR( byte_idx = 0; byte_idx < 8; byte_idx++ ) + { + hMetaTo->descriptive_meta.formatDescriptor[byte_idx] = hMetaFrom->descriptive_meta.formatDescriptor[byte_idx]; + move16(); + } + + hMetaTo->descriptive_meta.numberOfDirections = hMetaFrom->descriptive_meta.numberOfDirections; + hMetaTo->descriptive_meta.numberOfChannels = hMetaFrom->descriptive_meta.numberOfChannels; + hMetaTo->descriptive_meta.sourceFormat = hMetaFrom->descriptive_meta.sourceFormat; + hMetaTo->descriptive_meta.transportDefinition = hMetaFrom->descriptive_meta.transportDefinition; + hMetaTo->descriptive_meta.channelAngle = hMetaFrom->descriptive_meta.channelAngle; + hMetaTo->descriptive_meta.channelDistance = hMetaFrom->descriptive_meta.channelDistance; + hMetaTo->descriptive_meta.channelLayout = hMetaFrom->descriptive_meta.channelLayout; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + /* directional and common metadata */ + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + copy_masa_metadata_subframe_fx( hMetaFrom, sf, hMetaTo, sf ); + } + + return; +} +#else static void copy_masa_metadata( const MASA_METADATA_HANDLE hMetaFrom, /* i : MASA frame metadata to be copied */ MASA_METADATA_HANDLE hMetaTo /* o : MASA frame metadata copy destination */ @@ -4701,7 +4887,7 @@ static void copy_masa_metadata( return; } - +#endif /*-------------------------------------------------------------------* * are_masa_subframes_similar() @@ -4710,6 +4896,115 @@ static void copy_masa_metadata( *-------------------------------------------------------------------*/ /* r: similarity decision */ +#ifdef IVAS_FLOAT_FIXED +static UWord8 are_masa_subframes_similar_fx( + const MASA_METADATA_HANDLE frame1, /* i : MASA metadata frame 1 */ + const UWord8 sf1_idx, /* i : index of the subframe of frame1 to inspect */ + const MASA_METADATA_HANDLE frame2, /* i : MASA metadata frame 2 */ + const UWord8 sf2_idx /* i : index of the subframe of frame2 to inspect */ +) +{ + UWord8 num_dir; + UWord8 dir; + UWord8 band_idx; + UWord8 sf_differ; + + num_dir = frame1->descriptive_meta.numberOfDirections; + dir = 0; + band_idx = 0; + sf_differ = FALSE; + move16(); + move16(); + move16(); + move16(); + + IF( NE_16( num_dir, frame2->descriptive_meta.numberOfDirections ) ) + { + sf_differ = TRUE; + move16(); + } + ELSE + { + /* check per-direction metadata */ + dir = 0; + band_idx = 0; + move16(); + move16(); + + WHILE( EQ_16( sf_differ, FALSE ) && LE_16( dir, num_dir ) ) + { + test(); + band_idx = 0; + move16(); + WHILE( EQ_16( sf_differ, FALSE ) && LT_16( band_idx, MASA_FREQUENCY_BANDS ) ) + { + test(); + Word32 azi_dif_fx; + azi_dif_fx = L_abs( L_sub( frame1->directional_meta[dir].azimuth_fx[sf1_idx][band_idx], frame2->directional_meta[dir].azimuth_fx[sf2_idx][band_idx] ) ); + IF( GT_32( azi_dif_fx, 180 << Q22 ) ) + azi_dif_fx = L_sub( 360 << Q22, azi_dif_fx ); + + IF( GT_32( azi_dif_fx, ONE_IN_Q21 /*0.5 in Q22*/ ) ) + { + sf_differ = TRUE; + move16(); + BREAK; + } + + IF( GT_32( L_abs( L_sub( frame1->directional_meta[dir].elevation_fx[sf1_idx][band_idx], frame2->directional_meta[dir].elevation_fx[sf2_idx][band_idx] ) ), MASA_ANGLE_TOLERANCE_FX ) ) + { + sf_differ = TRUE; + move16(); + BREAK; + } + + IF( GT_32( L_abs( L_sub( frame1->directional_meta[dir].energy_ratio_fx[sf1_idx][band_idx], frame2->directional_meta[dir].energy_ratio_fx[sf2_idx][band_idx] ) ), MASA_RATIO_TOLERANCE_FX ) ) + { + sf_differ = TRUE; + move16(); + BREAK; + } + + IF( GT_32( L_abs( L_sub( frame1->directional_meta[dir].spread_coherence_fx[sf1_idx][band_idx], frame2->directional_meta[dir].spread_coherence_fx[sf2_idx][band_idx] ) ), MASA_COHERENCE_TOLERANCE_FX ) ) + { + sf_differ = TRUE; + move16(); + BREAK; + } + + band_idx = (UWord8) add( band_idx, 1 ); + move16(); + } + dir = (UWord8) add( dir, 1 ); + move16(); + } + + /* check the common metadata */ + WHILE( EQ_16( sf_differ, FALSE ) && LT_16( band_idx, MASA_FREQUENCY_BANDS ) ) + { + test(); + IF( GT_32( L_abs( L_sub( frame1->common_meta.surround_coherence_fx[sf1_idx][band_idx], frame2->common_meta.surround_coherence_fx[sf2_idx][band_idx] ) ), MASA_COHERENCE_TOLERANCE_FX ) ) + { + sf_differ = TRUE; + move16(); + BREAK; + } + + band_idx = (UWord8) add( band_idx, 1 ); + move16(); + } + } + + IF( sf_differ ) + { + return FALSE; + } + ELSE + { + return TRUE; + } +} +#endif static uint8_t are_masa_subframes_similar( const MASA_METADATA_HANDLE frame1, /* i : MASA metadata frame 1 */ const uint8_t sf1_idx, /* i : index of the subframe of frame1 to inspect */ @@ -4798,7 +5093,6 @@ static uint8_t are_masa_subframes_similar( } } - /*-------------------------------------------------------------------* * detect_framing_async() * @@ -4806,7 +5100,152 @@ static uint8_t are_masa_subframes_similar( * Analysis result is stored in hMasa->data.sync_state, and * potentially hMasa->masaMetadata is modified *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void detect_framing_async_fx( + MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder structure */ +) +{ + MASA_METADATA_HANDLE current_meta; + MASA_METADATA_HANDLE previous_meta; + MASA_SYNC_HANDLE sync_state; + MASA_FRAME_MODE frame_mode; + UWord8 n_sim_start, n_sim_stop, sf_idx; + UWord8 found_offset; + + current_meta = &( hMasa->masaMetadata ); /* metadata from current frame */ + sync_state = &( hMasa->data.sync_state ); /* synchronization structure */ + previous_meta = &( sync_state->previous_metadata ); + + /* check current frame, how many are similar from the start and from the end */ + n_sim_start = 1; + move16(); + FOR( sf_idx = n_sim_start; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + IF( EQ_16( are_masa_subframes_similar_fx( current_meta, 0, current_meta, sf_idx ), TRUE ) ) + { + n_sim_start = (UWord8) add( sf_idx, 1 ); + move16(); + } + ELSE + { + BREAK; + } + } + + /* number of similar sub-frames starting from the end of the frame */ + IF( EQ_16( n_sim_start, MAX_PARAM_SPATIAL_SUBFRAMES ) ) /* shortcut */ + { + n_sim_stop = n_sim_start; + move16(); + } + ELSE + { + n_sim_stop = 1; + move16(); + FOR( sf_idx = 2; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + /* we need to check only the two middle sub-frames, as all being the same would have taken the shortcut above */ + IF( EQ_16( are_masa_subframes_similar_fx( current_meta, MAX_PARAM_SPATIAL_SUBFRAMES - 1, current_meta, (UWord8) sub( MAX_PARAM_SPATIAL_SUBFRAMES, sf_idx ) ), TRUE ) ) + { + n_sim_stop = sf_idx; + move16(); + } + ELSE + { + BREAK; + } + } + } + frame_mode = MASA_FRAME_4SF; /* default mode: 4sf */ + move16(); + IF( GT_16( sync_state->prev_offset, MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) ) + { + /* earlier offset was large => reset the offset */ + found_offset = 0; + } + ELSE + { + /* keep previous offset unless something else is found. alternatively, we could reset always */ + found_offset = sync_state->prev_offset; + } + move16(); + + test(); + test(); + IF( EQ_16( n_sim_start, MAX_PARAM_SPATIAL_SUBFRAMES ) && EQ_16( n_sim_stop, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + { + /* full frame consists of similar sub-frames */ + frame_mode = MASA_FRAME_1SF; + move16(); + test(); + IF( ( sync_state->prev_sim_stop != 0 ) && EQ_16( are_masa_subframes_similar_fx( current_meta, 0, previous_meta, MAX_PARAM_SPATIAL_SUBFRAMES - 1 ), TRUE ) ) + { + /* > 4 sub-frames of similar data */ + IF( LT_16( sync_state->prev_sim_stop, 3 ) ) + { + /* can nicely align the framing with the earlier data and a small offset */ + found_offset = sync_state->prev_sim_stop; + } + ELSE + { + /* too many similar sub-frames to determine the offset accurately => keep earlier value */ + found_offset = sync_state->prev_offset; + } + move16(); + } + ELSE + { + /* earlier window was different => reset the offset */ + found_offset = 0; + move16(); + } + } + ELSE IF( EQ_16( n_sim_stop, 3 ) ) + { + /* first sub-frame different that the rest 3 + => make a risky guess that the future sf would be the same too and we're in an offset case */ + frame_mode = MASA_FRAME_1SF; + found_offset = 3; + move16(); + move16(); + } + ELSE IF( ( sync_state->prev_sim_stop > 0 ) && EQ_16( are_masa_subframes_similar_fx( current_meta, 0, previous_meta, MAX_PARAM_SPATIAL_SUBFRAMES - 1 ), TRUE ) ) + { + /* seeing data similar to past */ + test(); + IF( GT_16( n_sim_start, 1 ) && ( GE_16( add( n_sim_start, sync_state->prev_sim_stop ), MAX_PARAM_SPATIAL_SUBFRAMES ) ) ) + { + /* with the past, would have at least one long frame similar subframes */ + frame_mode = MASA_FRAME_1SF; + move16(); + + IF( sync_state->prev_offset == 0 ) + { + found_offset = (UWord8) s_min( 2, sync_state->prev_sim_stop ); + } + ELSE + { + found_offset = sync_state->prev_offset; + move16(); + } + } + } + + /* keep the original contents of the frame, but then perform interpolation later */ + /* just copy current frame to storage */ + copy_masa_metadata_fx( current_meta, previous_meta ); + + sync_state->prev_sim_stop = n_sim_stop; + sync_state->prev_offset = found_offset; + sync_state->frame_mode = frame_mode; + move16(); + move16(); + move16(); + + return; +} +#else static void detect_framing_async( MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder structure */ ) @@ -4930,7 +5369,7 @@ static void detect_framing_async( return; } - +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * masa_metadata_direction_alignment() @@ -4938,7 +5377,258 @@ static void detect_framing_async( * In 2dir MASA metadata, determine the ordering of the directional * fields such that the azi/ele change across time is minimized. *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void masa_metadata_direction_alignment_fx( + MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder handle */ +) +{ + UWord8 band, n_dirs; + MASA_DIR_ALIGN_HANDLE hAlignState; + MASA_METADATA_HANDLE hMeta; + hAlignState = &( hMasa->data.dir_align_state ); + hMeta = &( hMasa->masaMetadata ); + + n_dirs = (UWord8) add( hMeta->descriptive_meta.numberOfDirections, 1 ); /* 1-based */ + move16(); + FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + UWord8 sf; + Word16 diff_swap_fx; + Word16 diff_no_swap_fx; + + /* trade 2*(cos+sin) against storing the values between frames */ + Word16 prev_ele_dir1_sin_fx, prev_ele_dir2_sin_fx; + Word16 prev_ele_dir1_cos_fx, prev_ele_dir2_cos_fx; + + prev_ele_dir1_sin_fx = getSineWord16R2( extract_l( Mpy_32_32( hAlignState->previous_ele_dir1_fx[band], 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + prev_ele_dir2_sin_fx = getSineWord16R2( extract_l( Mpy_32_32( hAlignState->previous_ele_dir2_fx[band], 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + + prev_ele_dir1_cos_fx = getCosWord16R2( extract_l( Mpy_32_32( hAlignState->previous_ele_dir1_fx[band], 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + prev_ele_dir2_cos_fx = getCosWord16R2( extract_l( Mpy_32_32( hAlignState->previous_ele_dir2_fx[band], 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + Word32 azi_rad1_fx, ele_rad1_fx; + Word32 azi_rad2_fx, ele_rad2_fx; + Word16 cos_ele1_fx, cos_ele2_fx; + Word16 sin_ele1_fx, sin_ele2_fx; + Word16 temp1; + Word32 temp2; + Word16 temp1_e; + + + azi_rad1_fx = Mpy_32_16_1( hMeta->directional_meta[0].azimuth_fx[sf][band], 572 /*PI_OVER_180 q15*/ ); /*q22*/ + ele_rad1_fx = Mpy_32_16_1( hMeta->directional_meta[0].elevation_fx[sf][band], 572 /*PI_OVER_180 q15*/ ); /*q22*/ + + IF( GT_16( n_dirs, 1 ) ) + { + azi_rad2_fx = Mpy_32_16_1( hMeta->directional_meta[1].azimuth_fx[sf][band], 572 /*PI_OVER_180 q15*/ ); /*q22*/ + ele_rad2_fx = Mpy_32_16_1( hMeta->directional_meta[1].elevation_fx[sf][band], 572 /*PI_OVER_180 q15*/ ); /*q22*/ + + test(); + test(); + test(); + test(); + test(); + test(); + /* quick checks to detect constant data and earlier flip */ + IF( LT_32( L_abs( L_sub( azi_rad1_fx, hAlignState->previous_azi_dir1_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( azi_rad2_fx, hAlignState->previous_azi_dir2_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( ele_rad1_fx, hAlignState->previous_ele_dir1_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( ele_rad2_fx, hAlignState->previous_ele_dir2_fx[band] ) ), EPSILON_FX ) ) + { + diff_swap_fx = ONE_IN_Q13; /*1 q13*/ + diff_no_swap_fx = 0; + /* cached values that will be used for the short-cuts and over-written by the real computations, if done */ + sin_ele1_fx = prev_ele_dir1_sin_fx; /*q15*/ + sin_ele2_fx = prev_ele_dir2_sin_fx; /*q15*/ + cos_ele1_fx = prev_ele_dir1_cos_fx; /*q15*/ + cos_ele2_fx = prev_ele_dir2_cos_fx; /*q15*/ + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE IF( LT_32( L_abs( L_sub( azi_rad1_fx, hAlignState->previous_azi_dir2_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( azi_rad2_fx, hAlignState->previous_azi_dir1_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( ele_rad1_fx, hAlignState->previous_ele_dir2_fx[band] ) ), EPSILON_FX ) && + LT_32( L_abs( L_sub( ele_rad2_fx, hAlignState->previous_ele_dir1_fx[band] ) ), EPSILON_FX ) ) + { + diff_swap_fx = 0; + diff_no_swap_fx = ONE_IN_Q13; /*1.0 q13*/ + /* cached values that will be used for the short-cuts and over-written by the real computations, if done */ + sin_ele1_fx = prev_ele_dir2_sin_fx; /*q15*/ + sin_ele2_fx = prev_ele_dir1_sin_fx; /*q15*/ + cos_ele1_fx = prev_ele_dir2_cos_fx; /*q15*/ + cos_ele2_fx = prev_ele_dir1_cos_fx; /*q15*/ + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE + { + /* angular distance of the two vectors */ + /* pre-compute values for re-use */ + sin_ele1_fx = getSineWord16R2( extract_l( Mpy_32_32( ele_rad1_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + sin_ele2_fx = getSineWord16R2( extract_l( Mpy_32_32( ele_rad2_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + + cos_ele1_fx = getCosWord16R2( extract_l( Mpy_32_32( ele_rad1_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + cos_ele2_fx = getCosWord16R2( extract_l( Mpy_32_32( ele_rad2_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + + temp1 = getCosWord16R2( extract_l( Mpy_32_32( L_sub( azi_rad1_fx, hAlignState->previous_azi_dir1_fx[band] ), 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + temp1 = mult( mult( temp1, cos_ele1_fx ) /*q31*/, prev_ele_dir1_cos_fx /*q15*/ ); /*q15*/ + temp1 = add_sat( mult( sin_ele1_fx, prev_ele_dir1_sin_fx ), temp1 ); /*q15*/ + temp1_e = 1; /*stores expoenent for square root operation*/ + move16(); + temp2 = Sqrt32( L_sub( ONE_IN_Q30, L_mult0( temp1, temp1 ) ), &temp1_e ); /*31-temp1_e*/ + temp1 = BASOP_util_atan2( temp2, abs_s( temp1 ), sub( temp1_e, 16 ) ); /*q13*/ + diff_no_swap_fx = temp1; /*q13*/ + + temp1 = getCosWord16R2( extract_l( Mpy_32_32( L_sub( azi_rad2_fx, hAlignState->previous_azi_dir2_fx[band] ), 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + temp1 = mult( mult( temp1, cos_ele2_fx ) /*q31*/, prev_ele_dir2_cos_fx /*q15*/ ); /*q15*/ + temp1 = add_sat( mult( sin_ele2_fx, prev_ele_dir2_sin_fx ), temp1 ); /*q15*/ + temp1_e = 1; /*stores expoenent for square root operation*/ + move16(); + temp2 = Sqrt32( L_sub( ONE_IN_Q30, L_mult0( temp1, temp1 ) ), &temp1_e ); /*31-temp1_e*/ + temp1 = BASOP_util_atan2( temp2, abs_s( temp1 ), sub( temp1_e, 16 ) ); /*q13*/ + diff_no_swap_fx = add( diff_no_swap_fx, temp1 ); /*q13*/ + + temp1 = getCosWord16R2( extract_l( Mpy_32_32( L_sub( azi_rad1_fx, hAlignState->previous_azi_dir2_fx[band] ), 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + temp1 = mult( mult( temp1, cos_ele1_fx ) /*q31*/, prev_ele_dir2_cos_fx /*q15*/ ); /*q15*/ + temp1 = add_sat( mult( sin_ele1_fx, prev_ele_dir2_sin_fx ), temp1 ); /*q15*/ + temp1_e = 1; /*stores expoenent for square root operation*/ + move16(); + temp2 = Sqrt32( L_sub( ONE_IN_Q30, L_mult0( temp1, temp1 ) ), &temp1_e ); /*31-temp1_e*/ + temp1 = BASOP_util_atan2( temp2, abs_s( temp1 ), sub( temp1_e, 16 ) ); /*q13*/ + diff_swap_fx = temp1; /*q13*/ + + temp1 = getCosWord16R2( extract_l( Mpy_32_32( L_sub( azi_rad2_fx, hAlignState->previous_azi_dir1_fx[band] ), 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + temp1 = mult( mult( temp1, cos_ele2_fx ) /*q31*/, prev_ele_dir1_cos_fx /*q15*/ ); /*q15*/ + temp1 = add_sat( mult( sin_ele2_fx, prev_ele_dir1_sin_fx ), temp1 ); /*q15*/ + temp1_e = 1; /*stores expoenent for square root operation*/ + move16(); + temp2 = Sqrt32( L_sub( ONE_IN_Q30, L_mult0( temp1, temp1 ) ), &temp1_e ); /*31-temp1_e*/ + temp1 = BASOP_util_atan2( temp2, abs_s( temp1 ), sub( temp1_e, 16 ) ); /*q13*/ + diff_swap_fx = add( diff_swap_fx, temp1 ); /*q13*/ + } + } + ELSE + { + /* 1dir */ + sin_ele1_fx = getSineWord16R2( extract_l( Mpy_32_32( ele_rad1_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + cos_ele1_fx = getCosWord16R2( extract_l( Mpy_32_32( ele_rad1_fx, 2670177 /*2^24/(2*pi)*/ ) ) ); /*q15*/ + azi_rad2_fx = 0; + ele_rad2_fx = 0; + move32(); + move32(); + + sin_ele2_fx = 0; /* sin(0) */ + cos_ele2_fx = MAX_16; /* cos(0) in Q15*/ + move16(); + move16(); + + diff_swap_fx = ONE_IN_Q13; /*1.0 in Q13*/ + diff_no_swap_fx = 0; + move16(); + move16(); + } + + test(); + IF( GT_16( n_dirs, 1 ) && GT_16( diff_no_swap_fx, diff_swap_fx ) ) + { + /* swap the metadata of the two directions in this TF-tile */ + Word32 tmp_val; + Word16 tmp_val_16; + UWord16 tmp_int_val; + tmp_val = hMeta->directional_meta[0].azimuth_fx[sf][band]; /*q22*/ + hMeta->directional_meta[0].azimuth_fx[sf][band] = hMeta->directional_meta[1].azimuth_fx[sf][band]; /*q22*/ + hMeta->directional_meta[1].azimuth_fx[sf][band] = tmp_val; /*q22*/ + move32(); + move32(); + move32(); + + tmp_val = hMeta->directional_meta[0].elevation_fx[sf][band]; /*q22*/ + hMeta->directional_meta[0].elevation_fx[sf][band] = hMeta->directional_meta[1].elevation_fx[sf][band]; /*q22*/ + hMeta->directional_meta[1].elevation_fx[sf][band] = tmp_val; /*q22*/ + move32(); + move32(); + move32(); + + tmp_int_val = hMeta->directional_meta[0].spherical_index[sf][band]; /*q0*/ + hMeta->directional_meta[0].spherical_index[sf][band] = hMeta->directional_meta[1].spherical_index[sf][band]; /*q0*/ + hMeta->directional_meta[1].spherical_index[sf][band] = tmp_int_val; /*q0*/ + move32(); + move32(); + move32(); + + tmp_val = hMeta->directional_meta[0].energy_ratio_fx[sf][band]; /*q30*/ + hMeta->directional_meta[0].energy_ratio_fx[sf][band] = hMeta->directional_meta[1].energy_ratio_fx[sf][band]; /*q30*/ + hMeta->directional_meta[1].energy_ratio_fx[sf][band] = tmp_val; /*q30*/ + move32(); + move32(); + move32(); + + tmp_val_16 = hMeta->directional_meta[0].spread_coherence_fx[sf][band]; /*q15*/ + hMeta->directional_meta[0].spread_coherence_fx[sf][band] = hMeta->directional_meta[1].spread_coherence_fx[sf][band]; /*q15*/ + hMeta->directional_meta[1].spread_coherence_fx[sf][band] = tmp_val_16; /*q15*/ + move16(); + move16(); + move16(); + + hAlignState->previous_azi_dir1_fx[band] = azi_rad2_fx; /*q22*/ + hAlignState->previous_ele_dir1_fx[band] = ele_rad2_fx; /*q22*/ + move32(); + move32(); + + hAlignState->previous_azi_dir2_fx[band] = azi_rad1_fx; /*q22*/ + hAlignState->previous_ele_dir2_fx[band] = ele_rad1_fx; /*q22*/ + move32(); + move32(); + + prev_ele_dir1_cos_fx = cos_ele2_fx; /*q15*/ + prev_ele_dir1_sin_fx = sin_ele2_fx; /*q15*/ + move16(); + move16(); + + prev_ele_dir2_cos_fx = cos_ele1_fx; /*q15*/ + prev_ele_dir2_sin_fx = sin_ele1_fx; /*q15*/ + move16(); + move16(); + } + ELSE + { + hAlignState->previous_azi_dir1_fx[band] = azi_rad1_fx; /*q22*/ + hAlignState->previous_ele_dir1_fx[band] = ele_rad1_fx; /*q22*/ + move32(); + move32(); + + hAlignState->previous_azi_dir2_fx[band] = azi_rad2_fx; /*q22*/ + hAlignState->previous_ele_dir2_fx[band] = ele_rad2_fx; /*q22*/ + move32(); + move32(); + + prev_ele_dir1_cos_fx = cos_ele1_fx; /*q15*/ + prev_ele_dir1_sin_fx = sin_ele1_fx; /*q15*/ + move16(); + move16(); + + prev_ele_dir2_cos_fx = cos_ele2_fx; /*q15*/ + prev_ele_dir2_sin_fx = sin_ele2_fx; /*q15*/ + move16(); + move16(); + } + } /* sf */ + } /* band */ + + return; +} +#else static void masa_metadata_direction_alignment( MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder handle */ ) @@ -5095,7 +5785,7 @@ static void masa_metadata_direction_alignment( return; } - +#endif /*-------------------------------------------------------------------* * ivas_merge_masa_metadata() diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 119ae117b314b7fd28634060dc27fc4113557467..a6316ea3dbea53badcb67496eebc8ff63961a099 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -106,6 +106,180 @@ static void ivas_param_mc_parameter_quantizer( const float *x, const int16_t L, * Initialize Parametric MC encoder handle *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_param_mc_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +) +{ + Word16 i; +#ifndef FIX_901_PARAMMC_DEAD_CODE + int16_t k, l; +#endif + IVAS_FB_CFG *fb_cfg; + PARAM_MC_ENC_HANDLE hParamMC; + UWord16 config_index; + MC_LS_SETUP mc_input_setup; + Word16 max_bwidth, nchan_inp; + Word16 tmp1, tmp2; + Word32 input_Fs, ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move16(); + + /* Sanity Checks */ + IF( ( hParamMC = (PARAM_MC_ENC_HANDLE) malloc( sizeof( PARAM_MC_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Paramtric MC\n" ) ); + } + + mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup; + move32(); + max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + move16(); + input_Fs = st_ivas->hEncoderConfig->input_Fs; + move32(); + nchan_inp = st_ivas->hEncoderConfig->nchan_inp; + move16(); + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + move32(); + + /* Preparing Config */ + hParamMC->lfe_index = LFE_CHANNEL; + move16(); + st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels( ivas_total_brate, mc_input_setup ); + move16(); + + /* get configuration index */ + config_index = ivas_param_mc_get_configuration_index( mc_input_setup, ivas_total_brate ); + + /* set core coder dependent on the number of transport channels */ + SWITCH( st_ivas->nchan_transport ) + { + case 4: + case 3: + st_ivas->nCPE = 2; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + case 2: + st_ivas->nCPE = 1; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + } + + /* get dmx factors */ + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; + + /* set FB config. */ + IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, nchan_inp, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* Allocate and initialize FB mixer handle */ + IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hParamMC->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* open/init parameter coding */ +#ifndef FIX_901_PARAMMC_DEAD_CODE + ivas_param_mc_metadata_open( mc_input_setup, hParamMC->lfe_index, ivas_total_brate, &hParamMC->hMetadataPMC ); +#else + ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC ); +#endif +#ifndef FIX_901_PARAMMC_DEAD_CODE + /* init icc index states */ + for ( i = 0; i < PARAM_MC_PARAMETER_FRAMES; i++ ) + { + set_s( hParamMC->icc_map_index[i], -1, PARAM_MC_SZ_ICC_MAP ); + + for ( l = 0; l < hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe; l++ ) + { + for ( k = 0; k < hParamMC->hMetadataPMC.icc_map_size_full; k++ ) + { + if ( hParamMC->hMetadataPMC.icc_mapping[i][l][0] == hParamMC->hMetadataPMC.icc_map_full[0][k] && hParamMC->hMetadataPMC.icc_mapping[i][l][1] == hParamMC->hMetadataPMC.icc_map_full[1][k] ) + { + hParamMC->icc_map_index[i][l] = k; + } + } + } + } +#endif + + /* Band Grouping */ + IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) ) + { + Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) ) + { + Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) ) + { + Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); + } + ELSE + { + assert( 0 && "nbands must be 20, 14, or 10!" ); + } + + /* set max parameter band for abs cov */ + i = 0; + move16(); + WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC ) + { + hParamMC->max_param_band_abs_cov = i; + move16(); + i = add( i, 1 ); + } + + /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */ + FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ ) + { + hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC ); + move16(); + } + + /* set correct coded band width */ + hParamMC->hMetadataPMC.coded_bwidth = max_bwidth; + move16(); + hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth; + move16(); + ivas_param_mc_set_coded_bands( &hParamMC->hMetadataPMC ); + + /* initialize offset for transient detection */ + tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); + move16(); + tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS ); + move16(); + tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 ); + hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 ); + move16(); + + /* Init total/dmx ener factors */ + set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); + + /* init previous ILDs */ + FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) + { + set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); + } + + st_ivas->hParamMC = hParamMC; + + return error; +} +#else ivas_error ivas_param_mc_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) @@ -260,6 +434,7 @@ ivas_error ivas_param_mc_enc_open( return error; } +#endif /*------------------------------------------------------------------------- @@ -268,6 +443,164 @@ ivas_error ivas_param_mc_enc_open( * Reconfigure Parametric MC encoder *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_param_mc_enc_reconfig_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +) +{ + Word16 i; +#ifndef FIX_901_PARAMMC_DEAD_CODE + int16_t k, l; +#endif + PARAM_MC_ENC_HANDLE hParamMC; + UWord16 config_index; + MC_LS_SETUP mc_input_setup; + Word16 max_bwidth; + Word16 tmp1, tmp2; + Word32 input_Fs, ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move16(); + + mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup; + move32(); + max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + move16(); + input_Fs = st_ivas->hEncoderConfig->input_Fs; + move32(); + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + move32(); + hParamMC = st_ivas->hParamMC; + + /* Preparing Config */ + st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels( ivas_total_brate, mc_input_setup ); + move16(); + + /* get configuration index */ + config_index = ivas_param_mc_get_configuration_index( mc_input_setup, ivas_total_brate ); + + /* set core coder dependent on the number of transport channels */ + SWITCH( st_ivas->nchan_transport ) + { + case 4: + case 3: + st_ivas->nCPE = 2; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + case 2: + st_ivas->nCPE = 1; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + } + + /* get dmx factors */ + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; + +#ifndef FIX_901_PARAMMC_DEAD_CODE + /* deallocate the full icc map, gets newly allocated in the metadata open function */ + for ( i = 0; i < 2; i++ ) + { + if ( hParamMC->hMetadataPMC.icc_map_full[i] != NULL ) + { + free( hParamMC->hMetadataPMC.icc_map_full[i] ); + hParamMC->hMetadataPMC.icc_map_full[i] = NULL; + } + } + +#endif + /* open/init parameter coding */ +#ifndef FIX_901_PARAMMC_DEAD_CODE + ivas_param_mc_metadata_open( mc_input_setup, hParamMC->lfe_index, ivas_total_brate, &hParamMC->hMetadataPMC ); +#else + ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC ); +#endif + +#ifndef FIX_901_PARAMMC_DEAD_CODE + /* init icc index states */ + for ( i = 0; i < PARAM_MC_PARAMETER_FRAMES; i++ ) + { + set_s( hParamMC->icc_map_index[i], -1, PARAM_MC_SZ_ICC_MAP ); + + for ( l = 0; l < hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe; l++ ) + { + for ( k = 0; k < hParamMC->hMetadataPMC.icc_map_size_full; k++ ) + { + if ( hParamMC->hMetadataPMC.icc_mapping[i][l][0] == hParamMC->hMetadataPMC.icc_map_full[0][k] && hParamMC->hMetadataPMC.icc_mapping[i][l][1] == hParamMC->hMetadataPMC.icc_map_full[1][k] ) + { + hParamMC->icc_map_index[i][l] = k; + } + } + } + } + +#endif + /* Band Grouping */ + IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) ) + { + Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) ) + { + Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) ) + { + Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); + } + ELSE + { + assert( 0 && "nbands must be 20, 14, or 10!" ); + } + + /* set max parameter band for abs cov */ + i = 0; + move16(); + WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC ) + { + hParamMC->max_param_band_abs_cov = i; + move16(); + i = add( i, 1 ); + } + + /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */ + FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ ) + { + hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC ); + move16(); + } + + /* set correct coded band width */ + hParamMC->hMetadataPMC.coded_bwidth = max_bwidth; + move16(); + hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth; + move16(); + ivas_param_mc_set_coded_bands( &hParamMC->hMetadataPMC ); + + /* initialize offset for transient detection */ + tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); + move16(); + tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS ); + move16(); + tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 ); + hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 ); + move16(); + + /* Init total/dmx ener factors */ + set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); + + + return error; +} +#else ivas_error ivas_param_mc_enc_reconfig( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) @@ -405,6 +738,7 @@ ivas_error ivas_param_mc_enc_reconfig( return error; } +#endif /*------------------------------------------------------------------------- @@ -413,6 +747,28 @@ ivas_error ivas_param_mc_enc_reconfig( * Close Parametric MC encoder handle *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_mc_enc_close_fx( + PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */ + const Word32 sampling_rate ) +{ + test(); + IF( hParamMC == NULL || *hParamMC == NULL ) + { + return; + } + +#ifndef FIX_901_PARAMMC_DEAD_CODE + ivas_param_mc_metadata_close( &( *hParamMC )->hMetadataPMC ); +#endif + ivas_FB_mixer_close_fx( &( *hParamMC )->hFbMixer, sampling_rate, 0 ); + + free( ( *hParamMC ) ); + ( *hParamMC ) = NULL; + + return; +} +#else void ivas_param_mc_enc_close( PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */ const int32_t sampling_rate ) @@ -432,6 +788,7 @@ void ivas_param_mc_enc_close( return; } +#endif /*------------------------------------------------------------------------- diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index c4576e04585d65593b287bbf049f4b346de9a268..4c3ce7706b545a6aee1bfa132bccfefd49997f57 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -1754,7 +1754,11 @@ static ivas_error ivas_mc_enc_reconfig( } /*De-allocate handles for other MC modes*/ +#ifdef IVAS_FLOAT_FIXED + ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_param_mc_enc_close( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#endif ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); @@ -1800,7 +1804,11 @@ static ivas_error ivas_mc_enc_reconfig( } /*De-allocate handles for other MC modes*/ +#ifdef IVAS_FLOAT_FIXED + ivas_param_mc_enc_close_fx( &st_ivas->hParamMC, st_ivas->hEncoderConfig->input_Fs ); +#else ivas_param_mc_enc_close( &st_ivas->hParamMC, st_ivas->hEncoderConfig->input_Fs ); +#endif /* De-allocate McMasa-related handles */ #ifdef IVAS_FLOAT_FIXED @@ -1816,14 +1824,22 @@ static ivas_error ivas_mc_enc_reconfig( { if ( last_mc_mode != MC_MODE_PARAMMC ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_param_mc_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } } else { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_param_mc_enc_reconfig_fx( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_param_mc_enc_reconfig( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1904,7 +1920,11 @@ static ivas_error ivas_mc_enc_reconfig( } } +#ifdef IVAS_FLOAT_FIXED + ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_param_mc_enc_close( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); +#endif ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index e148508b89374e0dd646a0c2abfc0732023c21be..bbf7639f25c3c4ff8d63f21d73180189d7d6f6bf 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -2150,7 +2150,13 @@ void ivas_mdct_core_whitening_enc( #else core_signal_analysis_high_bitrate( new_samples[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, mdst_spectrum[ch], tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0 ); #endif - +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + int size = 960; + Word16 *spect_fx[2]; + // Allocate memory for both spect_fx[0] and spect_fx[1] + spect_fx[0] = (Word16 *) malloc( size * sizeof( Word16 ) ); + spect_fx[1] = (Word16 *) malloc( size * sizeof( Word16 ) ); +#endif /* BWD in MDCT domain */ if ( st->hTcxCfg->tcx_last_overlap_mode != TRANSITION_OVERLAP ) { @@ -2158,15 +2164,26 @@ void ivas_mdct_core_whitening_enc( for ( n = 0; n < nSubframes; n++ ) { +#ifndef IVAS_FLOAT_FIXED bw_detect( st, NULL, st->hTcxEnc->spectrum[n], NULL, MC_FORMAT /*just cannot be ISM_FORMAT*/, mct_on ); - +#else +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 l_frame = (int16_t) ( st->input_Fs / FRAMES_PER_SEC ); + q_spectrum = Q_factor_arr( st->hTcxEnc->spectrum[n], l_frame ); + floatToFixed_arr( st->hTcxEnc->spectrum[n], spect_fx[n], q_spectrum, l_frame ); +#endif + bw_detect_fx( st, NULL, spect_fx[n], NULL, NULL, MC_FORMAT /*just cannot be ISM_FORMAT*/, mct_on ); +#endif if ( nSubframes == NB_DIV && n == 0 ) { st->last_input_bwidth = st->input_bwidth; } } } - +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + free( spect_fx[0] ); + free( spect_fx[1] ); +#endif if ( st->last_core == ACELP_CORE ) /* reset past kernel info */ { st->hTcxEnc->kernel_switch_corr_past_flt = 0.f; diff --git a/lib_enc/ivas_pca_enc.c b/lib_enc/ivas_pca_enc.c index ab6e2011855babe879b99e3bb18dfad8f341d6a7..726df7c99b62d7377a9f42e7f45d804fa023681c 100644 --- a/lib_enc/ivas_pca_enc.c +++ b/lib_enc/ivas_pca_enc.c @@ -39,6 +39,9 @@ #include #include "wmc_auto.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" + /*-----------------------------------------------------------------------* * Local constants @@ -47,11 +50,15 @@ #define IVAS_PCA_SM_FAC 0.0234375f #define IVAS_PCA_N_ITER_QR 10 - +#ifdef IVAS_FLOAT_FIXED +#define IVAS_PCA_SM_FAC_FX 50331648 // Q31 +#define ONE_MINUS_IVAS_PCA_SM_FAC_FX 2097152000 // MAX_32 - IVAS_PCA_SM_FAC_FX -> Q31 +#endif /*-----------------------------------------------------------------------* * Local function definitions *-----------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void ivas_bitstream_write_int32( BSTR_ENC_HANDLE hMetaData, const int32_t val, @@ -65,8 +72,24 @@ static void ivas_bitstream_write_int32( return; } +#else +static void ivas_bitstream_write_int32( + BSTR_ENC_HANDLE hMetaData, + const Word32 val, + const Word16 bits ) +{ + /* MSBs */ + push_next_indice( hMetaData, (UWord16) L_shr( val, 16 ), sub( bits, 16 ) ); + + /* LSBs */ + push_next_indice( hMetaData, (UWord16) L_and( val, 0x0000FFFF ), 16 ); + + return; +} +#endif +#ifndef IVAS_FLOAT_FIXED static void pca_enc_reset( PCA_ENC_STATE *hPCA ) { @@ -89,7 +112,47 @@ static void pca_enc_reset( return; } +#else +static void pca_enc_reset( + PCA_ENC_STATE *hPCA ) +{ + Word16 i; + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* reset states for interpolation and multiplexing */ + eye_matrix( hPCA->prev_eigVec, FOA_CHANNELS, 1.0f ); + set_zero( hPCA->prev_ql, IVAS_PCA_INTERP ); + hPCA->prev_ql[0] = 1.0f; + set_zero( hPCA->prev_qr, IVAS_PCA_INTERP ); + hPCA->prev_qr[0] = 1.0f; + FOR( i = 0; i < FOA_CHANNELS; i++ ) + { + hPCA->prev_D[i] = 0.25f; + } + eye_matrix( hPCA->mem_eigVec_interp, FOA_CHANNELS, 1.0f ); + set_zero( hPCA->old_r_sm, FOA_CHANNELS * FOA_CHANNELS ); +#endif + + eye_matrix_fx( hPCA->prev_eigVec_fx, FOA_CHANNELS, MAX_WORD16 ); + set16_fx( hPCA->prev_ql_fx, 0, IVAS_PCA_INTERP ); + hPCA->prev_ql_fx[0] = MAX_WORD16; + move16(); + set16_fx( hPCA->prev_qr_fx, 0, IVAS_PCA_INTERP ); + hPCA->prev_qr_fx[0] = MAX_WORD16; + move16(); + FOR( i = 0; i < FOA_CHANNELS; i++ ) + { + hPCA->prev_D_fx[i] = shr( MAX_WORD16, 2 ); // 0.25 in Q15 + move16(); + } + eye_matrix_fx( hPCA->mem_eigVec_interp_fx, FOA_CHANNELS, MAX_WORD16 ); + set32_fx( hPCA->old_r_sm_fx, 0, FOA_CHANNELS * FOA_CHANNELS ); + hPCA->old_r_sm_q = 31; + move16(); + return; +} +#endif static void pca_transform_sub( float *eigVec, @@ -121,6 +184,44 @@ static void pca_transform_sub( return; } +#ifdef IVAS_FLOAT_FIXED +static void pca_transform_sub_fx( + Word16 *eigVec, + Word32 *transformed_data[8], /* i : input/transformed audio channels Q11 */ + const Word16 start, + const Word16 len, + const Word16 n_channels ) +{ + Word16 i, j, k; + Word32 temp; + Word32 buffer_data[FOA_CHANNELS]; + Word32 temp2; + FOR( j = 0; j < len; j++ ) + { + FOR( k = 0; k < n_channels; k++ ) + { + buffer_data[k] = transformed_data[k][j + start]; + move32(); + } + FOR( k = 0; k < n_channels; k++ ) + { + temp = 0; + move32(); + FOR( i = 0; i < n_channels; i++ ) + { + temp2 = Mpy_32_16_1( buffer_data[i], eigVec[k * IVAS_PCA_INTERP + i] ); + temp = L_add( temp, temp2 ); + } + transformed_data[k][add( j, start )] = temp; + move32(); + } + } + + return; +} + +#endif + static void pca_enc_transform( PCA_ENC_STATE *hPCA, float *ql, @@ -151,6 +252,36 @@ static void pca_enc_transform( } +#ifdef IVAS_FLOAT_FIXED +static void pca_enc_transform_fx( + PCA_ENC_STATE *hPCA, + Word16 *ql_fx, // Q15 + Word16 *qr_fx, // Q15 + Word32 *transformed_data_fx[8], // Q11 + const Word16 input_frame, + const Word16 n_channels ) +{ + Word16 time_slot; + Word16 slot_len; + Word16 eigVec_interp_fx[FOA_CHANNELS * FOA_CHANNELS]; /* eigenvectors in current frame */ + Word16 ql_interp_fx[IVAS_PCA_LEN_INTERP_Q], qr_interp_fx[IVAS_PCA_LEN_INTERP_Q]; + + quat_shortestpath_fx( hPCA->prev_ql_fx, ql_fx, hPCA->prev_qr_fx, qr_fx ); + pca_interp_preproc_fx( hPCA->prev_ql_fx, hPCA->prev_qr_fx, ql_fx, qr_fx, IVAS_PCA_N_SLOTS, ql_interp_fx, qr_interp_fx ); + + slot_len = idiv1616( input_frame, IVAS_PCA_N_SLOTS ); + + FOR( time_slot = 0; time_slot < IVAS_PCA_N_SLOTS; time_slot++ ) + { + /* convert from double quaternion to 4D matrix */ + dquat2mat_fx( &ql_interp_fx[IVAS_PCA_INTERP * time_slot], &qr_interp_fx[IVAS_PCA_INTERP * time_slot], eigVec_interp_fx ); + pca_transform_sub_fx( eigVec_interp_fx, transformed_data_fx, imult1616( slot_len, time_slot ), slot_len, n_channels ); + } + + return; +} +#endif + static void pca_update_state( PCA_ENC_STATE *hPCA, float *ql, @@ -166,6 +297,22 @@ static void pca_update_state( } +#ifdef IVAS_FLOAT_FIXED +static void pca_update_state_fx( + PCA_ENC_STATE *hPCA, + Word16 *ql, // Q15 + Word16 *qr, // Q15 + Word16 *eigVec, // Q15 + const Word16 n_channels ) +{ + Copy( qr, hPCA->prev_qr_fx, IVAS_PCA_INTERP ); + Copy( ql, hPCA->prev_ql_fx, IVAS_PCA_INTERP ); + Copy( eigVec, hPCA->prev_eigVec_fx, imult1616( n_channels, n_channels ) ); + + return; +} +#endif + static void swap_eigvec( float *eigVec, const int16_t i, @@ -190,6 +337,34 @@ static void swap_eigvec( return; } +#ifdef IVAS_FLOAT_FIXED +static void swap_eigvec_fx( + Word32 *eigVec, // Q31 + const Word32 i, + const Word32 j ) +{ + Word32 eigVec_tmp[FOA_CHANNELS]; + Word32 k; + + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + eigVec_tmp[k] = eigVec[k * FOA_CHANNELS + i]; + move32(); + } + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + eigVec[k * FOA_CHANNELS + i] = eigVec[k * FOA_CHANNELS + j]; + move32(); + } + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + eigVec[k * FOA_CHANNELS + j] = eigVec_tmp[k]; + move32(); + } + + return; +} +#endif static void sort4_D_eigVec( float *D, @@ -234,6 +409,51 @@ static void sort4_D_eigVec( return; } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS +static void sort4_D_eigVec_fx( + Word32 *D, // Q + Word32 *eigVec // Q31 +) +{ + Word32 tempr; + + IF( LT_32( D[0], D[1] ) ) + { + SWAP( D[0], D[1] ); + swap_eigvec_fx( eigVec, 0, 1 ); + } + + IF( LT_32( D[2], D[3] ) ) + { + SWAP( D[2], D[3] ); + swap_eigvec_fx( eigVec, 2, 3 ); + } + + IF( LT_32( D[0], D[2] ) ) + { + SWAP( D[0], D[2] ); + swap_eigvec_fx( eigVec, 0, 2 ); + } + + IF( LT_32( D[1], D[3] ) ) + { + SWAP( D[1], D[3] ); + swap_eigvec_fx( eigVec, 1, 3 ); + } + + IF( LT_32( D[1], D[2] ) ) + { + SWAP( D[1], D[2] ); + swap_eigvec_fx( eigVec, 1, 2 ); + } + + /* swap last 2 values */ + SWAP( D[2], D[3] ); + swap_eigvec_fx( eigVec, 2, 3 ); + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_pca_enc_init() @@ -593,3 +813,449 @@ void ivas_pca_enc( return; } + +void ivas_pca_enc_fx( + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + PCA_ENC_STATE *hPCA, /* i : PCA encoder structure */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + Word32 *data_fx[8], // Q11 + const Word16 input_frame, /* i : input frame length */ + const Word16 n_channels /* i : number of channels */ +) +{ + Word32 eigVec_tmp_fx[FOA_CHANNELS * FOA_CHANNELS]; /* transpose / tmp matrix for permutation */ + Word32 min_dot_fx, min_dot2_fx; + Word16 i, j, k, l; + Word16 fac_cost_fx; + Word16 len_subfr; + Word16 path[FOA_CHANNELS]; + Word32 r_fx[FOA_CHANNELS * FOA_CHANNELS]; /* covariance matrix */ + Word64 r_fx_64[FOA_CHANNELS * FOA_CHANNELS]; /* covariance matrix */ + Word32 D_fx[FOA_CHANNELS]; + Word32 eigVec_fx[FOA_CHANNELS * FOA_CHANNELS]; /* eigenvectors in current frame */ + Word32 index[2]; + Word32 *ptr_sig_fx[FOA_CHANNELS]; + Word16 temp_fx; + Word32 temp_fx32; + Word16 D_tmp_fx[FOA_CHANNELS]; + Word32 fac_D_fx, sum_D_fx; + Word32 ivas_total_brate; + Word32 alpha_fx; + Word32 one_minus_alpha_fx; + Word32 r_sm_fx[16]; + Word16 bypass_decision; + Word16 det_fx, temp_e; + Word64 W_tmp; + Word16 cost_mtx_fx[FOA_CHANNELS * FOA_CHANNELS]; /* cost matrix */ + Word16 ql_fx[IVAS_PCA_INTERP], qr_fx[IVAS_PCA_INTERP]; + Word32 L_tmp, L_tmp1; + Word16 eigVec_fx16[FOA_CHANNELS * FOA_CHANNELS]; + Word32 dist_alt_fx32, dotl_fx, dotr_fx; + Word16 q; + + ivas_total_brate = hEncoderConfig->ivas_total_brate; + move32(); + /* if PCA is disabled, just pass-through */ + IF( hEncoderConfig->Opt_PCA_ON == 0 ) + { + /* write by-pass indicator */ + push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 ); + + return; + } + + /* handle bitrate switching */ + IF( NE_32( ivas_total_brate, PCA_BRATE ) ) + { + pca_enc_reset( hPCA ); + + IF( NE_32( hEncoderConfig->last_ivas_total_brate, PCA_BRATE ) ) + { + eye_matrix_fx( hPCA->mem_eigVec_interp_fx, FOA_CHANNELS, MAX_16 ); + + /* copy input data into output directly as previous frame was already in by-pass mode */ + FOR( k = 0; k < n_channels; k++ ) + { + // ToDo: TBV + } + } + ELSE + { + /* set PCA by-pass mode in current frame and interpolate transform as previous frame used PCA */ + pca_enc_transform_fx( hPCA, ql_fx, qr_fx, data_fx, input_frame, n_channels ); // output Q9 + } + + pca_update_state_fx( hPCA, ql_fx, qr_fx, eigVec_fx16, n_channels ); + hPCA->prev_bypass_decision = PCA_MODE_INACTIVE; + move16(); + + return; + } + + /*-----------------------------------------------------------------* + * Covariance + *-----------------------------------------------------------------*/ + + len_subfr = shr( input_frame, 1 ); + + FOR( i = 0; i < input_frame; i += len_subfr ) + { + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + ptr_sig_fx[k] = &data_fx[k][i]; + } + + + cov_subfr_fx( ptr_sig_fx, r_fx_64, n_channels, shr( input_frame, 1 ) ); + Word16 tmp_q[FOA_CHANNELS * FOA_CHANNELS]; + FOR( Word16 idx = 0; idx < FOA_CHANNELS * FOA_CHANNELS; idx++ ) + { + Word16 w_norm = W_norm( r_fx_64[idx] ); + W_tmp = W_shl( r_fx_64[idx], w_norm ); + L_tmp = W_extract_h( W_tmp ); + r_fx[idx] = L_tmp; + tmp_q[idx] = add( sub( w_norm, 32 ), Q11 ); + move32(); + move16(); + } + + + q = tmp_q[0]; + move16(); + FOR( Word16 idx = 1; idx < FOA_CHANNELS * FOA_CHANNELS; idx++ ) + { + if ( GT_16( q, tmp_q[idx] ) ) + { + q = tmp_q[idx]; + move16(); + } + } + + + FOR( Word16 idx = 0; idx < FOA_CHANNELS * FOA_CHANNELS; idx++ ) + { + r_fx[idx] = L_shr( r_fx[idx], ( sub( tmp_q[idx], q ) ) ); + move32(); + } + + alpha_fx = IVAS_PCA_SM_FAC_FX; // Q31 + one_minus_alpha_fx = ONE_MINUS_IVAS_PCA_SM_FAC_FX; // Q31 + move32(); + move32(); + + Word16 min_q = s_min( q, hPCA->old_r_sm_q ); + + FOR( k = 0; k < FOA_CHANNELS * FOA_CHANNELS; k++ ) + { + L_tmp = L_shr( Mpy_32_32( alpha_fx, r_fx[k] ), sub( q, min_q ) ); + L_tmp1 = L_shr( Mpy_32_32( one_minus_alpha_fx, hPCA->old_r_sm_fx[k] ), sub( hPCA->old_r_sm_q, min_q ) ); + r_sm_fx[k] = L_add( L_tmp, L_tmp1 ); + hPCA->old_r_sm_fx[k] = r_sm_fx[k]; + move32(); + move32(); + } + hPCA->old_r_sm_q = min_q; + move16(); + } + + /* conditioning */ + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + temp_fx32 = r_sm_fx[k * FOA_CHANNELS + k]; + move32(); + IF( LT_32( temp_fx32, L_shr( 64424, sub( 31, hPCA->old_r_sm_q ) ) ) ) // IVAS_PCA_COV_THRES in Q31 + { + temp_fx32 = L_shr( 64424, sub( 31, hPCA->old_r_sm_q ) ); // IVAS_PCA_COV_THRES in Q31 + } + r_sm_fx[k * FOA_CHANNELS + k] = temp_fx32; /* pointer reuse */ + move32(); + } + + + /*-----------------------------------------------------------------* + * Eigenvalue decomposition + *-----------------------------------------------------------------*/ + eig_qr_fx( r_sm_fx, hPCA->old_r_sm_q, IVAS_PCA_N_ITER_QR, eigVec_fx, D_fx, n_channels ); + + /* force positive eigenvalues */ + sum_D_fx = 0; + Word16 sum_e = 0; + move32(); + move16(); + FOR( k = 0; k < n_channels; k++ ) + { + IF( D_fx[k] < 0 ) + { + D_fx[k] = L_negate( D_fx[k] ); + move32(); + + FOR( l = 0; l < n_channels; l++ ) + { + eigVec_fx[l * n_channels + k] = L_negate( eigVec_fx[l * n_channels + k] ); + move32(); + } + } + sum_D_fx = BASOP_Util_Add_Mant32Exp( sum_D_fx, sum_e, D_fx[k], sub( 31, hPCA->old_r_sm_q ), &sum_e ); + } + + /* normalize */ + Word16 tmp, exp; + tmp = BASOP_Util_Divide3232_Scale( 1, L_add( sum_D_fx, EPSILON_FX ), &exp ); + exp = add( exp, sub( 0, sum_e ) ); + IF( sum_D_fx == 0 ) + { + fac_D_fx = MAX_32; + move32(); + } + ELSE + { + fac_D_fx = L_shl( L_deposit_h( tmp ), exp ); // Q31 + } + + + FOR( k = 0; k < n_channels; k++ ) + { + D_fx[k] = Mpy_32_32( fac_D_fx, D_fx[k] ); + move32(); + } + + + /* sorting (sanity check) with SPAR inversion of last two channels */ + sort4_D_eigVec_fx( D_fx, eigVec_fx ); + + /* normalize and compute amount of decorrelation */ + dist_alt_fx32 = 0; + Word16 dist_alt_e16 = 0; + move32(); + move16(); + + FOR( k = 0; k < FOA_CHANNELS; k++ ) + { + dist_alt_fx32 = BASOP_Util_Add_Mant32Exp( dist_alt_fx32, dist_alt_e16, BASOP_Util_Loge( Mpy_32_32( r_fx[k * FOA_CHANNELS + k], fac_D_fx ), sub( 31, hPCA->old_r_sm_q ) ), 6, &dist_alt_e16 ); // Q25 + dist_alt_fx32 = BASOP_Util_Add_Mant32Exp( dist_alt_fx32, dist_alt_e16, L_negate( BASOP_Util_Loge( D_fx[k], sub( 31, hPCA->old_r_sm_q ) ) ), 6, &dist_alt_e16 ); // Q25 + } + + /*-----------------------------------------------------------------* + * Eigenvector alignment + *-----------------------------------------------------------------*/ + + IF( EQ_16( hPCA->prev_bypass_decision, PCA_MODE_ACTIVE ) ) + { + /* compute absolute cost matrix */ + FOR( k = 0; k < n_channels; k++ ) /* column */ + { + FOR( l = 0; l < n_channels; l++ ) /* row */ + { + fac_cost_fx = mult( hPCA->prev_D_fx[l], extract_l( D_fx[k] ) ); // hPCA->old_r_sm_q + temp_fx = 0; + temp_e = 0; + move16(); + move16(); + FOR( i = 0; i < n_channels; i++ ) /* row */ + { + temp_e = BASOP_Util_Add_MantExp( temp_fx, temp_e, mult( hPCA->prev_eigVec_fx[i * n_channels + l], extract_l( eigVec_fx[i * n_channels + k] ) ), 0, &temp_fx ); + } + IF( temp_fx < 0 ) + { + temp_fx = negate( temp_fx ); + } + cost_mtx_fx[k * n_channels + l] = shr( mult( temp_fx, fac_cost_fx ), temp_e ); // hPCA->old_r_sm_q + move16(); + } + } + + /* find optimal permutation */ + exhst_4x4_fx( cost_mtx_fx, path, 1 ); + } + ELSE + { + /* no alignment needed if previous PCA is inactive */ + FOR( i = 0; i < 4; i++ ) + { + path[i] = i; + move16(); + } + } + + /* permute eigenvectors */ + FOR( k = 0; k < n_channels; k++ ) + { + j = path[k]; + move16(); + /* copy j-th column to column k */ + FOR( l = 0; l < n_channels; l++ ) + { + eigVec_tmp_fx[l * n_channels + k] = eigVec_fx[l * n_channels + j]; + move16(); + } + D_tmp_fx[k] = extract_l( D_fx[j] ); + move16(); + } + + FOR( k = 0; k < n_channels * n_channels; k++ ) + { + eigVec_fx[k] = eigVec_tmp_fx[k]; + move32(); + } + + /* check for sign inversions */ + FOR( k = 0; k < n_channels; k++ ) /* column */ + { + temp_fx = 0; + temp_e = 0; + // Word64 W_add_fx = 1; + move16(); + move16(); + FOR( i = 0; i < n_channels; i++ ) /* row */ + { + temp_e = BASOP_Util_Add_MantExp( temp_fx, temp_e, mult( hPCA->prev_eigVec_fx[i * n_channels + k], extract_l( eigVec_fx[i * n_channels + k] ) ), 0, &temp_fx ); + } + move32(); + move16(); + + IF( temp_fx < 0 ) + { + FOR( i = 0; i < n_channels; i++ ) + { + eigVec_fx[i * n_channels + k] = L_negate( eigVec_fx[i * n_channels + k] ); + move32(); + } + } + } + + /* force rotation matrix(det = +1) */ + Copy_Scale_sig32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); + det_fx = mat_det4_fx( eigVec_fx16 ); + IF( det_fx < 0 ) + { + swap_eigvec_fx( eigVec_fx, 2, 3 ); + temp_fx = D_tmp_fx[3]; + D_tmp_fx[3] = D_tmp_fx[2]; + D_tmp_fx[2] = temp_fx; + move16(); + move16(); + move16(); + } + + /* update state */ + FOR( k = 0; k < n_channels; k++ ) + { + hPCA->prev_D_fx[k] = D_tmp_fx[k]; // Q31 + move16(); + } + + /*-----------------------------------------------------------------* + * Rotation matrix parametrization and quantization + *-----------------------------------------------------------------*/ + + /* convert frrm rotation matrix to double quaternion */ + Copy_Scale_sig_32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); + mat2dquat_fx( eigVec_fx16, ql_fx, qr_fx ); + + dotl_fx = Dot_product( hPCA->prev_ql_fx, ql_fx, 4 ); + dotr_fx = Dot_product( hPCA->prev_qr_fx, qr_fx, 4 ); + IF( LT_32( dotl_fx, dotr_fx ) ) + { + min_dot_fx = dotl_fx; + move32(); + } + ELSE + { + min_dot_fx = dotr_fx; + move32(); + } + + IF( LT_16( ql_fx[0], qr_fx[0] ) ) + { + min_dot2_fx = L_deposit_h( ql_fx[0] ); + } + ELSE + { + min_dot2_fx = L_deposit_h( qr_fx[0] ); + } + + bypass_decision = PCA_MODE_ACTIVE; + move16(); + if ( LT_32( L_shr( dist_alt_fx32, sub( 31, dist_alt_e16 ) ), IVAS_PCA_THRES_DIST_ALT_FX ) ) + { + bypass_decision = PCA_MODE_INACTIVE; + move16(); + } + if ( LT_32( min_dot_fx, IVAS_PCA_THRES_MIN_DOT_FX ) ) + { + bypass_decision = PCA_MODE_INACTIVE; + move16(); + } + if ( LT_32( min_dot2_fx, IVAS_PCA_THRES_MIN_DOT2_FX ) ) + { + bypass_decision = PCA_MODE_INACTIVE; + move16(); + } + + + /* if PCA is inactive */ + IF( EQ_16( bypass_decision, PCA_MODE_INACTIVE ) ) + { + eye_matrix_fx( eigVec_fx16, 4, MAX_16 ); + set16_fx( ql_fx, 0, 4 ); + set16_fx( qr_fx, 0, 4 ); + ql_fx[0] = MAX_16; + qr_fx[0] = MAX_16; + move16(); + move16(); + + /* write by-pass indicator */ + push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 ); + IF( EQ_16( hPCA->prev_bypass_decision, PCA_MODE_INACTIVE ) ) + { + eye_matrix_fx( hPCA->mem_eigVec_interp_fx, FOA_CHANNELS, MAX_16 ); + } + ELSE + { + /* set PCA by-pass mode in current frame and interpolate transform as previous frame used PCA */ + pca_enc_transform_fx( hPCA, ql_fx, qr_fx, data_fx, input_frame, n_channels ); + } + + pca_update_state_fx( hPCA, ql_fx, qr_fx, eigVec_fx16, n_channels ); + hPCA->prev_bypass_decision = PCA_MODE_INACTIVE; + move16(); + return; + } + + /* force ql to have first component with positive sign */ + + IF( ql_fx[0] < 0 ) + { + FOR( i = 0; i < 4; i++ ) + { + ql_fx[i] = negate( ql_fx[i] ); // Q15 + qr_fx[i] = negate( qr_fx[i] ); + move16(); + move16(); + } + } + + /* quantize double quaternion */ + pca_enc_s3_fx( ql_fx, &index[0] ); + pca_enc_s3_fx( qr_fx, &index[1] ); + + + /* write bypass flag to bitstream to indicate active mode */ + push_next_indice( hMetaData, PCA_MODE_ACTIVE, 1 ); + + ivas_bitstream_write_int32( hMetaData, index[0], IVAS_PCA_QBITS - 1 ); + ivas_bitstream_write_int32( hMetaData, index[1], IVAS_PCA_QBITS ); + + /* transform */ + + pca_enc_transform_fx( hPCA, ql_fx, qr_fx, data_fx, input_frame, n_channels ); + + /*-----------------------------------------------------------------* + * update state for next frame + *-----------------------------------------------------------------*/ + + hPCA->prev_bypass_decision = bypass_decision; + move16(); + pca_update_state_fx( hPCA, ql_fx, qr_fx, eigVec_fx16, n_channels ); + return; +} diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 3247cdf34c1238dc4eef3fe08c050b658c2ff137..bfc3155c85f7097757459a6d540f6cd8cda325df 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -45,6 +45,7 @@ #include "prot_fx.h" #ifdef IVAS_FLOAT_FIXED +#include "basop_util.h" #include "ivas_rom_com_fx.h" #endif @@ -145,19 +146,38 @@ static Word16 ivas_qmetadata_reorder_azimuth_index_fx( const Word16 azimuth_index, const Word16 avg_azimuth_index, const Word16 azimuth_alphabet ); +static ivas_error requantize_direction_EC_3_fx( Word16 *extra_bits, IVAS_QDIRECTION *q_direction, const Word16 coding_subbands, BSTR_ENC_HANDLE hMetaData, Word32 elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], Word16 *ind_order ); + #else static int16_t ivas_qmetadata_reorder_azimuth_index( const int16_t azimuth_index, const int16_t avg_azimuth_index, const int16_t azimuth_alphabet ); -#endif - static ivas_error requantize_direction_EC_3( int16_t *extra_bits, IVAS_QDIRECTION *q_direction, const int16_t coding_subbands, BSTR_ENC_HANDLE hMetaData, float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], int16_t *ind_order ); +#endif + +#ifdef IVAS_FLOAT_FIXED +static void calculate_two_distances_fx( + Word32 *el_fx, /* i : elevation values */ + Word16 *bits, /* i : number of bits for each tile */ + const Word16 total_bits, /* i : total number of bits for subband */ + const Word16 len, /* i : number of tiles */ + Word32 *p_d1, /* o : first distortion */ + Word32 *p_d2, /* o : second distortion */ + Word16 *Q_out ); +#else static void calculate_two_distances( float *el, int16_t *bits, const int16_t total_bits, const int16_t len, float *p_d1, float *p_d2 ); -static void joint_encoding( IVAS_QDIRECTION *q_direction, const int16_t j, const int16_t next_j, const int16_t coding_subbands, int16_t *bits_dir0, const int16_t allowed_bits, BSTR_ENC_HANDLE hMetaData, int16_t *diff ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void joint_encoding_fx( IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 next_j, const Word16 coding_subbands, Word16 *bits_dir0, const Word16 allowed_bits, BSTR_ENC_HANDLE hMetaData, Word16 *diff ); +static ivas_error write_ec_direction_fx( Word16 *num_bits_written, BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const Word16 j_idx, const Word16 len, const Word16 GR_ord_elevation, const Word16 GR_ord_azimuth, const Word16 use_context, const Word16 same ); +static Word16 write_fixed_rate_direction_fx( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const Word16 j_idx, const Word16 len ); +#else +static void joint_encoding( IVAS_QDIRECTION *q_direction, const int16_t j, const int16_t next_j, const int16_t coding_subbands, int16_t *bits_dir0, const int16_t allowed_bits, BSTR_ENC_HANDLE hMetaData, int16_t *diff ); static ivas_error write_ec_direction( int16_t *num_bits_written, BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len, const int16_t GR_ord_elevation, const int16_t GR_ord_azimuth, const int16_t use_context, const int16_t same ); - static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len ); +#endif + #ifdef IVAS_FLOAT_FIXED static Word16 ivas_qmetadata_quantize_coherence_fx( @@ -235,11 +255,18 @@ static Word16 encode_surround_coherence_fx( #else static int16_t encode_surround_coherence( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); #endif - -static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len ); - +#ifndef IVAS_FLOAT_FIXED static int16_t common_direction( IVAS_QDIRECTION *q_direction, const int16_t band_idx, const int16_t len, const int16_t bits_allowed, BSTR_ENC_HANDLE hMetaData, float *elevation_orig, float *azimuth_orig ); - +#else +static Word16 common_direction_fx( + IVAS_QDIRECTION *q_direction, + const Word16 band_idx, + const Word16 len, + const Word16 bits_allowed, + BSTR_ENC_HANDLE hMetaData, + Word32 *elevation_orig_fx, + Word32 *azimuth_orig_fx ); +#endif #ifdef IVAS_FLOAT_FIXED static Word16 ivas_diffuseness_huff_ec_encode_fx( BSTR_ENC_HANDLE hMetaData, @@ -736,8 +763,29 @@ ivas_error ivas_qmetadata_enc_encode_fx( only_reduce_bits_direction_fx( &extra_bits, q_direction, reduce_bits, nbands, nblocks, ind_order ); bits_dir[d] = hMetaData->nb_bits_tot; - requantize_direction_EC_3( &extra_bits, q_direction, nbands, hMetaData, elevation_orig_flt, azimuth_orig_flt, ind_order ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + for ( int j = 0; j < MASA_MAXIMUM_CODING_SUBBANDS; j++ ) + { + floatToFixed_arrL32( elevation_orig_flt[j], elevation_orig[j], Q22, 4 ); + floatToFixed_arrL32( azimuth_orig_flt[j], azimuth_orig[j], Q22, 4 ); + } + + for ( int k = q_direction->cfg.start_band; k < q_direction->cfg.nbands; k++ ) + { + floatToFixed_arrL32( q_direction->band_data[k].elevation, q_direction->band_data[k].elevation_fx, Q22, 4 ); + floatToFixed_arrL32( q_direction->band_data[k].azimuth, q_direction->band_data[k].azimuth_fx, Q22, 4 ); + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + requantize_direction_EC_3_fx( &extra_bits, q_direction, nbands, hMetaData, elevation_orig, azimuth_orig, ind_order ); bits_dir[d] = hMetaData->nb_bits_tot - bits_dir[d]; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int k = q_direction->cfg.start_band; k < q_direction->cfg.nbands; k++ ) + { + fixedToFloat_arrL32( q_direction->band_data[k].elevation_fx, q_direction->band_data[k].elevation, Q22, 4 ); + fixedToFloat_arrL32( q_direction->band_data[k].azimuth_fx, q_direction->band_data[k].azimuth, Q22, 4 ); + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS } /* finalize writing coherence */ @@ -2214,6 +2262,7 @@ Word16 quantize_direction2D_fx( } *phi_q = L_sub( *phi_q, 180 << Q22 ); move32(); + *index_phi = ivas_qmetadata_reorder_generic( sub( id_phi, shr( no_cw, 1 ) ) ); move16(); @@ -3703,7 +3752,111 @@ static int16_t GR_bits_new( * * Encoding azimuth indexes with GR code using context *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: numer of bits used for coding */ +static Word16 GR_bits_azimuth_context( + UWord16 *data_in, /* i : data to be encoded */ + Word16 *no_symb, /* i : number of symbols for each component */ + const Word16 no_data_in, /* i : number of input data */ + const Word16 GR_order, /* i : GR order (GR_order or GR_order-1 are used ) */ + const UWord16 *bits_dir, /* i : bits for encoding the direction for each TF tile */ + Word16 *real_GR_ord, /* o : which GR order has been used Q0 */ + Word16 *p_use_context /* o : flag telling if context has been used or not Q0 */ +) +{ + Word16 i, nbits, nbits1, use_context; + UWord16 cdata[MAX_PARAM_SPATIAL_SUBFRAMES]; + UWord16 data[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 min_val, max_val; + Word16 real_GR_ord1; + Word16 no_symb_local[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 no_data = 0; + move16(); + FOR( i = 0; i < no_data_in; i++ ) + { + IF( data_in[i] < MASA_NO_INDEX ) + { + no_symb_local[no_data] = no_symb[i]; + move16(); + data[no_data++] = data_in[i]; + move16(); + } + } + + IF( no_data == 0 ) + { + *p_use_context = -3; /* corresponding to nothing to be written */ + move16(); + return 0; + } + + nbits = 0; + move16(); + use_context = 0; + move16(); + FOR( i = 0; i < no_data; i++ ) + { + IF( LE_16( bits_dir[i], 1 ) ) + { + nbits = add( nbits, bits_dir[i] ); + use_context = 1; + move16(); + } + ELSE + { + *real_GR_ord = sub( GR_order, (Word16) EQ_16( bits_dir[i], 2 ) ); + move16(); + nbits = add( nbits, ivas_qmetadata_encode_extended_gr_length( data[i], no_symb_local[i], *real_GR_ord ) ); + } + } + + real_GR_ord1 = 0; + move16(); + IF( use_context == 0 ) + { + nbits = GR_bits_new( data, no_symb_local, no_data, GR_order, 1, real_GR_ord ); + nbits1 = nbits; + move16(); + min_val = data[0]; + move16(); + FOR( i = 1; i < no_data; i++ ) + { + if ( LT_32( data[i], min_val ) ) + { + min_val = data[i]; + move16(); + } + } + FOR( i = 0; i < no_data; i++ ) + { + cdata[i] = (UWord16) L_sub( data[i], min_val ); + move16(); + } + + maximum_s( no_symb_local, no_data, &max_val ); + nbits1 = add( GR_bits_new( cdata, no_symb_local, no_data, sub( GR_order, 1 ), 1, &real_GR_ord1 ), ivas_qmetadata_encode_extended_gr_length( min_val, max_val, MASA_GR_ORD_AZ ) ); + + IF( LT_16( nbits1, nbits ) ) + { + nbits = add( nbits1, 1 ); + use_context = -2; + move16(); + *real_GR_ord = real_GR_ord1; + move16(); + } + ELSE + { + nbits = add( nbits, 1 ); + use_context = -1; + move16(); + } + } + *p_use_context = use_context; + move16(); + return nbits; +} +#else /*! r: numer of bits used for coding */ static int16_t GR_bits_azimuth_context( uint16_t *data_in, /* i : data to be encoded */ @@ -3794,7 +3947,7 @@ static int16_t GR_bits_azimuth_context( return nbits; } - +#endif /*------------------------------------------------------------------------- * mean_removed_GR_new() @@ -5595,7 +5748,169 @@ void ivas_qmetadata_encode_extended_gr( /*-----------------------------------------------------------------------* * Local functions (EC3, requantize directions) *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 truncGR0_fx( + Word32 *data_fx, // Q22 + Word32 *data_hat_fx, // Q22 + UWord16 *data_idx, + const Word16 len, + const Word16 bits_allowed, + Word32 *st_fx, // Q31 + Word32 *ct_fx // Q31 +) +{ + Word16 i; + Word16 bits; + const Word16 remap3b[8] = { 1, 6, 2, 4, 0, 5, 3, 7 }; + const Word16 remap2b[4] = { 1, 2, 0, 3 }; + Word32 diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 indx[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 L_temp; + bits = 0; + move16(); + set_val_Word32( data_hat_fx, 0, len ); + set_val_Word32( diff_fx, 10000, len ); + + IF( LE_16( bits_allowed, add( len, 1 ) ) ) + { + bits = s_min( bits_allowed, len ); + set_val_Word32( data_hat_fx, 0, len ); + + FOR( i = 0; i < bits; i++ ) + { + IF( LE_32( L_abs( data_fx[i] ), 377487360 ) ) // 90 in Q22 + { + data_idx[i] = 0; + move16(); + data_hat_fx[i] = 0; + move32(); + } + ELSE + { + data_idx[i] = 1; + move16(); + data_hat_fx[i] = -754974720; //-180 in Q22 + move32(); + } + } + + return bits; + } + + FOR( i = 0; i < len; i++ ) + { + data_idx[i] = quantize_phi_fx( L_add( data_fx[i], DEGREE_180_Q_22 ), 0, &data_hat_fx[i], 8 ); + move16(); + data_hat_fx[i] = L_sub( data_hat_fx[i], DEGREE_180_Q_22 ); + move32(); + data_idx[i] = remap3b[data_idx[i]]; + move16(); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[i], 8, 0 ) ); + // diff[i] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[i] - data_hat[i] ) ); /*(data[i] - data_hat[i])*(data[i] - data_hat[i]);*/ + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31 + diff_fx[i] = -L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ); // Q30 + move32(); + } + + i = 0; + move16(); + IF( GT_16( bits, bits_allowed ) ) + { + sort_desc_ind_32_fx( diff_fx, len, indx ); + FOR( i = len - 1; i >= 0; i-- ) + { + IF( GT_32( data_idx[indx[i]], 3 ) ) + { + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + // data_idx[indx[i]] = quantize_phi( data[indx[i]] + 180, 0, &data_hat[indx[i]], 4 ); + data_idx[indx[i]] = quantize_phi_fx( L_add( data_fx[indx[i]], DEGREE_180_Q_22 ), 0, &data_hat_fx[indx[i]], 4 ); + move16(); + // data_hat[indx[i]] -= 180; + data_hat_fx[indx[i]] = L_sub( data_hat_fx[indx[i]], DEGREE_180_Q_22 ); + move32(); + data_idx[indx[i]] = remap2b[data_idx[indx[i]]]; + move16(); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) ); + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31 + + diff_fx[indx[i]] = -L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ); // Q30 + move32(); + } + IF( LE_16( bits, bits_allowed ) ) + { + BREAK; + } + } + } + + IF( GT_16( bits, bits_allowed ) ) + { + sort_desc_ind_32_fx( diff_fx, len, indx ); + FOR( i = len - 1; i >= 0; i-- ) + { + + IF( GT_16( data_idx[indx[i]], 1 ) ) + { + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + + IF( LE_32( L_abs( data_fx[indx[i]] ), 377487360 ) ) // 90 in Q22 + { + data_idx[indx[i]] = 0; + move16(); + // data_hat[i] = 0.0f; + data_hat_fx[indx[i]] = 0; + move32(); + } + ELSE + { + data_idx[indx[i]] = 1; + move16(); + // data_hat[i] = -180.0f; + data_hat_fx[indx[i]] = -754974720; //-180 in Q22 + move32(); + } + + bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) ); + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31 + + diff_fx[indx[i]] = -L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ); // Q30 + move32(); + } + + IF( LE_16( bits, bits_allowed ) ) + { + BREAK; + } + } + } + + IF( GT_16( bits, bits_allowed ) ) + { + + sort_desc_ind_32_fx( diff_fx, len, indx ); + FOR( i = len - 1; i >= 0; i-- ) + { + + if ( data_idx[indx[i]] > 0 ) + { + bits = sub( bits, data_idx[indx[i]] ); + data_idx[indx[i]] = 0; + move16(); + data_hat_fx[indx[i]] = 0; + move32(); + } + IF( LE_16( bits, bits_allowed ) ) + { + BREAK; + } + } + } + return bits; +} +#else static int16_t truncGR0( float *data, float *data_hat, @@ -5723,58 +6038,193 @@ static int16_t truncGR0( return bits; } - - +#endif /*-------------------------------------------------------------------* * truncGR0_chan() * * *-------------------------------------------------------------------*/ - -static int16_t truncGR0_chan( - const float *data, - float *data_hat, - uint16_t *data_idx, - const int16_t len, - const int16_t bits_allowed, - float *st, - float *ct ) +#ifdef IVAS_FLOAT_FIXED +static Word16 truncGR0_chan_fx( + const Word32 *data_fx, // Q22 + Word32 *data_hat_fx, // Q22 + UWord16 *data_idx, + const Word16 len, + const Word16 bits_allowed, + Word32 *st_fx, // Q31 + Word32 *ct_fx ) // Q31 { - int16_t i, idx_crt; - int16_t bits; - float diff[MAX_PARAM_SPATIAL_SUBFRAMES], sort_diff[MAX_PARAM_SPATIAL_SUBFRAMES], min_diff, sum_diff; - int16_t indx[MAX_PARAM_SPATIAL_SUBFRAMES]; - + Word16 i, idx_crt; + Word16 bits; + Word32 diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES], sort_diff_fx[MAX_PARAM_SPATIAL_SUBFRAMES], min_diff_fx, sum_diff_fx; + Word16 indx[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 L_temp; bits = 0; - set_f( data_hat, 0.0f, len ); - set_f( diff, 10000.0f, len ); - - if ( bits_allowed <= len + 1 ) + move16(); + set_val_Word32( data_hat_fx, 0, len ); + set_val_Word32( diff_fx, 10000, len ); + Word16 gb = find_guarded_bits_fx( len ); + IF( LE_16( bits_allowed, add( len, 1 ) ) ) { - bits = min( bits_allowed, len ); - set_f( data_hat, 0.0f, len ); - /*set_s(data_idx, 0, len); */ - for ( i = 0; i < bits; i++ ) + bits = s_min( bits_allowed, len ); + set_val_Word32( data_hat_fx, 0, len ); + + FOR( i = 0; i < bits; i++ ) { - if ( fabsf( data[i] ) <= 90 ) + IF( LE_32( L_abs( data_fx[i] ), 377487360 ) ) // 90 in Q22 { data_idx[i] = 0; - data_hat[i] = 0.0f; + move16(); + data_hat_fx[i] = 0; + move32(); } - else + ELSE { data_idx[i] = 1; - data_hat[i] = -180.0f; + move16(); + // data_hat[i] = -180.0f; + data_hat_fx[i] = -754974720; //-180 in Q22 + move32(); } } return bits; } - for ( i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { - data_idx[i] = quantize_phi_chan_lbr( data[i], &data_hat[i], 9 ); + data_idx[i] = quantize_phi_chan_lbr_fx( data_fx[i], &data_hat_fx[i], 9 ); + move16(); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 ) ); + // diff[i] = -st[i] - ct[i] * cosf( ( data[i] - data_hat[i] ) * PI_OVER_180 ); + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31 + diff_fx[i] = -L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ); // Q30 + move32(); + } - bits += ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 ); + WHILE( GT_16( bits, bits_allowed ) ) + { + // min_diff = 1000.0f; + min_diff_fx = 2097152000; // 1000 in Q21 + move32(); + Word16 min_diff_e = Q31 - Q21; + move16(); + idx_crt = -1; + move16(); + MVR2R_WORD32( diff_fx, sort_diff_fx, len ); + FOR( i = 0; i < len; i++ ) + { + IF( data_idx[i] > 0 ) + { + // sort_diff[i] = -st[i] - ct[i] * cosf( ( fabsf( data[i] ) - cb_azi_chan[( ( data_idx[i] + 1 ) >> 1 ) - 1] ) * PI_OVER_180 ); + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( L_abs( data_fx[i] ), cb_azi_chan_fx[( ( data_idx[i] + 1 ) >> 1 ) - 1] ), 91 ), 7 ) ) ) ); // Q31 + sort_diff_fx[i] = -L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ); // Q30 // Q30 + move32(); + sum_diff_fx = sum2_f_32_fx( sort_diff_fx, len, gb ); // Q(2*Q30-31-gb)= Q(Q29-gb) + Word16 flag = BASOP_Util_Cmp_Mant32Exp( sum_diff_fx, sub( Q31, sub( Q29, gb ) ), min_diff_fx, min_diff_e ); + if ( EQ_16( flag, -1 ) ) + { + min_diff_fx = sum_diff_fx; + move32(); + min_diff_e = sub( Q31, sub( Q29, gb ) ); + idx_crt = i; + move16(); + } + sort_diff_fx[i] = diff_fx[i]; // Q30 + move32(); + } + } + + IF( GT_16( idx_crt, -1 ) ) + { + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + data_idx[idx_crt] = quantize_phi_chan_lbr_fx( data_fx[idx_crt], &data_hat_fx[idx_crt], add( data_idx[idx_crt], 1 ) ); + move16(); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + // diff[idx_crt] = -st[idx_crt] - ct[idx_crt] * cosf( ( data[idx_crt] - data_hat[idx_crt] ) * PI_OVER_180 ); + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[idx_crt], data_hat_fx[idx_crt] ), 91 ), 7 ) ) ) ); // Q31 + + diff_fx[idx_crt] = -L_add( L_shr( st_fx[idx_crt], 1 ), L_shr( Mpy_32_32( ct_fx[idx_crt], L_temp ), 1 ) ); // Q30 + move32(); + } + ELSE + { + BREAK; + } + } + + IF( GT_16( bits, bits_allowed ) ) + { + MVR2R_WORD32( diff_fx, sort_diff_fx, len ); + sort_desc_ind_32_fx( sort_diff_fx, len, indx ); + + FOR( i = len - 1; i >= 0; i-- ) + { + idx_crt = indx[i]; + move16(); + IF( data_idx[idx_crt] > 0 ) + { + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + data_idx[idx_crt] = 0; + move16(); + data_hat_fx[idx_crt] = 0; + move32(); + bits = add( bits, 1 ); + } + + IF( LE_16( bits, bits_allowed ) ) + { + BREAK; + } + } + } + + return bits; +} +#else +static int16_t truncGR0_chan( + const float *data, + float *data_hat, + uint16_t *data_idx, + const int16_t len, + const int16_t bits_allowed, + float *st, + float *ct ) +{ + int16_t i, idx_crt; + int16_t bits; + float diff[MAX_PARAM_SPATIAL_SUBFRAMES], sort_diff[MAX_PARAM_SPATIAL_SUBFRAMES], min_diff, sum_diff; + int16_t indx[MAX_PARAM_SPATIAL_SUBFRAMES]; + + bits = 0; + set_f( data_hat, 0.0f, len ); + set_f( diff, 10000.0f, len ); + + if ( bits_allowed <= len + 1 ) + { + bits = min( bits_allowed, len ); + set_f( data_hat, 0.0f, len ); + /*set_s(data_idx, 0, len); */ + for ( i = 0; i < bits; i++ ) + { + if ( fabsf( data[i] ) <= 90 ) + { + data_idx[i] = 0; + data_hat[i] = 0.0f; + } + else + { + data_idx[i] = 1; + data_hat[i] = -180.0f; + } + } + return bits; + } + + for ( i = 0; i < len; i++ ) + { + data_idx[i] = quantize_phi_chan_lbr( data[i], &data_hat[i], 9 ); + + bits += ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 ); diff[i] = -st[i] - ct[i] * cosf( ( data[i] - data_hat[i] ) * PI_OVER_180 ); } @@ -5837,14 +6287,230 @@ static int16_t truncGR0_chan( return bits; } - +#endif /*-------------------------------------------------------------------* * common_direction() * * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 common_direction_fx( + IVAS_QDIRECTION *q_direction, + const Word16 band_idx, + const Word16 len, + const Word16 bits_allowed, + BSTR_ENC_HANDLE hMetaData, + Word32 *elevation_orig_fx, // Q22 + Word32 *azimuth_orig_fx // Q22 +) +{ + Word16 nbits; + Word16 no_th, i, id_th, k; + Word32 theta_cb_fx[5]; + Word32 dist_fx, best_dist_fx; + Word32 ct_fx[MAX_PARAM_SPATIAL_SUBFRAMES], st_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + + nbits = 0; + move16(); + IF( bits_allowed == 0 ) + { + FOR( i = 0; i < len; i++ ) + { + q_direction->band_data[band_idx].elevation_fx[i] = 0; + move32(); + q_direction->band_data[band_idx].azimuth_fx[i] = 0; + move32(); + } + + return 0; + } + + IF( LE_16( bits_allowed, add( len, 1 ) ) ) + { + set_val_Word32( q_direction->band_data[band_idx].elevation_fx, 0, len ); + set_val_Word32( st_fx, 0, len ); + + FOR( i = 0; i < len; i++ ) + { + // ct[i] = cosf( elevation_orig[i] * PI_OVER_180 ); + ct_fx[i] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ); // Q31 + move32(); + } + + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + nbits = truncGR0_chan_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st_fx, ct_fx ); + } + ELSE + { + nbits = truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st_fx, ct_fx ); + } + + FOR( i = 0; i < nbits; i++ ) + { + push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 ); + } + + return nbits; + } + + no_th = add( no_theta_masa[0], 3 ); /* only 5 values for theta; the lat 2 are +/-90 */ + + theta_cb_fx[0] = 0; + move32(); + theta_cb_fx[1] = delta_theta_masa_fx[2]; + move32(); + theta_cb_fx[2] = -theta_cb_fx[1]; + move32(); + // theta_cb[3] = 90.0f; + theta_cb_fx[3] = 377487360; // 90.0f in Q22 + move32(); + // theta_cb[4] = -90.0f; + theta_cb_fx[4] = -377487360; //-90.0f in Q22 + move32(); + // best_dist = 900000.0f; + best_dist_fx = 1843200000; // 900000.0f in Q11 + move32(); + Word16 best_dist_q = Q11; + move16(); + id_th = 0; + move16(); + Word16 gb = find_guarded_bits_fx( len ); + FOR( i = 0; i < no_th; i++ ) + { + // dist = 0.0f; + dist_fx = 0; + move32(); + FOR( k = 0; k < len; k++ ) + { + // dist += ( elevation_orig[k] - theta_cb[i] ) * ( elevation_orig[k] - theta_cb[i] ); + dist_fx = L_add( dist_fx, L_shr( Mpy_32_32( L_sub( elevation_orig_fx[k], theta_cb_fx[i] ), L_sub( elevation_orig_fx[k], theta_cb_fx[i] ) ), gb ) ); // Q(2*Q22-31) = Q13-gb + } + if ( LT_32( L_shr( dist_fx, sub( sub( Q13, gb ), best_dist_q ) ), best_dist_fx ) ) + { + id_th = i; + move16(); + best_dist_fx = dist_fx; + move32(); + best_dist_q = sub( Q13, gb ); + } + } + + set_val_Word32( q_direction->band_data[band_idx].elevation_fx, theta_cb_fx[id_th], len ); + + FOR( i = 0; i < len; i++ ) + { + q_direction->band_data[band_idx].elevation_index[i] = id_th; + move16(); + } + + IF( id_th == 0 ) + { + push_next_indice( hMetaData, 0, 1 ); /* average theta index */ + // set_f( st, 0.0f, len ); + set_val_Word32( st_fx, 0, len ); + + FOR( i = 0; i < len; i++ ) + { + // ct[i] = cosf( elevation_orig[i] * PI_OVER_180 ); + ct_fx[i] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ); // Q31 + move32(); + } + + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + nbits = truncGR0_chan_fx( /*azimuth_orig,*/ azimuth_orig_fx, /*q_direction->band_data[band_idx].azimuth,*/ q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, 1 ), /* st,*/ st_fx, /*ct,*/ ct_fx ) + 1; + } + ELSE + { + + nbits = truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - 1, st_fx, ct_fx ) + 1; + } + } + ELSE + { + IF( GE_16( id_th, 3 ) ) + { + /* theta is 90 or -90; only theta is sent */ + push_next_indice( hMetaData, add( id_th, 11 ), 4 ); /* average theta index */ + set_val_Word32( q_direction->band_data[band_idx].azimuth_fx, 0, len ); + FOR( i = 0; i < len; i++ ) + { + q_direction->band_data[band_idx].azimuth_index[i] = 0; + move16(); + } + nbits = 4; + move16(); + return nbits; + } + + set_val_Word32( st_fx, L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( theta_cb_fx[id_th], 91 ), 7 ) ) ) ), len ); + set_val_Word32( ct_fx, L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( theta_cb_fx[id_th], 91 ), 7 ) ) ) ), len ); + + FOR( i = 0; i < len; i++ ) + { + // st[i] *= sinf( elevation_orig[i] * PI_OVER_180 ); + st_fx[i] = Mpy_32_32( st_fx[i], L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ) ); // Q31; + move32(); + // ct[i] *= cosf( elevation_orig[i] * PI_OVER_180 ); + ct_fx[i] = Mpy_32_32( ct_fx[i], L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[i], 91 ), 7 ) ) ) ) ); // Q31; + move32(); + q_direction->band_data[band_idx].azimuth_index[i] = 0; + move16(); + } + + IF( EQ_16( id_th, 1 ) ) + { + push_next_indice( hMetaData, 2, 2 ); /* average theta index */ + } + ELSE + { + assert( id_th == 2 ); + push_next_indice( hMetaData, 6, 3 ); /* average theta index */ + } + + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + nbits = add( truncGR0_chan_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, add( id_th, 1 ) ), st_fx, ct_fx ), add( id_th, 1 ) ); + } + ELSE + { + + nbits = add( truncGR0_fx( azimuth_orig_fx, q_direction->band_data[band_idx].azimuth_fx, q_direction->band_data[band_idx].azimuth_index, len, sub( bits_allowed, add( id_th, 1 ) ), st_fx, ct_fx ), add( id_th, 1 ) ); + } + } + + IF( LE_16( sub( bits_allowed, add( id_th, 1 ) ), add( len, 1 ) ) ) + { + + FOR( i = 0; i < s_min( len, sub( bits_allowed, add( id_th, 1 ) ) ); i++ ) + { + push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 ); + } + } + ELSE + { + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + FOR( i = 0; i < len; i++ ) + { + ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 9, 0 ); + } + } + ELSE + { + FOR( i = 0; i < len; i++ ) + { + ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 8, 0 ); + } + } + } + + return nbits; +} +#else static int16_t common_direction( IVAS_QDIRECTION *q_direction, const int16_t band_idx, @@ -6024,14 +6690,183 @@ static int16_t common_direction( return nbits; } - - -/*-------------------------------------------------------------------* - * encode_directions_subband() - * - * - *-------------------------------------------------------------------*/ - + +#endif + +/*-------------------------------------------------------------------* + * encode_directions_subband() + * + * + *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 encode_directions_subband_fx( + IVAS_QDIRECTION *q_direction, + Word16 coding_subbands, + BSTR_ENC_HANDLE hMetaData, + const Word16 j, + const Word16 next_j, + const Word16 no_subframes, + const Word16 last_subband, + Word16 *p_diff, + Word32 *elevation_orig_fx, + Word32 *azimuth_orig_fx ) +{ + Word16 allowed_bits, use_vq, max_nb_idx, k; + Word16 diff; + Word32 d1_fx, d2_fx; + Word16 nbits; + Word16 *bits_dir0; + + nbits = 0; + move16(); + diff = *p_diff; + move16(); + bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; + move16(); + allowed_bits = sum16_fx( bits_dir0, no_subframes ); + + IF( allowed_bits > 0 ) + { + use_vq = 0; + move16(); + max_nb_idx = 0; + move16(); + FOR( k = 0; k < no_subframes; k++ ) + { + if ( GT_16( bits_dir0[k], use_vq ) ) + { + use_vq = bits_dir0[k]; + move16(); + max_nb_idx = k; + move16(); + } + } + + IF( GT_16( no_subframes, 1 ) ) + { + if ( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) ) + { + bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 ); + move16(); + allowed_bits = sub( allowed_bits, 1 ); + } + } + IF( GT_16( no_subframes, 1 ) ) + { + IF( LE_16( use_vq, LIMIT_USE_COMMON ) ) + { + /* calculate the two distances */ + Word16 Q_out; + calculate_two_distances_fx( q_direction->band_data[j].elevation_fx, bits_dir0, allowed_bits, no_subframes, &d1_fx, &d2_fx, &Q_out ); + test(); + test(); + IF( ( GT_16( use_vq, 1 ) && LE_32( d2_fx, d1_fx ) ) || LE_16( use_vq, 1 ) ) + { + IF( GT_16( use_vq, 1 ) ) + { + push_next_indice( hMetaData, 1, 1 ); /* signal VQ */ + } + + diff = add( diff, sub( common_direction_fx( q_direction, j, no_subframes, allowed_bits, hMetaData, /*elevation_orig,*/ elevation_orig_fx, /*azimuth_orig,*/ azimuth_orig_fx ), allowed_bits ) ); + + IF( last_subband == 0 ) + { + update_bits_next_block( q_direction, &diff, next_j, coding_subbands, no_subframes ); + } + } + ELSE + { + push_next_indice( hMetaData, 0, 1 ); + + IF( last_subband == 0 ) + { + MVR2R_WORD32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); + MVR2R_WORD32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff ); + } + ELSE + { + FOR( k = 0; k < no_subframes; k++ ) + { + /* requantize the direction */ + q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k], + &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); + move16(); + } + + IF( allowed_bits > 0 ) + { + nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes ); + } + } + } + } + ELSE + { + /* there is only joint coding */ + MVR2R_WORD32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); + MVR2R_WORD32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + + IF( last_subband == 0 ) + { + joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff ); + } + ELSE + { + FOR( k = 0; k < no_subframes; k++ ) + { + /* requantize the direction */ + q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k], + &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); + move16(); + } + + IF( allowed_bits > 0 ) + { + nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes ); + } + } + } + } + ELSE + { + /* 1 subframe case */ + /* there is only joint coding */ + MVR2R_WORD32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); + MVR2R_WORD32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + + IF( last_subband == 0 ) + { + joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff ); + } + ELSE + { + FOR( k = 0; k < no_subframes; k++ ) + { + /* requantize the direction */ + q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( elevation_orig_fx[k], azimuth_orig_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], &q_direction->band_data[j].azimuth_fx[k], + &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); + move16(); + } + + IF( allowed_bits > 0 ) + { + nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes ); + } + } + } + } + ELSE + { + set_val_Word32( q_direction->band_data[j].elevation_fx, 0, no_subframes ); + set_val_Word32( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); + } + + *p_diff = diff; + move16(); + return nbits; +} +#else static int16_t encode_directions_subband( IVAS_QDIRECTION *q_direction, int16_t coding_subbands, @@ -6187,6 +7022,7 @@ static int16_t encode_directions_subband( return nbits; } +#endif /*-------------------------------------------------------------------* * calc_var_azi() @@ -6338,7 +7174,7 @@ static int16_t calc_var_azi( * * *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static ivas_error requantize_direction_EC_3( int16_t *extra_bits, IVAS_QDIRECTION *q_direction, @@ -6437,57 +7273,384 @@ static ivas_error requantize_direction_EC_3( } else { - for ( k = 0; k < no_subframes; k++ ) - { - /* requantize the direction */ - q_direction->band_data[j].spherical_index[k] = quantize_direction2D( azimuth_orig[j][k], 1 << q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].azimuth[k], - &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); - q_direction->band_data[j].elevation_index[k] = 0; - } - nbits += write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes ); + for ( k = 0; k < no_subframes; k++ ) + { + /* requantize the direction */ + q_direction->band_data[j].spherical_index[k] = quantize_direction2D( azimuth_orig[j][k], 1 << q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].azimuth[k], + &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); + q_direction->band_data[j].elevation_index[k] = 0; + } + nbits += write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes ); + } + } + } + + *extra_bits = -diff; + + return IVAS_ERR_OK; +} +#else +static ivas_error requantize_direction_EC_3_fx( + Word16 *extra_bits, + IVAS_QDIRECTION *q_direction, + const Word16 coding_subbands, + BSTR_ENC_HANDLE hMetaData, + Word32 elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + Word16 *ind_order ) +{ + /* gradually increase the bits following the performance of the EC layer*/ + Word16 j, k; + Word16 use_vq; + Word16 diff, allowed_bits, nbits, last_j; + Word16 no_subframes, start_band; + Word32 st_fx[MAX_PARAM_SPATIAL_SUBFRAMES], ct_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + + Word16 *bits_dir0; + + nbits = 0; + move16(); + no_subframes = q_direction->cfg.nblocks; + move16(); + start_band = q_direction->cfg.start_band; + move16(); + + + IF( GT_16( q_direction->not_in_2D, MASA_LIMIT_2D ) ) + { + j = ind_order[coding_subbands - 1]; + move16(); + bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; + allowed_bits = sum_s( bits_dir0, no_subframes ); + last_j = sub( j, ( allowed_bits == 0 ) ); + diff = 0; + move16(); + IF( EQ_16( coding_subbands, 1 ) ) + { + last_j = start_band; + move16(); + } + FOR( j = 0; j < last_j; j++ ) + { + k = ind_order[j]; + move16(); + encode_directions_subband_fx( q_direction, coding_subbands, hMetaData, k, ind_order[j + 1], no_subframes, 0, &diff, elevation_orig_fx[k], azimuth_orig_fx[k] ); + } + + /* last subbands to be written in fixed rate */ + FOR( j = last_j; j < coding_subbands; j++ ) + { + k = ind_order[j]; + move16(); + encode_directions_subband_fx( q_direction, coding_subbands, hMetaData, k, 0, no_subframes, 1, &diff, elevation_orig_fx[k], azimuth_orig_fx[k] ); + } + } + ELSE /* 2D */ + { + diff = 0; + nbits = 0; + move16(); + move16(); + FOR( j = start_band; j < coding_subbands; j++ ) + { + bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; + move16(); + allowed_bits = sum_s( bits_dir0, no_subframes ); + move16(); + use_vq = 0; + move16(); + FOR( k = 0; k < no_subframes; k++ ) + { + IF( GT_16( bits_dir0[k], use_vq ) ) + { + use_vq = bits_dir0[k]; + move16(); + } + } + + IF( LE_16( use_vq, 3 ) && LE_16( allowed_bits, 11 ) ) + { + + set_val_Word32( st_fx, 0, no_subframes ); + + FOR( k = 0; k < no_subframes; k++ ) + { + // ct[k] = cosf( elevation_orig[j][k] * PI_OVER_180 ); + ct_fx[k] = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( elevation_orig_fx[j][k], 91 ), 7 ) ) ) ); // Q31 + move32(); + } + + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + // nbits += truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct ); + nbits = add( nbits, truncGR0_chan_fx( /*azimuth_orig,*/ azimuth_orig_fx[j], /*q_direction->band_data[j].azimuth,*/ q_direction->band_data[j].azimuth_fx, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, /*st,*/ st_fx, /*ct,*/ ct_fx ) ); + } + ELSE + { + nbits = add( nbits, truncGR0_fx( azimuth_orig_fx[j], q_direction->band_data[j].azimuth_fx, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st_fx, ct_fx ) ); + } + + IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) + { + FOR( k = 0; k < min( no_subframes, allowed_bits ); k++ ) + { + push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 ); + } + } + ELSE + { + FOR( k = 0; k < no_subframes; k++ ) + { + ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ? 9 : 8, 0 ); + } + } + } + ELSE + { + FOR( k = 0; k < no_subframes; k++ ) + { + /* requantize the direction */ + q_direction->band_data[j].spherical_index[k] = quantize_direction2D_fx( azimuth_orig_fx[j][k], 1 << q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].azimuth_fx[k], + &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); + move16(); + q_direction->band_data[j].elevation_index[k] = 0; + move16(); + } + nbits = add( nbits, write_fixed_rate_direction_fx( hMetaData, q_direction, j, no_subframes ) ); + } + } + } + + *extra_bits = -diff; + move16(); + return IVAS_ERR_OK; +} +#endif + +/*-------------------------------------------------------------------* + * write_fixed_rate_direction() + * + * writing of the spherical indexes + *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: number of bits written */ +static Word16 write_fixed_rate_direction_fx( + BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */ + IVAS_QDIRECTION *qdirection, /* i/o: quantized directional parameters */ + const Word16 j_idx, /* i : index of subband for which the data is written */ + const Word16 len /* i : number of data */ +) +{ + Word16 nbits, i; + + nbits = 0; + move16(); + FOR( i = 0; i < len; i++ ) + { + push_next_indice( hMetaData, qdirection->band_data[j_idx].spherical_index[i], qdirection->band_data[j_idx].bits_sph_idx[i] ); + nbits = extract_l( L_add( nbits, qdirection->band_data[j_idx].bits_sph_idx[i] ) ); + } + + return nbits; +} +#else +/*! r: number of bits written */ +static int16_t write_fixed_rate_direction( + BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */ + IVAS_QDIRECTION *qdirection, /* i/o: quantized directional parameters */ + const int16_t j_idx, /* i : index of subband for which the data is written */ + const int16_t len /* i : number of data */ +) +{ + int16_t nbits, i; + + nbits = 0; + for ( i = 0; i < len; i++ ) + { + push_next_indice( hMetaData, qdirection->band_data[j_idx].spherical_index[i], qdirection->band_data[j_idx].bits_sph_idx[i] ); + nbits += qdirection->band_data[j_idx].bits_sph_idx[i]; + } + + return nbits; +} +#endif + +/*-------------------------------------------------------------------* + * joint_encoding() + * + * joint encoding of elevation and azimuth + *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void joint_encoding_fx( + IVAS_QDIRECTION *q_direction, /* i/o: quantized directional parameters */ + const Word16 j, /* i : subband index */ + const Word16 next_j, /* i : next subband index */ + const Word16 coding_subbands, /* i : total number of subband */ + Word16 *bits_dir0, /* i/o: number of bits for each tile in each subband */ + const Word16 allowed_bits, /* i : maximum number of bits available for the current subband */ + BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ + Word16 *diff /* o : bits to be given/taken to next subband */ +) +{ + Word16 k; + Word16 GR_ord_azimuth, use_context, GR_ord_elevation; + UWord8 method; + Word16 nbits; + Word16 same; + UWord16 data[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 len_data = 0; + move16(); + Word16 no_symb_ele[MAX_PARAM_SPATIAL_SUBFRAMES]; + + FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) + { + q_direction->band_data[j].bits_sph_idx[k] = bits_dir0[k]; + move16(); + +/* requantize the direction */ +#if 1 + q_direction->band_data[j].spherical_index[k] = quantize_direction_fx( q_direction->band_data[j].elevation_fx[k], q_direction->band_data[j].azimuth_fx[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation_fx[k], + &q_direction->band_data[j].azimuth_fx[k], &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); +#else + q_direction->band_data[j].spherical_index[k] = quantize_direction( q_direction->band_data[j].elevation[k], q_direction->band_data[j].azimuth[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation[k], + &q_direction->band_data[j].azimuth[k], &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); +#endif + move16(); + IF( GE_32( bits_dir0[k], 3 ) ) + { + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; + move16(); + q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][q_direction->band_data[j].elevation_index[k]]; + move16(); + } + ELSE + { + q_direction->band_data[j].elevation_m_alphabet[k] = sub( shl( no_theta_masa[bits_dir0[k] - 3], 1 ), 1 ); + move16(); + q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][( q_direction->band_data[j].elevation_index[k] + 1 ) >> 1]; + move16(); + } + assert( q_direction->band_data[j].elevation_index[k] != MASA_NO_INDEX ); + } + ELSE IF( bits_dir0[k] > 0 ) + { + q_direction->band_data[j].elevation_m_alphabet[k] = 1; + move16(); + q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][0]; + move16(); + } + ELSE + { + q_direction->band_data[j].elevation_m_alphabet[k] = 1; + move16(); + q_direction->band_data[j].azimuth_m_alphabet[k] = 1; + move16(); + } + } + + FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) + { + IF( LE_32( q_direction->band_data[j].bits_sph_idx[k], 2 ) ) + { + q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX; + move16(); + } + ELSE + { + no_symb_ele[len_data] = q_direction->band_data[j].elevation_m_alphabet[k]; + move16(); + data[len_data++] = q_direction->band_data[j].elevation_index[k]; + move16(); + } + } + + + /* encode indexes for current subband and count the number of bits */ + + IF( EQ_16( q_direction->cfg.nblocks, 1 ) && LE_32( q_direction->band_data[j].bits_sph_idx[0], MASA_MIN_BITS_TF + 1 ) ) + { + /* encode with fixed rate only if only one subframe and very low number of bits */ + nbits = write_fixed_rate_direction_fx( hMetaData, q_direction, j, q_direction->cfg.nblocks ); + } + ELSE + { + + IF( len_data > 0 ) + { + nbits = GR_bits_new( data, no_symb_ele, len_data, MASA_GR_ORD_EL, 1, &GR_ord_elevation ); + } + ELSE + { + nbits = 0; + move16(); + GR_ord_elevation = MASA_GR_ORD_EL; + move16(); + } + + same = 1; + move16(); + FOR( k = 1; k < q_direction->cfg.nblocks; k++ ) + { + IF( NE_32( q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].elevation_index[0] ) ) + { + same = 0; + move16(); } } - } - - *extra_bits = -diff; - - return IVAS_ERR_OK; -} + IF( EQ_16( same, 1 ) && LT_32( q_direction->band_data[j].elevation_index[0], 4 ) ) + { + nbits = 3; + move16(); + } + ELSE + { + same = 0; + move16(); + nbits = add( nbits, 1 ); + } + nbits = add( nbits, GR_bits_azimuth_context( q_direction->band_data[j].azimuth_index, + q_direction->band_data[j].azimuth_m_alphabet, q_direction->cfg.nblocks, MASA_GR_ORD_AZ, + q_direction->band_data[j].bits_sph_idx, &GR_ord_azimuth, &use_context ) ); -/*-------------------------------------------------------------------* - * write_fixed_rate_direction() - * - * writing of the spherical indexes - *-------------------------------------------------------------------*/ + IF( allowed_bits == 0 ) + { + nbits = 0; + move16(); + } + ELSE + { + IF( GE_16( nbits, allowed_bits ) ) + { + nbits = add( allowed_bits, 1 ); /* fixed rate encoding */ + method = 1; + move16(); + push_next_indice( hMetaData, method, 1 ); -/*! r: number of bits written */ -static int16_t write_fixed_rate_direction( - BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */ - IVAS_QDIRECTION *qdirection, /* i/o: quantized directional parameters */ - const int16_t j_idx, /* i : index of subband for which the data is written */ - const int16_t len /* i : number of data */ -) -{ - int16_t nbits, i; + /* write current subband data */ + nbits = add( 1, write_fixed_rate_direction_fx( hMetaData, q_direction, j, q_direction->cfg.nblocks ) ); + } + ELSE + { + nbits = add( nbits, 1 ); /* EC coding */ + method = 0; + move16(); + push_next_indice( hMetaData, method, 1 ); - nbits = 0; - for ( i = 0; i < len; i++ ) - { - push_next_indice( hMetaData, qdirection->band_data[j_idx].spherical_index[i], qdirection->band_data[j_idx].bits_sph_idx[i] ); - nbits += qdirection->band_data[j_idx].bits_sph_idx[i]; + /* write current subband data */ + write_ec_direction_fx( &nbits, hMetaData, q_direction, j, q_direction->cfg.nblocks, GR_ord_elevation, GR_ord_azimuth, use_context, same ); + nbits = add( nbits, 1 ); + } + } } + *diff = add( *diff, sub( nbits, allowed_bits ) ); + update_bits_next_block( q_direction, diff, next_j, coding_subbands, q_direction->cfg.nblocks ); - return nbits; + return; } - - -/*-------------------------------------------------------------------* - * joint_encoding() - * - * joint encoding of elevation and azimuth - *-------------------------------------------------------------------*/ - +#else static void joint_encoding( IVAS_QDIRECTION *q_direction, /* i/o: quantized directional parameters */ const int16_t j, /* i : subband index */ @@ -6630,14 +7793,141 @@ static void joint_encoding( return; } - +#endif /*-------------------------------------------------------------------* * calculate_two_distances() * * calculate estimated distortions if encoding with VQ or not *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void calculate_two_distances_fx( + Word32 *el_fx, /* i : elevation values Q22 */ + Word16 *bits, /* i : number of bits for each tile */ + const Word16 total_bits, /* i : total number of bits for subband */ + const Word16 len, /* i : number of tiles */ + Word32 *p_d1, /* o : first distortion Q_out */ + Word32 *p_d2, /* o : second distortion Q_out */ + Word16 *Q_out ) +{ + Word16 i; + Word32 d1_fx, d2_fx, el_av_fx; + const Word32 cos_delta_phi_cb_fx[] = { // Q31 + 1821066112, + 1930158336, + 1991146880, + 2053638656, + 2092508032, + 2107969920, + 2121069568, + 2131377536 + }; + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + Word32 var_el_fx; + d1_fx = 0; + move32(); + d2_fx = 0; + move32(); + Word16 temp, temp1; + Word32 L_temp, L_temp1, L_temp2, L_temp3; + Word16 gb = find_guarded_bits_fx( len ); + el_av_fx = L_shl( mean_no_sat_Word32_fx( el_fx, len, gb ), gb ); // Q22-gb + IF( GT_16( total_bits, 9 ) ) + { + FOR( i = 0; i < len; i++ ) + { + IF( GT_16( bits[i], 2 ) ) + { + IF( LT_32( L_abs( el_fx[i] ), L_abs( ( L_sub( L_abs( el_fx[i] ), 188743680 ) ) ) ) ) // 188743680 = 45 in Q22 + { + /* el_hat = 0*/ + IF( EQ_16( bits[i], 3 ) ) + { + // d1 += 1 - 0.7f * cosf( el[i] * PI_OVER_180 ); + temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15 + d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1503238554, temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31 + // Q30-gb + } + ELSE + { + // d1 += 1 - 0.92f * cosf( el[i] * PI_OVER_180 ); + temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15 + d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1975684956, temp ), 1 ) ), gb ) ); // 1975684956 = 0.92 in Q31 + // Q30-gb + } + } + ELSE + { + IF( EQ_16( bits[i], 3 ) ) + { + // d1 += 1 - sinf( el[i] * PI_OVER_180 ) * 0.7f * sign( el[i] ); + temp = getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15 + d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( imult3216( 1503238554, sign_fx( el_fx[i] ) ), temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31 + // Q30-gb + } + ELSE + { + // d1 += 1 - 0.7f * 0.92f * cosf( el[i] * PI_OVER_180 ) - sinf( fabsf( el[i] * PI_OVER_180 ) ) * 0.7f; + temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15 + temp1 = getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( L_abs( el_fx[i] ), 91 ), 7 ) ) ); // Q15 + d1_fx = L_add( d1_fx, L_shr( L_sub( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1422493168, temp ), 1 ) ), L_shr( Mpy_32_16_1( 1503238554, temp1 ), 1 ) ), gb ) ); // 1422493168 = 0.92* 0.7 in Q31 ;1503238554 = 0.7 in Q31 + // Q30-gb + } + } + } + ELSE + { + IF( EQ_16( bits[i], 2 ) ) + { + // d1 += 1 - cosf( el[i] * PI_OVER_180 ) * 0.7f; + temp = getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ); // Q15 + d1_fx = L_add( d1_fx, L_shr( L_sub( ONE_IN_Q30, L_shr( Mpy_32_16_1( 1503238554, temp ), 1 ) ), gb ) ); // 1503238554 = 0.7 in Q31 + // Q31-gb + } + ELSE + { + // d1 += 1; + d1_fx = L_add( d1_fx, L_shr( ONE_IN_Q30, gb ) ); + } + } + // d2 += 1 - sinf( el_av * PI_OVER_180 ) * sinf( el[i] * PI_OVER_180 ) - cosf( el[i] * PI_OVER_180 ) * cosf( el_av * PI_OVER_180 ) * cos_delta_phi_cb[total_bits - 9]; + L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ) ); //*91/7 to convert angle in Q22 to radians + // Q15 + L_temp1 = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_fx[i], 91 ), 7 ) ) ) ); + L_temp2 = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_16_1( el_av_fx, 91 ), 7 ) ) ) ); + L_temp3 = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( el_av_fx, 91 ), 7 ) ) ) ); + // temp1f = sinf( el_av * PI_OVER_180 ) * sinf( el[i] * PI_OVER_180 ); + // L_temp4 = Mpy_32_32( L_temp2, L_temp1 ); + d2_fx = L_add( d2_fx, L_shr( L_sub( L_sub( ONE_IN_Q30, L_shr( Mpy_32_32( L_temp2, L_temp1 ), 1 ) ), L_shr( Mpy_32_32( Mpy_32_32( L_temp, L_temp3 ), cos_delta_phi_cb_fx[total_bits - 9] ), 1 ) ), gb ) ); // Q30-gb + } + } + Word16 Qin = Q22; + move16(); + // var_el = var( el, len ); + var_el_fx = var_fx_32in_32out( el_fx, &Qin, len, gb ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( var_el_fx, sub( 31, Qin ), 1300, 31 ); + if ( EQ_16( flag, 1 ) ) + { + // d2 = d1 + 0.1f; + d2_fx = L_add( d1_fx, L_shr( 214748365, sub( Q31, sub( Q30, gb ) ) ) ); // 214748365 = 0.1f in Q31 + } + *p_d1 = d1_fx; + move32(); + *p_d2 = d2_fx; + move32(); + *Q_out = sub( Q30, gb ); + move16(); + return; +} +#else static void calculate_two_distances( float *el, /* i : elevation values */ int16_t *bits, /* i : number of bits for each tile */ @@ -6712,14 +8002,178 @@ static void calculate_two_distances( return; } - +#endif /*-------------------------------------------------------------------* * write_ec_direction() * * write metadata using entropy encoding *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: number of bits written */ +static ivas_error write_ec_direction_fx( + Word16 *num_bits_written, /* o : Number of bits written */ + BSTR_ENC_HANDLE hMetaData, /* i : MASA metadata structure */ + IVAS_QDIRECTION *qdirection, /* i : quantized directional info */ + const Word16 j_idx, /* i : index of subband to encode and write */ + const Word16 len, /* i : number of tiles */ + const Word16 GR_ord_elevation, /* i : GR order for elevation encoding */ + const Word16 GR_ord_azimuth, /* i : GR order for azimuth encoding */ + const Word16 use_context, /* i : flag for context usiage in azimuth encoding */ + const Word16 same /* i : flag if elevation indexes are the same or not */ +) +{ + Word16 i, nbits, bits_crt, nr_NO_INDEX; + UWord16 data; + Word16 min_val, max_val; + + nr_NO_INDEX = 0; + move16(); + nbits = 0; + move16(); + /* write elevation */ + FOR( i = 0; i < len; i++ ) + { + data = qdirection->band_data[j_idx].elevation_index[i]; + test(); + if ( EQ_32( data, MASA_NO_INDEX ) || ( qdirection->band_data[j_idx].bits_sph_idx[i] == 0 ) ) + { + nr_NO_INDEX = add( nr_NO_INDEX, 1 ); + } + } + + IF( LT_16( nr_NO_INDEX, len ) ) + { + IF( EQ_16( same, 1 ) ) + { + push_next_indice( hMetaData, 1, 1 ); + nbits = add( nbits, 1 ); + push_next_indice( hMetaData, qdirection->band_data[j_idx].elevation_index[0], 2 ); + nbits = add( nbits, 2 ); + } + ELSE + { + push_next_indice( hMetaData, 0, 1 ); + nbits = add( nbits, 1 ); + + push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_elevation, MASA_GR_ORD_EL ) ), 1 ); + nbits = add( nbits, 1 ); + + FOR( i = 0; i < len; i++ ) + { + data = qdirection->band_data[j_idx].elevation_index[i]; + IF( LT_32( data, MASA_NO_INDEX ) ) + { + bits_crt = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].elevation_m_alphabet[i], GR_ord_elevation ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + } + } + } + } + + /* write azimuth */ + IF( use_context < 0 ) + { + IF( EQ_16( use_context, -1 ) ) + { + /* regular GR coding */ + push_next_indice( hMetaData, 0, 1 ); + nbits = add( nbits, 1 ); + push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_azimuth, MASA_GR_ORD_AZ ) ), 1 ); + nbits = add( nbits, 1 ); + + FOR( i = 0; i < len; i++ ) + { + data = qdirection->band_data[j_idx].azimuth_index[i]; + IF( LT_32( data, MASA_NO_INDEX ) ) + { + bits_crt = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + } + } + } + ELSE IF( EQ_16( use_context, -2 ) ) + { + /* min removed GR coding */ + push_next_indice( hMetaData, 1, 1 ); + nbits = add( nbits, 1 ); + push_next_indice( hMetaData, sub( 1, (Word16) EQ_16( GR_ord_azimuth, sub( MASA_GR_ORD_AZ, 1 ) ) ), 1 ); + nbits = add( nbits, 1 ); + + /* find min */ + min_val = MASA_NO_INDEX; + move16(); + FOR( i = 0; i < len; i++ ) + { + if ( LT_32( qdirection->band_data[j_idx].azimuth_index[i], min_val ) ) + { + min_val = qdirection->band_data[j_idx].azimuth_index[i]; + move16(); + } + } + + + /* write min*/ + bits_crt = hMetaData->nb_bits_tot; + move16(); + maximum_s( qdirection->band_data[j_idx].azimuth_m_alphabet, len, &max_val ); + ivas_qmetadata_encode_extended_gr( hMetaData, min_val, max_val, MASA_GR_ORD_AZ ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + + FOR( i = 0; i < len; i++ ) + { + data = (UWord16) L_sub( qdirection->band_data[j_idx].azimuth_index[i], min_val ); + IF( LT_32( data, sub( MASA_NO_INDEX, min_val ) ) ) + { + bits_crt = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + } + } + } + } + ELSE + { + FOR( i = 0; i < len; i++ ) + { + data = qdirection->band_data[j_idx].azimuth_index[i]; + IF( LT_32( data, MASA_NO_INDEX ) ) + { + SWITCH( qdirection->band_data[j_idx].bits_sph_idx[i] ) + { + case 0: + BREAK; + case 1: + nbits = add( nbits, 1 ); + push_next_indice( hMetaData, data, 1 ); + BREAK; + case 2: + bits_crt = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ - 1 ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + BREAK; + default: + bits_crt = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); + BREAK; + } + } + } + } + *num_bits_written = nbits; + move16(); + return IVAS_ERR_OK; +} +#else /*! r: number of bits written */ static ivas_error write_ec_direction( int16_t *num_bits_written, /* o : Number of bits written */ @@ -6873,7 +8327,7 @@ static ivas_error write_ec_direction( *num_bits_written = nbits; return IVAS_ERR_OK; } - +#endif /*-----------------------------------------------------------------------* * Local functions (coherence Q and coding) diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 8ea5eb8dca2329ab5f444a860137d7a77c924e5b..3e9f1e2ed9399a21132d3ce59cb68f6f7ca1192e 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -851,6 +851,13 @@ static ivas_error ivas_spar_cov_md_process( float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float diffuseness[IVAS_MAX_NUM_BANDS]; float Wscale_d[IVAS_MAX_NUM_BANDS]; +#ifdef IVAS_FLOAT_FIXED + Word16 order; + Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS]; + Word32 Wscale_d_fx[IVAS_MAX_NUM_BANDS]; +#endif int16_t d_start_band, d_end_band; int16_t dirac_band_idx; @@ -885,7 +892,87 @@ static ivas_error ivas_spar_cov_md_process( Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); } +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( b = d_start_band; b < d_end_band; b++ ) + { + for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ ) + { + azi_dirac_fx[b][i_ts] = float_to_fix( azi_dirac[b][i_ts], Q22 ); + ele_dirac_fx[b][i_ts] = float_to_fix( ele_dirac[b][i_ts], Q22 ); + } + diffuseness_fx[b] = float_to_fix( diffuseness[b], Q30 ); + Wscale_d_fx[b] = float_to_fix( Wscale_d[b], Q29 ); + } + for ( b = 0; b < IVAS_MAX_NUM_BANDS; b++ ) + { + for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ ) + { + hSpar->hMdEnc->spar_md.band_coeffs[b].P_re_fx[i] = float_to_fix( hSpar->hMdEnc->spar_md.band_coeffs[b].P_re[i], Q22 ); + hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re_fx[i] = float_to_fix( hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re[i], Q22 ); + } + hSpar->hMdEnc->spar_md.band_coeffs[b].q_P_re_fx = Q22; + hSpar->hMdEnc->spar_md.band_coeffs[b].q_pred_re_fx = Q22; + } + Word16 num_ch = ivas_sba_get_nchan_metadata_fx( sba_order, hEncoderConfig->ivas_total_brate ); + Word16 q_mixer_mat = 26; + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + q_mixer_mat = min( q_mixer_mat, Q_factor_arrL( hSpar->hMdEnc->mixer_mat[i][j], IVAS_MAX_NUM_BANDS ) ); + } + } + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + floatToFixed_arr32( hSpar->hMdEnc->mixer_mat[i][j], hSpar->hMdEnc->mixer_mat_fx[i][j], q_mixer_mat, IVAS_MAX_NUM_BANDS ); + } + } + hSpar->hMdEnc->q_mixer_mat_fx = q_mixer_mat; +#endif + IF( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) + { + order = sba_order; + move16(); + } + ELSE + { + order = 1; + move16(); + } + ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, 1, hSpar->hMdEnc->mixer_mat_fx, &hSpar->hMdEnc->q_mixer_mat_fx, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, order, dtx_vad, Wscale_d_fx, hQMetaData->useLowerRes, active_w_vlbr, *dyn_active_w_flag ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( b = 0; b < IVAS_MAX_NUM_BANDS; b++ ) + { + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + hSpar->hMdEnc->mixer_mat[i][j][b] = fixedToFloat_32( hSpar->hMdEnc->mixer_mat_fx[i][j][b], hSpar->hMdEnc->q_mixer_mat_fx ); + } + } + } + for ( b = 0; b < IVAS_MAX_NUM_BANDS; b++ ) + { + for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ ) + { + hSpar->hMdEnc->spar_md.band_coeffs[b].P_re[i] = fixedToFloat_32( hSpar->hMdEnc->spar_md.band_coeffs[b].P_re_fx[i], Q22 ); + hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re[i] = fixedToFloat_32( hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re_fx[i], Q22 ); + } + for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) + { + for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) + { + hSpar->hMdEnc->spar_md.band_coeffs[b].C_re[i][j] = fixedToFloat_32( hSpar->hMdEnc->spar_md.band_coeffs[b].C_re_fx[i][j], Q22 ); + } + } + } +#endif +#else ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, hQMetaData->useLowerRes, active_w_vlbr, *dyn_active_w_flag ); +#endif } if ( hSpar->hMdEnc->spar_hoa_md_flag ) @@ -1299,7 +1386,37 @@ static ivas_error ivas_spar_enc_process( if ( hSpar->hPCA != NULL ) { +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) + { + p_pcm_tmp_fx[i] = &pcm_tmp_fx[i][0]; + q_pcm_fx[i] = Q11; + FOR( j = 0; j < input_frame; j++ ) + { + p_pcm_tmp_fx[i][j] = float_to_fix( p_pcm_tmp[i][j], q_pcm_fx[i] ); + } + } + + ivas_pca_enc_fx( hEncoderConfig, hSpar->hPCA, hMetaData, p_pcm_tmp_fx, input_frame, FOA_CHANNELS ); + FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) + { + p_pcm_tmp_fx[i] = &pcm_tmp_fx[i][0]; + q_pcm_fx[i] = Q11; + FOR( j = 0; j < input_frame; j++ ) + { + p_pcm_tmp[i][j] = fix_to_float( p_pcm_tmp_fx[i][j], q_pcm_fx[i] ); + } + } + fixedToFloat_arr( hSpar->hPCA->prev_qr_fx, hSpar->hPCA->prev_qr, Q15, IVAS_PCA_INTERP ); + fixedToFloat_arr( hSpar->hPCA->prev_ql_fx, hSpar->hPCA->prev_ql, Q15, IVAS_PCA_INTERP ); + fixedToFloat_arr( hSpar->hPCA->prev_eigVec_fx, hSpar->hPCA->prev_eigVec, Q15, FOA_CHANNELS * FOA_CHANNELS ); + FOR( Word16 k = 0; k < 16; k++ ) + { + hSpar->hPCA->old_r_sm[k] = fixedToFloat( hSpar->hPCA->old_r_sm_fx[k], hSpar->hPCA->old_r_sm_q ); + } +#else ivas_pca_enc( hEncoderConfig, hSpar->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS ); +#endif } else { diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 6d1d81ecbe55a4c6f973d5aad11e37f22c4b2475..53177f642789a497cd10eba479ad06e8869e77d0 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include +#include #include "options.h" #include "prot.h" #ifdef IVAS_FLOAT_FIXED @@ -45,6 +46,9 @@ #endif #include #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#endif /*------------------------------------------------------------------------------------------* * PreProcessor @@ -184,6 +188,28 @@ ivas_error ivas_spar_md_enc_open( } } } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + memset( hMdEnc->spar_md.band_coeffs, 0, IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ); + IF( ( hMdEnc->mixer_mat_fx = (Word32 ***) malloc( num_channels * sizeof( Word32 ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + FOR( i = 0; i < num_channels; i++ ) + { + IF( ( hMdEnc->mixer_mat_fx[i] = (Word32 **) malloc( num_channels * sizeof( Word32 * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + FOR( j = 0; j < num_channels; j++ ) + { + IF( ( hMdEnc->mixer_mat_fx[i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + hMdEnc->q_mixer_mat_fx = 0; +#endif if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) { @@ -462,6 +488,7 @@ ivas_error ivas_spar_md_enc_init_fx( } } } + hMdEnc->q_mixer_mat_fx = 0; #if 0 // Some issue ivas_clear_band_coeffs_fx(hMdEnc->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS); #endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 2cabcf9fd0d313f2855a5ee9ddb8471e7bc1810b..4f3b805cf7e72db6ee0a7152204327f0db21c7a1 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1029,6 +1029,7 @@ typedef struct ivas_spar_md_enc_state_t Word16 spar_hoa_dirac2spar_md_flag; Word16 HOA_md_ind[IVAS_SPAR_MAX_CH]; Word32 ***mixer_mat_fx; + Word16 q_mixer_mat_fx; Word32 ***mixer_mat_local_fx; } ivas_spar_md_enc_state_t; @@ -1043,6 +1044,16 @@ typedef struct float mem_eigVec_interp[FOA_CHANNELS * FOA_CHANNELS]; float old_r_sm[FOA_CHANNELS * FOA_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED + Word16 prev_eigVec_fx[FOA_CHANNELS * FOA_CHANNELS]; // Q15 + Word16 prev_ql_fx[IVAS_PCA_INTERP]; // Q15 + Word16 prev_qr_fx[IVAS_PCA_INTERP]; // Q15 + Word16 prev_D_fx[IVAS_PCA_INTERP]; // Q15 + Word16 mem_eigVec_interp_fx[FOA_CHANNELS * FOA_CHANNELS]; // Q15 + Word32 old_r_sm_fx[FOA_CHANNELS * FOA_CHANNELS]; // old_r_sm_q + Word16 old_r_sm_q; +#endif + } PCA_ENC_STATE; /* SPAR main structure */ @@ -1210,6 +1221,14 @@ typedef struct ivas_omasa_encoder_one_data_struct typedef struct ivas_masa_dir_align_struct { +#ifdef IVAS_FLOAT_FIXED + Word32 previous_azi_dir1_fx[MASA_FREQUENCY_BANDS]; /*q22*/ + Word32 previous_ele_dir1_fx[MASA_FREQUENCY_BANDS]; /*q22*/ + + Word32 previous_azi_dir2_fx[MASA_FREQUENCY_BANDS]; /*q22*/ + Word32 previous_ele_dir2_fx[MASA_FREQUENCY_BANDS]; /*q22*/ +#endif // IVAS_FLOAT_FIXED + float previous_azi_dir1[MASA_FREQUENCY_BANDS]; float previous_ele_dir1[MASA_FREQUENCY_BANDS];