From 54e13e5c8881aaf22eeb2bd7c81e225371275ac4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 25 Mar 2024 14:30:44 +0530 Subject: [PATCH 1/3] Integration of fixed point sub-functions 7 [x] Implementation of ivas_swb_tbe_dec [x] Changes for swb/wb decode functions [x] stereo_dft_dec_res fixed point implementation [x] fixed implementation of spar function: ivas_spar_calc_smooth_facs_fx [x] Few functions converted to fixed point: splitAvailableBitsMCT, ivas_binaural_add_LFE_fix, tdm_bit_alloc, tdm_configure_dec --- lib_com/cnst.h | 2 + lib_com/ivas_mct_com.c | 187 +- lib_com/ivas_prot.h | 15 +- lib_com/ivas_prot_fx.h | 1 - lib_com/ivas_stereo_td_bit_alloc.c | 372 ++- lib_com/ivas_tools.c | 64 + lib_com/mslvq_com_fx.c | 72 +- lib_com/prot.h | 21 +- lib_com/prot_fx2.h | 73 + lib_com/rom_com.c | 63 + lib_com/rom_com.h | 9 + lib_com/swb_tbe_com_fx.c | 877 ++++++- lib_com/tools_fx.c | 18 + lib_dec/cng_dec_fx.c | 2 +- lib_dec/ivas_binRenderer_internal.c | 60 +- lib_dec/ivas_core_dec.c | 31 +- lib_dec/ivas_cpe_dec_fx.c | 65 +- lib_dec/ivas_jbm_dec.c | 179 +- lib_dec/ivas_spar_decoder.c | 163 +- lib_dec/ivas_stat_dec.h | 9 +- lib_dec/ivas_stereo_dft_dec_fx.c | 36 +- lib_dec/ivas_stereo_td_dec.c | 204 +- lib_dec/stat_dec.h | 2 + lib_dec/swb_tbe_dec.c | 3373 +++++++++++++++++++++++++++ lib_dec/swb_tbe_dec_fx.c | 539 +++-- 25 files changed, 6106 insertions(+), 331 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 221b77da7..c04e8f890 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1512,6 +1512,8 @@ enum #define SHB_GAIN_QDELTA 0.15f /* SHB gain scalar quantizer stepsize */ #define SHB_GAIN_QLOW_1k75 0.0f /* SHB gain lowest scalar quantizer value */ #define SHB_GAIN_QDELTA_1k75 0.08f /* SHB gain scalar quantizer stepsize */ +#define SHB_GAIN_QLOW_1k75_FX 0 /* SHB gain lowest scalar quantizer value */ +#define SHB_GAIN_QDELTA_1k75_FX 10486 /* SHB gain scalar quantizer stepsize Q17 */ #define SHB_GAIN_QLOW_FX -262144 /* Q18*/ /* SHB gain lowest scalar quantizer value */ #define SHB_GAIN_QLOW_FX_16 -65536 /* SHB gain lowest scalar quantizer value */ #define SHB_GAIN_QDELTA_FX_15 4915 /* SHB gain scalar quantizer step size */ diff --git a/lib_com/ivas_mct_com.c b/lib_com/ivas_mct_com.c index 352ef4221..7dac33b63 100644 --- a/lib_com/ivas_mct_com.c +++ b/lib_com/ivas_mct_com.c @@ -35,6 +35,7 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "prot.h" +#include "prot_fx1.h" #include "wmc_auto.h" #include @@ -52,7 +53,7 @@ * * split available TCX bits among channels *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void splitAvailableBitsMCT( void **sts, /* i/o: encoder/decoder state structure */ const int16_t total_bits, /* i : total number of available bits */ @@ -192,3 +193,187 @@ void splitAvailableBitsMCT( return; } + +#else + +void splitAvailableBitsMCT( + void **sts, /* i/o: encoder/decoder state structure */ + const Word16 total_bits, /* i : total number of available bits */ + const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits */ + const Word16 enc_dec, /* i : encoder or decoder flag */ + const Word16 nchan /* i : number of channels */ +) +{ + Word16 i, k, nSubframes, diff, bits_split, max_chn, tmp; + Word16 *bits_frame_channel; + Word16 min_chan_bits[MCT_MAX_CHANNELS], min_bits_tot, remaining_bits; + Word16 core[MCT_MAX_CHANNELS]; + MCT_CHAN_MODE mct_chan_mode[MCT_MAX_CHANNELS]; + min_bits_tot = 0; + + FOR( i = 0; i < nchan; i++ ) + { + IF( enc_dec == ENC ) + { + mct_chan_mode[i] = ( (Encoder_State *) sts[i] )->mct_chan_mode; + move16(); + core[i] = ( (Encoder_State *) sts[i] )->core; + move16(); + } + ELSE + { + mct_chan_mode[i] = ( (Decoder_State *) sts[i] )->mct_chan_mode; + move16(); + core[i] = ( (Decoder_State *) sts[i] )->core; + move16(); + } + } + + FOR( i = 0; i < nchan; i++ ) + { + IF(mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE ) + { + min_chan_bits[i] = 0; + move16(); + nSubframes = ( core[i] == TCX_20_CORE ) ? 1 : NB_DIV; + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + min_chan_bits[i] += SMDCT_MINIMUM_ARITH_BITS + MIN_SAFETY_BITS_MC; + move16(); + } + min_bits_tot += min_chan_bits[i]; + move16(); + } + } + + remaining_bits = total_bits - min_bits_tot; + move16(); + + /*initial value of bits already given*/ + bits_split = 0; + move16(); + + tmp = 0; + move16(); + max_chn = 0; + move16(); + FOR( i = 0; i < nchan; i++ ) + { + IF( enc_dec == ENC ) + { + bits_frame_channel = &( (Encoder_State *) sts[i] )->bits_frame_channel; + move16(); + } + ELSE /* DEC */ + { + bits_frame_channel = &( (Decoder_State *) sts[i] )->bits_frame_channel; + move16(); + } + + IF( + mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE ) + { + assert( split_ratio[i] >= 1 && split_ratio[i] < BITRATE_MCT_RATIO_RANGE ); + *bits_frame_channel = (Word16)L_shr((Word32)split_ratio[i]* remaining_bits, NBBITS_MCT_RATIO) + min_chan_bits[i]; + move16(); + bits_split += *bits_frame_channel; + move16(); + + /*determine channel with most bits (energy)*/ + IF( *bits_frame_channel > tmp ) + { + tmp = *bits_frame_channel; + move16(); + max_chn = i; + move16(); + } + } + } + + /*if bits distributed are more than available bits, substract the proportional amount of bits from all channels*/ + IF( bits_split != total_bits ) + { + diff = bits_split - total_bits; + move16(); + + /*re-count bits distributed to each channel*/ + bits_split = 0; + move16(); + + FOR( i = 0; i < nchan; i++ ) + { + IF( enc_dec == ENC ) + { + bits_frame_channel = &( (Encoder_State *) sts[i] )->bits_frame_channel; + move16(); + } + ELSE /* DEC */ + { + bits_frame_channel = &( (Decoder_State *) sts[i] )->bits_frame_channel; + move16(); + } + + IF( mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE ) + { + Word32 temp_res = (Word32) diff * split_ratio[i]; + IF( temp_res < 0 ) + { + temp_res = -temp_res; + move16(); + temp_res = L_shr( temp_res, NBBITS_MCT_RATIO ); + move16(); + temp_res = -temp_res; + move16(); + } + ELSE + { + temp_res = L_shr( temp_res, NBBITS_MCT_RATIO ); + move16(); + } + *bits_frame_channel -= (Word16)temp_res; + move16(); + *bits_frame_channel = max( min_chan_bits[i], *bits_frame_channel ); + move16(); + bits_split += *bits_frame_channel; + move16(); + } + } + } + + /*if there any bits left assign them to the channel with the maximum energy (or more bits)*/ + IF( total_bits != bits_split ) + { + IF( enc_dec == ENC ) + { + bits_frame_channel = &( (Encoder_State *) sts[max_chn] )->bits_frame_channel; + move16(); + } + ELSE /* DEC */ + { + bits_frame_channel = &( (Decoder_State *) sts[max_chn] )->bits_frame_channel; + move16(); + } + + *bits_frame_channel += ( total_bits - bits_split ); + move16(); + + /*if all channels are silent assign bits to ch 0*/ + IF( enc_dec == ENC ) + { + IF( ( (Encoder_State *) sts[max_chn] )->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + { + assert( bits_split == 0 ); + + ( (Encoder_State *) sts[max_chn] )->mct_chan_mode = MCT_CHAN_MODE_REGULAR; + ( (Encoder_State *) sts[max_chn] )->side_bits_frame_channel = ( ( (Encoder_State *) sts[max_chn] )->core ) * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); + *bits_frame_channel -= ( (Encoder_State *) sts[max_chn] )->side_bits_frame_channel; + move16(); + } + } + } + + return; +} + +#endif \ No newline at end of file diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index f2acd512f..070b04e13 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5986,7 +5986,12 @@ void ivas_binaural_add_LFE( float *input_f[], /* i : transport channels */ float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ ); - +void ivas_binaural_add_LFE_fix( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word16 output_frame, /* i : length of input frame */ + Word32 *input_fx[], /* i : transport channels */ + Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output */ +); /*----------------------------------------------------------------------------------* * renderer prototypes @@ -6251,6 +6256,14 @@ void lls_interp_n( const int16_t upd /* i : use 1 to update x[] with the interpolated output*/ ); +void lls_interp_n_fx( + Word16 x_fx[], /* i/o: input/output vector */ + const Word16 N, /* i : length of the input vector */ + Word16 *a_fx, /* o : calculated slope */ + Word16 *b_fx, /* o : calculated offset */ + const Word16 upd /* i : use 1 to update x[] with the interpolated output */ +); + void computeReferencePower_enc( const int16_t *band_grouping, /* i : Band grouping for estimation */ float Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index a592f0269..9370a84de 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1037,7 +1037,6 @@ void stereo_dft_dec_res_fx( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ Word16 q_res, /* i : q fact of residural buffer */ - Word16 q_output, /* i : q factor of output buffer */ Word32 *output /* o : output */ ); diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index 2cbc2e108..e4fd087f9 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -73,7 +73,7 @@ * * Bitbudget distribution between Primary and Secondary channel in TD stereo *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void tdm_bit_alloc( const int16_t ivas_format, /* i : IVAS format */ const int16_t ism_mode, /* i : ISM mode in combined format */ @@ -433,7 +433,377 @@ void tdm_bit_alloc( return; } +#else +void tdm_bit_alloc( + const Word16 ivas_format, /* i : IVAS format */ + const Word16 ism_mode, /* i : ISM mode in combined format */ + const int32_t element_brate_wo_meta, /* i : element bitrate without metadata */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reusage flag */ + Word32 *total_brate_pri, /* o : Allocated primary channel bitrate */ + Word32 *total_brate_sec, /* o : Allocated secondary channel bitrate */ + Word16 *tdm_low_rate_mode, /* o : secondary channel low rate mode flag*/ + const Word16 coder_type, /* i : secondary channel coder type */ + const Word16 ener_ratio_idx, /* i : correlation ratio indexe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 bwidth_pri, /* i : bandwidth of the primary channel */ + const Word16 bwidth_sec, /* i : bandwidth of the secondary channel */ + const Word16 flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan.*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ + const Word16 tdm_inst_ratio_idx_ref /* i : instantaneous correlation ratio idx */ +) +{ + Word16 idx, four_subfr_fcb, two_subfr_fcb; + Word32 bit_rate_diff_fx; + Word16 BWE_brate, tmp_bits; + Word16 tdm_inst_ratio_idx = tdm_inst_ratio_idx_ref; + IF( tdm_inst_ratio_idx == TDM_NQ ) + { + tdm_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM; /* Bit rate almost split half and half*/ + } + + /* Decision on using the low rate mode or the normal mode */ + /* default is using the low rate mode for the secondary channel coding*/ + /* UC and IC are automatically coded with low rate mode */ + *tdm_low_rate_mode = 1; + + /* Allocating different bitrate to channels */ + idx = 0; + IF( element_brate_wo_meta <= IVAS_13k2 ) + { + idx = 0; + } + ELSE IF( element_brate_wo_meta <= IVAS_16k4 ) + { + idx = 1; + } + ELSE IF( element_brate_wo_meta <= IVAS_24k4 ) + { + idx = 2; + } + ELSE IF( element_brate_wo_meta <= IVAS_32k ) + { + idx = 3; + } + ELSE IF( element_brate_wo_meta <= IVAS_48k ) + { + idx = 4; + } + + IF( coder_type == UNVOICED && tdm_bit_allc_tbl[idx][coder_type] >= 4200 ) + { + *tdm_low_rate_mode = 0; + } + + /* Secondary channel based bitrate allocation */ + *total_brate_sec = tdm_bit_allc_tbl[idx][coder_type]; + + /* secondary channel bitrate allocation based on the energy scaling ratio */ + IF( ( ( ivas_format != MASA_ISM_FORMAT || ism_mode == ISM_MODE_NONE ) && ( ( coder_type != UNVOICED ) || tdm_LRTD_flag == 1 ) ) || ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE && coder_type > UNVOICED ) ) + { + bit_rate_diff_fx = ( element_brate_wo_meta - 2 * *total_brate_sec ); + + IF( tdm_LRTD_flag == 1 ) /* > element_brate > STEREO_22k or CT0 not used */ + { + /* further adjustment in function of the energy/correlation ratio */ + IF( coder_type == INACTIVE ) + { + Word32 res_fix = 0; + res_fix = Mpy_32_32( 6442450, ( element_brate_wo_meta - 500 ) ); + res_fix = res_fix * 100; + //*total_brate_sec = max( *total_brate_sec, (Word16) ( 0.3f * ( element_brate_wo_meta - 500 ) / 100 ) * 100 ); + *total_brate_sec = max( *total_brate_sec, (Word16) res_fix ); + tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 200 * idx ); + } + ELSE + { + Word32 res_fix = 0; + res_fix = Mpy_32_32( 10737418, ( element_brate_wo_meta - 500 ) ); + res_fix = res_fix * 100; + //*total_brate_sec = max( *total_brate_sec, (Word16) ( 0.5f * ( element_brate_wo_meta - 500 ) / 100 ) * 100 ); + *total_brate_sec = max( *total_brate_sec, res_fix ); + /* tmp_bits = -abs(tdm_inst_ratio_idx-16)*200*idx; */ + tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 100 * idx ); + } + + /* tmp_bits should be subtract from the secondary channel bitrate */ + /* IF the primary channel doesn't correspond to the channel having the highest correlation to the mono- inverse the bitrate compensation */ + IF( ( ener_ratio_idx >= LRTD_STEREO_MID_IS_PRIM && tdm_inst_ratio_idx < LRTD_STEREO_MID_IS_PRIM ) || ( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM && tdm_inst_ratio_idx >= LRTD_STEREO_MID_IS_PRIM ) ) + { + tmp_bits *= -1; + } + bit_rate_diff_fx = tmp_bits; + } + ELSE{ + IF( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM ){ + + bit_rate_diff_fx = ( LRTD_STEREO_MID_IS_PRIM - ener_ratio_idx ) * bit_rate_diff_fx; + bit_rate_diff_fx = L_shr( bit_rate_diff_fx, 1 ); + bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation + } + ELSE + { + bit_rate_diff_fx = ( ener_ratio_idx - LRTD_STEREO_MID_IS_PRIM ) * bit_rate_diff_fx; + bit_rate_diff_fx = Mpy_32_32( 107374182, bit_rate_diff_fx ); + bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation + } +} +/*bit_rate_diff2 = ((Word16)(10.f*(-0.5f*ener_ratio_LR+0.5f)*bit_rate_diff)/100)*100;*/ +*total_brate_sec += ( (Word16) ( bit_rate_diff_fx / 100 ) * 100 ); +*total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[idx][coder_type] ); + +IF( coder_type == INACTIVE && tdm_LRTD_flag == 0 ) +{ + *total_brate_sec = min( *total_brate_sec, MIN_BRATE_SWB_BWE ); +} + +IF( ( ener_ratio_idx <= 1 || ener_ratio_idx >= 29 ) && coder_type >= UNVOICED ) +{ + Word16 delta_brate = 0; + + IF( bwidth_pri > WB ) + { + delta_brate = 600; /* To slightly compensate for SWB BWE instead of WB BWE */ + IF( element_brate_wo_meta <= IVAS_16k4 ) + { + delta_brate = 1250; /* To compensate for SWB BWE instead of WB BWE */ + } + } + + IF( element_brate_wo_meta <= IVAS_13k2 ) + { + *total_brate_sec = max( *total_brate_sec, 5600 + delta_brate ); /* ~42-47 % of the total bitrate */ + } + ELSE IF( element_brate_wo_meta <= IVAS_16k4 ) + { + *total_brate_sec = max( *total_brate_sec, 6500 + delta_brate ); /* ~40-43 % of the total bitrate */ + } + ELSE IF( element_brate_wo_meta <= IVAS_24k4 ) + { + *total_brate_sec = max( *total_brate_sec, 9000 + delta_brate ); /* ~37-39 % of the total bitrate */ + } + ELSE + { + *total_brate_sec = max( *total_brate_sec, 9600 + delta_brate ); /* ~30-32% of the total bitrate */ + } +} +ELSE +{ + *total_brate_sec = min( *total_brate_sec, (Word16) ( 0.0045f * element_brate_wo_meta ) * 100 ); +} + +*total_brate_sec = min( *total_brate_sec, 18000 ); +} +ELSE IF( coder_type == UNVOICED ) +{ + IF( tdm_lp_reuse_flag == 0 ) + { + *total_brate_sec += ( 31 + 5 ) * FRAMES_PER_SEC; + } +} + +IF( coder_type <= UNVOICED ) +{ + *total_brate_sec = min( *total_brate_sec, MAX_TDM_UC_BRATE ); + + IF( *total_brate_sec >= TDM_UC_NORMAL_MODE_MBRATE && tdm_lp_reuse_flag == 0 ) + { + *tdm_low_rate_mode = 0; + } + ELSE IF( *total_brate_sec >= TDM_UC_NORMAL_MODE_MBRATE_LP_R ) + { + *tdm_low_rate_mode = 0; + } + ELSE IF( ( tdm_lp_reuse_flag == 0 && *total_brate_sec < TDM_UC_NORMAL_MODE_MINBR_LP_R && coder_type == UNVOICED ) || ( tdm_lp_reuse_flag == 0 && *total_brate_sec < ( tdm_bit_allc_tbl[idx][0] + MID_LP_BRATE ) ) ) + { + *total_brate_sec += MID_LP_BRATE; + } +} + +/* verify that primary channel bitrate is higher than the minimum supported bitrate */ +IF( flag_ACELP16k_pri ) +{ + BWE_brate = SWB_TBE_1k75; + IF( element_brate_wo_meta < IVAS_24k4 ) + { + BWE_brate = SWB_TBE_1k10; + } + + IF( bwidth_pri > WB && tdm_LRTD_flag == 0 ) + { + BWE_brate += ( STEREO_BITS_ICBWE + STEREO_ICBWE_MSFLAG_BITS ) * FRAMES_PER_SEC; + } + IF( bwidth_pri > SWB && tdm_LRTD_flag == 1 ) + { + BWE_brate += 300; + } + + IF( bwidth_pri == FB ) + { + BWE_brate += ( FB_TBE_1k8 - SWB_TBE_1k75 ); + } + + IF( element_brate_wo_meta - *total_brate_sec - BWE_brate < 14000 ) + { + *total_brate_sec = element_brate_wo_meta - 14000 - BWE_brate; + } +} +ELSE +{ + BWE_brate = SWB_TBE_1k75; + IF( bwidth_pri == WB ) + { + BWE_brate = WB_BWE_0k35; + IF( tdm_LRTD_flag == 0 ) + { + BWE_brate += 250; /* ICA Brate */ + } + } + ELSE IF( tdm_LRTD_flag == 0 ) + { + BWE_brate += 350; /* ICA Brate */ + } +} + +IF( coder_type0 == TRANSITION ) +{ + IF( element_brate_wo_meta > IVAS_13k2 ) + { + *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( ACELP_8k00 + BWE_brate ) ); + } + ELSE + { + *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( ACELP_7k20 + BWE_brate ) ); + } +} +ELSE +{ + *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( 5900 + BWE_brate ) ); +} + +IF( coder_type == INACTIVE ) +{ + *total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[0][0] ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ +} +ELSE +{ + *total_brate_sec = max( *total_brate_sec, 3500 ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ +} + +/* Secondary channel bitrate adjusment */ +/* First, adjust the bitrate depending of what is transmitted */ +/* Second, choose the number of subframe for ACELP core depending of the targetted bitratre */ +/* Finally, verify that the concordance between the number of subframe, the parameters sent and the bitrate available */ +IF( coder_type == GENERIC /* || coder_type == AUDIO*/ ) +{ + /* Adjust the bitrate depending of what is transmitted */ + /* IF LPC are transmitted, ensure enough bits are used */ + IF( tdm_lp_reuse_flag == 0 ) + { + /* Pitch is transmitted as well, further increase the bitrate */ + IF( tdm_Pitch_reuse_flag == 0 ) + { + *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SEC_LPC_RATE + MIN_SIGN_RATE ); + + IF( tdm_LRTD_flag == 1 && bwidth_sec == SWB ) + { + /* ensure that there are enough bits to code SWB TBE_1k10 as well */ + *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SEC_LPC_RATE + MIN_SIGN_RATE + SWB_TBE_1k10 ); + } + } + ELSE /* only LPC is tranmitted -> IF ( *total_brate_sec < MIN_SEC_BRATE+MIN_SEC_LPC_RATE ) */ + { + *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_LPC_RATE + MIN_SIGN_RATE ); + } + } + ELSE IF( /*tdm_lp_reuse_flag == 1*/ tdm_Pitch_reuse_flag == 0 ) + { + *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SIGN_RATE ); + } + + /* Choose between 2 and 4 subfr, depending of the bitrate available and prevent the gap between the 2 atlernative */ + IF( tdm_LRTD_flag == 1 ) + { + four_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 4 * MIN_GAIN_BITS ) * FRAMES_PER_SEC ); + two_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC ); + } + ELSE + { + four_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 4 * MIN_GAIN_BITS ) * FRAMES_PER_SEC ); + two_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC ); + } + + IF( tdm_lp_reuse_flag == 0 ) + { + four_subfr_fcb -= MIN_SEC_LPC_RATE; + two_subfr_fcb -= MIN_SEC_LPC_RATE; + } + + IF( tdm_Pitch_reuse_flag == 0 ) + { + four_subfr_fcb -= ( MIN_SEC_ACB_RATE + 10 * FRAMES_PER_SEC ); + two_subfr_fcb -= MIN_SEC_ACB_RATE; + } + + /* Too much bits for the 2 subfr model but not enough for the the 4 subfr model -> slightly reduce the 2nd channel bitrate */ + IF( two_subfr_fcb > 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC && four_subfr_fcb < MIN_4SUBFR_FCB_RATE * FRAMES_PER_SEC ) + { + IF( tdm_LRTD_flag == 1 ) + { + *total_brate_sec = 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC + ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC; + } + ELSE + { + *total_brate_sec = 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC + ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC; + } + + IF( tdm_lp_reuse_flag == 0 ) + { + *total_brate_sec += MIN_SEC_LPC_RATE; + } + + IF( tdm_Pitch_reuse_flag == 0 ) + { + *total_brate_sec += MIN_SEC_ACB_RATE; + } + } + ELSE IF( four_subfr_fcb >= ( 40 ) * FRAMES_PER_SEC ) /* Enough bits to have minimally 2 x 12 + 2*7 bits FCB */ + { + *tdm_low_rate_mode = 0; /* Use normal rate mode */ + } + ELSE /* Possible slight increase of secondary channel bit budget to compensate for FCB limited flexibility */ + { + Word16 tmp_rate, i; + tmp_rate = two_subfr_fcb; + idx = NB_RATE_POSS - 2; + + for ( i = 0; i < NB_RATE_POSS; i++ ) + { + IF( tmp_rate <= fast_FCB_rates_2sfr[i] ) + { + idx = i; + break; + } + } + *total_brate_sec += ( fast_FCB_rates_2sfr[idx] - tmp_rate ); + } + /* To prevent 13.2 kb/s for primary channel as some bitstream issues arrise with it */ + IF( element_brate_wo_meta - *total_brate_sec == ACELP_13k20 ) + { + *total_brate_sec += 100; + } +} +/* prevent 2.4 kb/s and 2.8 kb/s as they are reserved bitrates for DTX and VBR */ +IF( *total_brate_sec == PPP_NELP_2k80 || *total_brate_sec == SID_2k40 ) +{ + *total_brate_sec -= 100; +} + +*total_brate_pri = element_brate_wo_meta - *total_brate_sec; +return; +} +#endif /*-------------------------------------------------------------------* * td_stereo_param_updt() * diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 88aac4a76..ed61b7ade 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -2083,6 +2083,70 @@ void lls_interp_n( return; } +void lls_interp_n_fx( + Word16 x_fx[], /* i/o: input/output vector */ + const Word16 N, /* i : length of the input vector */ + Word16 *a_fx, /* o : calculated slope */ + Word16 *b_fx, /* o : calculated offset */ + const Word16 upd /* i : use 1 to update x[] with the interpolated output */ +) +{ + Word16 i; + const Word16 n_i_fx[11] = { 0, 2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480 }; // Q11 + const Word16 one_by_n_fx[11] = { 0, 32767, 16384, 10911, 8192, 6553, 5459, 4681, 4096, 3640, 3276 }; + const Word16 sum_i_fx[12] = { 0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55 }; + + // 1.0f/ ( N * sum_ii[N] - sum_i[N] * sum_i[N] ) + const Word32 res_table[12] = { 0, 0, 0, 357913952, 107374184, 42949672, 20452226, 10956549, 6391320, 3976821, 2603010, 385 }; + + Word32 sum_x_fx, sum_ix_fx, slope_fx, offset_fx; + Word16 dot_exp = 0, sum_ix_q = 0; + ; + Word32 num; + assert(N > 0 && N <= 10); + + sum_x_fx = 0; + FOR (int idx = 0; idx < N; idx++) + { + sum_x_fx = (Word32)sum_x_fx + x_fx[idx]; + } + sum_ix_fx = dotp_fx(x_fx, n_i_fx, N, &dot_exp); + sum_ix_q = 30 - (dot_exp - (11 + 15)); + + sum_ix_fx = L_shr(sum_ix_fx, sum_ix_q - 15); + num = L_sub((sum_ix_fx * N), (sum_x_fx * sum_i_fx[N])); + slope_fx = Mpy_32_32(num, res_table[N]); + offset_fx = Mpy_32_16_1(L_sub(sum_x_fx, (slope_fx * sum_i_fx[N])), one_by_n_fx[N]); + + IF (upd) + { + FOR (i = 0; i < N; i++) + { + IF(slope_fx * i > MAX_WORD16) + { + x_fx[i] = MAX_WORD16; + } + ELSE + { + x_fx[i] = (Word16)L_add_sat((slope_fx * i), offset_fx); + } + } + } + + IF(a_fx != NULL) + { + *a_fx = (Word16)slope_fx; + } + + IF(b_fx != NULL) + { + *b_fx = (Word16)offset_fx; + } + + return; +} + + /* helper function for panning_wrap_angles */ static float wrap_azi( const float azi_deg ) diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 1ead3ba60..aa3e4195d 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -1199,4 +1199,74 @@ static void put_value_fx( } return; -} \ No newline at end of file +} + +void deindex_lvq_SHB_fx( + UWord32 index, + Word16 *out, + const Word16 nbits, + const Word16 mode) +{ + UWord16 i; + const Word8 *p_no_lead; + const Word16 *p_scales; + Word16 scale; + Word16 idx_scale; + UWord32 offsets[MAX_NO_SCALES + 1]; + + IF (mode == 0) + { + p_no_lead = &no_lead_BWE[(nbits - mslvq_SHB_min_bits[0]) * 3]; + p_scales = &scales_BWE_fx[(nbits - mslvq_SHB_min_bits[0]) * 3]; + } + ELSE + { + p_no_lead = &no_lead_BWE_3b[(nbits - mslvq_SHB_min_bits[1]) * 3]; + p_scales = &scales_BWE_3b_fx[(nbits - mslvq_SHB_min_bits[1]) * 3]; + } + + + IF (index == 0) + { + set16_fx(out, 0, LATTICE_DIM); + } + ELSE + { + /* create offsets */ + offsets[0] = 0; + FOR (i = 0; i < MAX_NO_SCALES; i++) + { + offsets[i + 1] = table_no_cv[p_no_lead[i]] + offsets[i]; + } + + /* find idx_scale */ + idx_scale = 0; + WHILE ((Word16)i <= MAX_NO_SCALES && index >= offsets[idx_scale]) + { + idx_scale++; + } + idx_scale--; + index -= offsets[idx_scale]; + + /* find idx_leader */ + i = 1; + WHILE (index >= table_no_cv[i]) + { + i++; + } + i = i - 1; + + decode_comb_fx((Word32)(index - table_no_cv[i] - 1), out, i); + + scale = p_scales[idx_scale]; + FOR (i = 0; i < LATTICE_DIM; i++) + { + Word32 temp = Mpy_32_16_1(sigma_BWE_fx[mode * LATTICE_DIM + i], scale); + temp = Mpy_32_16_1(temp, out[i]); + out[i] = extract_h(temp); + //out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i]; + } + } + + return; +} diff --git a/lib_com/prot.h b/lib_com/prot.h index 845f39f59..7f32169d4 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2671,7 +2671,26 @@ void swb_tbe_enc( float *White_exc16k, /* o : shaped white excitation for the FB TBE */ const float pitch_buf[] /* i : pitch for each subframe */ ); - +#ifdef IVAS_FLOAT_FIXED +void ivas_swb_tbe_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ + const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation */ + Word16 Q_exc, + //const float voice_factors[], /* i : voicing factors */ + const Word16 voice_factors_fx[], /* i : voicing factors */ + //const float old_syn_12k8_16k[], /* i : low band synthesis */ + const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis */ + Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE */ + Word32 *synth_fx, /* o : SHB synthesis/final synthesis */ + Word16 *pitch_buf_fx, + Word16 *Q_white_exc); + +/* Below 2 function to be cleaned up when intermediate float buffer maintenance is removed */ +void ivas_swb_tbe_dec_float2fix(Decoder_State *st, STEREO_ICBWE_DEC_HANDLE hStereoICBWE); + +void ivas_swb_tbe_dec_fix2float(Decoder_State *st, STEREO_ICBWE_DEC_HANDLE hStereoICBWE/*, Word16 Q_bwe_exc_orig*/); +#endif void swb_tbe_dec( Decoder_State *st, /* i/o: decoder state structure */ STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 31012bd6e..e5946de40 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -216,6 +216,13 @@ Word16 deindex_lvq_fx( Word16 *p_no_scales ); +void deindex_lvq_SHB_fx( + UWord32 index, + Word16 *out, + const Word16 nbits, + const Word16 mode +); + void permute_fx( Word16 *pTmp1, /* i/o: vector whose components are to be permuted */ const Word16 *perm /* i : permutation info (indexes that should be interchanged), max two perms */ @@ -2714,6 +2721,51 @@ void GenShapedSHBExcitation_fx( #endif ); +void GenShapedSHBExcitation_ivas_fx( + Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word32 *mem_csfilt, /* i/o: memory */ + Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ + Word16 *state_lpc_syn, /* i/o: memory */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ + Word16 bwe_seed[], /* i/o: random number generator seed */ + Word16 voice_factors[], /* i : voicing factor*/ + const Word16 extl, /* i : extension layer */ + Word16 *tbe_demph, /* i/o: de-emphasis memory */ + Word16 *tbe_premph, /* i/o: pre-emphasis memory */ + Word16 *lpc_shb_sf, /* i: LP coefficients */ + const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ + Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ + Word16 *shb_res, + Word16 *vf_ind, + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + Word16 *Q_bwe_exc, + Word16 *Q_bwe_exc_fb, + const Word16 Q_shb, + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi +#if 1//def ADD_IVAS_TBE_CODE + , /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16* nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16* mixExc16k, /* i/o: exc spreading for IC-BWE */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word32* prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16* prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16* Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ +#endif +); + void GenSHBSynth_fx( const Word16 *shb_target_speech, /* i : i synthesized speech */ Word16 *shb_syn_speech_32k, /* o : output highband component */ @@ -5497,6 +5549,20 @@ void swb_tbe_dec_fx( Word16* pitch_buf ); +void ivas_dequantizeSHBparams_fx_9_1( + Decoder_State *st_fx, + const Word16 extl, /* i : extension layer */ + Word32 extl_brate, /* i : extensiuon layer bitrate */ + Word16 *Q_lsf, /* o : SHB LSF from de-quantization Q15*/ + Word16 *Q_subgain, /* o : SHB subframe gains from de-quantization Q15*/ + Word32 *Q_framegrain, /* o : SHB frame gain from de-quantization Q18*/ + Word16 *uv_flag, /* o : unvoiced flag*/ + Word32 *Q_shb_ener_sf, /* o : Q15 */ + Word16 *Q_shb_res_gshape, /* o : Q14 */ + Word16 *Q_mixFactors, /* o : Q15 */ + Word16 *MSFlag +); + void fb_tbe_dec_fx( Decoder_State *st, /* i/o: encoder state structure */ const Word16 fb_exc[], /* i : FB excitation from the SWB part */ @@ -8942,6 +9008,13 @@ void v_add_fx( const int16_t N /* i : Vector length */ ); +void v_shr_16( + const Word16 x[], /* i : Input vector */ + const Word16 shift, /* i : Constant */ + Word16 y[], /* o : Output vector that contains x >> shift */ + const Word16 N /* i : Vector length */ +); + void v_shr( const Word32 x[], /* i : Input vector */ const Word16 shift, /* i : Constant */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 4270ec337..695c93c96 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -37916,6 +37916,12 @@ const float sigma_BWE[] = { 0.008809121277345f, 0.008799007638233f, 0.009070002122415f, 0.009080199707624f, 0.009739951681282f, 0.010572954192948f, 0.018255917586799f, 0.018995351636606f }; /* for 3 bits first stage */ +const Word32 sigma_BWE_fx[] = { +17011214, 16701976, 17561200, +17474996, 19251270, 20645372, 39204284, +40792208, 18917444, 18895726, 19477682, +19499580, 20916386, 22705246, 39204284, +40792208 }; /* for 3 bits first stage */ const float inv_sigma_BWE[] = { 126.2392994665869f, 128.5766227364854f, 122.2856952550425f, 122.8889356808437f, 111.5502335749417f, @@ -37928,6 +37934,12 @@ const float SHB_LSF_mean[10] = { 0.04131f, 0.08078f, 0.12348f, 0.16567f, 0.21045f, 0.25449f, 0.30101f, 0.34693f, 0.39605f, 0.44428f }; +const Word16 SHB_LSF_mean_fx[10] = { +1353, 2646, 4046, +5428, 6896, 8339, 9863, +11368, 12977, 14558 +}; + /* 4 bit VQ first stage */ /* An 6-by-16 matrix */ const float SHB_LSF_VQ4[96] = { @@ -37963,12 +37975,43 @@ const float SHB_LSF_VQ3[48] = { const float *const cb_LSF_BWE[] = { SHB_LSF_VQ4, SHB_LSF_VQ3 }; +const Word16 SHB_LSF_VQ4_fx[96] = +{ 150, 51, -507, -986, -1115, -944, +-184, -77, 95, 232, 440, 497, -115, +-107, -109, -242, -446, -592, 387, 799, +1132, 1263, 1259, 1122, -128, -599, -1214, +-1389, -1319, -1016, 533, 424, 148, -125, +-378, -501, -337, -590, -587, -630, -715, +-750, 504, 849, 750, 508, 234, 68, +176, -177, -407, 327, 206, 21, -107, +341, 423, 264, -17, -180, -110, -381, +-716, -725, -232, -42, 170, 265, 273, +336, 397, 450, 69, 285, 519, 686, +656, 564, 120, 115, -123, -382, -19, +234, -377, -629, -296, -95, 21, 63, +-206, -456, 518, 472, 179, 22 }; +/* 3 bit VQ first stage */ +const Word16 SHB_LSF_VQ3_fx[48] = +{ 278, 403, 285, 65, -206, -337, +386, 770, 838, 753, 599, 445, -196, +-455, -609, -524, -206, -78, 39, 199, +393, 514, 491, 462, -91, -435, -979, +-1241, -1225, -976, -52, -98, -216, -422, +-599, -688, 127, 137, 0, 52, 301, +412, -278, -422, 9, 199, 137, 72 }; +const Word16 *const cb_LSF_BWE_fx[] = { SHB_LSF_VQ4_fx, SHB_LSF_VQ3_fx }; + const int16_t mslvq_SHB_min_bits[] = {14, 12}; /* for 4 bits and 3 bits respectively */ const float scales_BWE[] = { 0.932f, 1.677f, 2.811f, /* 14 bits*/ 0.891f, 1.770f, 3.002f, /* 15 bits */ 0.849f, 1.769f, 3.226f}; /* 16 bits */ +const Word16 scales_BWE_fx[] = { +7634, 13737, +23027, 7299, 14499, +24592, 6955, 14491, +26427 }; const Word8 no_lead_BWE[] = { 8, 6, 5, /* 14 bits */ @@ -37982,6 +38025,12 @@ const float scales_BWE_3b[] = { 0.885f, 1.549f, 2.815f /* 14 bits*/ }; +const Word16 scales_BWE_3b_fx[] = { +7847, 14262, +28934, 7610, 12771, +21544, 7249, 12689, +23060 }; + const Word8 no_lead_BWE_3b[] = { 4, 5, 2, /* 12 bits */ 5, 5, 5, /* 13 bits */ @@ -37993,6 +38042,13 @@ const float LastCoefPred_0bit[18] = { 0.00817f, -0.00645f, -0.00937f, -0.00726f, 0.00363f, 0.02148f, 0.08237f, 0.20400f, 0.00000f }; +const Word32 LastCoefPred_0bit_fx[18] = +{ +10930692, -29356102, -14495515, +-11918534, 3435973, 89292368, 269423296, +1105954048, 0, 17544942, -13851270, +-20121922, -15590731, 7795365, 46127948, +176888224, 438086656, 0 }; const float LastCoefPred_1bit[36] = { 0.01760f, -0.02193f, 0.01160f, 0.00841f, 0.01782f, 0.04071f, 0.10121f, 0.37727f, 0.00451f, @@ -38001,6 +38057,13 @@ const float LastCoefPred_1bit[36] = { -0.01554f, -0.02277f, -0.00474f, 0.00468f, 0.01070f, 0.04327f, 0.09857f, 0.26611f, -0.01164f }; +const Word32 LastCoefPred_1bit_fx[36] = { +37795712, -47094316, 24910810, +18060338, 38268160, 87424056, 217346816, +810181184, 9685151, 53107272, -26843546, +11703786, -7301444, 20444044, 22655952, +138448272, 307648512, 9234180 }; + const int16_t config_LSF_BWE[] = { 4, 16, 1, /* 21 bits */ 4, 16, 1, /* 20 */ diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 3f805d8cb..4093dbbfa 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1991,21 +1991,30 @@ extern const Word16 tcx_mdct_window_trans_48_fx[60]; *----------------------------------------------------------------------------------*/ extern const float sigma_BWE[]; +extern const Word32 sigma_BWE_fx[]; extern const float inv_sigma_BWE[]; extern const float scales_BWE[]; extern const Word8 no_lead_BWE[]; extern const float scales_BWE_3b[]; +extern const Word16 scales_BWE_fx[]; +extern const Word16 scales_BWE_3b_fx[]; extern const Word8 no_lead_BWE_3b[]; extern const int16_t mslvq_SHB_min_bits[]; extern const float SHB_LSF_mean[]; +extern const Word16 SHB_LSF_mean_fx[]; extern const float SHB_LSF_VQ3[48]; extern const float SHB_LSF_VQ4[96]; extern const float *const cb_LSF_BWE[]; +extern const Word16 SHB_LSF_VQ3_fx[48]; +extern const Word16 SHB_LSF_VQ4_fx[96]; +extern const Word16 *const cb_LSF_BWE_fx[]; extern const float LastCoefPred_0bit[18]; extern const float LastCoefPred_1bit[36]; +extern const Word32 LastCoefPred_0bit_fx[18]; +extern const Word32 LastCoefPred_1bit_fx[36]; extern const int16_t config_LSF_BWE[]; diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 50166970b..6fd0a5d79 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7,10 +7,15 @@ #include "options.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ +#include "prot.h" #include "prot_fx1.h" #include "prot_fx2.h" #include "basop_util.h" +#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ +#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 //Q31 +#define POW_EXC16k_WHTND_FX 178125000 //Q-6 + /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -838,7 +843,7 @@ static void scale_st_swb( } /* L_gain_in/L_gain_out in Q14 */ /* overflows if L_gain_in > 2 * L_gain_out */ - g0_fx = shr(g0_fx, sh_g0); /* sh_g0 may be >0, <0, or =0 */ + g0_fx = shr_sat(g0_fx, sh_g0); /* sh_g0 may be >0, <0, or =0 */ //Need to verify? g0_fx = mult_r(g0_fx, agc_fac1_para_fx); /* L_gain_in/L_gain_out * AGC_FAC1_FX */ } @@ -2543,6 +2548,876 @@ void GenShapedSHBExcitation_fx( return; } +void GenShapedSHBExcitation_ivas_fx( + Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word32 *mem_csfilt, /* i/o: memory */ + Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ + Word16 *state_lpc_syn, /* i/o: memory */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ + Word16 bwe_seed[], /* i/o: random number generator seed */ + Word16 voice_factors[], /* i : voicing factor*/ + const Word16 extl, /* i : extension layer */ + Word16 *tbe_demph, /* i/o: de-emphasis memory */ + Word16 *tbe_premph, /* i/o: pre-emphasis memory */ + Word16 *lpc_shb_sf, /* i: LP coefficients */ + const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ + Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ + Word16 *shb_res, + Word16 *vf_ind, + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + Word16 *Q_bwe_exc, + Word16 *Q_bwe_exc_fb, + const Word16 Q_shb, + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi +#if 1//def ADD_IVAS_TBE_CODE + , /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16* nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16* mixExc16k, /* i/o: exc spreading for IC-BWE */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word32* prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16* prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16* Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ +#endif +) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER]; + Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; + Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ + Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ + Word16 Q_R; + Word32 LepsP[LPC_WHTN_ORDER + 1]; + Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; + Word32 pow1, pow22; + Word16 scale, temp1, temp2; + + Word16 excTmp2[L_FRAME16k]; + Word16 *White_exc16k; + Word16 excNoisyEnv[L_FRAME16k]; + Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ + Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ + Word16 varEnvShape; + Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ + Word16 exc16kWhtnd[L_FRAME16k]; + + Word32 L_tmp; + Word16 vf_tmp; + Word16 tmp, exp, tmp2; + Word16 voiceFacEst[NB_SUBFR16k]; + Word16 zero_mem[LPC_SHB_ORDER]; + Word32 syn_shb_ener_sf[4]; + Word16 tempSHB[80]; + Word16 Q_pow1, Q_pow22; + + Word32 L_tmp2, L_tmp3, L_tmp4; + Word16 temp; + + Word16 White_exc16k_FB_temp[L_FRAME16k]; + Word32 White_exc16k_32[L_FRAME16k]; + Word16 Q_temp; + Word16 prev_Q_bwe_exc_fb; + +#if 1//def ADD_IVAS_TBE_CODE + Word32 tempD; + Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; + Word16 cbsize; + Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; + Word16 c0, c1, c2, c3, c4, c5, g1, g2, g, den; + Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; + Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; + Word16 flag_plosive; + Word16 delta; + Word16 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; + + mix_factor = 0; +#endif + set16_fx(zero_mem, 0, LPC_SHB_ORDER); + set16_fx(wht_fil_mem, 0, LPC_WHTN_ORDER); + + FOR(i = 0; i < L_FRAME32k; i = i + 2) + { + exc32k[i] = negate(bwe_exc_extended[i]); + move16(); + exc32k[i + 1] = bwe_exc_extended[i + 1]; + move16(); + } + + /* Decimate by 2 */ + Decimate_allpass_steep_fx(exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k); + /* i: exc32k in Q_bwe_exc */ + /* o: exc16k in Q_bwe_exc */ + + autocorr_fx(exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1); + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max(R_l[0], 1); + move16(); + FOR(i = 1; i <= LPC_WHTN_ORDER; i++) + { + L_tmp = Mpy_32(R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1]); + L_Extract(L_tmp, &R_h[i], &R_l[i]); + } + E_LPC_lev_dur(R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL); + Copy_Scale_sig(lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub(norm_s(lpc_whtn[0]), 2)); + fir_fx(exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3); + + /* i: exc16k in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc */ + +#if 1//def ADD_IVAS_TBE_CODE + IF(GE_32(extl_brate, SWB_TBE_2k8)) +#else + IF(GE_32(bitrate, ACELP_24k40)) +#endif + { + temp2 = 0; + move16(); + FOR(j = 0; j < 4; j++) + { + temp1 = shb_res_gshape[j]; + move16(); + FOR(i = 0; i < 80; i++) + { + exc16kWhtnd[temp2 + i] = round_fx(L_shl(L_mult(exc16kWhtnd[temp2 + i], temp1), 1)); + /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ + } + temp2 = add(temp2, 80); + } + } + + /* Estimate pow1 associated with Low band nonlinear extended excitation */ + /* pow1=0.00001f */ + tmp = sub(shl(*Q_bwe_exc, 1), 31); +#ifdef BASOP_NOGLOB + pow1 = L_shl_sat(21475l/*0.00001f Q31*/, tmp); /* 0.00001f in 2*(Q_bwe_exc) */ +#else + pow1 = L_shl(21475l/*0.00001f Q31*/, tmp); /* 0.00001f in 2*(Q_bwe_exc) */ +#endif + FOR(k = 0; k < L_FRAME16k; k++) + { + /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ + excTmp2[k] = abs_s(exc16kWhtnd[k]); + move16(); + + /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ +#ifdef BASOP_NOGLOB + pow1 = L_mac0_sat(pow1, exc16kWhtnd[k], exc16kWhtnd[k]); /* 2*Q_bwe_exc */ +#else + pow1 = L_mac0(pow1, exc16kWhtnd[k], exc16kWhtnd[k]); /* 2*Q_bwe_exc */ +#endif + } + Q_pow1 = shl(*Q_bwe_exc, 1); + + test(); +#ifdef ADD_IVAS_TBE_CODE + IF(EQ_16(flag_ACELP16k, 0)) +#else + IF((LE_32(bitrate, ACELP_13k20)) && (GE_32(bitrate, ACELP_7k20))) +#endif + { + /* varEnvShape = mean_fx(voice_factors, 4); */ + /* unroll the loop */ + L_tmp = L_mult(voice_factors[0], 8192); + L_tmp = L_mac(L_tmp, voice_factors[1], 8192); + L_tmp = L_mac(L_tmp, voice_factors[2], 8192); + varEnvShape = mac_r(L_tmp, voice_factors[3], 8192); /* varEnvShape in Q15 */ + } + ELSE /* 16k core */ + { + /* varEnvShape = mean_fx(voice_factors, 5); */ + /* unroll the loop */ + L_tmp = L_mult(voice_factors[0], 6554); + L_tmp = L_mac(L_tmp, voice_factors[1], 6554); + L_tmp = L_mac(L_tmp, voice_factors[2], 6554); + L_tmp = L_mac(L_tmp, voice_factors[3], 6554); + varEnvShape = mac_r(L_tmp, voice_factors[4], 6554); /* varEnvShape in Q15 */ + } + + IF(EQ_16(extl, FB_TBE)) + { + /*pow(varEnvShape,3) */ + tmp = mult_r(varEnvShape, varEnvShape); + tmp = mult_r(tmp, varEnvShape); + + /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ + fb_deemph_fac = sub(22282/*0.68f Q15*/, tmp); + fb_deemph_fac = s_max(fb_deemph_fac, 15729/*0.48f Q15*/); + } + + /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ + varEnvShape = msu_r(1179773824l/*0.549375f Q31*/, 8172/*0.249375f Q15*/, varEnvShape); + + /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ + varEnvShape = s_max(varEnvShape, 9830/*0.3f Q15*/); + varEnvShape = s_min(varEnvShape, 16368/*0.4995f Q15*/); + varEnvShape = shl(varEnvShape, 1); + csfilt_num2[0] = sub(MAX_16, varEnvShape); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + + test(); + test(); + test(); +#if 1//def ADD_IVAS_TBE_CODE + IF(EQ_16(element_mode, EVS_MONO) && *mem_csfilt == 0 && ((EQ_32(bitrate, ACELP_9k60)) || (EQ_32(bitrate, ACELP_16k40)) || (EQ_32(bitrate, ACELP_24k40)))) +#else + IF(*mem_csfilt == 0 && ((EQ_32(bitrate, ACELP_9k60)) || (EQ_32(bitrate, ACELP_16k40)) || (EQ_32(bitrate, ACELP_24k40)))) +#endif + { + /* pre-init smoothing filter to avoid energy drop outs */ + L_tmp = L_mult(excTmp2[0], 1638); + FOR(i = 1; i < L_SUBFR16k / 4; i++) + { + L_tmp = L_mac(L_tmp, excTmp2[i], 1638); /*1638 = 1/20 in Q15*/ + } + /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ + + /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ + /* rather stick to the more conservative approach, to avoid potential clippings */ + test(); + IF(!(prev_bfi && EQ_16(extl, FB_TBE))) + { + /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ + varEnvShape = 26214/*0.8f Q15*/; + move16(); + csfilt_num2[0] = sub(MAX_16, varEnvShape); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + *mem_csfilt = Mult_32_16(L_tmp, varEnvShape); + move32(); + } +#if 1//def ADD_IVAS_TBE_CODE + IF (MSFlag > 0) + { + //varEnvShape = 0.995f; + varEnvShape = 32604; + //csfilt_num2[0] = 1.0f - varEnvShape; + csfilt_num2[0] = 32768 - varEnvShape; + neg_csfilt_den2[1] = varEnvShape; + } + + White_exc16k = exc16k; + + /* Track the low band envelope */ + IF(element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT) + { + IF(extl_brate != SWB_TBE_1k10 && extl_brate != SWB_TBE_1k75) + { + mem_csfilt_left = 0; + mem_csfilt_right = 0; + FOR (k = 0; k < L_FRAME16k; k++) + { + //excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; + excNoisyEnvLeft[k] = add(mem_csfilt_left, mult_r(csfilt_num2[0], excTmp2[k])); + //mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; + mem_csfilt_left = mult_r(neg_csfilt_den2[1], excNoisyEnvLeft[k]); + //excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; + excNoisyEnvRight[L_FRAME16k - k - 1] = add(mem_csfilt_right, mult_r(csfilt_num2[0], excTmp2[L_FRAME16k - k - 1])); + //mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; + mem_csfilt_right = mult_r(neg_csfilt_den2[1], excNoisyEnvRight[L_FRAME16k - k - 1]); + } + + alpha = 0; + //step = 1.0f / L_FRAME16k; + step = 102; //Q15 + FOR (k = 0; k < L_FRAME16k; k++) + { + //excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + (1 - alpha) * excNoisyEnvRight[k]; + excNoisyEnv[k] = add(mult_r(alpha, excNoisyEnvLeft[k]), mult_r((32767 - alpha), excNoisyEnvRight[k])); + alpha = add(alpha, step); + } + } + } + ELSE +#endif + { + /* Track the low band envelope */ + L_tmp = *mem_csfilt; + move32(); + FOR(i = 0; i < L_FRAME16k; i++) + { + excNoisyEnv[i] = mac_r(L_tmp, csfilt_num2[0], excTmp2[i]); + move16(); + /* excNoisyEnv : Q_bwe_exc, + *mem_csfilt: Q_bwe_exc+16, excTmp2: Q_bwe_exc, csfilt_num2[0] Q15 */ + L_tmp = L_mult(excNoisyEnv[i], neg_csfilt_den2[1]); /* Q_bwe_exc+16 */ + } + *mem_csfilt = L_tmp; + move32(); + } +#if 1//def ADD_IVAS_TBE_CODE + IF (extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75) + { + /* generate gaussian (white) excitation */ + FOR (k = 0; k < L_FRAME16k; k++) + { + White_exc16k[k] = own_random(&bwe_seed[0]); + } + + /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; + pow22 = POW_EXC16k_WHTND_FX; + Q_pow22 = -6; + //v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); + Word16 pow1_exp = Q31 - Q_pow1; + Word32 temp_pow = Sqrt32(pow1, &pow1_exp); + temp_pow = L_shl(Mpy_32_32(temp_pow, pow22_inv), pow1_exp); + /*Word16 out_exp; + Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); + temp_pow1 = L_shl(temp_pow1, out_exp);*/ + //v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); + L_tmp = 0; + FOR (k = 0; k < L_FRAME16k; k++) { + White_exc16k_32[k] = L_mult(White_exc16k[k], round_fx(temp_pow)); + White_exc16k[k] = round_fx(L_shl(White_exc16k_32[k], *Q_bwe_exc - NOISE_QADJ)); // Q_bwe_exc - NOISE_QADJ + L_tmp = max(L_tmp, L_abs(White_exc16k_32[k])); + } + Q_temp = norm_l(L_tmp); + IF (L_tmp == 0) + { + Q_temp = 31; + } + } + ELSE +#endif + { + /* create a random excitation - Reuse exc16k memory */ + White_exc16k = exc16k; + create_random_vector_fx(White_exc16k, L_FRAME, bwe_seed); + create_random_vector_fx(White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed); + + L_tmp = L_deposit_l(0); + tmp = add(*Q_bwe_exc, 1); + FOR(k = 0; k < L_FRAME16k; k++) + { +#ifdef BASOP_NOGLOB + L_tmp4 = L_shl_sat(L_deposit_l(White_exc16k[k]), tmp); +#else + L_tmp4 = L_shl(L_deposit_l(White_exc16k[k]), tmp); +#endif + IF (excNoisyEnv[k] != 0) + { + L_tmp4 = L_mult(excNoisyEnv[k], White_exc16k[k]);/* (Q_bwe_exc) +5 +1*/ + } + White_exc16k_32[k] = L_tmp4; + move32(); + L_tmp = L_max(L_tmp, L_abs(White_exc16k_32[k])); + } + Q_temp = norm_l(L_tmp); + IF (L_tmp == 0) + { + Q_temp = 31; + } + /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ + /* White_exc16k in Q6 */ + + /* calculate pow22 */ + /* pow22=0.00001f */ + tmp = sub(shl(sub(*Q_bwe_exc, NOISE_QADJ), 1), 31); + pow22 = L_shl(21475l/*0.00001f Q31*/, tmp); /* 0.00001f in 2*(Q_bwe_exc-NOISE_QADJ) */ + tmp = sub(NOISE_QFAC, 5); + FOR(k = 0; k < L_FRAME16k; k++) + { + /* White_exc16k[k] *= excNoisyEnv[k]; */ + White_exc16k[k] = mult_r(excNoisyEnv[k], shl(White_exc16k[k], tmp)); + move16(); + /* i: excNoisyEnv in (Q_bwe_exc) */ + /* i: White_exc16k in Q6 */ + /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ +#ifdef BASOP_NOGLOB + pow22 = L_mac0_sat(pow22, White_exc16k[k], White_exc16k[k]); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ +#else + pow22 = L_mac0(pow22, White_exc16k[k], White_exc16k[k]); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ +#endif + } + /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ + Q_pow22 = shl(sub(*Q_bwe_exc, NOISE_QADJ), 1); + } + +#if 1//def ADD_IVAS_TBE_CODE + flag_plosive = 0; + move16(); + test(); test(); test(); + IF(GE_32(extl_brate, SWB_TBE_2k8) || EQ_32(extl_brate, SWB_TBE_1k10) || EQ_32(extl_brate, SWB_TBE_1k75)) +#else + IF(GE_32(bitrate, ACELP_24k40)) +#endif + { + IF(EQ_16(*vf_ind, 20)) /* encoder side */ + { +#ifdef ADD_IVAS_TBE_CODE //BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! + if (extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75) + { + /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ + find_td_envelope(White_exc16k, L_FRAME16k, 20, NULL, EnvWhiteExc16k); + find_td_envelope(exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd); + + for (k = 0; k < L_FRAME4k; k++) + { + EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; + EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; + } + + /* calculate the optimal mix factor */ + c0 = c1 = c2 = c3 = c4 = c5 = 0.0f; + for (i = 0; i < NUM_SHB_SUBGAINS; i++) + { + c0_part[i] = sum2_f(&EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + c1_part[i] = -2.0f * dotp(&EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + c2_part[i] = sum2_f(&EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + c3_part[i] = -2.0f * dotp(&EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + c4_part[i] = 2.0f * dotp(&EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + c5_part[i] = sum2_f(&EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS); + + c0 += c0_part[i]; + c1 += c1_part[i]; + c2 += c2_part[i]; + c3 += c3_part[i]; + c4 += c4_part[i]; + c5 += c5_part[i]; + } + + den = 4.0f * c0 * c2 - c4 * c4; + g1 = (c3 * c4 - 2 * c1 * c2) / den; + g2 = (c1 * c4 - 2 * c0 * c3) / den; + + *Env_error = 0.0f; + flag_plosive = 0; + for (i = 0; i < NUM_SHB_SUBGAINS; i++) + { + Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; + *Env_error += Env_error_part[i]; + + if (Env_error_part[i] > THR_ENV_ERROR_PLOSIVE) + { + /* envelope error is too high -> likely a plosive */ + flag_plosive = 1; + } + } + + if (flag_plosive) + { + /* plosive detected -> set the mixing factor to 0 */ + *vf_ind = 0; + mix_factor = 0.0f; + } + else + { + /* normalize gain */ + g = g2 / (g1 + g2); + + /* quantization of the mixing factor */ + cbsize = 1 << NUM_BITS_SHB_VF; + delta = 1.0f / (cbsize - 1); + if (g > 1.0f) + { + g = 1.0f; + } + else if (g < delta) + { + /* prevent low gains to be quantized to 0 as this is reserved for plosives */ + g = delta; + } + + *vf_ind = usquant(g, &mix_factor, 0.0f, 1.0f / (cbsize - 1), cbsize); + } + } + else +#endif + { + Estimate_mix_factors_fx(shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, + (*Q_bwe_exc - NOISE_QADJ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind); + tmp = voiceFacEst[0]; + tmp2 = MAX_16; + if (LE_16(tmp, 22938/*0.7f Q15*/)) + { + tmp2 = 26214/*0.8f Q15*/; + } + } + } + ELSE /* decoder side */ + { +#if 1//def ADD_IVAS_TBE_CODE + IF (extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75) + { + IF (*vf_ind == 0) + { + //mix_factor = 0.0f; + mix_factor = 0; + flag_plosive = 1; + } + ELSE + { + //mix_factor = usdequant(*vf_ind, 0.0f, 1.0f / ((1 << NUM_BITS_SHB_VF) - 1)); + mix_factor = usdequant_fx(*vf_ind, 0, 2341); + } + } + ELSE +#endif + { + /* *vf_ind is an integer scale by 0.125f*/ + tmp = shl(*vf_ind, (15 - 3)); + tmp2 = MAX_16; + IF (LE_16(tmp, 22938/*0.7f Q15*/)) + { + tmp2 = 26214/*0.8f Q15*/; + } + } + } +#if 1//def ADD_IVAS_TBE_CODE + IF(NE_32(extl_brate, SWB_TBE_1k10) && NE_32(extl_brate, SWB_TBE_1k75)) +#endif + { + voice_factors[0] = mult_r(voice_factors[0], tmp2); + move16(); + voice_factors[1] = mult_r(voice_factors[1], tmp2); + move16(); + voice_factors[2] = mult_r(voice_factors[2], tmp2); + move16(); + voice_factors[3] = mult_r(voice_factors[3], tmp2); + move16(); + voice_factors[4] = mult_r(voice_factors[4], tmp2); + move16(); + } + } +#if 1//def ADD_IVAS_TBE_CODE + IF (element_mode >= IVAS_CPE_DFT && nlExc16k != NULL) + { + /* save buffers for IC-BWE */ + //mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); + Copy(exc16kWhtnd, nlExc16k, L_FRAME16k); + //v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); + /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); + Word16 temp_fac_exp = 0; + temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ + L_tmp = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &exp); + Word16 temp_fac = round_fx_sat(L_shl_sat(L_tmp, exp)); //Q15 + //v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); + FOR (k = 0; k < L_FRAME16k; k++) { + mixExc16k[k] = mult_r(White_exc16k[k], temp_fac); + } + } +#endif + + tmp = sub(Q_temp, 3); + FOR(k = 0; k < L_FRAME16k; k++) + { + White_exc16k_FB[k] = round_fx(L_shl(White_exc16k_32[k], tmp)); /* Q_bwe_exc +5 +1 +Q_temp -16 -3 */ + } + prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + *Q_bwe_exc_fb = sub(add(*Q_bwe_exc, Q_temp), 13); + + deemph_fx(White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph); + /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ + /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ +#if 1//def ADD_IVAS_TBE_CODE + IF (extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75) + { + IF (!flag_plosive) /* use only LB excitation in case of plosives */ + { + /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ + //old_scale = (float)sqrt(*prev_pow_exc16kWhtnd / pow1); + //old_scale = divide3232(*prev_pow_exc16kWhtnd, pow1); // exp = Q15 - (Q_pow1) + //Word16 old_scale_exp = Q15 - (Q_pow1); + //old_scale = Sqrt16(old_scale, &old_scale_exp); + //old_scale = shl(old_scale, old_scale_exp); //Q15 + L_tmp = root_a_over_b_fx(*prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp); + old_scale = round_fx_sat(L_shl_sat(L_tmp, exp)); //Q15 + //new_scale = 1.0f; + new_scale = 32767; + //step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); + step_scale = mult_r(sub(new_scale, old_scale), 205); + scale = old_scale; + + /* interpolate between the old and the new value of the mixing factor */ + old_fact = *prev_mix_factor; + new_fact = mix_factor; + //step = (new_fact - old_fact) / (L_FRAME16k / 2); + step = mult_r(sub(new_fact, old_fact), 205); + fact = old_fact; + + /* mixing of LB and gaussian excitation in the first half of the frame */ + FOR (k = 0; k < L_FRAME16k / 2; k++) + { + //exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; + //exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); + L_tmp = L_add( L_shl( L_mult( fact, mult_r( White_exc16k[k], scale ) ), NOISE_QADJ ), + L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + exc16kWhtnd[k] = round_fx( L_tmp ); + fact = add_sat(fact, step); + scale = add_sat(scale, step_scale); + } + + /* mixing of LB and gaussian excitation in the second half of the frame */ + FOR (; k < L_FRAME16k; k++) + { + //exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; + //exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); + L_tmp = L_add( L_shl( L_mult( new_fact, White_exc16k[k] ), NOISE_QADJ ), + mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + exc16kWhtnd[k] = round_fx( L_tmp ); + } + } + //preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); + preemph_fx(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); + } + ELSE +#endif + { +#if 1//def ADD_IVAS_TBE_CODE + IF (coder_type == UNVOICED || MSFlag == 1) +#else + IF(EQ_16(coder_type, UNVOICED)) +#endif + { + L_tmp = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &exp); +#ifdef BASOP_NOGLOB + scale = round_fx_sat(L_shl_sat(L_tmp, exp)); /*Q15 */ +#else + scale = round_fx(L_shl(L_tmp, exp)); /*Q15 */ +#endif + FOR(k = 0; k < L_FRAME16k; k++) + { + /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ + L_tmp = L_mult(White_exc16k[k], scale); + /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ + exc16kWhtnd[k] = round_fx(L_shl(L_tmp, NOISE_QADJ)); + /* exc16kWhtnd: Q_bwe_exc */ + } + preemph_fx(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); + /* i/o: exc16kWhtnd (Q_bwe_exc) */ + /* i/o: tbe_premph (Q_bwe_exc) */ + } + ELSE + { + Word16 nbSubFr, lSubFr; + Word16 tempQ15; + Word32 tempQ31; + /*nbSubFr = ( bitrate < ACELP_24k40 )? NB_SUBFR : NB_SUBFR16k;*/ + nbSubFr = NB_SUBFR16k; + lSubFr = (L_FRAME16k / NB_SUBFR16k); + IF(LT_32(bitrate, ACELP_24k40)) + { + nbSubFr = NB_SUBFR; + move16(); + lSubFr = (L_FRAME16k / NB_SUBFR); + move16(); + } + k = 0; + FOR(i = 0; i < nbSubFr; i++) + { + test(); + IF(EQ_16(coder_type, VOICED) && (LT_32(bitrate,ACELP_24k40))) + { + exp = 0; + tempQ15 = Sqrt16(voice_factors[i], &exp); /* Q15 */ + temp = shl(tempQ15, exp); /* Q15 exc16kWhtnd scale factor */ + exp = 0; + tempQ15 = Sqrt16(temp, &exp); /* Q15 */ + temp1 = shl(tempQ15, exp); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ + temp = sub(MAX_16, temp); + tempQ31 = Mult_32_16(pow1, temp); + L_tmp = root_a_over_b_fx(tempQ31, Q_pow1, pow22, Q_pow22, &exp); +#ifdef BASOP_NOGLOB + temp2 = round_fx_sat(L_shl_sat(L_tmp, exp)); /* Q15 whiteEnvShapedExc scale factor */ +#else + temp2 = round_fx(L_shl(L_tmp, exp)); /* Q15 whiteEnvShapedExc scale factor */ +#endif + } + ELSE + { + /* Adjust noise mixing for formant sharpening filter */ + tempQ15 = mult_r(SWB_NOISE_MIX_FAC_FX, formant_fac); + /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ + vf_tmp = sub(MAX_16, tempQ15); + vf_tmp = mult_r(voice_factors[i], vf_tmp); + + exp = 0; + tempQ15 = Sqrt16(vf_tmp, &exp); /* Q15 */ + temp1 = shl(tempQ15, exp); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ + temp = sub(MAX_16, vf_tmp); + tempQ31 = Mult_32_16(pow1, temp); + L_tmp = root_a_over_b_fx(tempQ31, Q_pow1, pow22, Q_pow22, &exp); +#ifdef BASOP_NOGLOB + temp2 = round_fx_sat(L_shl_sat(L_tmp, exp)); /* Q15 whiteEnvShapedExc scale factor */ +#else + temp2 = round_fx(L_shl(L_tmp, exp)); /* Q15 whiteEnvShapedExc scale factor */ +#endif + } + + FOR(j = 0; j < lSubFr; j++) + { + /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ + L_tmp = L_mult(temp2, White_exc16k[k + j]); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat(L_tmp, NOISE_QADJ); /* 16+(Q_bwe_exc) */ + exc16kWhtnd[k + j] = mac_r_sat(L_tmp, temp1, exc16kWhtnd[k + j]); +#else + L_tmp = L_shl(L_tmp, NOISE_QADJ); /* 16+(Q_bwe_exc) */ + exc16kWhtnd[k + j] = mac_r(L_tmp, temp1, exc16kWhtnd[k + j]); +#endif + move16(); + /* Q_bwe_exc */ + } + k = add(k, lSubFr); + + /* estimate the pre-emph factor */ + tempQ15 = sub(MAX_16, voice_factors[i]); + exp = 0; + temp = Sqrt16(tempQ15, &exp); + temp = shl(temp, exp - 1); + + temp2 = add(temp, shl(temp1, -1)); /* shift right by 1 to avoid overflow */ + temp = div_s(temp, temp2); /* Q15 */ + temp = mult_r(PREEMPH_FAC, temp); + + preemph_fx(&exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph); + /* exc16kWhtnd: Q_bwe_exc; + tbe_premph: Q_bwe_exc*/ + } + } + } + +#if 1//def ADD_IVAS_TBE_CODE + IF(LT_32(extl_brate, SWB_TBE_2k8)) +#else + IF(LT_32(bitrate, ACELP_24k40)) +#endif + { + Syn_filt_s(0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: excSHB in Q_bwe_exc */ + } + ELSE + { + set16_fx(zero_mem, 0, LPC_SHB_ORDER); + + Syn_filt_s(0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1); + syn_shb_ener_sf[0] = L_shr(sum2_fx(tempSHB, 80),3); + move32(); + + Syn_filt_s(0, lpc_shb_sf + (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1); + syn_shb_ener_sf[1] = L_shr(sum2_fx(tempSHB, 80),3); + move32(); + + Syn_filt_s(0, lpc_shb_sf + 2 * (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1); + syn_shb_ener_sf[2] = L_shr(sum2_fx(tempSHB, 80),3); + move32(); + + Syn_filt_s(0, lpc_shb_sf + 3 * (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1); + syn_shb_ener_sf[3] = L_shr(sum2_fx(tempSHB, 80),3); + move32(); + + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: tempSHB in Q_bwe_exc */ + /* o: syn_shb_ener_sf in (2*Q_bwe_exc+1) */ + IF(LE_32(bitrate, MAX_ACELP_BRATE)) + { + L_tmp = sum32_fx(syn_shb_ener_sf, 4); + + /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ + tmp = shl(Q_shb, 1); + tmp2 = add(shl(*Q_bwe_exc, 1), 1); + L_tmp2 = root_a_over_b_fx(shb_ener_sf_32, tmp, L_tmp, tmp2, &exp); /* L_tmp2 in (Q31-exp) */ + + *Q_bwe_exc = sub(*Q_bwe_exc, exp); + move16(); /* compensate for the exp shift */ + tmp2 = add(prev_Q_bwe_syn, n_mem2); + IF(GT_16(*Q_bwe_exc, tmp2)) + { + L_tmp2 = L_shl(L_tmp2, sub(tmp2, *Q_bwe_exc)); + *Q_bwe_exc = tmp2; + move16(); + } + FOR(i = 0; i < L_FRAME16k; i++) + { + L_tmp3 = Mult_32_16(L_tmp2, exc16kWhtnd[i]); /* *Q_bwe_exc + (31-exp) - 15 */ + exc16kWhtnd[i] = round_fx(L_tmp3); /* *Q_bwe_exc - exp */ + } + } + /* i: L_tmp2 in (Q31-exp) */ + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ + + /* Rescale the past memories: LP synth and SHB look ahead buffers */ + tmp = sub(*Q_bwe_exc, prev_Q_bwe_syn); + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + state_lpc_syn[i] = shl_sat(state_lpc_syn[i], tmp); + move16(); + } + FOR(i = -L_SHB_LAHEAD; i < 0; i++) + { + excSHB[i] = shl_sat(excSHB[i], tmp); + move16(); + } + /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ + + Syn_filt_s(0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1); + Syn_filt_s(0, lpc_shb_sf + (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1); + Syn_filt_s(0, lpc_shb_sf + 2 * (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1); + Syn_filt_s(0, lpc_shb_sf + 3 * (LPC_SHB_ORDER + 1), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1); + /* i: exc16kWhtnd in (Q_bwe_exc) */ + /* o: excSHB in (Q_bwe_exc) */ + } + + IF(EQ_16(extl, FB_TBE)) + { + tmp = sub(add(*Q_bwe_exc_fb, 20), prev_Q_bwe_exc_fb); + Scale_sig(fb_state_lpc_syn, LPC_SHB_ORDER, tmp); + Scale_sig(fb_tbe_demph, 1, tmp); + Syn_filt_s(0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1); + /* i: White_exc16k_FB in (14-n2) */ + /* o: White_exc16k_FB_temp in (14-n2) */ + + FOR(i = 0; i < 10; i++) + { + FOR(j = 0; j < 32; ++j) + { + White_exc16k_FB_temp[i * 32 + j] = mult_r(White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j]); + move16(); + } + } + + *Q_bwe_exc_fb = add(*Q_bwe_exc_fb, 20); + move16(); /**Q_bwe_exc_fb +35 +1 -16*/ + flip_spectrum_fx(White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k); + + deemph_fx(White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph); + + } + ELSE + { + set16_fx(White_exc16k_FB, 0, L_FRAME16k); + } + +#if 1//def ADD_IVAS_TBE_CODE + *prev_pow_exc16kWhtnd = L_shr_sat(pow1, Q_pow1); // power goes above MAX_32 + *prev_mix_factor = mix_factor; +#endif + return; +} /*====================================================================================*/ /* FUNCTION : void GenSHBSynth_fx() */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 463e64c1e..ac9804ee6 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -3711,6 +3711,24 @@ void v_shr( return; } + +void v_shr_16( + const Word16 x[], /* i : Input vector */ + const Word16 shift, /* i : Constant */ + Word16 y[], /* o : Output vector that contains x >> shift */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + + for ( i = 0; i < N; i++ ) + { + y[i] = shr(x[i], shift); + } + + return; +} + /*-------------------------------------------------------------------* * delay_signal() * diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index 29c4a92a3..8885879dc 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -751,7 +751,7 @@ void swb_CNG_dec_ivas_fx( { st_fx->last_vad_fx = 1; move16(); - st_fx->hTdCngDec->burst_cnt_fx = add(st_fx->hTdCngDec->burst_cnt_fx, 1); + st_fx->hTdCngDec->burst_cnt_fx = add_sat(st_fx->hTdCngDec->burst_cnt_fx, 1); //saturation reached? IF ( GT_16(st_fx->hTdCngDec->burst_cnt_fx, 10)) { st_fx->hTdCngDec->burst_cnt_fx = 0; diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 5c1f61d0f..adbfc2e70 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1823,7 +1823,7 @@ void ivas_binaural_hrtf_close( * * The functions adds the LFE to the left and right channels after binaural rendering *-------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void ivas_binaural_add_LFE( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t output_frame, /* i : length of input frame */ @@ -1831,6 +1831,7 @@ void ivas_binaural_add_LFE( float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ ) { + int16_t render_lfe, idx_lfe; float gain; @@ -1848,11 +1849,11 @@ void ivas_binaural_add_LFE( if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { gain = GAIN_LFE; + } else { - gain = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE; - } + gain = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE; } for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { @@ -1866,7 +1867,60 @@ void ivas_binaural_add_LFE( return; } +#else +void ivas_binaural_add_LFE_fix( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word16 output_frame, /* i : length of input frame */ + Word32 *input_fx[], /* i : transport channels */ + Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output */ +) +{ +#ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + IF( st_ivas->hCrendWrapper != NULL ) + { + st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe_fx = st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe * ( ONE_IN_Q14 ); + } +#endif + Word16 render_lfe, idx_lfe; + Word16 gain_fx; + + IF( st_ivas->hBinRenderer != NULL ) + { + render_lfe = st_ivas->hBinRenderer->render_lfe; + } + ELSE + { + render_lfe = TRUE; + } + + IF( render_lfe ) + { + IF( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + gain_fx = GAIN_LFE_FX; + } + ELSE + { + gain_fx = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe_fx : GAIN_LFE_FX; + } + FOR( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) + { + v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx - 1 + /* copy LFE to left and right channels */ + FOR( int idx = 0; idx < output_frame; idx++ ) + { + input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q + output_fx[0][idx] = L_add_sat( output_fx[0][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] ); + output_fx[1][idx] = L_add_sat( output_fx[1][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] ); + } + } + } + + return; +} + +#endif /*------------------------------------------------------------------------- * ivas_binRenderer() * diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 3d00a5556..3af6bacd7 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -109,6 +109,8 @@ ivas_error ivas_core_dec( float tmp_buffer[L_FRAME48k]; #ifdef IVAS_FLOAT_FIXED set_zero( tmp_buffer, L_FRAME48k ); + Word16 tmp_buffer_fx[L_FRAME48k]; + set_s(tmp_buffer_fx, 0, L_FRAME48k); #endif int16_t tmps, incr; float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; @@ -1930,7 +1932,7 @@ ivas_error ivas_core_dec( IF( hBWE_TD != NULL && st->extl == WB_TBE ) { fixedToFloat_arr( hBWE_TD->lsp_prevfrm_fx, hBWE_TD->lsp_prevfrm, Q15, LPC_SHB_ORDER ); - hBWE_TD->GainAttn = fixedToFloat( hBWE_TD->GainAttn_fx, Q15 ); + hBWE_TD->GainAttn = fixedToFloat( hBWE_TD->GainAttn_fx, Q15); hBWE_TD->prev_wb_bwe_frame_pow = fixedToFloat( hBWE_TD->prev_wb_bwe_frame_pow_fx, Q22 ); fixedToFloat_arrL( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_csfilt, st->prev_Q_bwe_exc, 2 ); FOR( i = 0; i < 2; ++i ) @@ -1992,7 +1994,32 @@ ivas_error ivas_core_dec( if ( st->extl == SWB_TBE || st->extl == FB_TBE || ( st->coder_type != AUDIO && st->coder_type != INACTIVE && st->core_brate >= SID_2k40 && st->core == ACELP_CORE && !st->con_tcx && output_Fs >= 32000 && st->bwidth > NB && st->bws_cnt > 0 ) ) { /* SWB TBE decoder */ - swb_tbe_dec( st, hStereoICBWE, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], tmp_buffer /*fb_exc*/, hb_synth[n], pitch_buf[n] ); + st->Q_syn = 0; + st->Q_exc = 0; + + floatToFixed_arrL(bwe_exc_extended[n], bwe_exc_extended_fx[n], 2 * st->Q_exc, L_FRAME32k + NL_BUFF_OFFSET); + floatToFixed_arr(voice_factors[n], voice_factors_fx[n], 15, NB_SUBFR16k); + floatToFixed_arrL(old_syn_12k8_16k[n], old_syn_12k8_16k_fx, Q11, L_FRAME16k); + + floatToFixed_arr(pitch_buf[n], pitch_buf_fx[n], Q6, NB_SUBFR16k); + + //Word32 synth_fx[L_FRAME48k]; + for (int i = 0; i < L_FRAME32k; i++) + { + hb_synth_32[n][i] = floatToFixed(hb_synth[n][i], Q11); + } + ivas_swb_tbe_dec_float2fix(st, hStereoICBWE); + Word16 Q_white_exc; + + ivas_swb_tbe_dec_fx(st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx, tmp_buffer_fx /*fb_exc*/, hb_synth_32[n], pitch_buf_fx[n], &Q_white_exc); + + ivas_swb_tbe_dec_fix2float(st, hStereoICBWE); + fixedToFloat_arrL(hb_synth_32[n], hb_synth[n], Q11, L_FRAME48k); + if (Q_white_exc > 31) { + Scale_sig(tmp_buffer_fx, L_FRAME48k, 31 - Q_white_exc); + } + fixedToFloat_arr(tmp_buffer_fx, tmp_buffer, min(Q_white_exc, 31), L_FRAME48k); + //original call: swb_tbe_dec( st, hStereoICBWE, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], tmp_buffer /*fb_exc*/, hb_synth[n], pitch_buf[n] ); /* FB TBE decoder */ if ( st->extl == FB_TBE ) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index e67f7a0aa..14ee5abd0 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -668,73 +668,32 @@ ivas_error ivas_cpe_dec_fx( /* DFT Stereo residual decoding */ IF( GT_16( hCPE->hStereoDft->res_cod_band_max, 0 ) && !st_ivas->bfi ) { - -#ifndef IVAS_FLOAT_FIXED_ +#ifndef IVAS_FLOAT_FIXED stereo_dft_dec_res( hCPE, res_buf, output_flt[1] ); #else { - Word32 output_fix[L_FRAME8k], i_max_val; - Word16 q_output_fix, q_pst_old_syn, s_max_val; - float max_val = 0.0f; - Word16 ii; - for (ii = 0; ii < NBPSF_PIT_MAX; ii++) - { - if (max_val < fabs(hCPE->hStereoDft->hBpf->pst_old_syn[ii])) - { - max_val = (float)fabs(hCPE->hStereoDft->hBpf->pst_old_syn[ii]); - } - } - s_max_val = (Word16)max_val; - if (max_val > 32767.0 || max_val < -32768.0) - { - assert(0); - } - IF (s_max_val != 0) - { - q_pst_old_syn = norm_s(s_max_val) - Q3; - } - ELSE - { - q_pst_old_syn = 0; - } - hCPE->hStereoDft->hBpf->q_pst_old_syn = q_pst_old_syn; - - for (ii = 0; ii < L_FRAME8k; ii++) - { - if (max_val < fabs(output_flt[1][ii])) - { - max_val = (float)fabs(output_flt[1][ii]); - } - } - i_max_val = (Word32)max_val; - IF (i_max_val != 0) - { - q_output_fix = norm_l(i_max_val) - Q8; - } - ELSE - { - q_output_fix = 0; - } - hCPE->hStereoDft->q_res_cod_mem_fx = q_output_fix; - floatToFixed_arrL(output_flt[1], &output_fix[0], q_output_fix, L_FRAME8k); - floatToFixed_arrL(hCPE->hStereoDft->res_cod_mem, hCPE->hStereoDft->res_cod_mem_fx, q_output_fix, sizeof(hCPE->hStereoDft->res_cod_mem_fx) / sizeof(hCPE->hStereoDft->res_cod_mem_fx[0])); - floatToFixed_arr(hCPE->hStereoDft->hBpf->pst_old_syn, hCPE->hStereoDft->hBpf->pst_old_syn_fx, q_pst_old_syn, sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx) / sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx[0])); + Word32 output_fix[L_FRAME8k]; + hCPE->hStereoDft->q_res_cod_mem_fx = 0; // keeping same as shift needed inside. + floatToFixed_arrL(hCPE->hStereoDft->res_cod_mem, hCPE->hStereoDft->res_cod_mem_fx, Q16, sizeof(hCPE->hStereoDft->res_cod_mem_fx) / sizeof(hCPE->hStereoDft->res_cod_mem_fx[0])); + floatToFixed_arr(hCPE->hStereoDft->hBpf->pst_old_syn, hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx) / sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx[0])); floatToFixed_arr(hCPE->hStereoDft->hBpf->mem_mean_pit, hCPE->hStereoDft->hBpf->mem_mean_pit_fx, Q4, sizeof(hCPE->hStereoDft->hBpf->mem_mean_pit) / sizeof(hCPE->hStereoDft->hBpf->mem_mean_pit[0])); floatToFixed_arr(hCPE->hCoreCoder[0]->old_pitch_buf, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, Q6, sizeof(hCPE->hCoreCoder[0]->old_pitch_buf_16_fx) / sizeof(hCPE->hCoreCoder[0]->old_pitch_buf_16_fx[0])); - hCPE->hStereoDft->hBpf->psf_att_fx = floatToFixed(hCPE->hStereoDft->hBpf->psf_att, Q15); + hCPE->hStereoDft->hBpf->psf_att_fx = (Word16)floatToFixed(hCPE->hStereoDft->hBpf->psf_att, Q15); + hCPE->hStereoDft->stab_fac_smooth_res_fx = floatToFixed(hCPE->hStereoDft->stab_fac_smooth_res, Q31); Copy(hCPE->hStereoDft->hBpf->Track_on_hist, hCPE->hStereoDft->hBpf->Track_on_hist_fx, sizeof(hCPE->hStereoDft->hBpf->Track_on_hist_fx) / sizeof(hCPE->hStereoDft->hBpf->Track_on_hist_fx[0])); Copy(hCPE->hStereoDft->hBpf->vibrato_hist, hCPE->hStereoDft->hBpf->vibrato_hist_fx, sizeof(hCPE->hStereoDft->hBpf->vibrato_hist_fx) / sizeof(hCPE->hStereoDft->hBpf->vibrato_hist_fx[0])); - stereo_dft_dec_res_fx(hCPE, res_buf_fx, Q8, q_output_fix, output_fix); + stereo_dft_dec_res_fx(hCPE, res_buf_fx, Q8, output_fix); Copy(hCPE->hStereoDft->hBpf->vibrato_hist_fx, hCPE->hStereoDft->hBpf->vibrato_hist, sizeof(hCPE->hStereoDft->hBpf->vibrato_hist_fx) / sizeof(hCPE->hStereoDft->hBpf->vibrato_hist_fx[0])); Copy(hCPE->hStereoDft->hBpf->Track_on_hist_fx, hCPE->hStereoDft->hBpf->Track_on_hist, sizeof(hCPE->hStereoDft->hBpf->Track_on_hist_fx) / sizeof(hCPE->hStereoDft->hBpf->Track_on_hist_fx[0])); + hCPE->hStereoDft->stab_fac_smooth_res = fixedToFloat(hCPE->hStereoDft->stab_fac_smooth_res_fx, Q15); hCPE->hStereoDft->hBpf->psf_att = fixedToFloat(hCPE->hStereoDft->hBpf->psf_att_fx, Q15); fixedToFloat_arr(hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf, Q6, sizeof(hCPE->hCoreCoder[0]->old_pitch_buf_16_fx) / sizeof(hCPE->hCoreCoder[0]->old_pitch_buf_16_fx[0])); fixedToFloat_arr(hCPE->hStereoDft->hBpf->mem_mean_pit_fx, hCPE->hStereoDft->hBpf->mem_mean_pit, Q4, sizeof(hCPE->hStereoDft->hBpf->mem_mean_pit) / sizeof(hCPE->hStereoDft->hBpf->mem_mean_pit[0])); - fixedToFloat_arr(hCPE->hStereoDft->hBpf->pst_old_syn_fx, hCPE->hStereoDft->hBpf->pst_old_syn, q_pst_old_syn, sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx) / sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx[0])); - fixedToFloat_arrL(hCPE->hStereoDft->res_cod_mem_fx, hCPE->hStereoDft->res_cod_mem, q_output_fix, sizeof(hCPE->hStereoDft->res_cod_mem_fx) / sizeof(hCPE->hStereoDft->res_cod_mem_fx[0])); - fixedToFloat_arrL(&output_fix[0], output_flt[1], q_output_fix, L_FRAME8k); + fixedToFloat_arr(hCPE->hStereoDft->hBpf->pst_old_syn_fx, hCPE->hStereoDft->hBpf->pst_old_syn, 0, sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx) / sizeof(hCPE->hStereoDft->hBpf->pst_old_syn_fx[0])); + fixedToFloat_arrL(hCPE->hStereoDft->res_cod_mem_fx, hCPE->hStereoDft->res_cod_mem, Q16, sizeof(hCPE->hStereoDft->res_cod_mem_fx) / sizeof(hCPE->hStereoDft->res_cod_mem_fx[0])); + fixedToFloat_arrL(&output_fix[0], output_flt[1], Q15, L_FRAME8k); } #endif diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 1fc8abe28..61f7e5d7d 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3393,6 +3393,7 @@ ivas_error ivas_jbm_dec_render( Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; Word32 tmp_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k] = { 0 }; Word32 *p_temp_fx[MAX_OUTPUT_CHANNELS]; + Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; Word16 subframe_len, gd_bits, exp, nchan_in, i, j; #endif SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -3427,6 +3428,9 @@ ivas_error ivas_jbm_dec_render( for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc[n] = p_output[n]; +#ifdef IVAS_FLOAT_FIXED + p_tc_fx[n] = p_output_fx[n]; +#endif } for ( n = 0; n < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; n++ ) @@ -3442,6 +3446,9 @@ ivas_error ivas_jbm_dec_render( for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; +#ifdef IVAS_FLOAT_FIXED + p_tc_fx[n] = &st_ivas->hTcBuffer->tc_fx[n][st_ivas->hTcBuffer->n_samples_rendered]; +#endif } } @@ -4078,43 +4085,39 @@ ivas_error ivas_jbm_dec_render( } exp -= gd_bits; *st_ivas->hCrendWrapper->p_io_qfactor = exp; - if ( crendInPlaceRotation ) - { - for ( i = 0; i < nchan_in; i++ ) - { - for ( j = 0; j < *nSamplesRendered; j++ ) - { - - p_temp_fx[i][j] = (Word32) float_to_fixed( p_output[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); - } - } - } - else + for (i = 0; i < nchan_in; i++) { - for ( i = 0; i < nchan_in; i++ ) - { - for ( j = 0; j < *nSamplesRendered; j++ ) - { - - p_temp_fx[i][j] = (Word32) float_to_fixed( p_tc[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); - } - } + for (j = 0; j < *nSamplesRendered; j++) + { + p_tc_fx[i][j] = (Word32)float_to_fixed(p_tc[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + } } if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, - &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_temp_fx, p_temp_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) { return error; } - for ( i = 0; i < nchan_out; i++ ) + //scaling all Tc to output q // needed + for (i = nchan_out; i < nchan_in; i++) { - for ( j = 0; j < *nSamplesRendered; j++ ) - { + for (j = 0; j < *nSamplesRendered; j++) + { + p_tc_fx[i][j] = (Word32)L_shr(p_tc_fx[i][j], exp - *st_ivas->hCrendWrapper->p_io_qfactor); + } + } + ivas_binaural_add_LFE_fix(st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx); - p_output[i][j] = fixed_to_float( p_temp_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); - } + for (i = 0; i < nchan_in; i++) + { + for (j = 0; j < *nSamplesRendered; j++) + { + // p_output[i][j] = fixed_to_float(p_output_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + p_tc[i][j] = fixed_to_float(p_tc_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + } } + #else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) @@ -4123,8 +4126,10 @@ ivas_error ivas_jbm_dec_render( { return error; } + + ivas_binaural_add_LFE(st_ivas, *nSamplesRendered, p_tc, p_output); #endif - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); + } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -4174,7 +4179,32 @@ ivas_error ivas_jbm_dec_render( return error; } - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); +#ifdef IVAS_FLOAT_FIXED + Word16 q = Q16; + q = q - find_guarded_bits_fx(*nSamplesRendered); + FOR(i = 0; i < st_ivas->nchan_transport; ++i) + { + //p_tc and pout point to same location + p_tc_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(p_tc[i], p_tc_fx[i], q, *nSamplesRendered); + p_output_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(p_output[i], p_output_fx[i], q, *nSamplesRendered); + } + + ivas_binaural_add_LFE_fix(st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx); + + FOR(i = 0; i < st_ivas->nchan_transport; ++i) + { + //p_tc and pout point to same location + fixedToFloat_arrL(p_tc_fx[i], p_tc[i], q, *nSamplesRendered); + free(p_tc_fx[i]); + fixedToFloat_arrL(p_output_fx[i], p_output[i], q, *nSamplesRendered); + free(p_output_fx[i]); + } +#else + ivas_binaural_add_LFE(st_ivas, *nSamplesRendered, p_tc, p_output); +#endif + } } else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) @@ -4186,7 +4216,25 @@ ivas_error ivas_jbm_dec_render( if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) { { - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); +#ifdef IVAS_FLOAT_FIXED + Word16 q = Q16; + q = q - find_guarded_bits_fx(*nSamplesRendered); + FOR(i = 0; i < max(st_ivas->hDecoderConfig->nchan_out, MC_PARAMUPMIX_MAX_INPUT_CHANS); ++i) + { + p_output_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(p_output[i], p_output_fx[i], q, *nSamplesRendered); + } + + ivas_binaural_add_LFE_fix( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx); + + FOR(i = 0; i < max(st_ivas->hDecoderConfig->nchan_out, MC_PARAMUPMIX_MAX_INPUT_CHANS); ++i) + { + fixedToFloat_arrL(p_output_fx[i], p_output[i], q, *nSamplesRendered); + free(p_output_fx[i]); + } +#else + ivas_binaural_add_LFE(st_ivas, *nSamplesRendered, p_output, p_output); +#endif } } else if ( st_ivas->renderer_type == RENDERER_MC ) @@ -4227,7 +4275,25 @@ ivas_error ivas_jbm_dec_render( return error; } - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); +#ifdef IVAS_FLOAT_FIXED + Word16 q = Q16; + q = q - find_guarded_bits_fx(*nSamplesRendered); + FOR(i = 0; i < max(st_ivas->hDecoderConfig->nchan_out, MC_PARAMUPMIX_MAX_INPUT_CHANS); ++i) + { + p_output_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(p_output[i], p_output_fx[i], q, *nSamplesRendered); + } + + ivas_binaural_add_LFE_fix(st_ivas, *nSamplesRendered, p_output_fx, p_output_fx); + + FOR(i = 0; i < max(st_ivas->hDecoderConfig->nchan_out, MC_PARAMUPMIX_MAX_INPUT_CHANS); ++i) + { + fixedToFloat_arrL(p_output_fx[i], p_output[i], q, *nSamplesRendered); + free(p_output_fx[i]); + } +#else + ivas_binaural_add_LFE(st_ivas, *nSamplesRendered, p_output, p_output); +#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) @@ -4626,21 +4692,32 @@ ivas_error ivas_jbm_dec_flush_renderer( for ( j = 0; j < hTcBuffer->n_samples_granularity; j++ ) { - p_temp_fx[i][j] = (Word32) float_to_fixed( hTcBuffer->tc[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); + hTcBuffer->tc_fx[i][j] = (Word32) float_to_fixed( hTcBuffer->tc[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); } } if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, - hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_temp_fx, p_temp_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } - for ( i = 0; i < nchan_out; i++ ) + //scaling all Tc to output q // needed + for (i = nchan_out; i < nchan_in; i++) { - for ( j = 0; j < hTcBuffer->n_samples_granularity; j++ ) - { + for (j = 0; j < *nSamplesRendered; j++) + { + hTcBuffer->tc_fx[i][j] = (Word32)L_shr(hTcBuffer->tc_fx[i][j], exp - *st_ivas->hCrendWrapper->p_io_qfactor); + } + } - p_output[i][j] = fixed_to_float( p_temp_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor ); - } + ivas_binaural_add_LFE_fix(st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc_fx, p_output_fx); + + for (i = 0; i < nchan_in; i++) + { + for (j = 0; j < *nSamplesRendered; j++) + { + // p_output[i][j] = fixed_to_float(p_output_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + st_ivas->hTcBuffer->tc[i][j] = fixed_to_float(st_ivas->hTcBuffer->tc_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + } } #else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, @@ -4648,8 +4725,10 @@ ivas_error ivas_jbm_dec_flush_renderer( { return error; } + ivas_binaural_add_LFE(st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc, p_output); #endif - ivas_binaural_add_LFE( st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc, p_output ); + + } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { @@ -4658,7 +4737,29 @@ ivas_error ivas_jbm_dec_flush_renderer( return error; } - ivas_binaural_add_LFE( st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc, p_output ); +#ifdef IVAS_FLOAT_FIXED + Word16 q = Q16; + q = q - find_guarded_bits_fx(*nSamplesRendered); + FOR(i = 0; i < st_ivas->nchan_transport; ++i) + { + //p_tc and pout point to same location + floatToFixed_arrL(st_ivas->hTcBuffer->tc[i], st_ivas->hTcBuffer->tc_fx[i], q, *nSamplesRendered); + p_output_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(p_output[i], p_output_fx[i], q, *nSamplesRendered); + } + + ivas_binaural_add_LFE_fix(st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc_fx, p_output_fx); + + FOR(i = 0; i < st_ivas->nchan_transport; ++i) + { + //p_tc and pout point to same location only need to do for 2 channels can be cleaned up later + fixedToFloat_arrL(st_ivas->hTcBuffer->tc_fx[i], st_ivas->hTcBuffer->tc[i], q, *nSamplesRendered); + fixedToFloat_arrL(p_output_fx[i], p_output[i], q, *nSamplesRendered); + free(p_output_fx[i]); + } +#else + ivas_binaural_add_LFE(st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output); +#endif } } else diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 25180c379..c1818b09f 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1466,6 +1466,121 @@ static void ivas_spar_get_skip_mat_fx( } #endif +#ifdef IVAS_FLOAT_FIXED +static void ivas_spar_calc_smooth_facs_fx( + Word32 *cldfb_in_ts_re_fx[CLDFB_NO_COL_MAX], // i + Word32 *cldfb_in_ts_im_fx[CLDFB_NO_COL_MAX], // i + Word16 q_cldfb, + Word16 nbands_spar, + const Word16 nSlots, + const Word16 isFirstSubframe, + ivas_fb_bin_to_band_data_t *bin2band, + Word16 *smooth_fac_fx, // o + Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1] ) // o +{ + Word16 b, bin, i, ts; + Word32 subframe_band_nrg_fx[IVAS_MAX_NUM_BANDS]; + Word32 smooth_long_avg_fx[IVAS_MAX_NUM_BANDS]; + Word32 smooth_short_avg_fx[IVAS_MAX_NUM_BANDS]; + Word32 L_temp; + Word16 exp_tmp, q_tmp; + bin = 0; + FOR( b = 0; b < nbands_spar; b++ ) + { + IF( GE_16( bin, CLDFB_NO_CHANNELS_MAX ) || ( GT_16( b, 0 ) && LT_16( bin2band->p_cldfb_map_to_spar_band[bin], bin2band->p_cldfb_map_to_spar_band[bin - 1] ) ) ) + { + BREAK; + } + + /* calculate band-wise subframe energies */ + subframe_band_nrg_fx[b] = 0; + WHILE( LT_16( bin, CLDFB_NO_CHANNELS_MAX ) && EQ_16( b, bin2band->p_cldfb_map_to_spar_band[bin] ) ) + { + FOR( ts = 0; ts < nSlots; ts++ ) + { + L_temp = L_add( L_shr( Mpy_32_32( cldfb_in_ts_re_fx[ts][bin], cldfb_in_ts_re_fx[ts][bin] ), 4 ), L_shr( Mpy_32_32( cldfb_in_ts_im_fx[ts][bin], cldfb_in_ts_im_fx[ts][bin] ), 4 ) ); // 2*q_cldfb - 35 + subframe_band_nrg_fx[b] = L_add_sat( subframe_band_nrg_fx[b], L_temp ); // 2*q_cldfb - 35 (saturation reached in 1 orig pytest) + } + bin++; + } + exp_tmp = sub( 66, i_mult( 2, q_cldfb ) ); + subframe_band_nrg_fx[b] = Sqrt32( subframe_band_nrg_fx[b], &exp_tmp ); + q_tmp = 31 - exp_tmp; + IF( isFirstSubframe && LT_16( nSlots, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + { + /* fill up to full 5ms subframe */ + smooth_buf_fx[b][0] = L_add( smooth_buf_fx[b][0], L_shr( subframe_band_nrg_fx[b], q_tmp ) ); // Q0 + } + ELSE + { + smooth_buf_fx[b][0] = L_shr( subframe_band_nrg_fx[b], q_tmp ); // Q0 + } + /* calculate short and long energy averages */ + smooth_short_avg_fx[b] = 0; + FOR( i = 0; i < 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i++ ) + { + smooth_short_avg_fx[b] = L_add( smooth_short_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 + } + + smooth_long_avg_fx[b] = smooth_short_avg_fx[b]; // Q0 + FOR( i = 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i < 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i++ ) + { + smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 + } + smooth_short_avg_fx[b] = Mpy_32_16_1( smooth_short_avg_fx[b], 5461 /*(1/6 in Q15)*/ ); // Q0 + smooth_long_avg_fx[b] = Mpy_32_16_1( smooth_long_avg_fx[b], 1639 /*(1/20 in Q15)*/ ); // Q0 + + /* calculate smoothing factor based on energy averages */ + /* reduce factor for higher short-term energy */ + IF( smooth_long_avg_fx[b] <= 0 ) + { + smooth_fac_fx[b] = 0; + } + ELSE IF( smooth_long_avg_fx[b] >= smooth_short_avg_fx[b] ) + { + smooth_fac_fx[b] = MAX_16; // 1.0f in Q15 + } + ELSE + { + smooth_fac_fx[b] = divide3232( smooth_long_avg_fx[b], smooth_short_avg_fx[b] ); // Q15 + } + + /* map factor to range [0;1] */ + smooth_fac_fx[b] = shl( mult_r( s_max( 0, sub( smooth_fac_fx[b], 9830 ) ), 23405 /*Q14*/ ), 1 ); // Q15 + + /* compress factor (higher compression in lowest bands) */ + IF( LT_16( b, 2 ) ) + { + exp_tmp = 0; + smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp ); + smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp ); + smooth_fac_fx[b] = shl( smooth_fac_fx[b], exp_tmp ); // Q15 + } + ELSE + { + exp_tmp = 0; + smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp ); + smooth_fac_fx[b] = shl( smooth_fac_fx[b], exp_tmp ); // Q15 + } + + /* apply upper bounds depending on band */ + smooth_fac_fx[b] = s_max( min_smooth_gains1_fx[b], s_min( max_smooth_gains2_fx[b], smooth_fac_fx[b] ) ); + } + + /* only update if we collected a full 5ms worth of energies for the buffer */ + IF( isFirstSubframe || EQ_16( nSlots, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + { + FOR( b = 0; b < nbands_spar; b++ ) + { + FOR( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- ) + { + smooth_buf_fx[b][i] = smooth_buf_fx[b][i - 1]; + } + } + } + return; +} +#else static void ivas_spar_calc_smooth_facs( float *cldfb_in_ts_re[CLDFB_NO_COL_MAX], float *cldfb_in_ts_im[CLDFB_NO_COL_MAX], @@ -1558,7 +1673,7 @@ static void ivas_spar_calc_smooth_facs( } return; } - +#endif /*-------------------------------------------------------------------* * ivas_spar_dec_agc_pca() @@ -2016,6 +2131,10 @@ void ivas_spar_dec_upmixer_sf( int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out; float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; +#ifdef IVAS_FLOAT_FIXED + Word32 *cldfb_in_ts_re_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; + Word32 *cldfb_in_ts_im_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; +#endif int16_t i, b, ts, out_ch, in_ch; int16_t num_spar_bands, spar_band, nchan_transport; int16_t num_in_ingest, split_band; @@ -2023,6 +2142,9 @@ void ivas_spar_dec_upmixer_sf( float *p_tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; int16_t md_idx; float Pcm_tmp[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; +#ifdef IVAS_FLOAT_FIXED + Word32 Pcm_tmp_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; +#endif int16_t numch_out_dirac; float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; @@ -2104,6 +2226,10 @@ void ivas_spar_dec_upmixer_sf( { cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; +#ifdef IVAS_FLOAT_FIXED + cldfb_in_ts_re_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][ts * num_cldfb_bands]; + cldfb_in_ts_im_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; +#endif } } } @@ -2115,6 +2241,10 @@ void ivas_spar_dec_upmixer_sf( { cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; +#ifdef IVAS_FLOAT_FIXED + cldfb_in_ts_re_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][ts * num_cldfb_bands]; + cldfb_in_ts_im_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; +#endif } } } @@ -2196,7 +2326,38 @@ void ivas_spar_dec_upmixer_sf( if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) { +#ifdef IVAS_FLOAT_FIXED + //float2fix (to be cleaned) + Word16 q_cldfb = 31; + for (ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++) + { + Word16 q_ts_re = Q_factor_arrL(cldfb_in_ts_re[0][ts], CLDFB_NO_CHANNELS_MAX); + Word16 q_ts_im = Q_factor_arrL(cldfb_in_ts_im[0][ts], CLDFB_NO_CHANNELS_MAX); + q_cldfb = min(q_cldfb, min(q_ts_re, q_ts_im)); + } + for (ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++) + { + floatToFixed_arrL(cldfb_in_ts_re[0][ts], cldfb_in_ts_re_fx[0][ts], q_cldfb, CLDFB_NO_CHANNELS_MAX); + floatToFixed_arrL(cldfb_in_ts_im[0][ts], cldfb_in_ts_im_fx[0][ts], q_cldfb, CLDFB_NO_CHANNELS_MAX); + } + for (i = 0; i < IVAS_MAX_NUM_BANDS; i++) { + floatToFixed_arrL(hSpar->hMdDec->smooth_buf[i], hSpar->hMdDec->smooth_buf_fx[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1); + } + floatToFixed_arr(hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_fac_fx, Q15, IVAS_MAX_NUM_BANDS); + //float2fix end + + ivas_spar_calc_smooth_facs_fx( cldfb_in_ts_re_fx[0], cldfb_in_ts_im_fx[0], q_cldfb, num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], + hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_buf_fx ); + + //fix2float (to be cleaned) + fixedToFloat_arr(hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_fac, Q15, IVAS_MAX_NUM_BANDS); + for (i = 0; i < IVAS_MAX_NUM_BANDS; i++) { + fixedToFloat_arrL(hSpar->hMdDec->smooth_buf_fx[i], hSpar->hMdDec->smooth_buf[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1); + } + //fix2float end +#else ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); +#endif } for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 7936d5bc5..2e7cc53d3 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -569,14 +569,15 @@ typedef struct stereo_icbwe_dec_data_structure float nlExc16k[L_FRAME16k]; float mixExc16k[L_FRAME16k]; #ifdef IVAS_FLOAT_FIXED - Word32 nlExc16k_fx[L_FRAME16k]; - Word32 mixExc16k_fx[L_FRAME16k]; + Word16 nlExc16k_fx[L_FRAME16k]; + Word16 mixExc16k_fx[L_FRAME16k]; #endif float shbSynthRef[L_FRAME16k]; int16_t MSFlag; float lpSHBRef[LPC_SHB_ORDER + 1]; float gshapeRef[NUM_SHB_SUBFR]; #ifdef IVAS_FLOAT_FIXED + Word16 shbSynthRef_fx[L_FRAME16k]; Word32 lpSHBRef_fx[LPC_SHB_ORDER + 1]; Word16 gshapeRef_fx[NUM_SHB_SUBFR]; #endif @@ -839,6 +840,10 @@ typedef struct ivas_spar_md_dec_state_t int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; float smooth_fac[IVAS_MAX_NUM_BANDS]; +#ifdef IVAS_FLOAT_FIXED + Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; + Word16 smooth_fac_fx[IVAS_MAX_NUM_BANDS]; +#endif float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; int16_t first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 49f7300b8..0956286d3 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1183,13 +1183,13 @@ void stereo_dft_dec_res_fx( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ Word16 q_res, /* i : q fact of residural buffer */ - Word16 q_output, /* i : q factor of output buffer */ Word32 *output /* o : output */ ) { Word16 i; Word16 win[L_FRAME8k + STEREO_DFT_OVL_8k]; Word16 out_16[L_FRAME8k + STEREO_DFT_OVL_8k]; + Word16 bpf_error_signal_8k_16[L_FRAME8k]; Word32 bpf_error_signal_8k[L_FRAME8k]; Word16 prev_bfi; Word16 fac, step; @@ -1210,19 +1210,27 @@ void stereo_dft_dec_res_fx( } /*Inverse MDCT*/ - TCX_MDCT_Inverse( res_buf, Q15, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + TCX_MDCT_Inverse( res_buf, q_res, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); IF ( !prev_bfi ) { /*OLA*/ /*overlapping parts*/ - Word16 q_shift = sub(hCPE->hStereoDft->q_res_cod_mem_fx, sub(Q15, q_res)); + Word16 q_shift = hCPE->hStereoDft->q_res_cod_mem_fx; + move16(); FOR ( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { win[i] = extract_h(L_add(hCPE->hStereoDft->res_cod_mem_fx[i], L_shl(L_mult(win[i], hCPE->hStereoDft->win_8k_fx[i]), q_shift))); + move16(); hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult(win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i]); + move32(); + } + IF (NE_16(q_shift, 0)) + { + v_shr_16(&win[STEREO_DFT_OVL_8k], negate(q_shift), &win[STEREO_DFT_OVL_8k], L_FRAME8k); } - hCPE->hStereoDft->q_res_cod_mem_fx = sub(Q15, q_res); + hCPE->hStereoDft->q_res_cod_mem_fx = 0; + move16(); } ELSE { @@ -1234,12 +1242,15 @@ void stereo_dft_dec_res_fx( step = shl(step, q_div); } fac = 0; + move16(); FOR ( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { win[i] = extract_h(Madd_32_16(Mpy_32_16_1(hCPE->hStereoDft->res_cod_mem_fx[i], sub(MAX_16, mult(fac, fac))), L_mult(hCPE->hStereoDft->win_8k_fx[i], win[i]), sub(MAX_16, mult(sub(MAX_16, fac), sub(MAX_16 , fac))))); + move16(); hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult(win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i]); + move32(); fac = add(fac, step); } } @@ -1250,19 +1261,21 @@ void stereo_dft_dec_res_fx( { /* bass post-filter */ bass_psfilter_fx( hCPE->hStereoDft->hBpf, hCPE->hCoreCoder[0]->Opt_AMR_WB, out_16, L_FRAME8k, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx + ( L_FRAME8k / STEREO_DFT_L_SUBFR_8k ), hCPE->hCoreCoder[0]->bpf_off, - hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, sub(q_output, Q16), bpf_error_signal_8k ); - + hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, 0, bpf_error_signal_8k_16 ); + Copy_Scale_sig_16_32(bpf_error_signal_8k_16, bpf_error_signal_8k, L_FRAME8k, Q15); res_bpf_flag = res_bpf_adapt_fx( hCPE->hStereoDft, bpf_error_signal_8k, res_buf ); IF ( prev_bfi ) { /* Ramp up BPF contribution for the first good frame */ step = (Word16)(0x00CD) ; // ( 1.0f / L_FRAME8k ); - fac = 0; + move16(); + fac = negate(step); FOR ( i = 0; i < L_FRAME8k; i++ ) { - bpf_error_signal_8k[i] = Mpy_32_16_1(bpf_error_signal_8k[i], fac); fac = add(fac, step); + bpf_error_signal_8k[i] = Mpy_32_16_1(bpf_error_signal_8k[i], fac); + move32(); } } Copy_Scale_sig_16_32(out_16, output, L_FRAME8k, 16); @@ -1275,6 +1288,13 @@ void stereo_dft_dec_res_fx( { set_val_Word16( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; + move16(); + Copy_Scale_sig_16_32(out_16, output, L_FRAME8k, 16); + } + ELSE + { + /* This step is needed to ensure output is properly populated with scaled values in all cases*/ + Copy_Scale_sig_16_32(out_16, output, L_FRAME8k, 16); } return; diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c index 82a1655b4..5945c9a6c 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec.c @@ -114,6 +114,7 @@ void stereo_td_init_dec_fx( * * Configure TD stereo decoder *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED Word32 power_table[32 + 1] = { 53687092, 60237908, 67588048, 75835024, 85088304, 95470648, 107119832, 120190432, 134855872, 151310800, 169773488, 190488992, 213732176, 239811440, 269072832, 301904704, @@ -121,6 +122,199 @@ Word32 power_table[32 + 1] = { 850883136, 954706496, 1071198464, 1201904384, 1348558720, 1513107968, 1697734912, 1904890240, 2137321728 }; // Q29 +void tdm_configure_dec( + const Word16 ivas_format, /* i : IVAS format */ + const Word16 ism_mode, /* i : ISM mode in combined format */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word16 *tdm_ratio_idx, /* o : ratio index */ + const Word16 nb_bits_metadata /* i : number of metadata bits */ +) +{ + STEREO_TD_DEC_DATA_HANDLE hStereoTD; + Decoder_State **sts; + Word16 tdm_tmp_SM_LRTD_flag; + Word16 mod_ct, core, bits_offset; + Word16 idx_LRTD_pri_side, tdm_inst_ratio_idx; + Word32 element_brate_adapt; + Word16 bstr_last_pos; + + hStereoTD = hCPE->hStereoTD; + sts = hCPE->hCoreCoder; + + element_brate_adapt = hCPE->element_brate + hCPE->brate_surplus; + bstr_last_pos = (Word16) ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata + (Word16) ( hCPE->brate_surplus / FRAMES_PER_SEC ); + + /*----------------------------------------------------------------* + * Decode CoreCoder signaling + *----------------------------------------------------------------*/ + + /* temporarily decode PCh signaling */ + bits_offset = sts[0]->next_bit_pos; + core = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 1 ); + bits_offset += 1; + + IF( core == ACELP_CORE && hCPE->element_brate < IVAS_24k4 ) + { + mod_ct = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 3 ); + /* Only transition mode is important to decoder, otherwise mod_ct is set to AUDIO only to easy debugging IF needed */ + IF( mod_ct != TRANSITION ) + { + mod_ct = AUDIO; + } + } + ELSE /* core != ACELP_CORE */ + { + mod_ct = AUDIO; /* coder_type == VOICED || coder_type == GENERIC */ + } + + /* Get few parameters needed to decode the bitrate allocated to each channel */ + /* Get the coder_type of the secondary channel (last parameter on 2 bits) */ + sts[1]->coder_type = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING, TDM_SECONDARY_SIGNALLING ); + + /* Get the LRTD config flag: 1 = LRTD configuration, favor closer bitrate per channel; + 0 = Pri/Sec configuration, bitrates linked wrt. the mono */ + tdm_tmp_SM_LRTD_flag = sts[1]->coder_type & 0x1; + sts[1]->coder_type >>= 1; + hStereoTD->tdm_Pitch_reuse_flag = 0; + + IF( sts[1]->coder_type == 2 ) + { + sts[1]->coder_type = GENERIC; + } + ELSE IF( sts[1]->coder_type == 3 ) + { + sts[1]->coder_type = AUDIO; + + IF( hCPE->element_brate <= IVAS_24k4 ) + { + hStereoTD->tdm_Pitch_reuse_flag = 1; + sts[1]->coder_type = GENERIC; + } + } + + /*----------------------------------------------------------------* + * Decode TDM parameters + *----------------------------------------------------------------*/ + + /* Get the correlation ratio */ + *tdm_ratio_idx = get_indice_st( sts[0], element_brate_adapt, (Word16) ( bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS ), TDM_RATIO_BITS ); + + hStereoTD->tdm_use_IAWB_Ave_lpc = 0; + IF( sts[1]->coder_type == INACTIVE ) + { + /* Get the flag on the LPC reusage type (primary channel of ave LPC */ + hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS ); + hStereoTD->tdm_lp_reuse_flag = 1; + } + ELSE + { + /* Get the flag on the LPC reusage */ + hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS ); + } + + sts[0]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* the flag was already read in function stereo_memory_dec() */ + sts[1]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; + + tdm_inst_ratio_idx = *tdm_ratio_idx; + + /* update past tdm_SM_flag */ + hStereoTD->tdm_prev_last_SM_flag = hStereoTD->tdm_last_SM_flag; + hStereoTD->tdm_last_SM_flag = hStereoTD->tdm_SM_flag; + + idx_LRTD_pri_side = -1; + IF( hStereoTD->tdm_LRTD_flag == 1 ) + { + idx_LRTD_pri_side = tdm_tmp_SM_LRTD_flag; + hStereoTD->tdm_SM_flag = 0; + IF( tdm_inst_ratio_idx == TDM_NQ ) + { + hStereoTD->flag_skip_DMX = 1; + } + ELSE + { + hStereoTD->flag_skip_DMX = 0; + } + /* Set primary channel */ + *tdm_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM; + IF( idx_LRTD_pri_side == 1 ) + { + *tdm_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM; + } + } + ELSE + { + hStereoTD->tdm_SM_flag = tdm_tmp_SM_LRTD_flag; + IF( hCPE->nchan_out == 1 ) + { + /* in case of mono output, use exclusively the YX upmixing scheme in order to deal with NOOP signals */ + hStereoTD->tdm_SM_flag = 0; + } + } + + IF( sts[1]->coder_type == INACTIVE && ( *tdm_ratio_idx >= 29 || *tdm_ratio_idx <= 1 ) ) + { + hStereoTD->tdm_lp_reuse_flag = hStereoTD->tdm_use_IAWB_Ave_lpc; + hStereoTD->tdm_use_IAWB_Ave_lpc = 0; + } + + /*sts[1]->tdm_inst_ratio_idx = sts[0]->tdm_inst_ratio_idx;*/ + + IF( hCPE->nchan_out == 1 && hCPE->hStereoDftDmx != NULL ) + { + /* in mono DMX, only targetGain is needed */ + Word16 tmpS = 20; + IF( hStereoTD->tdm_LRTD_flag == 0 ) + { + tmpS = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD ); + } + hCPE->hStereoDftDmx->targetGain_fx = power_table[tmpS]; +#ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + hCPE->hStereoDftDmx->targetGain = fixedToFloat(hCPE->hStereoDftDmx->targetGain_fx, 29 ); +#endif + } + ELSE + { + IF( hStereoTD->tdm_LRTD_flag == 0 ) + { + hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS, STEREO_BITS_TCA_CHAN ); + hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN, STEREO_BITS_TCA_CORRSTATS ); + hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD ); + } + ELSE + { + hCPE->hStereoTCA->refChanIndx = L_CH_INDX; + hCPE->hStereoTCA->indx_ica_NCShift = 0; + hCPE->hStereoTCA->indx_ica_gD = 20; + } + hCPE->hStereoTCA->targetGain_fx = power_table[hCPE->hStereoTCA->indx_ica_gD]; +#ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + hCPE->hStereoTCA->targetGain = fixedToFloat( hCPE->hStereoTCA->targetGain_fx, 29 ); +#endif + } + /* set the BW of the secondary channel */ + IF( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC ) + { + /* set BW of the secondary channel in LRTD stereo mode as the BW of the primary channel at higher bitrates */ + sts[1]->bwidth = sts[0]->bwidth; + } + ELSE + { + /* limit BW of the secondary channel in LRTD mode to WB for low bitrates */ + sts[1]->bwidth = WB; + } + + /*----------------------------------------------------------------* + * bitbudget distribution between channels (taking into account also metadata bitbudget) + *----------------------------------------------------------------*/ + + tdm_bit_alloc( ivas_format, ism_mode, hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus, + hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ), + &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag, + sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx ); + + return; +} +#else void tdm_configure_dec( const int16_t ivas_format, /* i : IVAS format */ const int16_t ism_mode, /* i : ISM mode in combined format */ @@ -268,10 +462,6 @@ void tdm_configure_dec( } hCPE->hStereoDftDmx->targetGain = usdequant( tmpS, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP ); hCPE->hStereoDftDmx->targetGain = powf( 10, hCPE->hStereoDftDmx->targetGain ); - -#ifdef IVAS_FLOAT_FIXED - hCPE->hStereoDftDmx->targetGain_fx = power_table[tmpS]; -#endif } else { @@ -289,10 +479,6 @@ void tdm_configure_dec( } hCPE->hStereoTCA->targetGain = usdequant( hCPE->hStereoTCA->indx_ica_gD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP ); hCPE->hStereoTCA->targetGain = powf( 10, hCPE->hStereoTCA->targetGain ); - -#ifdef IVAS_FLOAT_FIXED - hCPE->hStereoTCA->targetGain_fx = power_table[hCPE->hStereoTCA->indx_ica_gD]; -#endif } /* set the BW of the secondary channel */ if ( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC ) @@ -317,7 +503,7 @@ void tdm_configure_dec( return; } - +#endif /*-------------------------------------------------------------------* * Function tdm_downmix_plain() diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index f0480b9d9..eef159094 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1376,6 +1376,7 @@ typedef struct td_bwe_dec_structure Word32 GainFrame_prevfrm_fx; float GainShape_Delay[NUM_SHB_SUBFR / 2]; + Word16 GainShape_Delay_fx[NUM_SHB_SUBFR / 2]; float GainAttn; Word16 GainAttn_fx; @@ -1432,6 +1433,7 @@ typedef struct td_bwe_dec_structure float prev_pow_exc16kWhtnd; /* power of the LB excitation signal in the previous frame */ Word16 prev_pow_exc16kWhtnd_fx; /* power of the LB excitation signal in the previous frame */ + Word32 prev_pow_exc16kWhtnd_fx32; /* power of the LB excitation signal in the previous frame */ float prev_mix_factor; /* mixing factor in the previous frame */ Word16 prev_mix_factor_fx; /* mixing factor in the previous frame */ diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index ff07e8d78..ac5a2f701 100644 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -446,6 +446,3379 @@ void wb_tbe_dec( return; } +void calc_tilt_bwe_fx_loc( + const Word32 *sp_fx, /* i : input signal */ + Word32 *tilt_fx, /* o : signal tilt */ + Word16 *tilt_fx_q, /* o : signal tilt */ + const Word16 N /* i : signal length */ +) +{ + Word16 i; + Word64 r0_fx, r1_fx; + + r0_fx = EPSILON_FX_SMALL; + FOR(i = 0; i < N; i++) + { + r0_fx += ((Word64)sp_fx[i]) * (sp_fx[i]); + } + r1_fx = abs(sp_fx[1] - sp_fx[0]); + FOR(i = 2; i < N; i++) + { + IF (((Word64)(sp_fx[i] - sp_fx[i - 1])) * (sp_fx[i - 1] - sp_fx[i - 2]) < 0) + { + r1_fx += abs(sp_fx[i] - sp_fx[i - 1]); + } + } + Word16 headroom_left_r0 = W_norm(r0_fx); + Word16 headroom_left_r1 = W_norm(r1_fx); + Word16 r0_q = 0, r1_q = 0; + Word16 r0_bits_occ = 0, r1_bits_occ = 0; + IF(headroom_left_r0 < 32) + { + r0_fx = W_shr(r0_fx, (32 - headroom_left_r0)); + r0_q = (31 - ((2 * OUTPUT_Q) - (32 - headroom_left_r0))); + } + ELSE + { + r0_q = 31 - (2 * OUTPUT_Q); + } + + IF(headroom_left_r1 < 32) + { + r1_fx = W_shr(r1_fx, (32 - headroom_left_r1)); + r1_q = (OUTPUT_Q - (32 - headroom_left_r1)); + } + ELSE + { + r1_q = OUTPUT_Q; + } + Word32 temp_r0_inv = ISqrt32((Word32)r0_fx, &r0_q); + Word32 res = Mpy_32_32((Word32)r1_fx, temp_r0_inv); + Word16 res_q = r1_q + (r0_q < 0 ? (31 + (-1 * r0_q)) : r0_q) - 31; + Word16 norm_res = norm_l(res); + IF (norm_res > 0) + { + *tilt_fx = L_shl_sat(res, norm_res); + *tilt_fx_q = res_q + norm_res; + } + ELSE + { + *tilt_fx = res; + *tilt_fx_q = res_q; + } + return; +} + +/*-------------------------------------------------------------------* + * swb_tbe_dec() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +void rescale_genSHB_mem_dec( + Decoder_State *st_fx, + Word16 sf ) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ + IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + } + + IF( EQ_16( st_fx->extl, FB_TBE ) ) + { + } + hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); + move32(); + + hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); + move16(); + hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); + move16(); +} + +static void gradientGainShape( + Decoder_State *st_fx, + Word16 *GainShape_fx, + Word32 *GainFrame_fx) +{ + Word16 i, j, tmp; + Word16 GainShapeTemp[NUM_SHB_SUBFR / 4]; + Word16 GainGrad0[3]; + Word16 GainGrad1[3]; + Word16 GainGradFEC[4]; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + + /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ + FOR(j = 0; j < 3; j++) + { + GainGrad0[j] = sub(shr(hBWE_TD->GainShape_Delay_fx[j + 1], 1), shr(hBWE_TD->GainShape_Delay_fx[j], 1)); + move16(); /* Q14 */ + GainGrad1[j] = sub(shr(hBWE_TD->GainShape_Delay_fx[j + 5], 1), shr(hBWE_TD->GainShape_Delay_fx[j + 4], 1)); + move16(); /* Q14 */ + GainGradFEC[j + 1] = add(mult_r(GainGrad0[j], 13107), mult_r(GainGrad1[j], 19660)); + move16(); /* Q14 */ + } + + /* gradient for the first gainshape */ + test(); + test(); + test(); + IF(((GT_16(shr(GainGrad1[2], 1), GainGrad1[1])) && (GT_16(shr(GainGrad1[1], 1), GainGrad1[0]))) || + ((LT_16(shr(GainGrad1[2], 1), GainGrad1[1])) && (LT_16(shr(GainGrad1[1], 1), GainGrad1[0])))) + { + GainGradFEC[0] = add(mult_r(GainGrad1[1], 3277), mult_r(GainGrad1[2], 29490)); + move16(); /* Q14 */ + } + ELSE + { + GainGradFEC[0] = add(mult_r(GainGrad1[0], 6553), mult_r(GainGrad1[1], 9830)); + move16(); + GainGradFEC[0] = add(GainGradFEC[0], mult_r(GainGrad1[2], 16384)); + move16(); /* Q14 */ + } + + /* get the first gainshape template */ + test(); + test(); + IF((st_fx->prev_coder_type == UNVOICED || st_fx->last_good == UNVOICED_CLAS) && GainGradFEC[0] > 0) + { + GainShapeTemp[0] = add(shr(hBWE_TD->GainShape_Delay_fx[7], 1), GainGradFEC[0]); + move16(); + } + ELSE IF(GainGradFEC[0] > 0) + { + GainShapeTemp[0] = add(shr(hBWE_TD->GainShape_Delay_fx[7], 1), mult_r(GainGradFEC[0], 16384)); + move16(); /* Q14 */ + } + ELSE + { + GainShapeTemp[0] = shr(hBWE_TD->GainShape_Delay_fx[7], 1); + move16(); /* Q14 */ + } + + /*Get the second the third and the fourth gainshape template*/ + + tmp = shr(GainGrad1[2], 3); /* GainGrad1[2]/8 */ + tmp = mult_r(tmp, 26214); /* 0.8 in Q15 tmp*(8/10) */ + + test(); + IF((GT_16(tmp, GainGrad1[1])) && GainGrad1[1] > 0) + { + FOR(i = 1; i < NUM_SHB_SUBFR / 4; i++) + { + GainShapeTemp[i] = add(GainShapeTemp[i - 1], mult_r(GainGradFEC[i], 26214)); + move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ + GainShapeTemp[i] = s_max(GainShapeTemp[i], 328 /*0.01f Q15*/); + move16(); + } + } + ELSE + { + test(); + IF((GT_16(tmp, GainGrad1[1])) && GainGrad1[1] < 0) + { + FOR(i = 1; i < NUM_SHB_SUBFR / 4; i++) + { + GainShapeTemp[i] = add(GainShapeTemp[i - 1], mult_r(GainGradFEC[i], 6553)); + move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ + GainShapeTemp[i] = s_max(GainShapeTemp[i], 328 /*0.01f Q15*/); + move16(); /* Q14 */ + } + } + ELSE + { + FOR(i = 1; i < NUM_SHB_SUBFR / 4; i++) + { + GainShapeTemp[i] = add(GainShapeTemp[i - 1], GainGradFEC[i]); + move16(); + GainShapeTemp[i] = s_max(GainShapeTemp[i], 328 /*0.01f Q15*/); + move16(); + } + } + } + + /* Get the gainshape and gain frame for the current frame*/ + test(); + test(); + test(); + IF((st_fx->prev_coder_type == UNVOICED || st_fx->last_good == UNVOICED_CLAS) && st_fx->nbLostCmpt == 1) + { + FOR(i = 0; i < NUM_SHB_SUBFR / 4; i++) + { + FOR(j = 0; j < 4; j++) + { + tmp = mult_r(GainShapeTemp[i], 19660); /* GainShapeTemp[i]*0.6 */ + + IF(GT_16(8192, tmp)) + { + GainShape_fx[i * 4 + j] = shl(tmp, 2); + move16(); /* (GainShapeTemp[i]*0.6)>>1 */ + } + ELSE + { + GainShape_fx[i * 4 + j] = 32767; + move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 31129); + } + ELSE IF(st_fx->prev_coder_type == UNVOICED || st_fx->last_good == UNVOICED_CLAS) + { + FOR(i = 0; i < NUM_SHB_SUBFR / 4; i++) + { + FOR(j = 0; j < 4; j++) + { + IF(LT_16(GainShapeTemp[i], 16384)) + { + GainShape_fx[i * 4 + j] = shl(GainShapeTemp[i], 1); + move16(); + } + ELSE + { + GainShape_fx[i * 4 + j] = 32767; + move16(); + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 31129); + } + ELSE IF(st_fx->nbLostCmpt > 1) + { + FOR(i = 0; i < NUM_SHB_SUBFR / 4; i++) + { + FOR(j = 0; j < 4; j++) + { + GainShape_fx[i * 4 + j] = GainShapeTemp[i]; + move16(); + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 16384); + } + ELSE + { + FOR(i = 0; i < NUM_SHB_SUBFR / 4; i++) + { + FOR(j = 0; j < 4; j++) + { + IF(LT_16(GainShapeTemp[i], 16384)) + { + GainShape_fx[i * 4 + j] = shl(GainShapeTemp[i], 1); + move16(); + } + ELSE + { + GainShape_fx[i * 4 + j] = 32767; + move16(); + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 27852); + } + + *GainFrame_fx = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx); /* Q18 */ +} + +void find_max_mem_dec( + Decoder_State *st_fx, + Word16 *n_mem, + Word16 *n_mem2 + ,Word16 *n_mem3 +) +{ + Word16 i; + Word16 n_mem_32; + Word16 max = 0; + Word32 Lmax = 0; + Word16 tempQ15, max2 = 0; + Word16 max3; + Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* old BWE exc max */ + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + tempQ15 = abs_s(hBWE_TD->old_bwe_exc_extended_fx[i] ); + max = s_max( max, tempQ15 ); + } + + /* decimate all-pass steep memory */ + FOR ( i = 0; i < 7; i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); + max = s_max(max, tempQ15); + } + + /* -- keep norm of state_lpc_syn_fx, state_syn_shbexc_fx, + and mem_stp_swb_fx separately for 24.4 and 32kbps ----*/ + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->state_lpc_syn_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s(hBWE_TD->state_syn_shbexc_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_stp_swb_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ + *n_mem2 = norm_s(max2); + IF(max2 == 0) *n_mem2 = 15; + + IF(LT_32(st_fx->total_brate, ACELP_24k40)) + { + max = s_max(max, max2); + } + + /* de-emph and pre-emph memory */ + tempQ15 = abs_s(hBWE_TD->tbe_demph_fx ); + max = s_max(max, tempQ15); + + tempQ15 = abs_s(hBWE_TD->tbe_premph_fx ); + max = s_max(max, tempQ15); + + IF( EQ_16(st_fx->extl, FB_TBE)) + { + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->fb_state_lpc_syn_fx[i] ); + max = s_max(max, tempQ15); + } + /* FB de-emph memory */ + tempQ15 = abs_s(hBWE_TD->fb_tbe_demph_fx); + max = s_max(max, tempQ15); + } + /* estimate the norm for 16-bit memories */ + *n_mem = norm_s( max ); + IF( max == 0 ) + { + *n_mem = 15; + } + + /* estimate the norm for 32-bit memories */ + Lmax = L_abs(hBWE_TD->mem_csfilt_fx[0] ); /* only element [0] is used in env. shaping */ + + n_mem_32 = norm_l( Lmax ); + IF( Lmax == 0 ) + { + n_mem_32 = 31; + } + + tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); + *n_mem = s_max( tempQ15, 0 ); + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st_fx->syn_overlap_fx + 2. st_fx->genSHBsynth_state_lsyn_filt_shb_local + 3. st_fx->genSHBsynth_Hilbert_Mem_fx (32-bit) */ + max3 = 0; + /* find max in prev overlapSyn */ + FOR ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s(hBWE_TD->syn_overlap_fx[i] ); + max3 = s_max(max3, tempQ15); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + FOR ( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + tempQ15 = abs_s(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] ); + max3 = s_max(max3, tempQ15); + } + /* find max in prev int_3_over_2_tbemem_dec_fx */ + IF( EQ_32(st_fx->output_Fs, 48000)) + { + FOR ( i = 0; i < INTERP_3_2_MEM_LEN; i++ ) + { + tempQ15 = abs_s(hBWE_TD->int_3_over_2_tbemem_dec_fx[i] ); + max3 = s_max(max3, tempQ15); + } + } + IF( EQ_32(st_fx->output_Fs, 16000)) + { + FOR ( i = 0; i < (2*ALLPASSSECTIONS_STEEP+1); i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_resamp_HB_32k_fx[i] ); + max3 = s_max(max3, tempQ15); + } + } + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s( max3 ); + IF( max3 == 0 ) *n_mem3 = 15; + + Lmax3 = 0; + IF(EQ_16(st_fx->L_frame, L_FRAME)) + { + /* find max in prev genSHBsynth_Hilbert_Mem_fx */ + FOR ( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + tempQ32 = L_abs(hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] ); + Lmax3 = L_max(Lmax3, tempQ32); + } + } + + /* estimate the norm for 32-bit memories */ + n_mem_32 = norm_l( Lmax3 ); + IF( Lmax3 == 0 ) n_mem_32 = 31; + + tempQ15 = sub( s_min( *n_mem3, n_mem_32 ), 2 ); /* very important leave at least 2 bit head room + because of the Hilber transform and Q14 coeffs */ + *n_mem3 = s_max( tempQ15, 0 ); + /* --------------------------------------------------------------*/ +} + +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 +) +{ + Word16 i; + //Word16 n_mem_32; + Word16 tempQ15; + Word16 max3; + //Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st->syn_overlap_fx*/ + max3 = 0; + /* find max in prev overlapSyn */ + FOR(i = 0; i < L_SHB_LAHEAD; i++) + { + tempQ15 = abs_s(hBWE_TD->syn_overlap_fx[i]); + max3 = s_max(max3, tempQ15); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + //FOR(i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) + //{ + // tempQ15 = abs_s(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i]); + // max3 = s_max(max3, tempQ15); + //} + ///* find max in prev int_3_over_2_tbemem_dec_fx */ + //IF(EQ_32(st->output_Fs, 48000)) + //{ + // FOR(i = 0; i < INTERP_3_2_MEM_LEN; i++) + // { + // tempQ15 = abs_s(hBWE_TD->int_3_over_2_tbemem_dec_fx[i]); + // max3 = s_max(max3, tempQ15); + // } + //} + //IF(EQ_32(st->output_Fs, 16000)) + //{ + // FOR(i = 0; i < (2 * ALLPASSSECTIONS_STEEP + 1); i++) + // { + // tempQ15 = abs_s(hBWE_TD->mem_resamp_HB_32k_fx[i]); + // max3 = s_max(max3, tempQ15); + // } + //} + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s(max3); + IF (max3 == 0) *n_mem3 = 15; + + //Lmax3 = 0; + //IF(EQ_16(st->L_frame, L_FRAME)) + //{ + // /* find max in prev genSHBsynth_Hilbert_Mem_fx */ + // FOR(i = 0; i < HILBERT_MEM_SIZE; i++) + // { + // tempQ32 = L_abs(hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i]); + // Lmax3 = L_max(Lmax3, tempQ32); + // } + //} + + ///* estimate the norm for 32-bit memories */ + //n_mem_32 = norm_l(Lmax3); + //if (Lmax3 == 0) n_mem_32 = 31; + + //tempQ15 = sub(s_min(*n_mem3, n_mem_32), 2); /* very important leave at least 2 bit head room + // because of the Hilber transform and Q14 coeffs */ + //*n_mem3 = s_max(tempQ15, 0); + ///* --------------------------------------------------------------*/ +} + +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * ivas_swb_tbe_dec_fx() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +void ivas_swb_tbe_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ + const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation */ + Word16 Q_exc, + //const float voice_factors[], /* i : voicing factors */ + const Word16 voice_factors_fx[], /* i : voicing factors */ + //const float old_syn_12k8_16k[], /* i : low band synthesis */ + const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis */ + Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE */ + Word32 *synth_fx, /* o : SHB synthesis/final synthesis */ + Word16 *pitch_buf_fx, + Word16 *Q_white_exc) +{ + /*Local float2fix*/ + //Word32 old_syn_12k8_16k_fx[L_FRAME16k]; + ///*for (int idx = 0; idx < L_FRAME16k; idx++) + //{ + // old_syn_12k8_16k_fx[idx] = old_syn_12k8_16k[idx] * (1 << 11); + //}*/ + //floatToFixed_arrL(old_syn_12k8_16k, old_syn_12k8_16k_fx, Q11, L_FRAME16k); + // + //Word16 pitch_buf_fx[NB_SUBFR16k]; + //floatToFixed_arr(pitch_buf, pitch_buf_fx, Q6, NB_SUBFR16k); + + //Word32 synth_fx[L_FRAME48k]; + //for (int i = 0; i < L_FRAME32k; i++) + //{ + // synth_fx[i] = floatToFixed(synth[i], Q11); + //} + /*Local float2fix end*/ + + Word16 i, j,cnt, n; + Word16 stemp; + TD_BWE_DEC_HANDLE hBWE_TD; + //float shaped_shb_excitation[L_FRAME16k + L_SHB_LAHEAD]; + Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; + Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; + Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; + //float lsf_shb[LPC_SHB_ORDER], lpc_shb[LPC_SHB_ORDER + 1], GainShape[NUM_SHB_SUBFR], GainFrame; + Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; //Q12,Q12,Q15 + Word32 GainFrame_fx;//Q18 + //float error[L_FRAME32k]; + Word32 error_fx[L_FRAME32k]; + //float ener; + Word16 ener_fx; + Word32 L_ener; + int16_t is_fractive; + //float prev_pow, curr_pow, scale; + Word32 prev_pow_fx, curr_pow_fx, Lscale; + Word16 scale_fx; + //float curr_frame_pow, temp; + Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; + Word32 curr_frame_pow_fx; + Word16 curr_frame_pow_exp; + Word32 L_prev_ener_shb; + //float GainShapeTemp[NUM_SHB_SUBFR / 4], GainGrad0[3], GainGrad1[3], GainGradFEC[4]; + //float vf_modified[NB_SUBFR16k]; + Word16 vf_modified_fx[NB_SUBFR16k]; + //float f, inc; + Word16 f_fx, inc_fx; + //float GainFrame_prevfrm; + Word32 GainFrame_prevfrm_fx; + //float tilt_swb_fec; + Word32 tilt_swb_fec_32_fx; + Word16 tilt_swb_fec_fx_q; + Word16 tilt_swb_fec_fx; + //float prev_ener_ratio; + Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ + //float lsp_shb_1[LPC_SHB_ORDER], lsp_shb_2[LPC_SHB_ORDER], lsp_temp[LPC_SHB_ORDER]; + Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; + //float lpc_shb_sf[4 * ( LPC_SHB_ORDER + 1 )]; + Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; + //const float *ptr_lsp_interp_coef; + const Word16 *ptr_lsp_interp_coef_fx; + //float shb_ener_sf; + Word32 shb_ener_sf_32; + Word16 shb_res_gshape_fx[NB_SUBFR16k]; + //float shb_res_gshape[NB_SUBFR16k]; + //float mixFactors; + Word16 mixFactors_fx; + int16_t vind; + //float shb_res_dummy[L_FRAME16k]; + Word16 shb_res_dummy_fx[L_FRAME16k]; + //float shaped_shb_excitationTemp[L_FRAME16k]; + Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; + //float ener_tmp[NUM_SHB_SUBGAINS]; + Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; + //float GainShape_tmp[NUM_SHB_SUBGAINS]; + Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; + //float pitch; + Word16 pitch_fx; + int16_t l_subframe; + //float formant_fac; + Word16 formant_fac_fx; + //float synth_scale; + Word16 synth_scale_fx; + //float lsf_diff[LPC_SHB_ORDER], w[LPC_SHB_ORDER]; + Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; + //float refl[M]; + //float tilt_para; + Word16 refl_fx[M]; + Word16 tilt_para_fx; + //float *nlExc16k, *mixExc16k; + Word16 *nlExc16k_fx, *mixExc16k_fx; + int16_t MSFlag; + //float feedback; + Word16 feedback_fx; + //float GainShape_tilt; + Word16 GainShape_tilt_fx; + + //scaling + Word16 exp, tmp; + Word16 tmp1, tmp2; + Word16 mean_vf; + Word32 Lmax, L_tmp; + Word16 frac; + Word32 L_tmp1, L_tmp2; + Word16 Q_bwe_exc; + Word16 Q_bwe_exc_fb; + Word16 Q_shb; + Word16 n_mem, n_mem2, n_mem3, Qx, sc; + Word16 expa, expb; + Word16 fraca, fracb; + Word16 exp_ener, inv_ener; + + hBWE_TD = st->hBWE_TD; + + /* initializations */ + //GainFrame = 0.0f; + //mixFactors = 0.0f; + //shb_ener_sf = 0.0f; + GainFrame_fx = 0; + mixFactors_fx = 0; + shb_ener_sf_32 = 0; + //set_f( shaped_shb_excitationTemp, 0.0f, L_FRAME16k ); + set16_fx(shaped_shb_excitationTemp_fx, 0, L_FRAME16k); + IF ( st->hTdCngDec != NULL ) + { + st->hTdCngDec->shb_dtx_count = 0; + } + is_fractive = 0; + + IF( hStereoICBWE != NULL ) + { + //nlExc16k = hStereoICBWE->nlExc16k; + nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + //mixExc16k = hStereoICBWE->mixExc16k; + mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + MSFlag = hStereoICBWE->MSFlag; + } + ELSE + { + //nlExc16k = NULL; + nlExc16k_fx = NULL; + //mixExc16k = NULL; + mixExc16k_fx = NULL; + MSFlag = 0; + } + + /* find tilt */ + //calc_tilt_bwe( old_syn_12k8_16k, &tilt_swb_fec, L_FRAME ); + //currently considering word32 q11 can change to any q with minor change + calc_tilt_bwe_fx_loc(old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME); + tilt_swb_fec_fx = L_shr(tilt_swb_fec_32_fx, (tilt_swb_fec_fx_q - 11)); + + IF( st->bfi && st->clas_dec != UNVOICED_CLAS ) + { + //tilt_swb_fec = hBWE_TD->tilt_swb_fec; + tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; + } + + /* WB/SWB bandwidth switching */ + IF( ( st->tilt_wb > 5 && st->clas_dec == UNVOICED_CLAS ) || st->tilt_wb > 10 ) + { + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF((st->prev_fractive_fx == 0 && + (LT_32(st->prev_enerLH_fx, L_shl(st->enerLH_fx, 1)) && GT_32(st->prev_enerLH_fx, L_shr(st->enerLH_fx, 1)) + && LT_32(st->prev_enerLL_fx, L_shl(st->enerLL_fx, 1)) && GT_32(st->prev_enerLL_fx, L_shr(st->enerLL_fx, 1)))) + || (EQ_16(st->prev_fractive_fx, 1) && + GT_32(L_shr(st->prev_enerLH_fx, 2), Mult_32_16(st->enerLH_fx, 24576))) /* 24576 in Q13*/ + || (GT_32(L_shr(st->enerLL_fx, 1), Mult_32_16(st->enerLH_fx, 24576)) && /*24576 = 1.5 in Q14*/ + LT_16(st->tilt_wb_fx, 20480))/* 20480 = 10 in Q11*/ + ) + { + is_fractive = 0; + } + ELSE + { + is_fractive = 1; + } + } + + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + /*f = 1.0f / 22.0f; + inc = 1.0f / 22.0f;*/ + f_fx = 1489; /*Q15*/ + inc_fx = 1489; /*Q15*/ + + IF( is_fractive == 1 ) + { + //mvr2r( lsf_tab, hBWE_TD->lsp_prevfrm, LPC_SHB_ORDER ); + Copy(lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER); + } + ELSE + { + /*for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm[i] = f; + f += inc; + }*/ + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + IF ( ( st->last_extl != SWB_TBE && st->last_extl != FB_TBE && !(L_sub(L_shr(st->prev_enerLH_fx, 1), st->enerLH_fx) < 0 && L_sub(st->prev_enerLH_fx, L_shr(st->enerLH_fx, 1) > 0)) + ) || st->last_core != ACELP_CORE || ( st->last_core == ACELP_CORE && labs( st->last_core_brate - st->core_brate ) > 3600 ) || ( is_fractive ^ st->prev_fractive ) == 1 ) + { + //set_f( GainShape, 0.3536f, NUM_SHB_SUBFR ); + set16_fx(GainShape_fx, 11587, NUM_SHB_SUBFR); + } + ELSE + { + /*hBWE_TD->prev_GainShape = ( hBWE_TD->prev_GainShape > 0.3536f ) ? 0.353f : hBWE_TD->prev_GainShape; + set_f( GainShape, hBWE_TD->prev_GainShape, NUM_SHB_SUBFR );*/ + + IF(GT_16(hBWE_TD->prev_GainShape_fx, 11587)) + { + hBWE_TD->prev_GainShape_fx = 11587; + move16(); + } + set16_fx(GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR); + } + + /*mvr2r( hBWE_TD->lsp_prevfrm, lsf_shb, LPC_SHB_ORDER ); + set_f( shb_res_gshape, 0.2f, NB_SUBFR16k );*/ + + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER); + set16_fx(shb_res_gshape_fx, 3277/*0.2f Q14*/, NB_SUBFR16k); /* Q14 */ + } + ELSE + { + IF ( st->last_extl != SWB_TBE && st->last_extl != FB_TBE ) + { + /*f = 1.0f / 22.0f; + inc = 1.0f / 22.0f;*/ + f_fx = 1489; /*Q15*/ move16(); + inc_fx = 1489; /*Q15*/ move16(); + /*for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm[i] = f; + f += inc; + }*/ + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + + IF( !st->bfi ) + { + IF( st->use_partial_copy ) + { + IF( st->last_extl != SWB_TBE ) + { + //hBWE_TD->GainFrame_prevfrm = 0; + hBWE_TD->GainFrame_prevfrm_fx = 0; + /*f = 1.0f / 22.0f; + inc = 1.0f / 22.0f;*/ + f_fx = 1489/*0.045454f Q15*/; /*Q15*/ + inc_fx = 1489/*0.045454f Q15*/;; /*Q15*/ + /*for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm[i] = f; + f += inc; + }*/ + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + /*mvr2r( hBWE_TD->lsp_prevfrm, lsf_shb, LPC_SHB_ORDER ); + set_f( GainShape, RECIP_ROOT_EIGHT, NUM_SHB_SUBFR );*/ + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER); + set16_fx(GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR); + + IF( st->rf_frame_type == RF_NELP ) + { + /* Frame gain */ + /*GainFrame = usdequant( st->rf_indx_tbeGainFr, SHB_GAIN_QLOW, SHB_GAIN_QDELTA ); + GainFrame = (float) pow( 10.0, GainFrame );*/ + + GainFrame_fx = L_mac(SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX); + move32();/*Q18*/ + L_tmp = Mult_32_16(GainFrame_fx, 27213); /*Q16*/ /* 3.321928 in Q13 */ + + frac = L_Extract_lc(L_tmp, &exp); + L_tmp = Pow2(30, frac); + GainFrame_fx = L_shl(L_tmp, sub(exp, 12)); /*Q18*/ + + IF( st->core == ACELP_CORE && st->last_core == ACELP_CORE && !st->prev_use_partial_copy && st->prev_coder_type == UNVOICED && NE_32(GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx) && st->next_coder_type != GENERIC && st->last_extl == SWB_TBE ) + { + //GainFrame = 0.2f * GainFrame + 0.8f * hBWE_TD->GainFrame_prevfrm; + GainFrame_fx = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 26214), Mult_32_16(GainFrame_fx, 6553)); + } + } + ELSE + { + //temp = 0.0f; + temp_fx = 0; + /* Frame gain */ + /*switch ( st->rf_indx_tbeGainFr ) + { + case 0: + GainFrame = 0.5f; + if ( hBWE_TD->GainFrame_prevfrm <= 1.25 ) + { + temp = 0.8f; + } + break; + case 1: + GainFrame = 2.0f; + if ( hBWE_TD->GainFrame_prevfrm > 1.25 && hBWE_TD->GainFrame_prevfrm <= 3 ) + { + temp = 0.8f; + } + break; + case 2: + GainFrame = 4.0f; + if ( hBWE_TD->GainFrame_prevfrm > 3 && hBWE_TD->GainFrame_prevfrm <= 6 ) + { + temp = 0.8f; + } + break; + case 3: + GainFrame = 8.0f; + if ( hBWE_TD->GainFrame_prevfrm > 6 && hBWE_TD->GainFrame_prevfrm <= 16 ) + { + temp = 0.8f; + } + break; + default: + IVAS_ERROR( IVAS_ERR_INTERNAL, "RF SWB-TBE gain bits not supported." ); + }*/ + SWITCH(st->rf_indx_tbeGainFr) + { + case 0: + GainFrame_fx = 131072; /* 0.5f in Q18 */ + IF(LE_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/)) temp_fx = 26214/*0.8 Q15*/; + move16(); + BREAK; + case 1: + GainFrame_fx = 524288; /* 2.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/) && LE_32(hBWE_TD->GainFrame_prevfrm_fx, 786432l/*3 Q18*/)) temp_fx = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 2: + GainFrame_fx = 1048576;/* 4.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 786432l/*3 Q18*/) && LE_32(hBWE_TD->GainFrame_prevfrm_fx, 1572864l/*6 Q18*/)) temp_fx = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 3: + GainFrame_fx = 2097152;/* 8.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 1572864l/*6 Q18*/) && LE_32(hBWE_TD->GainFrame_prevfrm_fx, 4194304l/*16Q18*/)) temp_fx = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + default: + fprintf(stderr, "RF SWB-TBE gain bits not supported."); + } + + /*if ( st->last_extl == SWB_TBE ) + { + GainFrame = ( 1 - temp ) * GainFrame + temp * ( hBWE_TD->GainFrame_prevfrm ); + }*/ + IF(EQ_16(st->last_extl, SWB_TBE)) + { + GainFrame_fx = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, temp_fx), Mult_32_16(GainFrame_fx, sub(32767, temp_fx))); + } + + IF( st->core == ACELP_CORE && st->last_core == ACELP_CORE ) + { + IF( !st->prev_use_partial_copy && st->last_coder_type == VOICED && st->rf_frame_type == RF_GENPRED && GT_32(GainFrame_fx, 2097152) && LT_32(GainFrame_fx, 3059606)) + { + //GainFrame *= 0.3f; + GainFrame_fx = Mult_32_16(GainFrame_fx, 9830); + } + } + } + } + ELSE + { + /* de-quantization */ + //dequantizeSHBparams( st, st->extl, st->extl_brate, lsf_shb, GainShape, &GainFrame, &stemp, &shb_ener_sf, shb_res_gshape, &mixFactors, &MSFlag ); + ivas_dequantizeSHBparams_fx_9_1(st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, + &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag); + /*GainFrame = (float)GainFrame_fx / (1 << 18); + for (int idx = 0; idx < NUM_SHB_SUBFR; idx++) + { + GainShape[idx] = (float)GainShape_fx[idx] / (1 << 15); + } + for (int idx = 0; idx < LPC_SHB_ORDER; idx++) + { + lsf_shb[idx] = (float)lsf_shb_fx[idx] / (1 << 15); + } + if (mixFactors_fx == 32767) { + mixFactors = 1.0f; + } + else { + mixFactors = (float)mixFactors_fx / (1 << 15); + } + shb_ener_sf = fixedToFloat(shb_ener_sf_32, 0); + for (int idx = 0; idx < NB_SUBFR16k; idx++) + { + shb_res_gshape[idx] = (float)shb_res_gshape_fx[idx] / (1 << 14); + }*/ + IF ( hStereoICBWE != NULL ) + { + hStereoICBWE->MSFlag = MSFlag; + } + } + } + ELSE + { + //mvr2r( hBWE_TD->lsp_prevfrm, lsf_shb, LPC_SHB_ORDER ); + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER); + + //if ( st->codec_mode == MODE1 && st->element_mode == EVS_MONO ) + //{ + // /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ + // for ( j = 0; j < 3; j++ ) + // { + // GainGrad0[j] = hBWE_TD->GainShape_Delay[j + 1] - hBWE_TD->GainShape_Delay[j]; + // GainGrad1[j] = hBWE_TD->GainShape_Delay[j + 5] - hBWE_TD->GainShape_Delay[j + 4]; + // GainGradFEC[j + 1] = GainGrad0[j] * 0.4f + GainGrad1[j] * 0.6f; + // } + + // /* gradient for the first gainshape */ + // if ( ( GainGrad1[2] > 2 * GainGrad1[1] && GainGrad1[1] > 2 * GainGrad1[0] ) || + // ( GainGrad1[2] < 2 * GainGrad1[1] && GainGrad1[1] < 2 * GainGrad1[0] ) ) + // { + // GainGradFEC[0] = GainGrad1[1] * 0.1f + GainGrad1[2] * 0.9f; + // } + // else + // { + // GainGradFEC[0] = GainGrad1[0] * 0.2f + GainGrad1[1] * 0.3f + GainGrad1[2] * 0.5f; + // } + + // /* get the first gainshape template */ + // if ( ( st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS ) && GainGradFEC[0] > 0 ) + // { + // GainShapeTemp[0] = hBWE_TD->GainShape_Delay[7] + GainGradFEC[0]; + // } + // else if ( GainGradFEC[0] > 0 ) + // { + // GainShapeTemp[0] = hBWE_TD->GainShape_Delay[7] + GainGradFEC[0] * 0.5f; + // } + // else + // { + // GainShapeTemp[0] = hBWE_TD->GainShape_Delay[7]; + // } + + // /*Get the second the third and the fourth gainshape template*/ + // if ( ( GainGrad1[2] > 10.0f * GainGrad1[1] ) && GainGrad1[1] > 0 ) + // { + // for ( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // GainShapeTemp[i] = GainShapeTemp[i - 1] + GainGradFEC[i] * 0.8f; + // GainShapeTemp[i] = max( GainShapeTemp[i], 0.01f ); + // } + // } + // else if ( ( GainGrad1[2] > 10.0f * GainGrad1[1] ) && GainGrad1[1] < 0 ) + // { + // for ( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // GainShapeTemp[i] = GainShapeTemp[i - 1] + GainGradFEC[i] * 0.2f; + // GainShapeTemp[i] = max( GainShapeTemp[i], 0.01f ); + // } + // } + // else + // { + // for ( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // GainShapeTemp[i] = GainShapeTemp[i - 1] + GainGradFEC[i]; + // GainShapeTemp[i] = max( GainShapeTemp[i], 0.01f ); + // } + // } + + // /* Get the gainshape and gain frame for the current frame*/ + // if ( ( st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS ) && st->nbLostCmpt == 1 ) + // { + // for ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // for ( j = 0; j < 4; j++ ) + // { + // GainShape[i * 4 + j] = GainShapeTemp[i] * 1.2f; + // } + // } + // hBWE_TD->GainAttn *= 0.95f; + // } + // else if ( st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS ) + // { + // for ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // for ( j = 0; j < 4; j++ ) + // { + // GainShape[i * 4 + j] = GainShapeTemp[i]; + // } + // } + // hBWE_TD->GainAttn *= 0.95f; + // } + // else if ( st->nbLostCmpt > 1 ) + // { + // for ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // for ( j = 0; j < 4; j++ ) + // { + // GainShape[i * 4 + j] = GainShapeTemp[i] * 0.5f; + // } + // } + // hBWE_TD->GainAttn *= 0.5f; + // } + // else + // { + // for ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // for ( j = 0; j < 4; j++ ) + // { + // GainShape[i * 4 + j] = GainShapeTemp[i]; + // } + // } + // hBWE_TD->GainAttn *= 0.85f; + // } + + // GainFrame = hBWE_TD->GainAttn * hBWE_TD->GainFrame_prevfrm; + //} + //else + //{ + // for ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + // { + // for ( j = 0; j < 4; j++ ) + // { + // GainShape[i * 4 + j] = st->cummulative_damping_float * hBWE_TD->GainShape_Delay[4 + i]; + // } + // } + + // if ( tilt_swb_fec > 8 ) + // { + // if ( st->nbLostCmpt == 1 ) + // { + // GainFrame = (float) ( 0.6 * st->cummulative_damping_float * hBWE_TD->GainFrame_prevfrm ); + // } + // else if ( st->nbLostCmpt == 2 ) + // { + // GainFrame = (float) ( 0.35 * st->cummulative_damping_float * hBWE_TD->GainFrame_prevfrm ); + // } + // else + // { + // GainFrame = (float) ( 0.2 * st->cummulative_damping_float * hBWE_TD->GainFrame_prevfrm ); + // } + // } + // else + // { + // GainFrame = hBWE_TD->GainFrame_prevfrm; /* gain locking */ + // } + //} + + /*Fixed counterpart below*/ + IF ( st->codec_mode == MODE1 && st->element_mode == EVS_MONO ) + { + gradientGainShape( st, GainShape_fx, &GainFrame_fx ); + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); + move16(); + } + } + IF( GT_16( tilt_swb_fec_fx, 8 << 11) ) /* tilt_swb_fec_fx in Q11 */ + { + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); + } + ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); + } + ELSE + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); + } + GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); + } + ELSE + { + GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; + move16(); /* gain locking */ + } + } + + IF ( st->extl_brate >= SWB_TBE_2k8 ) + { + IF ( st->codec_mode == MODE1 && st->element_mode == EVS_MONO ) + { + /*scale = (float) ( hBWE_TD->prev1_shb_ener_sf / sqrt( ( hBWE_TD->prev2_shb_ener_sf * hBWE_TD->prev3_shb_ener_sf ) + 0.0001 ) ); + scale = hBWE_TD->prev_res_shb_gshape * min( scale, 1.0f ); + + if ( hBWE_TD->prev2_shb_ener_sf > 2.0f * hBWE_TD->prev1_shb_ener_sf || hBWE_TD->prev3_shb_ener_sf > 2.0f * hBWE_TD->prev2_shb_ener_sf ) + { + shb_ener_sf = 0.5f * scale * hBWE_TD->prev1_shb_ener_sf; + if ( st->nbLostCmpt > 1 ) + { + shb_ener_sf *= 0.5f; + } + } + else + { + shb_ener_sf = scale * scale * hBWE_TD->prev1_shb_ener_sf; + }*/ + + + L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ + tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ + tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ + i = sub( norm_s( tmp1 ), 1 ); + tmp1 = shl( tmp1, i ); /* Qi */ + IF( tmp == 0 ) + { + tmp = 32767 /*1.0f Q15*/; + move16(); /*Q15*/ + } + ELSE + { + scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ + scale_fx = s_max(scale_fx, 0 ); + /*scale = st->prev_res_shb_gshape * min(scale, 1.0f); */ +#ifdef BASOP_NOGLOB + tmp = shl_sat(scale_fx, 15 - exp - i ); /*Q15*/ +#else + tmp = shl( scale, 15 - exp - i ); /*Q15*/ +#endif + } + scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ + + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + /* shb_ener_sf_32 = 0.5f * scale * st_fx->prev1_shb_ener_sf_fx; */ + shb_ener_sf_32 = Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, scale_fx); + + IF( GT_16( st->nbLostCmpt, 1 ) ) + { + /* shb_ener_sf_32 *= 0.5f; */ + shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); + } + } + ELSE + { + /* shb_ener_sf = scale * scale * st_fx->prev1_shb_ener_sf_fx; */ + L_tmp = L_mult(scale_fx, scale_fx); /* Q29 */ + shb_ener_sf_32 = L_shl( Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); + } + } + ELSE + { + /*if ( hBWE_TD->prev2_shb_ener_sf > 2.0f * hBWE_TD->prev1_shb_ener_sf || hBWE_TD->prev3_shb_ener_sf > 2.0f * hBWE_TD->prev2_shb_ener_sf ) + { + shb_ener_sf = 0.5f * st->cummulative_damping_float * hBWE_TD->prev1_shb_ener_sf; + } + else + { + shb_ener_sf = st->cummulative_damping_float * hBWE_TD->prev1_shb_ener_sf; + }*/ + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + /* shb_ener_sf_32 = 0.5f * st->cummulative_damping * st_fx->prev1_shb_ener_sf_fx; */ + shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); + } + ELSE + { + shb_ener_sf_32 = Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); + } + } + } + // Add up part in fixed + + /*shb_ener_sf = max( shb_ener_sf, 1.0f ); + mixFactors = hBWE_TD->prev_mixFactors;*/ + shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); + mixFactors_fx = hBWE_TD->prev_mixFactors_fx; + + /*if ( st->codec_mode == MODE2 ) + { + set_f( shb_res_gshape, 1.0f, NB_SUBFR16k ); + } + else + { + set_f( shb_res_gshape, 0.2f, NB_SUBFR16k ); + }*/ + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ + } + ELSE + { + set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ + } + } + } + + /* get the gainshape delay */ + //mvr2r( &hBWE_TD->GainShape_Delay[4], &hBWE_TD->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + Copy(&hBWE_TD->GainShape_Delay_fx[4], &hBWE_TD->GainShape_Delay_fx[0], NUM_SHB_SUBFR / 4); + FOR ( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + //hBWE_TD->GainShape_Delay[i + 4] = GainShape[i * 4]; + hBWE_TD->GainShape_Delay_fx[i + 4] = GainShape_fx[i * 4]; + } + + //mvr2r( voice_factors, vf_modified, NB_SUBFR16k ); + + L_tmp = L_mult(voice_factors_fx[0], 8192); + L_tmp = L_mac(L_tmp, voice_factors_fx[1], 8192); + L_tmp = L_mac(L_tmp, voice_factors_fx[2], 8192); + mean_vf = mac_r(L_tmp, voice_factors_fx[3], 8192); + + Copy(voice_factors_fx, vf_modified_fx, NB_SUBFR16k); + + //if ( st->coder_type == VOICED || mean( voice_factors, 4 ) > 0.4f ) + IF(EQ_16(st->coder_type, VOICED) || GT_16(mean_vf, 13107/*0.4f Q15*/)) + { + FOR ( i = 1; i < NB_SUBFR; i++ ) + { + //vf_modified[i] = 0.8f * voice_factors[i] + 0.2f * voice_factors[i - 1]; + L_tmp = L_mult(voice_factors_fx[i], 26214/*0.8f Q15*/); + vf_modified_fx[i] = mac_r(L_tmp, voice_factors_fx[i - 1], 6554/*0.2f Q15*/); + } + + IF ( st->L_frame != L_FRAME ) + { + //vf_modified[4] = 0.8f * voice_factors[4] + 0.2f * voice_factors[3]; + L_tmp = L_mult(voice_factors_fx[4], 26214/*0.8f Q15*/); + vf_modified_fx[4] = mac_r(L_tmp, voice_factors_fx[3], 6554/*0.2f Q15*/); + } + } + + IF( st->use_partial_copy && st->nelp_mode_dec ) + { + //set_f( vf_modified, 0.0f, NB_SUBFR16k ); + set16_fx(vf_modified_fx, 0, NB_SUBFR16k); + } + + /* SHB LSF from current frame; and convert to LSP for interpolation */ + //lsf2lsp( lsf_shb, lsp_shb_2, LPC_SHB_ORDER, 1 ); + /*if (st->output_Fs != 32000) + { + assert("Check sample rate"); + }*/ + E_LPC_lsf_lsp_conversion(lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER); + + IF( st->last_extl == SWB_TBE || st->last_extl == FB_TBE ) + { + /* SHB LSP values from prev. frame for interpolation */ + //mvr2r( hBWE_TD->swb_lsp_prev_interp, lsp_shb_1, LPC_SHB_ORDER ); + Copy(hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER); + } + ELSE + { + /* Use current frame's LSPs; in effect no interpolation */ + //mvr2r( lsp_shb_2, lsp_shb_1, LPC_SHB_ORDER ); + Copy(lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER); + } + + IF ( st->bws_cnt == 0 && st->bws_cnt1 == 0 && st->prev_use_partial_copy == 0 && st->use_partial_copy == 0 ) + { + /*lsf_diff[0] = lsf_diff[LPC_SHB_ORDER - 1] = 0.5f; + for ( i = 1; i < ( LPC_SHB_ORDER - 1 ); i++ ) + { + lsf_diff[i] = lsf_shb[i] - lsf_shb[i - 1]; + }*/ + lsf_diff_fx[0] = 16384; + move16(); /*Q15*/ + lsf_diff_fx[sub(LPC_SHB_ORDER, 1)] = 16384; + move16(); /*Q15*/ + FOR(i = 1; i < LPC_SHB_ORDER - 1; i++) + { + lsf_diff_fx[i] = sub(lsf_shb_fx[i], lsf_shb_fx[sub(i, 1)]); + move16(); + } + + /*a2rc( hBWE_TD->cur_sub_Aq + 1, refl, M ); + tilt_para = 6.6956f * ( 1.0f + refl[0] ) * ( 1.0f + refl[0] ) - 3.8714f * ( 1.0f + refl[0] ) + 1.3041f;*/ + + a2rc_fx(hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M); + tmp = add(16384, shr(refl_fx[0], 1)); /*Q14*/ + tmp1 = mult(27425, tmp); + tmp1 = mult(tmp1, tmp); /*Q10*/ + tmp2 = shr(mult(31715, tmp), 2); /*Q10*/ + tilt_para_fx = add(sub(tmp1, tmp2), 1335); /*Q10*/ + + IF( st->last_extl != SWB_TBE && st->last_extl != FB_TBE ) + { + FOR ( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + //hBWE_TD->prev_lsf_diff[i - 1] = 0.5f * lsf_diff[i]; + hBWE_TD->prev_lsf_diff_fx[i - 1] = shr(lsf_diff_fx[i], 1); + } + } + + IF( st->extl_brate <= FB_TBE_1k8 ) + { + //if ( !(GT_16(hBWE_TD->prev_tilt_para_fx, 5120) && ( st->coder_type == TRANSITION || LT_16(tilt_para_fx, 1024)) ) && !( ( hBWE_TD->prev_tilt_para < 3.0f && st->prev_coder_type >= VOICED ) && GT_16(tilt_para_fx, 5120)) ) + //{ + // for ( i = 1; i < ( LPC_SHB_ORDER - 1 ); i++ ) + // { + // if ( lsf_diff[i] < 0 || hBWE_TD->prev_lsf_diff[i - 1] <= 0 ) /* safety check in case of bit errors */ + // { + // w[i] = 0; + // st->BER_detect = 1; + // } + // else + // { + // w[i] = ( lsf_diff[i] < hBWE_TD->prev_lsf_diff[i - 1] ) ? min( max( 0.8f * lsf_diff[i] / hBWE_TD->prev_lsf_diff[i - 1], 0.5f ), 1.0f ) : min( max( 0.8f * hBWE_TD->prev_lsf_diff[i - 1] / lsf_diff[i], 0.5f ), 1.0f ); + // } + // } + // w[0] = w[1]; + // w[LPC_SHB_ORDER - 1] = w[LPC_SHB_ORDER - 2]; + + // for ( i = 0; i < LPC_SHB_ORDER; i++ ) + // { + // lsp_temp[i] = lsp_shb_1[i] * ( 1.0f - w[i] ) + lsp_shb_2[i] * w[i]; + // } + //} + //else + //{ + // mvr2r( lsp_shb_2, lsp_temp, LPC_SHB_ORDER ); + //} + + + //Fixed + IF(!(GT_16(hBWE_TD->prev_tilt_para_fx, 5120) && (EQ_16(st->coder_type, TRANSITION) || LT_16(tilt_para_fx, 1024))) && + !(((LT_16(hBWE_TD->prev_tilt_para_fx, 3072) && GE_16(st->prev_coder_type, VOICED))) && GT_16(tilt_para_fx, 5120))) + { + FOR(i = 1; i < LPC_SHB_ORDER - 1; i++) + { + IF(LT_16(lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1])) + { + tmp = mult(26214, lsf_diff_fx[i]); + + test(); + IF(hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 || tmp < 0) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + } + ELSE + { + tmp = div_s(tmp,hBWE_TD->prev_lsf_diff_fx[i - 1]); + } + + tmp = s_max(tmp, 16384); + w_fx[i] = s_min(tmp, 32767); + move16(); + } + ELSE + { + tmp = mult(26214,hBWE_TD->prev_lsf_diff_fx[i - 1]); + + test(); + IF(lsf_diff_fx[i] <= 0 || tmp < 0) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + } + ELSE + { + tmp = div_s(tmp,lsf_diff_fx[i]); + } + + tmp = s_max(tmp,16384); + w_fx[i] = s_min(tmp,32767); + move16(); + } + } + w_fx[0] = w_fx[1]; + w_fx[sub(LPC_SHB_ORDER, 1)] = w_fx[sub(LPC_SHB_ORDER, 2)]; + + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + tmp1 = mult(lsp_shb_1_fx[i], sub(32767, w_fx[i])); + tmp2 = mult(lsp_shb_2_fx[i], w_fx[i]); + lsp_temp_fx[i] = add(tmp1, tmp2); + move16(); + } + } + ELSE + { + Copy(lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER); + } + + /* convert from lsp to lsf */ + //lsp2lsf( lsp_temp, lsf_shb, LPC_SHB_ORDER, 1 ); + lsp2lsf_fx(lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1); + } + + /*mvr2r( lsf_diff + 1, hBWE_TD->prev_lsf_diff, LPC_SHB_ORDER - 2 ); + hBWE_TD->prev_tilt_para = tilt_para;*/ + Copy(lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2); + hBWE_TD->prev_tilt_para_fx = tilt_para_fx; + } + ELSE + { + //mvr2r( lsp_shb_2, lsp_temp, LPC_SHB_ORDER ); + Copy(lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER); + } + + IF ( st->extl_brate >= SWB_TBE_2k8 ) + { + /* SHB LSP interpolation */ + //ptr_lsp_interp_coef = interpol_frac_shb_flt; + ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ + FOR ( j = 0; j < 4; j++ ) + { + /*for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + lsp_temp[i] = lsp_shb_1[i] * ( *ptr_lsp_interp_coef ) + lsp_shb_2[i] * ( *( ptr_lsp_interp_coef + 1 ) ); + } + ptr_lsp_interp_coef += 2;*/ + + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + /*lsp_temp_fx[i] = lsp_shb_1_fx[i]*(*ptr_lsp_interp_coef_fx) */ + /* + lsp_shb_2_fx[i]*(*(ptr_lsp_interp_coef_fx+1));*/ + L_tmp = L_mult(lsp_shb_1_fx[i], (*ptr_lsp_interp_coef_fx)); + lsp_temp_fx[i] = mac_r(L_tmp, lsp_shb_2_fx[i], (*(ptr_lsp_interp_coef_fx + 1))); + move16(); + } + ptr_lsp_interp_coef_fx += 2; + + /* convert from lsp to lsf */ + //lsp2lsf( lsp_temp, lsp_temp, LPC_SHB_ORDER, 1 ); + //lsp2lsf_fx(lsp_temp_fx, lsp_temp_fx, LPC_SHB_ORDER, 1); + + /* convert lsf to lpc for SHB synthesis */ + //lsp2a( lpc_shb_sf + j * ( LPC_SHB_ORDER + 1 ), lsp_temp, LPC_SHB_ORDER ); + //lpc_shb_sf[j * ( LPC_SHB_ORDER + 1 )] = 1.0f; + + //Fixed + tmp = i_mult(j, (LPC_SHB_ORDER + 1)); + /* convert LSPs to LP coefficients */ + E_LPC_f_lsp_a_conversion(lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER); + /* Bring the LPCs to Q12 */ + Copy_Scale_sig(lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub(norm_s(lpc_shb_sf_fx[tmp]), 2)); + lpc_shb_sf_fx[j * (LPC_SHB_ORDER + 1)] = ONE_IN_Q12;//recheck this + } + } + + /* Save the SWB LSP values from current frame for interpolation */ + //mvr2r( lsp_shb_2, hBWE_TD->swb_lsp_prev_interp, LPC_SHB_ORDER ); + Copy(lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER); + + /* save the shb_ener and mixFactor values */ + /*hBWE_TD->prev3_shb_ener_sf = hBWE_TD->prev2_shb_ener_sf; + hBWE_TD->prev2_shb_ener_sf = hBWE_TD->prev1_shb_ener_sf; + hBWE_TD->prev1_shb_ener_sf = shb_ener_sf; + hBWE_TD->prev_res_shb_gshape = shb_res_gshape[4]; + hBWE_TD->prev_mixFactors = mixFactors;*/ + + hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; + hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; + hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; + hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; + hBWE_TD->prev_mixFactors_fx = mixFactors_fx; + + /* SWB CNG/DTX - update memories */ + IF( st->hTdCngDec != NULL ) + { + /*mvr2r( st->hTdCngDec->lsp_shb_prev, st->hTdCngDec->lsp_shb_prev_prev, LPC_SHB_ORDER ); + mvr2r( lsf_shb, st->hTdCngDec->lsp_shb_prev, LPC_SHB_ORDER );*/ + + //here + Copy(st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER); + Copy(lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER); + } + + /* convert LSPs back into LP coeffs */ + /*lsp2a( lpc_shb, lsf_shb, LPC_SHB_ORDER ); + lpc_shb[0] = 1.0;*/ + E_LPC_f_lsp_a_conversion(lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER); + Copy_Scale_sig(lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub(norm_s(lpc_shb_fx[0]), 2)); /* Q12 */ + lpc_shb_fx[0] = ONE_IN_Q12; + + IF( st->extl_brate == SWB_TBE_1k10 || st->extl_brate == SWB_TBE_1k75 ) + { + //vind = (int16_t) ( mixFactors * ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) ); + Word32 vind_temp = (L_add(mixFactors_fx, 1) * ((1 << NUM_BITS_SHB_VF) - 1)); // check addition of 1 + vind = L_shr(vind_temp, 15); /* 3 for mpy by 8.0f, -15 to bring it to Q0 *//*mixFactors*7*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + ELSE + { + //vind = (int16_t) ( mixFactors * ( 1 << NUM_BITS_SHB_VF ) ); + vind = shl(mixFactors_fx, 3 - 15); /* 3 for mpy by 8.0f, -15 to bring it to Q0 *//*mixFactors*8*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + + /* Determine formant PF strength */ + //formant_fac = swb_formant_fac( lpc_shb[1], &hBWE_TD->tilt_mem ); + formant_fac_fx = swb_formant_fac_fx(lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx); + /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ + IF ( st->total_brate > ACELP_32k ) + { + /*for ( j = 0; j < 4; j++ ) + { + mvr2r( lpc_shb, &lpc_shb_sf[j * ( LPC_SHB_ORDER + 1 )], LPC_SHB_ORDER + 1 ); + }*/ + FOR(j = 0; j < 4; j++) + { + Copy(lpc_shb_fx, &lpc_shb_sf_fx[j*(LPC_SHB_ORDER + 1)], LPC_SHB_ORDER + 1); + } + } + + /* From low band excitation, generate highband excitation */ + /*Word16 q_state_syn_shbexc = Q_factor_arr(hBWE_TD->state_syn_shbexc, L_SHB_LAHEAD); + floatToFixed_arr(hBWE_TD->state_syn_shbexc, hBWE_TD->state_syn_shbexc_fx, q_state_syn_shbexc, L_SHB_LAHEAD);*/ + /*for (int i = 0; i < LPC_SHB_ORDER + 1; i++) + { + lpc_shb_fx[i] = lpc_shb[i] * ONE_IN_Q12; + }*/ + //floatToFixed_arr(lpc_shb, lpc_shb_fx, Q12, LPC_SHB_ORDER + 1); + + /*for (int i = 0; i < 4 * (LPC_SHB_ORDER + 1); i++) + { + lpc_shb_sf_fx[i] = lpc_shb_sf[i] * ONE_IN_Q12; + }*/ + //floatToFixed_arr(lpc_shb_sf, lpc_shb_sf_fx, Q12, 4 * (LPC_SHB_ORDER + 1)); + + /*for (int i = 0; i < LPC_SHB_ORDER; i++) + { + lsf_shb_fx[i] = lsf_shb[i] * ONE_IN_Q12; + }*/ + //floatToFixed_arr(lsf_shb, lsf_shb_fx, Q15, LPC_SHB_ORDER); + + /*for (int i = 0; i < NB_SUBFR16k; i++) + { + shb_res_gshape_fx[i] = shb_res_gshape[i] * ONE_IN_Q14; + }*/ + //floatToFixed_arr(shb_res_gshape, shb_res_gshape_fx, Q14, NB_SUBFR16k); + + /*for (int i = 0; i < NB_SUBFR16k; i++) + { + vf_modified_fx[i] = vf_modified[i] * ONE_IN_Q15; + }*/ + //floatToFixed_arr(vf_modified, vf_modified_fx, Q15, NB_SUBFR16k); + + //shb_ener_sf_32 = floatToFixed(shb_ener_sf, 0); + //formant_fac_fx = float_to_fix16(formant_fac, Q15); + //Move outside + //st->Q_syn = 0; + + + + /* -------- start of memory rescaling -------- */ + /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ + Lmax = 0; + FOR(cnt = 0; cnt < L_FRAME32k; cnt++) + { + Lmax = L_max(Lmax, L_abs(bwe_exc_extended_fx[cnt])); + } + Q_bwe_exc = norm_l(Lmax); + IF (Lmax == 0) + { + Q_bwe_exc = 31; + } + Q_bwe_exc = add(Q_bwe_exc, add(Q_exc, Q_exc)); + find_max_mem_dec(st, &n_mem, &n_mem2, &n_mem3); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ + + tmp = add(st->prev_Q_bwe_exc, n_mem); + IF(GT_16(Q_bwe_exc, tmp)) + { + Q_bwe_exc = tmp; + } + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub(Q_bwe_exc, st->prev_Q_bwe_exc); + IF(sc != 0) + { + rescale_genSHB_mem_dec(st, sc); + } + + /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ + //Copy(hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_16, NL_BUFF_OFFSET); + sc = sub(Q_bwe_exc, add(Q_exc, Q_exc)); + + FOR(cnt = 0; cnt < L_FRAME32k; cnt++) + { +#ifdef BASOP_NOGLOB + //bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx_sat(L_shl_sat(bwe_exc_extended_fx[cnt], sc)); + bwe_exc_extended_16[cnt] = round_fx_sat(L_shl_sat(bwe_exc_extended_fx[cnt], sc)); +#else + bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx(L_shl(bwe_exc_extended[cnt], sc)); +#endif + } + //Copy(bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET); + + /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ + //Copy(hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD); + + /* save the previous Q factor (32-bit) of the buffer */ + st->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + + Q_bwe_exc = sub(Q_bwe_exc, 16); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ + + /* -------- end of rescaling memories -------- */ + + Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; + move16(); + + //Word16 tmp_buffer[L_FRAME48k] = { 0 }; + //Word16 q_temp = 0; + Q_shb = 0; + + //*Q_bwe_exc_orig = Q_bwe_exc; + //mvr2r( hBWE_TD->state_syn_shbexc, shaped_shb_excitation, L_SHB_LAHEAD ); + Copy(hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD); + /*GenShapedSHBExcitation( shaped_shb_excitation + L_SHB_LAHEAD, lpc_shb, White_exc16k, hBWE_TD->mem_csfilt, + hBWE_TD->mem_genSHBexc_filt_down_shb, hBWE_TD->state_lpc_syn, st->coder_type, bwe_exc_extended, + hBWE_TD->bwe_seed, vf_modified, st->extl, &( hBWE_TD->tbe_demph ), &( hBWE_TD->tbe_premph ), + lpc_shb_sf, &shb_ener_sf, shb_res_gshape, shb_res_dummy, &vind, formant_fac, + hBWE_TD->fb_state_lpc_syn, &( hBWE_TD->fb_tbe_demph ), st->total_brate, st->prev_bfi, + st->element_mode, st->flag_ACELP16k, nlExc16k, mixExc16k, st->extl_brate, MSFlag, + NULL, &( hBWE_TD->prev_pow_exc16kWhtnd ), &( hBWE_TD->prev_mix_factor ), NULL, NULL );*/ + + /*GenShapedSHBExcitation_fx(shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, tmp_buffer, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, + &(hBWE_TD->tbe_demph_fx), &(hBWE_TD->tbe_premph_fx), lpc_shb_sf_fx, shb_ener_sf_32, + shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, + &(hBWE_TD->fb_tbe_demph_fx), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi);*/ + GenShapedSHBExcitation_ivas_fx(shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, + &(hBWE_TD->tbe_demph_fx), &(hBWE_TD->tbe_premph_fx), lpc_shb_sf_fx, shb_ener_sf_32, + shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, + &(hBWE_TD->fb_tbe_demph_fx), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, + st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, + NULL, &(hBWE_TD->prev_pow_exc16kWhtnd_fx32), &(hBWE_TD->prev_mix_factor_fx), NULL, NULL); + + //Scale_sig(shaped_shb_excitation_fx, L_SHB_LAHEAD, Q_bwe_exc - Q_bwe_exc_orig); + + /*if (Q_bwe_exc_fb > 31) { + Scale_sig(tmp_buffer, L_FRAME48k, 31 - Q_bwe_exc_fb); + Scale_sig(&hBWE_TD->fb_tbe_demph_fx, 1, 31 - Q_bwe_exc_fb); + }*/ + //fixedToFloat_arr(shaped_shb_excitation_fx, shaped_shb_excitation, Q_bwe_exc, L_FRAME16k + L_SHB_LAHEAD); + //fixedToFloat_arr(tmp_buffer, White_exc16k, min(Q_bwe_exc_fb, 31), L_FRAME48k); + + //<----Local fix2float----> + //n_mem + //st->prev_Q_bwe_exc = 9; + //floatToFixed_arr(hBWE_TD->old_bwe_exc_extended, hBWE_TD->old_bwe_exc_extended_fx, (st->prev_Q_bwe_exc), NL_BUFF_OFFSET); + //fixedToFloat_arr(hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_shb, (Q_bwe_exc_orig), 2 * ALLPASSSECTIONS_STEEP + 1); + //fixedToFloat_arrL(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_csfilt, Q_bwe_exc_orig + Q16, 2); + //printf(" %f\n", hBWE_TD->mem_csfilt[0]); + //hBWE_TD->tbe_premph = fixedToFloat(hBWE_TD->tbe_premph_fx, Q_bwe_exc_orig); + //hBWE_TD->tbe_demph = fixedToFloat(hBWE_TD->tbe_demph_fx, Q_bwe_exc_orig - NOISE_QADJ); + //hBWE_TD->fb_tbe_demph = fixedToFloat(hBWE_TD->fb_tbe_demph_fx, min(Q_bwe_exc_fb, 31)); + //n)mem2 + //fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, Q_bwe_exc, 10); + /* Back up the Q_bwe_exc associated with shaped_shb_excitation for the next frame*/ + //st->prev_Q_bwe_syn = Q_bwe_exc; + //floatToFixed_arr(hBWE_TD->state_syn_shbexc, hBWE_TD->state_syn_shbexc_fx, (st->prev_Q_bwe_exc), L_SHB_LAHEAD / 4); + //n_mem3 + //floatToFixed_arr(hBWE_TD->syn_overlap, hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD); + //fixedToFloat_arr(hBWE_TD->fb_state_lpc_syn_fx, hBWE_TD->fb_state_lpc_syn, Q_bwe_exc_fb - 16 - 4, LPC_SHB_ORDER); + //floatToFixed_arr(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP); + //floatToFixed_arr(hBWE_TD->int_3_over_2_tbemem_dec, hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + //floatToFixed_arr(hBWE_TD->mem_resamp_HB_32k, hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + //floatToFixed_arrL(hBWE_TD->genSHBsynth_Hilbert_Mem, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + /*if (nlExc16k && nlExc16k_fx) { + fixedToFloat_arr(nlExc16k_fx, nlExc16k, Q_bwe_exc, L_FRAME16k); + } + if (mixExc16k && mixExc16k_fx) { + fixedToFloat_arr(mixExc16k_fx, mixExc16k, st->Q_exc, L_FRAME16k); + } + hBWE_TD->prev_pow_exc16kWhtnd = fixedToFloat(hBWE_TD->prev_pow_exc16kWhtnd_fx32, 0); + hBWE_TD->prev_mix_factor = fixedToFloat(hBWE_TD->prev_mix_factor_fx, Q15);*/ + //<---------> + + *Q_white_exc = Q_bwe_exc_fb; + IF(EQ_16(st->extl, FB_TBE)) + { + st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); + } + ELSE + { + /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. + 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ + st->prev_Q_bwe_exc_fb = 51; + move16(); + } + /* fill-in missing SHB excitation */ + IF ( ( st->element_mode == IVAS_CPE_TD || st->element_mode == IVAS_CPE_DFT ) && st->last_core_brate <= SID_2k40 ) + { + //mvr2r( shaped_shb_excitation + L_SHB_LAHEAD, shaped_shb_excitation, L_SHB_LAHEAD ); + Copy(shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD); + } + + IF( hStereoICBWE != NULL ) + { + //mvr2r( shaped_shb_excitation + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef, L_FRAME16k ); + Copy(shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k); + } + + IF( st->extl_brate != SWB_TBE_1k10 && st->extl_brate != SWB_TBE_1k75 ) + { + FOR ( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) + { + /* TD BWE post-processing */ + /*PostShortTerm(&shaped_shb_excitation[L_SHB_LAHEAD + i], lpc_shb, &shaped_shb_excitationTemp[i], + hBWE_TD->mem_stp_swb, hBWE_TD->ptr_mem_stp_swb, &(hBWE_TD->gain_prec_swb), hBWE_TD->mem_zero_swb, formant_fac);*/ + + PostShortTerm_fx(&shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, + hBWE_TD->ptr_mem_stp_swb_fx, &(hBWE_TD->gain_prec_swb_fx), hBWE_TD->mem_zero_swb_fx, formant_fac_fx); + + } + + /*mvr2r( shaped_shb_excitationTemp, &shaped_shb_excitation[L_SHB_LAHEAD], L_FRAME16k ); + prev_pow = sum2_f( shaped_shb_excitation, L_SHB_LAHEAD + 10 ); + curr_pow = sum2_f( shaped_shb_excitation + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 );*/ + + Copy(shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k); /* Q_bwe_exc */ + + tmp = sub(shl(Q_bwe_exc, 1), 31 + 16); +#ifdef BASOP_NOGLOB + prev_pow_fx = L_shl_sat(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl_sat(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ +#else + prev_pow_fx = L_shl(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ +#endif + FOR(i = 0; i < L_SHB_LAHEAD + 10; i++) + { +#ifdef BASOP_NOGLOB + prev_pow_fx = L_mac0_sat(prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i]); /*2*Q_bwe_exc*/ + curr_pow_fx = L_mac0_sat(curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10]); /* 2*Q_bwe_exc */ +#else + prev_pow_fx = L_mac0(prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i]); /*2*Q_bwe_exc*/ + curr_pow_fx = L_mac0(curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10]); /* 2*Q_bwe_exc */ +#endif + } + + + /*if ( voice_factors[0] > 0.75f ) + { + curr_pow *= 0.25; + }*/ + IF (GT_16(voice_factors_fx[0], 24576/*0.75f Q15*/)) + { + curr_pow_fx = L_shr(curr_pow_fx, 2); /* Q(2*Q_bwe_exc) */ + } + + Lscale = root_a_over_b_fx(curr_pow_fx, + shl(Q_bwe_exc, 1), + prev_pow_fx, + shl(Q_bwe_exc, 1), + &exp); + + /*if ( prev_pow == 0 ) + { + scale = 0; + } + else + { + scale = (float) sqrt( curr_pow )/sqrt( prev_pow ); + } + + for ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + shaped_shb_excitation[i] *= scale; + } + for ( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp = ( i - 19 ) / 10.0f; + shaped_shb_excitation[i] *= ( temp * 1.0f + ( 1.0f - temp ) * scale ); + }*/ + + FOR(i = 0; i < L_SHB_LAHEAD; i++) + { + L_tmp = Mult_32_16(Lscale, shaped_shb_excitation_fx[i]); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx(L_shl(L_tmp, exp)); /* Q_bwe_exc */ + } + IF(exp < 0) + { + Lscale = L_shl(Lscale, exp); + exp = 0; + } + FOR(; i < L_SHB_LAHEAD + 10; i++) + { +#ifdef BASOP_NOGLOB + temp_fx = i_mult_sat(sub(i, 19), 3277/*0.1f Q15*/); /* Q15 */ + L_tmp1 = Mult_32_16(L_shl_sat(1, sub(31, exp)), temp_fx); /* Q31-exp */ +#else + temp_fx = i_mult(sub(i, 19), 3277/*0.1f Q15*/); /* Q15 */ + L_tmp1 = Mult_32_16(L_shl(1, sub(31, exp)), temp_fx); /* Q31-exp */ +#endif + temp_fx = sub(32767/*1.0f Q15*/, temp_fx); + Lscale = L_add(Mult_32_16(Lscale, temp_fx), L_tmp1); + L_tmp = Mult_32_16(Lscale, shaped_shb_excitation_fx[i]); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx(L_shl(L_tmp, exp)); /* Q_bwe_exc */ + } + + } + ELSE + { + /* reset the PF memories if the PF is not running */ + //set_f( hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER); + //hBWE_TD->gain_prec_swb = 1.0f; + hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + //set_f( hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER); + } + + /* Update SHB excitation */ + //mvr2r( shaped_shb_excitation + L_FRAME16k, hBWE_TD->state_syn_shbexc, L_SHB_LAHEAD ); + Copy(shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD); /* Q_bwe_exc */ + l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; + //ener = EPSILON; + L_ener = EPSILON_FX_SMALL; + /*for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + ener_tmp[i] = EPSILON; + for ( j = 0; j < l_subframe; j++ ) + { + ener_tmp[i] += shaped_shb_excitation[i * l_subframe + j] * shaped_shb_excitation[i * l_subframe + j] * 0.0125f; + } + ener_tmp[i] = (float) sqrt( ener_tmp[i] ); + ener += ener_tmp[i]; + } + ener /= NUM_SHB_SUBGAINS;*/ + + FOR(i = 0; i < NUM_SHB_SUBGAINS; i++) + { + L_tmp = 0; + ener_tmp_fx[i] = EPSILON_FX_SMALL; + + { + Word64 tmp64 = 0; + move64(); + FOR(j = 0; j < l_subframe; j++) + { + tmp64 = W_mac0_16_16(tmp64, shaped_shb_excitation_fx[i*l_subframe + j], shaped_shb_excitation_fx[i*l_subframe + j]);/* 2*Q_bwe_exc */ + } + L_tmp = W_sat_l(tmp64); + } + + L_tmp = Mult_32_16(L_tmp, 410/*0.0125 Q15*/); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ + IF(L_tmp != 0) + { + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + exp = sub(exp, 30 - (2 * Q_bwe_exc)); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); +#ifdef BASOP_NOGLOB + ener_tmp_fx[i] = L_shl_sat(L_tmp, sub(add(exp, shl(Q_bwe_exc, 1)), 31)); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ move32(); + L_ener = L_add_sat(L_ener, L_shr(ener_tmp_fx[i], 2));/* 2*Q_bwe_exc */ +#else + ener_tmp_fx[i] = L_shl(L_tmp, sub(add(exp, shl(Q_bwe_exc, 1)), 31)); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ move32(); + L_ener = L_add(L_ener, L_shr(ener_tmp_fx[i], 2));/* 2*Q_bwe_exc */ +#endif + } + } + ener_fx = s_max(1, round_fx(L_shl(L_ener, sub(19, shl(Q_bwe_exc, 1))))); /* Q3: 2*Q_bwe_exc+19-2*Q_bwe_exc-16 */ + + //ener = (float)ener_fx / (1 << 3); + + /* WB/SWB bandwidth switching */ + IF ( st->bws_cnt > 0 ) + { + //ener *= 0.35f; + + //ener_fx = mult(ener_fx, 11587); + ////if ( st->tilt_swb > 8 ) + //if (GT_16(st->tilt_swb_fx, 16384)) + //{ + // st->prev_fractive = 1; + //} + + //if ( is_fractive == 0 ) + //{ + // if ( st->tilt_wb > 1.0 ) + // { + // st->tilt_wb = 1.0f; + // } + // else if ( st->tilt_wb < 0.5 ) + // { + // st->tilt_wb = 0.5f; + // } + + // if ( st->prev_fractive == 1 && st->tilt_wb > 0.5 ) + // { + // st->tilt_wb = 0.5f; + // } + //} + //else + //{ + // if ( st->tilt_wb > 4 ) + // { + // if ( st->prev_fractive == 0 ) + // { + // st->tilt_wb = 4; + // } + // else + // { + // st->tilt_wb = 8; + // } + // } + // else + // { + // st->tilt_wb *= 2; + // } + //} + + IF(is_fractive == 0) + { + IF(GT_16(st->tilt_wb_fx, 2048)) /*assuming st->tilt_wb_fx in Q11*/ + { + st->tilt_wb_fx = 2048; + move16(); + } + ELSE IF(LT_16(st->tilt_wb_fx, 1024)) + { + st->tilt_wb_fx = 1024; + move16(); + } + test(); + IF (st->prev_fractive == 1 && GT_16(st->tilt_wb_fx, 1024)) + { + st->tilt_wb_fx = 1024; + move16(); + } + } + ELSE + { + IF(GT_16(st->tilt_wb_fx, 8192)) + { + IF(st->prev_fractive_fx == 0) + { + st->tilt_wb_fx = 8192; + } + ELSE + { + st->tilt_wb_fx = 16384; + } + } + ELSE + { + st->tilt_wb_fx = shl(st->tilt_wb_fx, 2); + } + } + + /*if ( ener != 0 ) + { + if ( ener * st->tilt_wb > st->enerLH ) + { + st->tilt_wb = 0.5f * st->enerLH / ener; + } + else if ( ener * st->tilt_wb < 0.05f * st->enerLH && is_fractive == 1 ) + { + st->tilt_wb = 0.25f * st->enerLH / ener; + } + + GainFrame_prevfrm = st->prev_ener_shb / ener; + } + else + { + GainFrame_prevfrm = 0; + }*/ + + // Test thispart!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + IF( ener_fx != 0 ) + { + L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 14 ) ); /* 3+11 +st->Q_syn2 -14 = st->Q_syn2*/ + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(3+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-3-exp) = 26- exp*/ + + test(); + IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ + { +#ifdef BASOP_NOGLOB + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ +#else + st->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ +#endif + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ + } + ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) + { +#ifdef BASOP_NOGLOB + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ +#else + st->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ +#endif + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ + } + L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ + GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ + } + ELSE + { + GainFrame_prevfrm_fx = 0; + } + + /*if ( is_fractive == 1 ) + { + GainFrame = 8.0f * st->tilt_wb; + } + else + { + GainFrame = 2.0f * st->tilt_wb; + }*/ + + IF( EQ_16( is_fractive, 1 ) ) + { + GainFrame_fx = L_shl( (Word32) st->tilt_wb_fx, 10 ); + } + ELSE + { + GainFrame_fx = L_shl( (Word32) st->tilt_wb_fx, 8 ); + } + + /*if ( ( is_fractive & st->prev_fractive ) == 1 && GainFrame > GainFrame_prevfrm ) + { + GainFrame = 0.2f * GainFrame + 0.8f * GainFrame_prevfrm; + } + else + { + if ( ( st->prev_enerLH < 2.0f * st->enerLH && st->prev_enerLH > 0.5f * st->enerLH ) && ( st->prev_enerLL < 2.0f * st->enerLL && st->prev_enerLL > 0.5f * st->enerLL ) && ( is_fractive ^ st->prev_fractive ) == 0 ) + { + GainFrame = 0.5f * GainFrame + 0.5f * GainFrame_prevfrm; + } + else + { + if ( is_fractive == 0 && st->prev_fractive == 1 ) + { + GainFrame = ( 1.0f - 0.1f * GainFrame ) * GainFrame + 0.1f * GainFrame * GainFrame_prevfrm; + } + else + { + GainFrame = 0.5f * GainFrame + 0.5f * GainFrame_prevfrm; + } + } + }*/ + + test(); + IF(EQ_16((is_fractive & st->prev_fractive), 1) && GT_32(GainFrame_fx, GainFrame_prevfrm_fx)) + { + GainFrame_fx = L_add(Mult_32_16(GainFrame_prevfrm_fx, 26214), Mult_32_16(GainFrame_fx, 6554));/* 18 +15 -15 = 18*/ + } + ELSE + { + test(); + test(); + test(); + test(); + IF((LT_32(L_shr(st->prev_enerLH_fx, 1), st->enerLH_fx) && GT_32(st->prev_enerLH_fx,L_shr(st->enerLH_fx,1))) + && (LT_32(L_shr(st->prev_enerLL_fx, 1), st->enerLL_fx) && GT_32(st->prev_enerLL_fx, L_shr(st->enerLL_fx, 1))) && (is_fractive ^ st->prev_fractive_fx) == 0) + { + GainFrame_fx = L_add(L_shr(GainFrame_fx, 1), L_shr(GainFrame_prevfrm_fx, 1)); + } + ELSE + { + test(); + IF(is_fractive == 0 && EQ_16(st->prev_fractive_fx, 1)) + { + L_tmp1 = L_shl(Mult_32_16(GainFrame_fx, 3277), 13); /* 31 */ + L_tmp = L_sub(2147483647, L_tmp1); /* 31 */ + GainFrame_fx = L_add(Mult_32_32(GainFrame_fx, L_tmp), Mult_32_32(GainFrame_prevfrm_fx, L_tmp1)); /* 18 */ + } + ELSE + { + GainFrame_fx = L_add(L_shr(GainFrame_fx, 1), L_shr(L_min(GainFrame_prevfrm_fx, GainFrame_fx), 1)); /* 18 */ + } + } + } + + GainFrame_fx = Mult_32_16(GainFrame_fx, i_mult(sub(N_WS2N_FRAMES, st->bws_cnt), 819)); /*Q18*/ + //GainFrame *= ( (float) N_WS2N_FRAMES - (float) st->bws_cnt ) / (float) N_WS2N_FRAMES; + } + ELSE + { + IF ( st->bws_cnt1 > 0 ) + { + //GainFrame *= (float) st->bws_cnt1 / (float) N_WS2N_FRAMES; + GainFrame_fx = Mult_32_16(GainFrame_fx, i_mult(st->bws_cnt1, 819)); /*Q18*/ + } + IF(GE_16(st->nbLostCmpt, 1)) + { + ener_fx = s_max(1, ener_fx); + exp_ener = norm_s(ener_fx); + tmp = shl(ener_fx, exp_ener);/*Q(3+exp)*/ + inv_ener = div_s(16384, tmp);/*Q(15+14-3-exp)*/ + prev_ener_ratio_fx = L_shr(L_mult0(st->prev_ener_shb_fx, inv_ener), sub(9, exp_ener)); /*Q: 1+26-exp-9+exp = 18 */ + } + + IF ( st->nbLostCmpt == 1 ) + { + /*prev_ener_ratio = st->prev_ener_shb / ener; + + if ( st->clas_dec != UNVOICED_CLAS && st->clas_dec != UNVOICED_TRANSITION && hBWE_TD->tilt_swb_fec < 8.0 && + ( ( st->enerLL > 0.5f * st->prev_enerLL && st->enerLL < 2.0f * st->prev_enerLL ) || ( st->enerLH > 0.5f * st->prev_enerLH && st->enerLH < 2.0f * st->prev_enerLH ) ) ) + { + if ( prev_ener_ratio > 4.0f * GainFrame ) + { + GainFrame = 0.4f * prev_ener_ratio + 0.6f * GainFrame; + } + else if ( prev_ener_ratio > 2.0f * GainFrame ) + { + GainFrame = 0.8f * prev_ener_ratio + 0.2f * GainFrame; + } + else + { + GainFrame = 0.2f * prev_ener_ratio + 0.8f * GainFrame; + } + + if ( tilt_swb_fec > hBWE_TD->tilt_swb_fec ) + { + GainFrame *= hBWE_TD->tilt_swb_fec > 0 ? ( min( 5.0f, tilt_swb_fec / hBWE_TD->tilt_swb_fec ) ) : 1.0f; + } + } + else if ( ( st->clas_dec != UNVOICED_CLAS || hBWE_TD->tilt_swb_fec > 8.0 ) && prev_ener_ratio > 4.0f * GainFrame && ( st->enerLL > 0.5f * st->prev_enerLL || st->enerLH > 0.5f * st->prev_enerLH ) ) + { + GainFrame = 0.2f * prev_ener_ratio + 0.8f * GainFrame; + }*/ + + IF(NE_16(st->clas_dec, UNVOICED_CLAS) && NE_16(st->clas_dec, UNVOICED_TRANSITION) && LT_16(hBWE_TD->tilt_swb_fec_fx, 16384) && + ((GT_32(st->enerLL_fx, L_shr(st->prev_enerLL_fx, 1)) && LT_32(L_shr(st->enerLL_fx, 1), st->prev_enerLL_fx)) || (GT_32(st->enerLH_fx, L_shr(st->prev_enerLH_fx, 1)) && LT_32(L_shr(st->enerLH_fx, 1), st->prev_enerLH_fx)))) + { + IF(GT_32(L_shr(prev_ener_ratio_fx, 2), GainFrame_fx))/*18*/ + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 13107), Mult_32_16(GainFrame_fx, 19661));/*18*/ + } + ELSE IF(GT_32(L_shr(prev_ener_ratio_fx, 1), GainFrame_fx)) + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 26214), Mult_32_16(GainFrame_fx, 6554)); + } + ELSE + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame_fx, 26214)); + } + + test(); + IF(GT_16(tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx) && hBWE_TD->tilt_swb_fec_fx > 0) + { + exp = norm_s(hBWE_TD->tilt_swb_fec_fx); + tmp = shl(hBWE_TD->tilt_swb_fec_fx, exp);/*Q(11+exp)*/ + tmp = div_s(16384, tmp);/*Q(15+14-11-exp)*/ + tmp = extract_h(L_shl(L_mult0(tmp, st->tilt_wb_fx), sub(exp, 1)));/*18 -exp +11 + exp -1 -16 =12; */ + GainFrame_fx = L_shl(Mult_32_16(GainFrame_fx, s_min(tmp, 20480)), 3); /*Q18 = 18 +12 -15 +3 */ + } + + } + ELSE IF((NE_16(st->clas_dec, UNVOICED_CLAS) || GT_16(hBWE_TD->tilt_swb_fec_fx, 4096)) && GT_32(L_shr(prev_ener_ratio_fx, 2), GainFrame_fx) && + (GT_32(st->enerLL_fx, L_shr(st->prev_enerLL_fx, 1)) || GT_32(st->enerLH_fx, L_shr(st->prev_enerLH_fx, 1)))) + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame_fx, 26214)); + } + + } + ELSE IF( st->nbLostCmpt > 1 ) + { + /*prev_ener_ratio = st->prev_ener_shb / ener; + if ( ( prev_ener_ratio > 4.0 * GainFrame ) && ( ( st->codec_mode == MODE1 && st->enerLL > st->prev_enerLL && st->enerLH > st->prev_enerLH ) || st->codec_mode == MODE2 ) ) + { + if ( tilt_swb_fec > 10.0f && hBWE_TD->tilt_swb_fec > 10.0f ) + { + GainFrame = min( ( prev_ener_ratio * 0.8f + GainFrame * 0.2f ), 4.0f * GainFrame ); + } + else + { + GainFrame = min( ( prev_ener_ratio * 0.5f + GainFrame * 0.5f ), 4.0f * GainFrame ); + } + } + else if ( ( prev_ener_ratio > GainFrame ) && ( ( st->codec_mode == MODE1 && st->enerLL > st->prev_enerLL && st->enerLH > st->prev_enerLH ) || st->codec_mode == MODE2 ) ) + { + if ( tilt_swb_fec > 10.0f && hBWE_TD->tilt_swb_fec > 10.0f ) + { + GainFrame = 0.5f * prev_ener_ratio + 0.5f * GainFrame; + } + else + { + GainFrame = 0.2f * prev_ener_ratio + 0.8f * GainFrame; + } + }*/ + + IF(GT_32(L_shr(prev_ener_ratio_fx, 2), GainFrame_fx) && ((EQ_16(st->codec_mode, MODE1) && GT_32(st->enerLL_fx, st->prev_enerLL_fx) && GT_32(st->enerLH_fx, st->prev_enerLH_fx)) || EQ_16(st->codec_mode, MODE2))) + { + test(); + IF(GT_16(tilt_swb_fec_fx, 20480) && GT_16(hBWE_TD->tilt_swb_fec_fx, 20480)) + { + GainFrame_fx = L_min(L_add(Mult_32_16(prev_ener_ratio_fx, 26214), Mult_32_16(GainFrame_fx, 6554)), L_shl(Mult_32_16(GainFrame_fx, 16384), 3)); /*Q18*/ + } + ELSE + { + GainFrame_fx = L_min(L_add(Mult_32_16(prev_ener_ratio_fx, 16384), Mult_32_16(GainFrame_fx, 16384)), L_shl(Mult_32_16(GainFrame_fx, 16384), 3)); /*Q18*/ + } + } + ELSE IF(GT_32(prev_ener_ratio_fx, GainFrame_fx) && ((EQ_16(st->codec_mode, MODE1) && GT_32(st->enerLL_fx, st->prev_enerLL_fx) && GT_32(st->enerLH_fx, st->prev_enerLH_fx)) || EQ_16(st->codec_mode, MODE2))) + { + test(); + IF(GT_16(tilt_swb_fec_fx, 20480) && GT_16(hBWE_TD->tilt_swb_fec_fx, 20480)) + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 16384), Mult_32_16(GainFrame_fx, 16384)); + } + ELSE + { + GainFrame_fx = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame_fx, 26214)); + } + } + + } + } + + st->prev_fractive = is_fractive; + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + IF( st->L_frame == L_FRAME ) + { + //pitch = 0.25f * sum_f( pitch_buf, 4 ); + L_tmp = L_mult(pitch_buf_fx[0], 8192); + FOR(i = 1; i < NB_SUBFR; i++) + { + L_tmp = L_mac(L_tmp, pitch_buf_fx[i], 8192); /* pitch_buf in Q6 x 0.25 in Q15 */ + } + pitch_fx = round_fx(L_tmp); /* Q6 */ + } + ELSE + { + //pitch = 0.2f * sum_f( pitch_buf, 5 ); + L_tmp = L_mult(pitch_buf_fx[0], 6554); + FOR(i = 1; i < NB_SUBFR16k; i++) + { + L_tmp = L_mac(L_tmp, pitch_buf_fx[i], 6554); /* pitch_buf in Q6 x 0.2 in Q15 */ + } + pitch_fx = round_fx(L_tmp); /* Q6 */ + } + + IF ( ( ( st->extl_brate >= SWB_TBE_2k8 && st->prev_coder_type == st->coder_type && st->coder_type != UNVOICED ) || ( st->extl_brate < SWB_TBE_2k8 && ( st->prev_coder_type == st->coder_type || ( st->prev_coder_type == VOICED && st->coder_type == GENERIC ) || ( st->prev_coder_type == GENERIC && st->coder_type == VOICED ) ) ) ) && GT_16(pitch_fx, 4480 /*70 in Q6*/) && st->extl < FB_TBE && st->extl_brate != SWB_TBE_1k10 && st->extl_brate != SWB_TBE_1k75 ) + { + /*for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp[i] = GainShape[i * 4]; + }*/ + FOR(i = 0; i < NUM_SHB_SUBGAINS; i++) + { + GainShape_tmp_fx[i] = GainShape_fx[shl(i, 2)]; /* Q15 */ move16(); + } + + /*for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + if ( ener_tmp[i] * GainShape_tmp[i] > hBWE_TD->prev_ener * hBWE_TD->prev_GainShape ) + { + GainShape_tmp[i] = 0.5f * ( hBWE_TD->prev_ener * hBWE_TD->prev_GainShape / ener_tmp[i] + GainShape_tmp[i] ); + } + hBWE_TD->prev_ener = ener_tmp[i]; + hBWE_TD->prev_GainShape = GainShape_tmp[i]; + }*/ + FOR(i = 0; i < NUM_SHB_SUBGAINS; i++) + { + /* if( ener_tmp_fx[i]*GainShape_tmp_fx[i] > st->prev_ener_fx*st->prev_GainShape_fx ) */ + L_tmp1 = Mult_32_16(ener_tmp_fx[i], GainShape_tmp_fx[i]); /* (2*Q_bwe_exc) */ + L_tmp2 = Mult_32_16(hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx); /* (2*st->prev_ener_fx_Q) */ + tmp = sub(shl(Q_bwe_exc, 1), shl(st->prev_ener_fx_Q, 1)); +#ifdef BASOP_NOGLOB + L_tmp2 = L_shl_sat(L_tmp2, tmp); /* new Q = (2*Q_bwe_exc) */ +#else + L_tmp2 = L_shl(L_tmp2, tmp); /* new Q = (2*Q_bwe_exc) */ +#endif + IF(GT_32(L_tmp1, L_tmp2)) + { + /*GainShape_tmp_fx[i] = 0.5f*(L_tmp2/ener_tmp_fx[i] + GainShape_tmp_fx[i]);*/ + /* tmp = L_tmp2/ener_tmp_fx[i]*/ + L_tmp = L_tmp2; + IF(L_tmp2 < 0) + { + L_tmp = L_negate(L_tmp2); + } + + expb = norm_l(L_tmp); +#ifdef BASOP_NOGLOB + fracb = round_fx_sat(L_shl_sat(L_tmp, expb)); +#else + fracb = round_fx(L_shl(L_tmp, expb)); +#endif + expb = 30 - expb; /* - (2*Q_bwe_exc_ext); */ + + expa = norm_l(ener_tmp_fx[i]); + fraca = extract_h(L_shl(ener_tmp_fx[i], expa)); + expa = 30 - expa; + + scale_fx = shr(sub(fraca, fracb), 15); + fracb = shl(fracb, scale_fx); + expb = sub(expb, scale_fx); + + tmp = div_s(fracb, fraca); + exp = sub(sub(expb, expa), 1); + tmp = shl(tmp, exp); + GainShape_tmp_fx[i] = add(tmp, shr(GainShape_tmp_fx[i], 1));/* Q15 */ + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; + hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; + st->prev_ener_fx_Q = Q_bwe_exc; + } + + /*for ( i = 0; i < NUM_SHB_SUBFR; i++ ) + { + GainShape[i] = GainShape_tmp[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + }*/ + FOR(i = 0; i < NUM_SHB_SUBFR; i++) + { + GainShape_fx[i] = GainShape_tmp_fx[i*NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + move16(); + } + } + ELSE + { + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + st->prev_Q_bwe_syn = Q_bwe_exc; + + + /* Gain shape smoothing after quantization */ + IF( st->extl_brate == SWB_TBE_1k10 || st->extl_brate == SWB_TBE_1k75 ) + { + FOR ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + //GainShape_tmp[i] = GainShape[i * NUM_SHB_SUBGAINS]; + GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; + } + + //lls_interp_n( GainShape_tmp, NUM_SHB_SUBGAINS, &GainShape_tilt, &temp, 1 ); + lls_interp_n_fx(GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1); + + /*if ( vind >= 6 && fabs( GainShape_tilt ) < 0.12f ) + { + feedback = 0.3f; + for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape[i] = ( 1 - feedback ) * GainShape[i * NUM_SHB_SUBGAINS] + feedback * GainShape_tmp[i]; + } + + for ( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) + { + GainShape[i] = GainShape[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + } + }*/ + IF(vind >= 6 && abs(GainShape_tilt_fx) < 3932) + { + feedback_fx = 9830; + FOR (i = 0; i < NUM_SHB_SUBGAINS; i++) + { + GainShape_fx[i] = add_sat(mult((32767 - feedback_fx), GainShape_fx[i * NUM_SHB_SUBGAINS]), mult(feedback_fx, GainShape_tmp_fx[i])); + } + + FOR(i = NUM_SHB_SUBFR - 1; i > 0; i--) + { + GainShape_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + } + } + } + + /* fil-in missing memory */ + IF ( ( st->element_mode == IVAS_CPE_TD || st->element_mode == IVAS_CPE_DFT ) && st->last_core_brate <= SID_2k40 ) + { + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + //hBWE_TD->syn_overlap[i] = shaped_shb_excitation[i] * subwin_shb[L_SHB_LAHEAD - i]; + Word16 intermediate = mult(shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i]); + //hBWE_TD->syn_overlap[i] *= window_shb[L_SHB_LAHEAD - 1 - i] * GainFrame; + Word32 intermediate_32 = Mpy_32_16_1(Mpy_32_16_1(GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i]), intermediate); + hBWE_TD->syn_overlap_fx[i] = (Word16)round_fx(L_shl_sat(intermediate_32, 16 - (Q_bwe_exc + 18 - 15))); + } + } + + Word16 n_mem3_new = 0; + //Word16 Qx = 0; + find_max_mem_dec_m3(st, &n_mem3_new); + + //ScaleShapedSHB( SHB_OVERLAP_LEN, shaped_shb_excitation, hBWE_TD->syn_overlap, GainShape, GainFrame, window_shb, subwin_shb ); + + //Scale_sig32(st->hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, Q_bwe_exc); + //sc = Q_bwe_exc; + ScaleShapedSHB_fx(SHB_OVERLAP_LEN, + shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ + hBWE_TD->syn_overlap_fx, + GainShape_fx, /* Q15 */ + GainFrame_fx, /* Q18 */ + window_shb_fx, + subwin_shb_fx, + &Q_bwe_exc + , &Qx + , n_mem3_new + , st->prev_Q_bwe_syn2); + //fixedToFloat_arr(st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, Qx, L_SHB_LAHEAD); + //fixedToFloat_arr(shaped_shb_excitation_fx, shaped_shb_excitation, Q_bwe_exc, L_SHB_LAHEAD); + + //sc = sub( Q_bwe_exc, sc ); + //IF(sc != 0) + //{ + // rescale_genSHB_mem_dec(st, sc); + // /*Scale_sig(shaped_shb_excitation_fx, L_FRAME16k + L_SHB_LAHEAD, sc); + // Scale_sig(hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, sc); + // Q_bwe_exc = add(Q_bwe_exc, sc);*/ + //} + //Q_bwe_exc_orig = add(Q_bwe_exc_orig, sc); + IF ( hStereoICBWE != NULL ) + { + //mvr2r( lpc_shb, hStereoICBWE->lpSHBRef, LPC_SHB_ORDER + 1 ); + //Copy(lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1); + Copy_Scale_sig_16_32(lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0); + //mvr2r( GainShape, hStereoICBWE->gshapeRef, NUM_SHB_SUBFR ); + Copy(GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR); + //hStereoICBWE->gFrameRef = GainFrame; + hStereoICBWE->gFrameRef_fx = GainFrame_fx; + + //mvr2r( shaped_shb_excitation, hStereoICBWE->shbSynthRef, L_FRAME16k ); + Copy(shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k); + } + + max_val = 0; + FOR(i = 0; i < L_FRAME16k; i++) + { + max_val = s_max(max_val, shaped_shb_excitation_fx[i]); /* Q0 */ + } + IF(max_val == 0) + { + curr_frame_pow_fx = 0; + move16(); + n = 0; + move16(); + } + ELSE + { + n = norm_s(max_val); + max_val = 0; + FOR(i = 0; i < L_FRAME16k; i++) + { +#ifdef BASOP_NOGLOB + shaped_shb_excitation_frac[i] = shl_sat(shaped_shb_excitation_fx[i], n); /*Q_bwe_exc+n*/ move16(); +#else + shaped_shb_excitation_frac[i] = shl(shaped_shb_excitation_fx[i], n); /*Q_bwe_exc+n*/ move16(); +#endif + } + + curr_frame_pow_fx = 0; + FOR(i = 0; i < L_FRAME16k; i++) + { + L_tmp = L_mult0(shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i]); /*2*(Q_bwe_exc+n)*/ + curr_frame_pow_fx = L_add(curr_frame_pow_fx, L_shr(L_tmp, 9)); /*2*(Q_bwe_exc+n)-9*/ + } + } + curr_frame_pow_exp = sub(shl(add(Q_bwe_exc, n), 1), 9); + tmp = sub(st->prev_frame_pow_exp, curr_frame_pow_exp); + IF(tmp > 0) /* shifting prev */ + { + IF(GT_16(tmp, 32)) + { + st->prev_frame_pow_exp = add(curr_frame_pow_exp, 32); + tmp = 32; + } + hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + } + ELSE /* shifting curr */ + { + IF(LT_16(tmp,-32)) + { + curr_frame_pow_exp = sub(st->prev_frame_pow_exp,32); + tmp = -32; + } + curr_frame_pow_fx = L_shr(curr_frame_pow_fx, -tmp); + curr_frame_pow_exp = st->prev_frame_pow_exp; + } + + /*curr_frame_pow = sum2_f( shaped_shb_excitation, L_FRAME16k ) + 0.001f; + curr_frame_pow = min( curr_frame_pow, FLT_MAX );*/ + + //curr_frame_pow = (float)curr_frame_pow_fx / (1 << curr_frame_pow_exp); + IF ( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) + { + /*if ( ( curr_frame_pow > 2.0f * hBWE_TD->prev_swb_bwe_frame_pow ) && + ( curr_frame_pow < 30.0f * hBWE_TD->prev_swb_bwe_frame_pow ) && + st->prev_coder_type == UNVOICED ) + { + scale = (float) sqrt( hBWE_TD->prev_swb_bwe_frame_pow / curr_frame_pow ); + if ( curr_frame_pow == 0 ) + { + scale = 0; + } + temp = (float) pow( scale, 0.125f ); + } + else + { + scale = 1.0f; + temp = 1.0f; + }*/ + IF((GT_32(L_shr(curr_frame_pow_fx, 1), hBWE_TD->prev_swb_bwe_frame_pow_fx)) && + (GT_32(hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp)) && EQ_16(st->prev_coder_type, UNVOICED)) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp); + scale_fx = round_fx(L_shl(L_tmp, exp)); /*Q15*/ + + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + temp_fx = round_fx(L_shl(L_tmp, exp)); /*Q15*/ + } + ELSE + { + scale_fx = temp_fx = 32767; + move16();/*Q15*/ + } + + /*for ( j = 0; j < 8; j++ ) + { + GainShape[2 * j] *= scale; + GainShape[2 * j + 1] *= scale; + for ( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation[i + j * L_FRAME16k / 8] *= scale; + } + + scale /= temp; + }*/ + FOR(j = 0; j < 8; j++) + { + GainShape_fx[2 * j] = mult_r(GainShape_fx[2 * j], scale_fx); + move16(); + GainShape_fx[2 * j + 1] = mult_r(GainShape_fx[2 * j + 1], scale_fx); + move16(); + FOR(i = 0; i < L_FRAME16k / 8; i++) + { + shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = mult_r(shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx); + move16(); + } + + IF(temp_fx > 0) + { + /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) + and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ + IF(LT_16(scale_fx, temp_fx)) + { + scale_fx = div_s(scale_fx, temp_fx); + } + ELSE + { + scale_fx = 32767; + move16(); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + /* adjust the FEC frame energy */ + IF( st->bfi ) + { + /*scale = 1.0f; + temp = 1.0f;*/ + scale_fx = temp_fx = 4096; + move16();/*Q12*/ + IF( st->nbLostCmpt == 1 ) + { + /*if ( curr_frame_pow > hBWE_TD->prev_swb_bwe_frame_pow && st->prev_coder_type != UNVOICED && st->last_good != UNVOICED_CLAS ) + { + scale = (float) sqrt( hBWE_TD->prev_swb_bwe_frame_pow / curr_frame_pow ); + if ( curr_frame_pow == 0 ) + { + scale = 0; + } + temp = (float) pow( scale, 0.125f ); + } + else if ( curr_frame_pow < 0.5f * hBWE_TD->prev_swb_bwe_frame_pow && st->nbLostCmpt == 1 && ( st->enerLL > 0.5 * st->prev_enerLL || st->enerLH > 0.5 * st->prev_enerLH ) && ( st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS || hBWE_TD->tilt_swb_fec > 5.0f ) ) + { + scale = (float) sqrt( hBWE_TD->prev_swb_bwe_frame_pow / curr_frame_pow ); + if ( curr_frame_pow == 0 ) + { + scale = 0; + } + temp = (float) pow( scale, 0.125f ); + }*/ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF(GT_32(curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx) && + NE_16(st->prev_coder_type, UNVOICED) && + NE_16(st->last_good, UNVOICED_CLAS)) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp); /*31 - exp*/ + scale_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + temp_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + } + ELSE IF(LT_32(curr_frame_pow_fx, L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx, 1)) && EQ_16(st->nbLostCmpt, 1) && + (GT_32(st->enerLL_fx, L_shr(st->prev_enerLL_fx, 1)) || GT_32(st->enerLH_fx, L_shr(st->prev_enerLH_fx, 1))) && + (EQ_16(st->prev_coder_type, UNVOICED) || EQ_16(st->last_good, UNVOICED_CLAS) || GT_16(hBWE_TD->tilt_swb_fec_fx, 10240))) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp); +#ifdef BASOP_NOGLOB + scale_fx = round_fx_sat(L_shl_sat(L_tmp, sub(exp, 3))); /*Q12*/ +#else + scale_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ +#endif + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + temp_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + } + } + ELSE IF ( st->nbLostCmpt > 1 ) + { + /*if ( curr_frame_pow > hBWE_TD->prev_swb_bwe_frame_pow ) + { + scale = (float) sqrt( hBWE_TD->prev_swb_bwe_frame_pow / curr_frame_pow ); + if ( curr_frame_pow == 0 ) + { + scale = 0; + } + temp = (float) pow( scale, 0.125f ); + } + else if ( curr_frame_pow < 0.5f * hBWE_TD->prev_swb_bwe_frame_pow && ( st->enerLL > 0.5 * st->prev_enerLL || st->enerLH > 0.5 * st->prev_enerLH ) && ( st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS || hBWE_TD->tilt_swb_fec > 5.0f ) ) + { + scale = (float) min( 2.0f, sqrt( hBWE_TD->prev_swb_bwe_frame_pow / curr_frame_pow ) ); + if ( curr_frame_pow == 0 ) + { + scale = 0; + } + temp = (float) pow( scale, 0.125f ); + }*/ + IF(GT_32(curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx)) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp); + scale_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); +#ifdef BASOP_NOGLOB + temp_fx = round_fx_sat(L_shl_sat(L_tmp, sub(exp, 3))); /*Q12*/ +#else + temp_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ +#endif + } + ELSE IF(LT_32(curr_frame_pow_fx, L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx, 1)) && + (GT_32(st->enerLL_fx, L_shr(st->prev_enerLL_fx, 1)) || GT_32(st->enerLH_fx, L_shr(st->prev_enerLH_fx, 1))) && + (st->prev_coder_type == UNVOICED || st->last_good == UNVOICED_CLAS || GT_16(hBWE_TD->tilt_swb_fec_fx, 10240))) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp); +#ifdef BASOP_NOGLOB + L_tmp = L_min(L_tmp, L_shl_sat(2, (31 - exp)));/*31 - exp*/ +#else + L_tmp = L_min(L_tmp, L_shl(2, (31 - exp)));/*31 - exp*/ +#endif + scale_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + L_tmp = root_a_fx(L_tmp, 31 - exp, &exp); + temp_fx = round_fx(L_shl(L_tmp, sub(exp, 3))); /*Q12*/ + } + } + + /*for ( j = 0; j < 8; j++ ) + { + GainShape[2 * j] *= scale; + GainShape[2 * j + 1] *= scale; + for ( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation[i + j * L_FRAME16k / 8] *= scale; + } + + scale /= temp; + }*/ + FOR(j = 0; j < 8; j++) + { +#ifdef BASOP_NOGLOB + GainShape_fx[2 * j] = shl_sat(mult_r(GainShape_fx[2 * j], scale_fx), 3); +#else + GainShape_fx[2 * j] = shl(mult_r(GainShape_fx[2 * j], scale_fx), 3); +#endif + move16(); /* 15 +12 +3-15 =15*/ +#ifdef BASOP_NOGLOB + GainShape_fx[2 * j + 1] = shl_sat(mult_r(GainShape_fx[2 * j + 1], scale_fx), 3); +#else + GainShape_fx[2 * j + 1] = shl(mult_r(GainShape_fx[2 * j + 1], scale_fx), 3); +#endif + move16(); + FOR(i = 0; i < 40; i++) + { + shaped_shb_excitation_fx[add(i, i_mult(j, 40))] = shl(mult_r(shaped_shb_excitation_fx[add(i, i_mult(j, 40))], scale_fx), 3); + move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ + } + + IF(temp_fx > 0) + { + IF(LT_16(scale_fx, temp_fx)) + { + scale_fx = shr(div_s(scale_fx, temp_fx), 3); + } + ELSE + { + tmp1 = sub(norm_s(scale_fx), 1); + tmp2 = norm_s(temp_fx); + scale_fx = div_s(shl(scale_fx, tmp1), shl(temp_fx, tmp2)); + scale_fx = shr(scale_fx, add(sub(tmp1, tmp2), 3)); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } +} + + //hBWE_TD->prev_swb_bwe_frame_pow = curr_frame_pow; + hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + /*st->prev_ener_shb = EPSILON; + for ( i = 0; i < L_FRAME16k; i++ ) + { + st->prev_ener_shb += shaped_shb_excitation[i] * shaped_shb_excitation[i]; + } + st->prev_ener_shb = (float) sqrt( st->prev_ener_shb / L_FRAME16k );*/ + + { + Word64 prev_ener_shb64 = 0; + move64(); + FOR(i = 0; i < L_FRAME16k; i++) + { + prev_ener_shb64 = W_mac0_16_16(prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i]); /* Q0 */ + } + L_prev_ener_shb = W_sat_l(prev_ener_shb64); + } + L_prev_ener_shb = Mult_32_16(L_prev_ener_shb, 26214); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ + st->prev_ener_shb_fx = 0; + IF(L_prev_ener_shb != 0) + { + exp = norm_l(L_prev_ener_shb); + tmp = extract_h(L_shl(L_prev_ener_shb, exp)); + exp = sub(exp, 30 - (2 * Q_bwe_exc + 8)); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + st->prev_ener_shb_fx = round_fx(L_shl(L_tmp, sub(exp, 14))); /* Q1 */ + } + + IF( st->hBWE_FD != NULL ) + { + /*for ( i = 0; i < SWB_FENV; i++ ) + { + st->hBWE_FD->prev_SWB_fenv[i] = (float) sqrt( curr_frame_pow / L_FRAME16k ); + }*/ + + L_tmp = Mult_32_16(curr_frame_pow_fx, 26214); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ + tmp = 0; + IF(L_tmp != 0) + { + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + exp = sub(exp, 30 - (curr_frame_pow_exp + 8)); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + tmp = round_fx(L_shl(L_tmp, sub(exp, 14))); /* Q1 */ + } + set16_fx(st->prev_SWB_fenv_fx, tmp, SWB_FENV); /* Q1 */ + } +#if 1 + //starting from here + + /*for (int i = 0; i < INTERP_3_2_MEM_LEN; i++) + { + st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i] = st->hBWE_TD->int_3_over_2_tbemem_dec[i] * (1 << 11); + } + for (int i = 0; i < HILBERT_MEM_SIZE; i++) + { + st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = st->hBWE_TD->genSHBsynth_Hilbert_Mem[i] * (1 << 11); + }*/ + //for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) + //{ + // //st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] = st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i] * (1 << 11); + // st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] = L_shl(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], Q11); + //} + /*for (int i = 0; i < L_SHB_TRANSITION_LENGTH; i++) + { + st->hBWE_TD->old_tbe_synth_fx_32[i] = hBWE_TD->old_tbe_synth[i] * (1 << 11); + }*/ + FOR (i = 0; i < L_FRAME16k + L_SHB_LAHEAD; i++) + { + //shaped_shb_excitation_fx_32[i] = shaped_shb_excitation[i] * (1 << 11); + shaped_shb_excitation_fx_32[i] = L_shl(shaped_shb_excitation_fx[i], Q11 - Q_bwe_exc); + } + /*for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++) + { + st->hBWE_TD->mem_resamp_HB_32k_fx_32[i] = st->hBWE_TD->mem_resamp_HB_32k[i] * (1 << 11); + }*/ + + //move up +#endif + + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + //Word16 loc_syn_dm_phase = hBWE_TD->syn_dm_phase;//delete + //GenSHBSynth( shaped_shb_excitation, error, hBWE_TD->genSHBsynth_Hilbert_Mem, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, st->L_frame, &(loc_syn_dm_phase) ); + GenSHBSynth_fx_32(shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); + + + //<----Local fix2float----> + //fixedToFloat_arrL(error_fx, error, Q11, L_FRAME32k); + //if (*Q_white_exc > 31) { + // Scale_sig(tmp_buffer, L_FRAME48k, 31 - *Q_white_exc); + // fixedToFloat_arr(tmp_buffer, White_exc16k, min(*Q_white_exc, 31), L_FRAME48k); + // //Scale_sig(&hBWE_TD->fb_tbe_demph_fx, 1, 31 - Q_bwe_exc_fb); + // Scale_sig(tmp_buffer, L_FRAME48k, *Q_white_exc - 31); + //} + //else{ + // fixedToFloat_arr(tmp_buffer, White_exc16k, min(*Q_white_exc, 31), L_FRAME48k); + //} + //fixedToFloat_arr(shaped_shb_excitation_fx, shaped_shb_excitation, Q_bwe_exc, L_FRAME16k + L_SHB_LAHEAD); + //fixedToFloat_arr(tmp_buffer, White_exc16k, min(Q_bwe_exc_fb, 31), L_FRAME48k); + + ////n_mem + ////st->prev_Q_bwe_exc = 9; + ////floatToFixed_arr(hBWE_TD->old_bwe_exc_extended, hBWE_TD->old_bwe_exc_extended_fx, (st->prev_Q_bwe_exc), NL_BUFF_OFFSET); + //fixedToFloat_arr(hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_shb, (Q_bwe_exc_orig), 2 * ALLPASSSECTIONS_STEEP + 1); + //fixedToFloat_arrL(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_csfilt, Q_bwe_exc_orig + Q16, 2); + ////printf(" %f\n", hBWE_TD->mem_csfilt[0]); + //hBWE_TD->tbe_premph = fixedToFloat(hBWE_TD->tbe_premph_fx, Q_bwe_exc_orig); + //hBWE_TD->tbe_demph = fixedToFloat(hBWE_TD->tbe_demph_fx, Q_bwe_exc_orig - NOISE_QADJ); + //hBWE_TD->fb_tbe_demph = fixedToFloat(hBWE_TD->fb_tbe_demph_fx, min(Q_bwe_exc_fb, 31)); + ////n)mem2 + ////st->prev_Q_bwe_syn = Q_bwe_exc; + //fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, st->prev_Q_bwe_syn, 10); + ///* Back up the Q_bwe_exc associated with shaped_shb_excitation for the next frame*/ + ////floatToFixed_arr(hBWE_TD->state_syn_shbexc, hBWE_TD->state_syn_shbexc_fx, (st->prev_Q_bwe_exc), L_SHB_LAHEAD / 4); + ////n_mem3 + //fixedToFloat_arr(hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap, Q_bwe_exc, L_SHB_LAHEAD); + //fixedToFloat_arr(hBWE_TD->fb_state_lpc_syn_fx, hBWE_TD->fb_state_lpc_syn, Q_bwe_exc_fb - 16 - 4, LPC_SHB_ORDER); + ////floatToFixed_arr(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP); + ////floatToFixed_arr(hBWE_TD->int_3_over_2_tbemem_dec, hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + ////floatToFixed_arr(hBWE_TD->mem_resamp_HB_32k, hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + ////floatToFixed_arrL(hBWE_TD->genSHBsynth_Hilbert_Mem, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + //if (nlExc16k && nlExc16k_fx) { + // fixedToFloat_arr(nlExc16k_fx, nlExc16k, Q_bwe_exc, L_FRAME16k); + //} + //if (mixExc16k && mixExc16k_fx) { + // fixedToFloat_arr(mixExc16k_fx, mixExc16k, st->Q_exc, L_FRAME16k); + //} + //hBWE_TD->prev_pow_exc16kWhtnd = fixedToFloat(hBWE_TD->prev_pow_exc16kWhtnd_fx32, 0); + //hBWE_TD->prev_mix_factor = fixedToFloat(hBWE_TD->prev_mix_factor_fx, Q15); + //<---------> + + //mvr2r( error + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth, L_SHB_TRANSITION_LENGTH ); + Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + + /* resample SHB synthesis (if needed) and scale down */ + //synth_scale = ( st->codec_mode == MODE1 ) ? 0.9f : 1.f; + /* resample SHB synthesis (if needed) and scale down */ + synth_scale_fx = 32767; + move16(); /* 1.0 in Q15 */ + IF(EQ_16(st->codec_mode, MODE1)) + { + synth_scale_fx = 29491; + move16(); /* 0.9 in Q15 */ + } + + IF( st->output_Fs == 48000 ) + { + IF( st->extl == FB_TBE ) + { + /*for ( i = 0; i < L_FRAME16k; i++ ) + { + White_exc16k[i] *= GainFrame * GainShape[NUM_SHB_SUBFR * i / L_FRAME16k]; + }*/ + + tmp = norm_l(GainFrame_fx); + IF(GainFrame_fx == 0) + { + tmp = 31; + } + L_tmp = L_shl(GainFrame_fx, tmp);/* 18 + tmp */ + + tmp1 = 0; + FOR(i = 0; i < L_FRAME16k; i++) + { + L_tmp1 = Mult_32_16(L_tmp, GainShape_fx[NUM_SHB_SUBFR * i / L_FRAME16k]); /* Q : 18 + tmp +15 -15*/ + White_exc16k_fx[i] = round_fx(Mult_32_16(L_tmp1, White_exc16k_fx[i]));/* 18 + tmp +*Q_white_exc -15 -16 */ + tmp1 = s_max(tmp1, abs_s(White_exc16k_fx[i])); + } + + *Q_white_exc = sub(add(*Q_white_exc, tmp), 13); /* *Q_white_exc + 18 + tmp -15 -16 */ + tmp = norm_s(tmp1); + IF(tmp1 == 0) + { + tmp = 15; + } + + FOR(i = 0; i < L_FRAME16k; i++) + { + White_exc16k_fx[i] = shl(White_exc16k_fx[i], sub(tmp, 1)); + move16(); + } + *Q_white_exc = sub(add(*Q_white_exc, tmp), 1); + move16(); + } + + //for ( i = 0; i < L_FRAME32k; i++ ) + //{ + // error[i] *= synth_scale; + // //error_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + //} + + IF(NE_16(synth_scale_fx, 32767)) /* 1.0 in Q15 */ + { + FOR(i = 0; i < L_FRAME32k; i++) + { + error_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + move32(); + } + } + //interpolate_3_over_2_allpass( error, L_FRAME32k, synth, hBWE_TD->int_3_over_2_tbemem_dec ); + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( st->output_Fs == 32000 ) + { + //for ( i = 0; i < L_FRAME32k; i++ ) + //{ + // synth[i] = synth_scale * error[i]; + // //synth_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + //} + IF(NE_16(synth_scale_fx, 32767)) /* 1.0 in Q15 */ + { + FOR(i = 0; i < L_FRAME32k; i++) + { + //synth[i] = mult_r(synth_scale_fx, error[i]); + synth_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + move32();/*Qx*/ + } + } + ELSE + { + //Copy(error, synth, L_FRAME32k); + Copy32(error_fx, synth_fx, L_FRAME32k); + } + } + ELSE IF( st->output_Fs == 16000 ) + { + //for ( i = 0; i < L_FRAME32k; i++ ) + //{ + // error[i] *= synth_scale; + // //error_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + //} + IF(NE_16(synth_scale_fx, 32767)) /* 1.0 in Q15 */ + { + FOR(i = 0; i < L_FRAME32k; i++) + { + //error[i] = mult_r(error[i], synth_scale_fx); + error_fx[i] = Mpy_32_16_1(error_fx[i], synth_scale_fx); + move32(); + } + } + + //Decimate_allpass_steep( error, hBWE_TD->mem_resamp_HB_32k, L_FRAME32k, synth ); + Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); + } + + + /* Update previous frame parameters for FEC */ + //mvr2r( lsf_shb, hBWE_TD->lsp_prevfrm, LPC_SHB_ORDER ); + IF( st->codec_mode == MODE1 ) + { + /*hBWE_TD->GainFrame_prevfrm = GainFrame; + hBWE_TD->tilt_swb_fec = tilt_swb_fec; + + if ( !st->bfi ) + { + hBWE_TD->GainAttn = 1.0f; + }*/ + + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move16(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + + IF(!st->bfi) + { + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + } + ELSE + { + //if ( !st->bfi ) + //{ + // hBWE_TD->tilt_swb_fec = tilt_swb_fec; + // hBWE_TD->GainFrame_prevfrm = GainFrame; /* gain locking on lost frame */ + // hBWE_TD->GainAttn = 1.0f; + //} + + IF(!st->bfi) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move16(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + } + + /*hBWE_TD->prev_ener = ener_tmp[NUM_SHB_SUBGAINS - 1]; + hBWE_TD->prev_GainShape = GainShape[NUM_SHB_SUBFR - 1];*/ + + hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; + hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; + st->prev_Q_bwe_syn2 = Q_bwe_exc; + move16(); + st->prev_Qx = Q_bwe_exc; + move16(); + + //local fix2float + /*if (*Q_white_exc > 31) { + Scale_sig(tmp_buffer, L_FRAME48k, 31 - *Q_white_exc); + } + fixedToFloat_arr(shaped_shb_excitation_fx, shaped_shb_excitation, Q_bwe_exc, L_FRAME16k + L_SHB_LAHEAD); + fixedToFloat_arr(tmp_buffer, White_exc16k, min(*Q_white_exc, 31), L_FRAME48k); + fixedToFloat_arrL(synth_fx, synth, Q11, L_FRAME48k);*/ + + return; +} + + +void ivas_swb_tbe_dec_float2fix(Decoder_State *st, STEREO_ICBWE_DEC_HANDLE hStereoICBWE) { + TD_BWE_DEC_HANDLE hBWE_TD = st->hBWE_TD; + // st->hBWE_TD->tilt_swb_fec_fx = float_to_fix16(st->hBWE_TD->tilt_swb_fec, Q11); + floatToFixed_arr( &st->hBWE_TD->prev_tilt_para, &st->hBWE_TD->prev_tilt_para_fx, Q10, 1 ); + floatToFixed_arr( &st->hBWE_TD->tilt_swb_fec, &st->hBWE_TD->tilt_swb_fec_fx, Q11, 1 ); + // st->tilt_wb_fx = float_to_fix16(st->tilt_wb, Q11); + floatToFixed_arr( &st->tilt_wb, &st->tilt_wb_fx, Q11, 1 ); + // st->hBWE_TD->tilt_mem_fx = float_to_fix16(st->hBWE_TD->tilt_mem, Q12); + floatToFixed_arr( &st->hBWE_TD->tilt_mem, &st->hBWE_TD->tilt_mem_fx, Q12, 1 ); + // st->tilt_swb_fx = float_to_fix16(st->tilt_swb, Q11); + floatToFixed_arr( &st->tilt_swb, &st->tilt_swb_fx, Q11, 1 ); + + st->hBWE_TD->prev_GainShape_fx = float_to_fix16( st->hBWE_TD->prev_GainShape, Q15 ); + st->hBWE_TD->GainFrame_prevfrm_fx = floatToFixed( st->hBWE_TD->GainFrame_prevfrm, Q18 ); + st->hBWE_TD->gain_prec_swb_fx = float_to_fix16( st->hBWE_TD->gain_prec_swb, Q14 ); + /*for (int idx = 0; idx < LPC_SHB_ORDER; idx++) + { + st->hBWE_TD->lsp_prevfrm_fx[idx] = st->hBWE_TD->lsp_prevfrm[idx] * (1 << 15); + st->hBWE_TD->swb_lsp_prev_interp_fx[idx] = st->hBWE_TD->swb_lsp_prev_interp[idx] * (1 << 15); + }*/ + floatToFixed_arr( st->hBWE_TD->lsp_prevfrm, st->hBWE_TD->lsp_prevfrm_fx, Q15, LPC_SHB_ORDER ); + floatToFixed_arr( st->hBWE_TD->swb_lsp_prev_interp, st->hBWE_TD->swb_lsp_prev_interp_fx, Q15, LPC_SHB_ORDER ); + /*for (int idx = 0; idx < LPC_SHB_ORDER - 2; idx++) + { + st->hBWE_TD->prev_lsf_diff_fx[idx] = st->hBWE_TD->prev_lsf_diff[idx] * (1 << 15); + }*/ + floatToFixed_arr( st->hBWE_TD->prev_lsf_diff, st->hBWE_TD->prev_lsf_diff_fx, Q15, LPC_SHB_ORDER - 2 ); + + /*for (int idx = 0; idx < LPC_SHB_ORDER; idx++) + { + st->hBWE_TD->GainShape_Delay_fx[idx] = st->hBWE_TD->GainShape_Delay[idx] * (1 << 15); + }*/ + floatToFixed_arr( st->hBWE_TD->GainShape_Delay, st->hBWE_TD->GainShape_Delay_fx, Q15, NUM_SHB_SUBFR / 2 ); + /*for (int idx = 0; idx < M + 1; idx++) + { + st->hBWE_TD->cur_sub_Aq_fx[idx] = st->hBWE_TD->cur_sub_Aq[idx] * (1 << 15); + }*/ + floatToFixed_arr( st->hBWE_TD->cur_sub_Aq, st->hBWE_TD->cur_sub_Aq_fx, Q12, M + 1 ); + + st->hBWE_TD->GainAttn_fx = float_to_fix16(st->hBWE_TD->GainAttn, Q15); + st->hBWE_TD->prev1_shb_ener_sf_fx = floatToFixed( st->hBWE_TD->prev1_shb_ener_sf, 0 ); // recheck + st->hBWE_TD->prev2_shb_ener_sf_fx = floatToFixed( st->hBWE_TD->prev2_shb_ener_sf, 0 ); // recheck + st->hBWE_TD->prev3_shb_ener_sf_fx = floatToFixed( st->hBWE_TD->prev3_shb_ener_sf, 0 ); // recheck + st->hBWE_TD->prev_res_shb_gshape_fx = float_to_fix16( st->hBWE_TD->prev_res_shb_gshape, Q14 ); // recheck + st->hBWE_TD->prev_mixFactors_fx = float_to_fix16( st->hBWE_TD->prev_mixFactors, Q15 ); // recheck + st->cummulative_damping = float_to_fix16( st->cummulative_damping_float, Q15 ); + if ( st->hTdCngDec != NULL ) + { + /*for (int idx = 0; idx < LPC_SHB_ORDER; idx++) + { + st->hTdCngDec->lsp_shb_prev_prev_fx[idx] = st->hTdCngDec->lsp_shb_prev_prev[idx] * (1 << 15); + st->hTdCngDec->lsp_shb_prev_fx[idx] = st->hTdCngDec->lsp_shb_prev[idx] * (1 << 15); + }*/ + floatToFixed_arr( st->hTdCngDec->lsp_shb_prev_prev, st->hTdCngDec->lsp_shb_prev_prev_fx, Q15, LPC_SHB_ORDER ); + floatToFixed_arr( st->hTdCngDec->lsp_shb_prev, st->hTdCngDec->lsp_shb_prev_fx, Q15, LPC_SHB_ORDER ); + } + + //check this value + st->enerLH_fx = floatToFixed(st->enerLH, 0); + st->prev_enerLH_fx = floatToFixed(st->prev_enerLH, 0); + st->prev_ener_shb_fx = float_to_fix16(st->prev_ener_shb, 1); + + //n_mem + //st->prev_Q_bwe_exc = 5; + st->prev_Q_bwe_exc = min(st->prev_Q_bwe_exc, 24); // to be checked? + floatToFixed_arr(hBWE_TD->old_bwe_exc_extended, hBWE_TD->old_bwe_exc_extended_fx, st->prev_Q_bwe_exc - 16, NL_BUFF_OFFSET); + floatToFixed_arr(hBWE_TD->mem_genSHBexc_filt_down_shb, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->prev_Q_bwe_exc - 16, 2 * ALLPASSSECTIONS_STEEP + 1); + floatToFixed_arr(hBWE_TD->mem_stp_swb, hBWE_TD->mem_stp_swb_fx, st->prev_Q_bwe_exc - 16, LPC_SHB_ORDER); + floatToFixed_arr(hBWE_TD->mem_zero_swb, hBWE_TD->mem_zero_swb_fx, st->prev_Q_bwe_exc - 16, LPC_SHB_ORDER); + floatToFixed_arrL(hBWE_TD->mem_csfilt, hBWE_TD->mem_csfilt_fx, st->prev_Q_bwe_exc, 2); + //hBWE_TD->tbe_premph_fx = float_to_fix16(hBWE_TD->tbe_premph, Q_bwe_exc); + hBWE_TD->tbe_premph_fx = (Word16)check_bounds_l(floatToFixed(hBWE_TD->tbe_premph, st->prev_Q_bwe_exc - 16), -32768, 32767); + //hBWE_TD->tbe_demph_fx = float_to_fix16(hBWE_TD->tbe_demph, 0); + hBWE_TD->tbe_demph_fx = (Word16)check_bounds_l(floatToFixed(hBWE_TD->tbe_demph, st->prev_Q_bwe_exc - 16 - NOISE_QADJ), -32768, 32767); + hBWE_TD->fb_tbe_demph_fx = (Word16)check_bounds_l(floatToFixed(hBWE_TD->fb_tbe_demph, st->prev_Q_bwe_exc_fb), -32768, 32767); + //n)mem2 + floatToFixed_arr(st->hBWE_TD->state_lpc_syn, st->hBWE_TD->state_lpc_syn_fx, st->prev_Q_bwe_syn, 10); + floatToFixed_arr(hBWE_TD->state_syn_shbexc, hBWE_TD->state_syn_shbexc_fx, st->prev_Q_bwe_syn, L_SHB_LAHEAD); + //n_mem3 + floatToFixed_arr(hBWE_TD->syn_overlap, hBWE_TD->syn_overlap_fx, st->prev_Q_bwe_syn2, L_SHB_LAHEAD); + floatToFixed_arr(hBWE_TD->fb_state_lpc_syn, hBWE_TD->fb_state_lpc_syn_fx, st->prev_Q_bwe_exc_fb - 16 - 4, LPC_SHB_ORDER); + floatToFixed_arr(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP); + floatToFixed_arr(hBWE_TD->int_3_over_2_tbemem_dec, hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + floatToFixed_arr(hBWE_TD->mem_resamp_HB_32k, hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + //floatToFixed_arrL(hBWE_TD->genSHBsynth_Hilbert_Mem, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, Q11, HILBERT_MEM_SIZE); + if (hStereoICBWE != NULL) { + if (hStereoICBWE->nlExc16k && hStereoICBWE->nlExc16k_fx) { + floatToFixed_arr(hStereoICBWE->nlExc16k, hStereoICBWE->nlExc16k_fx, st->prev_Q_bwe_exc - 16, L_FRAME16k); + } + if (hStereoICBWE->mixExc16k && hStereoICBWE->mixExc16k_fx) { + floatToFixed_arr(hStereoICBWE->mixExc16k, hStereoICBWE->mixExc16k_fx, st->Q_exc, L_FRAME16k); + } + floatToFixed_arrL(hStereoICBWE->lpSHBRef, hStereoICBWE->lpSHBRef_fx, Q12, LPC_SHB_ORDER + 1); + floatToFixed_arr(hStereoICBWE->gshapeRef, hStereoICBWE->gshapeRef_fx, Q15, NUM_SHB_SUBFR); + floatToFixed_arrL(&hStereoICBWE->gFrameRef, &hStereoICBWE->gFrameRef_fx, Q18, 1); + floatToFixed_arr(hStereoICBWE->shbSynthRef, hStereoICBWE->shbSynthRef_fx, st->prev_Qx, L_FRAME16k); + + } + //floatToFixed_arrL(hBWE_TD->mem_csfilt, hBWE_TD->mem_csfilt_fx, st->prev_Q_bwe_exc, 2); + hBWE_TD->prev_pow_exc16kWhtnd_fx32 = floatToFixed(hBWE_TD->prev_pow_exc16kWhtnd, 0); + hBWE_TD->prev_mix_factor_fx = float_to_fix16(hBWE_TD->prev_mix_factor, Q15); + +#if 1 + //starting from here + + for (int i = 0; i < INTERP_3_2_MEM_LEN; i++) + { + st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i] = floatToFixed(st->hBWE_TD->int_3_over_2_tbemem_dec[i], Q11); + } + for (int i = 0; i < HILBERT_MEM_SIZE; i++) + { + st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = floatToFixed(st->hBWE_TD->genSHBsynth_Hilbert_Mem[i], Q11); + } + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) + { + st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] = floatToFixed(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i], Q11); + } + + for (int i = 0; i < L_SHB_TRANSITION_LENGTH; i++) + { + st->hBWE_TD->old_tbe_synth_fx_32[i] = floatToFixed( hBWE_TD->old_tbe_synth[i], Q11); + } + + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++) + { + st->hBWE_TD->mem_resamp_HB_32k_fx_32[i] = floatToFixed(st->hBWE_TD->mem_resamp_HB_32k[i], Q11); + } + + //move up +#endif +} + +void ivas_swb_tbe_dec_fix2float (Decoder_State *st, STEREO_ICBWE_DEC_HANDLE hStereoICBWE/*, Word16 Q_bwe_exc_orig*/) { + + TD_BWE_DEC_HANDLE hBWE_TD = st->hBWE_TD; + + fixedToFloat_arr(&st->hBWE_TD->prev_tilt_para_fx, &st->hBWE_TD->prev_tilt_para, Q10, 1); + fixedToFloat_arr(&st->hBWE_TD->tilt_swb_fec_fx, &st->hBWE_TD->tilt_swb_fec, Q11, 1); + fixedToFloat_arr(&st->tilt_wb_fx, &st->tilt_wb, Q11, 1); + fixedToFloat_arr(&st->hBWE_TD->tilt_mem_fx, &st->hBWE_TD->tilt_mem, Q12, 1); + fixedToFloat_arr(&st->tilt_swb_fx, &st->tilt_swb, Q11, 1); + + st->hBWE_TD->prev_GainShape = fixedToFloat(st->hBWE_TD->prev_GainShape_fx, Q15); + st->hBWE_TD->GainFrame_prevfrm = fixedToFloat(st->hBWE_TD->GainFrame_prevfrm_fx, Q18); + st->hBWE_TD->gain_prec_swb = fixedToFloat(st->hBWE_TD->gain_prec_swb_fx, Q14); + fixedToFloat_arr(st->hBWE_TD->lsp_prevfrm_fx, st->hBWE_TD->lsp_prevfrm, Q15, LPC_SHB_ORDER); + fixedToFloat_arr(st->hBWE_TD->swb_lsp_prev_interp_fx, st->hBWE_TD->swb_lsp_prev_interp, Q15, LPC_SHB_ORDER); + fixedToFloat_arr(st->hBWE_TD->prev_lsf_diff_fx, st->hBWE_TD->prev_lsf_diff, Q15, LPC_SHB_ORDER - 2); + fixedToFloat_arr(st->hBWE_TD->GainShape_Delay_fx, st->hBWE_TD->GainShape_Delay, Q15, NUM_SHB_SUBFR / 2); + fixedToFloat_arr(st->hBWE_TD->cur_sub_Aq_fx, st->hBWE_TD->cur_sub_Aq, Q12, M + 1); + st->hBWE_TD->GainAttn = fixedToFloat(st->hBWE_TD->GainAttn_fx, Q15); + st->hBWE_TD->prev1_shb_ener_sf = fixedToFloat(st->hBWE_TD->prev1_shb_ener_sf_fx, 0); // recheck + st->hBWE_TD->prev2_shb_ener_sf = fixedToFloat(st->hBWE_TD->prev2_shb_ener_sf_fx, 0); // recheck + st->hBWE_TD->prev3_shb_ener_sf = fixedToFloat(st->hBWE_TD->prev3_shb_ener_sf_fx, 0); // recheck + st->hBWE_TD->prev_res_shb_gshape = fixedToFloat(st->hBWE_TD->prev_res_shb_gshape_fx, Q14); // recheck + st->hBWE_TD->prev_mixFactors = fixedToFloat(st->hBWE_TD->prev_mixFactors_fx, Q15); // recheck + st->cummulative_damping_float = fixedToFloat(st->cummulative_damping, Q15); + if (st->hTdCngDec != NULL) + { + fixedToFloat_arr(st->hTdCngDec->lsp_shb_prev_prev_fx, st->hTdCngDec->lsp_shb_prev_prev, Q15, LPC_SHB_ORDER); + fixedToFloat_arr(st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev, Q15, LPC_SHB_ORDER); + } + //check this value + st->enerLH = fixedToFloat(st->enerLH_fx, 0); + st->prev_enerLH = fixedToFloat(st->prev_enerLH_fx, 0); + st->prev_ener_shb = fixedToFloat(st->prev_ener_shb_fx, 1); + //n_mem + //st->prev_Q_bwe_exc = 9; + fixedToFloat_arr(hBWE_TD->old_bwe_exc_extended_fx, hBWE_TD->old_bwe_exc_extended, st->prev_Q_bwe_exc - 16, NL_BUFF_OFFSET); + fixedToFloat_arr(hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_shb, st->prev_Q_bwe_exc - 16, 2 * ALLPASSSECTIONS_STEEP + 1); + fixedToFloat_arr(hBWE_TD->mem_stp_swb_fx, hBWE_TD->mem_stp_swb, st->prev_Q_bwe_exc - 16, LPC_SHB_ORDER); + fixedToFloat_arr(hBWE_TD->mem_zero_swb_fx, hBWE_TD->mem_zero_swb, st->prev_Q_bwe_exc - 16, LPC_SHB_ORDER); + fixedToFloat_arrL(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_csfilt, st->prev_Q_bwe_exc, 2); + //printf(" %f\n", hBWE_TD->mem_csfilt[0]); + hBWE_TD->tbe_premph = fixedToFloat(hBWE_TD->tbe_premph_fx, st->prev_Q_bwe_exc - 16); + hBWE_TD->tbe_demph = fixedToFloat(hBWE_TD->tbe_demph_fx, st->prev_Q_bwe_exc - 16 - NOISE_QADJ); + if (st->prev_Q_bwe_exc_fb != 51) { + if (st->prev_Q_bwe_exc_fb > 31) { + Scale_sig(&hBWE_TD->fb_tbe_demph_fx, 1, 31 - st->prev_Q_bwe_exc_fb); + } + hBWE_TD->fb_tbe_demph = fixedToFloat(hBWE_TD->fb_tbe_demph_fx, min(st->prev_Q_bwe_exc_fb, 31)); + fixedToFloat_arr(hBWE_TD->fb_state_lpc_syn_fx, hBWE_TD->fb_state_lpc_syn, st->prev_Q_bwe_exc_fb - 16 - 4, LPC_SHB_ORDER); + } + else { + hBWE_TD->fb_tbe_demph = 0; + set_f(hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER); + } + //n)mem2 + //st->prev_Q_bwe_syn = Q_bwe_exc; + fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, st->prev_Q_bwe_syn, 10); + /* Back up the Q_bwe_exc associated with shaped_shb_excitation for the next frame*/ + fixedToFloat_arr(hBWE_TD->state_syn_shbexc_fx, hBWE_TD->state_syn_shbexc, (st->prev_Q_bwe_syn), L_SHB_LAHEAD); + //n_mem3 + fixedToFloat_arr(hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap, st->prev_Q_bwe_syn2, L_SHB_LAHEAD); + fixedToFloat_arr(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, 0, 2 * ALLPASSSECTIONS_STEEP); + fixedToFloat_arr(hBWE_TD->int_3_over_2_tbemem_dec_fx, hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN); + fixedToFloat_arr(hBWE_TD->mem_resamp_HB_32k_fx, hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + //fixedToFloat_arrL(hBWE_TD->genSHBsynth_Hilbert_Mem, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, Q11, HILBERT_MEM_SIZE); + if (hStereoICBWE != NULL) { + if (hStereoICBWE->nlExc16k && hStereoICBWE->nlExc16k_fx) { + fixedToFloat_arr(hStereoICBWE->nlExc16k_fx, hStereoICBWE->nlExc16k, st->prev_Q_bwe_exc - 16, L_FRAME16k); + } + if (hStereoICBWE->mixExc16k && hStereoICBWE->mixExc16k_fx) { + fixedToFloat_arr(hStereoICBWE->mixExc16k_fx, hStereoICBWE->mixExc16k, st->Q_exc, L_FRAME16k); + } + fixedToFloat_arrL(hStereoICBWE->lpSHBRef_fx, hStereoICBWE->lpSHBRef, Q12, LPC_SHB_ORDER + 1); + fixedToFloat_arr(hStereoICBWE->gshapeRef_fx, hStereoICBWE->gshapeRef, Q15, NUM_SHB_SUBFR); + fixedToFloat_arrL(&hStereoICBWE->gFrameRef_fx, &hStereoICBWE->gFrameRef, Q18, 1); + fixedToFloat_arr(hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef, st->prev_Qx, L_FRAME16k); + } + hBWE_TD->prev_pow_exc16kWhtnd = fixedToFloat(hBWE_TD->prev_pow_exc16kWhtnd_fx32, 0); + hBWE_TD->prev_mix_factor = fixedToFloat(hBWE_TD->prev_mix_factor_fx, Q15); + + for (int i = 0; i < INTERP_3_2_MEM_LEN; i++) + { + st->hBWE_TD->int_3_over_2_tbemem_dec[i] = fixedToFloat(st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i], Q11); + } + for (int i = 0; i < HILBERT_MEM_SIZE; i++) + { + st->hBWE_TD->genSHBsynth_Hilbert_Mem[i] = fixedToFloat(st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], Q11); + } + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) + { + st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i] = fixedToFloat(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i], Q11); + } + for (int i = 0; i < L_SHB_TRANSITION_LENGTH; i++) + { + st->hBWE_TD->old_tbe_synth[i] = fixedToFloat(hBWE_TD->old_tbe_synth_fx_32[i], Q11); + } + + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++) + { + st->hBWE_TD->mem_resamp_HB_32k[i] = fixedToFloat(st->hBWE_TD->mem_resamp_HB_32k_fx_32[i], Q11); + } + //<---------> + //printf("\nst->prev_ener_shb: %f ", st->prev_ener_shb); + //printf("\nhBWE_TD->tbe_demph: %f ", hBWE_TD->tbe_demph); +} +#endif + /*-------------------------------------------------------------------* * swb_tbe_dec() * diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index e15203cab..77c4ef1b3 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -24,9 +24,7 @@ static void dequantizeSHBparams_fx_9_1( Decoder_State* st_fx, const Word16 extl, Word32 extl_brate, Word16* Q_lsf, Word16* Q_subgain, Word32* Q_framegrain, Word16* uv_flag, Word32* Q_shb_ener_sf_32, Word16* Q_shb_res_gshape, Word16* Q_mixFactors); -#ifdef IVAS_FLOAT_FIXED -static void ivas_dequantizeSHBparams_fx_9_1( Decoder_State *st_fx, const Word16 extl, Word32 extl_brate, Word16 *Q_lsf, Word16 *Q_subgain, Word32 *Q_framegrain, Word16 *uv_flag, Word32 *Q_shb_ener_sf_32, Word16 *Q_shb_res_gshape, Word16 *Q_mixFactors ); -#endif + static void find_max_mem_dec( Decoder_State* st_fx, Word16* n_mem, Word16 *n_mem2, Word16 *n_mem3 ); static void rescale_genSHB_mem_dec( Decoder_State* st_fx, Word16 sf ); static void find_max_mem_wb( Decoder_State* st_fx, Word16* n_mem ); @@ -678,7 +676,8 @@ void ivas_wb_tbe_dec_fx( ELSE { /* de-quantization */ - ivas_dequantizeSHBparams_fx_9_1( st_fx, st_fx->extl, st_fx->extl_brate, lsf_wb, GainShape, &GainFrame, &uv_flag, 0, 0, 0 ); + Word16 ignore; + ivas_dequantizeSHBparams_fx_9_1( st_fx, st_fx->extl, st_fx->extl_brate, lsf_wb, GainShape, &GainFrame, &uv_flag, 0, 0, 0, &ignore ); } } ELSE @@ -3680,32 +3679,27 @@ static void Dequant_mirror_point_fx( return; } +Word16 dotp_loc( + const Word16 x[], /* i : vector x[] */ + const Word32 y[], /* i : vector y[] */ + const int16_t n /* i : vector length */ +) +{ + Word16 i; + Word32 suma; + Word16 guarded_bits = find_guarded_bits_fx(n); + suma = L_shr(Mpy_32_16_1(y[0], x[0]), guarded_bits); + FOR(i = 1; i < n; i++) + { + suma = L_add(suma, L_shr(Mpy_32_16_1(y[i], x[i]), guarded_bits)); + } + suma = L_shl_sat(suma, guarded_bits); -/*==========================================================================*/ -/* FUNCTION : static void dequantizeSHBparams_fx_9_1 () */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Dequantize super highband spectral envolope */ -/* temporal gains and frame gain */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _Word16 extl i : extension layer */ -/* _Word32 extl_brate i : extensiuon layer bitrate */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _Word16 *Q_lsf, o : SHB LSF from de-quantization Q15 */ -/* _Word16 *Q_subgain, o : SHB subframe gains from de-quantization Q15*/ -/* _Word32 *Q_framegrain o : SHB frame gain from de-quantization Q18 */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==========================================================================*/ -#ifdef IVAS_FLOAT_FIXED -static void ivas_dequantizeSHBparams_fx_9_1( + return extract_h(suma); +} + +void ivas_dequantizeSHBparams_fx_9_1( Decoder_State *st_fx, const Word16 extl, /* i : extension layer */ Word32 extl_brate, /* i : extensiuon layer bitrate */ @@ -3715,8 +3709,8 @@ static void ivas_dequantizeSHBparams_fx_9_1( Word16 *uv_flag, /* o : unvoiced flag*/ Word32 *Q_shb_ener_sf, /* o : Q15 */ Word16 *Q_shb_res_gshape, /* o : Q14 */ - Word16 *Q_mixFactors /* o : Q15 */ -) + Word16 *Q_mixFactors, /* o : Q15 */ + Word16 *MSFlag) { Word16 i, j, idxLSF, idxSubGain, idxFrameGain; Word16 Q_combined_gains[NUM_SHB_SUBFR / 4]; @@ -3729,54 +3723,62 @@ static void ivas_dequantizeSHBparams_fx_9_1( Word16 idx_shb_fr_gain, idx_res_gs[5], idx_mixFac; Word16 temp_shb_ener_sf_fx; TD_BWE_DEC_HANDLE hBWE_TD; + + UWord32 Idx_lvq; + Word16 Idx, Idx_pred; + Word16 num_bits_lvq; + Word16 out[LATTICE_DIM]; + const Word16 *cb_stage; + Word16 predictor_bits; + Word16 nbits = NUM_BITS_SHB_MSLVQ; hBWE_TD = st_fx->hBWE_TD; /* LSFs */ - IF( EQ_16( extl, WB_TBE ) ) + IF(EQ_16(extl, WB_TBE)) { - IF( EQ_32( extl_brate, WB_TBE_0k35 ) ) + IF(EQ_32(extl_brate, WB_TBE_0k35)) { - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + IF(EQ_16(st_fx->codec_mode, MODE2)) { - idxFrameGain = hBWE_TD->gFrame_WB_fx; - idxLSF = hBWE_TD->lsf_WB_fx; + idxFrameGain = hBWE_TD->gFrame_WB; + idxLSF = hBWE_TD->lsf_WB; } ELSE { - idxFrameGain = get_next_indice( st_fx, NUM_BITS_SHB_FrameGain_LBR_WB ); - idxLSF = get_next_indice( st_fx, NUM_BITS_LBR_WB_LSF ); + idxFrameGain = get_next_indice(st_fx, NUM_BITS_SHB_FrameGain_LBR_WB); + idxLSF = get_next_indice(st_fx, NUM_BITS_LBR_WB_LSF); } - Copy( lbr_wb_bwe_lsfvq_cbook_2bit_fx + idxLSF * LPC_SHB_ORDER_LBR_WB, Q_lsf, LPC_SHB_ORDER_LBR_WB ); - set16_fx( Q_subgain, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2 ); - Copy32( SHBCB_FrameGain16_fx + idxFrameGain, Q_framegrain, 1 ); + Copy(lbr_wb_bwe_lsfvq_cbook_2bit_fx + idxLSF * LPC_SHB_ORDER_LBR_WB, Q_lsf, LPC_SHB_ORDER_LBR_WB); + set16_fx(Q_subgain, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2); + Copy32(SHBCB_FrameGain16_fx + idxFrameGain, Q_framegrain, 1); } ELSE { - *uv_flag = (Word16) get_next_indice( st_fx, 1 ); - idxSubGain = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_SUBGAINS ); + *uv_flag = (Word16)get_next_indice(st_fx, 1); + idxSubGain = (Word16)get_next_indice(st_fx, NUM_BITS_SHB_SUBGAINS); move16(); - idxFrameGain = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_FrameGain ); + idxFrameGain = (Word16)get_next_indice(st_fx, NUM_BITS_SHB_FrameGain); move16(); - idxLSF = (Word16) get_next_indice( st_fx, NUM_BITS_WB_LSF ); + idxLSF = (Word16)get_next_indice(st_fx, NUM_BITS_WB_LSF); move16(); - Copy( wb_bwe_lsfvq_cbook_8bit_fx + idxLSF * LPC_SHB_ORDER_WB, Q_lsf, LPC_SHB_ORDER_WB ); - Copy( HBCB_SubGain5bit_fx + idxSubGain * NUM_SHB_SUBFR / 4, Q_combined_gains, NUM_SHB_SUBFR / 4 ); + Copy(wb_bwe_lsfvq_cbook_8bit_fx + idxLSF * LPC_SHB_ORDER_WB, Q_lsf, LPC_SHB_ORDER_WB); + Copy(HBCB_SubGain5bit_fx + idxSubGain * NUM_SHB_SUBFR / 4, Q_combined_gains, NUM_SHB_SUBFR / 4); - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + FOR(i = 0; i < NUM_SHB_SUBFR / 4; i++) { - L_tmp = L_mult( Q_combined_gains[i], 21771 ); /*Q26 0.166096 in Q17 */ - L_tmp = L_shr( L_tmp, 10 ); - frac = L_Extract_lc( L_tmp, &exp ); - tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + L_tmp = L_mult(Q_combined_gains[i], 21771); /*Q26 0.166096 in Q17 */ + L_tmp = L_shr(L_tmp, 10); + frac = L_Extract_lc(L_tmp, &exp); + tmp = extract_l(Pow2(14, frac)); /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ - Q_combined_gains[i] = shl( tmp, add( exp, 1 ) ); /* Q15 */ + Q_combined_gains[i] = shl(tmp, add(exp, 1)); /* Q15 */ } - FOR( i = 0; i < NUM_SHB_SUBFR / 2; i += 2 ) + FOR(i = 0; i < NUM_SHB_SUBFR / 2; i += 2) { Q_subgain[i] = Q_combined_gains[i / 2]; // Q15 move16(); @@ -3785,210 +3787,335 @@ static void ivas_dequantizeSHBparams_fx_9_1( } /* frame gain */ - Copy32( SHBCB_FrameGain64_fx + idxFrameGain, Q_framegrain, 1 ); + Copy32(SHBCB_FrameGain64_fx + idxFrameGain, Q_framegrain, 1); } } ELSE /* SWB TBE DEC */ { - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + IF(EQ_16(st_fx->codec_mode, MODE2)) { - idxSubGain = hBWE_TD->idxSubGains_fx; - idxFrameGain = hBWE_TD->idxFrameGain_fx; + idxSubGain = hBWE_TD->idxSubGains; + idxFrameGain = hBWE_TD->idxFrameGain; } ELSE { - idxSubGain = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_SUBGAINS ); - idxFrameGain = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_FRAMEGAIN ); + idxSubGain = (Word16)get_next_indice(st_fx, NUM_BITS_SHB_SUBGAINS); + IF( st_fx->extl_brate == SWB_TBE_1k75 ) + { + idxFrameGain = get_next_indice( st_fx, NUM_BITS_SHB_FRAMEGAIN_1k75 ); + } + ELSE + { + idxFrameGain = get_next_indice( st_fx, NUM_BITS_SHB_FRAMEGAIN ); + } } - test(); - IF( EQ_32( st_fx->total_brate, ACELP_24k40 ) || EQ_32( st_fx->total_brate, ACELP_32k ) ) - { - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + /* Multi Source Flag */ + IF(st_fx->element_mode >= IVAS_CPE_DFT && !(st_fx->element_mode == IVAS_CPE_TD && st_fx->tdm_LRTD_flag)) { - idx_shb_fr_gain = hBWE_TD->idx_shb_fr_gain_fx; + *MSFlag = get_next_indice(st_fx, STEREO_ICBWE_MSFLAG_BITS); } ELSE { - idx_shb_fr_gain = get_next_indice( st_fx, NUM_BITS_SHB_ENER_SF ); + *MSFlag = 0; } - temp_shb_ener_sf_fx = usdequant_fx( idx_shb_fr_gain, 0, 86 ); /* 86 = 0.042f in Q11 = Qin-1 */ - /* o: temp_shb_ener_sf_fx in Q12 */ - - /* *Q_shb_ener_sf = Pow(10.0, temp_shb_ener_sf_fx ); */ - /* = pow(2, 3.321928*temp_shb_ener_sf_fx) */ - L_tmp = L_mult( temp_shb_ener_sf_fx, 27213 ); /* 3.321928 in Q13 -> L_tmp in Q12+Q13+1 = Q26 */ - L_tmp = L_shl( L_tmp, -10 ); /* bring L_tmp from Q26 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent */ - L_tmp = Pow2( 14, frac ); - *Q_shb_ener_sf = L_shl( L_tmp, exp - 14 + 0 ); /* In Q_ener: 2*Q_shb+1, Q_shb = 0; */ - - FOR( i = 0; i < 5; i++ ) + test(); + IF(st_fx->extl_brate >= SWB_TBE_2k8) { - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + IF(EQ_16(st_fx->codec_mode, MODE2)) { - idx_res_gs[i] = hBWE_TD->idx_res_gs_fx[i]; - move16(); + idx_shb_fr_gain = hBWE_TD->idx_shb_fr_gain; } ELSE { - idx_res_gs[i] = get_next_indice( st_fx, NUM_BITS_SHB_RES_GS ); + idx_shb_fr_gain = get_next_indice(st_fx, NUM_BITS_SHB_ENER_SF); + } + temp_shb_ener_sf_fx = usdequant_fx(idx_shb_fr_gain, 0, 86); /* 86 = 0.042f in Q11 = Qin-1 */ + /* o: temp_shb_ener_sf_fx in Q12 */ + + /* *Q_shb_ener_sf = Pow(10.0, temp_shb_ener_sf_fx ); */ + /* = pow(2, 3.321928*temp_shb_ener_sf_fx) */ + L_tmp = L_mult(temp_shb_ener_sf_fx, 27213); /* 3.321928 in Q13 -> L_tmp in Q12+Q13+1 = Q26 */ + L_tmp = L_shl(L_tmp, -10); /* bring L_tmp from Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent */ + L_tmp = Pow2(14, frac); + *Q_shb_ener_sf = L_shl(L_tmp, exp - 14 + 0); /* In Q_ener: 2*Q_shb+1, Q_shb = 0; */ + + FOR(i = 0; i < 5; i++) + { + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + idx_res_gs[i] = hBWE_TD->idx_res_gs_fx[i]; + move16(); + } + ELSE + { + idx_res_gs[i] = get_next_indice(st_fx, NUM_BITS_SHB_RES_GS); + move16(); + } + Q_shb_res_gshape[i] = usdequant_fx(idx_res_gs[i], + 2048 /*0.125f Q14*/, /*2048 = 0.125 in Q14 */ + 1024 /*0.125f Q13*/ /*1024 = 0.125 in Q13 */ + ); move16(); + /* o: Q_shb_res_gshape in Q14 */ } - Q_shb_res_gshape[i] = usdequant_fx( idx_res_gs[i], - 2048 /*0.125f Q14*/, /*2048 = 0.125 in Q14 */ - 1024 /*0.125f Q13*/ /*1024 = 0.125 in Q13 */ - ); - move16(); - /* o: Q_shb_res_gshape in Q14 */ - } - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) - { - idx_mixFac = hBWE_TD->idx_mixFac_fx; + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + idx_mixFac = hBWE_TD->idx_mixFac; + move16(); + } + ELSE + { + idx_mixFac = (Word16)get_next_indice(st_fx, NUM_BITS_SHB_VF); + } + *Q_mixFactors = usdequant_fx(idx_mixFac, 4096 /* 0.125 in Q15 */, 2048 /* 0.125 in Q14 */); move16(); + /* o: Q_mixFactors in Q15 */ } ELSE { - idx_mixFac = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_VF ); + *Q_shb_ener_sf = L_deposit_l(0); + IF( st_fx->extl_brate == SWB_TBE_1k10 || st_fx->extl_brate == SWB_TBE_1k75 ) + { + idx_mixFac = get_next_indice(st_fx, NUM_BITS_SHB_VF); + *Q_mixFactors = usdequant_fx(idx_mixFac, 0 /* 0.0f in Q15*/, 2341 /*1.0f / ((1 << NUM_BITS_SHB_VF) - 1) in Q14*/); + } + ELSE + { + *Q_mixFactors = 0; + } + //*Q_mixFactors = 0; + move16(); + set16_fx(Q_shb_res_gshape, 0, 5); } - *Q_mixFactors = usdequant_fx( idx_mixFac, 4096 /* 0.125 in Q15 */, 2048 /* 0.125 in Q14 */ ); - move16(); - /* o: Q_mixFactors in Q15 */ - } - ELSE - { - *Q_shb_ener_sf = L_deposit_l( 0 ); - *Q_mixFactors = 0; - move16(); - set16_fx( Q_shb_res_gshape, 0, 5 ); - } - /* LSFs */ + /* LSFs */ - test(); - test(); - test(); - test(); - test(); - IF( ( st_fx->rf_flag == 0 ) && !( ( EQ_32( st_fx->total_brate, ACELP_9k60 ) ) || ( ( st_fx->total_brate == 0 ) && ( ( EQ_32( st_fx->last_total_brate, ACELP_9k60 ) ) || ( EQ_32( st_fx->last_total_brate, ACELP_13k20 ) && EQ_16( st_fx->rf_flag_last, 1 ) ) ) ) ) ) - - { - /* LSFs */ - test(); - test(); - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k6 ) || EQ_32( extl_brate, FB_TBE_1k8 ) || EQ_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, FB_TBE_3k0 ) ) - { - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + test(); + test(); + test(); + test(); + test(); + IF((st_fx->extl_brate == SWB_TBE_0k95 || st_fx->extl_brate == SWB_TBE_1k10) && st_fx->codec_mode == MODE1) { - FOR( i = 0; i < NUM_Q_LSF; i++ ) - { - lsf_idx[i] = hBWE_TD->lsf_idx_fx[i]; - move16(); - } + set16_fx(lsf_idx, 0, 5); + lsf_idx[0] = get_next_indice(st_fx, 8); + grid_idx = 0; + m_idx = 0; + + Copy(swb_tbe_lsfvq_cbook_8b + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER); } - ELSE + ELSE IF(st_fx->rf_flag == 0 && !((st_fx->element_mode == EVS_MONO && st_fx->total_brate == ACELP_9k60) || (st_fx->element_mode == EVS_MONO && (st_fx->total_brate == 0) && ((st_fx->last_total_brate == ACELP_9k60) || (st_fx->last_total_brate == ACELP_13k20 && st_fx->rf_flag_last))))) { - FOR( i = 0; i < NUM_Q_LSF; i++ ) + IF(st_fx->extl_brate == SWB_TBE_1k75) { - lsf_idx[i] = (Word16) get_next_indice( st_fx, lsf_q_num_bits[i] ); - move16(); - } - } - } - Dequant_lower_LSF_fx( lsf_idx, lsf_q ); + /* read multi-stage LVQ quantizer */ + IF(nbits >= 19) + { + cb_stage = cb_LSF_BWE_fx[0]; + } + ELSE + { + cb_stage = cb_LSF_BWE_fx[1]; + } + set16_fx(lsf_q,0, LPC_SHB_ORDER); - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) - { - m_idx = hBWE_TD->m_idx_fx; - } - ELSE - { - m_idx = (Word16) get_next_indice( st_fx, MIRROR_POINT_BITS ); - move16(); - } + /* VQ part */ + num_bits_lvq = config_LSF_BWE[(NUM_BITS_SHB_MSLVQ - nbits) * 3]; + Idx = get_next_indice(st_fx, num_bits_lvq); + v_add_16(lsf_q, cb_stage + Idx * 6, lsf_q, 6); - Dequant_mirror_point_fx( lsf_q, m_idx, &m ); + /* MSLVQ part */ + num_bits_lvq = nbits - num_bits_lvq - config_LSF_BWE[(NUM_BITS_SHB_MSLVQ - nbits) * 3 + 2]; + predictor_bits = config_LSF_BWE[(NUM_BITS_SHB_MSLVQ - nbits) * 3 + 2]; + Idx_pred = 0; - /* safety check in case of bit errors */ - IF( GT_16( m, MAX_LSF_FX ) ) - { - st_fx->BER_detect = 1; - m = MAX_LSF_FX - 1; - } + IF(num_bits_lvq == 16) + { + /* MSLVQ part */ + Idx_lvq = get_next_indice(st_fx, num_bits_lvq - 1) + ((get_next_indice(st_fx, 1)) << 15); + deindex_lvq_SHB_fx(Idx_lvq, out, num_bits_lvq, 0); + } + ELSE + { + /* MSLVQ part */ + Idx_lvq = get_next_indice(st_fx, num_bits_lvq); + deindex_lvq_SHB_fx(Idx_lvq, out, num_bits_lvq, (nbits < 19)); + } + + /* mvr2r( mean_lsf, Q_lsfs, LPC_SHB_ORDER ); */ + v_add_16(lsf_q, out, lsf_q, LATTICE_DIM); /* quantized mean removed data for first 8 dim*/ + + /* predict last 2 components */ + IF(predictor_bits == 0) + { + lsf_q[LATTICE_DIM] = dotp_loc(lsf_q, LastCoefPred_0bit_fx, LATTICE_DIM); + lsf_q[LATTICE_DIM + 1] = dotp_loc(lsf_q, &LastCoefPred_0bit_fx[LATTICE_DIM + 1], LATTICE_DIM); + } + ELSE + { + Idx_pred = get_next_indice(st_fx, 1); - IF( EQ_16( st_fx->codec_mode, MODE2 ) ) - { - grid_idx = hBWE_TD->grid_idx_fx; - } - ELSE - { - grid_idx = (Word16) get_next_indice( st_fx, NUM_LSF_GRID_BITS ); - move16(); - } + lsf_q[LATTICE_DIM] = dotp_loc(lsf_q, &LastCoefPred_1bit_fx[2 * (LATTICE_DIM + 1) * Idx_pred], LATTICE_DIM); + lsf_q[LATTICE_DIM + 1] = dotp_loc(lsf_q, &LastCoefPred_1bit_fx[2 * (LATTICE_DIM + 1) * Idx_pred + LATTICE_DIM + 1], LATTICE_DIM); + } - Map_higher_LSF_fx( lsf_q, m, lsf_grid_fx[grid_idx] ); + IF (nbits < NUM_BITS_SHB_MSLVQ) + { + Idx_pred = get_next_indice(st_fx, NUM_BITS_SHB_MSLVQ - nbits); + } - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - /* safety check in case of bit errors */ - IF( GT_16( lsf_q[LPC_SHB_ORDER - 1 - i], MAX_LSF_FX ) ) + v_add_16(SHB_LSF_mean_fx, lsf_q, lsf_q, LPC_SHB_ORDER); + v_sort(lsf_q, 0, LPC_SHB_ORDER - 1); + } + ELSE + { + /* LSFs */ + test(); + test(); + test(); + IF(EQ_32(extl_brate, SWB_TBE_1k6) || EQ_32(extl_brate, FB_TBE_1k8) || EQ_32(extl_brate, SWB_TBE_2k8) || EQ_32(extl_brate, FB_TBE_3k0)) + { + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + FOR(i = 0; i < NUM_Q_LSF; i++) + { + lsf_idx[i] = hBWE_TD->lsf_idx[i]; + move16(); + } + } + ELSE + { + FOR(i = 0; i < NUM_Q_LSF; i++) + { + lsf_idx[i] = (Word16)get_next_indice(st_fx, lsf_q_num_bits[i]); + move16(); + } + } + } + Dequant_lower_LSF_fx(lsf_idx, lsf_q); + + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + m_idx = hBWE_TD->m_idx; + } + ELSE + { + m_idx = (Word16)get_next_indice(st_fx, MIRROR_POINT_BITS); + move16(); + } + + Dequant_mirror_point_fx(lsf_q, m_idx, &m); + + /* safety check in case of bit errors */ + IF(GT_16(m, MAX_LSF_FX)) + { + st_fx->BER_detect = 1; + m = MAX_LSF_FX - 1; + } + + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + grid_idx = hBWE_TD->grid_idx; + } + ELSE + { + grid_idx = (Word16)get_next_indice(st_fx, NUM_LSF_GRID_BITS); + move16(); + } + + Map_higher_LSF_fx(lsf_q, m, lsf_grid_fx[grid_idx]); + } + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + /* safety check in case of bit errors */ + IF(GT_16(lsf_q[LPC_SHB_ORDER - 1 - i], MAX_LSF_FX)) + { + st_fx->BER_detect = 1; + lsf_q[LPC_SHB_ORDER - 1 - i] = MAX_LSF_FX - 1; + } + Q_lsf[i] = sub(16384, lsf_q[LPC_SHB_ORDER - 1 - i]); + move16(); + } + } + ELSE { - st_fx->BER_detect = 1; - lsf_q[LPC_SHB_ORDER - 1 - i] = MAX_LSF_FX - 1; + set16_fx(lsf_idx, 0, 5); + Copy(hBWE_TD->lsf_idx_fx, lsf_idx, 5); + grid_idx = 0; + m_idx = 0; + Copy(swb_tbe_lsfvq_cbook_8b + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER); } - Q_lsf[i] = sub( 16384, lsf_q[LPC_SHB_ORDER - 1 - i] ); - move16(); - } - } - ELSE - { - set16_fx( lsf_idx, 0, 5 ); - Copy( hBWE_TD->lsf_idx_fx, lsf_idx, 5 ); - grid_idx = 0; - m_idx = 0; - Copy( swb_tbe_lsfvq_cbook_8b + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER ); - } - space_lsfs_fx( Q_lsf, LPC_SHB_ORDER ); + space_lsfs_fx(Q_lsf, LPC_SHB_ORDER); - /* Dequantize subgain indices */ - j = idxSubGain * NUM_SHB_SUBGAINS; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - /* Q_subgain[i] = (float) pow(10.0, SHBCB_SubGain5bit[j++]); */ - - L_tmp = L_mult( SHBCB_SubGain5bit_fx[j++], 27213 ); /*Q28 3.321928 in Q13 */ - L_tmp = L_shr( L_tmp, 12 ); - frac = L_Extract_lc( L_tmp, &exp ); - tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - Q_subgain[i] = shl( tmp, add( exp, 1 ) ); /*Q15*/ - move16(); - } + /* Dequantize subgain indices */ + j = idxSubGain * NUM_SHB_SUBGAINS; + move16(); + FOR(i = 0; i < NUM_SHB_SUBGAINS; i++) + { + /* Q_subgain[i] = (float) pow(10.0, SHBCB_SubGain5bit[j++]); */ + + L_tmp = L_mult(SHBCB_SubGain5bit_fx[j++], 27213); /*Q28 3.321928 in Q13 */ + L_tmp = L_shr(L_tmp, 12); + frac = L_Extract_lc(L_tmp, &exp); + tmp = extract_l(Pow2(14, frac)); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + Q_subgain[i] = shl(tmp, add(exp, 1)); /*Q15*/ + move16(); + } - FOR( i = NUM_SHB_SUBFR - 1; i >= 0; i-- ) - { - Q_subgain[i] = Q_subgain[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; - move16(); - } + FOR(i = NUM_SHB_SUBFR - 1; i >= 0; i--) + { + Q_subgain[i] = Q_subgain[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + move16(); + } - /* Frame gain */ - *Q_framegrain = L_mac( SHB_GAIN_QLOW_FX, idxFrameGain, SHB_GAIN_QDELTA_FX ); - move32(); /*Q18*/ - L_tmp = Mult_32_16( *Q_framegrain, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ - frac = L_Extract_lc( L_tmp, &exp ); - L_tmp = Pow2( 30, frac ); - *Q_framegrain = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + /* Frame gain */ + IF(st_fx->extl_brate == SWB_TBE_1k75) + { + *Q_framegrain = L_mac(SHB_GAIN_QLOW_1k75_FX, idxFrameGain, SHB_GAIN_QDELTA_1k75_FX); + } + ELSE { + *Q_framegrain = L_mac(SHB_GAIN_QLOW_FX, idxFrameGain, SHB_GAIN_QDELTA_FX); + } + move32(); /*Q18*/ + L_tmp = Mult_32_16(*Q_framegrain, 27213); /*Q16*/ /* 3.321928 in Q13 */ + frac = L_Extract_lc(L_tmp, &exp); + L_tmp = Pow2(30, frac); + *Q_framegrain = L_shl(L_tmp, sub(exp, 12)); /*Q18*/ } return; } -#endif + + +/*==========================================================================*/ +/* FUNCTION : static void dequantizeSHBparams_fx_9_1 () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Dequantize super highband spectral envolope */ +/* temporal gains and frame gain */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 extl i : extension layer */ +/* _Word32 extl_brate i : extensiuon layer bitrate */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *Q_lsf, o : SHB LSF from de-quantization Q15 */ +/* _Word16 *Q_subgain, o : SHB subframe gains from de-quantization Q15*/ +/* _Word32 *Q_framegrain o : SHB frame gain from de-quantization Q18 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ static void dequantizeSHBparams_fx_9_1( Decoder_State* st_fx, -- GitLab From abbe5fa9155694fde01ec1df2445315b71db40bf Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 26 Mar 2024 13:48:03 +0530 Subject: [PATCH 2/3] Revert few issue changes in +10dB and -10dB scaled inputs. --- lib_com/ivas_stereo_td_bit_alloc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index e4fd087f9..e606c06fd 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -73,7 +73,7 @@ * * Bitbudget distribution between Primary and Secondary channel in TD stereo *-------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED +#ifndef IVAS_FLOAT_FIXED_ void tdm_bit_alloc( const int16_t ivas_format, /* i : IVAS format */ const int16_t ism_mode, /* i : ISM mode in combined format */ @@ -508,20 +508,22 @@ void tdm_bit_alloc( /* further adjustment in function of the energy/correlation ratio */ IF( coder_type == INACTIVE ) { - Word32 res_fix = 0; - res_fix = Mpy_32_32( 6442450, ( element_brate_wo_meta - 500 ) ); - res_fix = res_fix * 100; - //*total_brate_sec = max( *total_brate_sec, (Word16) ( 0.3f * ( element_brate_wo_meta - 500 ) / 100 ) * 100 ); - *total_brate_sec = max( *total_brate_sec, (Word16) res_fix ); + //Word32 res_fix = 0; + //res_fix = Mpy_32_32( 6442450, ( element_brate_wo_meta - 500 ) ); + //res_fix = res_fix * 100; + //*total_brate_sec = max( *total_brate_sec, (Word16) res_fix ); + + *total_brate_sec = max(*total_brate_sec, (int16_t)(0.3f * (element_brate_wo_meta - 500) / 100) * 100); tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 200 * idx ); } ELSE { - Word32 res_fix = 0; - res_fix = Mpy_32_32( 10737418, ( element_brate_wo_meta - 500 ) ); - res_fix = res_fix * 100; - //*total_brate_sec = max( *total_brate_sec, (Word16) ( 0.5f * ( element_brate_wo_meta - 500 ) / 100 ) * 100 ); - *total_brate_sec = max( *total_brate_sec, res_fix ); + //Word32 res_fix = 0; + //res_fix = Mpy_32_32( 10737418, ( element_brate_wo_meta - 500 ) ); + //res_fix = res_fix * 100; + //*total_brate_sec = max( *total_brate_sec, res_fix ); + + *total_brate_sec = max(*total_brate_sec, (int16_t)(0.5f * (element_brate_wo_meta - 500) / 100) * 100); /* tmp_bits = -abs(tdm_inst_ratio_idx-16)*200*idx; */ tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 100 * idx ); } -- GitLab From a4e0020593240316c6152e0d3176f0442ab00264 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 26 Mar 2024 20:51:02 +0530 Subject: [PATCH 3/3] Fix assertion/memory overflow errors --- lib_com/ivas_stereo_td_bit_alloc.c | 47 +++++++++++++++--------------- lib_dec/ivas_jbm_dec.c | 21 ++----------- lib_rend/ivas_crend.c | 7 +++++ 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index e606c06fd..3f648bee3 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -73,7 +73,7 @@ * * Bitbudget distribution between Primary and Secondary channel in TD stereo *-------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED_ +#ifndef IVAS_FLOAT_FIXED void tdm_bit_alloc( const int16_t ivas_format, /* i : IVAS format */ const int16_t ism_mode, /* i : ISM mode in combined format */ @@ -508,22 +508,22 @@ void tdm_bit_alloc( /* further adjustment in function of the energy/correlation ratio */ IF( coder_type == INACTIVE ) { - //Word32 res_fix = 0; - //res_fix = Mpy_32_32( 6442450, ( element_brate_wo_meta - 500 ) ); - //res_fix = res_fix * 100; - //*total_brate_sec = max( *total_brate_sec, (Word16) res_fix ); + Word32 res_fix = 0; + res_fix = Mpy_32_32(644245094, ( element_brate_wo_meta - 500 ) ); + res_fix = ( ( res_fix / 100 ) * 100 ); + *total_brate_sec = max( *total_brate_sec, res_fix ); - *total_brate_sec = max(*total_brate_sec, (int16_t)(0.3f * (element_brate_wo_meta - 500) / 100) * 100); + //*total_brate_sec = max(*total_brate_sec, (int16_t)(0.3f * (element_brate_wo_meta - 500) / 100) * 100); tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 200 * idx ); } ELSE { - //Word32 res_fix = 0; - //res_fix = Mpy_32_32( 10737418, ( element_brate_wo_meta - 500 ) ); - //res_fix = res_fix * 100; - //*total_brate_sec = max( *total_brate_sec, res_fix ); + Word32 res_fix = 0; + res_fix = Mpy_32_32(1073741824, ( element_brate_wo_meta - 500 ) ); + res_fix = ( ( res_fix / 100 ) * 100 ); + *total_brate_sec = max(*total_brate_sec, res_fix ); - *total_brate_sec = max(*total_brate_sec, (int16_t)(0.5f * (element_brate_wo_meta - 500) / 100) * 100); + //*total_brate_sec = max(*total_brate_sec, (int16_t)(0.5f * (element_brate_wo_meta - 500) / 100) * 100); /* tmp_bits = -abs(tdm_inst_ratio_idx-16)*200*idx; */ tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 100 * idx ); } @@ -537,19 +537,20 @@ void tdm_bit_alloc( bit_rate_diff_fx = tmp_bits; } ELSE{ - IF( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM ){ + IF( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM ) + { bit_rate_diff_fx = ( LRTD_STEREO_MID_IS_PRIM - ener_ratio_idx ) * bit_rate_diff_fx; - bit_rate_diff_fx = L_shr( bit_rate_diff_fx, 1 ); - bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation - } - ELSE - { - bit_rate_diff_fx = ( ener_ratio_idx - LRTD_STEREO_MID_IS_PRIM ) * bit_rate_diff_fx; - bit_rate_diff_fx = Mpy_32_32( 107374182, bit_rate_diff_fx ); - bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation - } -} + bit_rate_diff_fx = L_shr( bit_rate_diff_fx, 1 ); + bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation + } + ELSE + { + bit_rate_diff_fx = ( ener_ratio_idx - LRTD_STEREO_MID_IS_PRIM ) * bit_rate_diff_fx; + bit_rate_diff_fx = L_shr(bit_rate_diff_fx, 1); + bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation + } + } /*bit_rate_diff2 = ((Word16)(10.f*(-0.5f*ener_ratio_LR+0.5f)*bit_rate_diff)/100)*100;*/ *total_brate_sec += ( (Word16) ( bit_rate_diff_fx / 100 ) * 100 ); *total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[idx][coder_type] ); @@ -591,7 +592,7 @@ IF( ( ener_ratio_idx <= 1 || ener_ratio_idx >= 29 ) && coder_type >= UNVOICED ) } ELSE { - *total_brate_sec = min( *total_brate_sec, (Word16) ( 0.0045f * element_brate_wo_meta ) * 100 ); + *total_brate_sec = min(*total_brate_sec, Mpy_32_32(9663677, element_brate_wo_meta)* 100); } *total_brate_sec = min( *total_brate_sec, 18000 ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 61f7e5d7d..2fb1fb56f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -4089,7 +4089,7 @@ ivas_error ivas_jbm_dec_render( { for (j = 0; j < *nSamplesRendered; j++) { - p_tc_fx[i][j] = (Word32)float_to_fixed(p_tc[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + p_output_fx[i][j] = (Word32)float_to_fixed(p_output[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); } } if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, @@ -4099,22 +4099,13 @@ ivas_error ivas_jbm_dec_render( { return error; } - //scaling all Tc to output q // needed - for (i = nchan_out; i < nchan_in; i++) - { - for (j = 0; j < *nSamplesRendered; j++) - { - p_tc_fx[i][j] = (Word32)L_shr(p_tc_fx[i][j], exp - *st_ivas->hCrendWrapper->p_io_qfactor); - } - } ivas_binaural_add_LFE_fix(st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx); for (i = 0; i < nchan_in; i++) { for (j = 0; j < *nSamplesRendered; j++) { - // p_output[i][j] = fixed_to_float(p_output_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); - p_tc[i][j] = fixed_to_float(p_tc_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); + p_output[i][j] = fixed_to_float(p_output_fx[i][j], *st_ivas->hCrendWrapper->p_io_qfactor); } } @@ -4700,14 +4691,6 @@ ivas_error ivas_jbm_dec_flush_renderer( { return error; } - //scaling all Tc to output q // needed - for (i = nchan_out; i < nchan_in; i++) - { - for (j = 0; j < *nSamplesRendered; j++) - { - hTcBuffer->tc_fx[i][j] = (Word32)L_shr(hTcBuffer->tc_fx[i][j], exp - *st_ivas->hCrendWrapper->p_io_qfactor); - } - } ivas_binaural_add_LFE_fix(st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc_fx, p_output_fx); diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 5beca86b4..df2709b45 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -4099,6 +4099,13 @@ ivas_error ivas_rend_crendProcessSubframe( IF ( pCrend->hCrend->hReverb != NULL ) { *pCrend->p_io_qfactor -= 2; + for (int i = nchan_out; i < nchan_in; i++) + { + for (int j = 0; j < n_samples_to_render; j++) + { + output[i][j] = (Word32)L_shr(output[i][j], 2); + } + } } /* move to output */ FOR ( ch = 0; ch < nchan_out; ch++ ) -- GitLab