diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 9a73e1a01db9c998b17c2f1229fba9158a7443ff..9438ed5b6f903980505b60b0cff810e7429bcb1c 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1529,4 +1529,48 @@ void synchonize_channels_mdct_sid_fx( Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure */ const Word16 n /* i : channel number */ ); + +void ivas_interpolate_3_over_1_allpass_fx( + const Word16 *input_fx, /* i : input signal */ /* Q_input */ + const Word16 len, /* i : number of input samples */ + Word16 *out_fx, /* o : output signal */ /* Q_input */ + Word16 *mem_fx /* i/o: memory */ /* Q_input */ +); + +void ivas_wb_tbe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32 *bwe_exc_extended, /* i : bandwidth extended exciatation 2*Q_exc*/ + const Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + Word16 *synth, /* o : WB synthesis/final synthesis */ + Word16 *Q_synth ); + +void ivas_GenShapedWBExcitation_fx( + Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ + Word32 *mem_csfilt, /* i/o : memory Q_bwe_exc+16*/ + Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q_bwe_exc*/ + Word16 *state_lpc_syn, /* i/o : memory Q_bwe_exc*/ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q_bwe_exc*/ + const Word16 Q_bwe_exc, + Word16 bwe_seed[], /* i/o : random number generator seed */ + const Word16 voice_factors[], /* i : voicing factor Q15*/ + const Word16 uv_flag, /* i : unvoiced flag */ + const Word16 igf_flag ); + +Word16 ivas_wb_bwe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 output[], /* i : suntehsis @ internal Fs */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis */ + 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 */ + const Word16 pitch_buf_fx[], /* i : pitch buffer */ + Word16 *Qpost ); #endif diff --git a/lib_com/modif_fs_fx.c b/lib_com/modif_fs_fx.c index 717c8bbb233ff73aac81da52e53d7adfc4384668..8eb7dff6a5c30fbbc53be93513c0e8eff015102e 100644 --- a/lib_com/modif_fs_fx.c +++ b/lib_com/modif_fs_fx.c @@ -1111,6 +1111,100 @@ void interpolate_3_over_2_allpass_fx( * Interpolate 3/1 using allpass iir polyphase filter. Delay 4 samples @48k *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_interpolate_3_over_1_allpass_fx( + const Word16 *input_fx, /* i : input signal */ /* Q_input */ + const Word16 len, /* i : number of input samples */ + Word16 *out_fx, /* o : output signal */ /* Q_input */ + Word16 *mem_fx /* i/o: memory */ /* Q_input */ +) +{ + /* mem of current frame would be stored in Qinput, so the next call to this function shoulf have Q_mem parameter set to prev_Q_input */ + Word16 i; + Word16 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */ + Word16 *out1; + Word16 mem_temp; + const Word16 *filt_coeff_fx = allpass_poles_3_ov_2; + + out1 = &out_fx[0]; + + FOR( i = 0; i < len; i++ ) + { + /* Upper branch */ + /*Vu[0] = mem[0] + filt_coeff[0] * ( input_fx_temp[i] - mem[1] ); + Vu[1] = mem[1] + filt_coeff[1] * ( Vu[0] - mem[2] ); + mem[3] = mem[2] + filt_coeff[2] * ( Vu[1] - mem[3] );*/ + + Vu[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[0], sub_sat( input_fx[i], mem_fx[1] ) ) ); + move16(); /* all Vu's in : Q_current*/ + Vu[1] = add_sat( mem_fx[1], mult_r( filt_coeff_fx[1], sub_sat( Vu[0], mem_fx[2] ) ) ); + move16(); + mem_fx[3] = add_sat( mem_fx[2], mult_r( filt_coeff_fx[2], sub_sat( Vu[1], mem_fx[3] ) ) ); + move16(); + + + mem_fx[1] = Vu[0]; + move16(); + mem_fx[2] = Vu[1]; + move16(); + *out1++ = mem_fx[3]; + move16(); + + /* Middle branch */ + /* Vm[0] = mem[0] + filt_coeff[3] * (input[i]-mem[4]); + Vm[1] = mem[4] + filt_coeff[4] * (Vm[0]-mem[5]); + mem[6] = mem[5] + filt_coeff[5] * (Vm[1]-mem[6]); */ + Vm[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[3], sub_sat( input_fx[i], mem_fx[4] ) ) ); + move16(); + Vm[1] = add_sat( mem_fx[4], mult_r( filt_coeff_fx[4], sub_sat( Vm[0], mem_fx[5] ) ) ); + move16(); + mem_fx[6] = add_sat( mem_fx[5], mult_r( filt_coeff_fx[5], sub_sat( Vm[1], mem_fx[6] ) ) ); + move16(); + + mem_fx[4] = Vm[0]; + move16(); + mem_fx[5] = Vm[1]; + move16(); + *out1++ = mem_fx[6]; + move16(); + + /* Lower branch */ + /* Vl[0] = mem[0] + filt_coeff[6] * (input[i]-mem[7]); + Vl[1] = mem[7] + filt_coeff[7] * (Vl[0]-mem[8]); + mem[9] = mem[8] + filt_coeff[8] * (Vl[1]-mem[9]); */ + Vl[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[6], sub_sat( input_fx[i], mem_fx[7] ) ) ); + move16(); + Vl[1] = add_sat( mem_fx[7], mult_r( filt_coeff_fx[7], sub_sat( Vl[0], mem_fx[8] ) ) ); + move16(); + mem_fx[9] = add_sat( mem_fx[8], mult_r( filt_coeff_fx[8], sub_sat( Vl[1], mem_fx[9] ) ) ); + move16(); + + mem_fx[0] = input_fx[i]; + move16(); + mem_fx[7] = Vl[0]; + move16(); + mem_fx[8] = Vl[1]; + move16(); + *out1++ = mem_fx[9]; + move16(); + } + /*LPF*/ + FOR( i = 0; i < len * 3; i++ ) + { + mem_temp = out_fx[i]; + move16(); + out_fx[i] = sub_sat( mult_r( 18768 /*0.57276865021499168f Q15*/, add_sat( mem_fx[12], mem_fx[11] ) ), mult_r( 2425 /*0.074004974641176793f Q15*/, add_sat( mem_temp, mem_fx[10] ) ) ); + mem_fx[10] = mem_fx[11]; + move16(); + mem_fx[11] = mem_fx[12]; + move16(); + mem_fx[12] = mem_temp; + move16(); + } + return; +} +#endif + void interpolate_3_over_1_allpass_fx( const Word16 *input_fx, /* i : input signal */ /* Q_input */ const Word16 len, /* i : number of input samples */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6432fc0586fa39bd09976e81f90c0e7d6270690..91267d3cdfb04f3ec0cd9b2a8787f17e6c2538e8 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -915,6 +915,295 @@ void flip_spectrum_and_decimby4_fx( /*--------------------------------------------------------------------------*/ /* CALLED FROM : */ /*==========================================================================*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_GenShapedWBExcitation_fx( + Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ + Word32 *mem_csfilt, /* i/o : memory Q_bwe_exc+16*/ + Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q_bwe_exc*/ + Word16 *state_lpc_syn, /* i/o : memory Q_bwe_exc*/ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q_bwe_exc*/ + const Word16 Q_bwe_exc, + Word16 bwe_seed[], /* i/o : random number generator seed */ + const Word16 voice_factors[], /* i : voicing factor Q15*/ + const Word16 uv_flag, /* i : unvoiced flag */ + const Word16 igf_flag ) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER_WB]; + Word16 lpc_whtn[LPC_WHTN_ORDER_WB + 1]; + Word16 R_h[LPC_WHTN_ORDER_WB + 2], R_l[LPC_WHTN_ORDER_WB + 2]; + Word16 Q_R; + Word16 excTmp[L_FRAME16k]; + Word16 excTmp2[L_FRAME16k / 4]; + Word16 excTmp2_frac[L_FRAME16k / 4]; + Word16 exc4k[L_FRAME16k / 4]; + Word16 exc4k_frac[L_FRAME16k / 4]; + Word32 exc4k_32[L_FRAME16k / 4]; + Word32 pow1, pow22; + Word16 scale; + Word32 excNoisyEnv[L_FRAME16k / 4]; + Word16 csfilt_num2[1] = { 1638 }; /* Q15*/ + Word16 neg_csfilt_den2[2] = { -32768, 31457 }; /* Q15 */ + Word32 L_tmp, Ltemp1, Ltemp2; + Word16 temp1, temp2, exp; + Word32 Lmax; + Word16 max_val, n1, n2, sc; + Word32 LepsP[LPC_WHTN_ORDER_WB + 1]; + Word16 tmp_vfac; + Word16 avg_voice_fac; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*0.25f*sum_f(voice_factors, NB_SUBFR)*/ + L_tmp = L_mult( voice_factors[0], 8192 ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, voice_factors[i], 8192 ); + } + avg_voice_fac = round_fx( L_tmp ); + + test(); + test(); + test(); + test(); + IF( igf_flag != 0 && ( EQ_16( coder_type, VOICED ) || GT_16( avg_voice_fac, 11469 ) ) ) /*Q15 -> 0.35f*/ + { + csfilt_num2[0] = 6554; + move16(); /*Q15 -> 0.2f*/ + neg_csfilt_den2[1] = 26214; + move16(); /*Q15 -> 0.8f*/ + } + ELSE IF( igf_flag != 0 && ( EQ_16( coder_type, UNVOICED ) || LT_16( avg_voice_fac, 6654 ) ) ) /*Q15 -> 0.2f*/ + { + csfilt_num2[0] = 328; + move16(); /*Q15 -> 0.01f*/ + neg_csfilt_den2[1] = 32440; + move16(); /*Q15 -> 0.99f*/ + } + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER_WB ); + Decimate_allpass_steep_fx( bwe_exc_extended, mem_genSHBexc_filt_down1, L_FRAME32k, excTmp ); + flip_spectrum_and_decimby4_fx( excTmp, exc4k, L_FRAME16k, mem_genSHBexc_filt_down2, mem_genSHBexc_filt_down3, 0 ); + + IF( uv_flag ) + { + create_random_vector_fx( exc4kWhtnd, L_FRAME16k / 4, bwe_seed ); + IF( LT_16( Q_bwe_exc, 5 ) ) + { + + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4kWhtnd[i] = shl_r( exc4kWhtnd[i], sub( Q_bwe_exc, 5 ) ); /*Q(Q_bwe_exc)/Q5(if Q_bwe_exc > 5) */ + } + } + } + ELSE + { + autocorr_fx( exc4k, LPC_WHTN_ORDER_WB + 1, R_h, R_l, &Q_R, + L_FRAME16k / 4, win_flatten_4k_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_WB; 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_WB, NULL ); + + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER_WB + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); + + fir_fx( exc4k, lpc_whtn, exc4kWhtnd, wht_fil_mem, L_FRAME16k / 4, + LPC_WHTN_ORDER_WB, 0, 3 ); + + /* Ensure pow1 is greater than zero when computing normalization */ + max_val = 0; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excTmp2[i] = abs_s( exc4kWhtnd[i] ); + move16(); /* Q_bwe_exc */ + max_val = s_max( max_val, excTmp2[i] ); + move16(); + } + + IF( max_val == 0 ) + { + pow1 = 1; + move16(); + n1 = 0; + move16(); + } + ELSE + { + n1 = norm_s( max_val ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); // Q_bwe_exc + n1 +#else + excTmp2_frac[i] = shl( excTmp2[i], n1 ); +#endif + move16(); /* Q14 */ + } + n1 = sub( sub( 14, n1 ), Q_bwe_exc ); + pow1 = 1; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ + pow1 = L_add_o( pow1, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ +#else + L_tmp = L_mult( excTmp2_frac[i], excTmp2_frac[i] ); /* Q29 */ + pow1 = L_add( pow1, L_shr( L_tmp, 7 ) ); /* Q22 */ +#endif + } + } + + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); +#else + excNoisyEnv[i] = L_add( *mem_csfilt, L_mult( csfilt_num2[0], excTmp2[i] ) ); +#endif + move32(); /* Q_bwe_exc+16 */ + *mem_csfilt = Mult_32_16( excNoisyEnv[i], neg_csfilt_den2[1] ); + move32(); /* Q_bwe_exc+16 */ + } + + create_random_vector_fx( exc4k, L_FRAME16k / 4, bwe_seed ); + + /* Ensure pow22 is greater than zero when computing normalization */ + Lmax = 0; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4k_32[i] = Mult_32_16( excNoisyEnv[i], exc4k[i] ); + move32(); /* Q_bwe_exc+6 */ + Lmax = L_max( Lmax, L_abs( exc4k_32[i] ) ); + } + + IF( Lmax == 0 ) + { + pow22 = 1; + move16(); + n2 = 0; + move16(); + set16_fx( exc4k_frac, 0, L_FRAME16k / 4 ); + } + ELSE + { + n2 = norm_l( Lmax ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ +#else + exc4k_frac[i] = extract_h( L_shl( exc4k_32[i], n2 ) ); /* Q(14-n2) */ +#endif + } + n2 = 30 - n2 - ( Q_bwe_exc + 6 ); + pow22 = 1; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ + pow22 = L_add_o( pow22, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ +#else + L_tmp = L_mult( exc4k_frac[i], exc4k_frac[i] ); /* Q29 */ + pow22 = L_add( pow22, L_shr( L_tmp, 7 ) ); /* Q22 */ +#endif + } + } + + test(); + test(); + IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 ) ) ) + { + L_tmp = root_a_over_b_fx( pow1, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); +#ifdef BASOP_NOGLOB + scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ +#else + scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ +#endif + sc = sub( add( n2, Q_bwe_exc ), 14 ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ +#else + exc4kWhtnd[i] = round_fx( L_shl( L_mult( exc4k_frac[i], scale ), sc ) ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ +#endif + } + } + ELSE + { + sc = sub( add( n2, Q_bwe_exc ), 14 ); /* Q_bwe_exc+n2-14*/ + + k = 0; + FOR( i = 0; i < 4; i++ ) + { + test(); + IF( igf_flag != 0 && EQ_16( coder_type, VOICED ) ) + { + /*tmp_vfac = 2*voice_factors[i]; + tmp_vfac = min(1, tmp_vfac);*/ +#ifdef BASOP_NOGLOB + tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); +#else + BASOP_SATURATE_WARNING_OFF_EVS + tmp_vfac = shl( voice_factors[i], 1 ); + BASOP_SATURATE_WARNING_ON_EVS +#endif + } + ELSE + { + tmp_vfac = voice_factors[i]; + move16(); + } + + Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); +#ifdef BASOP_NOGLOB + temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ +#else + temp1 = round_fx( L_shl( Ltemp1, exp ) ); /* Q15 */ +#endif + L_tmp = Mult_32_16( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ + Ltemp2 = root_a_over_b_fx( L_tmp, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); +#ifdef BASOP_NOGLOB + temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ +#else + temp2 = round_fx( L_shl( Ltemp2, exp ) ); /* Q15 */ +#endif + FOR( j = 0; j < L_FRAME16k / 16; j++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ + L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ + exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ +#else + L_tmp = L_mult( temp1, exc4kWhtnd[k] ); /* Q(16+Q_bwe_exc) */ + L_tmp = L_add( L_tmp, L_shl( L_mult( temp2, exc4k_frac[k] ), sc ) ); /* Q(16+Q_bwe_exc) */ + exc4kWhtnd[k] = round_fx( L_tmp ); /* Q_bwe_exc */ +#endif + k++; + } + } + } + } + + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); + + return; +} +#endif + void GenShapedWBExcitation_fx( Word16* excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ const Word16* lpc_shb, /* i : lpc coefficients Q12*/ diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 10e4d9f6940b2ba20dc857845784c41dbb36e896..4906fe5e09d392250d57ffa20254230069b258ef 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -374,6 +374,13 @@ ivas_error init_decoder( } td_bwe_dec_init( st->hBWE_TD, st->extl, st->output_Fs ); + +#ifdef IVAS_FLOAT_FIXED + st->prev_Q_bwe_exc = 31; + st->prev_Qx = 0; + st->prev_ener_fx_Q = 31; + st->prev_frame_pow_exp = 0; +#endif } else { @@ -395,6 +402,11 @@ ivas_error init_decoder( } fd_bwe_dec_init_flt( st->hBWE_FD ); +#ifdef IVAS_FLOAT_FIXED + st->hBWE_FD->old_wtda_swb_fx_exp = 0; + st->hBWE_FD->mem_imdct_exp_fx = 0; + st->prev_Q_synth = 0; +#endif } else { diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index eea3629d363f492626f56dabc998a382401d97bb..abc98ad63f12d6affa3f3b80093f709a08064958 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -995,6 +995,176 @@ ivas_error ivas_core_dec( * WB BWE decoding *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + Word32 bwe_exc_extended_fx[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; + Word16 voice_factors_fx[CPE_CHANNELS][NB_SUBFR16k]; + Word16 hb_synth_fx_16[CPE_CHANNELS][L_FRAME48k]; + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k]; + Word16 output_fx_16[CPE_CHANNELS][L_FRAME48k]; + Word16 synth_fx_16[CPE_CHANNELS][L_FRAME48k]; + Word16 Q_input, i; + + st->Q_syn = 0; + st->Q_exc = 8; + Q_input = 0; + move16(); + + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st->hBWE_FD; + +#ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + IF( ( hBWE_TD != NULL && st->extl == WB_TBE ) || ( hBWE_FD != NULL && st->extl == WB_BWE && st->bws_cnt == 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], Q15, NB_SUBFR16k ); + floatToFixed_arr( hb_synth[n], hb_synth_fx_16[n], st->Q_syn, L_FRAME48k ); + floatToFixed_arr( output[n], output_fx_16[n], Q_input, L_FRAME48k ); + floatToFixed_arr( synth[n], synth_fx_16[n], st->Q_syn, L_FRAME48k ); + + st->prev_tilt_code_dec_fx = (Word16) floatToFixed( st->prev_tilt_code_dec, Q15 ); + st->bws_cnt_fx = st->bws_cnt; + + floatToFixed_arr( pitch_buf[n], pitch_buf_fx[n], Q6, NB_SUBFR16k ); + + st->prev_coder_type_fx = st->prev_coder_type; + st->tilt_wb_fx = (Word16) floatToFixed( st->tilt_wb, Q11 ); + } + + IF( hBWE_TD != NULL && st->extl == WB_TBE ) + { + floatToFixed_arr( hBWE_TD->lsp_prevfrm, hBWE_TD->lsp_prevfrm_fx, Q15, LPC_SHB_ORDER ); + hBWE_TD->GainFrame_prevfrm_fx = floatToFixed( hBWE_TD->GainFrame_prevfrm, Q18 ); + hBWE_TD->gFrame_WB_fx = hBWE_TD->gFrame_WB; + hBWE_TD->idxSubGains_fx = hBWE_TD->idxSubGains; + hBWE_TD->idxFrameGain_fx = hBWE_TD->idxFrameGain; + hBWE_TD->idx_shb_fr_gain_fx = hBWE_TD->idx_shb_fr_gain; + FOR( i = 0; i < NB_SUBFR16k; ++i ) + { + hBWE_TD->idx_res_gs_fx[i] = hBWE_TD->idx_res_gs[i]; + } + hBWE_TD->idx_mixFac_fx = hBWE_TD->idx_mixFac; + FOR( i = 0; i < NUM_Q_LSF; ++i ) + { + hBWE_TD->lsf_idx_fx[i] = hBWE_TD->lsf_idx[i]; + } + hBWE_TD->m_idx_fx = hBWE_TD->m_idx; + hBWE_TD->grid_idx_fx = hBWE_TD->grid_idx; + hBWE_TD->GainAttn_fx = (Word16) floatToFixed( hBWE_TD->GainAttn, Q15 ); + floatToFixed_arr( hBWE_TD->state_syn_shbexc, hBWE_TD->state_syn_shbexc_fx, ( st->prev_Q_bwe_exc - 16 ), L_SHB_LAHEAD / 4 ); + floatToFixed_arr( hBWE_TD->old_bwe_exc_extended, hBWE_TD->old_bwe_exc_extended_fx, 0, 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_genSHBexc_filt_down_wb2, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, ( st->prev_Q_bwe_exc - 16 ), 2 * ALLPASSSECTIONS_STEEP + 1 ); + floatToFixed_arr( hBWE_TD->mem_genSHBexc_filt_down_wb3, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, ( st->prev_Q_bwe_exc - 16 ), 2 * ALLPASSSECTIONS_STEEP + 1 ); + floatToFixed_arrL( hBWE_TD->mem_csfilt, hBWE_TD->mem_csfilt_fx, st->prev_Q_bwe_exc, 2 ); + FOR( i = 0; i < 2; ++i ) + { + hBWE_TD->bwe_seed_fx[i] = hBWE_TD->bwe_seed[i]; + } + floatToFixed_arr( hBWE_TD->syn_overlap, hBWE_TD->syn_overlap_fx, st->Q_syn, L_SHB_LAHEAD ); + hBWE_TD->prev_wb_bwe_frame_pow_fx = floatToFixed( hBWE_TD->prev_wb_bwe_frame_pow, Q22 ); + floatToFixed_arr( hBWE_TD->state_lsyn_filt_shb, hBWE_TD->state_lsyn_filt_shb_fx, st->prev_Qx, 2 * ALLPASSSECTIONS_STEEP ); + floatToFixed_arr( hBWE_TD->state_lsyn_filt_dwn_shb, hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->prev_Qx, 2 * ALLPASSSECTIONS_STEEP ); + floatToFixed_arr( hBWE_TD->mem_resamp_HB, hBWE_TD->state_32and48k_WB_upsample_fx, st->Q_syn, 2 * ALLPASSSECTIONS_STEEP ); + floatToFixed_arr( hBWE_TD->mem_resamp_HB, hBWE_TD->mem_resamp_HB_fx, st->Q_syn, INTERP_3_1_MEM_LEN ); + floatToFixed_arr( hBWE_TD->state_lpc_syn, hBWE_TD->state_lpc_syn_fx, ( st->prev_Q_bwe_exc - 16 ), LPC_SHB_ORDER ); + hBWE_TD->prev_wb_bwe_frame_pow_fx = floatToFixed( hBWE_TD->prev_wb_bwe_frame_pow, st->prev_frame_pow_exp ); + floatToFixed_arr( hBWE_TD->old_tbe_synth, hBWE_TD->old_tbe_synth_fx, st->prev_Qx, L_SHB_TRANSITION_LENGTH ); + } + + IF( hBWE_FD != NULL && st->extl == WB_BWE && st->bws_cnt == 0 ) + { + floatToFixed_arr( hBWE_FD->old_wtda_swb, hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->old_wtda_swb_fx_exp, L_FRAME48k ); + st->last_wb_bwe_ener_fx = (Word16) floatToFixed( hBWE_FD->last_wb_bwe_ener, Q3 ); + floatToFixed_arr( hBWE_FD->prev_SWB_fenv, st->prev_SWB_fenv_fx, Q1, SWB_FENV ); + floatToFixed_arr( hBWE_FD->mem_imdct, hBWE_FD->mem_imdct_fx, hBWE_FD->mem_imdct_exp_fx, L_FRAME48k ); + hBWE_FD->prev_Energy_wb_fx = floatToFixed( hBWE_FD->prev_Energy_wb, st->prev_Q_synth ); + hBWE_FD->prev_L_swb_norm_fx = hBWE_FD->prev_L_swb_norm; + hBWE_FD->Seed_fx = hBWE_FD->Seed; + hBWE_FD->prev_flag_fx = hBWE_FD->prev_flag; + st->coder_type_fx = st->coder_type; + } +#endif + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->extl, WB_TBE ) ) + { + /* WB TBE decoder */ + + ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_fx_16[n], &st->Q_syn ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && EQ_16( st->bws_cnt, 0 ) && EQ_32( st->extl_brate, 0 ) ) + { + /* do nothing */ + } + ELSE IF( EQ_16( st->extl, WB_BWE ) && EQ_16( st->bws_cnt, 0 ) ) + { + /* WB BWE decoder */ + st->Q_syn = ivas_wb_bwe_dec_fx( st, output_fx_16[n], synth_fx_16[n], hb_synth_fx_16[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &st->Q_syn ); + } + +#ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + IF( ( hBWE_TD != NULL && st->extl == WB_TBE ) || ( hBWE_FD != NULL && st->extl == WB_BWE && st->bws_cnt == 0 ) ) + { + fixedToFloat_arrL( bwe_exc_extended_fx[n], bwe_exc_extended[n], 2 * st->Q_exc, L_FRAME32k + NL_BUFF_OFFSET ); + fixedToFloat_arr( voice_factors_fx[n], voice_factors[n], Q15, NB_SUBFR16k ); + fixedToFloat_arr( hb_synth_fx_16[n], hb_synth[n], st->Q_syn, L_FRAME48k ); + fixedToFloat_arr( output_fx_16[n], output[n], Q_input, L_FRAME48k ); + fixedToFloat_arr( synth_fx_16[n], synth[n], 0, L_FRAME48k ); + + st->prev_tilt_code_dec = fixedToFloat( st->prev_tilt_code_dec_fx, Q15 ); + fixedToFloat_arr( pitch_buf_fx[n], pitch_buf[n], Q6, NB_SUBFR16k ); + st->prev_coder_type = st->prev_coder_type_fx; + st->tilt_wb = fixedToFloat( st->tilt_wb_fx, Q11 ); + } + + 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->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 ) + { + hBWE_TD->bwe_seed[i] = hBWE_TD->bwe_seed_fx[i]; + } + fixedToFloat_arr( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap, st->Q_syn, L_SHB_LAHEAD ); + + 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_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2, ( st->prev_Q_bwe_exc - 16 ), 2 * ALLPASSSECTIONS_STEEP + 1 ); + fixedToFloat_arr( hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3, ( st->prev_Q_bwe_exc - 16 ), 2 * ALLPASSSECTIONS_STEEP + 1 ); + + fixedToFloat_arr( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb, st->prev_Qx, 2 * ALLPASSSECTIONS_STEEP ); + fixedToFloat_arr( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb, st->prev_Qx, 2 * ALLPASSSECTIONS_STEEP ); + fixedToFloat_arr( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB, st->Q_syn, INTERP_3_1_MEM_LEN ); + fixedToFloat_arr( hBWE_TD->old_bwe_exc_extended_fx, hBWE_TD->old_bwe_exc_extended, 0, NL_BUFF_OFFSET ); + fixedToFloat_arr( hBWE_TD->state_syn_shbexc_fx, hBWE_TD->state_syn_shbexc, ( st->prev_Q_bwe_exc - 16 ), L_SHB_LAHEAD / 4 ); + fixedToFloat_arr( hBWE_TD->state_lpc_syn_fx, hBWE_TD->state_lpc_syn, ( st->prev_Q_bwe_exc - 16 ), LPC_SHB_ORDER ); + hBWE_TD->prev_wb_bwe_frame_pow = fixedToFloat( hBWE_TD->prev_wb_bwe_frame_pow_fx, st->prev_frame_pow_exp ); + + fixedToFloat_arr( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth, st->prev_Qx, L_SHB_TRANSITION_LENGTH ); + } + + IF( hBWE_FD != NULL && st->extl == WB_BWE && st->bws_cnt == 0 ) + { + hBWE_FD->last_wb_bwe_ener = fixedToFloat( st->last_wb_bwe_ener_fx, Q3 ); + fixedToFloat_arr( st->prev_SWB_fenv_fx, hBWE_FD->prev_SWB_fenv, Q1, SWB_FENV ); + hBWE_FD->prev_L_swb_norm = hBWE_FD->prev_L_swb_norm_fx; + hBWE_FD->Seed = hBWE_FD->Seed_fx; + hBWE_FD->prev_flag = hBWE_FD->prev_flag_fx; + fixedToFloat_arr( hBWE_FD->mem_imdct_fx, hBWE_FD->mem_imdct, hBWE_FD->mem_imdct_exp_fx, L_FRAME48k ); + fixedToFloat_arr( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->old_wtda_swb, hBWE_FD->old_wtda_swb_fx_exp, L_FRAME48k ); + hBWE_FD->prev_Energy_wb = fixedToFloat( hBWE_FD->prev_Energy_wb_fx, st->prev_Q_synth ); + st->coder_type = st->coder_type_fx; + } +#endif +#else if ( st->extl == WB_TBE ) { /* WB TBE decoder */ @@ -1009,6 +1179,7 @@ ivas_error ivas_core_dec( /* WB BWE decoder */ wb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame, voice_factors[n], pitch_buf[n] ); } +#endif /*---------------------------------------------------------------------* * SWB(FB) TBE decoding diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 3d39c52f01ed6a181766087e1d82c2b606dc09ce..7edb3fd72909c04a3887da1ed3d3cbe48bbe33a1 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -1563,7 +1563,18 @@ void stereo_icBWE_decproc( } /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ td_bwe_dec_init( hCPE->hCoreCoder[0]->hBWE_TD, -1, output_Fs ); +#ifdef IVAS_FLOAT_FIXED + hCPE->hCoreCoder[0]->prev_Q_bwe_exc = 31; + hCPE->hCoreCoder[0]->prev_Qx = 0; + hCPE->hCoreCoder[0]->prev_ener_fx_Q = 31; + hCPE->hCoreCoder[0]->prev_frame_pow_exp = 0; +#endif fd_bwe_dec_init_flt( hCPE->hCoreCoder[0]->hBWE_FD ); +#ifdef IVAS_FLOAT_FIXED + hCPE->hCoreCoder[0]->hBWE_FD->old_wtda_swb_fx_exp = 0; + hCPE->hCoreCoder[0]->hBWE_FD->mem_imdct_exp_fx = 0; + hCPE->hCoreCoder[0]->prev_Q_synth = 0; +#endif } if ( hCPE->element_mode == IVAS_CPE_DFT && ( max( hCPE->hStereoDft->td_gain[0], hCPE->hStereoDft->td_gain[1] ) > 0 ) ) diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 0de7d716b5e4948d318deb1546a10564378e04ac..83f386817b788f82315b0a3879c40eb3ccacf9df 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -606,6 +606,12 @@ ivas_error stereo_memory_dec( } td_bwe_dec_init( st->hBWE_TD, -1, st->output_Fs ); +#ifdef IVAS_FLOAT_FIXED + st->prev_Q_bwe_exc = 31; + st->prev_Qx = 0; + st->prev_ener_fx_Q = 31; + st->prev_frame_pow_exp = 0; +#endif if ( ( st->hBWE_FD = (FD_BWE_DEC_HANDLE) malloc( sizeof( FD_BWE_DEC_DATA ) ) ) == NULL ) { @@ -613,6 +619,11 @@ ivas_error stereo_memory_dec( } fd_bwe_dec_init_flt( st->hBWE_FD ); +#ifdef IVAS_FLOAT_FIXED + st->hBWE_FD->old_wtda_swb_fx_exp = 0; + st->hBWE_FD->mem_imdct_exp_fx = 0; + st->prev_Q_synth = 0; +#endif } /* Allocated FD_CNG instance for primary channel*/ @@ -824,6 +835,12 @@ ivas_error stereo_memory_dec( } td_bwe_dec_init( st->hBWE_TD, -1, st->output_Fs ); +#ifdef IVAS_FLOAT_FIXED + st->prev_Q_bwe_exc = 31; + st->prev_Qx = 0; + st->prev_ener_fx_Q = 31; + st->prev_frame_pow_exp = 0; +#endif if ( ( st->hBWE_FD = (FD_BWE_DEC_HANDLE) malloc( sizeof( FD_BWE_DEC_DATA ) ) ) == NULL ) { @@ -831,6 +848,11 @@ ivas_error stereo_memory_dec( } fd_bwe_dec_init_flt( st->hBWE_FD ); +#ifdef IVAS_FLOAT_FIXED + st->hBWE_FD->old_wtda_swb_fx_exp = 0; + st->hBWE_FD->mem_imdct_exp_fx = 0; + st->prev_Q_synth = 0; +#endif } } else /* tdm_LRTD_flag == 0 */ diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 4b539d9498e2500404fe16652ed2a3289c887724..1e0ffd4712ec79bf0567c4a35fc0bb8aa7fd55ce 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -352,6 +352,151 @@ Word16 WB_BWE_gain_deq_fx( * * WB BWE decoder (only for 16kHz signals) *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +Word16 ivas_wb_bwe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 output[], /* i : suntehsis @ internal Fs */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis */ + 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 */ + const Word16 pitch_buf_fx[], /* i : pitch buffer */ + Word16 *Qpost ) +{ + Word16 mode; + Word16 WB_fenv_fx[SWB_FENV]; + Word16 ysynth_fx[L_FRAME48k]; + Word16 Q_syn, exp, Q_syn_hb; + Word32 L_wtda_synth_fx[2 * L_FRAME48k], ysynth_32[L_FRAME48k], t_audio32_tmp[L_FRAME48k]; + Word16 scl, new_input_fx_exp; + Word16 i; + FD_BWE_DEC_HANDLE hBWE_FD; + + Word16 coder_type = st_fx->coder_type_fx; + + hBWE_FD = st_fx->hBWE_FD; + + /* MDCT of the core synthesis signal */ + + new_input_fx_exp = *Qpost; + move16(); + IF( st_fx->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft ) + { + /* 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 ); + direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, /*st->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); + } + 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 ); + *Qpost = sub( new_input_fx_exp, 15 ); + /* 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? */ + IF( scl > 0 ) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = Find_Max_Norm32( ysynth_32, output_frame ); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min( Q_syn, scl ); + } + Copy_Scale_sig32_16( ysynth_32, ysynth_fx, output_frame, 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->last_wb_bwe_ener_fx = extract_l( Mpy_32_16_r( L_add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ) ); + } + ELSE + { + Word32 tmp_brate; + + tmp_brate = st_fx->last_core_brate; + test(); + IF( EQ_32( st_fx->last_total_brate, ACELP_9k60 ) && EQ_16( st_fx->last_extl, SWB_TBE ) ) + { + tmp_brate = ACELP_8k00; /* this is needed in order to stay BE wrt. EVS mono */ + move16(); + } + IF( NE_16( st_fx->last_extl, WB_BWE ) ) + { + st_fx->prev_SWB_fenv_fx[0] = 0; + move16(); + } + + mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type_fx, st_fx->prev_SWB_fenv_fx[0], + voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); + move16(); + } + } + ELSE + { + /* FEC */ + mode = NORMAL; + move16(); + FOR( i = 0; i < 2; i++ ) + { + WB_fenv_fx[i] = mult_r( st_fx->prev_SWB_fenv_fx[i], 24576 ); + } + } + test(); + IF( NE_16( st_fx->last_extl, WB_BWE ) || st_fx->bfi ) + { + Copy( WB_fenv_fx, st_fx->prev_SWB_fenv_fx, 2 ); + } + + exp = norm_l( hBWE_FD->prev_Energy_wb_fx ); + IF( GT_16( add( st_fx->prev_Q_synth, exp ), Q_syn ) ) + { + hBWE_FD->prev_Energy_wb_fx = L_shr( hBWE_FD->prev_Energy_wb_fx, sub( st_fx->prev_Q_synth, Q_syn ) ); + } + ELSE + { + Q_syn = add( st_fx->prev_Q_synth, exp ); + hBWE_FD->prev_Energy_wb_fx = L_shl( hBWE_FD->prev_Energy_wb_fx, exp ); + } + WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, + st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm_fx, + st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed_fx, &hBWE_FD->prev_flag_fx, + st_fx->prev_coder_type_fx, Q_syn, &Q_syn_hb ); + IF( EQ_32( st_fx->output_Fs, 32000 ) ) + { + set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME16k ); + } + ELSE IF( EQ_32( st_fx->output_Fs, 48000 ) ) + { + set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME32k ); + } + Inverse_Transform( ysynth_32, &Q_syn_hb, t_audio32_tmp, 0, output_frame, output_frame, st_fx->element_mode ); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, + ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); + + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + /* add HB synth from hf_synth() */ + v_add_16( hb_synth_fx, synth_fx, hb_synth_fx, output_frame ); + } + hBWE_FD->prev_mode_fx = mode; + st_fx->prev_Q_synth = Q_syn; + return Q_syn_hb; +} +#endif + Word16 wb_bwe_dec_fx( #ifdef ADD_IVAS_BWE const Word16 output[], /* i : suntehsis @ internal Fs */ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 4daf093df7e4a6c4eab6d3c7f5ad7add30c5f3a1..9338482cc862fe86d528a943f2cc742800bf206b 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -12,6 +12,10 @@ #include "rom_dec.h" #include "stl.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif + /*-----------------------------------------------------------------* * Local functions *-----------------------------------------------------------------*/ @@ -20,6 +24,9 @@ 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 ); @@ -509,39 +516,625 @@ void ResetSHBbuffer_Dec_fx( Decoder_State* st_fx /* i/o: SHB encoder structure * hBWE_TD->gain_prec_swb_fx = 16384;/*Q14 =1*/ set16_fx( &st_fx->GainShape_Delay[0], 0, NUM_SHB_SUBFR / 2 ); - set16_fx(hBWE_TD->old_core_synth_fx, 0, L_FRAME16k); - set16_fx(hBWE_TD->old_tbe_synth_fx, 0, L_SHB_TRANSITION_LENGTH); - hBWE_TD->tilt_swb_fec_fx = 0; + set16_fx(hBWE_TD->old_core_synth_fx, 0, L_FRAME16k); + set16_fx(hBWE_TD->old_tbe_synth_fx, 0, L_SHB_TRANSITION_LENGTH); + hBWE_TD->tilt_swb_fec_fx = 0; + move16(); + + return; +} + + + + +/*==========================================================================*/ +/* FUNCTION : void wb_tbe_dec_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : WB TBE decoder, 6 - 8 kHz band decoding module */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 coder_type i : coding type */ +/* _Word32 *bwe_exc_extended i : bandwidth extended exciatation 2*Q_exc*/ +/* _Word16 Q_exc i : Q format */ +/* _Word16 voice_factors[] i : voicing factors Q15 */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *synth o : WB synthesis/final synthesis Q_synth */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Decoder_State *st_fx, i/o: decoder state structure */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_wb_tbe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32 *bwe_exc_extended, /* i : bandwidth extended exciatation 2*Q_exc*/ + const Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + Word16 *synth, /* o : WB synthesis/final synthesis */ + Word16 *Q_synth ) +{ + Word16 i; + Word16 shaped_wb_excitation[( L_FRAME16k + L_SHB_LAHEAD ) / 4]; + Word16 shaped_wb_excitation_frac[L_FRAME16k / 4]; + Word16 bwe_exc_extended_16[L_FRAME32k + 40]; + Word16 exc4kWhtnd[L_FRAME16k / 4]; + Word16 lsf_wb[LPC_SHB_ORDER_WB], lpc_wb[LPC_SHB_ORDER_WB + 1], GainShape[NUM_SHB_SUBFR]; + Word32 GainFrame; + Word16 error[L_FRAME16k]; + Word16 synth_frac[L_FRAME16k]; + Word16 upsampled_synth[L_FRAME48k]; + Word32 prev_pow, curr_pow, curr_frame_pow; + Word16 curr_frame_pow_exp; + Word16 temp, scale, n; + Word16 j; + + Word16 Q_bwe_exc, Q_bwe_exc_ext, Qx; + Word16 n_mem, cnt; + Word16 max = 0; + Word32 L_tmp, Lacc, Lscale, Lmax = 0; + Word16 tmp, exp, sc; + Word16 vf_modified[NB_SUBFR16k]; + Word16 uv_flag = 0; + Word16 dummy = 0; + Word32 dummy2[HILBERT_MEM_SIZE] = { 0 }; + Word16 f, inc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + IF( st_fx->bws_cnt_fx == 0 ) + { + /* Initialization */ + set16_fx( GainShape, 11469 /*0.35f Q15*/, NUM_SHB_SUBFR ); + GainFrame = 1; + + IF( !st_fx->bfi ) + { + IF( EQ_16( st_fx->use_partial_copy, 1 ) ) + { + IF( NE_16( st_fx->last_extl, WB_TBE ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + hBWE_TD->lsp_prevfrm_fx[0] = 3277 /*0.1f Q15*/; + move16(); + FOR( i = 1; i < LPC_SHB_ORDER_LBR_WB; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = add( hBWE_TD->lsp_prevfrm_fx[i - i], 3277 /*0.1f Q15*/ ); + } + } + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_LBR_WB ); + set16_fx( GainShape, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2 ); + + IF( EQ_16( st_fx->rf_frame_type, RF_NELP ) ) + { + /* Frame gain */ + st_fx->rf_indx_tbeGainFr = s_and( st_fx->rf_indx_tbeGainFr, 0xF ); /* only four LSBs are valid */ + Copy32( SHBCB_FrameGain16_fx + st_fx->rf_indx_tbeGainFr, &GainFrame, 1 ); + IF( EQ_16( st_fx->core, ACELP_CORE ) && EQ_16( st_fx->last_core, ACELP_CORE ) && !st_fx->prev_use_partial_copy && EQ_16( st_fx->prev_coder_type_fx, UNVOICED ) && NE_32( GainFrame, hBWE_TD->GainFrame_prevfrm_fx ) && EQ_16( st_fx->last_extl, WB_TBE ) ) + { + /*GainFrame = 0.2f*GainFrame + 0.8f*st_fx->GainFrame_prevfrm_fx;*/ + GainFrame = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame, 6553 ) ); + } + } + ELSE + { + temp = 0; + move16(); + /* Frame gain */ + SWITCH( st_fx->rf_indx_tbeGainFr ) + { + case 0: + GainFrame = 131072; /* 0.5f in Q18 */ + IF( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) + temp = 26214 /*0.8 Q15*/; + move16(); + BREAK; + case 1: + GainFrame = 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 = 26214 /*0.8 Q15*/; + move16(); + test(); + BREAK; + case 2: + GainFrame = 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 = 26214 /*0.8 Q15*/; + move16(); + test(); + BREAK; + case 3: + GainFrame = 2097152; /* 8.0f in Q18 */ + IF( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16 Q18*/ ) ) + temp = 26214 /*0.8 Q15*/; + move16(); + test(); + BREAK; + default: + fprintf( stderr, "RF SWB-TBE gain bits not supported." ); + } + IF( EQ_16( st_fx->last_extl, WB_TBE ) ) + { + + GainFrame = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp ), Mult_32_16( GainFrame, sub( 32767, temp ) ) ); + } + IF( EQ_16( st_fx->core, ACELP_CORE ) && EQ_16( st_fx->last_core, ACELP_CORE ) ) + { + IF( !st_fx->prev_use_partial_copy && EQ_16( st_fx->last_coder_type_fx, VOICED ) && EQ_16( st_fx->rf_frame_type, RF_GENPRED ) && LT_16( st_fx->prev_tilt_code_dec_fx, 1497 ) && GT_16( st_fx->prev_tilt_code_dec_fx, 200 ) ) + { + GainFrame = Mult_32_16( GainFrame, 9830 ); + } + } + } + } + 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 ); + } + } + ELSE + { + IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35 ) ) + { + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_LBR_WB ); + } + ELSE + { + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_WB ); + } + set16_fx( GainShape, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2 ); + + hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 27853 ); + move16(); + + IF( EQ_16( st_fx->codec_mode, MODE1 ) ) + { + GainFrame = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /*Q18*/ + } + ELSE + { + GainFrame = hBWE_TD->GainFrame_prevfrm_fx; /*Q18*/ + } + } + + IF( st_fx->extl_brate == WB_TBE_0k35 ) + { + /* convert LSPs back into LP coeffs */ + lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); + set16_fx( lpc_wb + LPC_SHB_ORDER_LBR_WB + 1, 0, ( LPC_SHB_ORDER_WB - LPC_SHB_ORDER_LBR_WB ) ); + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + move16(); + } + FOR( i = 1; i < LPC_SHB_ORDER_LBR_WB + 1; i++ ) + { + lpc_wb[i] = negate( lpc_wb[i] ); + move16(); + } + lpc_wb[0] = 4096; + move16(); + } + ELSE + { + /* convert LSPs back into LP coeffs */ + lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + move16(); + } + FOR( i = 1; i < LPC_SHB_ORDER_WB + 1; i++ ) + { + lpc_wb[i] = negate( lpc_wb[i] ); + move16(); + } + lpc_wb[0] = 4096; + move16(); + } + + Copy( voice_factors, vf_modified, NB_SUBFR16k ); + IF( coder_type == VOICED ) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + vf_modified[i] = add( mult_r( 26214, voice_factors[i] ), mult_r( 6554, voice_factors[i - 1] ) ); /* Q15 */ + move16(); + } + IF( st_fx->L_frame != L_FRAME ) + { + vf_modified[4] = add( mult_r( 26214, voice_factors[4] ), mult_r( 6554, voice_factors[3] ) ); /* Q15 */ + move16(); + } + } + + /* From low band excitation, generate highband excitation */ + Lmax = 0; + FOR( cnt = 0; cnt < L_FRAME32k + NL_BUFF_OFFSET; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended[cnt] ) ); + } + Q_bwe_exc = ( Lmax == 0 ) ? 31 : norm_l( Lmax ); + Q_bwe_exc = sub( Q_bwe_exc, 3 ); + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + find_max_mem_wb( st_fx, &n_mem ); + + IF( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) > n_mem ) + { + Q_bwe_exc = add( st_fx->prev_Q_bwe_exc, n_mem ); + } + + test(); + IF( uv_flag && GT_16( Q_bwe_exc, 20 ) ) + { + Q_bwe_exc = 20; + move16(); /* restrict this to 21 due to the Q factor requireemnt of the random number generator (keep 1 bit headroom) */ + } + + prev_pow = 0; + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + prev_pow = L_mac0( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ + } + + rescale_genWB_mem( st_fx, sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) ); + + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + FOR( cnt = 0; cnt < L_FRAME32k + NL_BUFF_OFFSET; cnt++ ) + { + bwe_exc_extended_16[cnt] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); + } + + Copy( hBWE_TD->state_syn_shbexc_fx, shaped_wb_excitation, L_SHB_LAHEAD / 4 ); + + Q_bwe_exc_ext = sub( Q_bwe_exc, 16 ); + + ivas_GenShapedWBExcitation_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, + hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, + hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, hBWE_TD->state_lpc_syn_fx, coder_type, + bwe_exc_extended_16, Q_bwe_exc_ext, hBWE_TD->bwe_seed_fx, vf_modified, uv_flag, st_fx->igf ); + + curr_pow = 0; + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + curr_pow = L_mac0( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ + } + + IF( GT_16( voice_factors[0], 24576 ) ) + { + curr_pow = L_shr( curr_pow, 2 ); /* Q(2*Q_bwe_exc_ext) */ + } + + Lscale = root_a_over_b_fx( curr_pow, shl_r( Q_bwe_exc_ext, 1 ), prev_pow, + shl_r( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ + shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ + } + Lscale = root_a_fx( Lscale, 31 - exp, &exp ); + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] ); /* Q(16-exp+Q_bwe_exc_ext) */ + shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ + + /* Update SHB excitation */ + Copy( shaped_wb_excitation + L_FRAME16k / 4, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); + + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + ScaleShapedWB_fx( SHB_OVERLAP_LEN / 2, shaped_wb_excitation, hBWE_TD->syn_overlap_fx, GainShape, GainFrame, + window_wb_fx, subwin_wb_fx, + Q_bwe_exc_ext, st_fx->L_frame, 0, &dummy, dummy, dummy2 ); + + max = 0; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + max = s_max( max, abs_s( shaped_wb_excitation[i] ) ); + } + + IF( max == 0 ) + { + curr_frame_pow = 1; + move16(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + shaped_wb_excitation_frac[i] = shl_o( shaped_wb_excitation[i], n, &Overflow ); /*Q14*/ + move16(); +#else + shaped_wb_excitation_frac[i] = shl( shaped_wb_excitation[i], n ); /*Q14*/ + move16(); +#endif + } + n = sub( 14, n ); + curr_frame_pow = 1; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i], &Overflow ); /*Q29*/ + curr_frame_pow = L_add_o( curr_frame_pow, L_shr( L_tmp, 7 ), &Overflow ); /*Q22*/ +#else + L_tmp = L_mult( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i] ); /*Q29*/ + curr_frame_pow = L_add( curr_frame_pow, L_shr( L_tmp, 7 ) ); /*Q22*/ +#endif + } + } + curr_frame_pow_exp = add( n, n ); + + IF( GT_16( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ) + { + curr_frame_pow = L_shr( curr_frame_pow, sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ); + curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + } + ELSE + { + hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, st_fx->prev_frame_pow_exp ) ); + } + + test(); + IF( !st_fx->bfi && ( st_fx->prev_bfi || st_fx->prev_use_partial_copy ) ) + { + IF( GT_32( L_shr( curr_frame_pow, 1 ), hBWE_TD->prev_wb_bwe_frame_pow_fx ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_wb_bwe_frame_pow_fx, 22, curr_frame_pow, 22, &exp ); + scale = 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 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 */ + } + ELSE + { + scale = temp = 32767; + move16(); /* Q15 */ + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape[2 * j] = mult_r( GainShape[2 * j], scale ); + GainShape[2 * j + 1] = mult_r( GainShape[2 * j + 1], scale ); + FOR( i = 0; i < L_FRAME16k / ( 4 * 8 ); i++ ) + { + shaped_wb_excitation[i + j * L_FRAME16k / ( 4 * 8 )] = mult_r( shaped_wb_excitation[i + j * L_FRAME16k / ( 4 * 8 )], scale ); + } + IF( temp > 0 ) + { + IF( LT_16( scale, temp ) ) + { + scale = div_s( scale, temp ); + } + ELSE + { + scale = 32767; + move16(); + } + } + ELSE + { + scale = 0; + move16(); + } + } + } + + hBWE_TD->prev_wb_bwe_frame_pow_fx = curr_frame_pow; + move32(); + st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + /* generate 16kHz SHB signal (6 - 8 kHz) from 2kHz signal */ + max = 0; + move16(); + FOR( cnt = 0; cnt < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; cnt++ ) + { + IF( abs_s( shaped_wb_excitation[cnt] ) > max ) + { + max = abs_s( shaped_wb_excitation[cnt] ); + } + } + Qx = norm_s( max ); + IF( max == 0 ) + { + Qx = 15; + move16(); + } + + Qx = sub( Qx, 1 ); /* 1 bit space for saturation */ + + max = 0; + move16(); + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + IF( abs_s( hBWE_TD->state_lsyn_filt_shb_fx[i] ) > max ) + max = abs_s( hBWE_TD->state_lsyn_filt_shb_fx[i] ); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + IF( abs_s( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ) > max ) + max = abs_s( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ); + } + + IF( EQ_32( st_fx->output_Fs, 32000 ) ) + { + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + max = s_max( max, abs_s( hBWE_TD->state_32and48k_WB_upsample_fx[i] ) ); + } + } + IF( EQ_32( st_fx->output_Fs, 48000 ) ) + { + FOR( i = 0; i < INTERP_3_1_MEM_LEN; i++ ) + { + max = s_max( max, abs_s( hBWE_TD->mem_resamp_HB_fx[i] ) ); + } + } + n_mem = 15; + IF( max != 0 ) + { + n_mem = norm_s( max ); + } + n_mem = s_max( n_mem, 0 ); + + IF( sub( Qx, st_fx->prev_Qx ) > n_mem ) + Qx = add( st_fx->prev_Qx, n_mem ); + + FOR( i = 0; i < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; i++ ) + { + shaped_wb_excitation[i] = shl( shaped_wb_excitation[i], Qx ); + move16(); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->state_lsyn_filt_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + move16(); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + move16(); + } + + GenWBSynth_fx( shaped_wb_excitation, error, hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx ); + + Copy( error + L_FRAME16k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH ); + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + synth[i] = mult_r( error[i], 21299 ); + move16(); + } + + max = 0; + move16(); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + max = s_max( max, abs_s( synth[cnt] ) ); + } + + IF( max == 0 ) + { + st_fx->last_wb_bwe_ener_fx = 0; + move16(); + } + ELSE + { + n = norm_s( max ); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ + move16(); + } + n = sub( sub( 14, n ), Qx ); + + Lacc = 0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ + Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + } + + L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ + exp = norm_l( L_tmp ); +#ifdef BASOP_NOGLOB + tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); +#else + tmp = round_fx( L_shl( L_tmp, exp ) ); +#endif + exp = sub( add( exp, 22 ), 30 ); + tmp = div_s( 16384, tmp ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ + st_fx->last_wb_bwe_ener_fx = round_fx( L_shl( L_tmp, add( exp, n - 12 ) ) ); /* Q3 */ + } + + + IF( EQ_32( st_fx->output_Fs, 32000 ) ) /* 32kHz sampling rate, but only WB output - interpolate */ + { + Scale_sig( hBWE_TD->state_32and48k_WB_upsample_fx, 2 * ALLPASSSECTIONS_STEEP, sub( Qx, st_fx->prev_Qx ) ); + Interpolate_allpass_steep_fx( synth, hBWE_TD->state_32and48k_WB_upsample_fx, L_FRAME16k, upsampled_synth ); + Copy( upsampled_synth, synth, L_FRAME32k ); + } + ELSE IF( EQ_32( st_fx->output_Fs, 48000 ) ) + { + Scale_sig( hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, st_fx->prev_Qx ) ); + ivas_interpolate_3_over_1_allpass_fx( synth, L_FRAME16k, upsampled_synth, hBWE_TD->mem_resamp_HB_fx ); + Copy( upsampled_synth, synth, L_FRAME48k ); + } + } + ELSE + { + f = 5461; + move16(); /* Q15 */ + inc = 5461; + move16(); /* Q15 */ + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + lsf_wb[i] = f; + move16(); /*Q15*/ +#ifdef BASOP_NOGLOB + f = add_sat( f, inc ); +#else + f = add( f, inc ); +#endif + move16(); + } + GainFrame = 0; /* Q18 */ + Qx = 0; + Q_bwe_exc = 31; + hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ + st_fx->prev_frame_pow_exp = 0; + move16(); + } + + /* Update previous frame parameters for FEC */ + IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35 ) ) + { + Copy( lsf_wb, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER_LBR_WB ); + } + ELSE + { + Copy( lsf_wb, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER_WB ); + } + hBWE_TD->GainFrame_prevfrm_fx = GainFrame; /* Q18 */ + + IF( !st_fx->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + + *Q_synth = Qx; + move16(); + + st_fx->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + st_fx->prev_Qx = Qx; move16(); return; } +#endif - - - -/*==========================================================================*/ -/* FUNCTION : void wb_tbe_dec_fx () */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : WB TBE decoder, 6 - 8 kHz band decoding module */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _Word16 coder_type i : coding type */ -/* _Word32 *bwe_exc_extended i : bandwidth extended exciatation 2*Q_exc*/ -/* _Word16 Q_exc i : Q format */ -/* _Word16 voice_factors[] i : voicing factors Q15 */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _Word16 *synth o : WB synthesis/final synthesis Q_synth */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Decoder_State *st_fx, i/o: decoder state structure */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==========================================================================*/ void wb_tbe_dec_fx( Decoder_State* st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -3100,6 +3693,292 @@ static void Dequant_mirror_point_fx( /*--------------------------------------------------------------------------*/ /* CALLED FROM : */ /*==========================================================================*/ +#ifdef IVAS_FLOAT_FIXED +static 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 i, j, idxLSF, idxSubGain, idxFrameGain; + Word16 Q_combined_gains[NUM_SHB_SUBFR / 4]; + Word16 lsf_q[LPC_SHB_ORDER]; + Word16 lsf_idx[NUM_Q_LSF]; + Word16 m_idx, grid_idx; + Word16 m; + Word32 L_tmp; + Word16 tmp, frac, exp; + Word16 idx_shb_fr_gain, idx_res_gs[5], idx_mixFac; + Word16 temp_shb_ener_sf_fx; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* LSFs */ + + IF( EQ_16( extl, WB_TBE ) ) + { + IF( EQ_32( extl_brate, WB_TBE_0k35 ) ) + { + IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + { + idxFrameGain = hBWE_TD->gFrame_WB_fx; + idxLSF = hBWE_TD->lsf_WB_fx; + } + ELSE + { + 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 ); + } + ELSE + { + *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 ); + move16(); + 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 ); + + 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 */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + Q_combined_gains[i] = shl( tmp, add( exp, 1 ) ); /* Q15 */ + } + + FOR( i = 0; i < NUM_SHB_SUBFR / 2; i += 2 ) + { + Q_subgain[i] = Q_combined_gains[i / 2]; // Q15 + move16(); + Q_subgain[i + 1] = Q_combined_gains[i / 2]; // Q15 + move16(); + } + + /* frame gain */ + Copy32( SHBCB_FrameGain64_fx + idxFrameGain, Q_framegrain, 1 ); + } + } + ELSE /* SWB TBE DEC */ + { + IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + { + idxSubGain = hBWE_TD->idxSubGains_fx; + idxFrameGain = hBWE_TD->idxFrameGain_fx; + } + ELSE + { + idxSubGain = (Word16) get_next_indice( st_fx, NUM_BITS_SHB_SUBGAINS ); + idxFrameGain = (Word16) 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 ) ) + { + idx_shb_fr_gain = hBWE_TD->idx_shb_fr_gain_fx; + } + ELSE + { + 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 */ + } + + IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + { + idx_mixFac = hBWE_TD->idx_mixFac_fx; + 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 + { + *Q_shb_ener_sf = L_deposit_l( 0 ); + *Q_mixFactors = 0; + move16(); + set16_fx( Q_shb_res_gshape, 0, 5 ); + } + + /* 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 ) ) + { + FOR( i = 0; i < NUM_Q_LSF; i++ ) + { + lsf_idx[i] = hBWE_TD->lsf_idx_fx[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_fx; + } + 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_fx; + } + 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 + { + 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 ); + + /* 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(); + } + + /* 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*/ + } + + return; +} +#endif + static void dequantizeSHBparams_fx_9_1( Decoder_State* st_fx, const Word16 extl, /* i : extension layer */