diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 70f7a56480d844bbd2d564ceaff38344f121c4c4..a9fab43cf0e1a4d484e64a23a0e2bc12477a9923 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1239,6 +1239,10 @@ enum #define MASA_MAXIMUM_TWO_DIR_BANDS 24 #define NBITS_HR_COH 4 +#define MASA_INV_ANGLE_AT_EQUATOR_DEG_Q30 (1453366656l) +#define MASA_ANGLE_AT_EQUATOR_DEG_Q31 (1586552905l) + + #define MASA_JBM_RINGBUFFER_FRAMES 3 typedef enum diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com.c index c0ace55715d870f69fadf2a56db874f07c5a5f32..b3622bd0ac8669ae19ea8f67fd92fa0fbd7e665a 100644 --- a/lib_com/ivas_masa_com.c +++ b/lib_com/ivas_masa_com.c @@ -58,8 +58,14 @@ *---------------------------------------------------------------*/ static int16_t quantize_theta_masa( float x, const int16_t no_cb, float *xhat ); +#ifdef IVAS_FLOAT_FIXED +static Word16 quantize_theta_masa_fx( const Word32 x_fx, const Word16 no_cb, Word32 *xhat_fx ); +#endif static int16_t quantize_phi_masa( float phi, const int16_t flag_delta, float *phi_hat, const int16_t n ); +#ifdef IVAS_FLOAT_FIXED +static int16_t quantize_phi_masa_fx( const Word32 phi, const Word16 flag_delta, Word32 *phi_hat, const Word16 n ); +#endif /*--------------------------------------------------------------- @@ -993,86 +999,91 @@ UWord16 index_theta_phi_16_fx( const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */ ) { - float abs_theta; - int16_t sign_th, id_phi, id_th; - uint16_t idx_sph; - uint16_t cum_n; - float theta_hat, phi_hat; - float theta, phi; - - float *p_theta_flt, *p_phi_flt; - float p_theta_flt_tmp = fix_to_float(*p_theta, Q22); - float p_phi_flt_tmp = fix_to_float(*p_phi, Q22); - p_theta_flt = &p_theta_flt_tmp; - p_phi_flt = &p_phi_flt_tmp; - - theta = *p_theta_flt; - phi = *p_phi_flt; - phi_hat = 0; - theta_hat = 0; - phi = phi + 180; + Word32 abs_theta_fx; + Word16 sign_th, id_phi, id_th; + UWord16 idx_sph; + UWord16 cum_n; + Word32 theta_hat_fx, phi_hat_fx; + Word32 theta_fx, phi_fx; + + theta_fx = *p_theta; + phi_fx = *p_phi; + phi_hat_fx = 0; + move32(); + theta_hat_fx = 0; + move32(); + phi_fx = phi_fx + ( 180 << Q22 ); - if ( theta < 0 ) + IF( LT_32( theta_fx, 0 ) ) { - abs_theta = -theta; + abs_theta_fx = L_negate( theta_fx ); sign_th = -1; + move16(); } - else + ELSE { - abs_theta = theta; + abs_theta_fx = theta_fx; sign_th = 1; + move16(); } - id_th = quantize_theta_masa( abs_theta, gridData->no_theta, &theta_hat ); - if ( gridData->no_theta > 1 ) + id_th = quantize_theta_masa_fx( abs_theta_fx, gridData->no_theta, &theta_hat_fx ); + IF( GT_16( gridData->no_theta, 1 ) ) { - if ( gridData->no_phi[id_th] > 1 ) + IF( GT_16( gridData->no_phi[id_th], 1 ) ) { - id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] ); + id_phi = quantize_phi_masa_fx( phi_fx, ( id_th % 2 == 1 ), &phi_hat_fx, gridData->no_phi[id_th] ); } - else + ELSE { id_phi = 0; - phi_hat = 180; + move16(); + phi_hat_fx = L_shl( 180, Q22 ); } } - else + ELSE { - id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] ); + id_phi = quantize_phi_masa_fx( phi_fx, ( id_th % 2 == 1 ), &phi_hat_fx, gridData->no_phi[id_th] ); + } + + *p_theta = theta_hat_fx; + move32(); + IF( EQ_16( sign_th, -1 ) ) + { + *p_theta = L_negate( theta_hat_fx ); } - *p_theta_flt = sign_th * theta_hat; - *p_phi_flt = phi_hat - 180; + *p_phi = L_sub( phi_hat_fx, L_shl( 180, Q22 ) ); /* Starting from Equator, alternating positive and negative */ - if ( id_th == 0 ) + IF( EQ_16( id_th, 0 ) ) { idx_sph = id_phi; + move16(); } - else + ELSE { - if ( id_th == gridData->no_theta - 1 ) - { - idx_sph = 65534 + ( sign_th < 0 ); - } - else + IF( EQ_16( id_th, sub( gridData->no_theta, 1 ) ) ) { - theta = MASA_ANGLE_AT_EQUATOR * (float) ( id_th + 0.5f ); - if ( id_th == 1 ) - { - cum_n = 2 * (uint16_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) ); - } - else + idx_sph = 65534; + move16(); + IF( LT_16( sign_th, 0 ) ) { - cum_n = 2 * (uint16_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) ); + idx_sph = 65535; + move16(); } + } + ELSE + { + cum_n = cum_n_for_id_th[id_th]; + move16(); cum_n += gridData->no_phi[0]; - if ( sign_th > 0 ) + IF( GT_16( sign_th, 0 ) ) { - cum_n -= 2 * gridData->no_phi[id_th]; + cum_n -= shl( gridData->no_phi[id_th], 1 ); } - else + ELSE { cum_n -= gridData->no_phi[id_th]; } @@ -1080,9 +1091,6 @@ UWord16 index_theta_phi_16_fx( } } - *p_theta = float_to_fix(*p_theta_flt, Q22); - *p_phi = float_to_fix(*p_phi_flt, Q22); - return idx_sph; } #endif @@ -1128,6 +1136,48 @@ static int16_t quantize_theta_masa( return imin; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * quantize_theta_masa_fx() + * + * + *------------------------------------------------------------------------*/ + +/*! r: output index */ +static Word16 quantize_theta_masa_fx( + const Word32 x_fx, /* i : theta value to be quantized */ + const Word16 no_cb, /* i : number of codewords */ + Word32 *xhat_fx /* o : quantized value */ +) +{ + Word16 imin; + Word32 diff1_fx, diff2_fx; + + imin = extract_l( L_shr( L_add( Mpy_32_32( x_fx, MASA_INV_ANGLE_AT_EQUATOR_DEG_Q30 ), ONE_IN_Q20 ), 21 ) ); // 22 + 30 - 31 = 21 -> Q21 - 21 = Q0 + + IF( GE_16( imin, sub( no_cb, 1 ) ) ) + { + imin = sub( no_cb, 1 ); + diff1_fx = L_sub( x_fx, L_shl( 90, Q22 ) ); + diff2_fx = L_sub( x_fx, Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( sub( imin, 1 ), 6 ) ) ); // q31 + q0+6 - 15 = q22 + IF( GT_32( L_abs( diff1_fx ), L_abs( diff2_fx ) ) ) + { + imin = sub( imin, 1 ); + *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22 + } + ELSE + { + *xhat_fx = L_shl( 90, Q22 ); + } + } + ELSE + { + *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22 + } + + return imin; +} +#endif /*------------------------------------------------------------------------- * quantize_phi_masa() @@ -1138,9 +1188,9 @@ static int16_t quantize_theta_masa( /*! r: index azimuth */ static int16_t quantize_phi_masa( float phi, /* i : azimuth value */ - const int16_t flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ + const Word16 flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ float *phi_hat, /* o : quantized azimuth */ - const int16_t n /* i : azimuth codebook size */ + const Word16 n /* i : azimuth codebook size */ ) { int16_t id_phi; @@ -1182,6 +1232,70 @@ static int16_t quantize_phi_masa( return id_phi; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * quantize_phi_masa_fx() + * + * + *------------------------------------------------------------------------*/ + +/*! r: index azimuth */ +static Word16 quantize_phi_masa_fx( + const Word32 phi_fx, /* i : azimuth value */ + const Word16 flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ + Word32 *phi_hat_fx, /* o : quantized azimuth */ + const Word16 n /* i : azimuth codebook size */ +) +{ + Word16 id_phi; + + Word32 dd_fx; + Word32 delta_phi_fx; + Word32 tmp32; + Word16 tmp_e, delta_phi_e; + + delta_phi_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( 360, n, &delta_phi_e ) ); + delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); + + IF( EQ_16( n, 1 ) ) + { + *phi_hat_fx = 0; + move32(); + + return 0; + } + + IF( EQ_16( flag_delta, 1 ) ) + { + dd_fx = L_shr( delta_phi_fx, 1 ); + } + ELSE + { + dd_fx = 0; + move32(); + } + + tmp32 = L_add( L_sub( phi_fx, dd_fx ), L_shr( delta_phi_fx, 1 ) ); + id_phi = BASOP_Util_Divide3232_Scale( tmp32, delta_phi_fx, &tmp_e ); + id_phi = shr( id_phi, ( 15 - tmp_e ) ); + + IF( EQ_16( id_phi, n ) ) + { + id_phi = 0; + move16(); + } + + IF( EQ_16( id_phi, -1 ) ) + { + id_phi = sub( n, 1 ); + } + + *phi_hat_fx = L_add( L_shl( Mpy_32_16_1( delta_phi_fx, id_phi ), 15 ), dd_fx ); // q22 + q0 - 15 = q7 -> q7 + 15 = q22 + + return id_phi; +} + +#endif /*------------------------------------------------------------------------- * deindex_sph_idx() diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index 6a5b4c853493e2f2ec1915651a63a61ea00c7c83..a90f830d2158a17a93d26b651976079ac3833d3d 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -320,6 +320,28 @@ const Word16 McMASA_LFEGain_vectors_fx_q13[64] = { -6553, -12943, 6717, 11632, -17530, 2129, 6881, 8355 }; +/* + This lookup table is calculated from, and therefore + depends on the following macros: + - MASA_NTOT2_FAC + - MASA_ASIN_OFFSET + - MASA_ANGLE_AT_EQUATOR +*/ +const UWord16 cum_n_for_id_th[122] = { + 0, 846, 1690, 2534, 3378, 4222, 5064, 5906, 6746, 7586, 8424, 9260, 10094, + 10928, 11760, 12588, 13416, 14240, 15064, 15882, 16700, 17514, 18326, 19134, + 19938, 20740, 21538, 22332, 23122, 23910, 24692, 25470, 26244, 27014, 27780, + 28540, 29296, 30046, 30792, 31532, 32268, 32998, 33722, 34440, 35152, 35860, + 36560, 37254, 37942, 38624, 39300, 39968, 40630, 41286, 41934, 42576, 43210, + 43836, 44456, 45068, 45672, 46270, 46858, 47440, 48014, 48578, 49136, 49684, + 50224, 50756, 51280, 51796, 52302, 52800, 53288, 53768, 54238, 54700, 55152, + 55596, 56030, 56454, 56870, 57274, 57670, 58058, 58434, 58800, 59158, 59504, + 59842, 60168, 60486, 60792, 61088, 61376, 61652, 61918, 62172, 62418, 62652, + 62876, 63090, 63294, 63486, 63668, 63838, 64000, 64150, 64288, 64416, 64534, + 64640, 64736, 64822, 64896, 64960, 65012, 65054, 65084, 65104, 65112 +}; + + /*----------------------------------------------------------------------------------* * Multi-channel LS setups *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index 5d5e9326779ee7ab5400e4534fb3d9aff63e4593..f10915790250eb61302a4e07194f678c441aa982 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -60,6 +60,8 @@ extern const Word16 ivas_divde_255[256]; extern const Word32 ism_azimuth_borders_fx[4]; extern const Word32 ism_elevation_borders_fx[4]; +extern const UWord16 cum_n_for_id_th[122]; + /* Multi-channel input and output setups */ extern const Word32 ls_azimuth_CICP2_fx[2]; extern const Word32 ls_elevation_CICP2_fx[2];