From fb1f1f4cde3783db814f3337104771c20ce0337b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 23 Feb 2024 18:56:53 +0530 Subject: [PATCH] decod_gen_2sbfr converted to fixed point --- lib_com/est_tilt_fx.c | 101 ++++++++++++ lib_com/ivas_prot.h | 17 ++ lib_com/prot_fx2.h | 83 ++++++++++ lib_com/rom_com.c | 23 +++ lib_com/rom_com.h | 1 + lib_com/swb_tbe_com_fx.c | 192 ++++++++++++++++++++++ lib_dec/inov_dec_fx.c | 180 +++++++++++++++++++++ lib_dec/ivas_td_low_rate_dec.c | 253 +++++++++++++++++++++++++++++ lib_dec/pit_dec_fx.c | 282 +++++++++++++++++++++++++++++++++ 9 files changed, 1132 insertions(+) diff --git a/lib_com/est_tilt_fx.c b/lib_com/est_tilt_fx.c index 09cd8110f..addad1aee 100644 --- a/lib_com/est_tilt_fx.c +++ b/lib_com/est_tilt_fx.c @@ -92,6 +92,107 @@ Word16 est_tilt_fx( /* o : tilt of the code Q15 * return tilt_code; } + +#ifdef IVAS_FLOAT_FIXED +/*======================================================================*/ +/* FUNCTION : est_tilt_ivas_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Estimate spectral tilt based on the relative E of adaptive */ +/* and innovative excitations */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16 *) exc : adaptive excitation vector Q0 */ +/* _ (Word16) gain_pit : adaptive gain Q14 */ +/* _ (Word16 *) code : algebraic exctitation vector Q12 */ +/* _ (Word32) gain_code : algebraic code gain Q16 */ +/* _ (Word16) Q_exc : Scaling factor of excitation Q0 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *) voice_fac : voicing factor Q15 */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/*-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ (Word16) tolt_code : tilt of the code Q15 */ +/*=======================================================================*/ +Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ +#if 1//def ADD_LRTD + , const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ +#endif +) +{ + Word16 i, tmp, exp, ener1, exp1, ener2, exp2; + Word32 L_tmp; + Word16 tilt_code; +#ifdef ADD_LRTD + PMT("FIX POINT NEED to be adapted for 16 kHz frame length ") +#endif + ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1)); + exp1 = sub(exp1, add(Q_exc, Q_exc)); + L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */ + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + ener1 = mult(ener1, tmp); + exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */ + + ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2)); + + exp = norm_l(gain_code); + tmp = extract_h(L_shl(gain_code, exp)); + tmp = mult(tmp, tmp); /* energy of innovative code excitation */ + ener2 = mult(ener2, tmp); + exp2 = sub(exp2, add(exp, exp)); + + i = sub(exp1, exp2); + BASOP_SATURATE_WARNING_OFF_EVS + ener1 = shr(ener1, sub(1, s_min(i, 0))); + ener2 = shr(ener2, add(s_max(0, i), 1)); + BASOP_SATURATE_WARNING_ON_EVS + tmp = sub(ener1, ener2); + ener1 = add(add(ener1, ener2), 1); + + /* find voice factor (1=voiced, -1=unvoiced) */ + exp = div_s(abs_s(tmp), ener1); + IF( LT_16( tmp, 0 ) ) + { + exp = negate(exp); + } + *voice_fac = exp; + move16(); + + IF(flag_tilt == 0) { + /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */ + + /* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */ + tilt_code = mac_r(8192L * 65536 - 0x8000, *voice_fac, 8192); /*Q15 */ + } + ELSE IF(flag_tilt == 1) + { + /*Between 0.25 (=unvoiced) and 0.5 (=voiced)*/ + //tilt_code = (float)(0.25f + (*voice_fac + 1.0f) * 0.125f); + tilt_code = mac_r(12288L * 65536 - 0x8000, *voice_fac, 4096); /*Q15 */ + } + ELSE + { + /*Between 0.28 (=unvoiced) and 0.56 (=voiced)*/ + //tilt_code = (float)(0.28f + (*voice_fac + 1.0f) * 0.14f); + tilt_code = mac_r(13763L * 65536 - 0x8000, *voice_fac, 4588); /*Q15 */ + } + + return tilt_code; +} +#endif + /*-------------------------------------------------------------------* * Est_tilt2: * diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 42c717020..9f9dd5af3 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -506,6 +506,23 @@ void decod_gen_2sbfr( const float tdm_Pri_pitch_buf[] /* i : pitch values for primary channel */ ); +#ifdef IVAS_FLOAT_FIXED +void decod_gen_2sbfr_ivas_fx( + Decoder_State *st, /* i/o: decoder static memory */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 *Aq, /* i : LP filter coefficient */ + Word16 *pitch_buf, /* o : floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *exc, /* i/o: adapt. excitation exc */ + Word16 *exc2, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *gain_buf, /* o : floating pitch gain for each subframe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel */ + Word16 Q_exc +); +#endif + void synchro_synthesis( const int32_t ivas_total_brate, /* i : IVAS total bitrate */ CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 638feecc6..b7baf8e9f 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -2757,6 +2757,36 @@ void prep_tbe_exc_fx( #endif ); +#ifdef IVAS_FLOAT_FIXED +void prep_tbe_exc_ivas_fx( + const Word16 L_frame_fx, /* i : length of the frame */ +#if 1//def ADD_IVAS_TBE_CODE + const Word16 L_subfr, +#endif + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + Word32 core_brate +#if 1//def ADD_IVAS_TBE_CODE + , /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#endif +); + +#endif Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ Word16* tilt_mem /* i/o: Tilt smoothing memory */ @@ -4238,6 +4268,22 @@ Word16 est_tilt_fx( /* o : tilt of the code , const Word16 L_subfr /* i : Sub frame lenght */ #endif ); + +#ifdef IVAS_FLOAT_FIXED +Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ +#if 1//def ADD_LRTD + , const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ +#endif +); +#endif + Word16 Est_tilt2( /* o : tilt of the code */ const Word16 *exc, /* i : adaptive excitation vector Qx */ const Word16 gain_pit, /* i : adaptive gain Q14 */ @@ -6234,6 +6280,27 @@ void init_tcx_cfg_fx( #endif ); +#ifdef IVAS_FLOAT_FIXED + Word16 pit_decode_ivas_fx( /* o : floating pitch value */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr /* i : subframe length */ +#if 1//def ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif + ); +#endif + void pit_Q_dec_fx( const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ const Word16 pitch_index, /* i : pitch index */ @@ -6316,6 +6383,22 @@ void init_tcx_cfg_fx( , const Word16 L_subfr /* i : subframe length */ ); +#ifdef IVAS_FLOAT_FIXED + void inov_decode_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12 */ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15 */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + Word16 *code, /* o : algebraic excitation */ + const Word16 L_subfr /* i : subframe length */ + ); +#endif + //dec4t64_fx.c void dec_acelp_4t64_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 1a1ffa0bb..42526d53f 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -1769,6 +1769,29 @@ const float inter4_2[65] = -0.000618f, -0.000434f, -0.000133f, 0.000063f, 0.000098f, 0.000048f, 0.000007f, 0.000000f }; + + +const Word16 inter4_2_fx_Q15[65] = +{ + 30801, + 28062, 20718, 11061, 1935, + -4294, -6533, -5195, -1846, + 1559, 3497, 3398, 1705, + -497, -2087, -2413, -1523, + -32, 1252, 1741, 1312, + 305, -710, -1237, -1087, + -426, 350, 848, 862, + 452, -119, -550, -650, + -418, -17, 330, 462, + 349, 85, -175, -306, + -265, -104, 76, 184, + 182, 93, -20, -98, + -110, -66, -3, 43, + 55, 37, 8, -13, + -20, -14, -4, 2, + 3, 1, 0, 0, +}; + const Word16 inter4_2_fx[] = { 0, 1, 2, 1, diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 0ee851313..f3a5a4ec4 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -193,6 +193,7 @@ extern const float sincos_t_rad3[]; extern const Word16 sincos_t_rad3_fx[]; extern const int16_t fft256_read_indexes[]; /* FFT */ extern const float inter4_2[]; /* 1/4 resolution interpolation filter */ +extern const Word16 inter4_2_fx_Q15[]; /* 1/4 resolution interpolation filter */ extern const Word16 inter4_2_fx[]; extern const Word16 pitch_inter4_1[UP_SAMP * L_INTERPOL1 + 1]; /*1Q14*/ extern const Word16 pitch_inter4_2[PIT_FIR_SIZE2]; /*1Q14*/ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 0c5fd5234..e6432fc05 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -4105,6 +4105,198 @@ void prep_tbe_exc_fx( return; } +#ifdef IVAS_FLOAT_FIXED +/*======================================================================================*/ +/* FUNCTION : prep_tbe_exc_ivas_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Prepare TBE excitation */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) L_frame_fx : length of the frame */ +/* _ (Word16) i_subfr_fx : subframe index */ +/* _ (Word16) gain_pit_fx : Pitch gain (14) */ +/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ +/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ +/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ +/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ +/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ + +void prep_tbe_exc_ivas_fx( + const Word16 L_frame_fx, /* i : length of the frame */ +#if 1//def ADD_IVAS_TBE_CODE + const Word16 L_subfr, +#endif + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + Word32 core_brate +#if 1//def ADD_IVAS_TBE_CODE + , /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#endif +) +{ + Word16 i; + Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; + Word16 tmp_code_preInt_fx[L_SUBFR]; + Word16 gain_code16 = 0; + Word16 tmp /*, tmp1, tmp2*/; + /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ + Word16 pitch; + + Word32 L_tmp, Ltemp1, Ltemp2; + Word32 tempQ31; + Word16 tempQ15; +#if 0//ndef ADD_IVAS_TBE_CODE + Word16 L_subfr = L_SUBFR; +#endif +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; + = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) + *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ + tempQ31 = L_deposit_h(VF_1st_PARAM_FX); + tempQ15 = mac_r(tempQ31, VF_2nd_PARAM_FX, voice_fac_fx); + tempQ31 = L_deposit_h(VF_0th_PARAM_FX); + *voice_factors_fx = mac_r(tempQ31, voice_fac_fx, tempQ15); + + tmp = 32767; + move16(); + +#ifdef BASOP_NOGLOB + pitch = shl_o(add(shl_o(T0, 2, &Overflow), T0_frac), 5, &Overflow); /* Q7 */ +#else /* BASOP_NOGLOB */ + pitch = shl(add(shl(T0, 2), T0_frac), 5); /* Q7 */ +#endif /* BASOP_NOGLOB */ + + test(); + test(); + IF(((EQ_16(coder_type, VOICED)) || (GT_16(pitch, 14784))) && (GT_32(core_brate, ACELP_8k00))) + { + tmp = MAX_16; + move16(); + *voice_factors_fx = mult_r(*voice_factors_fx, tmp); + } + + *voice_factors_fx = s_min(s_max(*voice_factors_fx, 0), MAX_16); + move16(); +#if 1 //def ADD_IVAS_TBE_CODE + IF(EQ_16(element_mode, IVAS_CPE_TD) && EQ_16(idchan, 1) && !tdm_LRTD_flag) + { + IF(flag_TD_BWE && i_subfr_fx == 0) + { + set16_fx(bwe_exc_fx, 0, L_FRAME32k); + } + return; + } + +#endif + IF(EQ_16(L_frame_fx, L_FRAME)) + { + interp_code_5over2_fx(code_fx, tmp_code_fx, L_subfr); /* code: Q9, tmp_code: Q9 */ +#ifdef BASOP_NOGLOB + gain_code16 = round_fx_o(L_shl_o(gain_code_fx, Q_exc, &Overflow), &Overflow); /*Q_exc */ +#else + gain_code16 = round_fx(L_shl(gain_code_fx, Q_exc)); /*Q_exc */ +#endif + FOR(i = 0; i < L_subfr* HIBND_ACB_L_FAC; i++) + { + L_tmp = L_mult(gain_code16, tmp_code_fx[i]); /* Q9 + Q_exc + 1*/ + L_tmp = L_shl(L_tmp, 5); /* Q9 + Q_exc + Q6*/ + L_tmp = L_mac(L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC]); /*Q15+Q_exc */ +#ifdef BASOP_NOGLOB + L_tmp = L_shl_o(L_tmp, 1, &Overflow); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o(L_tmp, &Overflow); /*Q_exc */ +#else /* BASOP_NOGLOB */ + L_tmp = L_shl(L_tmp, 1); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx(L_tmp); /*Q_exc */ +#endif /* BASOP_NOGLOB */ + } + } + ELSE + { + IF(gain_preQ_fx != 0) + { + FOR(i = 0; i < L_subfr; i++) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16(gain_code_fx, code_fx[i]); /* Q16 + Q9 + 1 - 16 = Q10 */ + Ltemp2 = L_mult(gain_preQ_fx, code_preQ_fx[i]); /*Q2 * Q10 -> Q12 */ + +#ifdef BASOP_NOGLOB + Ltemp1 = L_shl_o(Ltemp1, Q_exc + 6 /*Q_exc+16-19*/, &Overflow); /*Q_exc+16 */ + Ltemp2 = L_shl_o(Ltemp2, Q_exc + 4 /*Q_exc+16-13*/, &Overflow); /*Q_exc+16 */ + + tmp_code_preInt_fx[i] = round_fx_o(L_add_o(Ltemp1, Ltemp2, &Overflow), &Overflow); /* Q_exc */ +#else /* BASOP_NOGLOB */ + Ltemp1 = L_shl(Ltemp1, Q_exc + 6 /*Q_exc+16-19*/); /*Q_exc+16 */ + Ltemp2 = L_shl(Ltemp2, Q_exc + 4 /*Q_exc+16-13*/); /*Q_exc+16 */ + + tmp_code_preInt_fx[i] = round_fx(L_add(Ltemp1, Ltemp2)); /* Q_exc */ +#endif /* BASOP_NOGLOB */ + } + } + ELSE + { + FOR(i = 0; i < L_subfr; i++) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16(gain_code_fx, code_fx[i]); /* Q16 + Q9 + 1 - 16 = Q10 */ +#ifdef BASOP_NOGLOB + Ltemp1 = L_shl_o(Ltemp1, Q_exc + 6 /*Q_exc+16-19*/, &Overflow); /*Q_exc+16 */ + tmp_code_preInt_fx[i] = round_fx_o(Ltemp1, &Overflow); /* Q_exc */ +#else + Ltemp1 = L_shl(Ltemp1, Q_exc + 6 /*Q_exc+16-19*/); /*Q_exc+16 */ + tmp_code_preInt_fx[i] = round_fx(Ltemp1); /* Q_exc */ +#endif + } + } + + interp_code_4over2_fx(tmp_code_preInt_fx, tmp_code_fx, L_subfr); /* o: tmp_code in Q_exc */ + FOR(i = 0; i < L_subfr * 2; i++) + { + L_tmp = L_mult(gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2]); /*Q14+Q_exc+1 */ +#ifdef BASOP_NOGLOB + tmp = round_fx_o(L_shl_o(L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow), &Overflow); /* tmp in Q_exc */ + bwe_exc_fx[i + i_subfr_fx * 2] = add_o(tmp, tmp_code_fx[i], &Overflow); /*Q_exc */ move16(); +#else /* BASOP_NOGLOB */ + tmp = round_fx(L_shl(L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/)); /* tmp in Q_exc */ + bwe_exc_fx[i + i_subfr_fx * 2] = add(tmp, tmp_code_fx[i]); /*Q_exc */ move16(); +#endif + } + } + + return; +} +#endif /*=============================================================================*/ /* FUNCTION : void swb_formant_fac_fx ( ) */ diff --git a/lib_dec/inov_dec_fx.c b/lib_dec/inov_dec_fx.c index 370635f5b..563775f3e 100644 --- a/lib_dec/inov_dec_fx.c +++ b/lib_dec/inov_dec_fx.c @@ -183,3 +183,183 @@ PMT("CONDITION above is missing -> idchan") return; } + +#ifdef IVAS_FLOAT_FIXED +/*======================================================================*/ +/* FUNCTION : inov_decode_ivas_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Decode the algebraic innovation and do pitch sharpening */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16) i_subfr : length of the frame Q0 */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16) L_subfr : subframe length */ +/* _ (Word16) sharpFlag : formant sharpening flag */ +/* _ (Word16) tc_subfr : TC subframe index */ +/* _ (Word16 *) p_Aq : LP filter coefficients Q12 */ +/* _ (Word16) tilt_code : tilt of the excitation of previous subframe Q15*/ +/* _ (Word16) pt_pitch : current subframe fractional pitch Q6 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *[]) code : subframe length Q12 */ +/* _ (Word16 []) index_buf_4T : subframe length */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/*-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void inov_decode_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12 */ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15 */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + Word16 *code, /* o : algebraic excitation */ + const Word16 L_subfr /* i : subframe length */ +) +{ + Word16 nBits; + Word16 g1, g2; + + IF( EQ_16( L_frame, L_FRAME ) ) + { + g1 = FORMANT_SHARPENING_G1; + g2 = FORMANT_SHARPENING_G2; + } + ELSE + { + g1 = FORMANT_SHARPENING_G1_16k; + g2 = FORMANT_SHARPENING_G2_16k; + } + + IF( !Opt_AMR_WB ) + { +#if 1 // def IVAS_CODE + IF( st_fx->acelp_cfg.fcb_mode ) + { + Word16 i; + Word16 indexing_indices[8], wordcnt, bitcnt; + PulseConfig config; + IF( GE_16( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr], 0 ) ) + { + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr]; + + IF( EQ_16( nBits, 8 ) ) + { + // dec_acelp_1t64(st_fx, code, L_subfr); + dec_acelp_1t64_fx( st_fx, code, L_subfr ); + } + ELSE + { + // dec_acelp_fast(st_fx, nBits, code, L_subfr); + dec_acelp_fast_fx( st_fx, nBits, code, L_subfr ); + } + } + ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], 7 ) ) || ( st_fx->idchan == 0 && st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 3 ) ) + { + IF( EQ_16( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], 0 ) ) + { + // dec_acelp_1t64(st_fx, code, L_SUBFR); + dec_acelp_1t64_fx( st_fx, code, L_SUBFR ); + } + ELSE + { + // dec_acelp_fast(st_fx, st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], code, L_SUBFR); + dec_acelp_fast_fx( st_fx, st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], code, L_SUBFR ); + } + } + ELSE + { + wordcnt = shr( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ), 4 ); + bitcnt = ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ) & 15; + // PMT("CONDITION above is missing -> idchan") + FOR( i = 0; i < wordcnt; i++ ) + { + indexing_indices[i] = get_next_indice( st_fx, 16 ); + } + IF( bitcnt ) + { + indexing_indices[i] = get_next_indice( st_fx, bitcnt ); + } + config = PulseConfTable[st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]]; + D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, indexing_indices, &st_fx->BER_detect ); + } + } + ELSE + { + set16_fx( code, 0, L_SUBFR ); + } + } + ELSE +#endif + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]; + + IF( EQ_16( nBits, 7 ) ) + { + dec_acelp_1t64_fx( st_fx, code, L_SUBFR ); + } + ELSE IF( EQ_16( nBits, 12 ) ) + { + dec_acelp_2t32_fx( st_fx, code ); + } + ELSE + { + dec_acelp_4t64_fx( st_fx, nBits, code, Opt_AMR_WB ); + } + } + } + ELSE + { + IF( EQ_32( core_brate, ACELP_6k60 ) ) + { + dec_acelp_2t32_fx( st_fx, code ); + } + ELSE IF( EQ_32( core_brate, ACELP_8k85 ) ) + { + dec_acelp_4t64_fx( st_fx, 20, code, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_12k65 ) ) + { + dec_acelp_4t64_fx( st_fx, 36, code, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_14k25 ) ) + { + dec_acelp_4t64_fx( st_fx, 44, code, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_15k85 ) ) + { + dec_acelp_4t64_fx( st_fx, 52, code, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_18k25 ) ) + { + dec_acelp_4t64_fx( st_fx, 64, code, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_19k85 ) ) + { + dec_acelp_4t64_fx( st_fx, 72, code, Opt_AMR_WB ); + } + ELSE + { + dec_acelp_4t64_fx( st_fx, 88, code, Opt_AMR_WB ); + } + } + + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, code, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index b32c358a2..0c07774dd 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -399,6 +399,7 @@ void decod_gen_2sbfr( const float tdm_Pri_pitch_buf[] /* i : pitch values for primary channel */ ) { +#ifndef IVAS_FLOAT_FIXED int16_t T0, T0_frac, T0_min, T0_max; /* integer pitch variables */ float gain_pit = 0.0f; /* pitch gain */ float gain_code = 0.0f; /* gain/normalized gain of the algebraic excitation */ @@ -513,5 +514,257 @@ void decod_gen_2sbfr( /* SC-VBR */ st->prev_gain_pit_dec = gain_pit; + return; +#else + /*hGSCDec float2fix*/ + st->hGSCDec->seed_tcx_fx = st->hGSCDec->seed_tcx; + st->hGSCDec->cor_strong_limit_fx = st->hGSCDec->cor_strong_limit; + floatToFixed_arr( st->hGSCDec->old_y_gain, st->hGSCDec->old_y_gain_fx, Q12, MBANDS_GN ); + st->hGSCDec->noise_lev_fx = st->hGSCDec->noise_lev; + floatToFixed_arr( st->hGSCDec->lt_ener_per_band, st->hGSCDec->lt_ener_per_band_fx, Q12, MBANDS_GN ); + st->hGSCDec->Last_frame_ener_fx = st->hGSCDec->Last_frame_ener < MAX_32 ? floatToFixed( st->hGSCDec->Last_frame_ener, Q3 ) : MAX_32; + floatToFixed_arr( st->hGSCDec->Last_GSC_spectrum, st->hGSCDec->Last_GSC_spectrum_fx, Q10, L_FRAME ); + st->hGSCDec->Last_GSC_pit_band_idx_fx = st->hGSCDec->Last_GSC_pit_band_idx; + floatToFixed_arr( st->hGSCDec->last_exc_dct_in, st->hGSCDec->last_exc_dct_in_fx, 0, L_FRAME ); + // st->hGSCDec->last_ener_fx = float_to_fix16(st->hGSCDec->last_ener, 0); + Copy( st->hGSCDec->last_bitallocation_band, st->hGSCDec->last_bitallocation_band_fx, 6 ); + st->GSC_noisy_speech_fx = st->GSC_noisy_speech; + st->lp_gainc_fx = float_to_fix16( st->lp_gainc, Q3 ); + st->bfi_pitch_fx = float_to_fix16( st->bfi_pitch, Q6 ); + st->tilt_code_fx = float_to_fix16( st->tilt_code, Q15 ); + floatToFixed_arr( st->tilt_code_dec, st->tilt_code_dec_fx, Q15, NB_SUBFR16k ); + st->dm_fx.prev_state = float_to_fix16(st->dispMem[0], 0); + st->dm_fx.prev_gain_code = floatToFixed(st->dispMem[1], Q16); + floatToFixed_arr(&(st->dispMem[2]), st->dm_fx.prev_gain_pit, Q14, 6); + st->last_good_fx = st->last_good; + st->Last_GSC_noisy_speech_flag_fx = st->Last_GSC_noisy_speech_flag; + st->last_coder_type_fx = st->last_coder_type; + /*hGSCDec end*/ + + Word16 Aq_fx[NB_SUBFR16k * (M + 1)]; + Word16 pitch_buf_fx[NB_SUBFR16k]; + Word16 voice_factors_fx[5]; + Word16 old_exc_fx[L_EXC_DEC], *exc_fx; + Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; + Word16 bwe_exc_fx[L_FRAME32k], * p_bwe_exc_fx; + Word16 gain_buf_fx[NB_SUBFR16k]; + Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; + floatToFixed_arr(Aq, Aq_fx, Q14, NB_SUBFR16k * (M + 1)); + floatToFixed_arr(tdm_Pri_pitch_buf, tdm_Pri_pitch_buf_fx, Q6, NB_SUBFR); + floatToFixed_arr(exc - L_EXC_MEM_DEC, old_exc_fx, Q8, L_EXC_DEC); + exc_fx = old_exc_fx + L_EXC_MEM_DEC; + floatToFixed_arr(exc2 - L_EXC_MEM, old_exc2_fx, Q8, L_FRAME16k + L_EXC_MEM); + exc2_fx = old_exc2_fx + L_EXC_MEM; + floatToFixed_arr(gain_buf, gain_buf_fx, Q14, NB_SUBFR16k); + if (bwe_exc) { + set_s(bwe_exc_fx, 0, L_FRAME32k); + p_bwe_exc_fx = bwe_exc_fx; + } + else { + p_bwe_exc_fx = NULL; + } + decod_gen_2sbfr_ivas_fx( st, sharpFlag, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, p_bwe_exc_fx, gain_buf_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q8); + fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR16k ); + fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, 5 ); + fixedToFloat_arr( exc_fx, exc, Q8, L_FRAME ); + fixedToFloat_arr( exc2_fx, exc2, Q8, L_FRAME ); + fixedToFloat_arr(gain_buf_fx, gain_buf, Q14, NB_SUBFR16k); + if (bwe_exc) { + fixedToFloat_arr(p_bwe_exc_fx, bwe_exc, Q8, L_FRAME32k); + } + + /*hGSCDec fix2float*/ + st->hGSCDec->seed_tcx = st->hGSCDec->seed_tcx_fx; + st->hGSCDec->cor_strong_limit = st->hGSCDec->cor_strong_limit_fx; + fixedToFloat_arr( st->hGSCDec->old_y_gain_fx, st->hGSCDec->old_y_gain, Q12, MBANDS_GN ); + st->hGSCDec->noise_lev = st->hGSCDec->noise_lev_fx; + fixedToFloat_arr( st->hGSCDec->lt_ener_per_band_fx, st->hGSCDec->lt_ener_per_band, Q12, MBANDS_GN ); + st->hGSCDec->Last_frame_ener = fixedToFloat( st->hGSCDec->Last_frame_ener_fx, Q3 ); + fixedToFloat_arr( st->hGSCDec->Last_GSC_spectrum_fx, st->hGSCDec->Last_GSC_spectrum, Q10, L_FRAME ); + st->hGSCDec->Last_GSC_pit_band_idx = st->hGSCDec->Last_GSC_pit_band_idx_fx; + fixedToFloat_arr( st->hGSCDec->last_exc_dct_in_fx, st->hGSCDec->last_exc_dct_in, Q8, L_FRAME ); + st->hGSCDec->last_ener = fixedToFloat( st->hGSCDec->last_ener_fx, 0 ); + Copy( st->hGSCDec->last_bitallocation_band_fx, st->hGSCDec->last_bitallocation_band, 6 ); + st->GSC_noisy_speech = st->GSC_noisy_speech_fx; + st->lp_gainc = fixedToFloat( st->lp_gainc_fx, Q3 ); + st->bfi_pitch = fixedToFloat( st->bfi_pitch_fx, Q6 ); + st->tilt_code = fixedToFloat( st->tilt_code_fx, Q15 ); + fixedToFloat_arr( st->tilt_code_dec_fx, st->tilt_code_dec, Q15, NB_SUBFR16k ); + st->dispMem[0] = fixedToFloat(st->dm_fx.prev_state, 0); + st->dispMem[1] = fixedToFloat(st->dm_fx.prev_gain_code, Q16); + fixedToFloat_arr(st->dm_fx.prev_gain_pit, &(st->dispMem[2]), Q14, 6); +/*hGSCDec end*/ +#endif +} + +#ifdef IVAS_FLOAT_FIXED +/*---------------------------------------------------------------------* + * decod_gen_2sbfr_ivas_fx() + * + * Decode generic (GC), 2 subframes mode + *---------------------------------------------------------------------*/ + +void decod_gen_2sbfr_ivas_fx( + Decoder_State *st, /* i/o: decoder static memory */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 *Aq, /* i : LP filter coefficient */ + Word16 *pitch_buf, /* o : floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *exc, /* i/o: adapt. excitation exc */ + Word16 *exc2, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *gain_buf, /* o : floating pitch gain for each subframe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel */ + Word16 Q_exc ) +{ + Word16 T0, T0_frac, T0_min, T0_max; /* integer pitch variables */ + // float gain_pit = 0.0f; /* pitch gain */ + // float gain_code = 0.0f; /* gain/normalized gain of the algebraic excitation */ + // float norm_gain_code = 0.0f; /* normalized gain of the algebraic excitation */ + // float gain_inov = 0; /* Innovation gain */ + // float gains_mem[2 * (NB_SUBFR - 1)]; /* pitch gain and code gain from previous subframes */ + // float voice_fac; /* voicing factor */ + // float code[2 * L_SUBFR]; /* algebraic codevector */ + // const float *p_Aq; /* Pointer to frame LP coefficient */ + // float *pt_pitch; /* pointer to floating pitch */ + Word16 gain_pit = 0; /* pitch gain */ + Word32 gain_code = 0; /* gain/normalized gain of the algebraic excitation */ + Word32 norm_gain_code = 0; /* normalized gain of the algebraic excitation */ + Word16 gain_inov = 0; /* Innovation gain */ + // Word16 gains_mem[2 * (NB_SUBFR - 1)]; /* pitch gain and code gain from previous subframes */ + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ + Word16 voice_fac; /* voicing factor */ + Word16 code[2 * L_SUBFR]; /* algebraic codevector */ + const Word16 *p_Aq; /* Pointer to frame LP coefficient */ + Word16 *pt_pitch; /* pointer to floating pitch */ + Word16 i_subfr, i; /* tmp variables */ + Word16 L_frame; + Word16 pitch_limit_flag; + // float error; + Word16 error; + + /*------------------------------------------------------------------* + * Initialization + *------------------------------------------------------------------*/ + + L_frame = L_FRAME; + + T0 = PIT_MIN; + T0_frac = 0; + error = 0; + + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + + p_Aq = Aq; /* pointer to interpolated LPC parameters */ + pt_pitch = pitch_buf; /* pointer to the pitch buffer */ + + for ( i_subfr = 0; i_subfr < L_frame; i_subfr += 2 * L_SUBFR ) + { + /*----------------------------------------------------------------------* + * Decode pitch lag + *----------------------------------------------------------------------*/ + + //*pt_pitch = pit_decode_flt(st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf); + *pt_pitch = pit_decode_ivas_fx( st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + + // tbe_celp_exc_flt(st->element_mode, st->idchan, bwe_exc, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, st->tdm_LRTD_flag); + if ( !( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) && !( st->tdm_LRTD_flag ) ) ) + { + tbe_celp_exc( L_frame, i_subfr, T0, T0_frac, &error, bwe_exc ); + } + + /*--------------------------------------------------------------* + * Find the adaptive codebook vector + *--------------------------------------------------------------*/ + + // pred_lt4_flt(&exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP); + pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2_fx_Q15, L_INTERPOL2, PIT_UP_SAMP ); + + /*--------------------------------------------------------------* + * LP filtering of the adaptive excitation + *--------------------------------------------------------------*/ + + // lp_filt_exc_dec(st, MODE1, i_subfr, 2 * L_SUBFR, L_frame, st->acelp_cfg.ltf_mode, exc); + lp_filt_exc_dec_fx( st, MODE1, i_subfr, 2 * L_SUBFR, L_frame, st->acelp_cfg.ltf_mode, exc ); + + /*--------------------------------------------------------------* + * Innovation decoding + *--------------------------------------------------------------*/ + + // inov_decode(st, st->core_brate, 0, L_frame, sharpFlag, i_subfr, p_Aq, st->tilt_code, *pt_pitch, code, 2 * L_SUBFR); + inov_decode_ivas_fx( st, st->core_brate, 0, L_frame, sharpFlag, i_subfr, p_Aq, st->tilt_code_fx, *pt_pitch, code, 2 * L_SUBFR ); + + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + // gain_dec_lbr(st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gains_mem, 2 * L_SUBFR); + gain_dec_lbr_fx( st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gc_mem, gp_mem, 2 * L_SUBFR ); + // st->tilt_code = est_tilt(exc + i_subfr, gain_pit, code, gain_code, &voice_fac, 2 * L_SUBFR, 0); + // st->tilt_code_fx = est_tilt_fx(exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_exc/*, 2 * L_SUBFR, 0*/); + st->tilt_code_fx = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_exc, 2 * L_SUBFR, 0 ); + + /* update LP filtered gains for the case of frame erasures */ + // lp_gain_updt(i_subfr, gain_pit, norm_gain_code, &st->lp_gainp, &st->lp_gainc, L_frame); + // lp_gain_updt(i_subfr + L_SUBFR, gain_pit, norm_gain_code, &st->lp_gainp, &st->lp_gainc, L_frame); + lp_gain_updt_fx( i_subfr, gain_pit, norm_gain_code, &st->lp_gainp_fx, &st->lp_gainc_fx, L_frame ); + lp_gain_updt_fx( i_subfr + L_SUBFR, gain_pit, norm_gain_code, &st->lp_gainp_fx, &st->lp_gainc_fx, L_frame ); + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + for ( i = 0; i < 2 * L_SUBFR; i++ ) + { + // exc2[i + i_subfr] = gain_pit * exc[i + i_subfr]; + exc2[i + i_subfr] = mult_r( gain_pit, shl( exc[i + i_subfr], Q15 - Q14 ) ); + // exc[i + i_subfr] = exc2[i + i_subfr] + gain_code * code[i]; + exc[i + i_subfr] = add( exc2[i + i_subfr], (Word16) L_shr( Mpy_32_16_1( gain_code, code[i] ), Q9 ) ); + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + // prep_tbe_exc(L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, T0, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag); + // prep_tbe_exc_fx(L_frame, /*L_SUBFR,*/ i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_exc, T0, T0_frac, GENERIC, st->core_brate/*, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag*/); + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_exc, T0, T0_frac, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); + + voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; + + /*----------------------------------------------------------------* + * Excitation enhancements (update of total excitation signal) + * called twice because adapting it to double the subfr length would need lot of modifications + *----------------------------------------------------------------*/ + + // enhancer(MODE1, st->core_brate, -1, 0, GENERIC, L_frame, voice_fac, st->stab_fac, norm_gain_code, gain_inov, &st->gc_threshold, code, exc2 + i_subfr, gain_pit, st->dispMem); + // enhancer_fx(MODE1, st->core_brate, -1, 0, GENERIC, L_frame, voice_fac, st->stab_fac, norm_gain_code, gain_inov, &st->gc_threshold, code, exc2 + i_subfr, gain_pit, st->dispMem); + enhancer_fx( st->core_brate, 0, GENERIC, i_subfr, L_frame, voice_fac, st->stab_fac_fx, norm_gain_code, gain_inov, &st->gc_threshold_fx, code, exc2, gain_pit, &st->dm_fx, Q_exc ); + + // enhancer(MODE1, st->core_brate, -1, 0, GENERIC, L_frame, voice_fac, st->stab_fac, norm_gain_code, gain_inov, &st->gc_threshold, code + L_SUBFR, exc2 + i_subfr + L_SUBFR, gain_pit, st->dispMem); + // enhancer_fx(MODE1, st->core_brate, -1, 0, GENERIC, L_frame, voice_fac, st->stab_fac, norm_gain_code, gain_inov, &st->gc_threshold, code + L_SUBFR, exc2 + i_subfr + L_SUBFR, gain_pit, st->dispMem); + enhancer_fx( st->core_brate, 0, GENERIC, i_subfr, L_frame, voice_fac, st->stab_fac_fx, norm_gain_code, gain_inov, &st->gc_threshold_fx, code + L_SUBFR, exc2 + L_SUBFR, gain_pit, &st->dm_fx, Q_exc ); + + p_Aq += 2 * ( M + 1 ); + + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + pt_pitch++; + + gain_buf[i_subfr / L_SUBFR] = gain_pit; + gain_buf[( i_subfr + L_SUBFR ) / L_SUBFR] = gain_pit; + st->tilt_code_dec[i_subfr / L_SUBFR] = st->tilt_code; + st->tilt_code_dec[( i_subfr + L_SUBFR ) / L_SUBFR] = st->tilt_code; + } + + /* SC-VBR */ + st->prev_gain_pit_dec = gain_pit; + return; } +#endif diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index 46056e716..f9693f7ca 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -564,6 +564,288 @@ printf("function not tested yet\n"); return pitch; } +#ifdef IVAS_FLOAT_FIXED +/*======================================================================*/ +/* FUNCTION : pit_decode_ivas_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : calculate pitch value */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16) i_subfr : length of the frame Q0 */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) L_subfr : subframe length */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *) T0 : close loop integer pitch */ +/* _ (Word16 *) T0_frac : close loop fractional part of the pitch */ +/* _ (Word16 ) pitch : pitch value Q6 */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/* _ (Word16 *) T0_min : delta search min for sf 2 & 4 */ +/* _ (Word16 *) T0_max : delta search max for sf 2 & 4 */ +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ (Word16 ) pitch : close loop integer pitch Q6 */ +/*=======================================================================*/ + + +Word16 pit_decode_ivas_fx( /* o : floating pitch value */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr /* i : subframe length */ +#if 1//def ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif +) +{ + Word16 pitch; /*Q2*/ + Word16 pitch_index, nBits, pit_flag; + + pitch_index = 0; + + /*----------------------------------------------------------------* + * Set pit_flag = 0 for every subframe with absolute pitch search + *----------------------------------------------------------------*/ + pit_flag = i_subfr; + move16(); + + if ( EQ_16( i_subfr, PIT_DECODE_2XL_SUBFR ) ) + { + pit_flag = 0; + move16(); + } + + /*-------------------------------------------------------* + * Retrieve the pitch index + *-------------------------------------------------------*/ + IF( !Opt_AMR_WB ) + { + /*----------------------------------------------------------------* + * pitch Q: Set limit_flag to 0 for restrained limits, and 1 for extended limits + *----------------------------------------------------------------*/ + test(); + test(); + IF( i_subfr == 0 ) + { + *limit_flag = 1; + move16(); + + if ( EQ_16( coder_type, VOICED ) ) + { + *limit_flag = 2; + move16(); /* double-extended limits */ + } + test(); + if ( EQ_16( coder_type, GENERIC ) && EQ_32( core_brate, ACELP_7k20 ) ) + { + *limit_flag = 0; + move16(); + } + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) && EQ_32( coder_type, GENERIC ) && LE_32( core_brate, ACELP_13k20 ) ) + { + if ( GT_16( *T0, shr( add( PIT_FR1_EXTEND_8b, PIT_MIN ), 1 ) ) ) + { + *limit_flag = 0; + move16(); + } + } + + /*-------------------------------------------------------* + * Retrieve the number of Q bits + *-------------------------------------------------------*/ + + nBits = 0; + move16(); + IF( NE_16( coder_type, AUDIO ) ) + { + /* find the number of bits */ + nBits = st_fx->acelp_cfg.pitch_bits[i_subfr / L_subfr]; + move16(); + pitch_index = (Word16) get_next_indice( st_fx, nBits ); + move16(); + } + + /*-------------------------------------------------------* + * Pitch decoding in AUDIO mode + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + IF( EQ_16( coder_type, AUDIO ) ) + { + test(); + if ( EQ_16( L_subfr, L_FRAME / 2 ) && i_subfr != 0 ) + { + pit_flag = L_SUBFR; + move16(); + } + if ( pit_flag == 0 ) + { + nBits = 10; + move16(); + } + if ( pit_flag != 0 ) + { + nBits = 6; + move16(); + } + + pitch_index = (Word16) get_next_indice( st_fx, nBits ); + move16(); + + test(); + test(); + IF( EQ_16( L_subfr, L_FRAME / 2 ) && i_subfr != 0 && GE_16( pitch_index, 32 ) ) /* safety check in case of bit errors */ + { + pitch_index = shr( pitch_index, 1 ); + move16(); + st_fx->BER_detect = 1; + move16(); + } + + pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE IF( EQ_16( coder_type, VOICED ) ) + { + /*-------------------------------------------------------* + * Pitch decoding in VOICED mode + * (ACELP@12k8 core only) + *-------------------------------------------------------*/ + if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + pit_flag = i_subfr; + move16(); + } + + pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } +#if 1 // def ADD_LRTD + ELSE IF( EQ_16( st_fx->idchan, 1 ) && ( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) ) + { + test(); + test(); + /*-------------------------------------------------------* + * Pitch decoding with reusing of primary channel information + *-------------------------------------------------------*/ + Word16 loc_T0, loc_frac, delta, pit_tmp1, pit_tmp2, isubfridx; + + delta = 4; + pit_flag = L_SUBFR; + move16(); + move16(); + isubfridx = shr( i_subfr, 6 ); + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + move16(); + move16(); + pit_tmp1 = tdm_Pri_pitch_buf[isubfridx]; /*tdm_Pri_pitch_buf in Q6 ->pit_tmp1 and 2 in Q6 too */ + pit_tmp2 = tdm_Pri_pitch_buf[shr( add( i_subfr, 1 ), 6 )]; + /*loc_T0 = (int16_t)(0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]);*/ + loc_T0 = mac_r( L_mult( 16384, pit_tmp1 ), 16384, pit_tmp2 ); + /*loc_frac = (int16_t)(((0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]) - loc_T0) * 4.0f);*/ + } + ELSE + { + /*loc_T0 = (int16_t)tdm_Pri_pitch_buf[i_subfr / L_SUBFR];*/ + loc_T0 = tdm_Pri_pitch_buf[isubfridx]; /*Q6*/ + /*loc_frac = (int16_t)((tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0) * 4.0f);*/ + } + loc_frac = shr( sub( loc_T0, shl( shr( loc_T0, 6 ), 6 ) ), 4 ); /* Final result in Q 2*/ + loc_T0 = shr( loc_T0, 6 ); /*Q6 -> Q0*/ + + + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); + + IF( nBits > 0 ) + { + pit_Q_dec_fx( 0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE + { + *T0 = loc_T0; + *T0_frac = loc_frac; + move16(); + move16(); + } + printf( "function not tested yet\n" ); + } +#endif + ELSE + { + /*-------------------------------------------------------* + * Pitch decoding in GENERIC mode + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + IF( EQ_16( L_frame, L_FRAME ) ) + { + pit_Q_dec_fx( 0, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE + { + pit16k_Q_dec_fx( pitch_index, nBits, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + } + } + + /*-------------------------------------------------------* + * Pitch decoding in AMR-WB IO mode + *-------------------------------------------------------*/ + + ELSE + { + *limit_flag = 0; + move16(); + test(); + test(); + IF( i_subfr == 0 || ( EQ_16( i_subfr, 2 * L_SUBFR ) && EQ_32( core_brate, ACELP_8k85 ) ) ) + { + nBits = 8; + move16(); + } + ELSE + { + nBits = 5; + move16(); + } + IF( GT_32( core_brate, ACELP_8k85 ) ) + { + nBits = 6; + move16(); + test(); + if ( i_subfr == 0 || EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + nBits = 9; + move16(); + } + } + + pitch_index = (Word16) get_next_indice( st_fx, nBits ); + + pit_Q_dec_fx( 1, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + + /*-------------------------------------------------------* + * Compute floating pitch output + *-------------------------------------------------------*/ + + pitch = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); /* save subframe pitch values Q6 */ + + return pitch; +} +#endif /*----------------------------------------------------------* * pit_Q_dec_fx() -- GitLab