diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index af6c1ed7b8462d7fbd979481512251471a24b70f..e9b3c7b18a21520460255507464831eabab944e1 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -253,10 +253,12 @@ + + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 4c72cb99e0b939aba1c8e9f459fd22056472d8be..7729568e598800a33acd9375bb24dad79cbf1140 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -720,6 +720,49 @@ + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 5595309098a902fbd21c4fccb419d15526eaeaec..f21f6140a1a66dd551f88454f6952c175372b988 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -592,6 +592,8 @@ typedef enum /* Residual coding BPF */ #define STEREO_DFT_BPF_ADAPT_ALPHA (0.61f) #define STEREO_DFT_BPF_ADAPT_BETA (0.68f) +#define STEREO_DFT_BPF_ADAPT_ALPHA_FX (19988) /* STEREO_DFT_BPF_ADAPT_ALPHA in Q15 */ +#define STEREO_DFT_BPF_ADAPT_BETA_FX (22281) /* STEREO_DFT_BPF_ADAPT_BETA in Q15 */ /* Golomb-Rice encoding */ #define NO_SYMB_GR_SIDE_G 31 @@ -664,6 +666,7 @@ enum #define ECLVQ_GLOBAL_GAIN_FACTOR ( 20.0f * 127.0f / 90.0f ) #define ECLVQ_INV_GLOBAL_GAIN_FACTOR ( 1.0f / ( 20.0f * 127.0f / 90.0f ) ) +#define ECLVQ_INV_GLOBAL_GAIN_FACTOR_Q24 594468 /* the currently defined configuration indexes are: 0: un-optimized using uniform 4 bit parameters (reserved) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b9584d8750da05795edde98c514961f70ed9717c..79ad2bbc8b7646ce2960671d1e9220efa73ff7ec 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1424,11 +1424,13 @@ void stereo_dft_dec_res( ); /*! r: Decision to enable or disable BPF on DFT stereo residual */ +#ifndef IVAS_FLOAT_FIXED int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ ); +#endif // IVAS_FLOAT_FIXED void bpf_pitch_coherence( Decoder_State *st, /* i/o: decoder state structure */ @@ -1780,11 +1782,13 @@ int32_t ECSQ_encode_target_SNR( int16_t *global_gain_index_output ); +#ifndef IVAS_FLOAT_FIXED void ECSQ_decode( ECSQ_instance *ecsq_inst, const int16_t N, int16_t *output ); +#endif // IVAS_FLOAT_FIXED void ECSQ_dequantize_vector( const int16_t *input, diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index dbbf0657b7ebbd259aaeeb7908aca25ebffbd3e9..e56e131153c254c68de0413ec1da6558905f79e0 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -107,6 +107,54 @@ void ivas_td_decorr_get_ducking_gains_fx( Word32 *pOut_duck_gains, const Word16 frame_len, const Word16 tdet_flag ); -#endif + +// ivas_stereo_eclvq_dec.c +void ECSQ_decode( + ECSQ_instance *ecsq_inst, + const Word16 N, + Word16 *output ); +#endif // IVAS_FLOAT_FIXED + +// bass_psfilter.c +Word16 res_bpf_adapt_fx( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ + Word32 res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ +); + +// ivas_sns_com_fx.c +void sns_compute_scf_fx( + Word32 spectrum[], + const PsychoacousticParameters *pPsychParams, + const Word16 L_frame, + Word32 *scf ); + +void sns_interpolate_scalefactors_fx( + Word32 *scf_int, /* o : interpolated scalefactors for spectrum shaping */ + const Word32 *scf, /* i : sns scalefactors as derived from the signal or read from the bitstream */ + Word16 encoder_side /* i : flag, if scalefactors have to be inverted */ +); + +void sns_shape_spectrum_fx( + Word32 spectrum[], /* i/o: spectrum to be shaped */ + const PsychoacousticParameters *pPsychParams, /* i : psychoacoustic parameters used to get the frequency bands */ + const Word32 *scf_int, /* i : already interpolated SNS scalefactors */ + const Word16 L_frame /* i : frame length */ +); + +// ivas_stereo_eclvq_com_fx.c +Word32 ECSQ_dequantize_gain_fx( + const Word16 index ); + +void ECSQ_dequantize_vector_fx( + const Word16 *input, + const Word32 global_gain, + const Word16 N, + Word32 *output ); + +void ECSQ_init_instance_fx( + ECSQ_instance *ecsq_inst, + const Word16 config_index, + void *ac_handle ); #endif \ No newline at end of file diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com.c index 30ab85904071a0838be2ebe604e1e153cfd396d5..9ef7a7a7ef9bdee334b1a707642f3fe3c5107b2d 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com.c @@ -380,7 +380,7 @@ Word32 companding_azimuth_fx( { const Word16 pointsA[] = { 0, 60, 110, 150, 180, 0, 50, 90, 150, 180, 0, 30, 80, 150, 180 }; const Word16 pointsB[] = { 0, 90, 110, 170, 180, 0, 90, 110, 170, 180, 0, 10, 100, 170, 180 }; - const Word16 *pA, *pB; + const Word16 *pA; const Word32 pointsA_fx[] = { 0, 251658240, 461373440, 629145600, 754974720, 0, 209715200, 377487360, 629145600, 754974720, 0, 125829120, 335544320, 629145600, 754974720 }; // q=22 const Word32 pointsB_fx[] = { 0, 377487360, 461373440, 713031680, 754974720, 0, 377487360, 461373440, 713031680, 754974720, 0, 41943040, 419430400, 713031680, 754974720 }; // q=22 const Word32 *pA_fx, *pB_fx; @@ -408,14 +408,12 @@ Word32 companding_azimuth_fx( pA_fx = &pointsA_fx[start]; pB_fx = &pointsB_fx[start]; pA = &pointsA[start]; - pB = &pointsB[start]; IF( direction == -1 ) /* inverse companding */ { pA_fx = &pointsB_fx[start]; pB_fx = &pointsA_fx[start]; pA = &pointsB[start]; - pB = &pointsA[start]; } ELSE { diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index e34016da89f6b48217b49afebf116635517a7254..d39004cfd3ab17970e5da4396dbaa27f828ce8a0 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2696,13 +2696,13 @@ const Word32 no_phi_masa_inv_fx[NO_SPHERICAL_GRIDS][MAX_NO_THETA] = /* from 1 to {536870912}, {536870912, 1073741824}, {268435456, 536870912}, - {178956970, 306783378, 1073741824, 2147483648}, - {153391689, 165191049, 238609294, 1073741824, 2147483648}, - {97612893, 102261126, 126322567, 195225786, 715827882, 2147483648}, - {65075262, 67108864, 74051160, 93368854, 126322567, 238609294, 2147483648}, - {44739242, 45691141, 47721858, 52377649, 61356675, 76695844, 107374182, 178956970, 1073741824, 2147483648}, - {35791394, 35791394, 37025580, 38347922, 39768215, 42949672, 46684427, 52377649, 59652323, 71582788, 93368854, 126322567, 214748364, 2147483648}, - {24129029, 24129029, 24403223, 24970740, 25565281, 26512143, 27889398, 29417584, 31580641, 34087042, 37675151, 42107522, 48806446, 56512727, 71582788, 93368854, 143165576, 268435456, 2147483648} + {178956970, 306783378, 1073741824, 2147483647}, + {153391689, 165191049, 238609294, 1073741824, 2147483647}, + {97612893, 102261126, 126322567, 195225786, 715827882, 2147483647}, + {65075262, 67108864, 74051160, 93368854, 126322567, 238609294, 2147483647}, + {44739242, 45691141, 47721858, 52377649, 61356675, 76695844, 107374182, 178956970, 1073741824, 2147483647}, + {35791394, 35791394, 37025580, 38347922, 39768215, 42949672, 46684427, 52377649, 59652323, 71582788, 93368854, 126322567, 214748364, 2147483647}, + {24129029, 24129029, 24403223, 24970740, 25565281, 26512143, 27889398, 29417584, 31580641, 34087042, 37675151, 42107522, 48806446, 56512727, 71582788, 93368854, 143165576, 268435456, 2147483647} }; const Word32 azimuth_cb_fx[8] = diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..1440cc4ea463221bcdde3081ea73dfb1e2fe7764 --- /dev/null +++ b/lib_com/ivas_sns_com_fx.c @@ -0,0 +1,314 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "cnst.h" +#include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "ivas_prot.h" +#include "rom_com.h" +#include "ivas_rom_com.h" +#include +#include +#include "wmc_auto.h" + + +/*------------------------------------------------------------------- + * sns_compute_scf_fx() + * + * + *-------------------------------------------------------------------*/ + +void sns_compute_scf_fx( + Word32 spectrum[], + const PsychoacousticParameters *pPsychParams, + const Word16 L_frame, + Word32 *scf ) +{ + Word16 i, n, k; + Word32 x[FDNS_NPTS], xs[FDNS_NPTS], sum, mean, xl4[SNS_NPTS], nf, xl[FDNS_NPTS]; + Word32 L_tmp; + const Word16 *pow_tilt; + const UWord8 nBands = pPsychParams->nBands; + const UWord8 *bandLengths = pPsychParams->bandLengths; + Word8 bw = 0; + + const Word16 w_0 = 2730; // (1.0f / 12.0f) in Q15 + const Word16 w_1 = 5461; // (2.0f / 12.0f) in Q15 + const Word16 w_2 = 8192; // 0.25f ( 3.0f / 12.0f ) in Q15 + const Word16 w_3 = w_2; + const Word16 w_4 = w_1; + const Word16 w_5 = w_0; + + assert( nBands == FDNS_NPTS ); + + set32_fx( x, 0, FDNS_NPTS ); + + IF( bandLengths == NULL ) + { + bw = (Word8) shr( L_frame, 6 ); + /* Energy per band */ + k = 0; + FOR( i = 0; i < nBands; ++i ) + { + x[i] = 0; + FOR( n = 0; n < bw; ( ++n, ++k ) ) + { + x[i] = L_add( x[i], spectrum[k] ); + } + x[i] /= bw; + } + } + ELSE + { + /* Energy per band */ + k = 0; + FOR( i = 0; i < nBands; ++i ) + { + x[i] = 0; + FOR( n = 0; n < bandLengths[i]; ( ++n, ++k ) ) + { + x[i] = L_add( x[i], spectrum[k] ); + } + x[i] /= bandLengths[i]; + } + } + + /* Smoothing */ + xs[0] = L_add( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[1], 8192 /* 0.25 in Q15 */ ) ); + + FOR( i = 1; i < FDNS_NPTS - 1; i++ ) + { + xs[i] = L_add( L_add( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), Mpy_32_16_1( x[i - 1], 8192 /* 0.25 in Q15 */ ) ), Mpy_32_16_1( x[i + 1], 8192 /* 0.25 in Q15 */ ) ); + } + + xs[FDNS_NPTS - 1] = L_add( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ) ); + + /* Pre-emphasis */ + SWITCH( L_frame ) + { + case L_FRAME16k: + pow_tilt = pow_tilt_16k; + BREAK; + case L_FRAME25_6k: + pow_tilt = pow_tilt_25_6k; + BREAK; + case L_FRAME32k: + pow_tilt = pow_tilt_32k; + BREAK; + default: + pow_tilt = NULL; + assert( !"illegal frame length in sns_compute_scf_fx" ); + } + + FOR( i = 0; i < FDNS_NPTS; i++ ) + { + xs[i] = Mpy_32_16_1( xs[i], pow_tilt[i] ); + xs[i] = L_shl( xs[i], Q8 ); // xs => Q12 + } + + /* Noise floor at -40dB */ + sum = sum32_fx( xs, FDNS_NPTS ); + mean = L_shr( sum, 6 ); + + nf = Mpy_32_16_1( mean, 3 ); // 3 => powf( 10.0f, -4.0f ) in Q15 + nf = L_max( nf, 0 ); // 0 => powf( 2.0f, -32.0f ) in Q15 + + + FOR( i = 0; i < FDNS_NPTS; i++ ) + { + if ( LT_32( xs[i], nf ) ) + { + xs[i] = nf; + } + } + + /* Log-domain */ + FOR( i = 0; i < FDNS_NPTS; i++ ) + { + Word16 e_tmp = norm_l( xs[i] ); + Word16 f_tmp = Log2_norm_lc( L_shl( xs[i], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 12 ); + /* Note: Mpy_32_16 is used temporarily for this computation, It needs to be replaced with appropriate BASOP. */ + xl[i] = Mpy_32_16( e_tmp, f_tmp, 16384 ); /* Q16 */ + } + + /* Downsampling */ + L_tmp = L_deposit_l( 0 ); + L_tmp = Madd_32_16( L_tmp, xl[0], w_0 ); + L_tmp = Madd_32_16( L_tmp, xl[0], w_1 ); + L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); + L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); + L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); + L_tmp = Madd_32_16( L_tmp, xl[4], w_5 ); + xl4[0] = L_tmp; + + FOR( n = 1; n < SNS_NPTS - 1; n++ ) + { + int16_t n4 = 4 * n; + + L_tmp = L_deposit_l( 0 ); + L_tmp = Madd_32_16( L_tmp, xl[n4 - 1], w_0 ); + L_tmp = Madd_32_16( L_tmp, xl[n4], w_1 ); + L_tmp = Madd_32_16( L_tmp, xl[n4 + 1], w_2 ); + L_tmp = Madd_32_16( L_tmp, xl[n4 + 2], w_3 ); + L_tmp = Madd_32_16( L_tmp, xl[n4 + 3], w_4 ); + L_tmp = Madd_32_16( L_tmp, xl[n4 + 4], w_5 ); + xl4[n] = L_tmp; + } + + L_tmp = L_deposit_l( 0 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 5], w_0 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); + xl4[SNS_NPTS - 1] = L_tmp; + + /* Remove mean and scaling */ + sum = sum32_fx( xl4, SNS_NPTS ); + mean = L_shr( sum, 4 ); + + FOR( i = 0; i < SNS_NPTS; i++ ) + { + scf[i] = Mpy_32_16_1( L_sub( xl4[i], mean ), 27853 /* 0.85 in in Q15 */ ); + } + + return; +} + +/*------------------------------------------------------------------- + * sns_interpolate_scalefactors_fx() + * + * + *-------------------------------------------------------------------*/ + +void sns_interpolate_scalefactors_fx( + Word32 *scf_int, /* o : interpolated scalefactors for spectrum shaping*/ + const Word32 *scf, /* i : sns scalefactors as derived from the signal or read from the bitstream */ + Word16 encoder_side /* i : flag, if scalefactors have to be inverted */ +) +{ + Word16 n; + Word32 L_tmp; + Word16 exp; + + /* Interpolation */ + scf_int[0] = scf[0]; + scf_int[1] = scf[0]; + + FOR( n = 0; n <= M - 2; n++ ) + { + scf_int[n * 4 + 2] = L_add( scf[n], Mpy_32_16_1( L_sub( scf[n + 1], scf[n] ), 4096 ) ); /* 4096 -> 1/8 in Q15 */ + scf_int[n * 4 + 3] = L_add( scf[n], Mpy_32_16_1( L_sub( scf[n + 1], scf[n] ), 12288 ) ); /* 12288 -> 3/8 in Q15 */ + scf_int[n * 4 + 4] = L_add( scf[n], Mpy_32_16_1( L_sub( scf[n + 1], scf[n] ), 20480 ) ); /* 20480 -> 5/8 in Q15 */ + scf_int[n * 4 + 5] = L_add( scf[n], Mpy_32_16_1( L_sub( scf[n + 1], scf[n] ), 28672 ) ); /* 28672 -> 7/8 in Q15 */ + } + + scf_int[FDNS_NPTS - 2] = L_add( scf[M - 1], Mpy_32_16_1( L_sub( scf[M - 1], scf[M - 2] ), 4096 ) ); + scf_int[FDNS_NPTS - 1] = L_add( scf[M - 1], Mpy_32_16_1( L_sub( scf[M - 1], scf[M - 2] ), 12288 ) ); + + /* Inversion at encoder-side */ + IF( encoder_side == ENC ) + { + FOR( n = 0; n < FDNS_NPTS; n++ ) + { + scf_int[n] = L_negate( scf_int[n] ); + } + } + + /* Linear domain */ + FOR( n = 0; n < FDNS_NPTS; n++ ) + { + L_tmp = BASOP_util_Pow2( scf_int[n], Q15, &exp ); + exp = sub( 15, exp ); + scf_int[n] = L_shr( L_tmp, exp ); + } + + return; +} + + +/*------------------------------------------------------------------- + * sns_shape_spectrum_fx() + * + * + *-------------------------------------------------------------------*/ + +void sns_shape_spectrum_fx( + Word32 spectrum[], /* i/o: spectrum to be shaped */ + const PsychoacousticParameters *pPsychParams, /* i : psychoacoustic parameters used to get the frequency bands */ + const Word32 *scf_int, /* i : already interpolated SNS scalefactors */ + const Word16 L_frame /* i : frame length */ +) +{ + Word16 i, n, k, bw; + Word64 L64_tmp; + const UWord8 nBands = pPsychParams->nBands; + const UWord8 *bandLengths = pPsychParams->bandLengths; + + IF( bandLengths == NULL ) + { + bw = L_frame / nBands; + + /* Shape spectrum */ + k = 0; + FOR( i = 0; i < nBands; ++i ) + { + FOR( n = 0; n < bw; ( ++n, ++k ) ) + { + L64_tmp = W_mult_32_32( spectrum[k], scf_int[i] ); // Q32 + L64_tmp = W_shr( L64_tmp, 26 ); // Q6 + spectrum[k] = W_sat_l( L64_tmp ); // Q6 + } + } + } + ELSE + { + /* Shape spectrum */ + k = 0; + FOR( i = 0; i < nBands; ++i ) + { + FOR( n = 0; n < bandLengths[i]; ( ++n, ++k ) ) + { + L64_tmp = W_mult_32_32( spectrum[k], scf_int[i] ); // Q32 + L64_tmp = W_shr( L64_tmp, 26 ); // Q6 + spectrum[k] = W_sat_l( L64_tmp ); // Q6 + } + } + } + + return; +} diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9fd8146774c9459bc1736cd6984b65dc3b377e6f --- /dev/null +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -0,0 +1,109 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include +#include "ivas_prot.h" +#include "ivas_prot_fx.h" +#include "ivas_cnst.h" +#include +#include "prot.h" +#include "wmc_auto.h" + +/*--------------------------------------------------------------- + * ECSQ_init_instance_fx() + * + * initialize the encoder or decoder instance ecsq_inst, using the configuration index config_index; + * ac_handle is a pointer to a structure containing the bitstream writer and the arithmetic coding state; + * the return value is the approximate number of bits written, expressed in 22Q10 fixed-point representation + * ---------------------------------------------------------------*/ + +void ECSQ_init_instance_fx( + ECSQ_instance *ecsq_inst, + const Word16 config_index, + void *ac_handle ) +{ + ecsq_inst->config_index = config_index; + ecsq_inst->encoding_active = 1; + ecsq_inst->bit_count_estimate = 0; + ecsq_inst->ac_handle = ac_handle; + + return; +} + +/*--------------------------------------------------------------- + * ECSQ_dequantize_gain_fx() + * + * dequantize global gain index + * ---------------------------------------------------------------*/ + +Word32 ECSQ_dequantize_gain_fx( + const Word16 index ) +{ + Word32 global_gain; + Word32 L_tmp, L_prod; + Word16 gg_e, tmp_e = 16; + + /* pow(10.0, index * ECLVQ_INV_GLOBAL_GAIN_FACTOR) = pow(2.0,(index * ECLVQ_INV_GLOBAL_GAIN_FACTOR)*3.321928 */ + L_prod = Mpy_32_16_1( ECLVQ_INV_GLOBAL_GAIN_FACTOR_Q24, shl( index, 8 ) ); /* Q17 */ + L_tmp = Mpy_32_16_1( L_prod, 27213 ); /* Q17 + Q13 >> 15 => Q15 */ + + global_gain = BASOP_util_Pow2( L_tmp, tmp_e, &gg_e ); + gg_e = sub( 16, gg_e ); + + global_gain = L_shr( global_gain, gg_e ); + + return global_gain; +} + +/*--------------------------------------------------------------- + * ECSQ_dequantize_vector_fx() + * + * dequantize an integer-valued vector using optimal reconstruction points, which depend on the value of config_index + * ---------------------------------------------------------------*/ + +void ECSQ_dequantize_vector_fx( + const Word16 *input, + const Word32 global_gain, + const Word16 N, + Word32 *output ) +{ + Word16 i; + + FOR( i = 0; i < N; ++i ) + { + output[i] = Mpy_32_16_1( global_gain, input[i] ); + } + + return; +} diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 0f8805093a0d7cab5150a5fcc28e54934fb40120..916dd31ae962a0e34745ff9335021f57cdfb62a5 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -35,6 +35,7 @@ #include "options.h" #include #include "prot.h" +#include "prot_fx1.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" @@ -1420,7 +1421,7 @@ Word16 ceil_log_2( : val <= 1152921504606846976 ? 60 : val <= 2305843009213693952 ? 61 : val <= 4611686018427387904 ? 62 - : val <= 9223372036854775808 ? 63 + : val <= 9223372036854775807 ? 63 : 64; } @@ -1454,7 +1455,7 @@ Word64 var_32_fx( FOR( int i = 0; i < len; i++ ) { - var = var + Mpy_32_32( L_sub( x[i], mean ), L_sub( x[i], mean ) ); + var = var + Mpy_32_32( L_sub( x[i], (Word32) mean ), L_sub( x[i], (Word32) mean ) ); } var = var << ( 31 - q ); diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 2787dffcd4d4a92234d8340a5ec0c9f048eb1bbe..5b8e81734d85d994744266a24e6ff7e3fb9c4641 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -37883,6 +37883,46 @@ const Word32 bwMode2fs[4] = { 8000, 16000, 32000, 48000 }; const Word16 swb_lsp_prev_interp_init[10] = { 32767, 31164, 26510, 19261, 10126, 0, -10126, -19261, -26510, -31164 }; /* st->swb_lsp_prev_interp[i] = (float)cos( (float)i * PI / (float)10.0f )*/ +//ivas_sns_com_fx.c +/* + powf( 10.0f, (float) i * (float) tilt / ( (float) FDNS_NPTS - 1.0f ) / 10.0f ) where 0 =< i < FDNS_NPTS; + tilt = 19.f for L_FRAME16k, + 22.f for L_FRAME25_6k, + 23.5f for L_FRAME32k; +*/ +const Word16 pow_tilt_16k[64] = { /* Q7 */ + 128, 137, 147, 157, 168, 181, 194, 208, + 223, 239, 256, 274, 294, 315, 338, 362, + 388, 416, 446, 478, 513, 550, 589, 632, + 677, 726, 778, 834, 894, 958, 1027, 1101, + 1181, 1266, 1357, 1454, 1559, 1671, 1791, 1920, + 2058, 2206, 2365, 2535, 2717, 2913, 3122, 3347, + 3587, 3845, 4122, 4418, 4736, 5077, 5442, 5833, + 6253, 6702, 7184, 7701, 8255, 8848, 9485, 10167 +}; + +const Word16 pow_tilt_25_6k[64] = { /* Q7 */ + 128, 138, 150, 162, 176, 191, 207, 224, + 243, 263, 286, 309, 335, 364, 394, 427, + 463, 502, 544, 589, 639, 692, 750, 813, + 881, 955, 1035, 1122, 1216, 1317, 1428, 1547, + 1677, 1817, 1970, 2135, 2313, 2507, 2717, 2945, + 3191, 3459, 3748, 4062, 4402, 4771, 5170, 5603, + 6072, 6581, 7132, 7729, 8376, 9078, 9838, 10662, + 11554, 12522, 13570, 14707, 15938, 17273, 18719, 20286 +}; + +const Word16 pow_tilt_32k[64] = { /* Q7 */ + 128, 139, 151, 165, 180, 196, 214, 233, + 254, 277, 302, 329, 358, 390, 426, 464, + 505, 551, 600, 654, 713, 777, 846, 922, + 1005, 1095, 1194, 1301, 1417, 1545, 1683, 1834, + 1999, 2178, 2373, 2586, 2818, 3071, 3347, 3647, + 3974, 4330, 4719, 5142, 5603, 6106, 6654, 7250, + 7901, 8609, 9381, 10223, 11140, 12139, 13228, 14414, + 15707, 17115, 18650, 20323, 22146, 24132, 26297, 28655 +}; + const Word16 L_frame_inv[8] = { 0x4000, 0x369D, 0x3333, 0x2D83, 0x2AAB, 0x28F6, 0, 0x2222 }; const Word16 InvIntTable[65] = diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index a00dcd342f5ec0a616f10222bdbcdfb415def953..5b0a5bd4874a28747beb2b6be8434611e12d64e2 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -2021,4 +2021,8 @@ extern const Word16 Es_pred_qua[8]; extern const Word16 Es_pred_qua_2[16]; extern const Word16 T_DIV_L_Frame[];/*0Q15 * 2^-7 */ +//ivas_sns_com_fx.c +extern const Word16 pow_tilt_16k[64]; /* Q7 */ +extern const Word16 pow_tilt_25_6k[64]; /* Q7 */ +extern const Word16 pow_tilt_32k[64]; /* Q7 */ #endif diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index cafd3dbf9387394f7619609398e454cfadd05758..743a3406c3042e9164ed464e17d6485ae0481dda 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -46,6 +46,7 @@ #include #include "cnst.h" #include "prot_fx1.h" +#include "prot_fx2.h" #include "basop_util.h" #include "wmc_auto.h" diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c index d86ff070c7e8e24f3e36c0ae2a14489247453afb..77ce387225fd6efa4dfbc9d27034cb26e8a620b6 100644 --- a/lib_dec/TonalComponentDetection.c +++ b/lib_dec/TonalComponentDetection.c @@ -45,6 +45,9 @@ #include "stat_com.h" #include "wmc_auto.h" #include "ivas_prot.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*---------------------------------------------------------------------* @@ -96,7 +99,26 @@ void DetectTonalComponents_flt( } else { +#ifdef IVAS_FLOAT_FIXED + Word32 pScaledMdctSpectrum_fx[L_FRAME_MAX], scaleFactors_fx[FDNS_NPTS]; + FOR( Word16 c = 0; c < nSamplesCore; c++ ) + { + pScaledMdctSpectrum_fx[c] = (Word32) ( pScaledMdctSpectrum[c] * ONE_IN_Q7 ); + } + FOR( Word16 c = 0; c < FDNS_NPTS; c++ ) + { + scaleFactors_fx[c] = (Word32) ( scaleFactors[c] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( pScaledMdctSpectrum_fx, psychParamsCurrent, scaleFactors_fx, nSamplesCore ); + + FOR( Word16 c = 0; c < nSamplesCore; c++ ) + { + pScaledMdctSpectrum[c] = ( (float) pScaledMdctSpectrum_fx[c] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( pScaledMdctSpectrum, psychParamsCurrent, scaleFactors, nSamplesCore ); +#endif // IVAS_FLOAT_FIXED nBands = psychParamsCurrent->nBands; } diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index 0c5446c5b8a8383c3f40ac1dd74482e66cf3d5e9..c0b445fcbd32fe73ef2b03b2cb0dd091f2c2de36 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -44,6 +44,9 @@ #include "rom_com.h" #include #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*---------------------------------------------------------------------* * Local constants @@ -507,7 +510,7 @@ void addBassPostFilter( return; } - +#ifndef IVAS_FLOAT_FIXED /*---------------------------------------------------------------------* * res_bpf_adapt() * @@ -566,6 +569,7 @@ int16_t res_bpf_adapt( error_nrg *= 0.2f; /* Division by 5 for average value */ bpf_error_ratio = min( 2, error_nrg / res_hb_nrg ); /* Form decision variable and apply limit */ bpf_error_ratio = STEREO_DFT_BPF_ADAPT_BETA * bpf_error_ratio + ( 1 - STEREO_DFT_BPF_ADAPT_BETA ) * hStereoDft->bpf_error_ratio_mem; + //printf("\n%f\n", bpf_error_ratio); hStereoDft->bpf_error_ratio_mem = bpf_error_ratio; res_bpf_flag = bpf_error_ratio < 1; @@ -573,6 +577,75 @@ int16_t res_bpf_adapt( return res_bpf_flag; } +#else +/*---------------------------------------------------------------------* + * res_bpf_adapt_fx() + * + * Analyze BPF output and decide if it should be applied on DFT stereo + * residual signal + *---------------------------------------------------------------------*/ + +/*! r: Decision to enable or disable BPF on DFT stereo residual */ +Word16 res_bpf_adapt_fx( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ + Word32 res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ +) +{ + Word32 error_nrg; + Word32 tmp; + Word32 res_hb_nrg; + Word16 bpf_error_ratio; + Word16 res_bpf_flag; + Word16 i; + Word16 i_start; + Word16 i_end; + Word16 bw_inv; + + IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) + { + i_start = 39; + i_end = 64; + bw_inv = 1311; /* 1/(64 - 39) in Q15 */ + } + ELSE + { + i_start = 28; + i_end = 40; + bw_inv = 2720; /* 1/(40 - 28) in Q15*/ + } + + /* Measure energy of high frequency band in MDCT domain */ + res_hb_nrg = L_deposit_l( 0 ); + FOR( i = i_start; i < i_end; i++ ) + { + res_hb_nrg = Madd_32_32_r( res_hb_nrg, res_buf[i], res_buf[i] ); + } + res_hb_nrg = L_shl( (Word32) res_hb_nrg, Q7 ); // Q0 + res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); + res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); + hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; + + /* Measure energy of discontinuities at subframe boundaries */ + error_nrg = 0; + FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) + { + tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); + error_nrg = Madd_32_32( error_nrg, tmp, tmp ); + hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[i + STEREO_DFT_L_SUBFR_8k - 1]; + } + error_nrg = L_shr( error_nrg, 1 ); // Q0 + error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ + bpf_error_ratio = LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ? (Word16) ( L_shl( ( L_shl( error_nrg, Q5 ) / res_hb_nrg ), Q7 ) ) : shl( ONE_IN_Q12, 1 ); /* Form decision variable and apply limit */ + bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( sub( MAX_16, STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); + hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; + + res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q12 ); + + return res_bpf_flag; +} +#endif // IVAS_FLOAT_FIXED + /*---------------------------------------------------------------------* * bpf_pitch_coherence() * diff --git a/lib_dec/ivas_entropy_decoder.c b/lib_dec/ivas_entropy_decoder.c index 360dfbe8708ea9fa8b82fd16e1ae15da2ae4b881..36433182e5cb9af50ceecb45b6413abe7b6c4e24 100644 --- a/lib_dec/ivas_entropy_decoder.c +++ b/lib_dec/ivas_entropy_decoder.c @@ -44,7 +44,7 @@ * Static function declarations *------------------------------------------------------------------------------------------*/ -static int16_t ivas_huffman_code_bits_present( const int16_t *codebook, const int16_t code, const int16_t bits, const int16_t len ); +static Word16 ivas_huffman_code_bits_present( const Word16 *codebook, const Word16 code, const Word16 bits, const Word16 len ); /*-----------------------------------------------------------------------------------------* @@ -56,48 +56,48 @@ static int16_t ivas_huffman_code_bits_present( const int16_t *codebook, const in static void ivas_arith_decode_array( ivas_arith_t *pArith, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - const int16_t in_len, - int16_t *pSymbols ) + const Word16 in_len, + Word16 *pSymbols ) { - int16_t i, ind, model_idx; - int16_t *pCum_freq = NULL; + Word16 i, ind, model_idx; + Word16 *pCum_freq = NULL; Tastat as; - int16_t extra_bits_read = 0; + Word16 extra_bits_read = 0; - if ( in_len > 0 && pArith->range > 1 ) + IF( GT_16( in_len, 0 ) && GT_16( pArith->range, 1 ) ) { - if ( pArith->dyn_model_bits > 0 ) + IF( GT_16( pArith->dyn_model_bits, 0 ) ) { model_idx = get_next_indice( st0, pArith->dyn_model_bits ); - if ( model_idx > 0 ) + IF( GT_16( model_idx, 0 ) ) { pCum_freq = pArith->cum_freq[model_idx]; } - else + ELSE { pCum_freq = pArith->cum_freq[0]; } } - else + ELSE { pCum_freq = pArith->cum_freq[0]; } ivas_ari_start_decoding_14bits_ext_1_lfe( st0, &as, &extra_bits_read ); - for ( i = 0; i < in_len; i++ ) + FOR( i = 0; i < in_len; i++ ) { - ind = ivas_ari_decode_14bits_bit_ext_1_lfe( st0, &as, (const uint16_t *) pCum_freq, &extra_bits_read ); + ind = ivas_ari_decode_14bits_bit_ext_1_lfe( st0, &as, (const UWord16 *) pCum_freq, &extra_bits_read ); pSymbols[i] = pArith->vals[ind]; } ivas_ari_done_decoding_14bits_ext_1_lfe( st0, extra_bits_read ); } - else + ELSE { - for ( i = 0; i < in_len; i++ ) + FOR( i = 0; i < in_len; i++ ) { pSymbols[i] = 0; } @@ -116,27 +116,27 @@ static void ivas_arith_decode_array( static void ivas_arithCoder_decode_array_diff( ivas_arith_t *pArith, ivas_arith_t *pArith_diff, - int16_t *pSymbol_old, - const int16_t length, + Word16 *pSymbol_old, + const Word16 length, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t *pOutput_arr ) + Word16 *pOutput_arr ) { - int16_t n; - int16_t offset = pArith->vals[0]; + Word16 n; + Word16 offset = pArith->vals[0]; - if ( length > 0 ) + IF( GT_16( length, 0 ) ) { ivas_arith_decode_array( pArith_diff, st0, length, pOutput_arr ); } - for ( n = 0; n < length; n++ ) + FOR( n = 0; n < length; n++ ) { - pOutput_arr[n] = pSymbol_old[n] - offset + pOutput_arr[n]; + pOutput_arr[n] = add( sub( pSymbol_old[n], offset ), pOutput_arr[n] ); } - ivas_wrap_arround( pOutput_arr, 0, pArith_diff->range - 1, length ); + ivas_wrap_arround( pOutput_arr, 0, sub( pArith_diff->range, 1 ), length ); - for ( n = 0; n < length; n++ ) + FOR( n = 0; n < length; n++ ) { pOutput_arr[n] = pArith->vals[pOutput_arr[n]]; } @@ -151,22 +151,22 @@ static void ivas_arithCoder_decode_array_diff( * Huffman code bits present *-----------------------------------------------------------------------------------------*/ -static int16_t ivas_huffman_code_bits_present( - const int16_t *codebook, - const int16_t code, - const int16_t bits, - const int16_t len ) +static Word16 ivas_huffman_code_bits_present( + const Word16 *codebook, + const Word16 code, + const Word16 bits, + const Word16 len ) { - int16_t index = len + 1; - int16_t i = 0; - int16_t ind_t, code_t, bits_t; + Word16 index = add( len, 1 ); + Word16 i = 0; + Word16 ind_t, code_t, bits_t; - while ( i < len ) + WHILE ( LT_16( i, len ) ) { ind_t = codebook[0]; bits_t = codebook[1]; code_t = codebook[2]; - if ( ( code == code_t ) && ( bits == bits_t ) ) + IF( ( EQ_16( code, code_t ) ) && ( EQ_16( bits, bits_t ) ) ) { return ind_t; } @@ -187,22 +187,22 @@ static int16_t ivas_huffman_code_bits_present( ivas_error ivas_huffman_decode( ivas_huffman_cfg_t *huff_cfg, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t *dec_out ) + Word16 *dec_out ) { - int16_t code, num_bits_read, ind, bit; + Word16 code, num_bits_read, ind, bit; code = get_next_indice( st0, huff_cfg->min_len ); num_bits_read = huff_cfg->min_len; ind = ivas_huffman_code_bits_present( huff_cfg->codebook, code, num_bits_read, huff_cfg->sym_len ); - while ( ind > huff_cfg->sym_len ) + WHILE ( GT_16( ind, huff_cfg->sym_len ) ) { bit = get_next_indice( st0, 1 ); - num_bits_read += 1; + num_bits_read = add( num_bits_read, 1 ); code = code << 1 | bit; ind = ivas_huffman_code_bits_present( huff_cfg->codebook, code, num_bits_read, huff_cfg->sym_len ); - if ( num_bits_read > huff_cfg->max_len ) + IF( GT_16( num_bits_read, huff_cfg->max_len ) ) { return IVAS_ERR_INTERNAL; } @@ -222,19 +222,19 @@ ivas_error ivas_huffman_decode( static void arith_decode_cell_array( ivas_cell_dim_t *pCell_dims, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t num_bands, + Word16 num_bands, ivas_arith_t *pArith, - int16_t *pSymbol ) + Word16 *pSymbol ) { - int16_t total_symbol_len = 0; - int16_t i; + Word16 total_symbol_len = 0; + Word16 i; - for ( i = 0; i < num_bands; i++ ) + FOR( i = 0; i < num_bands; i++ ) { total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 ); } - assert( total_symbol_len <= IVAS_MAX_INPUT_LEN ); + assert( LE_16( total_symbol_len, IVAS_MAX_INPUT_LEN ) ); ivas_arith_decode_array( pArith, st0, total_symbol_len, pSymbol ); @@ -251,21 +251,21 @@ static void arith_decode_cell_array( static void arith_decode_cell_array_diff( ivas_cell_dim_t *pCell_dims, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t num_bands, + Word16 num_bands, ivas_arith_t *pArith, ivas_arith_t *pArith_diff, - int16_t *pSymbol, - int16_t *pSymbol_old ) + Word16 *pSymbol, + Word16 *pSymbol_old ) { - int16_t total_symbol_len = 0; - int16_t i; + Word16 total_symbol_len = 0; + Word16 i; - for ( i = 0; i < num_bands; i++ ) + FOR( i = 0; i < num_bands; i++ ) { total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 ); } - assert( total_symbol_len <= IVAS_MAX_INPUT_LEN ); + assert( LE_16( total_symbol_len, IVAS_MAX_INPUT_LEN ) ); ivas_arithCoder_decode_array_diff( pArith, pArith_diff, pSymbol_old, total_symbol_len, st0, pSymbol ); @@ -283,50 +283,50 @@ void ivas_arith_decode_cmplx_cell_array( ivas_arith_t *pArith_re_diff, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ ivas_cell_dim_t *pCell_dims, - int16_t *pDo_diff, - const int16_t num_bands, - int16_t *pSymbol_re, - int16_t *pSymbol_re_old ) + Word16 *pDo_diff, + const Word16 num_bands, + Word16 *pSymbol_re, + Word16 *pSymbol_re_old ) { - int16_t i, j, len, all_diff = 1, any_diff = 0; - int16_t cell_arr_diff[IVAS_MAX_INPUT_LEN]; - int16_t cell_arr_no_diff[IVAS_MAX_INPUT_LEN]; - int16_t cell_arr_diff_out[IVAS_MAX_INPUT_LEN]; - int16_t idx2 = 0; + Word16 i, j, len, all_diff = 1, any_diff = 0; + Word16 cell_arr_diff[IVAS_MAX_INPUT_LEN]; + Word16 cell_arr_no_diff[IVAS_MAX_INPUT_LEN]; + Word16 cell_arr_diff_out[IVAS_MAX_INPUT_LEN]; + Word16 idx2 = 0; - for ( i = 0; i < num_bands; i++ ) + FOR( i = 0; i < num_bands; i++ ) { - if ( pDo_diff[i] != 0 ) + IF( NE_16( pDo_diff[i], 0 ) ) { any_diff = 1; } - else + ELSE { all_diff = 0; } } - if ( any_diff == 1 ) + IF( EQ_16( any_diff, 1 ) ) { - if ( all_diff == 1 ) + IF( EQ_16( all_diff, 1 ) ) { arith_decode_cell_array_diff( pCell_dims, st0, num_bands, pArith_re, pArith_re_diff, pSymbol_re, pSymbol_re_old ); } - else + ELSE { ivas_cell_dim_t cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t cell_dims_diff[IVAS_MAX_NUM_BANDS]; - int16_t idx1 = 0, idx = 0; + Word16 idx1 = 0, idx = 0; - for ( i = 0; i < num_bands; i++ ) + FOR( i = 0; i < num_bands; i++ ) { len = pCell_dims[i].dim1 * pCell_dims[i].dim2; - if ( pDo_diff[i] != 0 ) + IF( NE_16( pDo_diff[i], 0 ) ) { cell_dims[i].dim1 = 0; cell_dims[i].dim2 = 0; - for ( j = 0; j < len; j++ ) + FOR( j = 0; j < len; j++ ) { cell_arr_diff[idx++] = pSymbol_re_old[idx1++]; } @@ -334,9 +334,9 @@ void ivas_arith_decode_cmplx_cell_array( cell_dims_diff[i].dim1 = pCell_dims[i].dim1; cell_dims_diff[i].dim2 = pCell_dims[i].dim2; } - else + ELSE { - for ( j = 0; j < len; j++ ) + FOR( j = 0; j < len; j++ ) { cell_arr_diff[idx] = 0; idx1++; @@ -355,18 +355,18 @@ void ivas_arith_decode_cmplx_cell_array( idx = 0; idx1 = 0; - for ( i = 0; i < num_bands; i++ ) + FOR( i = 0; i < num_bands; i++ ) { - if ( pDo_diff[i] != 0 ) + IF( NE_16( pDo_diff[i], 0 ) ) { - for ( j = 0; j < cell_dims_diff[i].dim1 * cell_dims_diff[i].dim2; j++ ) + FOR( j = 0; j < cell_dims_diff[i].dim1 * cell_dims_diff[i].dim2; j++ ) { pSymbol_re[idx++] = cell_arr_diff_out[idx2++]; } } - else + ELSE { - for ( j = 0; j < cell_dims[i].dim1 * cell_dims[i].dim2; j++ ) + FOR( j = 0; j < cell_dims[i].dim1 * cell_dims[i].dim2; j++ ) { pSymbol_re[idx++] = cell_arr_no_diff[idx1++]; } @@ -374,7 +374,7 @@ void ivas_arith_decode_cmplx_cell_array( } } } - else + ELSE { arith_decode_cell_array( pCell_dims, st0, num_bands, pArith_re, pSymbol_re ); } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 83e90e01f5915d5f4c3afb22a4227f6c6f07e449..44f4f86973ccd7888988a81827b027ce405f4280 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -2302,7 +2302,7 @@ static int16_t ivas_decode_masaism_metadata( nblocks = hQMetaData->q_direction->cfg.nblocks; /* Read MASA-to-total energy ratios */ -#ifdef IVAS_FLOAT_FIXED1 +#ifdef IVAS_FLOAT_FIXED Word16 q = 18; ivas_omasa_decode_masa_to_total_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, nbands, nblocks, &q ); diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 00dff066cc22bdf7c26a3011cecf2f41c6014087..875441418e0ec4955a05085f270b2cc15e740c70 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -44,6 +44,9 @@ #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* @@ -1015,7 +1018,22 @@ void ivas_mdct_core_tns_ns( if ( !bfi ) { +#ifdef IVAS_FLOAT_FIXED + Word32 sns_int_scf_fx[FDNS_NPTS], Aq_fx[SNS_NPTS]; + FOR( int c = 0; c < SNS_NPTS; c++ ) + { + Aq_fx[c] = (Word32) ( Aq[ch][k * M + c] * ONE_IN_Q16 ); + } + + sns_interpolate_scalefactors_fx( sns_int_scf_fx, Aq_fx, DEC ); + + FOR( int c = 0; c < FDNS_NPTS; c++ ) + { + sns_int_scf[c] = ( (float) sns_int_scf_fx[c] / ONE_IN_Q16 ); + } +#else sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); +#endif // IVAS_FLOAT_FIXED if ( MCT_flag && st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) { @@ -1054,7 +1072,26 @@ void ivas_mdct_core_tns_ns( decoder_tcx_tns( st, L_frame_global[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], &x[ch][k][0], fUseTns[ch][k], &tnsData[ch][k], bfi, k, 1 ); +#ifdef IVAS_FLOAT_FIXED + Word32 x_fx[L_FRAME48k], sns_int_scf_fx[FDNS_NPTS]; + FOR( Word16 c = 0; c < st->hTcxCfg->psychParamsCurrent->nBins; c++ ) + { + x_fx[c] = (Word32) ( x[ch][k][c] * ONE_IN_Q7 ); + } + FOR( Word16 c = 0; c < FDNS_NPTS; c++ ) + { + sns_int_scf_fx[c] = (Word32) ( sns_int_scf[c] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( x_fx, st->hTcxCfg->psychParamsCurrent, sns_int_scf_fx, st->hTcxCfg->psychParamsCurrent->nBins ); + + FOR( Word16 c = 0; c < st->hTcxCfg->psychParamsCurrent->nBins; c++ ) + { + x[ch][k][c] = ( (float) x_fx[c] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( x[ch][k], st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], st->hTcxCfg->psychParamsCurrent->nBins ); +#endif // IVAS_FLOAT_FIXED v_multc( x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf[FDNS_NPTS - 1], x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, L_spec[ch] - st->hTcxCfg->psychParamsCurrent->nBins ); decoder_tcx_tns( st, L_frame_global[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], &x[ch][k][0], fUseTns[ch][k], &tnsData[ch][k], bfi, k, 0 ); diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index bf480ea80995b2705503976b8f4950fcdb88ce73..6e6b7b380196465935eff27a517086dc0d6a6acd 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -47,7 +47,7 @@ * Local function prototypes *-----------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static Word16 ivas_qmetadata_entropy_decode_diffuseness( uint16_t *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, UWord16 *diffuseness_index_max_ec_frame ); +static Word16 ivas_qmetadata_entropy_decode_diffuseness( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, UWord16 *diffuseness_index_max_ec_frame ); #else static int16_t ivas_qmetadata_entropy_decode_diffuseness( uint16_t *bitstream, int16_t *index, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); #endif @@ -74,13 +74,16 @@ static Word16 ivas_qmetadata_ReorderElevationDecoded( const Word16 elev_dist, co static int16_t ivas_qmetadata_ReorderElevationDecoded( const int16_t elev_dist, const int16_t elev_avg, const int16_t elev_alph ); #endif +#ifndef IVAS_FLOAT_FIXED static int16_t read_directions( IVAS_QDIRECTION *q_direction, const uint8_t coding_subbands, const uint8_t masa_subframes, uint16_t *bitstream, int16_t *pbit_pos, int16_t *ind_order ); static int16_t read_common_direction( uint16_t *bitstream, IVAS_QDIRECTION *q_direction, const int16_t j, const int16_t no_subframes, const int16_t bits_total, int16_t *pbit_pos ); -static int16_t decode_fixed_rate( IVAS_QDIRECTION *q_direction, const uint16_t *bitstream, int16_t *pbit_pos, const int16_t b, const int16_t nblocks ); static int16_t decode_azimuth( IVAS_QDIRECTION *q_direction, uint16_t *bitstream, int16_t *pbit_pos, const int16_t idx_subband, const int16_t masa_subframes ); +#endif + +static int16_t decode_fixed_rate( IVAS_QDIRECTION *q_direction, const uint16_t *bitstream, int16_t *pbit_pos, const int16_t b, const int16_t nblocks ); #ifdef IVAS_FLOAT_FIXED @@ -104,7 +107,7 @@ static Word16 decode_elevation_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstr static Word16 decode_fixed_rate_composed_index_coherence_fx( UWord16 *bitstream, Word16 *p_bit_pos, const Word16 no_bands, Word16 *no_cv_vec, UWord16 *decoded_index, const Word16 no_symb ); -static void decode_spread_coherence_fx( IVAS_QMETADATA_HANDLE hQMetaData, int16_t idx_d, const int16_t no_frames, const int16_t hrmasa_flag ); +static void decode_spread_coherence_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 idx_d, const Word16 no_frames, const Word16 hrmasa_flag ); static Word16 ivas_diffuseness_huff_ec_decode_fx( const UWord16 *bitstream, Word16 *index, Word16 av ); @@ -112,7 +115,7 @@ static void read_stream_dct_coeffs_omasa_fx( Word16 *q_idx, Word32 *q_dct_data_f static Word16 read_coherence_data_hr_512_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, const Word16 idx_dir, const Word16 nbits_coh ); -static Word16 read_surround_coherence_hr_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, Word16 *q ); +//static Word16 read_surround_coherence_hr_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, Word16 *q ); static Word16 read_common_direction_fx( UWord16 *bitstream, IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 no_subframes, const Word16 bits_total, Word16 *pbit_pos ); @@ -120,6 +123,7 @@ static Word16 read_coherence_data_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVA #endif +#ifndef IVAS_FLOAT_FIXED static int16_t decode_elevation( IVAS_QDIRECTION *q_direction, uint16_t *bitstream, int16_t *pbit_pos, const int16_t j, const int16_t masa_subframes ); static int16_t decode_azimuth2D( IVAS_QDIRECTION *q_direction, uint16_t *bitstream, const int16_t coding_subbands, int16_t *pbit_pos, const int16_t no_frames ); @@ -127,6 +131,7 @@ static int16_t decode_azimuth2D( IVAS_QDIRECTION *q_direction, uint16_t *bitstre static void set_zero_direction( IVAS_QDIRECTION *q_direction, const int16_t idx_band, const int16_t len ); static int16_t read_truncGR_azimuth( uint16_t *bitstream, IVAS_QDIRECTION *q_direction, const int16_t j, const int16_t no_subframes, int16_t *pbit_pos ); +#endif #ifdef IVAS_FLOAT_FIXED static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWord16 *out, const Word16 start_pos, const Word16 len, const Word16 *huff_code, const Word16 max_len ); @@ -134,10 +139,13 @@ static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWo static ivas_error read_huf( int16_t *num_bits_read, const uint16_t *bitstream, uint16_t *out, const int16_t start_pos, const int16_t len, const int16_t *huff_code, const int16_t max_len ); #endif +#ifndef IVAS_FLOAT_FIXED static int16_t read_coherence_data( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t hrmasa_flag ); +#endif static int16_t read_surround_coherence( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData ); +#ifndef IVAS_FLOAT_FIXED static void decode_spread_coherence( IVAS_QMETADATA_HANDLE hQMetaData, int16_t idx_d, const int16_t no_frames, const int16_t hrmasa_flag ); static void decode_combined_index( uint64_t comb_index, const int16_t *no_cv_vec, uint16_t *index, const int16_t len ); @@ -147,6 +155,7 @@ static int16_t ivas_diffuseness_huff_ec_decode( const uint16_t *bitstream, int16 static int16_t read_GR_min_removed_data( uint16_t *bitstream, int16_t *p_bit_pos, const int16_t *no_cv_vec, const int16_t no_data, int16_t *decoded_idx, const int16_t no_symb ); static int16_t decode_fixed_rate_composed_index_coherence( uint16_t *bitstream, int16_t *p_bit_pos, const int16_t no_bands, int16_t *no_cv_vec, uint16_t *decoded_index, const int16_t no_symb ); +#endif #ifdef IVAS_FLOAT_FIXED static Word16 ivas_qmetadata_entropy_decode_diffuseness_hr_512( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction ); @@ -158,9 +167,11 @@ static int16_t ivas_qmetadata_raw_decode_dir_512( IVAS_QDIRECTION *q_direction, static int16_t read_surround_coherence_hr( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData ); +#ifndef IVAS_FLOAT_FIXED static int16_t read_coherence_data_hr_512( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t nbits_coh ); static void read_stream_dct_coeffs_omasa( int16_t *q_idx, float *q_dct_data, const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line ); +#endif /*-----------------------------------------------------------------------* @@ -547,8 +558,8 @@ int16_t ivas_qmetadata_dec_decode( { FOR( Word16 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) { - q_direction->band_data[j].elevation_fx[k] = q_direction->band_data[j].elevation[k] * ( 1 << 22 ); - q_direction->band_data[j].azimuth_fx[k] = q_direction->band_data[j].azimuth[k] * ( 1 << 22 ); + q_direction->band_data[j].elevation_fx[k] = (Word32)(q_direction->band_data[j].elevation[k] * ( 1 << 22 )); + q_direction->band_data[j].azimuth_fx[k] = (Word32)(q_direction->band_data[j].azimuth[k] * ( 1 << 22 )); } } bits_dir += ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, nbands, start_band, 0 ); @@ -702,8 +713,8 @@ int16_t ivas_qmetadata_dec_decode( { FOR( Word16 k = 0; k < nblocks; k++ ) { - q_direction->band_data[j].elevation_fx[k] = q_direction->band_data[j].elevation[k] * ( 1 << 22 ); - q_direction->band_data[j].azimuth_fx[k] = q_direction->band_data[j].azimuth[k] * ( 1 << 22 ); + q_direction->band_data[j].elevation_fx[k] = (Word32)(q_direction->band_data[j].elevation[k] * ( 1 << 22 )); + q_direction->band_data[j].azimuth_fx[k] = (Word32)(q_direction->band_data[j].azimuth[k] * ( 1 << 22 )); } } bits_dir = read_directions_fx( q_direction, (uint8_t) nbands, (uint8_t) nblocks, bitstream, index, ind_order ); @@ -734,7 +745,7 @@ int16_t ivas_qmetadata_dec_decode( { for ( int j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - q_direction->band_data[i].azimuth_fx[j] = q_direction->band_data[i].azimuth[j] * ( 1 << 22 ); + q_direction->band_data[i].azimuth_fx[j] = (Word32)(q_direction->band_data[i].azimuth[j] * ( 1 << 22 )); } } decode_spread_coherence_fx( hQMetaData, d, nblocks, 0 ); @@ -1705,27 +1716,28 @@ int16_t ivas_qmetadata_dec_sid_decode( * Local function definitions for diffuseness/energy ratios *-----------------------------------------------------------------------*/ -static int16_t ivas_diffuseness_huff_ec_decode( - const uint16_t *bitstream, - int16_t *index, - int16_t av ) +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_diffuseness_huff_ec_decode_fx( + const UWord16 *bitstream, + Word16 *index, + Word16 av ) { - int16_t val; + Word16 val; val = 0; - while ( val <= DIFF_EC_HUFF_GR0_LIMIT ) + WHILE( val <= DIFF_EC_HUFF_GR0_LIMIT ) { - if ( bitstream[( *index )--] == 1 ) + IF( bitstream[( *index )--] == 1 ) { val++; } - else + ELSE { - break; + BREAK; } } - if ( val == DIFF_EC_HUFF_GR0_LIMIT + 1 ) + IF( val == DIFF_EC_HUFF_GR0_LIMIT + 1 ) { val += 2 * bitstream[( *index )]; ( *index )--; @@ -1733,38 +1745,37 @@ static int16_t ivas_diffuseness_huff_ec_decode( ( *index )--; } - if ( val % 2 == 0 ) + IF( val % 2 == 0 ) { return -( val / 2 ) + av; } - else + ELSE { return ( val + 1 ) / 2 + av; } } - -#ifdef IVAS_FLOAT_FIXED -static Word16 ivas_diffuseness_huff_ec_decode_fx( - const UWord16 *bitstream, - Word16 *index, - Word16 av ) +#else +static int16_t ivas_diffuseness_huff_ec_decode( + const uint16_t *bitstream, + int16_t *index, + int16_t av ) { - Word16 val; + int16_t val; val = 0; - WHILE( val <= DIFF_EC_HUFF_GR0_LIMIT ) + while ( val <= DIFF_EC_HUFF_GR0_LIMIT ) { - IF( bitstream[( *index )--] == 1 ) + if ( bitstream[( *index )--] == 1 ) { val++; } - ELSE + else { - BREAK; + break; } } - IF( val == DIFF_EC_HUFF_GR0_LIMIT + 1 ) + if ( val == DIFF_EC_HUFF_GR0_LIMIT + 1 ) { val += 2 * bitstream[( *index )]; ( *index )--; @@ -1772,11 +1783,11 @@ static Word16 ivas_diffuseness_huff_ec_decode_fx( ( *index )--; } - IF( val % 2 == 0 ) + if ( val % 2 == 0 ) { return -( val / 2 ) + av; } - ELSE + else { return ( val + 1 ) / 2 + av; } @@ -2651,7 +2662,7 @@ static int16_t ivas_qmetadata_entropy_decode_dir( return ( index_start - *index ); } -#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_1 static Word16 ivas_qmetadata_entropy_decode_dir_fx( IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ UWord16 *bitstream, /* i : bitstream */ @@ -3381,70 +3392,72 @@ static int16_t ivas_qmetadata_ReorderElevationDecoded( *-----------------------------------------------------------------------*/ /*! r: number of bits read */ -static int16_t read_directions( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - const uint8_t coding_subbands, /* i : number of directions */ - const uint8_t masa_subframes, /* i : number of tiles */ - uint16_t *bitstream, /* i : bitstream to be read */ - int16_t *pbit_pos, - int16_t *ind_order ) +#ifdef IVAS_FLOAT_FIXED +static Word16 read_directions_fx( + IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ + const UWord8 coding_subbands, /* i : number of directions */ + const UWord8 masa_subframes, /* i : number of tiles */ + UWord16 *bitstream, /* i : bitstream to be read */ + Word16 *pbit_pos, + Word16 *ind_order ) { - int16_t j, k, allowed_bits, last_j, nbits, fixed_rate; - int16_t i; - int16_t diff; - uint16_t byteBuffer; - int16_t use_vq, max_nb_idx; - int16_t bit_pos; - int16_t *bits_dir0; + Word16 j, k, allowed_bits, last_j, nbits, fixed_rate; + Word16 i; + Word16 diff; + UWord16 byteBuffer; + Word16 use_vq, max_nb_idx; + Word16 bit_pos; + Word16 *bits_dir0; bit_pos = *pbit_pos; diff = 0; - if ( q_direction->not_in_2D ) + IF( q_direction->not_in_2D ) { - if ( coding_subbands > 1 ) + + IF( coding_subbands > 1 ) { j = ind_order[coding_subbands - 1]; allowed_bits = 0; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { allowed_bits += q_direction->band_data[j].bits_sph_idx[k]; } last_j = j - ( allowed_bits == 0 ); - for ( j = 0; j < last_j; j++ ) + FOR( j = 0; j < last_j; j++ ) { i = ind_order[j]; - bits_dir0 = (int16_t *) q_direction->band_data[i].bits_sph_idx; + bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; nbits = 0; allowed_bits = sum_s( bits_dir0, q_direction->cfg.nblocks ); use_vq = 0; max_nb_idx = 0; - for ( k = 0; k < q_direction->cfg.nblocks; k++ ) + FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) { - if ( bits_dir0[k] > use_vq ) + IF( bits_dir0[k] > use_vq ) { use_vq = bits_dir0[k]; max_nb_idx = k; } } - if ( q_direction->cfg.nblocks == 1 ) + IF( q_direction->cfg.nblocks == 1 ) { byteBuffer = 0; } - else + ELSE { byteBuffer = 0; - if ( use_vq <= 1 ) + IF( use_vq <= 1 ) { byteBuffer = 1; } - if ( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) + IF( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) { bits_dir0[max_nb_idx] -= 1; allowed_bits -= 1; @@ -3453,98 +3466,99 @@ static int16_t read_directions( } } - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { q_direction->band_data[i].bits_sph_idx[k] = bits_dir0[k]; - if ( bits_dir0[k] > 2 ) + IF( bits_dir0[k] > 2 ) { - if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; } - else + ELSE { q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3] * 2 - 1; } } - else + ELSE { q_direction->band_data[i].elevation_m_alphabet[k] = 1; } } - if ( allowed_bits > 0 ) + IF( allowed_bits > 0 ) { - if ( byteBuffer == 1 ) + IF( byteBuffer == 1 ) { - nbits = read_common_direction( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); + nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); } - else + ELSE { - if ( q_direction->cfg.nblocks == 1 && q_direction->band_data[i].bits_sph_idx[0] <= MASA_MIN_BITS_TF + 1 ) + IF( q_direction->cfg.nblocks == 1 && q_direction->band_data[i].bits_sph_idx[0] <= MASA_MIN_BITS_TF + 1 ) { /* there is fixed rate only, no need to read */ fixed_rate = 1; nbits = 0; } - else + ELSE { /* check if fixed_rate */ fixed_rate = bitstream[bit_pos--]; nbits = 1; } - if ( fixed_rate == 1 ) + IF( fixed_rate == 1 ) { /* decode_fixed_rate()*/ - nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); } - else + ELSE { - /* decode elevation */ - nbits += decode_elevation( q_direction, bitstream, &bit_pos, i, masa_subframes ); + /* decode elevation */ + nbits += decode_elevation_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); /* decode azimuth */ - nbits += decode_azimuth( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_azimuth_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); } } } - else + ELSE { - set_zero_direction( q_direction, i, masa_subframes ); + set_zero_direction_fx( q_direction, i, masa_subframes ); } + diff += nbits - allowed_bits; /* update bits for next block */ update_bits_next_block( q_direction, &diff, ind_order[j + 1], coding_subbands, masa_subframes ); } } - else + ELSE { last_j = q_direction->cfg.start_band; } - for ( j = last_j; j < coding_subbands; j++ ) + FOR( j = last_j; j < coding_subbands; j++ ) { i = ind_order[j]; - bits_dir0 = (int16_t *) q_direction->band_data[i].bits_sph_idx; + bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; nbits = 0; allowed_bits = sum_s( bits_dir0, q_direction->cfg.nblocks ); - if ( allowed_bits > 0 && masa_subframes == 1 ) + IF( allowed_bits > 0 && masa_subframes == 1 ) { - nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); } - else + ELSE { - if ( allowed_bits > 0 ) + IF( allowed_bits > 0 ) { use_vq = 0; max_nb_idx = 0; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( bits_dir0[k] > use_vq ) + IF( bits_dir0[k] > use_vq ) { use_vq = bits_dir0[k]; max_nb_idx = k; @@ -3553,7 +3567,7 @@ static int16_t read_directions( byteBuffer = 0; - if ( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) + IF( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) { bits_dir0[max_nb_idx] -= 1; allowed_bits -= 1; @@ -3562,115 +3576,114 @@ static int16_t read_directions( byteBuffer = bitstream[bit_pos--]; } - if ( allowed_bits > 0 ) + IF( allowed_bits > 0 ) { - if ( byteBuffer == 1 || use_vq <= 1 ) + IF( byteBuffer == 1 || use_vq <= 1 ) { - nbits = read_common_direction( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); + nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); } - else + ELSE { /* decode_fixed_rate()*/ - nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); } } - else + ELSE { - set_zero_direction( q_direction, i, masa_subframes ); + set_zero_direction_fx( q_direction, i, masa_subframes ); } } - else + ELSE { - set_zero_direction( q_direction, i, masa_subframes ); + set_zero_direction_fx( q_direction, i, masa_subframes ); } } } } - else + ELSE { /* 2D */ - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - for ( k = 0; k < q_direction->cfg.nblocks; k++ ) + FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) { - q_direction->band_data[j].elevation[k] = 0; + q_direction->band_data[j].elevation_fx[k] = 0; q_direction->band_data[j].elevation_index[k] = 0; } } - nbits = decode_azimuth2D( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); + + nbits = decode_azimuth2D_fx( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); } nbits = *pbit_pos - bit_pos; *pbit_pos = bit_pos; return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 read_directions_fx( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - const UWord8 coding_subbands, /* i : number of directions */ - const UWord8 masa_subframes, /* i : number of tiles */ - UWord16 *bitstream, /* i : bitstream to be read */ - Word16 *pbit_pos, - Word16 *ind_order ) +#else +static int16_t read_directions( + IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ + const uint8_t coding_subbands, /* i : number of directions */ + const uint8_t masa_subframes, /* i : number of tiles */ + uint16_t *bitstream, /* i : bitstream to be read */ + int16_t *pbit_pos, + int16_t *ind_order ) { - Word16 j, k, allowed_bits, last_j, nbits, fixed_rate; - Word16 i; - Word16 diff; - UWord16 byteBuffer; - Word16 use_vq, max_nb_idx; - Word16 bit_pos; - Word16 *bits_dir0; + int16_t j, k, allowed_bits, last_j, nbits, fixed_rate; + int16_t i; + int16_t diff; + uint16_t byteBuffer; + int16_t use_vq, max_nb_idx; + int16_t bit_pos; + int16_t *bits_dir0; bit_pos = *pbit_pos; diff = 0; - IF( q_direction->not_in_2D ) + if ( q_direction->not_in_2D ) { - - IF( coding_subbands > 1 ) + if ( coding_subbands > 1 ) { j = ind_order[coding_subbands - 1]; allowed_bits = 0; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { allowed_bits += q_direction->band_data[j].bits_sph_idx[k]; } last_j = j - ( allowed_bits == 0 ); - FOR( j = 0; j < last_j; j++ ) + for ( j = 0; j < last_j; j++ ) { i = ind_order[j]; - bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; + bits_dir0 = (int16_t *) q_direction->band_data[i].bits_sph_idx; nbits = 0; allowed_bits = sum_s( bits_dir0, q_direction->cfg.nblocks ); use_vq = 0; max_nb_idx = 0; - FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) + for ( k = 0; k < q_direction->cfg.nblocks; k++ ) { - IF( bits_dir0[k] > use_vq ) + if ( bits_dir0[k] > use_vq ) { use_vq = bits_dir0[k]; max_nb_idx = k; } } - IF( q_direction->cfg.nblocks == 1 ) + if ( q_direction->cfg.nblocks == 1 ) { byteBuffer = 0; } - ELSE + else { byteBuffer = 0; - IF( use_vq <= 1 ) + if ( use_vq <= 1 ) { byteBuffer = 1; } - IF( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) + if ( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) { bits_dir0[max_nb_idx] -= 1; allowed_bits -= 1; @@ -3679,99 +3692,98 @@ static Word16 read_directions_fx( } } - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { q_direction->band_data[i].bits_sph_idx[k] = bits_dir0[k]; - IF( bits_dir0[k] > 2 ) + if ( bits_dir0[k] > 2 ) { - IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; } - ELSE + else { q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3] * 2 - 1; } } - ELSE + else { q_direction->band_data[i].elevation_m_alphabet[k] = 1; } } - IF( allowed_bits > 0 ) + if ( allowed_bits > 0 ) { - IF( byteBuffer == 1 ) + if ( byteBuffer == 1 ) { - nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); + nbits = read_common_direction( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); } - ELSE + else { - IF( q_direction->cfg.nblocks == 1 && q_direction->band_data[i].bits_sph_idx[0] <= MASA_MIN_BITS_TF + 1 ) + if ( q_direction->cfg.nblocks == 1 && q_direction->band_data[i].bits_sph_idx[0] <= MASA_MIN_BITS_TF + 1 ) { /* there is fixed rate only, no need to read */ fixed_rate = 1; nbits = 0; } - ELSE + else { /* check if fixed_rate */ fixed_rate = bitstream[bit_pos--]; nbits = 1; } - IF( fixed_rate == 1 ) + if ( fixed_rate == 1 ) { /* decode_fixed_rate()*/ - nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); } - ELSE + else { - /* decode elevation */ - nbits += decode_elevation_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_elevation( q_direction, bitstream, &bit_pos, i, masa_subframes ); + /* decode azimuth */ - nbits += decode_azimuth_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_azimuth( q_direction, bitstream, &bit_pos, i, masa_subframes ); } } } - ELSE + else { - set_zero_direction_fx( q_direction, i, masa_subframes ); + set_zero_direction( q_direction, i, masa_subframes ); } - diff += nbits - allowed_bits; /* update bits for next block */ update_bits_next_block( q_direction, &diff, ind_order[j + 1], coding_subbands, masa_subframes ); } } - ELSE + else { last_j = q_direction->cfg.start_band; } - FOR( j = last_j; j < coding_subbands; j++ ) + for ( j = last_j; j < coding_subbands; j++ ) { i = ind_order[j]; - bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; + bits_dir0 = (int16_t *) q_direction->band_data[i].bits_sph_idx; nbits = 0; allowed_bits = sum_s( bits_dir0, q_direction->cfg.nblocks ); - IF( allowed_bits > 0 && masa_subframes == 1 ) + if ( allowed_bits > 0 && masa_subframes == 1 ) { - nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); } - ELSE + else { - IF( allowed_bits > 0 ) + if ( allowed_bits > 0 ) { use_vq = 0; max_nb_idx = 0; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( bits_dir0[k] > use_vq ) + if ( bits_dir0[k] > use_vq ) { use_vq = bits_dir0[k]; max_nb_idx = k; @@ -3780,7 +3792,7 @@ static Word16 read_directions_fx( byteBuffer = 0; - IF( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) + if ( use_vq > 1 && use_vq <= LIMIT_USE_COMMON ) { bits_dir0[max_nb_idx] -= 1; allowed_bits -= 1; @@ -3789,43 +3801,42 @@ static Word16 read_directions_fx( byteBuffer = bitstream[bit_pos--]; } - IF( allowed_bits > 0 ) + if ( allowed_bits > 0 ) { - IF( byteBuffer == 1 || use_vq <= 1 ) + if ( byteBuffer == 1 || use_vq <= 1 ) { - nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); + nbits = read_common_direction( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); } - ELSE + else { /* decode_fixed_rate()*/ - nbits += decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ); + nbits += decode_fixed_rate( q_direction, bitstream, &bit_pos, i, masa_subframes ); } } - ELSE + else { - set_zero_direction_fx( q_direction, i, masa_subframes ); + set_zero_direction( q_direction, i, masa_subframes ); } } - ELSE + else { - set_zero_direction_fx( q_direction, i, masa_subframes ); + set_zero_direction( q_direction, i, masa_subframes ); } } } } - ELSE + else { /* 2D */ - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { - FOR( k = 0; k < q_direction->cfg.nblocks; k++ ) + for ( k = 0; k < q_direction->cfg.nblocks; k++ ) { - q_direction->band_data[j].elevation_fx[k] = 0; + q_direction->band_data[j].elevation[k] = 0; q_direction->band_data[j].elevation_index[k] = 0; } } - - nbits = decode_azimuth2D_fx( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); + nbits = decode_azimuth2D( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); } nbits = *pbit_pos - bit_pos; *pbit_pos = bit_pos; @@ -3841,18 +3852,19 @@ static Word16 read_directions_fx( *-------------------------------------------------------------------*/ /*! r: number of bits read */ -static int16_t decode_azimuth( +#ifdef IVAS_FLOAT_FIXED +static Word16 decode_azimuth_fx( IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - uint16_t *bitstream, /* i : bitstream to be read */ - int16_t *pbit_pos, /* i/o: current position in bitstream */ - const int16_t idx_subband, /* i : subband index */ - const int16_t masa_subframes /* i : number of tiles */ + UWord16 *bitstream, /* i : bitstream to be read */ + Word16 *pbit_pos, /* i/o: current position in bitstream */ + const Word16 idx_subband, /* i : subband index */ + const Word16 masa_subframes /* i : number of tiles */ ) { - int16_t bit_pos, nbits, k; - uint16_t use_context, byteBuffer; - uint16_t min_idx; - int16_t j_az, max_val; + Word16 bit_pos, nbits, k; + UWord16 use_context, byteBuffer; + UWord16 min_idx; + Word16 j_az, max_val; nbits = 0; bit_pos = *pbit_pos; @@ -3860,95 +3872,96 @@ static int16_t decode_azimuth( j_az = 0; /* check number of valid indexes to decode */ - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[idx_subband].azimuth_index[k] < MASA_NO_INDEX ) + IF( q_direction->band_data[idx_subband].azimuth_index[k] < MASA_NO_INDEX ) { j_az++; } - else + ELSE { - q_direction->band_data[idx_subband].azimuth[k] = 0.f; /*To be in sync with encoder values.*/ + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; /*To be in sync with encoder values.*/ } } - if ( j_az == 0 ) + IF( j_az == 0 ) { return nbits; } - if ( byteBuffer == 0 ) + IF( byteBuffer == 0 ) { /* use context */ use_context = 0; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[idx_subband].bits_sph_idx[k] <= 1 ) + IF( q_direction->band_data[idx_subband].bits_sph_idx[k] <= 1 ) { use_context = 1; } } - if ( use_context == 1 ) + IF( use_context == 1 ) { - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 ) + IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 ) { q_direction->band_data[idx_subband].azimuth_index[k] = 0; - q_direction->band_data[idx_subband].azimuth[k] = 0; + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; } - else + ELSE { - if ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 1 ) + IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 1 ) { byteBuffer = bitstream[bit_pos--]; q_direction->band_data[idx_subband].azimuth_index[k] = byteBuffer; - q_direction->band_data[idx_subband].azimuth[k] = q_direction->band_data[idx_subband].azimuth_index[k] * ( -180.f ); + q_direction->band_data[idx_subband].azimuth_fx[k] = L_shl( q_direction->band_data[idx_subband].azimuth_index[k] * ( -180 ), 22 ); } - else + ELSE { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 2 ) ); - q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + // q_direction->band_data[idx_subband].azimuth_fx[k] = (float)deindex_azimuth_fx(q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup) / (float) (1<<22); } } } } - else + ELSE { /* read bit to check if min removed encoding */ byteBuffer = bitstream[bit_pos--]; - if ( byteBuffer == 0 ) /* regular GR coding5 */ + IF( byteBuffer == 0 ) /* regular GR coding5 */ { /* read GR_order */ byteBuffer = bitstream[bit_pos--]; nbits += 1; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) + IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) { - if ( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) + IF( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - byteBuffer ); - q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); } - else + ELSE { - q_direction->band_data[idx_subband].azimuth[k] = 0; + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } - else + ELSE { - q_direction->band_data[idx_subband].azimuth[k] = 0; + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } } - else + ELSE { /* min removed GR coding */ /* read GR_order */ @@ -3957,25 +3970,25 @@ static int16_t decode_azimuth( maximum_s( q_direction->band_data[idx_subband].azimuth_m_alphabet, masa_subframes, &max_val ); min_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, max_val, MASA_GR_ORD_AZ ); - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) + IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) { - if ( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) + IF( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - 1 - byteBuffer ); q_direction->band_data[idx_subband].azimuth_index[k] += min_idx; - q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); } - else + ELSE { - q_direction->band_data[idx_subband].azimuth[k] = 0; + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } - else + ELSE { - q_direction->band_data[idx_subband].azimuth[k] = 0; + q_direction->band_data[idx_subband].azimuth_fx[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } @@ -3989,20 +4002,19 @@ static int16_t decode_azimuth( return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 decode_azimuth_fx( +#else +static int16_t decode_azimuth( IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - UWord16 *bitstream, /* i : bitstream to be read */ - Word16 *pbit_pos, /* i/o: current position in bitstream */ - const Word16 idx_subband, /* i : subband index */ - const Word16 masa_subframes /* i : number of tiles */ + uint16_t *bitstream, /* i : bitstream to be read */ + int16_t *pbit_pos, /* i/o: current position in bitstream */ + const int16_t idx_subband, /* i : subband index */ + const int16_t masa_subframes /* i : number of tiles */ ) { - Word16 bit_pos, nbits, k; - UWord16 use_context, byteBuffer; - UWord16 min_idx; - Word16 j_az, max_val; + int16_t bit_pos, nbits, k; + uint16_t use_context, byteBuffer; + uint16_t min_idx; + int16_t j_az, max_val; nbits = 0; bit_pos = *pbit_pos; @@ -4010,96 +4022,95 @@ static Word16 decode_azimuth_fx( j_az = 0; /* check number of valid indexes to decode */ - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[idx_subband].azimuth_index[k] < MASA_NO_INDEX ) + if ( q_direction->band_data[idx_subband].azimuth_index[k] < MASA_NO_INDEX ) { j_az++; } - ELSE + else { - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; /*To be in sync with encoder values.*/ + q_direction->band_data[idx_subband].azimuth[k] = 0.f; /*To be in sync with encoder values.*/ } } - IF( j_az == 0 ) + if ( j_az == 0 ) { return nbits; } - IF( byteBuffer == 0 ) + if ( byteBuffer == 0 ) { /* use context */ use_context = 0; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[idx_subband].bits_sph_idx[k] <= 1 ) + if ( q_direction->band_data[idx_subband].bits_sph_idx[k] <= 1 ) { use_context = 1; } } - IF( use_context == 1 ) + if ( use_context == 1 ) { - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 ) + if ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 ) { q_direction->band_data[idx_subband].azimuth_index[k] = 0; - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; + q_direction->band_data[idx_subband].azimuth[k] = 0; } - ELSE + else { - IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 1 ) + if ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 1 ) { byteBuffer = bitstream[bit_pos--]; q_direction->band_data[idx_subband].azimuth_index[k] = byteBuffer; - q_direction->band_data[idx_subband].azimuth_fx[k] = L_shl( q_direction->band_data[idx_subband].azimuth_index[k] * ( -180 ), 22 ); + q_direction->band_data[idx_subband].azimuth[k] = q_direction->band_data[idx_subband].azimuth_index[k] * ( -180.f ); } - ELSE + else { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - ( q_direction->band_data[idx_subband].bits_sph_idx[k] == 2 ) ); - q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); - // q_direction->band_data[idx_subband].azimuth_fx[k] = (float)deindex_azimuth_fx(q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup) / (float) (1<<22); + q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); } } } } - ELSE + else { /* read bit to check if min removed encoding */ byteBuffer = bitstream[bit_pos--]; - IF( byteBuffer == 0 ) /* regular GR coding5 */ + if ( byteBuffer == 0 ) /* regular GR coding5 */ { /* read GR_order */ byteBuffer = bitstream[bit_pos--]; nbits += 1; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) + if ( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) { - IF( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) + if ( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - byteBuffer ); - q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); } - ELSE + else { - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; + q_direction->band_data[idx_subband].azimuth[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } - ELSE + else { - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; + q_direction->band_data[idx_subband].azimuth[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } } - ELSE + else { /* min removed GR coding */ /* read GR_order */ @@ -4108,25 +4119,25 @@ static Word16 decode_azimuth_fx( maximum_s( q_direction->band_data[idx_subband].azimuth_m_alphabet, masa_subframes, &max_val ); min_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, max_val, MASA_GR_ORD_AZ ); - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) + if ( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 ) { - IF( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) + if ( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]] > 1 ) { q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], MASA_GR_ORD_AZ - 1 - byteBuffer ); q_direction->band_data[idx_subband].azimuth_index[k] += min_idx; - q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); + q_direction->band_data[idx_subband].azimuth[k] = deindex_azimuth( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); } - ELSE + else { - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; + q_direction->band_data[idx_subband].azimuth[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } - ELSE + else { - q_direction->band_data[idx_subband].azimuth_fx[k] = 0; + q_direction->band_data[idx_subband].azimuth[k] = 0; q_direction->band_data[idx_subband].azimuth_index[k] = 0; } } @@ -4150,111 +4161,112 @@ static Word16 decode_azimuth_fx( *-------------------------------------------------------------------*/ /*! r: number of bits read */ -static int16_t decode_elevation( +#ifdef IVAS_FLOAT_FIXED +static Word16 decode_elevation_fx( IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - uint16_t *bitstream, /* i : input bitstream */ - int16_t *pbit_pos, /* i/o: current position to be read in bitstream*/ - const int16_t j, /* i : subband index */ - const int16_t masa_subframes /* i : number of tiles */ + UWord16 *bitstream, /* i : input bitstream */ + Word16 *pbit_pos, /* i/o: current position to be read in bitstream*/ + const Word16 j, /* i : subband index */ + const Word16 masa_subframes /* i : number of tiles */ ) { - int16_t nr_NO_INDEX, nbits; - int16_t bit_pos; - uint16_t byteBuffer; - int16_t k, GR_ord_elevation; - uint16_t same_idx; + Word16 nr_NO_INDEX, nbits; + Word16 bit_pos; + UWord16 byteBuffer; + Word16 k, GR_ord_elevation; + UWord16 same_idx; nr_NO_INDEX = 0; nbits = 0; bit_pos = *pbit_pos; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { q_direction->band_data[j].elevation_index[k] = 0; - q_direction->band_data[j].elevation[k] = 0; + q_direction->band_data[j].elevation_fx[k] = 0; - if ( q_direction->band_data[j].bits_sph_idx[k] > 0 ) + IF( q_direction->band_data[j].bits_sph_idx[k] > 0 ) { - if ( q_direction->band_data[j].bits_sph_idx[k] <= 2 ) + IF( q_direction->band_data[j].bits_sph_idx[k] <= 2 ) { q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX; nr_NO_INDEX += 1; - q_direction->band_data[j].elevation[k] = 0; + q_direction->band_data[j].elevation_fx[k] = 0; q_direction->band_data[j].elevation_m_alphabet[k] = 1; } - else + ELSE { - if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3]; } - else + ELSE { q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3] * 2 - 1; } } } - else + ELSE { nr_NO_INDEX++; } } - if ( nr_NO_INDEX < masa_subframes ) + IF( nr_NO_INDEX < masa_subframes ) { { /* read if same or not */ byteBuffer = bitstream[bit_pos--]; - if ( byteBuffer == 1 ) /* same value */ + IF( byteBuffer == 1 ) /* same value */ { /* read value */ byteBuffer = bitstream[bit_pos--]; byteBuffer = ( byteBuffer << 1 ) + bitstream[bit_pos--]; same_idx = byteBuffer; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].elevation_index[k] = same_idx; - q_direction->band_data[j].elevation[k] = deindex_elevation( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); + q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); } } } - else + ELSE { /* not same; decode mean removed GR */ byteBuffer = bitstream[bit_pos--]; GR_ord_elevation = MASA_GR_ORD_EL - byteBuffer; - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].elevation_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[j].elevation_m_alphabet[k], GR_ord_elevation ); - q_direction->band_data[j].elevation[k] = deindex_elevation( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); + q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); } } } } } - for ( k = 0; k < masa_subframes; k++ ) + FOR( k = 0; k < masa_subframes; k++ ) { - if ( ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) && - ( no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]] <= 1 ) ) + IF( ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) && + ( no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]] <= 1 ) ) { q_direction->band_data[j].azimuth_index[k] = MASA_NO_INDEX; q_direction->band_data[j].azimuth_m_alphabet[k] = 1; } - else + ELSE { q_direction->band_data[j].azimuth_index[k] = 0; - if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]]; } - else + ELSE { q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][0]; q_direction->band_data[j].elevation_index[k] = 0; @@ -4267,113 +4279,112 @@ static int16_t decode_elevation( return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 decode_elevation_fx( +#else +static int16_t decode_elevation( IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - UWord16 *bitstream, /* i : input bitstream */ - Word16 *pbit_pos, /* i/o: current position to be read in bitstream*/ - const Word16 j, /* i : subband index */ - const Word16 masa_subframes /* i : number of tiles */ + uint16_t *bitstream, /* i : input bitstream */ + int16_t *pbit_pos, /* i/o: current position to be read in bitstream*/ + const int16_t j, /* i : subband index */ + const int16_t masa_subframes /* i : number of tiles */ ) { - Word16 nr_NO_INDEX, nbits; - Word16 bit_pos; - UWord16 byteBuffer; - Word16 k, GR_ord_elevation; - UWord16 same_idx; + int16_t nr_NO_INDEX, nbits; + int16_t bit_pos; + uint16_t byteBuffer; + int16_t k, GR_ord_elevation; + uint16_t same_idx; nr_NO_INDEX = 0; nbits = 0; bit_pos = *pbit_pos; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { q_direction->band_data[j].elevation_index[k] = 0; - q_direction->band_data[j].elevation_fx[k] = 0; + q_direction->band_data[j].elevation[k] = 0; - IF( q_direction->band_data[j].bits_sph_idx[k] > 0 ) + if ( q_direction->band_data[j].bits_sph_idx[k] > 0 ) { - IF( q_direction->band_data[j].bits_sph_idx[k] <= 2 ) + if ( q_direction->band_data[j].bits_sph_idx[k] <= 2 ) { q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX; nr_NO_INDEX += 1; - q_direction->band_data[j].elevation_fx[k] = 0; + q_direction->band_data[j].elevation[k] = 0; q_direction->band_data[j].elevation_m_alphabet[k] = 1; } - ELSE + else { - IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3]; } - ELSE + else { q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3] * 2 - 1; } } } - ELSE + else { nr_NO_INDEX++; } } - IF( nr_NO_INDEX < masa_subframes ) + if ( nr_NO_INDEX < masa_subframes ) { { /* read if same or not */ byteBuffer = bitstream[bit_pos--]; - IF( byteBuffer == 1 ) /* same value */ + if ( byteBuffer == 1 ) /* same value */ { /* read value */ byteBuffer = bitstream[bit_pos--]; byteBuffer = ( byteBuffer << 1 ) + bitstream[bit_pos--]; same_idx = byteBuffer; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].elevation_index[k] = same_idx; - q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); + q_direction->band_data[j].elevation[k] = deindex_elevation( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); } } } - ELSE + else { /* not same; decode mean removed GR */ byteBuffer = bitstream[bit_pos--]; GR_ord_elevation = MASA_GR_ORD_EL - byteBuffer; - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].elevation_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[j].elevation_m_alphabet[k], GR_ord_elevation ); - q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); + q_direction->band_data[j].elevation[k] = deindex_elevation( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); } } } } } - FOR( k = 0; k < masa_subframes; k++ ) + for ( k = 0; k < masa_subframes; k++ ) { - IF( ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) && - ( no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]] <= 1 ) ) + if ( ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) && + ( no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]] <= 1 ) ) { q_direction->band_data[j].azimuth_index[k] = MASA_NO_INDEX; q_direction->band_data[j].azimuth_m_alphabet[k] = 1; } - ELSE + else { q_direction->band_data[j].azimuth_index[k] = 0; - IF( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) + if ( q_direction->band_data[j].elevation_index[k] < MASA_NO_INDEX ) { q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][q_direction->band_data[j].elevation_index[k]]; } - ELSE + else { q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[q_direction->band_data[j].bits_sph_idx[k] - 1][0]; q_direction->band_data[j].elevation_index[k] = 0; @@ -4463,6 +4474,93 @@ static Word16 decode_fixed_rate_fx( *-------------------------------------------------------------------*/ /*! r: number of bits read */ +#ifdef IVAS_FLOAT_FIXED +static Word16 decode_azimuth2D_fx( + IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ + UWord16 *bitstream, /* i : bitstream to be read */ + const Word16 coding_subbands, /* i : number of subbands */ + Word16 *pbit_pos, + const Word16 no_frames ) +{ + Word16 i, j, k; + Word16 allowed_bits, nbits; + Word16 use_vq; + UWord16 Buffer; + Word16 bit_pos; + Word16 *bits_dir0; + + bit_pos = *pbit_pos; + nbits = 0; + FOR( j = 0; j < coding_subbands; j++ ) + { + bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; + allowed_bits = sum_s( bits_dir0, no_frames ); + + IF( allowed_bits > 0 ) + { + use_vq = 0; + FOR( k = 0; k < no_frames; k++ ) + { + q_direction->band_data[j].elevation_fx[k] = 0; + q_direction->band_data[j].elevation_index[k] = 0; + + IF( bits_dir0[k] > use_vq ) + { + use_vq = bits_dir0[k]; + } + } + + IF( use_vq <= 3 && allowed_bits <= 11 ) + { + IF( allowed_bits <= no_frames + 1 ) + { + set_l( q_direction->band_data[j].azimuth_fx, 0, no_frames ); + FOR( k = 0; k < min( allowed_bits, no_frames ); k++ ) + { + q_direction->band_data[j].azimuth_fx[k] = L_shl( -180 * bitstream[bit_pos--], 22 ); + nbits += 1; + } + } + ELSE + { + nbits += read_truncGR_azimuth_fx( bitstream, q_direction, j, no_frames, &bit_pos ); + } + } + ELSE + { + FOR( k = 0; k < no_frames; k++ ) + { + Buffer = 0; + FOR( i = 0; i < bits_dir0[k]; i++ ) + { + Buffer = ( Buffer << 1 ) + bitstream[bit_pos--]; + } + + nbits += bits_dir0[k]; + + IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + { + q_direction->band_data[j].azimuth_fx[k] = L_shl( 360, 22 - bits_dir0[k] ) * Buffer - L_shl( 180, 22 ); + q_direction->band_data[j].azimuth_fx[k] = companding_azimuth_fx( q_direction->band_data[j].azimuth_fx[k], q_direction->cfg.mc_ls_setup, + ( q_direction->band_data[j].elevation_fx[k] > MC_MASA_THR_ELEVATION * ( 1 << 22 ) ), -1 ); + } + ELSE + { + q_direction->band_data[j].azimuth_fx[k] = L_shl( 360, 22 - bits_dir0[k] ) * Buffer - L_shl( 180, 22 ); + } + } + } + } + ELSE + { + set_zero_direction_fx( q_direction, j, no_frames ); + } + } + *pbit_pos = bit_pos; + + return nbits; +} +#else static int16_t decode_azimuth2D( IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ uint16_t *bitstream, /* i : bitstream to be read */ @@ -4548,101 +4646,34 @@ static int16_t decode_azimuth2D( return nbits; } +#endif + +/*-------------------------------------------------------------------* + * set_zero_direction() + * + * + *-------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static Word16 decode_azimuth2D_fx( - IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - UWord16 *bitstream, /* i : bitstream to be read */ - const Word16 coding_subbands, /* i : number of subbands */ - Word16 *pbit_pos, - const Word16 no_frames ) +static void set_zero_direction_fx( + IVAS_QDIRECTION *q_direction, + const Word16 idx_band, + const Word16 len ) { - Word16 i, j, k; - Word16 allowed_bits, nbits; - Word16 use_vq; - UWord16 Buffer; - Word16 bit_pos; - Word16 *bits_dir0; + Word16 k; - bit_pos = *pbit_pos; - nbits = 0; - FOR( j = 0; j < coding_subbands; j++ ) + FOR( k = 0; k < len; k++ ) { - bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; - allowed_bits = sum_s( bits_dir0, no_frames ); - - IF( allowed_bits > 0 ) - { - use_vq = 0; - FOR( k = 0; k < no_frames; k++ ) - { - q_direction->band_data[j].elevation_fx[k] = 0; - q_direction->band_data[j].elevation_index[k] = 0; - - IF( bits_dir0[k] > use_vq ) - { - use_vq = bits_dir0[k]; - } - } - - IF( use_vq <= 3 && allowed_bits <= 11 ) - { - IF( allowed_bits <= no_frames + 1 ) - { - set_l( q_direction->band_data[j].azimuth_fx, 0, no_frames ); - FOR( k = 0; k < min( allowed_bits, no_frames ); k++ ) - { - q_direction->band_data[j].azimuth_fx[k] = L_shl( -180 * bitstream[bit_pos--], 22 ); - nbits += 1; - } - } - ELSE - { - nbits += read_truncGR_azimuth_fx( bitstream, q_direction, j, no_frames, &bit_pos ); - } - } - ELSE - { - FOR( k = 0; k < no_frames; k++ ) - { - Buffer = 0; - FOR( i = 0; i < bits_dir0[k]; i++ ) - { - Buffer = ( Buffer << 1 ) + bitstream[bit_pos--]; - } - - nbits += bits_dir0[k]; - - IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) - { - q_direction->band_data[j].azimuth_fx[k] = L_shl( 360, 22 - bits_dir0[k] ) * Buffer - L_shl( 180, 22 ); - q_direction->band_data[j].azimuth_fx[k] = companding_azimuth_fx( q_direction->band_data[j].azimuth_fx[k], q_direction->cfg.mc_ls_setup, - ( q_direction->band_data[j].elevation_fx[k] > MC_MASA_THR_ELEVATION * ( 1 << 22 ) ), -1 ); - } - ELSE - { - q_direction->band_data[j].azimuth_fx[k] = L_shl( 360, 22 - bits_dir0[k] ) * Buffer - L_shl( 180, 22 ); - } - } - } - } - ELSE - { - set_zero_direction_fx( q_direction, j, no_frames ); - } + q_direction->band_data[idx_band].azimuth_fx[k] = 0; + q_direction->band_data[idx_band].azimuth_index[k] = 0; + q_direction->band_data[idx_band].elevation_fx[k] = 0; + q_direction->band_data[idx_band].elevation_index[k] = 0; + q_direction->band_data[idx_band].spherical_index[k] = 0; } - *pbit_pos = bit_pos; - return nbits; + return; } -#endif - -/*-------------------------------------------------------------------* - * set_zero_direction() - * - * - *-------------------------------------------------------------------*/ - +#else static void set_zero_direction( IVAS_QDIRECTION *q_direction, const int16_t idx_band, @@ -4661,26 +4692,6 @@ static void set_zero_direction( return; } - -#ifdef IVAS_FLOAT_FIXED -static void set_zero_direction_fx( - IVAS_QDIRECTION *q_direction, - const Word16 idx_band, - const Word16 len ) -{ - Word16 k; - - FOR( k = 0; k < len; k++ ) - { - q_direction->band_data[idx_band].azimuth_fx[k] = 0; - q_direction->band_data[idx_band].azimuth_index[k] = 0; - q_direction->band_data[idx_band].elevation_fx[k] = 0; - q_direction->band_data[idx_band].elevation_index[k] = 0; - q_direction->band_data[idx_band].spherical_index[k] = 0; - } - - return; -} #endif @@ -4690,32 +4701,33 @@ static void set_zero_direction_fx( * *-------------------------------------------------------------------*/ -static int16_t read_truncGR_azimuth( - uint16_t *bitstream, /* i : bitstream to be read */ +#ifdef IVAS_FLOAT_FIXED +static Word16 read_truncGR_azimuth_fx( + UWord16 *bitstream, /* i : bitstream to be read */ IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - const int16_t j, /* i : subband index */ - const int16_t no_subframes, /* i : number of tiles */ - int16_t *pbit_pos /* i/o: position in bitstream */ + const Word16 j, /* i : subband index */ + const Word16 no_subframes, /* i : number of tiles */ + Word16 *pbit_pos /* i/o: position in bitstream */ ) { - int16_t i; - int16_t nbits; - uint16_t idx; - int16_t no_symb, allowed_bits; + Word16 i; + Word16 nbits; + UWord16 idx; + Word16 no_symb, allowed_bits; - allowed_bits = sum_s( (int16_t *) q_direction->band_data[j].bits_sph_idx, no_subframes ); + allowed_bits = sum_s( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ); nbits = 0; - if ( allowed_bits <= no_subframes + 1 ) + IF( allowed_bits <= no_subframes + 1 ) { - for ( i = 0; i < min( allowed_bits, no_subframes ); i++ ) + FOR( i = 0; i < min( allowed_bits, no_subframes ); i++ ) { - if ( bitstream[( *pbit_pos )--] == 0 ) + IF( bitstream[( *pbit_pos )--] == 0 ) { - q_direction->band_data[j].azimuth[i] = 0.0f; + q_direction->band_data[j].azimuth_fx[i] = 0; } - else + ELSE { - q_direction->band_data[j].azimuth[i] = -180; + q_direction->band_data[j].azimuth_fx[i] = L_shl( -180, 22 ); } nbits++; } @@ -4723,11 +4735,11 @@ static int16_t read_truncGR_azimuth( return nbits; } - if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { no_symb = 9; } - else + ELSE { no_symb = 8; } @@ -4735,21 +4747,21 @@ static int16_t read_truncGR_azimuth( nbits = *pbit_pos; - for ( i = 0; i < no_subframes; i++ ) + FOR( i = 0; i < no_subframes; i++ ) { idx = ivas_qmetadata_DecodeExtendedGR( bitstream, pbit_pos, no_symb, 0 ); q_direction->band_data[j].azimuth_index[i] = idx; - if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { - q_direction->band_data[j].azimuth[i] = cb_azi_chan[( idx + 1 ) >> 1]; - if ( idx % 2 > 0 ) + q_direction->band_data[j].azimuth_fx[i] = cb_azi_chan_fx[( idx + 1 ) >> 1]; + IF( idx % 2 > 0 ) { - q_direction->band_data[j].azimuth[i] = -q_direction->band_data[j].azimuth[i]; + q_direction->band_data[j].azimuth_fx[i] = -q_direction->band_data[j].azimuth_fx[i]; } } - else + ELSE { - q_direction->band_data[j].azimuth[i] = azimuth_cb[idx]; + q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[idx]; } } @@ -4757,34 +4769,33 @@ static int16_t read_truncGR_azimuth( return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 read_truncGR_azimuth_fx( - UWord16 *bitstream, /* i : bitstream to be read */ +#else +static int16_t read_truncGR_azimuth( + uint16_t *bitstream, /* i : bitstream to be read */ IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure */ - const Word16 j, /* i : subband index */ - const Word16 no_subframes, /* i : number of tiles */ - Word16 *pbit_pos /* i/o: position in bitstream */ + const int16_t j, /* i : subband index */ + const int16_t no_subframes, /* i : number of tiles */ + int16_t *pbit_pos /* i/o: position in bitstream */ ) { - Word16 i; - Word16 nbits; - UWord16 idx; - Word16 no_symb, allowed_bits; + int16_t i; + int16_t nbits; + uint16_t idx; + int16_t no_symb, allowed_bits; - allowed_bits = sum_s( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ); + allowed_bits = sum_s( (int16_t *) q_direction->band_data[j].bits_sph_idx, no_subframes ); nbits = 0; - IF( allowed_bits <= no_subframes + 1 ) + if ( allowed_bits <= no_subframes + 1 ) { - FOR( i = 0; i < min( allowed_bits, no_subframes ); i++ ) + for ( i = 0; i < min( allowed_bits, no_subframes ); i++ ) { - IF( bitstream[( *pbit_pos )--] == 0 ) + if ( bitstream[( *pbit_pos )--] == 0 ) { - q_direction->band_data[j].azimuth_fx[i] = 0; + q_direction->band_data[j].azimuth[i] = 0.0f; } - ELSE + else { - q_direction->band_data[j].azimuth_fx[i] = L_shl( -180, 22 ); + q_direction->band_data[j].azimuth[i] = -180; } nbits++; } @@ -4792,11 +4803,11 @@ static Word16 read_truncGR_azimuth_fx( return nbits; } - IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { no_symb = 9; } - ELSE + else { no_symb = 8; } @@ -4804,21 +4815,21 @@ static Word16 read_truncGR_azimuth_fx( nbits = *pbit_pos; - FOR( i = 0; i < no_subframes; i++ ) + for ( i = 0; i < no_subframes; i++ ) { idx = ivas_qmetadata_DecodeExtendedGR( bitstream, pbit_pos, no_symb, 0 ); q_direction->band_data[j].azimuth_index[i] = idx; - IF( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) + if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { - q_direction->band_data[j].azimuth_fx[i] = cb_azi_chan_fx[( idx + 1 ) >> 1]; - IF( idx % 2 > 0 ) + q_direction->band_data[j].azimuth[i] = cb_azi_chan[( idx + 1 ) >> 1]; + if ( idx % 2 > 0 ) { - q_direction->band_data[j].azimuth_fx[i] = -q_direction->band_data[j].azimuth_fx[i]; + q_direction->band_data[j].azimuth[i] = -q_direction->band_data[j].azimuth[i]; } } - ELSE + else { - q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[idx]; + q_direction->band_data[j].azimuth[i] = azimuth_cb[idx]; } } @@ -4835,37 +4846,38 @@ static Word16 read_truncGR_azimuth_fx( *-------------------------------------------------------------------*/ /*! r: number of bits read */ -static int16_t read_common_direction( - uint16_t *bitstream, /* i : bitstream to be read */ +#ifdef IVAS_FLOAT_FIXED +static Word16 read_common_direction_fx( + UWord16 *bitstream, /* i : bitstream to be read */ IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - const int16_t j, /* i : subband index */ - const int16_t no_subframes, /* i : number of tiles */ - const int16_t bits_total, /* i : number of bits for subband directional data */ - int16_t *pbit_pos /* i/o: position in bitstream */ + const Word16 j, /* i : subband index */ + const Word16 no_subframes, /* i : number of tiles */ + const Word16 bits_total, /* i : number of bits for subband directional data */ + Word16 *pbit_pos /* i/o: position in bitstream */ ) { - int16_t nbits; - int16_t bit_pos; - int16_t i; - uint16_t byteBuffer; - int16_t bits_el; + Word16 nbits; + Word16 bit_pos; + Word16 i; + UWord16 byteBuffer; + Word16 bits_el; bit_pos = *pbit_pos; nbits = 0; - set_zero_direction( q_direction, j, no_subframes ); - if ( bits_total == 0 ) + set_zero_direction_fx( q_direction, j, no_subframes ); + IF( bits_total == 0 ) { return nbits; } - if ( bits_total <= no_subframes + 1 ) + IF( bits_total <= no_subframes + 1 ) { - for ( i = 0; i < min( no_subframes, bits_total ); i++ ) + FOR( i = 0; i < min( no_subframes, bits_total ); i++ ) { byteBuffer = bitstream[bit_pos--]; /*qdirection->azimuth_index[j][i] = (uint16_t)byteBuffer; */ - q_direction->band_data[j].azimuth[i] = azimuth_cb[byteBuffer]; + q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; nbits += 1; } *pbit_pos = bit_pos; @@ -4879,44 +4891,44 @@ static int16_t read_common_direction( bits_el = 1; nbits += 1; /* elevation is already set to 0*/ - if ( byteBuffer == 1 ) + IF( byteBuffer == 1 ) { byteBuffer = bitstream[bit_pos--]; bits_el += 1; nbits += 1; - if ( byteBuffer == 0 ) + IF( byteBuffer == 0 ) { - for ( i = 0; i < no_subframes; i++ ) + FOR( i = 0; i < no_subframes; i++ ) { - q_direction->band_data[j].elevation[i] = delta_theta_masa[2]; + q_direction->band_data[j].elevation_fx[i] = delta_theta_masa_fx[2]; } } - else + ELSE { byteBuffer = bitstream[bit_pos--]; bits_el += 1; nbits += 1; - if ( byteBuffer == 0 ) + IF( byteBuffer == 0 ) { - for ( i = 0; i < no_subframes; i++ ) + FOR( i = 0; i < no_subframes; i++ ) { - q_direction->band_data[j].elevation[i] = -delta_theta_masa[2]; + q_direction->band_data[j].elevation_fx[i] = -delta_theta_masa_fx[2]; } } - else + ELSE { /* theta is +/- 90; no azimuth is read */ byteBuffer = bitstream[bit_pos--]; nbits += 1; - if ( byteBuffer == 0 ) + IF( byteBuffer == 0 ) { - set_f( q_direction->band_data[j].elevation, 90.0f, no_subframes ); - set_f( q_direction->band_data[j].azimuth, 0.0f, no_subframes ); + set32_fx( q_direction->band_data[j].elevation_fx, 90 << 22, no_subframes ); + set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); } - else + ELSE { - set_f( q_direction->band_data[j].elevation, -90.0f, no_subframes ); - set_f( q_direction->band_data[j].azimuth, 0.0f, no_subframes ); + set32_fx( q_direction->band_data[j].elevation_fx, -90, no_subframes ); + set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); } *pbit_pos = bit_pos; @@ -4925,60 +4937,59 @@ static int16_t read_common_direction( } } - bits_el = sum_s( (int16_t *) q_direction->band_data[j].bits_sph_idx, no_subframes ) - bits_el; + bits_el = sum_s( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ) - bits_el; - if ( bits_el <= no_subframes + 1 ) + IF( bits_el <= no_subframes + 1 ) { nbits += min( no_subframes, bits_el ); - for ( i = 0; i < min( no_subframes, bits_el ); i++ ) + FOR( i = 0; i < min( no_subframes, bits_el ); i++ ) { byteBuffer = bitstream[bit_pos--]; /*qdirection->azimuth_index[j][i] = (uint16_t) byteBuffer; */ - q_direction->band_data[j].azimuth[i] = azimuth_cb[byteBuffer]; + q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; } } - else + ELSE { - nbits += read_truncGR_azimuth( bitstream, q_direction, j, no_subframes, &bit_pos ); + nbits += read_truncGR_azimuth_fx( bitstream, q_direction, j, no_subframes, &bit_pos ); } *pbit_pos = bit_pos; return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 read_common_direction_fx( - UWord16 *bitstream, /* i : bitstream to be read */ +#else +static int16_t read_common_direction( + uint16_t *bitstream, /* i : bitstream to be read */ IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - const Word16 j, /* i : subband index */ - const Word16 no_subframes, /* i : number of tiles */ - const Word16 bits_total, /* i : number of bits for subband directional data */ - Word16 *pbit_pos /* i/o: position in bitstream */ + const int16_t j, /* i : subband index */ + const int16_t no_subframes, /* i : number of tiles */ + const int16_t bits_total, /* i : number of bits for subband directional data */ + int16_t *pbit_pos /* i/o: position in bitstream */ ) { - Word16 nbits; - Word16 bit_pos; - Word16 i; - UWord16 byteBuffer; - Word16 bits_el; + int16_t nbits; + int16_t bit_pos; + int16_t i; + uint16_t byteBuffer; + int16_t bits_el; bit_pos = *pbit_pos; nbits = 0; - set_zero_direction_fx( q_direction, j, no_subframes ); - IF( bits_total == 0 ) + set_zero_direction( q_direction, j, no_subframes ); + if ( bits_total == 0 ) { return nbits; } - IF( bits_total <= no_subframes + 1 ) + if ( bits_total <= no_subframes + 1 ) { - FOR( i = 0; i < min( no_subframes, bits_total ); i++ ) + for ( i = 0; i < min( no_subframes, bits_total ); i++ ) { byteBuffer = bitstream[bit_pos--]; /*qdirection->azimuth_index[j][i] = (uint16_t)byteBuffer; */ - q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; + q_direction->band_data[j].azimuth[i] = azimuth_cb[byteBuffer]; nbits += 1; } *pbit_pos = bit_pos; @@ -4992,44 +5003,44 @@ static Word16 read_common_direction_fx( bits_el = 1; nbits += 1; /* elevation is already set to 0*/ - IF( byteBuffer == 1 ) + if ( byteBuffer == 1 ) { byteBuffer = bitstream[bit_pos--]; bits_el += 1; nbits += 1; - IF( byteBuffer == 0 ) + if ( byteBuffer == 0 ) { - FOR( i = 0; i < no_subframes; i++ ) + for ( i = 0; i < no_subframes; i++ ) { - q_direction->band_data[j].elevation_fx[i] = delta_theta_masa_fx[2]; + q_direction->band_data[j].elevation[i] = delta_theta_masa[2]; } } - ELSE + else { byteBuffer = bitstream[bit_pos--]; bits_el += 1; nbits += 1; - IF( byteBuffer == 0 ) + if ( byteBuffer == 0 ) { - FOR( i = 0; i < no_subframes; i++ ) + for ( i = 0; i < no_subframes; i++ ) { - q_direction->band_data[j].elevation_fx[i] = -delta_theta_masa_fx[2]; + q_direction->band_data[j].elevation[i] = -delta_theta_masa[2]; } } - ELSE + else { /* theta is +/- 90; no azimuth is read */ byteBuffer = bitstream[bit_pos--]; nbits += 1; - IF( byteBuffer == 0 ) + if ( byteBuffer == 0 ) { - set32_fx( q_direction->band_data[j].elevation_fx, 90 << 22, no_subframes ); - set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes ); + set_f( q_direction->band_data[j].elevation, 90.0f, no_subframes ); + set_f( q_direction->band_data[j].azimuth, 0.0f, no_subframes ); } - ELSE + else { - set32_fx( q_direction->band_data[j].elevation_fx, -90.0f, no_subframes ); - set32_fx( q_direction->band_data[j].azimuth_fx, 0.0f, no_subframes ); + set_f( q_direction->band_data[j].elevation, -90.0f, no_subframes ); + set_f( q_direction->band_data[j].azimuth, 0.0f, no_subframes ); } *pbit_pos = bit_pos; @@ -5038,21 +5049,21 @@ static Word16 read_common_direction_fx( } } - bits_el = sum_s( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ) - bits_el; + bits_el = sum_s( (int16_t *) q_direction->band_data[j].bits_sph_idx, no_subframes ) - bits_el; - IF( bits_el <= no_subframes + 1 ) + if ( bits_el <= no_subframes + 1 ) { nbits += min( no_subframes, bits_el ); - FOR( i = 0; i < min( no_subframes, bits_el ); i++ ) + for ( i = 0; i < min( no_subframes, bits_el ); i++ ) { byteBuffer = bitstream[bit_pos--]; /*qdirection->azimuth_index[j][i] = (uint16_t) byteBuffer; */ - q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; + q_direction->band_data[j].azimuth[i] = azimuth_cb[byteBuffer]; } } - ELSE + else { - nbits += read_truncGR_azimuth_fx( bitstream, q_direction, j, no_subframes, &bit_pos ); + nbits += read_truncGR_azimuth( bitstream, q_direction, j, no_subframes, &bit_pos ); } *pbit_pos = bit_pos; @@ -5065,224 +5076,224 @@ static Word16 read_common_direction_fx( * Local functions: coherence *-----------------------------------------------------------------------*/ -static void decode_spread_coherence( +#ifdef IVAS_FLOAT_FIXED +static void decode_spread_coherence_fx( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: quantized metadata structure */ - int16_t idx_d, /* i : direction index */ - const int16_t no_frames, /* i : number of time subframes */ - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ + Word16 idx_d, /* i : direction index */ + const Word16 no_frames, /* i : number of time subframes */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ ) { - int16_t i, j; - float var_azi; - int16_t idx_sub_cb; - float dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 i, j; + Word64 var_azi_fx; + Word16 idx_sub_cb; + Word32 dct_coh_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; IVAS_QDIRECTION *q_direction; - int16_t coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t min_index; + Word16 coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 min_index; coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands; coding_subbands = hQMetaData->q_direction[idx_d].cfg.nbands; - if ( coding_subbands_0 <= 5 ) + IF( coding_subbands_0 <= 5 ) { - for ( j = 0; j < 5; j++ ) + FOR( j = 0; j < 5; j++ ) { MASA_grouping[j] = j; } } - else + ELSE { - if ( coding_subbands_0 <= 8 ) + IF( coding_subbands_0 <= 8 ) { mvs2s( MASA_grouping_8_to_5, MASA_grouping, 8 ); } - else if ( coding_subbands_0 <= 12 ) + ELSE IF( coding_subbands_0 <= 12 ) { mvs2s( MASA_grouping_12_to_5, MASA_grouping, 12 ); } - else if ( coding_subbands_0 <= 18 ) + ELSE IF( coding_subbands_0 <= 18 ) { mvs2s( MASA_grouping_18_to_5, MASA_grouping, 18 ); } - else + ELSE { - if ( coding_subbands_0 <= 24 ) + IF( coding_subbands_0 <= 24 ) { mvs2s( MASA_grouping_24_to_5, MASA_grouping, 24 ); } } } - if ( coding_subbands < coding_subbands_0 ) + IF( coding_subbands < coding_subbands_0 ) { d = 0; - for ( j = 0; j < coding_subbands_0; j++ ) + FOR( j = 0; j < coding_subbands_0; j++ ) { - if ( hQMetaData->twoDirBands[j] == 1 ) + IF( hQMetaData->twoDirBands[j] == 1 ) { two_dir_band[d++] = j; } } } - else + ELSE { set_s( two_dir_band, 0, coding_subbands ); } q_direction = &hQMetaData->q_direction[idx_d]; - for ( i = 0; i < coding_subbands; i++ ) + FOR( i = 0; i < coding_subbands; i++ ) { - var_azi = var( q_direction->band_data[i].azimuth, no_frames ); - if ( hrmasa_flag ) + var_azi_fx = var_32_fx( q_direction->band_data[i].azimuth_fx, no_frames, 22 ); + IF( hrmasa_flag ) { minimum_s( (int16_t *) ( q_direction->band_data[i].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); min_index = min_index >> 1; } - else + ELSE { min_index = q_direction->band_data[i].energy_ratio_index[0]; } - if ( var_azi < MASA_DELTA_AZI_DCT0 ) + IF( var_azi_fx < L_shl( MASA_DELTA_AZI_DCT0, 22 ) ) { idx_sub_cb = MASA_NO_CV_COH * min_index; } - else + ELSE { idx_sub_cb = MASA_NO_CV_COH * ( min_index + DIRAC_DIFFUSE_LEVELS ); /* NO_CV_COH = 8 */ } - dct_coh[i][0] = coherence_cb0_masa[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index]; + dct_coh_fx[i][0] = coherence_cb0_masa_fx[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index]; - if ( coding_subbands < coding_subbands_0 ) + IF( coding_subbands < coding_subbands_0 ) { assert( idx_d == 1 ); - dct_coh[i][1] = coherence_cb1_masa[MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; + dct_coh_fx[i][1] = coherence_cb1_masa_fx[MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; } - else + ELSE { - dct_coh[i][1] = coherence_cb1_masa[MASA_grouping[i] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; + dct_coh_fx[i][1] = coherence_cb1_masa_fx[MASA_grouping[i] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; } - for ( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + FOR( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - dct_coh[i][j] = 0; + dct_coh_fx[i][j] = 0; } - invdct4_transform( dct_coh[i], q_direction->coherence_band_data[i].spread_coherence ); + invdct4_transform_fx( dct_coh_fx[i], q_direction->coherence_band_data[i].spread_coherence, 21 ); } return; } - -#ifdef IVAS_FLOAT_FIXED -static void decode_spread_coherence_fx( +#else +static void decode_spread_coherence( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: quantized metadata structure */ - Word16 idx_d, /* i : direction index */ - const Word16 no_frames, /* i : number of time subframes */ - const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ + int16_t idx_d, /* i : direction index */ + const int16_t no_frames, /* i : number of time subframes */ + const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ ) -{ - Word16 i, j; - Word64 var_azi_fx; - Word16 idx_sub_cb; - Word32 dct_coh_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; - Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; +{ + int16_t i, j; + float var_azi; + int16_t idx_sub_cb; + float dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; IVAS_QDIRECTION *q_direction; - Word16 coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; - Word16 min_index; + int16_t coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; + int16_t min_index; coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands; coding_subbands = hQMetaData->q_direction[idx_d].cfg.nbands; - IF( coding_subbands_0 <= 5 ) + if ( coding_subbands_0 <= 5 ) { - FOR( j = 0; j < 5; j++ ) + for ( j = 0; j < 5; j++ ) { MASA_grouping[j] = j; } } - ELSE + else { - IF( coding_subbands_0 <= 8 ) + if ( coding_subbands_0 <= 8 ) { mvs2s( MASA_grouping_8_to_5, MASA_grouping, 8 ); } - ELSE IF( coding_subbands_0 <= 12 ) + else if ( coding_subbands_0 <= 12 ) { mvs2s( MASA_grouping_12_to_5, MASA_grouping, 12 ); } - ELSE IF( coding_subbands_0 <= 18 ) + else if ( coding_subbands_0 <= 18 ) { mvs2s( MASA_grouping_18_to_5, MASA_grouping, 18 ); } - ELSE + else { - IF( coding_subbands_0 <= 24 ) + if ( coding_subbands_0 <= 24 ) { mvs2s( MASA_grouping_24_to_5, MASA_grouping, 24 ); } } } - IF( coding_subbands < coding_subbands_0 ) + if ( coding_subbands < coding_subbands_0 ) { d = 0; - FOR( j = 0; j < coding_subbands_0; j++ ) + for ( j = 0; j < coding_subbands_0; j++ ) { - IF( hQMetaData->twoDirBands[j] == 1 ) + if ( hQMetaData->twoDirBands[j] == 1 ) { two_dir_band[d++] = j; } } } - ELSE + else { set_s( two_dir_band, 0, coding_subbands ); } q_direction = &hQMetaData->q_direction[idx_d]; - FOR( i = 0; i < coding_subbands; i++ ) + for ( i = 0; i < coding_subbands; i++ ) { - var_azi_fx = var_32_fx( q_direction->band_data[i].azimuth_fx, no_frames, 22 ); - IF( hrmasa_flag ) + var_azi = var( q_direction->band_data[i].azimuth, no_frames ); + if ( hrmasa_flag ) { minimum_s( (int16_t *) ( q_direction->band_data[i].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); min_index = min_index >> 1; } - ELSE + else { min_index = q_direction->band_data[i].energy_ratio_index[0]; } - IF( var_azi_fx < L_shl( MASA_DELTA_AZI_DCT0, 22 ) ) + if ( var_azi < MASA_DELTA_AZI_DCT0 ) { idx_sub_cb = MASA_NO_CV_COH * min_index; } - ELSE + else { idx_sub_cb = MASA_NO_CV_COH * ( min_index + DIRAC_DIFFUSE_LEVELS ); /* NO_CV_COH = 8 */ } - dct_coh_fx[i][0] = coherence_cb0_masa_fx[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index]; + dct_coh[i][0] = coherence_cb0_masa[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index]; - IF( coding_subbands < coding_subbands_0 ) + if ( coding_subbands < coding_subbands_0 ) { assert( idx_d == 1 ); - dct_coh_fx[i][1] = coherence_cb1_masa_fx[MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; + dct_coh[i][1] = coherence_cb1_masa[MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; } - ELSE + else { - dct_coh_fx[i][1] = coherence_cb1_masa_fx[MASA_grouping[i] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; + dct_coh[i][1] = coherence_cb1_masa[MASA_grouping[i] * MASA_NO_CV_COH1 + q_direction->coherence_band_data[i].spread_coherence_dct1_index]; } - FOR( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + for ( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - dct_coh_fx[i][j] = 0; + dct_coh[i][j] = 0; } - invdct4_transform_fx( dct_coh_fx[i], q_direction->coherence_band_data[i].spread_coherence, 21 ); + invdct4_transform( dct_coh[i], q_direction->coherence_band_data[i].spread_coherence ); } return; @@ -5495,39 +5506,40 @@ static int16_t read_GR_min_removed_data( * *-------------------------------------------------------------------*/ -static int16_t decode_fixed_rate_composed_index_coherence( - uint16_t *bitstream, /* i : bitstream */ - int16_t *p_bit_pos, /* i : position in the bitstream */ - const int16_t no_bands, - int16_t *no_cv_vec, - uint16_t *decoded_index, - const int16_t no_symb ) +#ifdef IVAS_FLOAT_FIXED +static Word16 decode_fixed_rate_composed_index_coherence_fx( + UWord16 *bitstream, /* i : bitstream */ + Word16 *p_bit_pos, /* i : position in the bitstream */ + const Word16 no_bands, + Word16 *no_cv_vec, + UWord16 *decoded_index, + const Word16 no_symb ) { /* fixed rate */ - uint64_t no_cb; - uint16_t temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; - uint64_t idx_fr; - int16_t no_bits_vec1, half_no_bands; - int16_t bit_pos; - int16_t nbits, bits_GR; - int16_t j; - int16_t no_vals_local; - int16_t no_bits_vec; + UWord64 no_cb; + UWord16 temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord64 idx_fr; + Word16 no_bits_vec1, half_no_bands; + Word16 bit_pos; + Word16 nbits, bits_GR; + Word16 j; + Word16 no_vals_local; + Word16 no_bits_vec; bit_pos = *p_bit_pos; - set_s( (int16_t *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (Word16 *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); no_cb = 1; nbits = 0; - if ( no_bands > MASA_LIMIT_NO_BANDS_SUR_COH ) + IF( no_bands > MASA_LIMIT_NO_BANDS_SUR_COH ) { /* read 8-max_val with GR0 */ bits_GR = bit_pos; no_vals_local = no_symb - ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ); nbits += bits_GR - bit_pos; - for ( j = 0; j < no_bands; j++ ) + FOR( j = 0; j < no_bands; j++ ) { - if ( no_cv_vec[j] > no_vals_local ) + IF( no_cv_vec[j] > no_vals_local ) { no_cv_vec[j] = no_vals_local; } @@ -5535,64 +5547,64 @@ static int16_t decode_fixed_rate_composed_index_coherence( } half_no_bands = no_bands / 2; - if ( sum_s( no_cv_vec, no_bands ) > MASA_COH_LIMIT_2IDX ) + IF( sum_s( no_cv_vec, no_bands ) > MASA_COH_LIMIT_2IDX ) { no_cb = 1; - for ( j = 0; j < half_no_bands; j++ ) + FOR( j = 0; j < half_no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec = (Word16) ceil_log_2( no_cb ); no_cb = 1; - for ( j = half_no_bands; j < no_bands; j++ ) + FOR( j = half_no_bands; j < no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec1 = (Word16) ceil_log_2( no_cb ); } - else + ELSE { no_cb = 1; - for ( j = 0; j < no_bands; j++ ) + FOR( j = 0; j < no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec = (Word16) ceil_log_2( no_cb ); no_bits_vec1 = 0; } - if ( no_bits_vec1 > 0 ) + IF( no_bits_vec1 > 0 ) { idx_fr = 0; - for ( j = 0; j < no_bits_vec; j++ ) + FOR( j = 0; j < no_bits_vec; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - decode_combined_index( idx_fr, no_cv_vec, temp_index, half_no_bands ); + decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, half_no_bands ); idx_fr = 0; - for ( j = 0; j < no_bits_vec1; j++ ) + FOR( j = 0; j < no_bits_vec1; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec1; - decode_combined_index( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands ); + decode_combined_index_fx( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands ); } - else + ELSE { idx_fr = 0; - for ( j = 0; j < no_bits_vec; j++ ) + FOR( j = 0; j < no_bits_vec; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - decode_combined_index( idx_fr, no_cv_vec, temp_index, no_bands ); + decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, no_bands ); } - for ( j = 0; j < no_bands; j++ ) + FOR( j = 0; j < no_bands; j++ ) { decoded_index[j] = temp_index[j]; } @@ -5602,41 +5614,40 @@ static int16_t decode_fixed_rate_composed_index_coherence( return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 decode_fixed_rate_composed_index_coherence_fx( - UWord16 *bitstream, /* i : bitstream */ - Word16 *p_bit_pos, /* i : position in the bitstream */ - const Word16 no_bands, - Word16 *no_cv_vec, - UWord16 *decoded_index, - const Word16 no_symb ) +#else +static int16_t decode_fixed_rate_composed_index_coherence( + uint16_t *bitstream, /* i : bitstream */ + int16_t *p_bit_pos, /* i : position in the bitstream */ + const int16_t no_bands, + int16_t *no_cv_vec, + uint16_t *decoded_index, + const int16_t no_symb ) { /* fixed rate */ - UWord64 no_cb; - UWord16 temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; - UWord64 idx_fr; - Word16 no_bits_vec1, half_no_bands; - Word16 bit_pos; - Word16 nbits, bits_GR; - Word16 j; - Word16 no_vals_local; - Word16 no_bits_vec; + uint64_t no_cb; + uint16_t temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + uint64_t idx_fr; + int16_t no_bits_vec1, half_no_bands; + int16_t bit_pos; + int16_t nbits, bits_GR; + int16_t j; + int16_t no_vals_local; + int16_t no_bits_vec; bit_pos = *p_bit_pos; - set_s( (Word16 *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (int16_t *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); no_cb = 1; nbits = 0; - IF( no_bands > MASA_LIMIT_NO_BANDS_SUR_COH ) + if ( no_bands > MASA_LIMIT_NO_BANDS_SUR_COH ) { /* read 8-max_val with GR0 */ bits_GR = bit_pos; no_vals_local = no_symb - ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ); nbits += bits_GR - bit_pos; - FOR( j = 0; j < no_bands; j++ ) + for ( j = 0; j < no_bands; j++ ) { - IF( no_cv_vec[j] > no_vals_local ) + if ( no_cv_vec[j] > no_vals_local ) { no_cv_vec[j] = no_vals_local; } @@ -5644,64 +5655,64 @@ static Word16 decode_fixed_rate_composed_index_coherence_fx( } half_no_bands = no_bands / 2; - IF( sum_s( no_cv_vec, no_bands ) > MASA_COH_LIMIT_2IDX ) + if ( sum_s( no_cv_vec, no_bands ) > MASA_COH_LIMIT_2IDX ) { no_cb = 1; - FOR( j = 0; j < half_no_bands; j++ ) + for ( j = 0; j < half_no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (Word16) ceil_log_2( no_cb ); + no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); no_cb = 1; - FOR( j = half_no_bands; j < no_bands; j++ ) + for ( j = half_no_bands; j < no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec1 = (Word16) ceil_log_2( no_cb ); + no_bits_vec1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); } - ELSE + else { no_cb = 1; - FOR( j = 0; j < no_bands; j++ ) + for ( j = 0; j < no_bands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (Word16) ceil_log_2( no_cb ); + no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); no_bits_vec1 = 0; } - IF( no_bits_vec1 > 0 ) + if ( no_bits_vec1 > 0 ) { idx_fr = 0; - FOR( j = 0; j < no_bits_vec; j++ ) + for ( j = 0; j < no_bits_vec; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, half_no_bands ); + decode_combined_index( idx_fr, no_cv_vec, temp_index, half_no_bands ); idx_fr = 0; - FOR( j = 0; j < no_bits_vec1; j++ ) + for ( j = 0; j < no_bits_vec1; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec1; - decode_combined_index_fx( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands ); + decode_combined_index( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands ); } - ELSE + else { idx_fr = 0; - FOR( j = 0; j < no_bits_vec; j++ ) + for ( j = 0; j < no_bits_vec; j++ ) { idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, no_bands ); + decode_combined_index( idx_fr, no_cv_vec, temp_index, no_bands ); } - FOR( j = 0; j < no_bands; j++ ) + for ( j = 0; j < no_bands; j++ ) { decoded_index[j] = temp_index[j]; } @@ -5720,52 +5731,54 @@ static Word16 decode_fixed_rate_composed_index_coherence_fx( *-------------------------------------------------------------------*/ /*! r: number of bits read */ -static int16_t read_coherence_data_hr_512( - uint16_t *bitstream, /* i : bitstream */ - int16_t *p_bit_pos, /* i : position in the bitstream */ +#ifdef IVAS_FLOAT_FIXED +static Word16 read_coherence_data_hr_512_fx( + UWord16 *bitstream, /* i : bitstream */ + Word16 *p_bit_pos, /* i : position in the bitstream */ IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */ - const int16_t idx_dir, /* i : direction index */ - const int16_t nbits_coh ) + const Word16 idx_dir, /* i : direction index */ + const Word16 nbits_coh ) { - int16_t j, k, i; - int16_t nbands, nblocks; - int16_t min_index, GR_param; - int16_t cb_size, nbits; - int16_t decoded_idx; - float delta; + Word16 j, k, i; + Word16 nbands, nblocks; + Word16 min_index, GR_param; + Word16 cb_size, nbits; + Word16 decoded_idx; + Word32 delta_fx, decoded_idx_fx; // q = 22, q = 9 nbands = hQMetaData->q_direction[idx_dir].cfg.nbands; nblocks = hQMetaData->q_direction[idx_dir].cfg.nblocks; cb_size = 1 << nbits_coh; - delta = 256.0f / cb_size; + delta_fx = L_shl( 256, 22 - nbits_coh ); nbits = *p_bit_pos; - for ( k = 0; k < nblocks; k++ ) + FOR( k = 0; k < nblocks; k++ ) { /* read method */ - if ( bitstream[( *p_bit_pos )--] == 1 ) + IF( bitstream[( *p_bit_pos )--] == 1 ) { /* average removed */ /* read average index */ min_index = 0; - for ( i = 0; i < nbits_coh; i++ ) + FOR( i = 0; i < nbits_coh; i++ ) { - min_index = ( min_index << 1 ) + bitstream[( *p_bit_pos )--]; + min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )--] ); } /* read GR param */ GR_param = bitstream[( *p_bit_pos )--]; - for ( j = 0; j < nbands; j++ ) + FOR( j = 0; j < nbands; j++ ) { decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, 2 * cb_size, GR_param ); - if ( decoded_idx % 2 ) + IF( decoded_idx % 2 ) { - decoded_idx = ( ( decoded_idx + 1 ) >> 1 ) + min_index; + decoded_idx = add( shr( add( decoded_idx, 1 ), 1 ), min_index ); } - else + ELSE { - decoded_idx = -( decoded_idx >> 1 ) + min_index; + decoded_idx = add( negate( shr( decoded_idx, 1 ) ), min_index ); } - hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) ( decoded_idx * delta + delta / 2.0f ); + decoded_idx_fx = L_shl( decoded_idx, 9 ); + hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); } } else @@ -5774,7 +5787,7 @@ static int16_t read_coherence_data_hr_512( min_index = 0; for ( i = 0; i < nbits_coh; i++ ) { - min_index = ( min_index << 1 ) + bitstream[( *p_bit_pos )--]; + min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )--] ); } /* read GR param */ @@ -5782,64 +5795,63 @@ static int16_t read_coherence_data_hr_512( for ( j = 0; j < nbands; j++ ) { decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, cb_size - min_index, GR_param ) + min_index; - hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) ( decoded_idx * delta + delta / 2.0f ); + decoded_idx_fx = L_shl( decoded_idx, 9 ); + hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); } } } - nbits = nbits - *p_bit_pos; + nbits = sub( nbits, *p_bit_pos ); return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 read_coherence_data_hr_512_fx( - UWord16 *bitstream, /* i : bitstream */ - Word16 *p_bit_pos, /* i : position in the bitstream */ +#else +static int16_t read_coherence_data_hr_512( + uint16_t *bitstream, /* i : bitstream */ + int16_t *p_bit_pos, /* i : position in the bitstream */ IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */ - const Word16 idx_dir, /* i : direction index */ - const Word16 nbits_coh ) + const int16_t idx_dir, /* i : direction index */ + const int16_t nbits_coh ) { - Word16 j, k, i; - Word16 nbands, nblocks; - Word16 min_index, GR_param; - Word16 cb_size, nbits; - Word16 decoded_idx; - Word32 delta_fx, decoded_idx_fx; // q = 22, q = 9 + int16_t j, k, i; + int16_t nbands, nblocks; + int16_t min_index, GR_param; + int16_t cb_size, nbits; + int16_t decoded_idx; + float delta; nbands = hQMetaData->q_direction[idx_dir].cfg.nbands; nblocks = hQMetaData->q_direction[idx_dir].cfg.nblocks; cb_size = 1 << nbits_coh; - delta_fx = L_shl( 256, 22 - nbits_coh ); + delta = 256.0f / cb_size; nbits = *p_bit_pos; - FOR( k = 0; k < nblocks; k++ ) + for ( k = 0; k < nblocks; k++ ) { /* read method */ - IF( bitstream[( *p_bit_pos )--] == 1 ) + if ( bitstream[( *p_bit_pos )--] == 1 ) { /* average removed */ /* read average index */ min_index = 0; - FOR( i = 0; i < nbits_coh; i++ ) + for ( i = 0; i < nbits_coh; i++ ) { - min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )--] ); + min_index = ( min_index << 1 ) + bitstream[( *p_bit_pos )--]; } /* read GR param */ GR_param = bitstream[( *p_bit_pos )--]; - FOR( j = 0; j < nbands; j++ ) + for ( j = 0; j < nbands; j++ ) { decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, 2 * cb_size, GR_param ); - IF( decoded_idx % 2 ) + if ( decoded_idx % 2 ) { - decoded_idx = add( shr( add( decoded_idx, 1 ), 1 ), min_index ); + decoded_idx = ( ( decoded_idx + 1 ) >> 1 ) + min_index; } - ELSE + else { - decoded_idx = add( negate( shr( decoded_idx, 1 ) ), min_index ); + decoded_idx = -( decoded_idx >> 1 ) + min_index; } - decoded_idx_fx = L_shl( decoded_idx, 9 ); - hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); + hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) ( decoded_idx * delta + delta / 2.0f ); } } else @@ -5848,7 +5860,7 @@ static Word16 read_coherence_data_hr_512_fx( min_index = 0; for ( i = 0; i < nbits_coh; i++ ) { - min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )--] ); + min_index = ( min_index << 1 ) + bitstream[( *p_bit_pos )--]; } /* read GR param */ @@ -5856,13 +5868,12 @@ static Word16 read_coherence_data_hr_512_fx( for ( j = 0; j < nbands; j++ ) { decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, cb_size - min_index, GR_param ) + min_index; - decoded_idx_fx = L_shl( decoded_idx, 9 ); - hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); + hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (uint8_t) ( decoded_idx * delta + delta / 2.0f ); } } } - nbits = sub( nbits, *p_bit_pos ); + nbits = nbits - *p_bit_pos; return nbits; } @@ -5875,31 +5886,34 @@ static Word16 read_coherence_data_hr_512_fx( *------------------------------------------------------------------- */ /*! r: number of bits read */ -static int16_t read_coherence_data( - uint16_t *bitstream, /* i : bitstream */ - int16_t *p_bit_pos, /* i : position in the bitstream */ +#ifdef IVAS_FLOAT_FIXED +static Word16 read_coherence_data_fx( + UWord16 *bitstream, /* i : bitstream */ + Word16 *p_bit_pos, /* i : position in the bitstream */ IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */ - const int16_t idx_dir, /* i : direction index */ - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ + const Word16 idx_dir, /* i : direction index */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ ) { - int16_t j; - int16_t no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS]; - uint64_t no_cb; - int16_t no_bits_vec, nbits; - int16_t bits_GR; - uint16_t idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS]; - uint16_t av_index; - int16_t no_bits_vec1; - int16_t bit_pos; + Word16 j; + Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord64 no_cb; + Word16 no_bits_vec, nbits; + Word16 bits_GR; + UWord16 idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 av_index; + Word16 no_bits_vec1; + Word16 bit_pos; IVAS_QDIRECTION *q_direction; - int16_t coding_subbands; - uint64_t dct0_index; - int16_t decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS]; - uint16_t byteBuffer; - int16_t idx_ER; - int16_t min_index; - int16_t extra_cv; + Word16 coding_subbands; + UWord64 dct0_index; + Word16 decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 byteBuffer; + Word16 idx_ER; + Word16 min_index; + Word16 extra_cv; + Word16 num, den, q_num, q_den, q_res; + Word32 res; coding_subbands = hQMetaData->q_direction[idx_dir].cfg.nbands; extra_cv = (int16_t) ( coding_subbands / MASA_FACTOR_CV_COH ); @@ -5907,24 +5921,24 @@ static int16_t read_coherence_data( bit_pos = *p_bit_pos; nbits = 0; - if ( q_direction->cfg.nblocks == 1 ) + IF( q_direction->cfg.nblocks == 1 ) { - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - if ( hrmasa_flag ) + IF( hrmasa_flag ) { idx_ER = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> 1 ) + extra_cv; } - else + ELSE { idx_ER = 7 - q_direction->band_data[j].energy_ratio_index_mod[0] + extra_cv; } no_cv_vec[j] = idx_ER + 1; } - if ( sum_s( no_cv_vec, coding_subbands ) == coding_subbands ) + IF( sum_s( no_cv_vec, coding_subbands ) == coding_subbands ) { - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } @@ -5934,142 +5948,152 @@ static int16_t read_coherence_data( byteBuffer = bitstream[bit_pos--]; nbits += 1; - if ( byteBuffer & 1 ) + IF( byteBuffer & 1 ) { /* decode GR min removed */ nbits += read_GR_min_removed_data( bitstream, &bit_pos, no_cv_vec, coding_subbands, decoded_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv ); - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - if ( no_cv_vec[j] > 1 ) + IF( no_cv_vec[j] > 1 ) { - q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( decoded_idx[j] * ( 255.0f / (float) ( 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH ) ) ); + num = decoded_idx[j] * 255; + den = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH; + q_den = norm_s( den ); + q_num = norm_s( num ) - 1; + res = div_s( num << q_num, den << q_den ); + q_res = 15 - q_den + q_num; + res = L_shl( res, 16 - q_res ); + q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) (round_fx( res )); } - else + ELSE { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } } } - else + ELSE { uint16_t decoded_index[MASA_MAXIMUM_CODING_SUBBANDS]; /* decode joint index */ -#ifdef IVAS_FLOAT_FIXED nbits += decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, MASA_NO_CV_COH + coding_subbands / MASA_FACTOR_CV_COH ); -#else - nbits += decode_fixed_rate_composed_index_coherence( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, MASA_NO_CV_COH + coding_subbands / MASA_FACTOR_CV_COH ); -#endif - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - if ( no_cv_vec[j] > 1 ) + IF( no_cv_vec[j] > 1 ) { - q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( decoded_index[j] * ( 255.0f / (float) ( 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH ) ) ); + num = decoded_index[j] * 255; + den = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH; + q_den = norm_s( den ); + q_num = norm_s( num ) - 1; + res = div_s( num << q_num, den << q_den ); + q_res = 15 - q_den + q_num; + res = L_shl( res, 16 - q_res ); + q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) (round_fx( res )); } - else + ELSE { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } } } } - else + ELSE { - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - if ( hrmasa_flag ) + IF( hrmasa_flag ) { - minimum_s( (int16_t *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); + minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); no_cv_vec[j] = len_cb_dct0_masa[min_index >> 1]; /* spread coherence DCT0*/ } - else + ELSE { no_cv_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; /* spread coherence DCT0*/ } } - if ( sum_s( no_cv_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX ) + IF( sum_s( no_cv_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX ) { - uint16_t spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; no_cb = 1; - for ( j = 0; j < coding_subbands / 2; j++ ) + FOR( j = 0; j < coding_subbands / 2; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); no_cb = 1; - for ( j = coding_subbands / 2; j < coding_subbands; j++ ) + FOR( j = coding_subbands / 2; j < coding_subbands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec1 = ceil_log_2( no_cb ); // (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); dct0_index = 0; - for ( j = 0; j < no_bits_vec; j++ ) + FOR( j = 0; j < no_bits_vec; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - set_s( (int16_t *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); - decode_combined_index( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands / 2 ); + decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands / 2 ); dct0_index = 0; - for ( j = 0; j < no_bits_vec1; j++ ) + FOR( j = 0; j < no_bits_vec1; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec1; - decode_combined_index( dct0_index, &no_cv_vec[coding_subbands / 2], &spr_coh_temp_index[coding_subbands / 2], coding_subbands / 2 ); + decode_combined_index_fx( dct0_index, &no_cv_vec[coding_subbands / 2], &spr_coh_temp_index[coding_subbands / 2], coding_subbands / 2 ); - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; } } - else + ELSE { /* spread coherence */ - uint16_t spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; no_cb = 1; - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); - /* read joint index for DCT0 */ - no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + /* read joint index for DCT0 */ + no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); dct0_index = 0; - for ( j = 0; j < no_bits_vec; j++ ) + FOR( j = 0; j < no_bits_vec; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - set_s( (int16_t *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); - decode_combined_index( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands ); + decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands ); - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; } } /* read GR data for DCT1 */ - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { bits_GR = bit_pos; idx_dct1[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, 2 * MASA_NO_CV_COH1, 0 ); @@ -6082,13 +6106,13 @@ static int16_t read_coherence_data( nbits += ( bits_GR - bit_pos ); /* write indexes in metadata structure */ - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - if ( idx_dct1[j] % 2 ) + IF( idx_dct1[j] % 2 ) { q_direction->coherence_band_data[j].spread_coherence_dct1_index = ( idx_dct1[j] + 1 ) / 2 + av_index; } - else + ELSE { q_direction->coherence_band_data[j].spread_coherence_dct1_index = -idx_dct1[j] / 2 + av_index; } @@ -6100,35 +6124,32 @@ static int16_t read_coherence_data( return nbits; } - -#ifdef IVAS_FLOAT_FIXED -static Word16 read_coherence_data_fx( - UWord16 *bitstream, /* i : bitstream */ - Word16 *p_bit_pos, /* i : position in the bitstream */ +#else +static int16_t read_coherence_data( + uint16_t *bitstream, /* i : bitstream */ + int16_t *p_bit_pos, /* i : position in the bitstream */ IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure */ - const Word16 idx_dir, /* i : direction index */ - const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ + const int16_t idx_dir, /* i : direction index */ + const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ ) { - Word16 j; - Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS]; - UWord64 no_cb; - Word16 no_bits_vec, nbits; - Word16 bits_GR; - UWord16 idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS]; - UWord16 av_index; - Word16 no_bits_vec1; - Word16 bit_pos; - IVAS_QDIRECTION *q_direction; - Word16 coding_subbands; - UWord64 dct0_index; - Word16 decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS]; - UWord16 byteBuffer; - Word16 idx_ER; - Word16 min_index; - Word16 extra_cv; - Word16 num, den, q_num, q_den, q_res; - Word32 res; + int16_t j; + int16_t no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS]; + uint64_t no_cb; + int16_t no_bits_vec, nbits; + int16_t bits_GR; + uint16_t idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS]; + uint16_t av_index; + int16_t no_bits_vec1; + int16_t bit_pos; + IVAS_QDIRECTION *q_direction; + int16_t coding_subbands; + uint64_t dct0_index; + int16_t decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS]; + uint16_t byteBuffer; + int16_t idx_ER; + int16_t min_index; + int16_t extra_cv; coding_subbands = hQMetaData->q_direction[idx_dir].cfg.nbands; extra_cv = (int16_t) ( coding_subbands / MASA_FACTOR_CV_COH ); @@ -6136,24 +6157,24 @@ static Word16 read_coherence_data_fx( bit_pos = *p_bit_pos; nbits = 0; - IF( q_direction->cfg.nblocks == 1 ) + if ( q_direction->cfg.nblocks == 1 ) { - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { - IF( hrmasa_flag ) + if ( hrmasa_flag ) { idx_ER = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> 1 ) + extra_cv; } - ELSE + else { idx_ER = 7 - q_direction->band_data[j].energy_ratio_index_mod[0] + extra_cv; } no_cv_vec[j] = idx_ER + 1; } - IF( sum_s( no_cv_vec, coding_subbands ) == coding_subbands ) + if ( sum_s( no_cv_vec, coding_subbands ) == coding_subbands ) { - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } @@ -6163,152 +6184,142 @@ static Word16 read_coherence_data_fx( byteBuffer = bitstream[bit_pos--]; nbits += 1; - IF( byteBuffer & 1 ) + if ( byteBuffer & 1 ) { /* decode GR min removed */ nbits += read_GR_min_removed_data( bitstream, &bit_pos, no_cv_vec, coding_subbands, decoded_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv ); - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { - IF( no_cv_vec[j] > 1 ) + if ( no_cv_vec[j] > 1 ) { - num = decoded_idx[j] * 255; - den = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH; - q_den = norm_s( den ); - q_num = norm_s( num ) - 1; - res = div_s( num << q_num, den << q_den ); - q_res = 15 - q_den + q_num; - res = L_shl( res, 16 - q_res ); - q_direction->coherence_band_data[j].spread_coherence[0] = round_fx( res ); + q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( decoded_idx[j] * ( 255.0f / (float) ( 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH ) ) ); } - ELSE + else { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } } } - ELSE + else { uint16_t decoded_index[MASA_MAXIMUM_CODING_SUBBANDS]; /* decode joint index */ +#ifdef IVAS_FLOAT_FIXED nbits += decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, MASA_NO_CV_COH + coding_subbands / MASA_FACTOR_CV_COH ); - FOR( j = 0; j < coding_subbands; j++ ) +#else + nbits += decode_fixed_rate_composed_index_coherence( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, MASA_NO_CV_COH + coding_subbands / MASA_FACTOR_CV_COH ); +#endif + for ( j = 0; j < coding_subbands; j++ ) { - IF( no_cv_vec[j] > 1 ) + if ( no_cv_vec[j] > 1 ) { - num = decoded_index[j] * 255; - den = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH; - q_den = norm_s( den ); - q_num = norm_s( num ) - 1; - res = div_s( num << q_num, den << q_den ); - q_res = 15 - q_den + q_num; - res = L_shl( res, 16 - q_res ); - q_direction->coherence_band_data[j].spread_coherence[0] = round_fx( res ); + q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( decoded_index[j] * ( 255.0f / (float) ( 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> ( hrmasa_flag ) ) + coding_subbands / MASA_FACTOR_CV_COH ) ) ); } - ELSE + else { q_direction->coherence_band_data[j].spread_coherence[0] = 0; } } } } - ELSE + else { - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { - IF( hrmasa_flag ) + if ( hrmasa_flag ) { - minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); + minimum_s( (int16_t *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); no_cv_vec[j] = len_cb_dct0_masa[min_index >> 1]; /* spread coherence DCT0*/ } - ELSE + else { no_cv_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; /* spread coherence DCT0*/ } } - IF( sum_s( no_cv_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX ) + if ( sum_s( no_cv_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX ) { - UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + uint16_t spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; no_cb = 1; - FOR( j = 0; j < coding_subbands / 2; j++ ) + for ( j = 0; j < coding_subbands / 2; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); + no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); no_cb = 1; - FOR( j = coding_subbands / 2; j < coding_subbands; j++ ) + for ( j = coding_subbands / 2; j < coding_subbands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec1 = ceil_log_2( no_cb ); // (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + no_bits_vec1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); dct0_index = 0; - FOR( j = 0; j < no_bits_vec; j++ ) + for ( j = 0; j < no_bits_vec; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (int16_t *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); - decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands / 2 ); + decode_combined_index( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands / 2 ); dct0_index = 0; - FOR( j = 0; j < no_bits_vec1; j++ ) + for ( j = 0; j < no_bits_vec1; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec1; - decode_combined_index_fx( dct0_index, &no_cv_vec[coding_subbands / 2], &spr_coh_temp_index[coding_subbands / 2], coding_subbands / 2 ); + decode_combined_index( dct0_index, &no_cv_vec[coding_subbands / 2], &spr_coh_temp_index[coding_subbands / 2], coding_subbands / 2 ); - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; } } - ELSE + else { /* spread coherence */ - UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; + uint16_t spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; no_cb = 1; - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { no_cb *= no_cv_vec[j]; } - no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); + no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); - /* read joint index for DCT0 */ - no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); + /* read joint index for DCT0 */ + no_bits_vec = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); dct0_index = 0; - FOR( j = 0; j < no_bits_vec; j++ ) + for ( j = 0; j < no_bits_vec; j++ ) { dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos--]; } nbits += no_bits_vec; - set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); + set_s( (int16_t *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS ); - decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands ); + decode_combined_index( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands ); - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; } } /* read GR data for DCT1 */ - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { bits_GR = bit_pos; idx_dct1[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, 2 * MASA_NO_CV_COH1, 0 ); @@ -6321,13 +6332,13 @@ static Word16 read_coherence_data_fx( nbits += ( bits_GR - bit_pos ); /* write indexes in metadata structure */ - FOR( j = 0; j < coding_subbands; j++ ) + for ( j = 0; j < coding_subbands; j++ ) { - IF( idx_dct1[j] % 2 ) + if ( idx_dct1[j] % 2 ) { q_direction->coherence_band_data[j].spread_coherence_dct1_index = ( idx_dct1[j] + 1 ) / 2 + av_index; } - ELSE + else { q_direction->coherence_band_data[j].spread_coherence_dct1_index = -idx_dct1[j] / 2 + av_index; } @@ -6672,7 +6683,7 @@ static int16_t read_surround_coherence_hr( return bits_sur_coherence; } -#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED1 static Word16 read_surround_coherence_hr_fx( UWord16 *bitstream, /* i : bitstream */ Word16 *p_bit_pos, /* i : position in the bitstream */ @@ -6834,33 +6845,6 @@ static Word16 read_surround_coherence_hr_fx( * Decode combined index into several indexes *-------------------------------------------------------------------*/ -static void decode_combined_index( - uint64_t comb_index, /* i : index to be decoded */ - const int16_t *no_cv_vec, /* i : number of codewords for each element*/ - uint16_t *index, /* o : decoded indexes */ - const int16_t len /* i : number of elements */ -) -{ - int16_t i; - uint64_t base[MASA_MAXIMUM_CODING_SUBBANDS + 1]; - - base[0] = 1; - for ( i = 1; i < len; i++ ) - { - base[i] = base[i - 1] * no_cv_vec[i - 1]; - } - - for ( i = len - 1; i > 0; i-- ) - { - index[i] = (uint16_t) ( comb_index / base[i] ); - comb_index -= index[i] * base[i]; - } - - index[0] = (uint16_t) comb_index; - - return; -} - #ifdef IVAS_FLOAT_FIXED static void decode_combined_index_fx( UWord64 comb_index, /* i : index to be decoded */ @@ -6888,105 +6872,35 @@ static void decode_combined_index_fx( return; } -#endif - - -static void read_stream_dct_coeffs_omasa( - int16_t *q_idx, - float *q_dct_data, - const int16_t len_stream, - uint16_t *bit_stream, - int16_t *index, - const int16_t first_line ) +#else +static void decode_combined_index( + uint64_t comb_index, /* i : index to be decoded */ + const int16_t *no_cv_vec, /* i : number of codewords for each element*/ + uint16_t *index, /* o : decoded indexes */ + const int16_t len /* i : number of elements */ +) { - int16_t sign, nbits; - int16_t i, j, i_min; - - float step; - int16_t GR1, GR2; - - step = STEP_M2T; - nbits = 0; - sign = 1; - if ( first_line == 0 ) - { - /* read sign */ - sign = bit_stream[( *index )--]; - if ( sign == 0 ) - { - sign = -1; - } - nbits++; - } - - set_s( q_idx, 0, len_stream ); - /* read DCT 0 component */ - for ( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ ) - { - q_idx[0] = ( q_idx[0] << 1 ) + bit_stream[( *index )--]; - } - q_idx[0] *= sign; + int16_t i; + uint64_t base[MASA_MAXIMUM_CODING_SUBBANDS + 1]; - if ( q_idx[0] != 0 ) + base[0] = 1; + for ( i = 1; i < len; i++ ) { - if ( len_stream >= 8 ) - { - /* read index of last index encoded with GR2 */ - i_min = 0; - j = 4; - for ( i = 0; i < j; i++ ) - { - i_min = ( i_min << 1 ) + bit_stream[( *index )--]; - } - nbits += j; - /* read GR orders */ - GR1 = bit_stream[( *index )--] + 1; - if ( GR1 == 2 ) - { - GR2 = bit_stream[( *index )--]; - } - else - { - GR2 = 0; - } - - /* read GR data */ - for ( i = 1; i <= i_min; i++ ) - { - q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); - } - for ( i = i_min + 1; i < len_stream; i++ ) - { - q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 ); - } - } - else - { - /* read GR order (only one) */ - GR1 = bit_stream[( *index )--]; - for ( i = 1; i < len_stream; i++ ) - { - q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); - } - } + base[i] = base[i - 1] * no_cv_vec[i - 1]; } - /* deindex */ - q_dct_data[0] = q_idx[0] * step; - for ( i = 1; i < len_stream; i++ ) - { - if ( ( q_idx[i] % 2 ) == 0 ) - { - q_dct_data[i] = -( q_idx[i] >> 1 ) * step; - } - else - { - q_dct_data[i] = ( ( q_idx[i] + 1 ) >> 1 ) * step; - } + for ( i = len - 1; i > 0; i-- ) + { + index[i] = (uint16_t) ( comb_index / base[i] ); + comb_index -= index[i] * base[i]; } + index[0] = (uint16_t) comb_index; + return; } +#endif + #ifdef IVAS_FLOAT_FIXED static void read_stream_dct_coeffs_omasa_fx( @@ -7085,108 +6999,110 @@ static void read_stream_dct_coeffs_omasa_fx( return; } -#endif - - -/*------------------------------------------------------------------------- - * ivas_omasa_decode_masa_to_total() - * - *------------------------------------------------------------------------*/ - -void ivas_omasa_decode_masa_to_total( +#else +static void read_stream_dct_coeffs_omasa( + int16_t *q_idx, + float *q_dct_data, + const int16_t len_stream, uint16_t *bit_stream, int16_t *index, - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - const int16_t nbands, - const int16_t nblocks ) + const int16_t first_line ) { - int16_t i, j, k; - int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; - float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], - dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; - int16_t n_streams, len_stream; + int16_t sign, nbits; + int16_t i, j, i_min; - /* Setup coding parameters */ - n_streams = 1; - len_stream = nbands * nblocks; - if ( len_stream == 32 ) - { - n_streams = 4; - len_stream = 8; - } + float step; + int16_t GR1, GR2; - set_s( q_idx, 0, nbands * nblocks ); - for ( i = 0; i < n_streams; i++ ) + step = STEP_M2T; + nbits = 0; + sign = 1; + if ( first_line == 0 ) { - read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], &q_dct_data[i * len_stream], len_stream, bit_stream, index, i == 0 ); + /* read sign */ + sign = bit_stream[( *index )--]; + if ( sign == 0 ) + { + sign = -1; + } + nbits++; } - /* inverse DCT2 transform */ - switch ( len_stream ) + set_s( q_idx, 0, len_stream ); + /* read DCT 0 component */ + for ( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ ) { - case 4: - matrix_product( dct4, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp ); - mvr2r( dct_data_tmp, q_dct_data, nblocks ); - break; - case 5: - matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); - mvr2r( dct_data_tmp, q_dct_data, nbands ); - break; - case 8: - matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); - mvr2r( dct_data_tmp, q_dct_data, nbands ); - break; - case 12: - matrix_product( dct12, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); - mvr2r( dct_data_tmp, q_dct_data, nbands ); - break; - case 20: - matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); - matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/ - break; - case 32: - matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); - matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); - break; - default: - printf( "Incorrect number of coefficients for OMASA.\n" ); - break; + q_idx[0] = ( q_idx[0] << 1 ) + bit_stream[( *index )--]; } - k = 0; - for ( i = 0; i < nblocks; i++ ) + q_idx[0] *= sign; + + if ( q_idx[0] != 0 ) { - for ( j = 0; j < nbands; j++ ) + if ( len_stream >= 8 ) { - masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] ); - masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); - k++; - } - } + /* read index of last index encoded with GR2 */ + i_min = 0; + j = 4; + for ( i = 0; i < j; i++ ) + { + i_min = ( i_min << 1 ) + bit_stream[( *index )--]; + } + nbits += j; + /* read GR orders */ + GR1 = bit_stream[( *index )--] + 1; + if ( GR1 == 2 ) + { + GR2 = bit_stream[( *index )--]; + } + else + { + GR2 = 0; + } - if ( nblocks == 1 ) - { - for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + /* read GR data */ + for ( i = 1; i <= i_min; i++ ) + { + q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); + } + for ( i = i_min + 1; i < len_stream; i++ ) + { + q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 ); + } + } + else { - for ( j = 0; j < nbands; j++ ) + /* read GR order (only one) */ + GR1 = bit_stream[( *index )--]; + for ( i = 1; i < len_stream; i++ ) { - masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; + q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); } } } - if ( nbands == 1 ) + /* deindex */ + q_dct_data[0] = q_idx[0] * step; + for ( i = 1; i < len_stream; i++ ) { - for ( j = 1; j < 5; j++ ) + if ( ( q_idx[i] % 2 ) == 0 ) { - for ( i = 0; i < nblocks; i++ ) - { - masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; - } + q_dct_data[i] = -( q_idx[i] >> 1 ) * step; + } + else + { + q_dct_data[i] = ( ( q_idx[i] + 1 ) >> 1 ) * step; } } return; } +#endif + + +/*------------------------------------------------------------------------- + * ivas_omasa_decode_masa_to_total() + * + *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED void ivas_omasa_decode_masa_to_total_fx( @@ -7284,4 +7200,99 @@ void ivas_omasa_decode_masa_to_total_fx( return; } +#else +void ivas_omasa_decode_masa_to_total( + uint16_t *bit_stream, + int16_t *index, + float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + const int16_t nbands, + const int16_t nblocks ) +{ + int16_t i, j, k; + int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; + float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], + dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; + int16_t n_streams, len_stream; + + /* Setup coding parameters */ + n_streams = 1; + len_stream = nbands * nblocks; + if ( len_stream == 32 ) + { + n_streams = 4; + len_stream = 8; + } + + set_s( q_idx, 0, nbands * nblocks ); + for ( i = 0; i < n_streams; i++ ) + { + read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], &q_dct_data[i * len_stream], len_stream, bit_stream, index, i == 0 ); + } + + /* inverse DCT2 transform */ + switch ( len_stream ) + { + case 4: + matrix_product( dct4, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp ); + mvr2r( dct_data_tmp, q_dct_data, nblocks ); + break; + case 5: + matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); + mvr2r( dct_data_tmp, q_dct_data, nbands ); + break; + case 8: + matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); + mvr2r( dct_data_tmp, q_dct_data, nbands ); + break; + case 12: + matrix_product( dct12, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); + mvr2r( dct_data_tmp, q_dct_data, nbands ); + break; + case 20: + matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); + matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/ + break; + case 32: + matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); + matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); + break; + default: + printf( "Incorrect number of coefficients for OMASA.\n" ); + break; + } + k = 0; + for ( i = 0; i < nblocks; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] ); + masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); + k++; + } + } + + if ( nblocks == 1 ) + { + for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; + } + } + } + + if ( nbands == 1 ) + { + for ( j = 1; j < 5; j++ ) + { + for ( i = 0; i < nblocks; i++ ) + { + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; + } + } + } + + return; +} #endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 8d3a5cb9f959f6b7fdff6d0c9fe6d820e83448db..aede64b6d072fc4f748873471ecc449255abb622 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -153,6 +153,11 @@ typedef struct stereo_dft_dec_data_struct float res_hb_nrg_mem; float bpf_error_signal_last; float bpf_error_ratio_mem; +#ifdef IVAS_FLOAT_FIXED + Word32 res_hb_nrg_mem_fx; + Word32 bpf_error_signal_last_fx; + Word16 bpf_error_ratio_mem_fx; +#endif // IVAS_FLOAT_FIXED float res_cod_mem[STEREO_DFT_OVL_8k]; float buff_LBTCX_mem[NS2SA( 16000, STEREO_DFT32MS_OVL_NS )]; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 7e64c459384a8773e3ea49f86502ea68af6042d6..f0b7f59dc5bfdff1d61449c987db15bc384b5a60 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -43,7 +43,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" - +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * Local constants @@ -436,6 +438,11 @@ void stereo_dft_dec_reset( hStereoDft->bpf_error_signal_last = 0.0f; hStereoDft->bpf_error_ratio_mem = 1.0f; hStereoDft->res_hb_nrg_mem = 0.0f; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->res_hb_nrg_mem_fx = 0; + hStereoDft->bpf_error_signal_last_fx = 0; + hStereoDft->bpf_error_ratio_mem_fx = ONE_IN_Q12; +#endif // IVAS_FLOAT_FIXED /*reset parameters*/ set_zero( hStereoDft->side_gain, STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX ); @@ -1686,7 +1693,23 @@ void stereo_dft_dec_res( bass_psfilter( hCPE->hStereoDft->hBpf, hCPE->hCoreCoder[0]->Opt_AMR_WB, output, L_FRAME8k, hCPE->hCoreCoder[0]->old_pitch_buf + ( L_FRAME8k / STEREO_DFT_L_SUBFR_8k ), hCPE->hCoreCoder[0]->bpf_off, hCPE->hCoreCoder[0]->stab_fac, &hCPE->hStereoDft->stab_fac_smooth_res, hCPE->hCoreCoder[0]->last_coder_type, bpf_error_signal_8k ); +#ifndef IVAS_FLOAT_FIXED res_bpf_flag = res_bpf_adapt( hCPE->hStereoDft, bpf_error_signal_8k, res_buf ); +#else + Word32 bpf_error_signal_8k_fx[L_FRAME8k]; + Word32 res_buf_fx[STEREO_DFT_N_8k]; + FOR( int k = 0; k < STEREO_DFT_N_8k; k++ ) + { + res_buf_fx[k] = (Word32) ( res_buf[k] * ONE_IN_Q12 ); + } + FOR( int k = 0; k < L_FRAME8k; k++ ) + { + bpf_error_signal_8k_fx[k] = (Word32) ( bpf_error_signal_8k[k] * ONE_IN_Q16 ); + } + + res_bpf_flag = res_bpf_adapt_fx( hCPE->hStereoDft, bpf_error_signal_8k_fx, res_buf_fx ); +#endif // IVAS_FLOAT_FIXED + if ( prev_bfi ) { /* Ramp up BPF contribution for the first good frame */ @@ -2175,12 +2198,32 @@ void stereo_dft_dec_read_BS( push_wmops( "residual_decode" ); if ( I != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) { +#ifdef IVAS_FLOAT_FIXED + ECSQ_init_instance_fx( &ecsq_inst, 0 /*dummy index*/, &range_uni_dec_state ); +#else ECSQ_init_instance( &ecsq_inst, 0 /*dummy index*/, &range_uni_dec_state ); +#endif // IVAS_FLOAT_FIXED rc_uni_dec_init( &range_uni_dec_state, bit_stream_side + *nb_bits, max_bits - *nb_bits ); +#ifdef IVAS_FLOAT_FIXED + Word32 res_global_gain_fx; + + res_global_gain_fx = ECSQ_dequantize_gain_fx( I ); + + hStereoDft->res_global_gain = ( (float) res_global_gain_fx / ONE_IN_Q15 ); + +#ifdef DUMPS_ENABLED + dbgwrite_txt( &hStereoDft->res_global_gain, 1, "fixed_res_global_gain.txt", NULL ); +#endif // DUMPS_ENABLED +#else hStereoDft->res_global_gain = ECSQ_dequantize_gain( I ); +#ifdef DUMPS_ENABLED + dbgwrite_txt( &hStereoDft->res_global_gain, 1, "float_res_global_gain.txt", NULL ); +#endif // DUMPS_ENABLED +#endif // IVAS_FLOAT_FIXED + ecsq_inst.config_index = 2 * hStereoDft->res_cod_mode[k_offset] - 1; ECSQ_decode( &ecsq_inst, hStereoDft->res_cod_line_max, dec ); @@ -2189,7 +2232,32 @@ void stereo_dft_dec_read_BS( set_zero( res_buf, STEREO_DFT_N_8k ); +#ifdef IVAS_FLOAT_FIXED + Word32 res_buf_fx[800]; + Word16 dec_fx[800]; + Word16 c; + FOR( c = 0; c < hStereoDft->res_cod_line_max; c++ ) + { + dec_fx[c] = dec[c] * ONE_IN_Q8; + } + + ECSQ_dequantize_vector_fx( dec_fx, res_global_gain_fx, hStereoDft->res_cod_line_max, res_buf_fx ); + + FOR( c = 0; c < hStereoDft->res_cod_line_max; c++ ) + { + res_buf[c] = ( (float) res_buf_fx[c] / ONE_IN_Q8 ); + } +#ifdef DUMPS_ENABLED + dbgwrite_txt( res_buf, hStereoDft->res_cod_line_max, "fixed_res_buf.txt", NULL ); +#endif // DUMPS_ENABLED +#else ECSQ_dequantize_vector( dec, hStereoDft->res_global_gain, hStereoDft->res_cod_line_max, res_buf ); + +#ifdef DUMPS_ENABLED + dbgwrite_txt( res_buf, hStereoDft->res_cod_line_max, "float_res_buf.txt", NULL ); +#endif // DUMPS_ENABLED +#endif // IVAS_FLOAT_FIXED + } else { diff --git a/lib_dec/ivas_stereo_eclvq_dec.c b/lib_dec/ivas_stereo_eclvq_dec.c index 0a16d2acc7cb11027f80059d561c593c9bcde4f2..c9d66c0631674bd3a74220d5d3ffada1b75e7781 100644 --- a/lib_dec/ivas_stereo_eclvq_dec.c +++ b/lib_dec/ivas_stereo_eclvq_dec.c @@ -47,6 +47,7 @@ * * ---------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t arith_decode_elias_mod( RangeUniDecState *rc_st_dec ) { @@ -80,6 +81,41 @@ static int16_t arith_decode_elias_mod( return n; } +#else +static Word16 arith_decode_elias_mod( + RangeUniDecState *rc_st_dec ) +{ + Word16 n, n_bits, bit; + + n_bits = 0; + + bit = rc_uni_dec_read_bit( rc_st_dec ); + + WHILE( EQ_16( bit, 0 ) ) + { + bit = rc_uni_dec_read_bit( rc_st_dec ); + ++n_bits; + IF( EQ_16( n_bits, 17 ) ) + { + /* bitstream error encountered */ + rc_st_dec->bit_error_detected = 1; + return 0; + } + } + + IF( EQ_16( n_bits, 0 ) ) + { + /* code for 0 is 10 and code for 1 is 11 */ + n = rc_uni_dec_read_bit( rc_st_dec ); + } + ELSE + { + n = add( rc_uni_dec_read_bits( rc_st_dec, n_bits ), shl( 1, n_bits ) ); + } + + return n; +} +#endif // !IVAS_FLOAT_FIXED /*--------------------------------------------------------------- @@ -88,6 +124,7 @@ static int16_t arith_decode_elias_mod( * * ---------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t arith_decode_prob_escape( RangeUniDecState *rc_st_dec, const uint16_t cum_freq_table[], /* i : Cumulative frequency up to symbol */ @@ -106,6 +143,26 @@ static int16_t arith_decode_prob_escape( return symbol; } +#else +static Word16 arith_decode_prob_escape( + RangeUniDecState *rc_st_dec, + const UWord16 cum_freq_table[], /* i : Cumulative frequency up to symbol */ + const UWord16 sym_freq_table[], /* i : Symbol frequency */ + const Word16 table_size ) +{ + Word16 symbol; + + symbol = rc_uni_dec_read_symbol_fastS( rc_st_dec, cum_freq_table, sym_freq_table, table_size, ECSQ_PROB_BITS ); + + IF( EQ_16( symbol, sub( table_size, 1 ) ) ) /* escape symbol */ + { + /* decode the additional value using a modified Elias integer code */ + symbol = add( symbol, arith_decode_elias_mod( rc_st_dec ) ); + } + + return symbol; +} +#endif // !IVAS_FLOAT_FIXED /*--------------------------------------------------------------- @@ -116,6 +173,7 @@ static int16_t arith_decode_prob_escape( * the dequantized vector is obtained using the ECSQ_dequantize_vector method * ---------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ECSQ_decode( ECSQ_instance *ecsq_inst, const int16_t N, @@ -217,3 +275,114 @@ void ECSQ_decode( return; } +#else +void ECSQ_decode( + ECSQ_instance *ecsq_inst, + const Word16 N, + Word16 *output ) +{ + Word16 i, idx, segment, segment_count, seg_start, seg_stop; + const UWord16 *tab_vals_cum_freq; + const UWord16 *tab_vals_sym_freq; + const UWord16 *tab_abs_lsbs_cum_freq; + const UWord16 *tab_abs_lsbs_sym_freq; + RangeUniDecState *rc_st_dec; + Word16 param_zb; /* zero-based parameter index for coding */ + Word16 shift, lsbs, nonzero, left1, left0, sym, count0; + + rc_st_dec = (RangeUniDecState *) ecsq_inst->ac_handle; + + + segment_count = shr( sub( add( N, ECSQ_SEGMENT_SIZE ), 1 ), 3 ); + + FOR( segment = 0; segment < segment_count; ++segment ) + { + seg_start = shl( segment, 3 ); + seg_stop = sub( s_min( add( seg_start, ECSQ_SEGMENT_SIZE ), N ), 1 ); + + param_zb = rc_uni_dec_read_symbol_fastS( rc_st_dec, cum_freq_ECSQ_tab_param[ecsq_inst->config_index], sym_freq_ECSQ_tab_param[ecsq_inst->config_index], ECSQ_PARAM_COUNT, ECSQ_PROB_BITS ); + shift = s_max( 0, sub( param_zb, 3 ) ); /* first nonzero shift of 1 is used for param 3 */ + + IF( NE_16( param_zb, 0 ) ) /* not the ECSQ_ALL_ZERO_PARAM param */ + { + tab_vals_cum_freq = cum_freq_ECSQ_tab_vals[sub( param_zb, 1 )]; + tab_vals_sym_freq = sym_freq_ECSQ_tab_vals[sub( param_zb, 1 )]; + idx = s_min( shift, 4 ); + tab_abs_lsbs_cum_freq = cum_freq_ECSQ_tab_abs_lsbs[idx]; + tab_abs_lsbs_sym_freq = sym_freq_ECSQ_tab_abs_lsbs[idx]; + + FOR( i = seg_start; i <= seg_stop; ++i ) + { + sym = arith_decode_prob_escape( rc_st_dec, tab_vals_cum_freq, tab_vals_sym_freq, ECSQ_TAB_VALS_SIZE ); + + IF( NE_16( shift, 0 ) ) + { + IF( GT_16( sym, 0 ) || GT_16( shift, 4 ) ) + { + lsbs = rc_uni_dec_read_bits( rc_st_dec, shift ); + } + ELSE /* (sym == 0) && (shift <= 4) */ + { + lsbs = rc_uni_dec_read_symbol_fastS( rc_st_dec, tab_abs_lsbs_cum_freq, tab_abs_lsbs_sym_freq, shl( 1, shift ), ECSQ_PROB_BITS ); + } + sym = s_or( shl( sym, shift ), lsbs ); + } + + IF( NE_16( sym, 0 ) ) + { + /* map the sign bit to +1 or -1 and then multiply */ + IF( rc_uni_dec_read_bit( rc_st_dec ) ) + { + sym = negate( sym ); + } + } + + output[i] = sym; + } + } + ELSE + { + + nonzero = rc_uni_dec_read_bits( rc_st_dec, 2 ); + + left1 = nonzero; + left0 = sub( add( sub( seg_stop, seg_start ), 1 ), nonzero ); + + FOR( i = seg_start; i <= seg_stop; ++i ) + { + IF( EQ_16( left1, 0 ) ) + { + sym = 0; + } + ELSE IF( EQ_16( left0, 0 ) ) + { + sym = 1; + } + ELSE + { + count0 = left0 * ECSQ_tab_inverse[left0 + left1]; /* left0 * round(ECSQ_PROB_TOTAL / (left0 + left1)) */ + sym = rc_uni_dec_read_bit_prob_fast( rc_st_dec, count0, ECSQ_PROB_BITS ); + } + + IF( NE_16( sym, 0 ) ) + { + /* map the sign bit to +1 or -1 and then multiply */ + IF( rc_uni_dec_read_bit( rc_st_dec ) ) + { + sym = negate( sym ); + } + --left1; + } + ELSE + { + --left0; + } + + output[i] = sym; + } + } + } + + return; +} +#endif // !IVAS_FLOAT_FIXED diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index fa392bc494c58ee475850dc1bd2bbe1ce8e52ef8..1c0a2b69fdf4d63445ddfc8271646293c8642ad7 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -40,6 +40,9 @@ #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- @@ -315,7 +318,22 @@ void stereo_mdct_core_dec( { float sns_int_scf[FDNS_NPTS]; +#ifdef IVAS_FLOAT_FIXED + Word32 sns_int_scf_fx[FDNS_NPTS], Aq_fx[SNS_NPTS]; + FOR( int c = 0; c < SNS_NPTS; c++ ) + { + Aq_fx[c] = (Word32) ( Aq[ch][k * M + c] * ONE_IN_Q16 ); + } + + sns_interpolate_scalefactors_fx( sns_int_scf_fx, Aq_fx, DEC ); + + FOR( int c = 0; c < FDNS_NPTS; c++ ) + { + sns_int_scf[c] = ( (float) sns_int_scf_fx[c] / ONE_IN_Q16 ); + } +#else sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); +#endif // IVAS_FLOAT_FIXED if ( st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) { diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 1969cf9d72844b7acb3607baa393f3be08aa3e84..5bfd6322c7e6a6ac983005f165da08f92f83fd2e 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -43,6 +43,9 @@ #include "prot.h" #include "ivas_prot.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif // IVAS_FLOAT_FIXED /*******************************************************/ @@ -367,7 +370,26 @@ static void CalcPowerSpecAndDetectTonalComponents( } else { +#ifdef IVAS_FLOAT_FIXED + Word32 powerSpectrum_fx[L_FRAME_MAX], invScaleFactors_fx[FDNS_NPTS]; + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum_fx[c] = (Word32) ( powerSpectrum[c] * ONE_IN_Q7 ); + } + FOR( Word16 c = 0; c < FDNS_NPTS; c++ ) + { + invScaleFactors_fx[c] = (Word32) ( invScaleFactors[c] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( powerSpectrum_fx, psychParamsCurrent, invScaleFactors_fx, hTonalMDCTConc->nSamplesCore ); + + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum[c] = ( (float) powerSpectrum_fx[c] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore ); +#endif // IVAS_FLOAT_FIXED nBands = psychParamsCurrent->nBands; } @@ -453,7 +475,26 @@ void TonalMDCTConceal_Detect_ivas( } else { +#ifdef IVAS_FLOAT_FIXED + Word32 powerSpectrum_fx[L_FRAME_MAX], scaleFactors_fx[FDNS_NPTS]; + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum_fx[c] = (Word32) ( powerSpectrum[c] * ONE_IN_Q7 ); + } + FOR( Word16 c = 0; c < FDNS_NPTS; c++ ) + { + scaleFactors_fx[c] = (Word32) ( hTonalMDCTConc->secondLastBlockData.scaleFactors_float[c] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( powerSpectrum_fx, psychParamsCurrent, scaleFactors_fx, hTonalMDCTConc->nSamplesCore ); + + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum[c] = ( (float) powerSpectrum_fx[c] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, hTonalMDCTConc->nSamplesCore ); +#endif // IVAS_FLOAT_FIXED nBands = psychParamsCurrent->nBands; } @@ -885,7 +926,26 @@ void TonalMDCTConceal_Apply_ivas( } else { +#ifdef IVAS_FLOAT_FIXED + Word32 powerSpectrum_fx[L_FRAME_MAX], scaleFactors_fx[FDNS_NPTS]; + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum_fx[c] = (Word32) ( powerSpectrum[c] * ONE_IN_Q7 ); + } + FOR( Word16 c = 0; c < FDNS_NPTS; c++ ) + { + scaleFactors_fx[c] = (Word32) ( hTonalMDCTConc->secondLastBlockData.scaleFactors_float[c] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( powerSpectrum_fx, psychParamsCurrent, scaleFactors_fx, hTonalMDCTConc->nSamplesCore ); + + FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ ) + { + powerSpectrum[c] = ( (float) powerSpectrum_fx[c] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, hTonalMDCTConc->nSamplesCore ); +#endif // IVAS_FLOAT_FIXED nBands = psychParamsCurrent->nBands; } @@ -1149,9 +1209,42 @@ void TonalMdctConceal_whiten_noise_shape_ivas( { float scf[SNS_NPTS]; +#ifdef IVAS_FLOAT_FIXED + Word32 scf_fx[SNS_NPTS]; + Word32 whitenend_noise_shape_fx[L_FRAME16k]; + Word32 scfs_int_fx[FDNS_NPTS], scfs_bg_fx[FDNS_NPTS]; + + FOR( Word16 k = 0; k < L_FRAME16k; k++ ) + { + whitenend_noise_shape_fx[k] = (Word32) ( whitenend_noise_shape[k] * ONE_IN_Q7 ); + } + + sns_compute_scf_fx( whitenend_noise_shape_fx, psychParams, L_frame, scf_fx ); + + sns_interpolate_scalefactors_fx( scfs_int_fx, scf_fx, ENC ); + sns_interpolate_scalefactors_fx( scfs_bg_fx, scf_fx, DEC ); + + FOR( Word16 k = 0; k < SNS_NPTS; k++ ) + { + scf[k] = ( (float) scf_fx[k] / ONE_IN_Q16 ); + + scfs_int[k * 4 + 0] = ( (float) scfs_int_fx[k * 4 + 0] / ONE_IN_Q16 ); + scfs_int[k * 4 + 1] = ( (float) scfs_int_fx[k * 4 + 1] / ONE_IN_Q16 ); + scfs_int[k * 4 + 2] = ( (float) scfs_int_fx[k * 4 + 2] / ONE_IN_Q16 ); + scfs_int[k * 4 + 3] = ( (float) scfs_int_fx[k * 4 + 3] / ONE_IN_Q16 ); + + scfs_bg[k * 4 + 0] = ( (float) scfs_bg_fx[k * 4 + 0] / ONE_IN_Q16 ); + scfs_bg[k * 4 + 1] = ( (float) scfs_bg_fx[k * 4 + 1] / ONE_IN_Q16 ); + scfs_bg[k * 4 + 2] = ( (float) scfs_bg_fx[k * 4 + 2] / ONE_IN_Q16 ); + scfs_bg[k * 4 + 3] = ( (float) scfs_bg_fx[k * 4 + 3] / ONE_IN_Q16 ); + } +#else sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf ); + sns_interpolate_scalefactors( scfs_int, scf, ENC ); sns_interpolate_scalefactors( scfs_bg, scf, DEC ); +#endif // IVAS_FLOAT_FIXED + scfs_for_shaping = &scfs_int[0]; } else /* whitening_mode == ON_FIRST_GOOD_FRAME */ @@ -1161,7 +1254,28 @@ void TonalMdctConceal_whiten_noise_shape_ivas( if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) { +#ifdef IVAS_FLOAT_FIXED + Word32 whitenend_noise_shape_fx[L_FRAME16k]; + Word32 scfs_for_shaping_fx[FDNS_NPTS]; + + FOR( Word16 k = 0; k < L_FRAME16k; k++ ) + { + whitenend_noise_shape_fx[k] = (Word32) ( whitenend_noise_shape[k] * ONE_IN_Q7 ); + } + FOR( Word16 k = 0; k < FDNS_NPTS; k++ ) + { + scfs_for_shaping_fx[k] = (Word32) ( scfs_for_shaping[k] * ONE_IN_Q24 ); + } + + sns_shape_spectrum_fx( whitenend_noise_shape_fx, psychParams, scfs_for_shaping_fx, L_frame ); + + FOR( Word16 k = 0; k < L_FRAME16k; k++ ) + { + whitenend_noise_shape[k] = ( (float) whitenend_noise_shape_fx[k] / ONE_IN_Q6 ); + } +#else sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); +#endif // IVAS_FLOAT_FIXED mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx ); } else