From 3f1c8a2ec7e446bae8fd9dd75eca523a1a97eabe Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sat, 24 Aug 2024 11:14:13 +0530 Subject: [PATCH] Fix for high MLDs observed with LTV streams [x] MLD Fix for LTV - MASA 2TC at 24.4 kbps, 48kHz in, 48kHz out, STEREO out [x] Added missing scaling of st->hHQ_core->old_out_fx when st->Q_old_wtda is reset to 0 --- lib_com/prot_fx.h | 15 + lib_com/rom_com.c | 132 +++++++++ lib_com/rom_com.h | 1 + lib_dec/dec_gen_voic_fx.c | 2 +- lib_dec/dec_pit_exc_fx.c | 2 +- lib_dec/gain_dec_fx.c | 387 ++++++++++++++++++++++++++ lib_dec/ivas_corecoder_dec_reconfig.c | 4 + lib_dec/ivas_init_dec.c | 14 + lib_dec/ivas_stat_dec.h | 1 + lib_dec/ivas_td_low_rate_dec.c | 2 +- lib_dec/lib_dec_fx.c | 4 + 11 files changed, 561 insertions(+), 3 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index b6e161351..c65aa7392 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6416,6 +6416,21 @@ void gain_dec_lbr_fx( const Word16 L_subfr /* i : subfr lenght */ ); +void gain_dec_lbr_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *code_fx, /* i : algebraic excitation Q9 */ + Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes */ + Word16 gp_mem[] /* i/o: gain_pitch from previous subframes */ + , + const Word16 L_subfr /* i : subfr lenght */ +); + void lp_gain_updt_fx( const Word16 i_subfr, /* i : subframe number Q0 */ const Word16 gain_pit, /* i : Decoded gain pitch Q14 */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 8bc681806..4b29fbfbd 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -5511,6 +5511,138 @@ const float gp_gamma_4sfr_7b[2 * 128] = 1.20145f, 1.11183f, }; +const Word16 gp_gamma_4sfr_7b_fx[2 * 128] = /*Q14/Q9 */ +{ + 101, 174, + 228, 542, + 400, 269, + 735, 418, + 799, 111, + 1146, 802, + 1250, 345, + 1291, 1138, + 1327, 224, + 1478, 1705, + 1557, 491, + 1947, 295, + 1988, 639, + 2343, 386, + 2386, 213, + 2541, 133, + 2904, 2881, + 3198, 455, + 3204, 736, + 3219, 276, + 3463, 549, + 3709, 343, + 3741, 177, + 4431, 226, + 4480, 927, + 4516, 396, + 4547, 622, + 4900, 290, + 5011, 503, + 5601, 742, + 5616, 173, + 5688, 428, + 5975, 337, + 6196, 5865, + 6293, 253, + 6294, 580, + 6305, 1053, + 6792, 480, + 6951, 391, + 7151, 212, + 7298, 671, + 7475, 317, + 7757, 534, + 7917, 856, + 8195, 1449, + 8198, 437, + 8228, 261, + 8434, 154, + 8493, 622, + 8552, 358, + 9324, 493, + 9373, 744, + 9391, 217, + 9410, 296, + 9711, 14146, + 9711, 405, + 9724, 598, + 10128, 1140, + 10248, 8800, + 10391, 344, + 10530, 883, + 10541, 542, + 10559, 257, + 10772, 441, + 11075, 664, + 11463, 304, + 11510, 196, + 11551, 2230, + 11574, 501, + 11611, 391, + 12154, 784, + 12205, 576, + 12304, 133, + 12413, 343, + 12457, 84, + 12468, 445, + 12734, 247, + 12970, 639, + 13072, 1411, + 13142, 983, + 13159, 499, + 13356, 386, + 13460, 298, + 13838, 710, + 13850, 550, + 13930, 429, + 14446, 343, + 14449, 170, + 14511, 467, + 14530, 857, + 14697, 623, + 14770, 4569, + 14833, 229, + 15086, 512, + 15112, 387, + 15527, 574, + 15552, 1126, + 15573, 764, + 15662, 291, + 15677, 442, + 16056, 648, + 16200, 508, + 16322, 369, + 16719, 586, + 16832, 936, + 16835, 450, + 16969, 702, + 17188, 315, + 17425, 538, + 17680, 395, + 17808, 209, + 17855, 791, + 18054, 1861, + 18122, 471, + 18273, 632, + 18425, 3478, + 18630, 1239, + 18947, 143, + 18948, 2576, + 19051, 264, + 19068, 349, + 19112, 502, + 19303, 1530, + 19502, 836, + 19558, 422, + 19571, 692, + 19667, 1014, + 19685, 569 +}; + const Word16 gp_gamma_1sfr_8b_fx[2 * 256] = /*Q14/Q9 */ { 305, 152, diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 43384b6f0..c5f5a5e0c 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -337,6 +337,7 @@ extern const Word16 gp_gamma_1sfr_8b_fx[]; extern const Word16 gp_gamma_1sfr_7b_fx[]; extern const Word16 gp_gamma_1sfr_6b_fx[]; extern const Word16 gp_gamma_2sfr_7b_fx[]; +extern const Word16 gp_gamma_4sfr_7b_fx[]; extern const Word16 gp_gamma_2sfr_6b_fx[]; extern const Word16 gp_gamma_3sfr_7b_fx[]; extern const Word16 gp_gamma_3sfr_6b_fx[]; diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 524a554a1..3b38011be 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -721,7 +721,7 @@ ivas_error decod_gen_voic_ivas_fx( IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { - gain_dec_lbr_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); + gain_dec_lbr_ivas_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); } ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) { diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c index d65183d81..17abcbfc8 100644 --- a/lib_dec/dec_pit_exc_fx.c +++ b/lib_dec/dec_pit_exc_fx.c @@ -661,7 +661,7 @@ void dec_pit_exc_ivas_fx( * Estimate spectrum tilt and voicing *--------------------------------------------------------------*/ - gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); + gain_dec_lbr_ivas_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 #if 1 // def ADD_LRTD diff --git a/lib_dec/gain_dec_fx.c b/lib_dec/gain_dec_fx.c index e56c3294e..0142a6179 100644 --- a/lib_dec/gain_dec_fx.c +++ b/lib_dec/gain_dec_fx.c @@ -990,6 +990,393 @@ void gain_dec_lbr_fx( return; } +#ifdef IVAS_FLOAT_FIXED +void gain_dec_lbr_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *code_fx, /* i : algebraic excitation Q9 */ + Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes */ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ + const Word16 L_subfr /* i : subfr lenght */ +) +{ + Word16 index, nBits, n_pred, ctype; + Word16 gcode0_fx, aux_fx[10]; + Word32 L_tmp, L_tmp1, L_tmp2; + Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx; + const Word16 *b_fx, *cdbk_fx = 0; + /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt(Ecode); */ + Word16 shift_L_subfr; + shift_L_subfr = 6; + move16(); // for *cdbk_fx + move16(); + if ( GT_16( L_subfr, L_SUBFR ) ) + { + shift_L_subfr = add( shift_L_subfr, 1 ); + } + L_tmp = Dot_product12( code_fx, code_fx, L_subfr, &expg ); + expg = sub( expg, add( 18, shift_L_subfr ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + + expg2 = expg; + move16(); + L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc( L_tmp, &expg ); + + *gain_inov_fx = extract_h( L_shl_sat( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */ + move16(); + + /*-----------------------------------------------------------------* + * select the codebook, size and number of bits + * set the gains searching range + *-----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.gains_mode[shr( i_subfr, shift_L_subfr )]; + move16(); + + ctype = shl( sub( coder_type, 1 ), 1 ); + + /*-----------------------------------------------------------------* + * calculate prediction of gcode + * search for the best codeword + *-----------------------------------------------------------------*/ + test(); + IF( i_subfr == 0 ) + { + b_fx = b_1sfr_fx; + move16(); + n_pred = 2; + move16(); + cdbk_fx = gp_gamma_1sfr_6b_fx; + SWITCH( nBits ) + { + case 8: + { + cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/ + BREAK; + } + case 7: + { + cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/ + BREAK; + } + case 6: + { + cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/ + BREAK; + } + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl( ctype, 12 ); + move16(); + + /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); + gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); + gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */ + + e_tmp = norm_l( L_tmp2 ); + f_tmp = Log2_norm_lc( L_shl( L_tmp2, e_tmp ) ); + e_tmp = sub( expg2, add( 1, e_tmp ) ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/ + + L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 160 ); /*Q13, 20 in Q3*/ + L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q13*/ + + gcode0_fx = round_fx( L_shl( L_tmp, 11 ) ); /* Q8 */ + + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + + L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + /* retrieve the codebook index and calculate both gains */ + /*index = (Word16)get_indice( st_fx,"gain", i_subfr, ACELP_CORE);move16();*/ + index = (Word16) get_next_indice_fx( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult( cdbk_fx[add( shl( index, 1 ), 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); +#else + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); +#endif + move16(); /* Q10 -> Q16*/ + + gc_mem[0] = *gain_code_fx; + move32(); /*Q16*/ + gp_mem[0] = *gain_pit_fx; + move16(); /*Q14*/ + } + ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + b_fx = b_2sfr_fx; + move16(); + n_pred = 4; + move16(); + + cdbk_fx = gp_gamma_1sfr_6b_fx; + SWITCH( nBits ) + { + case 7: + { + cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/ + BREAK; + } + case 6: + { + cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/ + BREAK; + } + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl( ctype, 12 ); + move16(); + + /*aux_fx[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l( gc_mem[0] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux_fx[3] = shr( gp_mem[0], 2 ); /*Q12*/ + move16(); + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16) get_next_indice_fx( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult( cdbk_fx[add( shl( index, 1 ), 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); +#else + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); +#endif + move16(); /* Q10 -> Q16*/ + + gc_mem[1] = *gain_code_fx; + move32(); + gp_mem[1] = *gain_pit_fx; + move16(); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + b_fx = b_3sfr_fx; + move16(); + n_pred = 6; + move16(); + + cdbk_fx = gp_gamma_3sfr_6b_fx; + + if ( EQ_16( nBits, 7 ) ) + { + cdbk_fx = gp_gamma_3sfr_7b_fx; + // PMT("verify if gp_gamma_3sfr_7b_fx is correct") + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl( ctype, 12 ); + move16(); + + /*aux_fx[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l( gc_mem[0] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + e_tmp = norm_l( gc_mem[1] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux_fx[4] = shr( gp_mem[0], 2 ); + move16(); + aux_fx[5] = shr( gp_mem[1], 2 ); + move16(); + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16) get_next_indice_fx( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[shl( index, 1 )]; + move16(); + + L_tmp = L_mult( cdbk_fx[add( shl( index, 1 ), 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ +#else + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ +#endif + move32(); + gc_mem[2] = *gain_code_fx; + move32(); + gp_mem[2] = *gain_pit_fx; + move16(); + } + ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) ) + { + b_fx = b_4sfr_fx; + n_pred = 8; + move16(); + + + cdbk_fx = gp_gamma_4sfr_6b_fx; + + IF( EQ_16( nBits, 7 ) ) + { + cdbk_fx = gp_gamma_4sfr_7b_fx; + // PMT( "verify if gp_gamma_4sfr_7b_fx is correct" ) + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl( ctype, 12 ); + move16(); + + /*aux[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l( gc_mem[0] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + e_tmp = norm_l( gc_mem[1] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + /*aux[4] = (float)log10(gc_mem[2]); + = log2(gc_mem[2])*log10(2);*/ + e_tmp = norm_l( gc_mem[2] ); + f_tmp = Log2_norm_lc( L_shl( gc_mem[2], e_tmp ) ); + e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[2])=16*/ + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + aux_fx[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux_fx[5] = shr( gp_mem[0], 2 ); /*Q12*/ + move16(); + aux_fx[6] = shr( gp_mem[1], 2 ); /*Q12*/ + move16(); + aux_fx[7] = shr( gp_mem[2], 2 ); /*Q12*/ + move16(); + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16) get_next_indice_fx( st_fx, nBits ); + move16(); + *gain_pit_fx = cdbk_fx[shl( index, 1 )]; + move16(); + + L_tmp = L_mult( cdbk_fx[add( shl( index, 1 ), 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); +#else + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); +#endif + move32(); /* Q10 -> Q16*/ + } + + /* *norm_gain_code = *gain_code / *gain_inov; */ + expg = sub( norm_s( *gain_inov_fx ), 1 ); + expg = s_max( expg, 0 ); + + tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); + *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); + move32(); + + return; +} +#endif + /*====================================================================== */ /* FUNCTION : lp_gain_updt_fx() */ /*-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index 1ab53f387..66bd6d691 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -185,6 +185,8 @@ ivas_error ivas_corecoder_dec_reconfig_fx( move16(); nSCE_existing = s_min( nSCE_old, st_ivas->nSCE ); nCPE_existing = s_min( nCPE_old, st_ivas->nCPE ); + st_ivas->nCPE_old = nCPE_existing; + move16(); /* destroy superfluous core coder elements */ FOR( sce_id = st_ivas->nSCE; sce_id < nSCE_old; sce_id++ ) @@ -239,6 +241,8 @@ ivas_error ivas_corecoder_dec_reconfig_fx( nCPE_old = 0; move16(); nCPE_existing = s_min( nCPE_old, st_ivas->nCPE ); + st_ivas->nCPE_old = nCPE_existing; + move16(); } test(); IF( LE_16( st_ivas->nCPE, 1 ) && st_ivas->hMCT != NULL ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 1e67761fd..deaf84d4e 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1475,6 +1475,8 @@ ivas_error ivas_init_decoder_front( move16(); st_ivas->nCPE = 0; move16(); + st_ivas->nCPE_old = 0; + move16(); st_ivas->nchan_transport = -1; move16(); st_ivas->ism_mode = ISM_MODE_NONE; @@ -1886,6 +1888,8 @@ ivas_error ivas_init_decoder_fx( move16(); st_ivas->nCPE = 0; move16(); + st_ivas->nCPE_old = 0; + move16(); st_ivas->nchan_transport = 1; move16(); sce_id = 0; @@ -1909,6 +1913,8 @@ ivas_error ivas_init_decoder_fx( move16(); st_ivas->nCPE = 1; /* in stereo, there is always only one CPE */ move16(); + st_ivas->nCPE_old = 0; + move16(); cpe_id = 0; move16(); @@ -1941,6 +1947,8 @@ ivas_error ivas_init_decoder_fx( move16(); st_ivas->nCPE = 0; move16(); + st_ivas->nCPE_old = 0; + move16(); st_ivas->ism_extmeta_active = -1; move16(); st_ivas->ism_extmeta_cnt = 0; @@ -2269,6 +2277,8 @@ ivas_error ivas_init_decoder_fx( IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) { + st_ivas->nCPE_old = st_ivas->nCPE; + move16(); st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->nchan_ism, 1 ), 1 ) ); move16(); st_ivas->element_mode_init = IVAS_CPE_MDCT; @@ -2444,6 +2454,8 @@ ivas_error ivas_init_decoder_fx( move16(); st_ivas->nCPE = shr( st_ivas->nchan_transport, 1 ); move16(); + st_ivas->nCPE_old = 0; + move16(); st_ivas->element_mode_init = IVAS_CPE_MDCT; move16(); FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) @@ -2481,6 +2493,8 @@ ivas_error ivas_init_decoder_fx( move16(); st_ivas->nCPE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS >> 1; move16(); + st_ivas->nCPE_old = 0; + move16(); st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; move16(); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index a74a7536b..4055bde4c 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1546,6 +1546,7 @@ typedef struct Decoder_Struct /* core-decoder modules */ int16_t nSCE; /* number of total SCEs */ int16_t nCPE; /* number of total CPEs */ + int16_t nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ SCE_DEC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index b4d579650..283b0bacc 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -601,7 +601,7 @@ void decod_gen_2sbfr_ivas_fx( * Estimate spectrum tilt and voicing *--------------------------------------------------------------*/ - gain_dec_lbr_fx( st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gc_mem, gp_mem, 2 * L_SUBFR ); + gain_dec_lbr_ivas_fx( st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gc_mem, gp_mem, 2 * L_SUBFR ); st->tilt_code_fx = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, st->Q_exc, 2 * L_SUBFR, 0 ); move16(); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 1c6e084a4..2e59c9225 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -1402,6 +1402,10 @@ static ivas_error IVAS_DEC_GetTcSamples( /*core_switching_post_dec*/ IF( hCPE->hCoreCoder[n]->hHQ_core != NULL ) { + IF( LT_16( cpe_id, st_ivas->nCPE_old ) ) + { + Scale_sig( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, L_FRAME48k, negate( hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); + } hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda = 0; } } -- GitLab