From b0364efc074ffd66935f9deb359edddf1b81fddb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sun, 6 Oct 2024 17:29:09 +0530 Subject: [PATCH] MC-paramupmix, MC-MASA functions conversion and integration [x] mc_paramupmix_param_est_enc, mc_masa functions conversion [x] Enabled ProcessIGF_ivas_fx and mctStereoIGF_enc_fx in ivas_mct_core_enc, estDownmixGain fixed point version [x] spar_enc sub-functions integration [x] Conversion of ivas_acelp_tcx20_switching [x] ivas_osba_enc_reconfig() sub-functions conversion [x] Float code cleanup --- lib_com/cldfb.c | 23 +- lib_com/cnst.h | 1 + lib_com/ivas_cnst.h | 7 + lib_com/ivas_prot.h | 50 +- lib_com/ivas_prot_fx.h | 137 ++ lib_com/prot.h | 2 +- lib_enc/dtx_fx.c | 103 +- lib_enc/fd_cng_enc.c | 4 +- lib_enc/find_tilt.c | 2 +- lib_enc/igf_enc.c | 56 +- lib_enc/init_enc.c | 8 +- lib_enc/ivas_core_enc.c | 8 +- lib_enc/ivas_core_pre_proc_front.c | 216 +- lib_enc/ivas_corecoder_enc_reconfig.c | 18 +- lib_enc/ivas_cpe_enc.c | 43 - lib_enc/ivas_dirac_enc.c | 193 +- lib_enc/ivas_enc.c | 35 +- lib_enc/ivas_front_vad.c | 113 +- lib_enc/ivas_init_enc.c | 15 +- lib_enc/ivas_ism_enc.c | 14 +- lib_enc/ivas_masa_enc.c | 76 + lib_enc/ivas_mc_paramupmix_enc.c | 546 +++-- lib_enc/ivas_mcmasa_enc.c | 2668 ++++++++++++++++++++----- lib_enc/ivas_mct_core_enc.c | 285 +-- lib_enc/ivas_mct_enc.c | 232 ++- lib_enc/ivas_mct_enc_mct.c | 515 +---- lib_enc/ivas_omasa_enc.c | 2 +- lib_enc/ivas_osba_enc.c | 71 +- lib_enc/ivas_qmetadata_enc.c | 23 +- lib_enc/ivas_sba_enc.c | 2 +- lib_enc/ivas_spar_encoder.c | 63 +- lib_enc/ivas_stat_enc.h | 76 +- lib_enc/ivas_stereo_classifier.c | 2 +- lib_enc/ivas_stereo_ica_enc.c | 228 ++- lib_enc/ivas_stereo_mdct_core_enc.c | 47 +- lib_enc/ivas_stereo_switching_enc.c | 5 +- lib_enc/ivas_tcx_core_enc.c | 578 ++++++ lib_enc/long_enr.c | 3 +- lib_enc/nois_est.c | 8 +- lib_enc/nois_est_fx.c | 27 +- lib_enc/stat_enc.h | 43 +- lib_enc/tcx_utils_enc.c | 2 +- lib_enc/tcx_utils_enc_fx.c | 66 + 43 files changed, 4759 insertions(+), 1857 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 6cba0128d..c015e5738 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1949,8 +1949,8 @@ void analysisCldfbEncoder_ivas( } void analysisCldfbEncoder_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word32 *timeIn, /*q11*/ + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *timeIn, /*q11*/ Word16 timeInq, Word16 samplesToProcess, Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], @@ -1967,6 +1967,11 @@ void analysisCldfbEncoder_ivas_fx( Word32 *ppBuf_Imag[CLDFB_NO_COL_MAX]; Word16 *ppBuf_Real16[CLDFB_NO_COL_MAX]; Word16 *ppBuf_Imag16[CLDFB_NO_COL_MAX]; + Word32 l_timeIn[L_FRAME48k]; + Word16 norm_timeIn = L_norm_arr( timeIn, samplesToProcess ); + Word16 guard_bits = find_guarded_bits_fx( shl( samplesToProcess, 1 ) ); + Word16 shift = 0; + move16(); FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { @@ -1975,9 +1980,19 @@ void analysisCldfbEncoder_ivas_fx( ppBuf_Real16[i] = &realBuffer16[i][0]; ppBuf_Imag16[i] = &imagBuffer16[i][0]; } - cldfbAnalysis_ivas_fx( timeIn, ppBuf_Real, ppBuf_Imag, samplesToProcess, st->cldfbAnaEnc ); + IF( GT_16( guard_bits, norm_timeIn ) ) + { + shift = sub( guard_bits, norm_timeIn ); + v_shr_32( timeIn, l_timeIn, samplesToProcess, shift ); + } + ELSE + { + Copy32( timeIn, l_timeIn, samplesToProcess ); + } + + cldfbAnalysis_ivas_fx( l_timeIn, ppBuf_Real, ppBuf_Imag, samplesToProcess, st->cldfbAnaEnc ); - scale->lb_scale = sub( 16 + 5, timeInq ); + scale->lb_scale = sub( 16 + 5, sub( timeInq, shift ) ); enerScale.lb_scale = negate( scale->lb_scale ); enerScale.lb_scale16 = negate( scale->lb_scale ); move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index b830a3d73..feece3ae9 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -785,6 +785,7 @@ enum #define CLDFB_OVRLP_MIN_SLOTS 3 /* CLDFB resampling - minimize processing to minimum required for transition frame ACELP->TCX/HQ */ #define INV_CLDFB_BANDWIDTH ( 1.f / 800.f ) #define INV_CLDFB_BANDWIDTH_Q31 ( 2684355l ) +#define INV_CLDFB_BANDWIDTH_MDFT_FAC_Q31 ( 10737418 ) #define CLDFB_BANDWIDTH 800 #define L_FILT_2OVER3 12 diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index d4beedca7..7c23752cf 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -827,6 +827,10 @@ enum fea_names #define STEREO_TCA_GDMIN_FX -32768 #define STEREO_TCA_GDSTEP 0.05f #define STEREO_TCA_GDSTEP_FX 819 +#ifdef IVAS_FLOAT_FIXED +#define STEREO_TCA_GDMIN_FX_Q14 (-16384) +#define STEREO_TCA_GDSTEP_FX_Q13 (410) +#endif #define STEREO_BITS_TCA ( STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS + STEREO_BITS_TCA_GD ) #define STEREO_ICBWE_MSFLAG_BITS 1 /* BWE Multi Source flag */ @@ -1282,6 +1286,9 @@ enum #define MASA_COHERENCE_TOLERANCE 0.1f #define MASA_COHERENCE_THRESHOLD 0.1f +#ifdef IVAS_FLOAT_FIXED +#define MASA_COHERENCE_THRESHOLD_FX 214748365 // 0.1 in Q31 +#endif #define MASA_RATIO_TOLERANCE 0.1f #define MASA_RATIO_THRESHOLD 0.1f #define MASA_ANGLE_TOLERANCE 0.5f diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8d39bc559..b352b4803 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -159,7 +159,7 @@ void destroy_cpe_enc( void ivas_mct_enc_close( MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ ); - +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_corecoder_enc_reconfig( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const int16_t nSCE_old, /* i : number of SCEs in previous frame */ @@ -169,7 +169,7 @@ ivas_error ivas_corecoder_enc_reconfig( const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */ const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ ); - +#endif ivas_error ivas_sce_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const int16_t sce_id, /* i : SCE # identifier */ @@ -811,19 +811,21 @@ void ivas_smc_mode_selection( ); /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ +#ifndef IVAS_FLOAT_FIXED int16_t ivas_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - const float *inp, /* i : new input signal */ - const float *wsp, /* i : input weighted signal */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - const float *pitch_fr, /* i : fraction pitch values */ - const float *voicing_fr, /* i : fractional voicing values */ - const float currFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac, /* i : LP filter stability */ - float *res_cod_SNR_M, - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + Encoder_State *st, /* i/o: encoder state structure */ + const float *inp, /* i : new input signal */ + const float *wsp, /* i : input weighted signal */ + const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ + const float *pitch_fr, /* i : fraction pitch values */ + const float *voicing_fr, /* i : fractional voicing values */ + const float currFlatness, /* i : flatness */ + const float lsp_mid[M], /* i : LSPs at the middle of the frame */ + const float stab_fac, /* i : LP filter stability */ + float *res_cod_SNR_M, + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ); +#endif #ifndef IVAS_FLOAT_FIXED void ivas_decision_matrix_enc( @@ -4232,23 +4234,7 @@ void getChannelEnergies( float nrg[MCT_MAX_CHANNELS], /* o : energies */ const int16_t nchan /* i : number of channels */ ); -#ifdef IVAS_FLOAT_FIXED -void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - float *orig_spectrum[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - float powerSpec[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#endif - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ -); -#endif + void mctStereoIGF_enc( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ @@ -7553,6 +7539,7 @@ void ivas_ls_custom_setup( * McMASA prototypes *----------------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_mcmasa_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); @@ -7565,6 +7552,7 @@ void ivas_mcmasa_enc_close( ivas_error ivas_mcmasa_enc_reconfig( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); +#endif ivas_error ivas_mcmasa_dec_reconfig( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ @@ -7591,6 +7579,7 @@ void ivas_mcmasa_split_brate( int32_t *brate_cpe /* o : Pointer to CPE element bitrate */ ); +#ifndef IVAS_FLOAT_FIXED void ivas_mcmasa_enc( MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */ IVAS_QMETADATA_HANDLE hQMeta, /* o : Qmetadata handle */ @@ -7614,6 +7603,7 @@ void ivas_mcmasa_param_est_enc( const int16_t nchan_inp /* i : Number of input channels */ ); +#endif void ivas_mcmasa_dmx_modify( const int16_t n_samples, /* i : input frame length in samples */ float dmx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6315cb2da..0a07ebf47 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2754,7 +2754,22 @@ void ivas_spar_bitrate_dist_fx( const Word16 sba_order, /* i : Ambisonic (SBA) order */ const Word16 bwidth /* i : audio bandwidth */ ); +ivas_error ivas_corecoder_enc_reconfig_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 nSCE_old, /* i : number of SCEs in previous frame */ + const Word16 nCPE_old, /* i : number of CPEs in previous frame */ + const Word16 nchan_transport_old, /* i : number of TCs in previous frame */ + const Word32 brate_SCE, /* i : bitrate to be set for the SCEs */ + const Word32 brate_CPE, /* i : bitrate to be set for the CPEs */ + const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ +); +void ivas_sba_zero_vert_comp_fx( + Word32 *sba_data[], /* i : SBA signals */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sba_planar, /* i : SBA planar flag */ + const Word16 input_frame /* i : frame length */ +); void tdm_configure_dec_fx( const Word16 ivas_format, /* i : IVAS format */ const Word16 ism_mode, /* i : ISM mode in combined format */ @@ -2935,6 +2950,23 @@ void core_switching_pre_enc_ivas_fx( const Word16 last_element_mode /* i : last_element_mode */ ); +Word16 ivas_acelp_tcx20_switching_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 *inp_fx, /* i : new input signal */ + Word16 q_inp, /* i : i/p Q */ + Word16 *wsp, /* i : input weighted signal */ + Word16 non_staX, /* i : unbound non-stationarity for sp/mu clas */ + Word16 *pitch_fr, /* i : fraction pitch values */ + Word16 *voicing_fr, /* i : fractional voicing values */ + Word16 currFlatness, /* i : flatness */ + Word16 lsp_mid[M], /* i : LSPs at the middle of the frame */ + Word16 stab_fac, /* i : LP filter stability */ + Word32 *res_cod_SNR_M, + Word16 *res_cod_SNR_M_e, + Word16 *tcx_mdct_window_fx, + const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ +); + void encod_gen_2sbfr( Encoder_State *st, /* i/o: state structure */ const Word16 speech[], /* i : input speech */ @@ -3144,6 +3176,87 @@ Word16 ivas_omasa_ener_brate_fx( const Word16 input_frame, /* i : Input frame size */ Word16 data_e /*i:exponent for data_f */ ); +void computeDiffuseness_mdft_fx( + Word32 **buffer_intensity[DIRAC_NUM_DIMS], + const Word32 *buffer_energy, + const Word16 num_freq_bands, + const UWord16 no_col_avg_diff, + Word32 *diffuseness, + Word16 *q_factor_intensity, + Word16 *q_factor_energy, + Word16 *q_diffuseness /*Ouput Q*/ +); + +void computeDirectionVectors_fixed( + Word32 *intensity_real_x, + Word32 *intensity_real_y, + Word32 *intensity_real_z, + const Word16 enc_param_start_band, + const Word16 num_frequency_bands, + Word32 *direction_vector_x, /*Q30*/ + Word32 *direction_vector_y, /*Q30*/ + Word32 *direction_vector_z, /*Q30*/ + Word16 i_e /*Exponent of all the intensity buffers*/ ); + + +UWord8 ivas_masa_surrcoh_signicant_fx( + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Surround coherence */ + Word32 diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Diffuse to total ratio */ + const Word16 nSubFrames, /* i : Number of sub frames */ + const Word16 nBands /* i : Number of frequency bands */ +); + +/*----------------------------------------------------------------------------------* + * McMASA prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_mcmasa_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); +void ivas_mcmasa_enc_close_fx( + MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */ + const Word32 input_Fs /* i : input sampling rate */ +); + +ivas_error ivas_mcmasa_enc_reconfig_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_mcmasa_enc_fx( + MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */ + IVAS_QMETADATA_HANDLE hQMeta, /* o : Qmetadata handle */ + MASA_ENCODER_HANDLE hMasa, /* i/o: Encoder MASA handle */ + Word32 *data_f[], /* i : Input frame of audio */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_transport, /* i : Number of transport channels */ + const Word16 nchan_inp, /* i : Number of input channels */ + const Word16 q_inp /* i : Input data q-format */ +); +void ivas_mcmasa_param_est_enc_fx( + MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */ + MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */ + Word32 *data_f[], /* i : Audio frame in MC-format */ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */ + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */ + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */ + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_inp, /* i : Number of input channels */ + const Word16 q_inp /* i : Number of input channels */ +); + +void computeReferencePower_enc_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ + Word32 *reference_power, /* o : Estimated power */ + const Word16 enc_param_start_band, /* i : first band to process */ + const Word16 num_freq_bands, /* i : Number of frequency bands */ + const IVAS_FORMAT ivas_format, /* i : ivas_format */ + Word16 ref_power_w, /* i : use 0 if hodirac is enabled */ + const Word16 nchan_ana /* i : number of analysis channels */ +); void ivas_omasa_enc( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */ @@ -3158,4 +3271,28 @@ void ivas_omasa_enc( float *data_separated_object, /* o : Separated object audio signal */ int16_t *idx_separated_object /* o : Index of the separated object */ ); + +void mctStereoIGF_enc_fx( + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ + Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ + Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ + Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ +); + +void ivas_mct_core_enc_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ + const Word16 nChannels, /* i : number of channels to be coded */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word16 switch_bw, /* i : flag bandwidth switch occurance */ + const Word16 lfe_bits, /* i : bits spent for LFE */ + const Word16 sba_order /* i : Ambisonic (SBA) order */ +); + #endif diff --git a/lib_com/prot.h b/lib_com/prot.h index 61568e3b2..e30269296 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -9201,7 +9201,7 @@ void analysisCldfbEncoder_ivas( void analysisCldfbEncoder_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word32 *timeIn, /*q11*/ + Word32 *timeIn, /*q11*/ Word16 timeInq, /*q0*/ Word16 samplesToProcess, /*q0*/ Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index afc6fbe38..c94ff10c2 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -90,8 +90,14 @@ void dtx_ivas_fx( ELSE { /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ + test(); + test(); + test(); 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 ) ); + test(); + test(); + test(); 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(); @@ -105,6 +111,8 @@ void dtx_ivas_fx( st_fx->cng_type = FD_CNG; move16(); test(); + test(); + 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; @@ -113,6 +121,9 @@ void dtx_ivas_fx( } test(); 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 */ st_fx->fd_cng_reset_flag == 0 && @@ -159,7 +170,7 @@ void dtx_ivas_fx( 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 ) ) + if ( st_fx->rf_mode && st_fx->rf_fec_offset > 0 && EQ_32( st_fx->total_brate, ACELP_13k20 ) && ( st_fx->bwidth != NB ) ) { st_fx->Opt_RF_ON = 1; move16(); @@ -168,7 +179,7 @@ void dtx_ivas_fx( move16(); st_fx->bwidth = st_fx->last_bwidth; move32(); - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode > EVS_MONO ) { st_fx->codec_mode = MODE1; move16(); @@ -176,6 +187,7 @@ void dtx_ivas_fx( ELSE { st_fx->codec_mode = get_codec_mode( st_fx->total_brate ); + move16(); } } } @@ -183,15 +195,19 @@ void dtx_ivas_fx( /*------------------------------------------------------------------------* * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ - if ( st_fx->dtx_sce_sba == 0 ) + IF( st_fx->dtx_sce_sba == 0 ) { + test(); + test(); + test(); + test(); #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 ) ); + br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || + ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || + LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); #endif } test(); @@ -210,14 +226,18 @@ void dtx_ivas_fx( IF( st_fx->Opt_AMR_WB ) { st_fx->last_total_brate_cng = -1; + move16(); st_fx->last_rf_mode_cng = st_fx->rf_mode; move16(); } ELSE { st_fx->last_total_brate_cng = st_fx->total_brate; + move16(); st_fx->last_bwidth_cng = st_fx->bwidth; + move16(); st_fx->last_codec_mode_cng = st_fx->codec_mode; + move16(); } IF( hDtxEnc->cnt_SID == 0 ) @@ -243,18 +263,26 @@ void dtx_ivas_fx( 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 ) + if ( ( st_fx->core_brate == FRAME_NO_DATA ) && ( 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 ) ) + test(); + test(); + IF( ( ( 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 ) ) ) + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( 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(); @@ -266,11 +294,12 @@ void dtx_ivas_fx( 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 */ + IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, ACELP_24k40 ) || ( ( 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 ) ) ) + test(); + if ( ( 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(); @@ -280,7 +309,7 @@ void dtx_ivas_fx( { st_fx->cng_type = LP_CNG; move16(); - IF( st_fx->codec_mode == MODE2 ) + if ( EQ_16( st_fx->codec_mode, MODE2 ) ) { hTdCngEnc->lp_cng_mode2 = 1; move16(); @@ -290,6 +319,7 @@ void dtx_ivas_fx( } } /* reset the bitstream (IVAS format signalling was already written) */ + test(); IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { @@ -303,7 +333,7 @@ void dtx_ivas_fx( /* 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( ( NE_32( st_fx->core_brate, SID_2k40 ) ) && ( NE_32( st_fx->core_brate, SID_1k75 ) ) && ( st_fx->core_brate != FRAME_NO_DATA ) ) { IF( hDtxEnc != NULL ) { @@ -323,7 +353,7 @@ void dtx_ivas_fx( move16(); /* first SID update is only 3 frames after the active speech end */ } - IF( LT_16( hDtxEnc->interval_SID, hDtxEnc->max_SID ) ) + if ( LT_16( hDtxEnc->interval_SID, hDtxEnc->max_SID ) ) { hDtxEnc->max_SID = hDtxEnc->interval_SID; move16(); /* change SID update rate */ @@ -333,6 +363,7 @@ void dtx_ivas_fx( move16(); /* reset the counter of CNG frames for averaging */ } test(); + 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 ) ) @@ -342,24 +373,32 @@ void dtx_ivas_fx( 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 ); + lp_thresh = 327680; // 5 in Q16 + move32(); + fd_thresh = 131072; // 2 in Q16 + move32(); } ELSE - { - lp_thresh = L_shl( 10, Q27 ); - fd_thresh = L_shl( 5, Q27 ); + lp_thresh = 655360; // 10 in Q16 + move32(); + fd_thresh = 327680; // 5 in Q16 + move32(); } /*More conservative selection of LP-CNG for SCE*/ - if ( st_fx->cng_type == LP_CNG && ( st_fx->bckr_tilt_lt > lp_thresh ) ) + test(); + test(); + test(); + IF( st_fx->cng_type == LP_CNG && ( GT_32( st_fx->bckr_tilt_lt, lp_thresh ) ) ) { st_fx->cng_type = FD_CNG; + move16(); } - else if ( st_fx->cng_type == FD_CNG && ( st_fx->bckr_tilt_lt < fd_thresh ) && ( st_fx->lp_noise > L_shl( 2, Q27 ) ) ) + ELSE IF( EQ_16( st_fx->cng_type, FD_CNG ) && ( LT_32( st_fx->bckr_tilt_lt, fd_thresh ) ) && ( GT_16( st_fx->lp_noise_fx, 512 /* 2 in Q8 */ ) ) ) { st_fx->cng_type = LP_CNG; + move16(); } } ELSE @@ -372,18 +411,19 @@ void dtx_ivas_fx( 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*/ ) ) ) ) + IF( ( st_fx->cng_type == LP_CNG ) && ( ( ( st_fx->input_bwidth == NB ) && GT_32( st_fx->bckr_tilt_lt, 589824 /*9.f Q16*/ ) ) || ( ( 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*/ ) ) ) ) + ELSE IF( EQ_16( st_fx->cng_type, FD_CNG ) && ( ( ( st_fx->input_bwidth == NB ) && LT_32( st_fx->bckr_tilt_lt, 131072l /*2.f Q16*/ ) ) || ( ( 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; + move16(); } ELSE IF( st_fx->Opt_AMR_WB ) { @@ -391,7 +431,9 @@ void dtx_ivas_fx( move16(); } st_fx->active_fr_cnt_fx = add( st_fx->active_fr_cnt_fx, 1 ); + move16(); st_fx->active_fr_cnt_fx = s_min( st_fx->active_fr_cnt_fx, 200 ); + move16(); } /*------------------------------------------------------------------------* @@ -426,6 +468,7 @@ void dtx_ivas_fx( 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 + move32(); /* Active speech (voiced) */ @@ -443,10 +486,13 @@ void dtx_ivas_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 */ + move32(); hDtxEnc->VarDTX_cnt_voiced = add( hDtxEnc->VarDTX_cnt_voiced, 1 ); + move16(); hDtxEnc->VarDTX_cnt_voiced = s_min( hDtxEnc->VarDTX_cnt_voiced, MIN_CNT ); + move16(); } /* Background noise */ ELSE IF( !st_fx->Opt_AMR_WB ) @@ -466,8 +512,10 @@ void dtx_ivas_fx( move32(); /*2*Q_speech-guard_bits */ hDtxEnc->VarDTX_cnt_noise = add( hDtxEnc->VarDTX_cnt_noise, 1 ); + move16(); hDtxEnc->VarDTX_cnt_noise = s_min( hDtxEnc->VarDTX_cnt_noise, MIN_CNT ); + move16(); } } } @@ -478,7 +526,7 @@ void dtx_ivas_fx( /* Update encoded bandwidth */ test(); test(); - IF( st_fx->Opt_DTX_ON && ( st_fx->core_brate == SID_2k40 || st_fx->core_brate == FRAME_NO_DATA ) ) + IF( st_fx->Opt_DTX_ON && ( EQ_32( st_fx->core_brate, SID_2k40 ) || ( st_fx->core_brate == FRAME_NO_DATA ) ) ) { st_fx->bwidth = st_fx->last_bwidth; @@ -492,7 +540,7 @@ void dtx_ivas_fx( test(); test(); - IF( st_fx->Opt_RF_ON && ( EQ_32( st_fx->total_brate, ACELP_13k20 ) ) && ( EQ_16( st_fx->bwidth, NB ) ) ) + IF( st_fx->Opt_RF_ON && ( EQ_32( st_fx->total_brate, ACELP_13k20 ) ) && ( ( st_fx->bwidth == NB ) ) ) { st_fx->codec_mode = MODE1; move16(); @@ -503,7 +551,6 @@ void dtx_ivas_fx( move16(); } - test(); test(); IF( st_fx->Opt_RF_ON && NE_32( st_fx->total_brate, ACELP_13k20 ) ) { @@ -532,7 +579,7 @@ void dtx_ivas_fx( BREAK; } } - if ( n == FRAME_SIZE_NB ) + IF( EQ_16( n, FRAME_SIZE_NB ) ) { assert( !"Bitrate not supported: not part of EVS" ); } @@ -540,8 +587,10 @@ void dtx_ivas_fx( if ( EQ_16( st_fx->rf_mode, 1 ) ) { tmpbandwidthMin = WB; + move16(); } st_fx->bwidth = s_max( s_min( st_fx->bwidth, FrameSizeConfig[n].bandwidth_max ), tmpbandwidthMin ); + move16(); } } diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 325c0bf1c..718666927 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -307,7 +307,7 @@ void deleteFdCngEnc( * * Reset the instance of type FD_CNG *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void resetFdCngEnc( Encoder_State *st /* i/o: encoder state structure */ ) @@ -365,7 +365,7 @@ void resetFdCngEnc( return; } - +#endif /*-------------------------------------------------------------------* * perform_noise_estimation_enc() * diff --git a/lib_enc/find_tilt.c b/lib_enc/find_tilt.c index 36a97e346..cb8af8bab 100644 --- a/lib_enc/find_tilt.c +++ b/lib_enc/find_tilt.c @@ -142,7 +142,7 @@ void find_tilt_ivas_fx( Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); Ltmp = Mpy_32_16_r( Ltmp, 3277 ); Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); - *bckr_tilt_lt = L_add( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Ltmp ); + *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Ltmp ); move32(); test(); diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 69a0d1f19..4acf05384 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1531,12 +1531,16 @@ static void IGF_CalculateStereoEnvelope_fx( FOR( sfbCnt = 0; sfbCnt < sub( hGrid->sfbWrap[hGrid->nTiles], hGrid->sfbWrap[0] ); sfbCnt++ ) { /* reset filter */ - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfbCnt] = 0; /* Exponent is hPrivateData->sfb_tb_e*/ - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfbCnt] = 0; /* Exponent is hPrivateData->sfb_tb_e*/ - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfbCnt] = 0; /* Exponent is hPrivateData->sfb_sb_e*/ - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfbCnt] = 0; /* Exponent is hPrivateData->sfb_sb_e*/ - hPrivateData->sfb_sb_e[sfbCnt] = 0; - hPrivateData->sfb_tb_e[sfbCnt] = 0; + hPrivateData->prevSFM_FIR_SFB_TB_fx[sfbCnt] = 0; // exponent : hPrivateData->prevSFB_FIR_TB_e[sfbCnt] + hPrivateData->prevSFM_IIR_SFB_TB_fx[sfbCnt] = 0; // exponent : hPrivateData->prevSFB_IIR_TB_e[sfbCnt] + hPrivateData->prevSFM_FIR_SFB_SB_fx[sfbCnt] = 0; // exponent : hPrivateData->prevSFB_FIR_SB_e[sfbCnt] + hPrivateData->prevSFM_IIR_SFB_SB_fx[sfbCnt] = 0; // exponent : hPrivateData->prevSFB_IIR_SB_e[sfbCnt] + hPrivateData->prevSFB_FIR_TB_e[sfbCnt] = 0; + hPrivateData->prevSFB_IIR_TB_e[sfbCnt] = 0; + hPrivateData->prevSFB_FIR_SB_e[sfbCnt] = 0; + hPrivateData->prevSFB_IIR_SB_e[sfbCnt] = 0; + move16(); + move16(); move16(); move16(); move16(); @@ -1654,8 +1658,12 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = tmp_tb_fx; /*Exponent for hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] and hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] values stored in hPrivateData->sfb_tb_e[sfb] */ hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = tmp_sb_fx; /*Exponent for hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] and hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] values stored in hPrivateData->sfb_sb_e[sfb]*/ - hPrivateData->sfb_tb_e[sfb] = tmp_tb_e; - hPrivateData->sfb_sb_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; + move16(); + move16(); move16(); move16(); move16(); @@ -1683,7 +1691,9 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], diff_tb_e ); hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], diff_tb_e ); - hPrivateData->sfb_tb_e[sfb] = tmp_tb_e; + hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_tb_e; + hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_tb_e; + move16(); move16(); move16(); move16(); @@ -1698,7 +1708,9 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], diff_sb_e ); hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], diff_sb_e ); - hPrivateData->sfb_sb_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; + move16(); move16(); move16(); move16(); @@ -1893,6 +1905,14 @@ static void IGF_CalculateStereoEnvelope_fx( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = hPrivateData->SFM_tb_fx[sfb]; hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = tmp_sb_fx; hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = hPrivateData->SFM_sb_fx[sfb]; + hPrivateData->prevSFB_FIR_TB_e[sfb] = hPrivateData->sfb_tb_e[sfb]; + hPrivateData->prevSFB_IIR_TB_e[sfb] = hPrivateData->sfb_tb_e[sfb]; + hPrivateData->prevSFB_FIR_SB_e[sfb] = hPrivateData->sfb_sb_e[sfb]; + hPrivateData->prevSFB_IIR_SB_e[sfb] = hPrivateData->sfb_sb_e[sfb]; + move16(); + move16(); + move16(); + move16(); move16(); move16(); move16(); @@ -1904,6 +1924,10 @@ static void IGF_CalculateStereoEnvelope_fx( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = 0; hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = 0; hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = 0; + hPrivateData->prevSFB_FIR_TB_e[sfb] = 0; + hPrivateData->prevSFB_IIR_TB_e[sfb] = 0; + hPrivateData->prevSFB_FIR_SB_e[sfb] = 0; + hPrivateData->prevSFB_IIR_SB_e[sfb] = 0; hPrivateData->dampingFactorSmoothing[sfb] = 2; move16(); @@ -1911,6 +1935,10 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); move16(); move16(); + move16(); + move16(); + move16(); + move16(); } } ELSE @@ -1926,6 +1954,14 @@ static void IGF_CalculateStereoEnvelope_fx( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = 0; hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = 0; hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = 0; + hPrivateData->prevSFB_FIR_TB_e[sfb] = 0; + hPrivateData->prevSFB_IIR_TB_e[sfb] = 0; + hPrivateData->prevSFB_FIR_SB_e[sfb] = 0; + hPrivateData->prevSFB_IIR_SB_e[sfb] = 0; + move16(); + move16(); + move16(); + move16(); move16(); move16(); move16(); diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index a0fb097e6..386466a08 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -419,8 +419,11 @@ ivas_error init_encoder( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ); } - +#ifdef IVAS_FLOAT_FIXED + noise_est_init_ivas_fx( st->hNoiseEst ); +#else noise_est_init( st->hNoiseEst ); +#endif } else { @@ -1535,9 +1538,6 @@ ivas_error init_encoder_ivas_fx( } noise_est_init_ivas_fx( st->hNoiseEst ); -#if 1 - noise_est_init( st->hNoiseEst ); -#endif } ELSE { diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 96c4cd8ed..e219c00be 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -1344,8 +1344,8 @@ ivas_error ivas_core_enc( floatToFixed_arr16( hCPE->hStereoICBWE->dec_2over3_mem_lp, hCPE->hStereoICBWE->dec_2over3_mem_lp_fx, scale_factor, 3 ); floatToFixed_arr16( hCPE->hStereoICBWE->memModifyFs_icbwe[0], hCPE->hStereoICBWE->memModifyFs_icbwe_fx[0], scale_factor, 60 ); floatToFixed_arr16( hCPE->hStereoICBWE->memModifyFs_icbwe[1], hCPE->hStereoICBWE->memModifyFs_icbwe_fx[1], scale_factor, 60 ); - floatToFixed_arr16( hCPE->hStereoICBWE->icbwe_inp_mem[0], hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], scale_factor, 270 ); - floatToFixed_arr16( hCPE->hStereoICBWE->icbwe_inp_mem[1], hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], scale_factor, 270 ); + floatToFixed_arr16( hCPE->hStereoICBWE->icbwe_inp_mem[0], hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], scale_factor, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); + floatToFixed_arr16( hCPE->hStereoICBWE->icbwe_inp_mem[1], hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], scale_factor, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); floatToFixed_arr16( hCPE->hStereoICBWE->mem_decim_shb_ch0, hCPE->hStereoICBWE->mem_decim_shb_ch0_fx, 0, 90 ); @@ -1363,8 +1363,8 @@ ivas_error ivas_core_enc( fixedToFloat_arr( hCPE->hStereoICBWE->dec_2over3_mem_lp_fx, hCPE->hStereoICBWE->dec_2over3_mem_lp, scale_factor, 3 ); fixedToFloat_arr( hCPE->hStereoICBWE->memModifyFs_icbwe_fx[0], hCPE->hStereoICBWE->memModifyFs_icbwe[0], scale_factor, 60 ); fixedToFloat_arr( hCPE->hStereoICBWE->memModifyFs_icbwe_fx[1], hCPE->hStereoICBWE->memModifyFs_icbwe[1], scale_factor, 60 ); - fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], hCPE->hStereoICBWE->icbwe_inp_mem[0], scale_factor, 270 ); - fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], hCPE->hStereoICBWE->icbwe_inp_mem[1], scale_factor, 270 ); + fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], hCPE->hStereoICBWE->icbwe_inp_mem[0], scale_factor, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); + fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], hCPE->hStereoICBWE->icbwe_inp_mem[1], scale_factor, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); fixedToFloat_arr( hCPE->hStereoICBWE->mem_decim_shb_ch0_fx, hCPE->hStereoICBWE->mem_decim_shb_ch0, 0, 90 ); diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 7dae9fc7e..f80542a56 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -981,6 +981,7 @@ ivas_error pre_proc_front_ivas_fx( #endif Word16 localVAD_HE_SAD; float non_staX; + Word16 currFlatness_fx; Word32 non_staX_fx; float stab_fac; Word16 alw_pitch_lag_12k8[2]; @@ -1260,6 +1261,7 @@ ivas_error pre_proc_front_ivas_fx( #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED new_inp_12k8 = old_inp_12k8 + L_INP_MEM; /* pointer to new samples of the input signal in 12.8kHz core */ + // int x = L_INP_MEM - L_look; inp_12k8 = new_inp_12k8 - L_look; /* pointer to the current frame of input signal in 12.8kHz core */ #endif new_inp_12k8_fx = old_inp_12k8_fx + L_INP_MEM; /* pointer to new samples of the input signal in 12.8kHz core */ @@ -1594,8 +1596,6 @@ ivas_error pre_proc_front_ivas_fx( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS /*float to fix conversions for noise_est_pre_32fx*/ Etot_fx = (Word32) ( Etot * ( 1 << 24 ) ); - st->hNoiseEst->Etot_h_32fx = (Word32) ( st->hNoiseEst->Etot_h * 16777216.0 ); - st->hNoiseEst->Etot_l_32fx = (Word32) ( st->hNoiseEst->Etot_l * 16777216.0 ); st->hNoiseEst->Etot_l_lp_32fx = (Word32) ( st->hNoiseEst->Etot_l_lp * 16777216.0 ); st->hNoiseEst->Etot_last_32fx = (Word32) ( st->hNoiseEst->Etot_last * 16777216.0 ); st->hNoiseEst->Etot_v_h2_32fx = (Word32) ( st->hNoiseEst->Etot_v_h2 * 16777216.0 ); @@ -1620,9 +1620,6 @@ ivas_error pre_proc_front_ivas_fx( st->lt_mean_WB_fx = (Word16) st->lt_mean_WB * ( 1 << 11 ); st->lt_mean_SWB_fx = (Word16) st->lt_mean_SWB * ( 1 << 11 ); - /* float to fix for noise_est_down*/ - st->hNoiseEst->Etot_last_fx = float_to_fix16( st->hNoiseEst->Etot_last, 8 ); - st->hNoiseEst->totalNoise_fx = float_to_fix16( st->hNoiseEst->totalNoise, 8 ); Word16 Q_bands0 = 0, Q_bands1 = 0; IF( lr_vad_enabled && st->idchan == 0 ) { @@ -1632,8 +1629,6 @@ ivas_error pre_proc_front_ivas_fx( floatToFixed_arrL( fr_bands_LR[1], fr_bands_LR_fx[1], Q_bands1 + QSCALE, 2 * NB_BANDS ); floatToFixed_arrL( hCPE->hFrontVad[0]->hNoiseEst->bckr, hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, Q_bands0 + QSCALE, NB_BANDS ); floatToFixed_arrL( hCPE->hFrontVad[1]->hNoiseEst->bckr, hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, Q_bands1 + QSCALE, NB_BANDS ); - hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx = float_to_fix16( hCPE->hFrontVad[0]->hNoiseEst->totalNoise, 8 ); - hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx = float_to_fix16( hCPE->hFrontVad[1]->hNoiseEst->totalNoise, 8 ); Etot_LR_fx[0] = float_to_fix16( Etot_LR[0], 8 ); Etot_LR_fx[1] = float_to_fix16( Etot_LR[1], 8 ); hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx = float_to_fix16( hCPE->hFrontVad[0]->hNoiseEst->Etot_last, 8 ); @@ -1783,8 +1778,6 @@ ivas_error pre_proc_front_ivas_fx( } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS /*cleanup changes for noise_est_pre_32fx*/ - st->hNoiseEst->Etot_h = (float) ( st->hNoiseEst->Etot_h_32fx / 16777216.0 ); - st->hNoiseEst->Etot_l = (float) ( st->hNoiseEst->Etot_l_32fx / 16777216.0 ); st->hNoiseEst->Etot_l_lp = (float) ( st->hNoiseEst->Etot_l_lp_32fx / 16777216.0 ); st->hNoiseEst->Etot_last = (float) ( st->hNoiseEst->Etot_last_32fx / 16777216.0 ); st->hNoiseEst->Etot_lp = (float) ( st->hNoiseEst->Etot_lp_32fx / 16777216.0 ); @@ -1799,7 +1792,6 @@ ivas_error pre_proc_front_ivas_fx( /*fixed to float for noise_est_down*/ fixedToFloat_arrL( st->hNoiseEst->bckr_fx, st->hNoiseEst->bckr, Q_new + QSCALE, NB_BANDS ); - st->hNoiseEst->totalNoise = fixedToFloat( st->hNoiseEst->totalNoise_fx, 8 ); fixedToFloat_arrL( tmpN_fx, tmpN, Q_new + QSCALE, 20 ); fixedToFloat_arrL( tmpE_fx, tmpE, Q_new + QSCALE, 20 ); st->hNoiseEst->Etot_v_h2 = fixedToFloat( st->hNoiseEst->Etot_v_h2_fx, 8 ); @@ -1809,8 +1801,6 @@ ivas_error pre_proc_front_ivas_fx( { fixedToFloat_arrL( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, hCPE->hFrontVad[0]->hNoiseEst->bckr, Q_bands0 + QSCALE, NB_BANDS ); fixedToFloat_arrL( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, hCPE->hFrontVad[1]->hNoiseEst->bckr, Q_bands1 + QSCALE, NB_BANDS ); - hCPE->hFrontVad[0]->hNoiseEst->totalNoise = fixedToFloat( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, 8 ); - hCPE->hFrontVad[1]->hNoiseEst->totalNoise = fixedToFloat( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, 8 ); fixedToFloat_arrL( tmpN_LR_fx[0], tmpN_LR[0], Q_bands0 + QSCALE, 20 ); fixedToFloat_arrL( tmpE_LR_fx[0], tmpE_LR[0], Q_bands0 + QSCALE, 20 ); hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2 = fixedToFloat( hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, 8 ); @@ -1829,10 +1819,6 @@ ivas_error pre_proc_front_ivas_fx( #ifndef IVAS_FLOAT_FIXED corr_shift = correlation_shift( st->hNoiseEst->totalNoise ); #else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - // performing float to fix conversion of (totalNoise) - st->hNoiseEst->totalNoise_fx = float_to_fix16( st->hNoiseEst->totalNoise, 8 ); -#endif corr_shift_fx = correlation_shift_fx( st->hNoiseEst->totalNoise_fx ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS // performing fix to float conversion of (corr_shift_fx) @@ -1849,9 +1835,6 @@ ivas_error pre_proc_front_ivas_fx( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS st->last_totalNoise_fx = float_to_fix16( st->last_totalNoise, Q8 ); - st->hNoiseEst->totalNoise_fx = float_to_fix16( st->hNoiseEst->totalNoise, Q8 ); - - FOR( Word16 j = 0; j < TOTALNOISE_HIST_SIZE; j++ ) { st->totalNoise_increase_hist_fx[j] = float_to_fix16( st->totalNoise_increase_hist[j], Q8 ); @@ -2306,8 +2289,14 @@ ivas_error pre_proc_front_ivas_fx( corr_shiftL_fx = float_to_fix16( corr_shiftL, Q15 ); corr_shiftR_fx = float_to_fix16( corr_shiftR, Q15 ); - st->bckr_tilt_lt = float_to_fix( st->bckr_tilt_lt_flt, Q16 ); - + if ( (Word32) st->bckr_tilt_lt_flt == 32768 ) + { + st->bckr_tilt_lt = MAX_32; // Q16 + } + else + { + st->bckr_tilt_lt = float_to_fix( st->bckr_tilt_lt_flt, Q16 ); + } Word16 q_fr_bands = Q30; q_fr_bands = min( q_fr_bands, Q_factor_arrL( tmpN, NB_BANDS ) ); @@ -2386,60 +2375,19 @@ ivas_error pre_proc_front_ivas_fx( floatToFixed_arr16( st->hSpMusClas->past_log_enr, st->hSpMusClas->past_log_enr_fx, Q8, NB_BANDS_SPMUS ); - floatToFixed_arr16( st->hNoiseEst->old_S, st->hNoiseEst->old_S_fx, Q7, 128 ); - floatToFixed_arr16( st->hNoiseEst->cor_map, st->hNoiseEst->cor_map_fx, Q15, 128 ); - st->hNoiseEst->Etot_lp_fx = float_to_fix16( st->hNoiseEst->Etot_lp, Q8 ); st->hNoiseEst->Etot_v_h2_fx = float_to_fix16( st->hNoiseEst->Etot_v_h2, Q8 ); st->hNoiseEst->Etot_l_lp_fx = float_to_fix16( st->hNoiseEst->Etot_l_lp, Q8 ); - st->hNoiseEst->Etot_st_est_fx = float_to_fix16( st->hNoiseEst->Etot_st_est, Q8 ); - st->hNoiseEst->Etot_sq_st_est_fx = float_to_fix16( st->hNoiseEst->Etot_sq_st_est, Q2 ); - st->hNoiseEst->multi_harm_limit_fx = float_to_fix16( st->hNoiseEst->multi_harm_limit, Q9 ); - st->hNoiseEst->totalNoise_fx = float_to_fix16( st->hNoiseEst->totalNoise, Q8 ); - st->hNoiseEst->noise_char_fx = float_to_fix16( st->hNoiseEst->noise_char, Q11 ); - st->hNoiseEst->epsP_0_2_lp_fx = float_to_fix16( st->hNoiseEst->epsP_0_2_lp, Q12 ); - st->hNoiseEst->epsP_0_2_ad_lp_fx = float_to_fix16( st->hNoiseEst->epsP_0_2_ad_lp, Q12 ); - st->hNoiseEst->epsP_2_16_lp_fx = float_to_fix16( st->hNoiseEst->epsP_2_16_lp, Q12 ); - st->hNoiseEst->epsP_2_16_lp2_fx = float_to_fix16( st->hNoiseEst->epsP_2_16_lp2, Q12 ); - st->hNoiseEst->epsP_2_16_dlp_lp2_fx = float_to_fix16( st->hNoiseEst->epsP_2_16_dlp_lp2, Q12 ); - st->hNoiseEst->lt_tn_track_fx = float_to_fix16( st->hNoiseEst->lt_tn_track, Q15 ); - st->hNoiseEst->lt_tn_dist_fx = float_to_fix16( st->hNoiseEst->lt_tn_dist, Q8 ); - st->hNoiseEst->lt_haco_ev_fx = float_to_fix16( st->hNoiseEst->lt_haco_ev, Q15 ); - st->hNoiseEst->lt_Ellp_dist_fx = float_to_fix16( st->hNoiseEst->lt_Ellp_dist, Q8 ); st->hNoiseEst->sign_dyn_lp_fx = float_to_fix16( st->hNoiseEst->sign_dyn_lp, Q8 ); - st->hNoiseEst->act_pred_fx = float_to_fix16( st->hNoiseEst->act_pred, Q15 ); - st->hNoiseEst->lt_aEn_zero_fx = float_to_fix16( st->hNoiseEst->lt_aEn_zero, Q15 ); if ( lr_vad_enabled && st->idchan == 0 ) { for ( int j = 0; j < 2; j++ ) { - floatToFixed_arr16( hCPE->hFrontVad[j]->hNoiseEst->old_S, hCPE->hFrontVad[j]->hNoiseEst->old_S_fx, Q7, 128 ); - floatToFixed_arr16( hCPE->hFrontVad[j]->hNoiseEst->cor_map, hCPE->hFrontVad[j]->hNoiseEst->cor_map_fx, Q15, 128 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->Etot_lp, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->Etot_v_h2_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->Etot_v_h2, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->Etot_l_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->Etot_l_lp, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_st_est_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->Etot_st_est, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_sq_st_est_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->Etot_sq_st_est, Q2 ); - hCPE->hFrontVad[j]->hNoiseEst->multi_harm_limit_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->multi_harm_limit, Q9 ); - hCPE->hFrontVad[j]->hNoiseEst->totalNoise_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->totalNoise, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->noise_char_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->noise_char, Q11 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_lp, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_ad_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_ad_lp, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp2_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp2, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_dlp_lp2_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_dlp_lp2, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_tn_track_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->lt_tn_track, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_tn_dist_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->lt_tn_dist, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_haco_ev_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->lt_haco_ev, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_Ellp_dist_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->lt_Ellp_dist, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->sign_dyn_lp_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->sign_dyn_lp, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->act_pred_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->act_pred, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_aEn_zero_fx = float_to_fix16( hCPE->hFrontVad[j]->hNoiseEst->lt_aEn_zero, Q15 ); - - hCPE->hFrontVad[j]->lp_speech_fx = float_to_fix16( hCPE->hFrontVad[j]->lp_speech, Q8 ); - Etot_LR_fx[j] = float_to_fix16( Etot_LR[j], Q8 ); } } @@ -2571,57 +2519,18 @@ ivas_error pre_proc_front_ivas_fx( fixedToFloat_arr( st->hSpMusClas->past_log_enr_fx, st->hSpMusClas->past_log_enr, Q8, NB_BANDS_SPMUS ); - fixedToFloat_arr( st->hNoiseEst->old_S_fx, st->hNoiseEst->old_S, Q7, 128 ); - fixedToFloat_arr( st->hNoiseEst->cor_map_fx, st->hNoiseEst->cor_map, Q15, 128 ); - st->hNoiseEst->Etot_lp = fixedToFloat_16( st->hNoiseEst->Etot_lp_fx, Q8 ); st->hNoiseEst->Etot_v_h2 = fixedToFloat_16( st->hNoiseEst->Etot_v_h2_fx, Q8 ); st->hNoiseEst->Etot_l_lp = fixedToFloat_16( st->hNoiseEst->Etot_l_lp_fx, Q8 ); - st->hNoiseEst->multi_harm_limit = fixedToFloat_16( st->hNoiseEst->multi_harm_limit_fx, Q9 ); - st->hNoiseEst->totalNoise = fixedToFloat_16( st->hNoiseEst->totalNoise_fx, Q8 ); - st->hNoiseEst->noise_char = fixedToFloat_16( st->hNoiseEst->noise_char_fx, Q11 ); - st->hNoiseEst->epsP_0_2_lp = fixedToFloat_16( st->hNoiseEst->epsP_0_2_lp_fx, Q12 ); - st->hNoiseEst->epsP_0_2_ad_lp = fixedToFloat_16( st->hNoiseEst->epsP_0_2_ad_lp_fx, Q12 ); - st->hNoiseEst->epsP_2_16_lp = fixedToFloat_16( st->hNoiseEst->epsP_2_16_lp_fx, Q12 ); - st->hNoiseEst->epsP_2_16_lp2 = fixedToFloat_16( st->hNoiseEst->epsP_2_16_lp2_fx, Q12 ); - st->hNoiseEst->epsP_2_16_dlp_lp2 = fixedToFloat_16( st->hNoiseEst->epsP_2_16_dlp_lp2_fx, Q12 ); - st->hNoiseEst->lt_tn_track = fixedToFloat_16( st->hNoiseEst->lt_tn_track_fx, Q15 ); - st->hNoiseEst->lt_tn_dist = fixedToFloat_16( st->hNoiseEst->lt_tn_dist_fx, Q8 ); - st->hNoiseEst->lt_haco_ev = fixedToFloat_16( st->hNoiseEst->lt_haco_ev_fx, Q15 ); - st->hNoiseEst->lt_Ellp_dist = fixedToFloat_16( st->hNoiseEst->lt_Ellp_dist_fx, Q8 ); st->hNoiseEst->sign_dyn_lp = fixedToFloat_16( st->hNoiseEst->sign_dyn_lp_fx, Q8 ); - st->hNoiseEst->act_pred = fixedToFloat_16( st->hNoiseEst->act_pred_fx, Q15 ); - st->hNoiseEst->lt_aEn_zero = fixedToFloat_16( st->hNoiseEst->lt_aEn_zero_fx, Q15 ); - st->hNoiseEst->Etot_sq_st_est = fixedToFloat_16( st->hNoiseEst->Etot_sq_st_est_fx, Q2 ); - st->hNoiseEst->Etot_st_est = fixedToFloat_16( st->hNoiseEst->Etot_st_est_fx, Q8 ); - if ( lr_vad_enabled && st->idchan == 0 ) { for ( int j = 0; j < 2; j++ ) { - fixedToFloat_arr( hCPE->hFrontVad[j]->hNoiseEst->old_S_fx, hCPE->hFrontVad[j]->hNoiseEst->old_S, Q7, 128 ); - fixedToFloat_arr( hCPE->hFrontVad[j]->hNoiseEst->cor_map_fx, hCPE->hFrontVad[j]->hNoiseEst->cor_map, Q15, 128 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->Etot_lp_fx, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->Etot_v_h2 = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->Etot_v_h2_fx, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->Etot_l_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->Etot_l_lp_fx, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->multi_harm_limit = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->multi_harm_limit_fx, Q9 ); - hCPE->hFrontVad[j]->hNoiseEst->totalNoise = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->totalNoise_fx, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->noise_char = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->noise_char_fx, Q11 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_lp_fx, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_ad_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->epsP_0_2_ad_lp_fx, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp_fx, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp2 = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_lp2_fx, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_dlp_lp2 = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->epsP_2_16_dlp_lp2_fx, Q12 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_tn_track = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->lt_tn_track_fx, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_tn_dist = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->lt_tn_dist_fx, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_haco_ev = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->lt_haco_ev_fx, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_Ellp_dist = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->lt_Ellp_dist_fx, Q8 ); hCPE->hFrontVad[j]->hNoiseEst->sign_dyn_lp = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->sign_dyn_lp_fx, Q8 ); - hCPE->hFrontVad[j]->hNoiseEst->act_pred = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->act_pred_fx, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->lt_aEn_zero = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->lt_aEn_zero_fx, Q15 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_sq_st_est = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->Etot_sq_st_est_fx, Q2 ); - hCPE->hFrontVad[j]->hNoiseEst->Etot_st_est = fixedToFloat_16( hCPE->hFrontVad[j]->hNoiseEst->Etot_st_est_fx, Q8 ); } } @@ -2835,7 +2744,6 @@ ivas_error pre_proc_front_ivas_fx( Etot16_fx = extract_l( Etot_fx ); st->lp_speech_fx = float_to_fix16( st->lp_speech, 8 ); st->lp_noise_fx = float_to_fix16( st->lp_noise, 8 ); - st->hNoiseEst->totalNoise_fx = float_to_fix16( st->hNoiseEst->totalNoise, 8 ); st->hNoiseEst->Etot_last_fx = float_to_fix16( st->hNoiseEst->Etot_last, 8 ); #endif ivas_long_enr_fx( st, Etot16_fx, localVAD_HE_SAD, high_lpn_flag, NULL, 1, NULL, NULL ); @@ -2857,20 +2765,9 @@ ivas_error pre_proc_front_ivas_fx( // conv params from float to fix Etot_LR_fx[0] = float_to_fix16( Etot_LR[0], 8 ); Etot_LR_fx[1] = float_to_fix16( Etot_LR[1], 8 ); - hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx = float_to_fix16( hCPE->hFrontVad[0]->hNoiseEst->totalNoise, 8 ); - hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx = float_to_fix16( hCPE->hFrontVad[1]->hNoiseEst->totalNoise, 8 ); - hCPE->hFrontVad[0]->lp_speech_fx = float_to_fix16( hCPE->hFrontVad[0]->lp_speech, 8 ); - hCPE->hFrontVad[1]->lp_speech_fx = float_to_fix16( hCPE->hFrontVad[1]->lp_speech, 8 ); - hCPE->hFrontVad[0]->lp_noise_fx = float_to_fix16( hCPE->hFrontVad[0]->lp_noise, 8 ); - hCPE->hFrontVad[1]->lp_noise_fx = float_to_fix16( hCPE->hFrontVad[1]->lp_noise, 8 ); #endif ivas_long_enr_fx( st, -1, localVAD_HE_SAD, high_lpn_flag, hCPE->hFrontVad, CPE_CHANNELS, localVAD_HE_SAD_LR, Etot_LR_fx ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - // conv params from fix to float - hCPE->hFrontVad[0]->lp_speech = fix16_to_float( hCPE->hFrontVad[0]->lp_speech_fx, 8 ); - hCPE->hFrontVad[1]->lp_speech = fix16_to_float( hCPE->hFrontVad[1]->lp_speech_fx, 8 ); - hCPE->hFrontVad[0]->lp_noise = fix16_to_float( hCPE->hFrontVad[0]->lp_noise_fx, 8 ); - hCPE->hFrontVad[1]->lp_noise = fix16_to_float( hCPE->hFrontVad[1]->lp_noise_fx, 8 ); hCPE->hFrontVad[0]->hNoiseEst->Etot_last = fix16_to_float( hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, 8 ); hCPE->hFrontVad[1]->hNoiseEst->Etot_last = fix16_to_float( hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, 8 ); @@ -2962,6 +2859,37 @@ ivas_error pre_proc_front_ivas_fx( st->sba_br_sw_while_no_data = 1; } +/* these are for ivas_acelp_tcx20_switching_fx */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 lsp_mid_fx_1[M]; + Word32 res_cod_SNR_M_fx[STEREO_DFT_BAND_MAX]; + Word16 res_cod_SNR_M_fx_e[STEREO_DFT_BAND_MAX]; + Word16 tcx_mdct_window_fx[L_LOOK_16k]; + // Word16 stab_fac_fx; + float tmp = currFlatness * ONE_IN_Q7; + Word16 wsp_fx_temp[L_WSP]; + Word16 *wsp_fx_l; + non_staX16_fx = float_to_fix16( non_staX, Q8 ); + // currFlatness_fx = float_to_fix16_thrld( currFlatness, Q7 ); + if ( tmp > MAX_16 ) + { + currFlatness_fx = MAX_16; + } + else if ( tmp < MIN_16 ) + { + currFlatness_fx = MIN_16; + } + else + currFlatness_fx = (Word16) tmp; + stab_fac_fx = float_to_fix16( stab_fac, Q15 ); + if ( flag_16k_smc ) + floatToFixed_arr16( st->hTcxCfg->tcx_mdct_window_flt, tcx_mdct_window_fx, Q15, L_LOOK_16k ); + else + floatToFixed_arr16( st->hTcxCfg->tcx_mdct_window_flt, tcx_mdct_window_fx, Q15, L_LOOK_12k8 ); + floatToFixed_arr( pitch_fr, pitch_fr_fx, Q6, NB_SUBFR ); + floatToFixed_arr( voicing_fr, voicing_fr_fx, Q15, NB_SUBFR ); + floatToFixed_arrL( st->hTcxEnc->spectrum_long, st->hTcxEnc->spectrum_long_fx, Q15, N_MAX ); +#endif if ( flag_16k_smc ) { #ifdef IVAS_FLOAT_FIXED_CONVERSIONS @@ -2995,12 +2923,59 @@ ivas_error pre_proc_front_ivas_fx( fixedToFloat_arr( lsp_new_fx, lsp_new, Q15, M ); fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); #endif - +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 q_speech_enc; + floatToFixed_arr16( lsp_mid, lsp_mid_fx_1, Q15, M ); + q_speech_enc = s_min( Q_factor_arr( st->speech_enc_flt - 560, 2 * 560 ), Q_factor_arr( st->wspeech_enc_flt - 560, 2 * 560 ) ); + floatToFixed_arr( st->speech_enc_flt - 560, st->speech_enc - 560, q_speech_enc, 2 * 560 ); + floatToFixed_arr( st->wspeech_enc_flt - 560, st->wspeech_enc - 560, q_speech_enc, 2 * 560 ); +#endif + smc_dec = ivas_acelp_tcx20_switching_fx( st, st->speech_enc, q_speech_enc, st->wspeech_enc, non_staX16_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx_1, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, tcx_mdct_window_fx, flag_16k_smc ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < 7; i++ ) + { + res_cod_SNR_M[i] = me2f( res_cod_SNR_M_fx[i], res_cod_SNR_M_fx_e[i] ); + } + st->prevTempFlatness = fix16_to_float( st->prevTempFlatness_fx, Q7 ); +#endif +#else smc_dec = ivas_acelp_tcx20_switching( st, st->speech_enc_flt, st->wspeech_enc_flt, non_staX, pitch_fr, voicing_fr, currFlatness, lsp_mid, stab_fac, res_cod_SNR_M, flag_16k_smc ); +#endif } else { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS +#define ATT_SEG_LEN ( L_FRAME / ATT_NSEG ) + // Q_new = s_min(Q_factor_arr( inp_12k8, ATT_NSEG * ATT_SEG_LEN ), Q_factor_arr( st->Bin_E, 256 )) - 1; + Q_new = 0; /* Dynamic Q_new used above causes overflow issues */ + for ( int k = 0; k < ATT_NSEG * ATT_SEG_LEN; k++ ) + { + if ( fabs( inp_12k8[k] ) > 32768.0f ) + { + Q_new = -1; + break; + } + } + floatToFixed_arr16( lsp_mid, lsp_mid_fx_1, Q15, M ); + floatToFixed_arr( inp_12k8, inp_12k8_fx, Q_new, ATT_NSEG * ATT_SEG_LEN ); + floatToFixed_arr( wsp - L_WSP_MEM, wsp_fx_temp, Q_new, L_WSP_MEM ); + wsp_fx_l = wsp_fx_temp + L_WSP_MEM; + floatToFixed_arr( wsp, wsp_fx_l, Q_new, L_WSP - L_WSP_MEM ); +#endif + smc_dec = ivas_acelp_tcx20_switching_fx( st, inp_12k8_fx, Q_new, wsp_fx_l, non_staX16_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx_1, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, tcx_mdct_window_fx, flag_16k_smc ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->prevTempFlatness = fix16_to_float( st->prevTempFlatness_fx, Q7 ); + // st->prevTempFlatness = currFlatness; + for ( i = 0; i < 7; i++ ) + { + res_cod_SNR_M[i] = me2f( res_cod_SNR_M_fx[i], res_cod_SNR_M_fx_e[i] ); + } +#endif +#else smc_dec = ivas_acelp_tcx20_switching( st, inp_12k8, wsp, non_staX, pitch_fr, voicing_fr, currFlatness, lsp_mid, stab_fac, res_cod_SNR_M, flag_16k_smc ); +#endif } } /* Switch to ACELP for non-harmonic transient signals */ @@ -3008,14 +2983,6 @@ ivas_error pre_proc_front_ivas_fx( { #ifdef IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 Q_multi_harm_limit; - Word16 exp_multi_harm_limit = 0; - f2me_16( st->hNoiseEst->multi_harm_limit, &st->hNoiseEst->multi_harm_limit_fx, &exp_multi_harm_limit ); - Q_multi_harm_limit = 15 - exp_multi_harm_limit; - - Word16 Q_cor_map = Q_factor_arr( st->hNoiseEst->cor_map, L_FFT / 2 ); - floatToFixed_arr( st->hNoiseEst->cor_map, st->hNoiseEst->cor_map_fx, Q_cor_map, L_FFT / 2 ); - IF( EQ_16( element_mode, IVAS_SCE ) ) { Word16 q1 = Q_factor_arr( st->hTranDet->subblockEnergies.subblockNrg_flt, NSUBBLOCKS + MAX_TD_DELAY ); @@ -3045,7 +3012,7 @@ ivas_error pre_proc_front_ivas_fx( #endif IF( EQ_16( element_mode, IVAS_SCE ) ) { - if ( transient_analysis_ivas_fx( st->hTranDet, st->hNoiseEst->cor_map_fx, Q_cor_map, st->hNoiseEst->multi_harm_limit_fx, Q_multi_harm_limit ) ) + if ( transient_analysis_ivas_fx( st->hTranDet, st->hNoiseEst->cor_map_fx, Q15, st->hNoiseEst->multi_harm_limit_fx, Q9 ) ) { smc_dec = SPEECH; move16(); @@ -3056,7 +3023,7 @@ ivas_error pre_proc_front_ivas_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { test(); - if ( smc_dec != SPEECH && transient_analysis_ivas_fx( hCPE->hCoreCoder[i]->hTranDet, st->hNoiseEst->cor_map_fx, Q_cor_map, st->hNoiseEst->multi_harm_limit_fx, Q_multi_harm_limit ) ) + if ( smc_dec != SPEECH && transient_analysis_ivas_fx( hCPE->hCoreCoder[i]->hTranDet, st->hNoiseEst->cor_map_fx, Q15, st->hNoiseEst->multi_harm_limit_fx, Q9 ) ) { smc_dec = SPEECH; /* overwrite initial music decision, initial SPEECH_MUSIC never changed */ move16(); @@ -3065,7 +3032,6 @@ ivas_error pre_proc_front_ivas_fx( } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( st->hNoiseEst->cor_map_fx, st->hNoiseEst->cor_map, Q_cor_map, L_FFT / 2 ); IF( EQ_16( element_mode, IVAS_SCE ) ) { fixedToFloat_arrL( st->hTranDet->subblockEnergies.subblockNrg, st->hTranDet->subblockEnergies.subblockNrg_flt, ( 31 - st->hTranDet->subblockEnergies.subblockNrg_e ), NSUBBLOCKS + MAX_TD_DELAY ); diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index a97541343..bb0125e11 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -38,13 +38,12 @@ #include "prot_fx_enc.h" #include "ivas_prot.h" #include "wmc_auto.h" - +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * ivas_corecoder_enc_reconfig() * * Allocate, initialize, and configure SCE/CPE/MCT handles in case of bitrate switching *-------------------------------------------------------------------*/ - #ifndef IVAS_FLOAT_FIXED ivas_error ivas_corecoder_enc_reconfig( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ @@ -417,11 +416,8 @@ ivas_error ivas_corecoder_enc_reconfig( st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal * FRAMES_PER_SEC, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); -#ifdef IVAS_FLOAT_FIXED + IF( ( error = IGF_Reconfig_fx( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -478,11 +474,7 @@ ivas_error ivas_corecoder_enc_reconfig( st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); -#ifdef IVAS_FLOAT_FIXED - IF( ( error = IGF_Reconfig_fx( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) -#else if ( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -491,11 +483,7 @@ ivas_error ivas_corecoder_enc_reconfig( st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode = MCT_CHAN_MODE_REGULAR; } -#ifndef IVAS_FLOAT_FIXED initMdctStereoEncData( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct, hEncoderConfig->ivas_format, st_ivas->hCPE[st_ivas->nCPE - 1]->element_mode, st_ivas->hCPE[st_ivas->nCPE - 1]->element_brate, hEncoderConfig->max_bwidth, 0, NULL, 1 ); -#else - initMdctStereoEncData_fx( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct, hEncoderConfig->ivas_format, st_ivas->hCPE[st_ivas->nCPE - 1]->element_mode, st_ivas->hCPE[st_ivas->nCPE - 1]->element_brate, hEncoderConfig->max_bwidth, 0, NULL, 1 ); -#endif st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->isSBAStereoMode = ( ( hEncoderConfig->ivas_format == SBA_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); } } @@ -504,7 +492,7 @@ ivas_error ivas_corecoder_enc_reconfig( } #else /* Some float operations are still pending */ -ivas_error ivas_corecoder_enc_reconfig( +ivas_error ivas_corecoder_enc_reconfig_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 nSCE_old, /* i : number of SCEs in previous frame */ const Word16 nCPE_old, /* i : number of CPEs in previous frame */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 5da4e6484..91aaf3cc1 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -251,7 +251,6 @@ ivas_error ivas_cpe_enc( if ( sts[0]->hFdCngEnc != NULL ) { sts[0]->last_totalNoise_fx = (Word16) float_to_fix16( sts[0]->last_totalNoise, Q8 ); - sts[0]->hNoiseEst->totalNoise_fx = (Word16) float_to_fix16( sts[0]->hNoiseEst->totalNoise, Q8 ); for ( int i = 0; i < TOTALNOISE_HIST_SIZE - 1; i++ ) { sts[0]->totalNoise_increase_hist_fx[n] = (Word16) float_to_fix16( sts[0]->totalNoise_increase_hist[n], Q8 ); @@ -270,18 +269,11 @@ ivas_error ivas_cpe_enc( hCPE->hFrontVad[n]->mem_preemph_fx = (Word16) floatToFixed( hCPE->hFrontVad[n]->mem_preemph, Q_inp - 1 ); Q_buffer[n] = Q_factor_arr( hCPE->hFrontVad[n]->buffer_12k8 + L_FFT, L_FFT / 2 ); floatToFixed_arr( hCPE->hFrontVad[n]->buffer_12k8, hCPE->hFrontVad[n]->buffer_12k8_fx, Q_buffer[n], 384 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_h_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_h * 16777216.0 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_l_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_l * 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_l_lp_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_l_lp * 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_last_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_last * 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2 * 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_lp_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_lp * 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp_32fx = (Word32) ( hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp * 16777216.0 ); - hCPE->hFrontVad[n]->hNoiseEst->totalNoise_fx = (Word16) ( hCPE->hFrontVad[n]->hNoiseEst->totalNoise * ( 256.0 ) ); - - hCPE->hFrontVad[n]->lp_noise_fx = (Word16) floatToFixed( hCPE->hFrontVad[n]->lp_noise, Q8 ); - hCPE->hFrontVad[n]->lp_speech_fx = (Word16) floatToFixed( hCPE->hFrontVad[n]->lp_speech, Q8 ); - floatToFixed_arrL( hCPE->hFrontVad[n]->hNoiseEst->bckr, hCPE->hFrontVad[n]->hNoiseEst->bckr_fx, Q_new_old + QSCALE, 20 ); floatToFixed_arrL( hCPE->hFrontVad[n]->hNoiseEst->enrO, hCPE->hFrontVad[n]->hNoiseEst->enrO_fx, Q_new_old + QSCALE, 20 ); } @@ -298,7 +290,6 @@ ivas_error ivas_cpe_enc( if ( sts[0]->hFdCngEnc != NULL ) { sts[0]->last_totalNoise = fix16_to_float( sts[0]->last_totalNoise_fx, Q8 ); - sts[0]->hNoiseEst->totalNoise = fix16_to_float( sts[0]->hNoiseEst->totalNoise_fx, Q8 ); for ( int i = 0; i < TOTALNOISE_HIST_SIZE - 1; i++ ) { sts[0]->totalNoise_increase_hist[n] = fix16_to_float( sts[0]->totalNoise_increase_hist_fx[n], Q8 ); @@ -321,37 +312,12 @@ ivas_error ivas_cpe_enc( Etot_LR[n] = fixedToFloat( Etot_LR_fx[n], Q8 ); fixedToFloat_arrL( hCPE->hFrontVad[n]->hNoiseEst->bckr_fx, hCPE->hFrontVad[n]->hNoiseEst->bckr, Q_new_old + QSCALE, 20 ); fixedToFloat_arrL( hCPE->hFrontVad[n]->hNoiseEst->enrO_fx, hCPE->hFrontVad[n]->hNoiseEst->enrO, Q_new_old + QSCALE, 20 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_h = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_h_32fx / 16777216.0 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_l = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_l_32fx / 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_l_lp = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_l_lp_32fx / 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_last = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_last_32fx / 16777216.0 ); // hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2 = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2_32fx / 16777216.0 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_lp = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_lp_32fx / 16777216.0 ); - // hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp = (float) ( hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp_32fx / 16777216.0 ); - hCPE->hFrontVad[n]->lp_noise = fixedToFloat( hCPE->hFrontVad[n]->lp_noise_fx, Q8 ); - hCPE->hFrontVad[n]->lp_speech = fixedToFloat( hCPE->hFrontVad[n]->lp_speech_fx, Q8 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2 = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2_fx / ( 256.0 ) ); - hCPE->hFrontVad[n]->hNoiseEst->totalNoise = (float) ( (float) hCPE->hFrontVad[n]->hNoiseEst->totalNoise_fx / ( 256.0 ) ); hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp = (float) ( hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp_fx / ( 256.0 ) ); - fixedToFloat_arr( hCPE->hFrontVad[n]->hNoiseEst->old_S_fx, hCPE->hFrontVad[n]->hNoiseEst->old_S, Q7, 128 ); - fixedToFloat_arr( hCPE->hFrontVad[n]->hNoiseEst->cor_map_fx, hCPE->hFrontVad[n]->hNoiseEst->cor_map, Q15, 128 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_st_est = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->Etot_st_est_fx, Q8 ); - hCPE->hFrontVad[n]->hNoiseEst->Etot_sq_st_est = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->Etot_sq_st_est_fx, Q2 ); - hCPE->hFrontVad[n]->hNoiseEst->multi_harm_limit = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->multi_harm_limit_fx, Q9 ); - hCPE->hFrontVad[n]->hNoiseEst->noise_char = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->noise_char_fx, Q11 ); - - hCPE->hFrontVad[n]->hNoiseEst->noise_char = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->noise_char_fx, Q11 ); - hCPE->hFrontVad[n]->hNoiseEst->epsP_0_2_lp = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->epsP_0_2_lp_fx, Q12 ); - hCPE->hFrontVad[n]->hNoiseEst->epsP_0_2_ad_lp = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->epsP_0_2_ad_lp_fx, Q12 ); - hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_lp = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_lp_fx, Q12 ); - hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_lp2 = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_lp2_fx, Q12 ); - hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_dlp_lp2 = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->epsP_2_16_dlp_lp2_fx, Q12 ); - hCPE->hFrontVad[n]->hNoiseEst->lt_tn_track = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->lt_tn_track_fx, Q15 ); - hCPE->hFrontVad[n]->hNoiseEst->lt_tn_dist = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->lt_tn_dist_fx, Q8 ); - hCPE->hFrontVad[n]->hNoiseEst->lt_haco_ev = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->lt_haco_ev_fx, Q15 ); - hCPE->hFrontVad[n]->hNoiseEst->lt_Ellp_dist = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->lt_Ellp_dist_fx, Q8 ); - hCPE->hFrontVad[n]->hNoiseEst->act_pred = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->act_pred_fx, Q15 ); - hCPE->hFrontVad[n]->hNoiseEst->lt_aEn_zero = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->lt_aEn_zero_fx, Q15 ); if ( front_create_flag ) { fixedToFloat_arrL( hCPE->hFrontVad[n]->hNoiseEst->fr_bands1_fx, hCPE->hFrontVad[n]->hNoiseEst->fr_bands1, Q17, NB_BANDS ); @@ -359,8 +325,6 @@ ivas_error ivas_cpe_enc( fixedToFloat_arrL( hCPE->hFrontVad[n]->hNoiseEst->ave_enr_fx, hCPE->hFrontVad[n]->hNoiseEst->ave_enr, Q8, NB_BANDS ); fixedToFloat_arrL( hCPE->hFrontVad[n]->hNoiseEst->ave_enr2_fx, hCPE->hFrontVad[n]->hNoiseEst->ave_enr2, Q8, NB_BANDS ); } - // floatToFixed_arr( hCPE->hFrontVad[n]->mem_decim, hCPE->hFrontVad[n]->mem_decim_fx, Q_inp, 90 ); - // hCPE->hFrontVad[n]->mem_preemph_fx = (Word16) floatToFixed( hCPE->hFrontVad[n]->mem_preemph, Q_inp ); } // fixedToFloat_arrL( band_energies_fx, band_energies, Q_new + QSCALE + 2, 40 ); fixedToFloat_arrL( &band_energies_LR_fx[0], &band_energies_LR[0], Q_buffer[1] + QSCALE + 2 - band_ener_guardbits, 40 ); @@ -730,7 +694,6 @@ ivas_error ivas_cpe_enc( #endif // MSAN_FIX } floatToFixed_arrL( hCPE->hStereoDft->hItd->itd, hCPE->hStereoDft->hItd->itd_fx, 16, STEREO_DFT_ENC_DFT_NB ); - floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, 15, SSC_MAX_NFEA ); #ifndef MSAN_FIX hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); #endif // !MSAN_FIX @@ -804,7 +767,6 @@ ivas_error ivas_cpe_enc( sts[0]->ee_old_fx = floatToFixed( sts[0]->ee_old, Q6 ); sts[1]->ee_old_fx = floatToFixed( sts[1]->ee_old, Q6 ); - floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, Q15, 58 ); IF( hCPE->hStereoTD->tdm_last_SM_flag ) { floatToFixed_arr16( sts[0]->input, sts[0]->input_fx, 0, input_frame ); @@ -822,8 +784,6 @@ ivas_error ivas_cpe_enc( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS sts[0]->hNoiseEst->Etot_last = fix16_to_float( sts[0]->hNoiseEst->Etot_last_fx, Q8 ); sts[1]->hNoiseEst->Etot_last = fix16_to_float( sts[1]->hNoiseEst->Etot_last_fx, Q8 ); - - fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, Q15, 58 ); #endif /* Compute the downmix signal based on the ratio index */ @@ -881,7 +841,6 @@ ivas_error ivas_cpe_enc( } floatToFixed_arrL( hCPE->hStereoMdct->hItd->itd, hCPE->hStereoMdct->hItd->itd_fx, 16, STEREO_DFT_ENC_DFT_NB ); floatToFixed_arrL( hCPE->hStereoMdct->hItd->deltaItd, hCPE->hStereoMdct->hItd->deltaItd_fx, 16, STEREO_DFT_ENC_DFT_NB ); - floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, 15, SSC_MAX_NFEA ); floatToFixed_arr( hCPE->hCoreCoder[0]->voicing, hCPE->hCoreCoder[0]->voicing_fx, 15, 3 ); if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { @@ -894,7 +853,6 @@ ivas_error ivas_cpe_enc( if ( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { fixedToFloat_arrL( hCPE->hStereoMdct->hItd->itd_fx, hCPE->hStereoMdct->hItd->itd, 16, STEREO_DFT_ENC_DFT_NB ); - fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, 15, SSC_MAX_NFEA ); FOR( int16_t i = 0; i < CPE_CHANNELS; i++ ) { fixedToFloat_arr( &hCPE->input_mem_fx[i][0], &hCPE->input_mem[i][0], hCPE->q_input_mem[i], NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ); @@ -968,7 +926,6 @@ ivas_error ivas_cpe_enc( me2f_buf( hCPE->hStereoDft->DFT_fx[i], hCPE->hStereoDft->DFT_fx_e[i], hCPE->hStereoDft->DFT[i], STEREO_DFT_N_MAX_ENC ); } fixedToFloat_arrL( hCPE->hStereoDft->hItd->itd_fx, hCPE->hStereoDft->hItd->itd, 16, STEREO_DFT_ENC_DFT_NB ); - fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, 15, SSC_MAX_NFEA ); /*local fix2flt*/ diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index c08e64da0..1d327f291 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -308,26 +308,21 @@ ivas_error ivas_dirac_enc_reconfigure( * DirAC main configuration *-----------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED IF( ( error = ivas_dirac_config_fx( (void *) st_ivas, ENC ) ) != IVAS_ERR_OK ) { return error; } -#else - if ( ( error = ivas_dirac_config( (void *) st_ivas, ENC ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif - if ( st_ivas->hQMetaData->useLowerRes ) + IF( st_ivas->hQMetaData->useLowerRes ) { hDirAC->block_grouping[0] = 0; + move16(); hDirAC->block_grouping[1] = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); } - else + ELSE { - mvs2s( DirAC_block_grouping_5ms_MDFT, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); + MVR2R_WORD16( DirAC_block_grouping_5ms_MDFT, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); } return error; @@ -934,8 +929,68 @@ void computeReferencePower_enc( return; } - - +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * computeReferencePower_enc() + * + * + *-------------------------------------------------------------------------*/ +void computeReferencePower_enc_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ + Word32 *reference_power, /* o : Estimated power */ + const Word16 enc_param_start_band, /* i : first band to process */ + const Word16 num_freq_bands, /* i : Number of frequency bands */ + const IVAS_FORMAT ivas_format, /* i : ivas_format */ + Word16 ref_power_w, /* i : use 0 if hodirac is enabled */ + const Word16 nchan_ana /* i : number of analysis channels */ +) +{ + Word16 brange[2]; + Word16 ch_idx, i, j; + Word32 reference_power_W[DIRAC_MAX_NBANDS]; + FOR( i = 0; i < num_freq_bands; i++ ) + { + brange[0] = band_grouping[i + enc_param_start_band]; + move16(); + brange[1] = band_grouping[i + enc_param_start_band + 1]; + move16(); + reference_power[i] = 0; + move32(); + reference_power_W[i] = 0; + move32(); + FOR( j = brange[0]; j < brange[1]; j++ ) + { + reference_power_W[i] = L_add( reference_power_W[i], L_add( Mpy_32_32( Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ), Mpy_32_32( Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ) ) ); + move32(); + } + reference_power[i] = L_add( reference_power[i], reference_power_W[i] ); // 2*inp_q -31 + move32(); + FOR( ch_idx = 1; ch_idx < nchan_ana; ch_idx++ ) + { + /* abs()^2 */ + FOR( j = brange[0]; j < brange[1]; j++ ) + { + reference_power[i] = L_add( reference_power[i], L_add( Mpy_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Mpy_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ) ) ); + move32(); + } + // 2*inp_q - 31 + } + } + v_multc_fixed( reference_power, ONE_IN_Q30, reference_power, num_freq_bands ); + test(); + IF( EQ_16( ivas_format, SBA_FORMAT ) && EQ_16( ref_power_w, 1 ) ) + { + FOR( i = 0; i < num_freq_bands; i++ ) + { + reference_power[i] = max( reference_power[i], reference_power_W[i] ); + move32(); + } + } + return; +} +#endif /*------------------------------------------------------------------------- * ivas_dirac_param_est_enc() * @@ -1634,3 +1689,117 @@ void computeDiffuseness_mdft( return; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * computeDiffuseness_mdft() + * + * + *------------------------------------------------------------------------*/ +void computeDiffuseness_mdft_fx( + Word32 **buffer_intensity[DIRAC_NUM_DIMS], + const Word32 *buffer_energy, + const Word16 num_freq_bands, + const UWord16 no_col_avg_diff, + Word32 *diffuseness, + Word16 *q_factor_intensity, + Word16 *q_factor_energy, + Word16 *q_diffuseness /*Ouput Q*/ +) +{ + Word32 intensity_slow[DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS]; + Word16 intensity_slow_e[DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS]; + Word32 intensity_slow_abs[MASA_FREQUENCY_BANDS]; + Word16 intensity_slow_abs_e[MASA_FREQUENCY_BANDS]; + Word32 energy_slow[MASA_FREQUENCY_BANDS]; + Word16 energy_slow_e[MASA_FREQUENCY_BANDS]; + Word16 i, j, k; + Word32 tmp; + Word32 *p_tmp; + const Word32 *p_tmp_c; + Word16 *p_tmp_e, tmp_q; + + /* Compute Intensity slow and energy slow buffer_intensity and buffer_energy */ + + set_zero_fx( intensity_slow, i_mult( DIRAC_NUM_DIMS, MASA_FREQUENCY_BANDS ) ); + set16_fx( intensity_slow_e, 0, i_mult( DIRAC_NUM_DIMS, MASA_FREQUENCY_BANDS ) ); + set_zero_fx( intensity_slow_abs, MASA_FREQUENCY_BANDS ); + set16_fx( intensity_slow_abs_e, 0, no_col_avg_diff ); + set_zero_fx( energy_slow, MASA_FREQUENCY_BANDS ); + set16_fx( energy_slow_e, 0, no_col_avg_diff ); + + FOR( i = 0; i < no_col_avg_diff; ++i ) + { + /* Energy slow */ + p_tmp_c = buffer_energy + i_mult( i, num_freq_bands ); + tmp_q = q_factor_energy[i]; + move16(); + + FOR( k = 0; k < num_freq_bands; k++ ) + { + energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], p_tmp_c[k], sub( 31, tmp_q ), &energy_slow_e[k] ); + move32(); + } + + /* Intensity slow */ + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + FOR( k = 0; k < num_freq_bands; k++ ) + { + intensity_slow[j * num_freq_bands + k] = BASOP_Util_Add_Mant32Exp( intensity_slow[j * num_freq_bands + k], intensity_slow_e[j * num_freq_bands + k], p_tmp[k], sub( 31, q_factor_intensity[i] ), &intensity_slow_e[j * num_freq_bands + k] ); + move32(); + } + } + } + + /* intensity_slow.^2 + intensity_slow_abs*/ + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = intensity_slow + i_mult( j, num_freq_bands ); + p_tmp_e = intensity_slow_e + i_mult( j, num_freq_bands ); + + FOR( k = 0; k < num_freq_bands; k++ ) + { + p_tmp[k] = Mpy_32_32( p_tmp[k], p_tmp[k] ); + move32(); + tmp_q = sub( shl( sub( 31, p_tmp_e[k] ), 1 ), 31 ); + intensity_slow_abs[k] = BASOP_Util_Add_Mant32Exp( intensity_slow_abs[k], intensity_slow_abs_e[k], p_tmp[k], sub( 31, tmp_q ), &intensity_slow_abs_e[k] ); + move32(); + } + } + + /* Compute Diffuseness */ + p_tmp = intensity_slow_abs; + tmp_q = 0; + move16(); + FOR( i = 0; i < num_freq_bands; ++i ) + { + tmp = Sqrt32( p_tmp[i], &intensity_slow_abs_e[i] ); + + tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp, L_add( energy_slow[i], EPSILLON_FX ), &tmp_q ) ); + tmp_q = add( tmp_q, sub( intensity_slow_abs_e[i], energy_slow_e[i] ) ); + tmp = L_shl_sat( tmp, tmp_q ); + tmp = L_sub( ONE_IN_Q31, tmp ); + diffuseness[i] = tmp; + move32(); + + IF( LT_32( tmp, ONE_IN_Q31 ) ) + { + IF( tmp < 0 ) + { + diffuseness[i] = 0; + move32(); + } + } + ELSE + { + diffuseness[i] = ONE_IN_Q31; + move32(); + } + } + *q_diffuseness = Q31; + move16(); + + return; +} +#endif diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 0eda6be53..2e966212c 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -1192,9 +1192,40 @@ ivas_error ivas_enc( { hMetaData = st_ivas->hCPE[0]->hMetaData; /* Metadata is always with CPE in the case of separated channel */ } - +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 q_data = Q8; + for ( i = 0; i < nchan_inp; i++ ) + { + floatToFixed_arrL32( data_f[i], data_fx[i], q_data, input_frame ); + } +#endif + ivas_mcmasa_enc_fx( st_ivas->hMcMasa, st_ivas->hQMetaData, st_ivas->hMasa, data_fx, input_frame, st_ivas->nchan_transport, nchan_inp, q_data ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + st_ivas->hMasa->data.lfeToTotalEnergyRatio[i] = st_ivas->hMasa->data.lfeToTotalEnergyRatio_fx[i] / (float) ( 1 << ( Q31 - st_ivas->hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); + } + for ( i = 0; i < nchan_inp; i++ ) + { + fixedToFloat_arrL( data_fx[i], data_f[i], q_data, input_frame ); + } + Word32 ii, jj; + Word16 nBands = st_ivas->hMcMasa->nbands; + Word16 nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES; + FOR( ii = 0; ii < nBands; ii++ ) + { + FOR( jj = 0; jj < nBlocks; jj++ ) + { + st_ivas->hQMetaData->q_direction[0].band_data[ii].azimuth[jj] = fixedToFloat( st_ivas->hQMetaData->q_direction[0].band_data[ii].azimuth_fx[jj], Q22 ); + st_ivas->hQMetaData->q_direction[0].band_data[ii].elevation[jj] = fixedToFloat( st_ivas->hQMetaData->q_direction[0].band_data[ii].elevation_fx[jj], Q22 ); + st_ivas->hQMetaData->q_direction[0].band_data[ii].energy_ratio[jj] = fixedToFloat( st_ivas->hQMetaData->q_direction[0].band_data[ii].energy_ratio_fx[jj], Q31 ); + } + } +#endif +#else ivas_mcmasa_enc( st_ivas->hMcMasa, st_ivas->hQMetaData, st_ivas->hMasa, data_f, input_frame, st_ivas->nchan_transport, nchan_inp ); - +#endif if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, 0, -1, ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ) != IVAS_ERR_OK ) { diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 27a4fd577..34eab69e8 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -391,29 +391,15 @@ ivas_error front_vad_fx( /* Move previous frame 12k8 signal */ MVR2R_WORD16( hFrontVad->buffer_12k8_fx + L_FFT, hFrontVad->buffer_12k8_fx, L_FFT / 2 ); -#if 1 - /* Resample to 12k8 */ modify_Fs_fx( sts[n]->input_fx, input_frame, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2, INT_FS_12k8, hFrontVad->mem_decim_fx, ( sts[0]->max_bwidth == NB ), &Qband, &mem_decim_size ); -#else - modify_Fs( sts[n]->input, input_frame, sts[0]->input_Fs, hFrontVad->buffer_12k8 + L_FFT / 2, INT_FS_12k8, hFrontVad->mem_decim, ( sts[0]->max_bwidth == NB ) ); - -#endif -#if 0 - /* Preemphasis */ - preemph( hFrontVad->buffer_12k8 + L_FFT / 2, PREEMPH_FAC_FLT, L_FRAME, &hFrontVad->mem_preemph ); -#else /* Preemphasis */ hFrontVad->mem_preemph_fx = shl( hFrontVad->mem_preemph_fx, -1 - Qband ); PREEMPH_FX( hFrontVad->buffer_12k8_fx + L_FFT / 2, PREEMPH_FAC, L_FRAME, &hFrontVad->mem_preemph_fx ); -#endif -#if 0 - analy_sp( IVAS_CPE_TD, hCPE, sts[0]->input_Fs, hFrontVad->buffer_12k8 + L_FFT / 2 - 3 * ( L_SUBFR / 2 ), Bin_E, Bin_E_old, fr_bands[n], lf_E[n], &Etot_LR[n], sts[0]->min_band, sts[0]->max_band, band_energies, PS, fft_buffLR ); -#else Word16 Scale_fac[2]; Q_new = add( sub( Q_inp, Qband ), Q_add ); Scale_sig( hFrontVad->buffer_12k8_fx, L_FFT / 2, Q_new - Q_buffer[n] ); @@ -424,31 +410,22 @@ ivas_error front_vad_fx( Le_min_scaled = L_shl( Le_min_scaled, 2 ); ivas_analy_sp_fx( IVAS_CPE_TD, hCPE, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2 - 3 * ( L_SUBFR / 2 ), Q_new, fr_bands_fx[n], lf_E_fx[n], &Etot_LR_fx[n], sts[0]->min_band, sts[0]->max_band, Le_min_scaled, Scale_fac, Bin_E_fx, Bin_E_old_fx, PS_fx, lgBin_E_fx, band_energies_fx, fft_buffLR_fx ); - -#endif - /* add up energies for later calculating average of channel energies */ // Scale_sig32( &band_energies_LR_fx[0], ( Q_new + QSCALE + 2 ) - ( Q_new_old + QSCALE + 2 - band_ener_guardbits ), 40 ); Q_new_old = Q_new; v_add_fixed( &band_energies_fx[0], &band_energies_LR_fx[0], &band_energies_LR_fx[0], 2 * NB_BANDS, band_ener_guardbits ); -#if 0 - noise_est_pre( Etot_LR[n], hFrontVads[0]->ini_frame, hFrontVad->hNoiseEst, 0, 0, 0 ); -#else + Word32 Etot_fx = L_deposit_h( Etot_LR_fx[n] ); noise_est_pre_32fx( Etot_fx, hFrontVads[0]->ini_frame, hFrontVad->hNoiseEst, 0, 0, 0 ); -#endif /* wb_vad */ -#if 0 - hFrontVad->hVAD->vad_flag = wb_vad( sts[n], fr_bands[n], &dummy, &dummy, &dummy, &snr_sum_he, &localVAD_HE_SAD[n], &dummy, hFrontVad->hVAD, hFrontVad->hNoiseEst, hFrontVad->lp_speech, hFrontVad->lp_noise ); -#else Scale_sig32( hFrontVads[n]->hNoiseEst->bckr_fx, Q_new + QSCALE - ( Q_new_old + QSCALE ), 20 ); Scale_sig32( hFrontVads[n]->hNoiseEst->enrO_fx, Q_new + QSCALE - ( Q_new_old + QSCALE ), 20 ); hFrontVad->hNoiseEst->sign_dyn_lp_fx = extract_h( hFrontVad->hNoiseEst->sign_dyn_lp_32fx ); hFrontVad->hNoiseEst->Etot_v_h2_fx = extract_h( hFrontVad->hNoiseEst->Etot_v_h2_32fx ); hFrontVad->hVAD->vad_flag = wb_vad_ivas_fx( sts[n], fr_bands_fx[n], &dummy, &dummy, &dummy, &snr_sum_he_fx, &localVAD_HE_SAD[n], &dummy_short, Q_new, hFrontVad->hVAD, hFrontVad->hNoiseEst, hFrontVad->lp_speech_fx, hFrontVad->lp_noise_fx ); -#endif + test(); test(); if ( n == 0 && GT_16( n_chan, 1 ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) @@ -456,13 +433,9 @@ ivas_error front_vad_fx( sts[1]->last_coder_type = sts[0]->last_coder_type; move16(); } -#if 0 - /* DTX hangover addition */ - vad_flag_dtx[n] = dtx_hangover_addition( sts[n], hFrontVad->hVAD->vad_flag, hFrontVad->lp_speech - hFrontVad->lp_noise, 0 /* <- no cldfb addition */, &vad_hover_flag[n], hFrontVad->hVAD, hFrontVad->hNoiseEst, &hFrontVads[n]->rem_dtx_ho ); -#else vad_flag_dtx[n] = ivas_dtx_hangover_addition_fx( sts[n], hFrontVad->hVAD->vad_flag, hFrontVad->lp_speech_fx - hFrontVad->lp_noise_fx, 0 /* <- no cldfb addition */, &vad_hover_flag[n], hFrontVad->hVAD, hFrontVad->hNoiseEst, &hFrontVads[n]->rem_dtx_ho ); move16(); -#endif + if ( EQ_16( n_chan, 1 ) ) { sts[n]->vad_flag = hFrontVad->hVAD->vad_flag; @@ -473,24 +446,14 @@ ivas_error front_vad_fx( IF( EQ_16( n_chan, CPE_CHANNELS ) ) { /* get average channel energies, adding up was already done, so only need to scale by number of channels */ -#if 0 - v_multc( &band_energies_LR[0], 0.5f, &band_energies_LR[0], 2 * NB_BANDS ); -#else - v_multc_fixed( &band_energies_LR_fx[0], ONE_IN_Q30, &band_energies_LR_fx[0], 2 * NB_BANDS ); -#endif /* Logical OR between L and R decisions */ vad_flag_dtx[0] = vad_flag_dtx[0] || vad_flag_dtx[1]; } IF( sts[0]->hFdCngEnc != NULL ) { -#if 0 - resetFdCngEnc( sts[0] ); -#else resetFdCngEnc_fx( sts[0] ); - -#endif } test(); /* Part of DTX to decide if SID/NO_DATA */ @@ -558,21 +521,22 @@ ivas_error front_vad_create( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + noise_est_init_ivas_fx( hFrontVad->hNoiseEst ); +#else noise_est_init( hFrontVad->hNoiseEst ); - +#endif if ( ( hFrontVad->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); } - hFrontVad->lp_speech = 45.0f; /* Initialize the long-term active speech level in dB */ - hFrontVad->lp_noise = 0.0f; /* Initialize the long-term noise level in dB */ set_f( hFrontVad->mem_decim, 0, 2 * L_FILT_MAX ); set_f( hFrontVad->buffer_12k8, 0, 3 * L_FRAME / 2 ); #ifdef IVAS_FLOAT_FIXED wb_vad_init_ivas_fx( hFrontVad->hVAD ); - hFrontVad->lp_speech_fx = 23040; /* Initialize the long-term active speech level in dB */ + hFrontVad->lp_speech_fx = 11520; /* Initialize the long-term active speech level in dB */ hFrontVad->lp_noise_fx = 0; /* Initialize the long-term noise level in dB */ 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 ) ) ); @@ -915,16 +879,11 @@ ivas_error front_vad_spar( hFrontVad->mem_preemph_fx = (Word16) floatToFixed( hFrontVad->mem_preemph, Q_inp - 1 ); Word16 Q_buffer = Q_factor_arr( hFrontVad->buffer_12k8 + L_FFT, L_FFT / 2 ); floatToFixed_arr( hFrontVad->buffer_12k8, hFrontVad->buffer_12k8_fx, Q_buffer, 384 ); - hFrontVad->hNoiseEst->Etot_h_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_h * 16777216.0 ); - hFrontVad->hNoiseEst->Etot_l_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_l * 16777216.0 ); hFrontVad->hNoiseEst->Etot_l_lp_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_l_lp * 16777216.0 ); hFrontVad->hNoiseEst->Etot_last_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_last * 16777216.0 ); hFrontVad->hNoiseEst->Etot_v_h2_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_v_h2 * 16777216.0 ); hFrontVad->hNoiseEst->Etot_lp_32fx = (Word32) ( hFrontVad->hNoiseEst->Etot_lp * 16777216.0 ); hFrontVad->hNoiseEst->sign_dyn_lp_32fx = (Word32) ( hFrontVad->hNoiseEst->sign_dyn_lp * 16777216.0 ); - - hFrontVad->lp_noise_fx = (Word16) floatToFixed( hFrontVad->lp_noise, Q8 ); - hFrontVad->lp_speech_fx = (Word16) floatToFixed( hFrontVad->lp_speech, Q8 ); st->lp_speech_fx = (Word16) floatToFixed( st->lp_speech, Q8 ); st->lp_noise_fx = (Word16) floatToFixed( st->lp_noise, Q8 ); floatToFixed_arrL( hFrontVad->hNoiseEst->bckr, hFrontVad->hNoiseEst->bckr_fx, Q_new_old + QSCALE + 2, 20 ); @@ -949,9 +908,6 @@ ivas_error front_vad_spar( } fixedToFloat_arrL( PS_fx, PS, Q_buffer + QSCALE, 128 ); Etot[0] = fixedToFloat( Etot_fx[0], Q8 ); - - hFrontVad->hNoiseEst->Etot_h = (float) ( hFrontVad->hNoiseEst->Etot_h_32fx / 16777216.0 ); - hFrontVad->hNoiseEst->Etot_l = (float) ( hFrontVad->hNoiseEst->Etot_l_32fx / 16777216.0 ); hFrontVad->hNoiseEst->Etot_l_lp = (float) ( hFrontVad->hNoiseEst->Etot_l_lp_32fx / 16777216.0 ); hFrontVad->hNoiseEst->Etot_last = (float) ( hFrontVad->hNoiseEst->Etot_last_32fx / 16777216.0 ); // hFrontVad->hNoiseEst->Etot_v_h2 = (float) ( hFrontVad->hNoiseEst->Etot_v_h2_32fx / 16777216.0 ); @@ -973,7 +929,6 @@ ivas_error front_vad_spar( #ifndef MSAN_FIX floatToFixed_arrL( tmpE, tmpE_fx, Q_bands + QSCALE, NB_BANDS ); #endif - 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 ); @@ -989,7 +944,6 @@ ivas_error front_vad_spar( #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; @@ -1010,7 +964,7 @@ ivas_error front_vad_spar( 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 ); + st->lp_noise_fx = float_to_fix16( 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 ) @@ -1132,23 +1086,9 @@ ivas_error front_vad_spar( #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 ); - // 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_ivas_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 ); - 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 ); + cor_map_sum = fixedToFloat( cor_map_sum_fx, Q8 ); #endif } #if 0 @@ -1168,48 +1108,19 @@ ivas_error front_vad_spar( 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->lt_tn_dist_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_tn_dist, Q8 ); - hFrontVad->hNoiseEst->lt_Ellp_dist_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->lt_Ellp_dist, Q8 ); hFrontVad->hNoiseEst->sign_dyn_lp_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->sign_dyn_lp, Q8 ); - 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->totalNoise, Q8 ); 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->hNoiseEst->Etot_st_est_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->Etot_st_est, Q8 ); - hFrontVad->hNoiseEst->Etot_sq_st_est_fx = (Word16) floatToFixed( hFrontVad->hNoiseEst->Etot_sq_st_est, Q2 ); - hFrontVad->lp_speech_fx = (Word16) floatToFixed( hFrontVad->lp_speech, Q8 ); corr_shift_fx = (Word16) floatToFixed( corr_shift, Q15 ); floatToFixed_arrL( hFrontVad->hNoiseEst->bckr, hFrontVad->hNoiseEst->bckr_fx, Q_bands + QSCALE, NB_BANDS ); 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, NULL, &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, e_min_scaled, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); - hFrontVad->hNoiseEst->noise_char = (float) fixedToFloat( hFrontVad->hNoiseEst->noise_char_fx, Q11 ); fixedToFloat_arrL( hFrontVad->hNoiseEst->fr_bands1_fx, hFrontVad->hNoiseEst->fr_bands1, Q_bands + QSCALE, NB_BANDS ); fixedToFloat_arrL( hFrontVad->hNoiseEst->fr_bands2_fx, hFrontVad->hNoiseEst->fr_bands2, Q_bands + QSCALE, NB_BANDS ); fixedToFloat_arrL( hFrontVad->hNoiseEst->ave_enr_fx, hFrontVad->hNoiseEst->ave_enr, Q_bands + QSCALE, NB_BANDS ); fixedToFloat_arrL( hFrontVad->hNoiseEst->ave_enr2_fx, hFrontVad->hNoiseEst->ave_enr2, Q_bands + QSCALE, NB_BANDS ); - hFrontVad->hNoiseEst->Etot_st_est = fixedToFloat( hFrontVad->hNoiseEst->Etot_st_est_fx, Q8 ); - hFrontVad->hNoiseEst->Etot_sq_st_est = fixedToFloat( hFrontVad->hNoiseEst->Etot_sq_st_est_fx, Q2 ); - hFrontVad->hNoiseEst->epsP_2_16_lp2 = fixedToFloat( hFrontVad->hNoiseEst->epsP_2_16_lp2_fx, Q12 ); - hFrontVad->hNoiseEst->epsP_2_16_lp = fixedToFloat( hFrontVad->hNoiseEst->epsP_2_16_lp_fx, Q12 ); - hFrontVad->hNoiseEst->epsP_2_16_dlp_lp2 = fixedToFloat( hFrontVad->hNoiseEst->epsP_2_16_dlp_lp2_fx, Q12 ); - hFrontVad->hNoiseEst->lt_tn_track = fixedToFloat( hFrontVad->hNoiseEst->lt_tn_track_fx, Q15 ); - hFrontVad->hNoiseEst->lt_tn_dist = fixedToFloat( hFrontVad->hNoiseEst->lt_tn_dist_fx, Q8 ); - hFrontVad->hNoiseEst->lt_Ellp_dist = fixedToFloat( hFrontVad->hNoiseEst->lt_Ellp_dist_fx, Q8 ); - hFrontVad->hNoiseEst->lt_haco_ev = fixedToFloat( hFrontVad->hNoiseEst->lt_haco_ev_fx, Q15 ); - hFrontVad->hNoiseEst->lt_aEn_zero = fixedToFloat( hFrontVad->hNoiseEst->lt_aEn_zero_fx, Q15 ); - - hFrontVad->hNoiseEst->act_pred = fixedToFloat( hFrontVad->hNoiseEst->act_pred_fx, Q15 ); fixedToFloat_arrL( hFrontVad->hNoiseEst->bckr_fx, hFrontVad->hNoiseEst->bckr, Q_bands + Q7, NB_BANDS ); cor_map_sum = fixedToFloat( cor_map_sum_fx, Q8 ); non_staX = fixedToFloat( non_staX_fx, Q8 ); @@ -1285,12 +1196,8 @@ ivas_error front_vad_spar( /* 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 */ diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 577cb9a75..023434678 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -1173,8 +1173,11 @@ ivas_error ivas_init_encoder( { return error; } - +#ifndef IVAS_FLOAT_FIXED if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1807,7 +1810,11 @@ ivas_error ivas_init_encoder_fx( return error; } +#ifndef IVAS_FLOAT_FIXED if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2148,8 +2155,12 @@ void ivas_destroy_enc( /* Parametric MC handle */ ivas_param_mc_enc_close( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); - /* Multi-channel MASA handle */ +/* Multi-channel MASA handle */ +#ifdef IVAS_FLOAT_FIXED + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#endif /* OMASA handle */ ivas_omasa_enc_close( &( st_ivas->hOMasa ) ); diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index b148aad7c..177d52e38 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -560,19 +560,19 @@ ivas_error ivas_ism_enc( st->hTranDet->subblockEnergies.firState1 = (Word16) floatToFixed( st->hTranDet->subblockEnergies.firState1_flt, -1 ); st->hTranDet->subblockEnergies.firState2 = (Word16) floatToFixed( st->hTranDet->subblockEnergies.firState2_flt, -1 ); - FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY + 1; i++ ) + FOR( i = 0; i < NSUBBLOCKS + MAX_TD_DELAY + 1; i++ ) { st->hTranDet->subblockEnergies.accSubblockNrg[i] = floatToFixed( st->hTranDet->subblockEnergies.accSubblockNrg_flt[i], 7 ); } - FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) + FOR( i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) { st->hTranDet->subblockEnergies.subblockNrg[i] = floatToFixed( st->hTranDet->subblockEnergies.subblockNrg_flt[i], 7 ); st->hTranDet->subblockEnergies.subblockNrgChange[i] = (Word16) floatToFixed( st->hTranDet->subblockEnergies.subblockNrgChange_flt[i], 7 ); } - FOR( Word16 i = 0; i < L_FRAME_MAX / NSUBBLOCKS; i++ ) + FOR( i = 0; i < L_FRAME_MAX / NSUBBLOCKS; i++ ) { st->hTranDet->delayBuffer.buffer[i] = (Word16) floatToFixed( st->hTranDet->delayBuffer.buffer_flt[i], 7 ); } @@ -591,18 +591,18 @@ ivas_error ivas_ism_enc( st->hTranDet->subblockEnergies.firState1_flt = fixedToFloat( (Word32) st->hTranDet->subblockEnergies.firState1, -1 ); st->hTranDet->subblockEnergies.firState2_flt = fixedToFloat( (Word32) st->hTranDet->subblockEnergies.firState2, -1 ); - FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) + FOR( i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) { st->hTranDet->subblockEnergies.subblockNrg_flt[i] = fixedToFloat( st->hTranDet->subblockEnergies.subblockNrg[i], 7 ); st->hTranDet->subblockEnergies.subblockNrgChange_flt[i] = fixedToFloat( (Word32) st->hTranDet->subblockEnergies.subblockNrgChange[i], 7 ); } - FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY + 1; i++ ) + FOR( i = 0; i < NSUBBLOCKS + MAX_TD_DELAY + 1; i++ ) { st->hTranDet->subblockEnergies.accSubblockNrg_flt[i] = fixedToFloat( st->hTranDet->subblockEnergies.accSubblockNrg[i], 7 ); } - FOR( Word16 i = 0; i < L_FRAME_MAX / NSUBBLOCKS; i++ ) + FOR( i = 0; i < L_FRAME_MAX / NSUBBLOCKS; i++ ) { st->hTranDet->delayBuffer.buffer_flt[i] = fixedToFloat( (Word32) st->hTranDet->delayBuffer.buffer[i], -1 ); } @@ -1053,7 +1053,7 @@ ivas_error ivas_ism_enc_config( return error; } - IF( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, imult3216( ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ), CPE_CHANNELS ), MC_MODE_NONE ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, imult3216( ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ), CPE_CHANNELS ), MC_MODE_NONE ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index e460c2265..7794f0cfe 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -166,6 +166,8 @@ ivas_error ivas_masa_enc_open( hMasa->data.onset_detector_2 = 0.0f; set_zero( hMasa->data.lfeToTotalEnergyRatio, MAX_PARAM_SPATIAL_SUBFRAMES ); + set32_fx( hMasa->data.lfeToTotalEnergyRatio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + set16_fx( hMasa->data.lfeToTotalEnergyRatio_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); hMasa->data.prevq_lfeToTotalEnergyRatio = 0.0f; hMasa->data.prevq_lfeIndex = 0; @@ -1405,6 +1407,80 @@ ivas_error ivas_masa_enc_config( return error; } +/*-----------------------------------------------------------------------* + * ivas_masa_surrcoh_signicant() + * + * Determine if surrounding coherence is significant in this frame and should be encoded + *-----------------------------------------------------------------------*/ +UWord8 ivas_masa_surrcoh_signicant_fx( + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Surround coherence */ + Word32 diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Diffuse to total ratio */ + const Word16 nSubFrames, /* i : Number of sub frames */ + const Word16 nBands /* i : Number of frequency bands */ /* i : dynamic (min q for surroundingCoherence and diffuse_to_total_ratio) */ +) +{ + Word32 significanceMeasure1, significanceMeasure2, significanceMeasure; + Word32 surrCohToTotal, surrCohToTotalSum, surrCohToTotalTimesDiffSum, diffSum; + Word32 sf, band; + Word16 surrCohToTotalSum_e, surrCohToTotalTimesDiffSum_e, diffSum_e; + + // input buffers Q=31 + Word32 surrCohSignificanceCoef = 858993459; //( 0.4 * ( 1 << q ) ) 0.4 scaled to Q=31 + move32(); + Word32 threshold = 214748365; //( 0.1 * ( 1 << q ) ) 0.1 scaled to Q=31 + move32(); + FOR( sf = 0; sf < nSubFrames; sf++ ) + { + surrCohToTotalSum = 0; + move32(); + surrCohToTotalSum_e = 0; + move16(); + surrCohToTotalTimesDiffSum = 0; + move32(); + surrCohToTotalTimesDiffSum_e = 0; + move16(); + diffSum = 0; + move32(); + diffSum_e = 0; + move16(); + + FOR( band = 0; band < nBands; band++ ) + { + surrCohToTotal = Mpy_32_32( diffuse_to_total_ratio[sf][band], surroundingCoherence[sf][band] ); // 2Q -> Q + surrCohToTotalSum = BASOP_Util_Add_Mant32Exp( surrCohToTotalSum, surrCohToTotalSum_e, surrCohToTotal, 0, &surrCohToTotalSum_e ); + surrCohToTotalTimesDiffSum = BASOP_Util_Add_Mant32Exp( surrCohToTotalTimesDiffSum, surrCohToTotalTimesDiffSum_e, Mpy_32_32( (Word32) diffuse_to_total_ratio[sf][band], surrCohToTotal ), 0, &surrCohToTotalTimesDiffSum_e ); // Q2 -> Q + diffSum = BASOP_Util_Add_Mant32Exp( diffSum, diffSum_e, diffuse_to_total_ratio[sf][band], 0, &diffSum_e ); // Q + } + + Word16 significanceMeasure1_e, significanceMeasure2_e; + Word16 significanceMeasure_e; + significanceMeasure1 = L_deposit_h( BASOP_Util_Divide3216_Scale( surrCohToTotalSum, nBands, &significanceMeasure1_e ) ); // e1 exponent + significanceMeasure1_e = add( significanceMeasure1_e, sub( surrCohToTotalSum_e, 15 ) ); + significanceMeasure2 = L_deposit_h( BASOP_Util_Divide3232_Scale( Mpy_32_32( surrCohSignificanceCoef, surrCohToTotalTimesDiffSum ), L_add( diffSum, EPSILON_FX ), &significanceMeasure2_e ) ); // e2 exponent + significanceMeasure2_e = add( significanceMeasure2_e, sub( surrCohToTotalTimesDiffSum_e, diffSum_e ) ); + + IF( BASOP_Util_Cmp_Mant32Exp( significanceMeasure1, significanceMeasure1_e, significanceMeasure2, significanceMeasure2_e ) > 0 ) + { + significanceMeasure = significanceMeasure1; + move32(); + significanceMeasure_e = significanceMeasure1_e; + move16(); + } + ELSE + { + significanceMeasure = significanceMeasure2; + move32(); + significanceMeasure_e = significanceMeasure2_e; + move16(); + } + IF( BASOP_Util_Cmp_Mant32Exp( significanceMeasure, significanceMeasure_e, threshold, 0 ) > 0 ) // Q31 Comparision + { + return 1; + } + } + + return 0; +} /*-----------------------------------------------------------------------* * ivas_masa_surrcoh_signicant() diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index c87107859..c547a60bd 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -41,6 +41,7 @@ #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" #include "prot_fx.h" +#include "basop_util.h" #endif #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -61,7 +62,7 @@ static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, floa #endif #ifdef IVAS_FLOAT_FIXED -static ivas_error ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); +static ivas_error ivas_mc_paramupmix_param_est_enc_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, Word32 *input_frame_t_fx[], Word16 Q_input_frame_t, const Word16 input_frame, Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], Word16 *exp_alphas, Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], Word16 *exp_betas ); #else static void ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); #endif @@ -106,7 +107,56 @@ void ivas_mc_paramupmix_enc( bit_pos = 0; /* Parameter estimation */ +#ifdef IVAS_FLOAT_FIXED + Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word16 exp_alphas = 31, exp_betas = 31; + move16(); + move16(); + + ivas_mc_paramupmix_param_est_enc_fx( hMCParamUpmix, data_fx, st_ivas->q_data_fx, input_frame, alphas_fx, &exp_alphas, betas_fx, &exp_betas ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + for ( int ch_idx = 0; ch_idx < hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans; ch_idx++ ) + { + fixedToFloat_arrL( hMCParamUpmix->hFbMixer->ppFilterbank_prior_input_fx[ch_idx], hMCParamUpmix->hFbMixer->ppFilterbank_prior_input[ch_idx], Q14, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } + + for ( int b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) + { + for ( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + for ( int j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + for ( int k = 0; k < hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; k++ ) + { + hMCParamUpmix->cov_real[b][i][j][k] = me2f( hMCParamUpmix->cov_real_fx[b][i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[i][j][k] ) ); + hMCParamUpmix->cov_dtx_real[b][i][j][k] = me2f( hMCParamUpmix->cov_dtx_real_fx[b][i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_dtx_state->q_cov_real_per_band[i][j][k] ) ); + } + } + } + } + + Word16 len = hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; + if ( len < IVAS_MAX_NUM_BANDS ) + { + len = IVAS_MAX_NUM_BANDS; + } + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + for ( int j = 0; j < len; j++ ) + { + alphas[i][j] = me2f( alphas_fx[i][j], exp_alphas ); + betas[i][j] = me2f( betas_fx[i][j], exp_betas ); + } + } +#endif +#else ivas_mc_paramupmix_param_est_enc( hMCParamUpmix, data_f, input_frame, alphas, betas ); +#endif for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { @@ -340,6 +390,48 @@ ivas_error ivas_mc_paramupmix_enc_open( } } } +#ifdef IVAS_FLOAT_FIXED + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b] = (Word32 ***) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b][i] = (Word32 **) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b][i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + } + } + + IF( ( hMCParamUpmix->cov_dtx_real_fx[b] = (Word32 ***) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( hMCParamUpmix->cov_dtx_real_fx[b][i] = (Word32 **) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( hMCParamUpmix->cov_dtx_real_fx[b][i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + } + } + } +#endif st_ivas->hMCParamUpmix = hMCParamUpmix; @@ -830,119 +922,75 @@ static void ivas_mc_paramupmix_dmx( *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static ivas_error ivas_mc_paramupmix_param_est_enc( +static ivas_error ivas_mc_paramupmix_param_est_enc_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ - float *data_f[], /* i : Input frame in the time domain */ - const int16_t input_frame, /* i : Input frame length */ - float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], - float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ) -#else -static void ivas_mc_paramupmix_param_est_enc( - MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ - float *data_f[], /* i : Input frame in the time domain */ - const int16_t input_frame, /* i : Input frame length */ - float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], - float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ) -#endif + Word32 *data_f_fx[], + Word16 Q_data_f, + const Word16 input_frame, /* i : Input frame length */ + Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], + Word16 *exp_alphas, + Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], + Word16 *exp_betas ) { - float *pcm_in[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - float fr_realbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; - float fr_imagbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; - float FR_Real_Mid[L_FRAME48k], FR_Imag_Mid[L_FRAME48k]; - float *p_fr_realbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - float *p_fr_imagbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - float *pp_in_fr_real[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - float *pp_in_fr_imag[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; -#ifdef IVAS_FLOAT_FIXED + + Word32 *pcm_in_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + Word32 FR_Real_Mid_fx[L_FRAME48k], FR_Imag_Mid_fx[L_FRAME48k]; Word32 fr_realbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; Word32 fr_imagbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; Word32 *p_fr_realbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; Word32 *p_fr_imagbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_cov_real[IVAS_SPAR_MAX_CH]; Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH]; - Word32 cov_real_buf_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - Word32 cov_dtx_real_buf_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; Word32 *pp_in_fr_real_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH], *pp_in_fr_imag_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; Word16 q_ppIn_FR[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; -#else - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; -#endif - float rxx, rxy, ryy, cmat, rxxest, drxx, wetaux; - int16_t l_ts; - int16_t b, i, j, ts, bnd; - int16_t maxbands; - int16_t transient_det[MC_PARAMUPMIX_COMBINATIONS][2]; - int16_t transient_det_l[2], transient_det_r[2]; - const int16_t chan1s[MC_PARAMUPMIX_COMBINATIONS] = { 4, 5, 8, 9 }; - const int16_t chan2s[MC_PARAMUPMIX_COMBINATIONS] = { 6, 7, 10, 11 }; - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + Word32 rxy_fx, ryy_fx; + Word32 rxx_fx; + Word32 rxxest_fx, drxx_fx; + Word16 exp_drxx; + Word16 wetaux_fx, exp_wetaux; + Word16 cmat_fx, exp_cmat; + + Word16 l_ts; + Word16 b, i, j, ts, bnd; + Word16 maxbands; + Word16 transient_det[MC_PARAMUPMIX_COMBINATIONS][2]; + Word16 transient_det_l[2], transient_det_r[2]; + const Word16 chan1s[MC_PARAMUPMIX_COMBINATIONS] = { 4, 5, 8, 9 }; + const Word16 chan2s[MC_PARAMUPMIX_COMBINATIONS] = { 6, 7, 10, 11 }; + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + move16(); + move16(); + move16(); + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { - pcm_in[2 * i] = data_f[chan1s[i]]; - pcm_in[2 * i + 1] = data_f[chan2s[i]]; + pcm_in_fx[2 * i] = data_f_fx[chan1s[i]]; + pcm_in_fx[2 * i + 1] = data_f_fx[chan2s[i]]; + move16(); + move16(); + + Scale_sig32( pcm_in_fx[2 * i], input_frame, Q14 - Q_data_f ); + Scale_sig32( pcm_in_fx[2 * i + 1], input_frame, Q14 - Q_data_f ); } /*-----------------------------------------------------------------------------------------* * Transient detector *-----------------------------------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED - Word32 *pcm_in_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - Word32 arr_pcm_in[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; - Word32 k; - FOR( j = 0; j < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; j++ ) - { - pcm_in_fx[j] = arr_pcm_in[j]; - FOR( k = 0; k < input_frame; k++ ) - { - pcm_in_fx[j][k] = (Word32) ( pcm_in[j][k] * ( 1 << Q14 ) ); - } - } -#endif - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { -#ifndef IVAS_FLOAT_FIXED - ivas_transient_det_process( hMCParamUpmix->hTranDet[2 * i], pcm_in[2 * i], input_frame, transient_det_l ); - ivas_transient_det_process( hMCParamUpmix->hTranDet[2 * i + 1], pcm_in[2 * i + 1], input_frame, transient_det_r ); -#else ivas_transient_det_process_fx( hMCParamUpmix->hTranDet[2 * i], pcm_in_fx[2 * i], input_frame, transient_det_l ); -#ifdef DEBUGGING - float a[2]; - a[0] = transient_det_l[0]; - a[1] = transient_det_l[1]; - dbgwrite_txt( a, 2, "fixed.txt", NULL ); -#endif ivas_transient_det_process_fx( hMCParamUpmix->hTranDet[2 * i + 1], pcm_in_fx[2 * i + 1], input_frame, transient_det_r ); -#ifdef DEBUGGING - a[0] = transient_det_r[0]; - a[1] = transient_det_r[1]; - dbgwrite_txt( a, 2, "fixed.txt", NULL ); -#endif -#endif transient_det[i][0] = transient_det_l[0] || transient_det_r[0]; + move16(); transient_det[i][1] = transient_det_l[0] || transient_det_r[0]; + move16(); /* should probably be transient_det_l[1] || transient_det_r[1] , but choosing 0 reproduces the before merge state */ } - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) - { - p_fr_realbuffer[i] = fr_realbuffer[i]; - p_fr_imagbuffer[i] = fr_imagbuffer[i]; - } - - /* prepare Parameter MDFT analysis */ - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) - { - pp_in_fr_real[i] = p_fr_realbuffer[i]; - pp_in_fr_imag[i] = p_fr_imagbuffer[i]; - } - -#ifdef IVAS_FLOAT_FIXED FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) { p_fr_realbuffer_fx[i] = fr_realbuffer_fx[i]; @@ -960,12 +1008,11 @@ static void ivas_mc_paramupmix_param_est_enc( move32(); } -#endif - l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); -#ifdef IVAS_FLOAT_FIXED Word16 gb = find_guarded_bits_fx( l_ts ); + FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { ivas_fb_mixer_get_windowed_fr_fx( hMCParamUpmix->hFbMixer, pcm_in_fx, pp_in_fr_real_fx, pp_in_fr_imag_fx, l_ts, l_ts, hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans, gb ); @@ -980,38 +1027,236 @@ static void ivas_mc_paramupmix_param_est_enc( } } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - /*To be removed*/ - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + /*-----------------------------------------------------------------------------------------* + * Covariance process + *-----------------------------------------------------------------------------------------*/ + + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + pp_in_fr_real_fx[0] = p_fr_realbuffer_fx[2 * b]; + pp_in_fr_imag_fx[0] = p_fr_imagbuffer_fx[2 * b]; + pp_in_fr_real_fx[1] = FR_Real_Mid_fx; + pp_in_fr_imag_fx[1] = FR_Imag_Mid_fx; + + v_add_fx( pp_in_fr_real_fx[0], p_fr_realbuffer_fx[2 * b + 1], pp_in_fr_real_fx[1], L_FRAME48k ); + v_add_fx( pp_in_fr_imag_fx[0], p_fr_imagbuffer_fx[2 * b + 1], pp_in_fr_imag_fx[1], L_FRAME48k ); + + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) { - pcm_in_fx[i] -= l_ts; - pp_in_fr_real_fx[i] -= l_ts; - pp_in_fr_imag_fx[i] -= l_ts; + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + cov_real_fx[i][j] = hMCParamUpmix->cov_real_fx[b][i][j]; + move32(); + cov_dtx_real_fx[i][j] = hMCParamUpmix->cov_dtx_real_fx[b][i][j]; + move32(); + } + IF( ( q_cov_real[i] = (Word16 *) malloc( sizeof( Word16 ) * MC_PARAMUPMIX_NCH ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); + } + set_s( q_cov_real[i], Q31, MC_PARAMUPMIX_NCH ); + IF( ( q_cov_dtx_real[i] = (Word16 *) malloc( sizeof( Word16 ) * MC_PARAMUPMIX_NCH ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); + } + set_s( q_cov_dtx_real[i], Q31, MC_PARAMUPMIX_NCH ); + } + + set_s( q_ppIn_FR, Q14 - gb, MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH ); + ivas_enc_cov_handler_process_fx( hMCParamUpmix->hCovEnc[b], pp_in_fr_real_fx, pp_in_fr_imag_fx, q_ppIn_FR, cov_real_fx, q_cov_real, cov_dtx_real_fx, q_cov_dtx_real, hMCParamUpmix->hFbMixer->pFb, 0, hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands, MC_PARAMUPMIX_NCH, 0 /*dtx_vad*/, transient_det[b], HOA_md_ind, NULL, NULL, NULL, 0, 0 ); + + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + free( q_cov_real[i] ); + q_cov_real[i] = NULL; + free( q_cov_dtx_real[i] ); + q_cov_dtx_real[i] = NULL; } } - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + + maxbands = hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; + Word16 exp_alpha_buff[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] = { { 0 }, { 0 } }; + Word16 exp_beta_buff[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] = { { 0 }, { 0 } }; + move16(); + move16(); + + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { - for ( int ch_idx = 0; ch_idx < hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans; ch_idx++ ) + FOR( bnd = 0; bnd < maxbands; bnd++ ) { - fixedToFloat_arrL( pp_in_fr_real_fx[ch_idx], pp_in_fr_real[ch_idx], Q14 - gb, l_ts ); - fixedToFloat_arrL( pp_in_fr_imag_fx[ch_idx], pp_in_fr_imag[ch_idx], Q14 - gb, l_ts ); - fixedToFloat_arrL( hMCParamUpmix->hFbMixer->ppFilterbank_prior_input_fx[ch_idx], hMCParamUpmix->hFbMixer->ppFilterbank_prior_input[ch_idx], Q14, l_ts ); + rxy_fx = hMCParamUpmix->cov_real_fx[b][1][0][bnd]; + ryy_fx = hMCParamUpmix->cov_real_fx[b][1][1][bnd]; + + Word16 exp_tmp = 0; + move16(); + Word32 tmp = BASOP_Util_Add_Mant32Exp( ryy_fx, 31 - ( hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[1][1][bnd] ), EPSILON_FX_M, EPSILON_FX_E, &exp_tmp ); + exp_cmat = 0; + move16(); + cmat_fx = BASOP_Util_Divide3232_Scale( rxy_fx, tmp, &exp_cmat ); + exp_cmat = sub( add( exp_cmat, sub( 31, ( hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[1][0][bnd] ) ) ), exp_tmp ); + + Word16 alpha_fx = 0, exp_alpha_var = 0; + move16(); + move16(); + exp_alpha_var = BASOP_Util_Add_MantExp( cmat_fx, exp_cmat + 1, negate( ONE_IN_Q14 ), 1, &alpha_fx ); + + rxx_fx = hMCParamUpmix->cov_real_fx[b][0][0][bnd]; + Word32 tmp_2 = L_mult( cmat_fx, cmat_fx ); // exp_cmat * 2 + rxxest_fx = Mpy_32_32( tmp_2, ryy_fx ); + + exp_drxx = 0; + move16(); + drxx_fx = BASOP_Util_Add_Mant32Exp( rxx_fx, sub( 31, ( hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[0][0][bnd] ) ), L_negate( rxxest_fx ), + add( add( exp_cmat, exp_cmat ), sub( 31, ( hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[1][1][bnd] ) ) ), &exp_drxx ); + drxx_fx = L_max( drxx_fx, 0 ); + + exp_wetaux = 0; + move16(); + wetaux_fx = BASOP_Util_Divide3232_Scale( drxx_fx, tmp, &exp_wetaux ); + exp_wetaux = sub( add( exp_wetaux, exp_drxx ), exp_tmp ); + + Word16 sqrt_wetaux_fx = 0, exp_sqrt_wetaux = 0; + move16(); + move16(); + + IF( wetaux_fx != 0 ) + { + Word16 tmp_4 = 0, exp_tmp4 = 0; + move16(); + move16(); + BASOP_Util_Sqrt_InvSqrt_MantExp( wetaux_fx, exp_wetaux, &sqrt_wetaux_fx, &exp_sqrt_wetaux, &tmp_4, &exp_tmp4 ); + tmp_4 = tmp_4; + exp_tmp4 = exp_tmp4; + move16(); + move16(); + } + ELSE + { + exp_sqrt_wetaux = -1; + move16(); + } + + Word16 exp_betas_var = add( exp_sqrt_wetaux, 1 ); + move16(); + + alphas_fx[b][bnd] = L_deposit_h( alpha_fx ); + move16(); + betas_fx[b][bnd] = L_deposit_h( sqrt_wetaux_fx ); + move16(); + exp_alpha_buff[b][bnd] = exp_alpha_var; + move16(); + exp_beta_buff[b][bnd] = exp_betas_var; + move16(); } - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + } + + Word16 max_exp_alpha_buff = 0, max_exp_beta_buff = 0; + move16(); + move16(); + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + FOR( j = 0; j < maxbands; j++ ) { - pcm_in_fx[i] += l_ts; - pp_in_fr_real_fx[i] += l_ts; - pp_in_fr_imag_fx[i] += l_ts; + max_exp_alpha_buff = s_max( max_exp_alpha_buff, exp_alpha_buff[i][j] ); + max_exp_beta_buff = s_max( max_exp_beta_buff, exp_beta_buff[i][j] ); + } + } + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + FOR( j = 0; j < maxbands; j++ ) + { + alphas_fx[i][j] = L_shr( alphas_fx[i][j], max_exp_alpha_buff - exp_alpha_buff[i][j] ); + move16(); + betas_fx[i][j] = L_shr( betas_fx[i][j], max_exp_beta_buff - exp_beta_buff[i][j] ); + move16(); + } + } + *exp_alphas = max_exp_alpha_buff; + *exp_betas = max_exp_beta_buff; + move16(); + move16(); - pcm_in[i] += l_ts; - pp_in_fr_real[i] += l_ts; - pp_in_fr_imag[i] += l_ts; + IF( LT_16( maxbands, IVAS_MAX_NUM_BANDS ) ) + { + *exp_alphas = 0; + move16(); + *exp_betas = 0; + move16(); + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) + { + FOR( bnd = maxbands; bnd < IVAS_MAX_NUM_BANDS; bnd++ ) + { + alphas_fx[b][bnd] = 0; + move16(); + betas_fx[b][bnd] = 0; + move16(); + } } } -#endif + + return IVAS_ERR_OK; +} #else +static void ivas_mc_paramupmix_param_est_enc( + MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ + float *data_f[], /* i : Input frame in the time domain */ + const int16_t input_frame, /* i : Input frame length */ + float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], + float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ) +{ + float *pcm_in[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + float fr_realbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; + float fr_imagbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; + float FR_Real_Mid[L_FRAME48k], FR_Imag_Mid[L_FRAME48k]; + float *p_fr_realbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + float *p_fr_imagbuffer[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + float *pp_in_fr_real[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + float *pp_in_fr_imag[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float rxx, rxy, ryy, cmat, rxxest, drxx, wetaux; + int16_t l_ts; + int16_t b, i, j, ts, bnd; + int16_t maxbands; + int16_t transient_det[MC_PARAMUPMIX_COMBINATIONS][2]; + int16_t transient_det_l[2], transient_det_r[2]; + const int16_t chan1s[MC_PARAMUPMIX_COMBINATIONS] = { 4, 5, 8, 9 }; + const int16_t chan2s[MC_PARAMUPMIX_COMBINATIONS] = { 6, 7, 10, 11 }; + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + pcm_in[2 * i] = data_f[chan1s[i]]; + pcm_in[2 * i + 1] = data_f[chan2s[i]]; + } + + /*-----------------------------------------------------------------------------------------* + * Transient detector + *-----------------------------------------------------------------------------------------*/ + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + ivas_transient_det_process( hMCParamUpmix->hTranDet[2 * i], pcm_in[2 * i], input_frame, transient_det_l ); + ivas_transient_det_process( hMCParamUpmix->hTranDet[2 * i + 1], pcm_in[2 * i + 1], input_frame, transient_det_r ); + transient_det[i][0] = transient_det_l[0] || transient_det_r[0]; + transient_det[i][1] = transient_det_l[0] || transient_det_r[0]; + /* should probably be transient_det_l[1] || transient_det_r[1] , but choosing 0 reproduces the before merge state */ + } + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + p_fr_realbuffer[i] = fr_realbuffer[i]; + p_fr_imagbuffer[i] = fr_imagbuffer[i]; + } + + /* prepare Parameter MDFT analysis */ + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + pp_in_fr_real[i] = p_fr_realbuffer[i]; + pp_in_fr_imag[i] = p_fr_imagbuffer[i]; + } + + l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { ivas_fb_mixer_get_windowed_fr( hMCParamUpmix->hFbMixer, pcm_in, pp_in_fr_real, pp_in_fr_imag, l_ts, l_ts, hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans ); @@ -1025,7 +1270,6 @@ static void ivas_mc_paramupmix_param_est_enc( pp_in_fr_imag[i] += l_ts; } } -#endif /*-----------------------------------------------------------------------------------------* * Covariance process @@ -1045,89 +1289,12 @@ static void ivas_mc_paramupmix_param_est_enc( { for ( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) { -#ifdef IVAS_FLOAT_FIXED - cov_real_fx[i][j] = cov_real_buf_fx[i][j]; - cov_dtx_real_fx[i][j] = cov_dtx_real_buf_fx[i][j]; -#else cov_real[i][j] = hMCParamUpmix->cov_real[b][i][j]; cov_dtx_real[i][j] = hMCParamUpmix->cov_dtx_real[b][i][j]; -#endif - } -#ifdef IVAS_FLOAT_FIXED - IF( ( q_cov_real[i] = (Word16 *) malloc( sizeof( Word16 ) * MC_PARAMUPMIX_NCH ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); - } - set_s( q_cov_real[i], Q31, MC_PARAMUPMIX_NCH ); - IF( ( q_cov_dtx_real[i] = (Word16 *) malloc( sizeof( Word16 ) * MC_PARAMUPMIX_NCH ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); - } - set_s( q_cov_dtx_real[i], Q31, MC_PARAMUPMIX_NCH ); -#endif - } - -#ifdef IVAS_FLOAT_FIXED - FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) - { - IF( ( pp_in_fr_real_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR encoder Fixed" ); } - set_zero_fx( pp_in_fr_real_fx[i], input_frame ); - IF( ( pp_in_fr_imag_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR encoder Fixed" ); - } - set_zero_fx( pp_in_fr_imag_fx[i], input_frame ); - } - set_s( q_ppIn_FR, Q31, MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH ); - -#ifdef MSAN_FIX - FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) -#else - FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) -#endif - { - q_ppIn_FR[i] = L_get_q_buf1( pp_in_fr_real[i], input_frame ); - q_ppIn_FR[i] = min( q_ppIn_FR[i], L_get_q_buf1( pp_in_fr_imag[i], input_frame ) ); - floatToFixed_arrL( pp_in_fr_real[i], pp_in_fr_real_fx[i], q_ppIn_FR[i], input_frame ); - floatToFixed_arrL( pp_in_fr_imag[i], pp_in_fr_imag_fx[i], q_ppIn_FR[i], input_frame ); } -#endif -#ifdef IVAS_FLOAT_FIXED - ivas_enc_cov_handler_process_fx( hMCParamUpmix->hCovEnc[b], pp_in_fr_real_fx, pp_in_fr_imag_fx, q_ppIn_FR, cov_real_fx, q_cov_real, cov_dtx_real_fx, q_cov_dtx_real, hMCParamUpmix->hFbMixer->pFb, 0, hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands, MC_PARAMUPMIX_NCH, 0 /*dtx_vad*/, transient_det[b], HOA_md_ind, NULL, NULL, NULL, 0, 0 ); -#else ivas_enc_cov_handler_process( hMCParamUpmix->hCovEnc[b], pp_in_fr_real, pp_in_fr_imag, cov_real, cov_dtx_real, hMCParamUpmix->hFbMixer->pFb, 0, hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands, MC_PARAMUPMIX_NCH, 0 /*dtx_vad*/, transient_det[b], HOA_md_ind, NULL, NULL, NULL, 0, 0 ); -#endif - -#ifdef IVAS_FLOAT_FIXED - FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) - { - FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) - { - FOR( k = 0; k < hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; k++ ) - { - hMCParamUpmix->cov_real[b][i][j][k] = me2f( cov_real_fx[i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[i][j][k] ) ); - hMCParamUpmix->cov_dtx_real[b][i][j][k] = me2f( cov_dtx_real_fx[i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_dtx_state->q_cov_real_per_band[i][j][k] ) ); - } - } - free( q_cov_real[i] ); - q_cov_real[i] = NULL; - free( q_cov_dtx_real[i] ); - q_cov_dtx_real[i] = NULL; - } - // Note: No need to convert pp_in_fr_real_fx and pp_in_fr_imag_fx back to float as they are not used after ivas_mc_paramupmix_param_est_enc() - - FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) - { - free( pp_in_fr_real_fx[i] ); - pp_in_fr_real_fx[i] = NULL; - free( pp_in_fr_imag_fx[i] ); - pp_in_fr_imag_fx[i] = NULL; - } -#endif } maxbands = hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; @@ -1161,9 +1328,6 @@ static void ivas_mc_paramupmix_param_est_enc( } } -#ifdef IVAS_FLOAT_FIXED - return IVAS_ERR_OK; -#else return; -#endif } +#endif diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 3a49e4aae..00f8197c4 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -41,6 +41,9 @@ #include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_rom_com_fx.h" +#endif #include "ivas_rom_enc.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED @@ -54,13 +57,17 @@ #define NEAR_HORIZONTAL_PLANE_ELEVATION 17.5f #define VERTICAL_ENERGY_RATIO_OFFSET 0.15f - +#ifdef IVAS_FLOAT_FIXED +#define NEAR_HORIZONTAL_PLANE_ELEVATION_FX 73400320 /*Q22*/ +#define VERTICAL_ENERGY_RATIO_OFFSET_FX 4915 /*Q15*/ +#endif /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ /* Structure for covariance matrix */ +#ifndef IVAS_FLOAT_FIXED typedef struct { float xr[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; @@ -78,63 +85,142 @@ static void computeVerticalDiffuseness( float **buffer_intensity, const float *b static void computeEvenLayout( const float *ls_azimuth, float *ls_azimuth_even, const int16_t numChannels ); static void computeLfeEnergy( MCMASA_ENC_HANDLE hMcMasa, float *data_f[], const int16_t input_frame ); +#else +typedef struct +{ + Word32 xr_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; + Word32 xi_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; + Word16 xr_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xr_fx*/ + Word16 xi_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xi_fx*/ +} CovarianceMatrix; + +static void ivas_mcmasa_dmx_fx( + MCMASA_ENC_HANDLE hMcMasa, + Word32 *data_fx[], + Word16 data_e, + const Word16 input_frame, + const Word16 nchan_transport, + const Word16 nchan_inp ); + +static void compute_cov_mtx_fx( + Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */ + Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] */ + const Word16 freq, /* i : Freq to process */ + const Word16 N, /* i : Number of channels */ + CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */ + Word16 inp_exp /*Stores exponent for temp*/ +); +static void computeIntensityVector_enc_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, const Word16 num_frequency_bands, Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); + +static void computeVerticalDiffuseness_fx( + Word32 **buffer_intensity, /* i : Intensity vectors */ + const Word32 *buffer_energy, /* i : Energy */ + const Word16 averaging_length, /* i : Averaging length */ + const Word16 num_freq_bands, /* i : Number of frequency bands */ + Word32 *diffuseness, /* o : Estimated diffuseness */ + Word16 *buffer_intensity_q, + Word16 *buffer_energy_q ); + +static void computeEvenLayout_fx( + const Word32 *ls_azimuth, + Word32 *ls_azimuth_even, + const Word16 numChannels ); + +static void computeLfeEnergy_fx( MCMASA_ENC_HANDLE hMcMasa, Word32 *data_fx[], const Word16 input_frame, Word16 q_fac ); + +static Word16 ivas_getScaleFactor32( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x ) /* i: length of the array to scan */ +{ + Word16 i, i_min, i_max; + Word32 x_min, x_max; + + + x_max = 0; + move32(); + x_min = 0; + move32(); + FOR( i = 0; i < len_x; i++ ) + { + IF( x[i] >= 0 ) + x_max = L_max( x_max, x[i] ); + IF( x[i] < 0 ) + x_min = L_min( x_min, x[i] ); + } + + i_max = 0x1f; + move16(); + i_min = 0x1f; + move16(); + + IF( x_max != 0 ) + i_max = norm_l( x_max ); + + IF( x_min != 0 ) + i_min = norm_l( x_min ); + i = s_and( s_min( i_max, i_min ), 0x1F ); + + + return i; +} +#endif +#ifdef IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------* * ivas_mcmasa_enc_open() * * *--------------------------------------------------------------------------*/ -ivas_error ivas_mcmasa_enc_open( +ivas_error ivas_mcmasa_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) { - int16_t i, j; - float tmp_f; + Word16 i, j; + Word16 tmp_f; MCMASA_ENC_HANDLE hMcMasa; MASA_ENCODER_HANDLE hMasa; - float ls_azimuth[MCMASA_MAX_ANA_CHANS]; - float ls_elevation[MCMASA_MAX_ANA_CHANS]; - float ls_azimuth_even[MCMASA_MAX_ANA_CHANS]; - int16_t numAnalysisChannels; - float left_min, right_min, azi_diff; - const int16_t *band_mapping; - int16_t maxBin, input_frame; - int16_t nchan_inp; - int32_t input_Fs; - int32_t dirac_slot_ns; + Word32 ls_azimuth[MCMASA_MAX_ANA_CHANS]; + Word32 ls_elevation[MCMASA_MAX_ANA_CHANS]; + Word32 ls_azimuth_even[MCMASA_MAX_ANA_CHANS]; + Word16 numAnalysisChannels; + Word32 left_min, right_min, azi_diff; + const Word16 *band_mapping; + Word16 maxBin, input_frame; + Word16 nchan_inp; + Word32 input_Fs; + Word32 dirac_slot_ns; IVAS_FB_CFG *fb_cfg, *fb_cfgLfe; ivas_error error; error = IVAS_ERR_OK; + move32(); assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" ); hMasa = st_ivas->hMasa; - if ( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL ) + IF( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } nchan_inp = st_ivas->hEncoderConfig->nchan_inp; + move16(); input_Fs = st_ivas->hEncoderConfig->input_Fs; + move32(); /* Determine if to separate some channels from the analysis */ -#ifndef IVAS_FLOAT_FIXED - ivas_mcmasa_set_separate_channel_mode( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate ); -#else ivas_mcmasa_set_separate_channel_mode_fx( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate ); -#endif - numAnalysisChannels = nchan_inp - 1; - if ( hMcMasa->separateChannelEnabled ) + numAnalysisChannels = sub( nchan_inp, 1 ); + IF( hMcMasa->separateChannelEnabled ) { - numAnalysisChannels = nchan_inp - 2; + numAnalysisChannels = sub( nchan_inp, 2 ); } /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */ - if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_masa_enc_config( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -142,95 +228,116 @@ ivas_error ivas_mcmasa_enc_open( /* Determine the number of bands */ hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands; + move16(); hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands; + move16(); /* Determine band grouping */ - if ( hMcMasa->nbands == 24 ) + IF( EQ_16( hMcMasa->nbands, 24 ) ) { - for ( i = 0; i < hMcMasa->nbands + 1; i++ ) + FOR( i = 0; i < hMcMasa->nbands + 1; i++ ) { - hMcMasa->band_grouping[i] = MASA_band_grouping_24[i] * CLDFB_TO_MDFT_FAC; + hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[i], CLDFB_TO_MDFT_FAC ); + move16(); } } - else + ELSE { band_mapping = hMasa->data.band_mapping; - for ( i = 0; i < hMcMasa->nbands + 1; i++ ) + FOR( i = 0; i < hMcMasa->nbands + 1; i++ ) { - hMcMasa->band_grouping[i] = MASA_band_grouping_24[band_mapping[i]] * CLDFB_TO_MDFT_FAC; + hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[band_mapping[i]], CLDFB_TO_MDFT_FAC ); + move16(); } } - maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH * CLDFB_TO_MDFT_FAC + 0.5f ); + maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_MDFT_FAC_Q31 ), ONE_IN_Q31 /*0.5f in Q32*/ ) ) ); // Q0 - for ( i = 1; i < hMcMasa->nbands + 1; i++ ) + FOR( i = 1; i < hMcMasa->nbands + 1; i++ ) { - if ( hMcMasa->band_grouping[i] >= maxBin ) + IF( GE_32( hMcMasa->band_grouping[i], maxBin ) ) { hMcMasa->band_grouping[i] = maxBin; + move16(); hMcMasa->nbands = i; - break; + move16(); + BREAK; } } /* initialize delay compensation */ hMcMasa->num_samples_delay_comp = NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); + move16(); #ifdef DISABLE_DIRAC_DELAY_COMP hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */ #endif - tmp_f = (float) hMcMasa->num_samples_delay_comp / (float) ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ); - hMcMasa->num_slots_delay_comp = (int16_t) ( tmp_f ); + tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ); + hMcMasa->num_slots_delay_comp = tmp_f; + move16(); - if ( tmp_f > (float) hMcMasa->num_slots_delay_comp ) + IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) ) { - hMcMasa->num_slots_delay_comp++; - hMcMasa->offset_comp = -hMcMasa->num_samples_delay_comp; - hMcMasa->num_samples_delay_comp = hMcMasa->num_slots_delay_comp * NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ); - hMcMasa->offset_comp += hMcMasa->num_samples_delay_comp; + hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 ); + move16(); + hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp ); + move16(); + hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ); + move16(); + hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp ); + move16(); } - else + ELSE { hMcMasa->offset_comp = 0; + move16(); } /* set FB config. */ - if ( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) ) { return error; } /* Allocate and initialize FB mixer handle */ - if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + /* Allocate and initialize FB mixer handle */ + IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) { return error; } - - if ( hMcMasa->separateChannelEnabled ) + IF( hMcMasa->separateChannelEnabled ) { /* TD Energy calculation with LP */ - if ( ( hMcMasa->delay_buffer_lfe[0] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); - if ( ( hMcMasa->delay_buffer_lfe[1] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); hMcMasa->hFbMixerLfe = NULL; } - else + ELSE { /* Allocate and initialize FB mixer handle for LFE channel */ - if ( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) ) { return error; } - if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ), IVAS_ERR_OK ) ) { return error; } @@ -239,249 +346,789 @@ ivas_error ivas_mcmasa_enc_open( hMcMasa->delay_buffer_lfe[1] = NULL; } - if ( hMcMasa->separateChannelEnabled ) + IF( hMcMasa->separateChannelEnabled ) { - int16_t bufferSize; + Word16 bufferSize; /* Ring buffer for the filterbank of the LFE analysis. * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */ - bufferSize = (int16_t) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES ); - for ( i = 0; i < 2; i++ ) + bufferSize = (Word16) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES ); + FOR( i = 0; i < 2; i++ ) { - if ( ( hMcMasa->lfeAnaRingBuffer[i] = (float *) malloc( bufferSize * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->lfeAnaRingBuffer[i] = (Word32 *) malloc( bufferSize * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->lfeAnaRingBuffer[i], bufferSize ); - hMcMasa->lowpassSum[i] = 0.0f; + set_zero_fx( hMcMasa->lfeAnaRingBuffer[i], bufferSize ); + hMcMasa->lowpassSum[i] = 0; + move32(); } hMcMasa->ringBufferPointer = 0; + move16(); hMcMasa->ringBufferSize = bufferSize; + move16(); } dirac_slot_ns = DIRAC_SLOT_ENC_NS; + move32(); /* intensity 3-dim */ - for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { - if ( ( hMcMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ) ) == NULL ) + IF( ( hMcMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - if ( ( hMcMasa->direction_vector_m[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } } } - hMcMasa->no_col_avg_diff = (int8_t) ( DIRAC_NO_COL_AVG_DIFF_NS / dirac_slot_ns ); - for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { - if ( ( hMcMasa->buffer_intensity_real[i] = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL ) + IF( ( hMcMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - if ( ( hMcMasa->buffer_intensity_real[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->direction_vector_e[i][j] = (Word16 *) malloc( hMcMasa->nbands * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->buffer_intensity_real[i][j], hMcMasa->nbands ); } } - if ( ( hMcMasa->buffer_intensity_real_vert = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL ) + hMcMasa->no_col_avg_diff = (Word8) ( DIRAC_NO_COL_AVG_DIFF_NS / dirac_slot_ns ); + move16(); + + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + IF( ( hMcMasa->buffer_intensity_real_fx[i] = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + + FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) + { + IF( ( hMcMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); + } + } + set16_fx( hMcMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF ); + + IF( ( hMcMasa->buffer_intensity_real_vert_fx = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) + FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) { - if ( ( hMcMasa->buffer_intensity_real_vert[j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->buffer_intensity_real_vert_fx[j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->buffer_intensity_real_vert[j], hMcMasa->nbands ); + set_zero_fx( hMcMasa->buffer_intensity_real_vert_fx[j], hMcMasa->nbands ); } - if ( ( hMcMasa->buffer_energy = (float *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( float ) ) ) == NULL ) + IF( ( hMcMasa->buffer_energy_fx = (Word32 *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero( hMcMasa->buffer_energy, hMcMasa->nbands * hMcMasa->no_col_avg_diff ); + set_zero_fx( hMcMasa->buffer_energy_fx, hMcMasa->nbands * hMcMasa->no_col_avg_diff ); + set16_fx( hMcMasa->buffer_intensity_real_vert_q, 31, DIRAC_NO_COL_AVG_DIFF ); + set16_fx( hMcMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF ); - if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 ) + IF( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 ) { - mvr2r( ls_azimuth_CICP6, ls_azimuth, nchan_inp - 1 ); - mvr2r( ls_elevation_CICP6, ls_elevation, nchan_inp - 1 ); + Copy32( ls_azimuth_CICP6_fx, ls_azimuth, nchan_inp - 1 ); + Copy32( ls_elevation_CICP6_fx, ls_elevation, nchan_inp - 1 ); hMcMasa->numHorizontalChannels = 5; + move16(); hMcMasa->isHorizontalSetup = 1; + move16(); } - else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 ) + ELSE IF( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 ) { - mvr2r( ls_azimuth_CICP12, ls_azimuth, nchan_inp - 1 ); - mvr2r( ls_elevation_CICP12, ls_elevation, nchan_inp - 1 ); + Copy32( ls_azimuth_CICP12_fx, ls_azimuth, nchan_inp - 1 ); + Copy32( ls_elevation_CICP12_fx, ls_elevation, nchan_inp - 1 ); hMcMasa->numHorizontalChannels = 7; + move16(); hMcMasa->isHorizontalSetup = 1; + move16(); } - else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 ) + ELSE IF( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 ) { - mvr2r( ls_azimuth_CICP14, ls_azimuth, nchan_inp - 1 ); - mvr2r( ls_elevation_CICP14, ls_elevation, nchan_inp - 1 ); + Copy32( ls_azimuth_CICP14_fx, ls_azimuth, nchan_inp - 1 ); + Copy32( ls_elevation_CICP14_fx, ls_elevation, nchan_inp - 1 ); hMcMasa->numHorizontalChannels = 5; + move16(); hMcMasa->isHorizontalSetup = 0; + move16(); } - else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 ) + ELSE IF( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 ) { - mvr2r( ls_azimuth_CICP16, ls_azimuth, nchan_inp - 1 ); - mvr2r( ls_elevation_CICP16, ls_elevation, nchan_inp - 1 ); + Copy32( ls_azimuth_CICP16_fx, ls_azimuth, nchan_inp - 1 ); + Copy32( ls_elevation_CICP16_fx, ls_elevation, nchan_inp - 1 ); hMcMasa->numHorizontalChannels = 5; + move16(); hMcMasa->isHorizontalSetup = 0; + move16(); } - else + ELSE { - mvr2r( ls_azimuth_CICP19, ls_azimuth, nchan_inp - 1 ); - mvr2r( ls_elevation_CICP19, ls_elevation, nchan_inp - 1 ); + Copy32( ls_azimuth_CICP19_fx, ls_azimuth, nchan_inp - 1 ); + Copy32( ls_elevation_CICP19_fx, ls_elevation, nchan_inp - 1 ); hMcMasa->numHorizontalChannels = 7; + move16(); hMcMasa->isHorizontalSetup = 0; + move16(); } - if ( hMcMasa->separateChannelEnabled ) + IF( hMcMasa->separateChannelEnabled ) { - mvr2r( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); - mvr2r( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); - hMcMasa->numHorizontalChannels--; + Copy32( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); + Copy32( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); + hMcMasa->numHorizontalChannels = sub( hMcMasa->numHorizontalChannels, 1 ); + move16(); } - computeEvenLayout( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels ); - if ( !hMcMasa->isHorizontalSetup ) + computeEvenLayout_fx( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels ); + IF( !hMcMasa->isHorizontalSetup ) { - computeEvenLayout( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], numAnalysisChannels - hMcMasa->numHorizontalChannels ); + computeEvenLayout_fx( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], numAnalysisChannels - hMcMasa->numHorizontalChannels ); } - for ( i = 0; i < numAnalysisChannels; i++ ) + FOR( i = 0; i < numAnalysisChannels; i++ ) { - hMcMasa->chnlToFoaMtx[0][i] = 1.0f; - hMcMasa->chnlToFoaMtx[1][i] = sinf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 ); - hMcMasa->chnlToFoaMtx[2][i] = sinf( ls_elevation[i] * PI_OVER_180 ); - hMcMasa->chnlToFoaMtx[3][i] = cosf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 ); + hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; + move32(); + hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth[i], 91 /*32767/360*/ ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ) ); + move32(); + hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ), 16 ); + move32(); + hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth[i], 91 ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ) ); + move32(); - hMcMasa->chnlToFoaEvenMtx[0][i] = 1.0f; - hMcMasa->chnlToFoaEvenMtx[1][i] = sinf( ls_azimuth_even[i] * PI_OVER_180 ); - hMcMasa->chnlToFoaEvenMtx[2][i] = 0.0f; - hMcMasa->chnlToFoaEvenMtx[3][i] = cosf( ls_azimuth_even[i] * PI_OVER_180 ); + hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31; + move32(); + hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even[i], 91 ), 7 ) ) ), 16 ); + move32(); + hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0; + move32(); + hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even[i], 91 ), 7 ) ) ), 16 ); + move32(); } hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes; + move16(); - mvr2r( ls_azimuth, hMcMasa->ls_azimuth, numAnalysisChannels ); + Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); - for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) + FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) { - left_min = 360.0f; - right_min = -360.0f; + left_min = L_shl( 360, 22 ); + right_min = L_negate( L_shl( 360, 22 ) ); - for ( j = 0; j < hMcMasa->numHorizontalChannels; j++ ) + FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ ) { - azi_diff = ls_azimuth[j] - ls_azimuth[i]; + azi_diff = L_sub( ls_azimuth[j], ls_azimuth[i] ); - if ( azi_diff > 180.0f ) + IF( GT_32( azi_diff, ( 180 << 22 ) ) ) { - azi_diff -= 360.0f; + azi_diff = L_sub( azi_diff, 360 << 22 ); } - else if ( azi_diff < -180.0f ) + ELSE IF( LT_32( azi_diff, -( 180 << 22 ) ) ) { - azi_diff += 360.0f; + azi_diff = L_add( azi_diff, 360 << 22 ); } - - if ( azi_diff < left_min && azi_diff > 0.0f ) + test(); + IF( LT_32( azi_diff, left_min ) && GT_32( azi_diff, 0 ) ) { hMcMasa->leftNearest[i] = j; + move16(); left_min = azi_diff; + move32(); } - - if ( azi_diff > right_min && azi_diff < 0.0f ) + test(); + IF( GT_32( azi_diff, right_min ) && LT_32( azi_diff, 0 ) ) { hMcMasa->rightNearest[i] = j; + move16(); right_min = azi_diff; + move32(); } } } - hMcMasa->prevMultiChEne = 0.0f; - hMcMasa->prevDownmixEne = 0.0f; - hMcMasa->prevEQ = 1.0f; - input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); - for ( i = 0; i < input_frame; i++ ) + hMcMasa->prevMultiChEne_fx = 0; + move32(); + hMcMasa->prevDownmixEne_fx = 0; + move32(); + hMcMasa->prevMultiChEne_e = 0; + move16(); + hMcMasa->prevDownmixEne_e = 0; + move16(); + hMcMasa->prevEQ_e = 1; + move16(); + hMcMasa->prevEQ_fx = 1073741824; + move32(); + input_frame = (Word16) Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ); + FOR( i = 0; i < input_frame; i++ ) { - hMcMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame ); + hMcMasa->interpolator_fx[i] = div_s( i, input_frame ); + move16(); } mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); hMcMasa->index_buffer_intensity = 0; - + move16(); st_ivas->hMcMasa = hMcMasa; return error; } - - -/*------------------------------------------------------------------------- - * ivas_mcmasa_enc_reconfig() - * - * Reconfigure McMASA encoder - *------------------------------------------------------------------------*/ - -ivas_error ivas_mcmasa_enc_reconfig( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#else +ivas_error ivas_mcmasa_enc_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) { - int32_t ivas_total_brate; + int16_t i, j; + float tmp_f; + MCMASA_ENC_HANDLE hMcMasa; + MASA_ENCODER_HANDLE hMasa; + float ls_azimuth[MCMASA_MAX_ANA_CHANS]; + float ls_elevation[MCMASA_MAX_ANA_CHANS]; + float ls_azimuth_even[MCMASA_MAX_ANA_CHANS]; + int16_t numAnalysisChannels; + float left_min, right_min, azi_diff; + const int16_t *band_mapping; + int16_t maxBin, input_frame; + int16_t nchan_inp; + int32_t input_Fs; + int32_t dirac_slot_ns; + IVAS_FB_CFG *fb_cfg, *fb_cfgLfe; ivas_error error; error = IVAS_ERR_OK; - ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" ); + hMasa = st_ivas->hMasa; - if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) + if ( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL ) { - /* bitrate changed, may need to do something */ + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } - /* brute-force solution: close McMASA and re-instantiate with new settings */ - ivas_masa_enc_close( &( st_ivas->hMasa ) ); - ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); + nchan_inp = st_ivas->hEncoderConfig->nchan_inp; + input_Fs = st_ivas->hEncoderConfig->input_Fs; - /* Determine if to separate some channels from the analysis */ -#ifndef IVAS_FLOAT_FIXED - ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); -#else - ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); -#endif + /* Determine if to separate some channels from the analysis */ + ivas_mcmasa_set_separate_channel_mode( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate ); + + numAnalysisChannels = nchan_inp - 1; + if ( hMcMasa->separateChannelEnabled ) + { + numAnalysisChannels = nchan_inp - 2; + } + + /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */ + if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + + /* Determine the number of bands */ + hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands; + hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands; + + /* Determine band grouping */ + if ( hMcMasa->nbands == 24 ) + { + for ( i = 0; i < hMcMasa->nbands + 1; i++ ) { - return error; + hMcMasa->band_grouping[i] = MASA_band_grouping_24[i] * CLDFB_TO_MDFT_FAC; } - - if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + } + else + { + band_mapping = hMasa->data.band_mapping; + for ( i = 0; i < hMcMasa->nbands + 1; i++ ) { - return error; + hMcMasa->band_grouping[i] = MASA_band_grouping_24[band_mapping[i]] * CLDFB_TO_MDFT_FAC; } - - /* core SCE, CPE reconfiguration happens later */ } - return error; -} + maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH * CLDFB_TO_MDFT_FAC + 0.5f ); + + for ( i = 1; i < hMcMasa->nbands + 1; i++ ) + { + if ( hMcMasa->band_grouping[i] >= maxBin ) + { + hMcMasa->band_grouping[i] = maxBin; + hMcMasa->nbands = i; + break; + } + } + + /* initialize delay compensation */ + hMcMasa->num_samples_delay_comp = NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); +#ifdef DISABLE_DIRAC_DELAY_COMP + hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */ +#endif + tmp_f = (float) hMcMasa->num_samples_delay_comp / (float) ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ); + hMcMasa->num_slots_delay_comp = (int16_t) ( tmp_f ); + + if ( tmp_f > (float) hMcMasa->num_slots_delay_comp ) + { + hMcMasa->num_slots_delay_comp++; + hMcMasa->offset_comp = -hMcMasa->num_samples_delay_comp; + hMcMasa->num_samples_delay_comp = hMcMasa->num_slots_delay_comp * NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ); + hMcMasa->offset_comp += hMcMasa->num_samples_delay_comp; + } + else + { + hMcMasa->offset_comp = 0; + } + + /* set FB config. */ + if ( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Allocate and initialize FB mixer handle */ + if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + + if ( hMcMasa->separateChannelEnabled ) + { + /* TD Energy calculation with LP */ + if ( ( hMcMasa->delay_buffer_lfe[0] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + + if ( ( hMcMasa->delay_buffer_lfe[1] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + hMcMasa->hFbMixerLfe = NULL; + } + else + { + /* Allocate and initialize FB mixer handle for LFE channel */ + if ( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + hMcMasa->delay_buffer_lfe[0] = NULL; + hMcMasa->delay_buffer_lfe[1] = NULL; + } + + if ( hMcMasa->separateChannelEnabled ) + { + int16_t bufferSize; + + /* Ring buffer for the filterbank of the LFE analysis. + * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */ + bufferSize = (int16_t) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES ); + for ( i = 0; i < 2; i++ ) + { + if ( ( hMcMasa->lfeAnaRingBuffer[i] = (float *) malloc( bufferSize * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->lfeAnaRingBuffer[i], bufferSize ); + hMcMasa->lowpassSum[i] = 0.0f; + } + hMcMasa->ringBufferPointer = 0; + hMcMasa->ringBufferSize = bufferSize; + } + + + dirac_slot_ns = DIRAC_SLOT_ENC_NS; + + /* intensity 3-dim */ + for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + if ( ( hMcMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + if ( ( hMcMasa->direction_vector_m[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + } + } + + hMcMasa->no_col_avg_diff = (int8_t) ( DIRAC_NO_COL_AVG_DIFF_NS / dirac_slot_ns ); + for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + if ( ( hMcMasa->buffer_intensity_real[i] = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + + for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) + { + if ( ( hMcMasa->buffer_intensity_real[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->buffer_intensity_real[i][j], hMcMasa->nbands ); + } + } + + if ( ( hMcMasa->buffer_intensity_real_vert = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + + for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) + { + if ( ( hMcMasa->buffer_intensity_real_vert[j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->buffer_intensity_real_vert[j], hMcMasa->nbands ); + } + + if ( ( hMcMasa->buffer_energy = (float *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); + } + set_zero( hMcMasa->buffer_energy, hMcMasa->nbands * hMcMasa->no_col_avg_diff ); + + if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 ) + { + mvr2r( ls_azimuth_CICP6, ls_azimuth, nchan_inp - 1 ); + mvr2r( ls_elevation_CICP6, ls_elevation, nchan_inp - 1 ); + hMcMasa->numHorizontalChannels = 5; + hMcMasa->isHorizontalSetup = 1; + } + else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 ) + { + mvr2r( ls_azimuth_CICP12, ls_azimuth, nchan_inp - 1 ); + mvr2r( ls_elevation_CICP12, ls_elevation, nchan_inp - 1 ); + hMcMasa->numHorizontalChannels = 7; + hMcMasa->isHorizontalSetup = 1; + } + else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 ) + { + mvr2r( ls_azimuth_CICP14, ls_azimuth, nchan_inp - 1 ); + mvr2r( ls_elevation_CICP14, ls_elevation, nchan_inp - 1 ); + hMcMasa->numHorizontalChannels = 5; + hMcMasa->isHorizontalSetup = 0; + } + else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 ) + { + mvr2r( ls_azimuth_CICP16, ls_azimuth, nchan_inp - 1 ); + mvr2r( ls_elevation_CICP16, ls_elevation, nchan_inp - 1 ); + hMcMasa->numHorizontalChannels = 5; + hMcMasa->isHorizontalSetup = 0; + } + else + { + mvr2r( ls_azimuth_CICP19, ls_azimuth, nchan_inp - 1 ); + mvr2r( ls_elevation_CICP19, ls_elevation, nchan_inp - 1 ); + hMcMasa->numHorizontalChannels = 7; + hMcMasa->isHorizontalSetup = 0; + } + + if ( hMcMasa->separateChannelEnabled ) + { + mvr2r( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); + mvr2r( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); + hMcMasa->numHorizontalChannels--; + } + + computeEvenLayout( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels ); + if ( !hMcMasa->isHorizontalSetup ) + { + computeEvenLayout( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], numAnalysisChannels - hMcMasa->numHorizontalChannels ); + } + + for ( i = 0; i < numAnalysisChannels; i++ ) + { + hMcMasa->chnlToFoaMtx[0][i] = 1.0f; + hMcMasa->chnlToFoaMtx[1][i] = sinf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 ); + hMcMasa->chnlToFoaMtx[2][i] = sinf( ls_elevation[i] * PI_OVER_180 ); + hMcMasa->chnlToFoaMtx[3][i] = cosf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 ); + + hMcMasa->chnlToFoaEvenMtx[0][i] = 1.0f; + hMcMasa->chnlToFoaEvenMtx[1][i] = sinf( ls_azimuth_even[i] * PI_OVER_180 ); + hMcMasa->chnlToFoaEvenMtx[2][i] = 0.0f; + hMcMasa->chnlToFoaEvenMtx[3][i] = cosf( ls_azimuth_even[i] * PI_OVER_180 ); + } + + hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes; + + mvr2r( ls_azimuth, hMcMasa->ls_azimuth, numAnalysisChannels ); + + for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) + { + left_min = 360.0f; + right_min = -360.0f; + + for ( j = 0; j < hMcMasa->numHorizontalChannels; j++ ) + { + azi_diff = ls_azimuth[j] - ls_azimuth[i]; + + if ( azi_diff > 180.0f ) + { + azi_diff -= 360.0f; + } + else if ( azi_diff < -180.0f ) + { + azi_diff += 360.0f; + } + + if ( azi_diff < left_min && azi_diff > 0.0f ) + { + hMcMasa->leftNearest[i] = j; + left_min = azi_diff; + } + + if ( azi_diff > right_min && azi_diff < 0.0f ) + { + hMcMasa->rightNearest[i] = j; + right_min = azi_diff; + } + } + } + + hMcMasa->prevMultiChEne = 0.0f; + hMcMasa->prevDownmixEne = 0.0f; + hMcMasa->prevEQ = 1.0f; + input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); + for ( i = 0; i < input_frame; i++ ) + { + hMcMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame ); + } + + mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); + + hMcMasa->index_buffer_intensity = 0; + + st_ivas->hMcMasa = hMcMasa; + + return error; +} +#endif +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * ivas_mcmasa_enc_reconfig() + * + * Reconfigure McMASA encoder + *------------------------------------------------------------------------*/ + +ivas_error ivas_mcmasa_enc_reconfig_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + int32_t ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + + IF( NE_32( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ) ) + { + /* bitrate changed, may need to do something */ + + /* brute-force solution: close McMASA and re-instantiate with new settings */ + ivas_masa_enc_close( &( st_ivas->hMasa ) ); + + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); + + /* Determine if to separate some channels from the analysis */ + ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); + + IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + { + return error; + } + IF( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* core SCE, CPE reconfiguration happens later */ + } + + return error; +} +#else +/*------------------------------------------------------------------------- + * ivas_mcmasa_enc_reconfig() + * + * Reconfigure McMASA encoder + *------------------------------------------------------------------------*/ + +ivas_error ivas_mcmasa_enc_reconfig( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + int32_t ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + + IF( NE_32( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ) ) + { + /* bitrate changed, may need to do something */ + + /* brute-force solution: close McMASA and re-instantiate with new settings */ + ivas_masa_enc_close( &( st_ivas->hMasa ) ); +#ifndef IVAS_FLOAT_FIXED + ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#else + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#endif + + /* Determine if to separate some channels from the analysis */ +#ifndef IVAS_FLOAT_FIXED + ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); +#else + ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); +#endif + + IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + { + return error; + } +#ifndef IVAS_FLOAT_FIXED + if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#else + IF( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) +#endif + { + return error; + } + + /* core SCE, CPE reconfiguration happens later */ + } + + return error; +} +#endif +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * ivas_mcmasa_enc_close() + * + * + *--------------------------------------------------------------------------*/ + +void ivas_mcmasa_enc_close_fx( + MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */ + const int32_t input_Fs /* i : input sampling rate */ +) +{ + Word16 i, j; + + test(); + IF( hMcMasa == NULL || *hMcMasa == NULL ) + { + return; + } + + IF( ( *hMcMasa )->separateChannelEnabled ) + { + free( ( *hMcMasa )->delay_buffer_lfe[0] ); + free( ( *hMcMasa )->delay_buffer_lfe[1] ); + + FOR( i = 0; i < 2; i++ ) + { + free( ( *hMcMasa )->lfeAnaRingBuffer[i] ); + } + } + + ivas_FB_mixer_close( &( *hMcMasa )->hFbMixer, input_Fs, 0 ); + + IF( !( *hMcMasa )->separateChannelEnabled ) + { + ivas_FB_mixer_close( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 ); + } + + /* intensity 3-dim */ + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + free( ( *hMcMasa )->direction_vector_m_fx[i][j] ); + ( *hMcMasa )->direction_vector_m_fx[i][j] = NULL; + } + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + free( ( *hMcMasa )->direction_vector_e[i][j] ); + ( *hMcMasa )->direction_vector_e[i][j] = NULL; + } + + FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ ) + { + free( ( *hMcMasa )->buffer_intensity_real_fx[i][j] ); + ( *hMcMasa )->buffer_intensity_real_fx[i][j] = NULL; + } + + free( ( *hMcMasa )->buffer_intensity_real_fx[i] ); + ( *hMcMasa )->buffer_intensity_real_fx[i] = NULL; + + free( ( *hMcMasa )->direction_vector_m_fx[i] ); + ( *hMcMasa )->direction_vector_m_fx[i] = NULL; + + free( ( *hMcMasa )->direction_vector_e[i] ); + ( *hMcMasa )->direction_vector_e[i] = NULL; + } + + FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ ) + { + free( ( *hMcMasa )->buffer_intensity_real_vert_fx[j] ); + ( *hMcMasa )->buffer_intensity_real_vert_fx[j] = NULL; + } + free( ( *hMcMasa )->buffer_intensity_real_vert_fx ); + ( *hMcMasa )->buffer_intensity_real_vert_fx = NULL; + + free( ( *hMcMasa )->buffer_energy_fx ); + ( *hMcMasa )->buffer_energy_fx = NULL; + + free( ( *hMcMasa ) ); + ( *hMcMasa ) = NULL; + return; +} +#else /*--------------------------------------------------------------------------* * ivas_mcmasa_enc_close() * @@ -556,8 +1203,214 @@ void ivas_mcmasa_enc_close( return; } +#endif +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * ivas_mcmasa_enc() + * + * Multichannel MASA encoder + *--------------------------------------------------------------------------*/ + +void ivas_mcmasa_enc_fx( + MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */ + IVAS_QMETADATA_HANDLE hQMeta, /* o : Qmetadata handle */ + MASA_ENCODER_HANDLE hMasa, /* i/o: Encoder MASA handle */ + Word32 *data_fx[], /* i : Input frame of audio */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_transport, /* i : Number of transport channels */ + const Word16 nchan_inp, /* i : Number of input channels */ + const Word16 q_inp /* i : Input data q-format */ +) +{ + Word16 i, j, k; + Word16 nBands = hMcMasa->nbands; + move16(); + Word16 nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + UWord8 fixedDistance = 0; + move16(); + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 separatedChannelSignal[L_FRAME48k]; + + /* Compute low frequency energy */ + computeLfeEnergy_fx( hMcMasa, data_fx, input_frame, q_inp ); + + /* Sum center and LFE, move surround channels */ + v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); + FOR( i = 4; i < nchan_inp; i++ ) + { + Copy32( data_fx[i], data_fx[i - 1], input_frame ); + } + + IF( hMcMasa->separateChannelEnabled ) + { + /* Identify channel to separate */ + i = hMcMasa->separateChannelIndex; + move16(); + + /* Separate the identified channel */ + Copy32( data_fx[i], separatedChannelSignal, input_frame ); + + /* Move the remaining channels in order to perform the analysis without the separated channel */ + FOR( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ ) + { + Copy32( data_fx[i], data_fx[i - 1], input_frame ); + } + } + + /* Analysis */ + ivas_mcmasa_param_est_enc_fx( hMcMasa, hMasa, data_fx, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, input_frame, nchan_inp, q_inp ); + + /* Determine LFE-to-total energy ratio */ + FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hMasa->data.lfeToTotalEnergyRatio_fx[i] = BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ); + hMasa->data.lfeToTotalEnergyRatio_e[i] = add( sub( hMcMasa->lfeLfEne_e[i], hMcMasa->totalLfEne_e[i] ), hMasa->data.lfeToTotalEnergyRatio_e[i] ); + } + + /* Set analyzed values to the MASA struct */ + FOR( i = 0; i < nBands; i++ ) + { + FOR( j = 0; j < nBlocks; j++ ) + { + IF( hMcMasa->combineRatios ) + { + k = 0; + move16(); + } + ELSE + { + k = j; + move16(); + } + + hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; + move32(); + hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; + move32(); + hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; + move32(); + hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance; + move16(); + + IF( hQMeta->surcoh_band_data != NULL ) + { + hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (uint8_t) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q16 ) ) ); + hQMeta->surcoh_band_data[i].surround_coherence[j] = (uint8_t) round_fx( Mpy_32_32( surroundingCoherence_fx[k][i], L_shl( UINT8_MAX, Q16 ) ) ); + } + } + } + + /* At lower sampling rates, set zeros for higher bands that were not analyzed */ + IF( LT_16( nBands, hMcMasa->nCodingBands ) ) + { + FOR( i = nBands; i < hMcMasa->nCodingBands; i++ ) + { + FOR( j = 0; j < nBlocks; j++ ) + { + hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = 0; + move32(); + hQMeta->q_direction[0].band_data[i].elevation_fx[j] = 0; + move32(); + hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = 0; + move32(); + hQMeta->q_direction[0].band_data[i].distance[j] = 0; + move16(); + + IF( hQMeta->surcoh_band_data != NULL ) + { + hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = 0; + move16(); + hQMeta->surcoh_band_data[i].surround_coherence[j] = 0; + move16(); + } + } + } + } + + /* Downmix */ + ivas_mcmasa_dmx_fx( hMcMasa, data_fx, 31 - q_inp, input_frame, nchan_transport, nchan_inp ); + + IF( hMcMasa->separateChannelEnabled ) + { + /* Put separated channel back to data_f to first empty channel after the transport audio signals for encoding */ + Copy32( separatedChannelSignal, data_fx[2], input_frame ); + } + + /* Update mcMASA-relevant coding parameters */ + /* These are reset to default values as they may be modified during later processing. */ + hMasa->config.joinedSubframes = FALSE; + hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands; + move16(); + hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + hQMeta->all_coherence_zero = 1; + + /* Check spread coherence */ + i = 0; + move16(); + test(); + WHILE( LT_16( i, nBlocks ) && hQMeta->all_coherence_zero ) + { + j = 0; + move16(); + test(); + WHILE( LT_16( j, nBands ) && hQMeta->all_coherence_zero ) + { + IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX ) ) + { + hQMeta->all_coherence_zero = 0; + move16(); + } + j++; + } + i++; + } + /* Check surrounding coherence */ + IF( hQMeta->all_coherence_zero ) + { + Word32 diffuse_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 cohSignificant; + Word16 nSubFrames; + + IF( hMcMasa->combineRatios ) + { + nSubFrames = 1; + move16(); + } + ELSE + { + nSubFrames = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + } + + FOR( i = 0; i < nSubFrames; i++ ) + { + FOR( j = 0; j < nBands; j++ ) + { + diffuse_to_total_ratio_fx[i][j] = L_max( 0, L_sub( ONE_IN_Q31, energyRatio_fx[i][j] ) ); + move32(); + } + } + + cohSignificant = ivas_masa_surrcoh_signicant_fx( surroundingCoherence_fx, diffuse_to_total_ratio_fx, nSubFrames, nBands ); + IF( cohSignificant ) + { + hQMeta->all_coherence_zero = 0; + move16(); + } + } + hMasa->config.coherencePresent = !hQMeta->all_coherence_zero; + move16(); + return; +} +#else /*--------------------------------------------------------------------------* * ivas_mcmasa_enc() * @@ -725,7 +1578,7 @@ void ivas_mcmasa_enc( return; } - +#endif /*--------------------------------------------------------------------------* * ivas_mcmasa_param_est_enc() @@ -734,560 +1587,837 @@ void ivas_mcmasa_enc( *--------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -void ivas_mcmasa_param_est_enc( - MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */ - MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */ - float *data_f[], /* i : Audio frame in MC-format */ - float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */ - float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */ - float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */ - float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */ - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */ - const int16_t input_frame, /* i : Input frame size */ - const int16_t nchan_inp /* i : Number of input channels */ +void ivas_mcmasa_param_est_enc_fx( + MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */ + MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */ + Word32 *data_f[], /* i : Audio frame in MC-format */ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */ + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */ + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */ + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_inp, /* i : Number of input channels */ + const Word16 q_inp /* i : Number of input channels */ ) { - float reference_power[MDFT_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX]; - int16_t ts, i, j, d; - int16_t num_freq_bins, num_freq_bands, index; - float dir_v[DIRAC_NUM_DIMS]; -#ifdef IVAS_FLOAT_FIXED_ - Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 reference_power_fx[MDFT_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX]; + Word16 ts, i, j, d; + Word16 num_freq_bins, num_freq_bands, index; Word32 dir_v_fx[DIRAC_NUM_DIMS]; -#endif - int16_t l_ts; - float *pcm_in[MCMASA_MAX_ANA_CHANS]; - float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; - float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; - float *p_Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS]; - float *p_Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS]; - float Foa_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; - float Foa_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; - float FoaEven_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; - float FoaEven_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; - float intensity_even_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; - float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; - float diffuseness_vector[MASA_FREQUENCY_BANDS]; - float vertical_diffuseness_vector[MASA_FREQUENCY_BANDS]; - float diffuseness_m[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - float coherentEnergyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - int16_t band_m_idx, block_m_idx; - float renormalization_factor_diff[MASA_FREQUENCY_BANDS]; - float norm_tmp; - int16_t mrange[2], brange[2]; - int16_t numSubFramesForRatio; + Word16 out_exp[MASA_FREQUENCY_BANDS]; + Word16 q_vdv[MASA_FREQUENCY_BANDS]; + Word16 l_ts; + Word32 *pcm_in[MCMASA_MAX_ANA_CHANS]; + Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; + Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; + Word32 *p_Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS]; + Word32 *p_Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS]; + Word32 Foa_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + Word32 FoaEven_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + Word32 FoaEven_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word32 intensity_even_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; + Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; + Word32 diffuseness_m_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 diffuseness_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 coherentEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 coherentEnergyRatio_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 band_m_idx, block_m_idx; + Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; + Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS]; + Word32 norm_tmp_fx; + Word16 mrange[2], brange[2]; + Word16 numSubFramesForRatio; CovarianceMatrix COVls[MASA_FREQUENCY_BANDS]; - float absCOVls[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; - float lsEnergy[MCMASA_MAX_ANA_CHANS]; - float lsEnergySum, maxEne; - int16_t loudestCh; - float surrCoh, tempCoh, tempCoh2; - int16_t i1, i2, i3; - float angleDist, minAngleDist; - float currentAzi; - float lsEnergyRelation; - float tempLsEnergyRelation; - float stereoness, cohwideness, spreadCoh; - float stereoRatio, cohPanRatio; - float stereoCoh, cohPanCoh, cohRatio; - float renormalization_factor_coh[MASA_FREQUENCY_BANDS]; - int16_t numAnalysisChannels; - - num_freq_bins = input_frame / MDFT_NO_COL_MAX; + Word32 absCOVls_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; + Word16 absCOVls_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; + Word32 lsEnergy_fx[MCMASA_MAX_ANA_CHANS]; + Word16 lsEnergy_e[MCMASA_MAX_ANA_CHANS]; + Word32 lsEnergySum_fx, maxEne_fx; + Word16 lsEnergySum_e = 0, maxEne_e; + move16(); + Word16 loudestCh; + Word32 surrCoh_fx, tempCoh_fx, tempCoh2_fx; + Word16 surrCoh_e, tempCoh_e, tempCoh2_e; + Word16 i1, i2, i3; + Word32 angleDist_fx, minAngleDist_fx; + Word32 currentAzi_fx; + Word32 lsEnergyRelation_fx; + Word16 lsEnergyRelation_e; + Word32 tempLsEnergyRelation_fx; + Word16 tempLsEnergyRelation_e; + Word32 stereoness_fx, cohwideness_fx, spreadCoh_fx; + Word32 stereoRatio_fx, cohPanRatio_fx; + Word32 stereoCoh_fx, cohPanCoh_fx, cohRatio_fx; + Word16 stereoCoh_e, cohPanCoh_e, spreadCoh_e, stereoness_e; + Word32 renormalization_factor_coh_fx[MASA_FREQUENCY_BANDS]; + Word16 renormalization_factor_coh_e[MASA_FREQUENCY_BANDS]; + Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 numAnalysisChannels; + + num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX ); num_freq_bands = hMcMasa->nbands; - l_ts = input_frame / MDFT_NO_COL_MAX; + move16(); + l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX ); - numAnalysisChannels = nchan_inp - 1; - if ( hMcMasa->separateChannelEnabled ) + set16_fx( q_vdv, 31, MASA_FREQUENCY_BANDS ); + set16_fx( out_exp, 30, MASA_FREQUENCY_BANDS ); + + numAnalysisChannels = sub( nchan_inp, 1 ); + IF( hMcMasa->separateChannelEnabled ) { - numAnalysisChannels = nchan_inp - 2; + numAnalysisChannels = sub( nchan_inp, 2 ); } - if ( hMcMasa->combineRatios ) + IF( hMcMasa->combineRatios ) { /* Need to initialize renormalization_factors, and variables to be normalized */ - set_zero( renormalization_factor_diff, hMcMasa->nbands ); - set_zero( diffuseness_m[0], hMcMasa->nbands ); - set_zero( renormalization_factor_coh, hMcMasa->nbands ); - set_zero( surroundingCoherence[0], hMcMasa->nbands ); - set_zero( coherentEnergyRatio[0], hMcMasa->nbands ); + set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); + set16_fx( renormalization_factor_diff_e, 0, hMcMasa->nbands ); + set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); + set16_fx( &diffuseness_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); + set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); + set16_fx( renormalization_factor_coh_e, 31, hMcMasa->nbands ); + set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); + set16_fx( &surroundingCoherence_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); + set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); + set16_fx( &coherentEnergyRatio_e[0][0], 0, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); } /* Copy current frame to memory for delay compensation */ - for ( i = 0; i < numAnalysisChannels; i++ ) + FOR( i = 0; i < numAnalysisChannels; i++ ) { pcm_in[i] = data_f[i]; - p_Chnl_RealBuffer[i] = &Chnl_RealBuffer[i][0]; - p_Chnl_ImagBuffer[i] = &Chnl_ImagBuffer[i][0]; + p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; + p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; } /* do processing over all CLDFB time slots */ - for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) { mrange[0] = hMcMasa->block_grouping[block_m_idx]; + move16(); mrange[1] = hMcMasa->block_grouping[block_m_idx + 1]; + move16(); - for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { - hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0; - hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0; - hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0; + hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0; + move32(); + hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0; + move32(); + hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0; + move32(); } /* Reset variable */ - for ( i = 0; i < hMcMasa->nbands; i++ ) + FOR( i = 0; i < hMcMasa->nbands; i++ ) { - for ( j = 0; j < numAnalysisChannels; j++ ) + FOR( j = 0; j < numAnalysisChannels; j++ ) { - set_zero( COVls[i].xr[j], numAnalysisChannels ); - set_zero( COVls[i].xi[j], numAnalysisChannels ); + set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); + set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); + set16_fx( COVls[i].xr_e[j], 0, numAnalysisChannels ); + set16_fx( COVls[i].xi_e[j], 0, numAnalysisChannels ); } } - for ( ts = mrange[0]; ts < mrange[1]; ts++ ) + FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { - ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans ); + Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e; + Word16 inp_q = q_inp; + move16(); + move16(); + move16(); - ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans ); + ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer_fx, p_Chnl_ImagBuffer_fx, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans, 0 ); - for ( i = 0; i < numAnalysisChannels; i++ ) + ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans ); + + FOR( i = 0; i < numAnalysisChannels; i++ ) { pcm_in[i] += l_ts; + cr_q = s_min( cr_q, ivas_getScaleFactor32( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) ); + ci_q = s_min( ci_q, ivas_getScaleFactor32( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) ); } + sf = sub( s_min( cr_q, ci_q ), 5 ); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_sig32( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf + scale_sig32( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf + } + inp_q = add( inp_q, sf ); + c_e = sub( 31, inp_q ); + /* Compute covariance matrix */ - for ( i = 0; i < num_freq_bands; i++ ) + FOR( i = 0; i < num_freq_bands; i++ ) { brange[0] = hMcMasa->band_grouping[i]; + move16(); brange[1] = hMcMasa->band_grouping[i + 1]; - for ( j = brange[0]; j < brange[1]; j++ ) + move16(); + FOR( j = brange[0]; j < brange[1]; j++ ) { - compute_cov_mtx( Chnl_RealBuffer, Chnl_ImagBuffer, j, numAnalysisChannels, &( COVls[i] ) ); + compute_cov_mtx_fx( Chnl_RealBuffer_fx, Chnl_ImagBuffer_fx, j, numAnalysisChannels, &( COVls[i] ), sub( 31, inp_q ) ); } /* Store energies for guiding metadata encoding */ - hMasa->data.energy[block_m_idx][i] = 0.0f; - for ( j = 0; j < numAnalysisChannels; j++ ) + hMasa->data.energy_fx[block_m_idx][i] = 0; + move32(); + hMasa->data.energy_e[block_m_idx][i] = 31; + move16(); + FOR( j = 0; j < numAnalysisChannels; j++ ) { - hMasa->data.energy[block_m_idx][i] += COVls[i].xr[j][j]; + move32(); + hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] ); + } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IF( hMasa->data.energy_e[block_m_idx][i] < 31 ) + { + hMasa->data.energy[block_m_idx][i] = hMasa->data.energy_fx[block_m_idx][i] / (float) ( 1 << ( 31 - hMasa->data.energy_e[block_m_idx][i] ) ); + } + ELSE + { + hMasa->data.energy[block_m_idx][i] = hMasa->data.energy_fx[block_m_idx][i] * (float) ( 1 << ( hMasa->data.energy_e[block_m_idx][i] - 31 ) ); } +#endif } - if ( !hMcMasa->separateChannelEnabled ) + IF( !hMcMasa->separateChannelEnabled ) { /* Compute low frequency energy */ - for ( i = 0; i < numAnalysisChannels; i++ ) + FOR( i = 0; i < numAnalysisChannels; i++ ) { - for ( j = 0; j < CLDFB_TO_MDFT_FAC; j++ ) + FOR( j = 0; j < CLDFB_TO_MDFT_FAC; j++ ) { - hMcMasa->totalLfEne[block_m_idx] += Chnl_RealBuffer[i][j] * Chnl_RealBuffer[i][j] + Chnl_ImagBuffer[i][j] * Chnl_ImagBuffer[i][j]; + move32(); + hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] ); } } } /* Compute standard FOA */ /* W */ - v_add( Chnl_RealBuffer[0], Chnl_RealBuffer[1], Foa_RealBuffer[0], num_freq_bins ); - v_add( Chnl_ImagBuffer[0], Chnl_ImagBuffer[1], Foa_ImagBuffer[0], num_freq_bins ); - for ( i = 2; i < numAnalysisChannels; i++ ) + v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); + v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); + FOR( i = 2; i < numAnalysisChannels; i++ ) { - v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins ); - v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins ); + v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); + v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); } /* Y */ - v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins ); - for ( i = 1; i < numAnalysisChannels; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); } /* Z */ - if ( hMcMasa->isHorizontalSetup ) + IF( hMcMasa->isHorizontalSetup ) { /* Set zero for horizontal setups */ - set_zero( Foa_RealBuffer[2], num_freq_bins ); - set_zero( Foa_ImagBuffer[2], num_freq_bins ); + set_zero_fx( Foa_RealBuffer_fx[2], num_freq_bins ); + set_zero_fx( Foa_ImagBuffer_fx[2], num_freq_bins ); } - else + ELSE { - v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins ); - for ( i = 1; i < numAnalysisChannels; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); } } /* X */ - v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins ); - for ( i = 1; i < numAnalysisChannels; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); } /* Compute even FOA */ /* W */ - mvr2r( Foa_RealBuffer[0], FoaEven_RealBuffer[0], num_freq_bins ); - mvr2r( Foa_ImagBuffer[0], FoaEven_ImagBuffer[0], num_freq_bins ); + Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); + Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); /* Y */ - v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_RealBuffer[1], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_ImagBuffer[1], num_freq_bins ); - for ( i = 1; i < numAnalysisChannels; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[1][i], FoaEven_RealBuffer[1], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaEvenMtx[1][i], FoaEven_ImagBuffer[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); } /* Z (even setups are handled as horizontal) */ - set_zero( FoaEven_RealBuffer[2], num_freq_bins ); - set_zero( FoaEven_ImagBuffer[2], num_freq_bins ); + set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); + set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); /* X */ - v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_RealBuffer[3], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_ImagBuffer[3], num_freq_bins ); - for ( i = 1; i < numAnalysisChannels; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_RealBuffer[3], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_ImagBuffer[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); } /* Direction estimation */ - computeIntensityVector_enc( + computeIntensityVector_enc_fx( hMcMasa->band_grouping, - Foa_RealBuffer, - Foa_ImagBuffer, + Foa_RealBuffer_fx, + Foa_ImagBuffer_fx, 0, num_freq_bands, - intensity_real ); + intensity_real_fx ); - computeDirectionVectors( - intensity_real[0], - intensity_real[1], - intensity_real[2], + computeDirectionVectors_fixed( + intensity_real_fx[0], + intensity_real_fx[1], + intensity_real_fx[2], 0, num_freq_bands, - direction_vector[0], - direction_vector[1], - direction_vector[2] ); + direction_vector_fx[0], + direction_vector_fx[1], + direction_vector_fx[2], c_e ); /* Power and intensity estimation for diffuseness */ - computeIntensityVector_enc( + computeIntensityVector_enc_fx( hMcMasa->band_grouping, - FoaEven_RealBuffer, - FoaEven_ImagBuffer, + FoaEven_RealBuffer_fx, + FoaEven_ImagBuffer_fx, 0, num_freq_bands, - intensity_even_real ); - - computeReferencePower_enc( hMcMasa->band_grouping, - FoaEven_RealBuffer, - FoaEven_ImagBuffer, - reference_power[ts], - 0, - num_freq_bands, - MC_FORMAT, - 0, - FOA_CHANNELS, - NULL, - NULL ); + intensity_even_real_fx ); + + computeReferencePower_enc_fx( hMcMasa->band_grouping, + FoaEven_RealBuffer_fx, + FoaEven_ImagBuffer_fx, + reference_power_fx[ts], + 0, + num_freq_bands, + MC_FORMAT, + 0, + FOA_CHANNELS ); /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hMcMasa->index_buffer_intensity = ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ) + 1; /* averaging_length = 32 */ + move16(); index = hMcMasa->index_buffer_intensity; - for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + move16(); + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { /* only real part needed */ - mvr2r( intensity_even_real[i], &( hMcMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands ); + Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); } - mvr2r( reference_power[ts], &( hMcMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + hMcMasa->buffer_intensity_real_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); + move16(); + Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + hMcMasa->buffer_energy_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); + move16(); - computeDiffuseness_mdft( hMcMasa->buffer_intensity_real, hMcMasa->buffer_energy, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector ); + computeDiffuseness_mdft_fx( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, out_exp ); /* Compute vertical diffuseness, and tune original diffuseness if needed */ - if ( !hMcMasa->isHorizontalSetup ) + IF( !hMcMasa->isHorizontalSetup ) { - mvr2r( intensity_real[2], &( hMcMasa->buffer_intensity_real_vert[index - 1][0] ), num_freq_bands ); - computeVerticalDiffuseness( hMcMasa->buffer_intensity_real_vert, hMcMasa->buffer_energy, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector ); -#ifdef IVAS_FLOAT_FIXED - //////////////////////// to be removed /////////////////////////////// - Word32 x1_fx[MASA_FREQUENCY_BANDS]; - Word32 x2_fx[MASA_FREQUENCY_BANDS]; - Word32 y_fx[MASA_FREQUENCY_BANDS]; - Word16 x1_q_fx[MASA_FREQUENCY_BANDS]; - Word16 x2_q_fx[MASA_FREQUENCY_BANDS]; - Word16 y_q_fx[MASA_FREQUENCY_BANDS]; - FOR( i = 0; i < num_freq_bands; i++ ) - { - x1_q_fx[i] = Q_factor_L( diffuseness_vector[i] ); - x1_fx[i] = (Word32) ( diffuseness_vector[i] * ( W_shl( 1, x1_q_fx[i] ) ) ); - x2_q_fx[i] = Q_factor_L( vertical_diffuseness_vector[i] ); - x2_fx[i] = (Word32) ( vertical_diffuseness_vector[i] * ( W_shl( 1, x2_q_fx[i] ) ) ); - } - ///////////////////////////////////////////////////////////////////////// - - v_min_fx( (const Word32 *) x1_fx, x1_q_fx, (const Word32 *) x2_fx, x2_q_fx, y_fx, y_q_fx, num_freq_bands ); - - //////////////////////// to be removed //////////////////////////////// - FOR( i = 0; i < num_freq_bands; i++ ) - { - diffuseness_vector[i] = (Float32) y_fx[i] / ( W_shl( 1, y_q_fx[i] ) ); - } - /////////////////////////////////////////////////////////////////////// -#else - v_min( diffuseness_vector, vertical_diffuseness_vector, diffuseness_vector, num_freq_bands ); -#endif + Copy32( intensity_real_fx[2], &( hMcMasa->buffer_intensity_real_vert_fx[index - 1][0] ), num_freq_bands ); + hMcMasa->buffer_intensity_real_vert_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); + move16(); + computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q ); + v_min_fx( diffuseness_vector_fx, out_exp, vertical_diffuseness_vector_fx, q_vdv, diffuseness_vector_fx, out_exp, num_freq_bands ); } - for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { - norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] ); - - hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx]; - hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx]; - hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx]; - - if ( hMcMasa->combineRatios ) + norm_tmp_fx = Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q31, diffuseness_vector_fx[band_m_idx] ) ); /*2q-31*/ + hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), sub( 31, sub( shl( inp_q, 1 ), 32 ) ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); + move32(); + hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), sub( 31, sub( shl( inp_q, 1 ), 32 ) ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); + move32(); + hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), sub( 31, sub( shl( inp_q, 1 ), 32 ) ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); + move32(); + IF( hMcMasa->combineRatios ) { - diffuseness_m[0][band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx]; - renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx]; + diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[0][band_m_idx], diffuseness_e[0][band_m_idx], Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &diffuseness_e[0][band_m_idx] ); + move32(); + renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &renormalization_factor_diff_e[band_m_idx] ); + move32(); } - else + ELSE { - diffuseness_m[block_m_idx][band_m_idx] = diffuseness_vector[band_m_idx]; + diffuseness_m_fx[block_m_idx][band_m_idx] = diffuseness_vector_fx[band_m_idx]; + diffuseness_e[block_m_idx][band_m_idx] = Q31; + move32(); } } } - for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { - for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + Word16 max_e = MIN_16; + move16(); + FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) { - dir_v[d] = hMcMasa->direction_vector_m[d][block_m_idx][band_m_idx]; + max_e = s_max( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] ); } -#ifdef IVAS_FLOAT_FIXED_ - /*==========================================flt-2-fix======================================================*/ - Word16 q_dir_e = 0; - f2me_buf( dir_v, dir_v_fx, &q_dir_e, 3 ); - Scale_sig32( dir_v_fx, 3, -1 ); - /*==========================================flt-2-fix======================================================*/ - - ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, Q30, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] ); - - /*==========================================fix-2-flt======================================================*/ - azimuth_m_values[block_m_idx][band_m_idx] = fixedToFloat( azimuth_m_values_fx[block_m_idx][band_m_idx], Q22 ); - elevation_m_values[block_m_idx][band_m_idx] = fixedToFloat( elevation_m_values_fx[block_m_idx][band_m_idx], Q22 ); - /*==========================================fix-2-flt======================================================*/ -#else - ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] ); -#endif + max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/ + FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + dir_v_fx[d] = L_shr( hMcMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) ); + move32(); + } + Word16 div_q = sub( 31, max_e ); + ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, div_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] ); + elevation_m_values_fx[block_m_idx][band_m_idx] = L_add( elevation_m_values_fx[block_m_idx][band_m_idx], L_shr( elevation_m_values_fx[block_m_idx][band_m_idx], 5 ) ); + move32(); } /* Coherence processing */ - for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { /* Compute absolute values */ - for ( i = 0; i < numAnalysisChannels; i++ ) + FOR( i = 0; i < numAnalysisChannels; i++ ) { - for ( j = i; j < numAnalysisChannels; j++ ) + FOR( j = i; j < numAnalysisChannels; j++ ) { - absCOVls[i][j] = sqrtf( ( COVls[band_m_idx].xr[i][j] * COVls[band_m_idx].xr[i][j] + COVls[band_m_idx].xi[i][j] * COVls[band_m_idx].xi[i][j] ) ); + Word32 temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] ); + absCOVls_fx[i][j] = Sqrt32( temp, &absCOVls_e[i][j] ); + move32(); } - lsEnergy[i] = absCOVls[i][i]; + lsEnergy_fx[i] = absCOVls_fx[i][i]; + move32(); + lsEnergy_e[i] = absCOVls_e[i][i]; + move16(); } /* Find loudest channel */ - maxEne = lsEnergy[0]; + maxEne_fx = lsEnergy_fx[0]; + move32(); + maxEne_e = lsEnergy_e[0]; + move16(); loudestCh = 0; - for ( i = 1; i < numAnalysisChannels; i++ ) + move16(); + FOR( i = 1; i < numAnalysisChannels; i++ ) { - if ( lsEnergy[i] > maxEne ) + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], maxEne_fx, maxEne_e ), 1 ) ) { - maxEne = lsEnergy[i]; + maxEne_fx = lsEnergy_fx[i]; + move32(); + maxEne_e = lsEnergy_e[i]; + move16(); loudestCh = i; + move16(); } } /* Compute surrounding coherence */ - surrCoh = 1.0f; - for ( i = 0; i < numAnalysisChannels; i++ ) + surrCoh_fx = ONE_IN_Q31; + move32(); + surrCoh_e = 0; + move16(); + FOR( i = 0; i < numAnalysisChannels; i++ ) { - if ( i != loudestCh ) + IF( NE_16( i, loudestCh ) ) { - if ( i < loudestCh ) + IF( LT_16( i, loudestCh ) ) { i1 = i; + move16(); i2 = loudestCh; + move16(); } - else + ELSE { i1 = loudestCh; + move16(); i2 = i; + move16(); + } + Word16 temp_exp = add( lsEnergy_e[i1], lsEnergy_e[i2] ); + Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp ); + tempCoh_e = 0; + move16(); + tempCoh_fx = L_shl( BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], temp, &tempCoh_e ), 16 ); + tempCoh_e = add( sub( absCOVls_e[i1][i2], temp_exp ), tempCoh_e ); + IF( NE_16( BASOP_Util_Cmp_Mant32Exp( surrCoh_fx, surrCoh_e, tempCoh_fx, tempCoh_e ), -1 ) ) + { + surrCoh_fx = tempCoh_fx; + move32(); + surrCoh_e = tempCoh_e; + move16(); } - tempCoh = absCOVls[i1][i2] / ( sqrtf( ( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) ) ); - surrCoh = ( surrCoh < tempCoh ) ? surrCoh : tempCoh; } } - surrCoh = surrCoh * surrCoh; - surrCoh = ( surrCoh < 1.0f ) ? surrCoh : 1.0f; - surrCoh = ( surrCoh > 0.0f ) ? surrCoh : 0.0f; + surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); + surrCoh_e = 0; + move16(); + surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx ); + IF( GE_32( surrCoh_fx, ONE_IN_Q31 ) ) + { + surrCoh_fx = ONE_IN_Q31; + move32(); + } + surrCoh_fx = L_max( surrCoh_fx, 0 ); /* Compute spread coherence */ - if ( elevation_m_values[block_m_idx][band_m_idx] < NEAR_HORIZONTAL_PLANE_ELEVATION ) /* Computed only near horizontal plane */ + IF( LT_32( elevation_m_values_fx[block_m_idx][band_m_idx], NEAR_HORIZONTAL_PLANE_ELEVATION_FX ) ) /* Computed only near horizontal plane */ { - minAngleDist = 180.0f; + minAngleDist_fx = 754974720; /*Q22*/ + move32(); i1 = 0; - currentAzi = azimuth_m_values[block_m_idx][band_m_idx]; - for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) + move16(); + currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx]; + move32(); + FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) { - angleDist = fabsf( currentAzi - hMcMasa->ls_azimuth[i] ); - if ( angleDist > 180.0f ) + angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) ); + IF( GT_32( angleDist_fx, 754974720 /*180.0f Q.22*/ ) ) { - angleDist = fabsf( angleDist - 360.0f ); + angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 ) ); } - if ( angleDist < minAngleDist ) + IF( LT_32( angleDist_fx, minAngleDist_fx ) ) { - minAngleDist = angleDist; + minAngleDist_fx = angleDist_fx; + move32(); i1 = i; + move16(); } } i2 = hMcMasa->leftNearest[i1]; + move16(); i3 = hMcMasa->rightNearest[i1]; - - if ( i2 < i3 ) + move16(); + Word16 temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] ); + Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ); + IF( LT_16( i2, i3 ) ) { - stereoCoh = absCOVls[i2][i3] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) ); + stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i3], temp, &stereoCoh_e ); + stereoCoh_e = add( sub( absCOVls_e[i2][i3], temp_e ), stereoCoh_e ); } - else + ELSE { - stereoCoh = absCOVls[i3][i2] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) ); + stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i2], temp, &stereoCoh_e ); + stereoCoh_e = add( sub( absCOVls_e[i3][i2], temp_e ), stereoCoh_e ); } - lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] + EPSILON ); - stereoness = stereoCoh * lsEnergyRelation; - - if ( i1 < i2 ) + stereoCoh_fx = L_shl( stereoCoh_fx, 16 ); + Word32 temp1, temp2; + Word16 temp1_e, temp2_e; + temp1 = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i2], lsEnergy_e[i2], lsEnergy_fx[i3], lsEnergy_e[i3], &temp1_e ); + temp2 = BASOP_Util_Add_Mant32Exp( temp1, temp1_e, lsEnergy_fx[i1], lsEnergy_e[i1], &temp2_e ); + temp2 = L_add( temp2, EPSILON_FX ); + lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, temp2, &lsEnergyRelation_e ); + lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, temp2_e ) ); + lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); + stereoness_fx = Mult_32_32( stereoCoh_fx, lsEnergyRelation_fx ); + stereoness_e = stereoCoh_e; + move16(); + + IF( LT_16( i1, i2 ) ) { - tempCoh = absCOVls[i1][i2] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) ); + temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] ); + tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e ); + tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i1][i2], temp_e ) ); } - else + ELSE { - tempCoh = absCOVls[i2][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) ); + temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] ); + tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e ); + tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i2][i1], temp_e ) ); } - if ( i1 < i3 ) + tempCoh_fx = L_shl( tempCoh_fx, 16 ); + IF( LT_16( i1, i3 ) ) { - tempCoh2 = absCOVls[i1][i3] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) ); + temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] ); + tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i3], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e ); + tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i1][i3], temp_e ) ); } - else + ELSE { - tempCoh2 = absCOVls[i3][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) ); + temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] ); + tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e ); + tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i3][i1], temp_e ) ); } - cohPanCoh = ( tempCoh < tempCoh2 ) ? tempCoh : tempCoh2; - lsEnergyRelation = lsEnergy[i2] / ( lsEnergy[i1] + EPSILON ); - tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i2] + EPSILON ); - lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation; - tempLsEnergyRelation = lsEnergy[i3] / ( lsEnergy[i1] + EPSILON ); - lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation; - tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i3] + EPSILON ); - lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation; - cohwideness = cohPanCoh * lsEnergyRelation; - - spreadCoh = ( cohwideness > stereoness ) ? cohwideness : stereoness; - if ( spreadCoh > 0.5f ) + tempCoh2_fx = L_shl( tempCoh2_fx, 16 ); + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tempCoh_fx, tempCoh_e, tempCoh2_fx, tempCoh2_e ), -1 ) ) { - if ( cohwideness > stereoness ) + cohPanCoh_fx = tempCoh_fx; + move32(); + cohPanCoh_e = tempCoh_e; + move16(); + } + ELSE + { + cohPanCoh_fx = tempCoh2_fx; + move32(); + cohPanCoh_e = tempCoh2_e; + move16(); + } + IF( GT_32( cohPanCoh_fx, ONE_IN_Q30 ) ) + { + cohPanCoh_fx = ONE_IN_Q30; + move32(); + } + cohPanCoh_fx = L_shl_sat( cohPanCoh_fx, cohPanCoh_e ); /*Q31*/ + cohPanCoh_e = 0; + move16(); + lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i2], L_add( lsEnergy_fx[i1], EPSILON_FX ), &lsEnergyRelation_e ); + lsEnergyRelation_e = add( lsEnergyRelation_e, sub( lsEnergy_e[i2], lsEnergy_e[i1] ) ); + tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i2], EPSILON_FX ), &tempLsEnergyRelation_e ); + tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i2] ) ); + IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) ) + { + lsEnergyRelation_fx = tempLsEnergyRelation_fx; + move32(); + lsEnergyRelation_e = tempLsEnergyRelation_e; + move16(); + } + tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i3], L_add( lsEnergy_fx[i1], EPSILON_FX ), &tempLsEnergyRelation_e ); + tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i3], lsEnergy_e[i1] ) ); + IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) ) + { + lsEnergyRelation_fx = tempLsEnergyRelation_fx; + move32(); + lsEnergyRelation_e = tempLsEnergyRelation_e; + move16(); + } + tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i3], EPSILON_FX ), &tempLsEnergyRelation_e ); + tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i3] ) ); + IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) ) + { + lsEnergyRelation_fx = tempLsEnergyRelation_fx; + move32(); + lsEnergyRelation_e = tempLsEnergyRelation_e; + move16(); + } + lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); /*Q31*/ + cohwideness_fx = Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ); + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) ) + { + spreadCoh_fx = cohwideness_fx; + move32(); + spreadCoh_e = cohPanCoh_e; + move16(); + } + ELSE + { + spreadCoh_fx = stereoness_fx; + move32(); + spreadCoh_e = stereoness_e; + move16(); + } + IF( ( spreadCoh_e < 0 ) ) + { + spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); + spreadCoh_e = 0; + move16(); + } + IF( GT_32( spreadCoh_fx, L_shl_sat( 1, sub( 30, spreadCoh_e ) /*0.5f with exp=spreadCoh_e*/ ) ) ) + { + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) ) { - tempCoh = stereoness - ( cohwideness - 0.5f ); - spreadCoh = ( tempCoh > 0.5f ) ? tempCoh : 0.5f; + tempCoh_fx = BASOP_Util_Add_Mant32Exp( stereoness_fx, stereoness_e, L_negate( L_sub( cohwideness_fx, L_shl( 1, sub( 30, cohPanCoh_e ) ) ) ), cohPanCoh_e, &tempCoh_e ); + IF( ( tempCoh_e < 0 ) ) + { + tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); + tempCoh_e = 0; + move16(); + } + IF( GT_32( tempCoh_fx, L_shl_sat( 1, sub( 30, tempCoh_e ) ) ) ) + { + spreadCoh_fx = tempCoh_fx; + move32(); + } + ELSE + { + spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); + } + spreadCoh_e = tempCoh_e; + move16(); } } - spreadCoh = ( spreadCoh < 1.0f ) ? spreadCoh : 1.0f; - spreadCoh = ( spreadCoh > 0.0f ) ? spreadCoh : 0.0f; + IF( ( spreadCoh_e < 0 ) ) + { + spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); + spreadCoh_e = 0; + move16(); + } - /* Compute energy ratio tuning parameter */ - lsEnergySum = sum_f( lsEnergy, numAnalysisChannels ) + EPSILON; - lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum; - stereoRatio = stereoCoh * lsEnergyRelation - surrCoh; + IF( ( GE_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) ) + { + spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); + } + IF( ( spreadCoh_fx <= 0 ) ) + { + spreadCoh_fx = 0; + move32(); + } + spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); /*Q31*/ - lsEnergyRelation = ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum; - cohPanRatio = cohPanCoh * lsEnergyRelation - surrCoh; + /* Compute energy ratio tuning parameter */ + lsEnergySum_fx = 0; + move32(); + lsEnergySum_e = 0; + move16(); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e ); + } + lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX ); + lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, lsEnergySum_fx, &lsEnergyRelation_e ); + lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, lsEnergySum_e ) ); + lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); + stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); + + temp2 = L_sub( temp2, EPSILLON_FX ); + lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp2, lsEnergySum_fx, &lsEnergyRelation_e ); + lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp2_e, lsEnergySum_e ) ); + lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); + cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); + IF( GT_32( stereoRatio_fx, cohPanRatio_fx ) ) + { + cohRatio_fx = stereoRatio_fx; + move32(); + } + ELSE + { + cohRatio_fx = cohPanRatio_fx; + move32(); + } - cohRatio = ( stereoRatio > cohPanRatio ) ? stereoRatio : cohPanRatio; - cohRatio = ( cohRatio < 1.0f ) ? cohRatio : 1.0f; - cohRatio = ( cohRatio > 0.0f ) ? cohRatio : 0.0f; + IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) ) + { + cohRatio_fx = ONE_IN_Q31; + move32(); + } + IF( cohRatio_fx <= 0 ) + { + cohRatio_fx = 0; + move32(); + } } - else /* Otherwise, set spread coherence to zero */ + ELSE /* Otherwise, set spread coherence to zero */ { - spreadCoh = 0.0f; - cohRatio = 0.0f; - lsEnergySum = sum_f( lsEnergy, numAnalysisChannels ); + spreadCoh_fx = 0; + move32(); + cohRatio_fx = 0; + move32(); + lsEnergySum_fx = 0; + move32(); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e ); + } + lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX ); } /* Store values */ - spreadCoherence[block_m_idx][band_m_idx] = spreadCoh; - - if ( hMcMasa->combineRatios ) - { - surroundingCoherence[0][band_m_idx] += lsEnergySum * surrCoh; - coherentEnergyRatio[0][band_m_idx] += lsEnergySum * cohRatio; - renormalization_factor_coh[band_m_idx] += lsEnergySum; + spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q31*/ + move32(); + + IF( hMcMasa->combineRatios ) + { + surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( surroundingCoherence_fx[0][band_m_idx], surroundingCoherence_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, surrCoh_fx ), lsEnergySum_e, &surroundingCoherence_e[0][band_m_idx] ); + move32(); + coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( coherentEnergyRatio_fx[0][band_m_idx], coherentEnergyRatio_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, cohRatio_fx ), lsEnergySum_e, &coherentEnergyRatio_e[0][band_m_idx] ); + move32(); + renormalization_factor_coh_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_coh_fx[band_m_idx], renormalization_factor_coh_e[band_m_idx], lsEnergySum_fx, lsEnergySum_e, &renormalization_factor_coh_e[band_m_idx] ); + move32(); } - else + ELSE { - surroundingCoherence[block_m_idx][band_m_idx] = surrCoh; - coherentEnergyRatio[block_m_idx][band_m_idx] = cohRatio; + surroundingCoherence_fx[block_m_idx][band_m_idx] = surrCoh_fx; + move32(); + coherentEnergyRatio_fx[block_m_idx][band_m_idx] = cohRatio_fx; + move32(); } } } - if ( hMcMasa->combineRatios ) + IF( hMcMasa->combineRatios ) { - for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { - if ( renormalization_factor_diff[band_m_idx] > EPSILON ) - { - diffuseness_m[0][band_m_idx] /= renormalization_factor_diff[band_m_idx]; - } - else - { - diffuseness_m[0][band_m_idx] = 0.f; - } - if ( renormalization_factor_coh[band_m_idx] > EPSILON ) - { - surroundingCoherence[0][band_m_idx] /= renormalization_factor_coh[band_m_idx]; - coherentEnergyRatio[0][band_m_idx] /= renormalization_factor_coh[band_m_idx]; - } - else - { - surroundingCoherence[0][band_m_idx] = 0.f; - coherentEnergyRatio[0][band_m_idx] = 0.f; + Word16 diffuseness_m_e; + IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) ) + { + diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[0][band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e ); + move32(); + diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[0][band_m_idx], renormalization_factor_diff_e[band_m_idx] ) ); + diffuseness_m_fx[0][band_m_idx] = L_shl_sat( diffuseness_m_fx[0][band_m_idx], add( 16, diffuseness_m_e ) ); + move32(); + } + ELSE + { + diffuseness_m_fx[0][band_m_idx] = 0; + move32(); + } + IF( GT_32( renormalization_factor_coh_fx[band_m_idx], EPSILON_FX ) ) + { + Word16 cer_e = 31, sc_e = 31; + move16(); + move16(); + surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( surroundingCoherence_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &sc_e ); + move32(); + sc_e = add( sc_e, sub( surroundingCoherence_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) ); + surroundingCoherence_fx[0][band_m_idx] = L_shl_sat( surroundingCoherence_fx[0][band_m_idx], add( 16, sc_e ) ); + move32(); + coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( coherentEnergyRatio_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &cer_e ); + move32(); + cer_e = add( cer_e, sub( coherentEnergyRatio_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) ); + coherentEnergyRatio_fx[0][band_m_idx] = L_shl_sat( coherentEnergyRatio_fx[0][band_m_idx], add( 16, cer_e ) ); + move32(); + } + ELSE + { + surroundingCoherence_fx[0][band_m_idx] = 0; + move32(); + coherentEnergyRatio_fx[0][band_m_idx] = 0; + move32(); } } } /* Determine energy ratios */ - if ( hMcMasa->combineRatios ) + IF( hMcMasa->combineRatios ) { numSubFramesForRatio = 1; + move16(); } - else + ELSE { numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); } - for ( i = 0; i < numSubFramesForRatio; i++ ) + FOR( i = 0; i < numSubFramesForRatio; i++ ) { - for ( j = 0; j < hMcMasa->nbands; j++ ) + FOR( j = 0; j < hMcMasa->nbands; j++ ) { - energyRatio[i][j] = 1.0f - diffuseness_m[i][j]; - energyRatio[i][j] = ( energyRatio[i][j] > coherentEnergyRatio[i][j] ) ? energyRatio[i][j] : coherentEnergyRatio[i][j]; + energyRatio_fx[i][j] = L_sub( ONE_IN_Q31, diffuseness_m_fx[i][j] ); + move32(); + IF( GT_32( energyRatio_fx[i][j], coherentEnergyRatio_fx[i][j] ) ) + { + energyRatio_fx[i][j] = energyRatio_fx[i][j]; + move32(); + } + ELSE + { + energyRatio_fx[i][j] = coherentEnergyRatio_fx[i][j]; + move32(); + } } } @@ -1892,7 +3022,157 @@ void ivas_mcmasa_dmx_modify( /*--------------------------------------------------------------------------* * Local functions *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/* Compute downmix */ +static void ivas_mcmasa_dmx_fx( + MCMASA_ENC_HANDLE hMcMasa, + Word32 *data_fx[], + Word16 data_e, + const Word16 input_frame, + const Word16 nchan_transport, + const Word16 nchan_inp ) +{ + Word16 i, j; + Word16 numAnalysisChannels; + Word32 dmx_c_fx; + Word32 multiChEne_fx, downmixEne_fx; + Word32 prevEQ_fx, currEQ_fx, instEQ_fx; + Word32 alpha_fx, L_tmp, L_tmp1; + Word16 multiChEne_e, scale, downmixEne_e = 0, prevEQ_e, tmp, currEQ_e, instEQ_e; + move16(); + + numAnalysisChannels = sub( nchan_inp, 1 ); + IF( hMcMasa->separateChannelEnabled ) + { + numAnalysisChannels = sub( nchan_inp, 2 ); + } + + multiChEne_fx = 0; + move32(); + multiChEne_e = 0; + move16(); + FOR( j = 0; j < numAnalysisChannels; j++ ) + { + FOR( i = 0; i < input_frame; i++ ) + { + L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale ); + L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e + multiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, multiChEne_fx, multiChEne_e, &scale ); + multiChEne_e = scale; + move16(); + } + } + + IF( EQ_16( nchan_transport, 2 ) ) + { + Word16 numSideChannels; /* Channels other than left, right, center */ + Word16 leftIndex, rightIndex; + + numSideChannels = sub( shr( numAnalysisChannels, 1 ), 1 ); + FOR( j = 0; j < numSideChannels; j++ ) + { + IF( hMcMasa->separateChannelEnabled ) + { + leftIndex = add( shl( j, 1 ), 2 ); + rightIndex = add( shl( j, 1 ), 3 ); + } + ELSE + { + leftIndex = add( shl( j, 1 ), 3 ); + rightIndex = add( shl( j, 1 ), 4 ); + } + + FOR( i = 0; i < input_frame; i++ ) + { + data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); + move32(); + data_fx[1][i] = L_add( data_fx[1][i], data_fx[rightIndex][i] ); + move32(); + } + } + + IF( !hMcMasa->separateChannelEnabled ) + { + FOR( i = 0; i < input_frame; i++ ) + { + dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_fx[2][i] ) ); + move32(); + data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); + move32(); + data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); + move32(); + } + } + } + ELSE IF( EQ_16( nchan_transport, 1 ) ) + { + FOR( i = 0; i < input_frame; i++ ) + { + FOR( j = 1; j < numAnalysisChannels; j++ ) + { + data_fx[0][i] = L_add( data_fx[0][i], data_fx[j][i] ); + move32(); + } + } + } + downmixEne_fx = 0; + move32(); + FOR( j = 0; j < nchan_transport; j++ ) + { + FOR( i = 0; i < input_frame; i++ ) + { + L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale ); + L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e + downmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, downmixEne_fx, downmixEne_e, &downmixEne_e ); + } + } + + alpha_fx = 214748364; // Q31 + move32(); + + L_tmp = Mpy_32_32( alpha_fx, multiChEne_fx ); + L_tmp1 = Mpy_32_32( 1932735284, hMcMasa->prevMultiChEne_fx ); + hMcMasa->prevMultiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, multiChEne_e, L_tmp1, hMcMasa->prevMultiChEne_e, &hMcMasa->prevMultiChEne_e ); + move32(); + + L_tmp = Mpy_32_32( alpha_fx, downmixEne_fx ); + L_tmp1 = Mpy_32_32( 1932735284, hMcMasa->prevDownmixEne_fx ); + hMcMasa->prevDownmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, downmixEne_e, L_tmp1, hMcMasa->prevDownmixEne_e, &hMcMasa->prevDownmixEne_e ); + move32(); + + prevEQ_fx = hMcMasa->prevEQ_fx; + move32(); + prevEQ_e = hMcMasa->prevEQ_e; + move16(); + + tmp = BASOP_Util_Divide3232_Scale( hMcMasa->prevMultiChEne_fx, L_add( hMcMasa->prevDownmixEne_fx, EPSILON_FX ), &scale ); + currEQ_e = add( scale, sub( hMcMasa->prevMultiChEne_e, hMcMasa->prevDownmixEne_e ) ); + currEQ_fx = Sqrt32( L_deposit_h( tmp ), &currEQ_e ); + + hMcMasa->prevEQ_fx = currEQ_fx; + move32(); + hMcMasa->prevEQ_e = currEQ_e; + move16(); + FOR( i = 0; i < input_frame; i++ ) + { + L_tmp = Mpy_32_32( L_deposit_h( hMcMasa->interpolator_fx[i] ), currEQ_fx ); + L_tmp1 = L_sub( 1073741824, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) ); + L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx ); + instEQ_fx = BASOP_Util_Add_Mant32Exp( L_tmp, currEQ_e, L_tmp1, add( prevEQ_e, 1 ), &instEQ_e ); + + FOR( j = 0; j < nchan_transport; j++ ) + { + data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); + move32(); + move32(); + data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); + } + } + + return; +} +#else /* Compute downmix */ static void ivas_mcmasa_dmx( MCMASA_ENC_HANDLE hMcMasa, @@ -1998,8 +3278,55 @@ static void ivas_mcmasa_dmx( return; } +#endif +#ifdef IVAS_FLOAT_FIXED +/* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */ +static void compute_cov_mtx_fx( + Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */ + Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] */ + const Word16 freq, /* i : Freq to process */ + const Word16 N, /* i : Number of channels */ + CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */ + Word16 inp_exp /*Stores exponent for temp*/ +) +{ + Word16 i, j; + Word32 a, b, c, d; + Word32 temp; + Word16 norm_a, norm_b, norm_c, norm_d; + Word16 shift; + FOR( i = 0; i < N; i++ ) + { + a = sr[i][freq]; + move32(); + b = si[i][freq]; + move32(); + norm_a = norm_l( a ); + norm_b = norm_l( b ); + a = L_shl( a, norm_a ); /*inp_exp-norm_a*/ + b = L_shl( b, norm_b ); /*inp_exp-norm_b*/ + FOR( j = i; j < N; j++ ) + { + c = sr[j][freq]; + move32(); + d = si[j][freq]; + move32(); + norm_c = norm_l( c ); + norm_d = norm_l( d ); + c = L_shl( c, norm_c ); /*inp_exp-norm_c*/ + d = L_shl( d, norm_d ); /*inp_exp-norm_d*/ + temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); /*exp=inp_exp-norm_ab+inp_exp-norm_cd*/ + COVls->xr_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xr_fx[i][j], COVls->xr_e[i][j], temp, shift, &COVls->xr_e[i][j] ); + move32(); + temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( b, c ), sub( shl( inp_exp, 1 ), add( norm_b, norm_c ) ), L_negate( Mult_32_32( a, d ) ), sub( shl( inp_exp, 1 ), add( norm_a, norm_d ) ), &shift ); + COVls->xi_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xi_fx[i][j], COVls->xi_e[i][j], temp, shift, &COVls->xi_e[i][j] ); + move32(); + } + } - + return; +} +#else /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */ static void compute_cov_mtx( float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */ @@ -2027,8 +3354,8 @@ static void compute_cov_mtx( return; } - - +#endif +#ifndef IVAS_FLOAT_FIXED static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], @@ -2066,8 +3393,138 @@ static void computeIntensityVector_enc( return; } +#else +static void computeIntensityVector_enc_fx( + const Word16 *band_grouping, + Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], + const Word16 enc_param_start_band, /* i : first band to process */ + const Word16 num_frequency_bands, + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ) +{ + /* Reminder + * X = a + ib; Y = c + id + * X*Y = ac - bd + i(ad +bc) + */ + Word16 i, j; + Word32 real, img; + Word16 brange[2]; + + FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ ) + { + brange[0] = band_grouping[i]; + move16(); + brange[1] = band_grouping[i + 1]; + move16(); + + intensity_real[0][i] = 0; + move32(); + intensity_real[1][i] = 0; + move32(); + intensity_real[2][i] = 0; + move32(); + + FOR( j = brange[0]; j < brange[1]; j++ ) + { + real = Cldfb_RealBuffer[0][j]; + move32(); + img = Cldfb_ImagBuffer[0][j]; + move32(); + /* Intensity is XYZ order, audio is WYZX order. */ + intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q= 2* input_q -31 + move32(); + intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q= 2* input_q -31 + move32(); + intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q= 2* input_q -31 + move32(); + } + } + + return; +} +#endif +#ifdef IVAS_FLOAT_FIXED +static void computeVerticalDiffuseness_fx( + Word32 **buffer_intensity, /* i : Intensity vectors */ + const Word32 *buffer_energy, /* i : Energy */ + const int16_t averaging_length, /* i : Averaging length */ + const Word16 num_freq_bands, /* i : Number of frequency bands */ + Word32 *diffuseness, /* o : Estimated diffuseness */ + Word16 *buffer_intensity_q, + Word16 *buffer_energy_q ) +{ + Word32 intensity_slow[MASA_FREQUENCY_BANDS]; + Word32 intensity_slow_abs[MASA_FREQUENCY_BANDS]; + Word32 energy_slow[MASA_FREQUENCY_BANDS]; + Word16 i, k; + Word32 tmp = 0; + move32(); + const Word32 *p_tmp_c; + Word16 intensity_slow_e[MASA_FREQUENCY_BANDS], energy_slow_e[MASA_FREQUENCY_BANDS]; + + /* Set variables to zero */ + set32_fx( intensity_slow, 0, MASA_FREQUENCY_BANDS ); + set32_fx( energy_slow, 0, MASA_FREQUENCY_BANDS ); + set16_fx( intensity_slow_e, 0, MASA_FREQUENCY_BANDS ); + set16_fx( energy_slow_e, 0, MASA_FREQUENCY_BANDS ); + + FOR( i = 0; i < averaging_length; ++i ) + { + /* Energy slow */ + p_tmp_c = buffer_energy + i_mult( i, num_freq_bands ); + FOR( k = 0; k < num_freq_bands; k++ ) + { + energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], *( p_tmp_c ), sub( 31, buffer_energy_q[i] ), &energy_slow_e[k] ); /*q=min_q*/ + move32(); + p_tmp_c++; + } + /* Intensity slow */ + FOR( k = 0; k < num_freq_bands; k++ ) + { + intensity_slow[k] = BASOP_Util_Add_Mant32Exp( intensity_slow[k], intensity_slow_e[k], buffer_intensity[i][k], sub( 31, buffer_intensity_q[i] ), &intensity_slow_e[k] ); /*q=min_q*/ + move32(); + } + } + + /* Compute absolute value */ + FOR( k = 0; k < num_freq_bands; k++ ) + { + intensity_slow_abs[k] = L_abs( intensity_slow[k] ); /*min_q*/ + move32(); + } + + /* Compute Diffuseness */ + FOR( i = 0; i < num_freq_bands; ++i ) + { + Word16 tmp_e1, tmp_e2; + tmp = BASOP_Util_Divide3232_Scale( intensity_slow_abs[i], L_add( energy_slow[i], EPSILON_FX_SMALL ), &tmp_e1 ); + tmp_e1 = add( tmp_e1, sub( intensity_slow_e[i], energy_slow_e[i] ) ); + tmp = BASOP_Util_Divide3232_Scale( L_sub( tmp, L_shr( VERTICAL_ENERGY_RATIO_OFFSET_FX, tmp_e1 ) ), L_sub( ONE_IN_Q15, VERTICAL_ENERGY_RATIO_OFFSET_FX ), &tmp_e2 ); /* Tuned to avoid effect due to ambience of vertically un-even setups */ + tmp_e2 = add( tmp_e2, tmp_e1 ); + tmp = L_sub( L_shl( 1, sub( 15, tmp_e2 ) ), tmp ); + IF( tmp < 0 ) + { + tmp = 0; + move32(); + } + ELSE IF( GE_32( tmp, L_shl( 1, sub( 15, tmp_e2 ) ) ) ) + { + tmp = ONE_IN_Q31; + move32(); + } + ELSE + { + tmp = L_shl( tmp, add( 16, tmp_e2 ) ); + } + diffuseness[i] = tmp; + move32(); + } + return; +} +#endif // IVAS_FLOAT_FIXED +#ifndef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * computeVerticalDiffuseness() * @@ -2126,8 +3583,79 @@ static void computeVerticalDiffuseness( return; } +#endif +#ifdef IVAS_FLOAT_FIXED +static void computeEvenLayout_fx( + const Word32 *ls_azimuth, + Word32 *ls_azimuth_even, + const Word16 numChannels ) +{ + Word16 i; + Word16 j; + Word32 ls_azimuth_temp[MCMASA_MAX_ANA_CHANS]; + Word32 ls_azimuth_even_ordered[MCMASA_MAX_ANA_CHANS]; + Word16 ls_azimuth_order[MCMASA_MAX_ANA_CHANS]; + Word32 smallestAzimuth; + Word16 smallestAzimuthIndex; + Word32 lsSpacing; + UWord8 oddLayout; + Word32 startAzimuth; + Word16 numChannelsHalf; + + lsSpacing = L_shl( L_mult0( 360, div_s( 1, numChannels ) ), 6 ); /*Q.21*/ + oddLayout = (UWord8) s_and( numChannels, 1 ); + move16(); + numChannelsHalf = shr( numChannels, 1 ); + + Copy32( ls_azimuth, ls_azimuth_temp, numChannels ); + Scale_sig32( ls_azimuth_temp, numChannels, -1 ); /*Q.21*/ + FOR( i = 0; i < numChannels; i++ ) + { + smallestAzimuth = 1000 << 21; /*Q21*/ + move32(); + smallestAzimuthIndex = 0; + move16(); + FOR( j = 0; j < numChannels; j++ ) + { + IF( LT_32( ls_azimuth_temp[j], smallestAzimuth ) ) + { + smallestAzimuth = ls_azimuth_temp[j]; + move32(); + smallestAzimuthIndex = j; + move16(); + } + } + ls_azimuth_order[i] = smallestAzimuthIndex; + move32(); + ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 ); + move32(); + } + IF( oddLayout ) + { + startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, shl( numChannelsHalf, 1 ) ) ); /*Q.22*/ + } + ELSE + { + startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, sub( shl( numChannelsHalf, 1 ), 1 ) ) ); /*Q.22*/ + } + + FOR( i = 0; i < numChannels; i++ ) + { + ls_azimuth_even_ordered[i] = W_extract_l( W_add( W_mult_32_16( lsSpacing, i ), startAzimuth ) ); /*Q.22*/ + move32(); + } + + FOR( i = 0; i < numChannels; i++ ) + { + ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 ), 22 ), 22 ); /*((a+2^21)/2^22)*2^22*/ + move32(); + } + return; +} +#endif // IVAS_FLOAT_FIXED +#ifndef IVAS_FLOAT_FIXED static void computeEvenLayout( const float *ls_azimuth, float *ls_azimuth_even, @@ -2187,7 +3715,8 @@ static void computeEvenLayout( return; } - +#endif +#ifndef IVAS_FLOAT_FIXED static void computeLfeEnergy( MCMASA_ENC_HANDLE hMcMasa, float *data_f[], @@ -2307,3 +3836,146 @@ static void computeLfeEnergy( return; } +#else +static void computeLfeEnergy_fx( + MCMASA_ENC_HANDLE hMcMasa, + Word32 *data_fx[], + const Word16 input_frame, + Word16 q_inp ) +{ + Word16 l_ts; + Word16 block_m_idx; + Word16 mrange[2]; + Word16 separateChannelIndex; + Word16 lfeChannelIndex; + Word32 *pcm_in[1]; + Word16 inp_q = q_inp; + move16(); + + l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX ); + separateChannelIndex = hMcMasa->separateChannelIndex; + move16(); + lfeChannelIndex = LFE_CHANNEL; + move16(); + + IF( hMcMasa->separateChannelEnabled ) + { + Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); + Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); + } + ELSE + { + pcm_in[0] = &data_fx[lfeChannelIndex][0]; + } + + /* Reset variables */ + set32_fx( hMcMasa->lfeLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + set16_fx( hMcMasa->lfeLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + set32_fx( hMcMasa->totalLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + set16_fx( hMcMasa->totalLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + + /* Compute low-frequency energies */ + IF( hMcMasa->separateChannelEnabled ) /* Using low-pass filter */ + { + Word32 lowpassCoef; + Word16 lowPassSignal_q; + Word16 i, j; + Word32 delayedInputSignal[2][L_FRAME48k]; + Word32 lowPassSignal[2][L_FRAME48k]; + + Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts ); + Copy32( data_fx[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); + Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts ); + Copy32( data_fx[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); + + lowpassCoef = L_shl( div_w( 1, (Word32) hMcMasa->ringBufferSize ), Q7 ); // Q.38 + + FOR( i = 0; i < input_frame; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + Word32 temp1, temp2; + temp1 = Mpy_32_32( delayedInputSignal[j][i], lowpassCoef ); // Q(q_inp+7-gb) + temp2 = Mpy_32_32( hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer], lowpassCoef ); // Q(q_inp+7-gb) + hMcMasa->lowpassSum[j] = L_add( hMcMasa->lowpassSum[j], L_sub( temp1, temp2 ) ); + move32(); + lowPassSignal[j][i] = hMcMasa->lowpassSum[j]; + move32(); + hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i]; + move32(); + } + + hMcMasa->ringBufferPointer--; + IF( hMcMasa->ringBufferPointer < 0 ) + { + hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferSize, 1 ); + } + } + lowPassSignal_q = add( q_inp, Q7 ); + FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + mrange[0] = i_mult( hMcMasa->block_grouping[block_m_idx], l_ts ); + move16(); + mrange[1] = i_mult( hMcMasa->block_grouping[block_m_idx + 1], l_ts ); + move16(); + + FOR( i = mrange[0]; i < mrange[1]; i++ ) + { + hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[0][i], lowPassSignal[0][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] ); + move32(); + hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[1][i], lowPassSignal[1][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] ); + move32(); + } + hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], &hMcMasa->totalLfEne_e[block_m_idx] ); + move32(); + } + } + ELSE /* Using CLDFB */ + { + Word16 ts; + Word16 i; + Word32 Chnl_RealBuffer[2][DIRAC_NO_FB_BANDS_MAX]; + Word32 Chnl_ImagBuffer[2][DIRAC_NO_FB_BANDS_MAX]; + Word32 *p_Chnl_RealBuffer[2]; + Word32 *p_Chnl_ImagBuffer[2]; + + p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0]; + p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0]; + p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0]; + p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0]; + + + FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + mrange[0] = hMcMasa->block_grouping[block_m_idx]; + move16(); + mrange[1] = hMcMasa->block_grouping[block_m_idx + 1]; + move16(); + + FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) + { + ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans, 0 ); + + ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans ); + + pcm_in[0] += l_ts; + + /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */ + FOR( i = 0; i < CLDFB_TO_MDFT_FAC; i++ ) + { + hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer[0][i], Chnl_RealBuffer[0][i] ), Mpy_32_32( Chnl_ImagBuffer[0][i], Chnl_ImagBuffer[0][i] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] ); + move32(); + } + } + } + } + + IF( hMcMasa->separateChannelEnabled ) + { + Copy32( data_fx[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), ( hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp ) ); + Copy32( data_fx[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), ( hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp ) ); + } + + return; +} +#endif diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 48a988970..a5b543d85 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -739,7 +739,7 @@ void ivas_mct_core_enc( return; } #else -void ivas_mct_core_enc( +void ivas_mct_core_enc_fx( const IVAS_FORMAT ivas_format, /* i : IVAS format */ MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ @@ -753,17 +753,7 @@ void ivas_mct_core_enc( Word16 ch, ch_core, nSubframes, L_subframeTCX; Word16 i, cpe_id, n, nAvailBits; Word16 nCPE; - float *orig_spectrum[MCT_MAX_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */ - float powerSpec[MCT_MAX_CHANNELS][L_FRAME48k]; - float powerSpecMsInv_long[MCT_MAX_CHANNELS][L_FRAME48k]; /* MS inv power spectrum, also inverse MDST spectrum */ - float *powerSpecMsInv[MCT_MAX_CHANNELS][2]; - float *inv_mdst_spectrum[MCT_MAX_CHANNELS][2]; - float *inv_spectrum[MCT_MAX_CHANNELS][2]; - float *mdst_spectrum[MCT_MAX_CHANNELS][2] = { NULL }; - float inv_spectrum_long[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ -#if 0 Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */ -#endif Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k]; Word32 mdst_fx; Word32 powerSpecMsInv_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* MS inv power spectrum, also inverse MDST spectrum */ @@ -774,13 +764,14 @@ void ivas_mct_core_enc( Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ Word16 total_side_bits; Word16 chBitRatios[MCT_MAX_CHANNELS]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, tmp_s; + Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[L_FRAME48k], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *sts[MCT_MAX_CHANNELS]; Encoder_State *st; Word16 sp_aud_decision0[MCT_MAX_CHANNELS]; BSTR_ENC_HANDLE hBstr; + Word16 q_spectrum; push_wmops( "mct_encoding" ); @@ -794,7 +785,7 @@ void ivas_mct_core_enc( nCPE = shr( nChannels, 1 ); // nChannels / CPE_CHANNELS /*in case of odd number of channels*/ - if ( NE_16( ( nCPE * CPE_CHANNELS ), nChannels ) ) + IF( NE_16( ( nCPE * CPE_CHANNELS ), nChannels ) ) { nCPE = add( nCPE, 1 ); } @@ -808,13 +799,6 @@ void ivas_mct_core_enc( #endif // MSAN_FIX FOR( ch = 0; ch < nChannels; ch++ ) { -#if 1 // Float initialization to be removed - inv_mdst_spectrum[ch][0] = powerSpecMsInv[ch][0] = powerSpecMsInv_long[ch]; - inv_mdst_spectrum[ch][1] = powerSpecMsInv[ch][1] = powerSpecMsInv_long[ch] + N_TCX10_MAX; - inv_spectrum[ch][0] = inv_spectrum_long[ch]; - inv_spectrum[ch][1] = inv_spectrum_long[ch] + N_TCX10_MAX; -#endif - set32_fx( inv_spectrum_long_fx[ch], 0, L_FRAME48k ); set32_fx( powerSpec_fx[ch], 0, L_FRAME48k ); set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); @@ -841,18 +825,11 @@ void ivas_mct_core_enc( i = add( i, 1 ); CONTINUE; } -#if 1 // Float initialization to be removed - mdst_spectrum[i][0] = hMCT->p_mdst_spectrum_long[cpe_id][ch]; - mdst_spectrum[i][1] = hMCT->p_mdst_spectrum_long[cpe_id][ch] + N_TCX10_MAX; - orig_spectrum[i][0] = hMCT->p_orig_spectrum_long[cpe_id][ch]; - orig_spectrum[i][1] = hMCT->p_orig_spectrum_long[cpe_id][ch] + N_TCX10_MAX; -#endif + mdst_spectrum_fx[i][0] = hMCT->p_mdst_spectrum_long_fx[cpe_id][ch]; mdst_spectrum_fx[i][1] = hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] + N_TCX10_MAX; -#if 0 orig_spectrum_fx[i][0] = hMCT->p_orig_spectrum_long_fx[cpe_id][ch]; orig_spectrum_fx[i][1] = hMCT->p_orig_spectrum_long_fx[cpe_id][ch] + N_TCX10_MAX; -#endif sp_aud_decision0[i] = hCPE[cpe_id]->hCoreCoder[0]->sp_aud_decision0; move16(); @@ -865,7 +842,8 @@ void ivas_mct_core_enc( i = add( i, 1 ); } } - + q_origSpec = hMCT->q_orig_spectrum_long_fx; + move16(); hBstr = sts[0]->hBstr; FOR( ch = 0; ch < shr( hMCT->nchan_out_woLFE, 1 ); ch++ ) @@ -1133,254 +1111,86 @@ void ivas_mct_core_enc( ComputeSpectrumNoiseMeasure_fx( powerSpec_fx[ch], st->hTcxEnc->L_frameTCX, st->hTcxEnc->nmStartLine, NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ), st->hTcxEnc->memQuantZeros, st->hTcxEnc->L_frameTCX ); } -#if 1 // Float initialization to be removed - st->hTcxEnc->measuredBwRatio_flt = 1.f; /* No bandwidth limit for the noise filling */ -#endif st->hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* No bandwidth limit for the noise filling, Q14 */ + move16(); } -#if 1 // Fixed to float conversions, to be removed - Word16 length; - q_spec = 31; - move16(); - for ( ch = 0; ch < nChannels; ch++ ) - { - if ( sts[ch]->hTcxEnc->spectrum[0] ) - { - q_spec = 31 - sts[ch]->hTcxEnc->spectrum_e[0]; - } - 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 ( Word16 k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) - { - if ( sts[ch]->hTcxEnc->spectrum[0] ) - { - 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 ); - } - if ( mdst_spectrum[ch][0] ) - { - 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 ); - } - } - - fixedToFloat_arrL( powerSpecMsInv_fx[ch][0], powerSpecMsInv[ch][0], q_powSpec[ch], L_FRAME48k ); - fixedToFloat_arrL( powerSpec_fx[ch], powerSpec[ch], q_powSpec[ch], sts[ch]->hTcxEnc->L_frameTCX ); - } -#endif // 1 - - if ( sts[0]->igf ) + IF( sts[0]->igf ) { - if ( hMCT->currBlockDataCnt > 0 ) + IF( hMCT->currBlockDataCnt > 0 ) { -#ifdef IVAS_FLOAT_FIXED_ - /* High MLD cases are observed */ - mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, orig_spectrum, powerSpec, powerSpecMsInv, inv_spectrum, sp_aud_decision0 ); -#else - mctStereoIGF_enc( hMCT, sts, orig_spectrum, powerSpec, powerSpecMsInv, inv_spectrum, sp_aud_decision0 ); -#endif // IVAS_FLOAT_FIXED + mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, powerSpecMsInv_fx, q_powSpec, inv_spectrum_fx, sp_aud_decision0 ); } - else + ELSE { - for ( ch = 0; ch < nChannels; ch++ ) + FOR( ch = 0; ch < nChannels; ch++ ) { st = sts[ch]; /* update the pointer to the buffer of indices of the second channel */ - if ( ch > 0 ) + IF( ch > 0 ) { st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } - if ( - sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; + } + // nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; + // L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes; + nSubframes = NB_DIV; + move16(); + L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, 1 ); + IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + L_subframeTCX = st->hTcxEnc->L_frameTCX; + move16(); + move16(); } - nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes; - if ( st->igf ) + IF( st->igf ) { - for ( n = 0; n < nSubframes; n++ ) + FOR( n = 0; n < nSubframes; n++ ) { -#ifdef IVAS_FLOAT_FIXED_ - /* High MLD cases are observed */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData = &st->hIGFEnc->igfData; - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q7 ); - } - - float max_sb = 0; - float max_tb = 0; - Word16 max_sb_fx = 0; - Word16 max_tb_fx = 0; - - float max_fir_tb = 0; - float max_iir_tb = 0; - float max_fir_sb = 0; - float max_iir_sb = 0; - - Word16 max_fir_tb_fx = 0; - Word16 max_iir_tb_fx = 0; - Word16 max_fir_sb_fx = 0; - Word16 max_iir_sb_fx = 0; - FOR( Word16 sfb = 0; sfb < 23; sfb++ ) - { - f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - - max_fir_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_fir_tb ); - f2me_16( max_fir_tb, &max_fir_tb_fx, &hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ); - - max_iir_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_iir_tb ); - f2me_16( max_iir_tb, &max_iir_tb_fx, &hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ); - - max_fir_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_fir_sb ); - f2me_16( max_fir_sb, &max_fir_sb_fx, &hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ); - - max_iir_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_iir_sb ); - f2me_16( max_iir_sb, &max_iir_sb_fx, &hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ); - - max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - } - - for ( i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); - } - } - - int igfGridIdx; - if ( st->last_core == ACELP_CORE && st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - } - else if ( st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_NORM; - } - else - { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; - } - - Word16 q_spectrum; - q_spectrum = L_get_q_buf1( orig_spectrum[ch][n], hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - q_spectrum = min( q_spectrum, L_get_q_buf1( st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ) ); - } - floatToFixed_arrL32( orig_spectrum[ch][n], orig_spectrum_fx[ch][n], q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - floatToFixed_arrL32( st->hIGFEnc->spec_be_igf_flt, st->hIGFEnc->spec_be_igf, q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); - st->hIGFEnc->spec_be_igf_e = 31 - q_spectrum; - } - - q_spectrum = L_get_q_buf1( st->hTcxEnc->spectrum[n], hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - floatToFixed_arrL32( st->hTcxEnc->spectrum[n], st->hTcxEnc->spectrum_fx[n], q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - - // Word32 powerSpec_fx[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word16 q_powerSpec; - q_powerSpec = L_get_q_buf1( &powerSpec[ch][n * L_subframeTCX], hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - floatToFixed_arrL32( &powerSpec[ch][n * L_subframeTCX], &powerSpec_fx[ch][n * L_subframeTCX], q_powerSpec, hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - - if ( st->hIGFEnc ) - { - st->hIGFEnc->tns_predictionGain = float_to_fix16( st->hIGFEnc->tns_predictionGain_flt, Q23 ); - } - floatToFixed_arr16( &hPrivateData->igfInfo.grid[igfGridIdx].whiteningThreshold_flt[0][0], &hPrivateData->igfInfo.grid[igfGridIdx].whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); -#endif - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powerSpec, st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL32( st->hTcxEnc->spectrum_fx[n], st->hTcxEnc->spectrum[n], q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - fixedToFloat_arrL32( &powerSpec_fx[ch][n * L_subframeTCX], &powerSpec[ch][n * L_subframeTCX], q_powerSpec, hPrivateData->igfInfo.grid[igfGridIdx].infoGranuleLen ); - - if ( st->hIGFEnc ) - { - st->hIGFEnc->tns_predictionGain_flt = fix16_to_float( st->hIGFEnc->tns_predictionGain, Q23 ); - me2f_buf( st->hIGFEnc->spec_be_igf, st->hIGFEnc->spec_be_igf_e, st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); - } - - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); - } - - for ( i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); - } - } - - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att = fix16_to_float( st->hTdCngEnc->CNG_att_fx, Q7 ); - } -#endif -#else - ProcessIGF( st, st->hTcxEnc->spectrum[n], orig_spectrum[ch][n], &powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif + q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); + + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powSpec[ch], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + + st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); + st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); + move16(); + move16(); } } } } /*write IGF data to bitstream*/ - for ( ch = 0; ch < nChannels; ch++ ) + FOR( ch = 0; ch < nChannels; ch++ ) { st = sts[ch]; - if ( - sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } enc_prm_igf_mdct( st, hBstr ); } } /* correct side bits per channel*/ - for ( ch = 0; ch < nChannels; ch++ ) + FOR( ch = 0; ch < nChannels; ch++ ) { st = sts[ch]; - if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } - st->side_bits_frame_channel -= NBBITS_MCT_RATIO; /* Subtract estimated stereo bits */ - total_side_bits += st->side_bits_frame_channel; + st->side_bits_frame_channel = sub( st->side_bits_frame_channel, NBBITS_MCT_RATIO ); /* Subtract estimated stereo bits */ + move16(); + total_side_bits = add( total_side_bits, st->side_bits_frame_channel ); } /*--------------------------------------------------------------* @@ -1465,7 +1275,6 @@ void ivas_mct_core_enc( } } - pop_wmops(); return; diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 337f39eb5..d30e12f1c 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -440,6 +440,8 @@ ivas_error ivas_mct_enc( set_zero( mdst_spectrum_long[cpe_id][n], L_FRAME48k ); #endif #endif + set32_fx( orig_spectrum_long_fx[cpe_id][n], 0, L_FRAME48k ); + set32_fx( mdst_spectrum_long_fx[cpe_id][n], 0, L_FRAME48k ); hMCT->p_mdst_spectrum_long_fx[cpe_id][n] = mdst_spectrum_long_fx[cpe_id][n]; hMCT->p_orig_spectrum_long_fx[cpe_id][n] = orig_spectrum_long_fx[cpe_id][n]; @@ -544,8 +546,9 @@ ivas_error ivas_mct_enc( } } -#if 1 // Float to Fixed, to be removed +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // Float to Fixed, to be removed Word16 q_spec = Q31; + Word16 q_origSpec = Q31; Word16 length, ch, nCPE; nCPE = ( hMCT->nchan_out_woLFE % 2 ) == 0 ? ( hMCT->nchan_out_woLFE / 2 ) : ( hMCT->nchan_out_woLFE / 2 ) + 1; @@ -573,9 +576,13 @@ ivas_error ivas_mct_enc( q_spec = s_min( q_spec, Q_factor_arrL( &hMCT->p_mdst_spectrum_long[cpe_id][ch][k * N_TCX10_MAX], length ) - 1 ); } } + if ( hMCT->p_orig_spectrum_long[cpe_id][ch] ) + { + q_origSpec = s_min( q_origSpec, Q_factor_arrL( hMCT->p_orig_spectrum_long[cpe_id][ch], L_FRAME48k ) - 1 ); + } } } - + hMCT->q_orig_spectrum_long_fx = q_origSpec; for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { for ( ch = 0; ch < CPE_CHANNELS; ch++ ) @@ -594,13 +601,18 @@ ivas_error ivas_mct_enc( if ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum[0] ) { floatToFixed_arrL32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum[k], st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[k], q_spec, length ); - st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[k] = sub( Q31, q_spec ); + st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0] = sub( Q31, q_spec ); + st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[1] = sub( Q31, q_spec ); } if ( hMCT->p_mdst_spectrum_long[cpe_id][ch] ) { floatToFixed_arrL32( &hMCT->p_mdst_spectrum_long[cpe_id][ch][k * N_TCX10_MAX], &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], q_spec, length ); } } + if ( hMCT->p_orig_spectrum_long[cpe_id][ch] ) + { + floatToFixed_arrL32( hMCT->p_orig_spectrum_long[cpe_id][ch], hMCT->p_orig_spectrum_long_fx[cpe_id][ch], hMCT->q_orig_spectrum_long_fx, L_FRAME48k ); + } } } @@ -611,10 +623,195 @@ ivas_error ivas_mct_enc( hMCT->hBlockData[pair]->hStereoMdct->hItd->itd_fx[1] = float_to_fix( hMCT->hBlockData[pair]->hStereoMdct->hItd->itd[1], Q23 ); } } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Encoder_State *sts_tmp[MCT_MAX_CHANNELS]; + Encoder_State *st; + Word16 i; + IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; + nCPE = shr( hMCT->nchan_out_woLFE, 1 ); // nChannels / CPE_CHANNELS + + /*in case of odd number of channels*/ + IF( NE_16( ( nCPE * CPE_CHANNELS ), hMCT->nchan_out_woLFE ) ) + { + nCPE = add( nCPE, 1 ); + } + FOR( ( cpe_id = 0, i = 0 ); cpe_id < nCPE; cpe_id++ ) + { + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts_tmp[i] = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]; + IF( EQ_32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + i = add( i, 1 ); + CONTINUE; + } + i++; + } + } + FOR( int b = 0; b < hMCT->nchan_out_woLFE; b++ ) + { + st = sts_tmp[b]; + + if ( st->hIGFEnc ) + { + ch = 0; + hIGFEnc[ch] = st->hIGFEnc; + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 igfGridIdx; + IF( st->last_core == ACELP_CORE && EQ_16( st->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + } + ELSE IF( EQ_16( st->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_NORM; + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + } + hPrivateData = &hIGFEnc[ch]->igfData; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; + if ( hIGFEnc[ch] ) + { + hIGFEnc[ch]->tns_predictionGain = float_to_fix16( hIGFEnc[ch]->tns_predictionGain_flt, Q23 ); + } + + float max_sb = 0; + float max_tb = 0; + Word16 max_sb_fx = 0; + Word16 max_tb_fx = 0; + + float max_fir_tb = 0; + float max_iir_tb = 0; + float max_fir_sb = 0; + float max_iir_sb = 0; + + Word16 max_fir_tb_fx = 0; + Word16 max_iir_tb_fx = 0; + Word16 max_fir_sb_fx = 0; + Word16 max_iir_sb_fx = 0; + FOR( Word16 sfb = 0; sfb < 23; sfb++ ) + { + f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); + + max_fir_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_fir_tb ); + f2me_16( max_fir_tb, &max_fir_tb_fx, &hPrivateData->prevSFB_FIR_TB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ); + + max_iir_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_iir_tb ); + f2me_16( max_iir_tb, &max_iir_tb_fx, &hPrivateData->prevSFB_IIR_TB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ); + + max_fir_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_fir_sb ); + f2me_16( max_fir_sb, &max_fir_sb_fx, &hPrivateData->prevSFB_FIR_SB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ); + + max_iir_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_iir_sb ); + f2me_16( max_iir_sb, &max_iir_sb_fx, &hPrivateData->prevSFB_IIR_SB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ); + + max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); + f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + + max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); + f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + } + FOR( int k = 0; k < IGF_MAX_TILES; k++ ) + { + hPrivateData->prevSFM_FIR[k] = float_to_fix( hPrivateData->prevSFM_FIR_flt[k], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR[k] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[k], 13 ); /*2Q13*/ + FOR( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM_fx[k][j] = float_to_fix16( hPrivateData->igfPastSFM[k][j], 13 ); + } + } + floatToFixed_arr16( &hGrid->whiteningThreshold_flt[0][0], &hGrid->whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); + } + + if ( st->hTdCngEnc != NULL ) + { + st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q7 ); + } + } +#endif #endif // 1 /* joint MCT encoding */ - ivas_mct_core_enc( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (int16_t) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); + ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (int16_t) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_spec = 31; + move16(); + for ( ch = 0; ch < hMCT->nchan_out_woLFE; ch++ ) + { + sts_tmp[ch]->hTcxEnc->measuredBwRatio_flt = 1.f; /* No bandwidth limit for the noise filling */ + + if ( sts_tmp[ch]->hTcxEnc->spectrum[0] ) + { + q_spec = 31 - sts_tmp[ch]->hTcxEnc->spectrum_e[0]; + } + length = sts_tmp[ch]->hTcxEnc->L_frameTCX / ( ( sts_tmp[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + if ( sts_tmp[ch]->last_core == ACELP_CORE ) + { + length += length / 4; + } + for ( Word16 k = 0; k <= ( ( sts_tmp[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + if ( sts_tmp[ch]->hTcxEnc->spectrum[0] ) + { + fixedToFloat_arrL32( sts_tmp[ch]->hTcxEnc->spectrum_fx[k], sts_tmp[ch]->hTcxEnc->spectrum[k], q_spec, length ); + } + } + } + for ( int b = 0; b < hMCT->nchan_out_woLFE; b++ ) + { + st = sts_tmp[b]; + if ( st->hIGFEnc ) + { + ch = 0; + hIGFEnc[ch] = st->hIGFEnc; + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + + hPrivateData = &hIGFEnc[ch]->igfData; + + for ( Word16 sfb = 0; sfb < 23; sfb++ ) + { + hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_FIR_TB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_IIR_TB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_FIR_SB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_IIR_SB_e[sfb] ); + hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); + } + for ( int k = 0; k < IGF_MAX_TILES; k++ ) + { + hPrivateData->prevSFM_FIR_flt[k] = fixedToFloat( hPrivateData->prevSFM_FIR[k], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR_flt[k] = fixedToFloat( hPrivateData->prevSFM_IIR[k], 13 ); /*2Q13*/ + for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM[k][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[k][j], 13 ); + } + } + } + + if ( st->hTdCngEnc != NULL ) + { + st->hTdCngEnc->CNG_att = fix16_to_float( st->hTdCngEnc->CNG_att_fx, Q7 ); + } + if ( st->hIGFEnc ) + { + st->hIGFEnc->tns_predictionGain_flt = fix16_to_float( st->hIGFEnc->tns_predictionGain, Q23 ); + me2f_buf( st->hIGFEnc->spec_be_igf, st->hIGFEnc->spec_be_igf_e, st->hIGFEnc->spec_be_igf_flt, N_MAX_TCX - IGF_START_MN ); + } + } +#endif /* Spectrum quantization and coding */ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) @@ -626,7 +823,7 @@ ivas_error ivas_mct_enc( hCPE->hCoreCoder[0]->hBstr->ind_list = st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->ind_list + st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->nb_ind_tot; } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Encoder_State *st, **sts; + Encoder_State /**st,*/ **sts; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { sts = hCPE->hCoreCoder; @@ -1563,8 +1760,12 @@ static ivas_error ivas_mc_enc_reconfig( ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); +#ifdef IVAS_FLOAT_FIXED /* De-allocate McMasa-related handles */ + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#endif ivas_masa_enc_close( &( st_ivas->hMasa ) ); @@ -1604,8 +1805,11 @@ static ivas_error ivas_mc_enc_reconfig( ivas_param_mc_enc_close( &st_ivas->hParamMC, st_ivas->hEncoderConfig->input_Fs ); /* De-allocate McMasa-related handles */ +#ifdef IVAS_FLOAT_FIXED + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); - +#endif ivas_masa_enc_close( &( st_ivas->hMasa ) ); ivas_qmetadata_close( &st_ivas->hQMetaData ); @@ -1628,8 +1832,11 @@ static ivas_error ivas_mc_enc_reconfig( } /* De-allocate McMasa-related handles */ +#ifdef IVAS_FLOAT_FIXED + ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); +#else ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); - +#endif if ( st_ivas->hMasa != NULL ) { ivas_masa_enc_close( &( st_ivas->hMasa ) ); @@ -1677,8 +1884,11 @@ static ivas_error ivas_mc_enc_reconfig( { return error; } - +#ifdef IVAS_FLOAT_FIXED + if ( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) +#else if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1686,7 +1896,11 @@ static ivas_error ivas_mc_enc_reconfig( else { /* reconfigure McMASA instance */ +#ifdef IVAS_FLOAT_FIXED + if ( NE_32( ( error = ivas_mcmasa_enc_reconfig_fx( st_ivas ) ), IVAS_ERR_OK ) ) +#else if ( ( error = ivas_mcmasa_enc_reconfig( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1792,7 +2006,7 @@ static ivas_error ivas_mc_enc_reconfig( new_brate_CPE = ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; } - if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, new_brate_SCE, new_brate_CPE, last_mc_mode ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, new_brate_SCE, new_brate_CPE, last_mc_mode ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 2a200c8a4..0cfad1d3b 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -1604,522 +1604,182 @@ void mctStereoIGF_enc_fx( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - float *orig_spectrum[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - float powerSpec[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#endif // IVAS_FLOAT_FIXED - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ) { -#ifdef IVAS_FLOAT_FIXED Word32 *p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_inv_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_powerSpec_fx[NB_DIV]; -#endif // IVAS_FLOAT_FIXED - int16_t b, nSubframes, L_subframeTCX; - int16_t p_ch[2], n, ch, ch1, ch2; + Word16 b, nSubframes, L_subframeTCX; + Word16 p_ch[2], n, ch, ch1, ch2, s = 31; + Word16 q_pS_ch[2]; Encoder_State *p_st[NB_DIV]; Encoder_State *st; - float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV]; - float *p_orig_spectrum[CPE_CHANNELS][NB_DIV]; - float *p_powerSpec[NB_DIV]; - int16_t singleChEle[MCT_MAX_CHANNELS]; + Word16 singleChEle[MCT_MAX_CHANNELS]; + Word16 q_spectrum; L_subframeTCX = 0; /* to avoid compilation warning */ - set_s( singleChEle, 1, hMCT->nchan_out_woLFE ); + move16(); + set16_fx( singleChEle, 1, hMCT->nchan_out_woLFE ); - for ( b = 0; b < hMCT->currBlockDataCnt; b++ ) + FOR( b = 0; b < hMCT->currBlockDataCnt; b++ ) { ch1 = hMCT->hBlockData[b]->ch1; ch2 = hMCT->hBlockData[b]->ch2; + move16(); + move16(); p_ch[0] = ch1; p_ch[1] = ch2; + move16(); + move16(); singleChEle[hMCT->hBlockData[b]->ch1] = 0; singleChEle[hMCT->hBlockData[b]->ch2] = 0; + move16(); + move16(); /* point to encoder states of actual channels to write block pair bits */ p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; - if ( ch1 > 0 ) + IF( ch1 > 0 ) { sts[ch1]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } - if ( ch2 > 0 ) + IF( ch2 > 0 ) { sts[ch2]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } -#if 1 p_powerSpec_fx[0] = powerSpec_fx[ch1]; p_powerSpec_fx[1] = powerSpec_fx[ch2]; -#endif - p_powerSpec[0] = powerSpec[ch1]; - p_powerSpec[1] = powerSpec[ch2]; /* Band-wise M/S for MDST */ - nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV; - for ( n = 0; n < nSubframes; n++ ) + nSubframes = NB_DIV; + move16(); + if ( EQ_16( p_st[0]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + move16(); + } + + FOR( n = 0; n < nSubframes; n++ ) { -#if 1 - p_orig_spectrum[0][n] = orig_spectrum[ch1][n]; - p_orig_spectrum[1][n] = orig_spectrum[ch2][n]; - p_powerSpecMsInv[0][n] = powerSpecMsInv[ch1][n]; - p_powerSpecMsInv[1][n] = powerSpecMsInv[ch2][n]; -#endif p_orig_spectrum_fx[0][n] = orig_spectrum_fx[ch1][n]; p_orig_spectrum_fx[1][n] = orig_spectrum_fx[ch2][n]; p_powerSpecMsInv_fx[0][n] = powerSpecMsInv_fx[ch1][n]; p_powerSpecMsInv_fx[1][n] = powerSpecMsInv_fx[ch2][n]; p_inv_spectrum_fx[0][n] = inv_spectrum_fx[ch1][n]; p_inv_spectrum_fx[1][n] = inv_spectrum_fx[ch2][n]; - if ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] != hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] || - hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) - { + q_pS_ch[0] = q_powerSpec[ch1]; + q_pS_ch[1] = q_powerSpec[ch2]; + move16(); + move16(); -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - Word16 p_orig_spectrum_e[2]; - IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; - hIGFEnc[0] = p_st[0]->hIGFEnc; - hIGFEnc[1] = p_st[1]->hIGFEnc; + test(); + IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ) || + EQ_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) + { - Word16 igfGridIdx; - IF( p_st[0]->last_core == ACELP_CORE && EQ_16( p_st[0]->core, TCX_20_CORE ) ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - } - ELSE IF( EQ_16( p_st[0]->core, TCX_20_CORE ) ) - { - igfGridIdx = IGF_GRID_LB_NORM; - } - ELSE + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; + s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); + s = s_min( s, q_pS_ch[ch] ); } - f2me_buf( p_orig_spectrum[0][n], p_orig_spectrum_fx[0][n], &p_orig_spectrum_e[0], hIGFEnc[0]->infoStopLine ); - f2me_buf( p_orig_spectrum[1][n], p_orig_spectrum_fx[1][n], &p_orig_spectrum_e[1], hIGFEnc[1]->infoStopLine ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - H_IGF_GRID hGrid; - Word16 *swb_offset; - hPrivateData = &hIGFEnc[ch]->igfData; - hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; - swb_offset = hGrid->swb_offset; - hIGFEnc[ch]->tns_predictionGain = float_to_fix16( hIGFEnc[ch]->tns_predictionGain_flt, Q23 ); - p_st[ch]->hTcxEnc->spectrum_e[n] = 31 - Q_factor_arrL( p_st[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); - p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( &p_powerSpec[ch][0], hGrid->infoGranuleLen ) ); - p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( inv_spectrum[ch][n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); - p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( p_powerSpecMsInv[ch][0], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); - floatToFixed_arr32( p_st[ch]->hTcxEnc->spectrum[n], p_st[ch]->hTcxEnc->spectrum_fx[n], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); - floatToFixed_arr32( &p_powerSpec[ch][0], &p_powerSpec_fx[ch][0], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); - floatToFixed_arr32( inv_spectrum[ch][n], inv_spectrum_fx[ch][n], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); - floatToFixed_arr32( p_powerSpecMsInv[ch][0], p_powerSpecMsInv_fx[ch][0], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); - float max_sb = 0; - float max_tb = 0; - Word16 max_sb_fx = 0; - Word16 max_tb_fx = 0; - FOR( Word16 sfb = 0; sfb < 23; sfb++ ) - { - f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - max_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_tb ); - max_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_tb ); - max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_sb ); - f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - } - FOR( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ - FOR( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); - } - } - floatToFixed_arr16( &hGrid->whiteningThreshold_flt[0][0], &hGrid->whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); + scale_sig32( p_st[ch]->hTcxEnc->spectrum_fx[0], N_MAX, sub( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[0] ) ) ); + scale_sig32( p_inv_spectrum_fx[ch][0], L_FRAME48k, sub( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[0] ) ) ); + p_st[ch]->hTcxEnc->spectrum_e[0] = sub( 31, s ); + p_st[ch]->hTcxEnc->spectrum_e[1] = sub( 31, s ); + move16(); + move16(); + + scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pS_ch[ch] ) ); + scale_sig32( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->L_frameTCX, sub( s, q_pS_ch[ch] ) ); + q_powerSpec[ch1] = s; + q_powerSpec[ch2] = s; + move16(); + move16(); } -#endif /**********************************flt to fix ends here*******************************************************/ - hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0]; - hIGFEnc[1]->spec_be_igf_e = p_orig_spectrum_e[1]; + + p_st[0]->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); + p_st[1]->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); + move16(); + move16(); + ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate ); -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - H_IGF_GRID hGrid; - hPrivateData = &hIGFEnc[ch]->igfData; - hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; - me2f_buf( p_st[ch]->hTcxEnc->spectrum_fx[n], p_st[ch]->hTcxEnc->spectrum_e[n], p_st[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); - me2f_buf( &p_powerSpec_fx[ch][0], p_st[ch]->hTcxEnc->spectrum_e[n], &p_powerSpec[ch][0], hGrid->infoGranuleLen ); - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); - } - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); - } - } - } -#endif /**********************************fix to flt ends here*******************************************************/ } - else + ELSE { - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = p_st[ch]; - L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes; - -#ifdef IVAS_FLOAT_FIXED_ - /* High MLD cases are observed */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData = &st->hIGFEnc->igfData; - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q7 ); - } - - float max_sb = 0; - float max_tb = 0; - Word16 max_sb_fx = 0; - Word16 max_tb_fx = 0; - - float max_fir_tb = 0; - float max_iir_tb = 0; - float max_fir_sb = 0; - float max_iir_sb = 0; - - Word16 max_fir_tb_fx = 0; - Word16 max_iir_tb_fx = 0; - Word16 max_fir_sb_fx = 0; - Word16 max_iir_sb_fx = 0; - FOR( Word16 sfb = 0; sfb < 23; sfb++ ) - { - f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - - max_fir_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_fir_tb ); - f2me_16( max_fir_tb, &max_fir_tb_fx, &hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ); - - max_iir_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_iir_tb ); - f2me_16( max_iir_tb, &max_iir_tb_fx, &hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ); - - max_fir_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_fir_sb ); - f2me_16( max_fir_sb, &max_fir_sb_fx, &hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ); - - max_iir_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_iir_sb ); - f2me_16( max_iir_sb, &max_iir_sb_fx, &hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ); - - max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - } - - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); - } - } - - int igfGridIdx; - if ( st->last_core == ACELP_CORE && st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - } - else if ( st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_NORM; - } - else - { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; - } - - Word16 q_spectrum; - q_spectrum = L_get_q_buf1( orig_spectrum[p_ch[ch]][n], hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - q_spectrum = min( q_spectrum, L_get_q_buf1( st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ) ); - } - floatToFixed_arrL32( orig_spectrum[p_ch[ch]][n], orig_spectrum_fx[p_ch[ch]][n], q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - floatToFixed_arrL32( st->hIGFEnc->spec_be_igf_flt, st->hIGFEnc->spec_be_igf, q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); - st->hIGFEnc->spec_be_igf_e = 31 - q_spectrum; - } - - q_spectrum = L_get_q_buf1( st->hTcxEnc->spectrum[n], st->hTcxEnc->L_frameTCX / nSubframes ); - floatToFixed_arrL32( st->hTcxEnc->spectrum[n], st->hTcxEnc->spectrum_fx[n], q_spectrum, st->hTcxEnc->L_frameTCX / nSubframes ); - - // Word32 powerSpec_fx[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word16 q_powerSpec; - q_powerSpec = L_get_q_buf1( &powerSpec[p_ch[ch]][n * L_subframeTCX], L_subframeTCX ); - floatToFixed_arrL32( &powerSpec[p_ch[ch]][n * L_subframeTCX], &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], q_powerSpec, L_subframeTCX ); - - if ( st->hIGFEnc ) + L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, 1 ); + if ( EQ_16( nSubframes, 1 ) ) { - st->hIGFEnc->tns_predictionGain = float_to_fix16( st->hIGFEnc->tns_predictionGain_flt, Q23 ); - } - -#endif - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &q_powerSpec, st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL32( st->hTcxEnc->spectrum_fx[n], st->hTcxEnc->spectrum[n], q_spectrum, st->hTcxEnc->L_frameTCX / nSubframes ); - fixedToFloat_arrL32( &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &powerSpec[p_ch[ch]][n * L_subframeTCX], q_powerSpec, L_subframeTCX ); - - if ( st->hIGFEnc ) - { - st->hIGFEnc->tns_predictionGain_flt = fix16_to_float( st->hIGFEnc->tns_predictionGain, Q23 ); - me2f_buf( st->hIGFEnc->spec_be_igf, st->hIGFEnc->spec_be_igf_e, st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); + L_subframeTCX = st->hTcxEnc->L_frameTCX; + move16(); } - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); - } + q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); - } - } + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &q_powerSpec[p_ch[ch]], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att = fix16_to_float( st->hTdCngEnc->CNG_att_fx, Q7 ); - } -#endif -#else - ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[p_ch[ch]][n], &powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch1], 0 ); -#endif + st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); + move16(); } } } } /* channel elements that are coded separately detected */ - if ( sum_s( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 ) + IF( sum16_fx( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 ) { - for ( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ ) + FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ ) { - if ( singleChEle[ch] ) + IF( singleChEle[ch] ) { st = sts[ch]; - if ( - st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } - if ( ch > 0 ) + IF( ch > 0 ) { st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } - nSubframes = st->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV; - for ( n = 0; n < nSubframes; n++ ) + nSubframes = NB_DIV; + move16(); + if ( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) { -#ifdef IVAS_FLOAT_FIXED_ - /* High MLD cases are observed */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData = &st->hIGFEnc->igfData; - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q7 ); - } - - float max_sb = 0; - float max_tb = 0; - Word16 max_sb_fx = 0; - Word16 max_tb_fx = 0; - - float max_fir_tb = 0; - float max_iir_tb = 0; - float max_fir_sb = 0; - float max_iir_sb = 0; - - Word16 max_fir_tb_fx = 0; - Word16 max_iir_tb_fx = 0; - Word16 max_fir_sb_fx = 0; - Word16 max_iir_sb_fx = 0; - FOR( Word16 sfb = 0; sfb < 23; sfb++ ) - { - f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - - max_fir_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_fir_tb ); - f2me_16( max_fir_tb, &max_fir_tb_fx, &hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ); - - max_iir_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_iir_tb ); - f2me_16( max_iir_tb, &max_iir_tb_fx, &hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ); - - max_fir_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_fir_sb ); - f2me_16( max_fir_sb, &max_fir_sb_fx, &hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ); - - max_iir_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_iir_sb ); - f2me_16( max_iir_sb, &max_iir_sb_fx, &hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ); - - max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - } - - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); - } - } - - int igfGridIdx; - if ( st->last_core == ACELP_CORE && st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - } - else if ( st->core == TCX_20_CORE ) - { - igfGridIdx = IGF_GRID_LB_NORM; - } - else - { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; - } - - L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes; - Word16 q_spectrum; - q_spectrum = L_get_q_buf1( orig_spectrum[ch][n], hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - q_spectrum = min( q_spectrum, L_get_q_buf1( st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ) ); - } - floatToFixed_arrL32( orig_spectrum[ch][n], orig_spectrum_fx[ch][n], q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine ); - if ( st->hIGFEnc ) - { - floatToFixed_arrL32( st->hIGFEnc->spec_be_igf_flt, st->hIGFEnc->spec_be_igf, q_spectrum, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); - st->hIGFEnc->spec_be_igf_e = 31 - q_spectrum; - } - - q_spectrum = L_get_q_buf1( st->hTcxEnc->spectrum[n], st->hTcxEnc->L_frameTCX / nSubframes ); - floatToFixed_arrL32( st->hTcxEnc->spectrum[n], st->hTcxEnc->spectrum_fx[n], q_spectrum, st->hTcxEnc->L_frameTCX / nSubframes ); - - // Word32 powerSpec_fx[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word16 q_powerSpec; - q_powerSpec = L_get_q_buf1( &powerSpec[ch][n * L_subframeTCX], L_subframeTCX ); - floatToFixed_arrL32( &powerSpec[ch][n * L_subframeTCX], &powerSpec_fx[ch][n * L_subframeTCX], q_powerSpec, L_subframeTCX ); - - if ( st->hIGFEnc ) - { - st->hIGFEnc->tns_predictionGain = float_to_fix16( st->hIGFEnc->tns_predictionGain_flt, Q23 ); - } -#endif - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powerSpec, st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL32( st->hTcxEnc->spectrum_fx[n], st->hTcxEnc->spectrum[n], q_spectrum, st->hTcxEnc->L_frameTCX / nSubframes ); - fixedToFloat_arrL32( &powerSpec_fx[ch][n * L_subframeTCX], &powerSpec[ch][n * L_subframeTCX], q_powerSpec, L_subframeTCX ); + nSubframes = 1; + move16(); + } - if ( st->hIGFEnc ) - { - st->hIGFEnc->tns_predictionGain_flt = fix16_to_float( st->hIGFEnc->tns_predictionGain, Q23 ); - me2f_buf( st->hIGFEnc->spec_be_igf, st->hIGFEnc->spec_be_igf_e, st->hIGFEnc->spec_be_igf_flt, hPrivateData->igfInfo.grid[igfGridIdx].stopLine - IGF_START_MN ); - } + FOR( n = 0; n < nSubframes; n++ ) + { + q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_FIR_TB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_IIR_TB_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_FIR_SB_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_IIR_SB_e[sfb] ); - hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); - } + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powerSpec[ch], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); - } - } - - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att = fix16_to_float( st->hTdCngEnc->CNG_att_fx, Q7 ); - } -#endif -#else - ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[ch][n], &powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif + st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); + move16(); } } } @@ -2127,7 +1787,7 @@ void mctStereoIGF_enc_fx( return; } -#endif +#else void mctStereoIGF_enc( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ @@ -2239,3 +1899,4 @@ void mctStereoIGF_enc( return; } +#endif diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 71e395178..2bcaf05af 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -291,7 +291,7 @@ ivas_error ivas_omasa_enc_config( } /* reconfigure core-coders for ISMs */ - if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, 1, 2, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate, MC_MODE_NONE ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, 1, 2, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate, MC_MODE_NONE ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index 6e4d19a36..4da8169fb 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -80,7 +80,6 @@ static void ivas_merge_sba_transports_fx( Word16 *Q_out ) { Word16 i, j, nchan_sba; - nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); FOR( i = 0; i < nchan_sba; i++ ) @@ -167,7 +166,6 @@ ivas_error ivas_osba_enc_open_fx( hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); move32(); } - st_ivas->hOSba = hOSba; return error; @@ -304,10 +302,10 @@ ivas_error ivas_osba_enc_reconfig( { DIRAC_ENC_HANDLE hDirAC = st_ivas->hDirAC; SPAR_ENC_HANDLE hSpar; - int16_t analysis_order_old; - int16_t spar_reconfig_flag; - int16_t nbands_old; - int16_t ndir_old; + Word16 analysis_order_old; + Word16 spar_reconfig_flag; + Word16 nbands_old; + Word16 ndir_old; spar_reconfig_flag = 0; move16(); @@ -465,52 +463,57 @@ ivas_error ivas_osba_enc_reconfig( } } -#ifdef IVAS_FLOAT_FIXED ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); -#else - ivas_spar_config( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); -#endif hSpar = st_ivas->hSpar; - if ( st_ivas->nchan_transport == 1 ) + IF( EQ_16( st_ivas->nchan_transport, 1 ) ) { hEncoderConfig->element_mode_init = IVAS_SCE; + move16(); } - else + ELSE { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } - if ( nchan_transport_old != st_ivas->nchan_transport || ( ivas_total_brate < IVAS_512k && hEncoderConfig->last_ivas_total_brate >= IVAS_512k ) || ( ivas_total_brate >= IVAS_512k && hEncoderConfig->last_ivas_total_brate < IVAS_512k ) ) + test(); + test(); + test(); + test(); + IF( NE_16( nchan_transport_old, st_ivas->nchan_transport ) || ( LT_32( ivas_total_brate, IVAS_512k ) && GE_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) || ( GE_32( ivas_total_brate, IVAS_512k ) && LT_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) ) { /* FB mixer handle */ - if ( hDirAC->hFbMixer != NULL ) + IF( hDirAC->hFbMixer != NULL ) { ivas_FB_mixer_close( &( hDirAC->hFbMixer ), hEncoderConfig->input_Fs, 0 ); hDirAC->hFbMixer = NULL; } spar_reconfig_flag = 1; + move16(); ivas_spar_enc_close( &( st_ivas->hSpar ), hEncoderConfig->input_Fs, hEncoderConfig->nchan_inp, spar_reconfig_flag ); - if ( ( error = ivas_spar_enc_open( st_ivas, spar_reconfig_flag ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_spar_enc_open( st_ivas, spar_reconfig_flag ) ) != IVAS_ERR_OK ) { return error; } } st_ivas->hSpar->spar_reconfig_flag = spar_reconfig_flag; - if ( ( error = ivas_dirac_enc_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) + move16(); + IF( ( error = ivas_dirac_enc_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->hQMetaData->q_direction->cfg.nbands != nbands_old || st_ivas->hQMetaData->no_directions != ndir_old ) + test(); + IF( NE_16( st_ivas->hQMetaData->q_direction->cfg.nbands, nbands_old ) || NE_16( st_ivas->hQMetaData->no_directions, ndir_old ) ) { - int16_t dir, j, i; + Word16 dir, j, i; IVAS_QDIRECTION *q_direction = st_ivas->hQMetaData->q_direction; - for ( dir = 0; dir < st_ivas->hQMetaData->no_directions; dir++ ) + FOR( dir = 0; dir < st_ivas->hQMetaData->no_directions; dir++ ) { - for ( j = 0; j < q_direction[dir].cfg.nbands; j++ ) + FOR( j = 0; j < q_direction[dir].cfg.nbands; j++ ) { - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { q_direction[dir].band_data[j].energy_ratio_index[i] = 0; q_direction[dir].band_data[j].energy_ratio_index_mod[i] = 0; @@ -523,24 +526,29 @@ ivas_error ivas_osba_enc_reconfig( /*-----------------------------------------------------------------* * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ - - if ( old_ism_mode == ISM_MODE_NONE && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + test(); + test(); + IF( old_ism_mode == ISM_MODE_NONE && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) { - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; + st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->hEncoderConfig->nchan_ism, 1 ), 1 ) ); } - else if ( old_ism_mode == ISM_SBA_MODE_DISC && st_ivas->ism_mode == ISM_MODE_NONE ) + ELSE IF( EQ_32( old_ism_mode, ISM_SBA_MODE_DISC ) && st_ivas->ism_mode == ISM_MODE_NONE ) { - nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; + nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism ); } - else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) { - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; + st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->hEncoderConfig->nchan_ism, 1 ), 1 ) ); nCPE_old = st_ivas->nCPE; + move16(); nchan_transport_old = st_ivas->nchan_transport; - nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; + move16(); + nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism ); } - - if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, ivas_total_brate / st_ivas->nchan_transport, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ) ) != IVAS_ERR_OK ) + Word16 tmp_e; + Word32 bitrate_per_chan = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) ); + bitrate_per_chan = L_shr( bitrate_per_chan, sub( 15, tmp_e ) ); + IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, bitrate_per_chan, imult3216( bitrate_per_chan, CPE_CHANNELS ), MC_MODE_NONE ) ) != IVAS_ERR_OK ) { return error; } @@ -885,7 +893,6 @@ static void ivas_osba_render_ism_to_sba_fx( Word16 nchan_sba; nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); - FOR( i = 0; i < nchan_sba; i++ ) { set_val_Word32( data_out_fx[i], 0, input_frame ); diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index e7d6079fa..4d246daa0 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -8420,23 +8420,28 @@ static void transform_azimuth_dir2_fx( /* transform azimuth */ FOR( b = 0; b < hQMetaData->q_direction[1].cfg.nblocks; b++ ) { - hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_add( L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth_fx[b] ), 180 << Q22 ); - if ( GE_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 180 << Q22 ) ) + Word64 azimuth; + azimuth = W_add( W_deposit32_l( L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth_fx[b] ) ), 180 << Q22 ); + + if ( GE_64( azimuth, 180 << Q22 ) ) { - hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 360 << Q22 ); + azimuth = W_sub( azimuth, 360 << Q22 ); } - if ( LT_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], -( 180 << Q22 ) ) ) + if ( LT_64( azimuth, -( 180 << Q22 ) ) ) { - hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_add( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 360 << Q22 ); + azimuth = W_add( azimuth, 360 << Q22 ); } - if ( GE_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 180 << Q22 ) ) + if ( GE_64( azimuth, 180 << Q22 ) ) { - hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 360 << Q22 ); + azimuth = W_sub( azimuth, 360 << Q22 ); } - if ( LT_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], -( 180 << Q22 ) ) ) + if ( LT_64( azimuth, -( 180 << Q22 ) ) ) { - hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_add( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 360 << Q22 ); + azimuth = W_add( azimuth, 360 << Q22 ); } + + hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = W_extract_l( azimuth ); + move32(); } } } diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index 21953637e..549b7ccdc 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -321,7 +321,7 @@ ivas_error ivas_sba_enc_reconfigure( * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ - if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, ivas_total_brate / st_ivas->nchan_transport, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, ivas_total_brate / st_ivas->nchan_transport, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 62778a4dc..97c5a0d6e 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -939,6 +939,7 @@ static ivas_error ivas_spar_enc_process( int16_t ts, l_ts, num_del_samples, b, i_ts; float *ppIn_FR_real[IVAS_SPAR_MAX_CH], *ppIn_FR_imag[IVAS_SPAR_MAX_CH]; + Word32 *ppIn_FR_real_fx[IVAS_SPAR_MAX_CH], *ppIn_FR_imag_fx[IVAS_SPAR_MAX_CH]; float wyzx_del_buf[FOA_CHANNELS][IVAS_FB_1MS_48K_SAMP]; int16_t dyn_active_w_flag; int16_t nchan_fb_in; @@ -1094,29 +1095,81 @@ static ivas_error ivas_spar_enc_process( #endif /* prepare Parameter MDFT analysis */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS for ( i = 0; i < nchan_fb_in; i++ ) { ppIn_FR_real[i] = p_pcm_tmp[i]; ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; p_pcm_tmp[i] = data_f[i]; } +#endif - l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + for ( i = 0; i < nchan_fb_in; i++ ) + { + ppIn_FR_real_fx[i] = p_pcm_tmp_fx[i]; + ppIn_FR_imag_fx[i] = p_pcm_tmp_fx[i] + input_frame; + p_pcm_tmp_fx[i] = data_fx[i]; + } - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( i = 0; i < nchan_fb_in; i++ ) { - ivas_fb_mixer_get_windowed_fr( hSpar->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts, nchan_fb_in ); + floatToFixed_arrL( p_pcm_tmp[i], p_pcm_tmp_fx[i], Q14, input_frame ); + floatToFixed_arrL( hSpar->hFbMixer->ppFilterbank_prior_input[i], hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], Q14, input_frame ); + } +#endif + l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + Word16 gb = find_guarded_bits_fx( l_ts ); + FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + ivas_fb_mixer_get_windowed_fr_fx( hSpar->hFbMixer, p_pcm_tmp_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, l_ts, l_ts, nchan_fb_in, gb ); - ivas_fb_mixer_update_prior_input( hSpar->hFbMixer, p_pcm_tmp, l_ts, nchan_fb_in ); + ivas_fb_mixer_update_prior_input_fx( hSpar->hFbMixer, p_pcm_tmp_fx, l_ts, nchan_fb_in ); + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + p_pcm_tmp_fx[i] += l_ts; + ppIn_FR_real_fx[i] += l_ts; + ppIn_FR_imag_fx[i] += l_ts; + } + } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /*To be removed*/ + FOR( i = 0; i < nchan_fb_in; i++ ) + { + fixedToFloat_arrL( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->ppFilterbank_prior_input[i], Q14, input_frame ); + } + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { for ( i = 0; i < nchan_fb_in; i++ ) { + p_pcm_tmp_fx[i] -= l_ts; + ppIn_FR_real_fx[i] -= l_ts; + ppIn_FR_imag_fx[i] -= l_ts; + } + } + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + for ( int ch_idx = 0; ch_idx < nchan_fb_in; ch_idx++ ) + { + fixedToFloat_arrL( ppIn_FR_real_fx[ch_idx], ppIn_FR_real[ch_idx], Q14 - gb, l_ts ); + fixedToFloat_arrL( ppIn_FR_imag_fx[ch_idx], ppIn_FR_imag[ch_idx], Q14 - gb, l_ts ); + fixedToFloat_arrL( p_pcm_tmp_fx[ch_idx], p_pcm_tmp[ch_idx], Q14, l_ts ); + } + for ( i = 0; i < nchan_fb_in; i++ ) + { + p_pcm_tmp_fx[i] += l_ts; + ppIn_FR_real_fx[i] += l_ts; + ppIn_FR_imag_fx[i] += l_ts; + p_pcm_tmp[i] += l_ts; ppIn_FR_real[i] += l_ts; ppIn_FR_imag[i] += l_ts; } } - +#endif /* turn pointers back to the local buffer, needed for the following processing */ for ( i = 0; i < nchan_fb_in; i++ ) { diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 2e44e50ae..2e167fe14 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -584,6 +584,9 @@ typedef struct stereo_tca_enc_data_structure Word32 instTargetGain_fx; /* instantaneous gain norm applied on target (or right) channel in current frame //Q29*/ Word32 prevTargetGain_fx; /* gain norm applied on target (or right) channel in previous frame //Q29 taken from decoder*/ Word16 corrStatsSmoothFac_fx; /* gD/corrStats smoothing based on corrStats //Q15*/ + Word16 targetGain_fx_e; + Word16 instTargetGain_fx_e; + Word16 prevTargetGain_fx_e; Word16 lMemRecalc; Word16 lMemRecalc_12k8; @@ -790,9 +793,9 @@ typedef struct ivas_stereo_classifier_data_structure #ifndef IVAS_FLOAT_FIXED float unclr_relE_0_1_LT[UNCLR_RC_ORDER]; float unclr_wscore; -#endif - Word16 unclr_decision; /* UNCLR stereo classifier decision (0/1) */ float unclr_fv[SSC_MAX_NFEA]; /* UNCLR - feature vector */ +#endif + Word16 unclr_decision; /* UNCLR stereo classifier decision (0/1) */ Word16 unclr_corrLagMax_prev; #ifndef IVAS_FLOAT_FIXED float xtalk_score_buf[XTALK_SCORE_BUF_LEN]; @@ -888,11 +891,12 @@ typedef struct typedef struct front_vad_enc { - int16_t ini_frame; /* initialization frames counter */ - float lp_speech; /* long term speech average */ - /* Q9 long term speech average */ - float lp_noise; /* long term noise average */ - /* long term noise average */ + int16_t ini_frame; /* initialization frames counter */ +#ifndef IVAS_FLOAT_FIXED + float lp_speech; /* long term speech average */ + /* Q9 long term speech average */ + float lp_noise; /* long term noise average */ +#endif float mem_decim[2 * L_FILT_MAX]; /* decimation filter memory */ float buffer_12k8[3 * L_FRAME / 2]; /* 12k8 signal buffer */ @@ -1107,6 +1111,10 @@ typedef struct ivas_mc_paramupmix_enc_data_structure ivas_enc_cov_handler_state_t *hCovEnc[MC_PARAMUPMIX_COMBINATIONS]; float ***cov_real[MC_PARAMUPMIX_COMBINATIONS]; float ***cov_dtx_real[MC_PARAMUPMIX_COMBINATIONS]; +#ifdef IVAS_FLOAT_FIXED + Word32 ***cov_real_fx[MC_PARAMUPMIX_COMBINATIONS]; + Word32 ***cov_dtx_real_fx[MC_PARAMUPMIX_COMBINATIONS]; +#endif float *midside[MC_PARAMUPMIX_COMBINATIONS][MC_PARAMUPMIX_NCH]; /* hold PCM of mid-side data */ #ifdef IVAS_FLOAT_FIXED Word32 *midside_fx[MC_PARAMUPMIX_COMBINATIONS][MC_PARAMUPMIX_NCH]; /* hold PCM of mid-side data */ //(st_ivas->q_data_fx) @@ -1206,7 +1214,10 @@ typedef struct ivas_masa_sync_struct typedef struct ivas_masa_encoder_data_struct { float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - +#ifdef IVAS_FLOAT_FIXED + Word32 energy_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 energy_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; +#endif int16_t num_Cldfb_instances; HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_ENC_CLDFB_INSTANCES]; int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; @@ -1214,6 +1225,10 @@ typedef struct ivas_masa_encoder_data_struct float importanceWeight[MASA_FREQUENCY_BANDS]; SPHERICAL_GRID_DATA Sph_Grid16; float lfeToTotalEnergyRatio[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef IVAS_FLOAT_FIXED + Word32 lfeToTotalEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 lfeToTotalEnergyRatio_e[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float prevq_lfeToTotalEnergyRatio; int16_t prevq_lfeIndex; @@ -1247,7 +1262,11 @@ typedef struct ivas_mcmasa_enc_data_structure int16_t nCodingBands; /* delay compensation */ +#ifndef IVAS_FLOAT_FIXED float *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ +#else + Word32 *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ +#endif int16_t num_samples_delay_comp; int16_t num_slots_delay_comp; @@ -1257,13 +1276,19 @@ typedef struct ivas_mcmasa_enc_data_structure IVAS_FB_MIXER_HANDLE hFbMixerLfe; /* DirAC parameter estimation */ +#ifndef IVAS_FLOAT_FIXED float **direction_vector_m[DIRAC_NUM_DIMS]; /* Average direction vector */ +#else + Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ +#endif + Word16 **direction_vector_e[DIRAC_NUM_DIMS]; /* Average direction vector */ int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; int16_t block_grouping[5]; /* diffuseness */ int16_t index_buffer_intensity; int8_t no_col_avg_diff; +#ifndef IVAS_FLOAT_FIXED float **buffer_intensity_real[DIRAC_NUM_DIMS]; float **buffer_intensity_real_vert; float *buffer_energy; @@ -1271,26 +1296,60 @@ typedef struct ivas_mcmasa_enc_data_structure float chnlToFoaMtx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; float chnlToFoaEvenMtx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; float ls_azimuth[MCMASA_MAX_ANA_CHANS]; +#else + Word32 **buffer_intensity_real_fx[DIRAC_NUM_DIMS]; + Word16 buffer_intensity_real_q[DIRAC_NO_COL_AVG_DIFF]; + Word32 **buffer_intensity_real_vert_fx; + Word16 buffer_intensity_real_vert_q[DIRAC_NO_COL_AVG_DIFF]; + Word32 *buffer_energy_fx; + Word16 buffer_energy_q[DIRAC_NO_COL_AVG_DIFF]; + Word32 chnlToFoaMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; + Word32 chnlToFoaEvenMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; + Word32 ls_azimuth_fx[MCMASA_MAX_ANA_CHANS]; +#endif + int16_t leftNearest[MCMASA_MAX_ANA_CHANS]; int16_t rightNearest[MCMASA_MAX_ANA_CHANS]; int16_t numHorizontalChannels; uint8_t isHorizontalSetup; uint8_t combineRatios; +#ifndef IVAS_FLOAT_FIXED float prevMultiChEne; float prevDownmixEne; float prevEQ; float interpolator[L_FRAME48k]; +#else + Word32 prevMultiChEne_fx; + Word16 prevMultiChEne_e; + Word32 prevDownmixEne_fx; + Word16 prevDownmixEne_e; + Word32 prevEQ_fx; + Word16 prevEQ_e; + Word16 interpolator_fx[L_FRAME48k]; +#endif uint8_t separateChannelEnabled; int16_t separateChannelIndex; /* LFE coding */ +#ifndef IVAS_FLOAT_FIXED float lfeLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; float totalLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; float *lfeAnaRingBuffer[2]; +#else + Word32 lfeLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 lfeLfEne_e[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 totalLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 totalLfEne_e[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *lfeAnaRingBuffer[2]; +#endif int16_t ringBufferPointer; +#ifndef IVAS_FLOAT_FIXED float lowpassSum[2]; +#else + Word32 lowpassSum[2]; +#endif int16_t ringBufferSize; } MCMASA_ENC_DATA, *MCMASA_ENC_HANDLE; @@ -1436,6 +1495,7 @@ typedef struct mct_enc_data_structure #ifdef IVAS_FLOAT_FIXED Word32 *p_mdst_spectrum_long_fx[MCT_MAX_BLOCKS][CPE_CHANNELS]; Word32 *p_orig_spectrum_long_fx[MCT_MAX_BLOCKS][CPE_CHANNELS]; + Word16 q_orig_spectrum_long_fx; #endif int16_t tnsBits[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns bits in the frame */ int16_t tnsSize[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns parameters put into prm */ diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index b754db8de..1b1d27c34 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -464,8 +464,8 @@ void stereo_classifier_init( hStereoClassif->unclr_decision = 0; #ifndef IVAS_FLOAT_FIXED hStereoClassif->unclr_wscore = 0.0f; -#endif set_f( hStereoClassif->unclr_fv, -1.0f, SSC_MAX_NFEA ); +#endif hStereoClassif->unclr_corrLagMax_prev = 0; #ifndef IVAS_FLOAT_FIXED hStereoClassif->ave_ener_L = 0; diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 235d1a540..1bbd497e5 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1750,6 +1750,154 @@ static void corrStatsEst( return; } #endif + +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------- + * Function estDownmixGain_fx() + * + * Down mix gain estimation module; convert L/R to M/S. + * ---------------------------------------------------------------*/ + +static void estDownmixGain_fx( + STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */ + const Word32 *chan1, /* i : reference signal Qx */ + const Word32 *chan2, /* i/o: target signal to be scaled Qx */ + const Word16 q_chan, /* i : Q of the channel signal */ + const Word16 ncShift, /* i : shift */ + const Word16 length, /* i : input frame length */ + const Word16 element_mode, /* i : element mode */ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +) +{ + Word16 i, i1, i2; + Word32 tempN, tempD; + Word16 alpha, temp; + Word16 currentGain, currentGain_e; + Word32 currentGain_log10; + Word32 unclr_instTargetGain; + Word32 prevTargetGain_log10; + Word16 exp = 0; + Word16 shift = 0; + move16(); // exp + move16(); // shift + + IF( hStereoTCA->refChanIndx == L_CH_INDX ) + { + i1 = 0; + move16(); + i2 = ncShift; + move16(); + } + ELSE + { + i1 = ncShift; + move16(); + i2 = 0; + move16(); + } + + /* abs sample sum estimation */ + tempN = 0; + move32(); + tempD = 0; + move32(); + FOR( i = 0; i < length; i++ ) + { + tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); + tempD = L_add( tempD, L_abs( chan2[i2 + i] ) ); + } + + alpha = hStereoTCA->corrStatsSmoothFac_fx; + move16(); + IF( tempD == 0 ) + { + currentGain_e = norm_l( hStereoTCA->prevTargetGain_fx ); + currentGain = extract_h( L_shl( hStereoTCA->prevTargetGain_fx, currentGain_e ) ); + currentGain_e = add( currentGain_e, hStereoTCA->prevTargetGain_fx_e ); + } + ELSE + { + currentGain = BASOP_Util_Divide3232_Scale( tempN, tempD, &exp ); + currentGain_e = exp; + move16(); + } + + currentGain = s_max( EPSILON_FX, currentGain ); + hStereoTCA->instTargetGain_fx = L_deposit_h( currentGain ); + move32(); + hStereoTCA->instTargetGain_fx_e = currentGain_e; + move16(); + prevTargetGain_log10 = BASOP_Util_Log10( hStereoTCA->prevTargetGain_fx, hStereoTCA->prevTargetGain_fx_e ); // Output in Q25 + currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25 + // multiplication result will be Q25 should be fit to Q15 hence right shift by 10. + // Q25 - Q10 = Q15 + currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); + currentGain_e = 0; + move16(); + + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) && hStereoClassif != NULL ) + { + Word16 exp_chan = sub( Q31, q_chan ); + Word16 exp_div; + // tempD = powf( 10, currentGain ); + // 10 ^ currentGain = 2 ^ (3.32192809488 * currentGain) + // 3.32192809488 in Q13 27213 + tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp ); + unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); + exp = add( sub( exp_chan, exp ), exp_div ); + unclr_instTargetGain = BASOP_Util_Log10( L_add( unclr_instTargetGain, L_shr( MAX_32, sub( Q31, exp ) ) ), exp ); + // unclr_fv_fx is expected in Q15 - log result will be in Q25 - hence rightshift by 10. + hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); + move32(); + } + + test(); + IF( EQ_16( tdm_LRTD_flag, 1 ) ) + { + currentGain = 0; + move32(); + } + ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */ + { + currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, ¤tGain_e ); // Q = 15 + 0 - (15 - exp) + /* Division result Q has to be got back to the Q of initial currentGain hence the shift operation below */ + IF( currentGain_e != 0 ) + { + currentGain = shr( currentGain, sub( Q15, currentGain_e ) ); + currentGain_e = 0; + move16(); + } + } + + + IF( GE_16( norm_s( currentGain ), sub( currentGain_e, 1 ) ) ) + { + /* convert currentGain into Q14 */ + currentGain = shl( currentGain, sub( currentGain_e, 1 ) ); + currentGain_e = 1; + move16(); + } + ELSE + { + shift = sub( currentGain_e, 1 ); + move16(); + } + + /* quantize the target gain */ + hStereoTCA->indx_ica_gD = usquant_fx( currentGain, &temp, shr( STEREO_TCA_GDMIN_FX_Q14, shift ), shr( STEREO_TCA_GDSTEP_FX_Q13, shift ), 1 << STEREO_BITS_TCA_GD ); + move16(); + // hStereoTCA->targetGain_fx = powf( 10, temp ); + // 10 ^ temp = 2 ^ (3.32192809488 * temp) + // 3.32192809488 in Q13 27213 + // exponent of power function input will be 2 more since constant is in Q13 + hStereoTCA->targetGain_fx = BASOP_util_Pow2( L_mult( temp, 27213 ), add( currentGain_e, 2 ), &hStereoTCA->targetGain_fx_e ); + move32(); + + return; +} +#else /*--------------------------------------------------------------- * Function estDownmixGain() * @@ -1820,6 +1968,7 @@ static void estDownmixGain( return; } +#endif /*--------------------------------------------------------------- * Function icaMemUpdate() @@ -2152,6 +2301,10 @@ void stereo_tca_enc( #ifdef IVAS_FLOAT_FIXED Word32 corrEstStage2_fx[N_MAX_SHIFT_CHANGE + 1]; Word16 corrEstStage2_exp; + Word16 q_com; +#endif +#ifdef IVAS_FLOAT_FIXED + Word16 q_target; #endif /* temp variables */ float tempF, tempF1; @@ -2212,7 +2365,28 @@ void stereo_tca_enc( { hStereoTCA->refChanIndx = L_CH_INDX; hStereoTCA->corrStatsSmoothFac = 0.7f; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_com = L_get_q_buf1( ptrChanL, input_frame ); + // worst case input_frame value is 960 so taking 10 as guard bits + q_com = s_min( q_com, L_get_q_buf1( ptrChanR, input_frame ) ) - 10; + + floatToFixed_arrL32( ptrChanL, ptrChanL_fx, q_com, input_frame ); // not modified + floatToFixed_arrL32( ptrChanR, ptrChanR_fx, q_com, input_frame ); + q_target = L_get_q_buf1( &hStereoTCA->prevTargetGain, 1 ); + hStereoTCA->prevTargetGain_fx = float_to_fix( hStereoTCA->prevTargetGain, q_target ); + hStereoTCA->prevTargetGain_fx_e = Q31 - q_target; + hStereoTCA->corrStatsSmoothFac_fx = float_to_fix16( hStereoTCA->corrStatsSmoothFac, Q15 ); +#endif + estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, NULL, 0 ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hStereoTCA->instTargetGain = fix_to_float( hStereoTCA->instTargetGain_fx, Q31 - hStereoTCA->instTargetGain_fx_e ); + hStereoTCA->targetGain = fix_to_float( hStereoTCA->targetGain_fx, Q31 - hStereoTCA->targetGain_fx_e ); +#endif +#else estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 ); +#endif + hStereoTCA->prevTargetGain = hStereoTCA->targetGain; #ifdef DEBUG_MODE_INFO hStereoTCA->indx_ica_NCShift = 0; @@ -2277,7 +2451,6 @@ void stereo_tca_enc( /* resample the stereo channels */ #ifdef IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 q_com; q_com = L_get_q_buf1( ptrChanL, input_frame ); q_com = min( q_com, L_get_q_buf1( ptrChanR, input_frame ) ); q_com = min( q_com, L_get_q_buf1( hStereoTCA->memdecim, 12 ) ) - 4; @@ -2309,14 +2482,12 @@ void stereo_tca_enc( floatToFixed_arrL32( bufChanL_DS, bufChanL_DS_fx, q_com, L_FRAME_DS + ADDED_MEM_DS ); floatToFixed_arrL32( bufChanR_DS, bufChanR_DS_fx, q_com, L_FRAME_DS + ADDED_MEM_DS ); - floatToFixed_arrL32( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, Q15, SSC_MAX_NFEA ); hStereoTCA->prevTargetGain_fx = floatToFixed_32( hStereoTCA->prevTargetGain, Q29 ); #endif corrStatsEst_fx( hStereoTCA, bufChanL_DS_fx + ADDED_MEM_DS, bufChanR_DS_fx + ADDED_MEM_DS, q_com, ( L_FRAME_DS + L_XCORRMEM_DS ), dsFactor, hCPE->hCoreCoder[0]->vad_flag, hCPE->hCoreCoder[1]->vad_flag, hCPE->hStereoClassif ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL32( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, Q15, SSC_MAX_NFEA ); hStereoTCA->corrStatsSmoothFac = me2f_16( hStereoTCA->corrStatsSmoothFac_fx, 0 ); #endif #else @@ -2532,7 +2703,28 @@ void stereo_tca_enc( } /* Estimate and quantize the gain for scaling */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_com = L_get_q_buf1( ptrChanL, input_frame ); + // worst case input_frame value is 960 so taking 10 as guard bits + q_com = s_min( q_com, L_get_q_buf1( ptrChanR, input_frame ) ) - 10; + + floatToFixed_arrL32( ptrChanL, ptrChanL_fx, q_com, input_frame ); // not modified + floatToFixed_arrL32( ptrChanR, ptrChanR_fx, q_com, input_frame ); + q_target = L_get_q_buf1( &hStereoTCA->prevTargetGain, 1 ); + hStereoTCA->prevTargetGain_fx = float_to_fix( hStereoTCA->prevTargetGain, q_target ); + hStereoTCA->prevTargetGain_fx_e = Q31 - q_target; + hStereoTCA->corrStatsSmoothFac_fx = float_to_fix16( hStereoTCA->corrStatsSmoothFac, Q15 ); +#endif + estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hStereoTCA->instTargetGain = fix_to_float( hStereoTCA->instTargetGain_fx, Q31 - hStereoTCA->instTargetGain_fx_e ); + hStereoTCA->targetGain = fix_to_float( hStereoTCA->targetGain_fx, Q31 - hStereoTCA->targetGain_fx_e ); +#endif + +#else estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag ); +#endif /* quantize the corrStats */ hStereoTCA->indx_ica_NCShift = (int16_t) usquant( ( (float) currentNCShift ) / dsFactor, &tempF, 0, 1.0f, 1 << STEREO_BITS_TCA_CORRSTATS ); @@ -2552,7 +2744,27 @@ void stereo_tca_enc( v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh ); /* Estimate and quantize the gain for scaling */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_com = L_get_q_buf1( ptrChanL, input_frame ); + // worst case input_frame value is 960 so taking 10 as guard bits + q_com = s_min( q_com, L_get_q_buf1( ptrChanR, input_frame ) ) - 10; + + floatToFixed_arrL32( ptrChanL, ptrChanL_fx, q_com, input_frame ); // not modified + floatToFixed_arrL32( ptrChanR, ptrChanR_fx, q_com, input_frame ); + q_target = L_get_q_buf1( &hStereoTCA->prevTargetGain, 1 ); + hStereoTCA->prevTargetGain_fx = float_to_fix( hStereoTCA->prevTargetGain, q_target ); + hStereoTCA->prevTargetGain_fx_e = Q31 - q_target; + hStereoTCA->corrStatsSmoothFac_fx = float_to_fix16( hStereoTCA->corrStatsSmoothFac, Q15 ); +#endif + estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hStereoTCA->instTargetGain = fix_to_float( hStereoTCA->instTargetGain_fx, Q31 - hStereoTCA->instTargetGain_fx_e ); + hStereoTCA->targetGain = fix_to_float( hStereoTCA->targetGain_fx, Q31 - hStereoTCA->targetGain_fx_e ); +#endif +#else estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag ); +#endif } /*-----------------------------------------------------------------* @@ -2605,8 +2817,8 @@ void stereo_tca_enc( fixedToFloat_arrL32( sts[1]->input_buff32_fx, sts[1]->input_buff, q_com, 1965 ); if ( hCPE->hStereoICBWE != NULL ) { - fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], hCPE->hStereoICBWE->icbwe_inp_mem[0], hCPE->hStereoICBWE->q_dataChan_fx, NS2SA( 48000, L_MEM_RECALC_TBE_NS ) ); - fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], hCPE->hStereoICBWE->icbwe_inp_mem[1], hCPE->hStereoICBWE->q_dataChan_fx, NS2SA( 48000, L_MEM_RECALC_TBE_NS ) ); + fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], hCPE->hStereoICBWE->icbwe_inp_mem[0], hCPE->hStereoICBWE->q_dataChan_fx, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); + fixedToFloat_arr( hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], hCPE->hStereoICBWE->icbwe_inp_mem[1], hCPE->hStereoICBWE->q_dataChan_fx, NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ) ); } #endif #else @@ -3123,6 +3335,12 @@ void stereo_tca_init_enc_fx( move32(); move32(); move32(); + hStereoTCA->targetGain_fx_e = Q2; // Q31 - Q29 + hStereoTCA->prevTargetGain_fx_e = Q2; // Q31 - Q29 + hStereoTCA->instTargetGain_fx_e = Q2; // Q31 - Q29 + move16(); + move16(); + move16(); hStereoTCA->corrStatsSmoothFac_fx = 22937; // Q15 move16(); diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index 8b9d4e4d5..4bd593858 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -1239,22 +1239,41 @@ void stereo_mdct_core_enc( float max_tb = 0; Word16 max_sb_fx = 0; Word16 max_tb_fx = 0; + float max_fir_tb = 0; + float max_iir_tb = 0; + float max_fir_sb = 0; + float max_iir_sb = 0; + + Word16 max_fir_tb_fx = 0; + Word16 max_iir_tb_fx = 0; + Word16 max_fir_sb_fx = 0; + Word16 max_iir_sb_fx = 0; FOR( Word16 sfb = 0; sfb < 23; sfb++ ) { f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - max_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_tb ); - max_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_tb ); + + max_fir_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_fir_tb ); + f2me_16( max_fir_tb, &max_fir_tb_fx, &hPrivateData->prevSFB_FIR_TB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ); + + max_iir_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_iir_tb ); + f2me_16( max_iir_tb, &max_iir_tb_fx, &hPrivateData->prevSFB_IIR_TB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ); + + max_fir_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_fir_sb ); + f2me_16( max_fir_sb, &max_fir_sb_fx, &hPrivateData->prevSFB_FIR_SB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ); + + max_iir_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_iir_sb ); + f2me_16( max_iir_sb, &max_iir_sb_fx, &hPrivateData->prevSFB_IIR_SB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ); + max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_sb ); f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + + max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); + f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); } FOR( i = 0; i < IGF_MAX_TILES; i++ ) @@ -1285,10 +1304,10 @@ void stereo_mdct_core_enc( me2f_buf( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->spectrum_e[n], &p_powerSpec[ch][0], hGrid->infoGranuleLen ); for ( Word16 sfb = 0; sfb < 23; sfb++ ) { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_FIR_TB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->prevSFB_IIR_TB_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_FIR_SB_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->prevSFB_IIR_SB_e[sfb] ); hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index fca33216b..c7f07245d 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -91,7 +91,6 @@ static ivas_error allocate_CoreCoder_enc_fx( #ifdef IVAS_FLOAT_FIXED noise_est_init_ivas_fx( st->hNoiseEst ); #endif - noise_est_init( st->hNoiseEst ); } IF( st->hVAD == NULL ) @@ -154,7 +153,11 @@ static ivas_error allocate_CoreCoder_enc( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ) ); } +#ifndef IVAS_FLOAT_FIXED noise_est_init( st->hNoiseEst ); +#else + noise_est_init_ivas_fx( st->hNoiseEst ); +#endif } if ( st->hVAD == NULL ) diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 16e14a312..384ad2083 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -45,6 +45,7 @@ #include "prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" +#include "ivas_prot_fx.h" #endif /*-------------------------------------------------------------------* @@ -1244,6 +1245,7 @@ void stereo_tcx_core_enc( *-------------------------------------------------------------------*/ /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ +#ifndef IVAS_FLOAT_FIXED int16_t ivas_acelp_tcx20_switching( Encoder_State *st, /* i/o: encoder state structure */ const float *inp, /* i : new input signal */ @@ -1555,3 +1557,579 @@ int16_t ivas_acelp_tcx20_switching( return smc_dec_ol; } +#else +Word16 ivas_acelp_tcx20_switching_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 *inp_fx, + Word16 q_inp, + Word16 *wsp, /*q_inp i : input weighted signal */ + Word16 non_staX, /*Q8 i : unbound non-stationarity for sp/mu clas*/ + Word16 *pitch_fr, /*Q6 i : fraction pitch values */ + Word16 *voicing_fr, /*Q15 i : fractional voicing values */ + Word16 currFlatness, /*Q7 i : flatness */ + Word16 lsp_mid[M], /*Q15 i : LSPs at the middle of the frame */ + Word16 stab_fac, /* i : LP filter stability */ + Word32 *res_cod_SNR_M, + Word16 *res_cod_SNR_M_e, + Word16 *tcx_mdct_window_fx, + const Word16 flag_16k_smc /* i : flag to compute parameters with 16kHz core */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 i, j; + Word32 dsnr; + Word32 snr_acelp; + Word16 i2, T0; + Word16 pitch_fr_local[4], voicing_fr_local[4]; + Word16 smc_dec_ol; + Word16 L_frame, L_frame_tmp, L_loop; + Word16 overlap; + Word16 tcx_offset; + Word16 tmp16, s, L_frame_4, iter; + Word32 *x_fx, tmp32, ener, fac, offset; + Word16 e_x, ener_e, scale_A, Q_A_q_tcx; + Word16 gainlpc_fx[FDNS_NPTS]; + Word16 gainlpc_e[FDNS_NPTS]; + Word16 gainlpc_noinv[FDNS_NPTS]; + Word16 gainlpc_noinv_e[FDNS_NPTS]; + Word16 Ap_fx[M + 1]; + Word16 A_q_tcx_fx[NB_SUBFR16k * ( M + 1 )]; + Word16 window_fx[L_LOOK_16k]; + PWord16 window_p_fx[L_LOOK_16k]; + Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 tcx_mdct_window_fx_local[L_LOOK_16k], scale; + Word32 en[N_MAX / 4]; + Word32 offset_tcx, target; + Word32 y_fx[N_MAX]; + Word32 tcx_snr; + Flag Overflow; + Word32 gain, noise; + Word32 *pt_ener_sfr, ener_sfr[NB_SUBFR16k]; + + /* Initialization */ + IF( flag_16k_smc ) + { + L_frame = st->L_frame; + move16(); + } + ELSE + { + L_frame = L_FRAME; + move16(); + } + + L_frame_tmp = L_frame; + move16(); + Copy( tcx_mdct_window_fx, tcx_mdct_window_fx_local, L_LOOK_16k ); + x_fx = hTcxEnc->spectrum_long_fx; + move32(); + e_x = 31 - 15; + move16(); + + + /* Check minimum pitch for quantization */ + FOR( i = 0; i < 4; i++ ) + { + pitch_fr_local[i] = pitch_fr[i]; + move16(); + voicing_fr_local[i] = voicing_fr[i]; + move16(); + } + + basop_E_LPC_f_lsp_a_conversion( lsp_mid, A_q_tcx_fx, M ); + Q_A_q_tcx = sub( 14, norm_s( A_q_tcx_fx[0] ) ); + scale_A = sub( Q12, Q_A_q_tcx ); + Copy_Scale_sig( A_q_tcx_fx, A_q_tcx_fx, M + 1, scale_A ); + + /*--------------------------------------------------------------* + * Estimate TCX SNR + *---------------------------------------------------------------*/ + + target = L_add( 0x11A5D28, 0 ); /* 0x11A5D28 -> 850.f * log2(10)/10 (Q16) */ + IF( flag_16k_smc ) + { + tcx_offset = st->hTcxCfg->tcx_offset; + move16(); + + IF( st->last_core == ACELP_CORE ) + { + L_frame = add( L_frame, tcx_offset ); + + IF( st->hTcxCfg->lfacNext < 0 ) + { + L_frame = sub( L_frame, st->hTcxCfg->lfacNext ); + tcx_offset = st->hTcxCfg->lfacNext; + move16(); + } + ELSE + { + tcx_offset = 0; + move16(); + } + } + + overlap = st->hTcxCfg->tcx_mdct_window_delay; + move16(); + Copy( tcx_mdct_window_fx_local, window_fx, L_LOOK_16k ); // Q15 + } + ELSE + { + overlap = L_LOOK_12k8; + move16(); + tcx_offset = shr( overlap, 1 ); + move16(); + FOR( i = 0; i < shr( overlap, 1 ); i++ ) + { + st->hTcxCfg->tcx_mdct_window[i].v.re = tcx_mdct_window_fx_local[overlap - 1 - i]; + st->hTcxCfg->tcx_mdct_window[i].v.im = tcx_mdct_window_fx_local[i]; + move16(); + move16(); + } + mdct_window_sine_IVAS_updated( window_p_fx, INT_FS_12k8, overlap, FULL_OVERLAP, st->element_mode ); + FOR( i = 0; i < shr( overlap, 1 ); i++ ) + { + window_fx[overlap - 1 - i] = window_p_fx[i].v.re; + window_fx[i] = window_p_fx[i].v.im; + move16(); + move16(); + } + + IF( st->last_core == ACELP_CORE ) + { + L_frame = add( L_frame, shr( L_frame, 2 ) ); + tcx_offset = sub( tcx_offset, shr( L_frame, 2 ) ); + } + } + + Copy( inp_fx + sub( tcx_offset, shr( overlap, 1 ) ), xn_buf_fx, add( L_frame, overlap ) ); + + L_frame_4 = shr( L_frame, 2 ); + IF( st->last_core == ACELP_CORE ) + { + test(); + test(); + IF( ( ( tcx_offset < 0 ) && flag_16k_smc ) || !flag_16k_smc ) + { + set16_zero_fx( xn_buf_fx, shr( overlap, 1 ) ); + } + } + ELSE + { + FOR( i = 0; i < overlap; i++ ) + { + xn_buf_fx[i] = mult( xn_buf_fx[i], window_fx[i] ); + move16(); + } + } + + FOR( i = 0; i < overlap; i++ ) + { + xn_buf_fx[L_frame + i] = mult( xn_buf_fx[L_frame + i], window_fx[overlap - 1 - i] ); + move16(); + } + e_x = 16; + move16(); + TCX_MDCT( xn_buf_fx, x_fx, &e_x, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); + scale_A = getScaleFactor32( x_fx, L_frame ); + Copy_Scale_sig32( x_fx, x_fx, L_frame, scale_A ); + e_x = sub( e_x, scale_A ); + + tmp16 = mult_r( shl( L_frame, 5 ), 29309 /*16*0.0559017 Q15*/ ); /* L_frame / sqrt(2*NORM_MDCT_FACTOR); Q9 */ + FOR( i = 0; i < L_frame; i++ ) + { + x_fx[i] = Mpy_32_16_1( x_fx[i], tmp16 ); + y_fx[i] = x_fx[i]; + move32(); + move32(); + } + e_x = add( e_x, 6 ); + + basop_weight_a( A_q_tcx_fx, Ap_fx, 30147 /*0.92 in Q15*/ ); + basop_lpc2mdct( Ap_fx, M, gainlpc_fx, gainlpc_e, gainlpc_noinv, gainlpc_noinv_e ); + + mdct_shaping( x_fx, L_frame, gainlpc_fx, gainlpc_e ); + + FOR( i = 0; i < L_frame_4; i++ ) + { + /* normalization */ + s = 31; + move16(); + + tmp16 = norm_l( x_fx[0] ); + if ( x_fx[0] != 0 ) + s = s_min( s, tmp16 ); + + tmp16 = norm_l( x_fx[1] ); + if ( x_fx[1] != 0 ) + s = s_min( s, tmp16 ); + + tmp16 = norm_l( x_fx[2] ); + if ( x_fx[2] != 0 ) + s = s_min( s, tmp16 ); + + tmp16 = norm_l( x_fx[3] ); + if ( x_fx[3] != 0 ) + s = s_min( s, tmp16 ); + + s = sub( s, 2 ); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l( 1 ); + + tmp16 = extract_h( L_shl( x_fx[0], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x_fx[1], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x_fx[2], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x_fx[3], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + s = shl( sub( e_x, s ), 1 ); + + tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */ + tmp32 = L_shr( tmp32, 9 ); /* 15Q16 */ + en[i] = L_add( tmp32, 0x2FD5F ); /* 0x2FD5F -> 9.f * log2(10)/10 (15Q16) */ + move32(); + + x_fx += 4; + } + + fac = L_add( 0x2A854B, 0 ); /* 0x2A854B -> 128.f * log2(10)/10 (15Q16) */ + offset = L_add( fac, 0 ); + + FOR( iter = 0; iter < 10; iter++ ) + { + fac = L_shr( fac, 1 ); + offset = L_sub( offset, fac ); + ener = L_deposit_l( 0 ); + + FOR( i = 0; i < L_frame_4; i += 4 ) + { + tmp32 = L_sub( en[i], offset ); + + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + { + ener = L_add( ener, tmp32 ); + } + + tmp32 = L_sub( en[i + 1], offset ); + + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + { + ener = L_add( ener, tmp32 ); + } + + tmp32 = L_sub( en[i + 2], offset ); + + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + { + ener = L_add( ener, tmp32 ); + } + + tmp32 = L_sub( en[i + 3], offset ); + + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + { + ener = L_add( ener, tmp32 ); + } + + IF( GT_32( ener, target ) ) + { + offset = L_add( offset, fac ); + BREAK; + } + } + } + + if ( LE_32( offset, 0xAA153 ) ) /* 0xAA153 -> 32.f * log2(10)/10 */ + { + offset = L_add( 0xFFD57AB5, 0 ); /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ + } + offset_tcx = offset; + move32(); + + s = add( extract_h( offset ), 1 ); + offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 ); + ener = BASOP_Util_InvLog2( L_shl( offset, 9 ) ); + + ener = Mpy_32_16_1( Mpy_32_16_1( ener, 0x78AE ), getInvFrameLen( L_frame ) ); /* 0x78AE -> sqrt(2)/12 (Q18) */ + ener_e = sub( s, 9 ); + + IF( !flag_16k_smc ) + { + const Word16 *bands; + const Word16 bands_20[8] = { 0, 5, 9, 19, 34, 51, 81, 111 }; + const Word16 bands_25[8] = { 0, 4, 7, 15, 28, 40, 65, 89 }; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + Word32 nrg_s, nrg_n; + Word16 temp_e, e_num, e_den, temp_ene_e; + temp_ene_e = ener_e; + tmp32 = Sqrt32( ener, &temp_ene_e ); + /*Approximate SNR of TCX*/ + set32_fx( x_fx, tmp32, L_frame ); /* ener_e */ + mdct_noiseShaping_ivas_fx( x_fx, &temp_ene_e, L_frame, gainlpc_noinv, gainlpc_noinv_e ); + + IF( st->last_core != ACELP_CORE ) + { + /*25Hz resolution*/ + bands = bands_25; + } + ELSE + { + /*20Hz resolution*/ + bands = bands_20; + } + + FOR( iter = 0; iter < 7; iter++ ) + { + nrg_s = L_deposit_l( 1 ); + nrg_n = L_deposit_l( 1 ); + e_num = 0; + move16(); + e_den = 0; + move16(); + + FOR( i = bands[iter]; i < bands[iter + 1]; i++ ) + { + nrg_s = BASOP_Util_Add_Mant32Exp( nrg_s, e_num, Mpy_32_32( y_fx[i], y_fx[i] ), shl( e_x, 1 ), &e_num ); + nrg_n = BASOP_Util_Add_Mant32Exp( nrg_n, e_den, Mpy_32_32( x_fx[i], x_fx[i] ), shl( temp_ene_e, 1 ), &e_den ); + } + res_cod_SNR_M[iter] = BASOP_Util_Divide3232_Scale_cadence( nrg_s, nrg_n, &temp_e ); + move32(); + res_cod_SNR_M_e[iter] = add( temp_e, sub( e_num, e_den ) ); + move16(); + } + } + + pt_ener_sfr = ener_sfr; + tcx_snr = L_deposit_l( 0 ); + + L_loop = L_frame; + move16(); + if ( flag_16k_smc ) + { + L_loop = L_frame_tmp; + move16(); + } + Word16 temp32_e = 0; + move16(); + Word32 temp_energy = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( ener_e ), 25 ) ); + temp_energy = L_add( temp_energy, 201326592 /* 6 in Q25*/ ); + temp_energy = L_shr( temp_energy, 9 ); /*temp_energy is log(( ener * L_SUBFR ))*/ + FOR( i = 0; i < L_loop; i += L_SUBFR ) + { + tmp32 = L_deposit_l( 0 ); + + FOR( j = 0; j < L_SUBFR; j++ ) + { + tmp32 = BASOP_Util_Add_Mant32Exp( tmp32, temp32_e, L_mult0( wsp[i + j], wsp[i + j] ), sub( 31, add( q_inp, q_inp ) ), &temp32_e ); + } + IF( tmp32 == 0 ) + { + *pt_ener_sfr = -668739840; /* 0xFFEC1185 -> log2(1e-6) in 6Q25 */ + move32(); + tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ + move32(); + } + ELSE + { + tmp32 = L_add( BASOP_Util_Log2( tmp32 ), L_shl( L_deposit_l( temp32_e ), 25 ) ); + *pt_ener_sfr = tmp32; + move32(); + tmp32 = L_shr( tmp32, 9 ); /* 15Q16 */ + } + tcx_snr = L_sub( L_add( tcx_snr, tmp32 ), temp_energy ); /*15Q16*/ + pt_ener_sfr++; + } + tmp16 = BASOP_Util_Divide1616_Scale( L_SUBFR, L_loop, &temp32_e ); + tmp16 = shl( tmp16, temp32_e ); + tcx_snr = Mpy_32_16_1( tcx_snr, tmp16 ); + tcx_snr = L_shl( Mpy_32_16_1( tcx_snr, 0x6054 /* 0x6054 -> 10/log2(10) (2Q13) */ ), 2 ); /* Q16*/ + + /*--------------------------------------------------------------* + * Estimate ACELP SNR + *---------------------------------------------------------------*/ + + pt_ener_sfr = ener_sfr; + IF( flag_16k_smc ) + { + scale = 3014; // Q15 + move16(); + } + ELSE + { + scale = 1933; // Q15 + move16(); + } + + tmp32 = L_deposit_l( 0 ); + temp_energy = L_deposit_l( 0 ); + ener_e = 0; + move16(); + L_loop = L_FRAME; + move16(); + if ( flag_16k_smc ) + { + L_loop = L_frame_tmp; + move16(); + } + i2 = 0; + move16(); + FOR( i = 0; i < L_loop; i += L_SUBFR ) + { + test(); + IF( flag_16k_smc && EQ_32( st->sr_core, INT_FS_16k ) ) + { + T0 = shr( add( add( pitch_fr_local[mult_r( i2, 26214 /*(float)L_FRAME/(float)L_FRAME16k Q15*/ )], shr( pitch_fr_local[mult_r( i2, 26214 /*(float)L_FRAME/(float)L_FRAME16k Q15*/ )], 2 ) ), ( 1 << 5 ) ), 6 ); + } + ELSE + { + T0 = shr( add( pitch_fr_local[i2], ( 1 << 5 ) ), 6 ); + } + + gain = get_gain2( wsp + i, wsp + sub( i, T0 ), L_SUBFR ); + + noise = L_deposit_l( 1 ); + + FOR( j = 0; j < L_SUBFR; j++ ) + { + tmp16 = round_fx_o( L_shl_o( Mpy_32_16_r( gain, wsp[i + j - T0] ), 15, &Overflow ), &Overflow ); // q_in + tmp16 = sub_o( wsp[i + j], tmp16, &Overflow ); // q_in + noise = L_mac0_o( noise, tmp16, tmp16, &Overflow ); // 2*q_in// + } + test(); + IF( noise == 0 || EQ_32( noise, 1 ) ) + { + IF( flag_16k_smc ) + { + tmp32 = -784301312; // Q25 + move32(); + } + ELSE + { + tmp32 = -805809664; // Q25 + move32(); + } + } + ELSE + { + noise = Mpy_32_16_1( noise, scale ); + tmp32 = L_add( BASOP_Util_Log2( noise ), L_shl( sub( 31, add( q_inp, q_inp ) ), 25 ) ); // Q25 + } + tmp32 = L_sub( *pt_ener_sfr, tmp32 ); // Q25 + temp_energy = BASOP_Util_Add_Mant32Exp( tmp32, 6, temp_energy, ener_e, &ener_e ); + pt_ener_sfr++; + i2 = add( i2, 1 ); + } + tmp16 = BASOP_Util_Divide1616_Scale( L_SUBFR, L_loop, &temp32_e ); + tmp16 = shl( tmp16, temp32_e ); + tmp32 = Mpy_32_16_1( temp_energy, tmp16 ); /*ener_e*/ + tmp32 = L_shr( Mpy_32_16_1( tmp32, 0x6054 /* 0x6054 -> 10/log2(10) (2Q13) */ ), sub( 13, ener_e ) ); /* Q16*/ + snr_acelp = tmp32; + + /*--------------------------------------------------------------* + * Switching Decision + *---------------------------------------------------------------*/ + + dsnr = 0; + move16(); + /* hysteresis for very small SNR differences between ACELP and TCX */ + + /* try to use TCX instead of ACELP on temporally stationary frames */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( GT_32( snr_acelp, tcx_snr ) ) && + ( LT_32( snr_acelp, L_add( tcx_snr, 131072 /*2.0f Q16*/ ) ) ) && + ( LT_16( add_o( st->prevTempFlatness_fx, currFlatness, &Overflow ), 52 /*3.25f Q4*/ ) || EQ_16( stab_fac, 0x7fff ) || + ( !flag_16k_smc && ( st->sp_aud_decision0 > 0 ) && LT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 2560 /*20.f Q7*/ ) ) ) && + ( LE_16( st->Nb_ACELP_frames, 6 ) ) ) + { + dsnr = -131072 /*-2.0f Q16*/; + move32(); + } + /* try to use ACELP instead of TCX on transient and "buzzy" frames */ + test(); + test(); + test(); + if ( ( LT_32( snr_acelp, tcx_snr ) ) && + ( GT_32( snr_acelp, L_sub( tcx_snr, 131072 /*2.0f Q16*/ ) ) ) && + ( GT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) && + ( GE_16( st->Nb_ACELP_frames, 6 ) ) ) + { + dsnr = 131072 /*2.0f Q16*/; + move32(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( !flag_16k_smc ) && ( LT_32( offset_tcx, 0x18950F ) ) && GT_16( non_staX, 1280 /*5.0f Q8*/ ) && ( GE_32( snr_acelp, L_sub( tcx_snr, 262144 /*4.0f in Q16*/ ) ) ) && GE_16( st->Nb_ACELP_frames, 1 ) && ( ( GT_16( st->hSpMusClas->lps_fx, st->hSpMusClas->lpm_fx ) && GE_16( shr( sum16_fx( voicing_fr_local, 4 ), 2 ), 9830 ) ) || ( GE_16( st->Nb_ACELP_frames, 6 ) && GT_16( st->hSpMusClas->lps_fx, sub( st->hSpMusClas->lpm_fx, 192 /*1.5in Q7*/ ) ) ) ) && ( st->sp_aud_decision0 == 0 ) && st->vad_flag ) + { + /* Fine tuned across various databases based on various metrics to detect TCX frames in speech.*/ + dsnr = 262144; /*4.0f Q16*/ + move32(); + } + + IF( st->flag_noisy_speech_snr ) + { + test(); + IF( st->vad_flag || st->Opt_DTX_ON ) + { + dsnr = L_add( dsnr, 131072 /*2.0f Q16*/ ); + } + ELSE + { + dsnr = L_sub( dsnr, 131072 /*2.0f Q16*/ ); + } + } + + + /* Select ACELP or TCX */ + test(); + test(); + IF( GT_32( L_add( snr_acelp, dsnr ), tcx_snr ) && ( st->sp_aud_decision0 == 0 || GT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) ) + { + smc_dec_ol = 0; + move16(); + } + ELSE + { + smc_dec_ol = 2; + move16(); + } + st->prevTempFlatness_fx = currFlatness; + move16(); + return smc_dec_ol; +} +#endif diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c index 93ded5108..87b67b12a 100644 --- a/lib_enc/long_enr.c +++ b/lib_enc/long_enr.c @@ -45,7 +45,7 @@ * * Compute relative energy, long-term average total noise energy and total active speech energy *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void long_enr( Encoder_State *st, /* i/o: encoder state structure */ const float Etot, /* i : total channel energy */ @@ -161,3 +161,4 @@ void long_enr( return; } +#endif diff --git a/lib_enc/nois_est.c b/lib_enc/nois_est.c index 32585626d..d6ebcc603 100644 --- a/lib_enc/nois_est.c +++ b/lib_enc/nois_est.c @@ -85,7 +85,7 @@ * * Initialization of Noise estimator *-----------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void noise_est_init( NOISE_EST_HANDLE hNoiseEst /* i/o: Noise estimation handle */ ) @@ -102,12 +102,8 @@ void noise_est_init( hNoiseEst->bckr[i] = E_MIN; hNoiseEst->ave_enr[i] = E_MIN; } - hNoiseEst->totalNoise = 0.0f; -#ifdef IVAS_FLOAT_FIXED - hNoiseEst->totalNoise_fx = 0; -#endif hNoiseEst->first_noise_updt = 0; hNoiseEst->first_noise_updt_cnt = 0; @@ -152,7 +148,7 @@ void noise_est_init( return; } - +#endif #ifndef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 355613596..c3af6c904 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -274,7 +274,32 @@ void noise_est_init_ivas_fx( ) { Word16 i; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < NB_BANDS; i++ ) + { + hNoiseEst->fr_bands1[i] = 1e-5f; + hNoiseEst->fr_bands2[i] = 1e-5f; + hNoiseEst->ave_enr2[i] = E_MIN; + + hNoiseEst->enrO[i] = E_MIN; + hNoiseEst->bckr[i] = E_MIN; + hNoiseEst->ave_enr[i] = E_MIN; + } + hNoiseEst->first_noise_updt = 0; + hNoiseEst->first_noise_updt_cnt = 0; + hNoiseEst->aEn = 6; + hNoiseEst->aEn_inac_cnt = 0; + hNoiseEst->harm_cor_cnt = 0; + hNoiseEst->bg_cnt = 0; + hNoiseEst->low_tn_track_cnt = 0; + + hNoiseEst->Etot_lp = 0.0f; + hNoiseEst->Etot_l_lp = 0.0f; + hNoiseEst->Etot_last = 0.0f; + hNoiseEst->Etot_v_h2 = 0.0f; + hNoiseEst->sign_dyn_lp = 0.0f; +#endif FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->fr_bands1_fx[i] = 1; @@ -350,7 +375,7 @@ void noise_est_init_ivas_fx( /* Tonal detector */ FOR( i = 0; i < L_FFT / 2; i++ ) { - hNoiseEst->old_S_fx[i] = 1; + hNoiseEst->old_S_fx[i] = ONE_IN_Q7; move16(); } set16_fx( hNoiseEst->cor_map_fx, 0, L_FFT / 2 ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 688769db0..fdf3c8cc9 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -769,13 +769,14 @@ typedef struct noise_estimation_structure float fr_bands2[NB_BANDS]; /* spectrum per critical bands 2 frames ago */ Word32 fr_bands1_fx[NB_BANDS]; /* Q_new + Q_SCALE spectrum per critical bands of the previous frame */ Word32 fr_bands2_fx[NB_BANDS]; /* Q_new + Q_SCALE spectrum per critical bands 2 frames ago */ - - float old_S[L_FFT / 2]; /* Tonal detector - prev. log-energy spectrum with subtracted floor */ - float cor_map[L_FFT / 2]; /* Tonal detector - LT correlation map */ - float noise_char; /* Tonal detector - LT noise character */ +#ifndef IVAS_FLOAT_FIXED + float old_S[L_FFT / 2]; /* Tonal detector - prev. log-energy spectrum with subtracted floor */ + float cor_map[L_FFT / 2]; /* Tonal detector - LT correlation map */ + float noise_char; /* Tonal detector - LT noise character */ + float act_pred; /* Tonal detector - prediction of speech activity from 0 to 1 (0-inactive, 1-active) */ + float multi_harm_limit; /* Tonal detector - adaptive threshold */ +#endif float ave_enr2[NB_BANDS]; /* Tonal detector - LT average E per crit. band (for non_sta2) */ - float act_pred; /* Tonal detector - prediction of speech activity from 0 to 1 (0-inactive, 1-active) */ - float multi_harm_limit; /* Tonal detector - adaptive threshold */ float enrO[NB_BANDS]; /* Noise estimator - previous energy per critical band */ float bckr[NB_BANDS]; /* Noise estimator - background noise estimation per critical band */ float ave_enr[NB_BANDS]; /* Noise estimator - long-term average energy per critical band */ @@ -789,24 +790,29 @@ typedef struct noise_estimation_structure Word32 bckr_fx[NB_BANDS]; /* Q_new + Q_SCALE Noise estimator - background noise estimation per critical band */ Word32 ave_enr_fx[NB_BANDS]; /* Q_new + Q_SCALE Noise estimator - long-term average energy per critical band */ - int16_t aEn; /* Noise estimator - noise estimator adaptation flag */ - float totalNoise; /* Noise estimator - total noise energy */ + int16_t aEn; /* Noise estimator - noise estimator adaptation flag */ +#ifndef IVAS_FLOAT_FIXED + float totalNoise; /* Noise estimator - total noise energy */ +#endif Word16 totalNoise_fx; /* Q8 Noise estimator - total noise energy */ int16_t first_noise_updt; /* Noise estimator - flag used to determine if the first noise update frame */ int16_t first_noise_updt_cnt; /* Noise estimator - counter of frame after first noise update */ int16_t harm_cor_cnt; /* Noise estimator - 1st memory counter of harm or correlation frame */ int16_t bg_cnt; /* Noise estimator - pause length counter */ - float Etot_l; /* Noise estimator - Track energy from below */ - float Etot_h; /* Noise estimator - Track energy from above */ - 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 */ - +#ifndef IVAS_FLOAT_FIXED + float Etot_l; /* Noise estimator - Track energy from below */ + float Etot_h; /* Noise estimator - Track energy from above */ +#endif + 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 */ +#ifndef IVAS_FLOAT_FIXED float lt_tn_track; float lt_tn_dist; float lt_Ellp_dist; float lt_haco_ev; +#endif Word16 Etot_l_fx; /* Q8 Noise estimator - Track energy from below */ Word16 Etot_h_fx; /* Q8 Noise estimator - Track energy from above */ Word16 Etot_l_lp_fx; /* Q8 Noise estimator - Smoothed low energy */ @@ -824,6 +830,7 @@ typedef struct noise_estimation_structure Word16 lt_Ellp_dist_fx; /* Etot low lp same domain as *Etot_l_lp, Q8 */ Word16 lt_haco_ev_fx; /* Q15 */ int16_t low_tn_track_cnt; +#ifndef IVAS_FLOAT_FIXED float epsP_0_2_lp; float epsP_0_2_ad_lp; float epsP_2_16_lp; @@ -831,6 +838,7 @@ typedef struct noise_estimation_structure float epsP_2_16_dlp_lp; float epsP_2_16_dlp_lp2; float lt_aEn_zero; +#endif Word16 epsP_0_2_lp_fx; /* Q12, all epsP quotas , range ]8.0 ..0]*/ Word16 epsP_0_2_ad_lp_fx; Word16 epsP_2_16_lp_fx; @@ -840,8 +848,10 @@ typedef struct noise_estimation_structure float Etot_v_h2; float sign_dyn_lp; +#ifndef IVAS_FLOAT_FIXED float Etot_st_est; /* Noise estimation - short term estimate of E{ Etot } */ float Etot_sq_st_est; /* Noise estimation - short term estimate of E{ Etot^2 } */ +#endif Word16 Etot_v_h2_fx; Word16 sign_dyn_lp_fx; /*Q8*/ @@ -1795,6 +1805,7 @@ typedef struct tcx_enc_structure 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 */ + Word16 q_spectrum_long_fx; } TCX_ENC_DATA, *TCX_ENC_HANDLE; typedef struct TransientDetection @@ -2156,8 +2167,8 @@ typedef struct enc_core_structure Word16 lp_noise_fx; /* CNG and DTX - LP filtered total noise estimation Q8 */ Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ Word16 interval_SID_fx; - Word32 bckr_tilt_lt; - int16_t active_cnt; /* counter of active frames */ + Word32 bckr_tilt_lt; // Q16 + int16_t active_cnt; /* counter of active frames */ TD_CNG_ENC_HANDLE hTdCngEnc; diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index 9e52923e8..f377bfb0d 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -1515,7 +1515,7 @@ int16_t tcx_res_Q_spec( void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ - const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF (*q_spectrum) */ + const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec) */ Word16 *q_powerSpec, /* i/o: Q of power spectrum */ diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index e94b19229..cef9e3066 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3418,3 +3418,69 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) att = mult_r( att, att ); } } + +#if 0 +void mdct_preShaping_fx( + Word16 x[], + const Word16 lg, + const Word16 gains[] ) +{ + Word16 i, j, k, l; + Word16 g; + Word16 m, n, k1, k2; + + j = 0; /* not counted, is included in ptr init */ + /* FDNS_NPTS = 64 !!! */ + k = idiv1616( lg, FDNS_NPTS ); + m = lg % FDNS_NPTS; + move16(); + IF( m ) + { + IF( LE_16( m, ( FDNS_NPTS / 2 ) ) ) + { + n = idiv1616( FDNS_NPTS, m ); + k1 = k; + move16(); + k2 = add( k, 1 ); + } + ELSE + { + n = idiv1616( FDNS_NPTS, sub( FDNS_NPTS, m ) ); + k1 = add( k, 1 ); + k2 = k; + } + FOR( i = 0; i < lg; ) + { + IF( j % n ) + { + k = k1; + } + ELSE + { + k = k2; + } + g = 1.f / gains[j++]; // Q15 + + /* Limit number of loops, if end is reached */ + k = min( k, lg - i ); + FOR( l = 0; l < k; l++ ) + { + x[i++] = mult( x[i++], g ); + } + } + } + ELSE + { + FOR( i = 0; i < lg; ) + { + g = 1.f / gains[j++]; // Q15 + FOR( l = 0; l < k; l++ ) + { + x[i++] = mult( x[i++], g ); + } + } + } + + return; +} +#endif -- GitLab