Loading lib_com/cnst.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading lib_enc/cod_tcx.c +1 −1 Original line number Diff line number Diff line Loading @@ -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 ); } } } Loading lib_enc/gaus_enc_fx.c +494 −1 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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 Loading Loading @@ -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 Loading lib_enc/ivas_cpe_enc.c +2 −4 Original line number Diff line number Diff line Loading @@ -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 ); } Loading lib_enc/ivas_stereo_dft_td_itd.c +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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] ); Loading Loading @@ -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 ) ); } } } Loading Loading
lib_com/cnst.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading
lib_enc/cod_tcx.c +1 −1 Original line number Diff line number Diff line Loading @@ -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 ); } } } Loading
lib_enc/gaus_enc_fx.c +494 −1 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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 Loading Loading @@ -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 Loading
lib_enc/ivas_cpe_enc.c +2 −4 Original line number Diff line number Diff line Loading @@ -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 ); } Loading
lib_enc/ivas_stereo_dft_td_itd.c +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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] ); Loading Loading @@ -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 ) ); } } } Loading