From 539e17180a5940d78bd2ec703d8f8552b2d6c789 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 11 Sep 2024 16:54:57 +0530 Subject: [PATCH] Core coder functions integration/conversion to fixed point [x] acelp_core_enc porting [x] Conversion of SetTCXModeInfo() function in ivas_mdct_core_whitening_enc() call stack [x] Fix for LTV crash - ltv-stereo at 13.2 kbps, 48kHz in, 48kHz out [x] stereo_tcx_core_enc: Integrated writeTCXParam and writeLPCparam [x] hq lr enc conversion in hq-core path --- lib_com/ACcontextMapping_fx.c | 17 + lib_com/basop_util.c | 3 +- lib_com/bits_alloc.c | 10 + lib_com/bits_alloc_fx.c | 1076 +++++++++++++ lib_com/bitstream.c | 82 +- lib_com/hq2_core_com_fx.c | 183 +++ lib_com/ivas_prot_fx.h | 39 + lib_com/lsf_tools_fx.c | 83 +- lib_com/parameter_bitmaping.c | 95 ++ lib_com/prot.h | 30 + lib_com/prot_fx.h | 138 ++ lib_com/rom_com.c | 23 + lib_com/rom_com.h | 1 + lib_dec/FEC_HQ_phase_ecu_fx.c | 6 +- lib_dec/dec_tcx.c | 2 +- lib_enc/ACcontextMapping_enc_fx.c | 321 ++-- lib_enc/acelp_core_enc.c | 1261 +++++---------- lib_enc/ari_hm_enc_fx.c | 30 + lib_enc/core_switching_enc.c | 9 + lib_enc/enc_prm_fx.c | 425 +++++ lib_enc/gp_clip_fx.c | 58 + lib_enc/hq_core_enc.c | 30 +- lib_enc/hq_env_enc_fx.c | 541 ++++++- lib_enc/hq_lr_enc_fx.c | 2492 ++++++++++++++++++++++++++--- lib_enc/igf_enc_fx.c | 30 + lib_enc/ivas_mdct_core_enc.c | 51 +- lib_enc/ivas_range_uni_enc.c | 288 +++- lib_enc/ivas_tcx_core_enc.c | 8 +- lib_enc/lsf_enc.c | 1 + lib_enc/lsf_enc_fx.c | 67 +- lib_enc/lsf_msvq_ma_enc_fx.c | 95 ++ lib_enc/prot_fx_enc.h | 138 +- lib_enc/qlpc_avq_fx.c | 263 +++ lib_enc/stat_enc.h | 19 +- lib_enc/swb_bwe_enc_lr_fx.c | 283 ++++ lib_enc/tcq_core_enc_fx.c | 484 +++++- lib_enc/tns_base_enc_fx.c | 35 + lib_enc/transient_detection_fx.c | 250 ++- 38 files changed, 7647 insertions(+), 1320 deletions(-) diff --git a/lib_com/ACcontextMapping_fx.c b/lib_com/ACcontextMapping_fx.c index ef5508692..d55bcd6ac 100644 --- a/lib_com/ACcontextMapping_fx.c +++ b/lib_com/ACcontextMapping_fx.c @@ -74,3 +74,20 @@ Word16 update_mixed_context( Word16 ctx, Word16 a ) } return add( shl( s_and( ctx, 0xf ), 4 ), add( t, 13 ) ); } + +#ifdef IVAS_FLOAT_FIXED +Word32 update_mixed_context_ivas_fx( Word32 ctx, Word16 a ) +{ + Word32 t32; + + t32 = L_mac0( 1 - 13, s_and( a, ~1 ), add( shr( a, 2 ), 1 ) ); + + a = shr( a, 3 ); + + IF( t32 > 0 ) + { + t32 = L_min( a, 2 ); + } + return L_add( L_shl( L_and( ctx, 0xf ), 4 ), L_add( t32, 13 ) ); +} +#endif diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 3a1a8abaf..71f324f98 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -185,7 +185,8 @@ Word32 BASOP_Util_Log10( Word32 x, Word16 e ) } } Word32 res = BASOP_Util_Log2( x ); - res = L_add( Mpy_32_32( res, 646456993 /* log10(2) in Q31 */ ), Mpy_32_32( L_shl( e, 25 ), 646456993 /* log10(2) in Q31 */ ) ); // Adjusting for the exponent mismatch: multiplying first so as to avoid saturation + res = L_add( Mpy_32_32( res, 646456993 /* log10(2) in Q31 */ ), Mpy_32_32( L_shl( e, 24 ), 1292913986 /* log10(2) in Q32 */ ) ); // Adjusting for the exponent mismatch: multiplying first so as to avoid saturation + /* log10(2) is used in Q32 to support exponent till 127 in Mpy_32_32( L_shl( e, 24 ), 1292913986 )*/ return res; } diff --git a/lib_com/bits_alloc.c b/lib_com/bits_alloc.c index 3bec92ac8..67840f93e 100644 --- a/lib_com/bits_alloc.c +++ b/lib_com/bits_alloc.c @@ -48,7 +48,9 @@ static int16_t BITS_ALLOC_adjust_acelp_fixed_cdk( const int16_t bits_frame, int16_t *fixed_cdk_index, const int16_t nb_subfr ); +#ifndef IVAS_FLOAT_FIXED static int16_t allocate_unused( const int32_t core_brate, const int16_t coder_type, const int16_t unused_bits, const int16_t nb_prm, const int16_t subfr, const int16_t prm_type, int16_t *prm_bit_mode ); +#endif typedef enum { @@ -356,6 +358,7 @@ static int16_t BITS_ALLOC_adjust_acelp_fixed_cdk( * Selection of fixed innovation codebook bitbudget table *--------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t fcb_table( const int16_t n, const int16_t L_subfr ) @@ -370,6 +373,7 @@ static int16_t fcb_table( return ( out ); } +#endif /*-------------------------------------------------------------------* * acelp_FCB_allocator() @@ -377,6 +381,7 @@ static int16_t fcb_table( * Routine to allocate fixed innovation codebook bit-budget *--------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static ivas_error acelp_FCB_allocator( int16_t *nBits, /* i/o: available bit-budget */ int16_t fixed_cdk_index[], /* o : codebook index */ @@ -507,6 +512,7 @@ static ivas_error acelp_FCB_allocator( return error; } +#endif /*-------------------------------------------------------------------* @@ -517,6 +523,7 @@ static ivas_error acelp_FCB_allocator( * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz *--------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED ivas_error config_acelp1_IVAS( const int16_t enc_dec, /* i : encoder/decoder flag */ const int32_t total_brate, /* i : total bitrate */ @@ -1334,6 +1341,7 @@ ivas_error config_acelp1_IVAS( return error; } +#endif /*-------------------------------------------------------------------* * allocate_unused() @@ -1341,6 +1349,7 @@ ivas_error config_acelp1_IVAS( * Allocate unused bits *--------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t allocate_unused( const int32_t core_brate, const int16_t coder_type, @@ -1417,6 +1426,7 @@ static int16_t allocate_unused( return bit_added + max_bit_per_pos; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index be8fa2db1..c625f01fa 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -1744,6 +1744,1082 @@ ivas_error config_acelp1( return error; } +/*-------------------------------------------------------------------* + * config_acelp1_IVAS() + * + * Configure ACELP bit allocation + * - should be in range of <6700; 24350> for ACELP@12.8kHz + * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz + *--------------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED +ivas_error config_acelp1_IVAS( + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +) +{ + Word16 i, bits, nb_subfr; + Word16 flag_hardcoded, coder_type_sw, fix_first; + Word32 core_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + /*-----------------------------------------------------------------* + * Set the flag indicating two-stage Unvoiced (UC) frame + *-----------------------------------------------------------------*/ + + *uc_two_stage_flag = 0; + move16(); + + IF( EQ_16( coder_type, UNVOICED ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( GE_32( total_brate, MIN_UNVOICED_TWO_STAGE_BRATE ) && element_mode > EVS_MONO && ( idchan == 0 || ( ( GE_32( total_brate, 8500 ) || extl_brate == 0 ) && EQ_16( tdm_LRTD_flag, 1 ) ) ) ) + { + *uc_two_stage_flag = 1; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Set the number of subframes + *-----------------------------------------------------------------*/ + + IF( EQ_16( L_frame, L_FRAME ) ) + { + nb_subfr = NB_SUBFR; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + nb_subfr = NB_SUBFR16k; + move16(); + } + + coder_type_sw = coder_type; + move16(); + IF( core != ACELP_CORE ) + { + /* used in acelp_core_switch_enc() */ + nb_subfr = 1; + move16(); + if ( EQ_16( L_frame, L_FRAME ) ) + { + coder_type_sw = TRANSITION; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Check if the core_brate is hard coded (to keep BE for mono core) or not + *-----------------------------------------------------------------*/ + + flag_hardcoded = 0; + move16(); + i = 0; + move16(); + + WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) + { + IF( EQ_32( core_brate_inp, brate_intermed_tbl[i] ) ) + { + flag_hardcoded = 1; + move16(); + break; + } + + IF( LT_32( core_brate_inp, brate_intermed_tbl[i] ) ) + { + flag_hardcoded = 0; + move16(); + break; + } + + i = add( i, 1 ); + } + + test(); + test(); + test(); + if ( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( coder_type, AUDIO ) && + LE_32( core_brate_inp, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ + { + i = sub( i, 1 ); + } + + core_brate = brate_intermed_tbl[i]; + move32(); + + if ( element_mode > EVS_MONO ) + { + flag_hardcoded = 0; /* use automatic and flexible ACELP bit-budget allocation */ + move16(); + } + + test(); + if ( core != ACELP_CORE && element_mode == EVS_MONO ) /* needed for mode1 core switching in EVS mono */ + { + flag_hardcoded = 1; + move16(); + } + + /*-----------------------------------------------------------------* + * ACELP bit allocation + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( !( EQ_16( coder_type, TRANSITION ) && NE_16( tc_subfr, -1 ) ) || EQ_16( enc_dec, DEC ) ) + { + /* Set the bit-budget */ + bits = divide3216( core_brate_inp, FRAMES_PER_SEC / 2 ); + + test(); + test(); + if ( EQ_16( coder_type, TRANSITION ) && EQ_16( enc_dec, DEC ) && EQ_16( tc_call, 1 ) ) + { + bits = add( bits, *nBits_es_Pred ); /* equalize for 4th signaling bit estimated at the encoder in TC_0_192 */ + } + + test(); + test(); + /* Subtract signaling bits */ + IF( EQ_16( enc_dec, DEC ) && EQ_16( idchan, 1 ) && element_mode > EVS_MONO ) + { + bits = sub( bits, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); + + if ( EQ_16( tdm_LRTD_flag, 1 ) ) + { + bits = add( bits, STEREO_BITS_TCA ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + /* subtract TBE/BWE flag */ + if ( extl_brate > 0 && ( EQ_16( extl, WB_TBE ) || EQ_16( extl, SWB_TBE ) || EQ_16( extl, FB_TBE ) || EQ_16( extl, WB_BWE ) || EQ_16( extl, SWB_BWE ) || EQ_16( extl, FB_BWE ) ) ) + { + bits = sub( bits, 1 ); + } + } + ELSE + { + /* Subtract signaling bits */ + bits = sub( bits, signaling_bits ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + if ( extl_brate > 0 && ( EQ_16( extl, WB_TBE ) || EQ_16( extl, SWB_TBE ) || EQ_16( extl, FB_TBE ) || EQ_16( extl, WB_BWE ) || EQ_16( extl, SWB_BWE ) || EQ_16( extl, FB_BWE ) ) ) + { + /* extension layer signaling bit is counted in the extension layer bitbudget */ + bits = add( bits, 1 ); + } + + /*-----------------------------------------------------------------* + * LSF Q bit-budget + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( !tdm_lp_reuse_flag || idchan == 0 ) + { + /* LSF Q bit-budget */ + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX( core_brate, coder_type )]; + move16(); + + IF( !flag_hardcoded ) + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( element_mode, IVAS_SCE ) && tdm_low_rate_mode ) + { + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX( core_brate, coder_type )]; + move16(); + } + ELSE IF( ( LT_32( total_brate, 7200 ) || coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( idchan, 1 ) ) + { + /* TD stereo, secondary channel: do nothing */ + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX( core_brate, coder_type )]; + move16(); + } + ELSE IF( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) && LT_32( brate_intermed_tbl[i], ACELP_9k60 ) ) + { + /* primary channel: do nothing */ + } + ELSE IF( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) /*&& brate_intermed_tbl[i] >= ACELP_9k60*/ ) + { + acelp_cfg->lsf_bits = 42; + move16(); + } + ELSE IF( LE_32( total_brate, 9600 ) || EQ_16( coder_type, UNVOICED ) ) + { + acelp_cfg->lsf_bits = 31; + move16(); + } + ELSE IF( LE_32( total_brate, 20000 ) ) + { + acelp_cfg->lsf_bits = 36; + move16(); + } + ELSE + { + acelp_cfg->lsf_bits = 41; + move16(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + acelp_cfg->lsf_bits = 41; + move16(); + } + } + + bits = sub( bits, acelp_cfg->lsf_bits ); + + /* mid-LSF Q bit-budget */ + acelp_cfg->mid_lsf_bits = mid_LSF_bits_tbl[LSF_BIT_ALLOC_IDX( core_brate, coder_type )]; + move16(); + + test(); + if ( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) /*&& brate_intermed_tbl[i] < ACELP_9k60*/ ) + { + acelp_cfg->mid_lsf_bits = 5; + move16(); + /* primary channel: do nothing */ + } + + bits = sub( bits, acelp_cfg->mid_lsf_bits ); + } + ELSE IF( EQ_16( tdm_lp_reuse_flag, 1 ) && EQ_16( idchan, 1 ) && NE_16( active_cnt, 1 ) ) + { + bits = sub( bits, TDM_IC_LSF_PRED_BITS ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + /* gain Q bit-budget - part 1 */ + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && NE_16( coder_type, INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( EQ_16( coder_type, INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) + { + *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; + move16(); + bits = sub( bits, *nBits_es_Pred ); + } + ELSE IF( *uc_two_stage_flag ) + { + *nBits_es_Pred = 4; + move16(); + bits = sub( bits, *nBits_es_Pred ); + } + } + ELSE + { + bits = *unbits; + move16(); + } + + test(); + IF( EQ_16( coder_type, TRANSITION ) && EQ_16( tc_call, 0 ) ) + { + *unbits = bits; + move16(); + return error; + } + + /*-----------------------------------------------------------------* + * Low-rate mode - bits are allocated in tdm_low_rate_enc() + *-----------------------------------------------------------------*/ + + test(); + IF( EQ_16( element_mode, IVAS_SCE ) && tdm_low_rate_mode ) + { + acelp_cfg->FEC_mode = 0; + move16(); + acelp_cfg->ltf_mode = FULL_BAND; + move16(); + *nBits_es_Pred = 0; + move16(); + *unbits = 0; + move16(); + acelp_cfg->ubits = 0; + move16(); + + return error; + } + + /*-----------------------------------------------------------------* + * Supplementary information for FEC + *-----------------------------------------------------------------*/ + + acelp_cfg->FEC_mode = 0; + move16(); + test(); + test(); + IF( GE_32( core_brate, ACELP_11k60 ) && ( idchan == 0 || element_mode == EVS_MONO ) ) + { + acelp_cfg->FEC_mode = 1; + move16(); + + test(); + test(); + if ( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) && NE_16( coder_type, VOICED ) ) + { + bits = sub( bits, FEC_BITS_CLS ); + } + + IF( NE_16( coder_type, TRANSITION ) ) + { + IF( GE_32( total_brate, ACELP_16k40 ) ) + { + acelp_cfg->FEC_mode = 2; + move16(); + + test(); + if ( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) ) + { + bits = sub( bits, FEC_BITS_ENR ); + } + } + + IF( GE_32( total_brate, ACELP_32k ) ) + { + acelp_cfg->FEC_mode = 3; + move16(); + + test(); + if ( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) ) + { + bits = sub( bits, FEC_BITS_POS ); + } + } + } + } + + /*-----------------------------------------------------------------* + * LP filtering of the adaptive excitation + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( idchan > 0 && element_mode > EVS_MONO ) + { + acelp_cfg->ltf_mode = FULL_BAND; + move16(); + } + ELSE IF( EQ_16( coder_type, UNVOICED ) ) + { + acelp_cfg->ltf_mode = FULL_BAND; + move16(); + } + ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) ) && LT_32( core_brate, ACELP_11k60 ) ) + { + acelp_cfg->ltf_mode = LOW_PASS; + move16(); + } + ELSE IF( GE_32( core_brate, ACELP_11k60 ) && ( NE_16( coder_type, AUDIO ) && !( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME ) ) ) ) + { + test(); + test(); + IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ + { + acelp_cfg->ltf_mode = FULL_BAND; + move16(); + } + ELSE + { + acelp_cfg->ltf_mode = NORMAL_OPERATION; + move16(); + if ( coder_type != TRANSITION ) + { + bits = sub( bits, nb_subfr ); + } + } + } + ELSE + { + acelp_cfg->ltf_mode = FULL_BAND; + move16(); + } + + /*-----------------------------------------------------------------* + * UC bit-budget + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + if ( ( ( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) || ( coder_type == INACTIVE && LE_32( core_brate, ACELP_9k60 ) ) ) && ( idchan == 0 || element_mode == EVS_MONO ) ) + { + bits = sub( bits, NBITS_NOISENESS ); /* noiseness */ + } + test(); + if ( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) + { + bits = sub( bits, ( 3 * NB_SUBFR ) ); /* tilt factor */ + } + + /*-----------------------------------------------------------------* + * TC bit-budget + *-----------------------------------------------------------------*/ + + fix_first = 0; + move16(); + IF( EQ_16( coder_type, TRANSITION ) ) + { + IF( EQ_16( tc_call, 2 ) ) + { + fix_first = 1; + move16(); + } + + /* TC signaling */ + IF( EQ_16( L_frame, L_FRAME ) ) + { + IF( EQ_16( tc_subfr, TC_0_0 ) ) + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 1 ); /* TC signaling */ + } + + if ( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) + { + bits = sub( bits, 3 ); /* LP filtering flag */ + } + } + ELSE IF( EQ_16( tc_subfr, TC_0_64 ) ) + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 4 ); /* TC signaling */ + } + + if ( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) + { + bits = sub( bits, 3 ); /* LP filtering flag */ + } + } + ELSE IF( EQ_16( tc_subfr, TC_0_128 ) ) + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 4 ); /* TC signaling */ + } + + if ( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) + { + bits = sub( bits, 2 ); /* LP filtering flag */ + } + } + ELSE IF( EQ_16( tc_subfr, TC_0_192 ) ) + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 3 ); /* TC signaling */ + } + + if ( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) + { + bits = sub( bits, 1 ); /* LP filtering flag */ + } + } + ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 3 ); /* TC signaling */ + } + + test(); + IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) && NE_16( tc_subfr, 192 ) ) + { + bits = sub( bits, idiv1616( sub( L_FRAME - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ + } + } + ELSE + { + if ( enc_dec == ENC ) + { + bits = sub( bits, 4 ); /* TC signaling */ + } + + test(); + IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) && NE_16( tc_subfr, 192 ) ) + { + bits = sub( bits, idiv1616( sub( L_FRAME - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ + } + } + } + ELSE /* L_frame == L_FRAME16k */ + { + if ( enc_dec == ENC ) + { + IF( LE_16( tc_subfr, 2 * L_SUBFR ) ) + { + bits = sub( bits, 2 ); /* TC signaling */ + } + ELSE + { + bits = sub( bits, 3 ); /* TC signaling */ + } + } + + IF( NE_16( tc_subfr, 256 ) ) + { + bits = sub( bits, idiv1616( sub( L_FRAME16k - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ + } + } + + /* glottal-shape codebook bits */ + bits = sub( bits, ( 3 + 6 + 1 + 3 ) ); + } + + /*-----------------------------------------------------------------* + * pitch, innovation, gains bit-budget + *-----------------------------------------------------------------*/ + + acelp_cfg->fcb_mode = 0; + move16(); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( tdm_low_rate_mode, 1 ) && coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) ) /* GENERIC low rate mode for secondary channel */ + { + set16_fx( acelp_cfg->pitch_bits, 0, NB_SUBFR16k ); + set16_fx( acelp_cfg->gains_mode, 0, NB_SUBFR16k ); + + FOR( i = 0; i < 2; i++ ) + { + acelp_cfg->pitch_bits[i] = 0; + move16(); + IF( tdm_Pitch_reuse_flag == 0 ) + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX( ACELP_7k20, GENERIC, 2 * i * L_SUBFR, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + bits = sub( bits, acelp_cfg->pitch_bits[i] ); + } + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX( ACELP_7k20, GENERIC, i * L_SUBFR, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + bits = sub( bits, acelp_cfg->gains_mode[i] ); + } + acelp_cfg->fcb_mode = 1; + move16(); + + IF( GE_16( bits, 16 ) ) + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); + } + ELSE + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); + acelp_cfg->fixed_cdk_index[1] = -1; + move16(); + } + acelp_cfg->fixed_cdk_index[2] = -1; + move16(); + acelp_cfg->fixed_cdk_index[3] = -1; + move16(); + } + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) + { + /* pitch Q & gain Q bit-budget - part 2*/ + FOR( i = 0; i < nb_subfr; i++ ) + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + test(); + IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) && EQ_16( idchan, 1 ) ) + { + acelp_cfg->pitch_bits[i] = 0; + move16(); + } + ELSE + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + } + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type_sw, i * L_SUBFR, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + test(); + IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) && EQ_16( idchan, 1 ) ) + { + acelp_cfg->pitch_bits[i] = 0; + move16(); + } + ELSE + { + acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ( core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ( tc_subfr ) )]; + move16(); + } + acelp_cfg->gains_mode[i] = gain_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ( core_brate, coder_type_sw, i * L_SUBFR, TC_SUBFR2IDX_16KHZ( tc_subfr ) )]; + move16(); + } + + bits = sub( bits, acelp_cfg->pitch_bits[i] ); + + test(); + IF( coder_type == INACTIVE && EQ_16( acelp_cfg->gains_mode[i], 6 ) /* VQ vs. SQ threshold @32 kbps */ ) + { + bits = sub( bits, 5 ); + } + ELSE + { + IF( EQ_16( *uc_two_stage_flag, 1 ) ) + { + acelp_cfg->gains_mode[i] = 7; + move16(); + } + + bits = sub( bits, acelp_cfg->gains_mode[i] ); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + /* algebraic codebook bit-budget */ + IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) + { + FOR( i = 0; i < nb_subfr; i++ ) + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + acelp_cfg->fixed_cdk_index[i] = FCB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ( core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ( tc_subfr ) )]; + move16(); + } + bits = sub( bits, acelp_cfg->fixed_cdk_index[i] ); + } + } + ELSE IF( !( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) ) + { + test(); + IF( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) + { + i = idiv1616( bits, NB_SUBFR ); + if ( i % 2 == 0 ) + { + i = sub( i, 1 ); /* must be odd */ + } + i = s_min( i, 13 ); + i = s_max( i, 0 ); /* If i == 0-> random noise generator will be used as FCB */ + set16_fx( acelp_cfg->fixed_cdk_index, i, NB_SUBFR ); + bits = sub( bits, imult1616( i, NB_SUBFR ) ); + } + ELSE + { + acelp_cfg->fcb_mode = 1; + move16(); + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) ) + { + IF( GE_16( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), nb_subfr ) ) ) /* enough bits for all fcb */ + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + } + ELSE IF( GE_16( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 1 ) ) ) ) + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 1 ), L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_cfg->fixed_cdk_index[3] = -1; + move16(); + } + ELSE IF( GE_32( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 2 ) ) ) ) + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 2 ), L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_cfg->fixed_cdk_index[2] = acelp_cfg->fixed_cdk_index[1]; + move16(); + acelp_cfg->fixed_cdk_index[1] = -1; + move16(); + acelp_cfg->fixed_cdk_index[3] = -1; + move16(); + } + ELSE IF( GE_32( bits, ACELP_FIXED_CDK_BITS( 0 ) ) ) + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 1, L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_cfg->fixed_cdk_index[1] = acelp_cfg->fixed_cdk_index[0]; + move16(); + acelp_cfg->fixed_cdk_index[0] = -1; + move16(); + acelp_cfg->fixed_cdk_index[2] = -1; + move16(); + acelp_cfg->fixed_cdk_index[3] = -1; + move16(); + } + ELSE /* No FCB */ + { + acelp_cfg->fixed_cdk_index[0] = -1; + move16(); + acelp_cfg->fixed_cdk_index[1] = -1; + move16(); + acelp_cfg->fixed_cdk_index[2] = -1; + move16(); + acelp_cfg->fixed_cdk_index[3] = -1; + move16(); + } + } + ELSE IF( NE_16( element_mode, IVAS_CPE_TD ) && GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) + { + bits = 100; /* 9 kbps for fcb */ + move16(); + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + } + ELSE + { + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + } + } + } + + test(); + test(); + test(); + /* AVQ codebook */ + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) + { + FOR( i = 0; i < nb_subfr; i++ ) + { + IF( flag_hardcoded ) + { + acelp_cfg->AVQ_cdk_bits[i] = AVQ_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ( core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ( tc_subfr ) )]; + move16(); + { + bits = sub( bits, acelp_cfg->AVQ_cdk_bits[i] ); + } + } + + bits = sub( bits, G_AVQ_BITS ); + } + + test(); + test(); + if ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && LE_32( core_brate_inp, MAX_BRATE_AVQ_EXC_TD ) && EQ_16( coder_type, GENERIC ) ) + { + /* harm. flag ACELP AVQ */ + bits = sub( bits, 1 ); + } + + IF( !flag_hardcoded ) + { + Word16 bit_tmp; + + bit_tmp = idiv1616( bits, nb_subfr ); + set16_fx( acelp_cfg->AVQ_cdk_bits, bit_tmp, nb_subfr ); + bits = sub( bits, imult1616( bit_tmp, nb_subfr ) ); + + bit_tmp = bits % nb_subfr; + acelp_cfg->AVQ_cdk_bits[0] = add( acelp_cfg->AVQ_cdk_bits[0], bit_tmp ); + bits = sub( bits, bit_tmp ); + } + } + } + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) + { + Word32 Local_BR, Pitch_BR; + Word16 Pitch_CT; + + /* as defined at the beginning of [enc,dec]_pit_exc() */ + test(); + test(); + IF( GSC_IVAS_mode > 0 && ( GSC_noisy_speech || GT_32( core_brate, GSC_H_RATE_STG ) ) ) + { + Local_BR = ACELP_8k00; + move32(); + Pitch_CT = GENERIC; + move16(); + Pitch_BR = ACELP_8k00; + move32(); + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + Local_BR = ACELP_14k80; + move32(); + test(); + if ( GSC_IVAS_mode > 0 && LT_32( core_brate, IVAS_24k4 ) ) + { + Local_BR = ACELP_9k60; + move32(); + } + Pitch_BR = core_brate; + move32(); + } + } + ELSE IF( GSC_noisy_speech ) + { + Local_BR = ACELP_7k20; + move32(); + Pitch_CT = GENERIC; + move16(); + Pitch_BR = ACELP_7k20; + move32(); + if ( EQ_16( L_frame, L_FRAME16k ) ) + { + Pitch_BR = core_brate; + move16(); + } + } + ELSE + { + Local_BR = ACELP_7k20; + move32(); + Pitch_CT = AUDIO; + move16(); + Pitch_BR = core_brate; + move32(); + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + Local_BR = ACELP_13k20; + move32(); + Pitch_CT = GENERIC; + move16(); + } + } + + FOR( i = 0; i < nb_subfr; i++ ) + { + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ( Pitch_BR, Pitch_CT, i * L_SUBFR, 0 )]; + move16(); + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX( Local_BR, LOCAL_CT, i * L_SUBFR, 0 )]; + move16(); + } + ELSE + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX( Pitch_BR, Pitch_CT, i * L_SUBFR, 0 )]; + move16(); + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX( Local_BR, LOCAL_CT, i * L_SUBFR, 0 )]; + move16(); + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX( ACELP_7k20, LOCAL_CT, i * L_SUBFR, 0 )]; + move16(); + } + } + } + + test(); + test(); + test(); + IF( EQ_16( coder_type, TRANSITION ) && ( EQ_16( tc_call, 1 ) && tc_subfr == 0 && EQ_16( L_frame, L_FRAME ) ) ) + { + return error; + } + + /*-----------------------------------------------------------------* + * unused bits handling + *-----------------------------------------------------------------*/ + + acelp_cfg->ubits = 0; /* these bits could be reused for something else */ + move16(); + + test(); + IF( flag_hardcoded && NE_32( core_brate, PPP_NELP_2k80 ) ) + { + /* unused bits */ + test(); + test(); + IF( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE && LE_32( core_brate, ACELP_24k40 ) ) ) + { + acelp_cfg->ubits = 0; + move16(); + } + ELSE IF( EQ_16( L_frame, L_FRAME ) ) + { + acelp_cfg->ubits = reserved_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, TC_SUBFR2IDX( tc_subfr ) )]; + move16(); + } + ELSE + { + acelp_cfg->ubits = 0; + move16(); + } + + bits = sub( bits, acelp_cfg->ubits ); + } + + /* sanity check */ + test(); + test(); + test(); + IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || EQ_16( nb_subfr, NB_SUBFR16k ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ + { + acelp_cfg->ubits = 0; + move16(); + } + ELSE IF( flag_hardcoded && core == ACELP_CORE && bits != 0 ) + { + } + ELSE IF( bits > 0 && !( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) ) + { + test(); + test(); + test(); + test(); + IF( idchan > 0 && EQ_16( element_mode, IVAS_CPE_TD ) ) + { + IF( !tdm_lp_reuse_flag ) + { + acelp_cfg->lsf_bits = add( acelp_cfg->lsf_bits, bits ); /* increase LSF Q bits */ + move16(); + bits = 0; + move16(); + } + ELSE + { + Word16 nb_prm = 4; + move16(); + + if ( EQ_16( tdm_low_rate_mode, 1 ) ) + { + nb_prm = 2; + move16(); + } + /* First add remaining bits on gains */ + bits = sub( bits, allocate_unused( core_brate, coder_type, bits, nb_prm, 0, GAINSPRM, acelp_cfg->gains_mode ) ); + + /* Then, Increase pitch bit budget */ + test(); + IF( tdm_Pitch_reuse_flag == 0 && bits > 0 ) + { + bits = sub( bits, allocate_unused( core_brate, coder_type, bits, nb_prm, 0, PITCHPRM, acelp_cfg->pitch_bits ) ); + } + + /* Increase mid-lsf bit budget */ + test(); + IF( tdm_lp_reuse_flag == 0 && bits > 0 ) + { + bits = sub( bits, allocate_unused( core_brate, coder_type, bits, 1, 0, MID_LSFSPRM, &acelp_cfg->mid_lsf_bits ) ); + bits = sub( bits, allocate_unused( core_brate, coder_type, bits, 1, 0, LSFPRM, &acelp_cfg->lsf_bits ) ); + } + } + } + + ELSE IF( core == ACELP_CORE && GE_16( coder_type, UNVOICED ) && LE_16( coder_type, GENERIC ) && EQ_16( L_frame, L_FRAME ) ) + { + acelp_cfg->lsf_bits = add( acelp_cfg->lsf_bits, bits ); /* increase LSF Q bits */ + move16(); + + test(); + IF( GT_16( acelp_cfg->lsf_bits, 46 ) ) + { + acelp_cfg->ubits = sub( acelp_cfg->lsf_bits, 46 ); + move16(); + acelp_cfg->lsf_bits = 46; + move16(); + } + ELSE IF( GT_16( acelp_cfg->lsf_bits, 42 ) && EQ_16( L_frame, L_FRAME ) ) + { + acelp_cfg->ubits = sub( acelp_cfg->lsf_bits, 42 ); + move16(); + acelp_cfg->lsf_bits = 42; + move16(); + } + } + ELSE + { + acelp_cfg->ubits = bits; + move16(); + } + } + /*else if ( bits < 0 && !( coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD ) ) + { + }*/ + } + + return error; +} +#endif + /*-------------------------------------------------------------------* * allocate_unused() * diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 975dd3293..e8d44551c 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1727,7 +1727,7 @@ ivas_error push_next_indice( * push_next_bits() * Push a bit buffer into the buffer at the next position *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED ivas_error push_next_bits( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const uint16_t bits[], /* i : bit buffer to pack, sequence of single bits */ @@ -1793,7 +1793,87 @@ ivas_error push_next_bits( return error; } +#else +ivas_error push_next_bits( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ + const Word16 nb_bits /* i : number of bits to pack */ +) +{ + UWord16 code; + Word16 i, nb_bits_m15; + Indice *ptr; + Word16 prev_id; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; + + /* get the id of the previous indice -> will be re-used */ + IF( hBstr->nb_ind_tot > 0 ) + { + prev_id = hBstr->ind_list[hBstr->nb_ind_tot - 1].id; + move16(); + } + ELSE + { + prev_id = 0; + move16(); + } + nb_bits_m15 = sub( nb_bits, 15 ); + + FOR( i = 0; i < nb_bits_m15; i += 16 ) + { + code = (UWord16) L_or( L_shl( bits[i], 15 ), L_or( L_shl( bits[i + 1], 14 ), L_or( L_shl( bits[i + 2], 13 ), L_or( L_shl( bits[i + 3], 12 ), L_or( L_shl( bits[i + 4], 11 ), L_or( L_shl( bits[i + 5], 10 ), L_or( L_shl( bits[i + 6], 9 ), L_or( L_shl( bits[i + 7], 8 ), L_or( L_shl( bits[i + 8], 7 ), L_or( L_shl( bits[i + 9], 6 ), L_or( L_shl( bits[i + 10], 5 ), L_or( L_shl( bits[i + 11], 4 ), L_or( L_shl( bits[i + 12], 3 ), L_or( L_shl( bits[i + 13], 2 ), L_or( L_shl( bits[i + 14], 1 ), bits[i + 15] ) ) ) ) ) ) ) ) ) ) ) ) ) ) ); + + /* check the limits of the list of indices */ + IF( NE_32( ( error = check_ind_list_limits( hBstr ) ), IVAS_ERR_OK ) ) + { + return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices (frame %d) !\n" ); + } + ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; + ptr->value = code; + ptr->nb_bits = 16; + ptr->id = prev_id; + hBstr->nb_ind_tot = add( hBstr->nb_ind_tot, 1 ); + move16(); + move16(); + move16(); + move16(); + + ++ptr; + } + + FOR( ; i < nb_bits; ++i ) + { + /* check the limits of the list of indices */ + IF( NE_32( ( error = check_ind_list_limits( hBstr ) ), IVAS_ERR_OK ) ) + { + return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices (frame %d) !\n" ); + } + ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; + + ptr->value = bits[i]; + ptr->nb_bits = 1; + ptr->id = prev_id; + hBstr->nb_ind_tot = add( hBstr->nb_ind_tot, 1 ); + move16(); + move16(); + move16(); + move16(); + + ++ptr; + } + + hBstr->nb_bits_tot = add( hBstr->nb_bits_tot, nb_bits ); + move16(); + + return error; +} +#endif /*-------------------------------------------------------------------* * find_indice() diff --git a/lib_com/hq2_core_com_fx.c b/lib_com/hq2_core_com_fx.c index 58bc1934b..d24bb0d96 100644 --- a/lib_com/hq2_core_com_fx.c +++ b/lib_com/hq2_core_com_fx.c @@ -221,6 +221,189 @@ void mdct_spectrum_denorm_fx( return; } + + +#ifdef IVAS_FLOAT_FIXED +void mdct_spectrum_denorm_ivas_fx( + const Word32 inp_vector[], /* i : Q0 : */ + Word32 L_y2[], /* i/o : Qs : decoded spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */ + const Word32 L_band_energy[], /* i : Qbe : band energy */ + const Word16 npulses[], /* i : Q0 : number of coded spectrum */ + const Word16 bands, /* i : Q0 : number of subbands */ + const Word16 ld_slope_fx, /* i : Q15 : */ + const Word16 pd_thresh_fx /* i : Q15 : */ +) +{ + Word16 i, k; + Word32 L_Eyy; + Word32 L_tmp, L_temp; + Word16 temp_fx, temp_lo_fx, temp_hi_fx; + Word32 L_inp_tmp[L_FRAME48k]; + Word16 exp_norm; + Word16 exp_safe; + Word16 exp_normn, exp_normd; + + Word16 pd_fx; + Word16 Qpd; + + Word16 div_pd_fx; + Word16 Qdivpd; + Word32 L_div_pd; + + Word16 frac, exp; + + Word16 gain_tweak_fx; + Word16 Qtweak; + + Word16 exp_shift; + + Word16 QEyy; + Word16 pow_fx; + Word16 Qpow; + Word16 Qdiv; + Word16 Qgamma; + Word16 gamma_fx; + + Word16 cond_fx; + +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); /* allow overflow happen. */ +#endif + + exp_safe = 4; /* safe bit for overflow */ + move16(); + + FOR( k = 0; k < bands; k++ ) + { + L_tmp = L_deposit_l( 0 ); + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + L_inp_tmp[i] = L_mult( extract_l( inp_vector[i] ), extract_l( inp_vector[i] ) ); + move32(); /* Q0+Q0+1 */ + L_tmp = L_or( L_tmp, L_inp_tmp[i] ); + } + exp_norm = norm_l( L_tmp ); + exp_norm = sub( exp_norm, exp_safe ); + + L_Eyy = L_deposit_l( 0 ); + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + /*Eyy += (float) inp_vector[i] * inp_vector[i]; */ + L_Eyy = L_add( L_Eyy, L_shl( L_inp_tmp[i], exp_norm ) ); /* Q1+exp_norm */ + } + QEyy = add( 1, exp_norm ); + + IF( L_Eyy > 0x0L ) + { + /* Set gamma to be pulse gain which results in perfect quantized subband energy */ + /*gamma = (float) sqrt (pow (2.0f, band_energy[k]) / Eyy); */ + + /* Pow part (pow(2.0f, band_energy) ) */ + L_temp = L_shr( L_band_energy[k], sub( SWB_BWE_LR_Qbe, 16 ) ); + temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx ); + Qpow = sub( 14, temp_hi_fx ); + pow_fx = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qpow */ + + /* Div part ( pow (2.0f, band_energy[i])/Eyy ) */ + exp_normn = norm_s( pow_fx ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_l( L_Eyy ); + temp_fx = div_s( shl( pow_fx, exp_normn ), extract_h( L_shl( L_Eyy, exp_normd ) ) ); + Qdiv = add( sub( add( Qpow, exp_normn ), add( QEyy, exp_normd ) ), 31 ); + + exp_norm = norm_s( temp_fx ); + temp_fx = shl( temp_fx, exp_norm ); + Qdiv = add( Qdiv, exp_norm ); + + /* Sqrt part sqrt(pow (2.0f, band_energy[i])/Eyy) */ + Qgamma = add( Qdiv, 16 ); + IF( s_and( Qdiv, 1 ) == 0 ) /* Qdiv % 2 == 0 */ + { + L_temp = Sqrt_l( L_shr( L_deposit_h( temp_fx ), 1 ), &exp_norm ); + L_temp = L_shr( L_temp, exp_norm ); + Qgamma = sub( shr( Qgamma, 1 ), 1 ); + gamma_fx = round_fx( L_temp ); + } + ELSE + { + L_temp = Sqrt_l( L_deposit_h( temp_fx ), &exp_norm ); + L_temp = L_shr( L_temp, exp_norm ); + Qgamma = shr( Qgamma, 1 ); + gamma_fx = round_fx( L_temp ); + } + + /* Adjust gamma based on pulse density (0 bit MSE gain estimator) */ + /*pd = (float) npulses[k] / band_width[k]; */ + exp_normn = norm_s( npulses[k] ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( band_width[k] ); + pd_fx = div_s( shl( npulses[k], exp_normn ), shl( band_width[k], exp_normd ) ); + Qpd = add( sub( exp_normn, exp_normd ), 15 ); + +#ifdef BASOP_NOGLOB + cond_fx = sub( shl_o( pd_fx, sub( 15, Qpd ), &Overflow ), pd_thresh_fx /*Q15*/ ); +#else /* BASOP_NOGLOB */ + cond_fx = sub( shl( pd_fx, sub( 15, Qpd ) ), pd_thresh_fx /*Q15*/ ); +#endif + Overflow = 0; + move16(); /* allow overflow happen. */ + IF( cond_fx < 0 ) + { + /*gain_tweak = (float) pow (2.0f, (ld_slope * log2_f (pd / pd_thresh))); */ + /* Div part */ + exp_normn = norm_s( pd_fx ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( pd_thresh_fx ); + div_pd_fx = div_s( shl( pd_fx, exp_normn ), shl( pd_thresh_fx, exp_normd ) ); /* Qpd+exp_normn - (15 + exp_normd) + 15 */ + Qdivpd = add( sub( add( Qpd, exp_normn ), add( 15, exp_normd ) ), 15 ); + + /* Log2 part */ + exp_norm = norm_s( div_pd_fx ); + L_div_pd = L_deposit_h( shl( div_pd_fx, exp_norm ) ); + Qdivpd = add( add( Qdivpd, exp_norm ), 16 ); + + frac = Log2_norm_lc( L_div_pd ); + exp = sub( 30, Qdivpd ); + L_tmp = L_Comp( exp, frac ); /* Q16 */ + + /* Mult part */ + L_tmp = Mpy_32_16_1( L_tmp, ld_slope_fx ); + + /* Pow part */ + temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx ); + Qtweak = sub( 14, temp_hi_fx ); + gain_tweak_fx = extract_l( Pow2( 14, temp_lo_fx ) ); + + /*gamma *= gain_tweak; */ + L_tmp = L_mult( gamma_fx, gain_tweak_fx ); /* Qgamma+Qtweak+1 */ + exp_norm = norm_l( L_tmp ); +#ifdef BASOP_NOGLOB + gamma_fx = round_fx_o( L_shl_o( L_tmp, exp_norm, &Overflow ), &Overflow ); +#else + gamma_fx = round_fx( L_shl( L_tmp, exp_norm ) ); +#endif + Qgamma = sub( add( add( Qgamma, Qtweak ), exp_norm ), 15 ); /*Qgamma+Qtweak+1+exp_norm-16; */ + } + + exp_shift = sub( SWB_BWE_LR_Qs - 1, Qgamma ); + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + /*y2[i] = gamma * inp_vector[i]; */ + L_tmp = L_mult( gamma_fx, extract_l( inp_vector[i] ) ); /* Qgamma+0+1=Qgamma+1 */ + L_y2[i] = L_shl( L_tmp, exp_shift ); + move32(); + } + } + } + + return; +} +#endif + /*==========================================================================*/ /* FUNCTION : void hq2_core_configure_fx() */ /*--------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 86a915bb9..850985440 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2653,3 +2653,42 @@ void ivas_param_mc_metadata_open_fx( const Word32 ivas_total_brate, /* i : IVAS total bitrate */ HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* o : handle for the Parametric MC parameter coding state */ ); + +/*----------------------------------------------------------------------------------* + * Range Coder prototypes + *----------------------------------------------------------------------------------*/ + +void rc_uni_enc_init( + RangeUniEncState *rc_st_enc /* i/o: RC state handle */ +); + +void rc_uni_enc_encode_fast( + RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ + const UWord16 cum_freq, /* i : Cumulative frequency up to symbol */ + const UWord16 sym_freq, /* i : Symbol frequency */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +); + +void rc_uni_enc_encode_symbol_fastS( + RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ + const UWord16 symbol, /* i : Symbol to encode */ + const UWord16 cum_freq[], /* i : Cumulative frequency up to symbol */ + const UWord16 sym_freq[], /* i : Symbol frequency */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +); + +/*! r: Total number of bits produced */ +Word16 rc_uni_enc_finish( + RangeUniEncState *rc_st_enc /* i/o: RC state handle */ +); + +/*! r: Total number of bits produced */ +Word16 rc_uni_enc_virtual_finish( + RangeUniEncState *rc_st_enc /* i : RC state handle */ +); + +void rc_uni_enc_encode_bits( + RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ + const UWord16 value, /* i : Value to encode */ + const Word16 bits /* i : Number of bits */ +); diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index c3fb62b86..3a84633af 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -1282,7 +1282,7 @@ void reorder_lsf_fx( lsf[i] = lsf_min; move16(); } - lsf_min = add( lsf[i], min_dist ); + lsf_min = add_sat( lsf[i], min_dist ); } /*-----------------------------------------------------------------------* @@ -2902,6 +2902,87 @@ void lsf_syn_mem_backup_fx( return; } +#ifdef IVAS_FLOAT_FIXED +void lsf_syn_mem_backup_ivas_fx( + Encoder_State *st_fx, /* i: state structure */ + Word16 *btilt_code_fx, /* i: tilt code */ + Word32 *gc_threshold_fx, /* i: */ + Word16 *clip_var_bck_fx, /* o: */ + Word16 *next_force_sf_bck_fx, /* o: */ + + Word16 *lsp_new, /* i: LSP vector to quantize */ + Word16 *lsp_mid, /* i: mid-frame LSP vector */ + Word16 *clip_var, /* o: pitch clipping state var */ + Word16 *mem_AR, /* o: quantizer memory for AR model */ + Word16 *mem_MA, /* o: quantizer memory for AR model */ + Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup */ + Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup */ + Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets */ + Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets */ + Word16 *mem_syn_bck, /* o: synthesis filter memory */ + Word16 *mem_w0_bck, /* o: memory of the weighting filter */ + Word16 *streaklimit, + Word16 *pstreaklen ) +{ + Word16 i; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + + *clip_var = st_fx->clip_var_fx[0]; + move16(); + + FOR( i = 0; i < M; i++ ) + { + mem_AR[i] = st_fx->mem_AR_fx[i]; + move16(); + mem_MA[i] = st_fx->mem_MA_fx[i]; + move16(); + lsp_new_bck[i] = lsp_new[i]; + move16(); + lsp_mid_bck[i] = lsp_mid[i]; + move16(); + } + + *streaklimit = st_fx->streaklimit_fx; + move16(); + *pstreaklen = st_fx->pstreaklen; + move16(); + + FOR( i = 0; i < L_FFT; i++ ) + { + Bin_E[i] = st_fx->Bin_E_fx[i]; + move32(); + } + + FOR( i = 0; i < ( L_FFT / 2 ); i++ ) + { + Bin_E_old[i] = st_fx->Bin_E_old_fx[i]; + move32(); + } + + /* back-up memories */ + FOR( i = 0; i < M; i++ ) + { + mem_syn_bck[i] = hLPDmem->mem_syn[i]; + move16(); + } + + *mem_w0_bck = hLPDmem->mem_w0; + move16(); + + + *btilt_code_fx = hLPDmem->tilt_code; + move16(); + *gc_threshold_fx = hLPDmem->gc_threshold; + move16(); + Copy( st_fx->clip_var_fx, clip_var_bck_fx, 6 ); + *next_force_sf_bck_fx = st_fx->next_force_safety_net_fx; + move16(); + + + return; +} +#endif + void lsf_update_memory( Word16 narrowband, /* i : narrowband flag */ const Word16 qlsf[], /* i : quantized lsf coefficients */ diff --git a/lib_com/parameter_bitmaping.c b/lib_com/parameter_bitmaping.c index aae7af5f0..4c8d6d999 100644 --- a/lib_com/parameter_bitmaping.c +++ b/lib_com/parameter_bitmaping.c @@ -76,7 +76,26 @@ static Word16 PutIntoBitstream_fx( return value; } +#ifdef IVAS_FLOAT_FIXED +static Word16 PutIntoBitstream_ivas_fx( + const Word16 **pStream, + TEncodeValue EncodeValue, + Word16 index, + BSTR_ENC_HANDLE hBstr, + const Word16 nBits ) +{ + Word16 value; + Word16 codedValue; + move16(); + value = *( *pStream )++; + codedValue = EncodeValue( value, index ); + + push_next_indice( hBstr, codedValue, nBits ); + + return value; +} +#endif /** Get nBits long value from bitstream into *pStream. */ static int16_t GetFromBitstream( Decoder_State *st, @@ -99,13 +118,21 @@ static int16_t GetFromBitstream( return value; } +#ifdef IVAS_FLOAT_FIXED +static Word16 FixedWidthEncoding( Word16 value, Word16 index ) +{ + (void) index; /* suppress compiler warnings */ + return value; +} +#else static int16_t FixedWidthEncoding( int16_t value, int16_t index ) { (void) index; /* suppress compiler warnings */ return value; } +#endif /********************************/ @@ -359,7 +386,75 @@ void WriteToBitstream_fx( } } } +#ifdef IVAS_FLOAT_FIXED +void WriteToBitstream_ivas_fx( + ParamsBitMap const *paramsBitMap, + const Word16 nArrayLength, + const Word16 **pStream, + Word16 *pnSize, + BSTR_ENC_HANDLE hBstr, + Word16 *pnBits ) +{ + Word16 index; + Word16 iParam, nParams; + + + assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pStream != NULL ) && ( pnSize != NULL ) && ( hBstr != NULL ) && ( pnBits != NULL ) ); + nParams = paramsBitMap->nParams; + move16(); + + FOR( index = 0; index < nArrayLength; index++ ) + { + + FOR( iParam = 0; iParam < nParams; iParam++ ) + { + ParamBitMap const *param; + Word16 nBits; + /* If a function for encoding/decoding value is defined than it should take care of 0 */ + Word16 fShiftValue; + TEncodeValue EncodeValue; + Word16 value; + move16(); + param = ¶msBitMap->params[iParam]; + + move16(); + nBits = param->nBits; + IF( param->nBits == 0 ) + { +#define WMC_TOOL_SKIP + nBits = param->GetNumberOfBits( **pStream, index ); +#undef WMC_TOOL_SKIP + } + + fShiftValue = s_and( param->fZeroAllowed == 0, param->EncodeValue == NULL ); + + EncodeValue = param->EncodeValue; + if ( param->EncodeValue == NULL ) + { + move16(); + EncodeValue = &FixedWidthEncoding; + } + value = PutIntoBitstream_ivas_fx( pStream, EncodeValue, index, hBstr, nBits ); + IF( fShiftValue ) + { + value = add( value, 1 ); + } + + move16(); + *pnSize = add( *pnSize, 1 ); + move16(); + *pnBits = add( *pnBits, nBits ); + + test(); + IF( ( param->pSubParamBitMap != NULL ) && ( value > 0 ) ) + { + WriteToBitstream_ivas_fx( param->pSubParamBitMap, value, pStream, pnSize, hBstr, pnBits ); + } + } + } +} +#endif void ReadFromBitstream( ParamsBitMap const *paramsBitMap, diff --git a/lib_com/prot.h b/lib_com/prot.h index 27b358b7f..13606feb2 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2357,6 +2357,7 @@ void MDCT_classifier_reset( TCX_ENC_HANDLE hTcxEnc /* i/o: TCX Encoder Handle */ ); +#ifndef IVAS_FLOAT_FIXED ivas_error acelp_core_enc( Encoder_State *st, /* i/o: encoder state structure */ const float inp[], /* i : input signal of the current frame */ @@ -2376,6 +2377,27 @@ ivas_error acelp_core_enc( STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ ); +#else +ivas_error acelp_core_enc( + Encoder_State *st, /* i/o: encoder state structure */ + /*const*/ float inp[], /* i : input signal of the current frame */ + const float ener, /* i : residual energy from Levinson-Durbin */ + float A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ + float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes */ + const float epsP[M + 1], /* i : LP prediction errors */ + float lsp_new[M], /* i : LSPs at the end of the frame */ + float lsp_mid[M], /* i : LSPs in the middle of the frame */ + const int16_t vad_hover_flag, /* i : VAD hangover flag */ + const int16_t attack_flag, /* i : attack flag (GSC or TC) */ + float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ + float *voice_factors, /* o : voicing factors */ + float old_syn_12k8_16k[], /* o : ACELP core synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ + float pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ + int16_t *unbits, /* o : number of unused bits */ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ +); +#endif ivas_error acelp_core_switch_dec_bfi( Decoder_State *st /* i/o: decoder state structure */ @@ -9022,6 +9044,14 @@ void WriteToBitstream_fx( BSTR_ENC_HANDLE hBstr, Word16 *pnBits ); +void WriteToBitstream_ivas_fx( + ParamsBitMap const *paramsBitMap, + const Word16 nArrayLength, + const Word16 **pStream, + Word16 *pnSize, + BSTR_ENC_HANDLE hBstr, + Word16 *pnBits ); + void ReadFromBitstream( ParamsBitMap const *paramsBitMap, const int16_t nArrayLength, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index da94afae5..f5c8fba0e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2109,6 +2109,19 @@ void mdct_spectrum_denorm_fx( const Word16 pd_thresh_fx /* i : Q15 : */ ); +void mdct_spectrum_denorm_ivas_fx( + const Word32 inp_vector[], /* i : Q0 : */ + Word32 L_y2[], /* i/o : Qs : decoded spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */ + const Word32 L_band_energy[], /* i : Qbe : band energy */ + const Word16 npulses[], /* i : Q0 : number of coded spectrum */ + const Word16 bands, /* i : Q0 : numbers of subbands */ + const Word16 ld_slope_fx, /* i : Q15 : */ + const Word16 pd_thresh_fx /* i : Q15 : */ +); + void hq2_core_configure_fx( const Word16 frame_length, const Word16 num_bits, @@ -3428,6 +3441,14 @@ void gp_clip_test_lsf_fx( const Word16 m /* i : dimension of lsf */ ); +void gp_clip_test_lsf_ivas_fx( + const Word16 element_mode, /* i : element mode */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 lsf[], /* i : LSF vector */ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +); + /*========================================================================================================/ nelp_enc_fx.c /========================================================================================================*/ @@ -3475,6 +3496,31 @@ void swb_bwe_enc_lr_fx( Word16 *ni_seed_fx /* i/o: random seed for search buffer NI */ ); +void swb_bwe_enc_lr_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 L_m_core[], /* i : lowband synthesis */ + Word16 QsL, + const Word32 L_m_orig[], /* i/o: scaled orig signal (MDCT) */ + Word32 L_m[], /* o : highband synthesis with lowband zeroed */ + const Word32 L_total_brate, /* i : total bitrate for selecting subband pattern */ + Word16 BANDS_fx, /* i : Total number of Subbands in a frame */ + Word16 *band_start_fx, /* i : band start of each SB */ + Word16 *band_end_fx, /* i : band end of each SB */ + Word32 *L_band_energy, /* i : band_energy of each SB */ + Word16 Qbe, /* i : Q value of band energy */ + Word16 *p2a_flags_fx, /* i : HF tonal indicator */ + const Word16 hqswb_clas_fx, /* i : HQ_NORMAL2 or HQ_HARMONIC mode */ + Word16 lowlength_fx, /* i : lowband length */ + Word16 highlength_fx, /* i : highband length */ + Word16 *prev_frm_index_fx, /* i/o: previous frame lag index for harmonic mode */ + const Word16 har_bands_fx, /* i : Number of LF harmonic bands */ + Word16 *prev_frm_hfe2, /* i/o: */ + Word16 *prev_stab_hfe2, /* i/o: */ + const Word16 band_width_fx[], /* i : band_width information */ + const Word32 L_y2_ni[], /* i : band_width information */ + Word16 *ni_seed_fx /* i/o: random seed for search buffer NI */ +); + /*========================================================================================================/ isf_enc_amr_wb_fx.c /========================================================================================================*/ @@ -8704,6 +8750,8 @@ Word16 get_next_coeff_unmapped( Word16 update_mixed_context( Word16 ctx, Word16 a ); +Word32 update_mixed_context_ivas_fx( Word32 ctx, Word16 a ); + // ACcontextMapping_dec_fx.c @@ -10349,4 +10397,94 @@ Word16 ari_decode_14bits_sign_ivas( Word16 bits, Word16 *res, Tastat *s ); + +void lsf_syn_mem_backup_ivas_fx( + Encoder_State *st_fx, /* i: state structure */ + Word16 *btilt_code_fx, /* i: tilt code */ + Word32 *gc_threshold_fx, /* i: */ + Word16 *clip_var_bck_fx, /* o: */ + Word16 *next_force_sf_bck_fx, /* o: */ + + Word16 *lsp_new, /* i: LSP vector to quantize */ + Word16 *lsp_mid, /* i: mid-frame LSP vector */ + Word16 *clip_var, /* o: pitch clipping state var */ + Word16 *mem_AR, /* o: quantizer memory for AR model */ + Word16 *mem_MA, /* o: quantizer memory for AR model */ + Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup */ + Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup */ + Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets */ + Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets */ + Word16 *mem_syn_bck, /* o: synthesis filter memory */ + Word16 *mem_w0_bck, /* o: memory of the weighting filter */ + Word16 *streaklimit, + Word16 *pstreaklen ); + +ivas_error config_acelp1_IVAS( + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +ivas_error push_next_indice( + BSTR_ENC_HANDLE hBstr, + UWord16 value, /* i : value of the quantized indice */ + Word16 nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_bits( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ + const Word16 nb_bits /* i : number of bits to pack */ +); + +/*! r: index of next coefficient */ +Word16 get_next_coeff_mapped_ivas( + Word16 ii[2], /* i/o: coefficient indexes */ + Word32 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +); + +void RCcontextMapping_encode2_no_mem_s17_LCS_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 *x, + const Word16 nt, + Word16 lastnz, + const Word16 nbbits, + const Word16 resQMaxBits, + CONTEXT_HM_CONFIG *hm_cfg ); + +void writeTCXparam_fx( + Encoder_State *st, /* i/o: Encoder State handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ + Word16 param[], /* i : parameters */ + const Word16 nbits_header, + const Word16 nbits_start, + const Word16 nbits_lpc, + const Word16 *no_param_tns, /* i : number of TNS parameters per subframe */ + Word16 p_param[2], /* i/o: pointer to parameters from previous bs writing */ + const Word16 target_bitsTCX10[2], + const Word16 pre_past_flag ); #endif diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 0d4488499..838bbe9bd 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -22748,6 +22748,29 @@ const Word16 sigma_p_ivas_fx[][16] = {178, 205, 259, 258, 273, 285, 275, 289, 299, 300, 310, 320, 335, 329, 316, 269}, }; +const Word16 inv_sigma_p_ivas_fx[][16] = +{ + {552, 513, 470, 494, 487, 478, 492, 496, 496, 482, 480, 389, 339, 276, 743, 760}, + {640, 492, 472, 478, 482, 471, 470, 471, 623, 504, 501, 477, 459, 425, 420, 408}, + {1002, 939, 696, 589, 545, 480, 456, 450, 444, 462, 472, 424, 342, 441, 1568, 2996}, + {609, 534, 419, 432, 444, 403, 406, 407, 392, 425, 452, 378, 269, 278, 818, 1940}, + {32767}, + {575, 507, 459, 432, 425, 415, 440, 442, 449, 450, 489, 443, 299, 270, 1378, 2449}, + {591, 499, 456, 457, 449, 441, 448, 446, 444, 435, 420, 397, 364, 342, 496, 475}, + {482, 512, 498, 426, 280, 225, 422, 1410, 404, 404, 402, 385, 364, 342, 355, 361}, + {918, 832, 572, 507, 482, 430, 406, 399, 385, 366, 364, 344, 313, 309, 311, 335}, + {533, 436, 371, 399, 398, 368, 367, 348, 343, 342, 338, 319, 306, 305, 311, 334}, + {32767}, + {641, 523, 458, 434, 415, 410, 412, 395, 397, 394, 386, 380, 366, 392, 413, 419}, + {449, 380, 364, 366, 355, 362, 362, 356, 337, 323, 293, 296, 336, 352, 353, 283}, + {32767}, + {659, 486, 371, 386, 318, 328, 289, 284, 283, 258, 251, 257, 278, 290, 305, 330}, + {338, 279, 247, 244, 233, 239, 231, 232, 228, 215, 194, 194, 207, 210, 222, 180}, + {32767}, + {594, 466, 394, 376, 362, 358, 346, 350, 336, 332, 313, 329, 343, 358, 370, 419}, + {471, 409, 323, 325, 308, 295, 304, 290, 281, 280, 271, 262, 251, 255, 266, 312} +}; + const Word8 leaders_short[][MAX_NO_SCALES] = {{ 0, 0, 0}, { 1, 0, 0}, diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 414185564..48f78c8f5 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -638,6 +638,7 @@ extern const float inv_sigma_MSLVQ[][16]; extern const Word16 inv_sigma_MSLVQ_fx[][16]; extern const float inv_sigma_p[][16]; extern const Word16 inv_sigma_p_fx[][16]; +extern const Word16 inv_sigma_p_ivas_fx[][16]; extern const float scales[][MAX_NO_SCALES * 2]; extern const float scales_p[][MAX_NO_SCALES * 2]; extern const Word16 scales_fx[][MAX_NO_SCALES * 2]; diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 77a82258b..1508b8668 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -3067,10 +3067,10 @@ static void ivas_rec_wtda_fx( tmp_e = 0; tmp = BASOP_Util_Divide1616_Scale( ONE_IN_Q14, *w_hamm, &tmp_e ); tmp = shl( tmp, 1 ); - tmp = shr( tmp, sub( 4, tmp_e ) ); // Q11 - *pX_start = shl( mult_r( *pX_start, tmp ), 4 ); // Qin + tmp = shr( tmp, sub( 4, tmp_e ) ); // Q11 + *pX_start = shl_sat( mult_r( *pX_start, tmp ), 4 ); // Qin move16(); - *pX_end = shl( mult_r( *pX_end, tmp ), 4 ); // Qin + *pX_end = shl_sat( mult_r( *pX_end, tmp ), 4 ); // Qin move16(); pX_start++; pX_end--; diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index 1891fc2ab..b952ba542 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -2029,7 +2029,7 @@ void decoder_tcx_imdct_fx( } } - ITF_Detect_ivas_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); + ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 11d60b854..88494bb5b 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -8,8 +8,9 @@ #include "basop_util.h" #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "rom_com.h" -//#include "prot_fx.h" +#include "ivas_rom_com.h" #include "prot_fx_enc.h" /*-------------------------------------------------------------------* @@ -726,8 +727,6 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( return nbits_old; } -#ifdef IVAS_CODE_RANGE_CODER - /* Range Coder Functions */ /*-------------------------------------------------------------------* @@ -736,86 +735,103 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( * Range encoder *-------------------------------------------------------------------*/ -void RCcontextMapping_encode2_no_mem_s17_LCS( +void RCcontextMapping_encode2_no_mem_s17_LCS_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - const int16_t nt, - int16_t lastnz, - const int16_t nbbits, - const int16_t resQMaxBits, + Word16 *x, + const Word16 nt, + Word16 lastnz, + const Word16 nbbits, + const Word16 resQMaxBits, CONTEXT_HM_CONFIG *hm_cfg ) { - int16_t ptr[BITBUFSIZE]; + Word16 ptr[BITBUFSIZE]; RangeUniEncState rc_st_enc; - int16_t bp; - int16_t rc_tot_bits; /* No. of bits returned by range coder */ - int16_t pki, lev1; - uint16_t t; - int16_t rateFlag; - int16_t value; - int16_t nbbits_ntuples, nbbits_lsbs, nbbits_signs; - int16_t *lsbs_bits; - int16_t nt_half; - int16_t signs[N_MAX]; - int16_t a1, b1, k; + Word16 bp; + Word16 rc_tot_bits; /* No. of bits returned by range coder */ + Word16 pki, lev1; + UWord16 t; + Word16 rateFlag; + Word16 value; + Word16 nbbits_ntuples, nbbits_lsbs, nbbits_signs; + Word16 *lsbs_bits; + Word16 nt_half; + Word16 signs[N_MAX]; + Word16 a1, b1, k; a1 = 0; /* to avoid compilation warnings */ b1 = 0; /* to avoid compilation warnings */ /* Init */ - nt_half = nt >> 1; + nt_half = shr( nt, 1 ); /* Bits for encoding the number of encoded tuples */ nbbits_ntuples = 0; k = 1; - while ( k < nt / 2 ) + move16(); + move16(); + + WHILE( LT_16( k, shr( nt, 1 ) ) ) { - nbbits_ntuples++; - k = k << 1; + nbbits_ntuples = add( nbbits_ntuples, 1 ); + k = shl( k, 1 ); } t = 0; nbbits_signs = 0; nbbits_lsbs = 0; + move16(); + move16(); + move16(); - if ( hm_cfg ) + IF( hm_cfg ) { - int16_t a1_i, b1_i; - int32_t c[2], *ctx; - int32_t p1, p2; - int16_t ii[2]; - int16_t idx1, idx2, idx; - int16_t numPeakIndicesOrig, numHoleIndices; + Word16 a1_i, b1_i; + Word32 c[2], *ctx; + Word32 p1, p2; + Word16 ii[2]; + Word16 idx1, idx2, idx; + Word16 numPeakIndicesOrig, numHoleIndices; /* Rate flag */ - if ( nbbits > 400 ) + IF( GT_16( nbbits, 400 ) ) { rateFlag = 2 << NBITS_CONTEXT; + move16(); } - else + ELSE { rateFlag = 0; + move16(); } c[0] = c[1] = 0; + move32(); + move32(); /* mapped domain */ numPeakIndicesOrig = hm_cfg->numPeakIndices; - hm_cfg->numPeakIndices = min( hm_cfg->numPeakIndices, lastnz ); - numHoleIndices = lastnz - hm_cfg->numPeakIndices; + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); + move16(); + move16(); /* Mark hole indices beyond lastnz as pruned */ - for ( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) + FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) { - hm_cfg->holeIndices[k] = hm_cfg->holeIndices[k] + nt; + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); + move16(); } ii[0] = numPeakIndicesOrig; ii[1] = 0; + move16(); + move16(); p1 = p2 = 0; /* to avoid compilation warnings */ + move16(); + move16(); - lsbs_bits = ptr + nbbits - 1; + lsbs_bits = ptr + sub( nbbits, 1 ); /*Start Encoding*/ /* Initialize range encoder */ @@ -823,252 +839,317 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( /*Main Loop through the 2-tuples*/ b1_i = -1; + move16(); - for ( k = 0; k < lastnz; k += 2 ) + FOR( k = 0; k < lastnz; k += 2 ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); - idx = min( idx1, idx2 ); + idx = s_min( idx1, idx2 ); /* Get context */ - ctx = &c[p1 | p2]; + ctx = &c[L_or( p1, p2 )]; - t = (uint16_t) ( *ctx + rateFlag ); - t += ( nt_half >= idx ) ? 0 : ( 1 << NBITS_CONTEXT ); + t = (UWord16) L_add( *ctx, rateFlag ); + // t += ( nt_half >= idx ) ? 0 : ( 1 << NBITS_CONTEXT ); + IF( LT_16( nt_half, idx ) ) + { + t = add( t, ( 1 << NBITS_CONTEXT ) ); + } /* Init current 2-tuple encoding */ - a1 = (int16_t) abs( x[a1_i] ); - b1 = (int16_t) abs( x[b1_i] ); + a1 = abs_s( x[a1_i] ); + b1 = abs_s( x[b1_i] ); lev1 = -1; + move16(); /*Signs encoding*/ - if ( a1 > 0 ) + IF( a1 > 0 ) { - signs[nbbits_signs++] = ( (uint16_t) x[a1_i] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + // signs[nbbits_signs++] = ( (uint16_t) x[a1_i] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + if ( x[a1_i] >= 0 ) + { + signs[nbbits_signs] = 0; + move16(); + } + if ( x[a1_i] < 0 ) + { + signs[nbbits_signs] = 1; + move16(); + } + nbbits_signs = add( nbbits_signs, 1 ); } - if ( b1 > 0 ) + IF( b1 > 0 ) { - signs[nbbits_signs++] = ( (uint16_t) x[b1_i] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + // signs[nbbits_signs++] = ( (uint16_t) x[b1_i] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + if ( x[b1_i] >= 0 ) + { + signs[nbbits_signs] = 0; + move16(); + } + if ( x[b1_i] < 0 ) + { + signs[nbbits_signs] = 1; + move16(); + } + nbbits_signs = add( nbbits_signs, 1 ); } /* MSBs coding */ - while ( max( a1, b1 ) >= A_THRES ) + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) { pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + move16(); rc_uni_enc_encode_symbol_fastS( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ - *lsbs_bits-- = a1 & 1; - *lsbs_bits-- = b1 & 1; + *lsbs_bits-- = s_and( a1, 1 ); + *lsbs_bits-- = s_and( b1, 1 ); + move16(); + move16(); /* LSBs bit counting */ - nbbits_lsbs += 2; + nbbits_lsbs = add( nbbits_lsbs, 2 ); - a1 >>= 1; - b1 >>= 1; + a1 = shr( a1, 1 ); + b1 = shr( b1, 1 ); - lev1 = min( lev1 + 1, 2 ); + lev1 = s_min( add( lev1, 1 ), 2 ); } pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + move16(); rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ -#ifdef DEBUGGING - assert( rc_uni_enc_virtual_finish( &rc_st_enc ) <= nbbits - nbbits_signs - nbbits_lsbs - nbbits_ntuples ); -#endif /* Update context for next 2-tuple */ - if ( p1 == p2 ) + IF( EQ_32( p1, p2 ) ) { /* peak-peak or hole-hole context */ - if ( lev1 <= 0 ) + IF( lev1 <= 0 ) { - t = 1 + ( a1 + b1 ) * ( lev1 + 2 ); + t = (UWord16) L_add( 1, L_mult0( add( a1, b1 ), add( lev1, 2 ) ) ); } - else + ELSE { - t = 13 + lev1; + t = (UWord16) L_add( 13, lev1 ); } - *ctx = ( *ctx & 0xf ) * 16 + t; + *ctx = L_add( L_shl( L_and( *ctx, 0xf ), 4 ), t ); + move32(); } - else + ELSE { /* mixed context */ - if ( idx1 & 1 ) + IF( s_and( idx1, 1 ) ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas_fx( c[p1], abs_s( x[a1_i] ) ); + move32(); } - if ( idx2 & 1 ) + IF( s_and( idx2, 1 ) ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas_fx( c[p2], abs_s( x[b1_i] ) ); + move32(); } } } /*end of the 2-tuples loop*/ } - else /* if (!hm_cfg) */ + ELSE /* if (!hm_cfg) */ { - int16_t cp; - int16_t esc_nb, rateQ; - uint16_t s; + Word16 cp; + Word16 esc_nb, rateQ; + UWord16 s; /* Rate flag */ - if ( nbbits > 400 ) + IF( GT_16( nbbits, 400 ) ) { rateFlag = 2; + move16(); } - else + ELSE { rateFlag = 0; + move16(); } s = 0; + move16(); /* Find last non-zero tuple */ /* ensure termination of while loop by dummy value */ a1 = x[0]; x[0] = 1; /* ensure first tuple is non-zero */ + move16(); + move16(); - while ( x[lastnz - 1] == 0 && x[lastnz - 2] == 0 ) + WHILE( x[lastnz - 1] == 0 && x[lastnz - 2] == 0 ) { - lastnz -= 2; + test(); + lastnz = sub( lastnz, 2 ); } x[0] = a1; + move16(); - lsbs_bits = ptr + nbbits - 1; + lsbs_bits = ptr + sub( nbbits, 1 ); /*Start Encoding*/ /* Initialize range encoder */ rc_uni_enc_init( &rc_st_enc ); /*Main Loop through the 2-tuples*/ - for ( k = 0; k < lastnz; k += 2 ) + FOR( k = 0; k < lastnz; k += 2 ) { /* Init current 2-tuple encoding */ - a1 = (int16_t) abs( x[k + 0] ); - b1 = (int16_t) abs( x[k + 1] ); + a1 = abs_s( x[k + 0] ); + b1 = abs_s( x[k + 1] ); lev1 = 0; esc_nb = 0; + move16(); + move16(); /*Signs encoding*/ - if ( a1 > 0 ) + IF( a1 > 0 ) { - signs[nbbits_signs++] = ( (uint16_t) x[k + 0] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + // signs[nbbits_signs++] = ( (uint16_t) x[k + 0] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + if ( x[k] >= 0 ) + { + signs[nbbits_signs] = 0; + move16(); + } + if ( x[k] < 0 ) + { + signs[nbbits_signs] = 1; + move16(); + } + nbbits_signs = add( nbbits_signs, 1 ); } - if ( b1 > 0 ) + IF( b1 > 0 ) { - signs[nbbits_signs++] = ( (uint16_t) x[k + 1] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + // signs[nbbits_signs++] = ( (uint16_t) x[k + 1] >> ( sizeof( uint16_t ) * 8 - 1 ) ); + if ( x[k + 1] >= 0 ) + { + signs[nbbits_signs] = 0; + move16(); + } + if ( x[k + 1] < 0 ) + { + signs[nbbits_signs] = 1; + move16(); + } + nbbits_signs = add( nbbits_signs, 1 ); } - rateQ = rateFlag + ( k > ( nt >> 1 ) ); + rateQ = add( rateFlag, (Word16) GT_16( k, shr( nt, 1 ) ) ); /* MSBs coding */ - while ( max( a1, b1 ) >= A_THRES ) + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) { pki = ari_lookup_s17_LC[t + ( ( rateQ ) << NBITS_CONTEXT ) + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + move16(); rc_uni_enc_encode_symbol_fastS( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ - *lsbs_bits-- = a1 & 1; - *lsbs_bits-- = b1 & 1; + *lsbs_bits-- = s_and( a1, 1 ); + *lsbs_bits-- = s_and( b1, 1 ); + move16(); + move16(); /* LSBs bit counting */ - nbbits_lsbs += 2; + nbbits_lsbs = add( nbbits_lsbs, 2 ); - a1 >>= 1; - b1 >>= 1; + a1 = shr( a1, 1 ); + b1 = shr( b1, 1 ); - lev1++; - esc_nb = min( lev1, 3 ); + lev1 = add( lev1, 1 ); + esc_nb = s_min( lev1, 3 ); } + move16(); pki = ari_lookup_s17_LC[t + ( ( rateQ ) << NBITS_CONTEXT ) + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ -#ifdef DEBUGGING - assert( rc_uni_enc_virtual_finish( &rc_st_enc ) <= nbbits - nbbits_signs - nbbits_lsbs - nbbits_ntuples ); -#endif /* Update context for next 2-tuple */ - if ( esc_nb < 2 ) + IF( LT_16( esc_nb, 2 ) ) { - cp = 1 + ( ( a1 + b1 ) * ( esc_nb + 1 ) ); + cp = add( 1, imult1616( add( a1, b1 ), add( esc_nb, 1 ) ) ); } - else + ELSE { - cp = 12 + esc_nb; + cp = add( 12, esc_nb ); } /*Shift old 4 bits, replace last 4 bits*/ - s = ( s << 4 ) + cp; - t = s & 0xFF; + s = (UWord16) ( L_add( L_shl( s, 4 ), cp ) ); + t = (UWord16) L_and( s, 0xFF ); } /*end of the 2-tuples loop*/ } /* Finish range encoder */ rc_tot_bits = rc_uni_enc_finish( &rc_st_enc ); /* No. of bits consumed by range coder */ - bp = rc_tot_bits + nbbits_ntuples; /* Update bitstream pointer */ + bp = add( rc_tot_bits, nbbits_ntuples ); /* Update bitstream pointer */ /* Cross-check that there is no overflow */ -#ifdef DEBUGGING - assert( k == lastnz ); -#endif /* Push number of encoded tuples */ - value = ( lastnz >> 1 ) - 1; + value = sub( shr( lastnz, 1 ), 1 ); push_next_indice( hBstr, value, nbbits_ntuples ); /* Push range coded bits from byte_buffer to bitstream */ /* 1) Push all complete bytes, one byte at a time */ - for ( k = 0; k < ( rc_tot_bits >> 3 ); k++ ) + FOR( k = 0; k < ( rc_tot_bits >> 3 ); k++ ) { push_next_indice( hBstr, rc_st_enc.byte_buffer[k], 8 ); } /* 2) Push remaining bits */ - if ( ( rc_tot_bits & 7 ) != 0 ) + IF( s_and( rc_tot_bits, 7 ) != 0 ) { - push_next_indice( hBstr, rc_st_enc.byte_buffer[k] >> ( 8 - ( rc_tot_bits & 7 ) ), rc_tot_bits & 7 ); + push_next_indice( hBstr, shr( rc_st_enc.byte_buffer[k], sub( 8, s_and( rc_tot_bits, 7 ) ) ), s_and( rc_tot_bits, 7 ) ); } /* Push sign bits */ - push_next_bits( hBstr, (uint16_t *) signs, nbbits_signs ); - bp += nbbits_signs; + push_next_bits( hBstr, (UWord16 *) signs, nbbits_signs ); + bp = add( bp, nbbits_signs ); /*write residual Quantization bits*/ - for ( k = 0; k < min( nbbits - bp - nbbits_lsbs, resQMaxBits ); k++ ) + FOR( k = 0; k < s_min( nbbits - bp - nbbits_lsbs, resQMaxBits ); k++ ) { ptr[nbbits - 1 - nbbits_lsbs - k] = x[nt + k]; + move16(); } /* Write filler bits */ - for ( ; k < nbbits - bp - nbbits_lsbs; ++k ) + FOR( ; k < nbbits - bp - nbbits_lsbs; ++k ) { ptr[nbbits - 1 - nbbits_lsbs - k] = 0; + move16(); } /* Check for debugging */ assert( bp + k <= nbbits ); /* Push the rest of the buffer */ - push_next_bits( hBstr, (uint16_t *) &ptr[bp], nbbits - bp ); + push_next_bits( hBstr, (UWord16 *) &ptr[bp], sub( nbbits, bp ) ); /* return (bp+nbbits_lsbs);*/ /*return only for debug plot*/ return; } +#ifdef IVAS_CODE_RANGE_CODER + /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_no_mem_s17_LCS() * diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index fc418f652..f321a6c26 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -47,6 +47,7 @@ #include "prot_fx_enc.h" #include "ivas_rom_com.h" #include "wmc_auto.h" +#include "options_warnings.h" /*-------------------------------------------------------------------* * acelp_core_enc() @@ -56,7 +57,7 @@ #ifdef IVAS_FLOAT_FIXED ivas_error acelp_core_enc( Encoder_State *st, /* i/o: encoder state structure */ - const float inp[], /* i : input signal of the current frame */ + /*const*/ float inp[], /* i : input signal of the current frame */ const float ener, /* i : residual energy from Levinson-Durbin*/ float A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes*/ float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ @@ -74,7 +75,7 @@ ivas_error acelp_core_enc( float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ ) { - int16_t i, nBits; /* reserved bits */ + Word16 i, nBits; /* reserved bits */ LPD_state_HANDLE hLPDmem; /* i/o: acelp memories */ float old_exc_flt[L_EXC], *exc; /* excitation signal buffer */ float lsf_new[M]; /* ISFs at the end of the frame */ @@ -84,82 +85,100 @@ ivas_error acelp_core_enc( float exc2[L_FRAME16k]; /* enhanced excitation */ float Es_pred; /* predicited scaled innovation energy */ float tmp_noise; /* NB post-filter long-term noise energy*/ - int16_t tc_subfr; /* TC sub-frame indication */ + Word16 tc_subfr; /* TC sub-frame indication */ float old_bwe_exc[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ float *bwe_exc; /* excitation for SWB TBE */ - int16_t allow_cn_step; - int32_t int_fs; + Word16 allow_cn_step; + Word32 int_fs; float att; - int16_t nb_bits; /* parameters handling */ + Word16 nb_bits; /* parameters handling */ /* SC-VBR - back-up memories for LSF quantizer and synthesis filter */ - int16_t pstreaklen; + Word16 pstreaklen; float mem_MA[M], mem_AR[M], Bin_E[L_FFT], Bin_E_old[L_FFT / 2], lsp_new_bck[M], lsp_mid_bck[M], mem_syn_bck[M]; float clip_var, mem_w0_bck, streaklimit; float q_env[NUM_ENV_CNG]; - int16_t sid_bw = -1; + Word16 sid_bw = -1; float exc3[L_FRAME16k]; float syn1[L_FRAME16k]; float tilt_code_bck; float gc_threshold_bck; float clip_var_bck[6]; - int16_t next_force_sf_bck; - int16_t uc_two_stage_flag; - int16_t position; + Word16 next_force_sf_bck; + Word16 uc_two_stage_flag; + Word16 position; float tmpF; - int16_t ppp_mode, nelp_mode; - int16_t tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; + Word16 ppp_mode, nelp_mode; + Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; float *tdm_Pri_pitch_buf; /* bitstream */ BSTR_ENC_HANDLE hBstr = st->hBstr; -#if 0 - //Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ - Word16 lsf_new_fx[M]; /* ISFs at the end of the frame */ - Word16 Aq_fx[NB_SUBFR16k*(M + 1)]; /* A(z) quantized for the 4 subframes */ - Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ - Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ - Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ - Word16 Es_pred_fx; /* predicited scaled innovation energy */ - Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ - Word16 tc_subfr_fx; /* TC sub-frame indication */ - Word16 old_bwe_exc_fx[(PIT16k_MAX + (L_FRAME16k + 1) + L_SUBFR16k) * 2]; /* excitation buffer */ - Word16 *bwe_exc_fx; /* excitation for SWB TBE */ - Word16 allow_cn_step_fx; - Word16 int_fs_fx; - Word32 L_epsP[2]; +#if 1 + Word16 Q_exc = 0; + move16(); + Word16 A_fx[85]; + Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ + Word16 lsf_new_fx[M]; /* ISFs at the end of the frame */ + Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ + // Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ + Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ + // Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ + Word16 Es_pred_fx; /* predicited scaled innovation energy */ + // Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ + // Word16 tc_subfr_fx; /* TC sub-frame indication */ + Word16 old_bwe_exc_fx[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ + Word16 Q_old_bwe_exc; + Word16 *bwe_exc_fx; /* excitation for SWB TBE */ + // Word16 allow_cn_step_fx; + // Word16 int_fs_fx; + // Word32 L_epsP[2]; /* SC-VBR - back-up memories for LSF quantizer and synthesis filter */ - Word16 mCb1_fx, pstreaklen_fx; - Word16 mem_MA_fx[M], mem_AR_fx[M], lsp_new_bck_fx[M], lsf_new_bck_fx[M], lsp_mid_bck_fx[M], mem_syn_bck_fx[M]; + // Word16 mCb1_fx, pstreaklen_fx; + Word16 mem_MA_fx[M], mem_AR_fx[M], lsp_new_bck_fx[M], /*lsf_new_bck_fx[M],*/ lsp_mid_bck_fx[M], mem_syn_bck_fx[M]; Word32 Bin_E_fx[L_FFT], Bin_E_old_fx[L_FFT / 2]; Word16 clip_var_fx, mem_w0_bck_fx, streaklimit_fx; - Word16 indice; - Word16 tmp16; - Word16 enr_index; - Word16 enr; + // Word16 indice; + // Word16 tmp16; + // Word16 enr_index; + // Word16 enr; Word16 tilt_code_bck_fx; Word32 gc_threshold_bck_fx; Word16 clip_var_bck_fx[6]; - Word16 next_force_sf_bck_fx; - Word32 q_env_fx[NUM_ENV_CNG]; - Word16 coder_type; - Word16 exc3_fx[L_FRAME16k]; - Word16 syn1_fx[L_FRAME16k]; - Word16* tdm_Pri_pitch_buf_fx; + // Word16 next_force_sf_bck_fx; + // Word32 q_env_fx[NUM_ENV_CNG]; + // Word16 coder_type; + // Word16 exc3_fx[L_FRAME16k]; + // Word16 syn1_fx[L_FRAME16k]; + // Word16* tdm_Pri_pitch_buf_fx; Word16 att_fx; - Word16 lsp_new_fx[M]; /* i : LSPs at the end of the frame */ - Word16 lsp_mid_fx[M]; /* i : LSPs in the middle of the frame */ - Word16 old_syn_12k8_16k_fx[L_FRAME16k]; + Word16 lsp_new_fx[M]; /* i : LSPs at the end of the frame */ + Word16 lsp_mid_fx[M]; /* i : LSPs in the middle of the frame */ + // Word16 old_syn_12k8_16k_fx[L_FRAME16k]; + Word16 tmpF_fx; +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IF( st->hLPDmem ) + f2me_buf_16( &st->hLPDmem->old_exc_flt[-M - 1], &st->hLPDmem->old_exc[-M - 1], &st->hLPDmem->e_old_exc, L_EXC_MEM + M + 1 ); + IF( st->hBWE_TD ) + floatToFixed_arr16( st->hBWE_TD->old_bwe_exc, st->hBWE_TD->old_bwe_exc_fx, Q_exc, PIT16k_MAX * 2 ); + floatToFixed_arr16( st->lsp_old, st->lsp_old_fx, 15, M ); + floatToFixed_arr16( st->lsp_old16k, st->lsp_old16k_fx, 15, M ); + floatToFixed_arr16( lsp_mid, lsp_mid_fx, 15, M ); + floatToFixed_arr16( lsp_new, lsp_new_fx, 15, M ); + #endif ivas_error error; error = IVAS_ERR_OK; + move32(); - if ( st->element_mode == IVAS_CPE_MDCT && st->core_brate <= SID_2k40 ) + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LE_32( st->core_brate, SID_2k40 ) ) { /* Core was ACELP because of DTX in MDCT-Stereo, but SID encoding for that is done in separate function */ return error; @@ -173,133 +192,195 @@ ivas_error acelp_core_enc( hLPDmem = st->hLPDmem; Es_pred = 0; + Es_pred_fx = 0; + move16(); exc = old_exc_flt + L_EXC_MEM; /* pointer to excitation signal in the current frame */ mvr2r( hLPDmem->old_exc_flt, old_exc_flt, L_EXC_MEM ); - if ( st->hBWE_TD != NULL ) + exc_fx = old_exc_fx + L_EXC_MEM; /* pointer to excitation signal in the current frame */ + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); + + IF( st->hBWE_TD != NULL ) { bwe_exc = old_bwe_exc + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ mvr2r( st->hBWE_TD->old_bwe_exc, old_bwe_exc, PIT16k_MAX * 2 ); + bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ + Copy( st->hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); } - else + ELSE { bwe_exc = NULL; + bwe_exc_fx = NULL; } st->bpf_off = 0; - if ( st->last_core == HQ_CORE || st->last_codec_mode == MODE2 || st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) + move16(); + + test(); + test(); + test(); + IF( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) { /* in case of HQ->ACELP switching, do not apply BPF */ st->bpf_off = 1; + move16(); /* reset the GSC pre echo energy threshold in case of switching */ if ( st->hGSCEnc != NULL ) { st->hGSCEnc->Last_frame_ener = (float) MAX_32; + st->hGSCEnc->Last_frame_ener_fx = MAX_32; + move32(); } } /* force safety-net LSFQ in the first frames after CNG segment */ - if ( st->last_core_brate <= SID_2k40 ) + if ( LE_32( st->last_core_brate, SID_2k40 ) ) { st->Nb_ACELP_frames = 0; + move16(); } - st->Nb_ACELP_frames++; + st->Nb_ACELP_frames = add( st->Nb_ACELP_frames, 1 ); + move16(); - if ( st->L_frame == L_FRAME ) + IF( EQ_16( st->L_frame, L_FRAME ) ) { int_fs = INT_FS_12k8; + move32(); } - else + ELSE { int_fs = INT_FS_16k; + move32(); } tmp_noise = 0; tc_subfr = -1; + move16(); position = -1; + move16(); /* SC-VBR temporary variables */ pstreaklen = 0; + move16(); clip_var = 0; + clip_var_fx = 0; + move16(); mem_w0_bck = 0; + mem_w0_bck_fx = 0; + move16(); streaklimit = 0; + streaklimit_fx = 0; + move16(); /* channel-aware mode */ reset_rf_indices( st->hRF, st->L_frame, &st->rf_target_bits_write ); /* VBR modes */ - if ( st->Opt_SC_VBR ) + IF( st->Opt_SC_VBR ) { ppp_mode = st->hSC_VBR->ppp_mode; nelp_mode = st->hSC_VBR->nelp_mode; } - else + ELSE { ppp_mode = 0; nelp_mode = 0; } + move16(); + move16(); + test(); /* TD stereo */ - if ( st->element_mode == IVAS_CPE_TD && st->idchan == 1 ) + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) { tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; } - else + ELSE { tdm_lp_reuse_flag = 0; tdm_low_rate_mode = 0; - if ( st->element_mode == IVAS_SCE && st->low_rate_mode ) + test(); + if ( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) { tdm_low_rate_mode = 1; + move16(); } tdm_Pitch_reuse_flag = 0; tdm_Pri_pitch_buf = NULL; } + move16(); + move16(); + move16(); /*-----------------------------------------------------------------* * ACELP@12k8 / ACELP@16k switching *-----------------------------------------------------------------*/ - if ( st->last_L_frame != st->L_frame && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) + test(); + test(); + + UNUSED_PARAM( bwe_exc_fx ); + UNUSED_PARAM( exc_fx ); + IF( NE_16( st->last_L_frame, st->L_frame ) && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) { /* in case of switching, do not apply BPF (flag employed also in updt_enc()) */ st->bpf_off = 1; + move16(); /* force safety-net LSFQ in the first frames after ACELP@12k8/ACELP@16k switching */ st->Nb_ACELP_frames = 1; + move16(); /* convert old quantized LSP vector */ - if ( st->L_frame == L_FRAME ) + IF( EQ_16( st->L_frame, L_FRAME ) ) { - st->rate_switching_reset = lsp_convert_poly( st->lsp_old, st->L_frame, 0 ); + st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); + move16(); } - else + ELSE { st->rate_switching_reset = st->rate_switching_reset_16kHz; - mvr2r( st->lsp_old16k, st->lsp_old, M ); + move16(); + Copy( st->lsp_old16k_fx, st->lsp_old_fx, M ); } /* convert old quantized LSF vector */ - lsp2lsf( st->lsp_old, st->lsf_old, M, int_fs ); + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, int_fs ); /* interpolation of unquantized ISPs */ - if ( st->rate_switching_reset ) + IF( st->rate_switching_reset ) { /*extrapolation in case of unstable LSP*/ - int_lsp4( st->L_frame, lsp_mid, lsp_mid, lsp_new, A, M, 0 ); + int_lsp4_fx( st->L_frame, lsp_mid_fx, lsp_mid_fx, lsp_new_fx, A_fx, M, 0 ); } - else + ELSE { - int_lsp4( st->L_frame, st->lsp_old, lsp_mid, lsp_new, A, M, 0 ); + int_lsp4_fx( st->L_frame, st->lsp_old_fx, lsp_mid_fx, lsp_new_fx, A_fx, M, 0 ); } /* Reset LPC mem */ - mvr2r( GEWB_Ave, st->mem_AR, M ); - set_zero( st->mem_MA, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + set16_fx( st->mem_MA_fx, 0, M ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < NB_SUBFR16k; i++ ) + { + // Array is getting modified in chunks of 17 inside. + // So each chunk might have a different Q which is predicted by 1st element. + fixedToFloat_arr( &A_fx[i * ( M + 1 )], &A[i * ( M + 1 )], 14 - norm_s( A_fx[i * ( M + 1 )] ), ( M + 1 ) ); + } + for ( i = 0; i < M; i++ ) + { + st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; + st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; + st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; + } + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); +#endif /* update synthesis filter memories */ synth_mem_updt2_flt( st->L_frame, st->last_L_frame, hLPDmem->old_exc_flt, hLPDmem->mem_syn_r_flt, hLPDmem->mem_syn2_flt, hLPDmem->mem_syn_flt, ENC ); @@ -311,9 +392,12 @@ ivas_error acelp_core_enc( weight_a_subfr( st->L_frame / L_SUBFR, A, Aw, st->gamma_flt, M ); } + test(); + test(); if ( st->last_bwidth == NB && st->bwidth != NB && st->ini_frame != 0 ) { st->rate_switching_reset = 1; + move16(); } /*----------------------------------------------------------------* @@ -393,19 +477,77 @@ ivas_error acelp_core_enc( /*----------------------------------------------------------------* * Encoding of all other frames *----------------------------------------------------------------*/ -#if 0 ELSE { -#if 1 - /*-----------------------------------------------------------------* +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 tdm_lsfQ_PCh_fx[M]; + IF( tdm_lsfQ_PCh ) + { + for ( int ii = 0; ii < M; ii++ ) + { + tdm_lsfQ_PCh_fx[ii] = (Word16) ( ( tdm_lsfQ_PCh[ii] ) * 2.56f ); + } + } + + IF( st->hDtxEnc ) + { + floatToFixed_arr( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG_fx, Q15, M ); + } + floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); + for ( i = 0; i < M; i++ ) + { + st->lsf_old_fx[i] = (Word16) ( st->lsf_old[i] * 2.56f ); + } + st->mem_deemp_preQ_fx = (Word16) floatToFixed( st->mem_deemp_preQ, -1 ); + Word16 e_mem_syn_bck = 0, e_mem_w0 = 0, q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; + IF( st->hLPDmem ) + { + st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); + st->hLPDmem->gc_threshold = float_to_fix16( st->hLPDmem->gc_threshold_flt, Q16 ); + f2me_buf_16( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, &e_mem_syn_bck, M ); + f2me_16( st->hLPDmem->mem_w0_flt, &st->hLPDmem->mem_w0, &e_mem_w0 ); + } + floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); + floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); + for ( int ii = 0; ii < M; ii++ ) + { + st->mem_MA_fx[ii] = (Word16) ( ( st->mem_MA[ii] ) * 2.56f ); + st->mem_AR_fx[ii] = (Word16) ( ( st->mem_AR[ii] ) * 2.56f ); + lsf_new_fx[ii] = (Word16) ( ( lsf_new[ii] ) * 2.56f ); + } + st->clip_var_fx[0] = (Word16) ( st->clip_var[0] * 2.56f ); + for ( i = 1; i < 6; i++ ) + { + st->clip_var_fx[i] = (Word16) ( st->clip_var[i] * ONE_IN_Q14 ); + } + q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); + floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, q_comm_Bin, 128 ); + floatToFixed_arrL( st->Bin_E, st->Bin_E_fx, q_comm_Bin, 256 ); + st->streaklimit_fx = (Word16) floatToFixed( st->streaklimit, Q15 ); + Q_new = q_comm_Bin - ( QSCALE - 2 ); + FOR( Word16 idx = 0; idx < M; idx++ ) + { + st->lsf_adaptive_mean_fx[idx] = (Word16) ( st->lsf_adaptive_mean[idx] * 2.56f ); + IF( tdm_lsfQ_PCh ) + tdm_lsfQ_PCh_fx[idx] = (Word16) ( tdm_lsfQ_PCh[idx] * 2.56f ); + st->lsfoldbfi1_fx[idx] = (Word16) ( st->lsfoldbfi1[idx] * 2.56f ); + st->lsfoldbfi0_fx[idx] = (Word16) ( st->lsfoldbfi0[idx] * 2.56f ); + } +#endif + /*-----------------------------------------------------------------* * Configure ACELP bit allocation *-----------------------------------------------------------------*/ nb_bits = 0; + move16(); st->acelp_cfg.FEC_mode = 0; + move16(); uc_two_stage_flag = 0; + move16(); - if ( !nelp_mode && !ppp_mode ) + test(); + IF( !nelp_mode && !ppp_mode ) { config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } @@ -414,28 +556,34 @@ ivas_error acelp_core_enc( * After inactive period, use the most up-to-date ISPs *-----------------------------------------------------------------*/ + test(); #ifdef NON_BE_FIX_807_MASA_DTX_BRSW - if (st->hDtxEnc != NULL && (st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40)) + IF( st->hDtxEnc != NULL && ( st->last_core_brate == FRAME_NO_DATA || EQ_32( st->last_core_brate, SID_2k40 ) ) ) #else - if ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40 ) + IF( st->last_core_brate == FRAME_NO_DATA || EQ_32( st->last_core_brate, SID_2k40 ) ) #endif { - mvr2r( st->hDtxEnc->lspCNG, st->lsp_old, M ); - lsp2lsf( st->hDtxEnc->lspCNG, st->lsf_old, M, int_fs ); + Copy( st->hDtxEnc->lspCNG_fx, st->lsp_old_fx, M ); // Q15 + lsp2lsf_fx( st->hDtxEnc->lspCNG_fx, st->lsf_old_fx, M, int_fs ); } /*-----------------------------------------------------------------* * Reset higher ACELP pre-quantizer in case of switching *-----------------------------------------------------------------*/ - if ( !st->use_acelp_preq ) + IF( !st->use_acelp_preq ) { - st->mem_deemp_preQ = 0.0f; + st->mem_deemp_preQ_fx = 0; + move16(); + st->mem_preemp_preQ = 0.0f; st->last_code_preq = 0; + move16(); st->last_nq_preQ = 0; + move16(); } st->use_acelp_preq = 0; + move16(); /*-----------------------------------------------------------------* * LSF Quantization @@ -443,156 +591,177 @@ ivas_error acelp_core_enc( *-----------------------------------------------------------------*/ /* SC-VBR & channel-aware mode - back-up memories for LSF quantizer and synthesis filter */ - lsf_syn_mem_backup( st, &tilt_code_bck, &gc_threshold_bck, clip_var_bck, &next_force_sf_bck, lsp_new, lsp_mid, &clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, &mem_w0_bck, &streaklimit, &pstreaklen ); - Word16 tdm_lsfQ_PCh_fx[M]; - Word16 Q_new = 0; - IF ( !tdm_lp_reuse_flag ) + st->next_force_safety_net_fx = st->next_force_safety_net; + move16(); + lsf_syn_mem_backup_ivas_fx( st, &tilt_code_bck_fx, &gc_threshold_bck_fx, clip_var_bck_fx, &next_force_sf_bck, lsp_new_fx, lsp_mid_fx, &clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, &mem_w0_bck_fx, &streaklimit_fx, &pstreaklen ); + + IF( !tdm_lp_reuse_flag ) { -#if 1 - floatToFixed_arr(lsp_new, lsp_new_fx, 15, M); - FOR(Word16 idx = 0; idx < M; idx++) - { - st->lsf_old_fx[idx] = st->lsf_old[idx] * 2.56; - lsf_new_fx[idx] = lsf_new_fx[idx] * 2.56; - st->lsf_adaptive_mean_fx[idx] = st->lsf_adaptive_mean[idx] * 2.56; - st->mem_MA_fx[idx] = st->mem_MA[idx] * 2.56; - st->mem_AR_fx[idx] = st->mem_AR[idx] * 2.56; - tdm_lsfQ_PCh_fx[idx] = tdm_lsfQ_PCh[idx] * 2.56; - st->lsfoldbfi1_fx[idx] = st->lsfoldbfi1[idx] * 2.56; - st->lsfoldbfi0_fx[idx] = st->lsfoldbfi0[idx] * 2.56; - } - - FOR(Word16 idx = 0; idx < 6; idx++) - { - st->clip_var_fx[idx] = st->clip_var[idx] * 2.56; - } - - Q_new = Q_factor_arr(st->Bin_E, 256); - - floatToFixed_arrL(st->Bin_E_old, st->Bin_E_old_fx, 0, L_FFT ); - floatToFixed_arrL(st->Bin_E, st->Bin_E_fx, Q_new, L_FFT); - floatToFixed_arr(st->lsp_old, st->lsp_old_fx, 15, M); - floatToFixed_arr(lsp_mid, lsp_mid_fx, 15, M); - - st->stab_fac_fx = st->stab_fac * (1 << 15); - st->streaklimit_fx = st->streaklimit * (1 << 15); - st->pstreaklen_fx = st->pstreaklen; - - lsf_enc_ivas_fx(st, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh_fx, Q_new); - - Scale_sig(Aq_fx, NB_SUBFR16k * (M + 1), 14 - norm_l(Aq_fx[0])); - fixedToFloat_arr(Aq_fx, Aq, 12, NB_SUBFR16k * (M + 1)); - fixedToFloat_arr(lsp_new_fx, lsp_new, 15, M); - fixedToFloat_arr(lsp_mid_fx, lsp_mid, 15, M); - st->stab_fac = (float)st->stab_fac_fx / (1 << 15); - for (int i = 0; i < M; i++) { - - lsf_new[i] = lsf_new_fx[i] / 2.56; - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56; - st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56; - st->mem_MA[i] = st->mem_MA_fx[i] / 2.56; - st->mem_AR[i] = st->mem_AR_fx[i] / 2.56; - st->lsfoldbfi1[i] = st->lsfoldbfi1_fx[i] / 2.56; - st->lsfoldbfi0[i] = st->lsfoldbfi0_fx[i] / 2.56; - } - st->streaklimit = (float)st->streaklimit_fx / (1 << 15); - st->pstreaklen = st->pstreaklen_fx; -#else - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh ); -#endif + st->next_force_safety_net_fx = st->next_force_safety_net; + move16(); + lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh_fx, Q_new ); + st->next_force_safety_net = st->next_force_safety_net_fx; + move16(); } ELSE { - const float *pt_interp_2; + const Word16 *pt_interp_2_fx; - IF ( NE_16(st->active_cnt, 1 )) + IF( NE_16( st->active_cnt, 1 ) ) { -#if 0 - Word16 beta_index; - Word16 lsf_wgts[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf_fx(lsp_new_fx, lsf_new_fx, M, 12800); - - Unified_weighting_fx(&st->Bin_E_fx[L_FFT / 2], Q_new, lsf_new_fx, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M); - - tdm_SCh_lsf_reuse_fx(ENC, st->element_brate, lsf_new_fx, lsp_new_fx, tdm_lsfQ_PCh_fx, lsf_wgts, &beta_index); -#else - int16_t beta_index; - float lsf_wgts[M]; + Word16 beta_index; + Word16 lsf_wgts_fx[M]; /* intra_frame prediction for the LSFs */ - lsp2lsf( lsp_new, lsf_new, M, 12800 ); + lsp2lsf_fx( lsp_new_fx, lsf_new_fx, M, 12800 ); - Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); + Unified_weighting_fx( &st->Bin_E_fx[L_FFT / 2], add( Q_new, ( QSCALE - 2 ) ), lsf_new_fx, lsf_wgts_fx, st->bwidth == NB, EQ_16( st->coder_type, UNVOICED ), st->sr_core, M ); + + tdm_SCh_lsf_reuse_fx( ENC, st->element_brate, lsf_new_fx, lsp_new_fx, tdm_lsfQ_PCh_fx, lsf_wgts_fx, &beta_index ); - tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); -#endif push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); } - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) + pt_interp_2_fx = interpol_frac_12k8_fx; + + test(); + if ( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( st->coder_type, UNVOICED ) ) { - pt_interp_2 = interpol_frac2; + pt_interp_2_fx = interpol_frac2_fx; } - if ( st->active_cnt == 1 ) + IF( EQ_16( st->active_cnt, 1 ) ) { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - lsp2lsf( lsp_new, lsf_new, M, st->sr_core ); + Copy( lsp_new_fx, st->lsp_old_fx, M ); // Q15 + lsp2lsf_fx( lsp_new_fx, st->lsf_old_fx, M, st->sr_core ); // Q x2.56 + lsp2lsf_fx( lsp_new_fx, lsf_new_fx, M, st->sr_core ); // Q x2.56 } /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); + int_lsp_fx( st->L_frame, st->lsp_old_fx, lsp_new_fx, Aq_fx, M, pt_interp_2_fx, 0 ); /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } + st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 + } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); + tilt_code_bck = fix16_to_float( tilt_code_bck_fx, Q15 ); + gc_threshold_bck = fix_to_float( gc_threshold_bck_fx, Q16 ); + clip_var_bck[0] = (float) clip_var_bck_fx[0] / 2.56f; + for ( i = 1; i < 6; i++ ) + { + clip_var_bck[i] = (float) clip_var_bck_fx[i] / (float) ( ONE_IN_Q14 ); + } + clip_var = (float) clip_var_fx / 2.56f; + for ( int ii = 0; ii < M; ii++ ) + { + mem_AR[i] = (float) mem_AR_fx[i] / 2.56f; + mem_MA[i] = (float) mem_MA_fx[i] / 2.56f; + } + fixedToFloat_arr( lsp_new_bck_fx, lsp_new_bck, Q15, M ); + fixedToFloat_arr( lsp_mid_bck_fx, lsp_mid_bck, Q15, M ); + me2f_buf_16( mem_syn_bck_fx, e_mem_syn_bck, mem_syn_bck, M ); + mem_w0_bck = me2f( mem_w0_bck_fx, e_mem_w0 ); + streaklimit = fixedToFloat( streaklimit_fx, Q15 ); + fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); + fixedToFloat_arr( lsp_mid_fx, lsp_mid, 15, M ); + for ( i = 0; i < M; i++ ) + { + + lsf_new[i] = lsf_new_fx[i] / 2.56f; + st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; + st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56f; + st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; + st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; + st->lsfoldbfi1[i] = st->lsfoldbfi1_fx[i] / 2.56f; + st->lsfoldbfi0[i] = st->lsfoldbfi0_fx[i] / 2.56f; + } + fixedToFloat_arrL( st->Bin_E_old_fx, st->Bin_E_old, q_comm_Bin, 128 ); + fixedToFloat_arrL( st->Bin_E_fx, st->Bin_E, q_comm_Bin, 256 ); + st->clip_var[0] = st->clip_var_fx[0] / 2.56f; + fixedToFloat_arr( &st->clip_var_fx[1], &st->clip_var[1], Q14, 5 ); + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); + for ( i = 0; i < NB_SUBFR16k; i++ ) + { + // Array is getting modified in chunks of 17 inside. + // So each chunk might have a different Q which is predicted by 1st element. + fixedToFloat_arr( &Aq_fx[i * ( M + 1 )], &Aq[i * ( M + 1 )], 14 - norm_s( Aq_fx[i * ( M + 1 )] ), ( M + 1 ) ); + } + st->stab_fac = fixedToFloat( st->stab_fac_fx, Q15 ); +#endif +#endif - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) +#if 1 +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Q_exc = Q_factor_arr( old_exc_flt, st->L_frame ); + Q_old_bwe_exc = Q_factor_arr( old_bwe_exc, 1380 ); + floatToFixed_arr( old_bwe_exc, old_bwe_exc_fx, Q_old_bwe_exc, 1380 ); + hLPDmem->e_old_exc = Q_factor_arr( &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ) - 1; + Q_exc = s_min( Q_exc, hLPDmem->e_old_exc ); + hLPDmem->e_old_exc = Q15 - hLPDmem->e_old_exc; + floatToFixed_arr( &hLPDmem->old_exc_flt[-M - 1], &hLPDmem->old_exc[-M - 1], Q15 - hLPDmem->e_old_exc, L_EXC_MEM + M + 1 ); + floatToFixed_arr16( old_exc_flt, old_exc_fx, Q_exc, st->L_frame ); + f2me_buf_16( hLPDmem->mem_syn_flt, hLPDmem->mem_syn, &hLPDmem->e_mem_syn, M ); + + st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); + Word16 inp_buff[L_FRAME16k + M + 1]; + Word16 *inp_fx; + inp_fx = &inp_buff[M + 1]; + Q_new = Q_factor_arr( &inp[-M - 1], L_FRAME16k + M + 1 ); + floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); + floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); +#endif + test(); + IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) { /* Prepare ACB memory from last HQ frame */ - tmpF = hLPDmem->old_exc_flt[0]; - preemph( hLPDmem->old_exc_flt, st->preemph_fac_flt, st->L_frame, &tmpF ); - mvr2r( hLPDmem->old_exc_flt + st->L_frame - M, hLPDmem->mem_syn_flt, M ); - residu( Aq, M, hLPDmem->old_exc_flt, old_exc_flt, st->L_frame ); + tmpF_fx = hLPDmem->old_exc[0]; + PREEMPH_FX( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF_fx ); + hLPDmem->e_mem_syn = hLPDmem->e_old_exc; + Copy( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M ); + Residu3_fx( Aq_fx, hLPDmem->old_exc, old_exc_fx, st->L_frame, 0 ); } - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) + test(); + IF( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) { /* Prepare ACB memory of old_bwe_exc */ - if ( st->L_frame == L_FRAME ) + IF( EQ_16( st->L_frame, L_FRAME ) ) { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); + lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); } - else + ELSE { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); + lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); } + Q_old_bwe_exc = Q_exc; + move16(); } - /*---------------------------------------------------------------* * Calculation of LP residual (filtering through A[z] filter) *---------------------------------------------------------------*/ - calc_residu( inp, res, Aq, st->L_frame ); + calc_residu_fx( st, inp_fx, res_fx, Aq_fx ); +#if 1 // TODO: To be replaced with fixed version once available calculate_hangover_attenuation_gain( st, &att, vad_hover_flag ); - if ( att != 1.0f ) + att_fx = float_to_fix16( att, Q15 ); +#endif + + IF( NE_16( att_fx, 32767 /* ONE_IN_Q15 */ ) ) { - v_multc( res, att, res, st->L_frame ); + v_multc_fixed_16_16( res_fx, att_fx, res_fx, st->L_frame ); } /*-----------------------------------------------------------------* * Determine TC subframe classification *-----------------------------------------------------------------*/ - if ( st->coder_type == TRANSITION ) + IF( EQ_16( st->coder_type, TRANSITION ) ) { - tc_classif_enc( st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res ); + tc_classif_enc_fx( Q_new + 1, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } @@ -602,731 +771,20 @@ ivas_error acelp_core_enc( * (for memory-less gain quantizer) *---------------------------------------------------------------*/ - if ( nb_bits > 0 ) + IF( nb_bits > 0 ) { - Es_pred_enc( &Es_pred, &i, st->L_frame, L_SUBFR, res, st->voicing, nb_bits, uc_two_stage_flag ); - push_indice( hBstr, IND_ES_PRED, i, nb_bits ); - } - - /*------------------------------------------------------------* - * Encode excitation according to coding type - *------------------------------------------------------------*/ - - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - if ( st->coder_type <= UNVOICED ) - { - tdm_low_rate_enc( st, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, 0 /*attack_flag*/, lsf_new, &tmp_noise ); - } - else /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - } - else if ( nelp_mode ) - { - /* SC-VBR - NELP frames */ - encod_nelp( st, inp, Aw, Aq, res, syn, &tmp_noise, exc, exc2, pitch_buf, voice_factors, bwe_exc ); - } - else if ( st->coder_type == UNVOICED ) - { - /* UNVOICED frames (Gauss. excitation) */ - encod_unvoiced( st, inp, Aw, Aq, Es_pred, uc_two_stage_flag, res, syn, &tmp_noise, exc, pitch_buf, voice_factors, bwe_exc ); - } - else if ( st->coder_type == TRANSITION ) - { - encod_tran( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tc_subfr, position, unbits ); - } - else if ( ppp_mode ) - { - /* SC-VBR - PPP frames */ - if ( ( error = encod_ppp( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc ) ) != IVAS_ERR_OK ) - { - return error; - } - - - if ( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ - { - /* restore memories of LSF quantizer and synthesis filter */ - lsf_syn_mem_restore( st, tilt_code_bck, gc_threshold_bck, clip_var_bck, next_force_sf_bck, lsp_new, lsp_mid, clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, mem_w0_bck, streaklimit, pstreaklen ); - - /* Configure ACELP bit allocation */ - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - - /* redo LSF quantization */ - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL ); - - /* recalculation of LP residual (filtering through A[z] filter) */ - calc_residu( inp, res, Aq, st->L_frame ); - st->hTdCngEnc->burst_ho_cnt = 0; - - /* VOICED frames in SC-VBR */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - } - else if ( st->coder_type == AUDIO || ( st->coder_type == INACTIVE && st->inactive_coder_type_flag ) ) - { - /* AUDIO and INACTIVE frames (coded by GSC technology) */ - encod_audio( st, inp, Aw, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, attack_flag, lsf_new, &tmp_noise, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - else - { - /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - - - /* update mem_syn1_flt for ACELP core switching */ - mvr2r( hLPDmem->mem_syn_flt, hLPDmem->mem_syn1_flt, M ); - - /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - mvr2r( syn + st->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r_flt, L_SYN_MEM ); - - /* save and delay synthesis to be used by SWB BWE */ - if ( st->hBWE_FD != NULL ) - { - save_old_syn( st->L_frame, syn, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k, st->preemph_fac_flt, &st->hBWE_FD->mem_deemph_old_syn ); - } - - /*Update MODE2 core switching memory*/ - mvr2r( syn, syn1, st->L_frame ); - deemph( syn1, st->preemph_fac_flt, st->L_frame, &( hLPDmem->syn_flt[M] ) ); - mvr2r( syn1 + st->L_frame - M - 1, hLPDmem->syn_flt, M + 1 ); - - if ( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) - { - mvr2r( syn1 + st->L_frame / 2, st->hTcxEnc->Txnq_flt, st->L_frame / 2 ); - } - - /*--------------------------------------------------------------------------------------* - * Modify the excitation signal when the noise is stationary - *--------------------------------------------------------------------------------------*/ - - if ( !( st->idchan == 1 && st->element_mode == IVAS_CPE_TD ) && nelp_mode != 1 && !( st->element_mode == IVAS_SCE && tdm_low_rate_mode ) ) - { - /* exc2 buffer is needed only for updating of Aq[] which is needed for core switching */ - mvr2r( exc, exc2, st->L_frame ); - stat_noise_uv_enc( st, epsP, lsp_new, lsp_mid, Aq, exc2, uc_two_stage_flag ); - } - - /*-----------------------------------------------------------------* - * Encode supplementary information for Frame Error Concealment - *-----------------------------------------------------------------*/ - - FEC_encode( hBstr, st->acelp_cfg, syn, st->coder_type, st->clas, pitch_buf, res, &st->Last_pulse_pos, st->L_frame, st->total_brate ); - - if ( st->hBWE_TD != NULL ) - { - if ( st->L_frame == L_FRAME ) - { - mvr2r( Aq + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) ); - } - else - { - mvr2r( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) ); - } - } -#else - /*-----------------------------------------------------------------* - * Configure ACELP bit allocation - *-----------------------------------------------------------------*/ - - nb_bits = 0; - st->acelp_cfg.FEC_mode = 0; - uc_two_stage_flag = 0; -#if 0 // Both are in fixed point, but 1st one giveing crash for one file. - IF ( !nelp_mode && !ppp_mode ) - { - config_acelp1( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } -#else - if (!nelp_mode && !ppp_mode) - { - config_acelp1_IVAS(ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &(st->acelp_cfg), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode); - } -#endif - /*-----------------------------------------------------------------* - * After inactive period, use the most up-to-date ISPs - *-----------------------------------------------------------------*/ -#if 0 - floatToFixed_arr(st->lsp_old, st->lsp_old_fx, 15, M); - -#ifdef NON_BE_FIX_807_MASA_DTX_BRSW - IF (st->hDtxEnc != NULL && (st->last_core_brate == FRAME_NO_DATA || EQ_32(st->last_core_brate, SID_2k40))) -#else - IF(EQ_32(st->last_core_brate, FRAME_NO_DATA) || EQ_32(st->last_core_brate, SID_2k40)) -#endif - { - Copy(st->hDtxEnc->lspCNG_fx, st->lsp_old_fx, M); - lsp2lsf_fx(st->hDtxEnc->lspCNG_fx, st->lsf_old_fx, M, int_fs); - } - for (int i = 0; i < M; i++) { - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56; - } -#else -#ifdef NON_BE_FIX_807_MASA_DTX_BRSW - if (st->hDtxEnc != NULL && (st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40)) -#else - if ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40 ) -#endif - { - mvr2r( st->hDtxEnc->lspCNG, st->lsp_old, M ); - lsp2lsf( st->hDtxEnc->lspCNG, st->lsf_old, M, int_fs ); - } -#endif - /*-----------------------------------------------------------------* - * Reset higher ACELP pre-quantizer in case of switching - *-----------------------------------------------------------------*/ -#if 1 - IF (!st->use_acelp_preq) - { - st->mem_deemp_preQ_fx = 0; - st->mem_preemp_preQ_fx = 0; - st->last_code_preq = 0; - st->last_nq_preQ = 0; - } - st->use_acelp_preq = 0; - - if (!st->use_acelp_preq) - { - st->mem_deemp_preQ = 0.0f; - st->mem_preemp_preQ = 0.0f; - st->last_code_preq = 0; - st->last_nq_preQ = 0; - } -#else - if ( !st->use_acelp_preq ) - { - st->mem_deemp_preQ = 0.0f; - st->mem_preemp_preQ = 0.0f; - st->last_code_preq = 0; - st->last_nq_preQ = 0; - } - st->use_acelp_preq = 0; -#endif - /*-----------------------------------------------------------------* - * LSF Quantization - * A[z] calculation - *-----------------------------------------------------------------*/ - - /* SC-VBR & channel-aware mode - back-up memories for LSF quantizer and synthesis filter */ -#if 0 - floatToFixed_arr(lsp_new, lsp_new_fx, 15, M); - floatToFixed_arr(lsp_mid, lsp_mid_fx, 15, M); - floatToFixed_arr(st->Bin_E_old, st->Bin_E_old_fx, 15, L_FFT / 2); - floatToFixed_arr(st->clip_var, st->clip_var_fx, 8, 6); - FOR(Word16 idx = 0; idx < M; idx++) - { - - st->lsf_old_fx[idx] = st->lsf_old[idx] * 2.56; - st->lsf_adaptive_mean_fx[idx] = st->lsf_adaptive_mean[idx] * 2.56; - st->mem_MA_fx[idx] = st->mem_MA[idx] * 2.56; - st->mem_AR_fx[idx] = st->mem_AR[idx] * 2.56; - } - hLPDmem->tilt_code = hLPDmem->tilt_code_flt; - hLPDmem->gc_threshold = hLPDmem->gc_threshold_flt; - st->next_force_safety_net_fx = st->next_force_safety_net; - - lsf_syn_mem_backup_fx(st, &tilt_code_bck_fx, &gc_threshold_bck_fx, clip_var_bck_fx, &next_force_sf_bck, lsp_new_fx, lsf_new_fx, lsp_mid_fx, &clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsf_new_bck_fx, lsp_mid_bck_fx, &mCb1_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, &mem_w0_bck_fx, &streaklimit_fx, &pstreaklen_fx); - - fixedToFloat_arr(clip_var_bck_fx, clip_var_bck, 8, 6); - fixedToFloat_arr(lsp_new_bck_fx, lsp_new_bck, 15, M); - fixedToFloat_arr(lsp_mid_bck_fx, lsp_mid_bck, 15, M); - fixedToFloat_arr(lsp_mid_bck_fx, lsp_mid_bck, 15, M); - fixedToFloat_arr(Bin_E_fx, Bin_E, 15, L_FFT); - fixedToFloat_arr(Bin_E_old_fx, Bin_E_old, 15, L_FFT / 2); - fixedToFloat_arr(mem_syn_bck_fx, mem_syn_bck, 15, M); - - for (int i = 0; i < M; i++) { - - lsf_new[i] = lsf_new_fx[i] / 2.56; - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56; - st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56; - st->mem_MA[i] = st->mem_MA_fx[i] / 2.56; - st->mem_AR[i] = st->mem_AR_fx[i] / 2.56; - mem_MA[i] = mem_MA_fx[i] / 2.56; - mem_AR[i] = mem_AR_fx[i] / 2.56; - } - - clip_var = (float)clip_var_fx / (1 << 8); - mem_w0_bck = mem_w0_bck_fx; - streaklimit = streaklimit_fx; - mem_w0_bck = mem_w0_bck_fx; -#else - lsf_syn_mem_backup( st, &tilt_code_bck, &gc_threshold_bck, clip_var_bck, &next_force_sf_bck, lsp_new, lsp_mid, &clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, &mem_w0_bck, &streaklimit, &pstreaklen ); -#endif - if ( !tdm_lp_reuse_flag ) - { -#if 1 - Word16 Q_new = 0; - Word16 tdm_lsfQ_PCh_fx[M]; - - floatToFixed_arr(lsp_new, lsp_new_fx, 15, M); - FOR(Word16 idx = 0; idx < M; idx++) - { - st->lsf_old_fx[idx] = st->lsf_old[idx] * 2.56; - lsf_new_fx[idx] = lsf_new_fx[idx] * 2.56; - st->lsf_adaptive_mean_fx[idx] = st->lsf_adaptive_mean[idx] * 2.56; - st->mem_MA_fx[idx] = st->mem_MA[idx] * 2.56; - st->mem_AR_fx[idx] = st->mem_AR[idx] * 2.56; - tdm_lsfQ_PCh_fx[idx] = tdm_lsfQ_PCh[idx] * 2.56; - } - - FOR(Word16 idx = 0; idx < 6; idx++) - { - st->clip_var_fx[idx] = st->clip_var[idx] * 2.56; - } - - floatToFixed_arrL(st->Bin_E_old, st->Bin_E_old_fx, 0, L_FFT / 2); - floatToFixed_arrL(st->Bin_E, st->Bin_E_fx, 0, L_FFT / 2); - floatToFixed_arr(st->lsp_old, st->lsp_old_fx, 15, M); - floatToFixed_arr(lsp_mid, lsp_mid_fx, 15, M); - - st->stab_fac_fx = st->stab_fac * (1 << 15); - - lsf_enc_ivas_fx(st, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh_fx, Q_new); - - Scale_sig(Aq_fx, NB_SUBFR16k * (M + 1), 14 - norm_l(Aq_fx[0])); - fixedToFloat_arr(Aq_fx, Aq, 12, NB_SUBFR16k * (M + 1)); - fixedToFloat_arr(lsp_new_fx, lsp_new, 15, M); - fixedToFloat_arr(lsp_mid_fx, lsp_mid, 15, M); - st->stab_fac = (float)st->stab_fac_fx / (1 << 15); - for (int i = 0; i < M; i++) { - - lsf_new[i] = lsf_new_fx[i] / 2.56; - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56; - st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56; - st->mem_MA[i] = st->mem_MA_fx[i] / 2.56; - st->mem_AR[i] = st->mem_AR_fx[i] / 2.56; - } -#else - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh ); -#endif - } - else - { - const float *pt_interp_2; - - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - float lsf_wgts[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf( lsp_new, lsf_new, M, 12800 ); - - Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); - - tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); - - push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); - } - - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } - - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - lsp2lsf( lsp_new, lsf_new, M, st->sr_core ); - } - - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } - - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - tmpF = hLPDmem->old_exc_flt[0]; - preemph( hLPDmem->old_exc_flt, st->preemph_fac_flt, st->L_frame, &tmpF ); - mvr2r( hLPDmem->old_exc_flt + st->L_frame - M, hLPDmem->mem_syn_flt, M ); - residu( Aq, M, hLPDmem->old_exc_flt, old_exc_flt, st->L_frame ); - } - - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ - if ( st->L_frame == L_FRAME ) - { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } - } - - - /*---------------------------------------------------------------* - * Calculation of LP residual (filtering through A[z] filter) - *---------------------------------------------------------------*/ -#if 0 - floatToFixed_arr(Aq, Aq_fx, 12, NB_SUBFR16k*(M + 1)); - calc_residu_fx(st, inp_fx, res_fx, Aq_fx); -#else - calc_residu( inp, res, Aq, st->L_frame ); -#endif - calculate_hangover_attenuation_gain( st, &att, vad_hover_flag ); - if ( att != 1.0f ) - { - v_multc( res, att, res, st->L_frame ); - } - - /*-----------------------------------------------------------------* - * Determine TC subframe classification - *-----------------------------------------------------------------*/ - - if ( st->coder_type == TRANSITION ) - { - tc_classif_enc( st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res ); - - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } - - /*---------------------------------------------------------------* - * Calculation of prediction for scaled innovation energy - * (for memory-less gain quantizer) - *---------------------------------------------------------------*/ -#if 0 - Es_pred_fx = Es_pred * (1 << 8); - IF(nb_bits > 0) - { - Es_pred_enc_fx(&Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, 0); - push_indice(hBstr, IND_ES_PRED, i, nb_bits); - } - - Es_pred = (float)Es_pred_fx / (1 << 8); -#else - if ( nb_bits > 0 ) - { - Es_pred_enc( &Es_pred, &i, st->L_frame, L_SUBFR, res, st->voicing, nb_bits, uc_two_stage_flag ); - push_indice( hBstr, IND_ES_PRED, i, nb_bits ); - } -#endif - /*------------------------------------------------------------* - * Encode excitation according to coding type - *------------------------------------------------------------*/ - - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - if ( st->coder_type <= UNVOICED ) - { - tdm_low_rate_enc( st, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, 0 /*attack_flag*/, lsf_new, &tmp_noise ); - } - else /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - } - else if ( nelp_mode ) - { - /* SC-VBR - NELP frames */ - encod_nelp( st, inp, Aw, Aq, res, syn, &tmp_noise, exc, exc2, pitch_buf, voice_factors, bwe_exc ); - } - else if ( st->coder_type == UNVOICED ) - { - /* UNVOICED frames (Gauss. excitation) */ - encod_unvoiced( st, inp, Aw, Aq, Es_pred, uc_two_stage_flag, res, syn, &tmp_noise, exc, pitch_buf, voice_factors, bwe_exc ); - } - else if ( st->coder_type == TRANSITION ) - { - encod_tran( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tc_subfr, position, unbits ); - } - else if ( ppp_mode ) - { - /* SC-VBR - PPP frames */ - if ( ( error = encod_ppp( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc ) ) != IVAS_ERR_OK ) - { - return error; - } - - - if ( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ - { - /* restore memories of LSF quantizer and synthesis filter */ - lsf_syn_mem_restore( st, tilt_code_bck, gc_threshold_bck, clip_var_bck, next_force_sf_bck, lsp_new, lsp_mid, clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, mem_w0_bck, streaklimit, pstreaklen ); - - /* Configure ACELP bit allocation */ - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - - /* redo LSF quantization */ - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL ); - - /* recalculation of LP residual (filtering through A[z] filter) */ - calc_residu( inp, res, Aq, st->L_frame ); - st->hTdCngEnc->burst_ho_cnt = 0; - - /* VOICED frames in SC-VBR */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - } - else if ( st->coder_type == AUDIO || ( st->coder_type == INACTIVE && st->inactive_coder_type_flag ) ) - { - /* AUDIO and INACTIVE frames (coded by GSC technology) */ - encod_audio( st, inp, Aw, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, attack_flag, lsf_new, &tmp_noise, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - else - { - /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } - - /* update mem_syn1_flt for ACELP core switching */ - mvr2r( hLPDmem->mem_syn_flt, hLPDmem->mem_syn1_flt, M ); - - Copy(hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M); - - /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - mvr2r( syn + st->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r_flt, L_SYN_MEM ); - - Copy(syn_fx + st->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM); - /* save and delay synthesis to be used by SWB BWE */ -#if 1 - floatToFixed_arr(hLPDmem->mem_syn_r, hLPDmem->mem_syn_r_flt, 0, L_SYN_MEM); - floatToFixed_arr(hLPDmem->mem_syn1_fx, hLPDmem->mem_syn1_flt, 0, M); -#endif -#if 0 - floatToFixed_arr(st->hBWE_FD->old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, 0, 36); - floatToFixed_arr(syn, syn_fx, -1, L_FRAME16k); - st->hBWE_FD->mem_deemph_old_syn_fx = st->hBWE_FD->mem_deemph_old_syn; - st->preemph_fac = st->preemph_fac_flt * (1 << 15); - - save_old_syn_fx(st->L_frame, syn_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx); - - fixedToFloat_arr(old_syn_12k8_16k_fx, old_syn_12k8_16k, -1, 320); - fixedToFloat_arr(st->hBWE_FD->old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k, 0, 36); - st->hBWE_FD->mem_deemph_old_syn = st->hBWE_FD->mem_deemph_old_syn_fx; -#else - if ( st->hBWE_FD != NULL ) - { - save_old_syn( st->L_frame, syn, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k, st->preemph_fac_flt, &st->hBWE_FD->mem_deemph_old_syn ); - } -#endif - /*Update MODE2 core switching memory*/ - mvr2r( syn, syn1, st->L_frame ); -#if 0 - deemph(syn1, st->preemph_fac_flt, st->L_frame, &(hLPDmem->syn_flt[M])); -#else - deemph( syn1, st->preemph_fac_flt, st->L_frame, &( hLPDmem->syn_flt[M] ) ); -#endif - mvr2r( syn1 + st->L_frame - M - 1, hLPDmem->syn_flt, M + 1 ); - - if ( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) - { - mvr2r( syn1 + st->L_frame / 2, st->hTcxEnc->Txnq_flt, st->L_frame / 2 ); - } - - /*--------------------------------------------------------------------------------------* - * Modify the excitation signal when the noise is stationary - *--------------------------------------------------------------------------------------*/ - - if ( !( st->idchan == 1 && st->element_mode == IVAS_CPE_TD ) && nelp_mode != 1 && !( st->element_mode == IVAS_SCE && tdm_low_rate_mode ) ) - { - /* exc2 buffer is needed only for updating of Aq[] which is needed for core switching */ - mvr2r( exc, exc2, st->L_frame ); - stat_noise_uv_enc( st, epsP, lsp_new, lsp_mid, Aq, exc2, uc_two_stage_flag ); - } - - /*-----------------------------------------------------------------* - * Encode supplementary information for Frame Error Concealment - *-----------------------------------------------------------------*/ - - FEC_encode( hBstr, st->acelp_cfg, syn, st->coder_type, st->clas, pitch_buf, res, &st->Last_pulse_pos, st->L_frame, st->total_brate ); - - if ( st->hBWE_TD != NULL ) - { - if ( st->L_frame == L_FRAME ) - { - mvr2r( Aq + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) ); - } - else - { - mvr2r( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) ); - } - } - -#endif - } /* end of active inp coding */ -#else - else - { - /*-----------------------------------------------------------------* - * Configure ACELP bit allocation - *-----------------------------------------------------------------*/ - - nb_bits = 0; - st->acelp_cfg.FEC_mode = 0; - uc_two_stage_flag = 0; - - if ( !nelp_mode && !ppp_mode ) - { - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } - - /*-----------------------------------------------------------------* - * After inactive period, use the most up-to-date ISPs - *-----------------------------------------------------------------*/ - -#ifdef NON_BE_FIX_807_MASA_DTX_BRSW - if ( st->hDtxEnc != NULL && ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40 ) ) -#else - if ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40 ) -#endif - { - mvr2r( st->hDtxEnc->lspCNG, st->lsp_old, M ); - lsp2lsf( st->hDtxEnc->lspCNG, st->lsf_old, M, int_fs ); - } - - /*-----------------------------------------------------------------* - * Reset higher ACELP pre-quantizer in case of switching - *-----------------------------------------------------------------*/ - - if ( !st->use_acelp_preq ) - { - st->mem_deemp_preQ = 0.0f; - st->mem_preemp_preQ = 0.0f; - st->last_code_preq = 0; - st->last_nq_preQ = 0; - } - st->use_acelp_preq = 0; - - /*-----------------------------------------------------------------* - * LSF Quantization - * A[z] calculation - *-----------------------------------------------------------------*/ - - /* SC-VBR & channel-aware mode - back-up memories for LSF quantizer and synthesis filter */ - lsf_syn_mem_backup( st, &tilt_code_bck, &gc_threshold_bck, clip_var_bck, &next_force_sf_bck, lsp_new, lsp_mid, &clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, &mem_w0_bck, &streaklimit, &pstreaklen ); - - if ( !tdm_lp_reuse_flag ) - { - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh ); - } - else - { - const float *pt_interp_2; - - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - float lsf_wgts[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf( lsp_new, lsf_new, M, 12800 ); - - Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); -#ifdef IVAS_FLOAT_FIXED - Word16 lsf_new_fx[M]; - Word16 lsp_new_fx[M]; - Word16 tdm_lsfQ_PCh_fx[M]; - Word16 lsf_wgts_fx[M]; - for ( int ii = 0; ii < M; ii++ ) - { - lsf_new_fx[ii] = (Word16) ( ( lsf_new[ii] ) * 2.56f ); - tdm_lsfQ_PCh_fx[ii] = (Word16) ( ( tdm_lsfQ_PCh[ii] ) * 2.56f ); - lsf_wgts_fx[ii] = (Word16) ( ( lsf_wgts[ii] ) * 2.56f ); - } - floatToFixed_arr( lsp_new, lsp_new_fx, 15, M ); - - tdm_SCh_lsf_reuse_fx( ENC, st->element_brate, lsf_new_fx, lsp_new_fx, tdm_lsfQ_PCh_fx, lsf_wgts_fx, &beta_index ); - - for ( int ii = 0; ii < M; ii++ ) - { - lsf_new[ii] = (Word16) ( ( lsf_new_fx[ii] ) / 2.56f ); - lsf_wgts[ii] = (Word16) ( ( lsf_wgts_fx[ii] ) / 2.56f ); - } - fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); -#else - tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); -#endif - push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); - } - - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } - - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - lsp2lsf( lsp_new, lsf_new, M, st->sr_core ); - } - - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } - - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - tmpF = hLPDmem->old_exc_flt[0]; - preemph( hLPDmem->old_exc_flt, st->preemph_fac_flt, st->L_frame, &tmpF ); - mvr2r( hLPDmem->old_exc_flt + st->L_frame - M, hLPDmem->mem_syn_flt, M ); - residu( Aq, M, hLPDmem->old_exc_flt, old_exc_flt, st->L_frame ); - } - - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ - if ( st->L_frame == L_FRAME ) - { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp_flt( old_exc_flt, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } - } - - - /*---------------------------------------------------------------* - * Calculation of LP residual (filtering through A[z] filter) - *---------------------------------------------------------------*/ - - calc_residu( inp, res, Aq, st->L_frame ); - - calculate_hangover_attenuation_gain( st, &att, vad_hover_flag ); - if ( att != 1.0f ) - { - v_multc( res, att, res, st->L_frame ); - } - - /*-----------------------------------------------------------------* - * Determine TC subframe classification - *-----------------------------------------------------------------*/ - - if ( st->coder_type == TRANSITION ) - { - tc_classif_enc( st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res ); - - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } - - /*---------------------------------------------------------------* - * Calculation of prediction for scaled innovation energy - * (for memory-less gain quantizer) - *---------------------------------------------------------------*/ - - if ( nb_bits > 0 ) - { - Es_pred_enc( &Es_pred, &i, st->L_frame, L_SUBFR, res, st->voicing, nb_bits, uc_two_stage_flag ); + Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new + 1 ); push_indice( hBstr, IND_ES_PRED, i, nb_bits ); } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( old_exc_fx, old_exc_flt, Q15 - hLPDmem->e_old_exc, st->L_frame ); + me2f_buf_16( &hLPDmem->old_exc[-M - 1], hLPDmem->e_old_exc, &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ); + me2f_buf_16( hLPDmem->mem_syn, hLPDmem->e_mem_syn, hLPDmem->mem_syn_flt, M ); + fixedToFloat_arr( old_bwe_exc_fx, old_bwe_exc, Q_old_bwe_exc, 1380 ); + fixedToFloat_arr( res_fx, res, Q_new + 1, st->L_frame ); + Es_pred = fix16_to_float( Es_pred_fx, Q8 ); +#endif +#endif /*------------------------------------------------------------* * Encode excitation according to coding type @@ -1450,7 +908,6 @@ ivas_error acelp_core_enc( } /* end of active inp coding */ -#endif /*-----------------------------------------------------------------* * Write ACELP unused bits diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index 8414c56da..a71a49f14 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -53,6 +53,36 @@ Word16 EncodeIndex_fx( return 8; } } +#ifdef IVAS_FLOAT_FIXED +Word16 EncodeIndex_ivas_fx( + const Word16 Bandwidth, + Word16 PeriodicityIndex, + BSTR_ENC_HANDLE hBst /* i/o: bitstream handle */ +) +{ + Word16 NumRatioBitsBwLtpIndx; + + IF( s_and( PeriodicityIndex, kLtpHmFlag ) != 0 ) + { + Word16 LtpPitchIndex = shr( PeriodicityIndex, 9 ); + assert( 0 <= LtpPitchIndex && LtpPitchIndex <= 16 ); + + PeriodicityIndex = sub( PeriodicityIndex, 1 ); + assert( ( PeriodicityIndex & 0xff ) < ( 1 << NumRatioBits[Bandwidth][LtpPitchIndex] ) ); + + NumRatioBitsBwLtpIndx = NumRatioBits[Bandwidth][LtpPitchIndex]; + move16(); + + push_next_indice( hBst, s_and( PeriodicityIndex, 0xff ), NumRatioBitsBwLtpIndx ); + return NumRatioBitsBwLtpIndx; + } + ELSE + { + push_next_indice( hBst, PeriodicityIndex, 8 ); + return 8; + } +} +#endif /*-------------------------------------------------------------------* * SearchPeriodicityIndex_Single() * diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index 29a2db60e..119506fa9 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -43,6 +43,10 @@ #include "prot.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#endif + /*---------------------------------------------------------------------* * core_switching_pre_enc() * @@ -97,6 +101,11 @@ void core_switching_pre_enc( { set_f( hHQ_core->last_ni_gain, 0, BANDS_MAX ); set_f( hHQ_core->last_env, 0, BANDS_MAX ); + +#ifdef IVAS_FLOAT_FIXED + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); +#endif hHQ_core->last_max_pos_pulse = 0; hHQ_core->mode_count = 0; diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index f59fdf08f..92386c225 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -54,6 +54,46 @@ static void enc_prm_hm( } } } +#ifdef IVAS_FLOAT_FIXED +static void enc_prm_hm_ivas_fx( + Word16 *prm_hm, + Encoder_State *st, + Word16 L_frame ) +{ + Word8 flag; + BSTR_ENC_HANDLE hBstr = st->hBstr; + + + /* Disable HM for non-GC,VC modes */ + test(); + IF( NE_16( st->hTcxCfg->coder_type, VOICED ) && NE_16( st->hTcxCfg->coder_type, GENERIC ) ) + { + return; + } + + /* Flag */ + push_next_indice( hBstr, prm_hm[0], 1 ); + + IF( prm_hm[0] ) + { + /* Periodicy index */ + flag = 0; + move16(); + if ( GE_16( L_frame, L_FRAME ) ) + { + flag = 1; + move16(); + } + EncodeIndex_ivas_fx( flag, prm_hm[1], hBstr ); + + IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) ) + { + /* Gain index */ + push_next_indice( hBstr, prm_hm[2], kTcxHmNumGainBits ); + } + } +} +#endif /*-----------------------------------------------------------------* * Function enc_prm_rf_fx() * @@ -914,3 +954,388 @@ void enc_prm_fx( return; } + + +/*-------------------------------------------------------------------* + * writeLPCparam_fx() + * + * write LTC parameters + *-------------------------------------------------------------------*/ + +void writeLPCparam_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 param_lpc[], /* i : LPC parameters to write */ + const Word16 bits_param_lpc[], /* i : bits per LPC parameter */ + const Word16 no_param_lpc, /* i : number of LPC parameters */ + Word16 *nbits_lpc /* o : LPC bits written */ +) +{ + Word16 numlpc; + + test(); + IF( st->enableTcxLpc && st->core != ACELP_CORE ) + { + /* Encode the indices */ + *nbits_lpc = enc_lsf_tcxlpc_ivas_fx( ¶m_lpc, hBstr ); + move16(); + } + ELSE + { + IF( st->lpcQuantization == 0 ) + { + /* LPC quantizer */ + IF( EQ_16( st->core, TCX_20_CORE ) ) + { + numlpc = 1; + move16(); + } + ELSE + { + numlpc = 2; + move16(); + } + + *nbits_lpc = encode_lpc_avq_ivas_fx( hBstr, numlpc, param_lpc, st->core, st->element_mode ); + move16(); + } + ELSE IF( EQ_16( st->lpcQuantization, 1 ) ) + { + test(); + test(); + IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( st->coder_type, VOICED ) && EQ_16( st->core, ACELP_CORE ) ) + { + assert( st->element_mode == EVS_MONO ); + + *nbits_lpc = lsf_bctcvq_encprm_ivas_fx( hBstr, param_lpc, bits_param_lpc, no_param_lpc ); + move16(); + } + ELSE + { + *nbits_lpc = lsf_msvq_ma_encprm_ivas_fx( hBstr, param_lpc, st->core, st->coder_type, st->acelp_cfg.midLpc, bits_param_lpc, no_param_lpc ); + move16(); + } + } + ELSE + { + assert( 0 ); + } + } + + return; +} + +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * writeTCXparam_fx() + * + * write TCX core parameters + *-------------------------------------------------------------------*/ + +void writeTCXparam_fx( + Encoder_State *st, /* i/o: Encoder State handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ + Word16 param[], /* i : parameters */ + const Word16 nbits_header, + const Word16 nbits_start, + const Word16 nbits_lpc, + const Word16 *no_param_tns, /* i : number of TNS parameters per subframe */ + Word16 p_param[2], /* i/o: pointer to parameters from previous bs writing */ + const Word16 target_bitsTCX10[2], + const Word16 pre_past_flag ) +{ + Word16 *prm; + Word16 j, k, nSubframes, core, last_core; + Word16 lg, lgFB, hm_size, flag_ctx_hm; + Word16 total_nbbits, nbits_igf, nbits_tcx; + Word16 nTnsParams, nTnsBits; + Word16 pre_part, post_part; + + IF( pre_past_flag == 0 ) + { + pre_part = 1; + post_part = 0; + move16(); + move16(); + } + ELSE IF( EQ_16( pre_past_flag, 1 ) ) + { + pre_part = 0; + post_part = 1; + move16(); + move16(); + } + ELSE + { + pre_part = 1; + post_part = 1; + move16(); + move16(); + } + + /* Initialization */ + core = st->core; + last_core = st->last_core; + nbits_igf = 0; + move16(); + move16(); + move16(); + + nSubframes = 1; + move16(); + if ( EQ_16( core, TCX_10_CORE ) ) + { + nSubframes = 2; + move16(); + } + + /* loop over subframes */ + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + IF( LT_16( st->element_mode, IVAS_CPE_MDCT ) && k == 0 && st->igf && EQ_16( core, TCX_10_CORE ) ) + { + nbits_igf = IGFEncWriteConcatenatedBitstream_ivas_fx( st->hIGFEnc, hBstr ); + } + + flag_ctx_hm = 0; + move16(); + + prm = param + imult1616( k, NPRM_DIV ); + j = 0; + move16(); + + nbits_tcx = total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + move16(); + + test(); + test(); + IF( pre_part && st->enablePlcWaveadjust && EQ_16( k, sub( nSubframes, 1 ) ) ) + { + push_next_indice( hBstr, st->Tonal_SideInfo, 1 ); + } + + IF( post_part ) + { + /* TCX Gain */ + push_next_indice( hBstr, prm[j++], NBITS_TCX_GAIN ); + + /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ + push_next_indice( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); + } + ELSE + { + j = add( j, 1 + NOISE_FILL_RANGES ); + } + + /* LTP data */ + IF( pre_part ) + { + test(); + test(); + IF( ( k == 0 ) && ( st->hTcxEnc->tcxltp || GT_32( st->sr_core, 25600 ) ) ) /* PLC pitch info for HB */ + { + IF( prm[j] ) + { + push_next_indice( hBstr, 1, 1 ); + push_next_indice( hBstr, prm[j + 1], 9 ); + push_next_indice( hBstr, prm[j + 2], 2 ); + } + ELSE + { + push_next_indice( hBstr, 0, 1 ); + } + } + j = add( j, 3 ); + } + ELSE + { + j = add( j, sub( p_param[k], 2 ) ); + } + + /* TCX spectral data */ + lg = shr( st->last_L_frame, sub( nSubframes, 1 ) ); + lgFB = shr( st->hTcxCfg->tcx_coded_lines, sub( nSubframes, 1 ) ); + + test(); + test(); + IF( post_part && k == 0 && last_core == ACELP_CORE ) + { + /* ACE->TCX transition */ + lg = add( lg, st->hTcxCfg->tcx_offset ); + lgFB = add( lgFB, shr( lgFB, sub( 3, nSubframes ) ) ); + + IF( st->hTcxCfg->lfacNext < 0 ) + { + lg = sub( lg, st->hTcxCfg->lfacNext ); + } + } + + IF( pre_part ) + { + /* TNS data */ + nTnsParams = 0; + nTnsBits = 0; + move16(); + move16(); + + IF( st->hTcxCfg->fIsTNSAllowed ) + { + test(); + SetTnsConfig( st->hTcxCfg, core == TCX_20_CORE, ( last_core == ACELP_CORE ) && ( k == 0 ) ); + + IF( no_param_tns ) + { + IF( st->hTcxEnc->tnsData[k].nFilters < 0 ) + { + push_next_indice( hBstr, 1, 1 ); /* common_tns_data[] for subframe k */ + } + ELSE + { + push_next_indice( hBstr, 0, 1 ); /* common_tns_data[] for subframe k */ + } + } + test(); + IF( no_param_tns && ( st->hTcxEnc->tnsData[k].nFilters < 0 ) ) + { + /* a negative filter count means that the filters are identical to those in the first channel at the same sub-frame */ + nTnsParams = no_param_tns[k]; + move16(); + } + ELSE + { + WriteTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, prm + j, &nTnsParams, hBstr, &nTnsBits ); + } + IF( no_param_tns ) + { + nTnsBits = add( nTnsBits, 1 ); + } + j = add( j, nTnsParams ); + } + + IF( post_part ) + { + hm_size = imult1616( mult( 2, st->hTcxCfg->bandwidth ), lg ); + + test(); + test(); + IF( st->hTcxEnc->tcx_lpc_shaped_ari && last_core != ACELP_CORE && EQ_16( core, TCX_20_CORE ) ) + { + enc_prm_hm_ivas_fx( &prm[j], st, hm_size ); + } + + /*Context HM flag*/ + test(); + test(); + test(); + IF( st->hTcxCfg != NULL && st->hTcxCfg->ctx_hm && !( last_core == ACELP_CORE && k == 0 ) ) + { + push_next_indice( hBstr, prm[j], 1 ); + + IF( prm[j] ) + { + EncodeIndex_ivas_fx( (Word16) GE_16( hm_size, 256 ), prm[j + 1], hBstr ); + + flag_ctx_hm = 1; + move16(); + } + } + } + j = add( j, NPRM_CTX_HM ); + + IF( post_part ) + { + /* IGF data */ + IF( st->igf && EQ_16( core, TCX_20_CORE ) ) + { + Word16 gridIdx; + gridIdx = IGF_GRID_LB_NORM; + move16(); + if ( last_core == ACELP_CORE ) + { + gridIdx = IGF_GRID_LB_TRAN; + move16(); + } + st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; + move16(); + IGFEncWriteBitstream_ivas_fx( st->hIGFEnc, hBstr, &st->hIGFEnc->infoTotalBitsPerFrameWritten, gridIdx, 1 ); + } + + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + + IF( EQ_16( core, TCX_20_CORE ) ) + { + IF( st->rf_mode ) + { + total_nbbits = add( total_nbbits, st->rf_target_bits_write ); + } + nbits_tcx = sub( st->bits_frame_core, total_nbbits ); + } + ELSE /* TCX_10_CORE */ + { + nbits_tcx = sub( shr( sub( add( sub( sub( sub( st->bits_frame_core, nbits_header ), nbits_lpc ), nbits_igf ), 1 ), k ), 1 ), sub( total_nbbits, nbits_tcx ) ); + } + } + ELSE + { + /*Context HM flag*/ + p_param[k] = j; + move16(); + } + } + ELSE + { + nbits_tcx = st->bits_frame_channel; + move16(); + IF( EQ_16( core, TCX_10_CORE ) ) + { + nbits_tcx = sub( target_bitsTCX10[k], NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); + } + } + + IF( post_part ) + { + test(); + IF( st->hTcxEnc->tcx_lpc_shaped_ari && EQ_16( core, TCX_20_CORE ) ) + { + push_next_bits( hBstr, (UWord16 *) &prm[++j], nbits_tcx ); + j = add( j, nbits_tcx ); + } + ELSE + { + IF( st->element_mode > EVS_MONO ) + { + IF( flag_ctx_hm ) + { + RCcontextMapping_encode2_no_mem_s17_LCS_fx( hBstr, prm + j, lgFB, prm[j - 1], /* lastnz */ + nbits_tcx, imult1616( NPRM_RESQ, st->hTcxCfg->resq ), &hm_cfg[k] ); + } + ELSE + { + RCcontextMapping_encode2_no_mem_s17_LCS_fx( hBstr, prm + j, lgFB, prm[j - 1], /* lastnz */ + nbits_tcx, imult1616( NPRM_RESQ, st->hTcxCfg->resq ), NULL ); + } + } + ELSE + { + IF( flag_ctx_hm ) + { + ACcontextMapping_encode2_no_mem_s17_LC_fx( hBstr, prm + j, lgFB, prm[j - 1], /* lastnz */ + nbits_tcx, imult1616( NPRM_RESQ, st->hTcxCfg->resq ), &hm_cfg[k] ); + } + ELSE + { + ACcontextMapping_encode2_no_mem_s17_LC_fx( hBstr, prm + j, lgFB, prm[j - 1], /* lastnz */ + nbits_tcx, imult1616( NPRM_RESQ, st->hTcxCfg->resq ), NULL ); + } + } + } + } + } + + return; +} +#endif // IVAS_FLOAT_FIXED diff --git a/lib_enc/gp_clip_fx.c b/lib_enc/gp_clip_fx.c index 73a5c35ea..c3c2dc0d0 100644 --- a/lib_enc/gp_clip_fx.c +++ b/lib_enc/gp_clip_fx.c @@ -459,3 +459,61 @@ void gp_clip_test_lsf_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +void gp_clip_test_lsf_ivas_fx( + const Word16 element_mode, /* i : element mode */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 lsf[], /* i : LSF vector */ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +) +{ + Word16 i; + Word16 m; + Word16 dist, dist_min; + + dist_min = sub( lsf[1], lsf[0] ); + + IF( Opt_AMR_WB ) + { + m = M - 1; + move16(); + } + ELSE + { + m = M; + move16(); + } + + FOR( i = 2; i < m; i++ ) + { + dist = sub( lsf[i], lsf[i - 1] ); + dist_min = s_min( dist, dist_min ); + } + + // dist = 0.8f * mem[0] + 0.2f * dist_min; + dist = mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ); + + test(); + test(); + IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || GT_16( element_mode, EVS_MONO ) ) + { + IF( GT_16( dist, DIST_ISF_MAX_IO ) ) + { + dist = DIST_ISF_MAX_IO; + move16(); + } + } + ELSE if ( GT_16( dist, DIST_ISF_MAX ) ) + { + dist = DIST_ISF_MAX; + move16(); + } + + mem[0] = dist; + move16(); + + return; +} +#endif diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index dbc0f814a..c3571735b 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -42,6 +42,11 @@ #include "rom_com.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#include "prot_fx_enc.h" +#endif + /*-------------------------------------------------------------------------- * hq_core_enc() * @@ -67,11 +72,14 @@ void hq_core_enc( float Aq_old[M + 1]; float output[L_FRAME16k]; +#ifdef IVAS_FLOAT_FIXED + Word32 t_audio_fx[L_FRAME48k_EXT]; +#endif BSTR_ENC_HANDLE hBstr = st->hBstr; push_wmops( "hq_core_enc" ); - set_f( t_audio, 0, L_FRAME48k ); + set_f( t_audio, 0, L_FRAME48k_EXT ); st->Nb_ACELP_frames = 0; /* set input_frame length */ @@ -220,8 +228,22 @@ void hq_core_enc( if ( hq_core_type == LOW_RATE_HQ_CORE ) { + /* HQ low rate encoder */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + floatToFixed_arr32( t_audio, t_audio_fx, Q12, L_FRAME48k_EXT ); +#endif + hq_lr_enc_ivas_fx( st, t_audio_fx, inner_frame, &num_bits, is_transient ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL( st->hHQ_core->last_ni_gain_fx, st->hHQ_core->last_ni_gain, Q17, BANDS_MAX ); + fixedToFloat_arr( st->hHQ_core->last_env_fx, st->hHQ_core->last_env, Q1, BANDS_MAX ); + fixedToFloat_arrL( t_audio_fx, t_audio, Q12, L_FRAME48k_EXT ); +#endif +#else hq_lr_enc( st, t_audio, inner_frame, &num_bits, is_transient ); +#endif } else { @@ -320,6 +342,12 @@ void HQ_core_enc_init( set_s( hHQ_core->last_bitalloc_max_band, 0, 2 ); set_f( hHQ_core->last_ni_gain, 0, BANDS_MAX ); set_f( hHQ_core->last_env, 0, BANDS_MAX ); + +#ifdef IVAS_FLOAT_FIXED + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); +#endif hHQ_core->last_max_pos_pulse = 0; hHQ_core->crest_lp = HQ_CREST_THRESHOLD; diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index bfb983641..1d5ac96b8 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -4,12 +4,13 @@ #include #include "options.h" /* Compilation switches */ -//#include "prot_fx.h" /* Function prototypes */ +// #include "prot_fx.h" /* Function prototypes */ #include "rom_enc.h" #include "rom_com.h" #include "stl.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "prot.h" /*--------------------------------------------------------------------------------------* * encode_envelope_indices_fx() @@ -552,6 +553,544 @@ Word16 encode_envelope_indices_fx( /* o : Number of b return hcode_l; } + +#ifdef IVAS_FLOAT_FIXED +Word16 encode_envelope_indices_ivas_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + const Word16 num_sfm, /* i : Number of subbands Q0 */ + const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ + Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ + Word16 *LCmode, /* o : Coding mode if flag_pack=0, i : if flag_pack=1 Q0 */ + const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0 */ + const Word16 flag_HQ2, /* i : indicator of HQ2 core Q0 */ + const Word16 is_transient /* i : indicator of HQ_TRANSIENT Q0 */ +) +{ + Word16 bits; + Word16 prevj; + Word16 hcode_l; + Word16 i, j; + Word16 difidx_flag; + Word16 index_max, index_min, index_rad; + Word16 difidx_org[NB_SFM]; /* length of this buffer is max(BANDS_MAX,NB_SFM) */ + Word16 m, r; + Word16 v, k; + + + set16_fx( difidx_org, 0, NB_SFM ); + difidx_flag = 0; + move16(); + + /*------------------------------------------------------------------* + * Check Huffman encoding for QNorm indices + *------------------------------------------------------------------*/ + + /* LC mode index is changed to synchronize LR_MDCT signaling */ + /* LC mode 0 = Context based coding */ + /* LC mode 1 = resized huffman coding */ + /* LC mode 2 = normal Huffman Coding */ + /* LC mode 3 = bit packing */ + IF( flag_pack == 0 ) + { + test(); + IF( is_transient && EQ_16( flag_HQ2, LOW_RATE_HQ_CORE_TRAN ) ) + { + bits = 0; + move16(); + index_max = 0; + move16(); + index_min = 31; + move16(); + FOR( i = 0; i < num_sfm; i++ ) + { + IF( GT_16( difidx[i], index_max ) ) + { + index_max = difidx[i]; + move16(); + } + IF( LT_16( difidx[i], index_min ) ) + { + index_min = difidx[i]; + move16(); + } + } + test(); + IF( GT_16( index_min, 10 ) && LT_16( index_max, 22 ) ) + { + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + bits = add( bits, huffsizn_tran[j] ); + } + } + hcode_l = 0; + move16(); + *LCmode = 0; + move16(); + prevj = add( difidx[0], OFFSET_NORM ); + /* LC mode 0 = Context based coding */ + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + IF( GT_16( prevj, HTH_NORM ) ) + { + /* above */ + hcode_l = add( hcode_l, huffsizn_n[31 - j] ); + } + ELSE + { + IF( LT_16( prevj, LTH_NORM ) ) + { + /* less */ + hcode_l = add( hcode_l, huffsizn_n[j] ); + } + ELSE + { + /* equal */ + hcode_l = add( hcode_l, huffsizn_e[j] ); + } + } + prevj = j; + move16(); + } + test(); + IF( GE_16( hcode_l, bits ) && bits != 0 ) + { + /* LC mode 1 Transient Huffman Coding */ + *LCmode = 1; + move16(); + hcode_l = bits; + move16(); + } + } + ELSE + { + /* Check bits if LC mode == 3 -> Check bits if LC mode == 0 */ + hcode_l = 0; + move16(); + prevj = add( difidx[0], OFFSET_NORM ); + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + IF( GT_16( prevj, HTH_NORM ) ) + { + /* above */ + hcode_l = add( hcode_l, huffsizn_n[sub( 31, j )] ); + } + ELSE + { + IF( LT_16( prevj, LTH_NORM ) ) + { + /* less */ + hcode_l = add( hcode_l, huffsizn_n[j] ); + } + ELSE + { + /* equal */ + hcode_l = add( hcode_l, huffsizn_e[j] ); + } + } + prevj = j; + move16(); + } + + *LCmode = 0; + move16(); + + /* LR-MDCT core doesn't have coding mode 2 and 3 */ + IF( flag_HQ2 == NORMAL_HQ_CORE ) + { + /* Check bits if LC mode == 1 -> Check bits if LC mode == 2 */ + bits = 0; + move16(); + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + bits = add( bits, huffsizn[j] ); + } + + /*------------------------------------------------------------------------------* + * comparing bit expenses of coding mode 2 with that of the optimal coding mode + *------------------------------------------------------------------------------*/ + + if ( GT_16( hcode_l, bits ) ) + { + *LCmode = 2; + move16(); + } + hcode_l = s_min( hcode_l, bits ); + } + + /* Check bits if LC mode == 2 -> Check bits if LC mode == 1 */ + bits = 0; + move16(); + index_max = 0; + move16(); + index_min = 31; + move16(); + FOR( i = 1; i < num_sfm; i++ ) + { + difidx_org[i] = difidx[i]; + move16(); + } + + difidx_flag = 0; + move16(); + FOR( i = 2; i < num_sfm; i++ ) + { + IF( GT_16( difidx_org[i - 1], 17 ) ) + { + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + move16(); + IF( GT_16( difidx[i], 31 ) ) + { + difidx_flag = 1; + move16(); + BREAK; + } + } + + IF( LT_16( difidx_org[i - 1], 13 ) ) + { + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + move16(); + IF( difidx[i] < 0 ) + { + difidx_flag = 1; + move16(); + BREAK; + } + } + } + + index_rad = 0; + move16(); + IF( difidx_flag == 0 ) + { + FOR( i = 1; i < num_sfm; i++ ) + { + index_max = s_max( index_max, difidx[i] ); + index_min = s_min( index_min, difidx[i] ); + } + + index_rad = s_max( sub( 15, index_min ), sub( index_max, 15 ) ); + + IF( LE_16( index_rad, HUFF_THR ) ) + { + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + bits = add( bits, resize_huffsizn[j] ); + } + + /*------------------------------------------------------------------* + * comparing bit expenses of coding mode 1 with that of coding mode 0 + *------------------------------------------------------------------*/ + + if ( GT_16( hcode_l, bits ) ) + { + *LCmode = 1; + move16(); + } + hcode_l = s_min( hcode_l, bits ); + } + } + + /* LR-MDCT core doesn't have coding mode 2 and 3 */ + IF( flag_HQ2 == NORMAL_HQ_CORE ) + { + /*------------------------------------------------------------------------------* + * comparing bit expenses of coding mode 3 with that of the optimal coding mode + *------------------------------------------------------------------------------*/ + + if ( GE_16( hcode_l, numnrmibits ) ) + { + *LCmode = 3; + move16(); + } + hcode_l = s_min( hcode_l, numnrmibits ); + } + + test(); + test(); + IF( ( NE_16( *LCmode, 1 ) && flag_HQ2 == NORMAL_HQ_CORE ) || EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) + { + FOR( i = 2; i < num_sfm; i++ ) + { + difidx[i] = difidx_org[i]; + move16(); + } + } + } + } + ELSE + { + test(); + IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE_TRAN ) || EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) + { + push_indice( hBstr, IND_HQ2_DENG_HMODE, *LCmode, BITS_DE_HMODE ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, difidx[0], BITS_DE_FCOMP ); + } + ELSE + { + push_indice( hBstr, IND_LC_MODE, *LCmode, 2 ); + push_indice( hBstr, IND_YNRM, difidx[0], NORM0_BITS ); + } + + test(); + IF( is_transient && EQ_16( flag_HQ2, LOW_RATE_HQ_CORE_TRAN ) ) + { + hcode_l = 0; + move16(); + IF( EQ_16( *LCmode, 1 ) ) + { + /* LC mode 0 Transient Huffman Coding */ + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + m = huffnorm_tran[j]; + move16(); + r = huffsizn_tran[j]; + move16(); + v = 0; + move16(); + + /* Bit reverse */ + FOR( k = 0; k < r; k++ ) + { + v = lshl( v, 1 ); + v = s_or( v, s_and( m, 1 ) ); + m = lshr( m, 1 ); + } + + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + } + } + ELSE + { + /* LC mode 1 context based Coding */ + prevj = add( difidx[0], OFFSET_NORM ); + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + + IF( GT_16( prevj, HTH_NORM ) ) + { + /* above */ + r = huffsizn_n[sub( 31, j )]; + move16(); + m = huffnorm_n[sub( 31, j )]; + move16(); + } + ELSE + { + IF( LT_16( prevj, LTH_NORM ) ) + { + /* less */ + r = huffsizn_n[j]; + move16(); + m = huffnorm_n[j]; + move16(); + } + ELSE + { + /* equal */ + r = huffsizn_e[j]; + move16(); + m = huffnorm_e[j]; + move16(); + } + } + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + prevj = j; + move16(); + } + } + } + ELSE + { + hcode_l = 0; + move16(); + IF( *LCmode == 0 ) + { + /* LC mode 3 -> LC mode 0 */ + prevj = add( difidx[0], OFFSET_NORM ); + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + + IF( GT_16( prevj, HTH_NORM ) ) + { + /* above */ + r = huffsizn_n[sub( 31, j )]; + move16(); + m = huffnorm_n[sub( 31, j )]; + move16(); + } + ELSE + { + IF( LT_16( prevj, LTH_NORM ) ) + { + /* less */ + r = huffsizn_n[j]; + move16(); + m = huffnorm_n[j]; + move16(); + } + ELSE + { + /* equal */ + r = huffsizn_e[j]; + move16(); + m = huffnorm_e[j]; + move16(); + } + } + + IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + } + ELSE + { + push_indice( hBstr, IND_YNRM, m, r ); + } + + prevj = j; + move16(); + } + } + ELSE IF( EQ_16( *LCmode, 1 ) ) + { + IF( EQ_16( flag_HQ2, 1 ) ) + { + index_max = 0; + move16(); + index_min = 31; + move16(); + FOR( i = 1; i < num_sfm; i++ ) + { + difidx_org[i] = difidx[i]; + move16(); + } + + FOR( i = 2; i < num_sfm; i++ ) + { + IF( GT_16( difidx_org[i - 1], 17 ) ) + { + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + move16(); + IF( GT_16( difidx[i], 31 ) ) + { + difidx_flag = 1; + move16(); + BREAK; + } + } + + IF( LT_16( difidx_org[i - 1], 13 ) ) + { + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + move16(); + IF( difidx[i] < 0 ) + { + difidx_flag = 1; + move16(); + BREAK; + } + } + } + + IF( difidx_flag == 0 ) + { + FOR( i = 1; i < num_sfm; i++ ) + { + index_max = s_max( index_max, difidx[i] ); + index_min = s_min( index_min, difidx[i] ); + } + + index_rad = s_max( sub( 15, index_min ), sub( index_max, 15 ) ); + + IF( LE_16( index_rad, HUFF_THR ) ) + { + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + } + } + } + } + + /* LC mode 2 -> LC mode 1 */ + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + + m = resize_huffnorm[j]; + move16(); + r = resize_huffsizn[j]; + move16(); + v = 0; + move16(); + + /* Bit reverse */ + FOR( k = 0; k < r; k++ ) + { + v = lshl( v, 1 ); + v = s_or( v, s_and( m, 1 ) ); + m = lshr( m, 1 ); + } + + IF( flag_HQ2 == 0 ) + { + push_indice( hBstr, IND_YNRM, v, r ); + } + ELSE + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + } + } + } + ELSE IF( EQ_16( *LCmode, 2 ) ) + { + /* LC mode 1 -> LC mode 2 */ + FOR( i = 1; i < num_sfm; i++ ) + { + j = difidx[i]; + move16(); + + m = huffnorm[j]; + move16(); + r = huffsizn[j]; + move16(); + + push_indice( hBstr, IND_YNRM, m, r ); + } + } + ELSE + { + FOR( i = 1; i < num_sfm; i++ ) + { + push_indice( hBstr, IND_YNRM, difidx[i], NORMI_BITS ); + } + } + } + } + + return hcode_l; +} + +#endif /*--------------------------------------------------------------------------* * diff_envelope_coding_fx() * diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index 85827b9a1..4bb300f53 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -4,14 +4,15 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" +// #include "prot_fx.h" #include "rom_com_fx.h" #include "rom_enc.h" -//#include "basop_mpy.h" +// #include "basop_mpy.h" #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ +#include "prot.h" /*--------------------------------------------------------------------------* * Local function prototypes @@ -23,6 +24,35 @@ static Word16 p2a_threshold_quant_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_a static void mdct_spectrum_fine_gain_enc_fx( Encoder_State *st_fx, const Word32 L_ybuf[], Word32 L_y2[], const Word16 band_start[], const Word16 band_end[], const Word16 k_sort[], const Word16 bands, const Word32 L_qint, const Word16 Ngq, const Word16 gqlevs, const Word16 gqbits ); +#ifdef IVAS_FLOAT_FIXED + +static Word16 p2a_threshold_quant_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio, const Word16 band_start[], const Word16 band_end[], const Word16 band_width[], const Word16 bands, const Word16 p2a_bands, const Word16 p2a_th, Word16 *p2a_flags ); +static void mdct_spectrum_fine_gain_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 L_ybuf[], /* i : Q12 : input spectrum */ + Word32 L_y2[], /* i/o: Q12 : decoded spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 k_sort[], /* i : Q0 : sort table by band_energy */ + const Word16 bands, /* i : Q0 : nubmber of subbands */ + const Word32 L_qint, /* i : Q29 : */ + const Word16 Ngq, /* i : Q0 : */ + const Word16 gqlevs, /* i : Q0 : quantized level */ + const Word16 gqbits /* i : Q0 : quantized bits */ +); + +static Word16 band_energy_quant_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word32 *L_t_audio, + const Word16 band_start[], + const Word16 band_end[], + Word32 L_band_energy[], + const Word16 bands_fx, + const Word32 L_qint, /* Q29 */ + const Word16 eref_fx, /* Q10 */ + const Word16 is_transient ); +#endif + /*--------------------------------------------------------------------------* * spt_shorten_domain_set() * @@ -97,6 +127,78 @@ static void spt_shorten_domain_set_fx( return; } +#ifdef IVAS_FLOAT_FIXED +static void spt_shorten_domain_set_ivas_fx( + Encoder_State *st_fx, /* i: encoder state structure */ + const Word32 L_t_audio[], /* i: input spectrum */ + const Word16 p2a_flags[], /* i: p2a anlysis information */ + const Word16 new_band_start[], /* i: new band start position */ + const Word16 new_band_end[], /* i: new band end position */ + const Word16 new_band_width[], /* i: new subband band width */ + const Word16 bands, /* i: total number of subbands */ + Word16 band_start[], /* i/o: band start position */ + Word16 band_end[], /* i/o: band end position */ + Word16 band_width[], /* i: sub band band width */ + Word16 *bit_budget /* i/o: bit budget */ +) +{ + Word16 i, j, k; + Word16 kpos; + Word32 L_max_y2; + Word16 max_y2_pos; + Word16 spt_shorten_flag[SPT_SHORTEN_SBNUM]; + HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; + + kpos = 0; + j = 0; + move16(); + move16(); + FOR( k = sub( bands, SPT_SHORTEN_SBNUM ); k < bands; k++ ) + { + IF( EQ_16( p2a_flags[k], 1 ) ) + { + spt_shorten_flag[j] = 0; + move16(); + IF( hHQ_core->prev_SWB_peak_pos[kpos] != 0 ) + { + L_max_y2 = L_deposit_l( 0 ); + max_y2_pos = 0; + move16(); + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + IF( LT_32( L_max_y2, L_abs( L_t_audio[i] ) ) ) + { + L_max_y2 = L_abs( L_t_audio[i] ); + max_y2_pos = i; + move16(); + } + } + test(); + IF( GE_16( max_y2_pos, new_band_start[j] ) && LE_16( max_y2_pos, new_band_end[j] ) ) + { + band_start[k] = new_band_start[j]; + move16(); + band_end[k] = new_band_end[j]; + move16(); + band_width[k] = new_band_width[j]; + move16(); + spt_shorten_flag[j] = 1; + move16(); + } + } + push_indice( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); + *bit_budget = sub( *bit_budget, 1 ); + } + + kpos = add( kpos, 1 ); + j = add( j, 1 ); + } + + return; +} + +#endif + /*--------------------------------------------------------------------------* * hq_lr_enc_fx() * @@ -1064,142 +1166,1577 @@ void hq_lr_enc_fx( return; } -/*--------------------------------------------------------------------------* - * small_symbol_enc_tran() - * - * Huffman encoding of differential energies, estimating or packing bits - * if flag_pack = 0, LC mode info. is output else LC mode info. is input - * if flag_pack = 0, estimatng else packing bits - *--------------------------------------------------------------------------*/ - -static Word16 small_symbol_enc_tran_fx( /* o : bits */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack, /* i : indicator of packing or estimating bits */ - const Word16 is_transient ) +#ifdef IVAS_FLOAT_FIXED +void hq_lr_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 L_t_audio[], /* i/o: transform-domain coefs. */ + const Word16 inner_frame, /* i : inner frame length */ + Word16 *num_bits, /* i/o: number of available bits */ + const Word16 is_transient /* i : transient flag */ +) { - Word16 i, bits; - Word16 difidx[BANDS_MAX]; + Word16 i; + Word16 bit_budget, pbits; + Word16 bands, length, ni_seed, gqlevs, gqbits, Ngq, p2a_bands; + Word16 p2a_flags[BANDS_MAX]; + Word16 band_start[BANDS_MAX], band_end[BANDS_MAX], band_width[BANDS_MAX]; + Word32 L_band_energy[BANDS_MAX]; + Word16 ebits_fx; - FOR( i = 0; i < BANDS; i++ ) - { - difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); - move16(); - } + Word32 Rk_fx[BANDS_MAX]; + Word16 k1_step_fx, k2_step_fx; + Word16 k1_fx, k2_fx; - FOR( i = 0; i < BANDS; ++i ) + Word32 L_qint; /* Q29 */ + Word16 eref_fx; /* Q10 */ + Word16 bit_alloc_weight_fx; /* Q13 */ + Word16 k_sort[BANDS_MAX]; + Word16 npulses[BANDS_MAX]; + Word32 inp_vector[L_FRAME48k]; + + Word16 ld_slope_fx /*, Qldslope=15*/; + Word16 p2a_th_fx /*, Qp2ath=11*/; + Word16 pd_thresh_fx /*, Qpdth=15*/; + Word16 ni_coef_fx /*, Qnicoef=14*/; + + Word32 L_y2[L_FRAME48k]; + Word32 L_y2_ni[L_FRAME48k]; + + Word16 hqswb_clas; + Word16 lowlength; + Word16 highlength; + Word16 exp_norm; + Word32 L_m[L_FRAME32k]; + + Word16 har_bands; + + Word16 lowband, highband, bw_low = 0, bw_high = 20; + move16(); + move16(); + + Word32 bwe_br; + Word16 trans_bit, p2a_flags_tmp[BANDS_MAX]; + Word16 adjustFlag = 0; + move16(); + Word16 prev_SWB_peak_pos_tmp[SPT_SHORTEN_SBNUM]; + Word16 k, j; + Word16 flag_spt; + Word16 org_band_start[SPT_SHORTEN_SBNUM]; + Word16 org_band_end[SPT_SHORTEN_SBNUM]; + Word16 org_band_width[SPT_SHORTEN_SBNUM]; + Word16 new_band_start[SPT_SHORTEN_SBNUM]; + Word16 new_band_end[SPT_SHORTEN_SBNUM]; + Word16 new_band_width[SPT_SHORTEN_SBNUM]; + Word16 bws_cnt = 0; + move16(); + Word32 L_tmp, L_tmp2, L_tmp3; + Word16 exp, tmp, exp2, tmp1, tmp2, tmp3, alpha_fx, frac1; + Word32 enerH_fx; + Word32 enerL_fx; + Word32 Ep_fx[BANDS_MAX]; + Word32 Ep_avrg_fx, Ep_vari_fx; + Word32 Ep_avrgL_fx; + Word32 Ep_peak_fx; + Word32 Ep_tmp_fx[BANDS_MAX]; + Word16 gama_fx; /*Q15 0.85f; */ + Word16 beta_fx; /*Q14 1.05f; */ + Word32 L_band_energy_tmp[BANDS_MAX]; + UWord16 lo; + Word16 Q_band_energy; +#ifdef BASOP_NOGLOB + Flag Overflow; +#endif /* BASOP_NOGLOB */ + + BSTR_ENC_HANDLE hBstr = st->hBstr; + HQ_ENC_HANDLE hHQ_core = st->hHQ_core; + + + set32_fx( L_y2, 0x0L, L_FRAME48k ); + set32_fx( inp_vector, 0, inner_frame ); + flag_spt = 0; + move16(); + set16_fx( prev_SWB_peak_pos_tmp, 0, SPT_SHORTEN_SBNUM ); + adjustFlag = 0; + move16(); + bw_low = 0; + move16(); + bw_high = 20; + move16(); + enerL_fx = L_deposit_l( 0 ); + enerH_fx = L_deposit_l( 0 ); + + + bwe_br = st->core_brate; + hqswb_clas = HQ_NORMAL; + move16(); + + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) { - test(); - IF( GT_16( difidx[i], LRMDCT_BE_LIMIT ) || difidx[i] < 0 ) + IF( EQ_16( is_transient, 1 ) ) { - /* Huffman cannot encode this vector */ - return -1; + hqswb_clas = HQ_TRANSIENT; + move16(); + } + ELSE + { + hqswb_clas = peak_avrg_ratio_fx( st->total_brate, L_t_audio, NUMC_N, &hHQ_core->mode_count, &hHQ_core->mode_count1, SWB_BWE_LR_Qs ); } - } - /* Preparing lossless coding input */ - IF( flag_pack == 0 ) - { - /* estimating # of bits */ - bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + /* write the classification information into the bitstream */ + push_indice( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas, 2 ); + ( *num_bits ) = sub( *num_bits, 2 ); + move16(); + if ( EQ_16( hqswb_clas, HQ_NORMAL ) ) + { + flag_spt = 1; + move16(); + } } ELSE { - bits = 0; + /* write the transient bit into the bitstream */ + push_indice( st->hBstr, IND_HQ2_SWB_CLAS, is_transient, 1 ); + + /* subtract one bit for the transient flag */ + ( *num_bits ) = sub( *num_bits, 1 ); move16(); - encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ -} - + /* Configure encoder for different bandwidths, bitrates, etc. */ -/*--------------------------------------------------------------------------* - * small_symbol_enc() - * - * Huffman encoding of differential energies, estimating or packing bits - * if flag_pack = 0, LC mode info. is output else LC mode info. is input - * if flag_pack = 0, estimatng else packing bits - *--------------------------------------------------------------------------*/ + hq2_core_configure_fx( inner_frame, *num_bits, is_transient, &bands, &length, band_width, band_start, band_end, + &L_qint, &eref_fx, &bit_alloc_weight_fx, &gqlevs, &Ngq, &p2a_bands, &p2a_th_fx, &pd_thresh_fx, &ld_slope_fx, &ni_coef_fx, bwe_br ); -static Word16 small_symbol_enc_fx( /* o : bits */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack /* i : indicator of packing or estimating bits */ - , - const Word16 is_transient ) -{ - Word16 i, bits; - Word16 difidx[BANDS_MAX], LSB[BANDS_MAX]; - /* Preparing lossless coding input */ - difidx[0] = add( qbidx[0], DE_OFFSET0 ); + highlength = band_end[sub( bands, 1 )]; + move16(); + har_bands = bands; move16(); - FOR( i = 1; i < BANDS; ++i ) - { - difidx[i] = add( qbidx[i], DE_OFFSET1 ); - move16(); - } - FOR( i = 0; i < BANDS; ++i ) + test(); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && is_transient == 0 && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) { + /* reserve bits for HQ_NORMAL2 and HQ_HARMONIC modes */ test(); - IF( GE_16( difidx[i], DE_LIMIT ) || difidx[i] < 0 ) + IF( EQ_16( hqswb_clas, HQ_NORMAL ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) { - /* Huffman cannot encode this vector */ - return -1; + ( *num_bits ) = sub( *num_bits, get_usebit_npswb_fx( hqswb_clas ) ); + move16(); } } - /* splitting MSB and LSB */ - FOR( i = 0; i < BANDS; ++i ) + test(); + test(); + IF( ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) && EQ_16( st->bwidth, SWB ) ) { - LSB[i] = s_and( difidx[i], 1 ); - move16(); - difidx[i] = shr( difidx[i], 1 ); - move16(); + IF( NE_16( hHQ_core->prev_hqswb_clas, HQ_NORMAL ) ) + { + j = 0; + move16(); + FOR( k = sub( bands, SPT_SHORTEN_SBNUM ); k < bands; k++ ) + { + hHQ_core->prev_SWB_peak_pos[j] = 0; + move16(); + j = add( j, 1 ); + } + } } - /* Preparing lossless coding input */ - IF( flag_pack == 0 ) + test(); + IF( GT_16( inner_frame, length ) && is_transient ) { - /* estimating # of bits */ - /* Encoding MSB bits */ - bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + /* If so, collapse transient frame (4 short transforms) to remove uncoded coefficients */ - /* Encoding LSB bit packing */ + k1_step_fx = shr( length, 2 ); /* k1 = length/NUM_TIME_SWITCHING_BLOCKS */ + k2_step_fx = shr( inner_frame, 2 ); /* k2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS */ + k1_fx = k1_step_fx; + k2_fx = k2_step_fx; + move16(); + move16(); + FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + /*k1 = i*length/NUM_TIME_SWITCHING_BLOCKS; */ + /*k2 = i*inner_frame/NUM_TIME_SWITCHING_BLOCKS; */ + + Copy32( &L_t_audio[k2_fx], &L_t_audio[k1_fx], k1_step_fx ); + + k1_fx = add( k1_fx, k1_step_fx ); + k2_fx = add( k2_fx, k2_step_fx ); + } + } + + /* Spectral energy calculation/quantization */ + + ebits_fx = band_energy_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, L_band_energy, bands, + L_qint, eref_fx, is_transient ); + + /* First pass bit budget for TCQ of spectral band information */ + exp_norm = norm_s( gqlevs ); /* gqbits_fx = (short int) log2_f ((float) gqlevs_fx); */ + gqbits = sub( 14, exp_norm ); + + bit_budget = sub( sub( *num_bits, ebits_fx ), round_fx( L_shl( L_mult( Ngq, gqbits ), 15 ) ) ); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; */ + + + pbits = 0; + move16(); + + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) + { + IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + set16_fx( p2a_flags, 1, har_bands ); + } + ELSE + { + /* High band tonality detector based on per band peak-to-average ratio */ + pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); + bit_budget = sub( bit_budget, pbits ); + + IF( EQ_16( hqswb_clas, HQ_NORMAL ) ) + { + return_bits_normal2_fx( &bit_budget, p2a_flags, bands, bits_lagIndices_modeNormal ); + } + } + } + ELSE + { + /* High band tonality detector based on per band peak-to-average ratio */ + pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); + bit_budget = sub( bit_budget, pbits ); + } + + IF( EQ_16( flag_spt, 1 ) ) + { + /* initialize the desired parameters for SPT */ + spt_shorten_domain_band_save_fx( bands, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width ); + spt_shorten_domain_pre_fx( band_start, band_end, hHQ_core->prev_SWB_peak_pos, bands, bwe_br, new_band_start, new_band_end, new_band_width ); + spt_shorten_domain_set_ivas_fx( st, L_t_audio, p2a_flags, new_band_start, new_band_end, new_band_width, bands, band_start, band_end, band_width, &bit_budget ); + } + +#define WMC_TOOL_SKIP + /* Estimate number of bits per band */ + Q_band_energy = SWB_BWE_LR_Qbe; + move16(); + FOR( i = 0; i < bands; i++ ) + { + L_tmp = L_shl( L_band_energy[i], sub( 16, Q_band_energy ) ); /*Q16 */ + + frac1 = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ + L_tmp = Pow2( 30, frac1 ); + exp = sub( exp, 30 ); + Ep_fx[i] = L_shl( L_tmp, sub( exp, 6 ) ); /* Q -6 */ + } + + FOR( i = 0; i < bands; i++ ) + { + L_tmp2 = Ep_fx[i]; + L_tmp = L_max( 1, L_tmp2 ); + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + + L_tmp3 = (Word32) band_width[i]; + exp2 = norm_l( L_tmp3 ); + tmp2 = extract_h( L_shl( L_tmp3, exp2 ) ); + + exp2 = sub( exp, exp2 ); /* Denormalize and substract */ + + tmp3 = sub( tmp2, tmp ); + IF( tmp3 > 0 ) + { + tmp2 = shr( tmp2, 1 ); + } + IF( tmp3 > 0 ) + { + exp2 = add( exp2, 1 ); + } + tmp = div_s( tmp2, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc1( L_tmp, &exp2 ); + move32(); /*Q(31-exp2) */ + Ep_tmp_fx[i] = L_shr( L_tmp, sub( 15, exp2 ) ); /*Q13 */ + } +#undef WMC_TOOL_SKIP + + test(); + test(); + test(); + test(); + test(); + test(); + IF( is_transient == 0 && EQ_16( inner_frame, L_FRAME8k ) && LE_32( st->core_brate, ACELP_13k20 ) ) + { +#define WMC_TOOL_SKIP + lowband = 6; + move16(); + trans_bit = 2; + move16(); + bit_budget = sub( bit_budget, trans_bit ); + gama_fx = 27852; /*Q15 0.85f; */ + beta_fx = 17203; + move16(); + move16(); /*Q14 1.05f; */ + set_s( &p2a_flags_tmp[bands - trans_bit], 0, 2 ); + + IF( EQ_32( st->core_brate, ACELP_13k20 ) ) + { + beta_fx = 13107; + move16(); /*14 1.25f; */ + gama_fx = 31130; + move16(); /*0.95f; */ + mvs2s( &p2a_flags[sub( bands, trans_bit )], &p2a_flags_tmp[sub( bands, trans_bit )], trans_bit ); + } + + /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ + Ep_vari_fx = 0; + move32(); + Ep_avrg_fx = 0; + move32(); + Ep_avrgL_fx = 0; + move32(); + Ep_peak_fx = 0; + move32(); + FOR( i = 0; i < bands; i++ ) + { + IF( sub( i, lowband ) >= 0 ) + { + Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ + } + ELSE + { +#ifdef BASOP_NOGLOB + Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#else + Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ +#endif + IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) + { + Ep_peak_fx = Ep_tmp_fx[i]; + move32(); /*Q15 */ + } + } + } + /* modify the last p2a_bands subbands band_energies */ + k = bands; + mvl2l( L_band_energy, L_band_energy_tmp, k ); /*Q_band_energy */ + Mpy_32_16_ss( Ep_peak_fx, 24576, &L_tmp, &lo ); + Mpy_32_16_ss( Ep_peak_fx, shl( sub( bands, lowband ), 9 ), &L_tmp2, &lo ); + Mpy_32_16_ss( Ep_avrg_fx, 1126, &L_tmp3, &lo ); + + IF( ( ( L_sub( L_tmp, L_shr( Ep_avrgL_fx, 1 ) ) < 0 && st->core_brate == ACELP_13k20 ) || st->core_brate < ACELP_13k20 ) && + L_sub( L_tmp2, L_tmp3 ) < 0 && L_sub( L_tmp2, L_shr( Ep_avrg_fx, 7 ) ) > 0 ) + { + FOR( i = lowband; i < bands; i++ ) + { + Mpy_32_16_ss( Ep_avrg_fx, 24576, &L_tmp, &lo ); + IF( L_sub( L_shr( Ep_tmp_fx[i], 1 ), L_tmp ) < 0 ) + { + Mpy_32_16_ss( Ep_peak_fx, sub( bands, lowband ), &L_tmp, &lo ); + tmp = extract_h( L_shl( L_tmp, 14 ) ); /*Q-4 */ + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 13, exp ) ); /*Q(13+exp-15 +13-exp +4 = 15) */ + L_tmp2 = L_add( L_tmp, 13107 ); /*15 */ + tmp2 = extract_l( L_min( L_max( L_tmp2, 16384 ), gama_fx ) ); /*15 = 15 */ + Mpy_32_16_ss( L_band_energy_tmp[i], tmp2, &L_band_energy_tmp[i], &lo ); + } + } + } + ELSE + { + j = 0; + move16(); + FOR( i = sub( bands, trans_bit ); i < bands; i++ ) + { + alpha_fx = 16384; + move16(); /*Q14 */ + IF( sub( p2a_flags_tmp[i], 1 ) == 0 ) + { + Mpy_32_16_ss( Ep_tmp_fx[i], sub( bands, lowband ), &L_tmp, &lo ); + tmp = extract_h( L_shl( L_tmp, 14 ) ); /*Q-4 */ + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_vari_fx, 3277, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, tmp, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 12, exp ) ); /*Q(13+exp-15 +12-exp +4 = 14) */ + + tmp2 = extract_h( Ep_avrg_fx ); /*Q13-16=-3 */ + IF( tmp2 != 0 ) + { + exp = norm_s( tmp2 ); + tmp2 = shl( tmp2, exp ); /*Q(exp) */ + tmp2 = div_s( 16384, tmp2 ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp2 = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_vari_fx, 6554, &L_tmp2, &lo ); + Mpy_32_16_ss( L_tmp2, tmp2, &L_tmp2, &lo ); + L_tmp2 = L_shl( L_tmp2, sub( 13, exp ) ); /*Q(13+exp-15 +13-exp +3 = 14) */ + L_tmp = L_min( L_tmp, L_tmp2 ); /*14 */ + tmp = extract_l( L_min( L_tmp, 13107 ) ); /*14 */ + alpha_fx = add( 16384, tmp ); + } + IF( sub( hHQ_core->last_bitalloc_max_band[j++], 1 ) == 0 ) + { + Mpy_32_16_ss( Ep_tmp_fx[i], sub( bands, lowband ), &L_tmp, &lo ); + tmp = extract_h( L_shl( L_tmp, 14 ) ); /*Q-2 */ + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#else /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#endif /* BASOP_NOGLOB */ + } + ELSE + { + tmp2 = extract_h( Ep_avrg_fx ); /*13 -16 =-3 */ + IF( tmp2 != 0 ) + { + exp = norm_s( tmp2 ); + tmp2 = shl( tmp2, exp ); /*Q(exp) */ + tmp2 = div_s( 16384, tmp2 ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp2 = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_tmp_fx[i], tmp2, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 19, exp ) ); /*Q(13+exp-15 +19-exp +3 = 20) */ + Mpy_32_16_ss( L_tmp, shl( sub( bands, lowband ), 9 ), &L_tmp, &lo ); + L_tmp = L_max( L_tmp, 13926 ); /*14 */ + tmp2 = extract_l( L_min( L_tmp, 16384 ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp2 ), 1 ); /*14+14-15+1 =14 */ + } + Mpy_32_16_ss( L_band_energy_tmp[i], alpha_fx, &L_tmp, &lo ); + L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q(Q_band_energy+14-15 +1= Q_band_energy) */ + } + } + lowband = 3; + move16(); + Ep_avrg_fx = 0; + move32(); + Ep_avrgL_fx = 0; + move32(); + Ep_peak_fx = 0; + move32(); + FOR( i = 0; i < bands; i++ ) + { + IF( sub( i, lowband ) >= 0 ) + { +#ifdef BASOP_NOGLOB + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#else + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#endif + } + ELSE + { + Ep_avrgL_fx = L_add( Ep_avrgL_fx, L_shr( Ep_tmp_fx[i], 1 ) ); /*Q12 */ + IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) + { + Ep_peak_fx = Ep_tmp_fx[i]; + move32(); /*Q13 */ + } + } + } + Mpy_32_16_ss( Ep_peak_fx, 28262, &L_tmp, &lo ); + Mpy_32_16_ss( Ep_avrgL_fx, 24576, &L_tmp2, &lo ); + IF( L_sub( L_shr( Ep_avrg_fx, 2 ), L_tmp2 ) > 0 && L_sub( L_shr( Ep_avrg_fx, 4 ), L_tmp2 ) < 0 && L_sub( L_tmp, Ep_avrgL_fx ) > 0 ) + { + adjustFlag = 1; + move16(); + FOR( i = 0; i < lowband; i++ ) + { + tmp = extract_h( Ep_avrgL_fx ); /*Q-4 */ + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_peak_fx, tmp, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, lowband, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, 18842, &L_tmp, &lo ); +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 27, exp ) ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#else /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#endif /* BASOP_NOGLOB */ + Mpy_32_16_ss( L_band_energy_tmp[i], tmp2, &L_tmp, &lo ); + L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ + } + } +#undef WMC_TOOL_SKIP + + + hq2_bit_alloc_fx( L_band_energy_tmp, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); + + /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ + FOR( i = 0; i < 2; i++ ) + { + push_indice( hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + } + } + ELSE IF( is_transient == 0 && EQ_16( inner_frame, L_FRAME16k ) ) + { +#define WMC_TOOL_SKIP + bit_budget = sub( bit_budget, 2 ); /* bits in high bands to indicate the last 2 subbands is allocated bits or not */ + FOR( i = 0; i < bands; i++ ) + { +#ifndef BASOP_NOGLOB + Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); +#else /* BASOP_NOGLOB */ + Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); + move32(); +#endif /* BASOP_NOGLOB */ + } + IF( EQ_32( st->core_brate, ACELP_13k20 ) ) + { + lowband = 8; + move16(); + highband = 15; + move16(); + bw_low = sub( band_start[highband], band_start[lowband] ); + bw_high = sub( add( band_end[sub( bands, 1 )], 1 ), band_start[highband] ); + } + ELSE + { + lowband = 8; + move16(); + highband = 16; + move16(); + bw_low = sub( band_start[highband], band_start[lowband] ); + bw_high = sub( add( band_end[sub( bands, 1 )], 1 ), band_start[highband] ); + } + /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ + enerL_fx = 0; + move32(); + enerH_fx = 0; + move32(); + Ep_vari_fx = 0; + move32(); + Ep_avrg_fx = 0; + move32(); + FOR( i = 0; i < bands; i++ ) + { + IF( sub( i, lowband ) >= 0 && add( sub( i, bands ), p2a_bands ) < 0 ) + { + Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ +#ifndef BASOP_NOGLOB + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ + } + + IF( sub( i, highband ) >= 0 ) + { + enerH_fx = L_add( enerH_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ + } + ELSE IF( sub( i, lowband ) >= 0 ) + { + enerL_fx = L_add( enerL_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ + } + } + /* modify the last p2a_bands subbands band_energies */ + k = bands; + mvl2l( L_band_energy, L_band_energy_tmp, k ); /*Q_band_energy */ + + L_tmp = L_max( enerH_fx, enerL_fx ); + tmp = s_max( bw_low, bw_high ); + i = norm_l( L_tmp ); + j = norm_s( tmp ); + Mpy_32_16_ss( L_shl( enerH_fx, i ), shl( bw_low, j ), &L_tmp, &lo ); + Mpy_32_16_ss( L_shl( enerL_fx, i ), shl( bw_high, j ), &L_tmp2, &lo ); + L_tmp2 = L_sub( L_tmp, L_tmp2 ); + + FOR( i = sub( bands, p2a_bands ); i < bands; i++ ) + { + test(); + IF( sub( p2a_flags[i], 1 ) == 0 || L_tmp2 > 0 ) + { + tmp = sub( bands, p2a_bands ); + tmp = sub( tmp, lowband ); /*Q0 */ + +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif + IF( tmp1 != 0 ) + { + exp = norm_s( tmp1 ); + tmp1 = shl( tmp1, exp ); /*Q(exp) */ + tmp1 = div_s( 16384, tmp1 ); /*Q(15+14-exp = 29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp1 = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_tmp_fx[i], tmp1, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, tmp, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, 16384, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 32, exp ) ); /*Q15 */ + tmp = extract_l( L_min( L_tmp, 6554 ) ); /*Q15 */ + Mpy_32_16_ss( Ep_vari_fx, tmp1, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, tmp, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 15, exp ) ); /*Q15 */ + tmp = extract_l( L_shr( L_min( L_tmp, 13107 ), 1 ) ); /*Q14 */ + alpha_fx = add( tmp, 16384 ); /*Q14 */ + } + ELSE + { + alpha_fx = 16384; + move16(); /*Q14 */ + } + + IF( add( sub( i, bands ), p2a_bands ) > 0 ) + { + tmp = sub( bands, p2a_bands ); + IF( sub( hHQ_core->last_bitalloc_max_band[sub( i, add( tmp, 1 ) )], 1 ) == 0 ) + { + tmp = sub( tmp, lowband ); + Mpy_32_16_ss( Ep_tmp_fx[i], tmp, &L_tmp, &lo ); +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( L_tmp, 16 ) ); /*Q0 */ +#else /* BASOP_NOGLOB */ + tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ +#endif /* BASOP_NOGLOB */ + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q14 */ + tmp = extract_l( L_min( L_max( L_tmp, 16384 ), 20480 ) ); /*Q14 */ + L_tmp = L_mult( alpha_fx, tmp ); /*Q(14+14+1=29) */ + alpha_fx = extract_l( L_shr( L_tmp, 15 ) ); /*Q14*/ + } + ELSE + { + tmp = sub( tmp, lowband ); + +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif + IF( tmp1 != 0 ) + { + exp = norm_s( tmp1 ); + tmp1 = shl( tmp1, exp ); /*Q(exp) */ + tmp1 = div_s( 16384, tmp1 ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp1 = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_tmp_fx[i], tmp1, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, tmp, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 29, exp ) ); /*Q14 */ + tmp = extract_l( L_min( L_max( L_tmp, 13926 ), 16384 ) ); /*Q14 */ + L_tmp = L_mult( alpha_fx, tmp ); /*Q(14+14+1=29) */ + alpha_fx = extract_l( L_shr( L_tmp, 15 ) ); /*Q14 */ + } + } + Mpy_32_16_ss( L_band_energy_tmp[i], alpha_fx, &L_tmp, &lo ); + L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q Q_band_energy */ + } + lowband = 6; + move16(); + Ep_avrg_fx = 0; + move32(); + Ep_avrgL_fx = 0; + move32(); + Ep_peak_fx = 0; + move32(); + FOR( i = 0; i < bands; i++ ) + { + IF( sub( i, lowband ) >= 0 ) + { +#ifndef BASOP_NOGLOB + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ + } + ELSE + { +#ifndef BASOP_NOGLOB + Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ + IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) + { + Ep_peak_fx = Ep_tmp_fx[i]; + move32(); /*Q15 */ + } + } + } + + Mpy_32_16_ss( Ep_peak_fx, 24576, &L_tmp, &lo ); + Mpy_32_16_ss( Ep_peak_fx, 19661, &L_tmp2, &lo ); + Mpy_32_16_ss( Ep_avrgL_fx, 24576, &L_tmp3, &lo ); + + test(); + test(); + test(); + test(); + test(); + IF( ( L_sub( L_shr( Ep_avrgL_fx, 1 ), Ep_avrg_fx ) > 0 && L_sub( L_tmp, L_shr( Ep_avrgL_fx, 2 ) ) > 0 && L_sub( L_shr( Ep_avrgL_fx, 1 ), L_tmp2 ) < 0 ) || + ( L_sub( L_shr( Ep_avrg_fx, 1 ), Ep_avrgL_fx ) > 0 && L_sub( L_shr( Ep_avrg_fx, 3 ), L_tmp3 ) < 0 && L_sub( L_tmp, L_shr( Ep_avrgL_fx, 2 ) ) > 0 ) ) + { + adjustFlag = 1; + move16(); + FOR( i = 0; i < lowband; i++ ) + { +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( Ep_avrgL_fx, 1 ) ); /*Q0 */ +#else + tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ +#endif + IF( tmp != 0 ) + { + exp = norm_s( tmp ); + tmp = shl( tmp, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp=29-exp) */ + exp = sub( 29, exp ); + } + ELSE + { + tmp = 0x7fff; + move16(); + exp = 0; + move16(); + } + Mpy_32_16_ss( Ep_peak_fx, tmp, &L_tmp, &lo ); + Mpy_32_16_ss( L_tmp, lowband, &L_tmp, &lo ); + L_tmp = L_shl( L_tmp, sub( 28, exp ) ); /*Q14 0.5 */ + tmp = extract_l( L_min( L_tmp, 19661 ) ); /*Q14 */ + Mpy_32_16_ss( L_band_energy_tmp[i], tmp, &L_tmp, &lo ); + L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ + } + } +#undef WMC_TOOL_SKIP + + hq2_bit_alloc_fx( L_band_energy_tmp, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); + + /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ + FOR( i = 0; i < 2; i++ ) + { + push_indice( hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + } + } + ELSE IF( EQ_16( st->bwidth, SWB ) && EQ_16( hqswb_clas, HQ_HARMONIC ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) + { + /* bit allocation for harmonic mode */ + hq2_bit_alloc_har_fx( L_band_energy, bit_budget, bands, Rk_fx, p2a_bands, bwe_br, p2a_flags, band_width ); + } + ELSE + { + + /* estimate number of bits per band */ + hq2_bit_alloc_fx( L_band_energy, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); + } + + tcq_core_LR_enc_ivas_fx( hBstr, inp_vector, L_t_audio, L_y2, bit_budget, bands, band_start, band_end, band_width, Rk_fx, npulses, k_sort, p2a_flags, p2a_bands, hHQ_core->last_bitalloc_max_band, inner_frame, adjustFlag, is_transient ); + + test(); + test(); + IF( ( EQ_16( inner_frame, L_FRAME8k ) && LE_32( st->core_brate, ACELP_13k20 ) ) || EQ_16( inner_frame, L_FRAME16k ) ) + { + j = 0; + FOR( i = 2; i > 0; i-- ) + { + IF( npulses[bands - i] > 0 ) + { + hHQ_core->last_bitalloc_max_band[j] = 1; + move16(); + } + ELSE + { + hHQ_core->last_bitalloc_max_band[j] = 0; + move16(); + } + j++; + } + } + + /* Denormalize the coded MDCT spectrum */ + mdct_spectrum_denorm_ivas_fx( inp_vector, L_y2, band_start, band_end, band_width, L_band_energy, npulses, bands, ld_slope_fx, pd_thresh_fx ); + + /* Apply fine gain quantization to denormalized coded spectrum */ + mdct_spectrum_fine_gain_enc_ivas_fx( st, L_t_audio, L_y2, band_start, band_end, k_sort, bands, L_qint, Ngq, gqlevs, gqbits ); + + /* reStore the subband information*/ + IF( EQ_16( flag_spt, 1 ) ) + { + spt_shorten_domain_band_restore_fx( bands, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width ); + } + + /* Inject noise into components having relatively low pulse energy per band */ + ni_seed = add( add( add( npulses[0], npulses[1] ), npulses[2] ), npulses[3] ); + + Copy32( L_y2, L_y2_ni, band_end[bands - 1] + 1 ); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) + { + test(); + IF( EQ_16( hqswb_clas, HQ_NORMAL ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + preset_hq2_swb_fx( hqswb_clas, band_end, &har_bands, p2a_bands, length, bands, &lowlength, &highlength, L_m ); + + swb_bwe_enc_lr_ivas_fx( st, L_y2, SWB_BWE_LR_Qs, L_t_audio, L_m, bwe_br, + bands, band_start, band_end, L_band_energy, SWB_BWE_LR_Qbe, p2a_flags, hqswb_clas, lowlength, highlength, + hHQ_core->prev_frm_index, har_bands, &hHQ_core->prev_frm_hfe2, &hHQ_core->prev_stab_hfe2, band_width, L_y2_ni, &ni_seed ); + + post_hq2_swb_fx( L_m, lowlength, highlength, hqswb_clas, har_bands, bands, p2a_flags, band_start, band_end, L_y2, npulses ); + + IF( EQ_16( hqswb_clas, HQ_NORMAL ) ) + { + spt_swb_peakpos_tmp_save_fx( L_y2, bands, band_start, band_end, prev_SWB_peak_pos_tmp ); + FOR( k = 0; k < SPT_SHORTEN_SBNUM; k++ ) + { + test(); + IF( p2a_flags[bands - SPT_SHORTEN_SBNUM + k] == 0 || npulses[bands - SPT_SHORTEN_SBNUM + k] == 0 ) + { + prev_SWB_peak_pos_tmp[k] = 0; + move16(); + } + } + } + Copy32( L_y2_ni, L_y2, lowlength ); + } + ELSE + { + Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* HQ_TRANSIENT */ + } + } + ELSE + { + Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* NB, WB */ + } + + updat_prev_frm_fx( L_y2, L_t_audio, bwe_br, length, inner_frame, bands, st->bwidth, is_transient, hqswb_clas, &hHQ_core->prev_hqswb_clas, hHQ_core->prev_SWB_peak_pos, prev_SWB_peak_pos_tmp, &hHQ_core->prev_frm_hfe2, &hHQ_core->prev_stab_hfe2, bws_cnt ); + + IF( NE_16( st->bwidth, SWB ) ) + { + /* reset HQ classifier memories */ + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + } + + + test(); + test(); + test(); + IF( NE_16( hqswb_clas, HQ_HARMONIC ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) && EQ_16( st->bwidth, SWB ) ) + { + hHQ_core->prev_frm_index[0] = -1; + move16(); + hHQ_core->prev_frm_index[1] = -1; + move16(); + } + + /* update number of unused bits */ + *num_bits = 0; + move16(); + + hHQ_core->hvq_hangover = 0; + move16(); + + return; +} +#endif + + +/*--------------------------------------------------------------------------* + * small_symbol_enc_tran() + * + * Huffman encoding of differential energies, estimating or packing bits + * if flag_pack = 0, LC mode info. is output else LC mode info. is input + * if flag_pack = 0, estimatng else packing bits + *--------------------------------------------------------------------------*/ + +static Word16 small_symbol_enc_tran_fx( /* o : bits */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + const Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode, /* i/o: LC mode info */ + const Word16 flag_pack, /* i : indicator of packing or estimating bits */ + const Word16 is_transient ) +{ + Word16 i, bits; + Word16 difidx[BANDS_MAX]; + + FOR( i = 0; i < BANDS; i++ ) + { + difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); + move16(); + } + + FOR( i = 0; i < BANDS; ++i ) + { + test(); + IF( GT_16( difidx[i], LRMDCT_BE_LIMIT ) || difidx[i] < 0 ) + { + /* Huffman cannot encode this vector */ + return -1; + } + } + + /* Preparing lossless coding input */ + IF( flag_pack == 0 ) + { + /* estimating # of bits */ + bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + } + ELSE + { + bits = 0; + move16(); + encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); + } + + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ +} + + +#ifdef IVAS_FLOAT_FIXED + +static Word16 small_symbol_enc_tran_ivas_fx( /* o : bits */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + const Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode, /* i/o: LC mode info */ + const Word16 flag_pack, /* i : indicator of packing or estimating bits */ + const Word16 is_transient ) +{ + Word16 i, bits; + Word16 difidx[BANDS_MAX]; + + FOR( i = 0; i < BANDS; i++ ) + { + difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); + move16(); + } + + FOR( i = 0; i < BANDS; ++i ) + { + test(); + IF( GT_16( difidx[i], LRMDCT_BE_LIMIT ) || difidx[i] < 0 ) + { + /* Huffman cannot encode this vector */ + return -1; + } + } + + /* Preparing lossless coding input */ + IF( flag_pack == 0 ) + { + /* estimating # of bits */ + bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + } + ELSE + { + bits = 0; + move16(); + encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); + } + + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ +} + +#endif + +/*--------------------------------------------------------------------------* + * small_symbol_enc() + * + * Huffman encoding of differential energies, estimating or packing bits + * if flag_pack = 0, LC mode info. is output else LC mode info. is input + * if flag_pack = 0, estimatng else packing bits + *--------------------------------------------------------------------------*/ + +static Word16 small_symbol_enc_fx( /* o : bits */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + const Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode, /* i/o: LC mode info */ + const Word16 flag_pack /* i : indicator of packing or estimating bits */ + , + const Word16 is_transient ) +{ + Word16 i, bits; + Word16 difidx[BANDS_MAX], LSB[BANDS_MAX]; + + /* Preparing lossless coding input */ + difidx[0] = add( qbidx[0], DE_OFFSET0 ); + move16(); + + FOR( i = 1; i < BANDS; ++i ) + { + difidx[i] = add( qbidx[i], DE_OFFSET1 ); + move16(); + } + + FOR( i = 0; i < BANDS; ++i ) + { + test(); + IF( GE_16( difidx[i], DE_LIMIT ) || difidx[i] < 0 ) + { + /* Huffman cannot encode this vector */ + return -1; + } + } + + /* splitting MSB and LSB */ + FOR( i = 0; i < BANDS; ++i ) + { + LSB[i] = s_and( difidx[i], 1 ); + move16(); + difidx[i] = shr( difidx[i], 1 ); + move16(); + } + + /* Preparing lossless coding input */ + IF( flag_pack == 0 ) + { + /* estimating # of bits */ + /* Encoding MSB bits */ + bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + + /* Encoding LSB bit packing */ + bits = add( bits, BANDS ); + } + ELSE + { + /* Encoding MSB bits */ + bits = 0; + move16(); + encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); + + /* Encoding LSB bit packing */ + FOR( i = 0; i < BANDS; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); + } + } + + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ +} + +#ifdef IVAS_FLOAT_FIXED +static Word16 small_symbol_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode, /* i/o: LC mode info */ + const Word16 flag_pack, /* i : indicator of packing or estimating bits */ + const Word16 is_transient ) +{ + Word16 i, bits; + Word16 difidx[BANDS_MAX], LSB[BANDS_MAX]; + + /* Preparing lossless coding input */ + difidx[0] = add( qbidx[0], DE_OFFSET0 ); + move16(); + + FOR( i = 1; i < BANDS; ++i ) + { + difidx[i] = add( qbidx[i], DE_OFFSET1 ); + move16(); + } + + FOR( i = 0; i < BANDS; ++i ) + { + test(); + IF( GE_16( difidx[i], DE_LIMIT ) || difidx[i] < 0 ) + { + /* Huffman cannot encode this vector */ + return -1; + } + } + + /* splitting MSB and LSB */ + FOR( i = 0; i < BANDS; ++i ) + { + LSB[i] = s_and( difidx[i], 1 ); + move16(); + difidx[i] = shr( difidx[i], 1 ); + move16(); + } + + /* Preparing lossless coding input */ + IF( flag_pack == 0 ) + { + /* estimating # of bits */ + /* Encoding MSB bits */ + bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + + /* Encoding LSB bit packing */ bits = add( bits, BANDS ); } ELSE { /* Encoding MSB bits */ - bits = 0; - move16(); - encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); + bits = 0; + move16(); + encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); + + /* Encoding LSB bit packing */ + FOR( i = 0; i < BANDS; ++i ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); + } + } + + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ +} + +#endif + +static Word16 large_symbol_enc_fx( /* o : bits */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode0, /* i/o: LC mode info */ + const Word16 flag_pack /* i : indicator of packing or estimating bits */ +) +{ + Word16 i, bits, tmp; + Word16 LSB1[BANDS_MAX]; + Word16 min_q, max_q, offset0; + Word16 min_bits, min_bits_pos; + Word16 tdifidx0[BANDS_MAX], tdifidx1[BANDS_MAX]; + Word16 basic_shift; + Word16 bitsmode0, bitsmode1; + Word16 lsbdepth1; + Word16 cnt_outlyer, pos_outlyer, cnt_outlyer0; + + min_q = 513; + move16(); + max_q = -1; + move16(); + + cnt_outlyer0 = 0; + move16(); + cnt_outlyer = 0; + move16(); + bitsmode0 = 0; + move16(); + bitsmode1 = 0; + move16(); + pos_outlyer = 0; + move16(); + lsbdepth1 = 0; + move16(); + + test(); + test(); + IF( flag_pack == 0 || ( EQ_16( flag_pack, 1 ) && *hLCmode0 == 0 ) ) + { + test(); + test(); + IF( GT_16( qbidx[0], sub( ABS_ENG_OFFSET, 1 ) ) || LT_16( qbidx[0], -ABS_ENG_OFFSET ) ) + { + cnt_outlyer0 = 2; + move16(); + } + ELSE IF( GT_16( qbidx[0], 3 ) || LT_16( qbidx[0], -4 ) ) + { + cnt_outlyer0 = 1; + move16(); + } + ELSE + { + cnt_outlyer0 = 0; + move16(); + } + + cnt_outlyer = 0; + move16(); + pos_outlyer = -1; + move16(); + FOR( i = 1; i < BANDS; ++i ) + { + test(); + IF( GT_16( qbidx[i], 3 ) || LT_16( qbidx[i], -4 ) ) + { + cnt_outlyer = add( cnt_outlyer, 1 ); + pos_outlyer = i; + move16(); + } + + test(); + if ( GT_16( qbidx[i], sub( ABS_ENG_OFFSET, 1 ) ) || LT_16( qbidx[i], -ABS_ENG_OFFSET ) ) + { + cnt_outlyer = add( cnt_outlyer, 1 ); + } + } + + test(); + test(); + IF( cnt_outlyer0 == 0 && LE_16( cnt_outlyer, 1 ) ) + { + bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); + IF( EQ_16( cnt_outlyer, 1 ) ) + { + /* 01 */ + bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + } + + FOR( i = 0; i < pos_outlyer; ++i ) + { + tdifidx0[i] = qbidx[i]; + move16(); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } + + FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + { + tdifidx0[i] = qbidx[i]; + move16(); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } + } + ELSE IF( EQ_16( cnt_outlyer0, 1 ) && LE_16( cnt_outlyer, 1 ) ) + { + bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); + tdifidx0[0] = qbidx[0]; + move16(); + bitsmode0 = add( bitsmode0, BITS_ABS_ENG ); + IF( EQ_16( cnt_outlyer, 1 ) ) + { + /* 11 */ + bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + } + ELSE + { + pos_outlyer = 0; + move16(); + } + + FOR( i = 1; i < pos_outlyer; ++i ) + { + tdifidx0[i] = qbidx[i]; + move16(); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } + + FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + { + tdifidx0[i] = qbidx[i]; + move16(); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } + } + ELSE + { + bitsmode0 = 20000; + move16(); + } + } + + test(); + IF( flag_pack == 0 || EQ_16( *hLCmode0, 1 ) ) + { + /* components 0 range : -256~255 */ + max_q = MINIMUM_ENERGY_LOWBRATE; + move16(); + min_q = MAXIMUM_ENERGY_LOWBRATE; + move16(); + FOR( i = 0; i < BANDS; ++i ) + { + max_q = s_max( qbidx[i], max_q ); + min_q = s_min( qbidx[i], min_q ); + } + + /* Counting bits for transmitting all components using same method */ + FOR( i = 0;; ++i ) + { + /*if (max_q <= ((2<<(i+1))-1) && min_q >= -(2<<(i+1))) */ + test(); + IF( LE_16( max_q, sub( shl( 2, add( i, 1 ) ), 1 ) ) && GE_16( min_q, -shl( 2, add( i, 1 ) ) ) ) + { + BREAK; + } + } + basic_shift = i; + move16(); + + min_bits = 1000; + move16(); + min_bits_pos = basic_shift; + move16(); + tmp = add( basic_shift, 3 ); + FOR( offset0 = basic_shift; offset0 < tmp; offset0++ ) + { + max_q = MINIMUM_ENERGY_LOWBRATE; + move16(); + min_q = MAXIMUM_ENERGY_LOWBRATE; + move16(); + + bitsmode1 = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + FOR( i = 0; i < BANDS; ++i ) + { + bitsmode1 = add( bitsmode1, add( hessize[add( shr( qbidx[i], offset0 ), 4 )], offset0 ) ); + } + + IF( GT_16( min_bits, bitsmode1 ) ) + { + min_bits_pos = offset0; + move16(); + min_bits = bitsmode1; + move16(); + } + } + + bitsmode1 = min_bits; + move16(); + lsbdepth1 = min_bits_pos; + move16(); + + FOR( i = 0; i < BANDS; ++i ) + { + LSB1[i] = s_and( qbidx[i], sub( shl( 1, lsbdepth1 ), 1 ) ); + tdifidx1[i] = shr( qbidx[i], lsbdepth1 ); + } + } + + /* Preparing lossless coding input */ + IF( flag_pack == 0 ) + { + /* estimating # of bits */ + /* Encoding MSB bits */ + IF( LT_16( bitsmode0, bitsmode1 ) ) + { + bits = bitsmode0; + move16(); + *hLCmode0 = 0; + move16(); + } + ELSE + { + bits = bitsmode1; + move16(); + *hLCmode0 = 1; + move16(); + } + } + ELSE + { + /* Encoding MSB bits */ + IF( *hLCmode0 == 0 ) + { + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); + bits = BITS_DE_8SMODE; + move16(); + IF( cnt_outlyer0 == 0 ) + { + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); + bits = add( bits, BITS_DE_8SMODE_N0 ); + IF( EQ_16( cnt_outlyer, 1 ) ) + { + /* 01 */ + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); + push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + bits = add( bits, BITS_DE_8SPOS ); + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); + } + ELSE + { + /* 00 */ + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); + } + + FOR( i = 0; i < pos_outlyer; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } - /* Encoding LSB bit packing */ - FOR( i = 0; i < BANDS; ++i ) + FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + } + } + ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) + { + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); + bits = add( bits, BITS_DE_8SMODE_N0 ); + IF( EQ_16( cnt_outlyer, 1 ) ) + { + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); + push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + bits = add( bits, BITS_DE_8SPOS ); + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); + } + ELSE + { + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); + } + + FOR( i = 1; i < pos_outlyer; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); + } + + FOR( i = pos_outlyer + 1; i < BANDS; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); + } + } + } + ELSE { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); + bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); + push_indice_fx( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); + + FOR( i = 0; i < BANDS; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); + bits = add( bits, hessize[tdifidx1[i] + 4] ); + } + + IF( lsbdepth1 > 0 ) + { + FOR( i = 0; i < BANDS; ++i ) + { + push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); + } + /*bits += BANDS * lsbdepth1; */ + bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); + } } } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ + return bits; /* xx bits for diff. energies + 1 bit for LC coding mode */ } -static Word16 large_symbol_enc_fx( /* o : bits */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode0, /* i/o: LC mode info */ - const Word16 flag_pack /* i : indicator of packing or estimating bits */ + +#ifdef IVAS_FLOAT_FIXED +static Word16 large_symbol_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *qbidx, /* i : input of dequantized differential energy */ + const Word16 BANDS, /* i : number of bands */ + Word16 *hLCmode0, /* i/o: LC mode info */ + const Word16 flag_pack /* i : indicator of packing or estimating bits */ ) { Word16 i, bits, tmp; @@ -1427,129 +2964,320 @@ static Word16 large_symbol_enc_fx( /* o : bits /* Encoding MSB bits */ IF( *hLCmode0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); bits = BITS_DE_8SMODE; move16(); IF( cnt_outlyer0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 01 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { /* 00 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); } FOR( i = 0; i < pos_outlyer; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); } FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } - FOR( i = 1; i < pos_outlyer; ++i ) - { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); - } + FOR( i = 1; i < pos_outlyer; ++i ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); + } + + FOR( i = pos_outlyer + 1; i < BANDS; ++i ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); + } + } + } + ELSE + { + bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); + + FOR( i = 0; i < BANDS; ++i ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); + bits = add( bits, hessize[tdifidx1[i] + 4] ); + } + + IF( lsbdepth1 > 0 ) + { + FOR( i = 0; i < BANDS; ++i ) + { + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); + } + /*bits += BANDS * lsbdepth1; */ + bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); + } + } + } + + return bits; /* xx bits for diff. energies + 1 bit for LC coding mode */ +} +#endif + +/*-------------------------------------------------------------------* + * band_energy_quant() + * + * + *-------------------------------------------------------------------*/ + +static Word16 band_energy_quant_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word32 *L_t_audio, /* i : Q12 : input MDCT signal (Qs) */ + const Word16 band_start[], /* i : Q0 : band start table */ + const Word16 band_end[], /* i : Q0 : band end table */ + Word32 L_band_energy[], /* i : Q14 : band energy (Qbe) */ + const Word16 bands_fx, /* i : Q0 : number of bands */ + const Word32 L_qint, /* i : Q29 */ + const Word16 eref_fx, /* i : Q10 */ + const Word16 is_transient_fx /* i : Q0 : indicator for HQ_TRANSIENT */ +) +{ + Word16 i, k; + Word16 ebits; + Word16 hLCmode0, hLCmode1, deng_bits; + Word16 deng_cmode = 0; + Word16 hbits; + + Word32 L_E; + Word16 QE; + + Word16 rev_qint_fx; /* 1/qint */ + Word16 Qrev_qint; /* Q value for 1/qint */ + + Word16 bq0_fx; + Word16 bq1_fx[BANDS_MAX]; + Word16 bq2_fx[BANDS_MAX]; + + Word16 bq1_temp_fx[BANDS_MAX]; + Word16 bq2_temp_fx[BANDS_MAX]; + + Word32 L_tmp; + Word16 temp_fx; + Word16 frac, exp; + Word16 exp_safe; + Word16 exp_norm; + Word16 exp_norm2; + Word16 exp_normd; + + /* Calculate the band energies */ + exp_safe = 4; + move16(); /* 4: never overflow happen at L_E */ + FOR( k = 0; k < bands_fx; k++ ) + { + L_tmp = L_deposit_l( 1295 ); /* 1295 = sqrt(0.1) (Qs) */ + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + } + exp_norm = norm_l( L_tmp ); + exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ + + QE = add( shl( sub( add( SWB_BWE_LR_Qs, exp_norm ), 16 ), 1 ), 1 ); + L_E = L_shl( 590L, sub( QE, 15 ) ); /* 590 0.018f(Q15 -> QE) */ + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + /*E += yos[i] * yos[i]; */ + temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); + L_E = L_mac( L_E, temp_fx, temp_fx ); /* (Qs+exp_norm-16)*2+1 */ + } + + /*band_energy[k] = (float) log2_f (E + 1.0e-1f); */ + exp_norm2 = norm_l( L_E ); + exp = add( add( shl( sub( add( SWB_BWE_LR_Qs, exp_norm ), 16 ), 1 ), 1 ), exp_norm2 ); + L_E = L_shl( L_E, exp_norm2 ); + frac = Log2_norm_lc( L_E ); + exp = sub( 30, exp ); + L_tmp = L_Comp( exp, frac ); + L_band_energy[k] = L_shr( L_tmp, 2 ); /* Q16->Qbe(Q14) */ + } + + IF( is_transient_fx ) + { + reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); + } + + + /* Quantize the reference and band energies */ + exp_normd = norm_l( L_qint ); + rev_qint_fx = div_s( 0x4000, round_fx( L_shl( L_qint, exp_normd ) ) ); /* Q14-(29+exp_normd-16)+15 */ + Qrev_qint = sub( 14 - ( 29 - 16 ) + 15, exp_normd ); + + bq0_fx = round_fx( L_shl( L_mult( eref_fx, rev_qint_fx ), sub( 5, Qrev_qint ) ) ); /* 16-(10+Qrev_qint+1) */ + FOR( k = 0; k < bands_fx; k++ ) + { + /*bq1[k] = round_f (band_energy[k] / qint); */ + L_tmp = Mpy_32_16_1( L_band_energy[k], rev_qint_fx ); /* Q14+Qrev_qint-15 */ + bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* 16-(14+Qrev_qint-15) */ + } + + IF( is_transient_fx ) + { + + Copy( bq1_fx, bq1_temp_fx, bands_fx ); + + /* Calculate the differential energies */ + diffcod_lrmdct_fx( bands_fx, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient_fx ); + } + + /* Calculate the differential energies */ + bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); + FOR( k = 1; k < bands_fx; k++ ) + { + bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); + move16(); + } + + /* Modifying qbidx to be located in the range -256~255 */ + FOR( i = 0; i < bands_fx; ++i ) + { + if ( GT_16( bq2_fx[i], MAXIMUM_ENERGY_LOWBRATE ) ) + { + bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; + move16(); + } + if ( LT_16( bq2_fx[i], MINIMUM_ENERGY_LOWBRATE ) ) + { + bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; + move16(); + } + } + + /* Get number of bits by Huffman0 coding */ + ebits = large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 0 ); + + IF( is_transient_fx ) + { + /* Get number of bits by Huffman coding */ + hbits = small_symbol_enc_tran_fx( hBstr, bq2_temp_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); + } + ELSE + { + /* Get number of bits by Huffman coding */ + hbits = small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); + } - FOR( i = pos_outlyer + 1; i < BANDS; ++i ) - { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); - } - } + /* comparing used bits */ + test(); + IF( LT_16( ebits, hbits ) || EQ_16( hbits, -1 ) ) + { + deng_cmode = 0; + move16(); + push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 1 ); + deng_bits = add( ebits, BITS_DE_CMODE ); + } + ELSE + { + /* setting energy difference coding mode and storing it */ + deng_cmode = 1; + move16(); + push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + + deng_bits = add( hbits, BITS_DE_CMODE ); + + /* packing indice */ + IF( is_transient_fx ) + { + Copy( bq2_temp_fx, bq2_fx, bands_fx ); + small_symbol_enc_tran_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 1, is_transient_fx ); } ELSE { - bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); + small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 1, is_transient_fx ); + } + } - FOR( i = 0; i < BANDS; ++i ) - { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); - bits = add( bits, hessize[tdifidx1[i] + 4] ); - } + /* Reconstruct quantized spectrum */ + bq1_fx[0] = add( bq2_fx[0], bq0_fx ); + move16(); + FOR( k = 1; k < bands_fx; k++ ) + { + bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); + move16(); + } - IF( lsbdepth1 > 0 ) - { - FOR( i = 0; i < BANDS; ++i ) - { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); - } - /*bits += BANDS * lsbdepth1; */ - bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); - } - } + FOR( k = 0; k < bands_fx; k++ ) + { + L_band_energy[k] = Mpy_32_16_1( L_qint, bq1_fx[k] ); /* 29+0-15 -> Qbe(Q14) */ } - return bits; /* xx bits for diff. energies + 1 bit for LC coding mode */ + IF( is_transient_fx ) + { + reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); + } + + return ( deng_bits ); } -/*-------------------------------------------------------------------* - * band_energy_quant() - * - * - *-------------------------------------------------------------------*/ -static Word16 band_energy_quant_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word32 *L_t_audio, /* i : Q12 : input MDCT signal (Qs) */ - const Word16 band_start[], /* i : Q0 : band start table */ - const Word16 band_end[], /* i : Q0 : band end table */ - Word32 L_band_energy[], /* i : Q14 : band energy (Qbe) */ - const Word16 bands_fx, /* i : Q0 : number of bands */ - const Word32 L_qint, /* i : Q29 */ - const Word16 eref_fx, /* i : Q10 */ - const Word16 is_transient_fx /* i : Q0 : indicator for HQ_TRANSIENT */ -) +#ifdef IVAS_FLOAT_FIXED +static Word16 band_energy_quant_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word32 *L_t_audio, /* i : Q12 : input MDCT signal (Qs) */ + const Word16 band_start[], /* i : Q0 : band start table */ + const Word16 band_end[], /* i : Q0 : band end table */ + Word32 L_band_energy[], /* i : Q14 : band energy (Qbe) */ + const Word16 bands, /* i : Q0 : number of bands */ + const Word32 L_qint, /* i : Q29 */ + const Word16 eref_fx, /* i : Q10 */ + const Word16 is_transient /* i : Q0 : indicator for HQ_TRANSIENT */ ) { Word16 i, k; Word16 ebits; Word16 hLCmode0, hLCmode1, deng_bits; Word16 deng_cmode = 0; + move16(); Word16 hbits; - Word32 L_E; Word16 QE; @@ -1569,12 +3297,13 @@ static Word16 band_energy_quant_fx( Word16 exp_safe; Word16 exp_norm; Word16 exp_norm2; - Word16 exp_normd; + Word16 exp_normd; + /* Calculate the band energies */ /* Calculate the band energies */ exp_safe = 4; move16(); /* 4: never overflow happen at L_E */ - FOR( k = 0; k < bands_fx; k++ ) + FOR( k = 0; k < bands; k++ ) { L_tmp = L_deposit_l( 1295 ); /* 1295 = sqrt(0.1) (Qs) */ FOR( i = band_start[k]; i <= band_end[k]; i++ ) @@ -1603,51 +3332,52 @@ static Word16 band_energy_quant_fx( L_band_energy[k] = L_shr( L_tmp, 2 ); /* Q16->Qbe(Q14) */ } - IF( is_transient_fx ) + IF( is_transient ) { - reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); + reverse_transient_frame_energies_fx( L_band_energy, bands ); } - - /* Quantize the reference and band energies */ +#define WMC_TOOL_SKIP exp_normd = norm_l( L_qint ); rev_qint_fx = div_s( 0x4000, round_fx( L_shl( L_qint, exp_normd ) ) ); /* Q14-(29+exp_normd-16)+15 */ Qrev_qint = sub( 14 - ( 29 - 16 ) + 15, exp_normd ); bq0_fx = round_fx( L_shl( L_mult( eref_fx, rev_qint_fx ), sub( 5, Qrev_qint ) ) ); /* 16-(10+Qrev_qint+1) */ - FOR( k = 0; k < bands_fx; k++ ) + FOR( k = 0; k < bands; k++ ) { /*bq1[k] = round_f (band_energy[k] / qint); */ - L_tmp = Mpy_32_16_1( L_band_energy[k], rev_qint_fx ); /* Q14+Qrev_qint-15 */ + L_tmp = L_mls( L_band_energy[k], rev_qint_fx ); /* Q14+Qrev_qint-15 */ bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* 16-(14+Qrev_qint-15) */ } +#undef WMC_TOOL_SKIP - IF( is_transient_fx ) + IF( is_transient ) { - Copy( bq1_fx, bq1_temp_fx, bands_fx ); + Copy( bq1_fx, bq1_temp_fx, bands ); /* Calculate the differential energies */ - diffcod_lrmdct_fx( bands_fx, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient_fx ); + diffcod_lrmdct_fx( bands, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient ); } /* Calculate the differential energies */ bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); - FOR( k = 1; k < bands_fx; k++ ) + FOR( k = 1; k < bands; k++ ) { bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); move16(); } + /* Modifying qbidx to be located in the range -256~255 */ - FOR( i = 0; i < bands_fx; ++i ) + FOR( i = 0; i < bands; ++i ) { - if ( GT_16( bq2_fx[i], MAXIMUM_ENERGY_LOWBRATE ) ) + if ( bq2_fx[i] > MAXIMUM_ENERGY_LOWBRATE ) { bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; move16(); } - if ( LT_16( bq2_fx[i], MINIMUM_ENERGY_LOWBRATE ) ) + if ( bq2_fx[i] < MINIMUM_ENERGY_LOWBRATE ) { bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; move16(); @@ -1655,80 +3385,204 @@ static Word16 band_energy_quant_fx( } /* Get number of bits by Huffman0 coding */ - ebits = large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 0 ); + ebits = large_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode0, 0 ); + + IF( is_transient ) + { + /* Get number of bits by Huffman coding */ + hbits = small_symbol_enc_tran_ivas_fx( hBstr, bq2_temp_fx, bands, &hLCmode1, 0, is_transient ); + } + ELSE + { + /* Get number of bits by Huffman coding */ + hbits = small_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 0, is_transient ); + } + + test(); + IF( LT_16( ebits, hbits ) || EQ_16( hbits, -1 ) ) + { + deng_cmode = 0; + move16(); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + large_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode0, 1 ); + deng_bits = add( ebits, BITS_DE_CMODE ); + } + ELSE + { + /* setting energy difference coding mode and storing it */ + deng_cmode = 1; + move16(); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + + deng_bits = add( hbits, BITS_DE_CMODE ); + + /* packing indice */ + IF( is_transient ) + { + Copy( bq2_temp_fx, bq2_fx, bands ); + small_symbol_enc_tran_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 1, is_transient ); + } + ELSE + { + small_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 1, is_transient ); + } + } + + /* Reconstruct quantized spectrum */ + bq1_fx[0] = add( bq2_fx[0], bq0_fx ); + FOR( k = 1; k < bands; k++ ) + { + bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); + } + + FOR( k = 0; k < bands; k++ ) + { +#define WMC_TOOL_SKIP + L_band_energy[k] = L_mls( L_qint, (Word16) bq1_fx[k] ); + move32(); /* 29+0-15 -> Qbe(Q14) */ +#undef WMC_TOOL_SKIP + } + + IF( is_transient ) + { + reverse_transient_frame_energies_fx( L_band_energy, bands ); + } + + return ( deng_bits ); +} + +#endif + +/*-------------------------------------------------------------------* + * p2a_threshold_quant() + * + * + *-------------------------------------------------------------------*/ + +static Word16 p2a_threshold_quant_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: : bit stream */ + const Word32 *L_t_audio, /* i : Q12 : input spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */ + const Word16 bands, /* i : Q0 : number of subbands */ + const Word16 p2a_bands, /* i : Q0 : tonality indicator */ + const Word16 p2a_th_fx, /* i : Q11 : threshold tonal or not */ + Word16 *p2a_flags_fx /* i/o: Q0 : tonality flag */ +) +{ + Word16 i, j, k; + Word32 L_a, L_p, L_e; + Word16 Qa; + Word32 L_tmp; + Word16 temp_fx; + Word16 exp_norm; + Word16 exp_safe; + Word16 exp_normn, exp_normd; + + Word16 norm_a_fx, Qnorm_a; + Word16 pa_fx, Qpa; + + Word16 exp, frac; + + Word32 L_p2a; + Word16 p2a_fx; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + exp_safe = 4; /* never happen overflow. */ + + set16_fx( p2a_flags_fx, 1, bands ); + move16(); + + j = 0; + move16(); + FOR( k = sub( bands, p2a_bands ); k < bands; k++ ) + { + L_a = L_deposit_l( 0 ); + L_p = L_deposit_l( 0 ); + + L_tmp = L_deposit_l( 0 ); + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + } + exp_norm = norm_l( L_tmp ); + exp_norm = sub( exp_norm, exp_safe ); + + FOR( i = band_start[k]; i <= band_end[k]; i++ ) + { + temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); /* Q12+exp_norm-16 -> exp_norm-4 */ + L_e = L_mult( temp_fx, temp_fx ); + + if ( GT_32( L_e, L_p ) ) + { + L_p = L_add( L_e, 0 ); + } + L_a = L_add( L_a, L_e ); + } + Qa = sub( shl( exp_norm, 1 ), 7 ); /* (exp_norm-4)*2+1 */ + + IF( L_a > 0x0L ) + { + /* a /= band_width[k]; */ + exp_normn = norm_l( L_a ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( band_width[k] ); + norm_a_fx = div_l( L_shl( L_a, exp_normn ), shl( band_width[k], exp_normd ) ); + Qnorm_a = sub( sub( add( Qa, exp_normn ), exp_normd ), 1 ); /* (Qa+exp_normn)-exp_normd-1); */ + + /*p2a = 10.0f * (float) log10 (p / a); */ + p2a_fx = 0; + move16(); + IF( norm_a_fx > 0 ) + { + exp_normn = norm_l( L_p ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( norm_a_fx ); + pa_fx = div_l( L_shl( L_p, exp_normn ), shl( norm_a_fx, exp_normd ) ); + Qpa = sub( sub( add( Qa, exp_normn ), add( Qnorm_a, exp_normd ) ), 1 ); - IF( is_transient_fx ) - { - /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_tran_fx( hBstr, bq2_temp_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); - } - ELSE - { - /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); - } + L_tmp = L_deposit_h( pa_fx ); + Qpa = add( Qpa, 16 ); + exp = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp ) ); + exp = sub( 30, exp ); + exp = sub( exp, Qpa ); + L_tmp = L_Comp( exp, frac ); - /* comparing used bits */ - test(); - IF( LT_16( ebits, hbits ) || EQ_16( hbits, -1 ) ) - { - deng_cmode = 0; - move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); - large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 1 ); - deng_bits = add( ebits, BITS_DE_CMODE ); - } - ELSE - { - /* setting energy difference coding mode and storing it */ - deng_cmode = 1; - move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + /* 10/( log(10)/log(2) ) = 3.01029995663981195211 24660(Q13) */ + L_p2a = Mpy_32_16_1( L_tmp, 24660 ); /* 16+13-15 -> Q14 */ - deng_bits = add( hbits, BITS_DE_CMODE ); +#ifdef BASOP_NOGLOB + p2a_fx = round_fx_o( L_shl_o( L_p2a, 13, &Overflow ), &Overflow ); /* 27 -16 -> 11 */ +#else + p2a_fx = round_fx( L_shl( L_p2a, 13 ) ); /* 27 -16 -> 11 */ +#endif + } - /* packing indice */ - IF( is_transient_fx ) - { - Copy( bq2_temp_fx, bq2_fx, bands_fx ); - small_symbol_enc_tran_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 1, is_transient_fx ); + if ( LE_16( p2a_fx, p2a_th_fx ) ) + { + p2a_flags_fx[k] = 0; + move16(); + } } ELSE { - small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 1, is_transient_fx ); + p2a_flags_fx[k] = 0; + move16(); } - } - - /* Reconstruct quantized spectrum */ - bq1_fx[0] = add( bq2_fx[0], bq0_fx ); - move16(); - FOR( k = 1; k < bands_fx; k++ ) - { - bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); - move16(); - } - - FOR( k = 0; k < bands_fx; k++ ) - { - L_band_energy[k] = Mpy_32_16_1( L_qint, bq1_fx[k] ); /* 29+0-15 -> Qbe(Q14) */ - } - IF( is_transient_fx ) - { - reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); + push_indice_fx( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); + j = add( j, 1 ); } - return ( deng_bits ); + return ( j ); } - -/*-------------------------------------------------------------------* - * p2a_threshold_quant() - * - * - *-------------------------------------------------------------------*/ - -static Word16 p2a_threshold_quant_fx( +#ifdef IVAS_FLOAT_FIXED +static Word16 p2a_threshold_quant_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: : bit stream */ const Word32 *L_t_audio, /* i : Q12 : input spectrum */ const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ @@ -1761,6 +3615,7 @@ static Word16 p2a_threshold_quant_fx( #endif exp_safe = 4; /* never happen overflow. */ + move16(); set16_fx( p2a_flags_fx, 1, bands ); @@ -1826,7 +3681,7 @@ static Word16 p2a_threshold_quant_fx( #ifdef BASOP_NOGLOB p2a_fx = round_fx_o( L_shl_o( L_p2a, 13, &Overflow ), &Overflow ); /* 27 -16 -> 11 */ #else - p2a_fx = round_fx( L_shl( L_p2a, 13 ) ); /* 27 -16 -> 11 */ + p2a_fx = round_fx( L_shl( L_p2a, 13 ) ); /* 27 -16 -> 11 */ #endif } @@ -1842,13 +3697,15 @@ static Word16 p2a_threshold_quant_fx( move16(); } - push_indice_fx( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); + push_indice( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); j = add( j, 1 ); } return ( j ); } +#endif + /*-------------------------------------------------------------------* * mdct_spectrum_fine_gain_enc() * @@ -2015,3 +3872,166 @@ static void mdct_spectrum_fine_gain_enc_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +static void mdct_spectrum_fine_gain_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 L_ybuf[], /* i : Q12 : input spectrum */ + Word32 L_y2[], /* i/o: Q12 : decoded spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 k_sort[], /* i : Q0 : sort table by band_energy */ + const Word16 bands, /* i : Q0 : nubmber of subbands */ + const Word32 L_qint, /* i : Q29 : */ + const Word16 Ngq, /* i : Q0 : */ + const Word16 gqlevs, /* i : Q0 : quantized level */ + const Word16 gqbits /* i : Q0 : quantized bits */ +) +{ + Word16 i, k; + + Word16 delta_fx, Qdelta; + Word32 L_delta; + Word32 L_q; + + Word16 gain_table_fx[MAX_GQLEVS]; + Word16 Qgt; + Word16 gamma_fx; + Word16 Qgamma; + + Word16 exp_safe; + Word16 exp_normn, exp_normd; + Word16 exp_norm; + + Word32 L_temp; + Word16 temp_lo_fx, temp_hi_fx, temp_fx, temp2_fx; + + Word32 L_Eyy, L_Exy; + /*Word16 QE; */ + + Word16 d_fx; + Word16 dmin_fx; + Word16 imin_fx; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* Fine gain quantization on only the most significant energy bands */ + + /*delta = qint / gqlevs; */ + exp_normn = norm_l( L_qint ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( gqlevs ); + delta_fx = div_l( L_shl( L_qint, exp_normn ), shl( gqlevs, exp_normd ) ); + Qdelta = add( sub( exp_normn, exp_normd ), 28 ); /* 29+exp_normn-(exp_normd)-1; */ + L_delta = L_shl( L_deposit_h( delta_fx ), sub( 13, Qdelta ) ); + /*q = (-qint + delta) / 2.0f; */ + L_q = L_shr( L_sub( L_delta, L_qint ), 1 ); + + FOR( i = 0; i < gqlevs; i++ ) + { + /*gain_table[i] = (float) pow (2.0f, q * 0.5f); */ + L_temp = L_shr( L_shr( L_q, 1 ), sub( 29, 16 ) ); + temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx ); + Qgt = sub( 14, temp_hi_fx ); + gain_table_fx[i] = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qgt */ + + /*q += delta; */ + L_q = L_add( L_q, L_delta ); + gain_table_fx[i] = shl( gain_table_fx[i], sub( 14, Qgt ) ); /* Qgt -> Q14 */ + } + + FOR( k = sub( bands, Ngq ); k < bands; k++ ) + { + /*Eyy = 0.0f; */ + /*Exy = 0.0f; */ + /*for (i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++) */ + /*{ */ + /* Eyy += y2[i] * y2[i]; */ + /* Exy += ybuf[i] * y2[i]; */ + /*} */ + exp_safe = 4; + move16(); /* 4 is too large. but never happen overflow */ + L_temp = L_deposit_l( 0 ); + FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) + { + L_temp = L_or( L_temp, L_abs( L_y2[i] ) ); + L_temp = L_or( L_temp, L_abs( L_ybuf[i] ) ); + } + exp_norm = norm_l( L_temp ); + exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ + + L_Eyy = L_deposit_l( 0 ); + L_Exy = L_deposit_l( 0 ); + /*QE = add(shl(add(Qs-16, exp_norm), 1), 1); //(Qs+exp_norm-16)*2+1; */ + FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) + { + /*Eyy += y2[i] * y2[i]; */ + temp_fx = round_fx( L_shl( L_y2[i], exp_norm ) ); + L_Eyy = L_mac( L_Eyy, temp_fx, temp_fx ); + + /*Exy += ybuf[i] * y2[i]; */ + temp2_fx = round_fx( L_shl( L_ybuf[i], exp_norm ) ); + L_Exy = L_mac( L_Exy, temp2_fx, temp_fx ); + } + + test(); + IF( L_Eyy > 0x0L && L_Exy > 0x0L ) + { + /*gamma = Exy / Eyy; */ + exp_normn = norm_l( L_Exy ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_l( L_Eyy ); +#ifdef BASOP_NOGLOB + gamma_fx = div_l( L_shl_o( L_Exy, exp_normn, &Overflow ), round_fx_o( L_shl_o( L_Eyy, exp_normd, &Overflow ), &Overflow ) ); +#else + gamma_fx = div_l( L_shl( L_Exy, exp_normn ), round_fx( L_shl( L_Eyy, exp_normd ) ) ); +#endif + Qgamma = add( sub( exp_normn, exp_normd ), 15 ); /* exp_normn - (exp_normd-16) - 1; */ + gamma_fx = shl( gamma_fx, sub( 14, Qgamma ) ); /* Qgamma -> Q14 */ + + dmin_fx = 32767; + move16(); + imin_fx = -1; + move16(); + FOR( i = 0; i < gqlevs; i++ ) + { + d_fx = abs_s( sub( gamma_fx, gain_table_fx[i] ) ); + IF( LT_16( d_fx, dmin_fx ) ) + { + dmin_fx = d_fx; + move16(); + imin_fx = i; + move16(); + } + } + + gamma_fx = gain_table_fx[imin_fx]; + move16(); /* Q14 */ + + FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) + { + /*y2[i] *= gamma; */ + /* This IF statement for keeping same mantissa evenif y2 is plus or minus */ + IF( L_y2[i] >= 0x0 ) + { + L_y2[i] = L_shl( Mpy_32_16_1( L_y2[i], gamma_fx ), 1 ); + } + ELSE + { + L_y2[i] = L_negate( L_shl( Mpy_32_16_1( L_abs( L_y2[i] ), gamma_fx ), 1 ) ); + } + } + } + ELSE + { + imin_fx = 0; + move16(); + } + + push_indice( st_fx->hBstr, IND_HQ2_SUBBAND_GAIN, imin_fx, gqbits ); + } + + return; +} +#endif diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index b9f03750a..8be8d54e2 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1402,6 +1402,36 @@ Word16 IGFEncWriteConcatenatedBitstream_fx( return hInstance->infoTotalBitsWritten; } +#ifdef IVAS_FLOAT_FIXED +Word16 IGFEncWriteConcatenatedBitstream_ivas_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +) +{ + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + Word16 i; + Word16 tmp; + Word16 bitsLeft; + UWord8 *pBitstream; + + hPrivateData = &hInstance->igfData; + pBitstream = &hPrivateData->igfBitstream[0]; + + tmp = shr( hPrivateData->igfBitstreamBits, 3 ); + FOR( i = 0; i < tmp; i++ ) + { + push_next_indice( hBstr, pBitstream[i], 8 ); + } + + bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 ); + IF( bitsLeft > 0 ) + { + push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); + } + + return hInstance->infoTotalBitsWritten; +} +#endif /**********************************************************************/ /* apply the IGF encoder, main encoder interface diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 180594fa9..f1fcdc80a 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -101,8 +101,15 @@ static void enc_prm_pre_mdct( /*--------------------------------------------------------------------------------* * TCX20/TCX10 parameters *--------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED writeTCXparam( st, hBstr, NULL, param, 0, 0, 0, no_param_tns, p_param, NULL, 0 ); +#else +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); +#endif + + writeTCXparam_fx( st, hBstr, NULL, param, 0, 0, 0, no_param_tns, p_param, NULL, 0 ); +#endif st->side_bits_frame_channel = hBstr->nb_bits_tot - nbits_start; @@ -597,6 +604,9 @@ void ivas_mdct_core_whitening_enc( int16_t num_sns; int8_t skipped_first_channel; int16_t zero_side_flag[NB_DIV]; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 q_com; +#endif push_wmops( "mdct_core_whitening" ); @@ -652,7 +662,34 @@ void ivas_mdct_core_whitening_enc( for ( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_com = Q31; + q_com = L_get_q1( st->prevEnergyHF ); + q_com = s_min( q_com, L_get_q1( st->currEnergyHF ) ); + st->prevEnergyHF_fx = floatToFixed_32( st->prevEnergyHF, q_com ); + st->currEnergyHF_fx = floatToFixed_32( st->currEnergyHF, q_com ); + st->currEnergyHF_e_fx = sub( Q31, q_com ); + IF( st->hTranDet ) + { + st->hTranDet->subblockEnergies.q_subblockNrgChange = L_get_q_buf1( st->hTranDet->subblockEnergies.subblockNrgChange_flt, NSUBBLOCKS + MAX_TD_DELAY ); + floatToFixed_arrL32( st->hTranDet->subblockEnergies.subblockNrgChange_flt, st->hTranDet->subblockEnergies.subblockNrgChange_32, st->hTranDet->subblockEnergies.q_subblockNrgChange, NSUBBLOCKS + MAX_TD_DELAY ); + } + IF( st->hTcxEnc ) + { + st->hTcxEnc->tfm_mem_fx = floatToFixed_32( st->hTcxEnc->tfm_mem, Q31 ); + } +#endif + SetTCXModeInfo_ivas_fx( st, st->hTranDet, &st->hTcxCfg->tcx_curr_overlap_mode ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IF( st->hTcxEnc ) + { + st->hTcxEnc->tfm_mem = fixedToFloat_32( st->hTcxEnc->tfm_mem_fx, Q31 ); + } +#endif +#else SetTCXModeInfo( st, st->hTranDet, &st->hTcxCfg->tcx_curr_overlap_mode ); +#endif } } @@ -1197,7 +1234,11 @@ void ivas_mdct_core_whitening_enc( push_next_indice( hBstr, sns_low_br_mode, 1 ); } } +#ifdef IVAS_FLOAT_FIXED + encode_lpc_avq_ivas_fx( hBstr, num_sns, param_lpc[ch], st->core, st->element_mode ); +#else encode_lpc_avq( hBstr, num_sns, param_lpc[ch], st->core, st->element_mode ); +#endif st->side_bits_frame_channel += hBstr->nb_bits_tot - nbits_start_sns; } @@ -1367,7 +1408,15 @@ void ivas_mdct_quant_coder( } nbits_start = st->hBstr->nb_bits_tot; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); +#endif + + writeTCXparam_fx( st, st->hBstr, NULL, param_core[ch], 0, 0, 0, NULL, p_param[ch], target_bitsTCX10[ch], 1 ); +#else writeTCXparam( st, st->hBstr, NULL, param_core[ch], 0, 0, 0, NULL, p_param[ch], target_bitsTCX10[ch], 1 ); +#endif total_nbbits = st->hBstr->nb_bits_tot - nbits_start - nSubframes * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); diff --git a/lib_enc/ivas_range_uni_enc.c b/lib_enc/ivas_range_uni_enc.c index f990b3484..dbf0caa24 100644 --- a/lib_enc/ivas_range_uni_enc.c +++ b/lib_enc/ivas_range_uni_enc.c @@ -63,7 +63,23 @@ static void rc_uni_enc_shift( RangeUniEncState *rc_st_enc ); * * Initalize the range encoder *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED +void rc_uni_enc_init( + RangeUniEncState *rc_st_enc /* i/o: RC state handle */ +) +{ + rc_st_enc->rc_low = 0; + rc_st_enc->rc_range = 0xFFFFFFFF; + rc_st_enc->rc_cache = -1; + rc_st_enc->rc_carry = 0; + rc_st_enc->rc_carry_count = 0; + rc_st_enc->byte_count = 0; + rc_st_enc->last_byte_bit_count = -1; + + return; +} +#else void rc_uni_enc_init( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ) @@ -76,16 +92,24 @@ void rc_uni_enc_init( rc_st_enc->byte_count = 0; rc_st_enc->last_byte_bit_count = -1; + move32(); + move32(); + move16(); + move16(); + move16(); + move16(); + move16(); return; } +#endif /*-------------------------------------------------------------------* * rc_uni_enc_encode_fast() * * Encode given cumulative frequency and frequency when total frequency is a power of 2 *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void rc_uni_enc_encode_fast( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const uint16_t cum_freq, /* i : Cumulative frequency up to symbol */ @@ -120,6 +144,47 @@ void rc_uni_enc_encode_fast( return; } +#else +void rc_uni_enc_encode_fast( + RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ + const UWord16 cum_freq, /* i : Cumulative frequency up to symbol */ + const UWord16 sym_freq, /* i : Symbol frequency */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +) +{ + UWord32 r, tmp; + + r = UL_lshr( rc_st_enc->rc_range, tot_shift ); + tmp = UL_Mpy_32_32( r, (UWord32) cum_freq ); + + rc_st_enc->rc_low = UL_addNsD( rc_st_enc->rc_low, tmp ); + move32(); + if ( LT_64( rc_st_enc->rc_low, tmp ) ) + { + rc_st_enc->rc_carry = 1; + move16(); + } + + rc_st_enc->rc_range = UL_Mpy_32_32( r, (UWord32) sym_freq ); + move32(); + + /* rc_range was shifted right by up to 16, so at most two renormalizations are needed */ + IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) + { + rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); + move32(); + rc_uni_enc_shift( rc_st_enc ); + IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) + { + rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); + move32(); + rc_uni_enc_shift( rc_st_enc ); + } + } + + return; +} +#endif /*-------------------------------------------------------------------* @@ -127,7 +192,7 @@ void rc_uni_enc_encode_fast( * * Encode an alphabet symbol when total frequency is a power of 2 *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void rc_uni_enc_encode_symbol_fastS( RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ const uint16_t symbol, /* i : Symbol to encode */ @@ -140,14 +205,27 @@ void rc_uni_enc_encode_symbol_fastS( return; } +#else +void rc_uni_enc_encode_symbol_fastS( + RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ + const UWord16 symbol, /* i : Symbol to encode */ + const UWord16 cum_freq[], /* i : Cumulative frequency up to symbol */ + const UWord16 sym_freq[], /* i : Symbol frequency */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +) +{ + rc_uni_enc_encode_fast( rc_st_enc, cum_freq[symbol], sym_freq[symbol], tot_shift ); + return; +} +#endif /*-------------------------------------------------------------------* * rc_uni_enc_finish() * * Finalize the range encoder *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED /*! r: Total number of bits produced */ int16_t rc_uni_enc_finish( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ @@ -213,6 +291,90 @@ int16_t rc_uni_enc_finish( return total_bit_count; } +#else +/*! r: Total number of bits produced */ +Word16 rc_uni_enc_finish( + RangeUniEncState *rc_st_enc /* i/o: RC state handle */ +) +{ + Word16 total_bit_count; + UWord32 val, mask; + Word16 bits; + + /* floor(log2(x)) = floor(log2(x >> 24)) + 24, for any x >= 2 ^ 24 */ + /* 32 - floor(log2(y)) = norm_ul_float(y) + 1 = norm_l(y >> 24) - 22 */ + bits = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 22 ); /* bits = 32 - floor(log2(rc_range)) */ + /* completely equivalent with norm_ul_float(rc_st_enc->rc_range) + 1, but norm_l is faster */ + + bits = add( bits, 1 ); /* conservative number of bits, because the decoder only has rc_range available */ + + + mask = UL_lshr( 0xFFFFFFFFu, bits ); + val = UL_and( UL_addNsD( rc_st_enc->rc_low, mask ), ~mask ); + + if ( LT_64( val, rc_st_enc->rc_low ) ) + { + rc_st_enc->rc_carry = 1; + move16(); + } + + rc_st_enc->rc_low = val; + move32(); + + WHILE( bits > 0 ) + { + rc_uni_enc_shift( rc_st_enc ); + bits = sub( bits, 8 ); + } + + bits = add( bits, 8 ); + + IF( rc_st_enc->rc_carry_count > 0 ) + { + /* rc_carry_count > 0, therefore the last call to rc_uni_enc_shift incremented rc_carry_count */ + IF( rc_st_enc->rc_cache >= 0 ) /* may actually be always true, but it is difficult to prove formally */ + { + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_cache, rc_st_enc->rc_carry ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + move16(); + move16(); + } + + WHILE( GT_16( rc_st_enc->rc_carry_count, 1 ) ) + { + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_carry, 0xFF ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + rc_st_enc->rc_carry_count = sub( rc_st_enc->rc_carry_count, 1 ); + move16(); + move16(); + move16(); + } + /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */ + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) L_and( L_deposit_l( add( rc_st_enc->rc_carry, 0xFF ) ), L_shl( 0xFFu, sub( 8, bits ) ) ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + rc_st_enc->last_byte_bit_count = bits; + move16(); + move16(); + move16(); + } + ELSE + { + /* rc_carry_count == 0, therefore the last call to rc_uni_enc_shift wrote into rc_cache */ + /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */ + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) L_and( L_deposit_l( add( rc_st_enc->rc_carry, rc_st_enc->rc_cache ) ), L_shl( 0xFFu, sub( 8, bits ) ) ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + rc_st_enc->last_byte_bit_count = bits; + move16(); + move16(); + move16(); + } + + + total_bit_count = add( shl( sub( rc_st_enc->byte_count, 1 ), 3 ), rc_st_enc->last_byte_bit_count ); + + return total_bit_count; +} +#endif /*-------------------------------------------------------------------* @@ -220,7 +382,7 @@ int16_t rc_uni_enc_finish( * * Get the total number of bits that would be produced by finalization *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED /*! r: Total number of bits produced */ int16_t rc_uni_enc_virtual_finish( RangeUniEncState *rc_st_enc /* i : RC state handle */ @@ -238,6 +400,39 @@ int16_t rc_uni_enc_virtual_finish( return ( ( rc_st_enc->byte_count + rc_st_enc->rc_carry_count ) << 3 ) + norm_l( rc_st_enc->rc_range >> 24 ) - 13 - 8 * ( (uint16_t) rc_st_enc->rc_cache >> 15 ); } +#else +/*! r: Total number of bits produced */ +Word16 rc_uni_enc_virtual_finish( + RangeUniEncState *rc_st_enc /* i : RC state handle */ +) +{ + + /* + byte_count bytes have already been written to the byte_buffer array + 1 byte is pending if rc_cache >= 0, consisting of rc_cache or rc_cache + 1 + the pending byte bits are computed as 8 - 8 * ((uint16_t) rc_st_enc->rc_cache >> 15) + rc_carry_count bytes are pending, consisting of 0x00 or 0xFF + bits bits will be additionally written during the finalization procedure + bits is computed as norm_l(rc_st_enc->rc_range >> 24) - 21, as in rc_uni_enc_finish + */ + + Word16 tmp; + IF( rc_st_enc->rc_cache > 0 ) + { + tmp = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 13 ); + } + ELSE + { + tmp = sub( norm_l( UL_lshr( rc_st_enc->rc_range, 24 ) ), 13 + 8 ); + } + tmp = add( tmp, shl( add( rc_st_enc->byte_count, rc_st_enc->rc_carry_count ), 3 ) ); + + // return ( ( rc_st_enc->byte_count + rc_st_enc->rc_carry_count ) << 3 ) + + // norm_l( rc_st_enc->rc_range >> 24 ) - 13 - 8 * ( (uint16_t) rc_st_enc->rc_cache >> 15 ); + + return tmp; +} +#endif /*-------------------------------------------------------------------* @@ -245,7 +440,7 @@ int16_t rc_uni_enc_virtual_finish( * * Shift a byte out to bitstream (internal function) *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void rc_uni_enc_shift( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ) @@ -275,6 +470,49 @@ static void rc_uni_enc_shift( return; } +#else +static void rc_uni_enc_shift( + RangeUniEncState *rc_st_enc /* i/o: RC state handle */ +) +{ + test(); + IF( LT_64( rc_st_enc->rc_low, 0xFF000000u ) || rc_st_enc->rc_carry ) + { + IF( rc_st_enc->rc_cache >= 0 ) + { + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_cache, rc_st_enc->rc_carry ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + move16(); + move16(); + } + + WHILE( rc_st_enc->rc_carry_count > 0 ) + { + rc_st_enc->byte_buffer[rc_st_enc->byte_count] = (UWord8) add( rc_st_enc->rc_carry, 0xFF ); + rc_st_enc->byte_count = add( rc_st_enc->byte_count, 1 ); + rc_st_enc->rc_carry_count = sub( rc_st_enc->rc_carry_count, 1 ); + move16(); + move16(); + move16(); + } + + rc_st_enc->rc_cache = extract_l( UL_lshr( rc_st_enc->rc_low, 24 ) ); + rc_st_enc->rc_carry = 0; + move16(); + move16(); + } + ELSE + { + rc_st_enc->rc_carry_count = add( rc_st_enc->rc_carry_count, 1 ); + move16(); + } + + rc_st_enc->rc_low = UL_lshl( rc_st_enc->rc_low, 8 ); + move32(); + + return; +} +#endif /*-------------------------------------------------------------------* @@ -282,7 +520,7 @@ static void rc_uni_enc_shift( * * Encode up to 16 bits with uniform probability *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void rc_uni_enc_encode_bits( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const uint16_t value, /* i : Value to encode */ @@ -314,3 +552,41 @@ void rc_uni_enc_encode_bits( return; } +#else +void rc_uni_enc_encode_bits( + RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ + const UWord16 value, /* i : Value to encode */ + const Word16 bits /* i : Number of bits */ +) +{ + UWord32 tmp; + + rc_st_enc->rc_range = UL_lshr( rc_st_enc->rc_range, bits ); + move32(); + tmp = UL_Mpy_32_32( rc_st_enc->rc_range, value ); + + rc_st_enc->rc_low = UL_addNsD( rc_st_enc->rc_low, tmp ); + move32(); + if ( LT_64( rc_st_enc->rc_low, tmp ) ) + { + rc_st_enc->rc_carry = 1; + move16(); + } + + /* rc_range was shifted right by up to 16, so at most two renormalizations are needed */ + IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) + { + rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); + move32(); + rc_uni_enc_shift( rc_st_enc ); + IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) + { + rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); + move32(); + rc_uni_enc_shift( rc_st_enc ); + } + } + + return; +} +#endif diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 9c8ade511..961781180 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -846,8 +846,7 @@ void stereo_tcx_core_enc( /*--------------------------------------------------------------------------------* * Write LPC parameters *--------------------------------------------------------------------------------*/ - - writeLPCparam( st, hBstr, param_lpc, bits_param_lpc, no_param_lpc, &total_nbbits ); + writeLPCparam_fx( st, hBstr, param_lpc, bits_param_lpc, no_param_lpc, &total_nbbits ); assert( total_nbbits == ( nbits_lpc[0] + nbits_lpc[1] ) ); @@ -1004,6 +1003,7 @@ void stereo_tcx_core_enc( Word16 *lsp_new_fx = &lsp_new_fx_arr[0]; floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); + st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); #endif #ifdef IVAS_FLOAT_FIXED @@ -1077,9 +1077,7 @@ void stereo_tcx_core_enc( /*--------------------------------------------------------------------------------* * Encode TCX20/10 parameters *--------------------------------------------------------------------------------*/ - - /* TODO: convert this function */ - writeTCXparam( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, add( nbits_lpc[0], nbits_lpc[1] ), NULL, NULL, NULL, -1 ); + writeTCXparam_fx( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, add( nbits_lpc[0], nbits_lpc[1] ), NULL, NULL, NULL, -1 ); total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c index 855f78667..a999c061a 100644 --- a/lib_enc/lsf_enc.c +++ b/lib_enc/lsf_enc.c @@ -41,6 +41,7 @@ #include "rom_com.h" #include "prot.h" #include "prot_fx.h" +#include "prot_fx_enc.h" #include "basop_proto_func.h" #include "ivas_prot.h" #ifdef IVAS_FLOAT_FIXED diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 89f19c464..058af1b18 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -8,6 +8,7 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ @@ -416,7 +417,7 @@ void lsf_enc_ivas_fx( lsp2lsf_fx( lsp_new, lsf_new, M, int_fs ); /* check resonance for pitch clipping algorithm */ - gp_clip_test_lsf_fx( st->element_mode, lsf_new, st->clip_var_fx, 0 ); + gp_clip_test_lsf_ivas_fx( st->element_mode, st->core_brate, lsf_new, st->clip_var_fx, 0 ); /* Find the number of bits for LSF quantization */ nBits = 0; @@ -439,7 +440,7 @@ void lsf_enc_ivas_fx( nBits = 30; move16(); - if ( EQ_16( st->bwidth, NB ) ) + if ( st->bwidth == NB ) { nBits = 32; move16(); @@ -544,7 +545,7 @@ void lsf_enc_ivas_fx( L_tmp = L_mult( lsf_new[i], 10922 ); /*Q(x2.56+16)*/ L_tmp = L_mac( L_tmp, st->lsfoldbfi1_fx[i], 10922 ); /*Q(x2.56+16)*/ L_tmp = L_mac( L_tmp, st->lsfoldbfi0_fx[i], 10922 ); /*Q(x2.56+16)*/ - st->lsf_adaptive_mean_fx[i] = round_fx( L_tmp ); /*Q(x2.56)*/ + st->lsf_adaptive_mean_fx[i] = extract_h( L_tmp ); /*Q(x2.56)*/ } /* FEC - update LSF memories */ @@ -785,11 +786,11 @@ static void lsfq_CNG_ivas_fx( Vr_add( qlsf, &CNG_SN1_fx[idx_cv * M], qlsf, M ); /* write the VQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_0, idx_cv, 4 ); + push_indice( hBstr, IND_ISF_0_0, idx_cv, 4 ); /* write the LVQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); return; } @@ -1605,13 +1606,15 @@ void lsf_end_enc_ivas_fx( * Calculate the number of stages and levels for each stage based on allowed bit budget * Set absolute threshold for codebook-type decision logic depending on signal bandwidth *------------------------------------------------------------------------------------ -*/ - IF( EQ_16( st->bwidth, NB ) ) + IF( st->bwidth == NB ) { - abs_threshold = L_add( SFNETLOWLIMIT_NB, 0 ); + abs_threshold = SFNETLOWLIMIT_NB / 2; + move32(); } ELSE { - abs_threshold = L_add( SFNETLOWLIMIT_WB, 0 ); + abs_threshold = SFNETLOWLIMIT_WB / 2; + move32(); } /* Calculate LSF weighting coefficients */ Unified_weighting_fx( &st->Bin_E_fx[L_FFT / 2], Q_ener, lsf, wghts, (Word16) EQ_16( st->bwidth, NB ), (Word16) EQ_16( coder_type, UNVOICED ), st->sr_core, M ); @@ -1653,11 +1656,13 @@ void lsf_end_enc_ivas_fx( move16(); } + test(); + test(); /* TD stereo SCh: perform intra-frame prediction with pulling-to-mean */ IF( st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL ) { /* if secondary channel predmode is set to be > 2 */ - predmode += 3; + predmode = add( predmode, 3 ); tdm_SCh_LSF_intra_pred_fx( st->element_brate, tdm_lsfQ_PCh, pred3 ); } @@ -1704,14 +1709,14 @@ void lsf_end_enc_ivas_fx( test(); test(); test(); - IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) + if ( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) { /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); move16(); } - IF( st->pstreaklen == 0 ) + if ( st->pstreaklen == 0 ) { /* reset the consecutive AR-predictor multiplier */ st->streaklimit_fx = 32767; /*1.0 in Q15 */ @@ -1720,11 +1725,12 @@ void lsf_end_enc_ivas_fx( /* VOICED_WB@16kHz */ test(); + test(); IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( coder_type, VOICED ) && flag_1bit_gran == 0 ) { /* select safety_net or predictive */ safety_net = qlsf_Mode_Select_fx( wghts, Tmp2, st->streaklimit_fx, OP_LOOP_THR_HVO ); - IF( EQ_16( force_sf, 1 ) ) + if ( EQ_16( force_sf, 1 ) ) { safety_net = 1; move16(); @@ -1781,9 +1787,10 @@ void lsf_end_enc_ivas_fx( { Copy( ModeMeans_fx[mode_lvq], pred0, M ); - IF( EQ_16( predmode, 4 ) ) + if ( EQ_16( predmode, 4 ) ) { mode_lvq_p = 9; /* force to Generic WB with AR*/ + move16(); } FOR( i = 0; i < M; i++ ) @@ -1803,16 +1810,17 @@ void lsf_end_enc_ivas_fx( move16(); } - IF( EQ_16( st->pstreaklen, 0 ) ) + if ( st->pstreaklen == 0 ) { /* reset the adaptive scaling factor */ st->streaklimit_fx = 32767; + move16(); } /* intra pred */ /* use G AR pred for the intra mode (as a safety mode, this is why the indexes 0/1 are interchanged)*/ - lsf_allocate_fx( nBits - 1, mode_lvq, 9, &stages1, &stages0, levels1, levels0, bits1, bits0 ); + lsf_allocate_fx( sub( nBits, 1 ), mode_lvq, 9, &stages1, &stages0, levels1, levels0, bits1, bits0 ); Err[0] = vq_lvq_lsf_enc_ivas_fx( 2, 9, Tmp2, levels0, stages0, wghts, Idx0, lsf, pred3, &resq[M], &lsfq[M] ); IF( force_sf ) { @@ -1828,12 +1836,16 @@ void lsf_end_enc_ivas_fx( IF( LT_32( Mult_32_16( Err[0], ( st->streaklimit_fx ) ), L_add( Err[1], Mult_32_16( Err[1], PREFERSFNET_FX ) ) ) ) { safety_net = 1; + move16(); st->pstreaklen = 0; /* Reset the consecutive predictive frame counter */ + move16(); } ELSE { safety_net = 0; - ( st->pstreaklen )++; /* Increase the consecutive predictive frame counter by one */ + move16(); + st->pstreaklen = add( st->pstreaklen, 1 ); /* Increase the consecutive predictive frame counter by one */ + move16(); } } } @@ -1842,22 +1854,25 @@ void lsf_end_enc_ivas_fx( * Write indices to array *--------------------------------------------------------------------------*/ + test(); IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->core, ACELP_CORE ) ) { /* write coder_type bit for VOICED@16kHz or GENERIC@16kHz */ test(); + test(); IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && ( st->idchan == 0 ) ) { /* VOICED =2 and GENERIC=3, so "coder_type-2" means VOICED =0 and GENERIC=1*/ - push_indice_fx( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); + push_indice( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); } /* write predictor selection bit */ IF( GE_16( predmode, 2 ) ) { - push_indice_fx( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); + push_indice( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); } + test(); test(); IF( EQ_16( coder_type, VOICED ) && EQ_32( st->sr_core, INT_FS_16k ) && flag_1bit_gran == 0 ) { @@ -1866,7 +1881,7 @@ void lsf_end_enc_ivas_fx( Bit_alloc1 = &BC_TCVQ_BIT_ALLOC_40B[1]; FOR( i = 0; i < ( M / 2 ) + 3; i++ ) { - push_indice_fx( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); + push_indice( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); } } ELSE @@ -1907,7 +1922,7 @@ void lsf_end_enc_ivas_fx( move16(); cumleft -= num_bits; move16(); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); } WHILE( cumleft > 0 ) @@ -1927,7 +1942,7 @@ void lsf_end_enc_ivas_fx( } cumleft = sub( cumleft, num_bits ); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); i = add( i, 1 ); } } @@ -1935,7 +1950,8 @@ void lsf_end_enc_ivas_fx( ELSE { test(); - IF( EQ_16( coder_type, VOICED ) && EQ_32( st->sr_core, INT_FS_16k ) ) + test(); + IF( EQ_16( coder_type, VOICED ) && EQ_32( st->sr_core, INT_FS_16k ) && flag_1bit_gran == 0 ) { /* BC-TCVQ (only for VOICED@16kHz) */ /* Number of quantization indices */ @@ -2028,6 +2044,7 @@ void lsf_end_enc_ivas_fx( { /* Safety-net */ test(); + test(); IF( EQ_16( coder_type, VOICED ) && EQ_32( st->sr_core, INT_FS_16k ) && flag_1bit_gran == 0 ) { /* BC-TCQ */ @@ -2039,9 +2056,9 @@ void lsf_end_enc_ivas_fx( IF( EQ_16( st->tdm_LRTD_flag, 0 ) && EQ_16( st->idchan, 1 ) && tdm_lsfQ_PCh != NULL ) { /* intra mode*/ - Vr_subt( qlsf, pred1, st->mem_MA_fx, M ); vq_dec_lvq_ivas_fx( 0, qlsf, &indice[0], stages0, M, 9, levels0[stages0 - 1] ); Vr_add( qlsf, pred3, qlsf, M ); + Vr_subt( qlsf, pred1, st->mem_MA_fx, M ); } ELSE { @@ -3849,7 +3866,7 @@ static void lsf_mid_enc_ivas_fx( /* convert LSFs back to LSPs */ lsf2lsp_fx( qlsf, lsp, M, int_fs ); - push_indice_fx( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); + push_indice( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); return; } diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index fdb1ab0fc..0d2ea4a2a 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -723,6 +723,41 @@ Word16 enc_lsf_tcxlpc_fx( } return NumBits; } +#ifdef IVAS_FLOAT_FIXED +Word16 enc_lsf_tcxlpc_ivas_fx( + const Word16 **indices, /* i : Ptr to VQ indices */ + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +) +{ + Word16 i, NumBits; + + Word16 flag; + + /* Read flag */ + flag = ( *indices )[0]; + move16(); + ++*indices; + + NumBits = TCXLPC_NUMBITS; + move16(); + FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i ) + { + push_next_indice( hBstr, **indices, lsf_numbits[i] ); + ++*indices; + } + + IF( flag ) + { + NumBits = add( NumBits, TCXLPC_IND_NUMBITS ); + FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i ) + { + push_next_indice( hBstr, **indices, lsf_ind_numbits[i] ); + ++*indices; + } + } + return NumBits; +} +#endif /*--------------------------------------------------------------------------* * lsf_msvq_ma_encprm_fx() @@ -767,7 +802,45 @@ Word16 lsf_msvq_ma_encprm_fx( return nbits_lpc; } +#ifdef IVAS_FLOAT_FIXED +Word16 lsf_msvq_ma_encprm_ivas_fx( + BSTR_ENC_HANDLE hBstr, + const Word16 *param_lpc, + const Word16 core, + const Word16 acelp_mode, + const Word16 acelp_midLpc, + const Word16 *bits_param_lpc, + const Word16 no_indices ) +{ + Word16 i, nbits_lpc; + Word16 bits_midlpc; + bits_midlpc = MIDLSF_NBITS; + move16(); + nbits_lpc = 0; + move16(); + + FOR( i = 0; i < no_indices; i++ ) + { + + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); + param_lpc++; + nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); + } + IF( NE_16( acelp_mode, VOICED ) ) + { + test(); + IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + { + + push_next_indice( hBstr, *param_lpc, bits_midlpc ); + nbits_lpc = add( nbits_lpc, bits_midlpc ); + } + } + + return nbits_lpc; +} +#endif /*--------------------------------------------------------------------------* * lsf_bctcvq_encprm_fx() @@ -793,3 +866,25 @@ Word16 lsf_bctcvq_encprm_fx( return nbits_lpc; } +#ifdef IVAS_FLOAT_FIXED +Word16 lsf_bctcvq_encprm_ivas_fx( + BSTR_ENC_HANDLE hBstr, + const Word16 *param_lpc, + const Word16 *bits_param_lpc, + const Word16 no_indices ) +{ + Word16 i, nbits_lpc; + + nbits_lpc = 0; + move16(); + + FOR( i = 0; i < no_indices; i++ ) + { + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); + param_lpc++; + nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); + } + + return nbits_lpc; +} +#endif diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 6598d2f43..37fc691ab 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -868,6 +868,17 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, */ void RunTransientDetection_fx( Word16 const *i, Word16 nSamplesAvailable, struct TransientDetection *pTransientDetection ); +#ifdef IVAS_FLOAT_FIXED +/** Get the average temporal flatness measure using subblock energies aligned with the TCX. + * @param pTransientDetection Structure that contains transient detectors to be run. + * @param nCurrentSubblocks Number of the subblocks from the current frame to use for the calculation. + A lookeahead can also be use if it exists. + * @param nPrevSubblocks Number of subblocks from the previous frames to use for the calculation. + * @return average temporal flatness measure with exponent AVG_FLAT_E + */ +Word16 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( TRAN_DET_HANDLE hTranDet, const Word16 nCurrentSubblocks, const Word16 nPrevSubblocks, Word16 *exp_out ); +#endif + /** Get the average temporal flatness measure using subblock energies aligned with the TCX. * @param pTransientDetection Structure that contains transient detectors to be run. * @param nCurrentSubblocks Number of the subblocks from the current frame to use for the calculation. @@ -889,6 +900,18 @@ Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDete const Word16 nCurrentSubblocks, const Word16 nPrevSubblocks ); +#ifdef IVAS_FLOAT_FIXED +/** Set TCX window length and overlap configuration + * @param prevEnergyHF previous HF energy. Exponent must be the same as for currEnergyHF. + * @param currEnergyHF current HF energy. Exponent must be the same as for prevEnergyHF. + */ +void SetTCXModeInfo_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ + Word16 *tcxModeOverlap /* o : window overlap of current frame */ +); +#endif + /** Set TCX window length and overlap configuration * @param prevEnergyHF previous HF energy. Exponent must be the same as for currEnergyHF. * @param currEnergyHF current HF energy. Exponent must be the same as for prevEnergyHF. @@ -1215,6 +1238,12 @@ Word16 WriteTnsData_fx( STnsConfig const *pTnsConfig, Encoder_State *st, Word16 *pnBits ); +Word16 WriteTnsData_ivas_fx( STnsConfig const *pTnsConfig, + Word16 const *stream, + Word16 *pnSize, + BSTR_ENC_HANDLE hBstr, + Word16 *pnBits ); + void subband_FFT_fx( Word32 **Sr, /*(i) real part of the CLDFB*/ Word32 **Si, /*(i) imag part of the CLDFB*/ @@ -2022,6 +2051,13 @@ Word16 EncodeIndex_fx( Word16 PeriodicityIndex, BSTR_ENC_HANDLE hBst /* i/o: bitstream handle */ ); + +Word16 EncodeIndex_ivas_fx( + const Word16 Bandwidth, /* 0: NB, 1: (S)WB */ + Word16 PeriodicityIndex, + BSTR_ENC_HANDLE hBst /* i/o: bitstream handle */ +); + void enc_prm_side_Info_fx( PLC_ENC_EVS_HANDLE hPlc_Ext, Encoder_State *st ); /* Returns: number of bits written */ @@ -2030,6 +2066,12 @@ Word16 enc_lsf_tcxlpc_fx( BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ ); +/* Returns: number of bits written */ +Word16 enc_lsf_tcxlpc_ivas_fx( + const Word16 **indices, /* i : Ptr to VQ indices */ + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +); + Word16 encode_lpc_avq_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ const Word16 numlpc, /* i : Number of sets of lpc */ @@ -2038,12 +2080,26 @@ Word16 encode_lpc_avq_fx( const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ ); +Word16 encode_lpc_avq_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 numlpc, /* i : Number of sets of lpc */ + const Word16 *param_lpc, /* i : lpc parameters */ + const Word16 core, /* i : core */ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ +); + Word16 lsf_bctcvq_encprm_fx( BSTR_ENC_HANDLE hBstr, Word16 *param_lpc, Word16 *bits_param_lpc, Word16 no_indices ); +Word16 lsf_bctcvq_encprm_ivas_fx( + BSTR_ENC_HANDLE hBstr, + const Word16 *param_lpc, + const Word16 *bits_param_lpc, + const Word16 no_indices ); + Word16 lsf_msvq_ma_encprm_fx( BSTR_ENC_HANDLE hBstr, Word16 *param_lpc, @@ -2053,6 +2109,15 @@ Word16 lsf_msvq_ma_encprm_fx( Word16 *bits_param_lpc, Word16 no_indices ); +Word16 lsf_msvq_ma_encprm_ivas_fx( + BSTR_ENC_HANDLE hBstr, + const Word16 *param_lpc, + const Word16 core, + const Word16 acelp_mode, + const Word16 acelp_midLpc, + const Word16 *bits_param_lpc, + const Word16 no_indices ); + Word16 IGFEncWriteBitstream_fx( /**< out: | number of bits written per frame */ const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -2075,6 +2140,11 @@ Word16 IGFEncWriteConcatenatedBitstream_fx( BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ ); +Word16 IGFEncWriteConcatenatedBitstream_ivas_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +); + void signalling_enc_rf( Encoder_State *st /* i : encoder state structure */ ); @@ -2949,6 +3019,15 @@ void hq_lr_enc_fx( const Word16 is_transient_fx /* i : Q0 : transient flag */ ); +void hq_lr_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: : encoder state structure */ + Word32 L_t_audio[], /* i/o: Q12 : transform-domain coefs. */ + const Word16 inner_frame_fx, /* i : Q0 : inner frame length */ + Word16 *num_bits_fx, /* i/o: Q0 : number of available bits */ + const Word16 is_transient_fx /* i : Q0 : transient flag */ +); + + void hq_hr_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure fx */ Word32 *t_audio, /* i/o: transform-domain coefficients Q12 */ @@ -2958,6 +3037,15 @@ void hq_hr_enc_fx( const Word16 vad_hover_flag /* i : VAD hangover flag */ ); +void hq_hr_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure fx */ + Word32 *t_audio, /* i/o: transform-domain coefficients Q12 */ + const Word16 length, /* i : length of spectrum Q0 */ + Word16 *num_bits, /* i : number of available bits Q0 */ + const Word16 is_transient, /* i : transient flag Q0 */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ +); + void reordernorm_fx( const Word16 *ynrm, /* i : quantization indices for norms Q0 */ const Word16 *normqlg2, /* i : quantized norms Q0 */ @@ -2993,16 +3081,16 @@ void diff_envelope_coding_fx( Word16 *difidx /* o : differential code Q0 */ ); -Word16 encode_envelope_indices_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 num_sfm, /* i : Number of subbands Q0 */ - const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ - Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ - Word16 *LCmode, /* o : Coding mode if flag_pack=0, i : if flag_pack=1 Q0 */ - const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0 */ - const Word16 flag_HQ2 /* i : indicator of HQ2 core Q0 */ - , - const Word16 is_transient /* i : indicator of HQ_TRANSIENT Q0 */ +Word16 encode_envelope_indices_ivas_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + const Word16 num_sfm, /* i : Number of subbands Q0 */ + const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ + Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ + Word16 *LCmode, /* o : Coding mode if flag_pack=0, i : if flag_pack=1 Q0 */ + const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0 */ + const Word16 flag_HQ2 /* i : indicator of HQ2 core Q0 */ + , + const Word16 is_transient /* i : indicator of HQ_TRANSIENT Q0 */ ); void hq_generic_encoding_fx( @@ -3082,6 +3170,27 @@ ivas_error tcq_core_LR_enc_fx( const Word16 adjustFlag, const Word16 is_transient ); + +ivas_error tcq_core_LR_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word32 inp_vector[], + const Word32 coefs_norm_fx[], + Word32 coefs_quant_fx[], + const Word16 bit_budget, /* number of bits */ + const Word16 BANDS, + const Word16 *sfm_start, + const Word16 *sfm_end, + const Word16 *sfmsize, + Word32 *Rk_fx, + Word16 *npulses, + Word16 *k_sort, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame, + const Word16 adjustFlag, + const Word16 is_transient ); + Word16 encode_envelope_indices_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ const Word16 num_sfm, /* i : Number of subbands Q0 */ @@ -3420,4 +3529,13 @@ void amr_wb_enc_fx( const Word16 input_sp[], /* i : i signal */ const Word16 n_samples /* i : number of i samples */ ); + +void writeLPCparam_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 param_lpc[], /* i : LPC parameters to write */ + const Word16 bits_param_lpc[], /* i : bits per LPC parameter */ + const Word16 no_param_lpc, /* i : number of LPC parameters */ + Word16 *nbits_lpc /* o : LPC bits written */ +); #endif diff --git a/lib_enc/qlpc_avq_fx.c b/lib_enc/qlpc_avq_fx.c index 2740eac14..2ff68b43e 100644 --- a/lib_enc/qlpc_avq_fx.c +++ b/lib_enc/qlpc_avq_fx.c @@ -150,6 +150,29 @@ static Word16 unary_code( Word16 ind, BSTR_ENC_HANDLE hBstr ) return ( nb_bits ); } +#ifdef IVAS_FLOAT_FIXED +static Word16 unary_code_ivas_fx( Word16 ind, BSTR_ENC_HANDLE hBstr ) +{ + Word16 nb_bits; + + move16(); + nb_bits = 1; + + /* Index bits */ + ind = sub( ind, 1 ); + + FOR( ; ind > 0; ind-- ) + { + push_next_indice( hBstr, 1, 1 ); + nb_bits = add( nb_bits, 1 ); + } + + /* Stop bit */ + push_next_indice( hBstr, 0, 1 ); + + return ( nb_bits ); +} +#endif /*-------------------------------------------------------------------* * unpack4bits() * @@ -181,6 +204,34 @@ static Word16 unpack4bits( Word16 nbits, const Word16 *prm, BSTR_ENC_HANDLE hBst return ( i ); } +#ifdef IVAS_FLOAT_FIXED +static Word16 unpack4bits_ivas_fx( Word16 nbits, const Word16 *prm, BSTR_ENC_HANDLE hBstr ) +{ + Word16 i; + + IF( nbits == 0 ) + { + push_next_indice( hBstr, 0, 0 ); + i = 1; + move16(); + } + ELSE + { + move16(); + i = 0; + + FOR( ; nbits > 4; nbits -= 4 ) + { + push_next_indice( hBstr, prm[i], 4 ); + i = add( i, 1 ); + } + push_next_indice( hBstr, prm[i], nbits ); + i = add( i, 1 ); + } + + return ( i ); +} +#endif /*-------------------------------------------------------------------* * encode_lpc_avq_fx() * @@ -395,3 +446,215 @@ Word16 encode_lpc_avq_fx( return ( nb_bits ); } + +#ifdef IVAS_FLOAT_FIXED +Word16 encode_lpc_avq_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 numlpc, /* i : Number of sets of lpc */ + const Word16 *param_lpc, /* i : lpc parameters */ + const Word16 core, /* i : core */ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ +) +{ + Word16 k, j; + Word16 q_type, nb_ind; + Word16 i, qn1, qn2, nb, avqBits, st1; + Word16 nb_bits; + Word16 stereo_mode, bits_for_abs_quant; + + stereo_mode = 0; + move16(); + bits_for_abs_quant = LPC_ABS_QUANT_BITS; + move16(); + if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + { + bits_for_abs_quant = SNS_ABS_QUANT_BITS; + move16(); + } + + move16(); + move16(); + move16(); + st1 = 0; + j = 0; + nb_bits = 0; + + FOR( k = 0; k < numlpc; k++ ) + { + /* Retrieve quantizer type */ + + + move16(); + q_type = 0; + IF( k != 0 ) + { + move16(); + q_type = param_lpc[j]; + j = add( j, 1 ); + } + test(); + IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && k == 0 ) + { + stereo_mode = param_lpc[j]; + move16(); + j = add( j, 1 ); + } + /* Determine number of AVQ indices */ + move16(); + nb_ind = 0; + + IF( q_type == 0 ) + { + move16(); + st1 = param_lpc[j]; + j = add( j, 1 ); + } + move16(); + move16(); + qn1 = param_lpc[j]; + j = add( j, 1 ); + qn2 = param_lpc[j]; + j = add( j, 1 ); + IF( NE_16( qn1, SNS_LOW_BR_MODE ) ) + { + nb_ind = add( nb_ind, add( qn1, qn2 ) ); + } + + test(); + test(); + IF( k == 0 || ( EQ_16( k, 1 ) && NE_16( core, TCX_20_CORE ) ) ) + { + /* Encode quantizer type */ + move16(); + nb = 0; + IF( k != 0 ) + { + nb = 1; + move16(); + push_next_indice( hBstr, q_type, nb ); + } + nb_bits = add( nb_bits, nb ); + + /* Encode quantizer data */ + test(); + test(); + test(); + test(); + IF( ( ( q_type == 0 ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) || ( ( q_type == 0 ) && ( st1 >= 0 ) && EQ_16( element_mode, IVAS_CPE_MDCT ) ) ) + { + /* Absolute quantizer with 1st stage stochastic codebook */ + push_next_indice( hBstr, st1, bits_for_abs_quant ); + nb_bits = add( nb_bits, bits_for_abs_quant ); + } + + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && EQ_16( stereo_mode, 3 ) && st1 < 0 ) + { + push_next_indice( hBstr, add( st1, 2 ), 1 ); + nb_bits = add( nb_bits, 1 ); + } + + test(); + test(); + IF( NE_16( element_mode, IVAS_CPE_MDCT ) || ( NE_16( st1, -2 ) && NE_16( qn1, SNS_LOW_BR_MODE ) ) ) + { + + /* 2 bits to specify Q2,Q3,Q4,ext */ + nb_bits = add( nb_bits, 4 ); + i = sub( qn1, 2 ); + + if ( s_or( i < 0, (Word16) GT_16( i, 3 ) ) ) + { + move16(); + i = 3; + } + push_next_indice( hBstr, i, 2 ); + + i = sub( qn2, 2 ); + + if ( s_or( i < 0, (Word16) GT_16( i, 3 ) ) ) + { + move16(); + i = 3; + } + push_next_indice( hBstr, i, 2 ); + + /* Unary code for abs and rel LPC0/LPC2 */ + /* Q5 = 0, Q6=10, Q0=110, Q7=1110, ... */ + move16(); + nb = qn1; + + IF( GT_16( nb, 6 ) ) + { + nb = sub( nb, 3 ); + } + ELSE IF( GT_16( nb, 4 ) ) + { + nb = sub( nb, 4 ); + } + ELSE IF( nb == 0 ) + { + move16(); + nb = 3; + } + ELSE + { + move16(); + nb = 0; + } + + IF( nb > 0 ) + { + unary_code_ivas_fx( nb, hBstr ); + } + nb_bits = add( nb_bits, nb ); + + move16(); + nb = qn2; + + IF( GT_16( nb, 6 ) ) + { + nb = sub( nb, 3 ); + } + ELSE IF( GT_16( nb, 4 ) ) + { + nb = sub( nb, 4 ); + } + ELSE IF( nb == 0 ) + { + move16(); + nb = 3; + } + ELSE + { + move16(); + nb = 0; + } + + IF( nb > 0 ) + { + unary_code_ivas_fx( nb, hBstr ); + } + nb_bits = add( nb_bits, nb ); + + avqBits = shl( qn1, 2 ); + unpack4bits_ivas_fx( avqBits, ¶m_lpc[j], hBstr ); + j = add( j, qn1 ); + nb_bits = add( nb_bits, avqBits ); + + avqBits = shl( qn2, 2 ); + unpack4bits_ivas_fx( avqBits, ¶m_lpc[j], hBstr ); + j = add( j, qn2 ); + nb_bits = add( nb_bits, avqBits ); + } + } + ELSE + { + j = add( j, nb_ind ); + } + } + + return ( nb_bits ); +} +#endif diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index bff4b9b43..7e269230f 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -159,6 +159,10 @@ typedef struct Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; float subblockNrgChange_flt[NSUBBLOCKS + MAX_TD_DELAY]; /* subblockNrgChange[i] = max(subblockNrg[i]/subblockNrg[i-1], subblockNrg[i-1]/subblockNrg[i]) */ Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; +#ifdef IVAS_FLOAT_FIXED + Word32 subblockNrgChange_32[NSUBBLOCKS + MAX_TD_DELAY]; /* subblockNrgChange[i] = max(subblockNrg[i]/subblockNrg[i-1], subblockNrg[i-1]/subblockNrg[i]) */ + Word16 q_subblockNrgChange; +#endif int16_t nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ int16_t nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ @@ -1025,11 +1029,13 @@ typedef struct lpd_state_structure /* signal memory */ float syn_flt[1 + M]; /* Synthesis memory (non-pe) */ - Word16 syn[1 + M]; /* Synthesis memory (non-pe) */ /* ACELP memories*/ float old_exc_flt[L_EXC_MEM]; /* ACELP exc memory (Aq) */ - Word16 old_exc[L_EXC_MEM]; /* ACELP exc memory (Aq) */ + + Word16 syn[1 + M]; /* Synthesis memory (non-pe) */ + Word16 old_exc[L_EXC_MEM]; /* ACELP exc memory (Aq) */ + Word16 e_old_exc; float mem_w0_flt; float mem_syn_flt[M]; /* ACELP synthesis memory (pe) before post-proc */ @@ -1044,6 +1050,7 @@ typedef struct lpd_state_structure Word16 mem_syn_r[L_SYN_MEM]; /* ACELP synthesis memory for 1.25ms */ Word16 mem_syn3[M]; Word16 mem_w0; /* weighting filter memory */ + Word16 e_mem_syn; float tilt_code_flt; float gc_threshold_flt; /* Noise enhancer - threshold for gain_code */ @@ -1147,6 +1154,7 @@ typedef struct hq_enc_structure Word16 last_env_fx[BANDS_MAX]; int16_t last_max_pos_pulse; + } HQ_ENC_DATA, *HQ_ENC_HANDLE; /* PVQ range coder state */ @@ -1637,6 +1645,9 @@ typedef struct tcx_enc_structure uint16_t kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ uint16_t enc_ste_pre_corr_past; float tfm_mem; /* state of IIR filtered temporal flatness measure */ +#ifdef IVAS_FLOAT_FIXED + Word32 tfm_mem_fx; /* state of IIR filtered temporal flatness measure */ /* Q31 */ +#endif float buf_speech_ltp_flt[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; float *speech_ltp_flt; float *new_speech_ltp_flt; @@ -2389,9 +2400,9 @@ typedef struct enc_core_structure // // //#ifdef IVAS_CODE // -//#ifdef DEBUGGING +// #ifdef DEBUGGING // Word16 id_element; /* element ID */ -//#endif +// #endif // Word32 element_brate; /* element bitrate */ // Word16 extl_orig; /* extension layer */ // Word32 extl_brate_orig; /* extension layer bitrate */ diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index 8cca1104c..d43861d8b 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -36,6 +36,7 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" #include "enh32.h" +#include "prot.h" /*--------------------------------------------------------------------------* * GetSubbandCorrIndex2_har() @@ -1034,6 +1035,203 @@ static void EncodeSWBSubbands_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +static void EncodeSWBSubbands_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + Word32 *L_spectra, /* i/o: MDCT domain spectrum */ + Word16 QsL, /* i : Q value for L_spectra */ + const Word16 fLenLow_fx, /* i : lowband length */ + const Word16 fLenHigh_fx, /* i : highband length */ + const Word16 nBands_fx, /* i : number of subbands */ + const Word16 nBands_search_fx, /* i : number of subbands to be searched for BWE */ + const Word16 *sbWidth_fx, /* i : subband lengths */ + const Word16 *subband_offsets_fx, /* i : Subband offset for BWE */ + Word16 *lagIndices_fx, /* o : lowband index for each subband */ + const Word16 BANDS_fx, /* i : noise estimate from WB part */ + const Word16 *band_start_fx, /* i : Number subbands/Frame */ + const Word16 *band_end_fx, /* i : Band Start of each SB */ + Word32 *L_band_energy, /* i : Band end of each SB, :Qbe */ + Word16 Qbe, /* i : Q value of band energy */ + const Word16 *p2a_flags_fx, /* i : BAnd energy of each SB */ + const Word16 hqswb_clas_fx, /* i : lowband synthesis */ + Word16 *prev_frm_index_fx, /* i : clas information */ + const Word16 har_bands_fx, /* i/o: Index of the previous Frame */ + const Word16 *subband_search_offset_fx, /* i : Number of harmonic LF bands */ + Word16 *prev_frm_hfe2, /* i/o: */ + Word16 *prev_stab_hfe2, /* i/o: */ + const Word16 band_width_fx[], /* i : band width */ + const Word32 L_spectra_ni[], /* i : Qs noise injected spectra */ + Word16 *ni_seed_fx /* i/o: random seed */ +) +{ + Word16 i, k; + Word16 sspectra_fx[L_FRAME32k]; + Word16 sspectra_ni_fx[L_FRAME32k]; + Word16 sspectra_diff_fx[L_FRAME32k]; + Word16 Qss; /* Q value of Smoothed Spectrum low-subband */ + Word32 L_be_tonal[SWB_HAR_RAN1]; /* Q */ + Word16 ss_min_fx; /* Qss */ + Word32 L_th_g[NB_SWB_SUBBANDS]; + Word16 QbeL; + GainItem_fx pk_sf_fx[(NB_SWB_SUBBANDS) *8]; + Word16 pul_res_fx[NB_SWB_SUBBANDS]; + + GainItem_fx Nbiggest_fx[NB_SWB_SUBBANDS * N_NBIGGEST_PULSEARCH]; + + Word32 L_xSynth_har[L_FRAME32k]; /* Qs */ + + Word16 lagGains_fx[NB_SWB_SUBBANDS]; + Word16 QlagGains[NB_SWB_SUBBANDS]; + Word16 har_freq_est1, har_freq_est2; + Word16 flag_dis; + Word16 pos_max_hfe2; + HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; + + har_freq_est1 = 0; + move16(); + har_freq_est2 = 0; + move16(); + flag_dis = 1; + move16(); + pos_max_hfe2 = 0; + move16(); + + set16_fx( sspectra_fx, 0, fLenLow_fx ); + set16_fx( sspectra_ni_fx, 0, fLenLow_fx ); + set32_fx( L_xSynth_har, 0, L_FRAME32k ); + set16_fx( pul_res_fx, 0, NB_SWB_SUBBANDS ); + + + IF( EQ_16( hqswb_clas_fx, HQ_HARMONIC ) ) + { + pos_max_hfe2 = har_est_fx( L_spectra, fLenLow_fx, &har_freq_est1, &har_freq_est2, &flag_dis, prev_frm_hfe2, subband_search_offset_fx, sbWidth_fx, prev_stab_hfe2 ); + noise_extr_corcod_fx( L_spectra, L_spectra_ni, sspectra_fx, sspectra_diff_fx, sspectra_ni_fx, fLenLow_fx, hHQ_core->prev_hqswb_clas, &hHQ_core->prev_ni_ratio_fx, &Qss ); + /* Find best indices for each group */ + getswbindices_har_fx( + L_spectra, + QsL, sspectra_ni_fx, + nBands_search_fx, lagIndices_fx, prev_frm_index_fx, fLenLow_fx, subband_offsets_fx, sbWidth_fx, subband_search_offset_fx ); + + /* Write the indices into the bitstream */ + FOR( k = 0; k < nBands_search_fx; k++ ) + { + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_mode0_Har[k] ); + } + + IF( flag_dis == 0 ) + { + test(); + if ( NE_16( har_freq_est2, SWB_HAR_RAN1 ) || NE_16( har_freq_est2, *prev_frm_hfe2 ) ) + { + har_freq_est2 = add( har_freq_est2, lagIndices_fx[0] ); + move16(); + } + } + + gethar_noisegn_fx( st_fx->hBstr, L_spectra, QsL, sspectra_diff_fx, Qss, L_xSynth_har, + sbWidth_fx, lagIndices_fx, BANDS_fx, har_bands_fx, fLenLow_fx, fLenHigh_fx, + subband_offsets_fx, subband_search_offset_fx, band_start_fx, band_end_fx, band_width_fx, + L_band_energy, Qbe, L_be_tonal, &QbeL, sspectra_fx, + har_freq_est2, pos_max_hfe2, pul_res_fx, pk_sf_fx ); + + + Gettonl_scalfact_fx( L_xSynth_har, QsL, L_spectra_ni, fLenLow_fx, fLenHigh_fx, har_bands_fx, BANDS_fx, L_band_energy, Qbe, band_start_fx, band_end_fx, + p2a_flags_fx, L_be_tonal, QbeL, pk_sf_fx, Qss, pul_res_fx ); + + IF( flag_dis == 0 ) + { + *prev_frm_hfe2 = 0; + move16(); + } + ELSE + { + *prev_frm_hfe2 = har_freq_est2; + move16(); + } + + FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_xSynth_har[i - fLenLow_fx]; + move32(); /* QsL */ + } + } + } + ELSE + { + ss_min_fx = spectrumsmooth_noiseton_fx( L_spectra, /*QsL,*/ L_spectra_ni, sspectra_fx, sspectra_diff_fx, sspectra_ni_fx, &Qss, fLenLow_fx, ni_seed_fx ); + + /* Get lag indices */ + GetSWBIndices_fx( sspectra_fx, /*Qss,*/ L_spectra + fLenLow_fx, QsL, nBands_fx, sbWidth_fx, lagIndices_fx, fLenLow_fx, + Nbiggest_fx, subband_offsets_fx, sspectra_fx ); + + /* Bitstream operations */ + FOR( k = 0; k < nBands_fx; k++ ) + { + IF( EQ_16( p2a_flags_fx[BANDS_fx - NB_SWB_SUBBANDS + k], 1 ) ) + { + lagIndices_fx[k] = 0; + move16(); + lagGains_fx[k] = 0; + move16(); + QlagGains[k] = 15; + move16(); + } + ELSE + { + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_modeNormal[k] ); + } + } + + convert_lagIndices_pls2smp_fx( lagIndices_fx, nBands_fx, lagIndices_fx, sspectra_fx, sbWidth_fx, fLenLow_fx ); + + GetlagGains_fx( sspectra_ni_fx, Qss, &L_band_energy[BANDS_fx - NB_SWB_SUBBANDS], Qbe, nBands_fx, sbWidth_fx, lagIndices_fx, fLenLow_fx, lagGains_fx, QlagGains ); + FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) + { + lagGains_fx[k] = mult_r( lagGains_fx[k], 29491 ); /* lagGains[k]*0.9f; */ + } + + FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) + { + L_th_g[k] = L_deposit_l( 0 ); + IF( p2a_flags_fx[BANDS_fx - NB_SWB_SUBBANDS + k] == 0 ) + { + L_th_g[k] = L_shl( L_mult( lagGains_fx[k], ss_min_fx ), sub( QsL, add( add( QlagGains[k], Qss ), 1 ) ) ); /* QlagGain+Qss -> QsL */ + } + } + + GetSynthesizedSpecThinOut_fx( sspectra_ni_fx, Qss, L_xSynth_har, QsL, nBands_fx, sbWidth_fx, lagIndices_fx, lagGains_fx, QlagGains, fLenLow_fx ); + + /*Level adjustment for the missing bands*/ + noiseinj_hf_fx( L_xSynth_har, QsL, L_th_g, L_band_energy, Qbe, hHQ_core->prev_En_sb_fx, p2a_flags_fx, BANDS_fx, band_start_fx, band_end_fx, fLenLow_fx, fLenHigh_fx ); + + + FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) + { + IF( p2a_flags_fx[k] == 0 ) + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_xSynth_har[i - fLenLow_fx]; + move32(); /* Qob */ + } + } + ELSE + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_spectra_ni[i]; + move32(); + } + } + } + } + + return; +} +#endif /*--------------------------------------------------------------------------* * swb_bwe_enc_lr() * @@ -1121,3 +1319,88 @@ void swb_bwe_enc_lr_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +void swb_bwe_enc_lr_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 L_m_core[], /* i : lowband synthesis */ + Word16 QsL, /* i : Q value */ + const Word32 L_m_orig[], /* i/o: scaled orig signal (MDCT) */ + Word32 L_m[], /* o : highband synthesis with lowband zeroed */ + const Word32 L_total_brate, /* i : total bitrate for selecting subband pattern */ + Word16 BANDS_fx, /* i : Total number of Subbands in a frame */ + Word16 *band_start_fx, /* i : band start of each SB */ + Word16 *band_end_fx, /* i : band end of each SB */ + Word32 *L_band_energy, /* i : band_energy of each SB */ + Word16 Qbe, /* i : Q value of band energy */ + Word16 *p2a_flags_fx, /* i : HF tonal indicator */ + const Word16 hqswb_clas_fx, /* i : HQ_NORMAL2 or HQ_HARMONIC mode */ + Word16 lowlength_fx, /* i : lowband length */ + Word16 highlength_fx, /* i : highband length */ + Word16 *prev_frm_index_fx, /* i/o: previous frame lag index for harmonic mode */ + const Word16 har_bands_fx, /* i : Number of LF harmonic bands */ + Word16 *prev_frm_hfe2, /* i/o: */ + Word16 *prev_stab_hfe2, /* i/o: */ + const Word16 band_width_fx[], /* i : band_width information */ + const Word32 L_y2_ni[], /* i : band_width information */ + Word16 *ni_seed_fx /* i/o: random seed for search buffer NI */ +) +{ + Word16 k; + Word16 nBands_fx; + Word16 nBands_search_fx; + Word16 wBands_fx[NB_SWB_SUBBANDS]; + Word16 lagIndices_fx[NB_SWB_SUBBANDS]; + Word16 swb_lowband_fx, swb_highband_fx, allband_fx; + + const Word16 *subband_offsets_fx; + const Word16 *subband_search_offset_fx; + + Word32 *p_L_m; + + subband_search_offset_fx = subband_search_offsets_13p2kbps_Har; + subband_offsets_fx = subband_offsets_sub5_13p2kbps_Har; + + hf_parinitiz_fx( L_total_brate, hqswb_clas_fx, lowlength_fx, highlength_fx, wBands_fx, &subband_search_offset_fx, &subband_offsets_fx, &nBands_fx, &nBands_search_fx, &swb_lowband_fx, &swb_highband_fx ); + allband_fx = add( swb_lowband_fx, swb_highband_fx ); + move16(); + + /* Prepare m[], low part from WB core, high part from 32k input */ + Copy32( L_m_core, L_m, swb_lowband_fx ); + Copy32( &L_m_orig[swb_lowband_fx], &L_m[swb_lowband_fx], swb_highband_fx ); + + EncodeSWBSubbands_ivas_fx( + st_fx, + L_m, QsL, + swb_lowband_fx, swb_highband_fx, nBands_fx, nBands_search_fx, wBands_fx, subband_offsets_fx, + lagIndices_fx, + BANDS_fx, band_start_fx, band_end_fx, + L_band_energy, Qbe, + p2a_flags_fx, + hqswb_clas_fx, prev_frm_index_fx, har_bands_fx, subband_search_offset_fx, + prev_frm_hfe2, prev_stab_hfe2, + band_width_fx, L_y2_ni, ni_seed_fx ); + + p_L_m = &L_m[sub( allband_fx, 1 )]; + *p_L_m = Mult_32_16( *p_L_m, 2028 ); + move32(); + p_L_m--; /* 0.0625 = 2028 (Q15) */ + *p_L_m = Mult_32_16( *p_L_m, 4096 ); + move32(); + p_L_m--; /* 0.125 = 4096 (Q15) */ + *p_L_m = Mult_32_16( *p_L_m, 8192 ); + move32(); + p_L_m--; /* 0.25 = 8192 (Q15) */ + *p_L_m = Mult_32_16( *p_L_m, 16384 ); + move32(); + p_L_m--; /* 0.5 = 16384 (Q15) */ + + /* set low frequencies to zero */ + FOR( k = 0; k < swb_lowband_fx; k++ ) + { + L_m[k] = L_deposit_l( 0 ); + } + + return; +} +#endif diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index 29ea322b6..7ff5a9637 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -5,11 +5,13 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -//#include "prot_fx.h" +// #include "prot_fx.h" #include "rom_com.h" #include "ivas_error.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "prot.h" +#define IVAS_FLOAT ivas_error tcq_core_LR_enc_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -470,5 +472,485 @@ ivas_error tcq_core_LR_enc_fx( } + return error; +} + +ivas_error tcq_core_LR_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word32 inp_vector_fx[], /* x5 */ + const Word32 coefs_norm_fx[], /* Q12 */ + Word32 coefs_quant_fx[], /* Q12 */ + const Word16 bit_budget, /* number of bits */ + const Word16 BANDS, + const Word16 *sfm_start, + const Word16 *sfm_end, + const Word16 *sfmsize, + Word32 *R_fx, /* Q16 */ + Word16 *npulses, + Word16 *k_sort, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame, + const Word16 adjustFlag, + const Word16 is_transient ) +{ + Word16 i, j, k, size, nb_bytes; + + Word16 USQ_TCQ[NB_SFM]; /* TCQ is selected by default*/ + Word16 coefs_norm_dec_fx[L_FRAME32k]; /* New output buffer (TCQ+USQ)*/ + Word32 savedstates[TCQ_MAX_BAND_SIZE]; + ARCODEC arenc_fx, *parenc_fx; + TCQ_BITSTREAM bs_fx, *pbs_fx; + Word16 k_num[2]; + Word32 bit_surplus_fx[2]; + + Word16 flag_wbnb = 0; + Word16 lsbtcq_bits = TCQ_AMP; + Word16 tcq_arbits = 2; + Word16 nzb = 0; + Word16 nzbands = 0; + Word16 bcount = 0; + Word32 bsub_fx = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + Word32 abuffer_fx[MAX_PULSES]; + Word16 mbuffer_fx[MAX_PULSES]; + Word32 sbuffer_fx[MAX_PULSES]; + Word16 dpath[280]; + Word32 Rk_sort_fx[NB_SFM]; + Word32 step_scale_fx[NB_SFM]; + Word16 pulses_fx, nzp_fx; + + Word32 gain_fx, crosscorr_fx, selfcorr_fx; + Word16 hi, lo, exp; + Word32 surplus_fx, delta_fx, est_frame_bits_fx; + + Word32 leftbits = 0; + Word32 sepbits = 0; + Word32 divider = 0; + move16(); + move16(); + move16(); + ivas_error error; + + error = IVAS_ERR_OK; + move16(); + set16_fx( dpath, 0, 280 ); + set32_fx( abuffer_fx, 0, MAX_PULSES ); + set32_fx( sbuffer_fx, 0, MAX_PULSES ); + set16_fx( mbuffer_fx, 0, MAX_PULSES ); + /* initialization */ + set32_fx( Rk_sort_fx, 0, NB_SFM ); + set16_fx( USQ_TCQ, 0, NB_SFM ); + set16_fx( coefs_norm_dec_fx, 0, L_FRAME32k ); + + InitLSBTCQ_fx( &bcount ); + + test(); + test(); + IF( LE_16( input_frame, L_FRAME16k ) && adjustFlag == 0 && is_transient == 0 ) + { + flag_wbnb = 1; + move16(); + lsbtcq_bits = 0; + move16(); + tcq_arbits = 0; + move16(); + } + + /* TCQ Index initialize */ + parenc_fx = &arenc_fx; + pbs_fx = &bs_fx; + + pbs_fx->curPos = 7; + move16(); + pbs_fx->numbits = L_deposit_l( 0 ); + pbs_fx->numByte = L_deposit_l( 0 ); + move32(); + move32(); + FOR( i = 0; i < MAX_SIZEBUF_PBITSTREAM; i++ ) + { + pbs_fx->buf[i] = 0; + move16(); + } + ar_encoder_start_fx( parenc_fx, pbs_fx, L_deposit_l( bit_budget ) ); + + /* Bits distribution analysis */ + FOR( i = 0; i < BANDS; i++ ) + { + IF( GE_32( ar_div( R_fx[i], sfmsize[i] ), 49152 ) ) + { + /* USQ used for high importance bands*/ + USQ_TCQ[i] = 1; + move16(); + } + ELSE + { + /* TCQ used for usual bands */ + USQ_TCQ[i] = 0; + move16(); + } + + IF( R_fx[i] > 0 ) + { + /* nzbands++; */ + nzbands = add( nzbands, 1 ); + } + } + + FOR( j = 0; j < BANDS; j++ ) + { + IF( R_fx[j] > 0 ) + { + nzb = add( nzb, 1 ); + } + } + + bsub_fx = L_shl( add( tcq_arbits, lsbtcq_bits ), 16 ); /* Q16 */ + IF( bsub_fx > 0 ) + { + bsub_fx = L_add( bsub_fx, 2048 ); + } + FOR( j = BANDS - 1; j >= 0; j-- ) + { + IF( R_fx[j] > 0 ) + { + R_fx[j] = L_sub( R_fx[j], ar_div( bsub_fx, nzb ) ); + + IF( R_fx[j] < 0 ) + { + bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), R_fx[j] ) ); + R_fx[j] = L_deposit_l( 0 ); + } + ELSE + { + bsub_fx = L_sub( bsub_fx, ar_div( bsub_fx, nzb ) ); + } + /* nzb--; */ + nzb = sub( nzb, 1 ); + } + } + + /* Sort the bit allocation table (R) in ascending order, figure out number of pulses per band */ + srt_vec_ind_fx( R_fx, Rk_sort_fx, k_sort, BANDS ); + + /* Quantize spectral band shapes using TCQ */ + /* Select ISC */ + set32_fx( coefs_quant_fx, 0, add( sfm_end[BANDS - 1], 1 ) ); + Copy32( coefs_norm_fx, coefs_quant_fx, add( sfm_end[BANDS - 1], 1 ) ); + + delta_fx = L_deposit_l( 0 ); + est_frame_bits_fx = L_deposit_l( 0 ); + + test(); + test(); + IF( LE_16( input_frame, L_FRAME16k ) && adjustFlag == 0 && is_transient == 0 ) + { + surplus_fx = -131072; + move32(); + bit_allocation_second_fx( R_fx, Rk_sort_fx, BANDS, sfmsize, k_sort, k_num, p2a_flags, p2a_bands, last_bitalloc, input_frame ); + + nzbands = 0; + move16(); + FOR( j = 0; j < BANDS; j++ ) + { + IF( NE_16( j, k_num[0] ) && NE_16( j, k_num[1] ) ) + { + leftbits = L_add( leftbits, R_fx[k_sort[j]] ); + if ( R_fx[k_sort[j]] > 0 ) + { + nzbands = add( nzbands, 1 ); + } + } + ELSE + { + sepbits = L_add( sepbits, R_fx[k_sort[j]] ); + } + } + /* Separate the position information from the input signal(coefs_norm) */ + /* Gather the NZ coefficients*/ + FOR( k = 0; k < BANDS; k++ ) /* Loop through non-zero blocks */ + { + test(); + IF( NE_16( k, k_num[0] ) && NE_16( k, k_num[1] ) ) + { + test(); + test(); + IF( R_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 ) /* Then have non-zero block AND WILL BE ENCODED BY TCQ */ + { + /* Encode Position Info, NZ Info, Signs */ + size = sfmsize[k_sort[k]]; + move16(); + + /* Determine scale step, ISC and TCQ quantizer */ + GetISCScale_fx( &coefs_quant_fx[sfm_start[k_sort[k]]], size, + L_add( R_fx[k_sort[k]], delta_fx ), + /* R_fx[k_sort[k]], */ + &coefs_norm_dec_fx[sfm_start[k_sort[k]]], &step_scale_fx[k_sort[k]], &surplus_fx, &pulses_fx, savedstates, 0, &nzp_fx, 0, 0, 0, 0 ); + leftbits = L_sub( leftbits, L_add( R_fx[k_sort[k]], delta_fx ) ); + npulses[k_sort[k]] = pulses_fx; + move16(); + + encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_tcq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, savedstates, &est_frame_bits_fx ); + encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); + nzbands = sub( nzbands, 1 ); + } + /* Have USQ coded band */ + ELSE IF( R_fx[k_sort[k]] > 0 && EQ_16( USQ_TCQ[k_sort[k]], 1 ) ) + { + size = sfmsize[k_sort[k]]; + move16(); + + GetISCScale_fx( &coefs_quant_fx[sfm_start[k_sort[k]]], size, + L_add( R_fx[k_sort[k]], delta_fx ), + /* R_fx[k_sort[k]], */ + &coefs_norm_dec_fx[sfm_start[k_sort[k]]], &step_scale_fx[k_sort[k]], &surplus_fx, &pulses_fx, savedstates, 1, &nzp_fx, 0, 0, 0, 0 ); + leftbits = L_sub( leftbits, L_add( R_fx[k_sort[k]], delta_fx ) ); + npulses[k_sort[k]] = pulses_fx; + move16(); + + encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, &est_frame_bits_fx ); + encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); + nzbands = sub( nzbands, 1 ); + } + ELSE /* Then have zero block */ + { + npulses[k_sort[k]] = 0; + move16(); + size = sfmsize[k_sort[k]]; + move16(); + } + + delta_fx = L_deposit_l( 0 ); + test(); + IF( R_fx[k_sort[k]] > 0 && surplus_fx < 0 ) + { + /* delta_fx = L_deposit_h( div_l( surplus_fx, nzbands ) ); */ + IF( nzbands <= 1 ) + { + divider = 0; + } + ELSE + { + divider = 2; + } + + IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 ) + { + /* Overflow possible => start to distribute negative surplus */ + delta_fx = ar_div( surplus_fx + sepbits, nzbands ); + } + ELSE + { + delta_fx = 0; + move32(); + } + surplus_fx = L_sub( surplus_fx, delta_fx ); + } + } + } + + test(); + test(); + test(); + IF( ( GT_32( surplus_fx, 524288 ) && EQ_16( input_frame, L_FRAME8k ) ) || ( GT_32( surplus_fx, 786432 ) && EQ_16( input_frame, L_FRAME16k ) ) ) + { + bit_surplus_fx[0] = Mult_32_16( surplus_fx, 24576 ); /* Q16 */ + move32(); + bit_surplus_fx[1] = Mult_32_16( surplus_fx, 8192 ); /* Q16 */ + move32(); + } + ELSE + { + bit_surplus_fx[0] = surplus_fx; + move32(); + bit_surplus_fx[1] = L_deposit_l( 0 ); + move32(); + } + + FOR( k = 0; k < BANDS; k++ ) + { + FOR( j = 0; j < 2; j++ ) + { + IF( EQ_16( k, k_num[j] ) ) + { + R_fx[k_sort[k]] = L_add( R_fx[k_sort[k]], bit_surplus_fx[j] ); + move32(); + + test(); + test(); + IF( R_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 ) /* Then have non-zero block AND WILL BE ENCODED BY TCQ */ + { + /* Encode Position Info, NZ Info, Signs */ + size = sfmsize[k_sort[k]]; + move16(); + + /* Determine scale step, ISC and TCQ quantizer */ + GetISCScale_fx( &coefs_quant_fx[sfm_start[k_sort[k]]], size, R_fx[k_sort[k]], &coefs_norm_dec_fx[sfm_start[k_sort[k]]], &step_scale_fx[k_sort[k]], &surplus_fx, &pulses_fx, savedstates, 0, &nzp_fx, 0, 0, 0, 0 ); + + npulses[k_sort[k]] = pulses_fx; + move16(); + + encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_tcq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, savedstates, &est_frame_bits_fx ); + encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); + } + /* Have USQ coded band */ + ELSE IF( R_fx[k_sort[k]] > 0 && EQ_16( USQ_TCQ[k_sort[k]], 1 ) ) + { + size = sfmsize[k_sort[k]]; + move16(); + + GetISCScale_fx( &coefs_quant_fx[sfm_start[k_sort[k]]], size, R_fx[k_sort[k]], &coefs_norm_dec_fx[sfm_start[k_sort[k]]], &step_scale_fx[k_sort[k]], &surplus_fx, &pulses_fx, savedstates, 1, &nzp_fx, 0, 0, 0, 0 ); + + npulses[k_sort[k]] = pulses_fx; + move16(); + + encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, &est_frame_bits_fx ); + encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); + } + ELSE /* Then have zero block */ + { + npulses[k_sort[k]] = 0; + move16(); + size = sfmsize[k_sort[k]]; + move16(); + } + } + } + } + } + ELSE + { + surplus_fx = L_deposit_l( 0 ); + + /* Separate the position information from the input signal(coefs_norm) */ + /* Gather the NZ coefficients*/ + FOR( k = 0; k < BANDS; k++ ) /* Loop through non-zero blocks */ + { + IF( R_fx[k_sort[k]] > 0 ) + { + size = sfmsize[k_sort[k]]; + move16(); + GetISCScale_fx( &coefs_quant_fx[sfm_start[k_sort[k]]], size, R_fx[k_sort[k]] + delta_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], &step_scale_fx[k_sort[k]], &surplus_fx, &pulses_fx, savedstates, 1, &nzp_fx, &bcount, abuffer_fx, mbuffer_fx, sbuffer_fx ); + + npulses[k_sort[k]] = pulses_fx; + move16(); + encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, &est_frame_bits_fx ); + encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); + + /* nzbands--; */ + nzbands = sub( nzbands, 1 ); + } + ELSE /* Then have zero block */ + { + npulses[k_sort[k]] = 0; + move16(); + size = sfmsize[k_sort[k]]; + move16(); + } + + /* Surplus distribution */ + /* if( surplus > 0.0f && nzbands > 0 ) */ + test(); + IF( surplus_fx > 0 && nzbands > 0 ) + { + /* delta = surplus / nzbands; + surplus -= delta; */ + + delta_fx = ar_div( surplus_fx, nzbands ); + surplus_fx = L_sub( surplus_fx, delta_fx ); + } + } + } + + TCQLSB_fx( bcount, /*abuffer, */ abuffer_fx, /*mbuffer, */ mbuffer_fx, /*sbuffer, */ sbuffer_fx, dpath ); + + /* Save TCQ path to bitstream */ + SaveTCQdata_fx( parenc_fx, dpath, lsbtcq_bits ); + + /* Add tcq sequence to decoding buffer */ + InitLSBTCQ_fx( &bcount ); + + ar_encoder_done_fx( parenc_fx ); + + /* Loop through non-zero blocks */ + FOR( i = 0; i < L_FRAME32k; i++ ) + { + coefs_norm_dec_fx[i] = extract_l( L_mult0( coefs_norm_dec_fx[i], 5 ) ); + } + IF( !flag_wbnb ) + { + FOR( k = 0; k < BANDS; k++ ) + { + IF( R_fx[k_sort[k]] > 0 ) + { + size = sfmsize[k_sort[k]]; + move16(); + RestoreTCQ_fx( &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &bcount, mbuffer_fx ); + } + } + } + + nb_bytes = shr( bit_budget, 3 ); + j = sub( bit_budget, shl( nb_bytes, 3 ) ); + FOR( i = 0; i < nb_bytes; i++ ) + { + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, pbs_fx->buf[i], 8 ); + } + IF( j > 0 ) + { + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, shr( pbs_fx->buf[nb_bytes], sub( 8, j ) ), j ); + } + /* Clear decoding buffer */ + set32_fx( coefs_quant_fx, 0, sfm_end[BANDS - 1] + 1 ); + + /* New analysis of decoded frame */ + FOR( i = 0; i < BANDS; i++ ) + { + IF( R_fx[k_sort[i]] > 0 ) + { + gain_fx = L_deposit_l( 0 ); + + crosscorr_fx = L_deposit_l( 0 ); + selfcorr_fx = L_deposit_l( 0 ); + + FOR( j = 0; j < sfmsize[k_sort[i]]; j++ ) + { + crosscorr_fx = L_add( crosscorr_fx, Mult_32_16( coefs_norm_fx[sfm_start[k_sort[i]] + j], shl( coefs_norm_dec_fx[sfm_start[k_sort[i]] + j], 2 ) ) ); /*1 */ + selfcorr_fx = L_mac0( selfcorr_fx, coefs_norm_dec_fx[sfm_start[k_sort[i]] + j], coefs_norm_dec_fx[sfm_start[k_sort[i]] + j] ); + } + + exp = sub( norm_l( crosscorr_fx ), 1 ); + gain_fx = ar_div( L_shl( crosscorr_fx, exp ), selfcorr_fx ); /* 1 + exp */ +#ifdef BASOP_NOGLOB + gain_fx = L_shl_sat( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ +#else + gain_fx = L_shl( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ +#endif + lo = L_Extract_lc( gain_fx, &hi ); + /* Use optimal gain */ + FOR( j = 0; j < sfmsize[k_sort[i]]; j++ ) + { + inp_vector_fx[sfm_start[k_sort[i]] + j] = coefs_norm_dec_fx[sfm_start[k_sort[i]] + j]; + move32(); + coefs_quant_fx[sfm_start[k_sort[i]] + j] = L_add( L_shl( L_mult0( hi, coefs_norm_dec_fx[sfm_start[k_sort[i]] + j] ), 12 ), + L_shr( L_mult0( lo, coefs_norm_dec_fx[sfm_start[k_sort[i]] + j] ), 3 ) ); /* Q12 */ + move32(); + } + } + } + + return error; } diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index b371381d5..546326cb6 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -362,7 +362,42 @@ Word16 WriteTnsData_fx( STnsConfig const *pTnsConfig, Word16 const *stream, Word return TNS_NO_ERROR; } +#ifdef IVAS_FLOAT_FIXED +Word16 WriteTnsData_ivas_fx( STnsConfig const *pTnsConfig, Word16 const *stream, Word16 *pnSize, BSTR_ENC_HANDLE hBstr, Word16 *pnBits ) +{ + IF( GT_16( pTnsConfig->nMaxFilters, 1 ) ) + { + IF( pTnsConfig->allowTnsOnWhite ) + { + IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) + { + WriteToBitstream_ivas_fx( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits ); + } + ELSE + { + WriteToBitstream_ivas_fx( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits ); + } + } + ELSE + { + IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) + { + WriteToBitstream_ivas_fx( &tnsEnabledSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits ); + } + ELSE + { + WriteToBitstream_ivas_fx( &tnsEnabledSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits ); + } + } + } + ELSE + { + WriteToBitstream_ivas_fx( &tnsEnabledWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits ); + } + return TNS_NO_ERROR; +} +#endif /*********************************************************************************************/ /* Definitions of functions used in the mapping between TNS parameters and a bitstream. */ /*********************************************************************************************/ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 182f2acc5..49be6db41 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -6,7 +6,7 @@ #include "options.h" #include "stl.h" #include "basop_util.h" -//#include "prot_fx.h" +// #include "prot_fx.h" #include "rom_com.h" #include #include @@ -333,6 +333,254 @@ void RunTransientDetection_fx( Word16 const *input, Word16 nSamplesAvailable, Tr #endif } + +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * GetTCXAvgTemporalFlatnessMeasure_ivas_fx() + * + * + *-------------------------------------------------------------------*/ + +Word16 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( + TRAN_DET_HANDLE hTranDet, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks, + Word16 *exp_out ) +{ + Word16 i; + TransientDetector *pTransientDetector = &hTranDet->transientDetector; + const SubblockEnergies *pSubblockEnergies = pTransientDetector->pSubblockEnergies; + const Word16 nDelay = pTransientDetector->nDelay; + const Word16 nRelativeDelay = sub( pSubblockEnergies->nDelay, nDelay ); + const Word32 *pSubblockNrgChange = NULL; + Word32 sumTempFlatness; + Word64 sumTempFlatness_64; + Word16 q_tmp; + const Word16 nTotBlocks = add( nCurrentSubblocks, nPrevSubblocks ); + Word16 exp_diff; + move16(); + + /* Initialization */ + assert( nTotBlocks > 0 ); + sumTempFlatness_64 = 0; + move64(); + + assert( ( nPrevSubblocks <= nRelativeDelay ) && ( nCurrentSubblocks <= NSUBBLOCKS + nDelay ) ); + pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange_32[nRelativeDelay - nPrevSubblocks]; + FOR( i = 0; i < nTotBlocks; i++ ) + { + sumTempFlatness_64 = W_add( sumTempFlatness_64, W_deposit32_l( pSubblockNrgChange[i] ) ); + } + q_tmp = W_norm( sumTempFlatness_64 ); + sumTempFlatness = W_extract_l( W_shl( sumTempFlatness_64, sub( q_tmp, 32 ) ) ); + q_tmp = add( pSubblockEnergies->q_subblockNrgChange, sub( q_tmp, 32 ) ); + + i = BASOP_Util_Divide3216_Scale( sumTempFlatness, nTotBlocks, &exp_diff ); + *exp_out = sub( add( exp_diff, sub( Q31, q_tmp ) ), Q15 ); + move16(); + + return i; +} +#endif + + +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * isLongTermTransient_fx() + * + * + *-------------------------------------------------------------------*/ +static Word16 isLongTermTransient_fx( + const Word32 frameTFM, + Word32 *lastTFM ) +{ + Word32 currTFM, f; + + IF( GT_32( frameTFM, *lastTFM ) ) + { + f = Mpy_32_32( L_sub( frameTFM, *lastTFM ), L_sub( frameTFM, *lastTFM ) ); // Q31 + currTFM = L_add( Mpy_32_32( *lastTFM, L_sub( 2080374784 /* 0.96875f in Q31 */, f ) ), Mpy_32_32( frameTFM, L_add( 67108864 /* 0.03125f in Q31 */, f ) ) ); // Q31 + } + ELSE + { + currTFM = L_add( Mpy_32_32( *lastTFM, 2080374784 /* 0.96875f in Q31 */ ), Mpy_32_32( frameTFM, 67108864 /* 0.03125f in Q31 */ ) ); // Q31 + } + + *lastTFM = L_max( 33554432 /* 0.015625f in Q31 */, currTFM ); + move32(); + + IF( LT_32( currTFM, 1207959552 /* 0.5625f in Q31 */ ) ) + { + return 1; + } + return 0; +} +#endif + + +#ifdef IVAS_FLOAT_FIXED +void SetTCXModeInfo_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ + Word16 *tcxModeOverlap /* o : window overlap of current frame */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 tmp, exp_diff, exp_out; + + test(); + test(); + IF( EQ_16( st->codec_mode, MODE2 ) || ( GT_16( st->element_mode, EVS_MONO ) && NE_16( st->core, HQ_CORE ) ) ) + { + assert( hTranDet != NULL ); + + /* determine window sequence (1 long or 2 short windows) */ + test(); + IF( st->tcx10Enabled && st->tcx20Enabled ) + { + /* window switching based on transient detector output */ + test(); + test(); + test(); + test(); + /* window switching based on transient detector output */ + IF( ( ( hTranDet->transientDetector.bIsAttackPresent ) || ( GT_32( Mpy_32_32( st->currEnergyHF_fx, 55063683 /*1.0f/39.0f Q31*/ ), st->prevEnergyHF_fx ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) ) && + ( ( NE_16( st->last_core, ACELP_CORE ) ) && ( NE_16( st->last_core, AMR_WB_CORE ) ) ) ) + { + hTcxEnc->tcxMode = TCX_10; + move16(); + } + ELSE + { + hTcxEnc->tcxMode = TCX_20; + move16(); + } + } + ELSE + { + /* window selection (non-adaptive) based on flags only */ + IF( st->tcx10Enabled ) + { + hTcxEnc->tcxMode = TCX_10; + move16(); + } + ELSE IF( st->tcx20Enabled ) + { + hTcxEnc->tcxMode = TCX_20; + move16(); + } + ELSE + { + hTcxEnc->tcxMode = NO_TCX; + move16(); + } + } + /* set the left window overlap */ + test(); + test(); + IF( EQ_16( st->last_core, ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) ) + { + st->hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + move16(); + } + ELSE IF( ( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) && ( EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) ) + { + st->hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; + move16(); + } + ELSE + { + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + /* determine the right window overlap */ + IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) + { + IF( hTranDet->transientDetector.attackIndex < 0 ) + { + *tcxModeOverlap = HALF_OVERLAP; + move16(); + } + ELSE + { + *tcxModeOverlap = s_and( hTranDet->transientDetector.attackIndex, 3 ); + move16(); + if ( EQ_16( *tcxModeOverlap, 1 ) ) + { + *tcxModeOverlap = FULL_OVERLAP; + move16(); + } + } + tmp = BASOP_Util_Divide3216_Scale( ONE_IN_Q31, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( hTranDet, NSUBBLOCKS, 0, &exp_out ), &exp_diff ); + tmp = shl( tmp, sub( exp_diff, exp_out ) ); // Q15 + test(); + IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + test(); + if ( NE_16( *tcxModeOverlap, MIN_OVERLAP ) && LT_16( hTcxEnc->tcxltp_norm_corr_past, 18432 /* 0.5625f in Q15 */ ) ) + { + *tcxModeOverlap = HALF_OVERLAP; + move16(); + } + } + } + ELSE IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) + { + IF( EQ_16( hTranDet->transientDetector.attackIndex, 7 ) ) + { + *tcxModeOverlap = HALF_OVERLAP; + move16(); + } + ELSE IF( EQ_16( hTranDet->transientDetector.attackIndex, 6 ) ) + { + *tcxModeOverlap = MIN_OVERLAP; + move16(); + } + ELSE + { + *tcxModeOverlap = ALDO_WINDOW; + move16(); + } + tmp = BASOP_Util_Divide3216_Scale( ONE_IN_Q31, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( hTranDet, NSUBBLOCKS, 0, &exp_out ), &exp_diff ); + tmp = shl( tmp, sub( exp_diff, exp_out ) ); // Q15 + test(); + IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + test(); + if ( NE_16( *tcxModeOverlap, MIN_OVERLAP ) && LT_16( hTcxEnc->tcxltp_norm_corr_past, 18432 /* 0.5625f in Q15 */ ) ) + { + *tcxModeOverlap = HALF_OVERLAP; + move16(); + } + } + } + ELSE + { + /* NO_TCX */ + *tcxModeOverlap = TRANSITION_OVERLAP; + move16(); + if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75f in Q31 */ + move16(); + } + } + + /* for the ACELP -> TCX transition frames use full right window overlap */ + test(); + if ( ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( EQ_16( *tcxModeOverlap, ALDO_WINDOW ) ) ) + { + *tcxModeOverlap = FULL_OVERLAP; + move16(); + } + } + + return; +} +#endif + + void SetTCXModeInfo_fx( Encoder_State *st, TransientDetection const *pTransientDetection, Word16 *tcxModeOverlap ) -- GitLab