From 3d2a0cd354d806f59712c696fa4fe63e3869eafc Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 9 Jul 2024 13:12:36 +0200 Subject: [PATCH] backport fix 1137 from the float repo --- lib_com/gs_bitallocation.c | 334 +++++++++++++++++++++++++++++++++++++ lib_com/options.h | 2 + 2 files changed, 336 insertions(+) diff --git a/lib_com/gs_bitallocation.c b/lib_com/gs_bitallocation.c index 8bbf1d21c..a742f7191 100644 --- a/lib_com/gs_bitallocation.c +++ b/lib_com/gs_bitallocation.c @@ -51,6 +51,29 @@ static float Find_bit_frac( const int16_t nb_band, const int16_t remaining_bits static void reajust_bits( float *bits_per_bands, const int16_t st_band, const int16_t end_band, const int16_t sum_bit_in, const int16_t bit_bdgt_in ); +#ifdef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING +#define Q15_0_33 10922 /* 0.33 */ +#define Q18_0_1 26214 /* 0.1 */ +#define Q18_0_50 131072 /* 0.50 */ +#define Q18_0_75 196608 /* 0.75 */ +#define Q18_0_76 199229 /* 76/100 */ +#define Q18_1_0 262144 /* 1.0 */ +#define Q18_1_2 314573 /* 1.2 */ +#define Q18_112 29360128 /* 112 */ +#define Q18_DSR_NB_PULSE 1179648 /* 4.5 */ +#define Q18_1_5xDSR_NB_PULSE 1769472 /* 1.5x4.5 */ +#define Q18_2_0xDSR_NB_PULSE ( Q18_DSR_NB_PULSE << 1 ) /* 2.0x4.5 */ + +#define Q31_0_00125 2684355 /* 0.125/100 */ +#define Q31_0_0125 26843546 /* 0.0125 */ +#define Q31_0_015 32212255 /* 0.0125 */ +#define Q31_0_02 42949673 /* 0.02 */ +#define Q31_0_17 365072220 /* 0.17 */ +#define Q31_0_23 493921239 /* 0.23 */ +static Word16 Find_norm_inv( const Word32 ToDivide, Word16 *e_div ); +static Word16 Find_bit_alloc_IVAS_int( const Word32 core_brate, const Word16 GSC_IVAS_mode, const Word16 Diff_len, const Word16 nb_tot_bands, const Word16 L_frame, Word16 *bit, Word16 *max_ener_band, float *ener_vec, float *bits_per_bands ); +static Word16 maximum_fx( const Word16 *vec_fx, const Word16 lvec_fx, Word16 *max_fx ); +#endif /*-------------------------------------------------------------------* * bands_and_bit_alloc() @@ -89,8 +112,12 @@ void bands_and_bit_alloc( int16_t pos, band; float SWB_bit_budget; float bits_per_bands[MBANDS_GN_BITALLOC16k]; +#ifndef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING float fzero_val, mp, mb, nb_bands_adj, bit_adj; int16_t nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; +#else + float fzero_val; +#endif /* initializations */ nb_tot_bands = 16; @@ -190,6 +217,7 @@ void bands_and_bit_alloc( { if ( GSC_IVAS_mode > 0 ) { +#ifndef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING SWB_bit_budget = *bit; st_band = 5; @@ -368,6 +396,10 @@ void bands_and_bit_alloc( bits_per_bands[i] += sum_bit; } } +#else + nb_tot_bands = Find_bit_alloc_IVAS_int( core_brate, GSC_IVAS_mode, Diff_len, nb_tot_bands, L_frame, bit, max_ener_band, ener_vec, bits_per_bands ); + nb_bands = nb_tot_bands; +#endif } else if ( GSC_noisy_speech ) { @@ -927,3 +959,305 @@ static float Find_bit_frac( return ( var_out ); } + +#ifdef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING +static Word16 Find_bit_alloc_IVAS_int( /* o : Number of band to encode */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ + const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ + const Word16 nb_tot_bands_in, /* i : total number of band */ + const Word16 L_frame, /* i : frame length */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + Word16 *max_ener_band, /* i/o: Energy based sorted order */ + float *ener_vec_io, /* i/o: Energy per band order */ + float *bits_per_bands_o /* o : Number of bit allowed per allowed sub-band Q3 */ +) +{ + Word32 mp, mb, nb_bands_adj, bit_adj; + Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; + Word32 SWB_bit_budget; // Q0 -> Q18 + Word16 i, j, nb_bands_max, st_band, nb_tot_bands_loc, etmp; + Word32 sum_bit /*Q18*/, bit_fracf /*Q18*/; + Word16 d_tmp, e_div, tmp16, ener_vec[MBANDS_GN_BITALLOC16k]; + Word32 Ltmp, etmp_32fx, bits_per_bands[MBANDS_GN_BITALLOC16k]; + + SWB_bit_budget = *bit; // Q0 + st_band = 5; + nb_bands_max = nb_tot_bands_in; + + for ( i = 0; i < MBANDS_GN; i++ ) + { + ener_vec[i] = (short) ( ener_vec_io[i] ); /* Q12 -> Q12 */ + } + + if ( L_frame == L_FRAME16k ) + { + for ( i = MBANDS_GN; i < MBANDS_GN_BITALLOC16k; i++ ) + { + ener_vec[i] = (short) ( ener_vec_io[i] * 4096.0 + 0.5f ); /* Q0 -> Q12 */ + } + } + + set_l( bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); + + /* 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( Mpy_32_32( -Q31_0_00125, L_shl( Diff_len, 18 ) ), Q18_0_76 ); /* Q18 */ + + /* bit_fracf = check_bounds(bit_fracf, 0.50f, 0.75f); */ + bit_fracf = min( max( bit_fracf, Q18_0_50 ), Q18_0_75 ); + + /* 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 += Q18_0_1; /* Q18*/ + nb_bands_max -= 1; + } + + if ( GSC_IVAS_mode == 3 ) + { + /* bit_fracf -= 0.1f; */ + bit_fracf -= Q18_0_1; /* 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 = Q18_1_0; + 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( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, 18 ) ), Q18_0_75 ); // 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( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, 18 ) ), Q18_1_2 ); // Q18 + } + /*nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);*/ + + nb_bands_max = round_fx( Mpy_32_16_1( L_shl( nb_bands_adj, 5 ), shl( nb_bands_max, 10 - 2 ) ) ); /* Q0 */ + nb_bands_max = check_bounds_s( nb_bands_max, 5, nb_tot_bands_in ); + + /* bit_fracf *= SWB_bit_budget;*/ + /* At this point bit_fracf has a value below 1.0 */ + bit_fracf = Mpy_32_16_1( L_shl( bit_fracf, 10 ), extract_l( L_shl( SWB_bit_budget, 5 ) ) ); /* (Q(18+10)*Q(0+5) + 1 - 16 = Q18 */ + + /* Estimation of the number of bit used in HF */ + /* with only the first weighting The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */ + /* mb = .17f * bit_fracf;*/ + mb = Mpy_32_32( Q31_0_17, bit_fracf ); /* Q18 */ + + /* mp = 2 * DSR_NB_PULSE;*/ + mp = Q18_2_0xDSR_NB_PULSE; + if ( core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3 ) + { + /* mp = 1.5f * DSR_NB_PULSE;*/ + mp = Q18_1_5xDSR_NB_PULSE; + } + else if ( core_brate < GSC_L_RATE_STG ) + { + /* mp = DSR_NB_PULSE;*/ + mp = Q18_DSR_NB_PULSE; + } + + /* 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)); */ + d_tmp = Find_norm_inv( L_add( mp, mb ), &e_div ); + Ltmp = Mpy_32_16_1( L_sub( L_shl( SWB_bit_budget, 18 ), bit_fracf ), d_tmp ); /* Perform mult by 1/den */ + nb_tot_bands_loc = extract_h( L_shl( Ltmp, sub( 1, e_div ) ) ); /* adjust exponent: 1 is to take into account the / 2.0f, and e_div for the num and den of the division*/ + + mp = min( mp, mb ); + tmp16 = sub( add( nb_tot_bands_loc, st_band ), nb_bands_max ); + if ( tmp16 > 0 ) + { + /* bit_adj = ( ( mb + mp ) / 2 ) * ( nb_tot_bands_loc + st_band - nb_bands_max ); */ + bit_adj = Mpy_32_16_1( L_shl( L_add( mb, mp ), 5 ), shl( tmp16, 10 - 1 ) ); /* Q18+5 * Q0+10 + 1 -1 - 16 = Q18 (-1 is to cover for the /2 in the equation) */ + bit_adj = L_max( 0, bit_adj ); + nb_tot_bands_loc = nb_bands_max - st_band; + bit_fracf += bit_adj; /* Q18 */ + } + nb_tot_bands_loc += st_band; + + /* Allocate bits to LF */ + /* etmp = 0.23f; */ + etmp_32fx = Q31_0_23; + 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] = Mpy_32_32( bit_fracf, etmp_32fx ); /* 18 + 31 + 1 - 32 = Q18 */ + /* etmp -= 0.015f; */ + etmp_32fx -= Q31_0_015; /* Q18 */ + } + + /* SWB_bit_budget -= bit_fracf; */ + SWB_bit_budget = L_sub( L_shl( SWB_bit_budget, 18 ), bit_fracf ); /* Q0->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_loc - 1; i++ ) + { + if ( ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1] ) /* i +1 and i -1 can be considered as 2 ptrs */ + { + nb_pulse_per_band[i] = 1; + } + } + + for ( j = st_band; j < nb_tot_bands_loc; j++ ) + { + if ( j > 6 ) + { + i = maximum_fx( ener_vec, nb_tot_bands_loc, &etmp ); + } + else + { + i = j; + } + max_ener_band[j] = i; + ener_vec[i] = MIN16B; + } + + /* Recompute the final bit distribution for HF */ + if( nb_tot_bands_loc > st_band ) + { + /* This is not bit exact because of the precision lost */ + /* mb = ( SWB_bit_budget * 2 / ( nb_tot_bands_loc - st_band ) ) - mp; */ + d_tmp = Find_norm_inv( L_deposit_h( sub( nb_tot_bands_loc, st_band ) ), &e_div ); + mb = L_sub( L_shr( Mpy_32_16_1( L_shl( SWB_bit_budget, 1 ), d_tmp ), e_div ), mp ); /* Q18 */ + /* bit_fracf = ( mb - mp ) / ( nb_tot_bands_loc - st_band ); */ + bit_fracf = L_shr( Mpy_32_16_1( L_sub( mb, mp ), d_tmp ), e_div ); /* Q18 */ + + mb -= bit_fracf; + /* Do the distribution */ + for ( j = st_band; j < nb_tot_bands_loc; j++ ) + { + bits_per_bands[max_ener_band[j]] = Q18_DSR_NB_PULSE; + if ( nb_pulse_per_band[max_ener_band[j]] > 1 ) + { + bits_per_bands[max_ener_band[j]] = mb; + } + mb -= bit_fracf; + SWB_bit_budget -= 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] += Q18_1_0; + /* SWB_bit_budget--; */ + SWB_bit_budget -= Q18_1_0; + i--; + if ( i == -1 ) + { + i = st_band - 1; + } + } + } + + /*nb_bands = nb_tot_bands_loc;*/ + + sum_bit = 0; + j = 0; + for ( i = 0; i < nb_tot_bands_loc; i++ ) + { + /* if (bits_per_bands[i] > 112) */ + if ( bits_per_bands[i] > Q18_112 ) + { + /* sum_bit += bits_per_bands[i] - 112; */ + sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], Q18_112 ) ); + /* bits_per_bands[i] = 112; */ + bits_per_bands[i] = Q18_112; + j = add( j, add( i, 1 ) ); + } + + /* safety check for overage bit reallocation */ + /* else if (bits_per_bands[i] + sum_bit / 3 > 112) */ + else if ( L_add( bits_per_bands[i], Mpy_32_16_1( sum_bit, Q15_0_33 ) ) > Q18_112 ) + { + j = add( j, add( i, 1 ) ); + } + } + + if ( sum_bit != 0 ) + { + /* sum_bit /= (nb_bands - j); */ + d_tmp = Find_norm_inv( L_deposit_h( sub( nb_tot_bands_loc, j ) ), &e_div ); + sum_bit = L_shr( Mpy_32_16_1( sum_bit, d_tmp ), e_div ); /* Q18 */ + for ( i = j; i < nb_tot_bands_loc; i++ ) + { + bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); + } + } + + for ( i = 0; i < MBANDS_GN_BITALLOC16k; i++ ) + { + bits_per_bands_o[i] = (float) bits_per_bands[i] / 262144.0f; /* Q18 -> float */ + } + + return nb_tot_bands_loc; +} + +/* Find normalized 1 / ToDivide */ +static Word16 Find_norm_inv( + const Word32 ToDivide, + Word16 *e_div +) +{ + Word16 d_tmp, e_tmp; + + e_tmp = norm_l( ToDivide ); + d_tmp = round_fx( L_shl( ToDivide, e_tmp ) ); + d_tmp = div_s( 16384, d_tmp ); /* 1.0 in Q14, dividend is normalize so >= 16384 as required for the division */ + *e_div = sub( 14, e_tmp ); + + return d_tmp; +} + +static Word16 maximum_fx( /* o : index of the maximum value in the input vector */ + const Word16 *vec_fx, /* i : input vector */ + const Word16 lvec_fx, /* i : length of input vector */ + Word16 *max_fx /* o : maximum value in the input vector */ +) +{ + Word16 j, ind; + Word16 tmp; + + ind = 0; + tmp = vec_fx[0]; + + for ( j = 1; j < lvec_fx; j++ ) + { + if ( vec_fx[j] > tmp ) + { + ind = j; + } + tmp = s_max( tmp, vec_fx[j] ); + } + *max_fx = tmp; + + return ind; +} +#endif diff --git a/lib_com/options.h b/lib_com/options.h index 28c84b1dc..47e6a2721 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -70,6 +70,8 @@ #define NONBE_FIX_1010_STEREO_CNG_DIV_BY_ZERO /* Eri: Issue 1010: Division by zero in Stereo CNG */ #define NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES /* FhG: issue 1133: skip de-whitening of bg noise shape after frameloss period if the first good frame is an SID */ #define NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID /* FhG: issue 1133: in TCX PLC, don't scale hHQ_core->old_out after applying fade to noise in burst frame error */ +#define NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING /* VA: Add fix point bit allocation for special GSC mode such that float and fixed point have the same final bit allocation */ + /* #################### End FIXES switches ############################ */ #define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ -- GitLab