diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj
index 728f4cd51614e21d2ae7815342bf37b674078423..eaea38441a3e302744915d62b36ca2cabc5e937d 100644
--- a/Workspace_msvc/lib_com.vcxproj
+++ b/Workspace_msvc/lib_com.vcxproj
@@ -195,6 +195,7 @@
+
diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters
index 7f01afc95ba20bbdacada20f0926711d8af5010f..54806691daec178e44774e69615212a3de783f2b 100644
--- a/Workspace_msvc/lib_com.vcxproj.filters
+++ b/Workspace_msvc/lib_com.vcxproj.filters
@@ -520,6 +520,7 @@
+
diff --git a/lib_com/cnst.h b/lib_com/cnst.h
index 2d831cbc39812c1f16a7861580507c2ddd5c5cc5..5e32df687a7bd124d261b06d26358907fe40c5e0 100644
--- a/lib_com/cnst.h
+++ b/lib_com/cnst.h
@@ -1929,6 +1929,7 @@ typedef enum _DCTTYPE
#define MBANDS_GN_BITALLOC16k 20 /* Number of band for gain coding in GSC */
#define BAND1k2 3
#define DSR_NB_PULSE ( 4.5f )
+#define DSR_NB_PULSE_Q18 ( 1179648 )
#define MAX_EQ_LF 1.0f
#define MBANDS_LOC ( MBANDS_GN - 1 )
#define BIN_SIZE 25.0f
diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..d2e2efe664815ff87c35001c5f8ccdd19eafd93d
--- /dev/null
+++ b/lib_com/gs_bitallocation_ivas_fx.c
@@ -0,0 +1,1005 @@
+/*====================================================================================
+ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
+ ====================================================================================*/
+#include
+#include "options.h" /* Compilation switches */
+#include "cnst.h" /* Common constants */
+#include "rom_com.h" /* Static table prototypes */
+#include "prot.h" /* Function prototypes */
+#include "prot_fx1.h" /* Function prototypes */
+#include "prot_fx2.h" /* Function prototypes */
+#include "ivas_prot.h" /* Function prototypes */
+#include "assert.h" /* Debug prototypes */
+#include "stl.h"
+
+static void reajust_bits_fx( Word32* bits_per_bands, const Word16 st_band, const Word16 end_band, const Word16 sum_bit_in, const Word16 bit_bdgt_in);
+
+/*==================================================================================*/
+/* FUNCTION : void bands_and_bit_alloc_ivas_fx(); */
+/*----------------------------------------------------------------------------------*/
+/* PURPOSE : AC mode (GSC) bands and bits allocation */
+/*----------------------------------------------------------------------------------*/
+/* INPUT ARGUMENTS : */
+/* _ (Word16) cor_strong_limit : HF correlation */
+/* _ (Word16) noise_lev : dwn scaling factor Q0 */
+/* _ (Word32) core_brate : core codec used Q0 */
+/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */
+/* _ (Word16) bits_used : Number of bit used before frequency Q0 */
+/* _ (Word16) idx : Energy band 14 Q0 */
+/* _ (Word16*) exc_diff : Difference signal to quantize (Encoder only) */
+/* _ (Word16) coder_type : coding type Q0 */
+/* _ (Word16) bwidth : input signal bandwidth Q0 */
+/*----------------------------------------------------------------------------------*/
+/* OUTPUT ARGUMENTS : */
+/* _ (Word16*) max_ener_band : Sorted order */
+/* _ (Word16*) nb_subbands : Number of subband allowed Q0 */
+/* _ (Word16*) concat_in : Concatened PVQ's input vector (Encoder Only) */
+/* _ (Word16*) pvq_len : Number of bin covered with the PVQ Q0 */
+/*----------------------------------------------------------------------------------*/
+/* INPUT/OUTPUT ARGUMENTS : */
+/* _ (Word16*) bit :Number of bit allowed for frequency quantization */
+/* _ (Word16*) Ener_per_bd_iQ : Quantized energy vector Q13 */
+/* _ (Word32*) bits_per_bands : Number of bit allowed per allowed subband Q18 */
+/*----------------------------------------------------------------------------------*/
+/* RETURN ARGUMENTS : */
+/* _ None */
+/*==================================================================================*/
+void bands_and_bit_alloc_ivas_fx(
+ const Word16 cor_strong_limit, /* i : HF correlation */
+ const Word16 noise_lev, /* i : dwn scaling factor */
+ const Word32 core_brate, /* i : core bit rate */
+ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/
+ const Word16 bits_used, /* i : Number of bit used before frequency Q */
+ Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */
+ const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */
+ Word16 *max_ener_band, /* o : Sorted order */
+ Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */
+ Word16 *nb_subbands, /* o : Number of subband allowed */
+ const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */
+ Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */
+ Word16 *pvq_len, /* o : Number of bin covered with the PVQ */
+ const Word16 coder_type, /* i : coding type */
+ const Word16 bwidth, /* i : input signal bandwidth */
+ const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */
+ const Word16 L_frame, /* i : frame length */
+ const Word16 element_mode, /* i : element mode */
+ const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
+)
+{
+
+ Word16 bandoffset, i, j, nb_bands_max, bit_new_bands, bit_tmp, st_band, nb_bands;
+ Word16 ener_vec[MBANDS_GN_BITALLOC16k]; /*Q12 */
+ Word16 nb_tot_bands = 16;
+ Word16 bit_index, bit_index_mem, imax;
+ Word32 L_tmp;
+ Word32 sum_bit/*Q18*/, bit_fracf /*Q18*/;
+ Word16 etmp;
+ Word16 tmp;
+ Word16 Ener_per_bd_iQ_tmp[MBANDS_GN_BITALLOC16k]; //Q13
+ Word16 pos, band;
+ Word16 SWB_bit_budget;
+ Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; //Q18
+ Word16 w_sum_bit;
+ Word16 fzero_val;
+ Word32 mp, mb, nb_bands_adj, bit_adj;
+ Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k];
+#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING
+ (void)GSC_IVAS_mode;
+ (void)element_mode;
+#endif
+#ifdef BASOP_NOGLOB_DECLARE_LOCAL
+ Flag Overflow = 0;
+#endif
+ nb_tot_bands = MBANDS_GN;
+ move16();
+ IF (EQ_16(L_frame, L_FRAME16k))
+ {
+ nb_tot_bands = MBANDS_GN_BITALLOC16k;
+ move16();
+ }
+ Copy( Ener_per_bd_iQ, Ener_per_bd_iQ_tmp, nb_tot_bands);
+
+ set32_fx( bits_per_bands, 0, MBANDS_GN_BITALLOC16k);
+ set16_fx( out_bits_per_bands, 0, MBANDS_GN_BITALLOC16k);
+
+ /* To adapt current energy band to PVQ freq band for sorting*/
+#ifdef BASOP_NOGLOB
+ ener_vec[0] = add_o(Ener_per_bd_iQ[0],Ener_per_bd_iQ[1], &Overflow); /*Q12 */
+#else /* BASOP_NOGLOB */
+ ener_vec[0] = add(Ener_per_bd_iQ[0],Ener_per_bd_iQ[1]); /*Q12 */
+#endif
+ Copy( Ener_per_bd_iQ_tmp+1, ener_vec, MBANDS_GN-1); /*Q12 */
+ ener_vec[MBANDS_GN-1] = ener_vec[MBANDS_GN-2];
+ move16();
+ IF (EQ_16(L_frame, L_FRAME16k))
+ {
+ ener_vec[16] = Ener_per_bd_iQ[16];
+ ener_vec[17] = mac_r(L_mult(Ener_per_bd_iQ[16], 16384), Ener_per_bd_iQ[17],16384);
+ ener_vec[18] = Ener_per_bd_iQ[17];
+ ener_vec[19] = mult_r(Ener_per_bd_iQ[17], 26214);
+ move16(); move16(); move16(); move16();
+ }
+
+ /*------------------------------------------------------------------------
+ * Determination of the number of bits available to the frequency domain
+ * Allocation of a maximum number of band to be encoded
+ *-----------------------------------------------------------------------*/
+
+ nb_bands_max = nb_tot_bands;
+ move16();
+ bit_new_bands = 5;
+ move16();
+#if 1//def ADD_LRTD
+ IF(GT_32(core_brate, ACELP_16k40) && EQ_16(L_frame, L_FRAME16k))
+ {
+ bit_new_bands = 7;
+ move16();
+ }
+
+ i = 0;
+ move16();
+ WHILE (LT_16(i, SIZE_BRATE_INTERMED_TBL))
+ {
+ IF (LE_32(core_brate, brate_intermed_tbl[i]))
+ {
+ BREAK;
+ }
+
+ IF (EQ_32(brate_intermed_tbl[i], ACELP_24k40))
+ {
+ BREAK;
+ }
+
+ i = add(i,1);
+ }
+
+ IF(GT_16(element_mode, EVS_MONO) && EQ_16(coder_type, AUDIO) &&
+ LE_32(core_brate, STEREO_GSC_BIT_RATE_ALLOC) && EQ_32(brate_intermed_tbl[i], ACELP_9k60)) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */
+ {
+ i = sub(i,1);
+ }
+
+ bit_index = i_mult2( BRATE2IDX_fx(brate_intermed_tbl[i]), 17);
+#else
+ bit_index = i_mult2(BRATE2IDX_fx(core_brate),17);
+#endif
+ bit_index_mem = bit_index;
+ move16();
+
+ test();
+ test();
+ IF( (EQ_16(coder_type,AUDIO)||EQ_16(coder_type,INACTIVE))&&EQ_16(bwidth,NB))
+ {
+ IF(GE_32(core_brate,ACELP_9k60))
+ {
+ /* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - 25; */
+ L_tmp = Mult_32_16(core_brate,20971);
+ tmp = extract_l(L_shr_r(L_tmp,5));
+ *bit = sub(sub(tmp,bits_used), 25);
+ move16();
+ }
+ ELSE
+ {
+ L_tmp = Mult_32_16(core_brate,20971);
+ tmp = extract_l(L_shr_r(L_tmp,5));
+ *bit = sub(sub(tmp,bits_used), 21);
+ move16();
+ }
+ nb_tot_bands = 10;
+ move16();
+ }
+ ELSE
+ {
+ /* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - GSC_freq_bits[bit_index]; */
+
+ L_tmp = Mult_32_16(core_brate,20971);
+ tmp = extract_l(L_shr_r(L_tmp,5));
+ *bit = sub(sub(tmp,bits_used),GSC_freq_bits[bit_index]);
+ move16();
+ }
+
+#if 1 //def ADD_LRTD
+ IF(L_frame == L_FRAME16k)
+ {
+ *bit -= 8;
+ }
+
+ IF(coder_type == INACTIVE && core_brate <= GSC_LRES_GAINQ_LIMIT) /* can happen only for 2nd channel inactive */
+ {
+ *bit += GSC_LRES_NB_NITS;
+ }
+
+ IF(*bit > 0)
+ {
+ IF(GSC_IVAS_mode > 0)
+ {
+ SWB_bit_budget = *bit;
+ st_band = 5;
+
+ set_l(bits_per_bands, 0, MBANDS_GN_BITALLOC16k);
+
+ /* 2- Decide the pourcentage of bits allocated to LF (between 50-75%) depending of the temporal contribution in GSC */
+ //bit_fracf = (-0.125f * Diff_len + 76.0f) / 100;
+ bit_fracf = L_add(L_mult0(-328, Diff_len), 199229); //Q18
+ //bit_fracf = check_bounds(bit_fracf, 0.50f, 0.75f);
+ bit_fracf = check_bounds_l(bit_fracf, 131072, 196608); //Q18
+
+ /* Adjusment of the bitrate between LF and HF base on the content type */
+ /* 1 = new GSC bit alloc
+ 2 = GSC bit alloc for tc frame
+ 3 = more music like (should not happen often given music is coded with dft) */
+
+ IF(GSC_IVAS_mode <= 3)
+ {
+ nb_bands_max -= 6;
+ }
+
+ IF(GSC_IVAS_mode == 2)
+ {
+ //bit_fracf += 0.1f;
+ bit_fracf = L_add(bit_fracf, 26214);//Q18
+ nb_bands_max--;
+ }
+
+ IF(GSC_IVAS_mode == 3)
+ {
+ //bit_fracf -= 0.1f;
+ bit_fracf = L_sub(bit_fracf, 26214);//Q18
+ nb_bands_max += 3;
+ }
+
+ /* First find how much we want to share between LF and HF, at low bitrate, a miminum of bits is needed in LF by limitating the number of bands*/
+ /* Adjust the number of band based on the content type and bitrate */
+ //nb_bands_adj = 1.0f;
+ nb_bands_adj = ONE_IN_Q18;
+ IF(GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG)
+ {
+ //nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f;
+ nb_bands_adj = L_sub(L_mult0(SWB_bit_budget, 3277), 196608); //Q18
+ }
+ ELSE IF(GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG)
+ {
+ //nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f;
+ nb_bands_adj = L_sub(L_mult0(5243, SWB_bit_budget), 314572); //Q18
+ }
+ //nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);
+ nb_bands_max = (Word16) L_shr(nb_bands_max * nb_bands_adj, Q18); //Q0
+ nb_bands_max = check_bounds_s(nb_bands_max, 5, nb_tot_bands);
+
+ //bit_fracf *= SWB_bit_budget;
+ bit_fracf = bit_fracf * SWB_bit_budget; //Q18
+
+ /* Estimation of the number of bit used in HF */
+ /* with only the first weigthing The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */
+ //mb = .17f * bit_fracf;
+ mb = Mpy_32_32(1610612736, bit_fracf); //Q18
+ //mp = 2 * DSR_NB_PULSE);
+ mp = 2359296; //Q18
+ IF(core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3)
+ {
+ //mp = 1.5f * DSR_NB_PULSE;
+ mp = 1769472; //Q18
+ }
+ ELSE IF(core_brate < GSC_L_RATE_STG)
+ {
+ //mp = DSR_NB_PULSE;
+ mp = DSR_NB_PULSE_Q18;
+ }
+
+ /* We want max_ener_band[st_band] <= max_ener_band[st_band-1] and max_ener_band[nb_bands_max-1] <= max_ener_band[st_band]*/
+ /* We will estimate the number of bits to allocate of HF and put the remaining bits, if any, back on LF */
+ /* compute the total possible number of band to be coded */
+ //nb_tot_bands = (int16_t)((SWB_bit_budget - bit_fracf) / (mp + (mb - mp) / 2.0f));
+ nb_tot_bands = (Word16) ( L_sub( L_shl( SWB_bit_budget, Q18 ), bit_fracf ) / L_add( mp, L_shr( L_sub( mb, mp ), 1 ) ) );
+ mp = min(mp, mb);
+ IF(nb_tot_bands + st_band > nb_bands_max)
+ {
+ bit_adj = ((mb + mp) / 2) * (nb_tot_bands + st_band - nb_bands_max);
+ bit_adj = max(0, bit_adj);
+ nb_tot_bands = nb_bands_max - st_band;
+ //bit_fracf += bit_adj;
+ bit_fracf = L_add( bit_fracf, bit_adj );
+ }
+ nb_tot_bands += st_band;
+
+ /* Allocate bits to LF */
+ //etmp = 0.23f;
+ etmp = 7537; //Q15
+ FOR(j = 0; j < st_band; j++)
+ {
+ i = j;
+ max_ener_band[j] = i;
+ ener_vec[i] = MIN16B;
+ //bits_per_bands[j] = etmp * bit_fracf;
+ bits_per_bands[j] = (Word32)W_shr(W_mult0_32_32(etmp, bit_fracf), 15); //33 - 15 = Q18
+ //etmp -= 0.015f;
+ etmp = sub(etmp, 492);
+ }
+
+ //SWB_bit_budget -= bit_fracf;
+ SWB_bit_budget -= (Word16)L_shr(bit_fracf, Q18);
+
+ /* Find low energy band in HF */
+ set_s(nb_pulse_per_band, 2, MBANDS_GN_BITALLOC16k);
+ FOR(i = st_band + 2; i < nb_tot_bands - 1; i++)
+ {
+ IF(ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1])
+ {
+ nb_pulse_per_band[i] = 1;
+ }
+ }
+ FOR(j = st_band; j < nb_tot_bands; j++)
+ {
+ IF(j > 6)
+ {
+ i = maximum_fx(ener_vec, nb_tot_bands, &etmp);
+ }
+ ELSE
+ {
+ i = j;
+ }
+
+ max_ener_band[j] = i;
+ ener_vec[i] = MIN16B;
+ }
+
+ /* Recompute the final bit distribution for HF */
+ IF(nb_tot_bands > st_band)
+ {
+ //bit_fracf = DSR_NB_PULSE;
+ mb = L_shl((SWB_bit_budget * 2 / (nb_tot_bands - st_band)), Q18) - mp;
+ bit_fracf = (mb - mp) / (nb_tot_bands - st_band);
+ mb = L_sub(mb, bit_fracf);
+ /* Do the distribution */
+ FOR(j = st_band; j < nb_tot_bands; j++)
+ {
+ IF(nb_pulse_per_band[max_ener_band[j]] > 1)
+ {
+ bits_per_bands[max_ener_band[j]] = mb;
+ }
+ ELSE
+ {
+ //bits_per_bands[max_ener_band[j]] = 4.5f;
+ bits_per_bands[max_ener_band[j]] = 1179648;
+ }
+ mb = L_sub(mb, bit_fracf);
+ SWB_bit_budget = sub( SWB_bit_budget, (Word16) L_shr( bits_per_bands[max_ener_band[j]], Q18 ) );
+ }
+ }
+
+ /* Series of verification in case bit allocated != the budget */
+ IF(SWB_bit_budget > 0)
+ {
+ i = st_band - 1;
+ WHILE( SWB_bit_budget > 0 )
+ {
+ //bits_per_bands[i]++;
+ bits_per_bands[i] = L_add(bits_per_bands[i], 262144);
+ SWB_bit_budget--;
+ i--;
+ IF(i == -1)
+ {
+ i = st_band - 1;
+ }
+ }
+ }
+
+ nb_bands = nb_tot_bands;
+
+ sum_bit = 0;
+ j = 0;
+ FOR(i = 0; i < nb_bands; i++)
+ {
+ //if (bits_per_bands[i] > 112)
+ IF(bits_per_bands[i] > 29360128)
+ {
+ sum_bit += bits_per_bands[i] - 112;
+ sum_bit = L_add(sum_bit, L_sub(bits_per_bands[i] , 29360128));
+ //bits_per_bands[i] = 112;
+ bits_per_bands[i] = 29360128;
+ j = i + 1;
+ }
+
+ /* safety check for overage bit reallocation */
+ //else if (bits_per_bands[i] + sum_bit / 3 > 112)
+ ELSE IF(bits_per_bands[i] + sum_bit / 3 > 29360128)
+ {
+ j = i + 1;
+ }
+ }
+
+ IF(sum_bit != 0)
+ {
+ //sum_bit /= (nb_bands - j);
+ sum_bit = sum_bit/(nb_bands - j);
+ FOR(i = j; i < nb_bands; i++)
+ {
+ bits_per_bands[i] += sum_bit;
+ }
+ }
+ }
+ ELSE
+#endif
+ IF(EQ_16(GSC_noisy_speech, 1))
+ {
+ SWB_bit_budget = *bit;
+ move16();
+ nb_bands = 5;
+ move16();
+
+#if 1//def ADD_LRTD
+
+ //fzero_val = 0.0f;
+ fzero_val = 0;
+ IF(element_mode > EVS_MONO)
+ {
+ fzero_val = MIN16B;
+ }
+
+ IF(coder_type == UNVOICED && element_mode > EVS_MONO)
+ {
+ nb_bands = 3;
+ IF(SWB_bit_budget > 20)
+ {
+ nb_bands = 5;
+ }
+ }
+ ELSE IF(bwidth < SWB)
+ {
+ nb_bands = 7;
+ }
+
+#endif
+
+ st_band = nb_bands;
+ move16();
+
+ set32_fx(bits_per_bands, 0, MBANDS_GN);
+ /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */
+ bit_fracf = L_mult(div_s(1, nb_bands), shl(SWB_bit_budget, 2)); /* Q18 */
+
+ nb_tot_bands = sub(nb_bands_max, 6);
+ nb_tot_bands = s_min(nb_tot_bands, 16);
+
+ FOR(j = 0; j < 2; j++)
+ {
+ i = j;
+ move16();
+ max_ener_band[j] = i;
+ move16();
+ //ener_vec[i] = 0;
+ ener_vec[i] = fzero_val;
+ move16();
+ }
+#if 1//def ADD_LRTD
+ IF(bwidth < SWB)
+ {
+ IF(coder_type == UNVOICED && element_mode > EVS_MONO)
+ {
+ nb_tot_bands = 5;
+ }
+#endif
+ FOR(; j < nb_bands; j++)
+ {
+ i = maximum_fx(ener_vec, nb_tot_bands, &etmp);
+ max_ener_band[j] = i;
+ move16();
+ //ener_vec[i] = 0;
+ ener_vec[i] = fzero_val;
+ move16();
+ }
+#if 1//def ADD_LRTD
+ }
+ ELSE
+ {
+ FOR(; j < nb_bands; j++)
+ {
+ i = maximum_fx(ener_vec, nb_tot_bands, &etmp);
+ max_ener_band[j] = i;
+ ener_vec[i] = fzero_val;
+ }
+ }
+#endif
+ set32_fx(bits_per_bands, bit_fracf, nb_bands);
+ }
+ ELSE
+ {
+ bit_index++;
+ bit_tmp = sub(*bit,GSC_freq_bits[bit_index]);
+ bit_index++;
+ nb_bands_max = add(nb_bands_max,GSC_freq_bits[bit_index]);
+ bit_index++;
+
+ *pvq_len = 112;
+ move16();
+ st_band = 7;
+ move16();
+#if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k && core_brate > ACELP_16k40)
+ {
+ *pvq_len = 160;
+ st_band = 10;
+ nb_bands = *pvq_len / 16;
+ bit_tmp -= 35;
+ bit_new_bands = 5;
+ }
+#endif
+ IF(LE_32(core_brate,ACELP_9k60))
+ {
+ *pvq_len = 80;
+ move16();
+ st_band = 5;
+ move16();
+
+ IF(Diff_len == 0)
+ {
+ nb_bands_max = add(nb_bands_max,2);
+ bit_tmp = sub(bit_tmp,13);
+ }
+ }
+
+ ELSE IF(Diff_len == 0)
+ {
+ nb_bands_max = add(nb_bands_max,2);
+ bit_tmp = sub(bit_tmp,17);
+ }
+
+ nb_bands = shr(*pvq_len,4);
+#if 1//def ADD_LRTD
+ nb_bands_max = min(nb_bands_max, MBANDS_GN_BITALLOC16k);
+#endif
+ /*------------------------------------------------------------------------
+ * Ajustement of the maximum number of bands in function of the
+ * dynamics of the spectrum (more or less speech like)
+ *-----------------------------------------------------------------------*/
+ test();
+ test();
+ test();
+ test();
+ IF(EQ_16(coder_type,INACTIVE) || GE_16(noise_lev,NOISE_LEVEL_SP3))
+ {
+ /* Probably classification error -> concentrate bits on LF */
+#if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k && core_brate >= ACELP_24k40)
+ {
+ nb_bands_max = nb_tot_bands - 2;
+ }
+ ELSE IF(core_brate >= ACELP_16k40)
+ {
+ nb_bands_max = nb_bands + 2;
+ }
+ ELSE
+#endif
+ IF(GE_32(core_brate,ACELP_8k00))
+ {
+ nb_bands_max = add(nb_bands,1);
+ }
+ ELSE
+ {
+ nb_bands_max = nb_bands;
+ move16();
+ }
+ }
+ ELSE IF(GE_16(noise_lev,NOISE_LEVEL_SP2) ||
+ (LE_32(core_brate,ACELP_13k20) && GE_32(core_brate,ACELP_9k60) && cor_strong_limit == 0)) /* Very low dynamic, tend to speech, do not try to code HF at all */
+ {
+ nb_bands_max = sub(nb_bands_max,2);
+ }
+ ELSE IF(GE_16(noise_lev,NOISE_LEVEL_SP1)) /* Very low dynamic, tend to speech, code less HF */
+ {
+ nb_bands_max = sub(nb_bands_max,1);
+ }
+ #if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k)
+ {
+ IF(core_brate < ACELP_24k40)
+ {
+ nb_bands_max -= 4;
+ }
+ ELSE IF(core_brate < ACELP_32k)
+ {
+ IF(Diff_len > 0 || noise_lev >= NOISE_LEVEL_SP2)
+ {
+ nb_bands_max -= 2;
+ bit_new_bands *= 2;
+ }
+ }
+ ELSE IF(core_brate >= ACELP_32k)
+ {
+ bit_new_bands *= 2;
+ }
+ }
+
+#endif
+ test();
+ IF(EQ_16(bwidth,NB) && GT_16(nb_bands_max,10))
+ {
+ nb_bands_max = 10;
+ move16();
+ }
+
+ /*------------------------------------------------------------------------
+ * Find extra number of band to code according to bit rate availables
+ *-----------------------------------------------------------------------*/
+ WHILE(GE_16(bit_tmp,bit_new_bands) && LE_16(nb_bands,sub(nb_bands_max,1)))
+ {
+ bit_tmp = sub(bit_tmp,bit_new_bands);
+ nb_bands = add(nb_bands,1);
+ }
+
+ /*------------------------------------------------------------------------
+ * Fractional bits to distribute on the first x bands
+ *-----------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k && core_brate > ACELP_32k)
+ {
+ bit_fracf = 0;
+ }
+ ELSE
+#endif
+ {
+ bit_fracf = L_mult(div_s(1, st_band), shl(bit_tmp, 2)); /* Q18 */
+ }
+ /*------------------------------------------------------------------------
+ * Complete the bit allocation per frequency band
+ *-----------------------------------------------------------------------*/
+ imax = 5;
+ move16();
+
+ IF(GT_32(core_brate,ACELP_9k60))
+ {
+ imax = 7;
+ move16();
+ }
+ FOR(i = 0; i < imax; i++)
+ {
+ bits_per_bands[i] = L_add(GSC_freq_bits_fx[bit_index],bit_fracf);
+ move32();/* Q18 */
+ bit_index = add(bit_index,1);
+ }
+#if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k && core_brate > ACELP_16k40)
+ {
+ bit_index = 0;
+ i = imax - 1;
+ //bits_per_bands[i] += Compl_GSC_freq_bits[bit_index];
+ bits_per_bands[i] = L_add( bits_per_bands[i], L_shl( Compl_GSC_freq_bits[bit_index], Q18 ) );
+ i++;
+ bit_index++;
+
+ FOR(; i < 10; i++)
+ {
+ //bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf;
+ bits_per_bands[i] = L_add( bits_per_bands[i], L_add( L_shl( Compl_GSC_freq_bits[bit_index], Q18 ), bit_fracf ) );
+ bit_index++;
+ }
+ }
+#endif
+ IF(Diff_len == 0)
+ {
+ bit_index = add(bit_index_mem,10);
+ FOR(i = 0; i < 7; i++)
+ {
+ bits_per_bands[i] = L_add(bits_per_bands[i],GSC_freq_bits_fx[bit_index]);
+ move32();/*chk Q18 */
+ bit_index = add(bit_index,1);
+ }
+ }
+#if 1//def ADD_LRTD
+ IF(bit_fracf < 0)
+ {
+ FOR(j = 0; j < nb_tot_bands; j++)
+ {
+ bits_per_bands[j] = max(bits_per_bands[j], 0);
+ }
+ }
+
+#endif
+ /*--------------------------------------------------------------------------
+ * Complete the bit allocation per frequency band for 16kHz high brate mode
+ *--------------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ IF(L_frame == L_FRAME16k && core_brate > ACELP_32k)
+ {
+ FOR(j = st_band; j < nb_bands; j++)
+ {
+ //bits_per_bands[j] = bit_new_bands;
+ bits_per_bands[j] = L_shl(bit_new_bands, Q18);
+ }
+
+ //bit_fracf = (1.0f / nb_bands) * (bit_tmp);
+ bit_fracf = (262144 / nb_bands) * (bit_tmp);
+
+ //etmp = 2.0f * bit_fracf / (nb_bands + 1);
+ etmp = (Word16) L_shr(L_shl(bit_fracf, Q1) / (nb_bands + 1), Q3); //Q15
+ //bit_fracf = etmp;
+ bit_fracf = L_shl(etmp, Q3); //Q18
+ FOR(j = nb_bands - 1; j >= 0; j--)
+ {
+ //bits_per_bands[j] = etmp;
+ //etmp += bit_fracf;
+ bits_per_bands[j] = L_add(bits_per_bands[j], L_shl(etmp, Q3)); // Q18
+ etmp = (Word16)L_add(etmp, L_shr(bit_fracf, Q3));
+ }
+ }
+ ELSE
+#endif
+ {
+ FOR(j = st_band; j < nb_bands; j++)
+ {
+ bits_per_bands[j] = L_shl(bit_new_bands, 18);
+ move32(); /*chk Q18 */
+ }
+ }
+
+ /*--------------------------------------------------------------------------
+ * Compute a maximum band (band offset) for the search on maximal energy
+ * This is function of the spectral dynamic and the bitrate
+ *--------------------------------------------------------------------------*/
+
+ bandoffset = sub(nb_tot_bands,add(nb_bands,2));
+
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF(LE_16(noise_lev,NOISE_LEVEL_SP1a))
+ {
+ bandoffset = sub(bandoffset,1);
+ }
+ ELSE IF((LE_32(core_brate,ACELP_13k20) && (EQ_16(coder_type,INACTIVE) || GE_16(noise_lev,NOISE_LEVEL_SP3))) ||
+ (LE_32(core_brate,ACELP_13k20) && GE_32(core_brate,ACELP_9k60) && cor_strong_limit == 0))
+ {
+ bandoffset = add(bandoffset,1);
+ }
+
+ bandoffset = s_max(bandoffset ,0);
+
+ /*--------------------------------------------------------------------------
+ * Initiazed sorted vector
+ * For the first x bands to be included in th final sorted vector
+ * Sort the remaining bands in decrease energy order
+ *--------------------------------------------------------------------------*/
+ FOR(j = 0; j < nb_tot_bands; j++)
+ {
+ max_ener_band[j] = -10;
+ move16();
+ }
+ FOR(j = 0; j < st_band; j++)
+ {
+ max_ener_band[j] = j;
+ move16();
+ ener_vec[j] = -10;
+ move16();
+ }
+ pos = st_band;
+ move16();
+ FOR(; j < nb_bands; j++)
+ {
+ i = maximum_fx(ener_vec, sub(nb_tot_bands,bandoffset), &etmp);
+ pos = s_max(pos,i);
+ max_ener_band[j] = i;
+ move16();
+ ener_vec[i] = -10;
+ move16();
+ }
+
+ /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */
+ test();
+ test();
+ test();
+ IF(GT_16(sub(nb_tot_bands, bandoffset),nb_bands) && (GT_16(pos,7) && EQ_32(core_brate,ACELP_8k00)) && EQ_16(bwidth,WB))
+ {
+ band = sub(nb_tot_bands, add(bandoffset,nb_bands));
+ FOR(j = 0; j < band; j++)
+ {
+ i = maximum_fx(ener_vec, sub(nb_tot_bands,bandoffset), &etmp);
+ max_ener_band[add(nb_bands,j)] = i;
+ move16();
+ ener_vec[i] = -10;
+ move16();
+ bits_per_bands[add(nb_bands,j)] = 1310720;
+ move32(); /*Q18 */
+ }
+ nb_bands = add(nb_bands,band);
+
+ bit_tmp = i_mult2(band,5);
+
+ IF(LE_16(band,2))
+ {
+ FOR(j = sub(st_band,1); j < nb_bands; j++)
+ {
+ bits_per_bands[j] = L_add(bits_per_bands[j],262144); /*Q18 */ move32();
+ }
+ bit_tmp = add(bit_tmp, add(sub(nb_bands, st_band) , 1));
+ }
+
+ i = 0;
+ move16();
+ j = 0;
+ move16();
+ FOR(; bit_tmp > 0; bit_tmp--)
+ {
+ bits_per_bands[j] = L_sub(bits_per_bands[j],262144); /*Q18 */
+ j = add(j,1);
+ IF(EQ_16(j,sub(st_band, i)))
+ {
+ j = 0;
+ move16();
+ }
+ test();
+ IF(j == 0 && LT_16(i,sub(st_band, 1)))
+ {
+ i = add(i,1);
+ }
+ }
+ }
+ }
+ /*--------------------------------------------------------------------------
+ * Bit sum verification for GSC inactive at very high rate
+ * The maximum number of bits per band of length 16 is 112
+ * Redistribute the overage bits if needed
+ *--------------------------------------------------------------------------*/
+ sum_bit = 0;
+ move16();
+ j = 0;
+ move16();
+ FOR(i = 0; i < nb_bands; i++)
+ {
+ L_tmp = Mult_32_16(sum_bit, 10923);
+
+ IF(GT_32(bits_per_bands[i], 29360128)) /* 112 in Q18 */
+ {
+ sum_bit = L_add(sum_bit, L_sub(bits_per_bands[i], 29360128)); /* Q18 */
+ bits_per_bands[i] = 29360128;
+ move32();
+ j = add(i, 1);
+ }
+ ELSE IF(GT_32(L_add(bits_per_bands[i], L_tmp), 29360128)) /* Q18 */
+ {
+ j = add(i, 1);
+ }
+ }
+
+ IF(sum_bit != 0)
+ {
+ tmp = sub(nb_bands, j);
+ sum_bit = Mult_32_16(sum_bit, div_s(1, tmp)); /* Q18 */
+ FOR(i = j; i < nb_bands; i++)
+ {
+ bits_per_bands[i] = L_add(bits_per_bands[i], sum_bit);
+ move32();/* Q18 */
+ }
+ }
+ /*--------------------------------------------------------------------------
+ * second step of bit sum verification, normally sum_bit == *bit
+ *--------------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ sum_bit = 0;
+ FOR(i = 0; i < nb_bands; i++)
+ {
+ //bits_per_bands[i] = (float)floor(bits_per_bands[i]);
+ bits_per_bands[i] = L_shl( L_shr( bits_per_bands[i], Q18 ), Q18 );
+ sum_bit = L_add( sum_bit, L_shr( bits_per_bands[i], Q18 ) );
+ }
+ IF(GSC_IVAS_mode != 0 && sum_bit < *bit) /* If we need to add bits, we are doing it on the LF */
+ {
+ reajust_bits_fx(bits_per_bands, 0, nb_bands, (int16_t)sum_bit, *bit);
+ }
+ ELSE
+ {
+ reajust_bits_fx(bits_per_bands, nb_bands - 1, 0, (int16_t)sum_bit, *bit);
+ }
+ w_sum_bit = 0;
+ move16();
+ FOR(i = 0; i < nb_bands; i++)
+ {
+ out_bits_per_bands[i] = shl(extract_l(L_shr(bits_per_bands[i], 18)), 3);
+ move16();
+ w_sum_bit = add(w_sum_bit, out_bits_per_bands[i]); /* Q3 */
+ }
+ tmp = shl(*bit, 3);
+#else
+ IF(GT_16(tmp, w_sum_bit))
+ {
+ i = sub(nb_bands, 1);
+ move16();
+ FOR(; tmp > w_sum_bit; w_sum_bit += (1 << 3))
+ {
+ out_bits_per_bands[i] = add(out_bits_per_bands[i], 1 << 3);
+ move16();
+ i = sub(i, 1);
+ IF(i == 0)
+ {
+ i = sub(nb_bands, 1);
+ }
+ }
+ }
+#endif
+ /*--------------------------------------------------------------------------
+ * Recompute the real number/length of frequency bands to encode
+ *--------------------------------------------------------------------------*/
+ * nb_subbands = nb_bands;
+ move16();
+ *pvq_len = shl(*nb_subbands, 4);
+
+ /*--------------------------------------------------------------------------
+ * Concatenate bands (encoder only)
+ *--------------------------------------------------------------------------*/
+ IF(exc_diff != NULL)
+ {
+ FOR(j = 0; j < nb_bands; j++)
+ {
+ Copy(exc_diff + shl(max_ener_band[j], 4), concat_in + shl(j, 4), 16);
+ }
+ }
+#if 1//def ADD_LRTD
+ }
+ ELSE /* *bit == 0 */
+ {
+ set_s(out_bits_per_bands, 0, nb_tot_bands);
+ *nb_subbands = 0;
+ *pvq_len = 0;
+ }
+#endif
+ return;
+}
+#if 1//def ADD_LRTD
+/*-------------------------------------------------------------------*
+ * reajust_bits()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static void reajust_bits_fx(
+ Word32* bits_per_bands,
+ const Word16 st_band,
+ const Word16 end_band,
+ const Word16 sum_bit_in,
+ const Word16 bit_bdgt_in)
+{
+ Word16 i, amount_to_add, incr;
+ Word16 bit_bdgt, sum_bit;
+
+ incr = 1;
+ IF(end_band < st_band)
+ {
+ incr = -1;
+ }
+
+ IF(bit_bdgt_in < sum_bit_in)
+ {
+ amount_to_add = -1;
+ bit_bdgt = sum_bit_in;
+ sum_bit = bit_bdgt_in;
+ }
+ ELSE
+ {
+ bit_bdgt = bit_bdgt_in;
+ sum_bit = sum_bit_in;
+ amount_to_add = 1;
+ }
+
+ i = st_band;
+ WHILE(bit_bdgt > sum_bit)
+ {
+ //if (amount_to_add > 0 || (amount_to_add < 0 && bits_per_bands[i] > 1))
+ IF(amount_to_add > 0 || (amount_to_add < 0 && bits_per_bands[i] > 262144))
+ {
+ //bits_per_bands[i] += amount_to_add;
+ bits_per_bands[i] = L_add( bits_per_bands[i], L_shl( amount_to_add, Q18 ) );
+ sum_bit = add( sum_bit, abs_s( amount_to_add ) );
+ }
+
+ i += incr;
+ IF(i == end_band)
+ {
+ i = st_band;
+ }
+ }
+
+ return;
+}
+
+#endif
\ No newline at end of file
diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c
index b0b4315e5291a55fa8227f633c0b6e59ad601a7e..c98b90ef8c579b9370b1e9aa3c1645a652fb96d6 100644
--- a/lib_com/gs_gains_fx.c
+++ b/lib_com/gs_gains_fx.c
@@ -303,6 +303,86 @@ static void GSC_gain_adj(
return;
}
+
+#ifdef IVAS_FLOAT_FIXED
+/*-------------------------------------------------------------------*
+ * GSC_gain_adj_ivas_fx()
+ *
+ * Quantization of the energy per band
+ *-------------------------------------------------------------------*/
+static void GSC_gain_adj_ivas_fx(
+ const Word16 coder_type, /* i : Coder type */
+ const Word32 core_brate, /* i : Bit rate */
+ const Word16 mean_g, /* i : Average gain Q12 */
+ Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
+ const Word16 *y_gain_tmp, /* i : Dequantized gains */
+ Word16 *y_gainQ /* i/o: Output gains Q12 */
+)
+{
+ /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
+ Word16 Gain_off, i;
+
+ IF(NE_16(coder_type, INACTIVE) && NE_16(coder_type, UNVOICED))
+ {
+ FOR(i = 0; i < MBANDS_GN; i++)
+ {
+ old_y_gain[i] = y_gain_tmp[i];
+ move16();
+ y_gainQ[i] = add(y_gain_tmp[i], mean_g);
+ move16();
+ }
+ }
+ ELSE
+ {
+ Gain_off = 0;
+ move16();
+ IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
+ {
+ Gain_off = 18432;
+ move16(); /* 9 -> Q11 */
+ }
+ IF(LE_32(core_brate,ACELP_7k20))
+ {
+ Gain_off = 16384;
+ move16(); /* 8 -> Q11 */
+ }
+ ELSE IF(LE_32(core_brate,ACELP_8k00))
+ {
+ Gain_off = 13517;
+ move16(); /* 6.6f -> Q11 */
+ }
+ ELSE IF(LE_32(core_brate,ACELP_9k60))
+ {
+ Gain_off = 9830;
+ move16(); /*4.8f-> Q11 */
+ }
+ ELSE IF(LE_32(core_brate,ACELP_11k60))
+ {
+ Gain_off = 7168;
+ move16(); /* 3.5f -> Q11 */
+ }
+ ELSE IF(LE_32(core_brate,ACELP_13k20))
+ {
+ Gain_off = 6144;
+ move16(); /* 3.0f -> Q11 dB */
+ }
+
+ /*mimic ACELP decay of energy for low rates*/
+ FOR(i = 0; i < MBANDS_GN; i++)
+ {
+ old_y_gain[i] = y_gain_tmp[i];
+ move16();
+ /*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
+ //y_gainQ[i] = add(y_gain_tmp[i], sub(mean_g, i_mult2(i, mult_r(Gain_off, 102))));
+ y_gainQ[i] = add(y_gain_tmp[i], sub(mean_g, i_mult2(i, mult_r(Gain_off, 205))));
+ move16();
+ }
+ }
+
+ return;
+}
+#endif
+
/*==========================================================================*/
/* FUNCTION : Word16 gsc_gaindec_fx () */
/*--------------------------------------------------------------------------*/
@@ -462,6 +542,166 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */
}
+#ifdef IVAS_FLOAT_FIXED
+/*==========================================================================*/
+/* FUNCTION : Word16 gsc_gaindec_ivas_fx () */
+/*--------------------------------------------------------------------------*/
+/* PURPOSE : Generic signal frequency band decoding and application */
+/*--------------------------------------------------------------------------*/
+/* INPUT ARGUMENTS : */
+/* _ (Word16) pvq_bits_fx : core used Q0 */
+/* _ (Word16) coder_type_fx : coding type Q0 */
+/* _ (Word16) core_fx : core used Q0 */
+/* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
+/*--------------------------------------------------------------------------*/
+/* OUTPUT ARGUMENTS : */
+/* _ (Word16[]) y_gainQ_fx : quantized gain per band */
+/*--------------------------------------------------------------------------*/
+/* INPUT/OUTPUT ARGUMENTS : */
+/* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
+/*--------------------------------------------------------------------------*/
+/* RETURN ARGUMENTS : */
+/* _ (Word16) : average frequency gain */
+/*==========================================================================*/
+Word16 gsc_gaindec_ivas_fx( /* o : average frequency gain */
+ Decoder_State *st_fx, /* i/o: decoder state structure */
+ Word16 y_gainQ_fx[], /* o : quantized gain per band */
+ const Word32 core_brate_fx, /* i : core used */
+ Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
+ const Word16 coder_type_fx, /* i : coding type */
+ const Word16 bwidth_fx /* i : input signal bandwidth */
+)
+{
+ Word16 idx_g_fx, i;
+ Word16 mean_4g_fx;
+ Word16 y_gain_tmp3_fx[MBANDS_GN];
+
+ test();
+ test();
+ IF((EQ_16(coder_type_fx, AUDIO) || EQ_16(coder_type_fx, INACTIVE)) && EQ_16(bwidth_fx, NB))
+ {
+ idx_g_fx = (Word16)get_next_indice(st_fx, 6);
+ VDQ_vec_fx(&mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 6);
+ move16();
+ VDQ_vec_fx(y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3);
+
+ IF(LT_32(core_brate_fx, ACELP_9k60))
+ {
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+ VDQ_vec_fx(y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 4);
+ VDQ_vec_fx(y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4);
+ }
+ ELSE
+ {
+ idx_g_fx = (Word16)get_next_indice(st_fx, 6);
+ VDQ_vec_fx(y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 7);
+ VDQ_vec_fx(y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4);
+ }
+ test();
+ IF(LE_32(core_brate_fx, ACELP_9k60) && EQ_16(coder_type_fx, INACTIVE))
+ {
+ /* Some energy is needed in high band for stat_noise_uv_enc
+ to be functional in inactive speech */
+ y_gainQ_fx[10] = mean_fx(y_gainQ_fx + 6, 3);
+ move16();
+ y_gainQ_fx[11] = mean_fx(y_gainQ_fx + 7, 3);
+ move16();
+ y_gainQ_fx[12] = mean_fx(y_gainQ_fx + 8, 3);
+ move16();
+ y_gainQ_fx[13] = mean_fx(y_gainQ_fx + 9, 3);
+ move16();
+ y_gainQ_fx[14] = mean_fx(y_gainQ_fx + 10, 3);
+ move16();
+ y_gainQ_fx[15] = mean_fx(y_gainQ_fx + 11, 3);
+ move16();
+ }
+ ELSE
+ {
+ set16_fx(y_gainQ_fx + 10, 0, MBANDS_GN - 10);
+ }
+ }
+ ELSE
+ {
+ idx_g_fx = (Word16)get_next_indice(st_fx, 6);
+
+ VDQ_vec_fx(&mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1);
+
+ IF(LT_32(core_brate_fx,ACELP_9k60))
+ {
+ /*--------------------------------------------------------------------------------------*
+ * UQ of the first 8 bands and half of the last 8 bands
+ *--------------------------------------------------------------------------------------*/
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+ VDQ_vec_fx(y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+ VDQ_vec_fx(y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4);
+
+ /*----------------------------------------------------------------------*
+ * Interpolation of the last 4 Q bands to create bands 8-16
+ * And scaling
+ *----------------------------------------------------------------------*/
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+
+ VDQ_vec_fx(y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5);
+
+ Copy(y_gainQ_fx + 8, y_gain_tmp3_fx, 4);
+ set16_fx(y_gainQ_fx + 12, 0, 4);
+
+ fft_rel_fx(y_gainQ_fx + 8, 4, 2);
+
+ y_gainQ_fx[15] = y_gainQ_fx[11];
+ move16();
+ y_gainQ_fx[11] = 0;
+ move16();
+ ifft_rel_fx(y_gainQ_fx + 8, 8, 3);
+ FOR(i = 8; i < 16; i++)
+ {
+ /*y_gainQ_fx[i] *= 1.41f;*/
+ y_gainQ_fx[i] = round_fx(L_shl(L_mult(y_gainQ_fx[i] , 23101),1));/*Q12 */
+ }
+ /*----------------------------------------------------------------------*
+ * Copy the true Q values in the specific bands
+ *----------------------------------------------------------------------*/
+ y_gainQ_fx[8] = y_gain_tmp3_fx[0];
+ move16();
+ y_gainQ_fx[10] = y_gain_tmp3_fx[1];
+ move16();
+ y_gainQ_fx[12] = y_gain_tmp3_fx[2];
+ move16();
+ y_gainQ_fx[14] = y_gain_tmp3_fx[3];
+ move16();
+ }
+ ELSE
+ {
+ idx_g_fx = (Word16)get_next_indice(st_fx, 6);
+ VDQ_vec_fx(y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+ VDQ_vec_fx(y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 5);
+ VDQ_vec_fx(y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4);
+
+ idx_g_fx = (Word16)get_next_indice(st_fx, 4);
+ VDQ_vec_fx(y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4);
+ }
+ }
+
+ /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
+ GSC_gain_adj_ivas_fx(coder_type_fx, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx);
+
+ return mean_4g_fx;
+
+}
+#endif
/*-------------------------------------------------------------------*
* gsc_gainQ()
diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c
index cc8996e5c2c459a78388540e795f3bf5bce079d0..4fa9d6ae6214322665bc85dc000868b889fae7c5 100644
--- a/lib_com/gs_noisefill_fx.c
+++ b/lib_com/gs_noisefill_fx.c
@@ -1092,3 +1092,460 @@ void highband_exc_dct_in_fx(
return;
}
+
+#ifdef IVAS_FLOAT_FIXED
+void highband_exc_dct_in_ivas_fx(
+ const Word32 core_brate, /* i : core bitrate */
+ const Word16 *mfreq_bindiv, /* i : bin per bands tables */
+ Word16 last_bin, /* i : last bin of bit allocation */
+ Word16 Diff_len, /* i : number of bin before cut-off frequency */
+ Word16 noise_lev, /* i : pulses dynamic */
+ Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
+ Word16 *exc_diffQ, /* i : frequency coefficients of per band */
+ Word16 *seed_tcx, /* i : Seed for noise */
+ Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */
+ Word16 nb_subfr, /* i : Number of subframe considered */
+ Word16 *exc_dct_in, /* o : dct of residual signal */
+ Word16 last_coder_type, /* i : coding type of last frame */
+ Word16 *bitallocation_band, /* i : bit allocation flag of each band */
+ const Word16 *lsf_new, /* i : LSFs at the end of the frame */
+ Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */
+ Word16 *last_ener, /* i : frequency energy of last frame */
+ Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */
+ Word16 *bitallocation_exc, /* i : flag of decoded coefficients */
+ Word16 bfi, /* i : bad frame indicator */
+ const Word16 coder_type, /* i : coder type */
+ Word16 bwidth,
+ Word16 *exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */
+ Word16 Qexc_diffQ,
+ Word16 Q_exc,
+ const Word16 GSC_noisy_speech
+ , Word16 *lt_ener_per_band_fx, /* i/o: Average per band energy */
+ const Word16 L_frame, /* i : frame length */
+ const Word16 element_mode, /* i : IVAS element mode */
+ const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
+)
+{
+ Word16 i, j, k;
+ Word16 MAX_Bin = 0;
+ Word16 last_bin_tmp, ener = 0;
+ Word16 noisepb[MBANDS_GN16k];
+ Word16 Ener_per_bd_yQ[MBANDS_GN16k];
+ Word16 *src, *dst;
+ Word32 L_tmp;
+ Word16 length_bin, bwe_flag = 0, tmp;
+ Word16 frac, exp, tmp1;
+ Word16 tmp2;
+ Word16 *end, Q_hb_exc;
+#ifdef BASOP_NOGLOB_DECLARE_LOCAL
+ Flag Overflow = 0;
+#endif
+
+ FOR(j = 10; j < MBANDS_GN; j++)
+ {
+ /* ener += (float)pow(10, Ener_per_bd_iQ[j]);
+ ener += (float)pow(2, 3.321928*Ener_per_bd_iQ[j]); */
+
+ L_tmp = L_mult(Ener_per_bd_iQ[j], 27213); /* 3.321928 in Q13 -> Q27 */
+ L_tmp = L_shr(L_tmp, 10); /* From Q27 to Q16 */
+
+ frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */
+ tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
+ /* output of Pow2() will be: */
+ /* 16384 < Pow2() <= 32767 */
+ exp = sub(exp, 14);
+#ifdef BASOP_NOGLOB
+ tmp1 = shl_o(tmp, exp, &Overflow);
+#else /* BASOP_NOGLOB */
+ tmp1 = shl(tmp, exp);
+#endif /* BASOP_NOGLOB */
+ move16();
+#ifdef BASOP_NOGLOB
+ ener = add_o(tmp1, ener, &Overflow);/*Q0 */
+#else /* BASOP_NOGLOB */
+ ener = add(tmp1, ener);/*Q0 */
+#endif /* BASOP_NOGLOB */
+ }
+
+ test();
+ IF(EQ_32(core_brate, ACELP_8k00) && NE_16(bwidth, NB))
+ {
+ IF(NE_16(last_coder_type, AUDIO))
+ {
+ *last_ener = ener;
+ move16();
+ }
+ test();
+ test();
+ IF((GT_16(last_bin, 8) || Diff_len != 0) && EQ_16(last_coder_type, AUDIO))
+ {
+ MAX_Bin = 10;
+ move16();
+ bwe_flag = 1;
+ move16();
+ }
+ ELSE
+ {
+ MAX_Bin = 15;
+ move16();
+ }
+
+ last_bin_tmp = last_bin;
+ move16();
+ last_bin = s_max(last_bin, MAX_Bin);
+ last_bin = add(last_bin, 1);
+ }
+ ELSE
+ {
+ IF(EQ_16(L_frame, L_FRAME16k))
+ {
+ last_bin = MBANDS_GN16k;
+ move16();
+ }
+ ELSE
+ {
+ last_bin = MBANDS_GN;
+ move16();
+ }
+ last_bin_tmp = last_bin;
+ move16();
+ }
+
+ IF(bfi || LT_32(core_brate, 6000) || (LT_32(core_brate, 8600) && EQ_16(coder_type, UNVOICED)))
+ {
+ set16_fx(noisepb, 13107, MBANDS_GN); /*0.4 in Q15 */
+ }
+ ELSE IF(EQ_16(GSC_IVAS_mode, 3) || (GSC_IVAS_mode > 0 && EQ_16(GSC_noisy_speech, 1)))
+ {
+ set16_fx(noisepb, 13107/*0.4f*/, MBANDS_GN16k);
+ }
+ ELSE
+ {
+ EstimateNoiseLevel_fx(noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth, L_frame);
+ }
+
+ IF(exc_wo_nf != NULL)
+ {
+ Copy(exc_diffQ, exc_wo_nf, L_frame);
+ }
+
+ test();
+
+ IF(GSC_IVAS_mode == 0 && GSC_noisy_speech && !bfi && LE_16(element_mode, IVAS_SCE))
+ {
+ set16_fx(noisepb, 3277, MBANDS_GN);
+ }
+ IF(LT_32(core_brate, 6000) && LE_16(coder_type, UNVOICED))
+ {
+ FOR(i = 0; i < L_frame; i++)
+ {
+ IF(exc_diffQ[i] == 0)
+ {
+ //PMT("code below to be validated for IVAS use")
+ /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/
+ tmp = mult(shl(noisepb[0], 1), Random(seed_tcx));/*Q15 */
+ tmp = shr(tmp, sub(15, Qexc_diffQ));/*qNoise_fac */
+ exc_diffQ[i] = add(exc_diffQ[i], tmp);
+ move16();/*Q */
+ }
+ }
+ }
+ ELSE
+ {
+ Apply_NoiseFill_fx(exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ);
+ }
+ /*--------------------------------------------------------------------------------------*
+ * Quantize average gain
+ * Subtract Q averaged gain
+ * VQ of remaining gain per band
+ *--------------------------------------------------------------------------------------*/
+ test();
+ IF(EQ_32(core_brate, ACELP_8k00) && NE_16(bwidth, NB))
+ {
+ Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add(last_bin, 1), 0);
+ }
+ ELSE
+ {
+ Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1);
+
+ IF(LT_16(nb_subfr, 4) && LT_16(L_frame, L_FRAME16k))
+ {
+ FOR(i = L_FRAME - 16; i < L_FRAME; i++)
+ {
+ /*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */
+ tmp = msu_r(-7680 * 65536, -17564, shl(i,6));/*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */
+ L_tmp = L_mult(exc_diffQ[i],tmp); /*Q(Qexc_diffQ+10) */
+ exc_diffQ[i] = round_fx(L_shl(L_tmp,16 - 10));/*Qexc_diffQ */
+ }
+ }
+ }
+ /*--------------------------------------------------------------------------------------*
+ * Check potential energy excitation overshoot
+ *--------------------------------------------------------------------------------------*/
+ IF(bfi)
+ {
+ test();
+ IF(GSC_noisy_speech == 0 && GT_16(coder_type, UNVOICED)) /* Here coder_type == last_coder_type because of the bfi */
+ {
+ FOR(i = 0; i < last_bin; i++)
+ {
+ Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(sub(lt_ener_per_band_fx[i], 154), Ener_per_bd_yQ[i]));
+ move16();
+ lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
+ move16();
+ }
+ FOR(; i < MBANDS_GN; i++)
+ {
+ Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(lt_ener_per_band_fx[i], 154));
+ move16();
+ lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
+ move16();
+ }
+ }
+ ELSE
+ {
+ FOR(i = 0; i < last_bin; i++)
+ {
+ Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(add(lt_ener_per_band_fx[i],1229), Ener_per_bd_yQ[i]));
+ move16();
+ lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
+ move16();
+ }
+ FOR(; i < MBANDS_GN; i++)
+ {
+ Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], add(lt_ener_per_band_fx[i],1229));
+ move16();
+ lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
+ move16();
+ }
+ }
+ }
+ /*--------------------------------------------------------------------------------------*
+ * Apply decoded gain onto the difference signal
+ *--------------------------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ IF(GSC_IVAS_mode >= 1)
+ {
+ //float scale_factLF = 0.9f;
+ Word16 scale_factLF = 29491;
+ //float scale_factHF = 0.9f;
+ Word16 scale_factHF = 29491;
+
+ IF(GSC_IVAS_mode == 1 && GSC_noisy_speech == 0)
+ {
+ //scale_factHF = 0.8f;
+ scale_factHF = 26214;
+ }
+ ELSE IF(GSC_IVAS_mode == 2 || GSC_noisy_speech == 1)
+ {
+ //scale_factHF = 0.71f;
+ scale_factHF = 23265;
+ }
+ ELSE IF(GSC_IVAS_mode == 3)
+ {
+ //scale_factHF = 0.9f;
+ scale_factHF = 29491;
+ }
+ FOR(i = 0; i < pit_band_idx * 16; i++)
+ {
+ //exc_diffQ[i] *= scale_factLF;
+ exc_diffQ[i] = mult_r(exc_diffQ[i], scale_factLF);
+ }
+ FOR(; i < L_frame; i++)
+ {
+ //exc_diffQ[i] *= scale_factHF;
+ exc_diffQ[i] = mult_r(exc_diffQ[i], scale_factHF);
+ }
+ }
+ ELSE IF(GSC_noisy_speech)
+ {
+ //float scale_fact = 0.9f;
+ Word16 scale_fact = 29491;
+
+ IF(element_mode == IVAS_CPE_TD)
+ {
+ IF(coder_type == INACTIVE)
+ {
+ //scale_fact = 1.0f;
+ scale_fact = 32767;
+ }
+ ELSE
+ {
+ //scale_fact = 0.95f;
+ scale_fact = 31129;
+ }
+ }
+ ELSE IF(element_mode > IVAS_SCE)
+ {
+ //scale_fact = 0.71f;
+ scale_fact = 23265;
+ }
+
+ FOR(i = 0; i < L_frame; i++)
+ {
+ //exc_diffQ[i] *= scale_fact;
+ exc_diffQ[i] = mult_r(exc_diffQ[i], scale_fact);
+ }
+ }
+ IF(GSC_noisy_speech && element_mode > IVAS_SCE && core_brate < ACELP_7k20)
+ {
+ FOR(i = 80; i < L_frame; i++)
+ {
+ //exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f);
+ exc_diffQ[i] = mult_r( shl( exc_diffQ[i], 1 ) /*Q16*/, (Word16) L_shr( L_add( 629 * i, 312475 ) /*Q18*/, Q4 ) /*Q14*/ );
+ }
+ }
+#else
+ IF(GSC_noisy_speech)
+ {
+ FOR(i = 0; i < L_frame; i++)
+ {
+ exc_diffQ[i] = mult_r(exc_diffQ[i], 29491);
+ move16();
+ }
+ }
+#endif
+ Comp_and_apply_gain_fx(exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc);
+
+ IF(exc_wo_nf != NULL)
+ {
+ Comp_and_apply_gain_fx(exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, Q_exc);
+ Vr_add(exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame);
+ }
+ /*--------------------------------------------------------------------------------------*
+ * add the correction layer to the LF bins,
+ * and add the quantized pulses or the noise for the higher part of the spectrum
+ * (non valuable temporal content already zeroed)
+ * DC is Zeroed
+ *--------------------------------------------------------------------------------------*/
+
+ Vr_add(exc_dct_in, exc_diffQ, exc_dct_in, L_frame);
+ test();
+ IF(core_brate == ACELP_8k00 && bwidth != NB)
+ {
+ IF(EQ_16(bwe_flag, 1))
+ {
+ last_bin = sub(last_bin, 1);
+ tmp = i_mult(MAX_Bin, 16);
+ tmp1 = i_mult(last_bin, 16);
+ src = &exc_diffQ[sub(L_FRAME, 1)];
+ move16();
+ dst = &exc_dct_in[sub(tmp, 1)];
+ move16();
+ end = &exc_diffQ[sub(tmp1, 1)];
+ move16();
+
+ WHILE(src > end)
+ {
+ *src-- = *dst--;
+ move16();
+ }
+ test();
+ test();
+ IF((bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0) && EQ_32(core_brate, ACELP_8k00))
+ {
+ exc_diffQ[160] = 0;
+ move16();
+ }
+
+ Q_hb_exc = 0;
+ move16();
+ envelop_modify_fx(exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, Q_exc, &Q_hb_exc);
+ Copy_Scale_sig(&exc_diffQ[tmp1], &exc_dct_in[tmp1], sub(L_FRAME, tmp1), sub(Q_exc, Q_hb_exc)); /* from Q_hb_exc -> Q_exc as expected */
+ }
+
+ IF(LT_16(nb_subfr, 4))
+ {
+ FOR(i = sub(L_FRAME, 16); i < L_FRAME; i++)
+ {
+ /*exc_dct_in[i] *= (0.067f*i-15.f); */
+ tmp = mult_r(17564, shl(i, 6)); /*0.067 in Q18 and i in Q6= Q9 */
+ tmp = sub(tmp, 7680); /*15 in Q9 = Q9 */
+ L_tmp = L_mult(exc_dct_in[i], tmp);/*Q(Q_exc+10) */
+#ifdef BASOP_NOGLOB
+ exc_dct_in[i] = round_fx_o(L_shl_o(L_tmp, 6, &Overflow), &Overflow);/*Q_exc */
+#else /* BASOP_NOGLOB */
+ exc_dct_in[i] = round_fx(L_shl(L_tmp, 6));/*Q_exc */
+#endif /* BASOP_NOGLOB */
+ }
+ }
+
+ tmp1 = mult_r(ener, 16384);
+ tmp1 = sub(*last_ener, tmp1);
+ tmp = mult_r(*last_ener, 16384);
+ tmp = sub(ener, tmp);
+ test();
+ IF(tmp > 0 && tmp1 > 0)
+ {
+ length_bin = 6;
+ move16();
+ IF(last_coder_type != AUDIO)
+ {
+ set16_fx(last_bitallocation_band, 0, 6);
+ Copy(&exc_dct_in[(4 + length_bin) * 16], &last_exc_dct_in[(4 + length_bin) * 16], length_bin * 16);
+ }
+
+ FOR(i = 4; i < (4 + length_bin); i++)
+ {
+ test();
+ IF(!(bitallocation_band[i] == 0 && last_bitallocation_band[i - 4] == 0))
+ {
+ k = shl(add(i, length_bin), 4);
+ src = &exc_dct_in[k]; /*(i+length_bin)*16*/
+ dst = &last_exc_dct_in[k];
+ FOR(j = 0; j < 16; j++)
+ {
+ tmp = mult_r(10923, abs_s(*src));
+ tmp1 = mult_r(10923, abs_s(*dst));
+
+ IF(GT_16(tmp, abs_s(*dst)))
+ {
+ tmp2 = *src;
+#ifdef BASOP_NOGLOB
+ * src = mult_r(16384, sub_o(*src, abs_s(*dst), &Overflow)); /*Q_exc */ move16();
+ tmp = mult_r(16384, add_o(tmp2, abs_s(*dst), &Overflow)); /*Q_exc */
+#else /* BASOP_NOGLOB */
+ * src = mult_r(16384, sub(*src, abs_s(*dst))); /*Q_exc */ move16();
+ tmp = mult_r(16384, add(tmp2, abs_s(*dst))); /*Q_exc */
+#endif
+ IF(tmp2 > 0)
+ {
+ *src = tmp;
+ move16();
+ }
+ }
+ ELSE IF(GT_16(tmp1, abs_s(*src)))
+ {
+ tmp = mult_r(*src, 22938);
+ tmp1 = mult_r(9830, abs_s(*dst));
+ tmp2 = *src;
+ *src = sub(tmp, tmp1); /*Q_exc */ move16();
+ IF(tmp2 > 0)
+ {
+ *src = add(tmp, tmp1); /*Q_exc */ move16();
+ }
+ }
+ src++;
+ dst++;
+ }
+ }
+ }
+ }
+ IF(EQ_16(bwe_flag, 1))
+ {
+ Decreas_freqPeak_fx(lsf_new, exc_dct_in, 9830);
+ }
+ ELSE
+ {
+ Decreas_freqPeak_fx(lsf_new, exc_dct_in, 16384);
+ }
+ }
+
+ Copy(&exc_dct_in[64], &last_exc_dct_in[64], L_frame - 64);
+ Copy(&bitallocation_band[4], last_bitallocation_band, 6);
+ *last_ener = ener;
+ move16();
+
+ return;
+}
+#endif
\ No newline at end of file
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index 7db30e207cb8bbac1f47f9aed22c0dec6c87d640..c10546a531b44a4c037acab32f3cbe51de26aefb 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -2213,6 +2213,21 @@ uint16_t get_indice_st(
const int16_t nb_bits /* i : number of bits to quantize the indice */
);
+#ifdef IVAS_FLOAT_FIXED
+void tdm_low_rate_dec_fx(
+ Decoder_State *st, /* i/o: decoder static memory */
+ Word16 dct_epit[], /* o : GSC excitation in DCT domain */
+ //Word16 *tmp_noise, /* o : long term temporary noise energy */
+ 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 */
+ const Word16 *lsf_new, /* i : ISFs at the end of the frame */
+ Word16 Q_exc
+);
+#endif
+
void tdm_low_rate_dec(
Decoder_State *st, /* i/o: decoder static memory */
float dct_epit[], /* o : GSC excitation in DCT domain */
@@ -3027,6 +3042,12 @@ int16_t check_bounds_s(
const int16_t high /* i : High limit */
);
+Word32 check_bounds_l(
+ const Word32 value, /* i : Input value */
+ const Word32 low, /* i : Low limit */
+ const Word32 high /* i : High limit */
+);
+
ivas_error stereo_memory_enc(
CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
const int32_t input_Fs, /* i : input sampling rate */
diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c
index b03cb1331f3e3db9b07f18002e7032fe88c2ac7c..e4e7c53ae1394a6dddaa3546dd4aaa0f8936d75d 100644
--- a/lib_com/ivas_tools.c
+++ b/lib_com/ivas_tools.c
@@ -596,6 +596,26 @@ int16_t check_bounds_s(
}
+/*-------------------------------------------------------------------*
+ * check_bounds_l()
+ *
+ * Ensure the input value is within the given limits
+ *-------------------------------------------------------------------*/
+
+ /*! r: Adjusted value */
+Word32 check_bounds_l(
+ const Word32 value, /* i : Input value */
+ const Word32 low, /* i : Low limit */
+ const Word32 high /* i : High limit */
+)
+{
+ Word32 value_adj;
+
+ value_adj = min(max(value, low), high);
+
+ return value_adj;
+}
+
/****************************************************************************/
/* matrix functions */
/* matrices are ordered column-wise in memory */
diff --git a/lib_com/prot.h b/lib_com/prot.h
index 81b68fbeb83ec31fb34dae75c5d9cc46e3ec1306..d01005cc47e23a9947c67cac1d94d396c773adca 100644
--- a/lib_com/prot.h
+++ b/lib_com/prot.h
@@ -3412,6 +3412,28 @@ void bands_and_bit_alloc(
const int16_t GSC_IVAS_mode /* i : GSC IVAS mode */
);
+void bands_and_bit_alloc_ivas_fx(
+ const Word16 cor_strong_limit, /* i : HF correlation */
+ const Word16 noise_lev, /* i : dwn scaling factor */
+ const Word32 core_brate, /* i : core bit rate */
+ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/
+ const Word16 bits_used, /* i : Number of bit used before frequency Q */
+ Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */
+ const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */
+ Word16 *max_ener_band, /* o : Sorted order */
+ Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */
+ Word16 *nb_subbands, /* o : Number of subband allowed */
+ const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */
+ Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */
+ Word16 *pvq_len, /* o : Number of bin covered with the PVQ */
+ const Word16 coder_type, /* i : coding type */
+ const Word16 bwidth, /* i : input signal bandwidth */
+ const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */
+ const Word16 L_frame, /* i : frame length */
+ const Word16 element_mode, /* i : element mode */
+ const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
+);
+
/*! r: average frequency gain */
float gsc_gaindec(
Decoder_State *st, /* i/o: decoder state structure */
diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h
index 0779878764200090abd898dacbbb7b805588e252..9e354fcba41728cb1fda790d01861ddc9eef505d 100644
--- a/lib_com/prot_fx2.h
+++ b/lib_com/prot_fx2.h
@@ -1325,6 +1325,17 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */
const Word16 bwidth_fx /* i : i signal bandwidth */
);
+#ifdef IVAS_FLOAT_FIXED
+Word16 gsc_gaindec_ivas_fx( /* o : average frequency gain */
+ Decoder_State *st_fx, /* i/o: decoder state structure */
+ Word16 y_gainQ_fx[], /* o : quantized gain per band */
+ const Word32 core_brate_fx, /* i : core used */
+ Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
+ const Word16 coder_type_fx, /* i : coding type */
+ const Word16 bwidth_fx /* i : input signal bandwidth */
+);
+#endif
+
Word16 gsc_gainQ_fx(
BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
const Word16 y_gain4[], /* i : Energy per band Q13 */
@@ -4458,6 +4469,40 @@ void highband_exc_dct_in_fx(
const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
);
+#ifdef IVAS_FLOAT_FIXED
+void highband_exc_dct_in_ivas_fx(
+ const Word32 core_brate, /* i : core bitrate */
+ const Word16 *mfreq_bindiv, /* i : bin per bands tables */
+ Word16 last_bin, /* i : last bin of bit allocation */
+ Word16 Diff_len, /* i : number of bin before cut-off frequency */
+ Word16 noise_lev, /* i : pulses dynamic */
+ Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
+ Word16 *exc_diffQ, /* i : frequency coefficients of per band */
+ Word16 *seed_tcx, /* i : Seed for noise */
+ Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */
+ Word16 nb_subfr, /* i : Number of subframe considered */
+ Word16 *exc_dct_in, /* o : dct of residual signal */
+ Word16 last_coder_type, /* i : coding type of last frame */
+ Word16 *bitallocation_band, /* i : bit allocation flag of each band */
+ const Word16 *lsf_new, /* i : LSFs at the end of the frame */
+ Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */
+ Word16 *last_ener, /* i : frequency energy of last frame */
+ Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */
+ Word16 *bitallocation_exc, /* i : flag of decoded coefficients */
+ Word16 bfi, /* i : bad frame indicator */
+ const Word16 coder_type, /* i : coder type */
+ Word16 bwidth,
+ Word16 *exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */
+ Word16 Qexc_diffQ,
+ Word16 Q_exc,
+ const Word16 GSC_noisy_speech
+ , Word16 *lt_ener_per_band_fx, /* i/o: Average per band energy */
+ const Word16 L_frame, /* i : frame length */
+ const Word16 element_mode, /* i : IVAS element mode */
+ const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
+);
+#endif
+
//lsf_dec_bfi_fx.c
void lsf_dec_bfi(
const Word16 codec_mode, /* i: : codec mode: MODE1 | MODE2 */
@@ -5882,6 +5927,20 @@ void init_tcx_cfg_fx(
Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */
Word16 Q_exc
);
+
+ void gsc_dec_ivas_fx(
+ Decoder_State *st_fx, /* i/o: State structure */
+ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation */
+ const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
+ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/
+ const Word16 bits_used, /* i : Number of bit used before frequency Q */
+ const Word16 nb_subfr, /* i : Number of subframe considered */
+ const Word16 coder_type, /* i : coding type */
+ Word16 *last_bin, /* i : last bin of bit allocation */
+ const Word16 *lsf_new, /* i : ISFs at the end of the frame */
+ Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */
+ Word16 Q_exc
+ );
void GSC_dec_init(
GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */
diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c
index d1413f69f1dc4575c7bec0b053fc58ab1182da3f..5083a4087b1f985838200b3be828a027ff7c10ab 100644
--- a/lib_dec/gs_dec_fx.c
+++ b/lib_dec/gs_dec_fx.c
@@ -6,6 +6,7 @@
#include "options.h"
#include "cnst.h"
#include "rom_com.h"
+#include "prot.h"
#include "prot_fx1.h"
#include "prot_fx2.h"
#include "ivas_cnst.h"
@@ -814,6 +815,334 @@ void gsc_dec_fx(
return;
}
+
+#ifdef IVAS_FLOAT_FIXED
+/*==========================================================================*/
+/* FUNCTION : void gsc_dec_ivas_fx () */
+/*--------------------------------------------------------------------------*/
+/* PURPOSE : Generic audio signal decoder */
+/*--------------------------------------------------------------------------*/
+/* INPUT ARGUMENTS : */
+/* _ (Word16) pit_band_idx : bin position of the cut-off frequency Q0 */
+/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */
+/* _ (Word16) coder_type : coding type Q0 */
+/* _ (Word16) bits_used : Number of bit used before frequency Q Q0 */
+/* _ (Word16) nb_subfr : Number of subframe considered Q0 */
+/* _ (Word16) Qexc : Q format of exc_dct_in */
+/*--------------------------------------------------------------------------*/
+/* OUTPUT ARGUMENTS : */
+/* _ None */
+/*--------------------------------------------------------------------------*/
+/* INPUT/OUTPUT ARGUMENTS : */
+/* Decoder_State *st_fx:Decoder State Structure */
+/* _ (Word16[]) exc_dct_in : dctof pitch-only excitation / total excitation Qexc*/
+/*--------------------------------------------------------------------------*/
+/* RETURN ARGUMENTS : */
+/* _None */
+/*==========================================================================*/
+void gsc_dec_ivas_fx(
+ Decoder_State *st_fx, /* i/o: State structure */
+ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation */
+ const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
+ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/
+ const Word16 bits_used, /* i : Number of bit used before frequency Q */
+ const Word16 nb_subfr, /* i : Number of subframe considered */
+ const Word16 coder_type, /* i : coding type */
+ Word16 *last_bin, /* i : last bin of bit allocation */
+ const Word16 *lsf_new, /* i : ISFs at the end of the frame */
+ Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */
+ Word16 Q_exc
+)
+{
+ Word16 i, j, bit, nb_subbands, pvq_len;
+#if 1//def ADD_LRTD
+ Word16 bitallocation_band[MBANDS_GN_BITALLOC16k];
+ Word16 bitallocation_exc[2];
+ Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k];
+ Word16 max_ener_band[MBANDS_GN_BITALLOC16k];
+ Word16 exc_diffQ[L_FRAME16k];
+ Word16 bits_per_bands[MBANDS_GN_BITALLOC16k];
+ Word16 concat_out[L_FRAME16k];
+ Word16 max_eq, max_eq_val;
+#else
+ Word16 bitallocation_band[MBANDS_GN];
+ Word16 bitallocation_exc[2];
+ Word16 Ener_per_bd_iQ[MBANDS_GN];
+ Word16 max_ener_band[MBANDS_GN];
+ Word16 exc_diffQ[L_FRAME];
+ Word16 bits_per_bands[MBANDS_GN];
+ Word16 concat_out[L_FRAME];
+#endif
+ Word16 inpulses_fx[NB_SFM];
+ Word16 imaxpulse_fx[NB_SFM];
+ Word16 mean_gain;
+ Word16 Mbands_gn = 16;
+ Word16 Qexc_diffQ = Q_PVQ_OUT;
+ Word32 L_tmp;
+ Word16 Q_tmp;
+ Word16 seed_init;
+ GSC_DEC_HANDLE hGSCDec;
+ hGSCDec = st_fx->hGSCDec;
+
+ set16_fx(inpulses_fx, 0, NB_SFM);
+ set16_fx(imaxpulse_fx, 0, NB_SFM);
+
+ /*--------------------------------------------------------------------------------------*
+ * Initialization
+ *--------------------------------------------------------------------------------------*/
+ bit = bits_used;
+ move16();
+#if 1//def ADD_LRTD
+ test(); test(); test(); test();
+ IF(EQ_16(coder_type, INACTIVE) && (EQ_16(st_fx->tdm_LRTD_flag, 1) || EQ_16(st_fx->element_mode, IVAS_SCE)) && LE_32(st_fx->core_brate, GSC_LRES_GAINQ_LIMIT))
+ {
+ bit = add(bit, GSC_LRES_NB_NITS);
+ }
+
+ IF(EQ_16(st_fx->L_frame, L_FRAME16k))
+ {
+ Mbands_gn = MBANDS_GN16k;
+ move16();
+ }
+#endif
+ set16_fx(exc_diffQ, 0, st_fx->L_frame);
+
+ /*--------------------------------------------------------------------------------------*
+ * Gain decoding
+ *--------------------------------------------------------------------------------------*/
+
+ test();
+ IF(st_fx->bfi || st_fx->BER_detect)
+ {
+ /* copy old gain */
+ Copy(hGSCDec->old_y_gain_fx, Ener_per_bd_iQ, Mbands_gn);
+ mean_gain = mult_r(st_fx->lp_gainc_fx, 3277); /*Q3*/
+ FOR(i = 0; i < Mbands_gn; i++)
+ {
+ Ener_per_bd_iQ[i] = add(Ener_per_bd_iQ[i], shl(mean_gain, 9)); /*Q12*/ move16();
+ }
+
+ st_fx->lp_gainc_fx = mult_r(st_fx->lp_gainc_fx, 32112); /*Q3*/
+ }
+ ELSE
+ {
+
+#if 1//def ADD_LRTD
+ i = 0;
+ move16();
+ WHILE(LT_16(i, SIZE_BRATE_INTERMED_TBL))
+ {
+ IF(LE_32(st_fx->core_brate, brate_intermed_tbl[i]))
+ {
+ break;
+ }
+ i = add(i,1);
+ }
+
+ test(); test(); test(); test();
+ IF(GT_16(st_fx->element_mode, EVS_MONO) && EQ_16(coder_type, AUDIO) &&
+ LE_32(st_fx->core_brate, STEREO_GSC_BIT_RATE_ALLOC) && EQ_32(brate_intermed_tbl[i],ACELP_9k60)) /* Bit allocation is mapped to 8 kb/s instead of 9.6 kb/s in this case */
+ {
+ i--;
+ }
+ mean_gain = gsc_gaindec_ivas_fx(st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth);
+
+#else
+ mean_gain = gsc_gaindec_fx(st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth);
+#endif
+ st_fx->lp_gainc_fx = mult_r(640,mean_gain); /*10 in Q6 x Q12 -> lp_gainc in Q3 */
+ }
+
+ *last_bin = 0;
+ move16();
+ test();
+ IF(EQ_32(st_fx->core_brate, ACELP_8k00) && NE_16(st_fx->bwidth, NB))
+ {
+ bitallocation_exc[0] = 0;
+ move16();
+ bitallocation_exc[1] = 0;
+ move16();
+ }
+
+ set16_fx(bitallocation_band, 0, MBANDS_GN);
+
+ test();
+ IF((EQ_16(st_fx->bfi, 1)) || st_fx->BER_detect)
+ {
+ /*--------------------------------------------------------------------------------------*
+ * Copy old spectrum
+ * reduce spectral dynamic
+ * save spectrum
+ *--------------------------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ max_eq = 32767;
+ move16();
+#endif
+ test();
+ IF(EQ_16(st_fx->last_good_fx, INACTIVE_CLAS) || EQ_16(st_fx->Last_GSC_noisy_speech_flag_fx, 1))
+ {
+ FOR(i = 0; i < st_fx->L_frame; i++)
+ {
+ L_tmp = L_shr(L_mult(Random(&hGSCDec->seed_tcx_fx), 26214), 5); /*Q10*/
+ L_tmp = L_mac(L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554);
+ hGSCDec->Last_GSC_spectrum_fx[i] = round_fx(L_tmp); /*Q10*/
+ }
+ }
+
+ Copy(hGSCDec->Last_GSC_spectrum_fx, exc_diffQ, st_fx->L_frame);
+
+ FOR(i = 0; i < st_fx->L_frame; i++)
+ {
+ hGSCDec->Last_GSC_spectrum_fx[i] = mult_r(hGSCDec->Last_GSC_spectrum_fx[i], 24576); /*Q10*/ move16();
+ }
+
+ }
+ ELSE
+ {
+ /*--------------------------------------------------------------------------------------*
+ * PVQ decoder
+ *--------------------------------------------------------------------------------------*/
+
+ bands_and_bit_alloc_ivas_fx(hGSCDec->cor_strong_limit_fx, hGSCDec->noise_lev_fx, st_fx->core_brate, Diff_len, bit, &bit, Ener_per_bd_iQ,
+ max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech_fx,
+ st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode);
+
+#if 1//def ADD_LRTD
+ IF(bit == 0)
+ {
+ set16_fx(concat_out, 0, L_FRAME16k);
+ }
+#endif
+ {
+ pvq_core_dec_fx(st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE);
+ Scale_sig(concat_out, gsc_sfm_end[nb_subbands - 1], sub(Q_PVQ_OUT, Q_tmp));
+ }
+ seed_init = 0;
+ move16();
+
+#if 1//def ADD_LRTD
+ max_eq = 0;
+ max_eq_val = 32767;
+
+ IF(((st_fx->core_brate < ACELP_7k20 && st_fx->GSC_noisy_speech_fx == 1) || st_fx->core_brate < 6000) && coder_type <= UNVOICED)
+ {
+ j = maximum_fx(concat_out, nb_subbands * 16, &max_eq);
+ //max_eq = max_eq_val / (abs_s(concat_out[j]) + 328 /*0.01f*/ );
+ Word16 temp_max_eq = abs_s(concat_out[j]) + 10 /*0.01f in Q10*/;
+ IF( LE_16( temp_max_eq, ONE_IN_Q10 ) )
+ {
+ max_eq = max_eq_val;
+ }
+ ELSE
+ {
+ Word16 exp = 5;
+ max_eq = Inv16( temp_max_eq, &exp );
+ max_eq = shl(max_eq, exp);
+ }
+ }
+#endif
+ /* Reorder Q bands */
+ FOR(j = 0; j < nb_subbands; j++)
+ {
+ Copy(concat_out + j * 16, exc_diffQ + max_ener_band[j] * 16, 16);
+
+ *last_bin = s_max(*last_bin,max_ener_band[j]);
+ move16();
+
+ bitallocation_band[max_ener_band[j]] = 1;
+ move16();
+
+ seed_init = add(seed_init,inpulses_fx[j]);
+ }
+ test();
+ IF(NE_16(st_fx->last_coder_type_fx, AUDIO) /* First audio frame */
+ && NE_16(st_fx->last_coder_type_fx, UNVOICED))/* last_coder_type == INACTIVE is overwritten in update_dec to UNVOICED */
+ {
+ FOR(j = 0; j < shl(nb_subbands,4); j++)
+ {
+ IF(concat_out[j] > 0)
+ {
+ seed_init = extract_l(L_shl(seed_init,3));
+ }
+ IF(concat_out[j] < 0)
+ {
+ seed_init = add(seed_init,3);
+ move16();
+ }
+ }
+
+ hGSCDec->seed_tcx_fx = seed_init;
+ move16();
+ }
+ test();
+ IF(EQ_32(st_fx->core_brate,ACELP_8k00) && NE_16(st_fx->bwidth,NB))
+ {
+ IF(exc_diffQ[L_FRAME8k - 2] != 0)
+ {
+ bitallocation_exc[0] = 1;
+ move16();
+ }
+
+ IF(exc_diffQ[L_FRAME8k - 1] != 0)
+ {
+ bitallocation_exc[1] = 1;
+ move16();
+ }
+ }
+
+ Copy(exc_diffQ, hGSCDec->Last_GSC_spectrum_fx, st_fx->L_frame);
+
+ /*--------------------------------------------------------------------------------------*
+ * Skip adaptive (pitch) contribution frequency band (no noise added over the time contribution)
+ * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal
+ * Gain is based on the inter-correlation gain between the pulses found and residual signal
+ *--------------------------------------------------------------------------------------*/
+#if 1//def ADD_LRTD
+ test(); test(); test(); test(); test(); test();
+ IF(GE_16(st_fx->GSC_IVAS_mode, 1) && EQ_16(st_fx->GSC_noisy_speech_fx, 1))
+ {
+ FOR(i = 64; i < st_fx->L_frame; i++)
+ {
+ //PMT("GSC FIX point to be done here")
+ //exc_diffQ[i] *= max_eq;
+ exc_diffQ[i] = mult_r(exc_diffQ[i], max_eq);
+ }
+ }
+ ELSE IF(((LT_32(st_fx->core_brate, ACELP_7k20) && EQ_16(st_fx->GSC_noisy_speech_fx, 1)) || LT_32(st_fx->core_brate, 6000)) && LE_16(st_fx->coder_type, UNVOICED))
+ {
+ FOR(i = 0; i < L_FRAME; i++)
+ {
+ //PMT("GSC FIX point to be done here")
+ //exc_diffQ[i] *= max_eq;
+ exc_diffQ[i] = mult_r(exc_diffQ[i], max_eq);
+ }
+ }
+ ELSE
+#endif
+ {
+ freq_dnw_scaling_fx(hGSCDec->cor_strong_limit_fx, st_fx->coder_type_fx, hGSCDec->noise_lev_fx, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame);
+ }
+ }
+
+ /*--------------------------------------------------------------------------------------*
+ * Estimate noise level
+ *--------------------------------------------------------------------------------------*/
+
+ highband_exc_dct_in_ivas_fx(st_fx->core_brate, mfreq_bindiv_loc, *last_bin, Diff_len, hGSCDec->noise_lev_fx, pit_band_idx, exc_diffQ,
+ &hGSCDec->seed_tcx_fx, Ener_per_bd_iQ, nb_subfr, exc_dct_in, st_fx->last_coder_type_fx, bitallocation_band, lsf_new,
+ hGSCDec->last_exc_dct_in_fx, &hGSCDec->last_ener_fx, hGSCDec->last_bitallocation_band_fx, bitallocation_exc, st_fx->bfi, coder_type,
+ st_fx->bwidth, exc_wo_nf, Qexc_diffQ, Q_exc, st_fx->GSC_noisy_speech_fx, hGSCDec->lt_ener_per_band_fx
+ , st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode
+ );
+
+ exc_dct_in[0] = 0;
+ move16();
+
+ return;
+
+}
+#endif
+
/*-------------------------------------------------------------------*
* GSC_dec_init()
*
diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c
index ad35cda7ae3602ef350eb51949fece3b4f92defe..b32c358a2ee8096952dd4e1a8a412225743d8279 100644
--- a/lib_dec/ivas_td_low_rate_dec.c
+++ b/lib_dec/ivas_td_low_rate_dec.c
@@ -38,6 +38,8 @@
#include "ivas_rom_com.h"
#include "ivas_cnst.h"
#include "prot.h"
+#include "prot_fx1.h"
+#include "prot_fx2.h"
#include "ivas_prot.h"
#include "wmc_auto.h"
@@ -59,6 +61,7 @@ void tdm_low_rate_dec(
const float *lsf_new /* i : ISFs at the end of the frame */
)
{
+#ifndef IVAS_FLOAT_FIXED
int16_t tmp_nb_bits_tot, pit_band_idx;
GSC_DEC_HANDLE hGSCDec;
int16_t Diff_len, nb_subfr;
@@ -165,8 +168,216 @@ void tdm_low_rate_dec(
set_f( st->tilt_code_dec, 0, NB_SUBFR16k );
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->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 dct_epit_fx[L_FRAME];
+ //Word16 tmp_noise_fx;
+ Word16 pitch_buf_fx[NB_SUBFR16k];
+ Word16 voice_factors_fx[5];
+ Word16 exc_fx[L_FRAME];
+ Word16 exc2_fx[L_FRAME];
+ Word16 bwe_exc_fx[L_FRAME32k];
+ Word16 lsf_new_fx[M];
+ //floatToFixed_arr(exc, exc_fx, 0, L_FRAME);
+ //floatToFixed_arr(exc2, exc2_fx, 0, L_FRAME);
+ set_s(dct_epit_fx, 0, L_FRAME);
+ set_s(exc_fx, 0, L_FRAME);
+ set_s(exc2_fx, 0, L_FRAME);
+ set_s(bwe_exc_fx, 0, L_FRAME32k);
+ for (int i = 0; i < M; i++) {
+ lsf_new_fx[i] = (Word16)(lsf_new[i] * 2.56f);
+ }
+ tdm_low_rate_dec_fx(st, dct_epit_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, 0);
+ fixedToFloat_arr(dct_epit_fx, dct_epit, 0, L_FRAME);
+ //*tmp_noise = fixedToFloat(tmp_noise_fx, Q3);
+ fixedToFloat_arr(pitch_buf_fx, pitch_buf, Q6, NB_SUBFR16k);
+ fixedToFloat_arr(voice_factors_fx, voice_factors, Q15, 5);
+ fixedToFloat_arr(exc_fx, exc, 0, L_FRAME);
+ fixedToFloat_arr(exc2_fx, exc2 , 0, L_FRAME);
+ fixedToFloat_arr(bwe_exc_fx, bwe_exc, 0, 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, 0, 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);
+ /*hGSCDec end*/
+
+ *tmp_noise = st->lp_gainc;
+#endif
}
+#ifdef IVAS_FLOAT_FIXED
+void tdm_low_rate_dec_fx(
+ Decoder_State *st, /* i/o: decoder static memory */
+ Word16 dct_epit[], /* o : GSC excitation in DCT domain Q0 */
+ //Word16 *tmp_noise, /* o : long term temporary noise energy Q3 */
+ Word16 *pitch_buf, /* o : floating pitch values for each subframe Q6 */
+ Word16 *voice_factors, /* o : voicing factors Q15 */
+ Word16 *exc, /* i/o: adapt. excitation exc Q0? */
+ Word16 *exc2, /* i/o: adapt. excitation/total exc Q0? */
+ Word16 *bwe_exc, /* o : excitation for SWB TBE Q0? */
+ const Word16 *lsf_new, /* i : ISFs at the end of the frame Q8/100 (2.56x) */
+ Word16 Q_exc
+)
+{
+ Word16 tmp_nb_bits_tot, pit_band_idx;
+ GSC_DEC_HANDLE hGSCDec;
+ Word16 Diff_len, nb_subfr;
+ Word16 attack_flag;
+ Word16 last_bin;
+ //float exc_wo_nf[L_FRAME];
+ Word16 exc_wo_nf_fx[L_FRAME];
+
+ hGSCDec = st->hGSCDec;
+
+ /*---------------------------------------------------------------*
+ * Initialization
+ *---------------------------------------------------------------*/
+
+ nb_subfr = 2;
+
+ st->GSC_IVAS_mode = 0;
+ st->GSC_noisy_speech_fx = 1;
+ hGSCDec->noise_lev_fx = 14;
+
+ pit_band_idx = 10 + BAND1k2;
+ hGSCDec->Last_GSC_pit_band_idx_fx = pit_band_idx;
+
+ //st->tilt_code = 0.0f;
+ st->tilt_code_fx = 0;
+ //set_f(exc, 0, L_FRAME);
+ //set_f(dct_epit, 0, L_FRAME);
+ //set_f(pitch_buf, L_SUBFR, NB_SUBFR);
+ set_s(exc, 0, L_FRAME);
+ set_s(dct_epit, 0, L_FRAME);
+ set_s(pitch_buf, shl(L_SUBFR, Q6), NB_SUBFR);
+ st->bpf_off = 1;
+
+ //st->bfi_pitch = (int16_t)(mean(pitch_buf, 4) + 0.5f);
+ st->bfi_pitch_fx = mean_fx(pitch_buf, 4);
+ st->bfi_pitch_frame = L_FRAME;
+ Diff_len = L_FRAME / 2;
+ st->bpf_off = 0;
+ attack_flag = 0;
+
+ /*--------------------------------------------------------------------------------------*
+ * GSC decoder
+ *--------------------------------------------------------------------------------------*/
+
+ /* find the current total number of bits used */
+ tmp_nb_bits_tot = st->next_bit_pos;
+
+ IF(st->element_mode == IVAS_CPE_TD)
+ {
+ tmp_nb_bits_tot += TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS;
+ }
+
+ IF(st->tdm_LRTD_flag == 1)
+ {
+ tmp_nb_bits_tot -= STEREO_BITS_TCA;
+ }
+
+ IF(st->extl_brate_orig > 0)
+ {
+ /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */
+ tmp_nb_bits_tot--;
+ }
+
+ //gsc_dec(st, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st->coder_type, &last_bin, lsf_new, exc_wo_nf, tmp_noise);
+ gsc_dec_ivas_fx(st, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st->coder_type, &last_bin, lsf_new, exc_wo_nf_fx, Q_exc);
+
+ /*--------------------------------------------------------------------------------------*
+ * iDCT transform
+ *--------------------------------------------------------------------------------------*/
+
+ //edct(dct_epit, exc, L_FRAME, IVAS_CPE_TD);
+ edct_16fx(dct_epit, exc, L_FRAME, find_guarded_bits_fx(L_FRAME), IVAS_CPE_TD);
+
+ //edct(exc_wo_nf, exc_wo_nf, L_FRAME, IVAS_CPE_TD);
+ edct_16fx(exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, find_guarded_bits_fx(L_FRAME), IVAS_CPE_TD);
+
+ /*----------------------------------------------------------------------*
+ * Remove potential pre-echo in case an onset has been detected
+ *----------------------------------------------------------------------*/
+
+ //pre_echo_att(&hGSCDec->Last_frame_ener, exc, attack_flag, st->last_coder_type, st->L_frame);
+ pre_echo_att_fx(&hGSCDec->Last_frame_ener_fx, exc, attack_flag, Q_exc, st->last_coder_type, st->L_frame);
+
+
+ /*--------------------------------------------------------------------------------------*
+ * Update BWE excitation
+ *--------------------------------------------------------------------------------------*/
+
+ //set_f(voice_factors, 0.0f, NB_SUBFR16k);
+ set_s(voice_factors, 0, NB_SUBFR16k);
+
+ IF(st->hBWE_TD != NULL)
+ {
+ IF(st->tdm_LRTD_flag)
+ {
+ //interp_code_5over2(exc, bwe_exc, L_FRAME);
+ interp_code_5over2_fx(exc, bwe_exc, L_FRAME);
+ }
+ ELSE
+ {
+ //set_f(bwe_exc, 0, L_FRAME32k);
+ set_s(bwe_exc, 0, L_FRAME32k);
+ }
+ }
+
+ /*--------------------------------------------------------------------------------------*
+ * Updates
+ *--------------------------------------------------------------------------------------*/
+
+ //mvr2r(exc, exc2, L_FRAME);
+ Copy(exc, exc2, L_FRAME);
+ //mvr2r(exc_wo_nf, exc, L_FRAME);
+ Copy(exc_wo_nf_fx, exc, L_FRAME);
+
+ /*--------------------------------------------------------------------------------------*
+ * Channel aware mode parameters
+ *--------------------------------------------------------------------------------------*/
+
+ //set_f(st->tilt_code_dec, 0, NB_SUBFR16k);
+ set_s(st->tilt_code_dec_fx, 0, NB_SUBFR16k);
+
+ return;
+}
+#endif
/*---------------------------------------------------------------------*
* decod_gen_2sbfr()