diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 57f7226461242bed95799a94b545f4da33ca7d4a..6b75307f51ffffc376a1e0f66dcd659dd18c691d 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1891,6 +1891,7 @@ void GenShapedWBExcitation_ivas_fx( const Word16 igf_flag ); #endif +#ifndef HARM_FD_BWE /* o : Q_syn_hb*/ Word16 ivas_wb_bwe_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ @@ -1907,7 +1908,7 @@ Word16 ivas_wb_bwe_dec_fx( const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ Word16 *Qpost ); - +#endif void ivas_param_ism_config_fx( PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i/o: IVAS Param ISM Config Structure */ const Word16 nchan_obj /* i : number of ISM channels */ diff --git a/lib_com/options.h b/lib_com/options.h index 72cb319f05130aed0e4e24e318c2ef8c71368c43..b355f90ce68bca3a50a623e02e1664b03afdd17c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -99,6 +99,7 @@ #define FIX_2410_HARM_MODIF_FS /* VA: basop issue 2410: Remove duplicated modif_Fs */ #define HARM_LEV_DURBIN /* VA: basop issue 2423: harmonize levinson-Durbin algorithm */ #define HARMONIZE_TBE2 /* VA: basop issue 2399: Remove duplicated code: TBE, step 2 */ +#define HARM_FD_BWE /* VA: harmonize core-coder FD BWE function duplications */ /* #################### End BE switches ################################## */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index b0470c6be7b957aa90f4f716370fe7ac12a95693..c9ad7fcff8339eec8ea1d878a3770ed519a1784b 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -317,6 +317,13 @@ Word32 calc_tilt_bwe_fx( const Word16 N /* i : signal length */ ); +/* o : Tilt in Q24 */ +Word16 calc_tilt_bwe_fx_32( + const Word32 *sp, /* i : i signal */ + const Word16 exp_sp, /* i : Exp of inp signal */ + const Word16 N /* i : signal length */ +); + void calc_norm_envelop_fx( const Word16 SWB_signal[], /* i : SWB spectrum Q_syn*/ Word32 *envelope, /* o : normalized envelope Q_syn*/ @@ -325,6 +332,14 @@ void calc_norm_envelop_fx( const Word16 st_offset /* i : offset */ ); +void calc_norm_envelop_fx_32( + const Word32 SWB_signal_fx[], /* i : SWB spectrum : Q12 */ + Word32 *envelope_fx, /* o : normalized envelope : Q16 */ + const Word16 L_swb_norm, /* i : length of envelope : Q0 */ + const Word16 SWB_flength, /* i : Length of i /output : Q0 */ + const Word16 st_offset /* i : offset : Q0 */ +); + void WB_BWE_decoding_fx( const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ Word16 *WB_fenv, /* i : WB frequency envelopes */ @@ -365,6 +380,9 @@ void SWB_BWE_decoding_fx( ); void time_envelop_shaping_fx( +#ifdef HARM_FD_BWE + const Word16 element_mode, /* i : element mode */ +#endif Word16 werr[], /* i/o: SHB synthesis Q_synth*/ Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ const Word16 L, /* i : frame length */ @@ -378,14 +396,6 @@ void time_reduce_pre_echo_fx( Word16 Q_syn, Word16 Q_synth ); -void calc_norm_envelop_fx_32( - const Word32 SWB_signal_fx[], /* i : SWB spectrum : Q12 */ - Word32 *envelope_fx, /* o : normalized envelope : Q16 */ - const Word16 L_swb_norm, /* i : length of envelope : Q0 */ - const Word16 SWB_flength, /* i : Length of i /output : Q0 */ - const Word16 st_offset /* i : offset : Q0 */ -); - void hq_generic_decoding_fx( const Word16 HQ_mode, /* i : HQ mode */ Word32 *coeff_out1_fx, /* i/o: BWE i & temporary buffer */ @@ -2646,83 +2656,7 @@ Word16 E_UTIL_f_preemph3_ivas_fx( Word16 bits /* Q0 */ ); -Word16 WB_BWE_gain_pred_fx( - Word16 *WB_fenv, /* o : WB frequency envelopes */ - const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ - const Word16 coder_type, /* i : coding type */ - Word16 prev_coder_type, /* i : coding type of last frame */ - Word16 prev_WB_fenv, /* i : envelope for last frame */ - Word16 *voice_factors, /* i : voicing factors Q15 */ - const Word16 pitch_buf[], /* i : pitch buffer Q6 */ - Word32 last_core_brate, /* i : previous frame core bitrate */ - Word16 last_wb_bwe_ener, /* i : previous frame wb bwe signal energy */ - Word16 Q_syn, - Word16 last_extl_fx, - Word16 tilt_wb_fx ); - -void calc_normal_length_fx( - const Word16 core, /* i : core */ - const Word16 *sp, /* i : i signal */ - const Word16 mode, /* i : i mode */ - const Word16 extl, /* i : extension layer */ - Word16 *L_swb_norm, /* o : normalize length */ - Word16 *prev_L_swb_norm, /*i/o : last normalize length */ - Word16 Q_syn ); - -/* o : Tilt in Q24 */ -Word16 ivas_calc_tilt_bwe_fx( - const Word32 *sp, /* i : i signal */ - const Word16 exp_sp, /* i : Exp of inp signal */ - const Word16 N /* i : signal length */ -); - -void calc_norm_envelop_fx( - const Word16 SWB_signal[], /* i : SWB spectrum Q_syn*/ - Word32 *envelope, /* o : normalized envelope Q_syn*/ - const Word16 L_swb_norm, /* i : length of envelope Q0 */ - const Word16 SWB_flength, /* i : Length of i /output */ - const Word16 st_offset /* i : offset */ -); - -void WB_BWE_decoding_fx( - const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ - Word16 *WB_fenv, /* i : WB frequency envelopes */ - Word32 *WB_signal32, /* o : WB signal in MDCT domain */ - const Word16 WB_flength, /* i : Length of i /output */ - const Word16 mode, /* i : classification for WB signal */ - const Word16 last_extl, /* i : extl. layer for last frame */ - Word32 *prev_Energy, /* i/o: energy for last frame */ - Word16 *prev_WB_fenv, /* i/o: envelope for last frame */ - Word16 *prev_L_wb_norm, /* i/o: length for last frame wb norm */ - const Word16 extl, /* i : extension layer */ - const Word16 coder_type, /* i : coding type */ - const Word32 total_brate, /* i : core layer bitrate */ - Word16 *Seed, /* i/o: random generator seed */ - Word16 *prev_flag, /* i/o: attenu flag of last frame */ - Word16 prev_coder_type, /* i : coding type of last frame */ - Word16 Q_syn, - Word16 *Q_syn_hb /*o : Q value of WB_signal_32 */ -); - -void SWB_BWE_decoding_fx( - const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ - Word16 *SWB_fenv, /* i/o: SWB frequency envelopes */ - Word32 *SWB_signal, /* o : SWB signal in MDCT domain */ - const Word16 SWB_flength, /* i : Length of i /output */ - const Word16 mode, /* i : classification for SWB signal */ - Word16 *frica_flag, /* o : fricative signal flag */ - Word16 *prev_Energy, /* i/o: energy for last frame */ - Word16 *prev_SWB_fenv, /* i/o: envelope for last frame */ - Word16 *prev_L_swb_norm, /* i/o: length for last frame wb norm */ - const Word16 tilt_nb, /* i : tilt of synthesis wb signal */ - Word16 *Seed, /* i/o: random generator seed */ - const Word16 st_offset, /* i : offset value due to different core */ - Word16 *prev_weight, /* i/o: excitation weight value of last frame */ - const Word16 extl, /* i : extension layer */ - Word16 Q_syn, - const Word16 last_extl /* i : extension layer of last frame */ -); - +#ifndef HARM_FD_BWE void time_envelop_shaping_fx( Word16 werr[], /* i/o: SHB synthesis Q_synth*/ Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ @@ -2730,55 +2664,14 @@ void time_envelop_shaping_fx( Word16 *Q_synth ); void time_envelop_shaping_ivas_fx( +#ifdef HARM_FD_BWE + const Word16 element_mode, /* i : element mode */ +#endif Word16 werr[], /* i/o: SHB synthesis Q_synth*/ Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ const Word16 L, /* i : frame length */ Word16 *Q_synth ); - -void time_reduce_pre_echo_fx( - const Word16 *synth, /* i : ACELP core synthesis Q_syn*/ - Word16 *error, /* i/o: SHB BWE synthesis Q0*/ - Word16 prev_td_energy, /* o : last td energy Q0*/ - const Word16 L, /* i : subframe length */ - Word16 Q_syn, - Word16 Q_synth ); - -void calc_normal_length_fx_32( - const Word16 core, /* i : core : Q0 */ - const Word32 *sp, /* i : i signal : Q12 */ - const Word16 mode, /* i : i mode : Q0 */ - const Word16 extl, /* i : extension layer : Q0 */ - Word16 *L_swb_norm, /* o : normalize length : Q0 */ - Word16 *prev_L_swb_norm /*i/o : last normalize length : Q0 */ -); - -void calc_norm_envelop_fx_32( - const Word32 SWB_signal_fx[], /* i : SWB spectrum : Q12 */ - Word32 *envelope_fx, /* o : normalized envelope : Q16 */ - const Word16 L_swb_norm, /* i : length of envelope : Q0 */ - const Word16 SWB_flength, /* i : Length of i /output : Q0 */ - const Word16 st_offset /* i : offset : Q0 */ -); - -void hq_generic_decoding_fx( - const Word16 HQ_mode, /* i : HQ mode */ - Word32 *coeff_out1_fx, /* i/o: BWE i & temporary buffer */ - const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes */ - Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain */ - const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic*/ - Word16 *prev_L_swb_norm, /* i/o: last normalize length */ - const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ - const Word16 *R ); - -void save_old_syn_fx( - const Word16 L_frame, /* i : frame length */ - const Word16 syn[], /* i : ACELP synthesis */ - Word16 old_syn[], /* o : old synthesis buffer */ - Word16 old_syn_mem[], /* i/o: old synthesis buffer memory */ - const Word16 preemph_fac, /* i : preemphasis factor */ - Word16 *mem_deemph /* i/o: deemphasis filter memory */ -); - +#endif void find_td_envelope_fx( const Word16 inp[], /* i : input signal Qx */ const Word16 len, /* i : length of the input signal */ @@ -7287,7 +7180,9 @@ Word16 WB_BWE_gain_deq_fx( Word16 *WB_fenv /*Q15*/ ); +/* o : Q_syn_hb*/ Word16 wb_bwe_dec_fx( +#ifndef HARM_FD_BWE Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ const Word16 output_frame, /* i : frame length */ @@ -7295,6 +7190,17 @@ Word16 wb_bwe_dec_fx( const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *Qpost ); +#else + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 output_fx32[], /* o : synthesis @internal Fs Q11*/ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 output_frame, /* i : frame length */ + Word16 *voice_factors_fx, /* i : voicing factors Q15 */ + const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ + Word16 *Qpost ); +#endif /* o : BWE class */ Word16 swb_bwe_gain_deq_fx( diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index a413064d2eb6b709c9b037ba1c4f004186060303..525a1db8555a8df2e7f658086fc51a6505d58712 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -338,18 +338,15 @@ Word16 WB_BWE_gain_pred_fx( * * calc_envelope of low frequency spectrum *-------------------------------------------------------------------*/ + static void calc_norm_envelop_lf_fx( - const Word32 SWB_signal[], - /* i : SWB spectrum */ /* Q12 */ - Word32 *envelope, - /* o : normalized envelope */ /* Q12 */ - Word16 *L_swb_norm, /* i/o : length of envelope */ - const Word16 HQ_mode, - /* i : HQ mode */ /* Q0 */ - const Word16 hq_generic_offset, - /* i : frequency offset for representing hq generic */ /* Q0 */ - Word16 *sfreq, /* i : starting frequency index */ - Word16 *efreq /* i : ending frequency index */ + const Word32 SWB_signal[], /* i : SWB spectrum Q12 */ + Word32 *envelope, /* o : normalized envelope Q12 */ + Word16 *L_swb_norm, /* i/o: length of envelope */ + const Word16 HQ_mode, /* i : HQ mode Q0 */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic Q0 */ + Word16 *sfreq, /* i : starting frequency index */ + Word16 *efreq /* i : ending frequency index */ ) { Word16 lookback, env_index, n_freq, n_lag_now, n_lag; @@ -423,6 +420,8 @@ static void calc_norm_envelop_lf_fx( return; } + + /*-------------------------------------------------------------------* * calc_normal_length() * @@ -550,16 +549,18 @@ void calc_normal_length_fx( return; } + /*-------------------------------------------------------------------* * calc_tilt_bwe() * * calculate tilt parameter *-------------------------------------------------------------------*/ -Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 */ - const Word16 *sp, /* i : input signal Q(15 - exp_sp) */ - const Word16 exp_sp, /* i : Exp of inp signal */ - const Word16 N /* i : signal length */ +/* o : Tilt in Q24 */ +Word32 calc_tilt_bwe_fx( + const Word16 *sp, /* i : input signal Q(15 - exp_sp) */ + const Word16 exp_sp, /* i : Exp of inp signal */ + const Word16 N /* i : signal length */ ) { Word16 i, j; @@ -645,10 +646,13 @@ Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 return L_temp; } -Word16 ivas_calc_tilt_bwe_fx( /* o : Tilt in Q24 */ - const Word32 *sp, /* i : input signal */ - const Word16 exp_sp, /* i : Exp of inp signal Q(15 - exp_sp) */ - const Word16 N /* i : signal length */ + + +/* o : Tilt in Q24 */ +Word16 calc_tilt_bwe_fx_32( + const Word32 *sp, /* i : input signal */ + const Word16 exp_sp, /* i : Exp of inp signal Q(15 - exp_sp) */ + const Word16 N /* i : signal length */ ) { Word16 i, j; @@ -809,11 +813,12 @@ void calc_norm_envelop_fx( /* _Word16 *Seed, i/o: random generator seed Q15 */ /* _Word16 *prev_flag, i/o: attenu flag of last frame Q0 */ /*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ +/* RETURN ARGUMENTS : */ +/* _ None */ /*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ +/* CALLED FROM : */ /*==========================================================================*/ + void WB_BWE_decoding_fx( const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ Word16 *WB_fenv, /* i : WB frequency envelopes */ @@ -1938,7 +1943,9 @@ return; /* RETURN ARGUMENTS : */ /* _ None */ /*--------------------------------------------------------------------------*/ + void time_envelop_shaping_fx( +#ifndef HARM_FD_BWE Word16 werr[], /* i/o: SHB synthesis Q_synth*/ Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ const Word16 L, /* i : frame length */ @@ -2018,6 +2025,9 @@ void time_envelop_shaping_fx( } void time_envelop_shaping_ivas_fx( +#else + const Word16 element_mode, /* i : element mode */ +#endif Word16 werr[], /* i/o: SHB synthesis Q_synth*/ Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ const Word16 L, /* i : frame length */ @@ -2034,31 +2044,47 @@ void time_envelop_shaping_ivas_fx( pit = werr; exp_L = norm_s( L ); inv_L = div_s( shl( 1, sub( 14, exp_L ) ), L ); /*Q(29-exp_L) */ + FOR( i = 0; i < SWB_TENV; i++ ) { - Energy_64 = L_deposit_l( 0 ); - FOR( j = 0; j < L / 4; j++ ) +#ifdef HARM_FD_BWE + IF( element_mode == EVS_MONO ) { - Energy_64 = W_mac0_16_16( Energy_64, *pit, *pit ); /*(2*Q_synth) */ - pit++; + Energy = L_deposit_l( 0 ); + FOR( j = 0; j < L / 4; j++ ) + { + Energy = L_mac0_sat( Energy, *pit, *pit ); /*(2*Q_synth) */ + pit++; + } + Energy_Q = shl( ( *Q_synth ), 1 ); } - w_tmp = W_norm( Energy_64 ); - Energy_64 = W_shl( Energy_64, w_tmp ); - Energy = W_extract_h( Energy_64 ); /*2*Q_synth + w_tmp -32*/ - Energy_Q = sub( add( shl( ( *Q_synth ), 1 ), w_tmp ), 32 ); + ELSE +#endif + { + Energy_64 = L_deposit_l( 0 ); + FOR( j = 0; j < L / 4; j++ ) + { + Energy_64 = W_mac0_16_16( Energy_64, *pit, *pit ); /*(2*Q_synth) */ + pit++; + } + w_tmp = W_norm( Energy_64 ); + Energy_64 = W_shl( Energy_64, w_tmp ); + Energy = W_extract_h( Energy_64 ); /*2*Q_synth + w_tmp -32*/ + Energy_Q = sub( add( shl( ( *Q_synth ), 1 ), w_tmp ), 32 ); + } + Energy = Mult_32_16( Energy, inv_L ); /*Q(29-exp_L-15) -> Q(-exp_L+14+2*Q_synth+w_tmp-32) */ Energy_16 = 0; move16(); - /*exp = 31-(-exp_L+14 +(2*(*Q_synth)+w_tmp-32)); */ + /*exp = 31-(-exp_L+14+Energy_Q); */ exp = sub( 17, sub( Energy_Q, exp_L ) ); IF( Energy != 0 ) { exp = norm_l( Energy ); frac = extract_h( L_shl( Energy, exp ) ); - /*exp = sub(exp, 30-(-exp_L+14-2+(2*(*Q_synth)+w_tmp-32))); */ + /*exp = sub(exp, 30-(-exp_L+14-2+Energy_Q)); */ exp = sub( exp, sub( 30, add( sub( Energy_Q, exp_L ), 14 - 2 ) ) ); - tmp = div_s( 16384, frac ); L_tmp = L_deposit_h( tmp ); Energy = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp) */ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 07b2deddc3d6b0309a992cb26e82a6784253f8e7..9dd8f1873a911da420de68acef20957463bf74b6 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -370,7 +370,11 @@ ivas_error evs_dec_fx( ELSE IF( EQ_16( st_fx->extl, WB_BWE ) && st_fx->bws_cnt == 0 ) { /* WB BWE decoder */ +#ifdef HARM_FD_BWE + hb_synth_fx_exp = wb_bwe_dec_fx( st_fx, NULL, synth_fx, hb_synth_fx, 0, output_frame, voice_factors_fx, pitch_buf_fx, &Qpostd ); /*Q0*/ +#else hb_synth_fx_exp = wb_bwe_dec_fx( synth_fx, hb_synth_fx, output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); /*Q0*/ +#endif } /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index c9c080a7c64382b881b2f037f781888c89cd3dd0..be0b90043532a6880803d6f22cac72eb5c578013 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1073,7 +1073,11 @@ ivas_error ivas_core_dec_fx( { /* WB BWE decoder */ #ifdef FIX_2280_REDUCTION_UNNECESSARY_SCALING +#ifdef HARM_FD_BWE + Q_hb_synth_fx = wb_bwe_dec_fx( st, output_32_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); +#else Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_32_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); +#endif #else Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); #endif diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 61d5b345162cb15fb9ad075e970461d11e969152..1d9ec74449dfb096f28cc1802e8b1dd520bf8c61 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -354,7 +354,11 @@ Word16 WB_BWE_gain_deq_fx( *-------------------------------------------------------------------*/ /* o : Q_syn_hb */ +#ifdef HARM_FD_BWE +Word16 wb_bwe_dec_fx( +#else Word16 ivas_wb_bwe_dec_fx( +#endif Decoder_State *st_fx, /* i/o: decoder state structure */ #ifdef FIX_2280_REDUCTION_UNNECESSARY_SCALING Word32 output_fx32[], /* o : synthesis @internal Fs Q11*/ @@ -406,11 +410,10 @@ Word16 ivas_wb_bwe_dec_fx( Copy_Scale_sig_32_16( output_fx32, output, st_fx->L_frame, sub( Q_input, Q11 ) ); // Q_input #endif - /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* IVAS_fmToDo: delay output[] by 1.25ms ? */ lerp( output, ysynth_fx, L_FRAME16k, st_fx->L_frame ); wtda_fx( ysynth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k ); + *Qpost = sub( new_input_fx_exp, 15 ); move16(); direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, /*st->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); @@ -419,14 +422,14 @@ Word16 ivas_wb_bwe_dec_fx( ELSE { wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, - &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ - output_frame ); + &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ output_frame ); + *Qpost = sub( new_input_fx_exp, 15 ); move16(); - /* DCT of the ACELP core synthesis */ direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); ysynth_frame_size = output_frame; } + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ scl = sub( 16 + MAX_Q_NEW_INPUT, new_input_fx_exp ); /* Possible to Upscale? */ @@ -440,13 +443,23 @@ Word16 ivas_wb_bwe_dec_fx( } Copy_Scale_sig32_16( ysynth_32, ysynth_fx, ysynth_frame_size, scl ); Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); + IF( !st_fx->bfi ) { IF( st_fx->extl_brate > 0 ) { /* de-quantization */ mode = WB_BWE_gain_deq_fx( st_fx, WB_fenv_fx ); - st_fx->hBWE_FD->last_wb_bwe_ener_fx = extract_l( Mpy_32_16_r( L_add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 /*0.5f in Q15*/ ) ); +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) + { + hBWE_FD->last_wb_bwe_ener_fx = mult_r( add_sat( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ); // this would not saturate if written like : rounf_fx(L_mac(L_mult(WB_fenv_fx[0], 16384), WB_fenv_fx[1], 16384)) + } + ELSE +#endif + { + hBWE_FD->last_wb_bwe_ener_fx = extract_l( Mpy_32_16_r( L_add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 /*0.5f in Q15*/ ) ); + } move16(); } ELSE @@ -482,6 +495,7 @@ Word16 ivas_wb_bwe_dec_fx( move16(); } } + test(); IF( NE_16( st_fx->last_extl, WB_BWE ) || st_fx->bfi ) { @@ -535,7 +549,7 @@ Word16 ivas_wb_bwe_dec_fx( return Q_syn_hb; } - +#ifndef HARM_FD_BWE Word16 wb_bwe_dec_fx( Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ @@ -675,7 +689,7 @@ Word16 wb_bwe_dec_fx( return Q_syn_hb; } - +#endif /*-------------------------------------------------------------------* * swb_bwe_gain_deq() @@ -960,21 +974,19 @@ Word16 swb_bwe_dec_fx( /*---------------------------------------------------------------------* * SWB BWE decoding *---------------------------------------------------------------------*/ + /* windowing of the ACELP core synthesis */ new_input_fx_exp = *Qpost; move16(); - { - wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, - &hBWE_FD->old_wtda_swb_fx_exp, - ALDO_WINDOW, - ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ - output_frame ); - *Qpost = sub( new_input_fx_exp, 15 ); - move16(); - /* DCT of the ACELP core synthesis */ - direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); - } + wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, + &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ output_frame ); + + *Qpost = sub( new_input_fx_exp, 15 ); + move16(); + /* DCT of the ACELP core synthesis */ + direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ scl = sub( 16 + MAX_Q_NEW_INPUT, new_input_fx_exp ); /* Possible to Upscale? */ @@ -1147,7 +1159,11 @@ Word16 swb_bwe_dec_fx( } /* time envelope shaping when the current frame is TRANSIENT frame */ +#ifdef HARM_FD_BWE + time_envelop_shaping_fx( st_fx->element_mode, hb_synth_fx, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); +#else time_envelop_shaping_fx( hb_synth_fx, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); +#endif Q_syn_hb = sub( Q_syn_hb, 3 ); hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; @@ -1247,9 +1263,9 @@ void fd_bwe_dec_init_fx( } /*-------------------------------------------------------------------* - * WB_BWE_gain_deq() + * swb_bwe_dec_fx32() * - * Decoding of WB parameters + * SWB BWE decoder, 32-bit variant *-------------------------------------------------------------------*/ @@ -1293,11 +1309,10 @@ Word16 swb_bwe_dec_fx32( /*---------------------------------------------------------------------* * SWB BWE decoding *---------------------------------------------------------------------*/ + test(); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) { - /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* todo - delay output[] by 1.25ms ? */ L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); /* windowing of the ACELP core synthesis */ @@ -1318,6 +1333,7 @@ Word16 swb_bwe_dec_fx32( /* DCT of the ACELP core synthesis */ new_input_fx_exp = 11; move16(); + /* DCT of the ACELP core synthesis */ direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); ysynth_frame_size = output_frame; move16(); @@ -1513,7 +1529,11 @@ Word16 swb_bwe_dec_fx32( } /* time envelope shaping when the current frame is TRANSIENT frame */ +#ifdef HARM_FD_BWE + time_envelop_shaping_fx( st_fx->element_mode, hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); +#else time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); +#endif Q_syn_hb = sub( Q_syn_hb, 3 ); diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 868c62fe7ccef8a24297047d6501b6d2a6633aa7..27983b42e469050c699741b2e31c1c0e20c55090 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -408,7 +408,7 @@ static void updt_bw_switching_fx( { IF( st_fx->element_mode != EVS_MONO ) { - st_fx->tilt_swb_fx = ivas_calc_tilt_bwe_fx( synth32, Qpost, L_FRAME32k ); + st_fx->tilt_swb_fx = calc_tilt_bwe_fx_32( synth32, Qpost, L_FRAME32k ); } ELSE { diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index ac2560397f10c8329e1978efcda81279c779e3d1..7491697eda7b9a66670ee1f71cdf25e63bd70444 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -457,7 +457,11 @@ ivas_error evs_enc_fx( ELSE IF( EQ_16( st->extl, WB_BWE ) ) { /* WB BWE encoder */ +#ifdef HARM_FD_BWE + wb_bwe_enc_fx( st, new_inp_resamp16k ); +#else wb_bwe_enc_fx( st, new_inp_resamp16k, st->coder_type ); +#endif } /*---------------------------------------------------------------------* @@ -538,7 +542,11 @@ ivas_error evs_enc_fx( ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) ) { /* SWB BWE encoder */ +#ifdef HARM_FD_BWE + swb_bwe_enc_fx( st, EVS_MONO, old_inp_12k8, old_inp_16k, old_syn_12k8_16k, new_swb_speech, 0, shb_speech, Q_shb_spch, sub( Q_new, 1 ) ); +#else swb_bwe_enc_fx( st, old_inp_12k8, old_inp_16k, old_syn_12k8_16k, new_swb_speech, shb_speech, st->coder_type, Q_shb_spch, sub( Q_new, 1 ) ); +#endif } ELSE IF( EQ_16( st->extl, SWB_BWE_HIGHRATE ) || EQ_16( st->extl, FB_BWE_HIGHRATE ) ) { diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 795f64c12c65df1579dcaa26586ceda431ba20d3..e5e38904d93214e912350074563d8c8643acc48c 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -655,7 +655,11 @@ ivas_error ivas_core_enc_fx( ELSE IF( EQ_16( st->extl, WB_BWE ) && n == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { /* WB BWE encoder */ +#ifdef HARM_FD_BWE + wb_bwe_enc_fx( st, new_inp_resamp16k_fx[n] ); +#else wb_bwe_enc_ivas_fx( st, new_inp_resamp16k_fx[n] ); +#endif } /*---------------------------------------------------------------------* @@ -762,7 +766,11 @@ ivas_error ivas_core_enc_fx( ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) ) { /* SWB(FB) BWE encoder */ +#ifdef HARM_FD_BWE + swb_bwe_enc_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, st->q_inp, shb_speech_fx, 0, sub( Q_new[n], 1 ) ); +#else swb_bwe_enc_ivas_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, st->q_inp, shb_speech_fx, sub( Q_new[n], 1 ) ); +#endif } Scale_sig( old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q1, Q_new[n] ) ); // Q0 diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index ec0447a82a4f5f767f1d6ad600bffda3cf424ee5..a6a63e5dea2c3dd2bb71a77199cc79ac86914dd0 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -560,6 +560,7 @@ void StableHighPitchDetect_fx( Word16 EspecdB[] ); void swb_bwe_enc_fx( +#ifndef HARM_FD_BWE Encoder_State *st_fx, /* i/o: encoder state structure */ Word16 *old_input_12k8_fx, /* i : i signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : i signal @16kHz for SWB BWE */ @@ -571,6 +572,7 @@ void swb_bwe_enc_fx( Word16 Q_slb_speech ); void swb_bwe_enc_ivas_fx( +#endif Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ @@ -579,7 +581,12 @@ void swb_bwe_enc_ivas_fx( const Word16 *new_swb_speech_fx, /* i : original input signal at 32kHz */ const Word16 Q_new_swb_speech, /* i : Q for new_swb_speech_fx */ Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ +#ifdef HARM_FD_BWE + Word16 Q_shb_speech, + Word16 Q_slb_speech ); +#else const Word16 Q_slb_speech ); +#endif void swb_CNG_enc_fx( Encoder_State *st_fx, /* i/o: State structure */ @@ -682,12 +689,14 @@ void vad_param_updt_fx( ); void wb_bwe_enc_fx( +#ifndef HARM_FD_BWE Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 *new_wb_speech_fx, /* i : original i signal at 16kHz */ Word16 coder_type /* i : coding type */ ); void wb_bwe_enc_ivas_fx( +#endif Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 *new_wb_speech_fx /* i : original i signal at 16kHz */ ); @@ -996,23 +1005,6 @@ void set_bw_stereo_fx( CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structures */ ); -/* o : classification of wb signal */ -Word16 WB_BWE_encoding_fx( - const Word16 coder_type, /* i : coder type */ - const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ - Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ - Encoder_State *st_fx, /* i/o: Encoder structure */ - Word16 Q_synth, - Word16 Q_synth_lf ); - -/* o : classification of wb signal */ -Word16 WB_BWE_encoding_ivas_fx( - Encoder_State *st_fx, /* i/o: Encoder structure */ - const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ - Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ - Word16 Q_synth, - Word16 Q_synth_lf ); - void calculate_hangover_attenuation_gain_fx( Encoder_State *st, /* i : encoder state structure */ Word16 *att, /* o : attenuation factor */ diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 8dfd67076144aedb036372781aa67da3cd9a71b9..05802bf45c605f2fc23a5fd455e4b4fae6b6a304 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -11,9 +11,29 @@ #include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* - * Local functions + * Local functions declarations *---------------------------------------------------------------------*/ +#ifdef HARM_FD_BWE +static Word16 WB_BWE_encoding_fx( Encoder_State *st_fx, const Word32 *yos_fx, Word16 *WB_fenv_fx, Word16 Q_synth, const Word16 Q_synth_lf ); + +static Word16 SWB_BWE_encoding_fx( Encoder_State *st_fx, Word16 *insig_fx, const Word16 *insig_lp_fx, const Word16 *insig_hp_fx, const Word16 *synth_fx, const Word16 *yos_fx_16, const Word32 *yos_fx, Word16 *SWB_fenv_fx, const Word16 tilt_nb_fx, const Word16 st_offset, const Word16 Q_insig_lp, const Word16 Q_shb, const Word16 Q_synth, const Word16 Q_synth_lf ); +#else +static Word16 WB_BWE_encoding_fx( + const Word16 coder_type, /* i : coder type */ + const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ + Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ + Encoder_State *st_fx, /* i/o: Encoder structure */ + const Word16 Q_synth, + const Word16 Q_synth_lf ); + +static Word16 WB_BWE_encoding_ivas_fx( + Encoder_State *st_fx, /* i/o: Encoder structure */ + const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ + Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ + Word16 Q_synth, + const Word16 Q_synth_lf ); + static Word16 SWB_BWE_encoding_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ Word16 *insig_fx, /* i/o: delayed original input signal at 32kHz (might be rescaled)*/ @@ -25,10 +45,10 @@ static Word16 SWB_BWE_encoding_fx( const Word16 tilt_nb_fx, /* i : SWB tilt */ const Word16 st_offset, /* i : start frequency offset for BWE envelope */ const Word16 coder_type, /* i : coding type */ - Word16 Q_insig_lp, - Word16 Q_shb, - Word16 Q_synth, - Word16 Q_synth_lf ); + const Word16 Q_insig_lp, + const Word16 Q_shb, + const Word16 Q_synth, + const Word16 Q_synth_lf ); static Word16 SWB_BWE_encoding_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ @@ -40,17 +60,25 @@ static Word16 SWB_BWE_encoding_ivas_fx( Word16 *SWB_fenv_fx, /* o : frequency-domain quantized BWE envelope */ const Word16 tilt_nb_fx, /* i : SWB tilt */ const Word16 st_offset, /* i : start frequency offset for BWE envelope */ - Word16 Q_insig_lp, - Word16 Q_shb, - Word16 Q_synth, - Word16 Q_synth_lf ); + const Word16 Q_insig_lp, + const Word16 Q_shb, + const Word16 Q_synth, + const Word16 Q_synth_lf ); +#endif + + +/*-------------------------------------------------------------------* + * delay_input_signal_fx() + * + * + *-------------------------------------------------------------------*/ static void delay_input_signal_fx( Word16 *old_sig, Word16 *cur_sig, Word16 *new_sig, - Word16 m1, - Word16 m2, + const Word16 m1, + const Word16 m2, Word16 *Q_old, Word16 *Q_new ) { @@ -115,6 +143,7 @@ static void delay_input_signal_fx( return; } + /*-------------------------------------------------------------------* * wb_bwe_enc() * @@ -122,6 +151,7 @@ static void delay_input_signal_fx( *-------------------------------------------------------------------*/ void wb_bwe_enc_fx( +#ifndef HARM_FD_BWE Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 *new_wb_speech_fx, /* i : original input signal at 16kHz */ Word16 coder_type /* i : coding type */ @@ -201,6 +231,7 @@ void wb_bwe_enc_fx( *-------------------------------------------------------------------*/ void wb_bwe_enc_ivas_fx( +#endif Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 *new_wb_speech_fx /* i : original input signal at 16kHz */ ) @@ -221,6 +252,7 @@ void wb_bwe_enc_ivas_fx( /*---------------------------------------------------------------------* * Delay the original input signal to be synchronized with ACELP core synthesis *---------------------------------------------------------------------*/ + set16_fx( old_input_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); move16(); @@ -232,22 +264,32 @@ void wb_bwe_enc_ivas_fx( /*---------------------------------------------------------------------*/ /* WB BWE encoding */ - - - /* MDCT of the core synthesis signal */ + /* MDCT of the core synthesis signal */ /*---------------------------------------------------------------------*/ - new_input_fx_exp = -1; + + new_input_fx_exp = -Q1; move16(); +#ifdef HARM_FD_BWE + if ( st_fx->element_mode == EVS_MONO ) + { + new_input_fx_exp = 0; + move16(); + } +#endif wtda_fx( old_input_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, - &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ - L_FRAME16k ); + &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ L_FRAME16k ); /* DCT of the ACELP core synthesis */ direct_transform_fx( L_wtda_synth_fx, yorig_32, 0, L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); +#ifdef HARM_FD_BWE + mode = WB_BWE_encoding_fx( st_fx, yorig_32, WB_fenv_fx, new_input_fx_exp, new_input_fx_exp ); +#else mode = WB_BWE_encoding_ivas_fx( st_fx, yorig_32, WB_fenv_fx, new_input_fx_exp, new_input_fx_exp ); +#endif move16(); + push_indice( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } @@ -257,22 +299,33 @@ void wb_bwe_enc_ivas_fx( return; } + /*-------------------------------------------------------------------* * swb_bwe_enc() * * SWB BWE encoder (only for 32kHz signals) *-------------------------------------------------------------------*/ +#ifdef HARM_FD_BWE +void swb_bwe_enc_fx( +#else void swb_bwe_enc_ivas_fx( +#endif Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 last_element_mode, /* i : last element mode */ - Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ - Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ + const Word16 last_element_mode, /* i : last element mode */ + Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ + Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ const Word16 *new_swb_speech_fx, /* i : original input signal at 32kHz */ const Word16 Q_new_swb_speech, /* i : Q for new_swb_speech_fx */ Word16 *shb_speech_fx_Q0, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ - const Word16 Q_slb_speech ) +#ifdef HARM_FD_BWE + Word16 Q_shb_speech, + Word16 Q_slb_speech +#else + const Word16 Q_slb_speech +#endif +) { Word16 i; Word16 *new_input_fx; @@ -305,13 +358,26 @@ void swb_bwe_enc_ivas_fx( Word16 fb_band_begin; Word16 q_new_input_hp; Word16 shb_speech_fx[L_FRAME16k]; +#ifdef HARM_FD_BWE + Word16 Qenc_synth_hf, Qenc_synth; +#else Word16 Q_shb_speech; +#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; - Q_shb_speech = getScaleFactor16( shb_speech_fx_Q0, L_FRAME16k ); - Copy_Scale_sig( shb_speech_fx_Q0, shb_speech_fx, L_FRAME16k, Q_shb_speech ); // Q0 -> Q_shb_spch +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) + { + Copy( shb_speech_fx_Q0, shb_speech_fx, L_FRAME16k ); + } + ELSE +#endif + { + Q_shb_speech = getScaleFactor16( shb_speech_fx_Q0, L_FRAME16k ); + Copy_Scale_sig( shb_speech_fx_Q0, shb_speech_fx, L_FRAME16k, Q_shb_speech ); // Q0 -> Q_shb_spch + } /*---------------------------------------------------------------------* * Delay the original input signal to be synchronized with ACELP core synthesis @@ -354,230 +420,301 @@ void swb_bwe_enc_ivas_fx( Copy( old_input_12k8_fx + L_INP_MEM - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); Copy( hBWE_TD->old_speech_shb_fx + L_LOOK_16k + L_SUBFR16k - Sample_Delay_HP, new_input_hp_fx, Sample_Delay_HP ); } +#ifndef HARM_FD_BWE } +#endif Copy( hBWE_FD->old_input_lp_fx, old_input_lp_fx, Sample_Delay_LP ); Copy( old_input_12k8_fx + L_INP_MEM, &old_input_lp_fx[Sample_Delay_LP], L_FRAME - Sample_Delay_LP ); Copy( old_input_12k8_fx + L_INP_MEM + L_FRAME - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); +#ifdef HARM_FD_BWE } ELSE { - Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); - } - Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); - IF( st_fx->element_mode > EVS_MONO ) - { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); - Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) - { - Copy( old_input_16k_fx + L_INP_MEM - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); - Copy( hBWE_TD->old_speech_shb_fx + L_LOOK_16k + L_SUBFR16k - Sample_Delay_HP, new_input_hp_fx, Sample_Delay_HP ); - } - } - Copy( hBWE_FD->old_input_lp_fx, old_input_lp_fx, Sample_Delay_LP ); - Copy( old_input_16k_fx + L_INP_MEM, &old_input_lp_fx[Sample_Delay_LP], L_FRAME16k - Sample_Delay_LP ); - Copy( old_input_16k_fx + L_INP_MEM + L_FRAME16k - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + delay_input_signal_fx( hBWE_FD->old_input_lp_fx, old_input_lp_fx, &old_input_12k8_fx[L_INP_MEM], Sample_Delay_LP, L_FRAME, &hBWE_FD->prev_Q_input_lp, &Q_slb_speech ); } - - q_new_input_hp = s_min( Q_shb_speech, hBWE_FD->Q_new_input_hp ); - IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) +#endif +} +ELSE +{ + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - Copy_Scale_sig( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP, sub( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ); // Q_shb_speech - Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); // Q_shb_speech + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); } - ELSE + Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); + IF( st_fx->element_mode > EVS_MONO ) { - Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); // hBWE_FD->Q_new_input_hp - Copy_Scale_sig( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP, sub( hBWE_FD->Q_new_input_hp, Q_shb_speech ) ); // hBWE_FD->Q_new_input_hp - } - - hBWE_FD->Q_new_input_hp = Q_shb_speech; - move16(); - Copy( shb_speech_fx + L_FRAME16k - Sample_Delay_HP, hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); - new_input_fx = old_input_fx + Sample_Delay_SWB_BWE; - Copy( hBWE_FD->old_input_fx, old_input_fx, Sample_Delay_SWB_BWE ); - Copy( new_swb_speech_fx, new_input_fx, inner_frame ); - Copy( old_input_fx + inner_frame, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - /*----------------------------------------------------------------------* - * Calculate tilt of the input signal and the ACELP core synthesis - *----------------------------------------------------------------------*/ - - /* tilt returned in Q24 goto to Q11 */ - tilt_nb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3 ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - /*---------------------------------------------------------------------* - * SWB BWE encoding - * FB BWE encoding - *---------------------------------------------------------------------*/ - new_input_fx_q = Q_new_swb_speech; - move16(); - test(); - IF( ( EQ_16( st_fx->idchan, 1 ) ) && ( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) - { - FOR( i = 0; i < inner_frame; i++ ) + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - hBWE_FD->L_old_wtda_swb_fx[i] = mult_r( hBWE_FD->L_old_wtda_swb_fx[i], div_s( i, inner_frame ) ); - move16(); + Copy( old_input_16k_fx + L_INP_MEM - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + Copy( hBWE_TD->old_speech_shb_fx + L_LOOK_16k + L_SUBFR16k - Sample_Delay_HP, new_input_hp_fx, Sample_Delay_HP ); } +#ifndef HARM_FD_BWE } - /* MDCT of the core synthesis signal */ - wtda_fx( old_input_fx, &new_input_fx_q, L_old_input_fx, hBWE_FD->L_old_wtda_swb_fx, - &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ - inner_frame ); +#endif - /* DCT of the ACELP core synthesis */ - direct_transform_fx( L_old_input_fx, yorig_32, 0, inner_frame, &new_input_fx_q, st_fx->element_mode ); + Copy( hBWE_FD->old_input_lp_fx, old_input_lp_fx, Sample_Delay_LP ); + Copy( old_input_16k_fx + L_INP_MEM, &old_input_lp_fx[Sample_Delay_LP], L_FRAME16k - Sample_Delay_LP ); + Copy( old_input_16k_fx + L_INP_MEM + L_FRAME16k - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); +#ifdef HARM_FD_BWE +} +ELSE +{ + delay_input_signal_fx( hBWE_FD->old_input_lp_fx, old_input_lp_fx, &old_input_16k_fx[L_INP_MEM], Sample_Delay_LP, L_FRAME16k, &hBWE_FD->prev_Q_input_lp, &Q_slb_speech ); +} +#endif +} - /* high-band gain control in case of BWS */ - IF( st_fx->bwidth_sw_cnt > 0 ) - { - v_multc_fx_16( &yorig_32[L_FRAME16k], div_s( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ), &yorig_32[L_FRAME16k], sub( inner_frame, L_FRAME16k ) ); - } +q_new_input_hp = s_min( Q_shb_speech, hBWE_FD->Q_new_input_hp ); +#ifdef HARM_FD_BWE +IF( st_fx->element_mode == EVS_MONO ) +{ + Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); + Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); +} +ELSE IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) +#else + IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) +#endif +{ + Copy_Scale_sig( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP, sub( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ); // Q_shb_speech + Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); // Q_shb_speech +} +ELSE +{ + Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); // hBWE_FD->Q_new_input_hp + Copy_Scale_sig( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP, sub( hBWE_FD->Q_new_input_hp, Q_shb_speech ) ); // hBWE_FD->Q_new_input_hp +} - /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 8, new_input_fx_q ); - /* Possible to Upscale? */ - IF( scl > 0 ) +hBWE_FD->Q_new_input_hp = Q_shb_speech; +move16(); +Copy( shb_speech_fx + L_FRAME16k - Sample_Delay_HP, hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); +new_input_fx = old_input_fx + Sample_Delay_SWB_BWE; +Copy( hBWE_FD->old_input_fx, old_input_fx, Sample_Delay_SWB_BWE ); +Copy( new_swb_speech_fx, new_input_fx, inner_frame ); +Copy( old_input_fx + inner_frame, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + +/*----------------------------------------------------------------------* + * Calculate tilt of the input signal and the ACELP core synthesis + *----------------------------------------------------------------------*/ + +/* tilt returned in Q24 goto to Q11 */ +tilt_nb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3 ) ); + +/*---------------------------------------------------------------------* + * SWB BWE encoding + * FB BWE encoding + *---------------------------------------------------------------------*/ + +new_input_fx_q = Q_new_swb_speech; +move16(); + +test(); +IF( ( EQ_16( st_fx->idchan, 1 ) ) && ( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) +{ + FOR( i = 0; i < inner_frame; i++ ) { - /* Yes */ - /* Calc Room to Upscale */ - Q_synth = Find_Max_Norm32( yorig_32, inner_frame ); - /* Stay within MAX_Q_NEW_INPUT */ - scl = s_min( Q_synth, scl ); + hBWE_FD->L_old_wtda_swb_fx[i] = mult_r( hBWE_FD->L_old_wtda_swb_fx[i], div_s( i, inner_frame ) ); + move16(); } - Copy_Scale_sig32_16( yorig_32, yorig_fx, inner_frame, scl ); - Q_synth = add( sub( new_input_fx_q, 16 ), scl ); - max = 0; +} + +/* MDCT of the core synthesis signal */ +wtda_fx( old_input_fx, &new_input_fx_q, L_old_input_fx, hBWE_FD->L_old_wtda_swb_fx, &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ inner_frame ); + +/* DCT of the ACELP core synthesis */ +direct_transform_fx( L_old_input_fx, yorig_32, 0, inner_frame, &new_input_fx_q, st_fx->element_mode ); + +/* high-band gain control in case of BWS */ +#ifdef HARM_FD_BWE +test(); +IF( st_fx->bwidth_sw_cnt > 0 && st_fx->element_mode > EVS_MONO ) +#else + IF( st_fx->bwidth_sw_cnt > 0 ) +#endif +{ + v_multc_fx_16( &yorig_32[L_FRAME16k], div_s( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ), &yorig_32[L_FRAME16k], sub( inner_frame, L_FRAME16k ) ); +} + +/* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ +scl = sub( 16 + 8, new_input_fx_q ); +/* Possible to Upscale? */ +IF( scl > 0 ) +{ + /* Yes */ + /* Calc Room to Upscale */ + Q_synth = Find_Max_Norm32( yorig_32, inner_frame ); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min( Q_synth, scl ); +} +Copy_Scale_sig32_16( yorig_32, yorig_fx, inner_frame, scl ); +Q_synth = add( sub( new_input_fx_q, 16 ), scl ); +max = 0; +move16(); +Q_synth_hf = 0; +move16(); +IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) +{ + scl = 300; move16(); - Q_synth_hf = 0; +} +ELSE +{ + scl = 240; move16(); - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - scl = 300; - move16(); - } - ELSE - { - scl = 240; - move16(); - } - FOR( i = scl; i < inner_frame; i++ ) - { - max = s_max( max, abs_s( yorig_fx[i] ) ); - } +} +FOR( i = scl; i < inner_frame; i++ ) +{ + max = s_max( max, abs_s( yorig_fx[i] ) ); +} - IF( max == 0 ) +IF( max == 0 ) +{ + exp = 15; + move16(); +} +ELSE +{ + exp = norm_s( max ); +} +Copy_Scale_sig( &yorig_fx[scl], &yorig_fx[scl], sub( inner_frame, scl ), exp ); +Q_synth_hf = add( exp, Q_synth ); + +test(); +IF( EQ_16( st_fx->last_extl, SWB_BWE ) || EQ_16( st_fx->last_extl, FB_BWE ) ) +{ + exp = norm_l( st_fx->EnergyLT_fx ); + IF( GT_16( add( st_fx->EnergyLT_fx_exp, exp ), shl( sub( Q_synth_hf, 4 ), 1 ) ) ) { - exp = 15; - move16(); + Q_shb = sub( Q_synth_hf, 4 ); + st_fx->EnergyLT_fx = L_shr( st_fx->EnergyLT_fx, sub( st_fx->EnergyLT_fx_exp, shl( Q_shb, 1 ) ) ); + move32(); } ELSE { - exp = norm_s( max ); - } - Copy_Scale_sig( &yorig_fx[scl], &yorig_fx[scl], sub( inner_frame, scl ), exp ); - Q_synth_hf = add( exp, Q_synth ); - - test(); - IF( EQ_16( st_fx->last_extl, SWB_BWE ) || EQ_16( st_fx->last_extl, FB_BWE ) ) - { - exp = norm_l( st_fx->EnergyLT_fx ); - IF( GT_16( add( st_fx->EnergyLT_fx_exp, exp ), shl( sub( Q_synth_hf, 4 ), 1 ) ) ) - { - Q_shb = sub( Q_synth_hf, 4 ); - st_fx->EnergyLT_fx = L_shr( st_fx->EnergyLT_fx, sub( st_fx->EnergyLT_fx_exp, shl( Q_shb, 1 ) ) ); - move32(); - } - ELSE + Q_shb = shr( add( st_fx->EnergyLT_fx_exp, exp ), 1 ); + if ( EQ_16( s_and( exp, 0x0001 ), 1 ) ) { - Q_shb = shr( add( st_fx->EnergyLT_fx_exp, exp ), 1 ); - if ( EQ_16( s_and( exp, 0x0001 ), 1 ) ) - { - exp = sub( exp, 1 ); - } - st_fx->EnergyLT_fx = L_shl( st_fx->EnergyLT_fx, exp ); - move32(); + exp = sub( exp, 1 ); } + st_fx->EnergyLT_fx = L_shl( st_fx->EnergyLT_fx, exp ); + move32(); } - ELSE - { - Q_shb = sub( Q_synth_hf, 4 ); - } +} +ELSE +{ + Q_shb = sub( Q_synth_hf, 4 ); +} + +#ifdef HARM_FD_BWE +IF( st_fx->element_mode == EVS_MONO ) +{ + Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, Q_shb_speech ) ); + + Qenc_synth_hf = Q_synth_hf; + Qenc_synth = Q_synth; + move16(); + move16(); +} +ELSE +{ Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, q_new_input_hp ) ); - /* FB BWE encoding */ - IF( EQ_16( st_fx->extl, FB_BWE ) ) - { - fb_band_begin = FB_BAND_BEGIN; - move16(); - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - move16(); - } - energy_fbe_fb_fx = L_deposit_l( 0 ); - FOR( i = fb_band_begin; i < FB_BAND_END; i++ ) - { - tmp = shr( yorig_fx[i], 4 ); - energy_fbe_fb_fx = L_mac0( energy_fbe_fb_fx, tmp, tmp ); /*2*(Q_synth_hf-4) */ - } - ener_low_fx = 0; - move16(); - FOR( i = fb_band_begin - FB_BAND_WIDTH; i < fb_band_begin; i++ ) - { - tmp = shr( yorig_fx[i], 4 ); - ener_low_fx = L_mac0( ener_low_fx, tmp, tmp ); /*2*(Q_synth_hf-4) */ - } + Qenc_synth_hf = new_input_fx_q; + Qenc_synth = new_input_fx_q; + move16(); + move16(); +} - IF( energy_fbe_fb_fx != 0 ) - { - exp = norm_l( energy_fbe_fb_fx ); - frac = extract_h( L_shl( energy_fbe_fb_fx, exp ) ); - tmp = div_s( 16384, frac ); /*15+14-(exp+2*(Q_synth_hf-4)-16) -->45-(exp+2*(Q_synth_hf-4)) */ - L_tmp = Mult_32_16( ener_low_fx, tmp ); /*45-(exp+2*(Q_synth_hf-4)) + 2*(Q_synth_hf-4) - 15 = 30-exp */ - exp1 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp1 ); - exp = sub( sub( 31, exp1 ), sub( 30, exp ) ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ - fb_ener_adjust_fx = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ - } - ELSE - { - fb_ener_adjust_fx = 0; - move16(); - } +/* SWB BWE encoding */ +IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) +{ + SWB_BWE_encoding_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_fx, yorig_32, + SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, Qenc_synth_hf, Qenc_synth ); +} +ELSE +{ + SWB_BWE_encoding_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_fx, yorig_32, + SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, Qenc_synth_hf, Qenc_synth ); +} +#else + Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, q_new_input_hp ) ); +#endif - fb_ener_adjust_fx = s_min( fb_ener_adjust_fx, 16384 ); /*Q15 */ - idxGain = usquant_fx( fb_ener_adjust_fx, &ener_adjust_quan_fx, 0, 512, shl( 1, NUM_BITS_FB_FRAMEGAIN ) ); +/* FB BWE encoding */ +IF( EQ_16( st_fx->extl, FB_BWE ) ) +{ + fb_band_begin = FB_BAND_BEGIN; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + fb_band_begin = FB_BAND_BEGIN_12k8; + move16(); + } + energy_fbe_fb_fx = L_deposit_l( 0 ); + FOR( i = fb_band_begin; i < FB_BAND_END; i++ ) + { + tmp = shr( yorig_fx[i], 4 ); + energy_fbe_fb_fx = L_mac0( energy_fbe_fb_fx, tmp, tmp ); /*2*(Q_synth_hf-4) */ + } + ener_low_fx = 0; + move16(); + FOR( i = fb_band_begin - FB_BAND_WIDTH; i < fb_band_begin; i++ ) + { + tmp = shr( yorig_fx[i], 4 ); + ener_low_fx = L_mac0( ener_low_fx, tmp, tmp ); /*2*(Q_synth_hf-4) */ } - /* SWB BWE encoding */ - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + IF( energy_fbe_fb_fx != 0 ) { - SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); + exp = norm_l( energy_fbe_fb_fx ); + frac = extract_h( L_shl( energy_fbe_fb_fx, exp ) ); + tmp = div_s( 16384, frac ); /*15+14-(exp+2*(Q_synth_hf-4)-16) -->45-(exp+2*(Q_synth_hf-4)) */ + L_tmp = Mult_32_16( ener_low_fx, tmp ); /*45-(exp+2*(Q_synth_hf-4)) + 2*(Q_synth_hf-4) - 15 = 30-exp */ + exp1 = norm_l( L_tmp ); + L_tmp = L_shl( L_tmp, exp1 ); + exp = sub( sub( 31, exp1 ), sub( 30, exp ) ); + L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ + fb_ener_adjust_fx = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ } ELSE { - SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); + fb_ener_adjust_fx = 0; + move16(); } + fb_ener_adjust_fx = s_min( fb_ener_adjust_fx, 16384 ); /*Q15 */ + idxGain = usquant_fx( fb_ener_adjust_fx, &ener_adjust_quan_fx, 0, 512, shl( 1, NUM_BITS_FB_FRAMEGAIN ) ); +} - /* write FB BWE frame gain to the bitstream */ - IF( EQ_16( st_fx->extl, FB_BWE ) ) - { - push_indice( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); - } +#ifndef HARM_FD_BWE +/* SWB BWE encoding */ +IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) +{ + SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, + SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); +} +ELSE +{ + SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, + SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); +} - return; +#endif +/* write FB BWE frame gain to the bitstream */ +IF( EQ_16( st_fx->extl, FB_BWE ) ) +{ + push_indice( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); +} + +return; } +#ifndef HARM_FD_BWE /*-------------------------------------------------------------------* * swb_bwe_enc() * @@ -823,33 +960,35 @@ void swb_bwe_enc_fx( return; } - +#endif /*==========================================================================*/ -/* FUNCTION : static Word16 WB_BWE_fenv_q_fx() */ +/* FUNCTION : static Word16 WB_BWE_fenv_q_fx() */ /*--------------------------------------------------------------------------*/ -/* PURPOSE : Scalar quantizer routine */ +/* PURPOSE : Scalar quantizer routine */ /*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* Word16 *cb i: quantizer codebook Q10 */ -/* Word16 cb_length i: length of codebook */ -/* Word16 cb_dim i: dimension of codebook */ +/* INPUT ARGUMENTS : */ +/* Word16 *cb i: quantizer codebook Q10 */ +/* Word16 cb_length i: length of codebook */ +/* Word16 cb_dim i: dimension of codebook */ /*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ +/* OUTPUT ARGUMENTS : */ /*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Word16 *x i/o: energy of WB envelop Q10 */ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Word16 *x i/o: energy of WB envelop Q10 */ /*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ +/* RETURN ARGUMENTS : */ +/* _ None */ /*--------------------------------------------------------------------------*/ -/* */ +/* */ /*==========================================================================*/ -static Word16 WB_BWE_fenv_q_fx( /* o: quantized gain index */ - Word16 *x, /* i/o: energy of WB envelop Q10*/ - const Word16 *cb, /* i: quantizer codebook Q10 */ - const Word16 cb_length, /* i: length of codebook */ - const Word16 cb_dim /* i: dimension of codebook */ + +/* o: quantized gain index */ +static Word16 WB_BWE_fenv_q_fx( + Word16 *x, /* i/o: energy of WB envelop Q10*/ + const Word16 *cb, /* i : quantizer codebook Q10*/ + const Word16 cb_length, /* i : length of codebook */ + const Word16 cb_dim /* i : dimension of codebook */ ) { Word16 i, j, indx = 0; @@ -890,6 +1029,13 @@ static Word16 WB_BWE_fenv_q_fx( /* o: quantized gain i return ( indx ); } + +/*-------------------------------------------------------------------* + * get_normalize_spec_fx() + * + * + *-------------------------------------------------------------------*/ + static void get_normalize_spec_fx( const Word16 core, /* i : core selected */ const Word16 extl, /* i : extension layer selected */ @@ -983,13 +1129,14 @@ static void get_normalize_spec_fx( * classify signal of above 6.4kHz, can be used for WB/SWB switch *-------------------------------------------------------------------*/ -static Word16 FD_BWE_class_fx( /* o : FD BWE class */ - const Word16 *fSpectrum, /* i : input spectrum */ - const Word32 fGain, /* i : global gain */ - const Word16 tilt_nb, /* i : BWE tilt */ - Word16 Q_syn, - Word16 Q_shb, - Encoder_State *st_fx /* i/o: Encoder structure */ +/* o: FD BWE class */ +static Word16 FD_BWE_class_fx( + const Word16 *fSpectrum, /* i : input spectrum */ + const Word32 fGain, /* i : global gain */ + const Word16 tilt_nb, /* i : BWE tilt */ + const Word16 Q_syn, + const Word16 Q_shb, + Encoder_State *st_fx /* i/o: Encoder structure */ ) { Word16 i, j, k, noise, sharpMod = 0; @@ -1261,6 +1408,7 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class * freq_weights_fx() * *-------------------------------------------------------------------*/ + static void freq_weights_fx( const Word16 Band_Ener[], /* i : Band energy Q8 */ const Word16 f_weighting[], /* i : weigting coefs. Q15 */ @@ -1329,6 +1477,7 @@ static void freq_weights_fx( * vqWithCand_w_fx() * *-------------------------------------------------------------------*/ + static void vqWithCand_w_fx( const Word16 *x, /* i : input vector Q8 */ const Word16 *E_ROM_dico, /* i : codebook Q8 */ @@ -1524,7 +1673,6 @@ static Word16 vqSimple_w_fx( } } - /* Reading the selected vector */ Copy( &cb[index * dim], y, dim ); @@ -1536,11 +1684,11 @@ static Word16 vqSimple_w_fx( * MSVQ_Interpol_Tran_fx() * *-------------------------------------------------------------------*/ + static void MSVQ_Interpol_Tran_fx( - Word16 *SWB_env_energy, /* i/o : (original/quantized) energy Q8 */ - Word16 *indice /* o : quantized index */ + Word16 *SWB_env_energy, /* i/o: (original/quantized) energy Q8 */ + Word16 *indice /* o : quantized index */ ) - { Word16 k, n_band, candInd[N_CAND_TR], ind_tmp[2], tmp; Word16 env_temp11[SWB_FENV_TRANS / 2], env_temp12[SWB_FENV_TRANS / 2]; @@ -1622,6 +1770,7 @@ static void MSVQ_Interpol_Tran_fx( move16(); } } + return; } @@ -1757,6 +1906,7 @@ static void msvq_interpol_fx( * msvq_interpol_2_fx() * *-------------------------------------------------------------------*/ + static void msvq_interpol_2_fx( Word16 *hq_generic_fenv, /* i/o: (original/quantized) energy */ const Word16 *w_env, /* i : weighting coffecients */ @@ -1901,11 +2051,14 @@ static void msvq_interpol_2_fx( *-------------------------------------------------------------------*/ static void calculate_Tonality_fx( - const Word16 *org, /* i : MDCT coefficients of original Q_new*/ - const Word16 *gen, /* i : MDCT coefficients of generated signal Q15*/ - Word16 *SFM_org, /* o : Spectral Flatness results Q12*/ - Word16 *SFM_gen, /* o : Spectral Flatness results Q12*/ - const Word16 length /* i : length for calculating tonality */ +#ifdef HARM_FD_BWE + const Word16 element_mode, /* i : element mode */ +#endif + const Word16 *org, /* i : MDCT coefficients of original Q_new*/ + const Word16 *gen, /* i : MDCT coefficients of generated signal Q15*/ + Word16 *SFM_org, /* o : Spectral Flatness results Q12*/ + Word16 *SFM_gen, /* o : Spectral Flatness results Q12*/ + const Word16 length /* i : length for calculating tonality */ ) { Word16 n_coeff; @@ -1942,19 +2095,40 @@ static void calculate_Tonality_fx( } } +#ifdef HARM_FD_BWE max = 0; move16(); - FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) + IF( element_mode == EVS_MONO ) { - gen_spec[n_coeff] = abs_s( gen[n_coeff] ); - move16(); /*Q15 */ - /*test(); - if( sub(max,gen_spec[n_coeff]) < 0) +#endif + FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) { - max = gen_spec[n_coeff];move16(); - }*/ - max = s_max( max, org_spec[n_coeff] ); + gen_spec[n_coeff] = abs_s( gen[n_coeff] ); + move16(); /*Q15 */ + /*test(); + if( sub(max,gen_spec[n_coeff]) < 0) + { + max = gen_spec[n_coeff];move16(); + }*/ + max = s_max( max, org_spec[n_coeff] ); + } +#ifdef HARM_FD_BWE } + ELSE + { + FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) + { + gen_spec[n_coeff] = abs_s( gen[n_coeff] ); + move16(); /*Q15 */ + /*test(); + if( sub(max,gen_spec[n_coeff]) < 0) + { + max = gen_spec[n_coeff];move16(); + }*/ + max = s_max( max, gen_spec[n_coeff] ); + } + } +#endif l_shift = norm_s( max ); FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) { @@ -2048,6 +2222,7 @@ static void calculate_Tonality_fx( return; } +#ifndef HARM_FD_BWE /*-------------------------------------------------------------------* * calculate_Tonality_ivas_fx() * @@ -2201,6 +2376,7 @@ static void calculate_Tonality_ivas_fx( return; } +#endif /*-------------------------------------------------------------------* * energy_control_fx() @@ -2272,8 +2448,13 @@ static void energy_control_fx( FOR( n_band = 0; n_band < max_band; ) { - calculate_Tonality_fx( org_fx + swb_bwe_subband[n_band] + offset, SWB_signal_fx + swb_bwe_subband[n_band] + offset, +#ifdef HARM_FD_BWE + calculate_Tonality_fx( st_fx->element_mode, org_fx + swb_bwe_subband[n_band] + offset, SWB_signal_fx + swb_bwe_subband[n_band] + offset, &SFM_org_fx[n_band], &SFM_gen_fx[n_band], swb_bwe_subband[n_band + band_step] - swb_bwe_subband[n_band] ); +#else + calculate_Tonality_fx( org_fx + swb_bwe_subband[n_band] + offset, SWB_signal_fx + swb_bwe_subband[n_band] + offset, + &SFM_org_fx[n_band], &SFM_gen_fx[n_band], swb_bwe_subband[n_band + band_step] - swb_bwe_subband[n_band] ); +#endif IF( LT_16( SFM_gen_fx[n_band], mult_r( 24576, SFM_org_fx[n_band] ) ) ) { @@ -2291,9 +2472,11 @@ static void energy_control_fx( } n_band = add( n_band, band_step ); } + return; } +#ifndef HARM_FD_BWE /*-------------------------------------------------------------------* * energy_control_ivas_fx() * @@ -2386,6 +2569,7 @@ static void energy_control_ivas_fx( } return; } +#endif /*-------------------------------------------------------------------* * WB_BWE_encoding() @@ -2393,13 +2577,15 @@ static void energy_control_ivas_fx( * WB BWE main encoder *-------------------------------------------------------------------*/ -Word16 WB_BWE_encoding_fx( /* o : classification of wb signal */ - const Word16 coder_type, /* i : coder type */ - const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ - Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ - Encoder_State *st_fx, /* i/o: Encoder structure */ - Word16 Q_synth, - Word16 Q_synth_lf ) +/* o : classification of wb signal */ +static Word16 WB_BWE_encoding_fx( +#ifndef HARM_FD_BWE + const Word16 coder_type, /* i : coder type */ + const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ + Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ + Encoder_State *st_fx, /* i/o: Encoder structure */ + const Word16 Q_synth, + const Word16 Q_synth_lf ) { Word16 mode; Word16 i, n_coeff, n_band; @@ -2459,17 +2645,19 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb } /*-------------------------------------------------------------------* - * WB_BWE_encoding_ivas() + * WB_BWE_encoding() * * WB BWE main encoder *-------------------------------------------------------------------*/ -Word16 WB_BWE_encoding_ivas_fx( /* o : classification of wb signal */ - Encoder_State *st_fx, /* i/o: Encoder structure */ - const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ - Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ - Word16 Q_synth, - Word16 Q_synth_lf ) +/* o : classification of wb signal */ +static Word16 WB_BWE_encoding_ivas_fx( +#endif + Encoder_State *st_fx, /* i/o: Encoder structure */ + const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ + Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ + Word16 Q_synth, + const Word16 Q_synth_lf ) { Word16 mode; Word16 i, n_coeff, n_band; @@ -2484,46 +2672,115 @@ Word16 WB_BWE_encoding_ivas_fx( /* o : classification of Word16 q_shift, scale; Word16 q_WB_fenv[2]; Word16 yos_fx_16[L_FRAME16k]; - n_band = 0; - move16(); - FOR( i = 0; i < 2; i++ ) +#ifdef HARM_FD_BWE + Word16 Q_class, Q_energy, Q_fenv[2]; + + IF( st_fx->element_mode == EVS_MONO ) { - energy_fx_64 = 0; - move64(); - FOR( n_coeff = swb_bwe_subband[n_band]; n_coeff < swb_bwe_subband[n_band + 2]; n_coeff++ ) + Word16 new_input_fx_exp = Q_synth; + + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scale = sub( 16 + 8 /*MAX_Q_NEW_INPUT*/, new_input_fx_exp ); + + /* Possible to Upscale? */ + IF( scale > 0 ) { - energy_fx_64 = W_add( energy_fx_64, W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ) ); /*2*Q_synth*/ + /* Yes */ + /* Calc Room to Upscale */ + Q_synth = Find_Max_Norm32( yos_fx, L_FRAME16k ); + + /* Stay within MAX_Q_NEW_INPUT */ + scale = s_min( Q_synth, scale ); } - q_shift = W_norm( energy_fx_64 ); - energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ - q_shift = sub( q_shift, 32 ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, L_FRAME16k, scale ); + Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scale ), 1 ); - L_WB_fenv_fx[i] = energy_fx; - move32(); - q_WB_fenv[i] = add( shl( Q_synth, 1 ), q_shift ); + n_band = 0; + move16(); + FOR( i = 0; i < 2; i++ ) + { + energy_fx = L_deposit_l( 0 ); + FOR( n_coeff = swb_bwe_subband[n_band]; n_coeff < swb_bwe_subband[n_band + 2]; n_coeff++ ) + { + energy_fx = L_add( energy_fx, L_shr( L_mult0( yos_fx_16[n_coeff], yos_fx_16[n_coeff] ), 6 ) ); /*2*Q_synth-6 */ + } + + L_WB_fenv_fx[i] = energy_fx; + move32(); /*2*Q_synth-6 */ + n_band = add( n_band, 2 ); + } + + Q_class = Q_synth; + Q_energy = Q_synth; + move16(); + move16(); + Q_fenv[0] = Q_fenv[1] = sub( shl( Q_synth, 1 ), 2 ); move16(); - n_band = add( n_band, 2 ); } + ELSE +#endif + { + n_band = 0; + move16(); + FOR( i = 0; i < 2; i++ ) + { + energy_fx_64 = 0; + move64(); + FOR( n_coeff = swb_bwe_subband[n_band]; n_coeff < swb_bwe_subband[n_band + 2]; n_coeff++ ) + { + energy_fx_64 = W_add( energy_fx_64, W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ) ); /*2*Q_synth*/ + } + q_shift = W_norm( energy_fx_64 ); + energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ + q_shift = sub( q_shift, 32 ); + + L_WB_fenv_fx[i] = energy_fx; + move32(); + q_WB_fenv[i] = add( shl( Q_synth, 1 ), q_shift ); + move16(); + n_band = add( n_band, 2 ); - scale = s_min( L_norm_arr( yos_fx, L_FRAME16k ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); - Copy_Scale_sig32_16( yos_fx, yos_fx_16, L_FRAME16k, scale ); +#ifdef HARM_FD_BWE + Q_fenv[i] = add( q_WB_fenv[i], 4 ); +#endif + } + + scale = s_min( L_norm_arr( yos_fx, L_FRAME16k ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, L_FRAME16k, scale ); +#ifdef HARM_FD_BWE + Q_class = sub( add( Q_synth, scale ), Q16 ); + Q_energy = sub( add( Q_synth_lf, scale ), Q16 ); +#endif + } - mode = FD_BWE_class_fx( yos_fx_16, 0, 0, sub( add( Q_synth, scale ), Q16 ), 0, st_fx ); +#ifdef HARM_FD_BWE + mode = FD_BWE_class_fx( yos_fx_16, 0, 0, Q_class, 0, st_fx ); +#else + mode = FD_BWE_class_fx( yos_fx_16, 0, 0, sub( add( Q_synth, scale ), Q16 ), 0, st_fx ); +#endif - energy_control_ivas_fx( st_fx, ACELP_CORE, mode, st_fx->coder_type, yos_fx_16, 0, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); +#ifdef HARM_FD_BWE + energy_control_fx( st_fx, ACELP_CORE, mode, st_fx->coder_type, yos_fx_16, 0, energy_factor_fx, Q_energy ); +#else + energy_control_ivas_fx( st_fx, ACELP_CORE, mode, st_fx->coder_type, yos_fx_16, 0, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); +#endif FOR( i = 0; i < 2; i++ ) { - ener_40 = mult_r( shr( energy_factor_fx[shl( i, 1 )], 1 ), 26214 ); /*Q19 */ - L_tmp = Mpy_32_16_1( L_WB_fenv_fx[i], ener_40 ); /*q_WB_fenv[i]+4 */ + ener_40 = mult_r( shr( energy_factor_fx[shl( i, 1 )], 1 ), 26214 ); /* Q19 */ + L_tmp = Mpy_32_16_1( L_WB_fenv_fx[i], ener_40 ); /* 2*Q_synth-2 / q_WB_fenv[i]+4 */ IF( L_tmp ) { exp = norm_l( L_tmp ); tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); - /*exp = 30-exp-(q_WB_fenv[i]+4); */ - exp = sub( sub( 30, exp ), ( add( q_WB_fenv[i], 4 ) ) ); + /* exp = 30-exp-(2*Q_synth-2 / exp = 30-exp-(q_WB_fenv[i]+4) */ +#ifdef HARM_FD_BWE + exp = sub( sub( 30, exp ), Q_fenv[i] ); +#else + exp = sub( sub( 30, exp ), ( add( q_WB_fenv[i], 4 ) ) ); +#endif L_tmp = Mpy_32_16( exp, tmp, 32767 ); /* Q16 */ - WB_fenv_fx[i] = round_fx( L_shl( L_tmp, 10 ) ); /*Q10 */ + WB_fenv_fx[i] = round_fx( L_shl( L_tmp, 10 ) ); /* Q10 */ move16(); } ELSE @@ -2545,7 +2802,9 @@ Word16 WB_BWE_encoding_ivas_fx( /* o : classification of * * SWB BWE encoder *-------------------------------------------------------------------*/ + static Word16 SWB_BWE_encoding_fx( +#ifndef HARM_FD_BWE Encoder_State *st_fx, /* i/o: encoder state structure */ Word16 *insig_fx, /* i : delayed original input signal at 32kHz */ const Word16 *insig_lp_fx, /* i : delayed original lowband input signal at 32kHz */ @@ -2556,10 +2815,10 @@ static Word16 SWB_BWE_encoding_fx( const Word16 tilt_nb_fx, /* i : SWB tilt */ const Word16 st_offset, /* i : start frequency offset for BWE envelope */ const Word16 coder_type, /* i : coding type */ - Word16 Q_insig_lp, - Word16 Q_shb, - Word16 Q_synth, - Word16 Q_synth_lf ) + const Word16 Q_insig_lp, + const Word16 Q_shb, + const Word16 Q_synth, + const Word16 Q_synth_lf ) { Word16 IsTransient, mode; Word16 index; @@ -2982,22 +3241,27 @@ static Word16 SWB_BWE_encoding_fx( /*-------------------------------------------------------------------* * SWB_BWE_encoding() * - * SWB BWE encoder + * SWB BWE encoder, 32-bit variant *-------------------------------------------------------------------*/ + static Word16 SWB_BWE_encoding_ivas_fx( +#endif Encoder_State *st_fx, /* i/o: encoder state structure */ Word16 *insig_fx, /* i : delayed original input signal at 32kHz */ const Word16 *insig_lp_fx, /* i : delayed original lowband input signal at 32kHz */ const Word16 *insig_hp_fx, /* i : delayed original highband input signal at 32kHz */ const Word16 *synth_fx, /* i : delayed ACELP core synthesis at 12.8kHz */ - const Word32 *yos_fx, /* i : MDCT coefficients of the windowed original input signal at 32kHz */ - Word16 *SWB_fenv_fx, /* o : frequency-domain quantized BWE envelope */ - const Word16 tilt_nb_fx, /* i : SWB tilt */ - const Word16 st_offset, /* i : start frequency offset for BWE envelope */ - Word16 Q_insig_lp, - Word16 Q_shb, - Word16 Q_synth, - Word16 Q_synth_lf ) +#ifdef HARM_FD_BWE + const Word16 *yos_fx_16_orig, /* i : 16-bit MDCT coefficients of the windowed original input signal at 32kHz */ +#endif + const Word32 *yos_fx, /* i : 32-bit MDCT coefficients of the windowed original input signal at 32kHz */ + Word16 *SWB_fenv_fx, /* o : frequency-domain quantized BWE envelope */ + const Word16 tilt_nb_fx, /* i : SWB tilt */ + const Word16 st_offset, /* i : start frequency offset for BWE envelope */ + const Word16 Q_insig_lp, + const Word16 Q_shb, + const Word16 Q_synth, + const Word16 Q_synth_lf ) { Word16 IsTransient, mode; Word16 index; @@ -3026,6 +3290,9 @@ static Word16 SWB_BWE_encoding_ivas_fx( Word16 inner_frame; Word16 q_shift; Word16 yos_fx_16[L_FRAME_MAX]; +#ifdef HARM_FD_BWE + Word16 Q_class, Q_energy; +#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -3052,6 +3319,13 @@ static Word16 SWB_BWE_encoding_ivas_fx( move16(); } +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) + { + Copy( yos_fx_16_orig, yos_fx_16, inner_frame ); + } +#endif + /* HF transient detect */ IsTransient = detect_transient_fx( insig_hp_fx, L_FRAME16k, Q_shb, st_fx ); st_fx->EnergyLT_fx_exp = shl( Q_shb, 1 ); @@ -3066,19 +3340,37 @@ static Word16 SWB_BWE_encoding_ivas_fx( energy_fx = L_deposit_l( 0 ); FOR( i = 0; i < L; i++ ) { - energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*Q = 2 * Q_insig_lp - 7 */ + energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*Q = 2*Q_slb_speech - 7 / 2*Q_insig_lp - 7 */ } - if ( BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( energy_fx, 5958 /* 1/5.5f in Q15 */ ), sub( 31 + 7, shl( Q_insig_lp, 1 ) ), hBWE_FD->EnergyLF_fx, hBWE_FD->EnergyLF_exp ) > 0 ) +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) { - IsTransient_LF = 1; + if ( GT_32( Mult_32_16( energy_fx, 5958 ), hBWE_FD->EnergyLF_fx ) ) + { + IsTransient_LF = 1; + move16(); + } + + hBWE_FD->EnergyLF_fx = energy_fx; + hBWE_FD->EnergyLF_exp = sub( 31 + 7, shl( Q_insig_lp, 1 ) ); + move32(); move16(); } + ELSE +#endif + { + if ( BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( energy_fx, 5958 /* 1/5.5f in Q15 */ ), sub( 31 + 7, shl( Q_insig_lp, 1 ) ), hBWE_FD->EnergyLF_fx, hBWE_FD->EnergyLF_exp ) > 0 ) + { + IsTransient_LF = 1; + move16(); + } - hBWE_FD->EnergyLF_fx = energy_fx; - hBWE_FD->EnergyLF_exp = sub( 31 + 7, shl( Q_insig_lp, 1 ) ); - move32(); - move16(); + hBWE_FD->EnergyLF_fx = energy_fx; + hBWE_FD->EnergyLF_exp = sub( 31 + 7, shl( Q_insig_lp, 1 ) ); + move32(); + move16(); + } } /* tilt returned in Q24 go to Q11 */ @@ -3100,48 +3392,87 @@ static Word16 SWB_BWE_encoding_ivas_fx( push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); /* Energy for the different bands and global energies */ - global_gain_fx = L_deposit_l( 0 ); - FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) { - energy_fx_64 = W_deposit32_l( 0 ); - FOR( n_coeff = swb_bwe_trans_subband[n_band] + st_offset; n_coeff < swb_bwe_trans_subband[n_band + 1] + st_offset; n_coeff++ ) + global_gain_fx = L_deposit_l( 0 ); + FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) { - W_tmp = W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ); /*2*Q_synth */ - energy_fx_64 = W_add( W_tmp, energy_fx_64 ); /*2*Q_synth */ + energy_fx = L_deposit_l( 0 ); + FOR( n_coeff = swb_bwe_trans_subband[n_band] + st_offset; n_coeff < swb_bwe_trans_subband[n_band + 1] + st_offset; n_coeff++ ) + { + L_tmp = L_shr( L_mult0( yos_fx_16[n_coeff], yos_fx_16[n_coeff] ), 7 ); /*2*Q_synth-7 */ + energy_fx = L_add( L_tmp, energy_fx ); /*2*Q_synth-7 */ + } + global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( sub( shl( Q_synth, 1 ), 7 ), shl( Q_shb, 1 ) ) ) ); /*2*Q_shb */ + L_SWB_fenv_fx[n_band] = energy_fx; + move32(); } - q_shift = W_norm( energy_fx_64 ); - energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ - q_shift = sub( q_shift, 32 ); - global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( add( shl( Q_synth, 1 ), q_shift ), shl( Q_shb, 1 ) ) ) ); /*2*Q_shb */ - L_SWB_fenv_fx[n_band] = energy_fx; - move32(); - IF( L_SWB_fenv_fx[n_band] == 0 ) + global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ + + FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) { - q_SWB_fenv[n_band] = Q31; - move16(); + expd = norm_s( swb_bwe_trans_subband_width[n_band] ); + tmp = div_s( shl( 1, sub( 14, expd ) ), swb_bwe_trans_subband_width[n_band] ); /*Q(29-expd) */ + L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], tmp ); /*2*Q_synth-7+29-expd - 15 */ + exp = norm_l( L_tmp ); + tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); + exp = sub( sub( 30, exp ), sub( add( shl( Q_synth, 1 ), 7 ), expd ) ); + L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ + tmp = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ + + SWB_fenv_fx[n_band] = sub( tmp, Mean_env_tr_fx[n_band] ); + move16(); /*Q8 */ } - ELSE + } + ELSE +#endif + { + global_gain_fx = L_deposit_l( 0 ); + FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) { - q_SWB_fenv[n_band] = add( shl( Q_synth, 1 ), q_shift ); - move16(); + energy_fx_64 = W_deposit32_l( 0 ); + FOR( n_coeff = swb_bwe_trans_subband[n_band] + st_offset; n_coeff < swb_bwe_trans_subband[n_band + 1] + st_offset; n_coeff++ ) + { + W_tmp = W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ); /*2*Q_synth */ + energy_fx_64 = W_add( W_tmp, energy_fx_64 ); /*2*Q_synth */ + } + q_shift = W_norm( energy_fx_64 ); + energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ + q_shift = sub( q_shift, 32 ); + + global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( add( shl( Q_synth, 1 ), q_shift ), shl( Q_shb, 1 ) ) ) ); /*2*Q_shb */ + L_SWB_fenv_fx[n_band] = energy_fx; + move32(); + IF( L_SWB_fenv_fx[n_band] == 0 ) + { + q_SWB_fenv[n_band] = Q31; + move16(); + } + ELSE + { + q_SWB_fenv[n_band] = add( shl( Q_synth, 1 ), q_shift ); + move16(); + } } - } - global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ - FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) - { - expd = norm_s( swb_bwe_trans_subband_width[n_band] ); - tmp = div_s( shl( 1, sub( 14, expd ) ), swb_bwe_trans_subband_width[n_band] ); /*Q(29-expd) */ - L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], tmp ); /*q_SWB_fenv[n_band]+29-expd - 15 */ - exp = norm_l( L_tmp ); - tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); - exp = sub( sub( 30, exp ), sub( add( q_SWB_fenv[n_band], Q14 ), expd ) ); - L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ - tmp = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ + global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ - SWB_fenv_fx[n_band] = sub( tmp, Mean_env_tr_fx[n_band] ); - move16(); /*Q8 */ + FOR( n_band = 0; n_band < SWB_FENV_TRANS; n_band++ ) + { + expd = norm_s( swb_bwe_trans_subband_width[n_band] ); + tmp = div_s( shl( 1, sub( 14, expd ) ), swb_bwe_trans_subband_width[n_band] ); /*Q(29-expd) */ + L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], tmp ); /*q_SWB_fenv[n_band]+29-expd - 15 */ + exp = norm_l( L_tmp ); + tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); + exp = sub( sub( 30, exp ), sub( add( q_SWB_fenv[n_band], Q14 ), expd ) ); + L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ + tmp = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ + + SWB_fenv_fx[n_band] = sub( tmp, Mean_env_tr_fx[n_band] ); + move16(); /*Q8 */ + } } WB_tenv_orig_fx = L_deposit_l( 0 ); @@ -3188,7 +3519,17 @@ static Word16 SWB_BWE_encoding_ivas_fx( expd = norm_l( WB_tenv_syn_fx ); den = round_fx_sat( L_shl( WB_tenv_syn_fx, expd ) ); - expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); + +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) + { + expd = sub( sub( 30, expd ), sub( shl( st_fx->Q_syn2, 1 ), 7 ) ); + } + ELSE +#endif + { + expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); + } scale = shr( sub( den, num ), 15 ); num = shl( num, scale ); @@ -3381,48 +3722,103 @@ static Word16 SWB_BWE_encoding_ivas_fx( ELSE { /* Energy for the different bands and global energies */ - global_gain_fx = L_deposit_l( 0 ); - FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) { - energy_fx_64 = W_deposit32_l( 0 ); - FOR( n_coeff = swb_bwe_subband[n_band] + st_offset; n_coeff < swb_bwe_subband[n_band + 1] + st_offset; n_coeff++ ) + global_gain_fx = L_deposit_l( 0 ); + FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) { - W_tmp = W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ); /*2*Q_synth */ - energy_fx_64 = W_add( W_tmp, energy_fx_64 ); /*2*Q_synth */ + energy_fx = L_deposit_l( 0 ); + FOR( n_coeff = swb_bwe_subband[n_band] + st_offset; n_coeff < swb_bwe_subband[n_band + 1] + st_offset; n_coeff++ ) + { + L_tmp = L_shr( L_mult0( yos_fx_16[n_coeff], yos_fx_16[n_coeff] ), 5 ); /*2*Q_synth-5 */ + energy_fx = L_add( L_tmp, energy_fx ); /*2*Q_synth-5 */ + } + + IF( LT_16( n_band, sub( SWB_FENV, 2 ) ) ) + { + global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( 2 * Q_synth - 5, 2 * Q_shb ) ) ); /*2*Q_shb */ + } + L_SWB_fenv_fx[n_band] = energy_fx; + move32(); } - q_shift = W_norm( energy_fx_64 ); - energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ - q_shift = sub( q_shift, 32 ); - IF( LT_16( n_band, SWB_FENV - 2 ) ) + Q_class = Q_synth; + Q_energy = Q_synth_lf; + move16(); + move16(); + } + ELSE +#endif + { + global_gain_fx = L_deposit_l( 0 ); + FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) { - global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( add( shl( Q_synth, 1 ), q_shift ), shl( Q_shb, 1 ) ) ) ); /*2*Q_shb */ + energy_fx_64 = W_deposit32_l( 0 ); + FOR( n_coeff = swb_bwe_subband[n_band] + st_offset; n_coeff < swb_bwe_subband[n_band + 1] + st_offset; n_coeff++ ) + { + W_tmp = W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ); /*2*Q_synth */ + energy_fx_64 = W_add( W_tmp, energy_fx_64 ); /*2*Q_synth */ + } + q_shift = W_norm( energy_fx_64 ); + energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ + q_shift = sub( q_shift, 32 ); + + IF( LT_16( n_band, SWB_FENV - 2 ) ) + { + global_gain_fx = L_add( global_gain_fx, L_shr( energy_fx, sub( add( shl( Q_synth, 1 ), q_shift ), shl( Q_shb, 1 ) ) ) ); /*2*Q_shb */ + } + L_SWB_fenv_fx[n_band] = energy_fx; + move32(); + q_SWB_fenv[n_band] = add( shl( Q_synth, 1 ), q_shift ); + move16(); } - L_SWB_fenv_fx[n_band] = energy_fx; - move32(); - q_SWB_fenv[n_band] = add( shl( Q_synth, 1 ), q_shift ); - move16(); + +#ifdef HARM_FD_BWE + scale = s_min( L_norm_arr( yos_fx, inner_frame ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, scale ); + + Q_class = sub( add( Q_synth, scale ), Q16 ); + Q_energy = sub( add( Q_synth_lf, scale ), Q16 ); +#endif } global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ - scale = s_min( L_norm_arr( yos_fx, inner_frame ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); - Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, scale ); - mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( add( Q_synth, scale ), Q16 ), Q_shb, st_fx ); +#ifdef HARM_FD_BWE + mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, Q_class, Q_shb, st_fx ); +#else + scale = s_min( L_norm_arr( yos_fx, inner_frame ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, scale ); + mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( add( Q_synth, scale ), Q16 ), Q_shb, st_fx ); +#endif push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); - energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); +#ifdef HARM_FD_BWE + energy_control_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, Q_energy ); +#else + energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); +#endif FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) { - L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], energy_factor_fx[n_band] ); /*q_SWB_fenv[n_band] */ - L_tmp = Mult_32_16( L_tmp, swb_inv_bwe_subband_width_fx[n_band] ); /*q_SWB_fenv[n_band] */ + L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], energy_factor_fx[n_band] ); /* 2*Q_synth-5 / q_SWB_fenv[n_band] */ + L_tmp = Mult_32_16( L_tmp, swb_inv_bwe_subband_width_fx[n_band] ); /* 2*Q_synth-5 / q_SWB_fenv[n_band] */ IF( L_tmp != 0 ) { expn = norm_l( L_tmp ); tmp = Log2_norm_lc( L_shl( L_tmp, expn ) ); - expn = sub( 30, add( expn, q_SWB_fenv[n_band] ) ); +#ifdef HARM_FD_BWE + IF( st_fx->element_mode == EVS_MONO ) + { + expn = sub( 30, add( expn, sub( shl( Q_synth, 1 ), 5 ) ) ); + } + ELSE +#endif + { + expn = sub( 30, add( expn, q_SWB_fenv[n_band] ) ); + } L_tmp = Mpy_32_16( expn, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ SWB_fenv_fx[n_band] = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ move16(); @@ -3459,6 +3855,8 @@ static Word16 SWB_BWE_encoding_ivas_fx( return mode; } + + /*-------------------------------------------------------------------* * get_normalize_spec_fx_32() * @@ -3555,6 +3953,7 @@ static void get_normalize_spec_fx_32( * calculate_tonality_fx_32() * *-------------------------------------------------------------------*/ + static void calculate_tonality_fx_32( const Word32 *org_fx, /* i : MDCT coefficients of original : Q12 */ const Word32 *gen_fx, /* i : MDCT coefficients of generated signal : Q12 */ @@ -3687,6 +4086,7 @@ static void calculate_tonality_fx_32( * energy_control_fx_32() * *-------------------------------------------------------------------*/ + static void energy_control_fx_32( Encoder_State *st_fx, /* i/o: encoder structure */ const Word16 core, /* i : core : Q0 */ @@ -3788,6 +4188,7 @@ static void energy_control_fx_32( * decision_hq_generic_class_fx_32() * *-------------------------------------------------------------------*/ + static Word16 decision_hq_generic_class_fx_32( const Word32 *coefs_fx, /* i: original MDCT spectrum : Q12 */ const Word16 hq_generic_offset /* i: frequency offset of high frequency spectrum : Q0 */ @@ -3795,7 +4196,6 @@ static Word16 decision_hq_generic_class_fx_32( { Word16 i, k; Word16 nband; - Word16 inv_band_fx; Word32 L_tmp, L_tmp1, L_tmp2; Word16 exp, tmp, tmp2; @@ -3856,7 +4256,8 @@ static Word16 decision_hq_generic_class_fx_32( } } avgp2a_fx = Mult_32_16( avgp2a_fx, inv_band_fx ); /*16 + 15 - 15 */ - IF( GT_32( avgp2a_fx, 187227 ) ) /*8.6 / 10log10(2), Q16 */ + + IF( GT_32( avgp2a_fx, 187227 ) ) /*8.6 / 10log10(2), Q16 */ { return HQ_GENERIC_EXC1; } @@ -3870,6 +4271,7 @@ static Word16 decision_hq_generic_class_fx_32( * hq_generic_encoding_fx() * *-------------------------------------------------------------------*/ + void hq_generic_encoding_fx( const Word32 *coefs_fx, /* i : MDCT coefficients of weighted original : Q12 */ Word16 *hq_generic_fenv_fx, /* i/o: energy of SWB envelope : Q3 */ @@ -3903,7 +4305,6 @@ void hq_generic_encoding_fx( move16(); } - energy_control_fx_32( st_fx, HQ_CORE, -1, -1, coefs_fx, hq_generic_offset, energy_factor_fx ); IF( EQ_16( hHQ_core->hq_generic_speech_class, 1 ) ) @@ -4021,7 +4422,6 @@ void hq_generic_encoding_fx( } } - /* Energy VQ */ IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) { @@ -4069,7 +4469,6 @@ void hq_generic_encoding_fx( move16(); } - IF( EQ_16( st_fx->bwidth, FB ) ) { FOR( n_band = 0; n_band < DIM_FB; n_band++ ) @@ -4088,6 +4487,7 @@ void hq_generic_encoding_fx( return; } + /*-------------------------------------------------------------------* * fd_bwe_enc_init_fx() * @@ -4134,10 +4534,12 @@ void fd_bwe_enc_init_fx( return; } + /*-------------------------------------------------------------------* - * hq_generic_encoding_fx() + * hq_generic_hf_encoding_fx() * *-------------------------------------------------------------------*/ + void hq_generic_hf_encoding_fx( const Word32 *coefs_fx, /* i : MDCT coefficients of weighted original : Q12 */ Word16 *hq_generic_fenv_fx, /* i/o: energy of SWB envelope : Q1 */ @@ -4172,7 +4574,6 @@ void hq_generic_hf_encoding_fx( move16(); } - energy_control_fx_32( st_fx, HQ_CORE, -1, -1, coefs_fx, hq_generic_offset, energy_factor_fx ); IF( EQ_16( hHQ_core->hq_generic_speech_class, 1 ) ) @@ -4290,7 +4691,6 @@ void hq_generic_hf_encoding_fx( } } - /* Energy VQ */ IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) { @@ -4345,7 +4745,6 @@ void hq_generic_hf_encoding_fx( move16(); } - IF( EQ_16( length, L_SPEC48k ) ) { FOR( n_band = 0; n_band < DIM_FB; n_band++ )