diff --git a/lib_com/ACcontextMapping.c b/lib_com/ACcontextMapping.c index 07637ff320105e2b3401795614086daec85f97ce..54f5e18feee3490e5829aaee85b9d1dc82b0d809 100644 --- a/lib_com/ACcontextMapping.c +++ b/lib_com/ACcontextMapping.c @@ -47,6 +47,7 @@ *-------------------------------------------------------------------*/ /*! r: index of next coefficient */ +#ifndef IVAS_FLOAT_FIXED int16_t get_next_coeff_mapped_ivas( int16_t ii[2], /* i/o: coefficient indexes */ int32_t *pp, /* o : peak(1)/hole(0) indicator */ @@ -64,6 +65,28 @@ int16_t get_next_coeff_mapped_ivas( return hm_cfg->indexBuffer[*idx]; } +#else +Word16 get_next_coeff_mapped_ivas( + Word16 ii[2], /* i/o: coefficient indexes */ + Word32 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +) +{ + UWord32 p; + + p = s_and( sub( ii[1], hm_cfg->numPeakIndices ), sub( hm_cfg->indexBuffer[ii[1]], hm_cfg->indexBuffer[ii[0]] ) ); + p >>= sub( sizeof( p ) * 8, 1 ); + *pp = p; + move32(); + *idx = ii[p]; + move16(); + ii[p] = add( ii[p], 1 ); + move16(); + + return hm_cfg->indexBuffer[*idx]; +} +#endif /*-------------------------------------------------------------------* diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e5dfef0898627f9e1e417be7a96f526631f51fa3..4bcab73ec75e0f13d1bd0a4aa3b6f223b8fe7e65 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1919,6 +1919,7 @@ typedef enum _DCTTYPE #define N_SMC_MIXTURES 6 /* number of mixtures */ #define N_PCA_COEF 12 /* number of PCA components */ #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 */ #define M_LSP_SPMUS 6 /* number of LSPs used in speech/music classifier */ #define NB_BANDS_SPMUS 15 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 65b5e6c503c0d7b700492a3d6fc422bee20684be..27ceb3c0bc7229dc2ebf400e83fa3322c5091298 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -720,7 +720,27 @@ int16_t ivas_smc_gmm( int16_t *high_lpn_flag, /* i/o: sp/mus LPN flag */ const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ ); - +#ifdef IVAS_FLOAT_FIXED +/*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ +Word16 ivas_smc_gmm_fx( + Encoder_State *st, /* i/o: state structure */ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + const Word16 Etot_fx, /* i : total frame energy */ + Word16 lsp_new_fx[M], /* i : LSPs in current frame TODO:For now removing 'const' to avoid warning */ + Word16 cor_map_sum_fx, /* i : correlation map sum (from multi-harmonic anal.) */ + Word32 epsP_fx[M + 1], /* i : LP prediciton error TODO:For now removing 'const' to avoid warning */ + Word32 PS_fx[], /* i : energy spectrum TODO:For now removing 'const' to avoid warning */ + const Word16 non_sta_fx, /* i : unbound non-stationarity */ + const Word16 relE_fx, /* i : relative frame energy */ + Word16 *high_lpn_flag, /* i/o: sp/mus LPN flag */ + const Word16 flag_spitch /* i : flag to indicate very short stable pitch */ + , + Word16 Qfact_PS, + Word16 Q_esp, + Word16 Qfact_PS_past +); +#endif void ivas_smc_mode_selection( Encoder_State *st, /* i/o: encoder state structure */ const int32_t element_brate, /* i : element bitrate */ @@ -2900,11 +2920,6 @@ ivas_error initMdctItdHandling( const int32_t input_Fs /* i : input sampling rate */ ); -ivas_error initMdctItdHandling_fx( - STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const Word32 input_Fs /* i : input sampling rate */ -); - void stereo_mdct_enc_destroy( STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */ ); @@ -3195,10 +3210,12 @@ void parse_stereo_from_bitstream( ); #endif +#ifndef IVAS_FLOAT_FIXED void FindSplitRatio( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ Encoder_State **sts /* i/o: Encoder state structure */ ); +#endif void ComputeSpectrumNoiseMeasure( const float *powerSpec, @@ -3514,6 +3531,20 @@ void v_add_inc_fx( const Word16 y_inc, /* i : increment for vector y[] */ const Word16 N /* i : Vector length */ ); +Word32 logsumexp_fx( + const Word32 x[], /* i : input array x */ + const Word16 x_e, + const Word16 N /* i : number of elements in array x */ +); +Word32 lin_interp32_fx( + const Word32 x, /* i : the value to be mapped */ + const Word32 x1, /* i : source range interval: low end */ + const Word32 y1, /* i : source range interval: high end */ + const Word32 x2, /* i : target range interval: low */ + const Word32 y2, /* i : target range interval: high */ + const Word16 flag_sat, /* i : flag to indicate whether to apply saturation */ + Word16 *Q_io /*i/o : i/o Q factor of the output*/ +); #endif void v_mult_inc( @@ -3622,8 +3653,15 @@ float dot_product_cholesky( Word32 dot_product_cholesky_fx( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ - const Word16 N /* i : vector & matrix size */ + const Word16 N /* i : vector & matrix size */ ); +Word32 dot_product_cholesky_fixed( + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : Cholesky matrix A */ + const Word16 N, /* i : vector & matrix size */ + const Word16 exp_x, + const Word16 exp_A, + Word16 *exp_sum ); #endif #ifdef IVAS_FLOAT_FIXED @@ -3637,6 +3675,14 @@ void v_mult_mat_fx( const Word16 N, /* i : number of rows */ const Word16 C /* i : number of columns */ ); +void v_mult_mat_fixed( + Word32 *y, /* o : the product x*A */ + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : matrix A */ + const Word16 Nr, /* i : number of rows */ + const Word16 Nc, /* i : number of columns */ + Word16 guardbits +); #endif void v_mult_mat( diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6be57ae485f94705241d6e37db15ec78a1b1af96..39e8de6a0665d93195755d8e1746b865a3adeda9 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2445,4 +2445,61 @@ void ivas_ari_encode_14bits_ext_fx( Tastat *s, Word32 symbol, const UWord16 *cum_freq ); + +void ms_inv_mask_processing_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + const int16_t iSubframe, /* i : subframe number */ + const Word32 x_0_fx[], /* i : spectrum 1 */ + const Word32 x_1_fx[], /* i : spectrum 2 */ + Word32 x_inv_0_fx[], /* o : inverse spectrum 1 */ + Word32 x_inv_1_fx[], /* o : inverse spectrum 2 */ + int16_t maxSfb /* i : number of stereo frequency bands */ +); + +void ms_processing_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + const int16_t iSubframe, /* i : subframe number */ + Word32 x_0_fx[], /* i/o: spectrum 1 */ + Word32 x_1_fx[], /* i/o: spectrum 1 */ + Word16 maxSfb /* i : number of stereo frequency bands*/ +); + +void convertToMS_fx( + const int16_t L_frame, /* i : frame length */ + Word32 x0[], /* i/o: mid/left channel coefficients */ + Word32 x1[], /* i/o: side/right channel coefficients */ + const Word32 norm_fac /* i : normalization factor */ +); + +void FindSplitRatio_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Encoder_State **sts /* i/o: Encoder state structure */ +); + +void IGFEncStereoEncoder_fx( + STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ + const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ + const Word32 *mdctSpectrumL_fx, /* i : left spectrum */ + const Word32 *mdctSpectrumR_fx, /* i : right spectrum */ + Word16 q_mdctSpectrum, + Word16 *msMask, /* i/o: MS mask */ + Word16 *igfStereoMode, /* o : IGF stereo mode */ + const Word16 mdct_stereo_mode, /* i : MDCT stereo mode */ + const Word16 isTCX20, /* i : flag for indicating TCX20 */ + const Word16 isTransition /* i : flag for transtition */ +); + +void stereo_coder_tcx_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ + Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + Word16 q_spec ); #endif diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index e42efb441cdc6e4689f084fcc6bd52497b225abb..f579e64fc9bf994b2d2e2207693abb4d63547b74 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -809,6 +809,27 @@ void v_sub_s16_fx( return; } #endif // IVAS_FLOAT_FIXED + + +#ifdef IVAS_FLOAT_FIXED +void v_sub32_fx( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + + FOR( i = 0; LT_16( i, N ); i++ ) + { + y[i] = L_sub( x1[i], x2[i] ); + } + + return; +} +#endif // IVAS_FLOAT_FIXED + void v_sub_s( const int16_t x1[], /* i : Input vector 1 */ const int16_t x2[], /* i : Input vector 2 */ @@ -855,7 +876,8 @@ float dot_product_cholesky( pt_x = x; for ( j = 0; j <= i; j++ ) { - tmp_sum += *pt_x++ * *pt_A++; + float mul = *pt_x++ * *pt_A++; + tmp_sum += mul; } suma += tmp_sum * tmp_sum; @@ -863,8 +885,73 @@ float dot_product_cholesky( return suma; } +#ifdef IVAS_FLOAT_FIXED +Word32 dot_product_cholesky_fixed( + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : Cholesky matrix A */ + const Word16 N, /* i : vector & matrix size */ + const Word16 exp_x, + const Word16 exp_A, + Word16 *exp_sum ) +{ + Word16 i, j; + Word32 suma, tmp_sum, mul; + const Word32 *pt_x, *pt_A; + Word16 mul_exp, tmp_sum_exp; + mul_exp = add( exp_x, exp_A ); + pt_A = A; + suma = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + tmp_sum = 0; + move32(); + tmp_sum_exp = 0; + move16(); + pt_x = x; + FOR( j = 0; j <= i; j++ ) + { + mul = Mpy_32_32( *pt_x++, *pt_A++ ); + tmp_sum = BASOP_Util_Add_Mant32Exp( tmp_sum, tmp_sum_exp, mul, mul_exp, &tmp_sum_exp ); // exp_x+exp_A + } + + suma = BASOP_Util_Add_Mant32Exp( suma, *exp_sum, Mpy_32_32( tmp_sum, tmp_sum ), shl( tmp_sum_exp, 1 ), exp_sum ); + } + + return suma; +} +#endif #ifdef IVAS_FLOAT_FIXED +void v_mult_mat_fixed( + Word32 *y, /* o : the product x*A */ + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : matrix A */ + const Word16 Nr, /* i : number of rows */ + const Word16 Nc, /* i : number of columns */ + Word16 guardbits ) +{ + Word16 i, j; + const Word32 *pt_x, *pt_A; + Word32 tmp_y[MAX_V_MULT_MAT]; + Word32 *pt_y; + + pt_y = tmp_y; + pt_A = A; + + FOR( i = 0; i < Nc; i++ ) + { + pt_x = x; + *pt_y = 0; + FOR( j = 0; j < Nr; j++ ) + { + *pt_y = L_add( *pt_y, L_shr( Mpy_32_32( ( *pt_x++ ), ( *pt_A++ ) ), guardbits ) ); + } + pt_y++; + } + + mvr2r_Word32( tmp_y, y, Nc ); +} Word32 dot_product_cholesky_fx( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ @@ -1045,14 +1132,98 @@ float logsumexp( return logf( sum ) + max_exp; } +#ifdef IVAS_FLOAT_FIXED +Word32 logsumexp_fx( + const Word32 x[], /* i : input array x */ + const Word16 x_e, + const Word16 N /* i : number of elements in array x */ +) +{ + Word32 max_exp, temp32_sub; + Word32 sum, temp32, pow_temp; + Word32 log2_e_fx = 1549082005; // Q30 of log2(e); + Word16 log2_e_fx_e = 1; + move16(); + move16(); + Word16 i; + Word16 pow_e, sum_e = 0; + move16(); + max_exp = x[0]; + move32(); + sum = 0; + move32(); + FOR( i = 1; i < N; i++ ) + { + IF( GT_32( x[i], max_exp ) ) + { + max_exp = x[i]; + move32(); + } + } + FOR( i = 0; i < N; i++ ) + { + temp32_sub = L_sub( x[i], max_exp ); + pow_e = 0; + move16(); + temp32 = Mpy_32_32( log2_e_fx, temp32_sub ); + pow_temp = BASOP_util_Pow2( temp32, add( x_e, log2_e_fx_e ), &pow_e ); + sum = BASOP_Util_Add_Mant32Exp( sum, sum_e, pow_temp, pow_e, &sum_e ); + } + temp32 = L_add( BASOP_Util_Log2( sum ), L_shl( sum_e, Q25 ) ); + temp32 = Mpy_32_32( temp32, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + temp32 = L_add( L_shr( temp32, sub( x_e, 6 ) ), max_exp ); // q = 31-x_e + return temp32; +} +#endif /*---------------------------------------------------------------------* * lin_interp() * * Linearly maps x from source range to the target range *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: mapped output value */ +Word32 lin_interp32_fx( + const Word32 x, /* i : the value to be mapped */ + const Word32 x1, /* i : source range interval: low end */ + const Word32 y1, /* i : source range interval: high end */ + const Word32 x2, /* i : target range interval: low */ + const Word32 y2, /* i : target range interval: high */ + const Word16 flag_sat, /* i : flag to indicate whether to apply saturation */ + Word16 *Q_io /*i/o : i/o Q factor of the output*/ +) +{ + Word32 temp32; + Word32 temp_div; + Word16 temp_e = 0; + Word16 exp_out = 0; + move16(); + move16(); + IF( L_sub( x2, x1 ) == 0 ) + { + return y1; + } + ELSE IF( flag_sat ) + { + IF( GE_32( x, L_max( x1, x2 ) ) ) + { + return GT_32( x1, x2 ) ? y1 : y2; + } + ELSE IF( LE_32( x, L_min( x1, x2 ) ) ) + { + return LT_32( x1, x2 ) ? y1 : y2; + } + } + temp32 = Mpy_32_32( L_sub( x, x1 ), L_sub( y2, y1 ) ); // Qin*2 -31 + temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, L_sub( x2, x1 ), &temp_e ) ); // 31-temp_e + 2*Qin -31 - Qin = Qin-temp_e + temp32 = BASOP_Util_Add_Mant32Exp( y1, sub( 31, *Q_io ), temp_div, sub( 31, sub( *Q_io, temp_e ) ), &exp_out ); // Qin-temp_e + *Q_io = sub( 31, exp_out ); + return temp32; +} + +#endif /*! r: mapped output value */ float lin_interp( const float x, /* i : the value to be mapped */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 7bfe52d3e0231f9fb41ecfeceb579627ced8bd07..54444a92bc031356ebcf3eb972c40d53ec75ee0f 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -372,6 +372,12 @@ void v_sub_s16_fx( Word16 y[], /* o : Output vector that contains vector 1 - vector 2 */ const Word16 N /* i : Vector length */ ); +void v_sub32_fx( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N /* i : Vector length */ +); #endif // IVAS_FLOAT_FIXED /*! r: index of the winning codeword */ @@ -3710,7 +3716,19 @@ void speech_music_classif( int16_t *high_lpn_flag, /* o : sp/mus LPN flag */ const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ ); - +void ivas_find_wsp( + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : length of subframe */ + const Word16 nb_subfr, /* i : number of subframes */ + const Word16 *A_fx, /* i : A(z) filter coefficients */ + Word16 *Aw_fx, /* o : weighted A(z) filter coefficients */ + const Word16 *speech_fx, /* i : pointer to the denoised speech frame */ + const Word16 tilt_fact, /* i : tilt factor */ + Word16 *wsp_fx, /* o : poitnter to the weighted speech frame */ + Word16 *mem_wsp_fx, /* i/o: W(Z) denominator memory */ + const Word16 gamma, /* i : weighting factor */ + const Word16 L_look /* i : look-ahead */ +); void find_wsp( const int16_t L_frame, /* i : length of the frame */ const int16_t L_subfr, /* i : length of subframe */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index c90e50f849c723876ab64bfdad361d0a904c1122..4f0a2cbbc8301c069a13757fe5ca002e0ed687ee 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -5631,6 +5631,14 @@ Word32 dotp_fixed_guarded( const Word32 y[], /* i : vector y[] */ const Word16 n /* i : vector length */ ); + +Word32 dotp_me_fx( + const Word32 x[], /* i : vector x[] */ + const Word32 y[], /* i : vector y[] */ + const Word16 n, /* i : vector length */ + Word16 exp_x, + Word16 exp_y, + Word16 *exp_suma ); #endif void lsf_end_dec_fx( @@ -9172,6 +9180,10 @@ Word32 sum2_f_16_fx( const Word16 *vec, /* i : input vector */ const Word16 lvec /* i : length of input vector */ ); +Word32 sum2_f_16_gb_fx( + const Word16 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word16 gb ); Word16 vq_dec_lvq_ivas_fx( Word16 sf_flag, /* i : safety net flag */ @@ -9252,3 +9264,25 @@ void ivas_mdct_core_reconstruct_fx( void ari_start_encoding_14bits_ivas_fx( Tastat *s ); + +void tcx_scalar_quantization_ivas_fx( + Word32 *x, /* i: input coefficients */ + Word16 x_e, /* i: exponent */ + Word16 *xq, /* o: quantized coefficients */ + Word16 L_frame, /* i: frame length */ + Word16 gain, /* i: quantization gain */ + Word16 gain_e, /* i: quantization gain exponent */ + Word16 offset, /* i: rounding offset (deadzone) */ + Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0 */ + const Word16 alfe_flag ); + +Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS( + Word16 *x, /* Spectral coefficients */ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) */ + Word16 *lastnz_out, + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ + const Word16 target, /* Target bits */ + Word16 *stop, + Word16 mode, + CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ +); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index fe77f49185cc8aa3b197088d25a5d18a34fe780c..5b48dfadabca89c0173ac788ce9193b919d51f9a 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -897,13 +897,6 @@ static void filt_mu_fx( temp = add( temp, *ptrs ); /*Q12 */ #ifdef FIX_729_MISSING_RESCALING sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); -#ifdef DEBUGGING - if ( Overflow ) - { - fprintf( stderr, "Saturation in filt_mu_fx for ga = %d, temp = %d, result = %.2f at frame %d\n\n", ga, temp, (float) ga * temp * 4.0 / 65536.0, frame ); - Overflow = 0; - } -#endif #else sig_out[n] = shl( mult_r( ga, temp ), 1 ); #endif diff --git a/lib_com/tools.c b/lib_com/tools.c index 55d866a3e336a3db7a88de40da7394ddb577b9bf..4b1d12be2c0656823d4462b2c4b1a4dbb4134774 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -197,6 +197,22 @@ Word32 sum2_f_16_fx( return tmp; } +Word32 sum2_f_16_gb_fx( + const Word16 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word16 gb ) +{ + int16_t i; + Word32 tmp; + + tmp = 0; + FOR( i = 0; i < lvec; i++ ) + { + tmp = L_add( tmp, L_shr( L_mult0( vec[i], vec[i] ), gb ) ); + } + + return tmp; +} #endif float sum2_f( const float *vec, /* i : input vector */ @@ -1087,6 +1103,28 @@ Word32 dotp_fixed( } #ifdef IVAS_FLOAT_FIXED +Word32 dotp_me_fx( + const Word32 x[], /* i : vector x[] */ + const Word32 y[], /* i : vector y[] */ + const Word16 n, /* i : vector length */ + Word16 exp_x, + Word16 exp_y, + Word16 *exp_suma ) +{ + Word16 i; + Word32 suma; + Word32 mul; + Word16 mul_exp = add( exp_x, exp_y ); + suma = Mpy_32_32( x[0], y[0] ); + *exp_suma = mul_exp; + FOR( i = 1; i < n; i++ ) + { + mul = Mpy_32_32( x[i], y[i] ); + suma = BASOP_Util_Add_Mant32Exp( suma, *exp_suma, mul, mul_exp, exp_suma ); // exp_x+exp_A + } + + return suma; +} Word32 dotp_fixed_guarded( const Word32 x[], /* i : vector x[] */ const Word32 y[], /* i : vector y[] */ @@ -1128,7 +1166,8 @@ Word32 dotp_fixed_o( *res_q = add( sub( *res_q, log_len ), 1 ); move16(); test(); - WHILE( GT_64( suma, MAX_32 ) || GT_16( *res_q, 31 ) ) + test(); + WHILE( GT_64( suma, MAX_32 ) || LT_64( suma, MIN_32 ) || GT_16( *res_q, 31 ) ) { suma = W_shr( suma, 1 ); *res_q = sub( *res_q, 1 ); diff --git a/lib_enc/ACcontextMapping_enc.c b/lib_enc/ACcontextMapping_enc.c index a83ae0aca6f93e06882f85fdf322c48a86edccf8..0f37e51ded41f98065b81bd6e9cf82cdc36ea635 100644 --- a/lib_enc/ACcontextMapping_enc.c +++ b/lib_enc/ACcontextMapping_enc.c @@ -371,6 +371,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t find_last_nz_pair( const int16_t x[], const int16_t length, @@ -413,6 +414,53 @@ static int16_t find_last_nz_pair( return last_nz; } +#else +static Word16 find_last_nz_pair( + const Word16 x[], + const Word16 length, + const CONTEXT_HM_CONFIG *hm_cfg ) +{ + Word16 last_nz, i; + const Word16 *tmp; + + last_nz = 2; + move16(); + + IF( hm_cfg ) + { + /* mapped kernel */ + tmp = hm_cfg->indexBuffer; + + FOR( i = length; i >= 4; i -= 2 ) + { + test(); + IF( x[tmp[i - 2]] || x[tmp[i - 1]] ) + { + last_nz = i; + move16(); + BREAK; + } + } + } + ELSE + { + /* unmapped kernel */ + + FOR( i = length; i >= 4; i -= 2 ) + { + test(); + IF( x[i - 2] || x[i - 1] ) + { + last_nz = i; + move16(); + BREAK; + } + } + } + + return last_nz; +} +#endif /*-------------------------------------------------------------------* @@ -1011,6 +1059,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( * Range coder bit-estimation *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( int16_t *x, /* Spectral coefficients */ const int16_t nt, /* L - size of spectrum (no. of spectral coefficients) */ @@ -1366,6 +1415,426 @@ int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( return tot_bits2; } } +#else +Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS( + Word16 *x, /* Spectral coefficients */ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) */ + Word16 *lastnz_out, + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ + const Word16 target, /* Target bits */ + Word16 *stop, + Word16 mode, + CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ +) +{ + /* Common variables */ + Word16 a1, b1; + Word16 k, pki, lev1; + UWord16 t; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 bit_estimate_fx; + Word16 bit_estimate_e; + Word16 symbol; + const UWord8 *lookup; + Word32 nbits2_fx; // Q23 + Word16 nbits2_e; // Q23 + + /* Initialization */ + bit_estimate_fx = 2 * ONE_IN_Q29; + bit_estimate_e = 2; + move32(); + nbits2_fx = 0; + nbits2_e = 0; + move32(); + + /* bits to encode lastnz */ + k = 1; + move16(); + + WHILE( LT_16( k, nt / 2 ) ) + { + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ONE_IN_Q30, 1, &bit_estimate_e ); + k = k << 1; + /* check while condition */ + } + + nbits2_fx = bit_estimate_fx; + nbits2_e = bit_estimate_e; + + IF( hm_cfg ) + { + Word16 a1_i, b1_i; + Word16 stop2; + Word16 total_output_bits; + Word16 nt_half; + Word32 c[2], *ctx; + Word32 p1, p2; + Word16 ii[2]; + Word16 idx1, idx2, idx; + Word16 numPeakIndicesOrig = 0, numHoleIndices = 0; /* only to avoid compiler warning */ + move16(); + move16(); + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + rateFlag = 2 << NBITS_CONTEXT; /* Select context-A for higher bitrates */ + move16(); + } + ELSE + { + rateFlag = 0; /* Select context-B for lower bitrates */ + move16(); + } + + nt_half = shr( nt, 1 ); + move16(); + stop2 = 0; + move16(); + c[0] = c[1] = 0; + move32(); + move32(); + + /* Find last non-zero tuple in the mapped domain signal */ + lastnz = find_last_nz_pair( x, nt, hm_cfg ); + + lastnz2 = 2; + move16(); + + /* mapped domain */ + numPeakIndicesOrig = hm_cfg->numPeakIndices; + move16(); + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); + move16(); + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); + + /* Mark hole indices beyond lastnz as pruned */ + FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) + { + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); + move16(); + } + + ii[0] = numPeakIndicesOrig; + move16(); + ii[1] = 0; + move16(); + + p1 = p2 = 0; /* to avoid compilation warnings */ + move32(); + move32(); + + /* Main Loop through the 2-tuples */ + FOR( k = 0; k < lastnz; k += 2 ) + { + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); + + idx = s_min( idx1, idx2 ); + + /* Get context */ + ctx = &c[L_or( p1, p2 )]; + + t = (UWord16) L_add( *ctx, rateFlag ); + IF( LT_16( nt_half, idx ) ) + { + t = add( t, ( 1 << NBITS_CONTEXT ) ); + } + + /* Init current 2-tuple encoding */ + a1 = (Word16) abs( x[a1_i] ); + b1 = (Word16) abs( x[b1_i] ); + lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); + + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[lev1]; /* ESC symbol */ + + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane */ + + ( a1 ) = shr( a1, 1 ); + ( b1 ) = shr( b1, 1 ); + + lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + } + + pki = lookup[lev1]; + + symbol = add( a1, i_mult( A_THRES, b1 ) ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); + + /* Should we truncate? */ + IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) + { + stop2 = 1; + move16(); + + IF( *stop ) + { + BREAK; + } + } + ELSE + { + lastnz2 = add( b1_i, 1 ); + nbits2_fx = bit_estimate_fx; + move32(); + nbits2_e = bit_estimate_e; + move16(); + } + + /* Update context for next 2-tuple */ + IF( EQ_32( p1, p2 ) ) /* peak-peak or hole-hole context */ + { + lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); + + IF( lev1 <= 0 ) + { + t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); + } + ELSE + { + t = add( 13, lev1 ); + } + + *ctx = L_add( imult3216( L_and( *ctx, 0xf ), 16 ), t ); + move32(); + } + ELSE + { + /* mixed context */ + + IF( s_and( idx1, 1 ) ) + { + /* update first context */ + c[p1] = update_mixed_context_ivas( c[p1], (int16_t) abs( x[a1_i] ) ); + move32(); + } + + IF( s_and( idx2, 1 ) ) + { + /* update second context */ + c[p2] = update_mixed_context_ivas( c[p2], (int16_t) abs( x[b1_i] ) ); + move32(); + } + } + + } /*end of the 2-tuples loop*/ + + total_output_bits = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); + + IF( *stop ) + { + total_output_bits = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); + } + + IF( stop2 ) + { + stop2 = total_output_bits; + move16(); + } + + *nEncoded = lastnz2; + move16(); + *stop = stop2; /* If zero, it means no overflow occured during bit-estimation */ + move16(); + *lastnz_out = lastnz; + move16(); + + /* Restore hole indices beyond lastnz */ + FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) + { + hm_cfg->holeIndices[k] = sub( hm_cfg->holeIndices[k], nt ); + move16(); + } + hm_cfg->numPeakIndices = numPeakIndicesOrig; + move16(); + + return round_fx( L_add( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ), ONE_IN_Q14 ) ); + } + ELSE /* if (!hm_cfg) */ + { + Word16 esc_nb, cp, rateQ; + UWord16 s; + Word16 tot_bits2; + Word16 overflow_flag = 0; + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + rateFlag = 2; + move16(); + } + ELSE + { + rateFlag = 0; /* Select context-B for lower bitrates */ + move16(); + } + + t = 0; + move16(); + s = 0; + move16(); + cp = 0; + move16(); + lastnz = 1; + move16(); + lastnz2 = 0; + move16(); + tot_bits2 = 0; + move16(); + + /* Find last non-zero tuple in the mapped domain signal */ + FOR( lastnz = sub( nt, 2 ); lastnz >= 0; lastnz -= 2 ) + { + test(); + IF( ( x[lastnz] != 0 ) || ( x[lastnz + 1] != 0 ) ) + { + BREAK; + } + } + lastnz = add( lastnz, 2 ); + IF( LT_16( lastnz, 2 ) ) + { + lastnz = 2; /* At least one tuple is coded */ + move16(); + } + + lastnz2 = 2; + move16(); + + /* Main Loop through the 2-tuples */ + FOR( k = 0; k < lastnz; k += 2 ) + { + /* Init current 2-tuple encoding */ + a1 = abs_s( x[k] ); + b1 = abs_s( x[k + 1] ); + lev1 = 0; + move16(); + esc_nb = 0; + move16(); + rateQ = add( rateFlag, (Word16) GT_16( k, shr( nt, 1 ) ) ); + + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); + + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane */ + + ( a1 ) = shr( a1, 1 ); + ( b1 ) = shr( b1, 1 ); + + lev1 = add( lev1, 1 ); + esc_nb = s_min( lev1, 3 ); + + /* check while condition */ + } + + pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + + symbol = add( a1, i_mult( A_THRES, b1 ) ); + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); + + /* Should we truncate? */ + IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) /* Overflow occured */ + { + overflow_flag = 1; + move16(); + } + ELSE + { + IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ + { + nbits2_fx = bit_estimate_fx; + nbits2_e = bit_estimate_e; + move32(); + lastnz2 = add( k, 2 ); + } + } + + /* Update context for next 2-tuple */ + IF( LT_16( esc_nb, 2 ) ) + { + cp = add( 1, i_mult( add( a1, b1 ), add( esc_nb, 1 ) ) ); + } + ELSE + { + cp = add( 12, esc_nb ); + } + /*shift old bits and replace last 4 bits*/ + s = ( s << 4 ) + cp; + t = ( s & 0xFF ); + + } /*end of the 2-tuples loop*/ + + tot_bits2 = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); + IF( lastnz2 < lastnz ) /* Overflow occured because unable to code all tuples */ + { + overflow_flag = 1; + move16(); + } + IF( EQ_16( mode, -1 ) ) + { + tot_bits2 = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); + } + IF( overflow_flag == 0 ) /* No overflow */ + { + *stop = 0; + move16(); + } + ELSE /* Overflow */ + { + IF( *stop ){ + *stop = tot_bits2; + move16(); + } + ELSE + { + *stop = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); + move16(); + } +} + +*lastnz_out = lastnz; +move16(); +*nEncoded = lastnz2; +move16(); +/* Safety mechanism to avoid overflow */ +test(); +IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) +{ + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); + } +} + +return tot_bits2; +} +} +#endif /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_bandWise_start() @@ -1373,6 +1842,7 @@ int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( * Range coder - start bandwise bit-estimation *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED int16_t RCcontextMapping_encode2_estimate_bandWise_start( int16_t *x, const int16_t nt, @@ -1427,6 +1897,81 @@ int16_t RCcontextMapping_encode2_estimate_bandWise_start( return (int16_t) hContextMem->bit_estimate; } +#else +Word16 RCcontextMapping_encode2_estimate_bandWise_start( + Word16 *x, + const Word16 nt, + const Word16 target, + HANDLE_RC_CONTEXT_MEM hContextMem ) +{ + Word16 i, k; + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + hContextMem->rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + ELSE + { + hContextMem->rateFlag = 0; + move16(); + } + + hContextMem->bit_estimate_fx = 2; + move32(); + hContextMem->bit_estimate_e = Q31; + move16(); + + + /* Init */ + hContextMem->nt_half = shr( nt, 1 ); + move16(); + + /* bits to encode lastnz */ + k = 1; + move16(); + + WHILE( LT_16( k, hContextMem->nt_half ) ) + { + hContextMem->bit_estimate_fx = L_add( hContextMem->bit_estimate_fx, 1 ); + move32(); + + k = shl( k, 1 ); + /* check while condition */ + } + + /* bits to encode lastnz */ + hContextMem->nbits_old = extract_l( hContextMem->bit_estimate_fx ); + move16(); + + hContextMem->ctx = 0; + move16(); + hContextMem->lastnz = 2; + move16(); + + /* Find last non-zero tuple */ + + FOR( i = nt; i >= 4; i -= 2 ) + { + test(); + IF( x[i - 2] != 0 || x[i - 1] != 0 ) + { + hContextMem->lastnz = i; + move16(); + break; + } + } + Word16 tmp2 = extract_l( hContextMem->bit_estimate_fx ); + Word16 tmp = norm_l( hContextMem->bit_estimate_fx ); + hContextMem->bit_estimate_e = sub( Q31, tmp ); + move16(); + hContextMem->bit_estimate_fx = L_shl( hContextMem->bit_estimate_fx, tmp ); + move32(); + + return tmp2; +} +#endif /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_bandWise() @@ -1434,6 +1979,7 @@ int16_t RCcontextMapping_encode2_estimate_bandWise_start( * Range coder - bandwise bit-estimation *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED int16_t RCcontextMapping_encode2_estimate_bandWise( int16_t *x, const int16_t start_line, @@ -1515,3 +2061,94 @@ int16_t RCcontextMapping_encode2_estimate_bandWise( return bandBits; } +#else +Word16 RCcontextMapping_encode2_estimate_bandWise( + Word16 *x, + const Word16 start_line, + const Word16 end_line, + HANDLE_RC_CONTEXT_MEM hContextMem ) +{ + Word16 a1, b1, a1_i, b1_i; + Word16 k, pki, lev1; + UWord16 t; + Word16 bandBits = 0; + move16(); + Word16 total_output_bits; /* No. of bits after finalization */ + Word16 symbol; + const UWord8 *lookup; + Word16 idx; + + /* Main Loop through the 2-tuples */ + /*hContextMem->nt_half = end_line >> 1;*/ + FOR( k = start_line; k < min( hContextMem->lastnz, end_line ); k += 2 ) + { + a1_i = k; + move16(); + b1_i = add( k, 1 ); + + idx = k; + move16(); + + /* Get context */ + t = add( hContextMem->ctx, hContextMem->rateFlag ); + t = add( t, GE_16( hContextMem->nt_half, idx ) ? 0 : ( 1 << NBITS_CONTEXT ) ); + + /* Init current 2-tuple encoding */ + a1 = abs_s( x[a1_i] ); + b1 = abs_s( x[b1_i] ); + lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* Signs Bits */ + hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, Q1, &hContextMem->bit_estimate_e ); + hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, Q1, &hContextMem->bit_estimate_e ); + + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[lev1]; + hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], Q8, &hContextMem->bit_estimate_e ); + hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, 2 * ONE_IN_Q29, Q2, &hContextMem->bit_estimate_e ); /* Add the 2 LSB bits that were shifted out */ + // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; + // hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ + + ( a1 ) = shr( a1, 1 ); + ( b1 ) = shr( b1, 1 ); + + lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + /* check while condition */ + } + + pki = lookup[lev1]; + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol */ + hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], Q8, &hContextMem->bit_estimate_e ); + // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; + + /* Update context */ + lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); + + IF( lev1 <= 0 ) + { + t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); + } + ELSE + { + t = add( 13, lev1 ); + } + + hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); + + } /*end of the 2-tuples loop*/ + total_output_bits = round_fx( L_shr( hContextMem->bit_estimate_fx, sub( Q15, hContextMem->bit_estimate_e ) ) ); + // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); + + bandBits = sub( total_output_bits, hContextMem->nbits_old ); + hContextMem->nbits_old = total_output_bits; + move16(); + + return bandBits; +} +#endif diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index 74a0f62e67d3285d1ef2d86a4eb45bbe1ea77084..e84ed8f3af6ce3e1b0130262e614852204e70674 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -257,6 +257,10 @@ static void init_tcx( /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ hTcxEnc->spectrum[0] = hTcxEnc->spectrum_long; hTcxEnc->spectrum[1] = hTcxEnc->spectrum_long + N_TCX10_MAX; +#ifdef IVAS_FLOAT_FIXED + hTcxEnc->spectrum_fx[0] = hTcxEnc->spectrum_long_fx; + hTcxEnc->spectrum_fx[1] = hTcxEnc->spectrum_long_fx + N_TCX10_MAX; +#endif init_tcx_cfg( st->hTcxCfg, total_brate, st->sr_core, st->input_Fs, st->L_frame, st->bwidth, hTcxEnc->L_frameTCX, st->fscale, st->encoderLookahead_enc, st->encoderLookahead_FB, st->preemph_fac_flt, st->tcxonly, st->rf_mode, st->igf, st->hIGFEnc != NULL ? st->hIGFEnc->infoStopFrequency : 0, st->element_mode, st->ini_frame, MCT_flag ); diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 2043d082f958035427f2ab5121333b7ec2dc1619..aa3bd7fd691399094947cc9839cdb6fccdfcb4f8 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -4,14 +4,14 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" #include "rom_com.h" -//#include "basop_mpy.h" +// #include "basop_mpy.h" #include #include "prot_fx1.h" /* Function prototypes */ #include "prot_fx2.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "prot.h" /*-------------------------------------------------------------------* * Local constants @@ -34,6 +34,7 @@ /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ #define LP_NOISE_LV 5 /* LP_NOISE level */ + #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ #define MAX_BRATE_DTX_IVAS IVAS_64k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ @@ -42,7 +43,511 @@ *-------------------------------------------------------------------*/ static void update_SID_cnt( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, const Word16 Opt_AMR_WB ); +/*==================================================================================*/ +/* FUNCTION : dtx_ivas_fx() */ +/*----------------------------------------------------------------------------------*/ +/* PURPOSE : Discontinuous transmission operation */ +/*----------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Encoder_State_Fx) st_fx : encoder state structure */ +/* _ (Word16) vad : vad flag Q0 */ +/* _ (Word16[]) speech_fx : Pointer to the speech frame qSpeech */ +/* _ (Word16) qSpeech : speech buffer qformat value */ +/* _ (Word16*) qener : frame_ener/lt_ener_voiced/lt_ener_noise buf qformat */ +/*----------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) qener : frame_ener/lt_ener_voiced/lt_ener_noise buf qformat */ +/* _ (Encoder_State_Fx) st_fx : encoder state structure */ +/*----------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==================================================================================*/ +void dtx_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word16 vad, /* i : vad flag for DTX */ + const Word16 speech[] /* i : Pointer to the speech frame */ + +) +{ + Word16 alpha; + Word32 L_tmp; + DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; + TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; + + Word16 last_br_cng_flag, last_br_flag, br_dtx_flag; + + IF( st_fx->dtx_sce_sba != 0 ) + { + last_br_cng_flag = 1; + last_br_flag = 1; + br_dtx_flag = 1; + move16(); + move16(); + move16(); + } + ELSE + { + /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + + last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + br_dtx_flag = 0; + move16(); + } + /* Initialization */ + IF( st_fx->ini_frame == 0 ) + { + st_fx->active_fr_cnt_fx = CNG_TYPE_HO; + move16(); + + st_fx->cng_type = FD_CNG; + move16(); + test(); + if ( ( EQ_16( st_fx->codec_mode, MODE1 ) || st_fx->Opt_AMR_WB ) && EQ_16( st_fx->element_mode, IVAS_SCE ) && EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + st_fx->cng_type = LP_CNG; + move16(); + } + } + test(); + test(); + IF( st_fx->Opt_DTX_ON && vad == 0 && + GT_16( st_fx->ini_frame, 2 ) && /* CNG coding starts after 2 frames */ + st_fx->fd_cng_reset_flag == 0 && + NE_16( st_fx->last_core, AMR_WB_CORE ) && + st_fx->Opt_AMR_WB == 0 ) + { + test(); + test(); + test(); + IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && NE_32( st_fx->last_total_brate_cng, -1 ) && + NE_32( st_fx->last_total_brate_cng, st_fx->total_brate ) && last_br_cng_flag ) + { + st_fx->total_brate = st_fx->last_total_brate_cng; + move32(); + test(); + if ( !( EQ_32( st_fx->total_brate, ACELP_7k20 ) && st_fx->Opt_SC_VBR ) ) + { + st_fx->Opt_SC_VBR = 0; + move16(); + } + st_fx->rf_mode = st_fx->last_rf_mode_cng; + move16(); + st_fx->bwidth = st_fx->last_bwidth_cng; + move16(); + st_fx->codec_mode = st_fx->last_codec_mode_cng; + move16(); + } + test(); + test(); + IF( LE_32( st_fx->last_core_brate, SID_2k40 ) && NE_32( st_fx->last_total_brate, st_fx->total_brate ) && last_br_flag ) + + { + st_fx->total_brate = st_fx->last_total_brate; + move32(); + test(); + if ( !( EQ_32( st_fx->total_brate, ACELP_7k20 ) && st_fx->Opt_SC_VBR ) ) + { + st_fx->Opt_SC_VBR = 0; + move16(); + } + + st_fx->Opt_RF_ON = 0; + move16(); + test(); + test(); + test(); + if ( st_fx->rf_mode && st_fx->rf_fec_offset > 0 && EQ_32( st_fx->total_brate, ACELP_13k20 ) && NE_16( st_fx->bwidth, NB ) ) + { + st_fx->Opt_RF_ON = 1; + move16(); + } + st_fx->rf_mode = st_fx->Opt_RF_ON; + move16(); + st_fx->bwidth = st_fx->last_bwidth; + move32(); + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + st_fx->codec_mode = MODE1; + move16(); + } + ELSE + { + st_fx->codec_mode = get_codec_mode( st_fx->total_brate ); + } + } + } + + /*------------------------------------------------------------------------* + * Select SID or FRAME_NO_DATA frame if DTX is enabled + *------------------------------------------------------------------------*/ + if ( st_fx->dtx_sce_sba == 0 ) + { +#if 0 + br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || + EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, 15 * 256 ) ) ); +#else + br_dtx_flag = ( EQ_16( st_fx->element_mode, EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || + ( NE_16( st_fx->element_mode, EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || + LT_16( st_fx->lp_noise_fx, shl( 15, Q8 ) ); +#endif + } + test(); + test(); + test(); + test(); + IF( st_fx->Opt_DTX_ON && vad == 0 && + GT_16( st_fx->ini_frame, 2 ) && /* CNG coding starts after 2 frames */ + br_dtx_flag && + st_fx->fd_cng_reset_flag == 0 ) + { + /* reset counter */ + st_fx->active_fr_cnt_fx = 0; + move16(); + + IF( st_fx->Opt_AMR_WB ) + { + st_fx->last_total_brate_cng = -1; + st_fx->last_rf_mode_cng = st_fx->rf_mode; + move16(); + } + ELSE + { + st_fx->last_total_brate_cng = st_fx->total_brate; + st_fx->last_bwidth_cng = st_fx->bwidth; + st_fx->last_codec_mode_cng = st_fx->codec_mode; + } + + IF( hDtxEnc->cnt_SID == 0 ) + { + /* this will be a SID frame */ + IF( st_fx->Opt_AMR_WB ) + { + st_fx->core_brate = SID_1k75; + move32(); + } + ELSE + { + st_fx->core_brate = SID_2k40; + move32(); + } + } + ELSE + { + /* this will be a no data frame */ + st_fx->core_brate = FRAME_NO_DATA; + move32(); + } + + test(); + test(); + IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) && NE_16( st_fx->last_core, ACELP_CORE ) && !st_fx->Opt_AMR_WB ) + { + /* force SID frame when switching from HQ core or AMR-WB IO mode into inactive frame in ACELP core when DTX is on */ + st_fx->core_brate = SID_2k40; + move32(); + } + // PMT("dtx_sce_sba code is missing") + IF( ( NE_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->cng_type, FD_CNG ) ) && EQ_16( st_fx->dtx_sce_sba, 1 ) ) + { + st_fx->cng_type = FD_CNG; + move16(); + if ( EQ_16( st_fx->element_mode, EVS_MONO ) && ( EQ_32( st_fx->total_brate, ACELP_9k60 ) || EQ_32( st_fx->total_brate, ACELP_16k40 ) || EQ_32( st_fx->total_brate, ACELP_24k40 ) || EQ_32( st_fx->total_brate, ACELP_48k ) || EQ_32( st_fx->total_brate, HQ_96k ) || EQ_32( st_fx->total_brate, HQ_128k ) ) ) + { + st_fx->codec_mode = MODE2; + move16(); + } + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, ACELP_24k40 ) || ( NE_16( st_fx->element_mode, EVS_MONO ) && LE_32( st_fx->total_brate, ACELP_32k ) ) ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) ) /* at highest bitrates, use exclusively LP_CNG */ + { + test(); + test(); + IF( EQ_16( st_fx->element_mode, EVS_MONO ) && ( EQ_32( st_fx->total_brate, ACELP_9k60 ) || EQ_32( st_fx->total_brate, ACELP_16k40 ) || EQ_32( st_fx->total_brate, ACELP_24k40 ) ) ) + { + st_fx->codec_mode = MODE2; + move16(); + } + } + ELSE + { + st_fx->cng_type = LP_CNG; + move16(); + IF( st_fx->codec_mode == MODE2 ) + { + hTdCngEnc->lp_cng_mode2 = 1; + move16(); + } + st_fx->codec_mode = MODE1; + move16(); + } + } + /* reset the bitstream (IVAS format signalling was already written) */ + IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) + { + reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); + } + } + + /*------------------------------------------------------------------------* + * Reset counters when in active frame (not in SID or FRAME_NO_DATA frame) + *------------------------------------------------------------------------*/ + /* NB core bit rate can be "-1" at startup , so one can not use core_brate_fx <=2400 */ + test(); + test(); + IF( ( NE_32( st_fx->core_brate, SID_2k40 ) ) && ( NE_32( st_fx->core_brate, SID_1k75 ) ) && ( NE_32( st_fx->core_brate, FRAME_NO_DATA ) ) ) + { + IF( hDtxEnc != NULL ) + { + hDtxEnc->cnt_SID = 0; + move16(); + + /* change SID update rate */ + /* first SID update is only 8 (3) frames after the active speech end */ + IF( !st_fx->Opt_AMR_WB ) + { + hDtxEnc->max_SID = FIXED_SID_RATE; + move16(); + } + ELSE + { + hDtxEnc->max_SID = 3; + move16(); /* first SID update is only 3 frames after the active speech end */ + } + + IF( LT_16( hDtxEnc->interval_SID, hDtxEnc->max_SID ) ) + { + hDtxEnc->max_SID = hDtxEnc->interval_SID; + move16(); /* change SID update rate */ + } + + hDtxEnc->cng_cnt = 0; + move16(); /* reset the counter of CNG frames for averaging */ + } + test(); + IF( GE_16( st_fx->active_fr_cnt_fx, CNG_TYPE_HO ) && st_fx->Opt_AMR_WB == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_SCE ) ) + { + Word32 lp_thresh, fd_thresh; + // PMT( "lp_thresh scaling is to be found" ) + test(); + IF( st_fx->Opt_DTX_ON && EQ_16( st_fx->dtx_sce_sba, 1 ) ) + { + lp_thresh = L_shl( 5, Q27 ); + fd_thresh = L_shl( 2, Q27 ); + } + ELSE + + { + lp_thresh = L_shl( 10, Q27 ); + fd_thresh = L_shl( 5, Q27 ); + } + + /*More conservative selection of LP-CNG for SCE*/ + if ( st_fx->cng_type == LP_CNG && ( st_fx->bckr_tilt_lt > lp_thresh ) ) + { + st_fx->cng_type = FD_CNG; + } + else if ( st_fx->cng_type == FD_CNG && ( st_fx->bckr_tilt_lt < fd_thresh ) && ( st_fx->lp_noise > L_shl( 2, Q27 ) ) ) + { + st_fx->cng_type = LP_CNG; + } + } + ELSE + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st_fx->cng_type, LP_CNG ) && ( ( EQ_16( st_fx->input_bwidth, NB ) && GT_32( st_fx->bckr_tilt_lt, 589824l /*9.f Q16*/ ) ) || ( GT_16( st_fx->input_bwidth, NB ) && GT_32( st_fx->bckr_tilt_lt, 2949120l /*45.f Q16*/ ) ) ) ) + { + st_fx->cng_type = FD_CNG; + move16(); + } + ELSE IF( EQ_16( st_fx->cng_type, FD_CNG ) && ( ( EQ_16( st_fx->input_bwidth, NB ) && LT_32( st_fx->bckr_tilt_lt, 131072l /*2.f Q16*/ ) ) || ( GT_16( st_fx->input_bwidth, NB ) && LT_32( st_fx->bckr_tilt_lt, 655360l /*10.f Q16*/ ) ) ) ) + { + st_fx->cng_type = LP_CNG; + move16(); + } + } + st_fx->last_total_brate_cng = -1; + } + ELSE IF( st_fx->Opt_AMR_WB ) + { + st_fx->cng_type = LP_CNG; + move16(); + } + st_fx->active_fr_cnt_fx = add( st_fx->active_fr_cnt_fx, 1 ); + st_fx->active_fr_cnt_fx = s_min( st_fx->active_fr_cnt_fx, 200 ); + } + + /*------------------------------------------------------------------------* + * Update speech and background noise long-term energy + *------------------------------------------------------------------------*/ + IF( hDtxEnc != NULL ) + { + hDtxEnc->frame_ener_fx = L_deposit_l( 0 ); + + IF( st_fx->Opt_DTX_ON ) + { +#if 0 + Q_speech2 = add( shl( Q_speech, 1 ), 7 ); + FOR( j = 0; j < 16; j++ ) + { + L_tmp = L_mult0( *speech, *speech ); + speech++; + FOR( i = 1; i < L_FRAME / 16; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_o( L_tmp, *speech, *speech, &Overflow ); +#else /* BASOP_NOGLOB */ + L_tmp = L_mac0( L_tmp, *speech, *speech ); +#endif /* BASOP_NOGLOB */ + speech++; + } + hDtxEnc->frame_ener_fx = L_add( hDtxEnc->frame_ener_fx, L_shr( L_tmp, Q_speech2 ) ); /*Q(-7) */ + + } +#endif + // hDtxEnc->frame_ener = sum2_f( speech, L_FRAME ); + Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); + // Word16 Q_frame_ener = 2 * Q_speech; + hDtxEnc->frame_ener_fx = sum2_f_16_gb_fx( speech, L_FRAME, guard_bits ); // 2*Q_speech-guard_bits + + /* Active speech (voiced) */ + + IF( EQ_16( st_fx->clas, VOICED_CLAS ) ) + { + alpha = ALPHA_ENER_SLOW_FX; + move16(); + if ( GT_32( hDtxEnc->frame_ener_fx, hDtxEnc->lt_ener_voiced_fx ) ) + { + alpha = ALPHA_ENER_FAST_FX; + move16(); /*Q15 */ + } + + /*st_fx->lt_ener_voiced_fx = alpha * st_fx->lt_ener_voiced_fx + (1.0f-alpha) * st_fx->frame_ener_fx;*/ + L_tmp = L_sub( hDtxEnc->lt_ener_voiced_fx, hDtxEnc->frame_ener_fx ); + L_tmp = Mult_32_16( L_tmp, alpha ); + hDtxEnc->lt_ener_voiced_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); /*2*Q_speech-guard_bits */ + + hDtxEnc->VarDTX_cnt_voiced = add( hDtxEnc->VarDTX_cnt_voiced, 1 ); + + hDtxEnc->VarDTX_cnt_voiced = s_min( hDtxEnc->VarDTX_cnt_voiced, MIN_CNT ); + } + /* Background noise */ + ELSE IF( !st_fx->Opt_AMR_WB ) + { + alpha = ALPHA_ENER_SLOW_FX; + move16(); + if ( LT_32( hDtxEnc->frame_ener_fx, hDtxEnc->lt_ener_noise_fx ) ) + { + alpha = ALPHA_ENER_FAST_FX; + move16(); + } + + /*st_fx->lt_ener_noise_fx = alpha * st_fx->lt_ener_noise_fx + (1.0f-alpha) * st_fx->frame_ener_fx;*/ + L_tmp = L_sub( hDtxEnc->lt_ener_noise_fx, hDtxEnc->frame_ener_fx ); + L_tmp = Mult_32_16( L_tmp, alpha ); + hDtxEnc->lt_ener_noise_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); + move32(); /*2*Q_speech-guard_bits */ + + hDtxEnc->VarDTX_cnt_noise = add( hDtxEnc->VarDTX_cnt_noise, 1 ); + + hDtxEnc->VarDTX_cnt_noise = s_min( hDtxEnc->VarDTX_cnt_noise, MIN_CNT ); + } + } + } + + /* Update of the SID counter */ + update_SID_cnt( hDtxEnc, st_fx->core_brate, st_fx->Opt_AMR_WB ); + + /* Update encoded bandwidth */ + test(); + test(); + IF( st_fx->Opt_DTX_ON && ( st_fx->core_brate == SID_2k40 || st_fx->core_brate == FRAME_NO_DATA ) ) + { + + st_fx->bwidth = st_fx->last_bwidth; + move16(); + test(); + if ( GT_32( st_fx->last_core_brate, SID_2k40 ) && NE_32( st_fx->last_total_brate_cng, -1 ) ) + { + st_fx->bwidth = st_fx->last_bwidth_cng; + move16(); + } + + test(); + test(); + IF( st_fx->Opt_RF_ON && ( EQ_32( st_fx->total_brate, ACELP_13k20 ) ) && ( EQ_16( st_fx->bwidth, NB ) ) ) + { + st_fx->codec_mode = MODE1; + move16(); + reset_rf_indices_fx( st_fx ); + st_fx->Opt_RF_ON = 0; + move16(); + st_fx->rf_mode = 0; + move16(); + } + + test(); + test(); + IF( st_fx->Opt_RF_ON && NE_32( st_fx->total_brate, ACELP_13k20 ) ) + { + reset_rf_indices_fx( st_fx ); + move16(); + st_fx->Opt_RF_ON = 0; + move16(); + st_fx->rf_mode = 0; + } + + /* Set and limit the encoded bandwidth */ + IF( EQ_16( st_fx->codec_mode, MODE2 ) ) + { + Word16 n, bits_frame_nominal; + + UWord16 lsb; + Word16 tmpbandwidthMin; + + Mpy_32_16_ss( st_fx->total_brate, 5243, &L_tmp, &lsb ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + bits_frame_nominal = extract_l( L_shr( L_tmp, 3 ) ); /* Q0 */ + + FOR( n = 0; n < FRAME_SIZE_NB; n++ ) + { + IF( EQ_16( FrameSizeConfig[n].frame_bits, bits_frame_nominal ) ) + { + BREAK; + } + } + if ( n == FRAME_SIZE_NB ) + { + assert( !"Bitrate not supported: not part of EVS" ); + } + tmpbandwidthMin = FrameSizeConfig[n].bandwidth_min; + if ( EQ_16( st_fx->rf_mode, 1 ) ) + { + tmpbandwidthMin = WB; + } + st_fx->bwidth = s_max( s_min( st_fx->bwidth, FrameSizeConfig[n].bandwidth_max ), tmpbandwidthMin ); + } + } + + return; +} /*==================================================================================*/ /* FUNCTION : dtx_fx() */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index fad93012f130ac1cbcbb79d506166f1c0ef56394..d54d787f2d7cbe82ec6c91f557f6a8241dbbab31 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -41,7 +41,9 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot.h" +#include "prot_fx2.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" @@ -1036,7 +1038,19 @@ void FdCngEncodeMDCTStereoSID( /* M/S transform on log envelopes */ if ( is_inp_ms == 0 ) { +#ifndef IVAS_FLOAT_FIXED convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f ); +#else + Word32 ms_ptr_fx[2][NPART]; + Word16 q = s_min( Q_factor_arrL( ms_ptr[0], N ), Q_factor_arrL( ms_ptr[1], N ) ) - 1; + floatToFixed_arrL( ms_ptr[0], ms_ptr_fx[0], q, N ); + floatToFixed_arrL( ms_ptr[1], ms_ptr_fx[1], q, N ); + + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); + + fixedToFloat_arrL( ms_ptr_fx[0], ms_ptr[0], q, N ); + fixedToFloat_arrL( ms_ptr_fx[1], ms_ptr[1], q, N ); +#endif } side_energy = sum2_f( ms_ptr[1], N ); @@ -1125,7 +1139,19 @@ void FdCngEncodeMDCTStereoSID( /* undo M/S */ if ( is_inp_ms == 0 ) { +#ifndef IVAS_FLOAT_FIXED convertToMS( N, ms_ptr[0], ms_ptr[1], 1.0f ); +#else + Word32 ms_ptr_fx[2][NPART]; + Word16 q = s_min( Q_factor_arrL( ms_ptr[0], N ), Q_factor_arrL( ms_ptr[1], N ) ) - 1; + floatToFixed_arrL( ms_ptr[0], ms_ptr_fx[0], q, N ); + floatToFixed_arrL( ms_ptr[1], ms_ptr_fx[1], q, N ); + + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + + fixedToFloat_arrL( ms_ptr_fx[0], ms_ptr[0], q, N ); + fixedToFloat_arrL( ms_ptr_fx[1], ms_ptr[1], q, N ); +#endif } /* Compute gain against original left and right channels */ @@ -1260,7 +1286,19 @@ void FdCngEncodeDiracMDCTStereoSID( } /* M/S transform on log envelopes */ +#ifndef IVAS_FLOAT_FIXED convertToMS( N[0], ms_ptr[0], ms_ptr[1], 0.5f ); +#else + Word32 ms_ptr_fx[2][NPART]; + Word16 q = s_min( Q_factor_arrL( ms_ptr[0], N[0] ), Q_factor_arrL( ms_ptr[1], N[0] ) ) - 1; + floatToFixed_arrL( ms_ptr[0], ms_ptr_fx[0], q, N[0] ); + floatToFixed_arrL( ms_ptr[1], ms_ptr_fx[1], q, N[0] ); + + convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); + + fixedToFloat_arrL( ms_ptr_fx[0], ms_ptr[0], q, N[0] ); + fixedToFloat_arrL( ms_ptr_fx[1], ms_ptr[1], q, N[0] ); +#endif E[0] = sum_f( ms_ptr[0], N[0] ); @@ -1309,7 +1347,18 @@ void FdCngEncodeDiracMDCTStereoSID( gain[1] = gain[0]; /* undo M/S */ +#ifndef IVAS_FLOAT_FIXED convertToMS( NPART, ms_ptr[0], ms_ptr[1], 1.0f ); +#else + q = s_min( Q_factor_arrL( ms_ptr[0], NPART ), Q_factor_arrL( ms_ptr[1], NPART ) ) - 1; + floatToFixed_arrL( ms_ptr[0], ms_ptr_fx[0], q, NPART ); + floatToFixed_arrL( ms_ptr[1], ms_ptr_fx[1], q, NPART ); + + convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + + fixedToFloat_arrL( ms_ptr_fx[0], ms_ptr[0], q, NPART ); + fixedToFloat_arrL( ms_ptr_fx[1], ms_ptr[1], q, NPART ); +#endif /* restore channel noise envelopes */ for ( ch = 0; ch < CPE_CHANNELS; ch++ ) diff --git a/lib_enc/find_wsp.c b/lib_enc/find_wsp.c index d38fd99d8dc2a254cdfc47249842ae50ac5d6cf2..fb9efa29b99a2f63152a77443e44a2f8b40f13cb 100644 --- a/lib_enc/find_wsp.c +++ b/lib_enc/find_wsp.c @@ -39,13 +39,12 @@ #include "cnst.h" #include "prot.h" #include "wmc_auto.h" - +#include "prot_fx2.h" /*-------------------------------------------------------------------* * find_wsp() * * Compute weighted speech used in open-loop pitch search *-------------------------------------------------------------------*/ - void find_wsp( const int16_t L_frame, /* i : length of the frame */ const int16_t L_subfr, /* i : length of subframe */ @@ -93,3 +92,47 @@ void find_wsp( return; } +void ivas_find_wsp( + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : length of subframe */ + const Word16 nb_subfr, /* i : number of subframes */ + const Word16 *A_fx, /* i : A(z) filter coefficients */ + Word16 *Aw_fx, /* o : weighted A(z) filter coefficients */ + const Word16 *speech_fx, /* i : pointer to the denoised speech frame */ + const Word16 tilt_fact, /* i : tilt factor */ + Word16 *wsp_fx, /* o : poitnter to the weighted speech frame */ + Word16 *mem_wsp_fx, /* i/o: W(Z) denominator memory */ + const Word16 gamma, /* i : weighting factor */ + const Word16 L_look /* i : look-ahead */ +) +{ + Word16 *p_Aw_fx, tmp_fx; + Word16 i_subfr; + + + /*-----------------------------------------------------------------* + * Compute weighted A(z) unquantized for subframes + *-----------------------------------------------------------------*/ + weight_a_subfr_fx( nb_subfr, A_fx, Aw_fx, gamma, M ); + + /*-----------------------------------------------------------------* + * Compute weighted speech for all subframes + *-----------------------------------------------------------------*/ + p_Aw_fx = Aw_fx; + for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr ) + { + Residu3_fx( p_Aw_fx, &speech_fx[i_subfr], &wsp_fx[i_subfr], L_subfr, 0 ); + p_Aw_fx += ( M + 1 ); + } + p_Aw_fx -= ( M + 1 ); + + /*-----------------------------------------------------------------* + * Weighted speech computation is extended on look-ahead + *-----------------------------------------------------------------*/ + + deemph_fx( wsp_fx, tilt_fact, L_frame, mem_wsp_fx ); + Residu3_fx( p_Aw_fx, &speech_fx[L_frame], &wsp_fx[L_frame], L_look, 0 ); + tmp_fx = *mem_wsp_fx; + deemph_fx( &wsp_fx[L_frame], tilt_fact, L_look, &tmp_fx ); + return; +} diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 98d86d096d89ba02d1976af3ea30424251843ab2..f0e08363a2e93ea6e4b677edc95beae9c3d3a242 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -277,7 +277,13 @@ ivas_error init_encoder( st->predecision_flag = 0; st->diff_sm = 0; st->energy_sm = 0; - +#ifdef IVAS_FLOAT_FIXED + st->voicing0_sm_fx = 0; + st->voicing_sm_fx = 0; + st->LF_EnergyRatio_sm_fx = ONE_IN_Q7; + st->diff_sm_fx = 0; + st->energy_sm_fx = 0; +#endif set_s( st->pitch, L_SUBFR, 3 ); set_f( st->voicing, 0.0f, 3 ); @@ -488,6 +494,9 @@ ivas_error init_encoder( st->fd_cng_reset_flag = 0; st->cng_type = -1; st->bckr_tilt_lt_flt = 0.f; +#ifdef IVAS_FLOAT_FIXED + st->bckr_tilt_lt = 0; +#endif st->active_cnt = 0; if ( ( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO ) || ( st->element_mode == IVAS_CPE_MDCT && st->Opt_DTX_ON ) ) @@ -497,6 +506,9 @@ ivas_error init_encoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX variables\n" ) ); } dtx_enc_init( st, var_SID_rate_flag, interval_SID ); +#ifdef IVAS_FLOAT_FIXED + dtx_enc_init_fx( st, var_SID_rate_flag, interval_SID ); +#endif } else { @@ -790,6 +802,10 @@ ivas_error init_encoder( /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; +#ifdef IVAS_FLOAT_FIXED + st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; + st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; +#endif set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 48dff1e9c28351952c2f254e2f82875e232bd687..45cce0aedeeebb762e8820099c07807120ed4791 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -44,6 +44,9 @@ #include "wmc_auto.h" #include +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx_enc.h" +#endif /*---------------------------------------------------------------* * Local constants diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 316d279da58dfa538a1ecd179c05bd96c653d2d5..cfd4348cb353a854321eb5e2560c1bed36f7de80 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -1290,7 +1290,7 @@ ivas_error create_cpe_enc_fx( IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && LE_32( element_brate, MAX_MDCT_ITD_BRATE ) && EQ_16( ivas_format, STEREO_FORMAT ) ) { - IF( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) + IF( ( error = initMdctItdHandling( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 65748bfbae9e1cf386c67c7db023c8a8a3fcfbc3..9e7eafdcd5a4e666cc0b8bd054eb28f78ce209c6 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -43,7 +43,10 @@ #include #include "wmc_auto.h" #include - +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx_enc.h" +#include "prot_fx2.h" +#endif /*-----------------------------------------------------------------------------------------* * Function front_vad() @@ -323,8 +326,8 @@ ivas_error front_vad_create_fx( hFrontVad->lp_speech_fx = 23040; /* Initialize the long-term active speech level in dB */ hFrontVad->lp_noise_fx = 0; /* Initialize the long-term noise level in dB */ - set32_fx( hFrontVad->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); - set32_fx( hFrontVad->buffer_12k8_fx, 0, i_mult( 3, shr( L_FRAME, 1 ) ) ); + set16_fx( hFrontVad->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( hFrontVad->buffer_12k8_fx, 0, i_mult( 3, shr( L_FRAME, 1 ) ) ); hFrontVad->mem_preemph_fx = 0; hFrontVad->ini_frame = 0; hFrontVad->hVAD->vad_flag = 1; @@ -384,7 +387,490 @@ void front_vad_destroy( * * Standalone front-VAD module for SPAR *-----------------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error front_vad_spar( + SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ + const float *omni_in, /* i : omnidirectional input signal */ + ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : encoder configuration handle */ + const int16_t input_frame /* i : input frame length */ +) +{ + FRONT_VAD_ENC_HANDLE hFrontVad; + float input[L_FRAME48k]; + int16_t vad_flag_dtx[1]; + float fr_bands[1][2 * NB_BANDS]; + Word32 fr_bands_fx[1][2 * NB_BANDS] = { { 0 } }; + float Etot[1]; + Word16 Etot_fx[1]; + float lf_E[1][2 * VOIC_BINS]; + + int16_t localVAD_HE_SAD[1]; + int16_t vad_hover_flag[1]; + float band_energies[2 * NB_BANDS]; + int16_t high_lpn_flag; + Encoder_State *st; + float tmpN[NB_BANDS], tmpE[NB_BANDS]; + Word32 tmpN_fx[NB_BANDS] = { 0 }; + Word32 tmpE_fx[NB_BANDS] = { 0 }; + float corr_shift; + float dummy, res_energy; + Word16 corr_shift_fx; +#if 1 + + // Word32 res_energy_fx; + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], Aw_fx[NB_SUBFR16k * ( M + 1 )]; + +// Word32 epsP_fx[M + 1]; +// Word16 epsP_h[M + 1]; +// Word16 epsP_l[M + 1]; +// Word16 alw_voicing_fx[2]; +// Word16 lsp_new_fx[M]; +// Word16 lsp_mid_fx[M]; +#endif + float A[NB_SUBFR16k * ( M + 1 )], Aw[NB_SUBFR16k * ( M + 1 )]; + float epsP[M + 1]; + float lsp_new[M]; + float lsp_mid[M]; + int16_t alw_pitch_lag_12k8[2]; + float alw_voicing[2]; + float cor_map_sum; + float ncharX; + float sp_div; + float non_staX; + int16_t loc_harm; + float S_map[L_FFT / 2]; +#if 1 + + + // Word32 lf_E_fx[1][2 * VOIC_BINS]; + + + // Word16 non_staX_fx; +#endif + + // Word16 sp_floor; + // Word16 sp_div_fx; + // Word16 Q_sp_div; + Word16 cor_map_sum_fx; + Word16 dummy_fx; + Word16 S_map_fx[L_FFT / 2]; + // Word16 relE_fx; + Word16 *wsp_fx; + float *inp_12k8; +#if 1 + Word16 *inp_12k8_fx; +#endif + float old_wsp[L_WSP]; + Word16 old_wsp_fx[L_WSP]; + float *wsp; + + float relE; + + int16_t flag_spitch; + float PS[L_FRAME / 2]; + int16_t old_pitch; + ivas_error error; +#ifdef DUMP_VAD_SPAR + FILE *fptmpN_fl = fopen( "tmpN_fl.txt", "ab+" ); + FILE *fptmpE_fl = fopen( "tmpE_fl.txt", "ab+" ); + FILE *fpbckr_fl = fopen( "bckr_fl.txt", "ab+" ); + + FILE *fptmpN_fx = fopen( "tmpN_fx.txt", "ab+" ); + FILE *fptmpE_fx = fopen( "tmpE_fx.txt", "ab+" ); + FILE *fpbckr_fx = fopen( "bckr_fx.txt", "ab+" ); +#endif +#if 1 + FILE *fp_pitch = fopen( "fp_pitch.txt", "ab+" ); + FILE *fp_voice = fopen( "fp_voice.txt", "ab+" ); + /* FILE *fpbckr_fl = fopen( "bckr_fl.txt", "ab+" ); + + FILE *fptmpN_fx = fopen( "tmpN_fx.txt", "ab+" ); + FILE *fptmpE_fx = fopen( "tmpE_fx.txt", "ab+" ); + FILE *fpbckr_fx = fopen( "bckr_fx.txt", "ab+" );*/ +#endif + push_wmops( "front_vad_SPAR" ); + error = IVAS_ERR_OK; + hFrontVad = hSpar->hFrontVad; + st = hSpar->hCoreCoderVAD; + + if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_total_brate <= SBA_DTX_BITRATE_THRESHOLD ) + { + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + inp_12k8 = hFrontVad->buffer_12k8; + Word16 Q_bands = Q31; +#if 1 + Word16 Q_inp_12k8 = Q10; +#endif +#if 1 + inp_12k8_fx = hFrontVad->buffer_12k8_fx; + +#endif + mvr2r( st->old_wsp, old_wsp, L_WSP_MEM ); + floatToFixed_arr( st->old_wsp, st->old_wsp_fx, Q10, L_WSP_MEM ); + floatToFixed_arr( st->old_wsp2, st->old_wsp2_fx, Q10, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + floatToFixed_arr( st->mem_decim2, st->mem_decim2_fx, Q10, 3 ); + // st->mem_wsp_fx = (Word16) floatToFixed( st->mem_wsp, Q_inp_12k8 ); + + mvr2r_Word16( st->old_wsp_fx, old_wsp_fx, L_WSP_MEM ); + wsp = old_wsp + L_WSP_MEM; + wsp_fx = old_wsp_fx + L_WSP_MEM; + + st->core_brate = -1; /* updated in dtx() */ + st->input_bwidth = st->last_input_bwidth; + + /*------------------------------------------------------------------* + * compensate for SPAR filterbank delay + *-----------------------------------------------------------------*/ + + st->input = input; + mvr2r( omni_in, st->input, input_frame ); + + delay_signal_float( st->input, input_frame, hFrontVad->delay_buf, hFrontVad->delay_samples ); + + /*------------------------------------------------------------------* + * Front-VAD + *-----------------------------------------------------------------*/ + + if ( ( error = front_vad( NULL, st, hEncoderConfig, &hFrontVad, 0 /* MCT_flag */, input_frame, vad_flag_dtx, fr_bands, Etot, lf_E, localVAD_HE_SAD, vad_hover_flag, band_energies, &PS[0], &st->Bin_E[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + Q_bands = Q10; + // floatToFixed_arr( inp_12k8, inp_12k8_fx, Q_inp_12k8, 3 * L_FRAME / 2 ); + // Q_bands = Q_factor_arrL( fr_bands[0], 2 * NB_BANDS ); + floatToFixed_arrL( fr_bands[0], fr_bands_fx[0], Q_bands + QSCALE, 2 * NB_BANDS ); + floatToFixed_arrL( hFrontVad->hNoiseEst->bckr, hFrontVad->hNoiseEst->bckr_fx, Q_bands + QSCALE, NB_BANDS ); + floatToFixed_arrL( tmpE, tmpE_fx, Q_bands + QSCALE, NB_BANDS ); + hFrontVad->hNoiseEst->totalNoise_fx = (Word16) ( hFrontVad->hNoiseEst->totalNoise * ONE_IN_Q8 ); + Etot_fx[0] = (Word16) ( Etot[0] * ONE_IN_Q8 ); + hFrontVad->hNoiseEst->Etot_last_fx = (Word16) ( hFrontVad->hNoiseEst->Etot_last * ONE_IN_Q8 ); + hFrontVad->hNoiseEst->Etot_v_h2_fx = (Word16) ( hFrontVad->hNoiseEst->Etot_v_h2 * ONE_IN_Q8 ); + noise_est_down_fx( fr_bands_fx[0], hFrontVad->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx, Q_bands, Q_bands + QSCALE ); + // noise_est_down( fr_bands[0], hFrontVad->hNoiseEst->bckr, tmpN, tmpE, st->min_band, st->max_band, &hFrontVad->hNoiseEst->totalNoise, Etot[0], &hFrontVad->hNoiseEst->Etot_last, &hFrontVad->hNoiseEst->Etot_v_h2 ); +#ifdef DUMP_VAD_SPAR + for ( Word16 i = 0; i < 20; i++ ) + { + fprintf( fptmpN_fl, "%f\n", tmpN[i] ); + fprintf( fptmpE_fl, "%f\n", tmpE[i] ); + fprintf( fpbckr_fl, "%f\n", hFrontVad->hNoiseEst->bckr[i] ); + } +#endif + // fixedToFloat_arrL( fr_bands_fx[0], fr_bands[0], Q_bands, 2 * NB_BANDS ); + fixedToFloat_arrL( hFrontVad->hNoiseEst->bckr_fx, hFrontVad->hNoiseEst->bckr, Q_bands + Q7, NB_BANDS ); + hFrontVad->hNoiseEst->totalNoise = (float) hFrontVad->hNoiseEst->totalNoise_fx / ONE_IN_Q8; + fixedToFloat_arrL( tmpN_fx, tmpN, Q_bands + QSCALE, 20 ); + fixedToFloat_arrL( tmpE_fx, tmpE, Q_bands + QSCALE, 20 ); + // Etot[0] = (float) Etot_fx[0] / ONE_IN_Q8; + hFrontVad->hNoiseEst->Etot_last = (float) hFrontVad->hNoiseEst->Etot_last_fx / ONE_IN_Q8; + hFrontVad->hNoiseEst->Etot_v_h2 = (float) hFrontVad->hNoiseEst->Etot_v_h2_fx / ONE_IN_Q8; +#ifdef DUMP_VAD_SPAR + for ( Word16 i = 0; i < 20; i++ ) + { + fprintf( fptmpN_fx, "%f\n", tmpN[i] ); + fprintf( fptmpE_fx, "%f\n", tmpE[i] ); + fprintf( fpbckr_fx, "%f\n", hFrontVad->hNoiseEst->bckr[i] ); + } +#endif + // corr_shift = correlation_shift( hFrontVad->hNoiseEst->totalNoise ); + corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); + corr_shift = fixedToFloat( corr_shift_fx, Q15 ); +#if 1 + Q_inp_12k8 = Q9; // Q_factor_arr( inp_12k8, 3 * L_FRAME / 2 ); + floatToFixed_arr( inp_12k8, inp_12k8_fx, Q_inp_12k8, 3 * L_FRAME / 2 ); + // Q_lp_noise = Q_factor( st->lp_noise ); + st->lp_noise_fx = (Word16) floatToFixed( st->lp_noise, Q8 ); + dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx ); + Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); + IF( st->Opt_DTX_ON ) + { + st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, 2 * Q_inp_12k8 - guard_bits ); // 2*Q_speech + } +#else + dtx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8 ); +#endif + /* linear prediction analysis */ + alw_pitch_lag_12k8[0] = st->old_pitch_la; + alw_pitch_lag_12k8[1] = st->old_pitch_la; + alw_voicing[0] = st->voicing[2]; + alw_voicing[1] = st->voicing[2]; +#if 1 + analy_lp( inp_12k8, L_FRAME, L_LOOK_12k8, &res_energy, A, epsP, lsp_new, lsp_mid, st->lsp_old1, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */ ); +#else + // analy_lp( inp_12k8, L_FRAME, L_LOOK_12k8, &res_energy, A, epsP, lsp_new, lsp_mid, st->lsp_old1, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */ ); + + Word16 Q_r[2] = { 0 }; + floatToFixed_arr( st->lsp_old1, st->lsp_old1_fx, Q15, M ); + floatToFixed_arr( alw_voicing, alw_voicing_fx, Q15, 2 ); + Q_inp_12k8 = Q12; // Q_factor_arr( inp_12k8 - 90, 3 * L_FRAME / 2 + 90 ); + floatToFixed_arr( inp_12k8 - 90, inp_12k8_fx - 90, Q_inp_12k8, 3 * L_FRAME / 2 + 90 ); + analy_lp_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */, Q_inp_12k8, Q_r ); + for ( Word16 i = 0; i <= M; i++ ) + { + epsP_fx[i] = L_Comp( epsP_h[i], epsP_l[i] ); + } + fixedToFloat_arrL( epsP_fx, epsP, Q_r[0] - 24, M + 1 ); + fixedToFloat_arr( A_fx, A, Q14, NB_SUBFR16k * ( M + 1 ) ); + fixedToFloat_arr( lsp_new_fx, lsp_new, Q15, M ); + fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); + fixedToFloat_arr( st->lsp_old1_fx, st->lsp_old1, Q15, M ); + fixedToFloat_arr( st->mem_decim2_fx, st->mem_decim2, Q12, 3 ); + +#endif + relE = Etot[0] - st->lp_speech; +#if 0 + find_wsp( L_FRAME, L_SUBFR, NB_SUBFR, A, Aw, inp_12k8, TILT_FAC, wsp, &st->mem_wsp, GAMMA1_FLT, L_LOOK_12k8 ); +#else + + Q_inp_12k8 = Q9; // Q_factor_arr( inp_12k8-M, (3 * L_FRAME / 2)+M ); + floatToFixed_arr( inp_12k8 - M, inp_12k8_fx - M, Q_inp_12k8, ( 3 * L_FRAME / 2 ) + M ); + floatToFixed_arr( A, A_fx, Q12, NB_SUBFR16k * ( M + 1 ) ); + st->mem_wsp_fx = (Word16) floatToFixed( st->mem_wsp, Q_inp_12k8 ); + // find_wsp_fx( A_fx, inp_12k8_fx, wsp_fx, &st->mem_wsp_fx, TILT_FAC_FX, L_FRAME, L_LOOK_12k8, L_SUBFR, Aw_fx, GAMMA1, NB_SUBFR ); + ivas_find_wsp( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); + fixedToFloat_arr( wsp_fx, wsp, Q_inp_12k8, 368 ); + fixedToFloat_arr( Aw_fx, Aw, Q12, NB_SUBFR16k * ( M + 1 ) ); + // st->mem_wsp = fixedToFloat( st->mem_wsp_fx, Q_inp_12k8 ); +#endif + + if ( st->vad_flag == 0 ) + { + /* reset the OL pitch tracker memories during inactive frames */ +#if 1 + pitch_ol_init( &st->old_thres, &st->old_pitch, &st->delta_pit, &st->old_corr ); +#else + pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); +#endif + } + + old_pitch = st->pitch[1]; +#if 0 + floatToFixed_arr( st->voicing, st->voicing_fx, Q15,3 ); + floatToFixed_arr( wsp, wsp_fx, Q12, 368 ); + floatToFixed_arr( st->old_wsp2, st->old_wsp2_fx, Q12, 115 ); + floatToFixed_arr( st->mem_decim2, st->mem_decim2_fx, Q12, 3 ); + // st->old_corr_fx = (Word16)floatToFixed( st->old_corr, Q15 ); + corr_shift_fx = (Word16)floatToFixed( corr_shift, Q15); + // st->old_thres_fx = (Word16) floatToFixed( st->old_thres, Q15 ); + relE_fx = (Word16) floatToFixed( relE, Q8 ); + pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR ); + + //pitch_ol( st->pitch, st->voicing, &st->old_pitch, &st->old_corr, corr_shift, &st->old_thres, &st->delta_pit, st->old_wsp2, wsp, st->mem_decim2, relE, L_LOOK_12k8, st->clas, st->input_bwidth, st->Opt_SC_VBR ); + + fixedToFloat_arr( st->voicing_fx, st->voicing, Q15, 3 ); + fixedToFloat_arr( st->old_wsp2_fx, st->old_wsp2, Q12, 115 ); + fixedToFloat_arr( st->mem_decim2_fx, st->mem_decim2, Q12, 3 ); + st->old_corr = fixedToFloat( st->old_corr_fx, Q15 ); + // corr_shift_fx = floatToFixed( corr_shift, Q15 ); + st->old_thres = fixedToFloat( st->old_thres_fx, Q15 ); + //st->old_thres_fx = floatToFixed( relE, Q8 ); + for ( Word16 i = 0; i < 3; i++ ) + { + fprintf( fp_pitch, "%d\n", st->pitch[i] ); + fprintf( fp_voice, "%f\n", st->voicing[i] ); + + } + // fprintf( fpbckr_fl, "%f\n", hFrontVad->hNoiseEst->bckr[i] ); +#else + pitch_ol( st->pitch, st->voicing, &st->old_pitch, &st->old_corr, corr_shift, &st->old_thres, &st->delta_pit, st->old_wsp2, wsp, st->mem_decim2, relE, L_LOOK_12k8, st->clas, st->input_bwidth, st->Opt_SC_VBR ); +#endif + /* Updates for adaptive lag window memory */ + st->old_pitch_la = st->pitch[2]; +#if 0 + /* Detection of very short stable pitch period */ + StableHighPitchDetect( &flag_spitch, st->pitch, st->voicing, st->Bin_E, wsp, st->localVAD, &st->voicing_sm, &st->voicing0_sm, &st->LF_EnergyRatio_sm, &st->predecision_flag, &st->diff_sm, &st->energy_sm ); +#else + // StableHighPitchDetect( &flag_spitch, st->pitch, st->voicing, st->Bin_E, wsp, st->localVAD, &st->voicing_sm, &st->voicing0_sm, &st->LF_EnergyRatio_sm, &st->predecision_flag, &st->diff_sm, &st->energy_sm ); + floatToFixed_arr( wsp, wsp_fx, Q9, 368 ); + floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); + floatToFixed_arr( st->Bin_E, st->lgBin_E_fx, Q7, 128 ); + StableHighPitchDetect_fx( &flag_spitch, st->pitch, st->voicing_fx, wsp_fx, st->localVAD, &st->voicing_sm_fx, &st->voicing0_sm_fx, &st->LF_EnergyRatio_sm_fx, &st->predecision_flag, &st->diff_sm_fx, &st->energy_sm_fx, Q12, st->lgBin_E_fx ); + fixedToFloat_arr( st->lgBin_E_fx, st->Bin_E, Q7, 128 ); + st->LF_EnergyRatio_sm = fixedToFloat( st->LF_EnergyRatio_sm_fx, Q7 ); + st->voicing_sm = fixedToFloat( st->voicing_sm_fx, Q15 ); + st->voicing0_sm = fixedToFloat( st->voicing0_sm_fx, Q15 ); +#endif + if ( st->hSpMusClas != NULL ) + { + int16_t dummy_int; + dummy_int = 0; +#if 0 + loc_harm = multi_harm( st->Bin_E, hFrontVad->hNoiseEst->old_S, hFrontVad->hNoiseEst->cor_map, &hFrontVad->hNoiseEst->multi_harm_limit, st->total_brate, st->bwidth, ( st->hGSCEnc != NULL ) ? &st->hGSCEnc->cor_strong_limit : &dummy_int, &st->hSpMusClas->mean_avr_dyn, &st->hSpMusClas->last_sw_dyn, &cor_map_sum, &dummy, S_map ); +#else + floatToFixed_arr( hFrontVad->hNoiseEst->old_S, hFrontVad->hNoiseEst->old_S_fx, Q7, 128 ); + floatToFixed_arr( hFrontVad->hNoiseEst->cor_map, hFrontVad->hNoiseEst->cor_map_fx, Q15, 128 ); + // floatToFixed_arr( hFrontVad->hNoiseEst->cor_map, hFrontVad->hNoiseEst->old_S_fx, Q15, 128 ); + hFrontVad->hNoiseEst->multi_harm_limit_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->multi_harm_limit, Q9 ); + st->hSpMusClas->mean_avr_dyn_fx = (Word16) floatToFixed( st->hSpMusClas->mean_avr_dyn, Q7 ); + st->hSpMusClas->last_sw_dyn_fx = (Word16) floatToFixed( st->hSpMusClas->last_sw_dyn, Q7 ); + // cor_map_sum_fx = (Word16) floatToFixed( cor_map_sum, Q8 ); + // dummy_fx = (Word16) floatToFixed( dummy, Q7 ); + floatToFixed_arr( hFrontVad->hNoiseEst->old_S, hFrontVad->hNoiseEst->old_S_fx, Q7, 128 ); + // loc_harm = multi_harm( st->lgBin_E_fx, hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->cor_map_fx, &hFrontVad->hNoiseEst->multi_harm_limit, st->total_brate, st->bwidth, ( st->hGSCEnc != NULL ) ? &st->hGSCEnc->cor_strong_limit : &dummy_int, &st->hSpMusClas->mean_avr_dyn, &st->hSpMusClas->last_sw_dyn, &cor_map_sum, &dummy, S_map ); + loc_harm = multi_harm_fx( st->lgBin_E_fx, hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->cor_map_fx, &hFrontVad->hNoiseEst->multi_harm_limit_fx, st->total_brate, st->bwidth, ( st->hGSCEnc != NULL ) ? &st->hGSCEnc->cor_strong_limit : &dummy_int, &st->hSpMusClas->mean_avr_dyn_fx, &st->hSpMusClas->last_sw_dyn_fx, &cor_map_sum_fx, &dummy_fx, S_map_fx ); + fixedToFloat_arr( hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->old_S, Q7, 128 ); + fixedToFloat_arr( hFrontVad->hNoiseEst->cor_map_fx, hFrontVad->hNoiseEst->cor_map, Q15, 128 ); + // floatToFixed_arr( hFrontVad->hNoiseEst->cor_map, hFrontVad->hNoiseEst->old_S_fx, Q15, 128 ); + hFrontVad->hNoiseEst->multi_harm_limit = fixedToFloat( hFrontVad->hNoiseEst->multi_harm_limit_fx, Q9 ); + st->hSpMusClas->mean_avr_dyn = fixedToFloat( st->hSpMusClas->mean_avr_dyn_fx, Q7 ); + st->hSpMusClas->last_sw_dyn = fixedToFloat( st->hSpMusClas->last_sw_dyn_fx, Q7 ); + cor_map_sum = fixedToFloat( cor_map_sum_fx, Q8 ); + // dummy = fixedToFloat( dummy_fx, Q7 ); + fixedToFloat_arr( hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->old_S, Q7, 128 ); + +#endif + } +#if 1 + noise_est( st, old_pitch, tmpN, epsP, Etot[0], Etot[0] - hFrontVad->lp_speech, corr_shift, tmpE, fr_bands[0], &cor_map_sum, &ncharX, &sp_div, &non_staX, &loc_harm, lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp, &dummy, S_map, NULL, hFrontVad, hFrontVad->ini_frame ); +#else + // noise_est( st, old_pitch, tmpN, epsP, Etot[0], Etot[0] - hFrontVad->lp_speech, corr_shift, tmpE, fr_bands[0], &cor_map_sum, &ncharX, &sp_div, &non_staX, &loc_harm, lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp, &dummy, S_map, NULL, hFrontVad, hFrontVad->ini_frame ); + Word16 Q_esp = Q_factor_arrL( epsP, M + 1 ); + floatToFixed_arrL( epsP, epsP_fx, Q_esp, M + 1 ); + FOR( Word16 i = 0; i <= M; i++ ) + { + L_Extract( epsP_fx[i], &epsP_h[i], &epsP_l[i] ); + } + + floatToFixed_arrL( lf_E[0], lf_E_fx[0], Q_bands + QSCALE - 2, 148 ); + floatToFixed_arrL( hFrontVad->hNoiseEst->fr_bands1, hFrontVad->hNoiseEst->fr_bands1_fx, Q_bands + QSCALE, NB_BANDS ); + floatToFixed_arrL( hFrontVad->hNoiseEst->fr_bands2, hFrontVad->hNoiseEst->fr_bands2_fx, Q_bands + QSCALE, NB_BANDS ); + floatToFixed_arrL( hFrontVad->hNoiseEst->ave_enr, hFrontVad->hNoiseEst->ave_enr_fx, Q_bands + QSCALE, NB_BANDS ); + floatToFixed_arrL( hFrontVad->hNoiseEst->ave_enr2, hFrontVad->hNoiseEst->ave_enr2_fx, Q_bands + QSCALE, NB_BANDS ); + hFrontVad->hNoiseEst->noise_char_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->noise_char, Q11 ); + hFrontVad->hNoiseEst->act_pred_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->act_pred, Q15 ); + hFrontVad->hNoiseEst->lt_haco_ev_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_haco_ev, Q15 ); + hFrontVad->hNoiseEst->lt_tn_track_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_tn_track, Q15 ); + hFrontVad->hNoiseEst->lt_aEn_zero_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_aEn_zero, Q15 ); + hFrontVad->hNoiseEst->epsP_0_2_ad_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->epsP_0_2_ad_lp, Q12 ); + hFrontVad->hNoiseEst->epsP_0_2_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->epsP_0_2_lp, Q12 ); + hFrontVad->hNoiseEst->epsP_2_16_dlp_lp2_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->epsP_2_16_dlp_lp2, Q12 ); + hFrontVad->hNoiseEst->epsP_2_16_lp2_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->epsP_2_16_lp2, Q12 ); + hFrontVad->hNoiseEst->epsP_2_16_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->epsP_2_16_lp, Q12 ); + // hFrontVad->hNoiseEst->totalNoise_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_tn_track, Q15 ); + + hFrontVad->hNoiseEst->Etot_l_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->Etot_l_lp, Q8 ); + hFrontVad->hNoiseEst->Etot_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->Etot_lp, Q8 ); + hFrontVad->hNoiseEst->Etot_v_h2_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->Etot_v_h2, Q8 ); + hFrontVad->lp_speech_fx = (Word16) floatToFixed( hFrontVad->lp_speech, Q8 ); + corr_shift_fx = (Word16) floatToFixed( corr_shift, Q15 ); + noise_est_ivas_fx( st, old_pitch, tmpN_fx, epsP_h, epsP_l, Etot_fx[0], Etot_fx[0] - hFrontVad->lp_speech_fx, corr_shift_fx, tmpE_fx, fr_bands_fx[0], &cor_map_sum_fx, &sp_div_fx, &Q_sp_div, &non_staX_fx, &loc_harm, lf_E_fx[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp_fx, hFrontVad->hNoiseEst->Etot_v_h2_fx, &hFrontVad->hNoiseEst->bg_cnt, st->lgBin_E_fx, Q_bands, Q_bands + QSCALE, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); + cor_map_sum = fixedToFloat( cor_map_sum_fx, Q8 ); + non_staX = fixedToFloat( non_staX_fx, Q8 ); + fixedToFloat_arr( S_map_fx, S_map, Q7, 128 ); +#endif +#if 0 + vad_param_updt( st, corr_shift, corr_shift, A, st->pitch[1], &hFrontVad, 1 ); +#else + mvr2r_Word16( st->pitch, st->pitch_fx, 3 ); + corr_shift_fx = (Word16) floatToFixed( corr_shift, Q15 ); + hFrontVad->hVAD->running_avg_fx = (Word16) floatToFixed( hFrontVad->hVAD->running_avg, Q15 ); + hFrontVad->hVAD->ra_deltasum_fx = (Word16) floatToFixed( hFrontVad->hVAD->ra_deltasum, Q15 ); + floatToFixed_arr( A, A_fx, Q12, NB_SUBFR16k * ( M + 1 ) ); + floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); + vad_param_updt_fx( st, st->pitch[1], corr_shift_fx, corr_shift_fx, A_fx, &hFrontVad, 1 ); + hFrontVad->hVAD->running_avg = fixedToFloat( hFrontVad->hVAD->running_avg_fx, Q15 ); + hFrontVad->hVAD->ra_deltasum = fixedToFloat( hFrontVad->hVAD->ra_deltasum_fx, Q15 ); + +#endif + /* 1st stage speech/music classification (GMM model) */ + /* run only to get 'high_lpn_flag' parameter */ +#if 0 + ivas_smc_gmm( st, NULL, localVAD_HE_SAD[0], Etot[0], lsp_new, cor_map_sum, epsP, PS, non_staX, relE, &high_lpn_flag, flag_spitch ); +#else + SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas; +#if 1 + Word16 relE_fx; + Word16 lsp_new_fx[M]; + Word32 PS_fx[128]; + Word32 epsP_fx[M + 1]; + cor_map_sum_fx = (Word16) floatToFixed( cor_map_sum, Q8 ); + Word16 non_sta_fx = (Word16) floatToFixed( non_staX, Q8 ); + // Word32 epsP_fx[M + 1]; + Word16 Etot_fx_0 = (Word16) floatToFixed( Etot[0], Q8 ); + floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); + hSpMusClas->wdlp_0_95_sp_fx = (Word16) floatToFixed( hSpMusClas->wdlp_0_95_sp, Q8 ); + hSpMusClas->wdlp_xtalk_fx = floatToFixed( hSpMusClas->wdlp_xtalk, Q19 ); + hSpMusClas->wrise_fx = (Word16) ( hSpMusClas->wrise * ONE_IN_Q9 ); + relE_fx = (Word16) ( relE * ONE_IN_Q9 ); + hSpMusClas->prev_relE_fx = (Word16) ( hSpMusClas->prev_relE * ONE_IN_Q9 ); + hSpMusClas->relE_attack_sum_fx = (Word16) ( hSpMusClas->relE_attack_sum * ONE_IN_Q9 ); + Word16 Qfact_PS = Q_factor_arrL( PS, 128 ); + floatToFixed_arr32( PS, PS_fx, Qfact_PS, 128 ); + Word16 Q_esp = Q_factor_arrL( epsP, M + 1 ); + floatToFixed_arrL( epsP, epsP_fx, Q_esp, M + 1 ); + Word16 Qfact_PS_past = Q_factor_arrL( hSpMusClas->past_PS, 67 ); + floatToFixed_arr32( hSpMusClas->past_PS, hSpMusClas->past_PS_fx, Qfact_PS_past, 67 ); +#endif + ivas_smc_gmm_fx( st, NULL, localVAD_HE_SAD[0], Etot_fx_0, lsp_new_fx, cor_map_sum_fx, epsP_fx, PS_fx, non_sta_fx, relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, Q_esp, Qfact_PS_past ); +#if 1 + fixedToFloat_arr( hSpMusClas->past_dlp_fx, hSpMusClas->past_dlp, Q9, HANG_LEN - 1 ); + hSpMusClas->lpm = (Word16) fixedToFloat( hSpMusClas->lpm_fx, Q8 ); // Q8 + hSpMusClas->lps = (Word16) fixedToFloat( hSpMusClas->lps_fx, Q8 ); // Q8 + hSpMusClas->lpn = (Word16) fixedToFloat( hSpMusClas->lpn_fx, Q8 ); // Q8 + hSpMusClas->wdrop = (Word16) fixedToFloat( hSpMusClas->wdrop_fx, Q9 ); // Q8 + hSpMusClas->wrise = (Word16) fixedToFloat( hSpMusClas->wrise_fx, Q9 ); // Q8 + hSpMusClas->lt_dec_thres = (Word16) fixedToFloat( hSpMusClas->lt_dec_thres_fx, Q9 ); // Q8 + hSpMusClas->wdlp_0_95_sp = fixedToFloat( hSpMusClas->wdlp_0_95_sp_fx, Q8 ); + hSpMusClas->dlp_mean_LT = fixedToFloat_32( hSpMusClas->dlp_mean_LT_fx, Q19 ); + hSpMusClas->wdlp_xtalk = fixedToFloat( hSpMusClas->wdlp_xtalk_fx, Q19 ); + hSpMusClas->dlp_var_LT = fixedToFloat_32( hSpMusClas->dlp_var_LT_fx, Q19 ); + hSpMusClas->prev_relE = (Word16) fixedToFloat( hSpMusClas->prev_relE_fx, Q9 ); + hSpMusClas->prev_Etot = (Word16) fixedToFloat( hSpMusClas->prev_Etot_fx, Q8 ); + fixedToFloat_arrL32( hSpMusClas->past_PS_fx, hSpMusClas->past_PS, Qfact_PS_past, 67 ); + hSpMusClas->relE_attack_sum = (Word16) fixedToFloat( hSpMusClas->relE_attack_sum_fx, Q9 ); + fixedToFloat_arrL32( hSpMusClas->FV_st_fx, hSpMusClas->FV_st, Q20, 15 ); +#endif +#endif +#if 0 + /* long-term energy update */ + long_enr( st, -1, localVAD_HE_SAD[0], high_lpn_flag, &hFrontVad, 1, localVAD_HE_SAD, Etot ); +#else + hFrontVad->lp_speech_fx = (Word16) floatToFixed( hFrontVad->lp_speech, Q8 ); + hFrontVad->lp_noise_fx = (Word16) floatToFixed( hFrontVad->lp_noise, Q8 ); + /* long-term energy update */ + ivas_long_enr_fx( st, -1, localVAD_HE_SAD[0], high_lpn_flag, &hFrontVad, 1, localVAD_HE_SAD, Etot_fx ); + hFrontVad->lp_speech = fixedToFloat( hFrontVad->lp_speech_fx, Q8 ); + hFrontVad->lp_noise = fixedToFloat( hFrontVad->lp_noise_fx, Q8 ); + hFrontVad->hNoiseEst->Etot_last = fixedToFloat( hFrontVad->hNoiseEst->Etot_last_fx, Q8 ); +#endif + /* increase ini_frame counter */ + hFrontVad->ini_frame = min( hFrontVad->ini_frame + 1, MAX_FRAME_COUNTER ); + st->ini_frame = hFrontVad->ini_frame; + + hSpar->front_vad_flag = st->vad_flag; + hSpar->front_vad_dtx_flag = 1; + if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) + { + hSpar->front_vad_dtx_flag = 0; + } + hSpar->force_front_vad = 1; + st->last_core = 0; + } + else + { + hSpar->front_vad_flag = 1; + hSpar->front_vad_dtx_flag = 0; + hSpar->force_front_vad = 0; + } +#ifdef DUMP_VAD_SPAR + fclose( fptmpN_fl ); + fclose( fptmpE_fl ); + fclose( fpbckr_fl ); + + fclose( fptmpN_fx ); + fclose( fptmpE_fx ); + fclose( fpbckr_fx ); +#endif +#if 1 + fclose( fp_pitch ); + fclose( fp_voice ); +#endif + pop_wmops(); + return error; +} +#else ivas_error front_vad_spar( SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ const float *omni_in, /* i : omnidirectional input signal */ @@ -436,7 +922,6 @@ ivas_error front_vad_spar( /*------------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ - inp_12k8 = hFrontVad->buffer_12k8; mvr2r( st->old_wsp, old_wsp, L_WSP_MEM ); wsp = old_wsp + L_WSP_MEM; @@ -532,3 +1017,4 @@ ivas_error front_vad_spar( pop_wmops(); return error; } +#endif diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 554b16008683620b4664d46484a24b3b05739bf1..4e4bdded50c51ff968fd9c302bd7a144f1d81407 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -35,7 +35,9 @@ #include #include "ivas_cnst.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot.h" +#include "prot_fx2.h" #include "wmc_auto.h" #include @@ -280,7 +282,71 @@ static void getBlockValues( p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; +#ifndef IVAS_FLOAT_FIXED stereo_coder_tcx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1 ); +#else +#if 1 + Word16 k; + Word32 *p_inv_spectrum_fx[2][2]; + Word16 q_spec = Q31; + Word16 length; + Word32 *p_inv_mdst_spectrum_fx[2][2]; + Word32 *p_mdst_spectrum_fx[2][2]; + FOR( Word16 ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = p_st[ch]->hTcxEnc->L_frameTCX / ( ( p_st[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( p_st[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( p_st[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + p_inv_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + p_inv_mdst_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + p_mdst_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + q_spec = s_min( q_spec, Q_factor_arrL( p_st[ch]->hTcxEnc->spectrum[k], length ) - 1 ); + q_spec = s_min( q_spec, Q_factor_arrL( p_mdst_spectrum[ch][k], length ) - 1 ); + } + } + + FOR( Word16 ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = p_st[ch]->hTcxEnc->L_frameTCX / ( ( p_st[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( p_st[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( p_st[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + floatToFixed_arrL32( p_st[ch]->hTcxEnc->spectrum[k], p_st[ch]->hTcxEnc->spectrum_fx[k], q_spec, length ); + p_st[ch]->hTcxEnc->spectrum_e[k] = sub( Q31, q_spec ); + floatToFixed_arrL32( p_mdst_spectrum[ch][k], p_mdst_spectrum_fx[ch][k], q_spec, length ); + } + } + +#endif + stereo_coder_tcx_fx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum_fx, p_inv_spectrum_fx, p_inv_mdst_spectrum_fx, 1, q_spec ); +#if 1 + FOR( Word16 ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = p_st[ch]->hTcxEnc->L_frameTCX / ( ( p_st[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( p_st[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( p_st[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + fixedToFloat_arrL32( p_st[ch]->hTcxEnc->spectrum_fx[k], p_st[ch]->hTcxEnc->spectrum[k], q_spec, length ); + fixedToFloat_arrL32( p_inv_spectrum_fx[ch][k], p_inv_spectrum[ch][k], q_spec, length ); + fixedToFloat_arrL32( p_inv_mdst_spectrum_fx[ch][k], p_inv_mdst_spectrum[ch][k], q_spec, length ); + fixedToFloat_arrL32( p_mdst_spectrum_fx[ch][k], p_mdst_spectrum[ch][k], q_spec, length ); + free( p_inv_spectrum_fx[ch][k] ); + free( p_inv_mdst_spectrum_fx[ch][k] ); + free( p_mdst_spectrum_fx[ch][k] ); + } + } +#endif +#endif if ( ( sts[ch1]->core == TCX_20_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) || ( sts[ch1]->core == TCX_10_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO && hBlock->hStereoMdct->mdct_stereo_mode[1] == SMDCT_DUAL_MONO ) ) { @@ -715,6 +781,10 @@ void write_mct_bitstream( p_st[1] = sts[hBlock->ch2]; /*then business as usual for each block pair */ +#ifdef IVAS_FLOAT_FIXED + IF( hMCT->hBlockData[pair]->hStereoMdct->hItd ) + hMCT->hBlockData[pair]->hStereoMdct->hItd->itd_fx[1] = float_to_fix( hMCT->hBlockData[pair]->hStereoMdct->hItd->itd[1], Q23 ); +#endif write_stereo_to_bitstream( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr ); } diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index 565093d56a90a260295414ee36aa78ce7a0d0206..1afadbb2caad9907ce7083f6a8e1cd8d1aaf8258 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -722,6 +722,75 @@ const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = { 1.2858f,2.9245f,5.1959f,6.8503f,2.9659f,3.2823f,5.0458f,6.4686f,5.1703f,5.0458f,6.3065f,7.6781f,6.8301f,6.5324f,7.6601f,8.7521f,4.3982f } }; +#ifdef IVAS_FLOAT_FIXED +const Word32 ari_bit_estimate_s17_LC_fx[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = // Q23 +{ + {83886080, 75881672, 61002796, 63255136, 77113120, 68724512, 57378916, 59202600, 63963136, 59104456, 60121992, 61117720, 66920960, 61587484, 62456544, 63393548, 1051931 }, + {9617539, 43694580, 72206624, 86402664, 16572534, 38999476, 65683640, 84666224, 30722438, 45647448, 68510600, 83886080, 42014344, 52961476, 74412824, 88424320, 32977296 }, + {16015530, 25555894, 41778624, 55004940, 25458586, 25380572, 38384592, 49867756, 40708236, 37617036, 46374740, 55574528, 53380068, 47898952, 54527628, 62716588, 26883810 }, + {20729090, 24146608, 39261204, 53876672, 24633986, 22665180, 34551836, 47295812, 39185704, 34411748, 42599028, 52902756, 53020196, 47149012, 52844876, 61468364, 30629324 }, + {19936366, 26554138, 39356832, 51112628, 24781626, 25550022, 36755524, 47112940, 35624740, 35102968, 45841228, 54935316, 45424312, 43887520, 53501704, 61952388, 26163230 }, + {31474896, 29648696, 39356832, 48656444, 30920410, 26409854, 34061104, 42327240, 41032876, 34942748, 40391988, 46968656, 50284672, 43667736, 47443452, 52786156, 15354508 }, + {27007124, 26188396, 38003748, 50051468, 27327568, 23485586, 33204628, 44083812, 39452464, 33841324, 40623512, 49204220, 51062296, 44572868, 49642944, 56482176, 21983186 }, + {32589742, 28184046, 37683304, 48452600, 28982640, 23729694, 31635118, 41501800, 37901408, 32003378, 38158100, 46685960, 48331804, 42327240, 47076868, 53380068, 21107416 }, + {4258477, 28757826, 59104456, 80595232, 26965180, 37290720, 61117720, 78978744, 53876672, 58165768, 75125016, 90848624, 72497704, 73740056, 86402664, 97962168, 63818012 }, + {8635233, 22469726, 47518108, 66920960, 23672652, 28382856, 48574236, 65189552, 48291540, 48864480, 62982508, 76688656, 65853088, 65029328, 75125016, 86402664, 50715848 }, + {36038300, 31635118, 39242748, 47518108, 32798618, 27027256, 33274252, 40771992, 40538788, 34049360, 38598500, 45021660, 48780596, 41825600, 45424312, 50570724, 14716974 }, + {12080434, 20354118, 46038360, 66374860, 21324680, 24359678, 45175172, 62982508, 47406540, 45488064, 57898172, 71371112, 67493064, 62982508, 71105200, 81185784, 49553184 }, + {15030708, 20736638, 38705876, 53876672, 24454470, 24260694, 38262120, 51418812, 43804472, 41054688, 51062296, 61952388, 58256364, 54797744, 62849128, 71921408, 37178312 }, + {37403964, 33390016, 40771992, 48093568, 35361340, 29546356, 35102968, 41254336, 43317932, 36526516, 40350884, 45361396, 50284672, 43239080, 46306792, 50618540, 11327137 }, + {17194968, 21221500, 35457808, 47295812, 27103592, 25865434, 36213620, 45841228, 43667736, 40412956, 48739492, 57128100, 55574528, 52387696, 59400572, 65853088, 29113502 }, + {21471482, 22235684, 39375288, 54593900, 23342140, 21510908, 35009856, 49075872, 40580732, 35610480, 44140016, 55144192, 55214656, 48906424, 55004940, 63674568, 32843078 }, + {43558684, 37952580, 43108216, 48615340, 38943272, 32362410, 36362100, 41411204, 44311144, 37162372, 40003592, 44140016, 49731864, 42205604, 44514148, 47937540, 9255151 }, + {117440512, 117440512, 28514556, 38314968, 117440512, 117440512, 31228272, 39568224, 30326496, 32182056, 38054920, 44691148, 40003592, 40751020, 45237248, 50570724, 10523509 }, + {22771716, 23176046, 39356832, 54729796, 23619804, 21598988, 35251448, 49075872, 39823240, 35333656, 44602228, 55357264, 54132528, 48291540, 54935316, 62849128, 28298130 }, + {34837052, 30657006, 38907204, 48093568, 31444698, 25984552, 32853984, 41098308, 39665532, 33332134, 38508744, 45456188, 48452600, 41662860, 45615572, 51214128, 16284805 }, + {22184512, 26574272, 40559760, 52387696, 26468574, 24628114, 35526592, 46273240, 39863504, 35049280, 42524372, 51418812, 51011964, 45175172, 50378624, 57635608, 21915238 }, + {4598131, 26208528, 62456544, 90848624, 25592804, 35865492, 65853088, 89573560, 59301588, 62982508, 82460856, 100663296, 84666224, 84666224, 97962168, 109051904, 80032352 }, + {46273240, 40902012, 45808512, 50426440, 41919552, 35361340, 38925656, 43030204, 47004728, 39665532, 42062160, 45456188, 51680536, 43859836, 45939372, 48615340, 7052806 }, + {18423900, 28789702, 43694580, 53380068, 27613620, 26883810, 38279736, 48015552, 41321444, 37004668, 43887520, 51522832, 50863484, 45424312, 51893608, 57045052, 19697290 }, + {117440512, 117440512, 39280496, 45051860, 117440512, 117440512, 39394580, 44168536, 40023728, 40206600, 43640056, 47480360, 46171736, 45456188, 48172420, 51470820, 4772195 }, + {34222164, 44111496, 59400572, 67889840, 33193722, 38071696, 51733384, 60664736, 41708996, 43056208, 53750004, 61707440, 47221992, 47004728, 56171796, 62849128, 5373071 }, + {5433133, 27810752, 53939588, 73740056, 25978680, 33625736, 55074568, 71643744, 49642944, 52220764, 67889840, 81806544, 66024216, 66736408, 78978744, 92274688, 55574528 }, + {9987477, 22437010, 48615340, 69164912, 22240716, 26003846, 46581100, 64257576, 47706852, 45808512, 57898172, 70590136, 67690192, 62716588, 70845152, 80032352, 50863484 }, + {30684690, 32469784, 43213076, 51418812, 33448736, 30093292, 37851076, 45113096, 43999088, 38123708, 42876692, 48015552, 51265300, 44631588, 48172420, 52056344, 10875830 }, + {14467832, 21260088, 43056208, 61117720, 22180318, 23276710, 40371016, 56095460, 43586368, 40454900, 51214128, 63532800, 61002796, 56019964, 62982508, 72797176, 41662860 }, + {14800021, 19242628, 44750708, 64870784, 20720700, 22442042, 42623356, 60554004, 46826048, 43531844, 55074568, 68300048, 66554376, 60776304, 68300048, 77553520, 46933424 }, + {15023158, 23893272, 42062160, 57378916, 23625676, 24059366, 38437440, 52331492, 41411204, 38020528, 47821776, 59007148, 56171796, 51112628, 58532352, 67493064, 34086268 }, + {19163774, 22665180, 36894776, 49117816, 25928348, 24032524, 35089548, 46443528, 41732484, 37258840, 45679328, 54327980, 53876672, 49642944, 56171796, 63963136, 29113502 }, + {22422750, 23110616, 36801664, 48864480, 26403144, 23583732, 34360576, 45144132, 41593236, 36709388, 44840464, 53380068, 54866528, 49247000, 54661848, 61233484, 24719550 }, + {52786156, 45939372, 49642944, 53440468, 47185920, 39943196, 42648520, 45873940, 51265300, 43749948, 45550980, 48054140, 55144192, 47295812, 48780596, 50764500, 4665324 }, + {25013152, 23957864, 37969356, 51839920, 25183440, 21892590, 33102286, 45550980, 38888748, 33757436, 41298796, 51470820, 52443900, 46071912, 51787072, 59602736, 28351818 }, + {28010400, 25815102, 37683304, 50051468, 26521424, 22399262, 32182056, 43749948, 38227724, 32437908, 39626944, 49290620, 50378624, 43722264, 49421484, 57045052, 25435098 }, + {63118404, 55429404, 54327980, 57549208, 56640720, 48822536, 48372068, 50962472, 56962844, 49822460, 51162960, 52844876, 60016296, 53020196, 53876672, 55429404, 2546613 }, + {24288376, 30110908, 42698852, 52165396, 29580748, 27722672, 37226964, 45679328, 41525288, 36111280, 42327240, 49204220, 50522068, 43776788, 48615340, 54067936, 15380513 }, + {31434630, 28298130, 38314968, 48739492, 29436464, 24498930, 32589742, 42182116, 39205000, 33011690, 38907204, 46826048, 49160600, 42401056, 46790816, 52961476, 19214106 }, + {3153193, 31766820, 62982508, 85505080, 29105114, 41990016, 66736408, 84666224, 56640720, 62849128, 80595232, 95755960, 75497472, 78010696, 92274688, 104144568, 68300048 }, + {28313230, 28063250, 39242748, 49777160, 28313230, 24805114, 34172672, 43640056, 39318244, 34098012, 40708236, 48697548, 49377864, 43265084, 48211848, 54593900, 18742666 }, + {40084124, 34889900, 41076496, 47821776, 35695204, 29411298, 34360576, 40517816, 41755136, 34903320, 38742788, 43804472, 48533968, 41142768, 44225580, 48412336, 12035136 }, + {6888557, 22805270, 47706852, 65853088, 26156518, 31920332, 51316472, 66374860, 52671232, 53079756, 66736408, 78978744, 70340992, 68724512, 78978744, 89573560, 51839920 }, + {6934359, 23031762, 55214656, 81185784, 23076222, 30317268, 56248972, 77553520, 54262548, 55285960, 70590136, 87367352, 79493808, 75881672, 84666224, 95755960, 66736408 }, + {10658565, 23201212, 47221992, 67299288, 22065394, 25833558, 45743920, 63393548, 44197060, 43722264, 57898172, 71643744, 61952388, 59202600, 69622088, 79493808, 44900024 }, + {9992510, 19614244, 42474876, 58720256, 25422516, 28283030, 45519944, 59400572, 50912980, 49075872, 60444952, 71643744, 68300048, 65351452, 74072248, 82460856, 45175172 }, + {14219529, 22078816, 44083812, 62585728, 21781020, 23573666, 42037832, 58256364, 42573864, 40538788, 53258432, 66198700, 59007148, 55285960, 64109096, 74412824, 37649752 }, + {17939038, 22324602, 41164576, 58076012, 22442042, 22171090, 37901408, 53139316, 40580732, 37371248, 48412336, 60335900, 56482176, 51733384, 59400572, 68510600, 33914304 }, + {12215491, 19329870, 37226964, 51893608, 27263814, 27497858, 41120956, 52786156, 47898952, 45550980, 55795148, 64257576, 63674568, 59501236, 67299288, 74412824, 38037304 }, + {20357474, 23951992, 40104256, 55214656, 23968770, 22699574, 36111280, 49822460, 39356832, 35639000, 44572868, 55285960, 53563780, 47860364, 54460520, 62456544, 28351818 }, + {25089488, 24195262, 37934964, 51367640, 25617132, 22588844, 33841324, 46139020, 39803944, 35143236, 42825520, 52557144, 53139316, 46968656, 52902756, 59705080, 24173452 }, + {15014769, 19723296, 34707028, 46409136, 28560694, 27271364, 37952580, 47745440, 46005644, 43291928, 51214128, 59007148, 59807420, 55795148, 61952388, 68510600, 31326418 }, + {19625988, 26674096, 40288808, 51733384, 27075910, 24902422, 35035860, 45615572, 40329912, 35049280, 42182116, 50522068, 52110872, 45582856, 50912980, 58165768, 24431820 }, + {26508002, 25118848, 36724488, 46512316, 29821502, 25716116, 33853904, 42085648, 43082212, 37550764, 43265084, 49959192, 53687932, 47480360, 51522832, 56640720, 18096744 }, + {17097660, 21086444, 42375892, 60888712, 21402694, 21901816, 39337540, 55720488, 42109972, 38961728, 50237696, 63118404, 59301588, 54327980, 61952388, 71643744, 38262120 }, + {29236816, 27179928, 37952580, 47976128, 29717482, 25555894, 33566176, 42351564, 41525288, 35624740, 40902012, 48331804, 51787072, 45424312, 49509564, 54797744, 17241106 }, + {1703306, 35808452, 78484656, 109051904, 34347996, 51575680, 85505080, 109051904, 74072248, 82460856, 104144568, 117440512, 104144568, 104144568, 117440512, 117440512, 109051904 }, + {117440512, 117440512, 22240716, 38455896, 117440512, 117440512, 26714362, 40559760, 21398500, 26298286, 36740424, 47706852, 36755524, 39491048, 47076868, 56019964, 20389350 }, + {25392316, 25195184, 39185704, 52500104, 25642296, 22694540, 33901720, 46071912, 39185704, 34049360, 41990016, 51470820, 51680536, 45615572, 51062296, 58347800, 23840424 }, + {9318905, 20827236, 51062296, 75125016, 21589760, 26707650, 51575680, 72206624, 51787072, 51316472, 66374860, 81806544, 75125016, 71921408, 81185784, 92274688, 60444952 }, + {20310498, 21762566, 40084124, 56404160, 22670214, 21554528, 36832700, 51575680, 41120956, 37258840, 47480360, 58720256, 57045052, 51627688, 58440076, 66736408, 31208978 }, + {7740001, 25753026, 52220764, 71921408, 23155914, 29666312, 51418812, 68942616, 45712040, 47258900, 62849128, 77113120, 61952388, 61002796, 73103360, 84666224, 47369632 }, + {10786072, 24532484, 43586368, 57464480, 24879772, 27533928, 42327240, 54262548, 43371620, 42327240, 52902756, 64408572, 57295032, 54797744, 64257576, 73417936, 36894776 }, +}; +#endif /*----------------------------------------------------------------------------------* * Stereo downmix to EVS ROM tables diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 3c87e361e888e7798669680730140faa68091f7d..bec7df35711e59daba6e246f1ef1c0f921bbfdaf 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -114,6 +114,7 @@ extern const Word32 win_mdct_8k_fx[STEREO_DFT_OVL_8k]; *----------------------------------------------------------------------------------*/ extern const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS]; +extern const Word32 ari_bit_estimate_s17_LC_fx[RANGE_N_CONTEXT][RANGE_N_SYMBOLS]; /*----------------------------------------------------------------------------------* * ECLVQ Stereo ROM tables diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index c592390522da2643700e475ace3a73f3e69a8eb8..7b1a19313f52932f8ea7cf56b2715625aea90873 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -37,6 +37,8 @@ #include "cnst.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" +#include "prot_fx2.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" @@ -427,7 +429,19 @@ int16_t quantize_sns( if ( sns_stereo_mode[k] == SNS_STEREO_MODE_MS ) { +#ifndef IVAS_FLOAT_FIXED convertToMS( M, snsQ_out[0][k], snsQ_out[1][k], 0.5f ); +#else + Word32 snsQ_out_fx[2][2][M]; + Word16 q = s_min( Q_factor_arrL( snsQ_out[0][k], M ), Q_factor_arrL( snsQ_out[1][k], M ) ) - 1; + floatToFixed_arrL( snsQ_out[0][k], snsQ_out_fx[0][k], q, M ); + floatToFixed_arrL( snsQ_out[1][k], snsQ_out_fx[1][k], q, M ); + + convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q30 ); + + fixedToFloat_arrL( snsQ_out_fx[0][k], snsQ_out[0][k], q, M ); + fixedToFloat_arrL( snsQ_out_fx[1][k], snsQ_out[1][k], q, M ); +#endif } } } @@ -486,7 +500,19 @@ int16_t quantize_sns( { if ( sns_stereo_mode[k] == SNS_STEREO_MODE_MS ) { +#ifndef IVAS_FLOAT_FIXED convertToMS( M, snsQ_out[0][k], snsQ_out[1][k], 1.f ); +#else + Word32 snsQ_out_fx[2][2][M]; + Word16 q = s_min( Q_factor_arrL( snsQ_out[0][k], M ), Q_factor_arrL( snsQ_out[0][k], M ) ) - 1; + floatToFixed_arrL( snsQ_out[0][k], snsQ_out_fx[0][k], q, M ); + floatToFixed_arrL( snsQ_out[1][k], snsQ_out_fx[1][k], q, M ); + + convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 ); + + fixedToFloat_arrL( snsQ_out_fx[0][k], snsQ_out[0][k], q, M ); + fixedToFloat_arrL( snsQ_out_fx[1][k], snsQ_out[1][k], q, M ); +#endif } } } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 37e9288e1d5fe949484f987fe7c4dbbb03c84f84..ec2dbd2beb68ad17ced87fd99e732004f3a629ba 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -657,6 +657,7 @@ typedef struct ivas_stereo_classifier_data_structure float non_sta_ch1; float sp_div_ch1; float ps_diff_ch1, ps_diff_ch2; + Word32 ps_diff_ch1_fx, ps_diff_ch2_fx; float ps_sta_ch1, ps_sta_ch2; float prev_g_IPD; float prev_IPD; @@ -706,7 +707,6 @@ typedef struct ivas_stereo_classifier_data_structure Word32 nchar_ch1_fx, nchar_ch2_fx; Word32 non_sta_ch1_fx; Word32 sp_div_ch1_fx; - Word32 ps_diff_ch1_fx, ps_diff_ch2_fx; Word32 ps_sta_ch1_fx, ps_sta_ch2_fx; Word32 prev_g_IPD_fx; Word32 prev_IPD_fx; @@ -762,21 +762,28 @@ typedef struct front_vad_enc { int16_t ini_frame; /* initialization frames counter */ float lp_speech; /* long term speech average */ - Word16 lp_speech_fx; /* Q9 long term speech average */ + /* Q9 long term speech average */ float lp_noise; /* long term noise average */ - Word16 lp_noise_fx; /* long term noise average */ + /* long term noise average */ float mem_decim[2 * L_FILT_MAX]; /* decimation filter memory */ float buffer_12k8[3 * L_FRAME / 2]; /* 12k8 signal buffer */ - float mem_preemph; /* preemph filter memory */ - Word16 mem_preemph_fx; /* preemph filter memory */ - NOISE_EST_HANDLE hNoiseEst; /* Noise estimation handle */ - VAD_HANDLE hVAD; /* VAD handle */ + + float mem_preemph; /* preemph filter memory */ + Word16 mem_preemph_fx; /* preemph filter memory */ + NOISE_EST_HANDLE hNoiseEst; /* Noise estimation handle */ + VAD_HANDLE hVAD; /* VAD handle */ float *delay_buf; Word16 *delay_buf_fx; int16_t delay_samples; - int16_t rem_dtx_ho; /* Remaining hangover frames */ - Word32 mem_decim_fx[2 * L_FILT_MAX]; /* decimation filter memory */ - Word32 buffer_12k8_fx[3 * L_FRAME / 2]; /* 12k8 signal buffer */ + int16_t rem_dtx_ho; /* Remaining hangover frames */ + +#ifdef IVAS_FLOAT_FIXED + Word16 lp_speech_fx; + Word16 lp_noise_fx; + Word16 mem_decim_fx[2 * L_FILT_MAX]; /* decimation filter memory */ + Word16 buffer_12k8_fx[3 * L_FRAME / 2]; +#endif + // Word32 buffer_12k8_fx[3 * L_FRAME / 2]; /* 12k8 signal buffer */ } FRONT_VAD_ENC, *FRONT_VAD_ENC_HANDLE; diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index a755906d86c55493453513eebe343b6a6354d59d..00e6acb31f2a6148b7573fcdb1a1dcab8e9b62d1 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -233,8 +233,15 @@ void stereo_classifier_init( hStereoClassif->nchar_ch2 = 0.0f; hStereoClassif->non_sta_ch1 = 0.0f; hStereoClassif->sp_div_ch1 = 0.0f; + +#ifdef IVAS_FLOAT_FIXED + hStereoClassif->ps_diff_ch1_fx = 0; + hStereoClassif->ps_diff_ch2_fx = 0; + hStereoClassif->ps_sta_ch1_fx = 0; + hStereoClassif->ps_sta_ch2_fx = 0; +#endif hStereoClassif->ps_diff_ch1 = 0.0f; - hStereoClassif->ps_diff_ch2 = 0.0f; + hStereoClassif->ps_sta_ch1 = 0.0f; hStereoClassif->ps_sta_ch2 = 0.0f; hStereoClassif->prev_g_IPD = 0.5f; diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index 73081c98aa59022e542a42109485aec16870437b..db45ca3f9d1345f3adad69cc5542529a58dc12aa 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" @@ -258,7 +259,71 @@ void stereo_mdct_core_enc( if ( !hStereoMdct->isSBAStereoMode ) { +#ifndef IVAS_FLOAT_FIXED stereo_coder_tcx( hStereoMdct, sts, ms_mask, mdst_spectrum, inv_spectrum, inv_mdst_spectrum, 0 ); +#else +#if 1 + Word16 k; + Word32 *inv_spectrum_fx[2][2]; + Word16 q_spec = Q31; + Word16 length; + Word32 *inv_mdst_spectrum_fx[2][2]; + Word32 *mdst_spectrum_fx[2][2]; + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = sts[ch]->hTcxEnc->L_frameTCX / ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( sts[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + inv_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + inv_mdst_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + mdst_spectrum_fx[ch][k] = (Word32 *) malloc( sizeof( Word32 ) * length ); + q_spec = s_min( q_spec, Q_factor_arrL( sts[ch]->hTcxEnc->spectrum[k], length ) - 1 ); + q_spec = s_min( q_spec, Q_factor_arrL( mdst_spectrum[ch][k], length ) - 1 ); + } + } + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = sts[ch]->hTcxEnc->L_frameTCX / ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( sts[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + floatToFixed_arrL32( sts[ch]->hTcxEnc->spectrum[k], sts[ch]->hTcxEnc->spectrum_fx[k], q_spec, length ); + sts[ch]->hTcxEnc->spectrum_e[k] = sub( Q31, q_spec ); + floatToFixed_arrL32( mdst_spectrum[ch][k], mdst_spectrum_fx[ch][k], q_spec, length ); + } + } + +#endif + stereo_coder_tcx_fx( hStereoMdct, sts, ms_mask, mdst_spectrum_fx, inv_spectrum_fx, inv_mdst_spectrum_fx, 0, q_spec ); +#if 1 + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + length = sts[ch]->hTcxEnc->L_frameTCX / ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( sts[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + fixedToFloat_arrL32( sts[ch]->hTcxEnc->spectrum_fx[k], sts[ch]->hTcxEnc->spectrum[k], q_spec, length ); + fixedToFloat_arrL32( inv_spectrum_fx[ch][k], inv_spectrum[ch][k], q_spec, length ); + fixedToFloat_arrL32( inv_mdst_spectrum_fx[ch][k], inv_mdst_spectrum[ch][k], q_spec, length ); + fixedToFloat_arrL32( mdst_spectrum_fx[ch][k], mdst_spectrum[ch][k], q_spec, length ); + free( inv_spectrum_fx[ch][k] ); + free( inv_mdst_spectrum_fx[ch][k] ); + free( mdst_spectrum_fx[ch][k] ); + } + } +#endif +#endif } /*--------------------------------------------------------------* @@ -404,6 +469,10 @@ void stereo_mdct_core_enc( sts[0]->side_bits_frame_channel -= SMDCT_NBBITS_SPLIT_RATIO; if ( !hStereoMdct->isSBAStereoMode ) { +#ifdef IVAS_FLOAT_FIXED + IF( hStereoMdct->hItd ) + hStereoMdct->hItd->itd_fx[1] = float_to_fix( hStereoMdct->hItd->itd[1], Q23 ); +#endif stereo_bits = write_stereo_to_bitstream( hStereoMdct, sts, ms_mask, 0, hBstr ); } else @@ -415,7 +484,25 @@ void stereo_mdct_core_enc( * Split available bits between channels *---------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED FindSplitRatio( hCPE, sts ); +#else +#if 1 + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX / ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + IF( sts[ch]->last_core == ACELP_CORE ) + { + L_subframeTCX += L_subframeTCX / 4; + } + FOR( n = 0; n <= ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ) - 1; n++ ) + { + f2me_buf( sts[ch]->hTcxEnc->spectrum[n], sts[ch]->hTcxEnc->spectrum_fx[n], &sts[ch]->hTcxEnc->spectrum_e[n], L_subframeTCX ); + } + } +#endif + FindSplitRatio_fx( hCPE, sts ); +#endif assert( hStereoMdct->split_ratio > 0 && hStereoMdct->split_ratio < SMDCT_BITRATE_RATIO_RANGE ); diff --git a/lib_enc/ivas_stereo_mdct_igf_enc.c b/lib_enc/ivas_stereo_mdct_igf_enc.c index d56e3d34dfcf8720f50316e651811acb8064e421..3294013434829ba3a4f10011e5c00b103d9078ad 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc.c @@ -35,21 +35,26 @@ #include "options.h" #include #include "prot.h" +#include "prot_fx2.h" #include "cnst.h" #include "stat_enc.h" #include "ivas_stat_enc.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" /*-------------------------------------------------------------------* * Local constants *-------------------------------------------------------------------*/ -#define IGF_PATCH_MS 1 -#define IGF_PATCH_LR 0 -#define TARGET_COH_THRESHOLD 0.6f -#define SOURCE_COH_THRESHOLD 0.7f -#define PANNING_THRESHOLD 0.07f +#define IGF_PATCH_MS 1 +#define IGF_PATCH_LR 0 +#define TARGET_COH_THRESHOLD 0.6f +#define TARGET_COH_THRESHOLD_FX 19661 +#define SOURCE_COH_THRESHOLD 0.7f +#define SOURCE_COH_THRESHOLD_FX 22938 +#define PANNING_THRESHOLD 0.07f +#define PANNING_THRESHOLD_FX 2294 /*-------------------------------------------------------------------* @@ -58,6 +63,7 @@ * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static float calcCoh( const float *sig1, const float *sig2, @@ -94,6 +100,68 @@ static float calcCoh( return coh; } +#else +static Word16 calcCoh_fx( // Q15 + const Word32 *sig1_fx, // Q( q_sig ) + const Word32 *sig2_fx, // Q( q_sig ) + const Word16 q_sig, + const Word16 nSamples, + Word32 *corr, + Word16 *corr_e, + Word16 *predCoeff, + Word16 *predCoeff_e ) +{ + Word32 ener1_fx, ener2_fx, cEner_fx, cc_fx; + Word16 coh_fx, coh_e; + Word16 q_ener1, q_ener2, q_cEner, q_cc; + + coh_fx = 0; + move16(); + Word16 gB = find_guarded_bits_fx( nSamples ); + q_ener1 = shl( q_sig, 1 ); + q_ener2 = q_ener1; + move16(); + q_cc = q_ener1; + move16(); + ener1_fx = dotp_fixed_o( sig1_fx, sig1_fx, nSamples, gB, &q_ener1 ); + ener2_fx = dotp_fixed_o( sig2_fx, sig2_fx, nSamples, gB, &q_ener2 ); + cEner_fx = Mpy_32_32( ener1_fx, ener2_fx ); + q_cEner = sub( 62, add( q_ener1, q_ener2 ) ); + cEner_fx = Sqrt32( cEner_fx, &q_cEner ); + q_cEner = sub( Q31, q_cEner ); + cc_fx = dotp_fixed_o( sig1_fx, sig2_fx, nSamples, gB, &q_cc ); + + IF( corr != NULL ) + { + *corr = cc_fx; + *corr_e = sub( Q31, q_cc ); + move16(); + move32(); + } + + IF( cEner_fx > 0 ) + { + coh_fx = BASOP_Util_Divide3232_Scale( cc_fx, cEner_fx, &coh_e ); + coh_e = add( coh_e, sub( q_cEner, q_cc ) ); + coh_fx = shl_sat( coh_fx, coh_e ); // Q15 + } + + IF( predCoeff != NULL ) + { + *predCoeff = 0; + move32(); + IF( ener1_fx > 0 ) + { + *predCoeff = BASOP_Util_Divide3232_Scale( cc_fx, ener1_fx, predCoeff_e ); + move32(); + *predCoeff_e = add( *predCoeff_e, sub( q_ener1, q_cc ) ); + move16(); + } + } + + return coh_fx; +} +#endif /*-------------------------------------------------------------------* @@ -102,6 +170,7 @@ static float calcCoh( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void IGF_MsStereoDecision( STEREO_MDCT_BAND_PARAMETERS *sfbParam, H_IGF_GRID hGrid, @@ -226,6 +295,164 @@ static void IGF_MsStereoDecision( return; } +#else +static void IGF_MsStereoDecision_fx( + STEREO_MDCT_BAND_PARAMETERS *sfbParam, + H_IGF_GRID hGrid, + const Word32 *specL_fx, + const Word32 *specR_fx, + Word16 q_spec, + Word16 *igfStereoMode, /* output*/ + Word16 *msMask, /* output*/ + const Word16 mdct_stereo_mode ) +{ + Word16 sfb; + Word16 msMaskTrueSomewhere, msMaskFalseSomewhere; + Word16 numMsMaskTrue, numMsMaskFalse, numMsMaskThresh, numMsMaskMSForLR; + Word16 tile_idx; + Word16 strt_cpy; + Word16 thresh; + + thresh = TARGET_COH_THRESHOLD_FX; + move16(); + + if ( EQ_16( mdct_stereo_mode, SMDCT_MS_FULL ) ) + { + thresh = 13762; /* lower threshold if core is already MS */ + move16(); + } + + FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ ) + { + strt_cpy = hGrid->sbWrap[tile_idx]; + move16(); + + FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ ) + { + Word16 width = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] ); + Word32 cc_src_fx, cc_target_fx; + Word16 cc_src_e, cc_target_e; + Word16 pc_target_fx, pc_src_fx; + Word16 pc_target_e, pc_src_e; + Word16 tmp1, tmp1_e, tmp2, tmp2_e; + + Word16 coh_src = calcCoh_fx( &specL_fx[strt_cpy], &specR_fx[strt_cpy], q_spec, width, &cc_src_fx, &cc_src_e, &pc_src_fx, &pc_src_e ); + Word16 coh_target = calcCoh_fx( &specL_fx[hGrid->swb_offset[sfb]], &specR_fx[hGrid->swb_offset[sfb]], q_spec, width, &cc_target_fx, &cc_target_e, &pc_target_fx, &pc_target_e ); + tmp1_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, negate( pc_src_fx ), pc_src_e, &tmp1 ); + tmp2_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, -16384, 1, &tmp2 ); + + strt_cpy = add( strt_cpy, width ); + IF( GT_16( abs_s( coh_target ), thresh ) ) + { + /* target is very coherent */ + IF( GT_16( abs_s( coh_src ), SOURCE_COH_THRESHOLD_FX ) ) + { + test(); + IF( LT_16( abs_s( shl_sat( tmp1, tmp1_e ) ), PANNING_THRESHOLD_FX ) && GT_16( abs_s( shl_sat( tmp2, tmp2_e ) ), 2 * PANNING_THRESHOLD_FX ) ) /* same position but not close to the MID */ + { + /* same for the source, stereo pos are close, stay on LR */ + msMask[sfb] = IGF_PATCH_LR; + move16(); + } + ELSE + { + msMask[sfb] = IGF_PATCH_MS; + move16(); + } + } + ELSE + { + /* we need to get the coherent patch, do MS */ + msMask[sfb] = IGF_PATCH_MS; + move16(); + } + } + ELSE + { + /* target is not coherent, stick to LR patching */ + msMask[sfb] = IGF_PATCH_LR; + move16(); + } + } + } + + msMaskTrueSomewhere = 0; + move16(); + msMaskFalseSomewhere = 0; + move16(); + numMsMaskTrue = 0; + move16(); + numMsMaskFalse = 0; + move16(); + numMsMaskThresh = shr( sub( sfbParam->sfbCnt, sfbParam->nBandsStereoCore ), 2 ); + numMsMaskMSForLR = 0; + move16(); + + FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ ) + { + FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ ) + { + SWITCH( msMask[sfb] ) + { + case IGF_PATCH_LR: + msMask[sfb] = 0; + move16(); + numMsMaskFalse = add( numMsMaskFalse, 1 ); + msMaskFalseSomewhere = 1; + move16(); + break; + case IGF_PATCH_MS: + msMask[sfb] = 1; + move16(); + numMsMaskTrue = add( numMsMaskTrue, 1 ); + msMaskTrueSomewhere = 1; + move16(); + break; + default: + assert( 0 ); + break; + } + } + } + + IF( msMaskTrueSomewhere ) + { + IF( msMaskFalseSomewhere ) + { + *igfStereoMode = SMDCT_BW_MS; + move16(); + + test(); + IF( LE_16( numMsMaskFalse, numMsMaskThresh ) ) + { + *igfStereoMode = SMDCT_MS_FULL; + move16(); + set_s( &msMask[0], 1, sub( sfbParam->sfbCnt, sfbParam->nBandsStereoCore ) ); + } + ELSE IF( LE_16( numMsMaskTrue, numMsMaskThresh ) && !numMsMaskMSForLR ) + { + *igfStereoMode = SMDCT_DUAL_MONO; + move16(); + set_s( &msMask[0], 0, sub( sfbParam->sfbCnt, sfbParam->nBandsStereoCore ) ); + } + } + ELSE + { + *igfStereoMode = SMDCT_MS_FULL; + move16(); + set_s( &msMask[0], 1, sub( sfbParam->sfbCnt, sfbParam->nBandsStereoCore ) ); + } + } + ELSE + { + *igfStereoMode = SMDCT_DUAL_MONO; + move16(); + set_s( &msMask[0], 0, sub( sfbParam->sfbCnt, sfbParam->nBandsStereoCore ) ); + } + + return; +} +#endif /*-------------------------------------------------------------------* @@ -234,6 +461,7 @@ static void IGF_MsStereoDecision( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void IGFEncStereoEncoder( STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ @@ -269,3 +497,43 @@ void IGFEncStereoEncoder( return; } +#else +void IGFEncStereoEncoder_fx( + STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ + const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ + const Word32 *mdctSpectrumL_fx, /* i : left spectrum */ + const Word32 *mdctSpectrumR_fx, /* i : right spectrum */ + Word16 q_mdctSpectrum, + Word16 *msMask, /* i/o: MS mask */ + Word16 *igfStereoMode, /* o : IGF stereo mode */ + const Word16 mdct_stereo_mode, /* i : MDCT stereo mode */ + const Word16 isTCX20, /* i : flag for indicating TCX20 */ + const Word16 isTransition /* i : flag for transtition */ +) +{ + Word16 igfGridIdx; + H_IGF_GRID hGrid; + + IF( isTransition && isTCX20 ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + move16(); + } + ELSE IF( isTCX20 ) + { + igfGridIdx = IGF_GRID_LB_NORM; + move16(); + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + move16(); + } + + hGrid = &hIGFEnc->igfData.igfInfo.grid[igfGridIdx]; + IGF_MsStereoDecision_fx( sfbParam, hGrid, mdctSpectrumL_fx, mdctSpectrumR_fx, q_mdctSpectrum, igfStereoMode, msMask + sfbParam->nBandsStereoCore, mdct_stereo_mode ); + + return; +} +#endif diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc.c index ea78be94ecf3dbcfa446ef6edd655332bd7f4087..54618a32a50c134218fde2f26c1a8d181c9b3b99 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc.c @@ -37,8 +37,10 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" +#include "prot_fx2.h" #include "prot.h" #include "prot_fx1.h" +#include "prot_fx_enc.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_enc.h" @@ -58,13 +60,29 @@ * Local function prototypes *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void convertToBwMS( const int16_t startLine, const int16_t stopLine, float x0[], float x1[], const float norm_fac ); +#else +static void convertToBwMS_fx( const Word16 startLine, const Word16 stopLine, Word32 x0[], Word32 x1[], const Word32 norm_fac ); +#endif +#ifndef IVAS_FLOAT_FIXED void convertToMS( const int16_t L_frame, float x0[], float x1[], const float norm_fac ); +#else +void convertToMS_fx( const Word16 L_frame, Word32 x0_fx[], Word32 x1_fx[], const Word32 norm_fac ); +#endif +#ifndef IVAS_FLOAT_FIXED static float GetChannelEnergyRatio( Encoder_State **st, const int16_t iFirstSubframe, const int16_t iLastSubframe, const uint8_t ratioInRmsDomain ); +#else +static Word16 GetChannelEnergyRatio_fx( Encoder_State **st, const Word16 iFirstSubframe, const Word16 iLastSubframe, const UWord8 ratioInRmsDomain ); +#endif +#ifndef IVAS_FLOAT_FIXED static void MsStereoDecision( STEREO_MDCT_BAND_PARAMETERS *sfbParam, float *specL, float *specR, float *specM, float *specS, int16_t *mdct_stereo_mode, int16_t *msMask, const int16_t nBitsAvailable ); +#else +static void MsStereoDecision_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, Word32 *specL_fx, Word32 *specR_fx, Word32 *specM_fx, Word32 *specS_fx, Word16 q_spec, Word16 *mdct_stereo_mode, Word16 *msMask, const Word16 nBitsAvailable ); +#endif /*-------------------------------------------------------------------* @@ -74,6 +92,7 @@ static void MsStereoDecision( STEREO_MDCT_BAND_PARAMETERS *sfbParam, float *spec * MDCT-stereo *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void dft_ana_init( DFT_ANA_HANDLE hDft_ana, /*i : DFT analysis handle */ const int32_t input_Fs /*i : Input sampling frequency */ @@ -108,20 +127,16 @@ static void dft_ana_init( return; } -#ifdef IVAS_FLOAT_FIXED -static void dft_ana_init_fx( +#else +static void dft_ana_init( DFT_ANA_HANDLE hDft_ana, /*i : DFT analysis handle */ const Word32 input_Fs /*i : Input sampling frequency */ ) { - Word16 div1; - /* input_Fs / 48000 */ - div1 = extract_l( Mpy_32_32_r( input_Fs, 44739 /* 1 / 48000 in Q31 */ ) ); - - hDft_ana->N = i_mult( STEREO_DFT_HOP_MAX_ENC, div1 ); - hDft_ana->NFFT = i_mult( STEREO_DFT_N_MAX_ENC, div1 ); - hDft_ana->dft_ovl = i_mult( STEREO_DFT_OVL_MAX, div1 ); - hDft_ana->dft_zp = i_mult( STEREO_DFT_ZP_MAX_ENC, div1 ); + hDft_ana->N = extract_l( Mpy_32_16_1( input_Fs, 656 ) ); + hDft_ana->NFFT = extract_l( Mpy_32_16_1( input_Fs, 1311 ) ); + hDft_ana->dft_ovl = extract_l( Mpy_32_16_1( input_Fs, 287 ) ); + hDft_ana->dft_zp = extract_l( Mpy_32_16_1( input_Fs, 185 ) ); hDft_ana->dft_trigo_32k_fx = dft_trigo_32k_fx; @@ -139,21 +154,42 @@ static void dft_ana_init_fx( } ELSE { - assert( EQ_32( input_Fs, 48000 ) ); + assert( input_Fs == 48000 ); hDft_ana->dft_trigo_fx = dft_trigo_48k_fx; hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_48k_STEP; hDft_ana->win_ana_fx = win_ana_48k_fx; } +#if 1 // TODO: To be removed later + hDft_ana->dft_trigo_32k = dft_trigo_32k; + if ( input_Fs == 16000 ) + { + hDft_ana->dft_trigo = dft_trigo_32k; + hDft_ana->win_ana = win_ana_16k; + } + else if ( input_Fs == 32000 ) + { + hDft_ana->dft_trigo = dft_trigo_32k; + hDft_ana->win_ana = win_ana_32k; + } + else + { + hDft_ana->dft_trigo = dft_trigo_48k; + hDft_ana->win_ana = win_ana_48k; + } +#endif + return; } #endif + /*-------------------------------------------------------------------* * write_itd_data() * * Bitstream writing of ITDs *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void write_itd_data( ITD_DATA_HANDLE hItd, /* i : ITD data handle */ BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ @@ -203,7 +239,58 @@ static void write_itd_data( } return; } +#else +static void write_itd_data_fx( + ITD_DATA_HANDLE hItd, /* i : ITD data handle */ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +) +{ + Word16 k_offset; + Word16 itd; + k_offset = 1; + move16(); + + push_next_indice( hBstr, ( hItd->itd[k_offset] != 0 ), STEREO_DFT_ITD_MODE_NBITS ); + + IF( hItd->itd_fx[k_offset] != 0 ) + { + itd = hItd->itd_index[k_offset]; + IF( GT_16( itd, 255 ) ) + { + itd = sub( itd, 256 ); + + IF( LT_16( itd, 20 ) ) + { + push_next_indice( hBstr, 1, 1 ); /* use Huffman*/ + push_next_indice( hBstr, 1, 1 ); /* negative */ + push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] ); + } + ELSE + { + push_next_indice( hBstr, 0, 1 ); /* don't use Huffman */ + push_next_indice( hBstr, 1, 1 ); /* negative */ + push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS - 1 ); + } + } + ELSE + { + IF( LT_16( itd, 20 ) ) + { + push_next_indice( hBstr, 1, 1 ); /* use Huffman*/ + push_next_indice( hBstr, 0, 1 ); /* positive */ + push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] ); + } + ELSE + { + /* don't use Huffman and positive*/ + push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS + 1 ); + } + } + } + return; +} +#endif /*-------------------------------------------------------------------* * stereo_coder_tcx() @@ -211,6 +298,7 @@ static void write_itd_data( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void stereo_coder_tcx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ @@ -418,14 +506,341 @@ void stereo_coder_tcx( return; } +#else +void stereo_coder_tcx_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], + /* i/o: MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], + /* i/o: inverse spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) + Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], + /* i/o: inverse MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + Word16 q_spec ) +{ + STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL; + Word32 nrgRatio_fx[CPE_CHANNELS]; + Word16 nrgRatio_e[CPE_CHANNELS]; + Word16 nonQNrgRatio_fx[CPE_CHANNELS]; // Q15 + Word16 k; + Word16 nSubframes, L_frameTCX; + Word16 nAvailBitsMS[NB_DIV]; + Word16 tmp, e_tmp; + push_wmops( "stereo_coder_tcx" ); + + + set16_fx( nAvailBitsMS, 0, NB_DIV ); + + nSubframes = ( sts[0]->core == TCX_20_CORE && sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV; + L_frameTCX = sts[0]->hTcxEnc->L_frameTCX / nSubframes; + + set16_fx( &ms_mask[0][0], 0, MAX_SFB ); + set16_fx( &ms_mask[1][0], 0, MAX_SFB ); + + IF( !mct_on ) + { + IF( EQ_16( sts[0]->core, sts[1]->core ) ) + { + FOR( k = 0; k < nSubframes; k++ ) + { + nonQNrgRatio_fx[k] = GetChannelEnergyRatio_fx( sts, k, k, 1 ); // Q15 + move16(); + + hStereoMdct->global_ild[k] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[k] ) ) ) ); + move16(); + nrgRatio_fx[k] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[k] ), hStereoMdct->global_ild[k], &nrgRatio_e[k] ) ); + move32(); + /*nonQNrgRatio[k] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[k] ) ); + nonQNrgRatio[k] = 1.0f / nonQNrgRatio[k] - 1.0f;*/ + // Not getting used further + } + } + ELSE + { + nonQNrgRatio_fx[0] = nonQNrgRatio_fx[1] = GetChannelEnergyRatio_fx( sts, 0, nSubframes - 1, 1 ); + move16(); + hStereoMdct->global_ild[0] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[0] ) ) ) ); + move16(); + nrgRatio_fx[0] = nrgRatio_fx[1] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[0] ), hStereoMdct->global_ild[0], &nrgRatio_e[0] ) ); /* nrgRatio = nrg[1]/nrg[0] */ + move32(); + nrgRatio_e[1] = nrgRatio_e[0]; + move16(); + /*nonQNrgRatio[0] = nonQNrgRatio[1] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[0] ) ); + nonQNrgRatio[0] = nonQNrgRatio[1] = 1.0f / nonQNrgRatio[0] - 1.0f;*/ + // Not getting used further + } + + FOR( k = 0; k < nSubframes; k++ ) + { + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), 1 ) && LT_16( k, ( EQ_16( sts[1]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) ) + { + L_frameTCX = add( sts[1]->hTcxEnc->L_frameTCX, ( ( sts[1]->last_core == 0 ) ? shr( sts[1]->hTcxEnc->L_frameTCX, 2 ) : 0 ) ); + L_frameTCX = idiv1616( L_frameTCX, ( sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV ); + + e_tmp = nrgRatio_e[k]; + tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); + tmp = shl( tmp, e_tmp ); + + v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); + v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); + } + ELSE IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), -1 ) && LT_16( k, EQ_16( sts[0]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) + { + L_frameTCX = add( sts[0]->hTcxEnc->L_frameTCX, EQ_16( sts[0]->last_core, 0 ) ? shr( sts[0]->hTcxEnc->L_frameTCX, 2 ) : 0 ); + L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV ); + + /* This operation is resulting in some high MLDs in fixed point. */ + v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); + v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); + } + } + } + + IF( + ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) ) || NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) || ( NE_16( sts[0]->last_core, sts[1]->last_core ) && ( EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) ) || EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) + { + hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO; + move16(); + hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO; + move16(); + + + IF( sts[0]->igf ) + { + hStereoMdct->IGFStereoMode[0] = SMDCT_DUAL_MONO; + move16(); + hStereoMdct->IGFStereoMode[1] = SMDCT_DUAL_MONO; + move16(); + } + hStereoMdct->sw_uncorr = 1; + move16(); + + pop_wmops(); + return; + } + ELSE /* decide based on signal */ + { + FOR( k = 0; k < nSubframes; k++ ) + { + IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + sfbConf = &hStereoMdct->stbParamsTCX20; + } + ELSE + { + sfbConf = &hStereoMdct->stbParamsTCX10; + } + IF( EQ_16( sts[0]->last_core, ACELP_CORE ) ) + { + sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; + } + + IF( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && !mct_on ) /* band-wise HF ILD alignment to increase channel compaction */ + { + Word16 sfb = 1; + move16(); + + test(); + WHILE( LT_16( sfb, sfbConf->nBandsStereoCore ) && LT_16( sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ), 12 ) ) + { + test(); + sfb = add( sfb, 1 ); /* find start offset */ + } + + FOR( sfb--; sfb < sfbConf->nBandsStereoCore; sfb++ ) /* start one SFB early for the fade-in */ + { + const Word16 startLine = sfbConf->sfbOffset[sfb]; + move16(); + const Word16 endLine = sfbConf->sfbOffset[sfb + 1]; + move16(); + const Word16 sfbWidth = sub( endLine, startLine ); + + nrgRatio_e[0] = nrgRatio_e[1] = sub( Q31, q_spec ); + move16(); + move16(); + + nrgRatio_fx[0] = sum2_32_fx( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[0] ); + move32(); + nrgRatio_fx[1] = sum2_32_fx( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[1] ); + move32(); + + test(); + IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] ) /* no TNS in either ch */ + { + Word32 tmp_fx; + Word16 tmp_e; + tmp_e = sub( Q31, q_spec ); + tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e ); + nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); + tmp_e = sub( Q31, q_spec ); + tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e ); + nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); + } + IF( ( nrgRatio_fx[0] > 0 ) && ( nrgRatio_fx[1] > 0 ) && BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1] ) ) + { + Word16 fTemp_e, tmp_e; + Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); + fTemp_e = sub( fTemp_e, 1 ); + nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[0], &tmp_e ); + move32(); + nrgRatio_e[0] = add( tmp_e, sub( fTemp_e, nrgRatio_e[0] ) ); + move16(); + nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); + move32(); + + nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[1], &tmp_e ); + move32(); + nrgRatio_e[1] = add( tmp_e, sub( fTemp_e, nrgRatio_e[1] ) ); + move16(); + nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); + move32(); + + nrgRatio_fx[0] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[0], sub( nrgRatio_e[0], 2 ) ) ); // max( 0.25f, min( 4.f, nrgRatio[0] ) ); + move32(); + nrgRatio_fx[1] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[1], sub( nrgRatio_e[1], 2 ) ) ); // Q29 + move32(); + nrgRatio_e[0] = Q2; + move16(); + nrgRatio_e[1] = Q2; + move16(); + + IF( ( LT_16( sfbWidth, 12 ) && LT_16( add( sfb, 1 ), sfbConf->nBandsStereoCore ) ) || GT_32( sts[0]->element_brate, IVAS_48k ) ) /* attenuate ILD alignment in the first SFB or at 64k */ + { + nrgRatio_fx[0] = BASOP_Util_fPow( nrgRatio_fx[0], nrgRatio_e[0], ONE_IN_Q29, 0, &nrgRatio_e[0] ); + move32(); + nrgRatio_fx[1] = BASOP_Util_fPow( nrgRatio_fx[1], nrgRatio_e[1], ONE_IN_Q29, 0, &nrgRatio_e[1] ); + move32(); + } + ELSE + { + nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); + move32(); + nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); + move32(); + } + + nrgRatio_fx[0] = L_shl( nrgRatio_fx[0], sub( nrgRatio_e[0], 1 ) ); // Q30 + move32(); + nrgRatio_fx[1] = L_shl( nrgRatio_fx[1], sub( nrgRatio_e[1], 1 ) ); // Q30 + move32(); + + + v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); + v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); + scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + + v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); + v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); + scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + } + } + } + + /* set mask to zero */ + set16_fx( &ms_mask[k][0], 0, MAX_SFB ); + IF( mct_on ) + { + nAvailBitsMS[k] = shl( sts[0]->bits_frame_channel, 1 ); + move16(); + } + ELSE + { + nAvailBitsMS[k] = sts[0]->bits_frame_nominal; + move16(); + } + + nAvailBitsMS[k] = sub( nAvailBitsMS[k], add( sts[0]->side_bits_frame_channel, sts[1]->side_bits_frame_channel ) ); + move16(); + + IF( EQ_16( nSubframes, 2 ) ) + { + nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX10 ); + move16(); + } + ELSE + { + nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX20 ); + move16(); + } + + nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); + move16(); + + MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], q_spec, &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] ); + + IF( sts[0]->igf ) + { + IGFEncStereoEncoder_fx( sfbConf, sts[0]->hIGFEnc, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], q_spec, &ms_mask[k][0], + &hStereoMdct->IGFStereoMode[k], hStereoMdct->mdct_stereo_mode[k], (Word16) EQ_16( sts[0]->core, TCX_20_CORE ), (Word16) EQ_16( sts[0]->last_core, ACELP_CORE ) ); + } + ELSE + { + hStereoMdct->IGFStereoMode[k] = hStereoMdct->mdct_stereo_mode[k]; + move16(); + } + IF( NE_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) || NE_16( hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) ) + { + + ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sfbConf->sfbCnt ); + + ms_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sfbConf->sfbCnt ); + + IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] ) + { + sts[0]->hTcxEnc->tns_ms_flag[k] = 1; + move16(); + sts[1]->hTcxEnc->tns_ms_flag[k] = 1; + move16(); + ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], inv_mdst_spectrum_fx[0][k], inv_mdst_spectrum_fx[1][k], -1 ); + + ms_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], sfbConf->sfbCnt ); + } + } + } /* for k */ + } + /* for bitrate switching determine correlation depending on m/s decision */ + { + Word16 ms_bands[2]; + Word16 sw_uncorr[2], sw_uncorr_mean; + FOR( k = 0; k < nSubframes; k++ ) + { + sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; + ms_bands[k] = sum_s( ms_mask[k], sfbConf->nBandsStereoCore ); + move16(); + sw_uncorr[k] = sub( 32767, div_s( ms_bands[k], sfbConf->nBandsStereoCore ) ); + move16(); + } + IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + sw_uncorr_mean = sw_uncorr[0]; + move16(); + } + ELSE + { + sw_uncorr_mean = add( shr( sw_uncorr[0], 1 ), shr( sw_uncorr[1], 1 ) ); + } + hStereoMdct->sw_uncorr = extract_l( GT_16( sw_uncorr_mean, 19661 ) ); + move16(); + } + + pop_wmops(); + return; +} +#endif + /*-------------------------------------------------------------------* * ms_processing() * * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ms_processing( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: Encoder state structure */ @@ -462,7 +877,47 @@ void ms_processing( return; } +#else +void ms_processing_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + const int16_t iSubframe, /* i : subframe number */ + Word32 x_0_fx[], + /* i/o: spectrum 1 */ // Q( q_x ) + Word32 x_1_fx[], + /* i/o: spectrum 1 */ // Q( q_x ) + Word16 maxSfb /* i : number of stereo frequency bands*/ +) +{ + Word16 sfb; + STEREO_MDCT_BAND_PARAMETERS *sfbConf; + sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; + + IF( sts[0]->last_core == ACELP_CORE ) + { + assert( EQ_16( sts[1]->last_core, ACELP_CORE ) ); + sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; + } + + if ( EQ_16( maxSfb, -1 ) ) + { + maxSfb = sfbConf->sfbCnt; + move16(); + } + + FOR( sfb = 0; sfb < maxSfb; sfb++ ) + { + IF( NE_16( ms_mask[iSubframe][sfb], 0 ) ) + { + convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_0_fx, x_1_fx, SQRT2_OVER_2_FIXED ); + } + } + + return; +} +#endif /*-------------------------------------------------------------------* * ms_inv_mask_processing() @@ -470,6 +925,7 @@ void ms_processing( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ms_inv_mask_processing( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: Encoder state structure */ @@ -521,6 +977,64 @@ void ms_inv_mask_processing( return; } +#else +void ms_inv_mask_processing_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + const Word16 iSubframe, /* i : subframe number */ + const Word32 x_0_fx[], + /* i : spectrum 1 */ // Q( q_x ) + const Word32 x_1_fx[], + /* i : spectrum 2 */ // Q( q_x ) + Word32 x_inv_0_fx[], + /* o : inverse spectrum 1 */ // Q( q_x ) + Word32 x_inv_1_fx[], + /* o : inverse spectrum 2 */ // Q( q_x ) + Word16 maxSfb /* i : number of stereo frequency bands*/ +) +{ + Word16 sfb; + STEREO_MDCT_BAND_PARAMETERS *sfbConf; + Word16 nSubframes, L_subframeTCX; + + nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; + L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); + sfbConf = ( sts[0]->core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; + + IF( EQ_16( sts[0]->last_core, ACELP_CORE ) ) + { + assert( EQ_16( sts[1]->last_core, ACELP_CORE ) ); + sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; + } + + IF( EQ_16( maxSfb, -1 ) ) + { + maxSfb = sfbConf->sfbCnt; + move16(); + } + + FOR( sfb = 0; sfb < maxSfb; sfb++ ) + { + mvl2l( &x_0_fx[sfbConf->sfbOffset[sfb]], &x_inv_0_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); + mvl2l( &x_1_fx[sfbConf->sfbOffset[sfb]], &x_inv_1_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); + + IF( EQ_16( ms_mask[iSubframe][sfb], 0 ) ) + { + convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_inv_0_fx, x_inv_1_fx, SQRT2_OVER_2_FIXED ); + } + } + + /* set rest of inverse spectrum to zero */ + IF( GT_16( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) ) + { + set_zero_fx( &x_inv_0_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) ); + set_zero_fx( &x_inv_1_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) ); + } + + return; +} +#endif /*-------------------------------------------------------------------* @@ -529,6 +1043,7 @@ void ms_inv_mask_processing( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED int16_t write_stereo_to_bitstream( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: Encoder state structure */ @@ -629,7 +1144,137 @@ int16_t write_stereo_to_bitstream( if ( hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS ) { - for ( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ ) + for ( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ ) + { + push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 ); + } + } + } + } + + return ( hBstr->nb_bits_tot - start_bits ); +} +#else +Word16 write_stereo_to_bitstream( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0)*/ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +) +{ + Word16 i, k, nSubframes; + UWord16 mdct_stereo_mode, stereo_mode_bits; + STEREO_MDCT_BAND_PARAMETERS *sfbConf; + Word16 start_bits = hBstr->nb_bits_tot; + move16(); + + if ( !mct_on ) + { + assert( ( EQ_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && EQ_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || ( EQ_16( hStereoMdct->mdct_stereo_mode[0], SMDCT_DUAL_MONO ) && EQ_16( hStereoMdct->mdct_stereo_mode[1], SMDCT_DUAL_MONO ) ) ); + } + + nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || NE_16( sts[0]->core, sts[1]->core ) ) ? NB_DIV : 1; + move16(); + sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; + move16(); + + IF( EQ_16( sts[0]->last_core, ACELP_CORE ) ) + { + assert( EQ_16( sts[1]->ini_frame, 0 ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ); + sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; + } + + IF( hStereoMdct->hItd != NULL ) + { + write_itd_data_fx( hStereoMdct->hItd, hBstr ); + } + + FOR( k = 0; k < nSubframes; k++ ) + { + mdct_stereo_mode = 0; + move16(); + stereo_mode_bits = 1; + move16(); + + SWITCH( hStereoMdct->mdct_stereo_mode[k] ) + { + case SMDCT_DUAL_MONO: + mdct_stereo_mode = 0; + move16(); + stereo_mode_bits = 1; + move16(); + BREAK; + case SMDCT_MS_FULL: + mdct_stereo_mode = 2; + move16(); + stereo_mode_bits = 2; + move16(); + BREAK; + case SMDCT_BW_MS: + mdct_stereo_mode = 3; + move16(); + stereo_mode_bits = 2; + move16(); + BREAK; + default: + assert( !"Not supported MDCT stereo mode\n" ); + } + + push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits ); + + IF( !mct_on ) + { + IF( EQ_16( sts[0]->core, sts[1]->core ) || ( k == 0 ) ) + { + push_next_indice( hBstr, hStereoMdct->global_ild[k], SMDCT_GLOBAL_ILD_BITS ); + } + } + + IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) ) + { + FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ ) + { + push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 ); + } + } + + IF( sts[0]->igf ) + { + mdct_stereo_mode = 0; + move16(); + stereo_mode_bits = 1; + move16(); + SWITCH( hStereoMdct->IGFStereoMode[k] ) + { + case SMDCT_DUAL_MONO: + mdct_stereo_mode = 0; + move16(); + stereo_mode_bits = 1; + move16(); + BREAK; + case SMDCT_MS_FULL: + mdct_stereo_mode = 2; + move16(); + stereo_mode_bits = 2; + move16(); + BREAK; + case SMDCT_BW_MS: + mdct_stereo_mode = 3; + move16(); + stereo_mode_bits = 2; + move16(); + BREAK; + default: + assert( !"Not supported MDCT stereo mode\n" ); + } + + push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits ); + + + IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) ) + { + FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ ) { push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 ); } @@ -637,8 +1282,9 @@ int16_t write_stereo_to_bitstream( } } - return ( hBstr->nb_bits_tot - start_bits ); + return sub( hBstr->nb_bits_tot, start_bits ); } +#endif /*-------------------------------------------------------------------* * Band-wise M/S stereo processing @@ -646,6 +1292,7 @@ int16_t write_stereo_to_bitstream( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void convertToBwMS( const int16_t startLine, /* i : start line of sfb */ const int16_t stopLine, /* i : stop line of sfb */ @@ -666,6 +1313,33 @@ static void convertToBwMS( return; } +#else +static void convertToBwMS_fx( + const Word16 startLine, /* i : start line of sfb */ + const Word16 stopLine, /* i : stop line of sfb */ + Word32 x0[], + /* i/o: mid/left channel coefficients */ /* Q_x */ + Word32 x1[], + /* i/o: side/right channel coefficients */ /* Q_x */ + const Word32 norm_fac /* i : normalization factor */ /* Q31 */ +) +{ + Word16 j; + Word32 tmpValue_fx; + + FOR( j = startLine; j < stopLine; j++ ) + { + tmpValue_fx = x0[j]; + move32(); + x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); + move32(); + x1[j] = Mpy_32_32( L_sub( tmpValue_fx, x1[j] ), norm_fac ); + move32(); + } + + return; +} +#endif /*-------------------------------------------------------------------* * convertToMS() @@ -673,6 +1347,7 @@ static void convertToBwMS( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void convertToMS( const int16_t L_frame, /* i : frame length */ float x0[], /* i/o: mid/left channel coefficients */ @@ -684,6 +1359,21 @@ void convertToMS( return; } +#else +void convertToMS_fx( + const Word16 L_frame, /* i : frame length */ + Word32 x0[], + /* i/o: mid/left channel coefficients */ // Q(q_x) + Word32 x1[], + /* i/o: side/right channel coefficients */ // Q(q_x) + const Word32 norm_fac /* i : normalization factor */ // Q31 +) +{ + convertToBwMS_fx( 0, L_frame, x0, x1, norm_fac ); + + return; +} +#endif /*-------------------------------------------------------------------* * SQ_gain_estimate_stereo() @@ -692,6 +1382,7 @@ void convertToMS( *-------------------------------------------------------------------*/ /*! r: SQ gain */ +#ifndef IVAS_FLOAT_FIXED static float SQ_gain_estimate_stereo( float xL[], /* i : L vector to quantize */ float xR[], /* i : R vector to quantize */ @@ -761,6 +1452,104 @@ static float SQ_gain_estimate_stereo( /* return gain */ return powf( 10.0f, 0.45f + 0.5f * offset ); } +#else +static Word32 SQ_gain_estimate_stereo_fx( // e_res + Word32 xL_fx[], + /* i : L vector to quantize */ // e_xL + Word16 e_xL, + Word32 xR_fx[], + /* i : R vector to quantize */ // e_xR + Word16 e_xR, + const Word16 nbitsSQ, /* i : number of bits targeted */ + const Word16 lg, /* i : vector size (2048 max) */ + Word16 *e_res ) +{ + Word16 i, q, iter, e_ener, e_tmp; + Word32 ener_fx, tmp_32, target_fx, fac_fx, offset_fx; + Word32 en_fx[N_MAX / 2]; // Q(26) + Word16 lg2, lg_4, lg2_4; + + lg_4 = shr( lg, 2 ); + lg2_4 = shl( lg_4, 1 ); + lg2 = shl( lg2_4, 2 ); + i = 0; + move16(); + + set32_fx( en_fx, 21474836 /* 0.01 in Q31 */, N_MAX / 2 ); + + /* energy of quadruples with 9dB offset */ + /* ignore that we may take no all lines into account, max. 3 lines at the upper end of the spectrum can be missed (if lg is not a multiple of 4, happens also in SQGain()*/ + + FOR( q = 0; q < lg_4; q++ ) + { + ener_fx = BASOP_Util_Add_Mant32Exp( 21474836, 0, Mpy_32_32( xL_fx[i], xL_fx[i] ), e_xL * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 1], xL_fx[i + 1] ), e_xL * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 2], xL_fx[i + 2] ), e_xL * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 3], xL_fx[i + 3] ), e_xL * 2, &e_ener ); + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + move32(); + en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) + move32(); + i = add( i, 4 ); + } + i = 0; + FOR( ; q < lg2_4; q++ ) + { + ener_fx = BASOP_Util_Add_Mant32Exp( 21474836, 0, Mpy_32_32( xR_fx[i], xR_fx[i] ), e_xR * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 1], xR_fx[i + 1] ), e_xR * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 2], xR_fx[i + 2] ), e_xR * 2, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 3], xR_fx[i + 3] ), e_xR * 2, &e_ener ); + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + move32(); + en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) + move32(); + i = add( i, 4 ); + } + + /* SQ scale: 4 bits / 6 dB per quadruple */ + target_fx = L_mult( 19660 /* 0.15 in Q17 */, sub( nbitsSQ, shr( lg2, 4 ) ) ); // Q(18) + fac_fx = 429496729; /* 12.8 in Q25 */ + move32(); + offset_fx = fac_fx; + move32(); + + /* find offset (0 to 128 dB with step of 0.125dB) */ + FOR( iter = 0; iter < 10; iter++ ) + { + fac_fx = L_shr( fac_fx, 1 ); + offset_fx = L_sub( offset_fx, fac_fx ); + ener_fx = 0; + move32(); + e_ener = 0; + move16(); + + FOR( i = 0; i < lg2_4; i++ ) + { + tmp_32 = L_sub( en_fx[i], offset_fx ); + e_tmp = 6; + move16(); + + /* avoid SV with 1 bin of amp < 0.5f */ + IF( GT_32( tmp_32, 10066329 ) ) + { + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, tmp_32, e_tmp, &e_ener ); + + /* if ener is above target -> break and increase offset */ + IF( L_shl_sat( ener_fx, sub( e_ener, Q13 ) ) > target_fx ) + { + offset_fx = L_add( offset_fx, fac_fx ); + BREAK; + } + } + } + } + + /* return gain */ + tmp_32 = L_add( 12539858, Mpy_32_16_1( offset_fx, 13606 ) ); // Q23 + + return BASOP_util_Pow2( tmp_32, Q8, e_res ); +} +#endif /*-------------------------------------------------------------------* * QuantSpecEstimateBits() @@ -768,6 +1557,7 @@ static float SQ_gain_estimate_stereo( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static int16_t QuantSpecEstimateBits( float *spec, float G, @@ -791,6 +1581,35 @@ static int16_t QuantSpecEstimateBits( return sqBits; } +#else +static Word16 QuantSpecEstimateBits_fx( + Word32 *spec_fx, + Word16 spec_e, + Word16 G_fx, + Word16 G_e, + const Word16 length, + const Word16 nBitsAvailable, + Word16 sqQ[] ) +{ + Word16 stop, sqBits, nEncoded; + Word16 lastnz; + + tcx_scalar_quantization_ivas_fx( spec_fx, spec_e, sqQ, length, G_fx, G_e, 16384, NULL, 1 ); + + stop = 0; + move16(); + + sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, length, &lastnz, &nEncoded, nBitsAvailable, &stop, 0, NULL ); + + if ( stop != 0 ) + { + sqBits = stop; + move16(); + } + + return sqBits; +} +#endif /*-------------------------------------------------------------------* * context_update() @@ -798,6 +1617,7 @@ static int16_t QuantSpecEstimateBits( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void context_update( HANDLE_RC_CONTEXT_MEM ctxSrc, HANDLE_RC_CONTEXT_MEM ctxTarget, @@ -813,6 +1633,24 @@ static void context_update( return; } +#else +static void context_update( + HANDLE_RC_CONTEXT_MEM ctxSrc, + HANDLE_RC_CONTEXT_MEM ctxTarget, + const Word16 endLine ) +{ + Word16 last_nz; + + /* check if last_nz of target is smaller than endLine, save and update */ + last_nz = s_max( ctxTarget->lastnz, endLine ); + + mvc2c( (UWord8 *) ctxSrc, (UWord8 *) ctxTarget, sizeof( RC_CONTEXT_MEM ) ); + ctxTarget->lastnz = last_nz; + move16(); + + return; +} +#endif /*-------------------------------------------------------------------* * GetChannelEnergyRatio() @@ -820,6 +1658,7 @@ static void context_update( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static float GetChannelEnergyRatio( Encoder_State **sts, /* i/o: Encoder state structure */ const int16_t iFirstSubframe, @@ -858,6 +1697,75 @@ static float GetChannelEnergyRatio( return ( nrg[0] + nrg[1] ) > 0 ? nrg[0] / ( nrg[0] + nrg[1] ) : -1.0f; } +#else +static Word16 GetChannelEnergyRatio_fx( // Q15 + Encoder_State **sts, /* i/o: Encoder state structure */ + const Word16 iFirstSubframe, + const Word16 iLastSubframe, + const UWord8 ratioInRmsDomain ) +{ + Word16 ch, n, i; + Word32 nrg_fx[2]; + Word16 nrg_e[2]; + + /* Calculate energies per channel */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + const Encoder_State *st = sts[ch]; + + Word16 nSubframes = NB_DIV; + move16(); + + if ( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + move16(); + } + + Word16 L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, sub( nSubframes, 1 ) ); + + if ( st->last_core == ACELP_CORE ) + { + L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); + } + assert( iFirstSubframe >= 0 && ( iFirstSubframe <= iLastSubframe ) ); + + nrg_fx[ch] = 0; + move32(); + nrg_e[ch] = 0; + move16(); + + FOR( n = iFirstSubframe; n <= s_min( nSubframes - 1, iLastSubframe ); n++ ) + { + FOR( i = 0; i < L_subframeTCX; i++ ) + { + nrg_fx[ch] = BASOP_Util_Add_Mant32Exp( nrg_fx[ch], nrg_e[ch], Mpy_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ), shl( st->hTcxEnc->spectrum_e[n], 1 ), &nrg_e[ch] ); + move32(); + } + } + IF( ratioInRmsDomain && nrg_fx[ch] ) + { + nrg_fx[ch] = Sqrt32( nrg_fx[ch], &nrg_e[ch] ); + move32(); + } + } + + IF( L_add_sat( nrg_fx[0], nrg_fx[1] ) ) + { + nrg_fx[1] = BASOP_Util_Add_Mant32Exp( nrg_fx[0], nrg_e[0], nrg_fx[1], nrg_e[1], &nrg_e[1] ); + move32(); + + IF( NE_16( nrg_e[1], nrg_e[0] ) ) + { + nrg_fx[0] = L_shr( nrg_fx[0], sub( nrg_e[1], nrg_e[0] ) ); + move32(); + } + return divide3232( nrg_fx[0], nrg_fx[1] ); + } + + return MIN_16; +} +#endif /*-------------------------------------------------------------------* * FindSplitRatio() @@ -865,6 +1773,7 @@ static float GetChannelEnergyRatio( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void FindSplitRatio( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ Encoder_State **sts /* i/o: Encoder state structure */ @@ -875,7 +1784,6 @@ void FindSplitRatio( /* Calculate split ratio and quantize it */ hCPE->hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels */ - ratio_float = GetChannelEnergyRatio( sts, 0, 1, highRateMdctStereo ); if ( ratio_float >= 0 ) @@ -896,6 +1804,45 @@ void FindSplitRatio( return; } +#else +void FindSplitRatio_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Encoder_State **sts /* i/o: Encoder state structure */ +) +{ + const UWord8 highRateMdctStereo = ( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) && sts[0]->hTcxEnc->enc_ste_pre_corr_past ? 0 : 1 ); + move16(); + Word16 ratio_fx; + + /* Calculate split ratio and quantize it */ + hCPE->hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels */ + move16(); + + ratio_fx = GetChannelEnergyRatio_fx( sts, 0, 1, highRateMdctStereo ); // Q15 + + IF( ratio_fx >= 0 ) + { + hCPE->hStereoMdct->split_ratio = round_fx( L_mult( SMDCT_BITRATE_RATIO_RANGE, ratio_fx ) ); + move16(); + /* Tuning to get closer to the optimal split ratio */ + IF( LT_32( L_mult0( 9, ratio_fx ), 8 * ONE_IN_Q15 ) && GT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE + ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) ) + { + hCPE->hStereoMdct->split_ratio = sub( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); + move16(); + } + IF( GT_32( L_mult0( 9, ratio_fx ), 1 * ONE_IN_Q15 ) && LT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE - ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) ) + { + hCPE->hStereoMdct->split_ratio = add( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); + move16(); + } + + hCPE->hStereoMdct->split_ratio = s_min( SMDCT_BITRATE_RATIO_RANGE - 1, s_max( 1, hCPE->hStereoMdct->split_ratio ) ); + move16(); + } + + return; +} +#endif /*-------------------------------------------------------------------* * MsStereoDecision() @@ -903,6 +1850,7 @@ void FindSplitRatio( * *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void MsStereoDecision( STEREO_MDCT_BAND_PARAMETERS *sfbParam, float *specL, @@ -1023,6 +1971,153 @@ static void MsStereoDecision( return; } +#else +static void MsStereoDecision_fx( + STEREO_MDCT_BAND_PARAMETERS *sfbParam, + Word32 *specL_fx, /* Q( q_spec ) */ + Word32 *specR_fx, /* Q( q_spec ) */ + Word32 *specM_fx, + /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */ + Word32 *specS_fx, + /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */ + Word16 q_spec, + Word16 *mdct_stereo_mode, /* output */ + Word16 *msMask, /* output */ + const Word16 nBitsAvailable ) +{ + Word16 length = sfbParam->sfbOffset[sfbParam->nBandsStereoCore]; + + Word16 bitsL, bitsR, bitsM, bitsS; + Word16 bitsBW, bitsLR, bitsMS; + Word16 sfb, i; + Word16 nMSOn; /* Number of MS active bands */ + Word16 quantSpecL[N_MAX]; + Word16 quantSpecR[N_MAX]; + Word16 quantSpecM[N_MAX]; + Word16 quantSpecS[N_MAX]; + RC_CONTEXT_MEM ctxMem[4]; + HANDLE_RC_CONTEXT_MEM ctxL, ctxR, ctxM, ctxS; + + set16_fx( quantSpecL, 0, N_MAX ); + set16_fx( quantSpecR, 0, N_MAX ); + set16_fx( quantSpecM, 0, N_MAX ); + set16_fx( quantSpecS, 0, N_MAX ); + + assert( GT_16( nBitsAvailable, 0 ) ); + + ctxL = &ctxMem[0]; + ctxR = &ctxMem[1]; + ctxM = &ctxMem[2]; + ctxS = &ctxMem[3]; + Word16 specL_e, specR_e, specM_e, specS_e, G_fx, G_e; + Word16 e_GLR; + Word32 GLR_fx; + + specL_e = sub( Q31, q_spec ); + specR_e = sub( Q31, q_spec ); + specM_e = sub( Q31, q_spec ); + specS_e = sub( Q31, q_spec ); + + GLR_fx = SQ_gain_estimate_stereo_fx( specL_fx, specL_e, specR_fx, specR_e, nBitsAvailable, length, &e_GLR ); + + FOR( i = 0; i < length; i++ ) + { + specM_fx[i] = Mpy_32_32( L_add( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec ) + move32(); + specS_fx[i] = Mpy_32_32( L_sub( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec ) + move32(); + } + + G_fx = extract_h( GLR_fx ); /* seems to be favourable to underestimate a bit */ + G_e = sub( e_GLR, 1 ); + + /* do the full spectrum estimates already here, as side effect we get the quantized spectra... */ + bitsLR = add( QuantSpecEstimateBits_fx( specL_fx, specL_e, G_fx, G_e, length, nBitsAvailable, quantSpecL ), QuantSpecEstimateBits_fx( specR_fx, specR_e, G_fx, G_e, length, nBitsAvailable, quantSpecR ) ); + bitsMS = add( QuantSpecEstimateBits_fx( specM_fx, specM_e, G_fx, G_e, length, nBitsAvailable, quantSpecM ), QuantSpecEstimateBits_fx( specS_fx, specS_e, G_fx, G_e, length, nBitsAvailable, quantSpecS ) ); + + /* clean-up MS scratch buffers */ + set32_fx( specM_fx, 0, length ); + set32_fx( specS_fx, 0, length ); + + nMSOn = 0; + move16(); + bitsBW = 0; + move16(); + + RCcontextMapping_encode2_estimate_bandWise_start( quantSpecL, length, nBitsAvailable, ctxL ); + RCcontextMapping_encode2_estimate_bandWise_start( quantSpecR, length, nBitsAvailable, ctxR ); + + bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start( quantSpecM, length, nBitsAvailable, ctxM ) ); + bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start( quantSpecS, length, nBitsAvailable, ctxS ) ); + + /*find_max_lastnz(ctxL,ctxR,ctxM,ctxS);*/ + + FOR( sfb = 0; sfb < sfbParam->nBandsStereoCore; sfb++ ) + { + const Word16 startline = sfbParam->sfbOffset[sfb]; + move16(); + const Word16 endline = sfbParam->sfbOffset[sfb + 1]; + move16(); + + bitsL = RCcontextMapping_encode2_estimate_bandWise( quantSpecL, startline, endline, ctxL ); + bitsR = RCcontextMapping_encode2_estimate_bandWise( quantSpecR, startline, endline, ctxR ); + bitsM = RCcontextMapping_encode2_estimate_bandWise( quantSpecM, startline, endline, ctxM ); + bitsS = RCcontextMapping_encode2_estimate_bandWise( quantSpecS, startline, endline, ctxS ); + + IF( LE_16( add( bitsM, bitsS ), add( bitsL, bitsR ) ) ) + { + msMask[sfb] = 1; + move16(); + nMSOn = add( nMSOn, 1 ); + context_update( ctxM, ctxL, endline ); + context_update( ctxS, ctxR, endline ); + bitsBW = add( bitsBW, add( bitsM, bitsS ) ); + } + ELSE + { + msMask[sfb] = 0; + move16(); + + context_update( ctxL, ctxM, endline ); + context_update( ctxR, ctxS, endline ); + bitsBW = add( bitsBW, add( bitsL, bitsR ) ); + } + } + + bitsBW = add( bitsBW, sfbParam->nBandsStereoCore ); /* Signaling bits */ + + IF( LT_16( bitsLR, bitsBW ) ) + { + nMSOn = 0; + move16(); + set16_fx( msMask, 0, sfbParam->sfbCnt ); + bitsBW = bitsLR; + move16(); + } + + IF( LT_16( bitsMS, bitsBW ) ) + { + nMSOn = sfbParam->nBandsStereoCore; + move16(); + set16_fx( msMask, 1, sfbParam->sfbCnt ); + } + + *mdct_stereo_mode = SMDCT_BW_MS; + move16(); + IF( EQ_16( nMSOn, sfbParam->nBandsStereoCore ) ) + { + *mdct_stereo_mode = SMDCT_MS_FULL; + move16(); + } + ELSE IF( nMSOn == 0 ) + { + *mdct_stereo_mode = SMDCT_DUAL_MONO; + move16(); + } + + return; +} +#endif /*-----------------------------------------------------------------------* @@ -1161,6 +2256,7 @@ void initMdctStereoEncData_fx( * initialize encoder mdct ITD handling structures *-----------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED ivas_error initMdctItdHandling( STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ const int32_t input_Fs /* i : input sampling rate */ @@ -1190,8 +2286,8 @@ ivas_error initMdctItdHandling( return IVAS_ERR_OK; } -#ifdef IVAS_FLOAT_FIXED -ivas_error initMdctItdHandling_fx( +#else +ivas_error initMdctItdHandling( STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ const Word32 input_Fs /* i : input sampling rate */ ) @@ -1214,9 +2310,12 @@ ivas_error initMdctItdHandling_fx( /*Initialize ITD parameters*/ stereo_enc_itd_init_fx( hStereoMdct->hItd ); +#if 1 // TODO: To be removed later + stereo_enc_itd_init( hStereoMdct->hItd ); +#endif /*Initialize DFT analysis parameters*/ - dft_ana_init_fx( hStereoMdct->hDft_ana, input_Fs ); + dft_ana_init( hStereoMdct->hDft_ana, input_Fs ); return IVAS_ERR_OK; } @@ -1227,6 +2326,7 @@ ivas_error initMdctItdHandling_fx( * destroy MDCT stereo handle *-------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void stereo_mdct_enc_destroy( STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */ ) @@ -1248,3 +2348,26 @@ void stereo_mdct_enc_destroy( return; } +#else +void stereo_mdct_enc_destroy( + STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */ +) +{ + IF( ( *hStereoMdct )->hDft_ana != NULL ) + { + free( ( *hStereoMdct )->hDft_ana ); + ( *hStereoMdct )->hDft_ana = NULL; + } + + IF( ( *hStereoMdct )->hItd != NULL ) + { + free( ( *hStereoMdct )->hItd ); + ( *hStereoMdct )->hItd = NULL; + } + + free( *hStereoMdct ); + *hStereoMdct = NULL; + + return; +} +#endif diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index c7ead90bc90e969ff40c070f4d5746c51cd2743a..1a333aaf7b28e596adfbcd53ba88d85b444f103b 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -513,6 +513,10 @@ ivas_error stereo_memory_enc( } st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; +#ifdef IVAS_FLOAT_FIXED + st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; + st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; +#endif set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); st->hTcxEnc->tfm_mem = 0.75f; diff --git a/lib_enc/long_enr_fx.c b/lib_enc/long_enr_fx.c index e7f141b5f33e59f6d88100f1677779ec71a322fa..05ea4ee26b164104fe0a262afbb19d1a28e8df2c 100644 --- a/lib_enc/long_enr_fx.c +++ b/lib_enc/long_enr_fx.c @@ -4,7 +4,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" #include "stl.h" #include "prot_fx1.h" /* Function prototypes */ @@ -17,6 +16,129 @@ * * Compute relative energy, long-term average total noise energy and total active speech energy *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_long_enr_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + Word16 high_lpn_flag, /* i : sp/mus LPN flag */ + FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ + const Word16 n_chan, /* i : number of channels */ + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ + const Word16 Etot_LR[] /* i : total channel energy LR channels */ + +) +{ + Word16 tmp; + Word16 alpha; + NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst; + + /*-----------------------------------------------------------------* + * Compute long term estimate of total noise energy + * and total active speech energy + *-----------------------------------------------------------------*/ + Word16 n; + IF( hFrontVad != NULL ) + { + IF( LT_16( hFrontVad[0]->ini_frame, 4 ) ) + { + FOR( n = 0; n < n_chan; n++ ) + { + hFrontVad[n]->lp_noise_fx = hFrontVad[n]->hNoiseEst->totalNoise_fx; + tmp = add( hFrontVad[n]->lp_noise_fx, 2560 ); + + IF( LT_16( hFrontVad[n]->lp_speech_fx, tmp ) ) + { + hFrontVad[n]->lp_speech_fx = tmp; + move16(); + } + } + } + ELSE + { + Word16 smooth_prev, smooth_curr; + + IF( LT_16( hFrontVad[0]->ini_frame, 150 ) ) + { + smooth_prev = 31130; + smooth_curr = 1638; + } + ELSE + { + smooth_prev = 32113; + smooth_curr = 655; + } + + FOR( n = 0; n < n_chan; n++ ) + { + hFrontVad[n]->lp_noise_fx = add( mult_r( smooth_prev, hFrontVad[n]->lp_noise_fx ), mult_r( smooth_curr, hFrontVad[n]->hNoiseEst->totalNoise_fx ) ); + + IF( localVAD_HE_SAD_LR[n] && !high_lpn_flag ) + { + IF( LT_16( sub( hFrontVad[n]->lp_speech_fx, Etot_LR[n] ), 2560 ) ) + { + hFrontVad[n]->lp_speech_fx = add( mult_r( 32113, hFrontVad[n]->lp_speech_fx ), mult_r( 655, Etot_LR[n] ) ); + } + ELSE + { + hFrontVad[n]->lp_speech_fx = sub( hFrontVad[n]->lp_speech_fx, 13 ); + } + } + } + } + FOR( n = 0; n < n_chan; n++ ) + { + hFrontVad[n]->hNoiseEst->Etot_last_fx = Etot_LR[n]; + move16(); + } + } + ELSE + { + IF( LT_16( st_fx->ini_frame, 4 ) ) + { + st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; + move16(); + tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/ + st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp ); + } + ELSE + { + /* if ( st->ini_frame < 150 ) { + st->lp_noise = 0.95f * st->lp_noise + 0.05f * st->totalNoise; + } else { + st->lp_noise = 0.98f * st->lp_noise + 0.02f * st->totalNoise; + } */ + alpha = 655; + move16(); /* 0.02 Q15 */ + if ( LT_16( st_fx->ini_frame, 150 ) ) /* should match HE_LT_CNT_INIT_FX */ + { + alpha = 1638; + move16(); /* 0.05 Q15 */ + } + st_fx->lp_noise_fx = noise_est_AR1_Qx( hNoiseEst->totalNoise_fx, st_fx->lp_noise_fx, alpha ); /* Q8 state, alpha in Q15 */ + + test(); + IF( ( localVAD_HE_SAD != 0 ) && ( high_lpn_flag == 0 ) ) + { + IF( LT_16( sub( st_fx->lp_speech_fx, Etot ), 2560 ) ) /* 10.0 in Q8 */ + { + /* st->lp_speech = 0.98f * st->lp_speech + 0.02f * Etot; */ + st_fx->lp_speech_fx = noise_est_AR1_Qx( Etot, st_fx->lp_speech_fx, 655 ); /* Q8 state, 0.02 in Q15 */ + } + ELSE + { + st_fx->lp_speech_fx = sub( st_fx->lp_speech_fx, 13 ); /* st->lp_speech = st->lp_speech - 0.05f; linear decay*/ + } + } + } + } + + /*-----------------------------------------------------------------* + * Initialize parameters for energy tracking and signal dynamics + *-----------------------------------------------------------------*/ + return; +} +#endif void long_enr_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 855d25ce587e629b1a2ea965b5e55e64347f2ff8..b8ce1a186e44d765812544415405b068d131b9cd 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -2007,3 +2007,1371 @@ void noise_est_fx( return; } +#ifdef IVAS_FLOAT_FIXED + +/*-----------------------------------------------------------------* + * noise_est_fx() + * + * Noise energy estimation (noise energy is updated in case of noise-only frame) + *-----------------------------------------------------------------*/ +void noise_est_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 old_pitch1, /* i : previous frame OL pitch[1] */ + const Word32 tmpN[], /* i : temporary noise update Q_new + QSCALE */ + const Word16 epsP_h[], /* i : msb prediction error energies Q_r-1 */ + const Word16 epsP_l[], /* i : msb prediction error energies Q_r-1 */ + const Word16 Etot, /* i : total channel E (see find_enr_fx.c) Q8 */ + const Word16 relE, /* i : (VA_CHECK addition) relative frame energy Q8? */ + const Word16 corr_shift, /* i : normalized correlation correction Q15 */ + const Word32 enr[], /* i : averaged energy over both subframes Q_new + Q_SCALE */ + Word32 fr_bands[], /* i : spectrum per critical bands of the current frame Q_new + Q_SCALE */ + Word16 *cor_map_sum, /* o : Q8 */ + Word16 *sp_div, /* o : Q_sp_div */ + Word16 *Q_sp_div, /* o : Q factor for sp_div */ + Word16 *non_staX, /* o : non-stationarity for sp/mus classifier */ + Word16 *loc_harm, /* o : multi-harmonicity flag for UV classifier */ + const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE -2 */ + Word16 *st_harm_cor_cnt, /* i/o : 1st harm correlation timer Q0 */ + const Word16 Etot_l_lp, /* i : Smoothed low energy Q8 */ + const Word16 Etot_v_h2, /* i : Energy variations Q8 */ + Word16 *bg_cnt, /* i : Background burst length timer Q0 */ + Word16 EspecdB[], /* i/o: log E spectrum (with f=0) of the current frame Q7 for multi harm */ + Word16 Q_new, /* i : SCaling of current frame */ + const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ + Word16 *sp_floor, /* o : noise floor estimate Q7 */ + Word16 S_map[], /* o : short-term correlation map Q7 */ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ + FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ + const Word16 ini_frame /* i : Frame number (init) */ +) +{ + Word16 alpha, alpha2, alpha2m1, alpham1; + Word16 cor_min, cor_max, num, den, ExpNum, ExpDen, noise_chartmp; + Word16 wtmp1, wtmp, ExpLmax, ExpLmax2, tmpExp, nchar_thr, cor_tmp; + Word16 i, tmp_pc, pc, th_eps; + Word32 th_sta, Lnum, Lden, non_sta, LepsP, Ltmpden; + Word16 e_ener, f_ener; + Word32 Ltmp, Ltmp1, Lsum_num, Lsum_den, *pt1, *pt2, Ltmp2, Lnon_sta2; + Word16 spec_div, noise_char; + Word16 log_enr16; + Word16 updt_step; /* Q15 */ + Word16 aE_bgd, sd1_bgd, bg_bgd2; + Word16 tn_ini; + Word16 epsP_0_2, epsP_0_2_ad, epsP_0_2_ad_lp_max; + Word16 epsP_2_16, epsP_2_16_dlp, epsP_2_16_dlp_max; + Word16 PAU, BG_1, NEW_POS_BG; + + Word16 haco_ev_max; + Word16 Etot_l_lp_thr; + Word16 comb_ahc_epsP, comb_hcm_epsP; + + Word16 enr_bgd, cns_bgd, lp_bgd, ns_mask; + Word16 lt_haco_mask, bg_haco_mask; + Word16 SD_1, SD_1_inv, bg_bgd3, PD_1, PD_2, PD_3, PD_4, PD_5; + + Word16 non_staB; /* Q8 */ + Word32 L_tmp_enr, L_tmp_ave_enr, L_tmp_ave_enr2; + Word16 tmp_Q; + Word16 tmp, tmp2; /* general temp registers */ + Word16 tmp_enr, tmp_floor; /* constants in Q8 */ + Word16 vad_bwidth_fx; /* vad ns control variabel for input bwidth from teh BWD */ + /* for DTX operation */ + Word16 vad_2nd_stage_fx; + + Word16 lim_Etot_fx; /* Q8 */ + Word16 lim_Etot_sq_fx; /* Q2 */ + Word16 st_E_var_est_fx; /* Q2 */ + NOISE_EST_HANDLE hNoiseEst; + SP_MUS_CLAS_HANDLE hSpMusClas; + hSpMusClas = st_fx->hSpMusClas; + /* Check if LR-VAD */ + IF( hFrontVad != NULL ) + { + hNoiseEst = hFrontVad->hNoiseEst; + } + ELSE + { + hNoiseEst = st_fx->hNoiseEst; + } + + GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*-----------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + vad_bwidth_fx = st_fx->input_bwidth; + move16(); + + /*st_fx->ener_RAT = 10.0f * (float)log10( mean(lf_E, 8));*/ + + IF( hFrontVad == NULL ) + { + if ( hSpMusClas != NULL ) + { + Ltmp = L_shr( lf_E[0], 3 ); + FOR( i = 1; i < 8; i++ ) + { + Ltmp = L_add( Ltmp, L_shr( lf_E[i], 3 ) ); + } + IF( LT_32( Ltmp, L_shl( 1, add( Q_new, Q_SCALE - 2 ) ) ) ) + { + hSpMusClas->ener_RAT_fx = 0; + // PMT("hSpMusClas->ener_RAT_fx = 0, that should be validated") + } + ELSE + { + Ltmp = L_max( Ltmp, (Word32) 1L ); /* make sure log2_norm_lc does not cause table reading out of bounds */ + e_ener = norm_l( Ltmp ); + f_ener = Log2_norm_lc( L_shl( Ltmp, e_ener ) ); + e_ener = sub( 30, e_ener ); + e_ener = sub( e_ener, sub( add( Q_new, QSCALE ), 2 ) ); + Ltmp = Mpy_32_16( e_ener, f_ener, LG10 ); + wtmp = round_fx( L_shl( Ltmp, 10 ) ); /*Q8*/ + + /* st_fx->ener_RAT /= (Etot + 0.01f); */ + wtmp1 = add( Etot, 3 ); /*3 is 0.01 in Q8 */ + /* st_fx->ener_RAT_fx = wtmp/wtmp1 */ + hSpMusClas->ener_RAT_fx = 0; + move16(); + IF( wtmp > 0 ) + { + hSpMusClas->ener_RAT_fx = 32767; + move16(); /*Q15*/ + if ( GE_16( wtmp1, wtmp ) ) + { + hSpMusClas->ener_RAT_fx = div_s( wtmp, wtmp1 ); /*Q15*/ /* wtmp1 gte than wtmp */ + } + } + } + } + } + /*-----------------------------------------------------------------* + * Set the threshold for eps & non_sta based on input sampling rate + * The reason is that in case of 8kHz sampling input, there is nothing + * between 4kHz-6.4kHz. In noisy conditions, this makes a fast + * transition even in noise-only parts, hence producing a "higher + * order" spectral envelope => the epsP ratio is much less effective. + *-----------------------------------------------------------------*/ + + IF( NE_16( vad_bwidth_fx, NB ) ) /* WB input */ + { + th_eps = TH_EPS16_FX; + move16(); /*Q11*/ + th_sta = TH_STA16_FX; + move16(); /*Q10 */ + cor_min = COR_MIN16_FX; + move16(); /*Q15*/ + cor_max = COR_MAX16_FX; + move16(); /*Q15*/ + } + ELSE /* NB input */ + { + th_eps = TH_EPS8_FX; + move16(); /* Q11 */ + th_sta = TH_STA8_FX; + move16(); /* Q10 */ + cor_min = COR_MIN8_FX; + move16(); + cor_max = COR_MAX8_FX; + move16(); + } + + + /*-----------------------------------------------------------------* + * Estimation of pitch stationarity + *-----------------------------------------------------------------*/ + + /* pc = abs(pit[0] - pitO) + abs(pit[1] - pit[0]) */ /* needed in signal_clas() */ + wtmp = abs_s( sub( st_fx->pitch[0], old_pitch1 ) ); + wtmp1 = abs_s( sub( st_fx->pitch[1], st_fx->pitch[0] ) ); + pc = add( wtmp, wtmp1 ); + + + Ltmp = L_deposit_h( corr_shift ); + Ltmp = L_mac( Ltmp, st_fx->voicing_fx[0], 10923 ); +#ifdef BASOP_NOGLOB + Ltmp = L_mac_o( Ltmp, st_fx->voicing_fx[1], 10923, &Overflow ); + wtmp = mac_ro( Ltmp, st_fx->voicing_fx[2], 10923, &Overflow ); +#else /* BASOP_NOGLOB */ + Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 10923 ); + wtmp = mac_r( Ltmp, st_fx->voicing_fx[2], 10923 ); +#endif /* BASOP_NOGLOB */ + + tmp_pc = pc; + move16(); + if ( LT_16( wtmp, cor_min ) ) + { + tmp_pc = TH_PC_FX; + move16(); /* low correlation -> probably inactive signal */ + } + + move16(); /* Update */ + + /*-----------------------------------------------------------------* + * Multi-harmonic analysis + *-----------------------------------------------------------------*/ + IF( hFrontVad == NULL ) + { + IF( st_fx->hSpMusClas != NULL ) + { + i = 0; + move16(); + *loc_harm = multi_harm_fx( EspecdB, hNoiseEst->old_S_fx, hNoiseEst->cor_map_fx, &hNoiseEst->multi_harm_limit_fx, st_fx->total_brate, + st_fx->bwidth, ( st_fx->hGSCEnc != NULL ) ? &hGSCEnc->cor_strong_limit : &i, &hSpMusClas->mean_avr_dyn_fx, &hSpMusClas->last_sw_dyn_fx, cor_map_sum, sp_floor, S_map ); + } + } + /*-----------------------------------------------------------------* + * Detection of frames with non-stationary spectral content + *-----------------------------------------------------------------*/ + + /* weighted sum of spectral changes per critical bands */ + Lsum_num = L_deposit_l( 0 ); + Lsum_den = L_deposit_l( 0 ); + + /* Find a proper scaling to prevent overflow, but acheiving good computation on low level signals */ + tmpExp = 0; + move16(); + ExpLmax = sub( 30, norm_l( fr_bands[10] ) ); + ExpLmax2 = sub( 30, norm_l( hNoiseEst->fr_bands2_fx[10] ) ); + tmpExp = s_max( tmpExp, sub( shl( s_max( ExpLmax, ExpLmax2 ), 1 ), s_min( ExpLmax, ExpLmax2 ) ) ); + FOR( i = 11; i <= st_fx->max_band; i++ ) + { + ExpLmax = sub( 30, norm_l( fr_bands[i] ) ); + ExpLmax2 = sub( 30, norm_l( hNoiseEst->fr_bands2_fx[i] ) ); + tmpExp = s_max( tmpExp, sub( shl( s_max( ExpLmax, ExpLmax2 ), 1 ), s_min( ExpLmax, ExpLmax2 ) ) ); + } + tmpExp = sub( tmpExp, 30 - 4 - 4 ); /* 4bits for internal summation and 4 bits for comparaison */ + + pt1 = fr_bands + 10; + pt2 = hNoiseEst->fr_bands2_fx + 10; + FOR( i = 10; i <= st_fx->max_band; i++ ) + { + Lnum = L_max( *pt1, *pt2 ); /* Don't need if anymore */ +#ifdef BASOP_NOGLOB + Lsum_den = L_add_o( Lsum_den, Lnum, &Overflow ); +#else /* BASOP_NOGLOB */ + Lsum_den = L_add( Lsum_den, Lnum ); +#endif /* BASOP_NOGLOB */ + Ltmpden = L_min( *pt1, *pt2 ); + if ( Ltmpden == 0 ) + { + Ltmpden = L_add( Ltmpden, 1 ); + } + ExpNum = sub( norm_l( Lnum ), 1 ); + num = extract_h( L_shl( Lnum, ExpNum ) ); + num = mult_r( num, num ); + ExpDen = norm_l( Ltmpden ); + den = extract_h( L_shl( Ltmpden, ExpDen ) ); + num = div_s( num, den ); + Ltmp = L_shr( num, add( sub( sub( shl( ExpNum, 1 ), ExpDen ), 15 + 1 ), tmpExp ) ); + Lsum_num = L_add( Lsum_num, Ltmp ); + + pt1++; + pt2++; + } + Lsum_den = L_shr( Lsum_den, tmpExp ); + + + /* calculation of spectral diversity */ + /* THR_SPDIV_FX = 5 , 1/5 Q15 = 6554 */ + spec_div = 0; + move16(); + if ( GT_32( Mult_32_16( Lsum_num, 6554 ), Lsum_den ) ) /* Qx+Q15+1-16 ==> Qx */ + { + spec_div = 1; + move16(); + } + + /* *sp_div = Lsum_num / (Lsum_den + 1e-5f); */ + ExpNum = sub( norm_l( Lsum_num ), 1 ); + num = extract_h( L_shl( Lsum_num, ExpNum ) ); + + Lsum_den = L_add( Lsum_den, 1 ); + + ExpDen = norm_l( Lsum_den ); + den = extract_h( L_shl( Lsum_den, ExpDen ) ); + + *sp_div = div_s( num, den ); + move16(); + + *Q_sp_div = add( 15, sub( ExpNum, ExpDen ) ); + move16(); + + /*-----------------------------------------------------------------* + * Detection of frames with high energy content in high frequencies + *-----------------------------------------------------------------*/ + + /* calculation of energy in first 10 critical bands */ + Ltmp = sum32_fx( &fr_bands[st_fx->min_band], sub( 10, st_fx->min_band ) ); + + /* calculation of energy in the rest of bands */ + Ltmp2 = sum32_fx( &fr_bands[10], sub( st_fx->max_band, 9 ) ); + +#ifdef BASOP_NOGLOB + wtmp = shl_o( 1, sub( add( Q_new, QSCALE ), 1 ), &Overflow ); +#else /* BASOP_NOGLOB */ + wtmp = shl( 1, sub( add( Q_new, QSCALE ), 1 ) ); +#endif /* BASOP_NOGLOB */ + test(); + IF( L_msu( Ltmp, 100, wtmp ) < 0 || L_msu( Ltmp2, 100, wtmp ) < 0 ) + { + noise_chartmp = 0; + move16(); + } + ELSE + { + /* ftemp2 /= ftemp */ + ExpNum = sub( norm_l( Ltmp2 ), 1 ); + num = extract_h( L_shl( Ltmp2, ExpNum ) ); + + ExpDen = norm_l( Ltmp ); + den = extract_h( L_shl( Ltmp, ExpDen ) ); + num = div_s( num, den ); +#ifdef BASOP_NOGLOB + noise_chartmp = extract_h( L_shr_o( num, add( sub( ExpNum, ExpDen ), 4 - 16 ), &Overflow ) ); /* Q11 */ +#else /* BASOP_NOGLOB */ + noise_chartmp = extract_h( L_shr( num, add( sub( ExpNum, ExpDen ), 4 - 16 ) ) ); /* Q11 */ +#endif /* BASOP_NOGLOB */ + } + + noise_chartmp = s_min( noise_chartmp, (Word16) 10 << 11 ); /* Q11 */ + + /* update LT value of the final parameter */ + /* *st_noise_char = M_ALPHA * *st_noise_char + (1-M_ALPHA) * noise_chartmp */ + hNoiseEst->noise_char_fx = mac_r( L_mult( M_ALPHA_FX, hNoiseEst->noise_char_fx ), ONE_MINUS_M_ALPHA, noise_chartmp ); + + + nchar_thr = THR_NCHAR_WB_FX; + move16(); /* 1.0 Q11 */ + if ( EQ_16( vad_bwidth_fx, NB ) ) + { + nchar_thr = THR_NCHAR_NB_FX; + move16(); /* 1.0 Q11 */ + } + + noise_char = 0; + move16(); + if ( GT_16( hNoiseEst->noise_char_fx, nchar_thr ) ) + { + noise_char = 1; + move16(); + } + + /* save the 2 last spectra per crit. bands for the future */ + Copy32( hNoiseEst->fr_bands1_fx, hNoiseEst->fr_bands2_fx, NB_BANDS ); + Copy32( fr_bands + NB_BANDS, hNoiseEst->fr_bands1_fx, NB_BANDS ); + + /*-----------------------------------------------------------------* + * Non-stationarity estimation for each band + * Handicap high E frames in average computing + *-----------------------------------------------------------------*/ + + /* set averaging factor */ + /* ftemp = relE; */ + /* if( ftemp < 0.0f ) { ftemp = 0.0f; } */ + tmp = s_max( relE, 0 ); /* Q8 */ + + /* alpha = 0.064f * ftemp + 0.75f; */ + Ltmp = Mult_32_16( (Word32) 137438953L, tmp ); /* Q31(.064)+Q8+1-16 --> Q24 */ + Ltmp = L_mac( Ltmp, 256, 24576 ); /* Q8+Q15(.75)+1 --> Q24 */ +#ifdef BASOP_NOGLOB + alpha = round_fx_o( L_shl_o( Ltmp, 7, &Overflow ), &Overflow ); /*Q24 +7 --> Q31 Q15*/ +#else /* BASOP_NOGLOB */ + alpha = round_fx( L_shl( Ltmp, 7 ) ); /*Q24 +7 --> Q31 Q15*/ +#endif /* BASOP_NOGLOB */ + + /*if( alpha > 0.999f { alpha = 0.999f;} */ + alpha = s_min( alpha, 32735 ); /*.999 in Q15*/ + alpham1 = negate( add( -32768, alpha ) ); /* 1.0 - alpha */ + /*--------------------------------------------------------------* + * during significant attacks, replace the LT energy by the + * current energy this will cause non_sta2 failures to occur in + * different frames than non_sta failures + *--------------------------------------------------------------*/ + + alpha2 = alpha; + move16(); + alpha2m1 = alpham1; + move16(); + IF( spec_div > 0 ) + { + alpha2 = 0; + move16(); + alpha2m1 = 32767; + move16(); + } + Lnon_sta2 = L_deposit_l( 1 << 10 ); + + non_sta = L_deposit_l( 1 << 10 ); + *non_staX = 0; + move16(); + non_staB = 0; + move16(); + + FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) + { + /* + 1.0f added to reduce sensitivity to non stationarity in low energies */ + /* tmp_enr = enr[i] + 1.0f; */ + tmp_Q = add( Q_new, Q_SCALE ); + Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ +#ifdef BASOP_NOGLOB + L_tmp_enr = L_add_o( enr[i], Ltmp, &Overflow ); /* enr scale dynamic */ + L_tmp_ave_enr = L_add_o( hNoiseEst->ave_enr_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ +#else /* BASOP_NOGLOB */ + L_tmp_enr = L_add( enr[i], Ltmp ); /* enr scale dynamic */ + L_tmp_ave_enr = L_add( hNoiseEst->ave_enr_fx[i], Ltmp ); /* ave__enr scale dynamic */ +#endif /* BASOP_NOGLOB */ + + IF( LE_32( non_sta, th_sta ) ) /* Just to limit the saturation */ + { + /* if( enr[i] > st_ave_enr2[i] ) */ + /* non_sta2 = non_sta2 * ((enr[i]+1) / (st_ave_enr2[i]+1)) */ + Lnum = L_max( L_tmp_enr, L_tmp_ave_enr ); + + /* else */ + /* non_sta2 = non_sta2 * ((st_ave_enr2[i]+1) / (enr[i]+1)) */ + Lden = L_min( L_tmp_enr, L_tmp_ave_enr ); + + ExpNum = sub( norm_l( Lnum ), 1 ); + num = extract_h( L_shl( Lnum, ExpNum ) ); + Lnum = L_shl( Lnum, ExpNum ); + ExpDen = norm_l( Lden ); + den = extract_h( L_shl( Lden, ExpDen ) ); + num = div_s( num, den ); + Ltmp = Mult_32_16( non_sta, num ); +#ifdef BASOP_NOGLOB + non_sta = L_shr_o( Ltmp, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ +#else /* BASOP_NOGLOB */ + non_sta = L_shr( Ltmp, sub( ExpNum, ExpDen ) ); /* Q10 */ +#endif /* BASOP_NOGLOB */ + } + + /* st->ave_enr[i] = alpha * st->ave_enr[i] + (1-alpha) * enr[i];*/ /* update long-term average */ + Ltmp = Mult_32_16( hNoiseEst->ave_enr_fx[i], alpha ); + Ltmp = L_add( Ltmp, Mult_32_16( enr[i], alpham1 ) ); + hNoiseEst->ave_enr_fx[i] = L_max( Le_min_scaled, Ltmp ); + move32(); + + /* calculation of another non-stationarity measure (following attacks) */ + /*if( non_sta2 <= th_sta ){ + tmp_ave2 = st->ave_enr2[i] + 1.0f; + if( tmp_enr > tmp_ave2 ){ + non_sta2 = non_sta2 * ( tmp_enr / tmp_ave2 ); + } else { + non_sta2 = non_sta2 * (tmp_ave2 / tmp_enr ); + } + } */ + + /* ave_enr2:: calculation of another non-stationarity measure (following attacks) */ + Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ + /*L_tmp_enr = L_add(enr[i] , Ltmp );*/ /* enr scale dynamic , done above */ +#ifdef BASOP_NOGLOB + L_tmp_ave_enr2 = L_add_o( hNoiseEst->ave_enr2_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ +#else + L_tmp_ave_enr2 = L_add( hNoiseEst->ave_enr2_fx[i], Ltmp ); /* ave__enr scale dynamic */ +#endif + IF( LE_32( Lnon_sta2, th_sta ) ) /* Just to limit the saturation */ + { + Lnum = L_max( L_tmp_enr, L_tmp_ave_enr2 ); + Lden = L_min( L_tmp_enr, L_tmp_ave_enr2 ); + + ExpNum = sub( norm_l( Lnum ), 1 ); + num = extract_h( L_shl( Lnum, ExpNum ) ); + Lnum = L_shl( Lnum, ExpNum ); + ExpDen = norm_l( Lden ); + den = extract_h( L_shl( Lden, ExpDen ) ); + num = div_s( num, den ); + Ltmp1 = Mult_32_16( Lnon_sta2, num ); +#ifdef BASOP_NOGLOB + Lnon_sta2 = L_shr_o( Ltmp1, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ +#else /* BASOP_NOGLOB */ + Lnon_sta2 = L_shr( Ltmp1, sub( ExpNum, ExpDen ) ); /* Q10 */ +#endif /* BASOP_NOGLOB */ + } + + /* st_ave_enr2[i] = (float)alpha2 * st_ave_enr2[i] + + (1.0f - alpha2) * (enr[i]) */ + Ltmp1 = Mult_32_16( hNoiseEst->ave_enr2_fx[i], alpha2 ); + Ltmp1 = L_add( Ltmp1, Mult_32_16( enr[i], alpha2m1 ) ); + hNoiseEst->ave_enr2_fx[i] = L_max( Le_min_scaled, Ltmp1 ); + move32(); + + /* calculation of non-stationarity measure for speech/music classification */ + IF( hFrontVad == NULL ) + { + test(); + test(); + IF( GE_16( i, START_BAND_SPMUS ) && LT_16( i, NB_BANDS_SPMUS + START_BAND_SPMUS ) && st_fx->hSpMusClas != NULL ) + { + /* log_enr = (float)ln_fx(enr[i]); */ + log_enr16 = noise_est_ln_q8_fx( enr[i], 0, tmp_Q ); + wtmp = abs_s( sub( log_enr16, hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] ) ); +#ifdef BASOP_NOGLOB + *non_staX = add_o( *non_staX, wtmp, &Overflow ); +#else /* BASOP_NOGLOB */ + *non_staX = add( *non_staX, wtmp ); +#endif /* BASOP_NOGLOB */ + move16(); /* Q8 */ + hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] = log_enr16; + move16(); + } + } + IF( GE_16( i, 2 ) && LE_16( i, 16 ) ) + { + IF( GE_16( ini_frame, 100 ) ) + { + /* calculate non-stationarity feature relative background */ + tmp_enr = noise_est_ln_q8_fx( enr[i], 1, tmp_Q ); /* 1.0f added */ + tmp_floor = LN_E_MIN_PLUS_ONE_FX; + move16(); /* non dynamic init constant in Q8 */ + tmp_floor = noise_est_ln_q8_fx( hNoiseEst->bckr_fx[i], 1, tmp_Q ); +#ifdef BASOP_NOGLOB + non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ +#else /* BASOP_NOGLOB */ + non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ +#endif /* BASOP_NOGLOB */ + } + ELSE /*ini_frame < 100*/ + { + /* calculate non-stationarity feature relative background */ + tmp_enr = noise_est_ln_q8_fx( enr[i], 1, tmp_Q ); /* 1.0f added */ + tmp_floor = LN_E_MIN_PLUS_ONE_FX; + move16(); /* non dynamic init constant in Q8 */ + tmp_floor = noise_est_ln_q8_fx( E_MIN_FX, 1, tmp_Q ); +#ifdef BASOP_NOGLOB + non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ +#else /* BASOP_NOGLOB */ + non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ +#endif /* BASOP_NOGLOB */ + } + } + + } /* end of band loop FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) */ + + IF( LT_16( Etot, -1280 ) ) + { + non_sta = L_deposit_l( 1024 ); /* 1.0 in Q10 */ + Lnon_sta2 = L_deposit_l( 1024 ); /* 1.0 in Q10 */ + } + + lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ + lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ + + if ( st_fx->ini_frame < 150 ) + { + /* Allow use of quicker filter during init - if needed */ + /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ + hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); + move16(); + /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ + hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); + move16(); + } + else + { + /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ + hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); + move16(); + /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ + hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); + move16(); + } + + st_E_var_est_fx = sub( hNoiseEst->Etot_sq_st_est_fx, extract_h( L_shl_r( L_mult( hNoiseEst->Etot_st_est_fx, hNoiseEst->Etot_st_est_fx ), 1 ) ) ); + + + /*-----------------------------------------------------------------* + * Count frames since last correlation or harmonic event + *-----------------------------------------------------------------*/ + + Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); + Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 ); + + test(); + test(); + *st_harm_cor_cnt = add( *st_harm_cor_cnt, 1 ); + if ( ( Etot > 0 ) && ( ( *loc_harm > 0 ) || ( GT_16( round_fx( Ltmp ), COR_MAX_NNE_FX ) ) ) ) + { + *st_harm_cor_cnt = 0; + move16(); + } + + IF( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ + ( GT_16( st_fx->ini_frame, 10 ) && + GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ + ) + { + *st_harm_cor_cnt = 1; + } + + if ( GT_16( *st_harm_cor_cnt, 1 ) && + GT_16( Etot, 7680 ) && /* 30.0f in Q8 */ + GT_16( st_E_var_est_fx, 32 ) /* 8.0f in Q2 */ + ) + { + + /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ + *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 1 ) ); + } + + + /*-----------------------------------------------------------------* + * Energy based pause length counter + *-----------------------------------------------------------------*/ + test(); + IF( ( *bg_cnt >= 0 ) && ( GT_16( sub( Etot, Etot_l_lp ), 1280 ) /*5.0 in Q8*/ ) ) + { + /* Possible speech burst */ + *bg_cnt = -1; + move16(); + } + ELSE + { + test(); + if ( EQ_16( *bg_cnt, -1 ) && ( LT_16( sub( Etot, Etot_l_lp ), 1280 ) ) /*5 in Q8*/ ) + { + /* Possible start of speech pause */ + *bg_cnt = 0; + move16(); + } + } + if ( *bg_cnt >= 0 ) + { + *bg_cnt = add( *bg_cnt, 1 ); + move16(); + } + + /*-----------------------------------------------------------------* + * Linear predition efficiency 0 to 2 order + *-----------------------------------------------------------------*/ + + /*epsP_0_2 = max(0 , min(8, epsP[0] / epsP[2])); */ + Ltmp = eps_quota_fx( epsP_h[0], epsP_l[0], + epsP_h[2], epsP_l[2], 12 ); /* Word32 Q12 */ + BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ +#ifdef BASOP_NOGLOB + epsP_0_2 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ +#else /* BASOP_NOGLOB */ + epsP_0_2 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ +#endif /* BASOP_NOGLOB */ + BASOP_SATURATE_WARNING_ON_EVS + + epsP_0_2 = s_max( 0, epsP_0_2 ); /* min value is 0 , Q12 */ + + + /* st->epsP_0_2_lp = 0.15f * epsP_0_2 + (1.0f-0.15f) * st->epsP_0_2_lp; */ + alpha = 4915; + move16(); /*0.15 in Q15 */ + hNoiseEst->epsP_0_2_lp_fx = noise_est_AR1_Qx( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx, alpha ); + + /* epsP_0_2_ad = (float) fabs(epsP_0_2 - st->epsP_0_2_lp ); */ + epsP_0_2_ad = abs_s( sub( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx ) ); /* Q12 */ + + /*if (epsP_0_2_ad < st->epsP_0_2_ad_lp) { + st->epsP_0_2_ad_lp = 0.1f * epsP_0_2_ad + (1.0f - 0.1f) * st->epsP_0_2_ad_lp; + } else { + st->epsP_0_2_ad_lp = 0.2f * epsP_0_2_ad + (1.0f - 0.2f) * st->epsP_0_2_ad_lp; + } */ + alpha = 6554; + move16(); /* 0.2 Q15 */ + if ( LT_16( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ) ) + { + alpha = shr( alpha, 1 ); /* 0.1 Q15 */ + } + hNoiseEst->epsP_0_2_ad_lp_fx = noise_est_AR1_Qx( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx, alpha ); + + /* epsP_0_2_ad_lp_max = max(epsP_0_2_ad,st->epsP_0_2_ad_lp);*/ + epsP_0_2_ad_lp_max = s_max( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ); /* Q12 */ + + + /*-----------------------------------------------------------------* + * Linear predition efficiency 2 to 16 order + *-----------------------------------------------------------------*/ + + /* epsP_2_16 = max(0 , min(8, epsP[2] / epsP[16])); */ + Ltmp = eps_quota_fx( epsP_h[2], epsP_l[2], + epsP_h[16], epsP_l[16], 12 ); /* Word32 Q12 */ + BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ +#ifdef BASOP_NOGLOB + epsP_2_16 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , + NB saturation in Q12 sets max value to 7,999 */ +#else /* BASOP_NOGLOB */ + epsP_2_16 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , + NB saturation in Q12 sets max value to 7,999 */ +#endif /* BASOP_NOGLOB */ + BASOP_SATURATE_WARNING_ON_EVS + + epsP_2_16 = s_max( 0, epsP_2_16 ); /* min value is 0 , Q12 */ + + + /* if (epsP_2_16 > st->epsP_2_16_lp){ + st->epsP_2_16_lp = 0.2f * epsP_2_16 + (1.0f-0.2f) * st->epsP_2_16_lp; + } else { + st->epsP_2_16_lp = 0.03f * epsP_2_16 + (1.0f-0.03f) * st->epsP_2_16_lp; + } + + st->epsP_2_16_lp2 = 0.02f * epsP_2_16 + (1.0f-0.02f) * st->epsP_2_16_lp2; */ + + alpha = 983; + move16(); /* 0.03 Q15 */ + if ( GT_16( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx ) ) + { + alpha = 6554; + move16(); /* 0.2 Q15 */ + } + hNoiseEst->epsP_2_16_lp_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx, alpha ); + + hNoiseEst->epsP_2_16_lp2_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp2_fx, 655 ); /* 0.02 */ + + epsP_2_16_dlp = sub( hNoiseEst->epsP_2_16_lp_fx, hNoiseEst->epsP_2_16_lp2_fx ); + + + /* if (epsP_2_16_dlp < st->epsP_2_16_dlp_lp2 ) { + st->epsP_2_16_dlp_lp2 = 0.02f * epsP_2_16_dlp + (1.0f-0.02f) * st->epsP_2_16_dlp_lp2; + } else { + st->epsP_2_16_dlp_lp2 = 0.05f * epsP_2_16_dlp + (1.0f-0.05f) * st->epsP_2_16_dlp_lp2; + }*/ + alpha = 1638; + move16(); /* 0.05 Q15 */ + if ( LT_16( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ) ) + { + alpha = 655; + move16(); /* 0.02 Q15 */ + } + hNoiseEst->epsP_2_16_dlp_lp2_fx = noise_est_AR1_Qx( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx, alpha ); + + /* epsP_2_16_dlp_max = max(epsP_2_16_dlp,st->epsP_2_16_dlp_lp2); */ + epsP_2_16_dlp_max = s_max( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ); + + /*-----------------------------------------------------------------* + * long term extensions of frame features + *-----------------------------------------------------------------*/ + + tmp = sub( Etot, hNoiseEst->totalNoise_fx ); /* Q8 */ + /* st->lt_tn_track = 0.03f* (Etot - st->totalNoise < 10) + 0.97f*st->lt_tn_track; */ + tmp2 = 0; + move16(); + if ( LT_16( tmp, 2560 ) ) /*10 in Q8 */ + { + tmp2 = 32767; + move16(); + } + hNoiseEst->lt_tn_track_fx = noise_est_AR1_Qx( tmp2, hNoiseEst->lt_tn_track_fx, 983 ); /*0.03 in Q15 ,Q15 state*/ + + /* st->lt_tn_dist = 0.03f* (Etot - st->totalNoise) + 0.97f*st->lt_tn_dist; */ + hNoiseEst->lt_tn_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_tn_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ + + /* st->lt_Ellp_dist = 0.03f* (Etot - st->Etot_l_lp) + 0.97f*st->lt_Ellp_dist;*/ + tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ + hNoiseEst->lt_Ellp_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_Ellp_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ + + + /* if (st->harm_cor_cnt == 0) { + st->lt_haco_ev = 0.03f*1.0 + 0.97f*st->lt_haco_ev; + } else { + st->lt_haco_ev = 0.99f*st->lt_haco_ev; + } */ + IF( *st_harm_cor_cnt == 0 ) + { + hNoiseEst->lt_haco_ev_fx = noise_est_AR1_Qx( (Word16) 32767, hNoiseEst->lt_haco_ev_fx, 983 ); /*.03 in Q15 , Q15 state */ + } + ELSE + { + hNoiseEst->lt_haco_ev_fx = mult_r( 32440, hNoiseEst->lt_haco_ev_fx ); /*.99 in Q15 , Q15 state */ + } + + + /* if (st->lt_tn_track < 0.05f) { + st->low_tn_track_cnt++; + } else { + st->low_tn_track_cnt=0; + }*/ + tmp = 0; + move16(); + move16(); + if ( LT_16( hNoiseEst->lt_tn_track_fx, 1638 ) ) /* 0.05 in Q15*/ + { + tmp = add( hNoiseEst->low_tn_track_cnt, 1 ); + } + hNoiseEst->low_tn_track_cnt = tmp; + move16(); + + + /* update of the long-term non-stationarity measure (between 0 and 1) */ + /* if ( (non_sta > th_sta) || (*loc_harm > 0) ) { + st->act_pred = M_GAMMA * st->act_pred + (1-M_GAMMA) * 1; + } else { + st->act_pred = M_GAMMA * st->act_pred + (1-M_GAMMA) * 0; + }*/ + Ltmp = L_mult( M_GAMMA_FX, hNoiseEst->act_pred_fx ); /*Q15*Q15+1 --> Q31 , 32440= .99 Q15 */ + tmp = round_fx( Ltmp ); /* Q15 */ + test(); + if ( ( GT_32( non_sta, th_sta ) ) /* float th_sta NB 5e10 , WB 3.5e10*/ + || ( *loc_harm > 0 ) ) + { + tmp = mac_r( Ltmp, ( -32768 + M_GAMMA_FX ), -32768 ); /* (-0.01)*(-1.0) */ + } + hNoiseEst->act_pred_fx = tmp; + move16(); + + + /*-----------------------------------------------------------------* + * Background noise adaptation enable flag + *-----------------------------------------------------------------*/ + Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); + Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 ); +#ifdef BASOP_NOGLOB + cor_tmp = mac_ro( Ltmp, corr_shift, MAX_16, &Overflow ); +#else /* BASOP_NOGLOB */ + cor_tmp = mac_r( Ltmp, corr_shift, MAX_16 ); +#endif + + LepsP = eps_quota_fx( epsP_h[2], epsP_l[2], + epsP_h[16], epsP_l[16], 11 ); /* L_epsP in Q11 */ + /* note this epsP2/eps16 is not limited to 8 as, epsP_2_16 is !! */ + + vad_2nd_stage_fx = 0; + move16(); /* background noise present - decrement counter */ + /* + if( ( (*st_harm_cor_cnt < 3*HC_CNT_SLOW ) + && ( ( non_sta > th_sta ) || + ( tmp_pc < TH_PC ) || + ( noise_char > 0) ) + ) + || + ( (st->ini_frame > 150) && (Etot - Etot_l_lp) > 10 ) || + ( 0.5f * (voicing[0]+voicing[1]) > cor_max ) || + ( epsP[2] / epsP[16] > th_eps ) || + ( *loc_harm > 0) || + ((st->act_pred > 0.8f) && (non_sta2 > th_sta)) + ) */ + + Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); /* Q15 + Q15(.5)) + 1 -> Q31 */ + cor_tmp = mac_r( Ltmp, st_fx->voicing_fx[1], 16384 ); /* Q31 -16 -> Q15 */ + if ( Etot < 0 ) + { + cor_tmp = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + if ( ( ( LT_16( *st_harm_cor_cnt, ( 3 * HC_CNT_SLOW_FX ) ) ) && ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || ( GT_16( noise_char, 0 ) ) ) ) || + ( ( GT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( sub( Etot, Etot_l_lp ), 2560 ) ) ) || + ( GT_16( cor_tmp, cor_max ) ) || /* Q15 */ + ( GT_32( LepsP, th_eps ) ) || /* Q11 */ + ( GT_16( *loc_harm, 0 ) ) || + ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) /*act_pred in Q15 , th_sta in Q10 */ + ) + { + vad_2nd_stage_fx = 1; + move16(); /* active signal present - increment counter */ + } + + tmp = 2; + move16(); /* Signal present */ + if ( vad_2nd_stage_fx == 0 ) + { + tmp = -1; + move16(); /* Background present */ + } + hNoiseEst->aEn = add( hNoiseEst->aEn, tmp ); + + + hNoiseEst->aEn = s_min( hNoiseEst->aEn, 6 ); + hNoiseEst->aEn = s_max( hNoiseEst->aEn, 0 ); + /*-----------------------------------------------------------------* + * Stereo classifier - save raw aEn + *-----------------------------------------------------------------*/ + + if ( hStereoClassif != NULL ) + { + /* + if ( ( non_sta > th_sta ) || + ( tmp_pc < TH_PC ) || + ( 0.5f * ( st->voicing[0] + st->voicing[1] ) > cor_max ) || + ( epsP[2] / epsP[16] > th_eps ) || + ( ( hNoiseEst->act_pred > 0.8f ) && ( non_sta2 > th_sta ) ) )*/ + if ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || + ( GT_16( cor_tmp, cor_max ) ) || + ( GT_32( LepsP, th_eps ) ) || + ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) ) /*act_pred in Q15 , th_sta in Q10 */ + { + /* active signal present - increment counter */ + hStereoClassif->aEn_raw[st_fx->idchan] = hStereoClassif->aEn_raw[st_fx->idchan] + 2; + } + else + { + /* background noise present - decrement counter */ + hStereoClassif->aEn_raw[st_fx->idchan] = hStereoClassif->aEn_raw[st_fx->idchan] - 1; + } + + if ( hStereoClassif->aEn_raw[st_fx->idchan] > 6 ) + { + hStereoClassif->aEn_raw[st_fx->idchan] = 6; + } + else if ( hStereoClassif->aEn_raw[st_fx->idchan] < 0 ) + { + hStereoClassif->aEn_raw[st_fx->idchan] = 0; + } + } + + + /* Additional NNE detectors */ + + /* comb_ahc_epsP = max(max(st->act_pred, st->lt_haco_ev), epsP_2_16_dlp); */ + /* Q15 Q15 Q12 */ + comb_ahc_epsP = s_max( s_max( shr( hNoiseEst->act_pred_fx, 15 - 12 ), shr( hNoiseEst->lt_haco_ev_fx, 15 - 12 ) ), epsP_2_16_dlp ); /* Q12 */ + + + /* comb_hcm_epsP = max(max(st->lt_haco_ev,epsP_2_16_dlp_max),epsP_0_2_ad_lp_max); */ + /* Q15 Q12 Q12 */ + comb_hcm_epsP = s_max( s_max( shr( hNoiseEst->lt_haco_ev_fx, 15 - 12 ), epsP_2_16_dlp_max ), epsP_0_2_ad_lp_max ); /* Q12 */ + + /*haco_ev_max = max(*st_harm_cor_cnt==0,st->lt_haco_ev); */ + tmp = 0; + move16(); + if ( *st_harm_cor_cnt == 0 ) + { + tmp = (Word16) 32767; + move16(); + } + haco_ev_max = s_max( tmp, hNoiseEst->lt_haco_ev_fx ); /* Q15 */ + + /* Etot_l_lp_thr = st->Etot_l_lp + (1.5f + 1.5f * (st->Etot_lp<50.0f))*st->Etot_v_h2; */ + tmp = 12288; + move16(); /* 1.5 Q13 */ + if ( LT_16( hNoiseEst->Etot_lp_fx, 12800 ) ) /* 50.0 in Q8 */ + { + tmp = shl( tmp, 1 ); /*1.5 + 1.5 Q13 */ + } + Ltmp = L_deposit_h( hNoiseEst->Etot_l_lp_fx ); + Etot_l_lp_thr = round_fx( L_add( Ltmp, L_shl( L_mult( tmp, Etot_v_h2 ), 2 ) ) ); /* Q13+Q8+1 +2 = Q24 -> Q8*/ + + /* enr_bgd = Etot < Etot_l_lp_thr; */ + enr_bgd = 0; + move16(); + if ( LT_16( Etot, Etot_l_lp_thr ) ) /* Q8 */ + { + enr_bgd = 1; + move16(); /* Q0 */ + } + + /* cns_bgd = (epsP_0_2 > 7.95f) && (non_sta< 1e3f); */ + cns_bgd = 0; + move16(); + test(); + if ( ( GT_16( epsP_0_2, 32563 ) ) /* 7.95 in Q12 */ + && ( LT_32( non_sta, 1024000L ) ) ) /* 1e3f in Q10 ? */ + { + cns_bgd = 1; + move16(); /* Q0 */ + } + + /*lp_bgd = epsP_2_16_dlp_max < 0.10f; */ + lp_bgd = 0; + move16(); + if ( LT_16( epsP_2_16_dlp_max, 410 ) ) /*0.10 Q12 */ + { + lp_bgd = 1; + move16(); /* Q0 */ + } + + + /* ns_mask = non_sta < 1e5f; */ + ns_mask = 0; + move16(); + if ( LT_32( non_sta, (Word32) 102400000L ) ) /* (1e5f in Q10)*/ + { + ns_mask = 1; + move16(); /* Q0 */ + } + + + /* lt_haco_mask = st->lt_haco_ev < 0.5f; */ + lt_haco_mask = 0; + move16(); + if ( LT_16( hNoiseEst->lt_haco_ev_fx, 16384 ) ) /* ( .5 in Q15)*/ + { + lt_haco_mask = 1; + move16(); /* Q0 */ + } + + /* bg_haco_mask = haco_ev_max < 0.4f; */ + bg_haco_mask = 0; + move16(); + if ( LT_16( haco_ev_max, 13107 ) ) /* ( 0.4 in Q15)*/ + { + bg_haco_mask = 1; + move16(); /* Q0 */ + } + + + /* SD_1 = ( (epsP_0_2_ad > 0.5f) && (epsP_0_2 > 7.95f) ); */ + SD_1 = 0; + move16(); + test(); + if ( ( GT_16( epsP_0_2_ad, 2048 ) ) /* 0.5 in Q12 */ + && ( GT_16( epsP_0_2, 32563 ) ) ) /* 7.95 in Q12 */ + { + SD_1 = 1; + move16(); /* Q0 */ + } + SD_1_inv = sub( 1, SD_1 ); /* Q0 */ + + /* NB "STL::test()"; has a cost of 2, using bitwise "s_and" , "s_or" at a cost of 1 */ + /* NB only lowest bit position is used, result is always 0 or 1 */ + + /* bg_bgd3 = enr_bgd || ( ( cns_bgd || lp_bgd ) && ns_mask && lt_haco_mask && SD_1==0 ); */ + tmp = s_and( s_and( s_and( s_or( cns_bgd, lp_bgd ), ns_mask ), lt_haco_mask ), SD_1_inv ); + bg_bgd3 = s_or( enr_bgd, tmp ); + + /*PD_1 = (epsP_2_16_dlp_max < 0.10f ) ; */ + PD_1 = 0; + move16(); + if ( ( LT_16( epsP_2_16_dlp_max, 410 ) ) ) /* 0.10 in Q12 */ + { + PD_1 = 1; + move16(); /* Q0 */ + } + + /*PD_2 = (epsP_0_2_ad_lp_max < 0.10f ) ; */ + PD_2 = 0; + move16(); + if ( ( LT_16( epsP_0_2_ad_lp_max, 410 ) ) ) /* 0.10 in Q12 */ + { + PD_2 = 1; + move16(); /* Q0 */ + } + + /*PD_3 = (comb_ahc_epsP < 0.85f ); */ + PD_3 = 0; + move16(); + if ( ( LT_16( comb_ahc_epsP, 3482 ) ) ) /* 0.85 in Q12 */ + { + PD_3 = 1; + move16(); /* Q0 */ + } + + /* PD_4 = comb_ahc_epsP < 0.15f; */ + PD_4 = 0; + move16(); + if ( ( LT_16( comb_ahc_epsP, 614 ) ) ) /* 0.15 in Q12 */ + { + PD_4 = 1; + move16(); /* Q0 */ + } + + /*PD_5 = comb_hcm_epsP < 0.30f; */ + PD_5 = 0; + move16(); + if ( ( LT_16( comb_hcm_epsP, 1229 ) ) ) /* 0.30 in Q12 */ + { + PD_5 = 1; + move16(); /* Q0 */ + } + + /* BG_1 = ( (SD_1==0) || (Etot < Etot_l_lp_thr) ) + && bg_haco_mask && (st->act_pred < 0.85f) && (st->Etot_lp < 50.0f); */ + BG_1 = 0; + move16(); + test(); + test(); + test(); + test(); + if ( ( ( SD_1 == 0 ) || ( LT_16( Etot, Etot_l_lp_thr ) ) ) && ( bg_haco_mask != 0 ) && ( LT_16( hNoiseEst->act_pred_fx, 27853 ) ) /* 0.85f in Q15 */ + && ( LT_16( hNoiseEst->Etot_lp_fx, 50 * 256 ) ) ) /* 50.0 in Q8 */ + { + BG_1 = 1; + move16(); + } + + /* PAU = (st->aEn==0) + || ( (Etot < 55.0f) && (SD_1==0) + && ( ( PD_3 && (PD_1 || PD_2 ) ) || ( PD_4 || PD_5 ) ) ); */ + PAU = 0; + move16(); /*Q0*/ + if ( hNoiseEst->aEn == 0 ) + { + PAU = 1; + move16(); /*Q0*/ + } + tmp = 0; + move16(); /*Q0*/ + if ( LT_16( Etot, 55 * 256 ) ) /*55.0 in Q8 */ + { + tmp = 1; + move16(); /*Q0*/ + } + tmp = s_and( tmp, SD_1_inv ); + PAU = s_or( PAU, s_and( tmp, s_or( s_and( PD_3, s_or( PD_1, PD_2 ) ), s_or( PD_4, PD_5 ) ) ) ); + + + /* NEW_POS_BG = (PAU | BG_1) & bg_bgd3; note bitwise logic in float */ + NEW_POS_BG = s_and( s_or( PAU, BG_1 ), bg_bgd3 ); + + /* Original silence detector works in most cases */ + /* aE_bgd = (st->aEn == 0);*/ + aE_bgd = 0; + move16(); + if ( hNoiseEst->aEn == 0 ) + { + aE_bgd = 1; + move16(); + } + + + /* When the signal dynamics is high and the energy is close to the background estimate */ + /* sd1_bgd = (st->sign_dyn_lp > 15) + && (Etot - st->Etot_l_lp ) < 2*st->Etot_v_h2 + && st->harm_cor_cnt > 20; */ + sd1_bgd = 0; + move16(); + test(); + test(); + if ( ( GT_16( hNoiseEst->sign_dyn_lp_fx, 15 * 256 ) ) /* 15 in Q8 */ + && ( LT_16( sub( Etot, hNoiseEst->Etot_l_lp_fx ), shl( Etot_v_h2, 1 ) ) ) /* Q8 , Etot_v_h2 has limited dynmics can be upscaled*/ + && ( GT_16( *st_harm_cor_cnt, 20 ) ) ) + { + sd1_bgd = 1; + move16(); + } + + /* tn_ini = st->ini_frame < 150 && st->harm_cor_cnt > 5 && + ( (st->act_pred < 0.59f && st->lt_haco_ev <0.23f ) || + st->act_pred < 0.38f || + st->lt_haco_ev < 0.15f || + non_staB < 50.0f || + aE_bgd );*/ + + tmp = 0; + move16(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ + || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ + || ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ + || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ + || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ + && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ + && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ + ) ) + { + tmp = 1; + move16(); + } + + tn_ini = 0; + move16(); + test(); + test(); + if ( ( LT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( hNoiseEst->harm_cor_cnt, 5 ) ) /* > 5 Q0 */ + && ( LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) /* 7 in Q8 */ + && ( NE_16( tmp, 0 ) ) ) + { + tn_ini = 1; + move16(); + } + + /* Energy close to the background estimate serves as a mask for other background detectors */ + /* bg_bgd2 = Etot < Etot_l_lp_thr || tn_ini ; */ + bg_bgd2 = 0; + move16(); + test(); + if ( ( LT_16( Etot, Etot_l_lp_thr ) ) || ( tn_ini != 0 ) ) + { + bg_bgd2 = 1; + move16(); /* Q0 */ + } + + updt_step = 0; + move16(); /* Q15 */ + /*if (( bg_bgd2 && ( aE_bgd || sd1_bgd || st->lt_tn_track >0.90f || NEW_POS_BG ) ) + || tn_ini ) */ + tmp = 0; + move16(); + if ( GT_16( hNoiseEst->lt_tn_track_fx, 29491 ) ) /* .90 in Q15 */ + { + tmp = 1; + move16(); + } + + IF( s_or( s_and( bg_bgd2, s_or( aE_bgd, s_or( sd1_bgd, s_or( tmp, NEW_POS_BG ) ) ) ), tn_ini ) ) + { + /*if( ( ( st->act_pred < 0.85f ) + && (aE_bgd !=0) + && ( st->lt_Ellp_dist < 10 || sd1_bgd ) + && (st->lt_tn_dist<40) + && ( ( Etot - st->totalNoise ) < 10.0f ) + ) + || ( (st->first_noise_updt == 0) && (st->harm_cor_cnt > 80) && (aE_bgd!=0) && (st->lt_aEn_zero > 0.5f) ) + || ( (tn_ini!=0) && ( aE_bgd != 0) || (non_staB < 10.0) || (st->harm_cor_cnt > 80) ) + )*/ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); /* for the ELSE IF below*/ + test(); + test(); + test(); + test(); + test(); + test(); /* for the ELSE IF below*/ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( LT_16( hNoiseEst->act_pred_fx, 27853 ) ) /* 0.85 in Q15 */ + && ( NE_16( aE_bgd, 0 ) ) && ( ( LT_16( hNoiseEst->lt_Ellp_dist_fx, 10 * 256 ) ) || ( NE_16( sd1_bgd, 0 ) ) ) /* 10.0 in Q8*/ + && ( LT_16( hNoiseEst->lt_tn_dist_fx, 40 * 256 ) ) /* 40.0 in Q8*/ + && ( LT_16( sub( Etot, hNoiseEst->totalNoise_fx ), 10 * 256 ) ) /* 10.0 in Q8*/ + ) || + ( ( hNoiseEst->first_noise_updt == 0 ) && ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) && ( aE_bgd != 0 ) && ( GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 ) ) /*.5 in Q15*/ + ) || + ( ( tn_ini != 0 ) && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 10 * 256 ) ) || ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) ) /* 10.0 in Q8*/ + ) ) + + { + updt_step = 32767; + move16(); + hNoiseEst->first_noise_updt = 1; + FOR( i = 0; i < NB_BANDS; i++ ) + { + hNoiseEst->bckr_fx[i] = tmpN[i]; + move32(); + } + } + /* else if ( ( ( st->act_pred < 0.80f ) && ( aE_bgd || PAU ) && st->lt_haco_ev < 0.10f ) + || ( ( st->act_pred < 0.70f ) && ( aE_bgd || non_staB < 17.0f ) && PAU && st->lt_haco_ev < 0.15f ) + || ( st->harm_cor_cnt > 80 && st->totalNoise > 5.0f && Etot < max(1.0f,Etot_l_lp + 1.5f* st->Etot_v_h2) ) + || + ( st->harm_cor_cnt > 50 && st->first_noise_updt > 30 && aE_bgd && st->lt_aEn_zero>0.5f ) + || tn_ini + ) */ + ELSE IF( ( ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* .8 in Q15*/ + && ( ( aE_bgd != 0 ) || ( PAU != 0 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 3277 ) ) ) /* .10 in q15*/ + || ( ( LT_16( hNoiseEst->act_pred_fx, 22938 ) ) /* 0.70 in Q15 */ + && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 17 * 256 ) ) ) /* 17.0 in Q8 */ + && ( PAU != 0 ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) /* 0.15 in Q15 */ + ) || + ( ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) && ( GT_16( hNoiseEst->totalNoise_fx, 5 * 256 ) ) /* 5.0 in Q8 */ + && ( LT_16( Etot, s_max( (Word16) 1 * 256, add( Etot_l_lp, add( hNoiseEst->Etot_v_h2_fx, shr( hNoiseEst->Etot_v_h2_fx, 1 ) ) ) ) ) ) /* 1.5= 1.0+.5 */ + ) || + ( ( GT_16( hNoiseEst->harm_cor_cnt, 50 ) ) && ( GT_16( hNoiseEst->first_noise_updt, 30 ) ) && ( aE_bgd != 0 ) && ( GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 ) ) ) /*.5 in Q15*/ + || ( tn_ini != 0 ) ) + + { + updt_step = 3277; + move16(); /* 0.1 in Q15 */ + /* if ( !aE_bgd && st->harm_cor_cnt < 50 + && ( (st->act_pred > 0.6f) + || ( (tn_ini==0) && (Etot_l_lp - st->totalNoise < 10.0f) && non_staB > 8.0f ) + ) + ) + */ + test(); + test(); + test(); + test(); + test(); + IF( ( aE_bgd == 0 ) && ( LT_16( hNoiseEst->harm_cor_cnt, 50 ) ) && ( ( GT_16( hNoiseEst->act_pred_fx, 19661 ) ) /* 0.6 in Q15*/ + || ( ( tn_ini == 0 ) && ( LT_16( sub( Etot_l_lp, hNoiseEst->totalNoise_fx ), 10 * 256 ) ) /* 10.0 in Q8 */ + && ( GT_16( non_staB, 8 * 256 ) ) /* 8.0 in in Q8*/ + ) ) ) + { + updt_step = 328; + move16(); /* 0.01 Q15 */ + } + /* + IF (updt_step > 0 ) + { + */ + hNoiseEst->first_noise_updt = 1; + move16(); + FOR( i = 0; i < NB_BANDS; i++ ) + { + /* st->bckr[i] = st->bckr[i] + updt_step * (tmpN[i]-st->bckr[i]);*/ + /* 32 bit state update */ + Ltmp = L_sub( tmpN[i], hNoiseEst->bckr_fx[i] ); /*Q_new+Q_SCALE*/ + Ltmp = Mult_32_16( Ltmp, updt_step ); /* Q_new+Q_SCALE+15+1 -16*/ + hNoiseEst->bckr_fx[i] = L_add( Ltmp, hNoiseEst->bckr_fx[i] ); + move32(); + } + /* + } */ + } + /*else if (aE_bgd || st->harm_cor_cnt > 100 )*/ + ELSE IF( ( aE_bgd != 0 ) || ( GT_16( hNoiseEst->harm_cor_cnt, 100 ) ) ) + { + hNoiseEst->first_noise_updt = add( hNoiseEst->first_noise_updt, 1 ); + } + } + ELSE + { + /* If in music lower bckr to drop further */ + test(); + test(); + IF( ( GT_16( hNoiseEst->low_tn_track_cnt, 300 ) ) && ( GT_16( hNoiseEst->lt_haco_ev_fx, 29491 ) ) /*.9 in Q15 */ + && ( hNoiseEst->totalNoise_fx > 0 ) ) + { + updt_step = -655; + move16(); /* for debug purposes */ + FOR( i = 0; i < NB_BANDS; i++ ) + { + IF( GT_32( hNoiseEst->bckr_fx[i], L_shl( Le_min_scaled, 1L ) ) ) /* 2*E_MIN(float) in float, here we use 2*Le_min_scaled Q_new+Q_SCALE */ + { + /* st->bckr[i] = 0.98f*st->bckr[i]; */ + hNoiseEst->bckr_fx[i] = Mult_32_16( hNoiseEst->bckr_fx[i], 32113 ); /* .98 in Q15 */ + move32(); /* move to array */ + } + } + } + /*st->lt_aEn_zero = 0.2f * (st->aEn==0) + (1-0.2f) *st->lt_aEn_zero;*/ + /* y(n+1)= alpha*tmp + (1-alpha)*y(n) */ + tmp = 0; + move16(); + if ( hNoiseEst->aEn == 0 ) + { + tmp = 32767; + move16(); + } + hNoiseEst->lt_aEn_zero_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_aEn_zero_fx, 6554 ); /* alpha=0.2 , Q15 */ + } + + return; +} + +#endif diff --git a/lib_enc/pitch_ol_fx.c b/lib_enc/pitch_ol_fx.c index deb99d727ed7100969df6ebec7d16e99934737bb..692e06ad952ae75aade5d431a5910a4186f67fd5 100644 --- a/lib_enc/pitch_ol_fx.c +++ b/lib_enc/pitch_ol_fx.c @@ -5,7 +5,7 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" +// #include "prot_fx.h" #include "basop_util.h" #include "rom_com_fx.h" #include "rom_com.h" @@ -47,101 +47,1240 @@ /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ +static Word32 Dot_product12_o_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 *exp, /* (o) : exponent of result (0..+30) */ + Flag *Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ +); +static Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 *exp /* (o) : exponent of result (0..+30) */ +); +static Word32 Dot_product12_OL_ivas( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); +static Word32 Dot_product12_OL_back_ivas( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); + static void LP_Decim2_Copy( const Word16 x[], Word16 y[], Word16 l, Word16 mem[] ); -static void pitch_neighbour_fx( Word16 sect0, Word16 pitch_tmp[], Word16 pitch[3][2 * NSECT], Word16 corr_tmp[], Word16 corr[3][2 * NSECT], Word16 thres1[2 * NHFR], Word16 ind_tmp[2 * NHFR] ); +static void pitch_neighbour_fx( Word16 sect0, Word16 pitch_tmp[], Word16 pitch[3][2 * NSECT], Word16 corr_tmp[], Word16 corr[3][2 * NSECT], Word16 thres1[2 * NHFR], Word16 ind_tmp[2 * NHFR] ); + +static void find_mult_fx( Word16 *fac, Word16 pitch0, Word16 pitch1, Word16 pit_max0, Word16 *corr, Word16 *old_pitch, Word16 *old_corr, Word16 delta, Word16 step ); + +static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, Word16 diff_max ); + +static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); + +static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); +#ifdef BASOP_NOGLOB +static Word32 Dot_product12_o_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 *exp, /* (o) : exponent of result (0..+30) */ + Flag *Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ +) +#else /* BASOP_NOGLOB */ +Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 *exp /* (o) : exponent of result (0..+30) */ +) +#endif /* BASOP_NOGLOB */ +{ + Word16 i, sft; + Word32 L_sum; +#ifdef BASOP_NOGLOB + Flag Overflow_ignored = 0; +#endif /* BASOP_NOGLOB */ + +#ifdef BASOP_NOGLOB + L_sum = L_mac_o( 0, x[0], y[0], &Overflow_ignored ); +#else + L_sum = L_mac( 1, x[0], y[0] ); +#endif + FOR( i = 1; i < lg; i++ ) + { +#ifdef BASOP_NOGLOB + L_sum = L_mac_o( L_sum, x[i], y[i], Overflow_out ? Overflow_out : &Overflow_ignored ); +#else /* BASOP_NOGLOB */ + L_sum = L_mac( L_sum, x[i], y[i] ); +#endif /* BASOP_NOGLOB */ + } + + /* Normalize acc in Q31 */ + + sft = norm_l( L_sum ); + L_sum = L_shl( L_sum, sft ); + + *exp = sub( 30, sft ); + move16(); /* exponent = 0..30 */ + + return L_sum; +} + +static Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 *exp /* (o) : exponent of result (0..+30) */ +) +{ + /* Ignore internal overflows */ + return Dot_product12_o_ivas( x, y, lg, exp, NULL ); +} +/*---------------------------------------------------------------------* + * Dot_product12_OL_back() + * + * two different length dot products of x and y, computed backward + *---------------------------------------------------------------------*/ +static Word32 Dot_product12_OL_back_ivas( /* o : Q31: normalized result (1 < val <= -1) */ + Word16 *sum1, /* o : Q31: normalized result 2 */ + const Word16 x[], /* i : 12bits: x vector */ + const Word16 y[], /* i : 12bits: y vector */ + const Word16 lg, /* i : vector length */ + const Word16 lg2, /* i : vector length 2 */ + Word16 *exp, /* o : exponent of result (0..+30) */ + Word16 *exp2 /* o : exponent of result 2 (0..+30) */ +) +{ + Word16 i, sft; + Word32 L_sum, L_sum2; + Flag Overflow_ignored = 0; + + L_sum = L_mac( 0, x[0], y[0] ); + IF( LE_16( lg, lg2 ) ) + { + FOR( i = 1; i < lg; i++ ) + { + L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); + } + /* sets to 'L_sum' in 1 clock */ + L_sum2 = L_sum; + move32(); + FOR( ; i < lg2; i++ ) + { + L_sum2 = L_mac_o( L_sum2, x[-i], y[-i], &Overflow_ignored ); + } + } + ELSE + { + FOR( i = 1; i < lg2; i++ ) + { + L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); + } + /* sets to 'L_sum' in 1 clock */ + L_sum2 = L_sum; + move32(); + FOR( ; i < lg; i++ ) + { + L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); + } + } + + /* Q31 */ + sft = norm_l( L_sum ); + L_sum = L_shl( L_sum, sft ); + *exp = sub( 30, sft ); + move16(); /* exponent = 0..30 */ + + sft = norm_l( L_sum2 ); + L_sum2 = L_shl( L_sum2, sft ); + *exp2 = sub( 30, sft ); + move16(); /* exponent = 0..30 */ + + *sum1 = extract_h( L_shr( L_sum2, 1 ) ); + + return L_sum; +} +/*---------------------------------------------------------------------* + * Dot_product12_OL + * + * two different length dot products of x and y + *---------------------------------------------------------------------*/ +static Word32 Dot_product12_OL_ivas( /* o : Q31: normalized result (1 < val <= -1) */ + Word16 *sum1, /* o : Q31: normalized result 2 */ + const Word16 x[], /* i : 12bits: x vector */ + const Word16 y[], /* i : 12bits: y vector */ + const Word16 lg, /* i : vector length */ + const Word16 lg2, /* i : vector length 2 */ + Word16 *exp, /* o : exponent of result (0..+30) */ + Word16 *exp2 /* o : exponent of result 2 (0..+30) */ +) +{ + Word16 i, sft; + Word32 L_sum, L_sum2; + Flag Overflow_ignored = 0; + L_sum = L_mac( 0, x[0], y[0] ); + IF( LE_16( lg, lg2 ) ) + { + FOR( i = 1; i < lg; i++ ) + { + L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); + } + /* sets to 'L_sum' in 1 clock */ + L_sum2 = L_sum; + move32(); + FOR( ; i < lg2; i++ ) + { + L_sum2 = L_mac_o( L_sum2, x[i], y[i], &Overflow_ignored ); + } + } + ELSE + { + FOR( i = 1; i < lg2; i++ ) + { + L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); + } + /* sets to 'L_sum' in 1 clock */ + L_sum2 = L_sum; + move32(); + FOR( ; i < lg; i++ ) + { + L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); + } + } + + /* Q31 */ + sft = norm_l( L_sum ); + L_sum = L_shl( L_sum, sft ); + *exp = sub( 30, sft ); + move16(); /* exponent = 0..30 */ + + sft = norm_l( L_sum2 ); + L_sum2 = L_shl( L_sum2, sft ); + *exp2 = sub( 30, sft ); + move16(); /* exponent = 0..30 */ + + *sum1 = extract_h( L_shr( L_sum2, 1 ) ); + + return L_sum; +} +/*-----------------------------------------------------------------* + * pitch_ol_init() + * + * Open loop pitch variable initialization + *-----------------------------------------------------------------*/ +void pitch_ol_init_fx( + Word16 *old_thres, /* o : threshold for reinforcement of past pitch influence */ + Word16 *old_pitch, /* o : pitch of the 2nd half-frame of previous frame */ + Word16 *delta_pit, /* o : pitch evolution extrapolation */ + Word16 *old_corr /* o : correlation */ +) +{ + *old_thres = 0; + move16(); + *old_pitch = 0; + move16(); + *delta_pit = 0; + move16(); + *old_corr = 0; + move16(); +} + + +/*==================================================================================*/ +/* FUNCTION : pitch_ol_fx() */ +/*----------------------------------------------------------------------------------*/ +/* PURPOSE : + * Compute the open loop pitch lag. + * + * The pitch lag search is divided into two sets. + * Each set is divided into three sections. + * Each section cannot have a pitch multiple. + * We find a maximum for each section. + * We compare the maxima of each section. + * + * 1st set 2nd set + * 1st section: lag delay = 115 down to 62 and 115 down to 78 + * 2nd section: lag delay = 61 down to 32 and 77 down to 41 + * 3rd section: lag delay = 31 down to 17 and 40 down to 22 + * 4th section: lag delay = 16 down to 10 and 21 down to 12 + * + * As there is a margin between section overlaps, especially for + * longer delays, this section selection is more robust for not + * to find multiples in the same section when pitch evolves rapidly. + * + * For each section, the length of the vectors to correlate is + * greater/equal to the longest pitch delay. */ +/*----------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */ +/* _ (Word16[]) old_corr_fx : correlation Q15 */ +/* _ (Word16[]) corr_shift_fx : normalized correlation correction Q15 */ +/* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */ +/* to past frame pitch Q15 */ +/* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */ +/* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */ +/* _ (Word16[]) wsp_fx : weighted speech for current frame & look-ahead qwsp */ +/* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */ +/* _ (Word16[]) relE_fx : relative frame energy Q8 */ +/* _ (Word16[]) L_look : look-ahead Q0 */ +/* _ (Word16[]) Opt_SC_VBR : SC-VBR flag Q0 */ +/* _ (Word16*) qwsp : wsp & filter memory Qformat */ +/*----------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) pitch : open loop pitch lag for each half-frame Q0 */ +/* _ (Word16[]) T_op : open loop pitch lag for each half-frm for quant Q0 */ +/* _ (Word16[]) voicing_fx : max normalized correlation for each half-frame QIn */ +/* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */ +/* _ (Word16[]) old_corr_fx : correlation Q15 */ +/* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */ +/* to past frame pitch Q15 */ +/* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */ +/* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */ +/* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */ +/*----------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==================================================================================*/ + +void pitch_ol_fx( + Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */ + Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */ + Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */ + Word16 *old_corr, /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean) Q15 */ + Word16 corr_shift, /* i : normalized correlation correction Q15 */ + Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */ + Word16 *delta_pit, /* i/o: old pitch extrapolation correction in range [-14,+14] Q0 */ + Word16 *st_old_wsp2, /* i/o: weighted speech memory qwsp */ + const Word16 *wsp, /* i : weighted speech for current frame and look-ahead qwsp */ + Word16 mem_decim2[3], /* i/o: wsp decimation filter memory qwsp */ + const Word16 relE, /* i : relative frame energy Q8 */ + const Word16 last_class, /* i : frame classification of last frame */ + const Word16 bwidth, /* i : bandwidth */ + const Word16 Opt_SC_VBR /* i : SC-VBR flag */ +) +{ + Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2; + Word16 tmp_mem[3]; + + Word16 scale1[2 * DELTA_COH - 1]; + Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )]; + Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )], exp_sect[8], exp_sect1[8], exp_sect0; + Word16 cor_buf[2 * LEN_X]; + Word16 *pt_exp1, *pt_exp2, *pt_exp3, *pt_exp4; + Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6; + Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4, *pt_cor5, *pt_cor6; + Word16 thres1[6]; + Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1; + Word16 ind_corX, ind1_corX; + + Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1; + Word16 len_temp; + Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1]; + + Word16 enr0[NSECT], enr0_exp[NSECT], enr0_1[NSECT], enr0_1_exp[NSECT], enr1, enr1_exp, enr2_exp; + Word32 enr, enr2, Ltmp; + Word16 fac, tmp16, tmp16_2; + Word16 qCorX, qScaledX; + Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean; + const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1; + + Word16 pit_min_coding; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*--------------------------------------------------------------* + * Initialization + *--------------------------------------------------------------*/ + len = len_12k8; + len1 = len1_12k8; + sublen = sublen_12k8; + sublen1 = sublen1_12k8; + pit_max = pit_max_12k8; + sec_length = sec_length_12k8; + sec_length1 = sec_length1_12k8; + + test(); + if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) ) + { + /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/ + *old_thres = 0; + move16(); + } + + pit_min_coding = PIT_MIN_EXTEND; + move16(); + test(); + test(); + test(); + test(); + IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) || + ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 3277 ) ) ) ) ) /* 0.1 inQ15*/ + { + pit_min = PIT_MIN / OPL_DECIM; + move16(); + pit_min1 = PIT_MIN_1 / OPL_DECIM; + move16(); + subsect0 = 2; + move16(); + sect0 = 1; + move16(); + } + ELSE + { + pit_min = PIT_MIN2 / OPL_DECIM; + move16(); + pit_min1 = PIT_MIN2_1 / OPL_DECIM; + move16(); + subsect0 = 0; + move16(); + sect0 = 0; + move16(); + } + + len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 ); + move16(); + len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 ); + move16(); + + /*--------------------------------------------------------------* + * Find decimated weighted speech + * Update wsp buffer with the memory + * decimation of wsp[] to search pitch in LF and to reduce complexity + * Extend the decimation of wsp to the end of the speech buffer + * Update wsp memory + *--------------------------------------------------------------*/ + Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + + LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 ); + + /* Avoid uninitialized memory access */ + set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 ); + tmp_mem[0] = mem_decim2[0]; + move16(); + tmp_mem[1] = mem_decim2[1]; + move16(); + tmp_mem[2] = mem_decim2[2]; + move16(); + + LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[shr( L_FRAME, 1 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/ + + Copy( &old_wsp2[shr( L_FRAME, 1 )], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + + /*-----------------------------------------------------------------* + * Attenuate the correlation correction factor due to noise. + * Reset correlation buffer outside the useful range. + * Find the scaling functions for immediate neigbours and + * further ones. + *-----------------------------------------------------------------*/ + + corr_shift = shr( corr_shift, 1 ); + + set16_fx( scaled_buf, 0, DELTA_COH - 1 ); + set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 ); + set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 ); + set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) ); + + pt1 = scale1 + DELTA_COH - 1; + pt2 = pt1; + tmp16 = mult( negate( *old_thres ), MAX_16 / DELTA_COH ); + k = *old_thres; + move16(); + FOR( i = 0; i < DELTA_COH; i++ ) + { + /* + * *pt1 = ( -(*old_thres)/DELTA_COH * i + *old_thres+1.0f ); + * To keep Q15 values, the following code does not add 1 to the result. + * A scaling factor must be applied accordingly (see next use of scale1) + */ + *pt1 = k; + move16(); + k = add( k, tmp16 ); + *pt2-- = *pt1++; + move16(); + } + + /*-----------------------------------------------------------------------------* + * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames + *-----------------------------------------------------------------------------*/ + old_tmp = add( *old_pitch, *delta_pit ); + old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM ); + old_tmp = s_max( old_tmp, pit_min ); + old_tmp1 = add( old_tmp, *delta_pit ); + old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM ); + old_tmp1 = s_max( old_tmp1, pit_min ); + + /*-----------------------------------------------------------------* + * Loop for all three half-frames (current frame + look-ahead) + *-----------------------------------------------------------------*/ + pt_cor0 = scaled_buf + DELTA_COH - 1; + + pt_cor2 = pt_cor0 - pit_min + old_tmp; + pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x; + + FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */ + { + pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */ + pt2 = pt1 - pit_min; /* *pt2 -> Q12 */ + pt4 = pt1 - pit_min1; /* *pt4 -> Q12 */ + + enr = L_deposit_l( 1 ); + + pt_cor1 = pt_cor0; + pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; + + pt_exp1 = scaled_buf_exp + DELTA_COH - 1; + pt_exp2 = pt_exp1; + pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x; + pt_exp4 = pt_exp3; + + IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */ + { + pt3 = pt1; + pt5 = pt1; + + FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */ + { + /*-----------------------------------------------------------------* + * Find fixed vector energy + *-----------------------------------------------------------------*/ + + /* 1st set */ + k = (Word16) ( pt1 - pt3 ); + move16(); + + FOR( k = add( k, len[j] ); k > 0; k-- ) + { + enr = L_mac0( enr, *pt3, *pt3 ); + pt3++; + } + /* keep Q15 normalized result */ + cnt = norm_l( enr ); + enr0[j] = extract_h( L_shl( enr, cnt ) ); + enr0_exp[j] = sub( 30, cnt ); + move16(); + + /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */ + pt5 = pt3; + enr2 = enr; /* sets to 'enr' in 1 clock */ + move32(); + + /* 2nd set */ + k = (Word16) ( pt1 - pt5 ); + move16(); + + FOR( k = add( k, len1[j] ); k > 0; k-- ) + { + enr2 = L_mac0( enr2, *pt5, *pt5 ); + pt5++; + } + cnt = norm_l( enr2 ); + enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); + enr0_1_exp[j] = sub( 30, cnt ); + move16(); + } + + /*----------------------------------------------------------* + * Find correlation for the non-overlapping pitch lag values + *----------------------------------------------------------*/ + exp_sect[subsect0] = 0; + move16(); + pt_cor5 = pt_cor1; + pt_cor6 = pt_cor3; + + tmp16 = exp_sect[subsect0]; + move16(); + + k = (Word16) ( pt2 - pt1 + pit_max[subsect0] ); + + IF( k >= 0 ) + { + len_temp = sublen[0]; + move16(); + + FOR( ; k >= 0; k-- ) + { + /* Keep Q15 normalized result */ + /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ + /* Update exponent to reflect shr by 1 */ + *pt_cor1 = extract_h( L_shr( Dot_product12( pt1, pt2--, len_temp, pt_exp1 ), 1 ) ); + + /* save the biggest exponent */ + tmp16 = s_max( tmp16, *pt_exp1 ); + + pt_cor1++; + pt_exp1++; + } + } + exp_sect[subsect0] = tmp16; + move16(); + + /*----------------------------------------------------------* + * For each subsection, find the correlation + *----------------------------------------------------------*/ + FOR( j = subsect0; j < NSUBSECT; j++ ) + { + len_temp = sublen[j]; + move16(); + + k = (Word16) ( pt2 - pt1 ); + move16(); + k = add( k, pit_max[j + 1] ); + exp_sect[j + 1] = 0; + move16(); + exp_sect1[j] = 0; + move16(); + + IF( k >= 0 ) + { + ind = exp_sect[j + 1]; + move16(); + ind1 = exp_sect1[j]; + move16(); + + FOR( ; k >= 0; k-- ) + { + /* Keep Q15 normalized result */ + /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ + /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */ + *pt_cor1 = extract_h( L_shr( Dot_product12_OL( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); + /* The line above replaces: + * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16(); + * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16(); + */ + + /* save the biggest exponent */ + ind = s_max( ind, *pt_exp1 ); + ind1 = s_max( ind1, *pt_exp3 ); + + pt_cor1++; + pt_exp1++; + pt_cor3++; + pt_exp3++; + } + exp_sect[j + 1] = ind; + move16(); + exp_sect1[j] = ind1; + move16(); + } /* IF (k >= 0) */ + } /* FOR (j = subsect0; ... */ + } + ELSE /* 3rd half-frame (look-ahead) */ + { + pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1; + pt3 = pt6; + pt5 = pt6; + + /*-----------------------------------------------------------------* + * For each section in both sets, find fixed vector energy + *-----------------------------------------------------------------*/ + + FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */ + { + /* 1st set */ + k = (Word16) ( pt3 - pt6 ); + move16(); + + FOR( k = add( k, len[j] ); k > 0; k-- ) + { + enr = L_mac0( enr, *pt3, *pt3 ); + pt3--; + } + + cnt = norm_l( enr ); + enr0[j] = extract_h( L_shl( enr, cnt ) ); /*qwsp+cnt-16*/ + enr0_exp[j] = sub( 30, cnt ); + move16(); + + /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */ + pt5 = pt3; + enr2 = enr; + move16(); + + /* 2nd set */ + k = (Word16) ( pt5 - pt6 ); + move16(); + + FOR( k = add( k, len1[j] ); k > 0; k-- ) + { + enr2 = L_mac0( enr2, *pt5, *pt5 ); + pt5--; + } + + cnt = norm_l( enr2 ); + enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); /*qwsp+cnt-16*/ + enr0_1_exp[j] = sub( 30, cnt ); + move16(); + } + + /* Set pointers */ + IF( sect0 != 0 ) + { + pt2 = pt6 - add( pit_max[1], 1 ); + k = sub( pit_max[2], pit_max[1] ); + move16(); + } + ELSE + { + pt2 = pt6 - pit_min; + k = 2; + move16(); + } + + /*-----------------------------------------------------------------* + * Find correlation for the non-overlapping pitch lag values + *-----------------------------------------------------------------*/ + exp_sect[subsect0] = 0; + move16(); + pt_cor5 = pt_cor1; + pt_cor6 = pt_cor3; + + tmp16 = exp_sect[subsect0]; + move16(); + + IF( k > 0 ) + { + len_temp = sublen[0]; + move16(); + + FOR( ; k > 0; k-- ) + { + /* Following lines are equivalent of Dot_product12() but with a backward incrementing */ + Ltmp = L_deposit_l( 1 ); + FOR( m = 0; m < len_temp; m++ ) + { + Ltmp = L_mac( Ltmp, pt6[-m], pt2[-m] ); + } + + /* Normalize acc in Q31 */ + tmp16_2 = norm_l( Ltmp ); + Ltmp = L_shl( Ltmp, tmp16_2 ); + *pt_exp1 = sub( 30, tmp16_2 ); + move16(); /* exponent = 0..30 */ + + /* Save result */ + *pt_cor1 = extract_h( L_shr( Ltmp, 1 ) ); + + /* Save the biggest exponent */ + tmp16 = s_max( tmp16, *pt_exp1 ); + + pt_cor1++; + pt_exp1++; + pt2--; + } + exp_sect[subsect0] = tmp16; + move16(); + } + + /*-----------------------------------------------------------------* + * For each subsection, find the correlation (overlapping pitch lag values) + *-----------------------------------------------------------------*/ + + FOR( j = subsect0; j < NSUBSECT; j++ ) + { + exp_sect[j + 1] = 0; + move16(); + exp_sect1[j] = 0; + move16(); + + ind = exp_sect[j + 1]; + move16(); + ind1 = exp_sect1[j]; + move16(); + + k = sub( pit_max[j + 1], pit_max[j] ); + + FOR( ; k > 0; k-- ) + { + *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); + + /* Save the biggest exponent */ + ind = s_max( ind, *pt_exp1 ); + ind1 = s_max( ind1, *pt_exp3 ); + + pt_cor1++; + pt_exp1++; + pt_cor3++; + pt_exp3++; + } + exp_sect[j + 1] = ind; + move16(); + exp_sect1[j] = ind1; + move16(); + } + } /* 3rd half-frame (look-ahead) */ + + /* Scale all values in each section to the same exponent for upcoming Find_max() */ + offset = 0; + move16(); + offset1 = 0; + move16(); + exp_sect1[7] = 0; /* padding */ + move16(); + FOR( j = sect0; j < NSECT; j++ ) + { + exp_sect0 = s_max( exp_sect[j * 2], exp_sect[j * 2 + 1] ); + + /* scaling of exp for track 1 */ + offset = add( offset, sec_length[j] ); + k = (Word16) ( pt_cor0 - pt_cor5 ); + move16(); + FOR( k = add( k, offset ); k > 0; k-- ) + { + cnt = sub( exp_sect0, *pt_exp2 ); + tmp16 = s_min( 15, cnt ); + if ( cnt > 0 ) + { + tmp16 = shr( *pt_cor5, tmp16 ); + } + if ( cnt > 0 ) + { + *pt_cor5 = tmp16; + move16(); + } + *pt_exp2 = s_max( *pt_exp2, exp_sect0 ); + move16(); + pt_cor5++; + pt_exp2++; + } + + exp_sect0 = s_max( exp_sect1[j * 2], exp_sect1[j * 2 + 1] ); + + /* scaling of exp for track 2 */ + offset1 = add( offset1, sec_length1[j] ); + k = (Word16) ( pt_cor0 - pt_cor6 + ( DELTA_COH - 1 ) ); + move16(); + k = add( k, len_x ); + FOR( k = add( k, offset1 ); k > 0; k-- ) + { + cnt = sub( exp_sect0, *pt_exp4 ); + tmp16 = s_min( 15, cnt ); + if ( cnt > 0 ) + { + tmp16 = shr( *pt_cor6, tmp16 ); + } + if ( cnt > 0 ) + { + *pt_cor6 = tmp16; + move16(); + } + *pt_exp4 = s_max( *pt_exp4, exp_sect0 ); + move16(); + pt_cor6++; + pt_exp4++; + } + } /* FOR (j = sect0; ... */ + + Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector */ + Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 ); + + /*-----------------------------------------------------------------* + * Scale correlation function in the neighbourhood of + * the extrapolated pitch + *-----------------------------------------------------------------*/ + pt_cor1 = pt_cor2 - ( DELTA_COH - 1 ); + pt_cor3 = pt_cor4 - ( DELTA_COH - 1 ); + pt2 = scale1; + + FOR( k = 0; k < 2 * DELTA_COH - 1; k++ ) + { + /* all Q15 here */ + *pt_cor1 = add( *pt_cor1, mult( *pt_cor1, *pt2 ) ); + move16(); + *pt_cor3 = add( *pt_cor3, mult( *pt_cor3, *pt2++ ) ); + move16(); + + pt_cor1++; + pt_cor3++; + } + + /* Update for next half-frame & look-ahead */ + pt_cor2 = pt_cor0 - pit_min + old_tmp1; + pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x; + + /*-----------------------------------------------------------------* + * For each section, find maximum correlation and compute + * normalized correlation + *-----------------------------------------------------------------*/ + + pt_cor1 = pt_cor0; + pt_exp1 = scaled_buf_exp + DELTA_COH - 1; + offset = 0; + move16(); + pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; + pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x; + offset1 = 0; + move16(); + + FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */ + { + /* 1st set */ + offset_la = 0; + move16(); + if ( EQ_16( i, 2 ) ) + { + offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] ); + } + + /* 2nd set */ + offset_la1 = 0; + move16(); + if ( EQ_16( i, 2 ) ) + { + offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] ); + } + + /* 1st set of candidates */ + ind = add( maximum_fx( pt_cor1, sec_length[j], &ftmp ), offset ); + pitchX[i][j] = add( ind, pit_min ); + move16(); + pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector */ + + enr1_exp = 0; + move16(); +#ifdef BASOP_NOGLOB + enr1 = add_o( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1, &Overflow ); +#else + enr1 = add( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1 ); +#endif + + enr2 = L_mult( enr0[j], enr1 ); + enr2_exp = norm_l( enr2 ); + enr2 = L_shl( enr2, enr2_exp ); + enr2_exp = sub( 31, add( sub( 28, add( enr0_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) ); + + enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/ + enr1_exp = norm_l( enr2 ); + enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/ + enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/ + + Ltmp = L_mult0( cor_buf[ind], enr1 ); + qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) ); +#ifdef BASOP_NOGLOB + corX[i][j] = extract_h( L_shr_o( Ltmp, sub( qCorX, 31 ), &Overflow ) ); +#else /* BASOP_NOGLOB */ + corX[i][j] = extract_h( L_shr( Ltmp, sub( qCorX, 31 ) ) ); +#endif /* BASOP_NOGLOB */ + qCorX = 31; + move16(); + + Ltmp = L_mult0( pt_cor0[ind], enr1 ); + qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) ); + scaledX[i][j] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) ); + qScaledX = 12; + move16(); + + pt_cor1 += sec_length[j]; + move16(); + offset = add( offset, sec_length[j] ); + + /* 2nd set of candidates */ + ind1 = add( maximum_fx( pt_cor3, sec_length1[j], &ftmp ), offset1 ); + pitchX[i][j + NSECT] = add( ind1, pit_min1 ); + move16(); + pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1; + move16(); /* selected moving vector */ + enr1_exp = 0; + move16(); +#ifdef BASOP_NOGLOB + enr1 = add_o( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1, &Overflow ); +#else + enr1 = add( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1 ); +#endif + + enr2 = L_mult( enr0_1[j], enr1 ); + enr2_exp = norm_l( enr2 ); + enr2 = L_shl( enr2, enr2_exp ); + + enr2_exp = sub( 31, add( sub( 28, add( enr0_1_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) ); + enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/ + enr1_exp = norm_l( enr2 ); + enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/ + enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/ + + Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 ); + + qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) ); +#ifdef BASOP_NOGLOB + corX[i][j + NSECT] = extract_h( L_shr_o( Ltmp, qCorX - 31, &Overflow ) ); +#else /* BASOP_NOGLOB */ + corX[i][j + NSECT] = extract_h( L_shr( Ltmp, qCorX - 31 ) ); +#endif /* BASOP_NOGLOB */ + qCorX = 31; + move16(); + + Ltmp = L_mult0( pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x], enr1 ); + qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) ); + scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) ); + /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/ + qScaledX = 12; + move16(); + + pt_cor3 += sec_length1[j]; + move16(); + offset1 = add( offset1, sec_length1[j] ); + + } /* FOR j < NSECT */ + } /* FOR i < NHFR */ + + /*-----------------------------------------------------------------* + * Favor a smaller delay if it happens that it has its multiple + * in the longer-delay sections (harmonics check) + *-----------------------------------------------------------------*/ + + FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */ + { + fac = THRES0; + move16(); + find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */ + find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + test(); + IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) ) + { + find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + } + fac = THRES0; + move16(); + find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */ + find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + test(); + IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) ) + { + find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + } + } + fac = THRES0; + move16(); /* the look-ahead */ + find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */ + find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + test(); + IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) ) + { + find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + } + fac = THRES0; + move16(); + find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */ + find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ + test(); + IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) ) + { + find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */ + } + + /*-----------------------------------------------------------------* + * Do 1st estimate for pitch values + * Adjust the normalized correlation using estimated noise level + * Compute the maximum scaling for the neighbour correlation + * reinforcement + *-----------------------------------------------------------------*/ + add_sect0 = add( NSECT, sect0 ); + sub_sect0 = sub( NSECT, sect0 ); + FOR( i = 0; i < NHFR; i++ ) + { + /* 1st set of pitch candidates */ + ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 ); + ind_tmp[i] = ind; + move16(); + pitch_tmp[i] = pitchX[i][ind]; + move16(); +#ifdef BASOP_NOGLOB + cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow ); +#else /* BASOP_NOGLOB */ + cor_tmp[i] = add( corX[i][ind], corr_shift ); +#endif /* BASOP_NOGLOB */ + move16(); + + /* Higher is the neighbour's correlation, higher is the weighting */ + /* operands are Q15, result is Q15 */ + thres1[i] = mult( THRES1, cor_tmp[i] ); + move16(); + + /* 2nd set of pitch candidates */ + ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 ); + ind_tmp[i + NHFR] = ind1; + move16(); + pitch_tmp[i + NHFR] = pitchX[i][ind1]; + move16(); +#ifdef BASOP_NOGLOB + cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow ); +#else /* BASOP_NOGLOB */ + cor_tmp[i + NHFR] = add( corX[i][ind1], corr_shift ); +#endif + move16(); + + /* Higher is the neighbour's correlation, higher is the weighting */ + /* operands are Q15, result is Q15 */ + thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] ); + move16(); + } + /*-----------------------------------------------------------------* + * Take into account previous and next pitch values of the present + * frame and look-ahead. Choose the pitch lags and normalize + * correlations for each half-frame & look-ahead + *-----------------------------------------------------------------*/ -static void find_mult_fx( Word16 *fac, Word16 pitch0, Word16 pitch1, Word16 pit_max0, Word16 *corr, Word16 *old_pitch, Word16 *old_corr, Word16 delta, Word16 step ); + pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp ); + FOR( i = 0; i < NHFR; i++ ) + { + ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 ); + ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 ); -static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, Word16 diff_max ); + ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 ); + ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 ); -static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); + if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) ) + { + ind = ind1; + move16(); + } + test(); + if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) ) + { + ind_corX = ind1_corX; + move16(); + } + test(); + test(); + test(); + IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) && + ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) && + ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) ) + { + pitch[i] = pitchX[i][ind_corX]; + move16(); + voicing[i] = corX[i][ind_corX]; + move16(); + } + ELSE + { + pitch[i] = pitchX[i][ind]; + move16(); + voicing[i] = corX[i][ind]; + move16(); + } + } -static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); + /*-----------------------------------------------------------------* + * Increase the threshold for correlation reinforcement with + * the past if correlation high and pitch stable + *-----------------------------------------------------------------*/ + /* all Q15 here */ + /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */ + Ltmp = L_mult( voicing[0], 16384 ); + Ltmp = L_mac( Ltmp, voicing[1], 16384 ); + cor_mean = round_fx( L_add( Ltmp, corr_shift ) ); -/*-----------------------------------------------------------------* - * pitch_ol_init() - * - * Open loop pitch variable initialization - *-----------------------------------------------------------------*/ -void pitch_ol_init_fx( - Word16 *old_thres, /* o : threshold for reinforcement of past pitch influence */ - Word16 *old_pitch, /* o : pitch of the 2nd half-frame of previous frame */ - Word16 *delta_pit, /* o : pitch evolution extrapolation */ - Word16 *old_corr /* o : correlation */ -) -{ - *old_thres = 0; + /* pitch unstable in present frame or from previous frame or normalized correlation too low */ + coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH ); move16(); - *old_pitch = 0; + coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH ); + move16(); + + test(); + test(); + test(); + IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) ) + { + /* Reset the threshold */ + *old_thres = 0; + move16(); + } + ELSE + { + /* The threshold increase is directly dependent on normalized correlation */ + /* *old_thres += (0.16f * cor_mean); */ + *old_thres = round_fx( L_mac( L_deposit_h( *old_thres ), 5243, cor_mean ) ); + } + + *old_thres = s_min( *old_thres, THRES3 ); + move16(); + + IF( GT_16( voicing[1], voicing[0] ) ) + { + *old_corr = voicing[1]; + move16(); + } + ELSE + { + *old_corr = cor_mean; + move16(); + } + + /*-----------------------------------------------------------------* + * Extrapolate the pitch value for the next frame by estimating + * the pitch evolution. This value is added to the old_pitch + * in the next frame and is then used when the normalized + * correlation is reinforced by the past estimate + *-----------------------------------------------------------------*/ + tmp_buf[0] = *old_pitch; move16(); + FOR( i = 0; i < NHFR; i++ ) + { + tmp_buf[i + 1] = pitch[i]; + move16(); + } + *delta_pit = 0; move16(); - *old_corr = 0; + cnt = 0; move16(); -} + FOR( i = 0; i < NHFR; i++ ) + { + diff = sub( tmp_buf[i + 1], tmp_buf[i] ); + move16(); + coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH ); -/*==================================================================================*/ -/* FUNCTION : pitch_ol_fx() */ -/*----------------------------------------------------------------------------------*/ -/* PURPOSE : - * Compute the open loop pitch lag. - * - * The pitch lag search is divided into two sets. - * Each set is divided into three sections. - * Each section cannot have a pitch multiple. - * We find a maximum for each section. - * We compare the maxima of each section. - * - * 1st set 2nd set - * 1st section: lag delay = 115 down to 62 and 115 down to 78 - * 2nd section: lag delay = 61 down to 32 and 77 down to 41 - * 3rd section: lag delay = 31 down to 17 and 40 down to 22 - * 4th section: lag delay = 16 down to 10 and 21 down to 12 - * - * As there is a margin between section overlaps, especially for - * longer delays, this section selection is more robust for not - * to find multiples in the same section when pitch evolves rapidly. - * - * For each section, the length of the vectors to correlate is - * greater/equal to the longest pitch delay. */ -/*----------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */ -/* _ (Word16[]) old_corr_fx : correlation Q15 */ -/* _ (Word16[]) corr_shift_fx : normalized correlation correction Q15 */ -/* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */ -/* to past frame pitch Q15 */ -/* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */ -/* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */ -/* _ (Word16[]) wsp_fx : weighted speech for current frame & look-ahead qwsp */ -/* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */ -/* _ (Word16[]) relE_fx : relative frame energy Q8 */ -/* _ (Word16[]) L_look : look-ahead Q0 */ -/* _ (Word16[]) Opt_SC_VBR : SC-VBR flag Q0 */ -/* _ (Word16*) qwsp : wsp & filter memory Qformat */ -/*----------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16[]) pitch : open loop pitch lag for each half-frame Q0 */ -/* _ (Word16[]) T_op : open loop pitch lag for each half-frm for quant Q0 */ -/* _ (Word16[]) voicing_fx : max normalized correlation for each half-frame QIn */ -/* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */ -/* _ (Word16[]) old_corr_fx : correlation Q15 */ -/* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */ -/* to past frame pitch Q15 */ -/* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */ -/* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */ -/* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */ -/*----------------------------------------------------------------------------------*/ + if ( coh_flag != 0 ) + { + *delta_pit = add( *delta_pit, diff ); + move16(); + } + cnt = add( cnt, coh_flag ); + } + if ( EQ_16( cnt, 2 ) ) + { + /* *delta_pit /= 2; */ + *delta_pit = shr( *delta_pit, 1 ); + move16(); + } + IF( EQ_16( cnt, 3 ) ) + { + k = *delta_pit; + move16(); + /* *delta_pit /= 3; */ + if ( k < 0 ) + { + *delta_pit = mult( *delta_pit, -32768 ); + move16(); + } + tmp16 = mult( *delta_pit, 10923 ); + if ( k < 0 ) + { + tmp16 = mult( tmp16, -32768 ); + } + *delta_pit = tmp16; + move16(); + } -/*----------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*==================================================================================*/ + /*--------------------------------------------------------------* + * Update old pitch, upsample pitch, + *--------------------------------------------------------------*/ + *old_pitch = pitch[1]; + move16(); -void pitch_ol_fx( + FOR( i = 0; i < NHFR; i++ ) + { + /* compensate decimation */ + pitch[i] = i_mult2( pitch[i], OPL_DECIM ); + move16(); + } + + return; +} + +void pitch_ol_ivas_fx( Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */ Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */ Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */ @@ -324,7 +1463,7 @@ void pitch_ol_fx( pt2 = pt1 - pit_min; /* *pt2 -> Q12 */ pt4 = pt1 - pit_min1; /* *pt4 -> Q12 */ - enr = L_deposit_l( 1 ); + enr = 0; pt_cor1 = pt_cor0; pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; @@ -348,10 +1487,10 @@ void pitch_ol_fx( /* 1st set */ k = (Word16) ( pt1 - pt3 ); move16(); - + Flag overflow = 0; FOR( k = add( k, len[j] ); k > 0; k-- ) { - enr = L_mac0( enr, *pt3, *pt3 ); + enr = L_mac0_o( enr, *pt3, *pt3, &overflow ); pt3++; } /* keep Q15 normalized result */ @@ -371,7 +1510,7 @@ void pitch_ol_fx( FOR( k = add( k, len1[j] ); k > 0; k-- ) { - enr2 = L_mac0( enr2, *pt5, *pt5 ); + enr2 = L_mac0_o( enr2, *pt5, *pt5, &overflow ); pt5++; } cnt = norm_l( enr2 ); @@ -403,7 +1542,7 @@ void pitch_ol_fx( /* Keep Q15 normalized result */ /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ /* Update exponent to reflect shr by 1 */ - *pt_cor1 = extract_h( L_shr( Dot_product12( pt1, pt2--, len_temp, pt_exp1 ), 1 ) ); + *pt_cor1 = extract_h( L_shr( Dot_product12_ivas( pt1, pt2--, len_temp, pt_exp1 ), 1 ) ); /* save the biggest exponent */ tmp16 = s_max( tmp16, *pt_exp1 ); @@ -443,7 +1582,7 @@ void pitch_ol_fx( /* Keep Q15 normalized result */ /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */ - *pt_cor1 = extract_h( L_shr( Dot_product12_OL( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); + *pt_cor1 = extract_h( L_shr( Dot_product12_OL_ivas( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); /* The line above replaces: * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16(); * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16(); @@ -474,7 +1613,7 @@ void pitch_ol_fx( /*-----------------------------------------------------------------* * For each section in both sets, find fixed vector energy *-----------------------------------------------------------------*/ - + Flag overflow = 0; FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */ { /* 1st set */ @@ -483,7 +1622,7 @@ void pitch_ol_fx( FOR( k = add( k, len[j] ); k > 0; k-- ) { - enr = L_mac0( enr, *pt3, *pt3 ); + enr = L_mac0_o( enr, *pt3, *pt3, &overflow ); pt3--; } @@ -503,7 +1642,7 @@ void pitch_ol_fx( FOR( k = add( k, len1[j] ); k > 0; k-- ) { - enr2 = L_mac0( enr2, *pt5, *pt5 ); + enr2 = L_mac0_o( enr2, *pt5, *pt5, &overflow ); pt5--; } @@ -549,7 +1688,7 @@ void pitch_ol_fx( Ltmp = L_deposit_l( 1 ); FOR( m = 0; m < len_temp; m++ ) { - Ltmp = L_mac( Ltmp, pt6[-m], pt2[-m] ); + Ltmp = L_mac_o( Ltmp, pt6[-m], pt2[-m], &overflow ); } /* Normalize acc in Q31 */ @@ -592,7 +1731,7 @@ void pitch_ol_fx( FOR( ; k > 0; k-- ) { - *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); + *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back_ivas( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); /* Save the biggest exponent */ ind = s_max( ind, *pt_exp1 ); @@ -1462,7 +2601,6 @@ static Word32 Dot_product12_OL_back( /* o : Q31: normalized r return L_sum; } - void pitchDoubling_det_fx( Word16 *wspeech, Word16 *pitch_ol, diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index b05dfcce2dc7ee305a125611dfc162889ef9a0ce..37b8eb340a9ad5a3d902e127e50e911e4ed99e25 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -149,6 +149,14 @@ void dtx_fx( ); +void dtx_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word16 vad, /* i : vad flag for DTX */ + const Word16 speech[] /* i : Pointer to the speech frame */ + +); + Word16 dtx_hangover_addition_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 vad_flag, /* i Q0 */ @@ -238,7 +246,19 @@ void long_enr_fx( const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ Word16 high_lpn_flag ); +#ifdef IVAS_FLOAT_FIXED +void ivas_long_enr_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + Word16 high_lpn_flag, /* i : sp/mus LPN flag */ + FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ + const Word16 n_chan, /* i : number of channels */ + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ + const Word16 Etot_LR[] /* i : total channel energy LR channels */ +); +#endif Word16 mdct_classifier_fx( /* o: MDCT A/B decision */ const Word16 *Y, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ Encoder_State *st_fx, /* i/o: Encoder state variable */ @@ -295,7 +315,38 @@ void noise_est_fx( #endif const Word16 ini_frame /* i : Frame number (init) */ ); - +#ifdef IVAS_FLOAT_FIXED +void noise_est_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 old_pitch1, /* i : previous frame OL pitch[1] */ + const Word32 tmpN[], /* i : temporary noise update Q_new + QSCALE */ + const Word16 epsP_h[], /* i : msb prediction error energies Q_r-1 */ + const Word16 epsP_l[], /* i : msb prediction error energies Q_r-1 */ + const Word16 Etot, /* i : total channel E (see find_enr_fx.c) Q8 */ + const Word16 relE, /* i : (VA_CHECK addition) relative frame energy Q8? */ + const Word16 corr_shift, /* i : normalized correlation correction Q15 */ + const Word32 enr[], /* i : averaged energy over both subframes Q_new + Q_SCALE */ + Word32 fr_bands[], /* i : spectrum per critical bands of the current frame Q_new + Q_SCALE */ + Word16 *cor_map_sum, /* o : Q8 */ + Word16 *sp_div, /* o : Q_sp_div */ + Word16 *Q_sp_div, /* o : Q factor for sp_div */ + Word16 *non_staX, /* o : non-stationarity for sp/mus classifier */ + Word16 *loc_harm, /* o : multi-harmonicity flag for UV classifier */ + const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE -2 */ + Word16 *st_harm_cor_cnt, /* i/o : 1st harm correlation timer Q0 */ + const Word16 Etot_l_lp, /* i : Smoothed low energy Q8 */ + const Word16 Etot_v_h2, /* i : Energy variations Q8 */ + Word16 *bg_cnt, /* i : Background burst length timer Q0 */ + Word16 EspecdB[], /* i/o: log E spectrum (with f=0) of the current frame Q7 for multi harm */ + Word16 Q_new, /* i : SCaling of current frame */ + const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ + Word16 *sp_floor, /* o : noise floor estimate Q7 */ + Word16 S_map[], /* o : short-term correlation map Q7 */ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ + FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ + const Word16 ini_frame /* i : Frame number (init) */ +); +#endif void noise_est_pre_fx( const Word16 Etot, /* i : Energy of current frame */ const Word16 ini_frame_fx, /* i : Frame number (init) */ @@ -329,6 +380,23 @@ void pitch_ol2_fx( const Word16 delta /* i : delta for pitch search (2 or 7) */ ); +void pitch_ol_ivas_fx( + Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */ + Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */ + Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */ + Word16 *old_corr, /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean) Q15 */ + Word16 corr_shift, /* i : normalized correlation correction Q15 */ + Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */ + Word16 *delta_pit, /* i/o: old pitch extrapolation correction in range [-14,+14] Q0 */ + Word16 *st_old_wsp2, /* i/o: weighted speech memory qwsp */ + const Word16 *wsp, /* i : weighted speech for current frame and look-ahead qwsp */ + Word16 mem_decim2[3], /* i/o: wsp decimation filter memory qwsp */ + const Word16 relE, /* i : relative frame energy Q8 */ + const Word16 last_class, /* i : frame classification of last frame */ + const Word16 bwidth, /* i : bandwidth */ + const Word16 Opt_SC_VBR /* i : SC-VBR flag */ +); + void pitch_ol_fx( Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */ Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */ @@ -2755,10 +2823,9 @@ void pre_proc_fx( Word16 lsp_new[M], /* o : LSPs at the end of the frame */ Word16 lsp_mid[M], /* o : LSPs in the middle of the frame */ Word16 *vad_hover_flag, - Word16 *attack_flag, /* o : flag signalling attack encoded by AC mode (GSC) */ - Word16 *new_inp_resamp16k, /* o : new i signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - Word16 *Voicing_flag, /* o : voicing flag for HQ FEC */ - + Word16 *attack_flag, /* o : flag signalling attack encoded by AC mode (GSC) */ + Word16 *new_inp_resamp16k, /* o : new i signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ + Word16 *Voicing_flag, /* o : voicing flag for HQ FEC */ Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : cldfb real buffer */ Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : cldfb imag buffer */ CLDFB_SCALE_FACTOR *cldfbScale, /* o : cldfb scale */ diff --git a/lib_enc/rom_enc.c b/lib_enc/rom_enc.c index 9b4d998d65e41f874714cdd66559ca2bddf4bf7b..3b9302765cb64dd7f630a71ea2e64bf750310a9e 100644 --- a/lib_enc/rom_enc.c +++ b/lib_enc/rom_enc.c @@ -412,12 +412,24 @@ const float sm_means[N_SMC_FEATURES] = { 109.073304f, 0.727576f, 0.246557f, 0.291464f, 0.836498f, 1.021915f, 1.213649f, 64.230265f, 1.236224f, -2.347783f, 1.795570f, -0.039230f, -0.292081f, 0.611993f, 5.587905f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 sm_means_fx[N_SMC_FEATURES] = +{ +114371648, 762918, 258533, 305622, 877131, 1071555, 1272603, 67350312, +1296274, -2461829, 1882791, -41135, -306269, 641721, 5859343, +}; +#endif const float sm_scale[N_SMC_FEATURES] = { 44.621579f, 0.159182f, 0.063806f, 0.067614f, 0.112130f, 0.103447f, 0.091769f, 16.522003f, 0.115806f, 1.284023f, 3.337835f, 1.726416f, 1.422670f, 0.270914f, 0.422958f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 sm_scale_fx[N_SMC_FEATURES] = +{//Q20 +46789116, 166914, 66905, 70898, 117576, 108472, 96226, 17324576, +121431, 1346395, 3499973, 1810278, 1491777, 284073, 443503, +}; +#endif const float hout_intervals[N_SMC_FEATURES * 2] = { 18.000000f, 230.000000f, 0.000000f, 0.999769f, 0.119389f, 0.990880f, 0.255791f, 1.181627f, @@ -426,25 +438,51 @@ const float hout_intervals[N_SMC_FEATURES * 2] = -11.751500f, 10.883281f, 0.000793f, 1.994476f, 3.021017f, 10.545962f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 hout_intervals_fx[N_SMC_FEATURES * 2] = +{//Q20 +18874368, 241172480, 0, 1048333, 125188, 1039013, 268216, 1239025, +426065, 1451491, 608719, 1618445, 818630, 1973136, 0, 127492952, +0, 275457504, -8950052, -58, -15134888, 18681054, -11149023, 12630839, +-12322341, 11411947, 831, 2091359, 3167766, 11058243, +}; +#endif const float bcox_add_cnst[N_SMC_FEATURES] = { 0.000000f, 0.000000f, -0.878682f, -0.726044f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.778993f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 bcox_add_cnst_fx[N_SMC_FEATURES] = +{ + 0, 0, -1886955264, -1559167616, 0, 0, 0, 0, +-1672874752, 0, 0, 0, 0, 0, 0, +}; +#endif const float bcox_lmbd[N_SMC_FEATURES] = { 0.000000f, 0.000000f, -0.664282f, -0.422504f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.634475f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 bcox_lmbd_fx[N_SMC_FEATURES] = +{ +0, 0, -1426534784, -907320448, 0, 0, 0, 0, +-1362524672, 0, 0, 0, 0, 0, 0, +}; +#endif const float pca_mean_[N_SMC_FEATURES] = { 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.000000f, -0.000000f, 0.000000f, -0.000000f, -0.000000f, 0.000000f, 0.000000f, -0.000000f, 0.000000f, 0.000000f, 0.000000f }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 pca_mean_fx[N_SMC_FEATURES] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +}; +#endif const float pca_components_[N_SMC_FEATURES * N_PCA_COEF] = { 0.025076f, -0.242897f, 0.309604f, 0.391805f, 0.384930f, 0.378366f, 0.352165f, -0.191363f, 0.158511f, 0.329501f, 0.145794f, 0.086507f, 0.009591f, 0.276506f, -0.007154f, @@ -460,7 +498,35 @@ const float pca_components_[N_SMC_FEATURES * N_PCA_COEF] = -0.025136f, -0.058113f, 0.137926f, 0.044374f, -0.239076f, 0.007627f, 0.343252f, 0.516920f, 0.447960f, -0.427809f, 0.100915f, 0.071696f, 0.016780f, 0.162128f, 0.327376f, -0.016076f, -0.042889f, -0.441975f, 0.409942f, -0.243623f, -0.482644f, 0.460423f, 0.052715f, -0.067754f, 0.305681f, 0.058106f, -0.008628f, 0.098064f, -0.032513f, -0.123637f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 pca_components_fx[N_SMC_FEATURES * N_PCA_COEF] = +{ + //Q31 +53850300, -521617344, 664869504, 841394816, 826630912, 812534784, 756268608, -410948928, +340399776, 707598016, 313090240, 185772368, 20596516, 593792128, -15363098, 552253312, +-333467712, 528749120, 182890448, 96868696, 32978906, -34922380, 862927680, -1019088384, +569624320, -298519552, 97158600, 415727072, -688403776, 1008881344, 39696236, 883947200, +-590381888, 251015072, 628265664, 568803968, 309151744, 270411136, -356222432, -344628160, +1206892288, -198603584, -495733728, -719314688, 159293888, -1166596864, 280759872, 331511360, +-81920056, 75333728, 215553664, 490723648, 432773792, -99411312, 345044800, -779497920, +-1242942080, -503838304, -167628272, -107908904, -391501312, 80378168, 131556992, 200443984, +127420944, -416188768, -172488032, 193806112, -74691632, 242253328, -305453792, 1222304768, +-1564175488, 12887049, 198238512, -1246255616, 574915712, 215371136, 530961024, 363511008, +-221427040, -658203712, 398349632, 82134808, 83833464, 233839488, 623672192, 1075657344, +30015378, -106077104, -140690240, 98930280, -510246400, -587343232, 286442112, 674346368, +982237568, -34930968, -186231936, -322264288, -911922496, 959551552, 488664192, -448772544, +-378040864, -1026978240, -1448578688, -578708160, -296335552, 35369056, 95511480, -66737348, +-386493376, -261140448, -263822656, 508893504, -20220706, -31720480, -254169728, 639462656, +-167057040, 899647488, -181004960, -47577500, -325298688, 48760764, 203744656, -1062381632, +244351424, 282318944, -274137024, 26607322, 168482976, 159102768, 1480558976, -177899696, +29734058, 1058730944, 682360768, -553178880, -241886112, 403883680, -807309952, -628843328, +-992895488, 53388592, 67669360, -22754736, -593890880, -267031008, -53979148, -124796720, +296193824, 95292440, -513411808, 16378858, 737128064, 1110077184, 961986752, -918712832, +216713312, 153965984, 36034776, 348167232, 703034624, -34522948, -92103424, -949134080, +880343744, -523176416, -1036470080, 988750848, 113204600, -145500608, 656444928, 124781688, +-18528488, 210590832, -69821136, -265508432, +}; +#endif const float means_speech[N_SMC_MIXTURES*N_PCA_COEF] = { 4.144528f, -0.445994f, -0.070302f, 0.359876f, -0.040196f, -0.118265f, 0.644765f, -0.174143f, -0.114585f, 0.658716f, 0.278107f, -0.260928f, @@ -470,7 +536,21 @@ const float means_speech[N_SMC_MIXTURES*N_PCA_COEF] = -0.413334f, -1.784803f, -0.187205f, -0.391714f, -0.243155f, -0.223117f, -0.018042f, 0.129642f, 0.137285f, -0.049526f, 0.029685f, -0.024247f, -0.694581f, -1.756488f, 0.597206f, 1.030080f, 0.297682f, 0.383268f, 0.135800f, -0.177134f, 0.096645f, -0.268388f, -0.151836f, -0.101950f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 means_speech_fx[N_SMC_MIXTURES*N_PCA_COEF] = +{ + //Q27 + 556269120, -59860300, -9435775, 48301740, -5395016, -15873260, 86538896, -23373078, +-15379338, 88411368, 37326888, -35021164, -4035256, -161975568, 85803920, -81899120, +-7169642, 64167884, -82728320, -29112898, 81431240, 15287399, -468956, 29038140, +-256403904, -208488720, 86349912, 56074020, 36843036, 19549348, 1753688, -32431970, +29630308, 14530545, -8338545, 4083037, 253332208, -116034448, -127942512, -33905276, +8696369, -14094204, -30782970, 37237904, 4475893, -12044833, -4461531, 2582617, +-55476752, -239552208, -25126230, -52574964, -32635712, -29946256, -2421556, 17400254, +18426080, -6647267, 3984253, -3254377, -93225080, -235751824, 80155632, 138254992, +39954200, 51441360, 18226768, -23774524, 12971472, -36022428, -20379082, -13683497, +}; +#endif const float log_det_chol_speech[N_SMC_MIXTURES] = { 6.500575f, 5.852711f, 5.579274f, 6.652653f, 4.752021f, 5.338445f, @@ -487,7 +567,69 @@ const float prec_chol_speech[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) }; #ifdef IVAS_FLOAT_FIXED -const Word32 prec_chol_speech_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { 232432352, -59879628, 304533312, -125429152, 99142344, 326068544, -56826444, 46350480, 37527544, 329625600, 31308164, -19632564, 32069984, 57804624, 403167520, 3554890, 64722740, -62716724, 56281252, -4959882, 478142080, -101929504, -14876156, 39897560, -40777760, -47372952, 187926288, 341264960, 21311090, -155172336, 108759040, -143880592, -20300968, -5616206, 73920144, 570679040, 218755296, -162775504, -64450816, -7369627, -36893500, -37446476, -80293072, 8201777, 597213568, -152507040, -256513440, -45927696, -77678512, -140313632, -170642272, -94367944, 112342656, 201967072, 756224576, -208080960, 225792336, 58484840, 66006132, -48434348, 7039720, -102562208, 39706704, -339747744, -90058216, 796577920, 202634944, 37851548, 10156524, 82895824, 73911016, -121567440, -148495536, -112251120, 27724282, 54130280, 84421344, 906663552, 209343680, 32186754, 306301216, -116259936, -36924908, 224391904, -24221736, 35642860, 46462152, 312121440, -39075344, -7622225, 60599840, 68880272, 244525904, -58326728, -36760892, 23687014, 173225968, 23444078, 473461088, -15582947, -34961840, 37741220, 31105764, -74304544, 12497281, 425261888, 33453500, 9509863, -120815016, 63221652, 7134209, 101693816, 61658284, 770215168, -17228724, -276690656, 128551864, -10146055, -15149155, 107287480, -8414646, -387697024, 649792832, 50705580, -73682312, -57487332, 8967623, -3074928, 20067160, 135318848, 273094432, -35929816, 819158720, -19654308, -23457232, 20863072, 11649830, -4230006, 119185344, 150983408, -51511960, -81179712, 365100416, 677546368, -1104880, 67182952, -148998320, -17748684, -31462514, 36981012, -243459152, -30465546, 39841460, -70792064, -7307618, 793560192, 196828960, -32199102, 232271296, -76255536, 20992994, 207772000, 19910932, 13635984, 32428882, 280196960, -25198842, -1165278, 42992624, -13211856, 237527792, -62810408, -99852624, 47340472, 231473232, -57426664, 489151424, 19632028, 2961111, -8761465, 94918512, -12379975, 80280456, 362603424, 142636400, 32065152, -350124672, 127381216, 47764332, 62010736, -35439924, 1157346560, -346969728, -366012832, 596499264, 170357456, 55534196, 444685088, 84101632, -1036655616, 1080018176, 147994640, -5793911, -7695776, 55731228, 16318191, 137087568, 107977896, 172195712, -159871568, 713860352, 105155024, -52278340, -47440328, 26797374, 11704323, 154628224, 63859720, 177926800, -3174517, 294978624, 586304384, -55530976, 100304664, -184816464, -121156736, -22429392, -187445792, -66290940, 399174784, -145260096, -435817856, -227558112, 632079616, 235678272, -8552354, 240827680, -37353868, -9822859, 337976896, -48387368, -7377143, 35740572, 353392864, 21862994, -32516660, 28525294, 31415538, 414974112, -20909780, 53856472, -18235358, 45784888, -63774628, 489165088, -36009004, -13625515, 11037798, -62288300, 22793928, 41337988, 507775744, 36684656, -117420112, 22649242, -64967556, -21585164, -59302760, 61845652, 551227904, 28334704, -96908688, -10986795, -3158680, -1148098, -1090116, -21733072, -98534064, 548509440, -12526541, -124452312, -39815688, 28119150, -82867096, -48626816, 41780368, 15056276, 114722336, 752520384, -72335840, 138609600, 457950, 58517588, -34335848, 7930120, 68274944, 71795744, -218303520, 30022896, 684244416, 29311810, 24879134, -5031822, -3604014, -107700064, 34280548, -161518960, -29972698, 45524776, -28767690, 70451960, 997068864, 181172464, -10389794, 282143392, -18262200, -9411616, 194651136, -34642400, 14696036, 32774090, 266709152, -12321724, -7934147, 42899744, 17961822, 326197120, -61064236, 2757905, -9434969, 114016616, -45294724, 423241632, 44844560, 7194607, -20771536, 17406428, -12688407, 27344446, 398144544, -20988432, 7578201, -36547220, 31998848, 1553972, 12336757, 23499376, 524998272, 38193264, -220705488, -3866007, -51896088, -8053332, 4608500, 2672543, 105980736, 617651200, 138849584, -138894416, -16658031, 14451491, -13349295, 42108932, 90309472, 45946488, 90752120, 714260864, -36247644, 218070784, 60232888, 133086544, 36377836, 146851648, 21597244, -80293880, -242705376, -25434260, 721932224, -73526080, 12684917, -26789322, -47208132, -29985852, -50325744, 4686614, 48175036, 81419696, -245451200, -121876408, 664714368, 166866720, 2983391, 263386720, -68162208, -7784091, 192441376, -145223, -15735686, -35828080, 344984128, 6308501, -28874260, 1040187, 139961712, 251922656, -73661104, -232072656, 127662000, 362434304, 189085392, 530900640, -2567048, -48370192, -40885672, 82937160, 128033784, 63094680, 384248448, 54663660, -320496640, -208546160, 766008512, 371514944, 699983808, 56493048, 1276140544, -85480856, -172129408, 182972048, 17228992, 16679505, 132060848, 21129896, -319555488, 617272960, 74918456, -142655184, 15233981, 243838976, 160190736, 297619744, 148904096, 314365024, -1673695, 579634560, 47073380, -135740560, 44690208, 97419520, 61031752, 157764080, 80927112, 97527968, 62705448, 190179008, 603058240, -73368240, 30219122, -3786282, -19939118, -20823612, -51310096, -75429024, 90901104, 18365818, -393250432, -234402672, 705817728 }; +const Word32 prec_chol_speech_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = +{ + //Q28 + 232432352, -59879628, 304533312, -125429152, 99142344, 326068544, -56826444, 46350480, +37527544, 329625600, 31308164, -19632564, 32069984, 57804624, 403167520, 3554890, +64722740, -62716724, 56281252, -4959882, 478142080, -101929504, -14876156, 39897560, +-40777760, -47372952, 187926288, 341264960, 21311090, -155172336, 108759040, -143880592, +-20300968, -5616206, 73920144, 570679040, 218755296, -162775504, -64450816, -7369627, +-36893500, -37446476, -80293072, 8201777, 597213568, -152507040, -256513440, -45927696, +-77678512, -140313632, -170642272, -94367944, 112342656, 201967072, 756224576, -208080960, +225792336, 58484840, 66006132, -48434348, 7039720, -102562208, 39706704, -339747744, +-90058216, 796577920, 202634944, 37851548, 10156524, 82895824, 73911016, -121567440, +-148495536, -112251120, 27724282, 54130280, 84421344, 906663552, 209343680, 32186754, +306301216, -116259936, -36924908, 224391904, -24221736, 35642860, 46462152, 312121440, +-39075344, -7622225, 60599840, 68880272, 244525904, -58326728, -36760892, 23687014, +173225968, 23444078, 473461088, -15582947, -34961840, 37741220, 31105764, -74304544, +12497281, 425261888, 33453500, 9509863, -120815016, 63221652, 7134209, 101693816, +61658284, 770215168, -17228724, -276690656, 128551864, -10146055, -15149155, 107287480, +-8414646, -387697024, 649792832, 50705580, -73682312, -57487332, 8967623, -3074928, +20067160, 135318848, 273094432, -35929816, 819158720, -19654308, -23457232, 20863072, +11649830, -4230006, 119185344, 150983408, -51511960, -81179712, 365100416, 677546368, +-1104880, 67182952, -148998320, -17748684, -31462514, 36981012, -243459152, -30465546, +39841460, -70792064, -7307618, 793560192, 196828960, -32199102, 232271296, -76255536, +20992994, 207772000, 19910932, 13635984, 32428882, 280196960, -25198842, -1165278, +42992624, -13211856, 237527792, -62810408, -99852624, 47340472, 231473232, -57426664, +489151424, 19632028, 2961111, -8761465, 94918512, -12379975, 80280456, 362603424, +142636400, 32065152, -350124672, 127381216, 47764332, 62010736, -35439924, 1157346560, +-346969728, -366012832, 596499264, 170357456, 55534196, 444685088, 84101632, -1036655616, +1080018176, 147994640, -5793911, -7695776, 55731228, 16318191, 137087568, 107977896, +172195712, -159871568, 713860352, 105155024, -52278340, -47440328, 26797374, 11704323, +154628224, 63859720, 177926800, -3174517, 294978624, 586304384, -55530976, 100304664, +-184816464, -121156736, -22429392, -187445792, -66290940, 399174784, -145260096, -435817856, +-227558112, 632079616, 235678272, -8552354, 240827680, -37353868, -9822859, 337976896, +-48387368, -7377143, 35740572, 353392864, 21862994, -32516660, 28525294, 31415538, +414974112, -20909780, 53856472, -18235358, 45784888, -63774628, 489165088, -36009004, +-13625515, 11037798, -62288300, 22793928, 41337988, 507775744, 36684656, -117420112, +22649242, -64967556, -21585164, -59302760, 61845652, 551227904, 28334704, -96908688, +-10986795, -3158680, -1148098, -1090116, -21733072, -98534064, 548509440, -12526541, +-124452312, -39815688, 28119150, -82867096, -48626816, 41780368, 15056276, 114722336, +752520384, -72335840, 138609600, 457950, 58517588, -34335848, 7930120, 68274944, +71795744, -218303520, 30022896, 684244416, 29311810, 24879134, -5031822, -3604014, +-107700064, 34280548, -161518960, -29972698, 45524776, -28767690, 70451960, 997068864, +181172464, -10389794, 282143392, -18262200, -9411616, 194651136, -34642400, 14696036, +32774090, 266709152, -12321724, -7934147, 42899744, 17961822, 326197120, -61064236, +2757905, -9434969, 114016616, -45294724, 423241632, 44844560, 7194607, -20771536, +17406428, -12688407, 27344446, 398144544, -20988432, 7578201, -36547220, 31998848, +1553972, 12336757, 23499376, 524998272, 38193264, -220705488, -3866007, -51896088, +-8053332, 4608500, 2672543, 105980736, 617651200, 138849584, -138894416, -16658031, +14451491, -13349295, 42108932, 90309472, 45946488, 90752120, 714260864, -36247644, +218070784, 60232888, 133086544, 36377836, 146851648, 21597244, -80293880, -242705376, +-25434260, 721932224, -73526080, 12684917, -26789322, -47208132, -29985852, -50325744, +4686614, 48175036, 81419696, -245451200, -121876408, 664714368, 166866720, 2983391, +263386720, -68162208, -7784091, 192441376, -145223, -15735686, -35828080, 344984128, +6308501, -28874260, 1040187, 139961712, 251922656, -73661104, -232072656, 127662000, +362434304, 189085392, 530900640, -2567048, -48370192, -40885672, 82937160, 128033784, +63094680, 384248448, 54663660, -320496640, -208546160, 766008512, 371514944, 699983808, +56493048, 1276140544, -85480856, -172129408, 182972048, 17228992, 16679505, 132060848, +21129896, -319555488, 617272960, 74918456, -142655184, 15233981, 243838976, 160190736, +297619744, 148904096, 314365024, -1673695, 579634560, 47073380, -135740560, 44690208, +97419520, 61031752, 157764080, 80927112, 97527968, 62705448, 190179008, 603058240, +-73368240, 30219122, -3786282, -19939118, -20823612, -51310096, -75429024, 90901104, +18365818, -393250432, -234402672, 705817728, +}; #endif const float weights_speech[N_SMC_MIXTURES] = @@ -504,7 +646,21 @@ const float means_music[N_SMC_MIXTURES*N_PCA_COEF] = -0.944544f, 1.303678f, 0.326616f, 0.443005f, 0.339787f, 0.353776f, 0.811425f, -0.201050f, 0.056356f, 0.825931f, 0.425448f, -0.400853f, 2.416758f, 0.991434f, -0.249973f, -0.264729f, -0.003941f, -0.242565f, -0.114334f, 0.179267f, 0.085679f, -0.001649f, -0.267403f, 0.028878f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 means_music_fx[N_SMC_MIXTURES*N_PCA_COEF] = +{ + //Q27 + 88128840, 204692912, 12705453, 71462352, 12596468, 40563280, -1386066, -52265056, +-39146480, -6666997, 9846481, 10781844, -57806772, -1044348, 8851928, -134822384, +-26193530, -61436556, 53966400, 37307696, -3429397, 19347082, 13950591, -11268518, +-48344556, 197877728, -36032360, -8134399, -1136958, -20838778, -32593702, 16027207, +-26324122, -40342764, -3959959, 8085410, -332178944, 164642336, -341718, 34049964, +-15855543, 8985877, 22481872, 6408225, -40554556, 2538594, 4626216, 1585111, +-126774552, 174976704, 43837656, 59459124, 45605440, 47483012, 108907616, -26984474, +7563974, 110854584, 57102664, -53801580, 324371776, 133068016, -33550808, -35531324, +-528952, -32556524, -15345650, 24060810, 11499641, -221325, -35890224, 3875939, +}; +#endif const float log_det_chol_music[N_SMC_MIXTURES] = { 3.236255f, 3.517110f, 5.675361f, 2.875446f, -2.234983f, 7.961542f, @@ -523,7 +679,66 @@ const float prec_chol_music[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) #ifdef IVAS_FLOAT_FIXED const Word32 prec_chol_music_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { -232322304, 25836912, 235062480, -21970368, -88834688, 289087264, 38061464, 12829336, 25661356, 216226640, 3946806, 35926596, -49888460, 17696070, 235923888, -6313870, -29279598, 78824728, -1208764, 27664958, 273027328, -37742024, -71072048, 103689640, -10025259, -37697196, -61880548, 396421184, -26288422, 15300284, -459293, -23770764, 3474360, -25473720, 47310944, 332768160, 39007700, 9191767, -7766106, -35545148, 21523424, 6770747, -124619552, 1410091, 508736736, -25959320, -7817109, 19565456, 1404185, -51538532, -45457932, 165445904, -28407450, -81223736, 586521024, -46704816, -52083996, 9754944, -31150324, -39091720, -40270152, 66884720, 30225296, 100608000, 24531512, 657688896, 68076576, 48213692, -48020152, 49097380, -4268929, 59026004, -192775040, -50962204, -31122406, -117876448, -182476256, 625576192, 144678656, -9655086, 218327952, 6044361, -48620372, 254562448, -42861896, -13298292, 33123862, 287620000, -12122277, -30804848, 33071786, 16293764, 388198208, -19213268, 24338774, 14173929, -33506382, -87690080, 361291840, 34886676, 52138220, -48904644, -17044846, 2490812, 73471056, 354929120, 40659380, 38784092, 24256364, -112064552, -5929471, -94763888, -36720092, 322304000, -56521232, -65294776, 11020081, -15673409, 12677670, -51147960, -59997204, 68434128, 456261088, 44138304, 4000225, -77793136, 61852092, -3655554, -41457440, 71121976, -86157848, -69391640, 621925248, 56908, 50305072, -2964869, 102686760, -14214731, -68874360, 41617696, -34848560, -20007568, 56042344, 554498560, -36107792, -20590342, -25757992, -64163052, 53273432, 35053644, -77861048, -7609071, 98731368, 8330089, 81691888, 807686592, 206408080, 29242554, 246745872, -30320054, -141839152, 416885632, -31085094, 1968705, -7943542, 294907488, 972004, 26633630, -66413080, -21165868, 367168960, 11512928, -20904948, 56274004, -44399224, -4818953, 360435008, -49596404, 13496398, 7960453, 47073916, -4338185, -43219720, 462487456, 13815031, 2689991, 103510592, -71014872, -75477072, -97242624, -9769708, 371118464, -17768548, -22740510, -33236068, -8622415, 24936848, 18291192, -70021120, 2836020, 476147872, 63471028, 25856776, -21647440, 32818918, 34664144, 29404152, 114646368, -122478512, -68419632, 815255936, 35136860, -35646080, -34052916, 1725771, 2581812, -62708940, 215970288, -82662016, -34325112, 447461504, 753578304, -99274408, -3290213, 4633733, -15484968, -36483064, 40284916, -407272960, 58910844, 134671648, -601330048, -345841248, 981086208, 206335056, 1025423, 222901824, -58332100, -39948832, 262789184, -18609020, 1410628, -1774089, 212590416, 18125298, 28513752, -59463552, 4719095, 246369264, -81872, -23613194, 15571135, -16710912, 46739712, 268572096, 29908542, 37123820, 22983444, 55254756, 2779112, -57131120, 341562368, 5126580, 21001584, -6036039, -24000546, -46808700, -51209432, -9852655, 337137760, -8485513, -113351704, -16093779, -60946660, 8815152, -10634339, -80527416, 50575120, 478848064, 149115360, 27080038, 22408992, -24449906, 61073900, 40576168, 139484976, -77672608, -93439968, 705148288, 18536542, 21612006, -26196616, -17896592, 48906792, 10430328, 52505440, -55231936, -34737696, 181267760, 633243008, -77855408, -1544846, -16549583, -11117523, 31134218, 10136123, -124216360, 27077622, 80264352, -345837472, -203551920, 593004544, 99558952, 18271060, 165076528, -18376286, -30611842, 213814752, -21311628, -7249636, 15457856, 170620528, -4867540, -16669573, -49741896, 22724940, 143143472, -39989100, -10398384, 72010760, 44482440, 6079526, 200783008, -1092263, 15936208, 13659607, 18654116, -27689922, -23768886, 188797104, 12175964, -32829120, -61108256, 16816140, 3177470, 18617342, -5304821, 286432992, 28388660, -118288232, 51768048, -15788031, 7528809, 37260184, -33815620, -179149264, 306826016, -17569370, 22469390, -41274636, -16302085, -108179, -24384408, 16991428, -10070088, 94377344, 317392448, -28549990, -4354291, -2879238, 26857504, 15448729, 28430268, -357556, -21060910, -72179608, -65214248, 414794528, 6270384, -21697370, 62073552, -9898557, 21225192, 16768895, 1158030, 20269024, 9883257, 18578686, -97534416, 397891136, 324576576, 23795998, 325167936, -97054984, -170963328, 433155232, -19735912, 25351044, 93515664, 372817920, 21614692, -10068209, 19011672, 14128295, 503773088, -8658386, 33526246, -13009456, -61316296, -60996588, 463537312, -78218872, -20931524, 80347832, -46129292, 3235184, 61337772, 540847488, -10609643, -67685192, 110726408, -146586160, -74121744, -133886744, 76196480, 465427072, 12021882, -46549660, 25719874, -9411616, 1885759, 63607392, -72460128, -51621212, 528433184, -179129392, -56301116, -69872408, 23375360, -64939904, -75586056, 97111088, -49225964, 47048952, 831205824, -126763272, -4281814, -11618423, -14073534, -94524984, -89800784, 104806864, 30433332, -80776520, 390530912, 774659392, 128537096, 13576928, -10674873, 30707942, -18166370, 3521068, -300103584, -56028652, 119586656, -8497861, 3017751, 1177908480, + //Q28 +232322304, 25836912, 235062480, -21970368, -88834688, 289087264, 38061464, 12829336, +25661356, 216226640, 3946806, 35926596, -49888460, 17696070, 235923888, -6313870, +-29279598, 78824728, -1208764, 27664958, 273027328, -37742024, -71072048, 103689640, +-10025259, -37697196, -61880548, 396421184, -26288422, 15300284, -459293, -23770764, +3474360, -25473720, 47310944, 332768160, 39007700, 9191767, -7766106, -35545148, +21523424, 6770747, -124619552, 1410091, 508736736, -25959320, -7817109, 19565456, +1404185, -51538532, -45457932, 165445904, -28407450, -81223736, 586521024, -46704816, +-52083996, 9754944, -31150324, -39091720, -40270152, 66884720, 30225296, 100608000, +24531512, 657688896, 68076576, 48213692, -48020152, 49097380, -4268929, 59026004, +-192775040, -50962204, -31122406, -117876448, -182476256, 625576192, 144678656, -9655086, +218327952, 6044361, -48620372, 254562448, -42861896, -13298292, 33123862, 287620000, +-12122277, -30804848, 33071786, 16293764, 388198208, -19213268, 24338774, 14173929, +-33506382, -87690080, 361291840, 34886676, 52138220, -48904644, -17044846, 2490812, +73471056, 354929120, 40659380, 38784092, 24256364, -112064552, -5929471, -94763888, +-36720092, 322304000, -56521232, -65294776, 11020081, -15673409, 12677670, -51147960, +-59997204, 68434128, 456261088, 44138304, 4000225, -77793136, 61852092, -3655554, +-41457440, 71121976, -86157848, -69391640, 621925248, 56908, 50305072, -2964869, +102686760, -14214731, -68874360, 41617696, -34848560, -20007568, 56042344, 554498560, +-36107792, -20590342, -25757992, -64163052, 53273432, 35053644, -77861048, -7609071, +98731368, 8330089, 81691888, 807686592, 206408080, 29242554, 246745872, -30320054, +-141839152, 416885632, -31085094, 1968705, -7943542, 294907488, 972004, 26633630, +-66413080, -21165868, 367168960, 11512928, -20904948, 56274004, -44399224, -4818953, +360435008, -49596404, 13496398, 7960453, 47073916, -4338185, -43219720, 462487456, +13815031, 2689991, 103510592, -71014872, -75477072, -97242624, -9769708, 371118464, +-17768548, -22740510, -33236068, -8622415, 24936848, 18291192, -70021120, 2836020, +476147872, 63471028, 25856776, -21647440, 32818918, 34664144, 29404152, 114646368, +-122478512, -68419632, 815255936, 35136860, -35646080, -34052916, 1725771, 2581812, +-62708940, 215970288, -82662016, -34325112, 447461504, 753578304, -99274408, -3290213, +4633733, -15484968, -36483064, 40284916, -407272960, 58910844, 134671648, -601330048, +-345841248, 981086208, 206335056, 1025423, 222901824, -58332100, -39948832, 262789184, +-18609020, 1410628, -1774089, 212590416, 18125298, 28513752, -59463552, 4719095, +246369264, -81872, -23613194, 15571135, -16710912, 46739712, 268572096, 29908542, +37123820, 22983444, 55254756, 2779112, -57131120, 341562368, 5126580, 21001584, +-6036039, -24000546, -46808700, -51209432, -9852655, 337137760, -8485513, -113351704, +-16093779, -60946660, 8815152, -10634339, -80527416, 50575120, 478848064, 149115360, +27080038, 22408992, -24449906, 61073900, 40576168, 139484976, -77672608, -93439968, +705148288, 18536542, 21612006, -26196616, -17896592, 48906792, 10430328, 52505440, +-55231936, -34737696, 181267760, 633243008, -77855408, -1544846, -16549583, -11117523, +31134218, 10136123, -124216360, 27077622, 80264352, -345837472, -203551920, 593004544, +99558952, 18271060, 165076528, -18376286, -30611842, 213814752, -21311628, -7249636, +15457856, 170620528, -4867540, -16669573, -49741896, 22724940, 143143472, -39989100, +-10398384, 72010760, 44482440, 6079526, 200783008, -1092263, 15936208, 13659607, +18654116, -27689922, -23768886, 188797104, 12175964, -32829120, -61108256, 16816140, +3177470, 18617342, -5304821, 286432992, 28388660, -118288232, 51768048, -15788031, +7528809, 37260184, -33815620, -179149264, 306826016, -17569370, 22469390, -41274636, +-16302085, -108179, -24384408, 16991428, -10070088, 94377344, 317392448, -28549990, +-4354291, -2879238, 26857504, 15448729, 28430268, -357556, -21060910, -72179608, +-65214248, 414794528, 6270384, -21697370, 62073552, -9898557, 21225192, 16768895, +1158030, 20269024, 9883257, 18578686, -97534416, 397891136, 324576576, 23795998, +325167936, -97054984, -170963328, 433155232, -19735912, 25351044, 93515664, 372817920, +21614692, -10068209, 19011672, 14128295, 503773088, -8658386, 33526246, -13009456, +-61316296, -60996588, 463537312, -78218872, -20931524, 80347832, -46129292, 3235184, +61337772, 540847488, -10609643, -67685192, 110726408, -146586160, -74121744, -133886744, +76196480, 465427072, 12021882, -46549660, 25719874, -9411616, 1885759, 63607392, +-72460128, -51621212, 528433184, -179129392, -56301116, -69872408, 23375360, -64939904, +-75586056, 97111088, -49225964, 47048952, 831205824, -126763272, -4281814, -11618423, +-14073534, -94524984, -89800784, 104806864, 30433332, -80776520, 390530912, 774659392, +128537096, 13576928, -10674873, 30707942, -18166370, 3521068, -300103584, -56028652, +119586656, -8497861, 3017751, 1177908480, }; #endif @@ -541,7 +756,21 @@ const float means_noise[N_SMC_MIXTURES*N_PCA_COEF] = -1.990813f, -0.723883f, -1.196019f, -1.768941f, -0.344735f, -0.677093f, -0.256214f, 1.351858f, -0.353724f, 0.768104f, -0.384513f, -0.371595f, -2.101499f, -1.294068f, -0.188406f, -1.843713f, -0.786294f, -0.539876f, 0.241184f, 1.600162f, -0.300266f, 1.225627f, 0.080940f, -0.231195f, }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 means_noise_fx[N_SMC_MIXTURES*N_PCA_COEF] = +{ + //Q27 + 139344176, 85522728, -140739360, -127496240, -11822971, -83343840, -30885916, 128914920, +55142280, 43453528, -85148664, 1472368, -161889936, -113373848, -98158928, -153415568, +-42456556, -57162792, 60016264, 208695008, -13554783, 127521472, -30868064, -26999372, +178972768, 74413936, -168077904, -33409476, 6877316, -59676692, -21294850, 147021424, +33076482, 7783688, -105503456, 23490786, 165446160, 44187832, -118290112, -7072334, +20942126, -40746756, -14936017, 106057376, 17580778, 8650601, -64193252, 13850330, +-267202400, -97157928, -160526960, -237423248, -46269548, -90877888, -34388460, 181443312, +-47476032, 103093176, -51608460, -49874636, -282058432, -173686864, -25287426, -247458976, +-105534592, -72460928, 32371168, 214770112, -40301020, 164500864, 10863583, -31030468, +}; +#endif const float log_det_chol_noise[N_SMC_MIXTURES] = { 11.878154f, 13.025598f, 12.831137f, 7.099546f, 13.242941f, 11.898383f, @@ -559,7 +788,67 @@ const float prec_chol_noise[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) #ifdef IVAS_FLOAT_FIXED const Word32 prec_chol_noise_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = -{ 438274304, -101757704, 527959936, -92401656, -40066944, 569343040, -172637280, 92605400, 90126936, 502116576, -70281768, 15855140, 42644192, -75216424, 659778944, 21871852, 200184128, -66884720, -206631952, -271753600, 579995584, -41937404, 180430768, -70175472, 31213406, -61285692, -15286594, 914624320, 95589064, -197632384, 189309536, -378043296, -192572912, -278483808, 89525912, 667027200, 86715120, -398169504, -134308192, -24187914, -117845048, -77955000, 87847112, -65235184, 674295616, 118658400, 141179872, -385477600, 90381952, 47387716, -172783040, 213091584, -92059136, 180518816, 1113415808, 89164056, 159457376, -287768704, 140198736, 53548040, 12615661, 211052816, -195082784, -315002016, 199766976, 1060323264, -162984080, -169212048, 275297472, -209311472, -148597008, 90449592, -308289792, 131478344, 206830864, -316232544, -116264224, 1640643200, 575459840, -110880488, 540680576, -20299626, -120988960, 592097728, 75230912, 156925216, 72533680, 553807552, -272710816, -155779808, 38634840, -156862400, 752763072, -182010784, 94162056, -90105192, -416297760, -234046992, 690654080, 181351232, 128870224, -96438120, 75957304, 10280273, -216431728, 1041874240, -2115271, -161272000, 112353664, -387182976, 14206141, -50861004, -182521616, 664376128, -13428752, -358865984, -61852360, -3840774, -153737552, -335891136, 127812056, 72605352, 719982528, -11629161, -73992352, -370089824, -83219288, -95394448, -78352816, -28330678, -1691143, 79366160, 1178542208, -85602184, 94195616, -206783344, 134659312, -21508390, -89069568, 127365104, -119468808, -308679296, 307254432, 1144636160, 19030194, -8984535, -70737840, -155128048, 221865936, 50559280, 68931808, -94236416, 266750224, 260988512, 297829664, 1781693056, 421042624, -59415772, 527790560, -98705864, -94187288, 738609024, -33151778, 77225928, -97992632, 568460672, 43811888, 22125524, -44354932, -38434856, 696296640, 8982924, 76764488, 78076064, -148321856, -92465280, 669700032, 31240518, 1078842, -80158048, 17065784, 42776532, -97703528, 836559488, 101995008, -23285702, -44140184, -65183912, -32696244, -173090400, 116281136, 675435968, 24943022, -289375584, -28602066, -60206048, -67754184, -46702400, 88339696, -173576816, 792158656, 13933948, -103396240, -80619760, 4375229, 22152636, 20907632, 211938912, -232494096, 278967264, 1247803392, -70594232, 74254616, -54600844, 26415928, -10635144, 33370554, 298018912, -152319936, -244328336, 782944064, 1259614592, 20826564, 8513699, 101483096, -35796672, -149573040, -20171850, -532795264, 142151072, 163440688, -597162880, -376404768, 1708897920, 209270944, -23997324, 331448000, 6588480, -58776092, 382514624, -18828332, 39394512, -32496796, 381425568, 21953188, -17026056, -17383880, 29140548, 410380096, -22143510, 714575, 45383844, 30147180, -75072000, 468424448, 6863357, -2480612, -3718636, -18806856, 45715632, -12727867, 520436480, 52698712, 758061, -3390071, -57345060, -19137300, -94494648, 48669764, 553184256, 15456245, -55625196, 37220456, -21190832, 14073266, 37691024, -82113600, -125746712, 566309184, 24663312, -79263352, -81187768, 18228110, -23309324, -35227592, 45638592, -100310304, 111057384, 747604032, -38703024, -49378972, -1829387, -24915374, -44106092, 3890166, 95093528, 4453076, -105516344, 61340456, 779151360, 14067092, 24841018, 46075604, 14026826, -73798008, -27891786, -172234896, 22042846, 8342168, -136356624, -15677436, 917865664, 323919712, -183311616, 550143680, -136109392, -92123024, 508834976, -36581580, 25082610, 186993744, 612834112, 3323231, -41768288, 10869757, -32662958, 900676672, -132146208, 173920944, -285617472, -265424416, -17592454, 746075264, 174698064, 87668608, -12579422, 50304000, -52162648, -8793140, 1121056000, 147971552, -143892672, 40492148, -332957664, -99433056, -229635520, 90426776, 754189248, 91340536, -315738880, 3497714, 95215400, -131254200, -125219504, 210190864, -40012452, 774223424, 323906560, 82644032, -378786592, 18817058, 56163140, 78116600, -101264320, -171897472, 108985600, 1384031744, 217351648, 179599424, -252806064, 287773824, -31378494, -40052984, 121498448, -198681968, -319067488, 616561856, 1259752576, -10863851, -35322348, 214155392, -580386432, 360088192, 294499200, -423245408, 122124976, 92175096, -14300899, 19809194, 1852783360, 372837536, -142020880, 513938464, -66074584, -101171176, 458718880, -55148724, 84335712, 174501568, 494334368, -23007872, -3568849, -19046838, -125238024, 850134528, -69946760, 193497408, -212820192, -393971456, -100102000, 727705408, 162900592, 171089760, -145332032, -88654296, 45897900, 17440252, 800112128, 49616000, -91281208, 77360680, -280252256, -125265672, -100565856, -62217164, 572262784, 35549444, -258559712, -79083232, 11355357, -30667678, -250266672, -44622024, 54628764, 688208640, 147327840, -118213336, -250863936, -92370248, 8184597, -101297072, -22858352, -70537856, 128080216, 1281079808, 22687360, 96064192, -115392352, 184689760, 94979176, -117889608, 20655572, -206588192, -316042752, 525827200, 1154297216, -55784644, 65338264, -189560800, -157846496, 258337456, 90826744, -80055240, -94396936, 206332112, 185089200, 185797056, 1643156480, +{ + //Q28 + 438274304, -101757704, 527959936, -92401656, -40066944, 569343040, -172637280, 92605400, +90126936, 502116576, -70281768, 15855140, 42644192, -75216424, 659778944, 21871852, +200184128, -66884720, -206631952, -271753600, 579995584, -41937404, 180430768, -70175472, +31213406, -61285692, -15286594, 914624320, 95589064, -197632384, 189309536, -378043296, +-192572912, -278483808, 89525912, 667027200, 86715120, -398169504, -134308192, -24187914, +-117845048, -77955000, 87847112, -65235184, 674295616, 118658400, 141179872, -385477600, +90381952, 47387716, -172783040, 213091584, -92059136, 180518816, 1113415808, 89164056, +159457376, -287768704, 140198736, 53548040, 12615661, 211052816, -195082784, -315002016, +199766976, 1060323264, -162984080, -169212048, 275297472, -209311472, -148597008, 90449592, +-308289792, 131478344, 206830864, -316232544, -116264224, 1640643200, 575459840, -110880488, +540680576, -20299626, -120988960, 592097728, 75230912, 156925216, 72533680, 553807552, +-272710816, -155779808, 38634840, -156862400, 752763072, -182010784, 94162056, -90105192, +-416297760, -234046992, 690654080, 181351232, 128870224, -96438120, 75957304, 10280273, +-216431728, 1041874240, -2115271, -161272000, 112353664, -387182976, 14206141, -50861004, +-182521616, 664376128, -13428752, -358865984, -61852360, -3840774, -153737552, -335891136, +127812056, 72605352, 719982528, -11629161, -73992352, -370089824, -83219288, -95394448, +-78352816, -28330678, -1691143, 79366160, 1178542208, -85602184, 94195616, -206783344, +134659312, -21508390, -89069568, 127365104, -119468808, -308679296, 307254432, 1144636160, +19030194, -8984535, -70737840, -155128048, 221865936, 50559280, 68931808, -94236416, +266750224, 260988512, 297829664, 1781693056, 421042624, -59415772, 527790560, -98705864, +-94187288, 738609024, -33151778, 77225928, -97992632, 568460672, 43811888, 22125524, +-44354932, -38434856, 696296640, 8982924, 76764488, 78076064, -148321856, -92465280, +669700032, 31240518, 1078842, -80158048, 17065784, 42776532, -97703528, 836559488, +101995008, -23285702, -44140184, -65183912, -32696244, -173090400, 116281136, 675435968, +24943022, -289375584, -28602066, -60206048, -67754184, -46702400, 88339696, -173576816, +792158656, 13933948, -103396240, -80619760, 4375229, 22152636, 20907632, 211938912, +-232494096, 278967264, 1247803392, -70594232, 74254616, -54600844, 26415928, -10635144, +33370554, 298018912, -152319936, -244328336, 782944064, 1259614592, 20826564, 8513699, +101483096, -35796672, -149573040, -20171850, -532795264, 142151072, 163440688, -597162880, +-376404768, 1708897920, 209270944, -23997324, 331448000, 6588480, -58776092, 382514624, +-18828332, 39394512, -32496796, 381425568, 21953188, -17026056, -17383880, 29140548, +410380096, -22143510, 714575, 45383844, 30147180, -75072000, 468424448, 6863357, +-2480612, -3718636, -18806856, 45715632, -12727867, 520436480, 52698712, 758061, +-3390071, -57345060, -19137300, -94494648, 48669764, 553184256, 15456245, -55625196, +37220456, -21190832, 14073266, 37691024, -82113600, -125746712, 566309184, 24663312, +-79263352, -81187768, 18228110, -23309324, -35227592, 45638592, -100310304, 111057384, +747604032, -38703024, -49378972, -1829387, -24915374, -44106092, 3890166, 95093528, +4453076, -105516344, 61340456, 779151360, 14067092, 24841018, 46075604, 14026826, +-73798008, -27891786, -172234896, 22042846, 8342168, -136356624, -15677436, 917865664, +323919712, -183311616, 550143680, -136109392, -92123024, 508834976, -36581580, 25082610, +186993744, 612834112, 3323231, -41768288, 10869757, -32662958, 900676672, -132146208, +173920944, -285617472, -265424416, -17592454, 746075264, 174698064, 87668608, -12579422, +50304000, -52162648, -8793140, 1121056000, 147971552, -143892672, 40492148, -332957664, +-99433056, -229635520, 90426776, 754189248, 91340536, -315738880, 3497714, 95215400, +-131254200, -125219504, 210190864, -40012452, 774223424, 323906560, 82644032, -378786592, +18817058, 56163140, 78116600, -101264320, -171897472, 108985600, 1384031744, 217351648, +179599424, -252806064, 287773824, -31378494, -40052984, 121498448, -198681968, -319067488, +616561856, 1259752576, -10863851, -35322348, 214155392, -580386432, 360088192, 294499200, +-423245408, 122124976, 92175096, -14300899, 19809194, 1852783360, 372837536, -142020880, +513938464, -66074584, -101171176, 458718880, -55148724, 84335712, 174501568, 494334368, +-23007872, -3568849, -19046838, -125238024, 850134528, -69946760, 193497408, -212820192, +-393971456, -100102000, 727705408, 162900592, 171089760, -145332032, -88654296, 45897900, +17440252, 800112128, 49616000, -91281208, 77360680, -280252256, -125265672, -100565856, +-62217164, 572262784, 35549444, -258559712, -79083232, 11355357, -30667678, -250266672, +-44622024, 54628764, 688208640, 147327840, -118213336, -250863936, -92370248, 8184597, +-101297072, -22858352, -70537856, 128080216, 1281079808, 22687360, 96064192, -115392352, +184689760, 94979176, -117889608, 20655572, -206588192, -316042752, 525827200, 1154297216, +-55784644, 65338264, -189560800, -157846496, 258337456, 90826744, -80055240, -94396936, +206332112, 185089200, 185797056, 1643156480, }; #endif @@ -1178,7 +1467,42 @@ const float mel_fb[246] = 1.43369924f, 1.19031958f, 0.94874676f, 0.70895416f, 0.47091573f, 0.23460598f }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 mel_fb_fx[246] = +{ +1306887040, 840596608, 701826176, 1445657472, 297866656, 1849617024, 67613584, 2079870080, +2136398336, 43602444, 11085289, 2103881216, 216592064, 1930891520, 495221376, 1652262272, +868758208, 1278725376, 1328027264, 819456448, 1865122304, 325699488, 282361312, 1821784192, +998734592, 1148749056, 1731480576, 371805248, 416003072, 1775678336, 1210549888, 936933760, +2096551936, 879033408, 50931740, 1268450304, 1850000256, 711813440, 297483360, 1435670272, +1757021184, 688459456, 390462400, 1459024128, 1799094144, 792129792, 348389472, 1355353856, +1960859008, 1008777088, 81952272, 186624608, 1138706560, 2065531392, 1326562816, 446434464, +820920896, 1701049216, 1735416832, 897505024, 79218296, 412066848, 1249978624, 2068265344, +1427142016, 645470720, 720341696, 1502012928, 2028388992, 1280196608, 547690816, 119094688, +867287040, 1599792768, 1977710976, 1274684288, 585524928, 169772688, 872799360, 1561958656, +2057180032, 1394176384, 743519808, 104758968, 90303584, 753307264, 1403963776, 2042724736, +1624950272, 1008721792, 403173792, 522533408, 1138761856, 1744309888, 1955425920, 1370165248, +794546816, 228258160, 192057744, 777318400, 1352936832, 1919225472, 1818485248, 1269977216, +729947136, 198137088, 328998400, 877506496, 1417536512, 1949346560, 1821784192, 1305685504, +797099392, 295810368, 325699488, 841798208, 1350384256, 1851673344, 1949095552, 1461789952, +981187520, 507106368, 39371848, 198388080, 685693696, 1166296064, 1640377344, 2108111744, +1725299968, 1269762304, 820087488, 376126688, 422183712, 877721408, 1327396096, 1771356928, +2085220096, 1652262272, 1224604032, 802116992, 384677824, 62263592, 495221376, 922879680, +1345366656, 1762805888, 2119650816, 1711953664, 1308959104, 910559680, 516651968, 127135704, +27832838, 435529952, 838524608, 1236923904, 1630831744, 2020347904, 1889397760, 1508377088, +1131466752, 758579072, 389629024, 24534324, 258085904, 639106560, 1016016832, 1388904576, +1757854592, 2122949376, 1810698880, 1453078016, 1099080704, 748633920, 401667360, 58112508, +336784768, 694405568, 1048403008, 1398849664, 1745816320, 2089371136, 1865386624, 1528457728, +1194747136, 864193536, 536738048, 212323040, 282097056, 619025856, 952736576, 1283290112, +1610745600, 1935160576, 2038376192, 1719875840, 1404252672, 1091455232, 781433280, 474137984, +169521872, 109107440, 427607776, 743230976, 1056028416, 1366050432, 1673345664, 1977961728, +2015022208, 1715626752, 1418774912, 1124424064, 832532224, 543058752, 255963904, 132461384, +431856928, 728708736, 1023059648, 1314951424, 1604424960, 1891519744, 2118692480, 1836239488, +1556051584, 1278092800, 1002327744, 728722176, 457242624, 187856208, 28791110, 311244128, +591432000, 869390912, 1145155968, 1418761472, 1690241024, 1959627392, 2068014592, 1802719104, +1539422848, 1278095872, 1018709056, 761233728, 505641920, 251906256, +}; +#endif const float dct_mtx[NB_MEL_BANDS * NB_MEL_COEF] = { 2.23434405e-01f, 2.22056858e-01f, 2.19310256e-01f, 2.15211533e-01f, 2.09785960e-01f, 2.03066987e-01f, 1.95096038e-01f, 1.85922257e-01f, 1.75602204e-01f, 1.64199505e-01f, 1.51784461e-01f, 1.38433616e-01f, @@ -1246,7 +1570,76 @@ const float dct_mtx[NB_MEL_BANDS * NB_MEL_COEF] = 2.22056858e-01f, 1.38433616e-01f, -7.73941268e-02f, -2.19310256e-01f, -1.51784461e-01f, 6.06959298e-02f, 2.15211533e-01f, 1.64199505e-01f, -4.36235222e-02f, -2.09785960e-01f, -1.75602204e-01f, 2.62821611e-02f, 2.03066987e-01f, 1.85922257e-01f, -8.77876168e-03f, -1.95096038e-01f }; - +#ifdef IVAS_FLOAT_FIXED +const Word32 dct_mtx_fx[NB_MEL_BANDS * NB_MEL_COEF] = +{ //Q31 + 479821728, 476863456, 470965184, 462163232, 450511904, 436083040, 418965536, 399264992, +377102848, 352615744, 325954656, 297283936, 266780352, 234631984, 201037040, 166202624, +130343520, 93680800, 56440512, 18852248, -18852248, -56440512, -93680800, -130343520, +-166202624, -201037040, -234631984, -266780352, -297283936, -325954656, -352615744, -377102848, +-399264992, -418965536, -436083040, -450511904, -462163232, -470965184, -476863456, -479821728, +478711680, 466924192, 443639520, 409430944, 365140832, 311859712, 250899600, 183761504, +112098584, 37675424, -37675424, -112098584, -183761504, -250899600, -311859712, -365140832, +-409430944, -443639520, -466924192, -478711680, -478711680, -466924192, -443639520, -409430944, +-365140832, -311859712, -250899600, -183761504, -112098584, -37675424, 37675424, 112098584, +183761504, 250899600, 311859712, 365140832, 409430944, 443639520, 466924192, 478711680, +476863456, 450511904, 399264992, 325954656, 234631984, 130343520, 18852248, -93680800, +-201037040, -297283936, -377102848, -436083040, -470965184, -479821728, -462163232, -418965536, +-352615744, -266780352, -166202624, -56440512, 56440512, 166202624, 266780352, 352615744, +418965536, 462163232, 479821728, 470965184, 436083040, 377102848, 297283936, 201037040, +93680800, -18852248, -130343520, -234631984, -325954656, -399264992, -450511904, -476863456, +474279968, 427854144, 339546976, 218002576, 75118568, -75118568, -218002576, -339546976, +-427854144, -474279968, -474279968, -427854144, -339546976, -218002576, -75118568, 75118568, +218002576, 339546976, 427854144, 474279968, 474279968, 427854144, 339546976, 218002576, +75118568, -75118568, -218002576, -339546976, -427854144, -474279968, -474279968, -427854144, +-339546976, -218002576, -75118568, 75118568, 218002576, 339546976, 427854144, 474279968, +470965184, 399264992, 266780352, 93680800, -93680800, -266780352, -399264992, -470965184, +-470965184, -399264992, -266780352, -93680800, 93680800, 266780352, 399264992, 470965184, +470965184, 399264992, 266780352, 93680800, -93680800, -266780352, -399264992, -470965184, +-470965184, -399264992, -266780352, -93680800, 93680800, 266780352, 399264992, 470965184, +470965184, 399264992, 266780352, 93680800, -93680800, -266780352, -399264992, -470965184, +466924192, 365140832, 183761504, -37675424, -250899600, -409430944, -478711680, -443639520, +-311859712, -112098584, 112098584, 311859712, 443639520, 478711680, 409430944, 250899600, +37675424, -183761504, -365140832, -466924192, -466924192, -365140832, -183761504, 37675424, +250899600, 409430944, 478711680, 443639520, 311859712, 112098584, -112098584, -311859712, +-443639520, -478711680, -409430944, -250899600, -37675424, 183761504, 365140832, 466924192, +462163232, 325954656, 93680800, -166202624, -377102848, -476863456, -436083040, -266780352, +-18852248, 234631984, 418965536, 479821728, 399264992, 201037040, -56440512, -297283936, +-450511904, -470965184, -352615744, -130343520, 130343520, 352615744, 470965184, 450511904, +297283936, 56440512, -201037040, -399264992, -479821728, -418965536, -234631984, 18852248, +266780352, 436083040, 476863456, 377102848, 166202624, -93680800, -325954656, -462163232, +456689664, 282249728, 0, -282249728, -456689664, -456689664, -282249728, 0, +282249728, 456689664, 456689664, 282249728, 0, -282249728, -456689664, -456689664, +-282249728, 0, 282249728, 456689664, 456689664, 282249728, 0, -282249728, +-456689664, -456689664, -282249728, 0, 282249728, 456689664, 456689664, 282249728, +0, -282249728, -456689664, -456689664, -282249728, 0, 282249728, 456689664, +450511904, 234631984, -93680800, -377102848, -479821728, -352615744, -56440512, 266780352, +462163232, 436083040, 201037040, -130343520, -399264992, -476863456, -325954656, -18852248, +297283936, 470965184, 418965536, 166202624, -166202624, -418965536, -470965184, -297283936, +18852248, 325954656, 476863456, 399264992, 130343520, -201037040, -436083040, -462163232, +-266780352, 56440512, 352615744, 479821728, 377102848, 93680800, -234631984, -450511904, +443639520, 183761504, -183761504, -443639520, -443639520, -183761504, 183761504, 443639520, +443639520, 183761504, -183761504, -443639520, -443639520, -183761504, 183761504, 443639520, +443639520, 183761504, -183761504, -443639520, -443639520, -183761504, 183761504, 443639520, +443639520, 183761504, -183761504, -443639520, -443639520, -183761504, 183761504, 443639520, +443639520, 183761504, -183761504, -443639520, -443639520, -183761504, 183761504, 443639520, +436083040, 130343520, -266780352, -476863456, -352615744, 18852248, 377102848, 470965184, +234631984, -166202624, -450511904, -418965536, -93680800, 297283936, 479821728, 325954656, +-56440512, -399264992, -462163232, -201037040, 201037040, 462163232, 399264992, 56440512, +-325954656, -479821728, -297283936, 93680800, 418965536, 450511904, 166202624, -234631984, +-470965184, -377102848, -18852248, 352615744, 476863456, 266780352, -130343520, -436083040, +427854144, 75118568, -339546976, -474279968, -218002576, 218002576, 474279968, 339546976, +-75118568, -427854144, -427854144, -75118568, 339546976, 474279968, 218002576, -218002576, +-474279968, -339546976, 75118568, 427854144, 427854144, 75118568, -339546976, -474279968, +-218002576, 218002576, 474279968, 339546976, -75118568, -427854144, -427854144, -75118568, +339546976, 474279968, 218002576, -218002576, -474279968, -339546976, 75118568, 427854144, +418965536, 18852248, -399264992, -436083040, -56440512, 377102848, 450511904, 93680800, +-352615744, -462163232, -130343520, 325954656, 470965184, 166202624, -297283936, -476863456, +-201037040, 266780352, 479821728, 234631984, -234631984, -479821728, -266780352, 201037040, +476863456, 297283936, -166202624, -470965184, -325954656, 130343520, 462163232, 352615744, +-93680800, -450511904, -377102848, 56440512, 436083040, 399264992, -18852248, -418965536, +}; +#endif const float SF[N_FEATURES*2] = { 0.0048f, -0.0952f, diff --git a/lib_enc/rom_enc.h b/lib_enc/rom_enc.h index 812db4821e8047a3c9fe7c84ae18a6f65df3ffb8..3542e43a6aa17e18596c8ea5c52bc5f30c17c7eb 100644 --- a/lib_enc/rom_enc.h +++ b/lib_enc/rom_enc.h @@ -124,6 +124,23 @@ extern const float means_music[]; extern const float weights_noise[]; extern const float means_noise[]; extern const float prec_chol_speech[]; +#ifdef IVAS_FLOAT_FIXED +extern const Word32 pca_components_fx[]; +extern const Word32 pca_mean_fx[]; +extern const Word32 sm_means_fx[]; +extern const Word32 sm_scale_fx[]; +extern const Word32 bcox_lmbd_fx[N_SMC_FEATURES]; +extern const Word32 hout_intervals_fx[]; +extern const Word32 bcox_add_cnst_fx[N_SMC_FEATURES]; +extern const Word32 prec_chol_speech_fx[]; +extern const Word32 prec_chol_music_fx[]; +extern const Word32 prec_chol_noise_fx[]; +extern const Word32 means_speech_fx[]; +extern const Word32 means_music_fx[]; +extern const Word32 means_noise_fx[]; +extern const Word32 mel_fb_fx[]; +extern const Word32 dct_mtx_fx[]; +#endif extern const float log_det_chol_speech[]; extern const float prec_chol_music[]; extern const float log_det_chol_music[]; diff --git a/lib_enc/speech_music_classif.c b/lib_enc/speech_music_classif.c index d529e73a6da00e16fe1aa46e0fe7833512f861cf..6a5aa1c4a2507a7daa086c729b113a4bc8ad2f43 100644 --- a/lib_enc/speech_music_classif.c +++ b/lib_enc/speech_music_classif.c @@ -113,18 +113,27 @@ void speech_music_clas_init( int16_t i; set_f( hSpMusClas->FV_st, 0.0f, N_SMC_FEATURES ); - +#ifdef IVAS_FLOAT_FIXED + set_zero_fx( hSpMusClas->FV_st_fx, N_SMC_FEATURES ); +#endif hSpMusClas->inact_cnt = 0; set_s( hSpMusClas->past_dec, 0, HANG_LEN - 1 ); set_f( hSpMusClas->past_dlp, 0, HANG_LEN - 1 ); set_f( hSpMusClas->past_dlp_mean_ST, 0, HANG_LEN - 1 ); hSpMusClas->dlp_mean_ST = 0.0f; +#ifdef IVAS_FLOAT_FIXED + hSpMusClas->dlp_mean_ST_fx = 0; + hSpMusClas->dlp_var_LT_fx = 0; +#endif hSpMusClas->dlp_mean_LT = 0.0f; hSpMusClas->dlp_var_LT = 0.0f; for ( i = 0; i < N_SMC_FEATURES; i++ ) { hSpMusClas->prev_FV[i] = 0.5f * hout_intervals[2 * i] + 0.5f * hout_intervals[2 * i + 1]; +#ifdef IVAS_FLOAT_FIXED + hSpMusClas->prev_FV_fx[i] = (Word32) ( hSpMusClas->prev_FV[i] * ONE_IN_Q20 ); +#endif } for ( i = 0; i < NB_BANDS_SPMUS; i++ ) @@ -1129,7 +1138,6 @@ static int16_t attack_det( * * 1st stage of the speech/music classification (based on the GMM model) *---------------------------------------------------------------------*/ - /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ #ifdef IVAS_FLOAT_FIXED diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index bba2c502a73df084323ef3ca645c61340d9359ec..26170c4d2a437cb3a509acd0945766b28cf83942 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -6,7 +6,7 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" +// #include "prot_fx.h" #include "rom_enc.h" #include "rom_com_fx.h" #include "rom_com.h" @@ -14,7 +14,11 @@ #include "prot_fx1.h" /* Function prototypes */ #include "prot_fx2.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ - +#ifdef IVAS_FLOAT_FIXED +#include +#include "ivas_prot.h" +#include "prot.h" +#endif /*---------------------------------------------------------------------* * Local constants *---------------------------------------------------------------------*/ @@ -24,7 +28,8 @@ #define ATT_3LSUB_POS_16k 26 /* (short)((4.0f * ATT_NSEG / (float)NB_SUBFR16k) + 0.5f) */ #define LOG_PROB_CONST 11292 /*0.5f * N_FEATURES * LOG_PI2 in Q10 */ - +#define DLP_BIAS 0.138121f +#define DLP_BIAS_FX 72415 /*Q19*/ /*---------------------------------------------------------------------* * Local functions *---------------------------------------------------------------------*/ @@ -54,6 +59,31 @@ 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 +Word32 log_weights_speech_compute[N_SMC_MIXTURES] = { + -3529378, + -3679759, + -3803054, + -3229859, + -4048972, + -3929047, +}; +Word32 log_weights_music_compute[N_SMC_MIXTURES] = { + -5058325, + -4983143, + -3436984, + -5133896, + -8505198, + -2561831, +}; +Word32 log_weights_noise_compute[N_SMC_MIXTURES] = { + -433769, + -105783, + 407264, + -3350157, + 103199, + -627672, +}; /*---------------------------------------------------------------------* * speech_music_clas_init_fx() * @@ -1469,322 +1499,447 @@ static Word16 attack_det_fx( /* o : attack flag return attack; } -#ifdef IVAS_CODE +#ifdef IVAS_FLOAT_FIXED /* -------------------------------------------------------------------- - * *ivas_smc_gmm() * *1st stage of the speech / music classification(based on the GMM model) * -------------------------------------------------------------------- - */ /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ -int16_t ivas_smc_gmm( +Word16 ivas_smc_gmm_fx( Encoder_State *st, /* i/o: state structure */ STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float Etot, /* i : total frame energy */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float non_sta, /* i : unbound non-stationarity */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* i/o: sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -) + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + const Word16 Etot_fx, /* i : total frame energy */ + Word16 lsp_new_fx[M], /* i : LSPs in current frame TODO:For now removing 'const' to avoid warning */ + Word16 cor_map_sum_fx, /* i : correlation map sum (from multi-harmonic anal.) */ + Word32 epsP_fx[M + 1], /* i : LP prediciton error TODO:For now removing 'const' to avoid warning */ + Word32 PS_fx[], /* i : energy spectrum TODO:For now removing 'const' to avoid warning */ + const Word16 non_sta_fx, /* i : unbound non-stationarity */ + const Word16 relE_fx, /* i : relative frame energy */ + Word16 *high_lpn_flag, /* i/o: sp/mus LPN flag */ + const Word16 flag_spitch /* i : flag to indicate very short stable pitch */ + , + Word16 Qfact_PS, + Word16 Q_esp, + Word16 Qfact_PS_past ) { - int16_t i, m, dec; - int16_t flag_odv; - float lps, lpm, lpn; - float ps[N_SMC_MIXTURES], pm[N_SMC_MIXTURES], pn[N_SMC_MIXTURES]; - float fvm[N_PCA_COEF], lprob; - float dlp, ftmp, sum_PS, ps_diff, ps_sta, wrelE, wdrop, wght; - float wrise; - float dlp_mean2var; - float FV[N_SMC_FEATURES], *pFV, PS_norm[128], dPS[128]; - const float *pODV; - float *pFV_st, smc_st_mean_fact; - int16_t relE_attack_flag; - int16_t j, len; - const float *pt_mel_fb; - float melS[NB_MEL_BANDS], mfcc[NB_MEL_BANDS]; - int16_t odv_cnt; - int16_t i_out[N_SMC_FEATURES], *p_out; - + Word16 i, m, dec; + Word16 flag_odv; + Word32 lps_fx, lpm_fx, lpn_fx; + Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; + Word32 lprob_fx; + Word16 lprob_exp = 0; + Word32 fvm_fx[N_PCA_COEF]; + Word16 fvm_exp = 0; + Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; + Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; + Word32 wrise_fx; + Word16 dlp_mean2var_fx; + Word16 dlp_mean2var_q; + Word32 FV_fx[N_SMC_FEATURES], *pFV_fx; + Word32 dPS_fx[128]; + Word32 PS_norm_fx[128]; + const Word32 *pODV_fx; + Word32 *pFV_st_fx; + Word16 relE_attack_flag, smc_st_mean_fact_fx; + Word16 j, len; + const Word32 *pt_mel_fb_fx; + Word32 melS_fx[NB_MEL_BANDS], mfcc_fx[NB_MEL_BANDS]; + Word16 odv_cnt; + Word16 i_out[N_SMC_FEATURES], *p_out; + Word16 temp_exp; + Word16 Qfact_FV; + Word32 temp32, temp32_log; + Word32 temp32_log1, temp32_log2; + Word16 temp16; + Word16 dotp_exp = 0; /*------------------------------------------------------------------* * Initialization *------------------------------------------------------------------*/ SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas; - + Word32 temp_sqrt, temp_acos; /*------------------------------------------------------------------* * State machine (sp_mus_state: -8 = INACTIVE, -7:-1 = UNSTABLE, 0:7 = ENTRY, 8 = STABLE ) *------------------------------------------------------------------*/ - if ( localVAD_HE_SAD ) + IF( localVAD_HE_SAD ) { - if ( relE < -20 ) + test(); + IF( LT_16( relE_fx, -10240 ) ) { - if ( hSpMusClas->sp_mus_state > 0 ) + IF( hSpMusClas->sp_mus_state > 0 ) { - if ( hSpMusClas->sp_mus_state < HANG_LEN ) + if ( LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { /* energy is too low but we are in entry period -> reset the inactive counter to allow new entry later */ hSpMusClas->inact_cnt = 0; + move16(); } /* energy is too low -> we are going to instable state */ hSpMusClas->sp_mus_state = 0; + move16(); } - else if ( hSpMusClas->sp_mus_state > -HANG_LEN ) + ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) ) { /* energy is still too low -> we are still in instable state */ - hSpMusClas->sp_mus_state--; + hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 ); } } - else if ( hSpMusClas->sp_mus_state <= 0 ) + ELSE IF( hSpMusClas->sp_mus_state <= 0 ) { - if ( hSpMusClas->inact_cnt == 0 ) + IF( hSpMusClas->inact_cnt == 0 ) { hSpMusClas->sp_mus_state = 1; + move16(); } - else + ELSE { hSpMusClas->sp_mus_state = HANG_LEN; + move16(); } hSpMusClas->inact_cnt = 12; + move16(); } - else if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + ELSE IF( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) { /* we are inside an entry period -> increment the counter of entry frames */ - hSpMusClas->sp_mus_state++; + hSpMusClas->sp_mus_state = add( hSpMusClas->sp_mus_state, 1 ); } - if ( hSpMusClas->sp_mus_state < 0 && hSpMusClas->inact_cnt > 0 ) + IF( hSpMusClas->sp_mus_state < 0 && hSpMusClas->inact_cnt > 0 ) { - hSpMusClas->inact_cnt--; + hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 ); } } - else + ELSE { - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + test(); + test(); + IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { hSpMusClas->inact_cnt = 0; + move16(); } - else if ( hSpMusClas->inact_cnt > 0 ) + ELSE IF( hSpMusClas->inact_cnt > 0 ) { - hSpMusClas->inact_cnt--; + hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 ); } - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { hSpMusClas->sp_mus_state = -HANG_LEN; + move16(); } - else if ( hSpMusClas->sp_mus_state > 0 ) + ELSE IF( hSpMusClas->sp_mus_state > 0 ) { hSpMusClas->sp_mus_state = -1; + move16(); } - else if ( hSpMusClas->sp_mus_state > -HANG_LEN ) + ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) ) { /* we are in inactive state */ - hSpMusClas->sp_mus_state--; + hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 ); } } /* detect attacks based on relE */ - if ( relE > hSpMusClas->prev_relE ) + IF( GT_16( relE_fx, hSpMusClas->prev_relE_fx ) ) { - hSpMusClas->relE_attack_sum += relE - hSpMusClas->prev_relE; + hSpMusClas->relE_attack_sum_fx = add_sat( sub_sat( relE_fx, hSpMusClas->prev_relE_fx ), hSpMusClas->relE_attack_sum_fx ); } - else + ELSE { - hSpMusClas->relE_attack_sum = 0; + hSpMusClas->relE_attack_sum_fx = 0; + move16(); } - hSpMusClas->prev_relE = relE; - + hSpMusClas->prev_relE_fx = relE_fx; + move16(); + test(); + test(); + test(); /* update counter from last VAD 0->1 change */ - if ( hSpMusClas->prev_vad == 0 && localVAD_HE_SAD == 1 ) + IF( hSpMusClas->prev_vad == 0 && EQ_16( localVAD_HE_SAD, 1 ) ) { hSpMusClas->vad_0_1_cnt = 1; + move16(); } - else if ( localVAD_HE_SAD == 1 && hSpMusClas->vad_0_1_cnt > 0 && hSpMusClas->vad_0_1_cnt < 50 ) + ELSE IF( EQ_16( localVAD_HE_SAD, 1 ) && hSpMusClas->vad_0_1_cnt > 0 && LT_16( hSpMusClas->vad_0_1_cnt, 50 ) ) { - hSpMusClas->vad_0_1_cnt++; + hSpMusClas->vad_0_1_cnt = add( hSpMusClas->vad_0_1_cnt, 1 ); } - else + ELSE { hSpMusClas->vad_0_1_cnt = 0; + move16(); } hSpMusClas->prev_vad = localVAD_HE_SAD; - - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN && hSpMusClas->relE_attack_sum > 5.0f ) + move16(); + test(); + test(); + IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && GT_16( hSpMusClas->relE_attack_sum_fx, 2560 ) ) { - hSpMusClas->relE_attack_cnt++; + hSpMusClas->relE_attack_cnt = add( hSpMusClas->relE_attack_cnt, 1 ); /* set flag only in the first X frames in a series */ - if ( hSpMusClas->relE_attack_cnt > 0 && hSpMusClas->relE_attack_cnt < 3 ) + IF( hSpMusClas->relE_attack_cnt > 0 && LT_16( hSpMusClas->relE_attack_cnt, 3 ) ) { relE_attack_flag = 1; } - else + ELSE { relE_attack_flag = 0; } + move16(); } - else + ELSE { hSpMusClas->relE_attack_cnt = 0; relE_attack_flag = 0; + move16(); + move16(); } - hSpMusClas->prev_Etot = Etot; + hSpMusClas->prev_Etot_fx = Etot_fx; /*------------------------------------------------------------------* * Preparation of the feature vector *------------------------------------------------------------------*/ - pFV = FV; - + pFV_fx = FV_fx; + test(); + test(); /* [0] OL pitch */ - if ( relE_attack_flag || st->tc_cnt == 1 || st->tc_cnt == 2 ) + IF( relE_attack_flag || EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) ) { - *pFV++ = (float) st->pitch[2]; + *pFV_fx++ = L_shl( st->pitch[2], Q20 ); } - else + ELSE { - *pFV++ = (float) ( st->pitch[0] + st->pitch[1] + st->pitch[2] ) / 3.0f; + // *pFV_fx++ = (float) ( st->pitch[0] + st->pitch[1] + st->pitch[2] ) / 3.0f; + *pFV_fx++ = Mpy_32_32( L_shl( add( add( st->pitch[0], st->pitch[1] ), st->pitch[2] ), Q20 ), 715827883 ); } - + test(); + test(); /* [1] voicing */ - if ( relE_attack_flag || st->tc_cnt == 1 || st->tc_cnt == 2 ) + IF( relE_attack_flag || EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) ) { - *pFV++ = st->voicing[2]; + *pFV_fx++ = st->voicing_fx[2]; } - else + ELSE { - *pFV++ = ( st->voicing[0] + st->voicing[1] + st->voicing[2] ) / 3.0f; + // *pFV++ = ( st->voicing[0] + st->voicing[1] + st->voicing[2] ) / 3.0f; + *pFV_fx++ = Mpy_32_32( L_shl( L_add( L_add( st->voicing_fx[0], st->voicing_fx[1] ), st->voicing_fx[2] ), Q5 ), 715827883 ); } + temp_exp = 1; + move16(); + temp16 = lsp_new_fx[2]; + move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 + temp_sqrt = Sqrt32( temp32, &temp_exp ); + temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); + *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + temp_exp = 1; + move16(); + temp16 = lsp_new_fx[3]; + move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 + temp_sqrt = Sqrt32( temp32, &temp_exp ); + temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); + *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + temp_exp = 1; + move16(); + temp16 = lsp_new_fx[4]; + move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 + temp_sqrt = Sqrt32( temp32, &temp_exp ); + temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); + *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + temp_exp = 1; + move16(); + temp16 = lsp_new_fx[5]; + move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 + temp_sqrt = Sqrt32( temp32, &temp_exp ); + temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); + *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + temp_exp = 1; + move16(); + temp16 = lsp_new_fx[6]; + move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 + temp_sqrt = Sqrt32( temp32, &temp_exp ); + temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); + *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + // temf = acosf( lsp_new[2] ); /* [2,3,4,5,6] LSFs */ - *pFV++ = acosf( lsp_new[2] ); - *pFV++ = acosf( lsp_new[3] ); - *pFV++ = acosf( lsp_new[4] ); - *pFV++ = acosf( lsp_new[5] ); - *pFV++ = acosf( lsp_new[6] ); + /* *pFV++ = acosf( lsp_new[2] ); + *pFV++ = acosf( lsp_new[3] ); + *pFV++ = acosf( lsp_new[4] ); + *pFV++ = acosf( lsp_new[5] ); + *pFV++ = acosf( lsp_new[6] );*/ /* [7] cor_map_sum */ - *pFV++ = cor_map_sum; + *pFV_fx++ = L_shl( cor_map_sum_fx, Q12 ); /* [8] non_sta */ - *pFV++ = non_sta; + *pFV_fx++ = L_shl( non_sta_fx, Q12 ); /* [9] epsP */ - *pFV++ = logf( epsP[14] + 1e-5f ) - logf( epsP[0] + 1e-5f ); + temp32 = epsP_fx[14]; + move32(); + temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) ); + temp32_log1 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + + temp32 = epsP_fx[0]; + move32(); + temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) ); + temp32_log2 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + + *pFV_fx++ = L_shr( L_add( temp32_log1, temp32_log2 ), Q5 ); + //*pFV++ = logf( epsP[14] + 1e-5f ) - logf( epsP[0] + 1e-5f ); /* [10,11,12] MFCCs */ - set_zero( melS, NB_MEL_BANDS ); - pt_mel_fb = mel_fb; - for ( i = 0; i < NB_MEL_BANDS; i++ ) + set_zero_fx( melS_fx, NB_MEL_BANDS ); + + pt_mel_fb_fx = mel_fb_fx; + move32(); + + FOR( i = 0; i < NB_MEL_BANDS; i++ ) { j = mel_fb_start[i]; + move16(); len = mel_fb_len[i]; - melS[i] = logf( dotp( &PS[j], pt_mel_fb, len ) + 1e-5f ); - pt_mel_fb += len; + move16(); + temp32 = dotp_me_fx( &PS_fx[j], pt_mel_fb_fx, len, 31 - Qfact_PS, Q1, &dotp_exp ); + temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( dotp_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + melS_fx[i] = temp32_log; + move32(); + // melS[i] = logf( dotp( &PS[j], pt_mel_fb, len ) + 1e-5f ); + pt_mel_fb_fx += len; } - v_mult_mat( mfcc, melS, dct_mtx, NB_MEL_BANDS, NB_MEL_COEF ); - - *pFV++ = mfcc[2]; - *pFV++ = mfcc[6]; - *pFV++ = mfcc[12]; + Word16 guard_bits = find_guarded_bits_fx( NB_MEL_BANDS ); + v_mult_mat_fixed( mfcc_fx, melS_fx, dct_mtx_fx, NB_MEL_BANDS, NB_MEL_COEF, guard_bits ); // Q19 + *pFV_fx++ = L_shl( mfcc_fx[2], 1 ); // Q20 + *pFV_fx++ = L_shl( mfcc_fx[6], 1 ); + *pFV_fx++ = L_shl( mfcc_fx[12], 1 ); + /* *pFV++ = mfcc[2]; + *pFV++ = mfcc[6]; + *pFV++ = mfcc[12];*/ /* calculation of differential normalized power spectrum */ - sum_PS = 1e-5f; - for ( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) + sum_PS_fx = 1; + move32(); + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - sum_PS += PS[i]; + sum_PS_fx = L_add( L_shr( PS_fx[i], Q7 ), sum_PS_fx ); // Qfact_PS - Q7 } - for ( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) + temp_exp = 0; + move16(); + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - PS_norm[i] = PS[i] / sum_PS; - dPS[i] = fabsf( PS_norm[i] - hSpMusClas->past_PS[i - LOWEST_FBIN] ); + temp32 = BASOP_Util_Divide3232_Scale( PS_fx[i], sum_PS_fx, &temp_exp ); + PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, add( sub( 15, temp_exp ), 7 ) ) ); // Qfact_PS_past + move32(); + dPS_fx[i] = L_abs( L_sub( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ); + move32(); } /* [13] ps_diff (spectral difference) */ - ps_diff = 0; - for ( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) + ps_diff_fx = 0; + move32(); + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - ps_diff += dPS[i]; + ps_diff_fx = L_add( L_shr( dPS_fx[i], Q7 ), ps_diff_fx ); // Qfact_PS_past-7 } - *pFV++ = ps_diff; + *pFV_fx++ = L_shr( ps_diff_fx, sub( sub( Qfact_PS_past, Q7 ), Q20 ) ); /// ps_diff; /* [14] ps_sta (spectral stationarity) */ - ps_sta = 0; - for ( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) + ps_sta_fx = 0; + move32(); + Word16 ps_sta_exp = 0; + move16(); + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - if ( PS_norm[i] > hSpMusClas->past_PS[i - LOWEST_FBIN] ) + IF( GT_32( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) { - ps_sta += PS_norm[i] / ( dPS[i] + 1e-5f ); + temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( PS_norm_fx[i], ( dPS_fx[i] + 1 ), &temp_exp ) ); // 31-temp_exp + ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } - else + ELSE { - ps_sta += hSpMusClas->past_PS[i - LOWEST_FBIN] / ( dPS[i] + 1e-5f ); + // ps_sta += hSpMusClas->past_PS[i - LOWEST_FBIN] / ( dPS[i] + 1e-5f ); + temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( hSpMusClas->past_PS_fx[i - LOWEST_FBIN], ( dPS_fx[i] + 1 ), &temp_exp ) ); // 31-temp_exp + move32(); + ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } } - - *pFV++ = logf( ps_sta + 1e-5f ); - mvr2r( &PS_norm[LOWEST_FBIN], hSpMusClas->past_PS, HIGHEST_FBIN - LOWEST_FBIN ); + temp32_log = L_add( BASOP_Util_Log2( ps_sta_fx ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); + mvr2r_Word32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */ - if ( hStereoClassif != NULL ) + IF( hStereoClassif != NULL ) { - if ( st->idchan == 0 ) + IF( st->idchan == 0 ) { - hStereoClassif->ps_diff_ch1 = ps_diff; - hStereoClassif->ps_sta_ch1 = logf( ps_sta + 1e-5f ); + hStereoClassif->ps_diff_ch1_fx = ps_diff_fx; // Qfact_PS_past - 7 + hStereoClassif->ps_sta_ch1_fx = temp32_log; // logf( ps_sta + 1e-5f );Q25 } - else + ELSE { - hStereoClassif->ps_diff_ch2 = ps_diff; - hStereoClassif->ps_sta_ch2 = logf( ps_sta + 1e-5f ); + hStereoClassif->ps_diff_ch2_fx = ps_diff_fx; + hStereoClassif->ps_sta_ch2_fx = temp32_log; // logf( ps_sta + 1e-5f );Q25 } + move32(); + move32(); } /*------------------------------------------------------------------* * Outlier detection based on feature histograms *------------------------------------------------------------------*/ - flag_odv = 0; - if ( localVAD_HE_SAD ) + move16(); + IF( localVAD_HE_SAD ) { - pFV = FV; - pODV = hout_intervals; + pFV_fx = FV_fx; + pODV_fx = hout_intervals_fx; p_out = i_out; odv_cnt = 0; - for ( i = 0; i < N_SMC_FEATURES; i++ ) + move16(); + FOR( i = 0; i < N_SMC_FEATURES; i++ ) { - if ( *pFV < pODV[0] || *pFV > pODV[1] ) + IF( LT_32( *pFV_fx, pODV_fx[0] ) || GT_32( *pFV_fx, pODV_fx[1] ) ) { *p_out++ = i; - odv_cnt++; + odv_cnt = add( odv_cnt, 1 ); } - pFV++; - pODV += 2; + pFV_fx++; + pODV_fx += 2; } /* set outlier flag */ - if ( odv_cnt >= 2 ) + IF( GE_16( odv_cnt, 2 ) ) { flag_odv = 1; - + move16(); /* replace outlying features with values from the previous frame */ - for ( i = 0; i < odv_cnt; i++ ) + FOR( i = 0; i < odv_cnt; i++ ) { - FV[i_out[i]] = hSpMusClas->prev_FV[i_out[i]]; + FV_fx[i_out[i]] = hSpMusClas->prev_FV_fx[i_out[i]]; + move32(); } } } @@ -1792,54 +1947,70 @@ int16_t ivas_smc_gmm( /*------------------------------------------------------------------* * Adaptive short-term mean filter on feature vector *------------------------------------------------------------------*/ - - pFV = FV; - pFV_st = hSpMusClas->FV_st; - smc_st_mean_fact = SMC_ST_MEAN_FACT; - for ( i = 0; i < N_SMC_FEATURES; i++ ) + Qfact_FV = 20; + move16(); + pFV_fx = FV_fx; + pFV_st_fx = hSpMusClas->FV_st_fx; + smc_st_mean_fact_fx = SMC_ST_MEAN_RSHIFT_FACT_FX; + move16(); + FOR( i = 0; i < N_SMC_FEATURES; i++ ) { - *pFV_st = smc_st_mean_fact * ( *pFV_st ) + ( 1 - smc_st_mean_fact ) * ( *pFV ); - - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN && ( relE_attack_flag || flag_odv ) ) + //*pFV_st = smc_st_mean_fact * ( *pFV_st ) + ( 1 - smc_st_mean_fact ) * ( *pFV ); + *pFV_st_fx = L_add( L_shr( *pFV_st_fx, smc_st_mean_fact_fx ), L_shr( *pFV_fx, 1 ) ); + test(); + test(); + test(); + test(); + test(); + IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && ( relE_attack_flag || flag_odv ) ) { /* strong attack or outlier frame during entry state -> features cannot be trusted but there is also no useful past info -> */ /* -> do whatever you want because dlp will be reset to 0 anyway */ - pFV++; - pFV_st++; + pFV_fx++; + pFV_st_fx++; } - else if ( hSpMusClas->sp_mus_state == HANG_LEN && ( st->tc_cnt == 1 || st->tc_cnt == 2 ) ) + ELSE IF( hSpMusClas->sp_mus_state == HANG_LEN && ( EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) ) ) { /* energy attack in stable state -> use current features intead of the long-term average */ - pFV++; - pFV_st++; + pFV_fx++; + pFV_st_fx++; } - else + ELSE { - *pFV++ = *pFV_st++; + *pFV_fx++ = *pFV_st_fx++; } } /* update */ - mvr2r( FV, hSpMusClas->prev_FV, N_SMC_FEATURES ); - + mvr2r_Word32( FV_fx, hSpMusClas->prev_FV_fx, N_SMC_FEATURES ); /*------------------------------------------------------------------* * Non-linear power transformation (boxcox) on certain features *------------------------------------------------------------------*/ - - pFV = FV; - for ( i = 0; i < N_SMC_FEATURES; i++ ) + pFV_fx = FV_fx; + FOR( i = 0; i < N_SMC_FEATURES; i++ ) { - if ( bcox_lmbd[i] != 0 ) + IF( bcox_lmbd_fx[i] != 0 ) { - *pFV -= bcox_add_cnst[i]; - if ( *pFV < 1 ) + *pFV_fx = L_sub( *pFV_fx, L_shr( bcox_add_cnst_fx[i], sub( 31, Qfact_FV ) ) ); + IF( LT_32( *pFV_fx, L_shl( 1, Qfact_FV ) ) ) { - *pFV = 1; + *pFV_fx = L_shl( 1, Qfact_FV ); } - *pFV = ( powf( *pFV, bcox_lmbd[i] ) - 1 ) / bcox_lmbd[i]; + Word16 pow_e = 0; + move32(); + temp32_log = L_add( BASOP_Util_Log2( *pFV_fx ), L_shl( sub( 31, Qfact_FV ), Q25 ) ); // Q25 + temp32 = Mpy_32_32( temp32_log, bcox_lmbd_fx[i] ); // Q25 + Word32 pow_temp = BASOP_util_Pow2( temp32, sub( 31, Q25 ), &pow_e ); + temp32 = L_sub( pow_temp, L_shl( 1, 31 - pow_e ) ); + temp_exp = 0; + move32(); + temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, bcox_lmbd_fx[i], &temp_exp ) ); + *pFV_fx = L_shl( temp32, sub( Qfact_FV, sub( 31, add( temp_exp, pow_e ) ) ) ); + // float temp = powf( *pFV, bcox_lmbd[i] ); + // *pFV = ( powf( *pFV, bcox_lmbd[i] ) - 1 ) / bcox_lmbd[i]; } - pFV++; + pFV_fx++; } /*------------------------------------------------------------------* @@ -1847,302 +2018,375 @@ int16_t ivas_smc_gmm( * PCA *------------------------------------------------------------------*/ - pFV = FV; - for ( i = 0; i < N_SMC_FEATURES; i++ ) + pFV_fx = FV_fx; + FOR( i = 0; i < N_SMC_FEATURES; i++ ) { /* Standard scaler - mean and variance normalization */ - *pFV = ( *pFV - sm_means[i] ) / sm_scale[i]; - pFV++; - + // *pFV = ( *pFV - sm_means[i] ) / sm_scale[i]; + temp32 = L_sub( *pFV_fx, sm_means_fx[i] ); + temp_exp = 0; + temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, sm_scale_fx[i], &temp_exp ) ); + *pFV_fx = L_shl( temp32, Qfact_FV - ( 31 - temp_exp ) ); + pFV_fx++; /* MinMax sclaer - mean and variance normalization */ /**pFV = *pFV * sm_scale[i] + sm_min[i];*/ - /*pFV++;*/ } /* PCA */ - v_sub( FV, pca_mean_, FV, N_SMC_FEATURES ); - v_mult_mat( FV, FV, pca_components_, N_SMC_FEATURES, N_PCA_COEF ); - + v_sub_fixed( FV_fx, pca_mean_fx, FV_fx, N_SMC_FEATURES, 0 ); + v_mult_mat_fixed( FV_fx, FV_fx, pca_components_fx, N_SMC_FEATURES, N_PCA_COEF, 0 ); /*------------------------------------------------------------------* * Calculation of posterior probability * Log-probability *------------------------------------------------------------------*/ /* run loop for all mixtures (for each mixture, calculate the probability of speech, music and noise) */ - lps = lpm = lpn = 0; - for ( m = 0; m < N_SMC_MIXTURES; m++ ) + lps_fx = lpm_fx = lpn_fx = 0; + move32(); + move32(); + move32(); + FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { - v_sub( FV, &means_speech[m * N_PCA_COEF], fvm, N_PCA_COEF ); - lprob = dot_product_cholesky( fvm, &prec_chol_speech[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - ps[m] = logf( weights_speech[m] ) + log_det_chol_speech[m] - 0.5f * N_PCA_COEF * logf( PI2 ) - 0.5f * lprob; - - v_sub( FV, &means_music[m * N_PCA_COEF], fvm, N_PCA_COEF ); - lprob = dot_product_cholesky( fvm, &prec_chol_music[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - pm[m] = logf( weights_music[m] ) + log_det_chol_music[m] - 0.5f * N_PCA_COEF * logf( PI2 ) - 0.5f * lprob; + v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); + fvm_exp = sub( 31, Qfact_FV ); + 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( log_weights_speech_compute[m], L_shr( L_shl_sat( lprob_fx, sub( Q19, sub( Q31, lprob_exp ) ) ), 1 ) ); + 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( log_weights_music_compute[m], L_shr( L_shl_sat( lprob_fx, sub( Q19, sub( Q31, lprob_exp ) ) ), 1 ) ); + move32(); + v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - v_sub( FV, &means_noise[m * N_PCA_COEF], fvm, N_PCA_COEF ); - lprob = dot_product_cholesky( fvm, &prec_chol_noise[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - pn[m] = logf( weights_noise[m] ) + log_det_chol_noise[m] - 0.5f * N_PCA_COEF * logf( PI2 ) - 0.5f * lprob; + 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( log_weights_music_compute[m], L_shr( L_shl_sat( lprob_fx, sub( Q19, sub( Q31, lprob_exp ) ) ), 1 ) ); + move32(); } - lps = logsumexp( ps, N_SMC_MIXTURES ); - lpm = logsumexp( pm, N_SMC_MIXTURES ); - lpn = logsumexp( pn, N_SMC_MIXTURES ); - + lps_fx = logsumexp_fx( ps_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); + lpm_fx = logsumexp_fx( pm_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); + lpn_fx = logsumexp_fx( pn_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); *high_lpn_flag = 0; - if ( lpn > lps && lpn > lpm ) + move16(); + if ( GT_32( lpn_fx, lps_fx ) && GT_32( lpn_fx, lpm_fx ) ) { *high_lpn_flag = 1; + move32(); } - hSpMusClas->lpm = lpm; - hSpMusClas->lps = lps; - hSpMusClas->lpn = lpn; + hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q8 + hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q8 + hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q8 /* determine HQ Generic speech class */ - if ( st->hHQ_core != NULL ) + IF( st->hHQ_core != NULL ) { - if ( lps > lpm + 0.5f ) + IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q18 ) ) ) { st->hHQ_core->hq_generic_speech_class = 1; } - else + ELSE { st->hHQ_core->hq_generic_speech_class = 0; } + move16(); } /*------------------------------------------------------------------* * Decision without hangover * Weighted decision *------------------------------------------------------------------*/ - + test(); + test(); + test(); + test(); + test(); /* decision without hangover (0 - speech/noise, 1 - music) */ - if ( !localVAD_HE_SAD || Etot < 10 || ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN && ( relE_attack_flag || flag_odv ) ) ) + IF( !localVAD_HE_SAD || LT_16( Etot_fx, 2560 ) || ( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && ( relE_attack_flag || flag_odv ) ) ) { - dlp = 0; + dlp_fx = 0; + move32(); } - else + ELSE { - dlp = lpm - lps + DLP_BIAS; + dlp_fx = L_add( L_sub( lpm_fx, lps_fx ), DLP_BIAS_FX ); - if ( dlp > 30.0f ) + IF( GT_32( dlp_fx, 15728640 ) ) /*30.0f in Q19*/ { - dlp = 30.0f; + dlp_fx = 15728640; } - else if ( dlp < -30.0f ) + ELSE IF( LT_32( dlp_fx, -15728640 ) ) { - dlp = -30.0f; + dlp_fx = -15728640; } + move32(); } - dec = dlp > 0; - + dec = (Word16) GT_32( dlp_fx, 0 ); /* calculate weight based on relE (higher relE -> lower weight, lower relE -> higher weight) */ - wrelE = lin_interp( relE, 15.0f, 0.9f, -15.0f, 0.99f, 1 ); + Word16 Qio = Q25; + move16(); + wrelE_fx = lin_interp32_fx( L_deposit_h( relE_fx ), 503316480, 30198989, -503316480, 33218888, 1, &Qio ); // Q25 + wrelE_fx = L_shr( wrelE_fx, sub( Qio, 25 ) ); /* calculate weight based on drops of dlp (close to 1 during sudden drops of dlp, close to 0 otherwise) */ - hSpMusClas->dlp_mean_ST = 0.8f * hSpMusClas->dlp_mean_ST + 0.2f * dlp; - hSpMusClas->lt_dec_thres = hSpMusClas->dlp_mean_ST; - - if ( dlp < 0 && dlp < hSpMusClas->dlp_mean_ST ) + // hSpMusClas->dlp_mean_ST = 0.8f * hSpMusClas->dlp_mean_ST + 0.2f * dlp; + hSpMusClas->dlp_mean_ST_fx = L_add( Mpy_32_32( 419430, hSpMusClas->dlp_mean_ST_fx ), Mpy_32_32( 104858, dlp_fx ) ); + hSpMusClas->lt_dec_thres_fx = extract_l( L_shr( hSpMusClas->dlp_mean_ST_fx, 10 ) ); + test(); + IF( dlp_fx < 0 && LT_32( dlp_fx, hSpMusClas->dlp_mean_ST_fx ) ) { - if ( hSpMusClas->dlp_mean_ST > 0 ) + IF( hSpMusClas->dlp_mean_ST_fx > 0 ) { - hSpMusClas->wdrop = -dlp; + hSpMusClas->wdrop_fx = -extract_l( L_shr( dlp_fx, 10 ) ); // Q9 } - else if ( hSpMusClas->wdrop > 0 ) + ELSE IF( hSpMusClas->wdrop_fx > 0 ) { - hSpMusClas->wdrop += hSpMusClas->dlp_mean_ST - dlp; + hSpMusClas->wdrop_fx = extract_l( L_shr( L_sub( hSpMusClas->dlp_mean_ST_fx, dlp_fx ), 10 ) ); } } - else + ELSE { - hSpMusClas->wdrop = 0; + hSpMusClas->wdrop_fx = 0; + move16(); } - - wdrop = lin_interp( hSpMusClas->wdrop, 15.0f, 0.7f, 0.0f, 1.0f, 1 ); - + Qio = Q25; + move16(); + wdrop_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wdrop_fx ), 503316480, 23488102, 0, ONE_IN_Q25, 1, &Qio ); + wdrop_fx = L_shr( wdrop_fx, sub( Qio, 25 ) ); + test(); + test(); /* calculate weight based on rises of dlp (close to 1 during sudden rise of dlp, close to 0 otherwise) */ - if ( hSpMusClas->sp_mus_state == HANG_LEN && hSpMusClas->dlp_mean_ST > 0 && hSpMusClas->dlp_mean_ST > hSpMusClas->past_dlp_mean_ST[0] ) + IF( EQ_16( hSpMusClas->sp_mus_state, HANG_LEN ) && hSpMusClas->dlp_mean_ST_fx > 0 && hSpMusClas->dlp_mean_ST_fx > hSpMusClas->past_dlp_mean_ST_fx[0] ) { - if ( hSpMusClas->past_dlp_mean_ST[0] < 0 ) + IF( hSpMusClas->past_dlp_mean_ST_fx[0] < 0 ) { - hSpMusClas->wrise = hSpMusClas->dlp_mean_ST; + hSpMusClas->wrise_fx = extract_l( L_shr( hSpMusClas->dlp_mean_ST_fx, 10 ) ); } - else if ( hSpMusClas->wrise > 0 ) + ELSE IF( hSpMusClas->wrise_fx > 0 ) { - hSpMusClas->wrise += hSpMusClas->dlp_mean_ST - hSpMusClas->past_dlp_mean_ST[0]; + hSpMusClas->wrise_fx = add( hSpMusClas->wrise_fx, extract_l( L_shr( L_sub( hSpMusClas->dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST_fx[0] ), 10 ) ) ); } } - else + ELSE { - hSpMusClas->wrise = 0; + hSpMusClas->wrise_fx = 0; + move16(); } - wrise = lin_interp( hSpMusClas->wrise, 5.0f, 0.95f, 0.0f, 1.0f, 1 ); + Qio = Q25; + move16(); + wrise_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wrise_fx ), 167772160, 31876710, 0, ONE_IN_Q25, 1, &Qio ); + wrise_fx = L_shr( wrise_fx, sub( Qio, 25 ) ); /* combine weights into one */ - wght = wrelE * wdrop * wrise; - + // wght = wrelE * wdrop * wrise; + wght_fx = Mpy_32_32( Mpy_32_32( wrelE_fx, wdrop_fx ), wrise_fx ); // Q13 + test(); /* ratio of delta means vs. delta variances */ - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + if ( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { - hSpMusClas->dlp_mean_LT = dlp; - hSpMusClas->dlp_var_LT = 0; + + hSpMusClas->dlp_mean_LT_fx = dlp_fx; + hSpMusClas->dlp_var_LT_fx = 0; + move32(); + move32(); } - hSpMusClas->dlp_mean_LT = 0.9f * hSpMusClas->dlp_mean_LT + 0.1f * dlp; - ftmp = dlp - hSpMusClas->dlp_mean_LT; - hSpMusClas->dlp_var_LT = 0.9f * hSpMusClas->dlp_var_LT + 0.1f * ( ftmp * ftmp ); + hSpMusClas->dlp_mean_LT_fx = L_add( Mpy_32_32( 1932735283, hSpMusClas->dlp_mean_LT_fx ), Mpy_32_32( 214748365, dlp_fx ) ); // Q19 - if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + temp32 = L_sub( dlp_fx, hSpMusClas->dlp_mean_LT_fx ); + hSpMusClas->dlp_var_LT_fx = L_add( Mpy_32_32( 1932735283, hSpMusClas->dlp_var_LT_fx ), Mpy_32_32( 214748365, temp32 ) ); + + test(); + IF( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) { - dlp_mean2var = 0; + dlp_mean2var_fx = 0; + dlp_mean2var_q = 0; + move16(); + move16(); } - else + ELSE { - dlp_mean2var = fabsf( hSpMusClas->dlp_mean_LT ) / ( sqrtf( fabsf( hSpMusClas->dlp_var_LT ) ) + 1.0f ); + temp_exp = sub( Q31, Q19 ); + Word16 div_e = 0; + move16(); + temp32 = Sqrt32( L_abs( hSpMusClas->dlp_var_LT_fx ), &temp_exp ); + temp_sqrt = L_add( Sqrt32( L_abs( hSpMusClas->dlp_var_LT_fx ), &temp_exp ), 1 ); + dlp_mean2var_fx = BASOP_Util_Divide3232_Scale( L_abs( hSpMusClas->dlp_mean_LT_fx ), temp_sqrt, &div_e ); + dlp_mean2var_q = sub( add( Q3, temp_exp ), div_e ); // 15-div_e+Q19 -(31-temp_exp) } - if ( dlp_mean2var > 15.0f ) + if ( GT_32( L_deposit_l( dlp_mean2var_fx ), L_shl( 15, dlp_mean2var_q ) ) ) { /* decrease the weight little bit when the classifier indicates "strong speech" or "strong music" */ - wght *= 0.9f; + // wght *= 0.9f; + wght_fx = Mpy_32_32( wght_fx, 1932735283 ); // Q13 } - if ( wght > 1.0f ) + IF( GT_32( wght_fx, ONE_IN_Q13 ) ) { - wght = 1.0f; + wght_fx = ONE_IN_Q13; } - else if ( wght < 0.01f ) + ELSE IF( LT_32( wght_fx, 82 ) ) { - wght = 0.01f; + wght_fx = 82; } - - if ( Etot < 10 ) + move32(); + if ( LT_16( Etot_fx, 256 ) ) { /* silence */ - wght = 0.92f; + wght_fx = 7537; + move32(); } /* calculate weighted decision */ - hSpMusClas->wdlp_0_95_sp = wght * hSpMusClas->wdlp_0_95_sp + ( 1 - wght ) * dlp; + // hSpMusClas->wdlp_0_95_sp = wght * hSpMusClas->wdlp_0_95_sp + ( 1 - wght ) * dlp; + + hSpMusClas->wdlp_0_95_sp_fx = (Word16) L_add( L_shl( Mpy_32_16_1( wght_fx, hSpMusClas->wdlp_0_95_sp_fx ), Q2 ), L_shl( Mpy_32_32( L_sub( ONE_IN_Q13, wght_fx ), dlp_fx ), Q5 ) ); // Q8 /* xtalk classifier: apply long hysteresis to prevent LRTD on music */ - hSpMusClas->wdlp_xtalk = 0.995f * hSpMusClas->wdlp_xtalk + 0.005f * dlp; + + hSpMusClas->wdlp_xtalk_fx = L_add( Mpy_32_32( 2136746229, hSpMusClas->wdlp_xtalk_fx ), Mpy_32_32( 10737418, dlp_fx ) ); /*------------------------------------------------------------------* * Final speech/music decision *------------------------------------------------------------------*/ - if ( flag_spitch ) + IF( flag_spitch ) { hSpMusClas->flag_spitch_cnt = 5; + move16(); } - else if ( hSpMusClas->flag_spitch_cnt > 0 ) + ELSE IF( hSpMusClas->flag_spitch_cnt > 0 ) { - hSpMusClas->flag_spitch_cnt--; + hSpMusClas->flag_spitch_cnt = sub( hSpMusClas->flag_spitch_cnt, 1 ); } - - if ( Etot < 10 ) + test(); + IF( Etot_fx < 2560 ) { /* silence */ dec = 0; + move16(); } - else if ( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + ELSE IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { + temp32 = L_mult( w_spmus_fx[hSpMusClas->sp_mus_state - 1][0], (Word16) L_shr( dlp_fx, 10 ) ); /*Q25 */ + 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 */ - ftmp = w_spmus[hSpMusClas->sp_mus_state - 1][0] * dlp; - ftmp += dotp( &w_spmus[hSpMusClas->sp_mus_state - 1][1], hSpMusClas->past_dlp, HANG_LEN - 1 ); - if ( ftmp > 2.0f ) + IF( GT_32( temp32, L_shl( 2, 25 ) ) ) { - if ( dlp > 2.0f ) + IF( GT_32( dlp_fx, L_shl( 2, 19 ) ) ) { dec = 2; } - else + ELSE { dec = 1; } } - else + ELSE { dec = 0; } + move16(); } - else + ELSE { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); /* stable active state */ - if ( hSpMusClas->past_dec[0] == 0 && hSpMusClas->past_dec[1] == 0 && hSpMusClas->past_dec[2] == 0 && - ( ( hSpMusClas->flag_spitch_cnt > 0 && hSpMusClas->wdlp_0_95_sp > 3.4f ) || ( hSpMusClas->flag_spitch_cnt == 0 && hSpMusClas->wdlp_0_95_sp > 2.1f ) ) ) + IF( hSpMusClas->past_dec[0] == 0 && hSpMusClas->past_dec[1] == 0 && hSpMusClas->past_dec[2] == 0 && + ( ( hSpMusClas->flag_spitch_cnt > 0 && GT_16( hSpMusClas->wdlp_0_95_sp_fx, 870 ) ) || ( hSpMusClas->flag_spitch_cnt == 0 && GT_16( hSpMusClas->wdlp_0_95_sp_fx, 538 ) ) ) ) { /* switching from speech to unclear */ dec = 1; } - else if ( hSpMusClas->past_dec[0] == 0 && hSpMusClas->vad_0_1_cnt < 50 && hSpMusClas->relE_attack_sum == 0.0f && hSpMusClas->wdlp_0_95_sp > 1.0f ) + ELSE IF( hSpMusClas->past_dec[0] == 0 && LT_16( hSpMusClas->vad_0_1_cnt, 50 ) && hSpMusClas->relE_attack_sum_fx == 0 && GT_16( hSpMusClas->wdlp_0_95_sp_fx, 256 ) ) { /* switch from speech to unclear also during slowly rising weak music onsets */ dec = 1; } - else if ( hSpMusClas->past_dec[0] == 1 && hSpMusClas->wdlp_0_95_sp > 2.5f ) + ELSE IF( EQ_16( hSpMusClas->past_dec[0], 1 ) && GT_16( hSpMusClas->wdlp_0_95_sp_fx, 640 ) ) { /* switching from unclear to music */ dec = 2; } - else if ( hSpMusClas->past_dec[0] == 2 && hSpMusClas->past_dec[1] == 2 && hSpMusClas->past_dec[2] == 2 && hSpMusClas->wdlp_0_95_sp < -1.0f ) + ELSE IF( EQ_16( hSpMusClas->past_dec[0], 2 ) && EQ_16( hSpMusClas->past_dec[1], 2 ) && EQ_16( hSpMusClas->past_dec[2], 2 ) && LT_16( hSpMusClas->wdlp_0_95_sp_fx, -256 ) ) { /* switching from music to unclear */ dec = 1; } - else if ( hSpMusClas->past_dec[0] == 1 && hSpMusClas->wdlp_0_95_sp < -2.5f ) + ELSE IF( EQ_16( hSpMusClas->past_dec[0], 1 ) && LT_16( hSpMusClas->wdlp_0_95_sp_fx, -640 ) ) { /* switching from unclear to speech */ dec = 0; } - else + ELSE { dec = hSpMusClas->past_dec[0]; } + move16(); } /*------------------------------------------------------------------* * raw S/M decision based on smoothed GMM score *------------------------------------------------------------------*/ - - if ( dec == 0 || st->hSpMusClas->wdlp_0_95_sp <= 0 ) + test(); + IF( dec == 0 || st->hSpMusClas->wdlp_0_95_sp_fx <= 0 ) { st->sp_aud_decision0 = 0; st->sp_aud_decision1 = 0; } - else + ELSE { st->sp_aud_decision0 = 1; st->sp_aud_decision1 = 1; } - + move16(); + move16(); /*------------------------------------------------------------------* * Updates *------------------------------------------------------------------*/ /* update buffer of past non-binary decisions */ - mvr2r( &hSpMusClas->past_dlp[0], &hSpMusClas->past_dlp[1], HANG_LEN - 2 ); - hSpMusClas->past_dlp[0] = dlp; - + mvr2r_Word16( &hSpMusClas->past_dlp_fx[0], &hSpMusClas->past_dlp_fx[1], HANG_LEN - 2 ); + hSpMusClas->past_dlp_fx[0] = extract_l( L_shr( dlp_fx, 10 ) ); + move16(); mvr2r( &hSpMusClas->past_dlp_mean_ST[0], &hSpMusClas->past_dlp_mean_ST[1], HANG_LEN - 2 ); - hSpMusClas->past_dlp_mean_ST[0] = hSpMusClas->dlp_mean_ST; - + hSpMusClas->past_dlp_mean_ST_fx[0] = hSpMusClas->dlp_mean_ST_fx; + move32(); /* update buffer of past binary decisions */ mvs2s( &hSpMusClas->past_dec[0], &hSpMusClas->past_dec[1], HANG_LEN - 2 ); hSpMusClas->past_dec[0] = dec; - + move16(); #ifdef DEBUG_MODE_INFO dbgwrite( &st->hSpMusClas->wdlp_0_95_sp, sizeof( float ), 1, 1, "res/wdlp_0_95_sp.x" ); #endif return dec; } - +#endif +#ifdef IVAS_CODE /*---------------------------------------------------------------------* * ivas_smc_mode_selection() * diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 719b7f661e4dd1605cd973c12f5cd6d920c1e718..a7ff97e14f45ebfced492388bdfb5713bcb231bf 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -92,7 +92,7 @@ typedef struct bitstream_enc_data_structure void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ - // Indice *ind_list_fx; /* list of indices */ + // Indice *ind_list_fx; /* list of indices */ Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ Word16 last_ind_fx; /* last written indice */ @@ -432,6 +432,7 @@ typedef struct td_cng_enc_structure int16_t cng_ener_seed; /* CNG and DTX - seed for random generator for variation of excitation energy */ int16_t cng_ener_seed1; float lp_sp_enr; + Word16 lp_sp_enr_fx; /*Q8*/ int16_t last_allow_cn_step; int16_t ho_hist_size; /* CNG and DTX - size of DTX hangover history buffer for averaging, <0,HO_HIST_SIZE> */ @@ -443,6 +444,7 @@ typedef struct td_cng_enc_structure float ho_lsp_hist[HO_HIST_SIZE * M]; /* CNG and DTX - old LSP buffer for averaging */ float ho_ener_hist[HO_HIST_SIZE]; /* CNG and DTX - energy buffer for averaging */ float ho_env_hist[HO_HIST_SIZE * NUM_ENV_CNG]; + Word16 ho_lsp_circ_fx[HO_HIST_SIZE * M]; /* CNG and DTX - old LSP buffer for averaging */ Word32 ho_ener_circ_fx[HO_HIST_SIZE]; /* CNG and DTX - energy buffer for averaging */ Word32 ho_env_circ_fx[HO_HIST_SIZE * NUM_ENV_CNG]; @@ -615,6 +617,7 @@ typedef struct fd_cng_enc_structure typedef struct dtx_enc_structure { + int16_t cnt_SID; /* CNG and DTX - counter of SID update for the interop. mode or DTX, if enabled */ int16_t first_CNG; /* CNG and DTX - first CNG frame flag */ int16_t cng_cnt; /* CNG and DTX - counter of CNG frames for averaging */ @@ -629,6 +632,7 @@ typedef struct dtx_enc_structure float frame_ener; Word32 lt_ener_voiced_fx; /* CNG and DTX - long-term energy of signal (measured on voiced parts) */ Word32 lt_ener_noise_fx; /* CNG and DTX - long-term energy of background noise */ + Word32 frame_ener_fx; int16_t cng_hist_size; /* CNG and DTX - size of CNG history buffer for averaging, <0,DTX_HIST_SIZE> */ float lt_ener_last_SID; /* CNG and DTX - long-term energy of last SID frame */ @@ -767,6 +771,7 @@ typedef struct noise_estimation_structure float Etot_l_lp; /* Noise estimator - Smoothed low energy */ float Etot_last; /* Noise estimator - Energy of last frame */ float Etot_lp; /* Noise estimator - Filtered input energy */ + float lt_tn_track; float lt_tn_dist; float lt_Ellp_dist; @@ -825,12 +830,14 @@ typedef struct noise_estimation_structure typedef struct sp_mus_clas_structure { - float FV_st[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ + float FV_st[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ + Word32 FV_st_fx[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ float past_PS[HIGHEST_FBIN - LOWEST_FBIN]; float past_ps_diff; Word32 past_PS_fx[HIGHEST_FBIN - LOWEST_FBIN]; Word16 past_ps_diff_fx; float prev_FV[N_SMC_FEATURES]; + Word32 prev_FV_fx[N_SMC_FEATURES]; float past_epsP; float past_epsP2; Word16 past_epsP2_fx; @@ -838,18 +845,24 @@ typedef struct sp_mus_clas_structure float wdrop; Word16 wdrop_fx; float wrise; + Word16 wrise_fx; float wdlp_0_95_sp; Word16 wdlp_0_95_sp_fx; float wdlp_xtalk; + Word32 wdlp_xtalk_fx; int16_t sp_mus_state; int16_t past_dec[HANG_LEN - 1]; /* Speech/music classifier - buffer of past binary decisions */ float past_dlp[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions */ Word16 past_dlp_fx[HANG_LEN - 1]; - float past_dlp_mean_ST[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ + float past_dlp_mean_ST[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ + Word32 past_dlp_mean_ST_fx[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ float dlp_mean_ST; + Word32 dlp_mean_ST_fx; int16_t flag_spitch_cnt; float dlp_mean_LT; + Word32 dlp_mean_LT_fx; float dlp_var_LT; + Word32 dlp_var_LT_fx; float last_lsp[M_LSP_SPMUS]; float last_cor_map_sum; float last_non_sta; @@ -874,6 +887,7 @@ typedef struct sp_mus_clas_structure float lt_dec_thres; /* Speech/music classifier - Long term speech/music thresold values */ float ener_RAT; /* Speech/music classifier - LF/to total energy ratio */ Word16 mold_corr_fx; + Word16 mean_avr_dyn_fx; /* Q7 Speech/music classifier - long term average dynamic */ Word16 last_sw_dyn_fx; /* Q7 Speech/music classifier - last dynamic */ Word16 lt_dec_thres_fx; /* Speech/music classifier - Long term speech/music thresold values */ @@ -881,10 +895,13 @@ typedef struct sp_mus_clas_structure int16_t relE_attack_cnt; float prev_relE; + Word16 prev_relE_fx; float prev_Etot; + Word16 prev_Etot_fx; int16_t prev_vad; int16_t vad_0_1_cnt; float relE_attack_sum; + Word16 relE_attack_sum_fx; /* speech/music classifier improvement parameters */ float old_Bin_E[3 * N_OLD_BIN_E]; @@ -978,6 +995,7 @@ typedef struct sp_mus_clas_structure float lpm; Word16 lps_fx; Word16 lpm_fx; + Word16 lpn_fx; float lpn; @@ -1006,6 +1024,7 @@ typedef struct lpd_state_structure float mem_syn2_flt[M]; /* ACELP synthesis memory (pe) after post-proc */ float mem_syn_r_flt[L_SYN_MEM]; /* ACELP synthesis memory for 1.25ms */ float mem_syn3_flt[M]; + Word16 mem_syn[M]; /* ACELP synthesis memory (pe) before post-proc */ Word16 mem_syn1_fx[M]; /* synthesis filter memory (for core switching and FD BWE) */ Word16 mem_syn2[M]; /* ACELP synthesis memory (pe) after post-proc */ @@ -1063,8 +1082,8 @@ typedef struct gsc_enc_structure float mid_dyn; /* AC mode (GSC) - signal dynamic */ Word16 mem_w0_tmp_fx; Word16 mem_syn_tmp_fx[M]; - Word16 mid_dyn_fx; /* AC mode (GSC) - signal dynamic */ + Word16 mid_dyn_fx; /* AC mode (GSC) - signal dynamic */ int16_t noise_lev; /* AC mode (GSC) - noise level */ int16_t past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ float Last_frame_ener; /* AC mode (GSC) - Last frame energy */ @@ -1076,7 +1095,9 @@ typedef struct gsc_enc_structure Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ float lt_gpitch; + Word16 lt_gpitch_fx; /*Q15 */ + } GSC_ENC_DATA, *GSC_ENC_HANDLE; /*----------------------------------------------------------------------------------* @@ -1646,7 +1667,8 @@ typedef struct tcx_enc_structure Word16 tcx_target_bits_fac; int16_t tns_ms_flag[2]; - Word32 *spectrum_fx[2]; /* MDCT output for a short block */ + Word32 *spectrum_fx[2]; /* MDCT output for a short block */ + Word16 spectrum_e[2]; Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ } TCX_ENC_DATA, *TCX_ENC_HANDLE; @@ -1787,14 +1809,13 @@ typedef struct enc_core_structure int16_t pstreaklen; /* LSF quantizer */ - float streaklimit; /* LSF quantizer */ - float stab_fac; /* LSF stability factor */ - float mem_preemph; /* preemphasis filter memory */ - float old_wsp[L_WSP_MEM]; /* old weighted signal vector */ - float old_wsp2[( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM]; /* old decimated weighted signal vector */ - float mem_wsp; /* weighted signal vector memory */ - float mem_decim2[3]; /* weighted signal decimation filter memory */ - + float streaklimit; /* LSF quantizer */ + float stab_fac; /* LSF stability factor */ + float mem_preemph; /* preemphasis filter memory */ + float old_wsp[L_WSP_MEM]; /* old weighted signal vector */ + float old_wsp2[( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM]; /* old decimated weighted signal vector */ + float mem_wsp; /* weighted signal vector memory */ + float mem_decim2[3]; /* weighted signal decimation filter memory */ float clip_var[6]; /* pitch gain clipping memory */ float mem_AR[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean) */ float mem_MA[M]; /* MA memory of LSF quantizer (past quantized residual) (used also in AMR-WB IO mode) */ @@ -1807,19 +1828,20 @@ typedef struct enc_core_structure Word16 no_scales_fx[MAX_NO_MODES][2]; /* LSF LVQ structure Q0*/ Word16 no_scales_p_fx[MAX_NO_MODES_p][2]; /* LSF LVQ structure Q0*/ Word16 stab_fac_fx; /* LSF stability factor */ - Word16 mem_deemph_fx; /* deemphasis filter memory */ - Word16 mem_preemph_fx; /* preemphasis filter memory */ - Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ - Word16 old_wsp_fx[L_WSP_MEM]; /* old weighted signal vector */ - /*Word16 old_exc_fx[L_EXC_MEM];*/ /* old excitation vector */ - Word16 old_wsp2_fx[( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM]; /* old decimated weighted signal vector qwsp */ - Word16 mem_wsp_fx; /* weighted signal vector memory */ - Word16 mem_decim2_fx[3]; /* weighted signal decimation filter memory qwsp */ - Word16 clip_var_fx[6]; - Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean) */ - Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual) (used also in AMR-WB IO mode) */ - Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ + Word16 mem_preemph_fx; /* preemphasis filter memory */ + + Word16 old_wsp_fx[L_WSP_MEM]; /* old weighted signal vector */ + /*Word16 old_exc_fx[L_EXC_MEM];*/ /* old excitation vector */ + Word16 old_wsp2_fx[( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM]; /* old decimated weighted signal vector qwsp */ + Word16 mem_wsp_fx; /* weighted signal vector memory */ + Word16 mem_decim2_fx[3]; /* weighted signal decimation filter memory qwsp */ + Word16 clip_var_fx[6]; + Word16 mem_deemph_fx; /* deemphasis filter memory */ + Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ + Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean) */ + Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual) (used also in AMR-WB IO mode) */ + Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ int16_t GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ int16_t GSC_IVAS_mode; @@ -1857,6 +1879,7 @@ typedef struct enc_core_structure int16_t old_pitch; /* previous pitch for open-loop pitch search */ int16_t delta_pit; /* open-loop pitch extrapolation correction */ float ee_old; /* previous frame low/high frequency energy ratio */ + Word32 ee_old_fx; int16_t min_band; /* minimum critical band of useful bandwidth */ int16_t max_band; /* maximum critical band of useful bandwidth */ @@ -1876,7 +1899,6 @@ typedef struct enc_core_structure Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ Word16 last_vad_spa_fx; - Word16 last_L_frame; /* ACELP@16kHz - last L_frame value */ float mem_preemph16k; /* ACELP@16kHz - preemphasis filter memory @16kHz */ float mem_deemp_preQ; /* ACELP@16kHz - prequantizer deemhasis memory */ @@ -2159,6 +2181,7 @@ typedef struct enc_core_structure float preemph_fac_flt; /* Preemphasis factor */ float gamma_flt; + Word16 preemph_fac; /*Preemphasis factor*/ Word16 gamma; @@ -2192,6 +2215,7 @@ typedef struct enc_core_structure int16_t encoderLookahead_FB; /* pitch_ol for adaptive lag window */ + int16_t old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ @@ -2328,6 +2352,7 @@ typedef struct enc_core_structure // // /*----------------------------------------------------------------------------------* // * Common parameters + // *----------------------------------------------------------------------------------*/ // /*----------------------------------------------------------------------------------* // * Stereo/IVAS parameters @@ -2562,6 +2587,7 @@ typedef struct enc_core_structure // /*----------------------------------------------------------------------------------* // * AMR-WB IO handle // *----------------------------------------------------------------------------------*/ +// HANDLE_CLDFB_FILTER_BANK cldfbAna_Fx; // // AMRWB_IO_ENC_HANDLE hAmrwb_IO; /* AMR-WB IO encoder handle */ // @@ -2864,6 +2890,10 @@ typedef struct context_rc_mem_struct int16_t rateFlag; int16_t lastnz; int16_t nt_half; +#ifdef IVAS_FLOAT_FIXED + Word32 bit_estimate_fx; + Word16 bit_estimate_e; +#endif } RC_CONTEXT_MEM, *HANDLE_RC_CONTEXT_MEM; diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index 6b95cae29ce39d13d1779517be9e93e8a8444291..609e03bf4c130e8dd0c13adad2f781e33c796c8b 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -39,6 +39,8 @@ #include "options.h" #include #include "prot.h" +#include "prot_fx2.h" +#include "prot_fx_enc.h" #include "rom_com.h" #include "cnst.h" #include "wmc_auto.h" @@ -614,6 +616,87 @@ void tcx_scalar_quantization( return; } +#ifdef IVAS_FLOAT_FIXED +void tcx_scalar_quantization_ivas_fx( + Word32 *x, + /* i: input coefficients */ // x_e + Word16 x_e, /* i: exponent */ + Word16 *xq, /* o: quantized coefficients */ + Word16 L_frame, /* i: frame length */ + Word16 gain, + /* i: quantization gain */ // gain_e + Word16 gain_e, /* i: quantization gain exponent */ + Word16 offset, /* i: rounding offset (deadzone) */ + Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0 */ + const Word16 alfe_flag ) +{ + Word16 i, tmp16, s; + Word32 tmp32, offs32; + + + /* common exponent for x and gain for comparison */ + tmp16 = sub( gain_e, x_e ); + tmp32 = L_shl( L_deposit_h( gain ), s_max( -31, s_min( tmp16, 0 ) ) ); + tmp16 = negate( s_max( tmp16, 0 ) ); + + i = sub( L_frame, 1 ); + IF( memQuantZeros_fx != NULL ) + { + test(); + WHILE( ( memQuantZeros_fx[i] != 0 ) && ( LT_32( L_abs( L_shl( x[i], tmp16 ) ), tmp32 ) ) ) + { + test(); + xq[i] = 0; + move16(); + i = sub( i, 1 ); + } + } + + /* invert gain */ + gain = Inv16( gain, &gain_e ); + + s = sub( add( x_e, gain_e ), 15 ); + + /*It should almost never happen and if so the quantization will be discarded later on (saturation of gain Quantizer).*/ + IF( GT_16( s, 31 ) ) + { + /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/ + gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/ + gain_e = 2; + + s = sub( add( x_e, gain_e ), 15 ); + } + + /* substract 0x8000 to affect the mac_r in the following loop + so it acts like extract_h. the 0x4000 will be multiplied by 2 + by the mac_r to get to 0x8000 and disable the round. */ + offset = sub( offset, 0x4000 ); + + FOR( ; i >= 0; i-- ) + { + offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */ +#ifdef BASOP_NOGLOB + offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */ + tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */ +#else + offs32 = L_shl( offs32, s ); /* convert to 15Q16 */ + tmp16 = mac_r( offs32, offset, 1 ); /* add offset and truncate */ +#endif + if ( x[i] < 0 ) + tmp16 = negate( tmp16 ); /* restore sign */ + + xq[i] = tmp16; + move16(); + } + + IF( alfe_flag == 0 ) + { + AdaptLowFreqEmph_fx( x, x_e, xq, gain, gain_e, + 0, NULL, NULL, + L_frame ); + } +} +#endif /*---------------------------------------------------------------------* * tcx_scalar_quantization_rateloop()