diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 40cc0e36c653e891e7de681372bb4edcdc63358c..bf6e305d157a0c60d9ebd12738fd941cbb03c68c 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1935,7 +1935,7 @@ typedef enum _DCTTYPE #define N_SMC_FEATURES 15 /* number of features */ #define N_SMC_MIXTURES 6 /* number of mixtures */ #define N_PCA_COEF 12 /* number of PCA components */ -#define HALF_N_PCA_COEF_LOG_P12_Q19 5781461//Q19 of (0.5f * N_PCA_COEF *logf( PI2 )) +#define HALF_N_PCA_COEF_LOG_P12_Q18 2890731 //Q18 of (0.5f * N_PCA_COEF *logf( PI2 )) #define SMC_ST_MEAN_FACT 0.5 /* forgetting factor of short-term IIR mean filter */ #define SMC_ST_MEAN_RSHIFT_FACT_FX 1 /* SMC_ST_MEAN_FACT equivalent right shift factor */ diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 370ac69f7b4565b91bb076622ba4bb586058d9bb..aaa7e4e2e13f01ee0207daa1bad4b3d412ba7824 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -144,7 +144,7 @@ void TNSAnalysisStereo_fx( BREAK; } - CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, &hTcxEnc->tnsData[k], NULL ); + CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k], NULL ); } } } diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index 9b91bd505c9273da79cb65a2f25c626463fc1f98..03683dceacecf1333166d2c5a289887391dcbdc9 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -28,6 +28,8 @@ static Word16 cod_2pos_fx( const Word16 ind1, const Word16 ind2, const Word16 si static void gauss2v_fx( BSTR_ENC_HANDLE hBstr, const Word16 h[], const Word16 xn[], const Word16 dn[], Word16 code[], Word16 y1[], Word32 *gain, const Word16 lg, const Word16 shift, const Word16 Q_new, const Word16 nb_bits ); +static void gauss2v_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word16 h[], const Word16 xn[], const Word16 dn[], Word16 code[], Word16 y1[], Word32 *gain, const Word16 lg, const Word16 shift, const Word16 Q_new, const Word16 nb_bits ); + /*-------------------------------------------------------------------* * Gaus_encode * @@ -181,7 +183,7 @@ Word16 gaus_encode_ivas_fx( nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; move16(); - gauss2v_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); + gauss2v_ivas_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); /*----------------------------------------------------------------* * Encode gaussian gain @@ -741,6 +743,497 @@ void gauss2v_fx( return; } +void gauss2v_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 h[], /* i : weighted LP filter impulse response Q15 */ + const Word16 xn[], /* i : target signal Q12 */ + const Word16 dn[], /* i : backward filtered target Q12 */ + Word16 code[], /* o : gaussian excitation Q9 */ + Word16 y1[], /* o : zero-memory filtered gauss. excitation Q8 */ + Word32 *gain, /* o : excitation gain. 32-bit number in Q16 */ + const Word16 lg, /* i : subframe size Q0 */ + const Word16 shift, /* i : Scaling factor Q0 */ + const Word16 Q_new, /* i : Scaling factor Q0 */ + const Word16 nb_bits /* i : nb ob bits per track (max 6) */ +) +{ + Word16 i, j, ind1, ind2; + Word16 nvec, step; + Word32 cor, cora, dotprod; + Word16 enerw; + Word32 eneri, cor2; + Word32 enerw32, cor2w32; + Word16 *cpt1; + Word16 *pt1, *pt2; + Word32 max_val[NMAX + 1]; + Word16 *pos[NMAX + 1]; + Word32 sign[NMAX + 1]; + Word32 ener[NMAX + 1], corr[NMAX + 1], ener1; + Word16 dico2[L_SUBFR * NMAX]; + Word16 exp_num; + Word16 exp_den; + Word16 Num; + Word16 Den; + Word32 GainPortion1; + Word32 GainPortion2; + Word32 cor_abs; + Word16 cor_neg; + Word16 div_result; + Word32 ener_sqrt; + Word32 Portion; + Word16 sign1, sign2; + Word16 enerw_norm, enerw_mantissa; + Word16 cor2w_norm, cor2w_mantissa; + Word16 eneri_norm, eneri_mantissa; + Word16 cor2_norm, cor2_mantissa; + Word16 difference_norm; + Word32 cor32; /* 32-bit intermediate value*/ + Word16 hi1, lo1; + Word16 update_best; + Word16 idx; + Word32 Lc0, Lc1, Lnum, Lden; + Word16 gxx, gcc, index_delta, delta, m_sign, inv_delta; + Word16 hg[190], Gaus_dico2[190]; + Word16 shiftP3; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + /*----------------------------------------------------------------* + * Encode the tilt of gaussian excitation + *----------------------------------------------------------------*/ + + /* Compute spectral tilt of target */ + Lc0 = L_mult( xn[1], xn[1] ); + Lc1 = L_mult( xn[1], xn[0] ); + FOR( i = 2; i < L_SUBFR; i++ ) + { + /* fc0 += xn[i]*xn[i] */ + /* fc1 += xn[i]*xn[i-1] */ +#ifdef BASOP_NOGLOB + Lc0 = L_mac_sat( Lc0, xn[i], xn[i] ); + Lc1 = L_mac_sat( Lc1, xn[i], xn[i - 1] ); +#else + Lc0 = L_mac( Lc0, xn[i], xn[i] ); + Lc1 = L_mac( Lc1, xn[i], xn[i - 1] ); +#endif + } + /* fgxx = fc1/fc0 */ + exp_num = sub( norm_l( Lc1 ), 1 ); + Num = extract_h( L_shl( Lc1, exp_num ) ); + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + Lc0 = L_max( Lc0, 1 ); + exp_den = norm_l( Lc0 ); + Den = extract_h( L_shl( Lc0, exp_den ) ); + gxx = shr( div_s( Num, Den ), sub( exp_num, sub( exp_den, 2 ) ) ); /* Q13 */ + gxx = i_mult2( gxx, m_sign ); /* Apply sign */ + + set16_fx( hg, 0, 190 ); /* Compute spectral tilt of filtered codebook */ + Copy( h, hg, L_SUBFR ); + conv_fx( gaus_dico_fx, hg, Gaus_dico2, 190 ); + + Lc0 = L_mult( Gaus_dico2[1], Gaus_dico2[1] ); + Lc1 = L_mult( Gaus_dico2[1], Gaus_dico2[0] ); + FOR( i = 2; i < 190; i++ ) + { + /* fc0 += fgaus_dico2[i]*fgaus_dico2[i] */ + /* fc1 += fgaus_dico2[i]*fgaus_dico2[i-1] */ + Lc0 = L_mac( Lc0, Gaus_dico2[i], Gaus_dico2[i] ); + Lc1 = L_mac( Lc1, Gaus_dico2[i], Gaus_dico2[i - 1] ); + } + + /* fgcc = fc1/fc0 */ + + exp_num = sub( norm_l( Lc1 ), 1 ); + Num = extract_h( L_shl( Lc1, exp_num ) ); + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + + Lc0 = L_max( Lc0, 1 ); + exp_den = norm_l( Lc0 ); + Den = extract_h( L_shl( Lc0, exp_den ) ); + gcc = shr( div_s( Num, Den ), sub( exp_num, sub( exp_den, 2 ) ) ); /* Q13 */ + gcc = i_mult2( gcc, m_sign ); /* Apply sign */ + + /* fdelta = (1-fgcc*fgxx) / (2*fgcc+fgxx) Compute and quantize spectral tilt modification factor */ + Lnum = L_sub( 134217728L, L_mult( gcc, gxx ) ); /* Q30 */ + Lden = L_mac( L_mult( gxx, 8192 ), gcc, 16384 ); /* Q30 */ + + exp_num = sub( norm_l( Lnum ), 1 ); + Num = extract_h( L_shl( Lnum, exp_num ) ); + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + + Lden = L_max( Lden, 1 ); + exp_den = norm_l( Lden ); + Den = extract_h( L_shl( Lden, exp_den ) ); + +#ifdef BASOP_NOGLOB + delta = shr_o( div_s( Num, Den ), sub( exp_num, exp_den ), &Overflow ); /* Q15 */ +#else /* BASOP_NOGLOB */ + delta = shr( div_s( Num, Den ), sub( exp_num, exp_den ) ); /* Q15 */ +#endif + delta = i_mult2( delta, m_sign ); /* Apply sign */ + /* index_delta = (short)(FAC_DELTA * fdelta) */ + index_delta = shr( delta, SFAC_DELTA ); + + /* index_delta [0,7] */ + index_delta = s_max( index_delta, 0 ); + index_delta = s_min( index_delta, 7 ); + + /* fdelta = STEP_DELTA * (float)index_delta */ + delta = shl( index_delta, 11 ); /* delta in Q15 */ + + IF( delta > 0 ) /* Adapt spectral tilt of initial codebook */ + { + /* Computation of 1 / (1+fdelta*fdelta) */ + inv_delta = inv_delta_tab[sub( index_delta, 1 )]; + move16(); /* Q15 */ + + /* fgaus_dico2[0] = gaus_dico[0] */ + Gaus_dico2[0] = gaus_dico_fx[0]; + move16(); + FOR( i = 1; i < 190; i++ ) + { + /* fgaus_dico2[i] = (gaus_dico[i] - fdelta*gaus_dico[i-1]) / (1 + fdelta*fdelta) */ + Lnum = L_msu( L_deposit_h( gaus_dico_fx[i] ), delta, gaus_dico_fx[i - 1] ); + Gaus_dico2[i] = round_fx( Mpy_32_16_1( Lnum, inv_delta ) ); + move16(); + } + } + ELSE + { + FOR( i = 0; i < 190; i++ ) + { + /* fgaus_dico2[i] = gaus_dico[i] */ + Gaus_dico2[i] = gaus_dico_fx[i]; + move16(); + } + } + + /*----------------------------------------------------------------* + * Initializations + *----------------------------------------------------------------*/ + + ind1 = 0; + move16(); + ind2 = 0; + move16(); + + nvec = shl( 1, nb_bits ); + step = shr( 0x80, nb_bits ); + + /*----------------------------------------------------------------* + * dot product between dn and gaussian codevectors, + * keep NMAX best vectors + *----------------------------------------------------------------*/ + + set32_fx( max_val, 0, NMAX + 1 ); + set32_fx( sign, 0, NMAX + 1 ); + + FOR( i = 0; i < NMAX + 1; i++ ) + { + pos[i] = (Word16 *) Gaus_dico2; + } + + cpt1 = Gaus_dico2; + move16(); + + FOR( i = 0; i < nvec; i++ ) + { + /* Dot product without normalization, because values are compared with each other afterwards. */ + cor = Dot_product( cpt1, dn, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31*/ + cora = L_abs( cor ); + j = NMAX - 1; + move16(); + + DO + { + IF( GE_32( cora, max_val[j] ) ) + { + max_val[j + 1] = max_val[j]; + move32(); /*Q31*/ + pos[j + 1] = pos[j]; + move16(); /*Pointer*/ + sign[j + 1] = sign[j]; + move32(); /*Q31*/ + max_val[j] = cora; + move32(); /*Q31*/ + pos[j] = cpt1; + move16(); /*Pointer*/ + sign[j] = cor; + move32(); /*Q31*/ + } + j--; + } + WHILE( j >= 0 ); + cpt1 += step; + } + + /*----------------------------------------------------------------* + * filter selected vectors + * put sign + * compute energy + *----------------------------------------------------------------*/ + + pt1 = dico2; + move16(); + FOR( i = 0; i < NMAX; i++ ) + { + /* Input vector (pos) Q12, filter coefs in Q15, result in same format as input vector (Q12) */ + conv_fx( pos[i], h, pt1, lg ); + + /* put sign and compute energy */ + IF( sign[i] < 0 ) + { + FOR( j = 0; j < lg; j++ ) + { + pt1[j] = negate( pt1[j] ); + move16(); /*Store into dico2*/ + } + } + ener[i] = Dot_product( pt1, pt1, lg ); /* pt1 points to filtered vector in dico2, in Q12 */ + move32(); /* Result is for Q12 * Q12 with length of 64 (6 bits) + 1 left shift => Q31 */ + corr[i] = Dot_product( pt1, xn, lg ); /* must be equal to sign[i] !! */ + move32(); /* pt1 points into dico2, in Q12. xn is in Q12 */ + /* Result is for Q12 * Q12 with length of 64 (6 bits) + 1 left shift => Q31 */ + pt1 += L_SUBFR; + } + + /*------------------------------------------------------------------------* + * try all combinations of NMAX best vectors + *------------------------------------------------------------------------*/ + + pt1 = dico2; + move16(); + + /* Initial values for search algorithm */ + enerw32 = L_deposit_h( 0x80 ); + cor2w32 = L_deposit_l( -2 ); + enerw_norm = norm_l( enerw32 ); + cor2w_norm = norm_l( cor2w32 ); + cor2w_mantissa = round_fx( L_shl( cor2w32, cor2w_norm ) ); + enerw_mantissa = round_fx( L_shl( enerw32, enerw_norm ) ); + + FOR( i = 0; i < NMAX; i++ ) + { + pt2 = pt1; + move16(); + FOR( j = i; j < NMAX; j++ ) + { + cor32 = L_add( corr[i], corr[j] ); /* Q31 */ + + dotprod = Dot_product( pt1, pt2, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31 */ + + /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ + /* Use ScalingShift to stay aligned with ener[] */ + eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ + eneri = L_add( ener[i], eneri ); + eneri = L_add( ener[j], eneri ); /* Q31 */ + + lo1 = L_Extract_lc( cor32, &hi1 ); + cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ + + cor2_norm = norm_l( cor2 ); + eneri_norm = norm_l( eneri ); +#ifdef BASOP_NOGLOB + cor2_mantissa = round_fx_o( L_shl_o( cor2, cor2_norm, &Overflow ), &Overflow ); + eneri_mantissa = round_fx_o( L_shl_o( eneri, eneri_norm, &Overflow ), &Overflow ); +#else + cor2_mantissa = round_fx( L_shl( cor2, cor2_norm ) ); + eneri_mantissa = round_fx( L_shl( eneri, eneri_norm ) ); +#endif + difference_norm = sub( add( cor2_norm, enerw_norm ), add( cor2w_norm, eneri_norm ) ); + + update_best = 0; + move16(); + + IF( difference_norm > 0 ) + { + if ( GT_32( L_shr( L_mult( cor2_mantissa, enerw_mantissa ), difference_norm ), + L_mult( cor2w_mantissa, eneri_mantissa ) ) ) + { + update_best = 1; + move16(); + } + } + ELSE + { + if ( L_msu_sat( L_shl( L_mult( cor2w_mantissa, eneri_mantissa ), difference_norm ), cor2_mantissa, enerw_mantissa ) < 0 ) // Saturation to be revisited + { + update_best = 1; + move16(); + } + } + IF( update_best != 0 ) + { + cor2w_mantissa = cor2_mantissa; + move16(); + cor2w_norm = cor2_norm; + move16(); + enerw_mantissa = eneri_mantissa; + move16(); + enerw_norm = eneri_norm; + move16(); + ind1 = i; + move16(); + ind2 = j; + move16(); + } + pt2 += L_SUBFR; + } + pt1 += L_SUBFR; + } + + enerw = round_fx( L_shr( L_deposit_h( enerw_mantissa ), enerw_norm ) ); + + /*----------------------------------------------------------------* + * Compute zero-memory filtered gauss. excitation y + *----------------------------------------------------------------*/ + + pt1 = dico2 + ind1 * L_SUBFR; + move16(); /*Pointer arithmetic*/ + pt2 = dico2 + ind2 * L_SUBFR; + move16(); + + shiftP3 = add( shift, 3 ); + FOR( i = 0; i < lg; i++ ) + { + /* Sum of 2 Q12 values, must give a Q1.8 */ + y1[i] = shr( add( pt1[i], pt2[i] ), shiftP3 ); + move16(); /* Compensate for "shift" */ + } + + /*----------------------------------------------------------------* + * signs of vectors + *----------------------------------------------------------------*/ + + sign1 = ( -32768 ); + move16(); + if ( sign[ind1] >= 0 ) + { + sign1 = 32767; + move16(); + } + + sign2 = ( -32768 ); + move16(); + if ( sign[ind2] >= 0 ) + { + sign2 = 32767; + move16(); + } + + /*----------------------------------------------------------------* + * Compute code + *----------------------------------------------------------------*/ + + pt1 = pos[ind1]; + move16(); /* Points to gaussian vector (gaus_dico_fx) in Q12 */ + pt2 = pos[ind2]; + move16(); /* Points to gaussian vector (gaus_dico_fx) in Q12 */ + + /* sign[ind1] and sign[ind2] */ + FOR( i = 0; i < lg; i++ ) + { + /* code[i]=(pt1[i]*sign1 + pt2[i]*sign2) /8 */ + /* Division by 8 (shift by 3) is for scaling (Q12 to Q0.9 output) */ + code[i] = shr( add( mult( pt1[i], sign1 ), mult( pt2[i], sign2 ) ), 3 ); + move16(); + } + + cor = L_add( corr[ind1], corr[ind2] ); + + /*----------------------------------------------------------------* + * Compute index + *----------------------------------------------------------------*/ + + i = (Word16) ( ( pos[ind1] - Gaus_dico2 ) / step ); /* Division by step can be replaced by shift. Pointer arithmetic */ + j = (Word16) ( ( pos[ind2] - Gaus_dico2 ) / step ); /* Division by step can be replaced by shift. Pointer arithmetic */ + + idx = cod_2pos_fx( i, j, sign1, sign2, nvec ); + move16(); + + push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); + push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 ); + + /*----------------------------------------------------------------* + * Find quantized gain + *----------------------------------------------------------------*/ + + /* Divide cor/enerw: intermediate result stored into GainPortion1 */ + cor_neg = 0; + move16(); + if ( cor < 0 ) /* Make Num positive. */ + { + cor_neg = 1; + move16(); + } + cor_abs = L_abs( cor ); + + exp_num = sub( norm_l( cor_abs ), 1 ); + exp_den = norm_s( enerw ); + Num = round_fx( L_shl( cor_abs, exp_num ) ); + Den = shl( enerw, exp_den ); + + GainPortion1 = L_deposit_l( 0 ); /* Unexpected division by zero. Eliminate this gain contribution */ + IF( Den != 0 ) /* Protection against division by zero */ + { + div_result = div_s( Num, Den ); /* Q15 */ + IF( cor_neg != 0 ) + { + div_result = negate( div_result ); /* Retrieve sign */ + } + /* Re-scale to compensate for normalization*/ + GainPortion1 = L_shr( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); + } + + ener1 = Dot_product( xn, xn, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31 */ + + exp_num = sub( norm_s( enerw ), 1 ); + exp_den = norm_l( ener1 ); + Num = shl( enerw, exp_num ); +#ifdef BASOP_NOGLOB + Den = round_fx_sat( L_shl_sat( ener1, exp_den ) ); +#else + Den = round_fx( L_shl( ener1, exp_den ) ); +#endif + GainPortion2 = L_deposit_l( 0 ); /* Unexpected division by zero. Eliminate this gain contribution */ + IF( Den != 0 ) /* Protection against division by zero */ + { + div_result = div_s( Num, Den ); /* Q15 */ + + /* Re-scale to compensate for normalization*/ +#ifdef BASOP_NOGLOB + GainPortion2 = L_shr_sat( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); +#else + GainPortion2 = L_shr( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); +#endif + } + +#ifdef BASOP_NOGLOB + ener_sqrt = Isqrt( L_shl_sat( GainPortion2, 1 ) ); /* Make value a Q16 prior to division (align on power of 4) */ +#else + ener_sqrt = Isqrt( L_shl( GainPortion2, 1 ) ); /* Make value a Q16 prior to division (align on power of 4) */ +#endif + ener_sqrt = L_shr( ener_sqrt, 8 ); /* Left-shift Q23 result to make a Q15 result */ + + Portion = Mult_32_16( GainPortion1, 19661 ); /* Performs GainPortion1*.6 */ + Portion = Madd_32_16( Portion, ener_sqrt, 13107 ); /* Performs ener_sqrt*.4 */ + + /* Gain must be output in a 32-bit variable as a Q16 */ + /* Compensate for Q_new */ +#ifdef BASOP_NOGLOB + *gain = L_shl_o( Portion, sub( 13, Q_new ), &Overflow ); +#else + *gain = L_shl( Portion, sub( 13, Q_new ) ); +#endif + move32(); + + return; +} /*---------------------------------------------------------------------* * Put selected codevector positions and signs into quantization index diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 0c33b08b505f9263397475b2f3b9647b9bc45907..be6223e23763c37e287b9616956c4879468d2bcf 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -1025,12 +1025,10 @@ ivas_error ivas_cpe_enc_fx( } } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - FOR( int i = 0; i < CPE_CHANNELS; i++ ) + FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { - Copy_Scale_sig_16_32( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], Q16 + Q1, L_INP_12k8 ); + Copy_Scale_sig_16_32( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], L_INP_12k8, Q16 + Q1 ); } -#endif stereo_dft_enc_res_fx( hCPE->hStereoDft, old_inp_12k8_fx[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits ); } diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c index 6a60af2c063ba382a99591a3f689c84817075eda..b997495be50c065ab637383c80e992e112cdd5c5 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd.c @@ -344,6 +344,7 @@ void stereo_td_itd_fx( Word16 itd, itd_max; Word16 shift_input[L_FRAME48k]; Word16 shift_mem[L_FRAME48k]; + Word16 q_shift_mem; Word16 *mdct_mem[CPE_CHANNELS]; // Word16 q_mdct_mem[CPE_CHANNELS]; Word16 q_shift, q_new_shift; @@ -452,12 +453,16 @@ void stereo_td_itd_fx( /*shift past part*/ Copy( input_mem[ch] + shift[ch], shift_mem, size_ovl - shift[ch] ); Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] ); + q_shift_mem = sts[ch]->q_inp; + move16(); } ELSE { /*shift past part*/ Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] ); Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] ); + q_shift_mem = sts[ch]->q_inp; + move16(); } /*shift current part*/ Copy( sts[ch]->input_fx + shift[ch], shift_input, input_frame - shift[ch] ); @@ -491,7 +496,9 @@ void stereo_td_itd_fx( ELSE { Copy( shift_mem, mdct_mem[ch], input_frame ); - Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, *q_input_mem ) ); + sts[ch]->q_old_inp = q_new_shift; + move16(); + Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); } } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index d7c0a9bc6a9de6e8f9301d52bcce2fcd15d44115..c587b96a64699d04d81e1cd79fc277461b6cff40 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1585,8 +1585,9 @@ void E_ACELP_innovative_codebook_fx( void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + const Word16 pSpectrum_e, + STnsData *pTnsData, /* o : TNS data struct */ + Word16 *predictionGain /* o : TNS prediction gain Q7*/ ); /** Detect TNS parameters. diff --git a/lib_enc/rom_enc.c b/lib_enc/rom_enc.c index aabc7deefae8579778101ee7e4615ecdb18b95bd..099940620cf6418683b6b04a2ceaccc3ec8d5e2b 100644 --- a/lib_enc/rom_enc.c +++ b/lib_enc/rom_enc.c @@ -310,13 +310,8 @@ const Word32 means_speech_fx[N_SMC_MIXTURES*N_PCA_COEF] = 401886, 142397, -185738, 101340, -281425, -159212, -106902, }; const Word32 log_det_chol_speech_fx[N_SMC_MIXTURES] = -{//Q19 - 3408173, - 3068506, - 2925146, - 3487906, - 2491427, - 2798882, +{//Q18 + 1704087, 1534253, 1462573, 1743953, 1245714, 1399441 }; const Word32 prec_chol_speech_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { @@ -396,13 +391,8 @@ const Word32 means_music_fx[N_SMC_MIXTURES*N_PCA_COEF] = -254348, -119888, 187975, 89841, -1729, -280392, 30281, }; const Word32 log_det_chol_music_fx[N_SMC_MIXTURES] = -{//Q19 - 1696729, - 1843978, - 2975523, - 1507561, - -1171774, - 4174141, +{//Q18 + 848365, 921989, 1487762, 753781, -585887, 2087071, }; const Word32 prec_chol_music_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { @@ -482,13 +472,8 @@ const Word32 means_noise_fx[N_SMC_MIXTURES*N_PCA_COEF] = -566101, 252900, 1677892, -314852, 1285163, 84872, -242426, }; const Word32 log_det_chol_noise_fx[N_SMC_MIXTURES] = -{//Q19 - 6227573, - 6829164, - 6727211, - 3722206, - 6943115, - 6238179, +{//Q18 + 3113787, 3414582, 3363606, 1861103, 3471558, 3119090 }; const Word32 prec_chol_noise_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index fc0278233b19e487ce2827f4c9448fd1ae58326d..25d35c7d11206c03007433127a74d080bda715c9 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -32,7 +32,7 @@ #define LOG_PROB_CONST 11292 /*0.5f * N_FEATURES * LOG_PI2 in Q10 */ #define DLP_BIAS 0.138121f -#define DLP_BIAS_FX 72415 /*Q19*/ +#define DLP_BIAS_FX 36208 /*Q18*/ #define TON_ALPHA_FX 31130 /* 0.95f in Q15 */ #define THR_MASS_MAX_FX 3565158 /* 0.85f in Q22 */ @@ -69,30 +69,15 @@ static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 la static void order_spectrum_fx( Word16 *vec, Word16 len ); static void detect_sparseness_fx( Encoder_State *st_fx, const Word16 localVAD_HE_SAD, const Word16 voi_fv ); -// Q19 +// Q18 Word32 log_weights_speech_compute[N_SMC_MIXTURES] = { - -1156091, - -966805, - -946740, - -936304, - -758939, - -946469, + -578045, -483403, -473370, -468152, -379470, -473234 }; Word32 log_weights_music_compute[N_SMC_MIXTURES] = { - -973594, - -1045660, - -631047, - -859997, - -1551963, - -954511, + -486797, -522830, -315523, -429999, -775981, -477255 }; Word32 log_weights_noise_compute[N_SMC_MIXTURES] = { - -879882, - -1153486, - -538486, - -1290903, - -1058455, - -1084391, + -439941, -576743, -269243, -645452, -529228, -542196 }; /*---------------------------------------------------------------------* * speech_music_clas_init_fx() @@ -2297,19 +2282,19 @@ Word16 ivas_smc_gmm_fx( lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - ps_fx[m] = L_sub( L_sub( L_shr( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), 1 ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 / 2 ); // Q18 + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pm_fx[m] = L_sub( L_sub( L_shr( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), 1 ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 / 2 ); // Q18 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pn_fx[m] = L_sub( L_sub( L_shr( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), 1 ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 / 2 ); // Q18 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } @@ -2324,14 +2309,17 @@ Word16 ivas_smc_gmm_fx( move32(); } - hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 12 ) ); // Q7 - hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 12 ) ); // Q7 - hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 12 ) ); // Q7 + hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q7 + hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q7 + hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 + move16(); + move16(); + move16(); /* determine HQ Generic speech class */ IF( st->hHQ_core != NULL ) { - IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q18 ) ) ) + IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q17 ) ) ) { st->hHQ_core->hq_generic_speech_class = 1; } @@ -2360,6 +2348,7 @@ Word16 ivas_smc_gmm_fx( ELSE { dlp_fx = L_add( L_sub( lpm_fx, lps_fx ), DLP_BIAS_FX ); + dlp_fx = L_shl( dlp_fx, 1 ); // Q19 IF( GT_32( dlp_fx, 15728640 ) ) /*30.0f in Q19*/ { @@ -2540,9 +2529,9 @@ Word16 ivas_smc_gmm_fx( temp32 = L_add( temp32, Dot_product( &w_spmus_fx[hSpMusClas->sp_mus_state - 1][1], hSpMusClas->past_dlp_fx, sub( HANG_LEN, 1 ) ) ); move16(); /* entry state -> final decision is calculated based on weighted average of past non-binary decisions */ - IF( GT_32( temp32, L_shl( 2, 25 ) ) ) + IF( GT_32( temp32, 2 << 25 ) ) { - IF( GT_32( dlp_fx, L_shl( 2, 19 ) ) ) + IF( GT_32( dlp_fx, 2 << 19 ) ) { dec = 2; } diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index 9790bbae23e59b711aff1559f789e2d700f3eb1f..34d23e22b2029ab1328323629c595b6da894c843 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -16,7 +16,7 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#define HLM_MIN_NRG ( 32768.0f * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) ) +#define HLM_MIN_NRG_FX 858993459 // ( 32768.0f * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) ) in Q26 /** Get TNS filter parameters from autocorrelation. * @@ -313,113 +313,55 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + const Word32 pSpectrum[], /* i : MDCT spectrum */ + const Word16 pSpectrum_e, + STnsData *pTnsData, /* o : TNS data struct */ + Word16 *predictionGain /* o : TNS prediction gain */ ) { - Word16 idx0, idx1, nSubdivisions, iSubdivisions, spectrumLength; - STnsFilter *pFilter; - Word16 iStartLine, n, i, iEndLine, tmp, headroom, shift, lag; - Word16 facs[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; - Word16 facs_e[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; /* exponents of facs[][] */ - Word16 shifts[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; - Word16 iFilter = 0; - move16(); + Word32 norms[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; + Word16 norms_exp[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; + Word16 i, iFilter, idx0, idx1, nSubdivisions, iSubdivisions, spectrumLength; + Word16 iStartLine, iEndLine, lag; + Word16 fac, fac_e, exp; + Word32 rxx[TNS_MAX_FILTER_ORDER + 1]; + Word64 W_tmp; const Word16 *pWindow; - Word32 L_tmp, tmp32; + STnsFilter *pFilter; - /* Calculate norms for each spectrum part */ + FOR( i = 0; i < TNS_MAX_NUM_OF_FILTERS; i++ ) + { + set32_fx( norms[i], 0, MAX_SUBDIVISIONS ); + } + /* Calculate norms for each spectrum part */ FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ ) { -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif idx0 = pTnsConfig->iFilterBorders[iFilter + 1]; move16(); idx1 = pTnsConfig->iFilterBorders[iFilter]; move16(); nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions; move16(); - assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS ); + /* Variable initialization */ + assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS ); FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) { - /* iStartLine = idx0 + (idx1-idx0)*iSubdivisions/nSubdivisions; - iEndLine = idx0 + (idx1-idx0)*(iSubdivisions+1)/nSubdivisions; */ - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); - - tmp = sub( idx1, idx0 ); - iStartLine = imult1616( tmp, iSubdivisions ); - iEndLine = add( iStartLine, tmp ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); - iStartLine = add( iStartLine, idx0 ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); - iEndLine = add( iEndLine, idx0 ); - - /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ - headroom = getScaleFactor32( &pSpectrum[iStartLine], sub( iEndLine, iStartLine ) ); - - /* Calculate norm of spectrum band */ - L_tmp = Norm32Norm( pSpectrum + iStartLine, headroom, sub( iEndLine, iStartLine ), &shift ); - - /* Check threshold HLM_MIN_NRG */ - BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB - tmp32 = L_sub( L_shl_o( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ), &Overflow ), 3277l /*HLM_MIN_NRG Q7*/ ); -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ) ), 3277l /*HLM_MIN_NRG Q7*/ ); -#endif - BASOP_SATURATE_WARNING_ON_EVS; + iStartLine = add( idx0, idiv1616U( i_mult( sub( idx1, idx0 ), iSubdivisions ), nSubdivisions ) ); + iEndLine = add( idx0, idiv1616U( i_mult( sub( idx1, idx0 ), add( iSubdivisions, 1 ) ), nSubdivisions ) ); - /* get pre-shift for autocorrelation */ - tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */ - tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */ - shifts[iFilter][iSubdivisions] = s_min( tmp, headroom ); + /* Variable initialization */ + norms_exp[iFilter][iSubdivisions] = pSpectrum_e; move16(); - - /* calc normalization factor */ - facs[iFilter][iSubdivisions] = 0; - move16(); - facs_e[iFilter][iSubdivisions] = 0; - move16(); - - if ( tmp32 > 0 ) - { - facs[iFilter][iSubdivisions] = 0x7FFF; - move16(); /* normalization not needed for one subdivision */ - } - - test(); - IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) ) - { - move16(); - facs_e[iFilter][iSubdivisions] = shl( sub( tmp, shifts[iFilter][iSubdivisions] ), 1 ); - move16(); - tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ - L_tmp = L_shl_sat( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ - - /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ - move16(); - facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 */ - } + norms[iFilter][iSubdivisions] = sum2_32_exp_fx( pSpectrum + iStartLine, sub( iEndLine, iStartLine ), &norms_exp[iFilter][iSubdivisions], 8 ); // norms_exp[iFilter][iSubdivisions] + move32(); } } + /* Calculate normalized autocorrelation for spectrum subdivision and get TNS filter parameters based on it */ FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ ) { -#define RXX_E ( 3 ) - Word32 rxx[TNS_MAX_FILTER_ORDER + 1]; - Word16 tmpbuf[350]; - - set32_fx( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); - idx0 = pTnsConfig->iFilterBorders[iFilter + 1]; move16(); idx1 = pTnsConfig->iFilterBorders[iFilter]; @@ -428,82 +370,57 @@ void CalculateTnsFilt_fx( pFilter = pTnsData->filter + iFilter; nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions; move16(); - FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) - { - IF( facs[iFilter][iSubdivisions] == 0 ) - { - BREAK; - } - - - /* iStartLine = idx0 + (idx1-idx0)*iSubdivisions/nSubdivisions; - iEndLine = idx0 + (idx1-idx0)*(iSubdivisions+1)/nSubdivisions; */ - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); - - iStartLine = imult1616( spectrumLength, iSubdivisions ); - iEndLine = add( iStartLine, spectrumLength ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); - iStartLine = add( iStartLine, idx0 ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); - iEndLine = add( iEndLine, idx0 ); - - - move16(); - shift = shifts[iFilter][iSubdivisions]; - - move16(); - pWindow = tnsAcfWindow_fx; - n = sub( iEndLine, iStartLine ); - assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); - FOR( i = 0; i < n; i++ ) - { - tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i], shift ) ); - move16(); - } + set32_fx( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); /* WMOPS: This initialization is required */ - FOR( lag = 0; lag <= pTnsConfig->maxOrder; lag++ ) + /* Variable initialization */ + test(); + FOR( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && ( L_shr_sat( norms[iFilter][iSubdivisions], sub( 6, norms_exp[iFilter][iSubdivisions] ) ) > HLM_MIN_NRG_FX ); iSubdivisions++ ) + { + test(); + fac = BASOP_Util_Divide3232_Scale( 1, norms[iFilter][iSubdivisions], &fac_e ); + fac_e = add( sub( Q31, norms_exp[iFilter][iSubdivisions] ), fac_e ); + iStartLine = add( idx0, idiv1616U( i_mult( spectrumLength, iSubdivisions ), nSubdivisions ) ); + iEndLine = add( idx0, idiv1616U( i_mult( spectrumLength, add( iSubdivisions, 1 ) ), nSubdivisions ) ); + pWindow = tnsAcfWindow_fx; // Q15 + + /* For additional loop condition */ + /* Variable initialization */ + FOR( lag = 1; lag <= pTnsConfig->maxOrder; lag++ ) { - n = sub( sub( iEndLine, lag ), iStartLine ); - - L_tmp = L_deposit_l( 0 ); - FOR( i = 0; i < n; i++ ) + W_tmp = 0; + move64(); + FOR( i = 0; i < iEndLine - iStartLine - lag; i++ ) { -#ifdef BASOP_NOGLOB - L_tmp = L_mac0_sat( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#else - L_tmp = L_mac0( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#endif + W_tmp = W_mac_32_32( W_tmp, pSpectrum[iStartLine + i], pSpectrum[iStartLine + lag + i] ); } - - if ( lag != 0 ) - L_tmp = Mpy_32_16_1( L_tmp, *pWindow++ ); - - L_tmp = Mpy_32_16_1( L_tmp, facs[iFilter][iSubdivisions] ); - L_tmp = L_shl( L_tmp, facs_e[iFilter][iSubdivisions] ); - - rxx[lag] = L_add( rxx[lag], L_tmp ); + exp = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, exp ); + exp = sub( shl( pSpectrum_e, 1 ), exp ); + W_tmp = W_mult_32_32( L_mult( fac, ( *pWindow ) ), W_extract_h( W_tmp ) ); // exp + fac_e + rxx[lag] = L_add( rxx[lag], W_extract_h( W_shl( W_tmp, sub( add( fac_e, exp ), 2 ) ) ) ); // Q29 move32(); + pWindow++; } } IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */ { + // To be checked + rxx[0] = L_shl( pTnsConfig->pTnsParameters[iFilter].nSubdivisions, Q29 ); // Q29 + move32(); pFilter->spectrumLength = spectrumLength; move16(); /* Limit the maximum order to spectrum length/4 */ GetFilterParameters( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); } } - if ( predictionGain ) + + IF( predictionGain ) { assert( pTnsConfig->nMaxFilters == 1 ); - move16(); *predictionGain = pTnsData->filter->predictionGain; + move16(); } return;